Subversion Repositories spk

Rev

Rev 196 | Rev 218 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
#include <spk.h>
2
 
197 cycrow 3
Utils::WString g_dir;
1 cycrow 4
 
5
#ifdef _WIN32
6
#include <windows.h>
7
#include <direct.h>
8
//#include <shlobj.h>
9
#else
10
#include <dirent.h> 
11
#include <sys/types.h> 
12
#include <sys/param.h> 
13
#include <sys/stat.h> 
14
#include <unistd.h> 
15
#endif
16
 
17
void PrintError ( int err )
18
{
19
	switch ( err )
20
	{
21
		case CATERR_NODATFILE:
22
			printf ( "No dat file found\n" );
23
			break;
24
		case CATERR_NOCATFILE:
25
			printf ( "Unable to open cat file\n" );
26
			break;
27
		case CATERR_FILEEMPTY:
28
			printf ( "Cat file is empty\n" );
29
			break;
30
		case CATERR_READCAT:
31
			printf ( "Unable to read cat file\n" );
32
			break;
33
		case CATERR_DECRYPT:
34
			printf ( "Unable to decrypt cat file\n" );
35
			break;
36
		case CATERR_MISMATCH:
37
			printf ( "Dat file size mismatch\n" );
38
			break;
39
	}
40
}
41
 
197 cycrow 42
void ListFiles ( CyString filename, Utils::WString &searchmask )
1 cycrow 43
{
44
	printf ( "Listing files in %s...", filename.c_str() );
197 cycrow 45
	if (!searchmask.empty())
46
		wprintf(L"(%s)", searchmask.c_str() );
47
	printf("\n");
1 cycrow 48
 
49
	CCatFile catfile;
197 cycrow 50
	int err = catfile.open(filename.ToString(), L"", CATREAD_CATDECRYPT);
1 cycrow 51
 
52
	if ( err == CATERR_NONE )
53
	{
54
		printf ( "Opened file\n" );
124 cycrow 55
		for (unsigned int i = 0; i < catfile.GetNumFiles(); i++)
1 cycrow 56
		{
57
			SInCatFile *file = catfile.GetFile ( i );
58
 
197 cycrow 59
			if (!searchmask.empty())
1 cycrow 60
			{
197 cycrow 61
				if (!searchmask.match(file->sFile))
1 cycrow 62
					continue;
63
			}
64
 
197 cycrow 65
			wprintf(L"[%9s] %s\n", SPK::GetSizeString(file->lSize).c_str(), file->sFile.c_str() );
1 cycrow 66
		}
67
	}
68
	else
69
		PrintError ( err );
70
}
71
 
197 cycrow 72
bool findFiles(Utils::WStringList &files, const Utils::WString &filepattern)
127 cycrow 73
{
197 cycrow 74
	CFileIO File((filepattern.contains(L":")) ? filepattern : g_dir + L"/" + filepattern);
75
	return File.GetDirIO().dirList(files, Utils::WString::Null(), File.filename());
127 cycrow 76
}
1 cycrow 77
 
127 cycrow 78
 
