Subversion Repositories spk

Rev

Rev 305 | Rev 314 | 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
 
197 cycrow 75
bool findFiles(Utils::WStringList &files, const Utils::WString &filepattern)
127 cycrow 76
{
197 cycrow 77
	CFileIO File((filepattern.contains(L":")) ? filepattern : g_dir + L"/" + filepattern);
305 cycrow 78
	return File.GetDirIO().dirList(files, Utils::WString::Null(), File.filename(), true);
127 cycrow 79
}
1 cycrow 80
 
127 cycrow 81
 
222 cycrow 82
void ExtractFile (const Utils::WString &filename, const Utils::WString &to, bool preserve )
1 cycrow 83
{
222 cycrow 84
	if ( !filename.contains(L"::") ) return;
41 cycrow 85
 
222 cycrow 86
	Utils::WString catfile = filename.token(L"::", 1);
87
	Utils::WString filemask = filename.token(L"::", 2);
1 cycrow 88
 
89
	CCatFile cat;
222 cycrow 90
	int err = cat.open(catfile, L"", CATREAD_DAT);
1 cycrow 91
	if ( err )
92
	{
93
		PrintError ( err );
94
		return;
95
	}
96
 
97
	// all files
222 cycrow 98
	if ( filemask == L"*" )
1 cycrow 99
	{
124 cycrow 100
		for (unsigned int i = 0; i < cat.GetNumFiles(); i++)
1 cycrow 101
		{
102
			SInCatFile *f = cat.GetFile(i);
222 cycrow 103
			if (!cat.extractFile(f, to))
197 cycrow 104
				wprintf(L"Error: %s\n", cat.getErrorString().c_str() );
1 cycrow 105
			else
197 cycrow 106
				wprintf(L"File has been written (%s)\n", cat.errorString().c_str() );
1 cycrow 107
		}
108
 
109
		return;
110
	}
111
 
41 cycrow 112
	//TODO: add proper file mask for extracting
222 cycrow 113
	Utils::WStringList fileList;
114
	fileList.pushBack(filemask);
115
	if (fileList.empty())
1 cycrow 116
	{
222 cycrow 117
		wprintf(L"Error: unable to find any files matching: %s\n", filemask.c_str() );
1 cycrow 118
		return;
119
	}
120
 
222 cycrow 121
	for (auto itr = fileList.begin(); itr != fileList.end(); itr++)
1 cycrow 122
	{
222 cycrow 123
		Utils::WString file = (*itr)->str;
124
		if (!cat.extractFile(file, to, preserve))
197 cycrow 125
			wprintf(L"Error: %s\n", cat.getErrorString().c_str() );
1 cycrow 126
		else
197 cycrow 127
			wprintf(L"File has been written (%s)\n", cat.errorString().c_str() );
1 cycrow 128
	}
129
}
130
 
276 cycrow 131
void AppendFile (const Utils::WString &sFile, const Utils::WString &filepattern )
1 cycrow 132
{
197 cycrow 133
	Utils::WString catfile;
134
	Utils::WString file;
1 cycrow 135
 
276 cycrow 136
	Utils::WString C_File = sFile.findReplace(L"\\", L"/");
1 cycrow 137
	bool doFile = false;
276 cycrow 138
	if ( !C_File.contains(L"::"))
1 cycrow 139
	{
276 cycrow 140
		catfile = C_File;
1 cycrow 141
		doFile = true;
142
	}
143
	else
144
	{
276 cycrow 145
		catfile = C_File.token(L"::", 1);
305 cycrow 146
		file = C_File.token(L"::", 2);
1 cycrow 147
	}
148
 
305 cycrow 149
	if (!catfile.contains(":"))
150
		catfile = g_dir + L"/" + catfile;
151
 
197 cycrow 152
	Utils::WStringList list;
153
	findFiles(list, filepattern);
158 cycrow 154
	if (!list.size())
1 cycrow 155
	{
197 cycrow 156
		wprintf(L"Error: no files found to add: %s\n", filepattern.c_str());
1 cycrow 157
		return;
158
	}
159
 
160
	CCatFile cat;
197 cycrow 161
	int err = cat.open(catfile, L"", CATREAD_CATDECRYPT);
305 cycrow 162
	if ( err && err != CATERR_CREATED)
1 cycrow 163
	{
164
		PrintError ( err );
165
		return;
166
	}
167
 
158 cycrow 168
	for (auto itr = list.begin(); itr != list.end(); itr++)
1 cycrow 169
	{
197 cycrow 170
		Utils::WString filename = (*itr)->str;
305 cycrow 171
		Utils::WString toFile = file;
158 cycrow 172
		if (doFile)
305 cycrow 173
			toFile = filename;
1 cycrow 174
 
305 cycrow 175
		if (!toFile.contains(L"."))
1 cycrow 176
		{
305 cycrow 177
			if (toFile[toFile.length() - 1] != L'/')
178
				toFile += L"/";
179
			toFile += CFileIO(filename).filename();
1 cycrow 180
		}
181
 
305 cycrow 182
		if (cat.appendFile(filename, toFile))
183
			wprintf(L"File %s has beed added to: %s::%s\n", filename.c_str(), catfile.c_str(), toFile.c_str());
1 cycrow 184
		else
197 cycrow 185
			wprintf(L"Error: Unable to add file: %s\n", filename.c_str());
1 cycrow 186
	}
187
}
188
 
