~ubuntu-branches/ubuntu/gutsy/unzoo/gutsy

« back to all changes in this revision

Viewing changes to unzoo.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Schoepf
  • Date: 2005-05-17 22:01:26 UTC
  • Revision ID: james.westby@ubuntu.com-20050517220126-k5fwxwblu27zx4sw
Tags: 4.4-4
Modified patch from -3 with feedback from Joey Hess. Thanks!

Show diffs side-by-side

added added

removed removed

Lines of Context:
2479
2479
 
2480
2480
/****************************************************************************
2481
2481
**
2482
 
*F  ExtrArch(<bim>,<out>,<ovr>,<pre>,<arc>,<filec>,<files>) . extract members
 
2482
*F  ExtrArch(<bim>,<out>,<ovr>,<pre>,<frc>,<arc>,<filec>,<files>) . extract members
2483
2483
**
2484
2484
**  'ExtrArch' extracts the members  of the archive with  the name <arc> that
2485
2485
**  match one  of the file name  patterns '<files>[0] .. <files>[<filec>-1]'.
2491
2491
**  stdout, i.e., to the screen.  and if it  is 2, the members are extracted.
2492
2492
**  If <ovr> is 0, members will not overwrite  existing files; otherwise they
2493
2493
**  will.  <pre> is a prefix that is prepended to all path names.
 
2494
**  <frc> is 1 if the user requested extraction of members even if this would
 
2495
** result in a directory traversal.
2494
2496
*/
2495
 
int             ExtrArch ( bim, out, ovr, pre, arc, filec, files )
 
2497
int             ExtrArch ( bim, out, ovr, pre, frc, arc, filec, files )
2496
2498
    unsigned long       bim;
2497
2499
    unsigned long       out;
2498
2500
    unsigned long       ovr;
2499
2501
    char *              pre;
 
2502
    unsigned long       frc;
2500
2503
    char *              arc;
2501
2504
    unsigned long       filec;
2502
2505
    char *              files [];
2582
2585
            continue;
2583
2586
        }
2584
2587
 
 
2588
        /* check the path for directory traversal                          */
 
2589
        if (frc != 1) {
 
2590
            /* but only if the user did not request otherwise              */
 
2591
 
 
2592
            /* building the universal path of this member                  */
 
2593
            char patu [sizeof(Entry.diru) + sizeof(Entry.namu) + 2];
 
2594
            strcpy( patu, Entry.diru );
 
2595
            if ( strlen(patu) && patu[strlen(patu)-1] != '/') strcat( patu, "/" );
 
2596
            strcat( patu, (Entry.lnamu ? Entry.namu : Entry.nams) );
 
2597
 
 
2598
            int found_trav = 0;
 
2599
 
 
2600
            if ( strstr( patu, "/../" )) {
 
2601
                found_trav = 1;
 
2602
 
 
2603
                /* remove "/../" from the path                             */
 
2604
                char tmp [sizeof(patu)];
 
2605
                char *p;
 
2606
                char *q;
 
2607
                memset(tmp, 0, sizeof(tmp));
 
2608
                q = patu;
 
2609
 
 
2610
                while ( !strncmp(q, "/../", 4) ) {
 
2611
                    q += 3;
 
2612
                }
 
2613
                if (q[0] == '/') q++;
 
2614
 
 
2615
                while ((p = strstr( q, "/../" )) != NULL) {
 
2616
                    if (q[0] == '/') q++;
 
2617
                    if (p > q) strncat(tmp, q, p-q);
 
2618
                    if (tmp[strlen(tmp)-1] != '/') strcat(tmp, "/");
 
2619
                    p += 3;
 
2620
                    q = p;
 
2621
                }
 
2622
                strncat(tmp, q+1, patu + strlen(patu) - q);
 
2623
                strcpy(patu, tmp);
 
2624
 
 
2625
                printf("unzoo: skipped \"/../\" path component(s) in '%s'\n", Entry.patl);
 
2626
            }
 
2627
            if ( *patu == '/' && !strlen( pre ) ) {
 
2628
                found_trav = 1;
 
2629
 
 
2630
                char *p = malloc(sizeof(patu));
 
2631
                char *q = p;
 
2632
                memset(p, 0, sizeof(patu));
 
2633
                strcpy(p, patu);
 
2634
                while ( q[0] == '/' ) q++;
 
2635
                strcpy(patu, q);
 
2636
                free(p);
 
2637
 
 
2638
                printf("unzoo: skipped root directory path component in '%s'\n", patl);
 
2639
            }
 
2640
            if ( !strncmp( patu, "../", 3 )) {
 
2641
                found_trav = 1;
 
2642
 
 
2643
                char tmp [sizeof(patu)];
 
2644
                memset(tmp, 0, sizeof(tmp));
 
2645
                strcpy(tmp, patu + 3);
 
2646
                strcpy(patu, tmp);
 
2647
 
 
2648
                printf("unzoo: skipped \"../\" path component in '%s'\n", patl);
 
2649
            }
 
2650
 
 
2651
            if (found_trav) {
 
2652
                /* patu contains the sanitized 'universal' path, i.e.      */
 
2653
                /* separated by '/' characters, including the file name.   */
 
2654
 
 
2655
                char *f = strrchr( patu, '/' );
 
2656
                *f++ = '\0';
 
2657
                /* Now, patu points to the directory part, f to the file   */
 
2658
 
 
2659
                memset( Entry.diru, 0, sizeof(Entry.diru) );
 
2660
                strncpy( Entry.diru, patu, sizeof(Entry.diru)-1 );
 
2661
                if ( Entry.lnamu > 0 ) {
 
2662
                    memset( Entry.namu, 0, sizeof(Entry.namu) );
 
2663
                    strncpy( Entry.namu, f, sizeof(Entry.namu)-1 );
 
2664
                } else {
 
2665
                    memset( Entry.nams, 0, sizeof(Entry.nams) );
 
2666
                    strncpy( Entry.nams, f, sizeof(Entry.nams)-1 );
 
2667
                }
 
2668
 
 
2669
                /* convert the names to local format                       */
 
2670
                if ( Entry.system == 0 || Entry.system == 2 ) {
 
2671
                    CONV_DIRE( Entry.dirl, Entry.diru );
 
2672
                    CONV_NAME( Entry.naml, (Entry.lnamu ? Entry.namu : Entry.nams) );
 
2673
                }
 
2674
                else {
 
2675
                    strcpy( Entry.dirl, Entry.diru );
 
2676
                    strcpy( Entry.naml, (Entry.lnamu ? Entry.namu : Entry.nams) );
 
2677
                }
 
2678
                /* sizeof(patl)=512, sizeof({dirl|naml}=256} */
 
2679
                strcpy( Entry.patl, Entry.dirl );
 
2680
                strcat( Entry.patl, Entry.naml );
 
2681
            }
 
2682
        }
 