1 cycrow 79
void ExtractFile ( CyString filename, CyString to, bool preserve )
80
{
54 cycrow 81
	if ( !filename.IsIn ( "::" ) ) return;
41 cycrow 82
 
125 cycrow 83
	Utils::String catfile = filename.GetToken ( "::", 1, 1 ).ToString();
84
	Utils::String filemask = filename.GetToken ( "::", 2, 2 ).ToString();
1 cycrow 85
 
86
	CCatFile cat;
125 cycrow 87
	int err = cat.open(catfile, "", CATREAD_DAT);
1 cycrow 88
	if ( err )
89
	{
90
		PrintError ( err );
91
		return;
92
	}
93
 
94
	// all files
95
	if ( filemask == "*" )
96
	{
124 cycrow 97
		for (unsigned int i = 0; i < cat.GetNumFiles(); i++)
1 cycrow 98
		{
99
			SInCatFile *f = cat.GetFile(i);
181 cycrow 100
			if (!cat.extractFile(f, to.ToString()))
197 cycrow 101
				wprintf(L"Error: %s\n", cat.getErrorString().c_str() );
1 cycrow 102
			else
197 cycrow 103
				wprintf(L"File has been written (%s)\n", cat.errorString().c_str() );
1 cycrow 104
		}
105
 
106
		return;
107
	}
108
 
41 cycrow 109
	//TODO: add proper file mask for extracting
110
	//CyStringList *fileList = FindFiles(filemask);
111
	CyStringList *fileList = new CyStringList;
125 cycrow 112
	fileList->PushBack(CyString(filemask));
41 cycrow 113
	if ( !fileList || fileList->Empty() )
1 cycrow 114
	{
41 cycrow 115
		if ( fileList ) delete fileList;
1 cycrow 116
		printf ( "Error: unable to find any files matching: %s\n", filemask.c_str() );
117
		return;
118
	}
119
 
120
	for ( SStringList *fl = fileList->Head(); fl; fl = fl->next )
121
	{
181 cycrow 122
		Utils::String file = fl->str.ToString();
123
		if (!cat.extractFile(file, to.ToString(), preserve))
197 cycrow 124
			wprintf(L"Error: %s\n", cat.getErrorString().c_str() );
1 cycrow 125
		else
197 cycrow 126
			wprintf(L"File has been written (%s)\n", cat.errorString().c_str() );
1 cycrow 127
	}
128
 
129
	delete fileList;
130
}
131
 
197 cycrow 132
void AppendFile ( CyString C_File, const Utils::WString &filepattern )
1 cycrow 133
{
197 cycrow 134
	Utils::WString catfile;
135
	Utils::WString file;
1 cycrow 136
 
137
	C_File = C_File.FindReplace("\\", "/");
138
 
139
	bool doFile = false;
140
	if ( !C_File.IsIn ( "::" ) )
141
	{
125 cycrow 142
		catfile = C_File.ToString();
1 cycrow 143
		doFile = true;
144
	}
145
	else
146
	{
125 cycrow 147
		catfile = C_File.GetToken ( "::", 1, 1 ).ToString();
148
		file = C_File.GetToken ( "::", 2, 2 ).ToString();
1 cycrow 149
	}
150
 
197 cycrow 151
	Utils::WStringList list;
152
	findFiles(list, filepattern);
158 cycrow 153
	if (!list.size())
1 cycrow 154
	{
197 cycrow 155
		wprintf(L"Error: no files found to add: %s\n", filepattern.c_str());
1 cycrow 156
		return;
157
	}
158
 
159
	CCatFile cat;
197 cycrow 160
	int err = cat.open(catfile, L"", CATREAD_CATDECRYPT);
1 cycrow 161
	if ( err )
162
	{
163
		PrintError ( err );
164
		return;
165
	}
166
 
158 cycrow 167
	for (auto itr = list.begin(); itr != list.end(); itr++)
1 cycrow 168
	{
197 cycrow 169
		Utils::WString filename = (*itr)->str;
158 cycrow 170
		if (doFile)
1 cycrow 171
			file = filename;
172
 
197 cycrow 173
		if (!file.contains(L"."))
1 cycrow 174
		{
197 cycrow 175
			if (file[file.length() - 1] != L'/')
176
				file += L"/";
177
			file += CFileIO(filename).filename();
1 cycrow 178
		}
179
 
181 cycrow 180
		if (cat.appendFile(filename, file))
197 cycrow 181
			wprintf(L"File %s has beed added to: %s::%s\n", filename.c_str(), catfile.c_str(), file.c_str());
1 cycrow 182
		else
197 cycrow 183
			wprintf(L"Error: Unable to add file: %s\n", filename.c_str());
1 cycrow 184
	}
185
}
186
 
