Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 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
 
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
 
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
 
81
static int cmd_quit(char *args)
82
{
83
    return 0;
84
} /* cmd_quit */
85
 
86
 
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
 
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
 
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. */
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
 
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
 
262
static int cmd_mount(char *args)
263
{
264
    return cmd_mount_internal(args, MNTTYPE_PATH);
265
} /* cmd_mount */
266
 
267
 
268
static int cmd_mount_mem(char *args)
269
{
270
    return cmd_mount_internal(args, MNTTYPE_MEMORY);
271
} /* cmd_mount_mem */
272
 
273
 
274
static int cmd_mount_handle(char *args)
275
{
276
    return cmd_mount_internal(args, MNTTYPE_HANDLE);
277
} /* cmd_mount_handle */
278
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
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
 
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
 
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
 
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
 
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
 
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
 
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. */
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
 
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
 
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
 
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
 
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
 
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
 
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