Subversion Repositories spk

Rev

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