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