226 cycrow 189
void RemoveFile (const Utils::WString &C_File, const Utils::WString &remfile )
1 cycrow 190
{
191
	// first open the cat file
192
	CCatFile cat;
226 cycrow 193
	int err = cat.open(C_File, L"", CATREAD_CATDECRYPT);
1 cycrow 194
	if ( err )
195
	{
196
		PrintError ( err );
197
		return;
198
	}
199
 
226 cycrow 200
	SInCatFile *f = cat.findData(remfile);
1 cycrow 201
	if ( !f )
202
	{
226 cycrow 203
		wprintf(L"Unable to find %s in cat file\n", remfile.c_str() );
1 cycrow 204
		return;
205
	}
206
 
124 cycrow 207
	if (cat.removeFile(f))
1 cycrow 208
		printf ( "File has been removed from archive\n" );
209
}
210
 
276 cycrow 211
void UnpackFile(const Utils::WString &file, const Utils::WString &tofile, const Utils::WString &ext)
1 cycrow 212
{
197 cycrow 213
	Utils::WStringList list;
185 cycrow 214
	if(!findFiles(list, file) || !list.size())
1 cycrow 215
	{
226 cycrow 216
		wprintf(L"Error: no files found to unpack: %s\n", file.c_str());
1 cycrow 217
		return;
218
	}
219
 
276 cycrow 220
	for(auto itr = list.first(); itr; itr = list.next())
1 cycrow 221
	{
312 cycrow 222
		Utils::WString filename = itr->str;
1 cycrow 223
 
224
		C_File f(filename);
276 cycrow 225
		if (!f.CheckValidFilePointer())
226
		{
227
			CFileIO File((file.contains(L":")) ? file : g_dir + L"/" + file);
228
			filename = File.GetDirIO().file(itr->str);
229
			f.setFilename(filename);
230
		}
231
 
232
		Utils::WString oldFilename = f.filename();
233
 
1 cycrow 234
		if ( !f.CheckValidFilePointer() )
197 cycrow 235
			wprintf(L"Error: %s doesn't exists\n", filename.c_str() );
1 cycrow 236
		else if ( !f.ReadFromFile() )
197 cycrow 237
			wprintf(L"Error: unable to open file: %s\n", filename.c_str() );
1 cycrow 238
		else
239
		{
312 cycrow 240
			if(!f.UnPCKFile())
241
				wprintf(L"Error: unable to unpack file: %s\n", filename.c_str());
1 cycrow 242
			else
312 cycrow 243
			{
244
				if (tofile.empty())
245
					f.changeFileExt(ext.empty() ? L"xml" : ext);
246
				else if (tofile.left(2) == L"*.")
247
					f.changeFileExt(CFileIO(tofile).extension().toString());
248
				else
249
					f.setFilename(tofile);
1 cycrow 250
 
312 cycrow 251
				if (!f.writeFilePointer())
252
					wprintf(L"Error: unable to write file: %s\n", tofile.c_str());
253
				else
254
					wprintf(L"%s has been unpacked to %s\n", oldFilename.c_str(), f.filename().c_str());
255
			}
1 cycrow 256
		}
257
	}
258
}
259
 