187
void RemoveFile ( CyString C_File, CyString remfile )
188
{
189
	// first open the cat file
190
	CCatFile cat;
125 cycrow 191
	int err = cat.open(C_File.ToString(), "", CATREAD_CATDECRYPT);
1 cycrow 192
	if ( err )
193
	{
194
		PrintError ( err );
195
		return;
196
	}
197
 
181 cycrow 198
	SInCatFile *f = cat.findData(remfile.ToString());
1 cycrow 199
	if ( !f )
200
	{
201
		printf ( "Unable to find %s in cat file\n", remfile.c_str() );
202
		return;
203
	}
204
 
124 cycrow 205
	if (cat.removeFile(f))
1 cycrow 206
		printf ( "File has been removed from archive\n" );
207
}
208
 
185 cycrow 209
void UnpackFile(const Utils::String &file, const Utils::String &tofile )
1 cycrow 210
{
197 cycrow 211
	Utils::WStringList list;
185 cycrow 212
	if(!findFiles(list, file) || !list.size())
1 cycrow 213
	{
214
		printf("Error: no files found to unpack: %s\n", file.c_str());
215
		return;
216
	}
217
 
127 cycrow 218
	for(auto itr = list.first(); itr; list.next())
1 cycrow 219
	{
197 cycrow 220
		Utils::WString filename = CFileIO(file).dir() + L"/" + itr->str;
1 cycrow 221
 
222
		C_File f(filename);
223
		if ( !f.CheckValidFilePointer() )
197 cycrow 224
			wprintf(L"Error: %s doesn't exists\n", filename.c_str() );
1 cycrow 225
		else if ( !f.ReadFromFile() )
197 cycrow 226
			wprintf(L"Error: unable to open file: %s\n", filename.c_str() );
1 cycrow 227
		else
228
		{
229
			f.UnPCKFile();
185 cycrow 230
			if ( tofile.empty() )
178 cycrow 231
				f.changeFileExt("xml");
185 cycrow 232
			else if ( tofile.left(2) == "*." )
196 cycrow 233
				f.changeFileExt(CFileIO(tofile).extension().toString());
1 cycrow 234
			else
185 cycrow 235
				f.setFilename(tofile);
1 cycrow 236
 
129 cycrow 237
			if ( !f.writeFilePointer() )
1 cycrow 238
				printf("Error: unable to write file: %s\n", tofile.c_str() );
239
			else
197 cycrow 240
				wprintf(L"%hs has been unpacked to %s\n", file.c_str(), f.filename().c_str() );
1 cycrow 241
		}
242
	}
243
}
244
 
185 cycrow 245
void PackFile(const Utils::String &file, const Utils::String &tofile)
1 cycrow 246
{
197 cycrow 247
	Utils::WStringList list;
185 cycrow 248
	if(!findFiles(list, file) || !list.size())
1 cycrow 249
	{
250
		printf("Error: no files found to pack: %s\n", file.c_str());
251
		return;
252
	}
253
 
127 cycrow 254
	for(auto itr = list.first(); itr; itr = list.next())
1 cycrow 255
	{
197 cycrow 256
		Utils::WString filename = CFileIO(file).dir() + L"/" + itr->str;
1 cycrow 257
 
258
		C_File f(filename);
259
		if ( !f.CheckValidFilePointer() )
197 cycrow 260
			wprintf(L"Error: %s doesn't exists\n", filename.c_str() );
1 cycrow 261
		else if ( !f.ReadFromFile() )
197 cycrow 262
			wprintf(L"Error: unable to open file: %s\n", filename.c_str() );
1 cycrow 263
		else if ( !f.PCKFile() )
197 cycrow 264
			wprintf(L"Error: unable to pack file: %s\n", filename.c_str() );
1 cycrow 265
		else
266
		{
185 cycrow 267
			if ( tofile.empty() )
1 cycrow 268
			{
197 cycrow 269
				if ( f.checkFileExt(L"bob") )
270
					f.changeFileExt(L"pbb");
271
				else if ( f.checkFileExt(L"bod") )
272
					f.changeFileExt(L"pbd");
1 cycrow 273
				else
197 cycrow 274
					f.changeFileExt(L"pck");
1 cycrow 275
			}
197 cycrow 276
			else if ( tofile.left(2) == L"*." )
185 cycrow 277
				f.changeFileExt(tofile.right(3));
1 cycrow 278
			else
185 cycrow 279
				f.setFilename(tofile);
1 cycrow 280
 
129 cycrow 281
			if ( !f.writeFilePointer() )
1 cycrow 282
				printf("Error: unable to write file: %s\n", tofile.c_str() );
283
			else
197 cycrow 284
				wprintf(L"%hs has been packed to %s\n", file.c_str(), f.filename().c_str() );
1 cycrow 285
		}
286
	}
287
}
288
 
