Subversion Repositories spk

Rev

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