1 /**
2  * Test program for PhysicsFS. May only work on Unix.
3  *
4  * Please see the file LICENSE.txt in the source's root directory.
5  *
6  *  This file written by Ryan C. Gordon.
7  */
8 
9 #define _CRT_SECURE_NO_WARNINGS 1
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <errno.h>
14 #include <string.h>
15 
16 #if (defined __MWERKS__)
17 #include <SIOUX.h>
18 #endif
19 
20 #if (defined PHYSFS_HAVE_READLINE)
21 #include <unistd.h>
22 #include <readline/readline.h>
23 #include <readline/history.h>
24 #endif
25 
26 #include <time.h>
27 
28 /* Define this, so the compiler doesn't complain about using old APIs. */
29 #define PHYSFS_DEPRECATED
30 
31 #include "physfs.h"
32 
33 #define TEST_VERSION_MAJOR  3
34 #define TEST_VERSION_MINOR  0
35 #define TEST_VERSION_PATCH  2
36 
37 static FILE *history_file = NULL;
38 static PHYSFS_uint32 do_buffer_size = 0;
39 
output_versions(void)40 static void output_versions(void)
41 {
42     PHYSFS_Version compiled;
43     PHYSFS_Version linked;
44 
45     PHYSFS_VERSION(&compiled);
46     PHYSFS_getLinkedVersion(&linked);
47 
48     printf("test_physfs version %d.%d.%d.\n"
49            " Compiled against PhysicsFS version %d.%d.%d,\n"
50            " and linked against %d.%d.%d.\n\n",
51             TEST_VERSION_MAJOR, TEST_VERSION_MINOR, TEST_VERSION_PATCH,
52             (int) compiled.major, (int) compiled.minor, (int) compiled.patch,
53             (int) linked.major, (int) linked.minor, (int) linked.patch);
54 } /* output_versions */
55 
56 
output_archivers(void)57 static void output_archivers(void)
58 {
59     const PHYSFS_ArchiveInfo **rc = PHYSFS_supportedArchiveTypes();
60     const PHYSFS_ArchiveInfo **i;
61 
62     printf("Supported archive types:\n");
63     if (*rc == NULL)
64         printf(" * Apparently, NONE!\n");
65     else
66     {
67         for (i = rc; *i != NULL; i++)
68         {
69             printf(" * %s: %s\n    Written by %s.\n    %s\n",
70                     (*i)->extension, (*i)->description,
71                     (*i)->author, (*i)->url);
72             printf("    %s symbolic links.\n",
73                     (*i)->supportsSymlinks ? "Supports" : "Does not support");
74         } /* for */
75     } /* else */
76 
77     printf("\n");
78 } /* output_archivers */
79 
80 
cmd_quit(char * args)81 static int cmd_quit(char *args)
82 {
83     return 0;
84 } /* cmd_quit */
85 
86 
cmd_init(char * args)87 static int cmd_init(char *args)
88 {
89     if (*args == '\"')
90     {
91         args++;
92         args[strlen(args) - 1] = '\0';
93     } /* if */
94 
95     if (PHYSFS_init(args))
96         printf("Successful.\n");
97     else
98         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
99 
100     return 1;
101 } /* cmd_init */
102 
103 
cmd_deinit(char * args)104 static int cmd_deinit(char *args)
105 {
106     if (PHYSFS_deinit())
107         printf("Successful.\n");
108     else
109         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
110 
111     return 1;
112 } /* cmd_deinit */
113 
114 
cmd_addarchive(char * args)115 static int cmd_addarchive(char *args)
116 {
117     char *ptr = strrchr(args, ' ');
118     int appending = atoi(ptr + 1);
119     *ptr = '\0';
120 
121     if (*args == '\"')
122     {
123         args++;
124         *(ptr - 1) = '\0';
125     } /* if */
126 
127     /*printf("[%s], [%d]\n", args, appending);*/
128 
129     if (PHYSFS_mount(args, NULL, appending))
130         printf("Successful.\n");
131     else
132         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
133 
134     return 1;
135 } /* cmd_addarchive */
136 
137 
138 /* wrap free() to avoid calling convention wankery. */
freeBuf(void * buf)139 static void freeBuf(void *buf)
140 {
141     free(buf);
142 } /* freeBuf */
143 
144 typedef enum
145 {
146     MNTTYPE_PATH,
147     MNTTYPE_MEMORY,
148     MNTTYPE_HANDLE
149 } MountType;
150 
cmd_mount_internal(char * args,const MountType mnttype)151 static int cmd_mount_internal(char *args, const MountType mnttype)
152 {
153     char *ptr;
154     char *mntpoint = NULL;
155     int appending = 0;
156     int rc = 0;
157 
158     if (*args == '\"')
159     {
160         args++;
161         ptr = strchr(args, '\"');
162         if (ptr == NULL)
163         {
164             printf("missing string terminator in argument.\n");
165             return 1;
166         } /* if */
167         *(ptr) = '\0';
168     } /* if */
169     else
170     {
171         ptr = strchr(args, ' ');
172         *ptr = '\0';
173     } /* else */
174 
175     mntpoint = ptr + 1;
176     if (*mntpoint == '\"')
177     {
178         mntpoint++;
179         ptr = strchr(mntpoint, '\"');
180         if (ptr == NULL)
181         {
182             printf("missing string terminator in argument.\n");
183             return 1;
184         } /* if */
185         *(ptr) = '\0';
186     } /* if */
187     else
188     {
189         ptr = strchr(mntpoint, ' ');
190         *(ptr) = '\0';
191     } /* else */
192     appending = atoi(ptr + 1);
193 
194     /*printf("[%s], [%s], [%d]\n", args, mntpoint, appending);*/
195 
196     if (mnttype == MNTTYPE_PATH)
197         rc = PHYSFS_mount(args, mntpoint, appending);
198 
199     else if (mnttype == MNTTYPE_HANDLE)
200     {
201         PHYSFS_File *f = PHYSFS_openRead(args);
202         if (f == NULL)
203         {
204             printf("PHYSFS_openRead('%s') failed. reason: %s.\n", args, PHYSFS_getLastError());
205             return 1;
206         } /* if */
207 
208         rc = PHYSFS_mountHandle(f, args, mntpoint, appending);
209         if (!rc)
210             PHYSFS_close(f);
211     } /* else if */
212 
213     else if (mnttype == MNTTYPE_MEMORY)
214     {
215         FILE *in = fopen(args, "rb");
216         void *buf = NULL;
217         long len = 0;
218 
219         if (in == NULL)
220         {
221             printf("Failed to open %s to read into memory: %s.\n", args, strerror(errno));
222             return 1;
223         } /* if */
224 
225         if ( (fseek(in, 0, SEEK_END) != 0) || ((len = ftell(in)) < 0) )
226         {
227             printf("Failed to find size of %s to read into memory: %s.\n", args, strerror(errno));
228             fclose(in);
229             return 1;
230         } /* if */
231 
232         buf = malloc(len);
233         if (buf == NULL)
234         {
235             printf("Failed to allocate space to read %s into memory: %s.\n", args, strerror(errno));
236             fclose(in);
237             return 1;
238         } /* if */
239 
240         if ((fseek(in, 0, SEEK_SET) != 0) || (fread(buf, len, 1, in) != 1))
241         {
242             printf("Failed to read %s into memory: %s.\n", args, strerror(errno));
243             fclose(in);
244             free(buf);
245             return 1;
246         } /* if */
247 
248         fclose(in);
249 
250         rc = PHYSFS_mountMemory(buf, len, freeBuf, args, mntpoint, appending);
251     } /* else */
252 
253     if (rc)
254         printf("Successful.\n");
255     else
256         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
257 
258     return 1;
259 } /* cmd_mount_internal */
260 
261 
cmd_mount(char * args)262 static int cmd_mount(char *args)
263 {
264     return cmd_mount_internal(args, MNTTYPE_PATH);
265 } /* cmd_mount */
266 
267 
cmd_mount_mem(char * args)268 static int cmd_mount_mem(char *args)
269 {
270     return cmd_mount_internal(args, MNTTYPE_MEMORY);
271 } /* cmd_mount_mem */
272 
273 
cmd_mount_handle(char * args)274 static int cmd_mount_handle(char *args)
275 {
276     return cmd_mount_internal(args, MNTTYPE_HANDLE);
277 } /* cmd_mount_handle */
278 
cmd_getmountpoint(char * args)279 static int cmd_getmountpoint(char *args)
280 {
281     if (*args == '\"')
282     {
283         args++;
284         args[strlen(args) - 1] = '\0';
285     } /* if */
286 
287     printf("Dir [%s] is mounted at [%s].\n", args, PHYSFS_getMountPoint(args));
288     return 1;
289 } /* cmd_getmountpoint */
290 
cmd_removearchive(char * args)291 static int cmd_removearchive(char *args)
292 {
293     if (*args == '\"')
294     {
295         args++;
296         args[strlen(args) - 1] = '\0';
297     } /* if */
298 
299     if (PHYSFS_unmount(args))
300         printf("Successful.\n");
301     else
302         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
303 
304     return 1;
305 } /* cmd_removearchive */
306 
307 
cmd_enumerate(char * args)308 static int cmd_enumerate(char *args)
309 {
310     char **rc;
311 
312     if (*args == '\"')
313     {
314         args++;
315         args[strlen(args) - 1] = '\0';
316     } /* if */
317 
318     rc = PHYSFS_enumerateFiles(args);
319 
320     if (rc == NULL)
321         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
322     else
323     {
324         int file_count;
325         char **i;
326         for (i = rc, file_count = 0; *i != NULL; i++, file_count++)
327             printf("%s\n", *i);
328 
329         printf("\n total (%d) files.\n", file_count);
330         PHYSFS_freeList(rc);
331     } /* else */
332 
333     return 1;
334 } /* cmd_enumerate */
335 
336 
cmd_getdirsep(char * args)337 static int cmd_getdirsep(char *args)
338 {
339     printf("Directory separator is [%s].\n", PHYSFS_getDirSeparator());
340     return 1;
341 } /* cmd_getdirsep */
342 
343 
cmd_getlasterror(char * args)344 static int cmd_getlasterror(char *args)
345 {
346     printf("last error is [%s].\n", PHYSFS_getLastError());
347     return 1;
348 } /* cmd_getlasterror */
349 
350 
cmd_getcdromdirs(char * args)351 static int cmd_getcdromdirs(char *args)
352 {
353     char **rc = PHYSFS_getCdRomDirs();
354 
355     if (rc == NULL)
356         printf("Failure. Reason: [%s].\n", PHYSFS_getLastError());
357     else
358     {
359         int dir_count;
360         char **i;
361         for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++)
362             printf("%s\n", *i);
363 
364         printf("\n total (%d) drives.\n", dir_count);
365         PHYSFS_freeList(rc);
366     } /* else */
367 
368     return 1;
369 } /* cmd_getcdromdirs */
370 
371 
cmd_getsearchpath(char * args)372 static int cmd_getsearchpath(char *args)
373 {
374     char **rc = PHYSFS_getSearchPath();
375 
376     if (rc == NULL)
377         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
378     else
379     {
380         int dir_count;
381         char **i;
382         for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++)
383             printf("%s\n", *i);
384 
385         printf("\n total (%d) directories.\n", dir_count);
386         PHYSFS_freeList(rc);
387     } /* else */
388 
389     return 1;
390 } /* cmd_getcdromdirs */
391 
392 
cmd_getbasedir(char * args)393 static int cmd_getbasedir(char *args)
394 {
395     printf("Base dir is [%s].\n", PHYSFS_getBaseDir());
396     return 1;
397 } /* cmd_getbasedir */
398 
399 
cmd_getuserdir(char * args)400 static int cmd_getuserdir(char *args)
401 {
402     printf("User dir is [%s].\n", PHYSFS_getUserDir());
403     return 1;
404 } /* cmd_getuserdir */
405 
406 
cmd_getprefdir(char * args)407 static int cmd_getprefdir(char *args)
408 {
409     char *org;
410     char *appName;
411     char *ptr = args;
412 
413     org = ptr;
414     ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; appName = ptr;
415     printf("Pref dir is [%s].\n", PHYSFS_getPrefDir(org, appName));
416     return 1;
417 } /* cmd_getprefdir */
418 
419 
cmd_getwritedir(char * args)420 static int cmd_getwritedir(char *args)
421 {
422     printf("Write dir is [%s].\n", PHYSFS_getWriteDir());
423     return 1;
424 } /* cmd_getwritedir */
425 
426 
cmd_setwritedir(char * args)427 static int cmd_setwritedir(char *args)
428 {
429     if (*args == '\"')
430     {
431         args++;
432         args[strlen(args) - 1] = '\0';
433     } /* if */
434 
435     if (PHYSFS_setWriteDir(args))
436         printf("Successful.\n");
437     else
438         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
439 
440     return 1;
441 } /* cmd_setwritedir */
442 
443 
cmd_permitsyms(char * args)444 static int cmd_permitsyms(char *args)
445 {
446     int num;
447 
448     if (*args == '\"')
449     {
450         args++;
451         args[strlen(args) - 1] = '\0';
452     } /* if */
453 
454     num = atoi(args);
455     PHYSFS_permitSymbolicLinks(num);
456     printf("Symlinks are now %s.\n", num ? "permitted" : "forbidden");
457     return 1;
458 } /* cmd_permitsyms */
459 
460 
cmd_setbuffer(char * args)461 static int cmd_setbuffer(char *args)
462 {
463     if (*args == '\"')
464     {
465         args++;
466         args[strlen(args) - 1] = '\0';
467     } /* if */
468 
469     do_buffer_size = (unsigned int) atoi(args);
470     if (do_buffer_size)
471     {
472         printf("Further tests will set a (%lu) size buffer.\n",
473                 (unsigned long) do_buffer_size);
474     } /* if */
475 
476     else
477     {
478         printf("Further tests will NOT use a buffer.\n");
479     } /* else */
480 
481     return 1;
482 } /* cmd_setbuffer */
483 
484 
cmd_stressbuffer(char * args)485 static int cmd_stressbuffer(char *args)
486 {
487     int num;
488 
489     if (*args == '\"')
490     {
491         args++;
492         args[strlen(args) - 1] = '\0';
493     } /* if */
494 
495     num = atoi(args);
496     if (num < 0)
497         printf("buffer must be greater than or equal to zero.\n");
498     else
499     {
500         PHYSFS_File *f;
501         int rndnum;
502 
503         printf("Stress testing with (%d) byte buffer...\n", num);
504         f = PHYSFS_openWrite("test.txt");
505         if (f == NULL)
506             printf("Couldn't open test.txt for writing: %s.\n", PHYSFS_getLastError());
507         else
508         {
509             int i, j;
510             char buf[37];
511             char buf2[37];
512 
513             if (!PHYSFS_setBuffer(f, num))
514             {
515                 printf("PHYSFS_setBuffer() failed: %s.\n", PHYSFS_getLastError());
516                 PHYSFS_close(f);
517                 PHYSFS_delete("test.txt");
518                 return 1;
519             } /* if */
520 
521             strcpy(buf, "abcdefghijklmnopqrstuvwxyz0123456789");
522             srand((unsigned int) time(NULL));
523 
524             for (i = 0; i < 10; i++)
525             {
526                 for (j = 0; j < 10000; j++)
527                 {
528                     PHYSFS_uint32 right = 1 + (PHYSFS_uint32) (35.0 * rand() / (RAND_MAX + 1.0));
529                     PHYSFS_uint32 left = 36 - right;
530                     if (PHYSFS_writeBytes(f, buf, left) != left)
531                     {
532                         printf("PHYSFS_writeBytes() failed: %s.\n", PHYSFS_getLastError());
533                         PHYSFS_close(f);
534                         return 1;
535                     } /* if */
536 
537                     rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
538                     if (rndnum == 42)
539                     {
540                         if (!PHYSFS_flush(f))
541                         {
542                             printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
543                             PHYSFS_close(f);
544                             return 1;
545                         } /* if */
546                     } /* if */
547 
548                     if (PHYSFS_writeBytes(f, buf + left, right) != right)
549                     {
550                         printf("PHYSFS_writeBytes() failed: %s.\n", PHYSFS_getLastError());
551                         PHYSFS_close(f);
552                         return 1;
553                     } /* if */
554 
555                     rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
556                     if (rndnum == 42)
557                     {
558                         if (!PHYSFS_flush(f))
559                         {
560                             printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
561                             PHYSFS_close(f);
562                             return 1;
563                         } /* if */
564                     } /* if */
565                 } /* for */
566 
567                 if (!PHYSFS_flush(f))
568                 {
569                     printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
570                     PHYSFS_close(f);
571                     return 1;
572                 } /* if */
573 
574             } /* for */
575 
576             if (!PHYSFS_close(f))
577             {
578                 printf("PHYSFS_close() failed: %s.\n", PHYSFS_getLastError());
579                 return 1;  /* oh well. */
580             } /* if */
581 
582             printf(" ... test file written ...\n");
583             f = PHYSFS_openRead("test.txt");
584             if (f == NULL)
585             {
586                 printf("Failed to reopen stress file for reading: %s.\n", PHYSFS_getLastError());
587                 return 1;
588             } /* if */
589 
590             if (!PHYSFS_setBuffer(f, num))
591             {
592                 printf("PHYSFS_setBuffer() failed: %s.\n", PHYSFS_getLastError());
593                 PHYSFS_close(f);
594                 return 1;
595             } /* if */
596 
597             for (i = 0; i < 10; i++)
598             {
599                 for (j = 0; j < 10000; j++)
600                 {
601                     PHYSFS_uint32 right = 1 + (PHYSFS_uint32) (35.0 * rand() / (RAND_MAX + 1.0));
602                     PHYSFS_uint32 left = 36 - right;
603                     if (PHYSFS_readBytes(f, buf2, left) != left)
604                     {
605                         printf("PHYSFS_readBytes() failed: %s.\n", PHYSFS_getLastError());
606                         PHYSFS_close(f);
607                         return 1;
608                     } /* if */
609 
610                     rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
611                     if (rndnum == 42)
612                     {
613                         if (!PHYSFS_flush(f))
614                         {
615                             printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
616                             PHYSFS_close(f);
617                             return 1;
618                         } /* if */
619                     } /* if */
620 
621                     if (PHYSFS_readBytes(f, buf2 + left, right) != right)
622                     {
623                         printf("PHYSFS_readBytes() failed: %s.\n", PHYSFS_getLastError());
624                         PHYSFS_close(f);
625                         return 1;
626                     } /* if */
627 
628                     rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
629                     if (rndnum == 42)
630                     {
631                         if (!PHYSFS_flush(f))
632                         {
633                             printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
634                             PHYSFS_close(f);
635                             return 1;
636                         } /* if */
637                     } /* if */
638 
639                     if (memcmp(buf, buf2, 36) != 0)
640                     {
641                         printf("readback is mismatched on iterations (%d, %d).\n", i, j);
642                         printf("wanted: [");
643                         for (i = 0; i < 36; i++)
644                             printf("%c", buf[i]);
645                         printf("]\n");
646 
647                         printf("   got: [");
648                         for (i = 0; i < 36; i++)
649                             printf("%c", buf2[i]);
650                         printf("]\n");
651                         PHYSFS_close(f);
652                         return 1;
653                     } /* if */
654                 } /* for */
655 
656                 if (!PHYSFS_flush(f))
657                 {
658                     printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
659                     PHYSFS_close(f);
660                     return 1;
661                 } /* if */
662 
663             } /* for */
664 
665             printf(" ... test file read ...\n");
666 
667             if (!PHYSFS_eof(f))
668                 printf("PHYSFS_eof() returned true! That's wrong.\n");
669 
670             if (!PHYSFS_close(f))
671             {
672                 printf("PHYSFS_close() failed: %s.\n", PHYSFS_getLastError());
673                 return 1;  /* oh well. */
674             } /* if */
675 
676             PHYSFS_delete("test.txt");
677             printf("stress test completed successfully.\n");
678         } /* else */
679     } /* else */
680 
681     return 1;
682 } /* cmd_stressbuffer */
683 
684 
cmd_setsaneconfig(char * args)685 static int cmd_setsaneconfig(char *args)
686 {
687     char *org;
688     char *appName;
689     char *arcExt;
690     int inclCD;
691     int arcsFirst;
692     char *ptr = args;
693 
694         /* ugly. */
695     org = ptr;
696     ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; appName = ptr;
697     ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; arcExt = ptr;
698     ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; inclCD = atoi(arcExt);
699     arcsFirst = atoi(ptr);
700 
701     if (strcmp(arcExt, "!") == 0)
702         arcExt = NULL;
703 
704     if (PHYSFS_setSaneConfig(org, appName, arcExt, inclCD, arcsFirst))
705         printf("Successful.\n");
706     else
707         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
708 
709     return 1;
710 } /* cmd_setsaneconfig */
711 
712 
cmd_mkdir(char * args)713 static int cmd_mkdir(char *args)
714 {
715     if (*args == '\"')
716     {
717         args++;
718         args[strlen(args) - 1] = '\0';
719     } /* if */
720 
721     if (PHYSFS_mkdir(args))
722         printf("Successful.\n");
723     else
724         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
725 
726     return 1;
727 } /* cmd_mkdir */
728 
729 
cmd_delete(char * args)730 static int cmd_delete(char *args)
731 {
732     if (*args == '\"')
733     {
734         args++;
735         args[strlen(args) - 1] = '\0';
736     } /* if */
737 
738     if (PHYSFS_delete(args))
739         printf("Successful.\n");
740     else
741         printf("Failure. reason: %s.\n", PHYSFS_getLastError());
742 
743     return 1;
744 } /* cmd_delete */
745 
746 
cmd_getrealdir(char * args)747 static int cmd_getrealdir(char *args)
748 {
749     const char *rc;
750 
751     if (*args == '\"')
752     {
753         args++;
754         args[strlen(args) - 1] = '\0';
755     } /* if */
756 
757     rc = PHYSFS_getRealDir(args);
758     if (rc)
759         printf("Found at [%s].\n", rc);
760     else
761         printf("Not found.\n");
762 
763     return 1;
764 } /* cmd_getrealdir */
765 
766 
cmd_exists(char * args)767 static int cmd_exists(char *args)
768 {
769     int rc;
770 
771     if (*args == '\"')
772     {
773         args++;
774         args[strlen(args) - 1] = '\0';
775     } /* if */
776 
777     rc = PHYSFS_exists(args);
778     printf("File %sexists.\n", rc ? "" : "does not ");
779     return 1;
780 } /* cmd_exists */
781 
782 
cmd_isdir(char * args)783 static int cmd_isdir(char *args)
784 {
785     PHYSFS_Stat statbuf;
786     int rc;
787 
788     if (*args == '\"')
789     {
790         args++;
791         args[strlen(args) - 1] = '\0';
792     } /* if */
793 
794     rc = PHYSFS_stat(args, &statbuf);
795     if (rc)
796         rc = (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY);
797     printf("File %s a directory.\n", rc ? "is" : "is NOT");
798     return 1;
799 } /* cmd_isdir */
800 
801 
cmd_issymlink(char * args)802 static int cmd_issymlink(char *args)
803 {
804     PHYSFS_Stat statbuf;
805     int rc;
806 
807     if (*args == '\"')
808     {
809         args++;
810         args[strlen(args) - 1] = '\0';
811     } /* if */
812 
813     rc = PHYSFS_stat(args, &statbuf);
814     if (rc)
815         rc = (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
816     printf("File %s a symlink.\n", rc ? "is" : "is NOT");
817     return 1;
818 } /* cmd_issymlink */
819 
820 
cmd_cat(char * args)821 static int cmd_cat(char *args)
822 {
823     PHYSFS_File *f;
824 
825     if (*args == '\"')
826     {
827         args++;
828         args[strlen(args) - 1] = '\0';
829     } /* if */
830 
831     f = PHYSFS_openRead(args);
832     if (f == NULL)
833         printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
834     else
835     {
836         if (do_buffer_size)
837         {
838             if (!PHYSFS_setBuffer(f, do_buffer_size))
839             {
840                 printf("failed to set file buffer. Reason: [%s].\n",
841                         PHYSFS_getLastError());
842                 PHYSFS_close(f);
843                 return 1;
844             } /* if */
845         } /* if */
846 
847         while (1)
848         {
849             char buffer[128];
850             PHYSFS_sint64 rc;
851             PHYSFS_sint64 i;
852             rc = PHYSFS_readBytes(f, buffer, sizeof (buffer));
853 
854             for (i = 0; i < rc; i++)
855                 fputc((int) buffer[i], stdout);
856 
857             if (rc < sizeof (buffer))
858             {
859                 printf("\n\n");
860                 if (!PHYSFS_eof(f))
861                 {
862                     printf("\n (Error condition in reading. Reason: [%s])\n\n",
863                            PHYSFS_getLastError());
864                 } /* if */
865                 PHYSFS_close(f);
866                 return 1;
867             } /* if */
868         } /* while */
869     } /* else */
870 
871     return 1;
872 } /* cmd_cat */
873 
cmd_cat2(char * args)874 static int cmd_cat2(char *args)
875 {
876     PHYSFS_File *f1 = NULL;
877     PHYSFS_File *f2 = NULL;
878     char *fname1;
879     char *fname2;
880     char *ptr;
881 
882     fname1 = args;
883     if (*fname1 == '\"')
884     {
885         fname1++;
886         ptr = strchr(fname1, '\"');
887         if (ptr == NULL)
888         {
889             printf("missing string terminator in argument.\n");
890             return 1;
891         } /* if */
892         *(ptr) = '\0';
893     } /* if */
894     else
895     {
896         ptr = strchr(fname1, ' ');
897         *ptr = '\0';
898     } /* else */
899 
900     fname2 = ptr + 1;
901     if (*fname2 == '\"')
902     {
903         fname2++;
904         ptr = strchr(fname2, '\"');
905         if (ptr == NULL)
906         {
907             printf("missing string terminator in argument.\n");
908             return 1;
909         } /* if */
910         *(ptr) = '\0';
911     } /* if */
912 
913     if ((f1 = PHYSFS_openRead(fname1)) == NULL)
914         printf("failed to open '%s'. Reason: [%s].\n", fname1, PHYSFS_getLastError());
915     else if ((f2 = PHYSFS_openRead(fname2)) == NULL)
916         printf("failed to open '%s'. Reason: [%s].\n", fname2, PHYSFS_getLastError());
917     else
918     {
919         char *buffer1 = NULL;
920         size_t buffer1len = 0;
921         char *buffer2 = NULL;
922         size_t buffer2len = 0;
923         char *ptr = NULL;
924         size_t i;
925 
926         if (do_buffer_size)
927         {
928             if (!PHYSFS_setBuffer(f1, do_buffer_size))
929             {
930                 printf("failed to set file buffer for '%s'. Reason: [%s].\n",
931                         fname1, PHYSFS_getLastError());
932                 PHYSFS_close(f1);
933                 PHYSFS_close(f2);
934                 return 1;
935             } /* if */
936             else if (!PHYSFS_setBuffer(f2, do_buffer_size))
937             {
938                 printf("failed to set file buffer for '%s'. Reason: [%s].\n",
939                         fname2, PHYSFS_getLastError());
940                 PHYSFS_close(f1);
941                 PHYSFS_close(f2);
942                 return 1;
943             } /* if */
944         } /* if */
945 
946 
947         do
948         {
949             int readlen = 128;
950             PHYSFS_sint64 rc;
951 
952             ptr = realloc(buffer1, buffer1len + readlen);
953             if (!ptr)
954             {
955                 printf("(Out of memory.)\n\n");
956                 free(buffer1);
957                 free(buffer2);
958                 PHYSFS_close(f1);
959                 PHYSFS_close(f2);
960                 return 1;
961             } /* if */
962 
963             buffer1 = ptr;
964             rc = PHYSFS_readBytes(f1, buffer1 + buffer1len, readlen);
965             if (rc < 0)
966             {
967                 printf("(Error condition in reading '%s'. Reason: [%s])\n\n",
968                        fname1, PHYSFS_getLastError());
969                 free(buffer1);
970                 free(buffer2);
971                 PHYSFS_close(f1);
972                 PHYSFS_close(f2);
973                 return 1;
974             } /* if */
975             buffer1len += (size_t) rc;
976 
977             ptr = realloc(buffer2, buffer2len + readlen);
978             if (!ptr)
979             {
980                 printf("(Out of memory.)\n\n");
981                 free(buffer1);
982                 free(buffer2);
983                 PHYSFS_close(f1);
984                 PHYSFS_close(f2);
985                 return 1;
986             } /* if */
987 
988             buffer2 = ptr;
989             rc = PHYSFS_readBytes(f2, buffer2 + buffer2len, readlen);
990             if (rc < 0)
991             {
992                 printf("(Error condition in reading '%s'. Reason: [%s])\n\n",
993                        fname2, PHYSFS_getLastError());
994                 free(buffer1);
995                 free(buffer2);
996                 PHYSFS_close(f1);
997                 PHYSFS_close(f2);
998                 return 1;
999             } /* if */
1000             buffer2len += (size_t) rc;
1001         } while (!PHYSFS_eof(f1) || !PHYSFS_eof(f2));
1002 
1003         printf("file '%s' ...\n\n", fname1);
1004         for (i = 0; i < buffer1len; i++)
1005             fputc((int) buffer1[i], stdout);
1006         free(buffer1);
1007 
1008         printf("\n\nfile '%s' ...\n\n", fname2);
1009         for (i = 0; i < buffer2len; i++)
1010             fputc((int) buffer2[i], stdout);
1011         free(buffer2);
1012 
1013         printf("\n\n");
1014     } /* else */
1015 
1016     if (f1)
1017         PHYSFS_close(f1);
1018 
1019     if (f2)
1020         PHYSFS_close(f2);
1021 
1022     return 1;
1023 } /* cmd_cat2 */
1024 
1025 
1026 #define CRC32_BUFFERSIZE 512
cmd_crc32(char * args)1027 static int cmd_crc32(char *args)
1028 {
1029     PHYSFS_File *f;
1030 
1031     if (*args == '\"')
1032     {
1033         args++;
1034         args[strlen(args) - 1] = '\0';
1035     } /* if */
1036 
1037     f = PHYSFS_openRead(args);
1038     if (f == NULL)
1039         printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
1040     else
1041     {
1042         PHYSFS_uint8 buffer[CRC32_BUFFERSIZE];
1043         PHYSFS_uint32 crc = -1;
1044         PHYSFS_sint64 bytesread;
1045 
1046         while ((bytesread = PHYSFS_readBytes(f, buffer, CRC32_BUFFERSIZE)) > 0)
1047         {
1048             PHYSFS_uint32 i, bit;
1049             for (i = 0; i < bytesread; i++)
1050             {
1051                 for (bit = 0; bit < 8; bit++, buffer[i] >>= 1)
1052                     crc = (crc >> 1) ^ (((crc ^ buffer[i]) & 1) ? 0xEDB88320 : 0);
1053             } /* for */
1054         } /* while */
1055 
1056         if (bytesread < 0)
1057         {
1058             printf("error while reading. Reason: [%s].\n",
1059                    PHYSFS_getLastError());
1060             return 1;
1061         } /* if */
1062 
1063         PHYSFS_close(f);
1064 
1065         crc ^= -1;
1066         printf("CRC32 for %s: 0x%08X\n", args, crc);
1067     } /* else */
1068 
1069     return 1;
1070 } /* cmd_crc32 */
1071 
1072 
cmd_filelength(char * args)1073 static int cmd_filelength(char *args)
1074 {
1075     PHYSFS_File *f;
1076 
1077     if (*args == '\"')
1078     {
1079         args++;
1080         args[strlen(args) - 1] = '\0';
1081     } /* if */
1082 
1083     f = PHYSFS_openRead(args);
1084     if (f == NULL)
1085         printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
1086     else
1087     {
1088         PHYSFS_sint64 len = PHYSFS_fileLength(f);
1089         if (len == -1)
1090             printf("failed to determine length. Reason: [%s].\n", PHYSFS_getLastError());
1091         else
1092             printf(" (cast to int) %d bytes.\n", (int) len);
1093 
1094         PHYSFS_close(f);
1095     } /* else */
1096 
1097     return 1;
1098 } /* cmd_filelength */
1099 
1100 #define WRITESTR "The cat sat on the mat.\n\n"
1101 
cmd_append(char * args)1102 static int cmd_append(char *args)
1103 {
1104     PHYSFS_File *f;
1105 
1106     if (*args == '\"')
1107     {
1108         args++;
1109         args[strlen(args) - 1] = '\0';
1110     } /* if */
1111 
1112     f = PHYSFS_openAppend(args);
1113     if (f == NULL)
1114         printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
1115     else
1116     {
1117         size_t bw;
1118         PHYSFS_sint64 rc;
1119 
1120         if (do_buffer_size)
1121         {
1122             if (!PHYSFS_setBuffer(f, do_buffer_size))
1123             {
1124                 printf("failed to set file buffer. Reason: [%s].\n",
1125                         PHYSFS_getLastError());
1126                 PHYSFS_close(f);
1127                 return 1;
1128             } /* if */
1129         } /* if */
1130 
1131         bw = strlen(WRITESTR);
1132         rc = PHYSFS_writeBytes(f, WRITESTR, bw);
1133         if (rc != bw)
1134         {
1135             printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
1136                    (int) rc, (int) bw, PHYSFS_getLastError());
1137         } /* if */
1138         else
1139         {
1140             printf("Successful.\n");
1141         } /* else */
1142 
1143         PHYSFS_close(f);
1144     } /* else */
1145 
1146     return 1;
1147 } /* cmd_append */
1148 
1149 
cmd_write(char * args)1150 static int cmd_write(char *args)
1151 {
1152     PHYSFS_File *f;
1153 
1154     if (*args == '\"')
1155     {
1156         args++;
1157         args[strlen(args) - 1] = '\0';
1158     } /* if */
1159 
1160     f = PHYSFS_openWrite(args);
1161     if (f == NULL)
1162         printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
1163     else
1164     {
1165         size_t bw;
1166         PHYSFS_sint64 rc;
1167 
1168         if (do_buffer_size)
1169         {
1170             if (!PHYSFS_setBuffer(f, do_buffer_size))
1171             {
1172                 printf("failed to set file buffer. Reason: [%s].\n",
1173                         PHYSFS_getLastError());
1174                 PHYSFS_close(f);
1175                 return 1;
1176             } /* if */
1177         } /* if */
1178 
1179         bw = strlen(WRITESTR);
1180         rc = PHYSFS_writeBytes(f, WRITESTR, bw);
1181         if (rc != bw)
1182         {
1183             printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
1184                    (int) rc, (int) bw, PHYSFS_getLastError());
1185         } /* if */
1186         else
1187         {
1188             printf("Successful.\n");
1189         } /* else */
1190 
1191         PHYSFS_close(f);
1192     } /* else */
1193 
1194     return 1;
1195 } /* cmd_write */
1196 
1197 
modTimeToStr(PHYSFS_sint64 modtime,char * modstr,size_t strsize)1198 static char* modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
1199 {
1200     if (modtime < 0)
1201         strncpy(modstr, "Unknown\n", strsize);
1202     else
1203     {
1204         time_t t = (time_t) modtime;
1205         char *str = ctime(&t);
1206         strncpy(modstr, str, strsize);
1207     } /* else */
1208 
1209     modstr[strsize-1] = '\0';
1210     return modstr;
1211 } /* modTimeToStr */
1212 
1213 
cmd_getlastmodtime(char * args)1214 static int cmd_getlastmodtime(char *args)
1215 {
1216     PHYSFS_Stat statbuf;
1217     if (!PHYSFS_stat(args, &statbuf))
1218         printf("Failed to determine. Reason: [%s].\n", PHYSFS_getLastError());
1219     else
1220     {
1221         char modstr[64];
1222         modTimeToStr(statbuf.modtime, modstr, sizeof (modstr));
1223         printf("Last modified: %s (%ld).\n", modstr, (long) statbuf.modtime);
1224     } /* else */
1225 
1226     return 1;
1227 } /* cmd_getLastModTime */
1228 
cmd_stat(char * args)1229 static int cmd_stat(char *args)
1230 {
1231     PHYSFS_Stat stat;
1232     char timestring[65];
1233 
1234     if (*args == '\"')
1235     {
1236         args++;
1237         args[strlen(args) - 1] = '\0';
1238     } /* if */
1239 
1240     if(!PHYSFS_stat(args, &stat))
1241     {
1242         printf("failed to stat. Reason [%s].\n", PHYSFS_getLastError());
1243         return 1;
1244     } /* if */
1245 
1246     printf("Filename: %s\n", args);
1247     printf("Size %d\n",(int) stat.filesize);
1248 
1249     if(stat.filetype == PHYSFS_FILETYPE_REGULAR)
1250         printf("Type: File\n");
1251     else if(stat.filetype == PHYSFS_FILETYPE_DIRECTORY)
1252         printf("Type: Directory\n");
1253     else if(stat.filetype == PHYSFS_FILETYPE_SYMLINK)
1254         printf("Type: Symlink\n");
1255     else
1256         printf("Type: Unknown\n");
1257 
1258     printf("Created at: %s", modTimeToStr(stat.createtime, timestring, 64));
1259     printf("Last modified at: %s", modTimeToStr(stat.modtime, timestring, 64));
1260     printf("Last accessed at: %s", modTimeToStr(stat.accesstime, timestring, 64));
1261     printf("Readonly: %s\n", stat.readonly ? "true" : "false");
1262 
1263     return 1;
1264 } /* cmd_filelength */
1265 
1266 
1267 
1268 /* must have spaces trimmed prior to this call. */
count_args(const char * str)1269 static int count_args(const char *str)
1270 {
1271     int retval = 0;
1272     int in_quotes = 0;
1273 
1274     if (str != NULL)
1275     {
1276         for (; *str != '\0'; str++)
1277         {
1278             if (*str == '\"')
1279                 in_quotes = !in_quotes;
1280             else if ((*str == ' ') && (!in_quotes))
1281                 retval++;
1282         } /* for */
1283         retval++;
1284     } /* if */
1285 
1286     return retval;
1287 } /* count_args */
1288 
1289 
1290 static int cmd_help(char *args);
1291 
1292 typedef struct
1293 {
1294     const char *cmd;
1295     int (*func)(char *args);
1296     int argcount;
1297     const char *usage;
1298 } command_info;
1299 
1300 static const command_info commands[] =
1301 {
1302     { "quit",           cmd_quit,           0, NULL                         },
1303     { "q",              cmd_quit,           0, NULL                         },
1304     { "help",           cmd_help,           0, NULL                         },
1305     { "init",           cmd_init,           1, "<argv0>"                    },
1306     { "deinit",         cmd_deinit,         0, NULL                         },
1307     { "addarchive",     cmd_addarchive,     2, "<archiveLocation> <append>" },
1308     { "mount",          cmd_mount,          3, "<archiveLocation> <mntpoint> <append>" },
1309     { "mountmem",       cmd_mount_mem,      3, "<archiveLocation> <mntpoint> <append>" },
1310     { "mounthandle",    cmd_mount_handle,   3, "<archiveLocation> <mntpoint> <append>" },
1311     { "removearchive",  cmd_removearchive,  1, "<archiveLocation>"          },
1312     { "unmount",        cmd_removearchive,  1, "<archiveLocation>"          },
1313     { "enumerate",      cmd_enumerate,      1, "<dirToEnumerate>"           },
1314     { "ls",             cmd_enumerate,      1, "<dirToEnumerate>"           },
1315     { "getlasterror",   cmd_getlasterror,   0, NULL                         },
1316     { "getdirsep",      cmd_getdirsep,      0, NULL                         },
1317     { "getcdromdirs",   cmd_getcdromdirs,   0, NULL                         },
1318     { "getsearchpath",  cmd_getsearchpath,  0, NULL                         },
1319     { "getbasedir",     cmd_getbasedir,     0, NULL                         },
1320     { "getuserdir",     cmd_getuserdir,     0, NULL                         },
1321     { "getprefdir",     cmd_getprefdir,     2, "<org> <app>"                },
1322     { "getwritedir",    cmd_getwritedir,    0, NULL                         },
1323     { "setwritedir",    cmd_setwritedir,    1, "<newWriteDir>"              },
1324     { "permitsymlinks", cmd_permitsyms,     1, "<1or0>"                     },
1325     { "setsaneconfig",  cmd_setsaneconfig,  5, "<org> <appName> <arcExt> <includeCdRoms> <archivesFirst>" },
1326     { "mkdir",          cmd_mkdir,          1, "<dirToMk>"                  },
1327     { "delete",         cmd_delete,         1, "<dirToDelete>"              },
1328     { "getrealdir",     cmd_getrealdir,     1, "<fileToFind>"               },
1329     { "exists",         cmd_exists,         1, "<fileToCheck>"              },
1330     { "isdir",          cmd_isdir,          1, "<fileToCheck>"              },
1331     { "issymlink",      cmd_issymlink,      1, "<fileToCheck>"              },
1332     { "cat",            cmd_cat,            1, "<fileToCat>"                },
1333     { "cat2",           cmd_cat2,           2, "<fileToCat1> <fileToCat2>"  },
1334     { "filelength",     cmd_filelength,     1, "<fileToCheck>"              },
1335     { "stat",           cmd_stat,           1, "<fileToStat>"               },
1336     { "append",         cmd_append,         1, "<fileToAppend>"             },
1337     { "write",          cmd_write,          1, "<fileToCreateOrTrash>"      },
1338     { "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>"            },
1339     { "setbuffer",      cmd_setbuffer,      1, "<bufferSize>"               },
1340     { "stressbuffer",   cmd_stressbuffer,   1, "<bufferSize>"               },
1341     { "crc32",          cmd_crc32,          1, "<fileToHash>"               },
1342     { "getmountpoint",  cmd_getmountpoint,  1, "<dir>"                      },
1343     { NULL,             NULL,              -1, NULL                         }
1344 };
1345 
1346 
output_usage(const char * intro,const command_info * cmdinfo)1347 static void output_usage(const char *intro, const command_info *cmdinfo)
1348 {
1349     if (cmdinfo->argcount == 0)
1350         printf("%s \"%s\" (no arguments)\n", intro, cmdinfo->cmd);
1351     else
1352         printf("%s \"%s %s\"\n", intro, cmdinfo->cmd, cmdinfo->usage);
1353 } /* output_usage */
1354 
1355 
cmd_help(char * args)1356 static int cmd_help(char *args)
1357 {
1358     const command_info *i;
1359 
1360     printf("Commands:\n");
1361     for (i = commands; i->cmd != NULL; i++)
1362         output_usage("  -", i);
1363 
1364     return 1;
1365 } /* output_cmd_help */
1366 
1367 
trim_command(const char * orig,char * copy)1368 static void trim_command(const char *orig, char *copy)
1369 {
1370     const char *i;
1371     char *writeptr = copy;
1372     int spacecount = 0;
1373     int have_first = 0;
1374 
1375     for (i = orig; *i != '\0'; i++)
1376     {
1377         if (*i == ' ')
1378         {
1379             if ((*(i + 1) != ' ') && (*(i + 1) != '\0'))
1380             {
1381                 if ((have_first) && (!spacecount))
1382                 {
1383                     spacecount++;
1384                     *writeptr = ' ';
1385                     writeptr++;
1386                 } /* if */
1387             } /* if */
1388         } /* if */
1389         else
1390         {
1391             have_first = 1;
1392             spacecount = 0;
1393             *writeptr = *i;
1394             writeptr++;
1395         } /* else */
1396     } /* for */
1397 
1398     *writeptr = '\0';
1399 
1400     /*
1401     printf("\n command is [%s].\n", copy);
1402     */
1403 } /* trim_command */
1404 
1405 
process_command(char * complete_cmd)1406 static int process_command(char *complete_cmd)
1407 {
1408     const command_info *i;
1409     char *cmd_copy;
1410     char *args;
1411     int rc = 1;
1412 
1413     if (complete_cmd == NULL)  /* can happen if user hits CTRL-D, etc. */
1414     {
1415         printf("\n");
1416         return 0;
1417     } /* if */
1418 
1419     cmd_copy = (char *) malloc(strlen(complete_cmd) + 1);
1420     if (cmd_copy == NULL)
1421     {
1422         printf("\n\n\nOUT OF MEMORY!\n\n\n");
1423         return 0;
1424     } /* if */
1425 
1426     trim_command(complete_cmd, cmd_copy);
1427     args = strchr(cmd_copy, ' ');
1428     if (args != NULL)
1429     {
1430         *args = '\0';
1431         args++;
1432     } /* else */
1433 
1434     if (cmd_copy[0] != '\0')
1435     {
1436         for (i = commands; i->cmd != NULL; i++)
1437         {
1438             if (strcmp(i->cmd, cmd_copy) == 0)
1439             {
1440                 if ((i->argcount >= 0) && (count_args(args) != i->argcount))
1441                     output_usage("usage:", i);
1442                 else
1443                     rc = i->func(args);
1444                 break;
1445             } /* if */
1446         } /* for */
1447 
1448         if (i->cmd == NULL)
1449             printf("Unknown command. Enter \"help\" for instructions.\n");
1450 
1451 #if (defined PHYSFS_HAVE_READLINE)
1452         add_history(complete_cmd);
1453         if (history_file)
1454         {
1455             fprintf(history_file, "%s\n", complete_cmd);
1456             fflush(history_file);
1457         } /* if */
1458 #endif
1459 
1460     } /* if */
1461 
1462     free(cmd_copy);
1463     return rc;
1464 } /* process_command */
1465 
1466 
open_history_file(void)1467 static void open_history_file(void)
1468 {
1469 #if (defined PHYSFS_HAVE_READLINE)
1470 #if 0
1471     const char *envr = getenv("TESTPHYSFS_HISTORY");
1472     if (!envr)
1473         return;
1474 #else
1475     char envr[256];
1476     strcpy(envr, PHYSFS_getUserDir());
1477     strcat(envr, ".testphys_history");
1478 #endif
1479 
1480     if (access(envr, F_OK) == 0)
1481     {
1482         char buf[512];
1483         FILE *f = fopen(envr, "r");
1484         if (!f)
1485         {
1486             printf("\n\n"
1487                    "Could not open history file [%s] for reading!\n"
1488                    "  Will not have past history available.\n\n",
1489                     envr);
1490             return;
1491         } /* if */
1492 
1493         do
1494         {
1495             if (fgets(buf, sizeof (buf), f) == NULL)
1496                 break;
1497 
1498             if (buf[strlen(buf) - 1] == '\n')
1499                 buf[strlen(buf) - 1] = '\0';
1500             add_history(buf);
1501         } while (!feof(f));
1502 
1503         fclose(f);
1504     } /* if */
1505 
1506     history_file = fopen(envr, "ab");
1507     if (!history_file)
1508     {
1509         printf("\n\n"
1510                "Could not open history file [%s] for appending!\n"
1511                "  Will not be able to record this session's history.\n\n",
1512                 envr);
1513     } /* if */
1514 #endif
1515 } /* open_history_file */
1516 
1517 
main(int argc,char ** argv)1518 int main(int argc, char **argv)
1519 {
1520     char *buf = NULL;
1521     int rc = 0;
1522 
1523 #if (defined __MWERKS__)
1524     extern tSIOUXSettings SIOUXSettings;
1525     SIOUXSettings.asktosaveonclose = 0;
1526     SIOUXSettings.autocloseonquit = 1;
1527     SIOUXSettings.rows = 40;
1528     SIOUXSettings.columns = 120;
1529 #endif
1530 
1531     printf("\n");
1532 
1533     if (!PHYSFS_init(argv[0]))
1534     {
1535         printf("PHYSFS_init() failed!\n  reason: %s.\n", PHYSFS_getLastError());
1536         return 1;
1537     } /* if */
1538 
1539     output_versions();
1540     output_archivers();
1541 
1542     open_history_file();
1543 
1544     printf("Enter commands. Enter \"help\" for instructions.\n");
1545     fflush(stdout);
1546 
1547     do
1548     {
1549 #if (defined PHYSFS_HAVE_READLINE)
1550         buf = readline("> ");
1551 #else
1552         int i;
1553         buf = (char *) malloc(512);
1554         memset(buf, '\0', 512);
1555         printf("> ");
1556         fflush(stdout);
1557         for (i = 0; i < 511; i++)
1558         {
1559             int ch = fgetc(stdin);
1560             if (ch == EOF)
1561             {
1562                 strcpy(buf, "quit");
1563                 break;
1564             } /* if */
1565             else if ((ch == '\n') || (ch == '\r'))
1566             {
1567                 buf[i] = '\0';
1568                 break;
1569             } /* else if */
1570             else if (ch == '\b')
1571             {
1572                 if (i > 0)
1573                     i--;
1574             } /* else if */
1575             else
1576             {
1577                 buf[i] = (char) ch;
1578             } /* else */
1579         } /* for */
1580 #endif
1581 
1582         rc = process_command(buf);
1583         fflush(stdout);
1584         if (buf != NULL)
1585             free(buf);
1586     } while (rc);
1587 
1588     if (!PHYSFS_deinit())
1589         printf("PHYSFS_deinit() failed!\n  reason: %s.\n", PHYSFS_getLastError());
1590 
1591     if (history_file)
1592         fclose(history_file);
1593 
1594 /*
1595     printf("\n\ntest_physfs written by ryan c. gordon.\n");
1596     printf(" it makes you shoot teh railgun bettar.\n");
1597 */
1598 
1599     return 0;
1600 } /* main */
1601 
1602 /* end of test_physfs.c ... */
1603 
1604