289
void PrintSyntax(CyString cmd)
290
{
291
	printf ( "Syntax: %s <flags> [arguments]\n", cmd.c_str() );
292
	printf ( "Flags:\n");
293
	printf ( "\t-l <filename> [filemask]\n");
294
	printf ( "\t\tLists the contents of a cat file, with optional search mask\n");
295
	printf ( "\t-x <catfile::filename> [dir]\n");
296
	printf ( "\t\textracts a file from a cat file to the optional directory\n");
297
	printf ( "\t-xp <catfile::filename> [dir]\n");
298
	printf ( "\t\textracts a file from a cat file to the optional directory, preserves directory structure\n");
299
	printf ( "\t-xa <catfile> [dir]\n");
300
	printf ( "\t\textracts all files to optional directory\n");
301
	printf ( "\t-a <filename> <catfile::tofile>\n");
302
	printf ( "\t\tAdds the file into a cat archive, saves it as <tofile>\n");
303
	printf ( "\t-r <catfile> <file>\n");
304
	printf ( "\t\tRemoves a file from an archive\n");
305
	printf ( "\t-u <filename> <tofile>\n");
306
	printf ( "\t\tUnpacks a file, ie from pck to xml/txt\n");
307
	printf ( "\t-p <filename> <tofile>\n");
308
	printf ( "\t\tPacks a file, ie from xml/txt to pck\n");
309
}
310
 