276 cycrow 260
void PackFile(const Utils::WString &file, const Utils::WString &tofile)
1 cycrow 261
{
197 cycrow 262
	Utils::WStringList list;
185 cycrow 263
	if(!findFiles(list, file) || !list.size())
1 cycrow 264
	{
276 cycrow 265
		wprintf(L"Error: no files found to pack: %s\n", file.c_str());
1 cycrow 266
		return;
267
	}
268
 
127 cycrow 269
	for(auto itr = list.first(); itr; itr = list.next())
1 cycrow 270
	{
312 cycrow 271
		Utils::WString filename = itr->str;
1 cycrow 272
 
273
		C_File f(filename);
274
		if ( !f.CheckValidFilePointer() )
197 cycrow 275
			wprintf(L"Error: %s doesn't exists\n", filename.c_str() );
1 cycrow 276
		else if ( !f.ReadFromFile() )
197 cycrow 277
			wprintf(L"Error: unable to open file: %s\n", filename.c_str() );
1 cycrow 278
		else if ( !f.PCKFile() )
197 cycrow 279
			wprintf(L"Error: unable to pack file: %s\n", filename.c_str() );
1 cycrow 280
		else
281
		{
185 cycrow 282
			if ( tofile.empty() )
1 cycrow 283
			{
197 cycrow 284
				if ( f.checkFileExt(L"bob") )
285
					f.changeFileExt(L"pbb");
286
				else if ( f.checkFileExt(L"bod") )
287
					f.changeFileExt(L"pbd");
1 cycrow 288
				else
197 cycrow 289
					f.changeFileExt(L"pck");
1 cycrow 290
			}
197 cycrow 291
			else if ( tofile.left(2) == L"*." )
185 cycrow 292
				f.changeFileExt(tofile.right(3));
1 cycrow 293
			else
185 cycrow 294
				f.setFilename(tofile);
1 cycrow 295
 
129 cycrow 296
			if ( !f.writeFilePointer() )
276 cycrow 297
				wprintf(L"Error: unable to write file: %s\n", tofile.c_str() );
1 cycrow 298
			else
276 cycrow 299
				wprintf(L"%s has been packed to %s\n", file.c_str(), f.filename().c_str() );
1 cycrow 300
		}
301
	}
302
}
303
 
298 cycrow 304
void PrintSyntax(const Utils::WString &cmd)
1 cycrow 305
{
298 cycrow 306
	wprintf(L"Syntax: %s <flags> [arguments]\n", cmd.c_str() );
307
	wprintf(L"Flags:\n");
308
	wprintf(L"\t-l <filename> [filemask]\n");
309
	wprintf(L"\t\tLists the contents of a cat file, with optional search mask\n");
310
	wprintf(L"\t-x <catfile::filename> [dir]\n");
311
	wprintf(L"\t\textracts a file from a cat file to the optional directory\n");
312
	wprintf(L"\t-xp <catfile::filename> [dir]\n");
313
	wprintf(L"\t\textracts a file from a cat file to the optional directory, preserves directory structure\n");
314
	wprintf(L"\t-xa <catfile> [dir]\n");
315
	wprintf(L"\t\textracts all files to optional directory\n");
316
	wprintf(L"\t-a <filename> <catfile::tofile>\n");
317
	wprintf(L"\t\tAdds the file into a cat archive, saves it as <tofile>\n");
318
	wprintf(L"\t-r <catfile> <file>\n");
319
	wprintf(L"\t\tRemoves a file from an archive\n");
320
	wprintf(L"\t[--ext:EXTENSION] -u <filename> [tofile]\n");
321
	wprintf(L"\t\tUnpacks a file, ie from pck to xml/txt\n");
322
	wprintf(L"\t-p <filename> <tofile>\n");
323
	wprintf(L"\t\tPacks a file, ie from xml/txt to pck\n");
1 cycrow 324
}
325
 
