Subversion Repositories spk

Rev

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