Subversion Repositories spk

Rev

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