311
int main ( int argc, char **argv )
312
{
313
	printf ( "\nCATPCK Tool V1.21 27/03/2011 (SPK: %.2f) Created by Cycrow\n\n", GetLibraryVersion() );
314
 
315
	// parse the cmd name
197 cycrow 316
	Utils::WString cmd (argv[0]);
317
	cmd = cmd.findReplace(L"\\", L"/");
318
	g_dir = cmd.tokens(L"/", 1, cmd.countToken(L"/") - 1);
319
	cmd = cmd.token (L"/", -1);
1 cycrow 320
 
197 cycrow 321
	if (g_dir.empty())
1 cycrow 322
	{
323
	    #ifdef _WIN32
197 cycrow 324
		g_dir = Utils::WString(_getcwd(NULL, 0));
1 cycrow 325
		#else
197 cycrow 326
		g_dir = Utils::WString(getcwd(NULL, 0));
1 cycrow 327
		#endif
197 cycrow 328
		if (g_dir.empty())
329
			g_dir = L"./";
1 cycrow 330
	}
331
 
332
	if ( argc < 2 )
197 cycrow 333
		PrintSyntax(CyString(cmd.toString()));
1 cycrow 334
	else
335
	{
336
		CyString command ( argv[1] );
337
		command.ToLower();
338
 
339
		if ( (command == "-l") || (command == "-list") )
340
		{
341
			if ( argc < 3 )
197 cycrow 342
				wprintf(L"Syntax: %s -l <filename> [filemask]\n\tLists the contents of the cat file\n", cmd.c_str() );
1 cycrow 343
			else if ( argc < 4 )
197 cycrow 344
				ListFiles ( CyString(argv[2]), Utils::WString(L""));
1 cycrow 345
			else
197 cycrow 346
				ListFiles ( CyString(argv[2]), Utils::WString(argv[3]));
1 cycrow 347
		}
348
		else if ( (command == "-x") || (command == "-extract") || (command == "-xp") || (command == "-extractpreserve") )
349
		{
350
			if ( argc < 3 )
197 cycrow 351
				wprintf(L"Syntax: %s %hs <catfile::filename> [dir]\n\tExtracts a file from the cat archive\n", cmd.c_str(), command.c_str() );
1 cycrow 352
			else if ( argc < 4 )
353
				ExtractFile ( CyString(argv[2]), CyString(""), (command == "-xp" || command == "-extractpreserve") ? true : false );
354
			else
355
				ExtractFile ( CyString(argv[2]), CyString(argv[3]), (command == "-xp" || command == "-extractpreserve") ? true : false );
356
		}
357
		else if ( (command == "-xa") || (command == "-extractall") )
358
		{
359
			if ( argc < 3 )
197 cycrow 360
				wprintf(L"Syntax: %s %hs <catfile> [dir]\n\tExtracts all files from the cat archive\n", cmd.c_str(), command.c_str() );
1 cycrow 361
			else if ( argc < 4 )
362
				ExtractFile ( CyString(argv[2]) + "::*", CyString(""), true );
363
			else
364
				ExtractFile ( CyString(argv[2]) + "::*", CyString(argv[3]), true );
365
		}
366
		else if ( (command == "-a") || (command == "-append") )
367
		{
368
			if ( argc < 4 )
197 cycrow 369
				wprintf(L"Syntax: %s -a <filename> <catfile::tofile>\n\tAppends a file into the archive\n", cmd.c_str() );
1 cycrow 370
			else
197 cycrow 371
				AppendFile ( CyString(argv[3]), Utils::WString(argv[2]));
1 cycrow 372
		}
373
		else if ( (command == "-r") || (command == "-remove") )
374
		{
375
			if ( argc < 4 )
197 cycrow 376
				wprintf(L"Syntax: %s -r <catfile> <filename>\n\tRemoves a file from the archive\n", cmd.c_str() );
1 cycrow 377
			else
378
				RemoveFile ( CyString(argv[2]), CyString(argv[3]) );
379
		}
380
		else if ( (command == "-u") || (command == "-unpack") )
381
		{
382
			if ( argc < 3 )
197 cycrow 383
				wprintf(L"Syntax: %s -u <filename> [to]\n\tUnpacks a file", cmd.c_str() );
1 cycrow 384
			else if ( argc < 4 )
185 cycrow 385
				UnpackFile(argv[2], "" );
1 cycrow 386
			else
185 cycrow 387
				UnpackFile(argv[2], argv[3]);
1 cycrow 388
		}
389
		else if ( (command == "-p") || (command == "-pack") )
390
		{
391
			if ( argc < 3 )
197 cycrow 392
				wprintf(L"Syntax: %s -p <filename> [to]\n\tPacks a file to .pck", cmd.c_str() );
1 cycrow 393
			else if ( argc < 4 )
185 cycrow 394
				PackFile(argv[2], "");
1 cycrow 395
			else
185 cycrow 396
				PackFile(argv[2], argv[3]);
1 cycrow 397
		}
398
		else
399
		{
400
			printf("Invalaid flag: %s\n\n", command.c_str());
197 cycrow 401
			PrintSyntax(CyString(cmd.toString()));
1 cycrow 402
		}
403
	}
404
 
405
#ifdef _DEBUG
406
	char pause;
407
	printf ( "\n\nPress a key to end\n" );
408
	scanf ( "%c", &pause );
409
#endif
410
 
411
	return 0;
412
}
413