326
int main ( int argc, char **argv )
327
{
328
	printf ( "\nCATPCK Tool V1.21 27/03/2011 (SPK: %.2f) Created by Cycrow\n\n", GetLibraryVersion() );
329
 
330
	// parse the cmd name
305 cycrow 331
	Utils::CommandLine cmd(argc, argv);
332
	g_dir = cmd.cmdDir();
276 cycrow 333
 
1 cycrow 334
	if ( argc < 2 )
305 cycrow 335
		PrintSyntax(cmd.cmdName());
1 cycrow 336
	else
337
	{
305 cycrow 338
		Utils::WString command(cmd.arg(0).lower());
1 cycrow 339
 
305 cycrow 340
		auto& args = cmd.args();
276 cycrow 341
 
342
		if ( (command == L"-l") || (command == L"-list") )
343
		{
344
			if ( args.size() < 2 )
305 cycrow 345
				wprintf(L"Syntax: %s -l <filename> [filemask]\n\tLists the contents of the cat file\n", cmd.cmdName().c_str());
276 cycrow 346
			else if ( args.size() < 3)
347
				ListFiles(args[1], Utils::WString(L""));
1 cycrow 348
			else
276 cycrow 349
				ListFiles(args[1], args[2]);
1 cycrow 350
		}
276 cycrow 351
		else if ( (command == L"-x") || (command == L"-extract") || (command == L"-xp") || (command == L"-extractpreserve") )
1 cycrow 352
		{
276 cycrow 353
			if ( args.size() < 2 )
305 cycrow 354
				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 355
			else if ( args.size() < 3)
356
				ExtractFile (args[1], L"", (command == L"-xp" || command == L"-extractpreserve") ? true : false );
1 cycrow 357
			else
276 cycrow 358
				ExtractFile (args[1], args[2], (command == L"-xp" || command == L"-extractpreserve") ? true : false );
1 cycrow 359
		}
276 cycrow 360
		else if ( (command == L"-xa") || (command == L"-extractall") )
1 cycrow 361
		{
276 cycrow 362
			if ( args.size() < 2)
305 cycrow 363
				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 364
			else if ( args.size() < 3)
365
				ExtractFile(args[1] + L"::*", L"", true );
1 cycrow 366
			else
276 cycrow 367
				ExtractFile(args[1] + L"::*", args[2], true );
1 cycrow 368
		}
276 cycrow 369
		else if ( (command == L"-a") || (command == L"-append") )
1 cycrow 370
		{
276 cycrow 371
			if (args.size() < 3 )
305 cycrow 372
				wprintf(L"Syntax: %s -a <filename> <catfile::tofile>\n\tAppends a file into the archive\n", cmd.cmdName().c_str() );
1 cycrow 373
			else
305 cycrow 374
				AppendFile(cmd.arg(2), cmd.arg(1));
1 cycrow 375
		}
276 cycrow 376
		else if ( (command == L"-r") || (command == L"-remove") )
1 cycrow 377
		{
276 cycrow 378
			if ( args.size() < 3 )
305 cycrow 379
				wprintf(L"Syntax: %s -r <catfile> <filename>\n\tRemoves a file from the archive\n", cmd.cmdName().c_str() );
1 cycrow 380
			else
276 cycrow 381
				RemoveFile (args[1], args[2]);
1 cycrow 382
		}
276 cycrow 383
		else if ( (command == L"-u") || (command == L"-unpack") )
1 cycrow 384
		{
305 cycrow 385
			Utils::WString ext = cmd.switchData(L"--ext");
276 cycrow 386
 
387
			if ( args.size() < 2 )
305 cycrow 388
				wprintf(L"Syntax: %s [--ext:EXTENSION] -u <filename> [to]\n\tUnpacks a file", cmd.cmdName().c_str() );
276 cycrow 389
			else if ( args.size() < 3)
390
				UnpackFile(args[1], L"", ext);
1 cycrow 391
			else
276 cycrow 392
				UnpackFile(args[1], args[2], ext);
1 cycrow 393
		}
276 cycrow 394
		else if ( (command == L"-p") || (command == L"-pack") )
1 cycrow 395
		{
276 cycrow 396
			if ( args.size() < 2 )
305 cycrow 397
				wprintf(L"Syntax: %s -p <filename> [to]\n\tPacks a file to .pck", cmd.cmdName().c_str() );
276 cycrow 398
			else if ( args.size() < 3)
399
				PackFile(args[1], L"");
1 cycrow 400
			else
276 cycrow 401
				PackFile(args[1], args[2]);
1 cycrow 402
		}
403
		else
404
		{
276 cycrow 405
			wprintf(L"Invalaid flag: %s\n\n", command.c_str());
305 cycrow 406
			PrintSyntax(cmd.cmdName());
1 cycrow 407
		}
408
	}
409
 
410
#ifdef _DEBUG
411
	char pause;
412
	printf ( "\n\nPress a key to end\n" );
413
	scanf ( "%c", &pause );
414
#endif
415
 
416
	return 0;
417
}
418