2683
 
2585
2684
        /* check that such a file does not already exist                   */
2586
2685
        strcpy( patl, pre );  strcat( patl, Entry.patl );
2587
2686
        if ( out == 2 && ovr == 0 && OpenReadFile(patl,0L) ) {
2740
2839
    printf("  <file>: list only files matching at least one pattern,\n");
2741
2840
    printf("          '?' matches any char, '*' matches any string.\n");
2742
2841
    printf("\n");
2743
 
    printf("unzoo -x [-abnpo] [-j <prefix>] <archive>[.zoo] [<file>..]\n");
 
2842
    printf("unzoo -x [-abnpo] [-t] [-j <prefix>] <archive>[.zoo] [<file>..]\n");
2744
2843
    printf("  extract the members of the archive\n");
2745
2844
    printf("  -a:  extract all members as text files ");
2746
2845
    printf("(not only those with !TEXT! comments)\n");
2750
2849
    printf("  -p:  extract to stdout\n");
2751
2850
    printf("  -o:  extract over existing files\n");
2752
2851
    printf("  -j:  extract to '<prefix><membername>'\n");
 
2852
    printf("  -f:  force extraction of members to their original locations\n");
 
2853
    printf("       even if this results in files extracted outside the\n");
 
2854
    printf("       working directory. THIS COULD POTENTIALLY OVERWRITE\n");
 
2855
    printf("       IMPORTANT FILES, SO USE WITH CARE!\n");
2753
2856
    printf("  <file>: extract only files matching at least one pattern,\n");
2754
2857
    printf("          '?' matches any char, '*' matches any string.\n");
2755
2858
    return 1;
2773
2876
    unsigned long       bim;            /* extraction mode option          */
2774
2877
    unsigned long       out;            /* output destination option       */
2775
2878
    unsigned long       ovr;            /* overwrite file option           */
 
2879
    unsigned long       frc;            /* force extraction option         */
2776
2880
    char *              pre;            /* prefix to prepend to path names */
2777
2881
    char                argl [256];     /* interactive command line        */
2778
2882
    int                 argd;           /* interactive command count       */
2792
2896
    do {
2793
2897
 
2794
2898
        /* scan the command line arguments                                 */
2795
 
        cmd = 1;  ver = 0;  bim = 0;  out = 2;  ovr = 0;
 
2899
        cmd = 1;  ver = 0;  bim = 0;  out = 2;  ovr = 0; frc = 0;
2796
2900
        pre = "";
2797
2901
        while ( 1 < argc && argv[1][0] == '-' ) {
2798
2902
            if ( argv[1][2] != '\0' )  cmd = 0;
2802
2906
            case 'x': case 'X': if ( cmd != 0 )  cmd = 2;            break;
2803
2907
            case 'a': case 'A': if ( cmd != 2 )  cmd = 0;  bim = 1;  break;
2804
2908
            case 'b': case 'B': if ( cmd != 2 )  cmd = 0;  bim = 2;  break;
 
2909
            case 'f': case 'F': if ( cmd != 2 )  cmd = 0;  frc = 1; break;
2805
2910
            case 'n': case 'N': if ( cmd != 2 )  cmd = 0;  out = 0;  break;
2806
2911
            case 'p': case 'P': if ( cmd != 2 )  cmd = 0;  out = 1;  break;
2807
2912
            case 'o': case 'O': if ( cmd != 2 )  cmd = 0;  ovr = 1;  break;
2818
2923
            res = ListArch( ver, argv[1],
2819
2924
                            (unsigned long)argc-2, argv+2 );
2820
2925
        else if ( cmd == 2 && 1 < argc )
2821
 
            res = ExtrArch( bim, out, ovr, pre, argv[1],
 
2926
            res = ExtrArch( bim, out, ovr, pre, frc, argv[1],
2822
2927
                            (unsigned long)argc-2, argv+2 );
2823
2928
        else
2824
2929
            res = HelpArch();