Subversion Repositories spk

Rev

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