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