Subversion Repositories spk

Rev

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