1 /*---------------------------------------------------------------------------*
2   Project:  archiver for Revolution dvd
3   File:     darch.c
4 
5   Copyright (C) 2001-2006 Nintendo All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: darch.c,v $
14   Revision 1.3.4.1  2008/09/09 11:42:52  nakano_yoshinobu
15   Update version number.
16 
17   Revision 1.4  2008/08/08 02:15:34  nakano_yoshinobu
18   Updated its version number to 1.03.
19 
20   Revision 1.3  2007/11/16 05:08:53  nakano_yoshinobu
21   Removed #include Windows.h.
22 
23   Revision 1.2  2006/04/27 05:27:01  yasuh-to
24   Modified error handling when any arguments are not there.
25 
26   Revision 1.1  2006/04/20 01:41:22  hiratsu
27   Initial check-in.
28 
29 
30     4     03/05/01 14:56 Hashida
31     Updated its version number to 1.02.
32 
33     3     7/31/01 11:29a Hashida
34     Removed a redundant options from major option list, and sorted
35     alphabetically.
36 
37     2     7/09/01 7:01p Hashida
38     Modified to mention -V option in usage().
39 
40     1     7/02/01 11:34p Hashida
41     Initial revision.
42 
43   $NoKeywords: $
44  *---------------------------------------------------------------------------*/
45 
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <fcntl.h>
50 #include <io.h>
51 
52 #include <errno.h>
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 
56 #include "darch.h"
57 
58 
59 #define VERSION                 "1.03"
60 
61 char fstFile[FILENAME_MAX];
62 char userFile[FILENAME_MAX];
63 static char arcFile[FILENAME_MAX];
64 
65 char arcRoot[FILENAME_MAX];
66 
67 char*   progName;
68 
69 int  debugMode = 0;
70 diskMap  map;
71 
72 void*   BigBuffer;
73 
74 static unsigned int         MajorMode = 0;
75 
76 #define MAJOR_MODE_CREATE           0x0001
77 #define MAJOR_MODE_LIST             0x0002
78 #define MAJOR_MODE_EXTRACT          0x0004
79 #define MAJOR_MODE_DIFF             0x0008
80 #define MAJOR_MODE_DELETE           0x0010
81 #define MAJOR_MODE_REPLACE          0x0020
82 #define MAJOR_MODE_LIST_IN_DISC_ORDER           0x0040
83 
84 
85 static char* MajorOptions = "`-cdeltx'";
86 
87 int         verbose = 0;
88 
89 #define ARGUMENTS_MAX           256
90 
91 static Arg_s        Arg[ARGUMENTS_MAX];
92 static int          ArgCount = 0;
93 
94 
usage(void)95 static void usage(void)
96 {
97     fprintf(stderr, "\n");
98     fprintf(stderr, "Usage:  %s [-c files/directories ...] [-d directory] [-x directory] [-e files/directories...] [-htlvV] file\n", progName);
99     fprintf(stderr, "\n");
100     fprintf(stderr, "    -c   Creates a new archive\n");
101     fprintf(stderr, "    -t   Lists the contents of an archive in tar-like order\n");
102     fprintf(stderr, "    -l   Lists the contents of an archive in the order in disc\n");
103     fprintf(stderr, "    -x   Extracts files from an archive\n");
104     fprintf(stderr, "    -d   Finds differences between archive and file system\n");
105     fprintf(stderr, "    -e   Erases files/directories from an archive\n");
106     fprintf(stderr, "    -v   Turns on verbose mode\n");
107     fprintf(stderr, "    -V   Shows version number\n");
108     fprintf(stderr, "    -h   Prints this message and exit\n");
109     fprintf(stderr, "    file Archive file\n");
110 }
111 
112 
main(int argc,char * argv[])113 int main(int argc, char *argv[])
114 {
115     char*           p;
116     char*           currDir = ".";
117     char**          argStartMinus1;
118 
119 
120     if ( (progName = strrchr(argv[0], '/')) != NULL )
121     {
122         progName++;
123     }
124     else
125     {
126         progName = argv[0];
127     }
128 
129 
130     while (--argc > 0)
131     {
132         if (**(++argv) == '-')
133         {
134             p = *argv;
135             while (*++p)
136             {
137                 switch (*p)
138                 {
139                   case 'h':
140                     usage();
141                     exit(0);
142                     break;
143 
144                   case 'C':
145                     currDir = *++argv;
146                     argc--;
147                     break;
148 
149                   case 'c':
150                     argStartMinus1 = argv;
151 
152                     if (argc == 1)
153                     {
154                         fprintf(stderr, "%s: You need to specify at least one"
155                                 " directory/file\n", progName);
156                         exit(1);
157                     }
158 
159                     while ( (*argv[1] != '-') && (argv[2] != NULL) )
160                     {
161                         argv++;
162                         argc--;
163                     }
164 
165                     Arg[ArgCount].currDir = currDir;
166                     Arg[ArgCount].argStart = argStartMinus1 + 1;
167                     Arg[ArgCount].argNum = argv - argStartMinus1;
168 
169                     if(++ArgCount >= ARGUMENTS_MAX)
170                     {
171                         fprintf(stderr, "%s: Too many arguments\n", progName);
172                         exit(1);
173                     }
174                     MajorMode |= MAJOR_MODE_CREATE;
175                     break;
176 
177                   case 'e':
178                     argStartMinus1 = argv;
179 
180                     if (argc == 1)
181                     {
182                         fprintf(stderr, "%s: You need to specify at least one"
183                                 " directory/file to erase\n", progName);
184                         exit(1);
185                     }
186 
187                     while ( (*argv[1] != '-') && (argv[2] != NULL) )
188                     {
189                         argv++;
190                         argc--;
191                     }
192 
193                     Arg[ArgCount].currDir = currDir;
194                     Arg[ArgCount].argStart = argStartMinus1 + 1;
195                     Arg[ArgCount].argNum = argv - argStartMinus1;
196 
197                     if(++ArgCount >= ARGUMENTS_MAX)
198                     {
199                         fprintf(stderr, "%s: Too many arguments\n", progName);
200                         exit(1);
201                     }
202                     MajorMode |= MAJOR_MODE_DELETE;
203                     break;
204 
205                   case 'd':
206                     if (argc == 1)
207                     {
208                         fprintf(stderr, "%s: You need to specify "
209                                 " a directory to see the difference\n", progName);
210                         exit(1);
211                     }
212                     strcpy(arcRoot, *++argv);
213                     argc--;
214                     MajorMode |= MAJOR_MODE_DIFF;
215                     break;
216 
217                   case 't':
218                     MajorMode |= MAJOR_MODE_LIST;
219                     break;
220 
221                   case 'l':
222                     MajorMode |= MAJOR_MODE_LIST_IN_DISC_ORDER;
223                     break;
224 
225                   case 'x':
226                     if (argc == 1)
227                     {
228                         fprintf(stderr, "%s: You need to specify a"
229                                 " directory name to extract\n", progName);
230                         exit(1);
231                     }
232 
233                     strcpy(arcRoot, *++argv);
234                     argc--;
235                     MajorMode |= MAJOR_MODE_EXTRACT;
236                     break;
237 
238                   case 'v':
239                     verbose = 1;
240                     break;
241 
242                   case 'V':
243                     fprintf(stderr, "Revolution archiver  v.%s\n", VERSION);
244                     exit(0);
245                     break;
246 
247                   default:
248                     fprintf(stderr, "%s: Unknown option -- %c\n", progName, *p);
249                     usage();
250                     exit(1);
251                     break;
252                 }
253 
254             }
255 
256         }
257         else
258             break;
259     }
260 
261     if (debugMode)
262     {
263         int             i, j;
264 
265         for (i = 0; i < ArgCount; i++)
266         {
267             fprintf(stderr, "curr dir is %s\n", Arg[i].currDir);
268             fprintf(stderr, "directories to erase is ");
269 
270             for(j = 0; j < Arg[i].argNum; j++)
271             {
272                 fprintf(stderr, "%s ", (Arg[i].argStart)[j]);
273             }
274             fprintf(stderr, "\n");
275             fprintf(stderr, "\n");
276         }
277     }
278 
279     if (argc == 0)
280     {
281         fprintf(stderr, "%s: You need to specify archive file name\n",
282                 progName);
283         usage();
284         exit(1);
285     }
286 
287     if (argc > 1)
288     {
289         fprintf(stderr, "%s: You may not specify more than one archive file name\n", progName);
290         usage();
291         exit(1);
292     }
293 
294     strcpy(arcFile, *argv);
295 
296     // Check if only one major mode was specified
297     if ( ((MajorMode - 1) & MajorMode) != 0 )
298     {
299         fprintf(stderr, "%s: You may not specify more than one %s option\n",
300                 progName, MajorOptions);
301         usage();
302         exit(1);
303     }
304 
305     if (MajorMode == 0)
306     {
307         fprintf(stderr, "%s: You must specify one of the %s options\n",
308                 progName, MajorOptions);
309         usage();
310         exit(1);
311     }
312 
313     if (debugMode)
314     {
315         fprintf(stdout, "output file name is %s\n", arcFile);
316         fprintf(stdout, "root is %s\n", arcRoot);
317     }
318 
319     if ( NULL == (BigBuffer = malloc(ALLOC_MEMSIZE)) )
320     {
321         fprintf(stderr, "%s: malloc failed\n", progName);
322         exit(1);
323     }
324 
325     switch (MajorMode)
326     {
327       case MAJOR_MODE_CREATE:
328         CreateArc(arcFile, Arg, ArgCount);
329         break;
330 
331       case MAJOR_MODE_LIST:
332         ListArc(arcFile);
333         break;
334 
335       case MAJOR_MODE_LIST_IN_DISC_ORDER:
336         ListArcInDiscOrder(arcFile);
337         break;
338 
339       case MAJOR_MODE_EXTRACT:
340         ExtractArc(arcFile, arcRoot);
341         break;
342 
343       case MAJOR_MODE_DIFF:
344         DiffArc(arcFile, arcRoot);
345         break;
346 
347       case MAJOR_MODE_DELETE:
348         DeleteArc(arcFile, Arg, ArgCount);
349         break;
350 
351     }
352 
353     free(BigBuffer);
354 
355     return 0;
356 }
357 
358