home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / zoo141_c.lzh / ZOOLIST.C < prev    next >
C/C++ Source or Header  |  1987-02-07  |  12KB  |  338 lines

  1. /* zoolist.c */
  2. /*
  3. Copyright (C) 1986 Rahul Dhesi -- All rights reserved
  4. */
  5. #include "options.h"
  6. #include "portable.h"
  7. #include "zoomem.h"  /* to get ZOOCOUNT */
  8.  
  9. /* Lists files in archive */
  10. #include "zoo.h"
  11. #include "errors.i"
  12. #include <stdio.h>
  13. #include "various.h"
  14. #include "zoofns.h"
  15.  
  16. static char tot_fmt[] = "%8lu %3u%% %8lu  %4d file%s\n"; 
  17. /* static char tot_fmt[] = "%8lu %3u%%  %8lu   %23d files\n"; */
  18. /* static char tot_fmt[] = "TOTAL %4d    %8lu %3u%%  %8lu\n"; */
  19. static char tot_line[] = 
  20.    /* "------------  --------  ---  --------  --------- --------\n"; */
  21.    "--------  --- --------  --------- --------\n";
  22.  
  23. static char dbl_percent[] = "Archive %s:  %s";
  24.  
  25. #ifdef LINT_ARGS
  26. void show_comment (struct direntry *, FILE *, int, char *);
  27. int ver_too_high (struct zoo_header *);
  28. #endif
  29.  
  30. void zoolist (argv, option, argc)
  31. char **argv, *option;
  32. int argc;
  33. {
  34. char whichname[PATHSIZE];  /* which name to use */
  35. char *this_zoo;            /* currently matched archive name */
  36. register FILE *zoo_file;
  37. char *flist[ZOOCOUNT];       /* list of ptrs to input archive names */
  38. int fptr;                  /* will point to within list of archive names */
  39.  
  40. struct direntry direntry;
  41. struct zoo_header zoo_header;
  42. int size_factor;
  43. char packing[9];
  44. unsigned long tot_org_siz = 0L, tot_siz_now = 0L;
  45. int   tot_sf;
  46. int file_count = 0;
  47. int del_count = 0;                  /* number of deleted entries */
  48. int bad_pack;                 /* 1 if packing method is unknown */
  49. static char *month_list="000JanFebMarAprMayJunJulAugSepOctNovDec";
  50. static char dashes[] = "------------\n";
  51. int year, month, day, hours, min, sec;
  52. int list_deleted = 0;         /* list deleted files too */
  53. int fast = 0;                 /* fast list */
  54. int column;                   /* for column printing */
  55. long fiz_ofs = 0;             /* offset where to start */
  56. int verb_list = 0;            /* if verbose listing needed */
  57. int show_name = 0;            /* if archive name to be included in listing */
  58. int zoocount = 1;             /* number of archives to list */
  59. int biglist = 0;              /* multiarchive listing */
  60. int longest;                  /* length of longest archive name */
  61.  
  62. while (*option) {
  63.    switch (*option) {
  64.       case 'a': show_name++; break;
  65.       case 'd': list_deleted++; break;
  66.       case 'f': fast++; break;
  67.       case 'c':
  68.       case 'v': verb_list++; break;
  69.       case 'l': break;
  70.       case 'L': biglist++; zoocount = argc; break;
  71.       case '@': 
  72.          ++option;
  73.          fiz_ofs = calc_ofs(option); 
  74.          goto no_more;
  75.       default:
  76.          prterror ('w', option_ignored, *option);
  77.    }
  78.    option++;
  79. }
  80.  
  81. no_more:  /* come from exit from while loop above */
  82.  
  83. if (fast && show_name) {      /* don't allow 'a' with 'f' */
  84.    show_name = 0;
  85.    prterror ('w', option_ignored, 'a');
  86. }
  87.  
  88. #ifdef WILDCARDS
  89.    /* For each archive name supplied, if it is not a char range and
  90.       does not contain a dot, append "*.zoo". */
  91.    {
  92.       int i;
  93.       for (i = 0; i < argc;  i++) {
  94.          if (strchr (nameptr (argv[i]), EXT_CH) == NULL && 
  95.                            !match_half (nameptr (argv[0]), "?-?"))
  96.             argv[i] = newcat (argv[i], "*.zoo");
  97.       }
  98.    }
  99. #endif
  100.  
  101. makelist (zoocount, argv, flist,        ZOOCOUNT-2,   ".",".","..", &longest);
  102. /*        ^argc     ^argv ^list_pointer ^max_no_files   ^exclude */
  103.  
  104. for (fptr = 0;  (this_zoo = flist[fptr]) != NULL; fptr++) {
  105.    int ercount;                  /* count of errors */
  106.    int entrycount;               /* count of directory entries */
  107.    int column;                   /* for column printing */
  108.    int expl_deleted;             /* explain what D means */
  109.    int expl_comment;             /* explain what comment means */
  110.    int expl_ver;                 /* Explain what V means */
  111.    int expl_star;                /* Explain what * means */
  112.    int first_time;               /* first time through loop for an archive */
  113.  
  114.    ercount = entrycount = column = del_count =
  115.       expl_deleted = expl_comment = expl_ver = expl_star = 0;
  116.    first_time = 1;
  117.  
  118. #ifndef WILDCARDS
  119.    /* Add default extension if none supplied */
  120.    if (strchr (nameptr (this_zoo), EXT_CH) == NULL)
  121.       this_zoo = newcat (this_zoo, EXT_DFLT);
  122. #endif
  123.  
  124.    zoo_file = fopen (this_zoo, FRDSTR);
  125.  
  126.    if (zoo_file == NULL) {
  127.       prterror ('e', could_not_open, this_zoo);
  128.       continue;
  129.    } else if (!show_name)
  130.       printf ("\nArchive %s:\n", this_zoo);
  131.    
  132. if (fiz_ofs != 0L) {                /* if offset specified, start there */
  133.    prterror('m', "Starting at %ld\n", fiz_ofs);
  134.    fseek (zoo_file, fiz_ofs, 0);
  135. } else {
  136.    if (frd_zooh (&zoo_header, zoo_file) == -1 ||
  137.                                              zoo_header.zoo_tag != ZOO_TAG) {
  138.       prterror ('e', dbl_percent, this_zoo, invalid_header);
  139.       goto loop_end;
  140.    }
  141.    /* Seek to the beginning of the first directory entry */
  142.    if (fseek (zoo_file, zoo_header.zoo_start, 0) != 0) {
  143.       ercount++;
  144.       prterror ('e', dbl_percent, this_zoo, bad_directory);
  145.       goto loop_end;
  146.    }
  147.    if (!show_name && ver_too_high (&zoo_header)) {
  148.       ercount++;
  149.       if (ercount < 2) {
  150.          prterror ('w', dbl_percent, this_zoo, "");
  151.          prterror ('M', wrong_version, zoo_header.major_ver, zoo_header.minor_ver);
  152.       }
  153.    }
  154. } /* end if (fiz_ofs !- 0L) */
  155.  
  156.    /* Now we print information about each file in the archive */
  157.    
  158.    if (!show_name) { /* initialize for each file only if not disk catalog */
  159.       tot_org_siz = 0L;  
  160.       tot_siz_now = 0L;
  161.       file_count = 0;
  162.       del_count = 0;
  163.    }
  164.  
  165.    while (1) {
  166.       if (readdir (&direntry, zoo_file, 0) == -1) {
  167.          prterror ('F', dbl_percent, this_zoo, bad_directory);
  168.          goto givesummary;
  169.       }
  170.       if (direntry.zoo_tag != ZOO_TAG) {
  171.          long currpos, zoolength;
  172.          prterror ('F', dbl_percent, this_zoo, invalid_header);
  173.          if ((currpos = ftell (zoo_file)) != -1L)
  174.             if (fseek (zoo_file, 0L, 2) == 0)
  175.                if ((zoolength = ftell (zoo_file)) != -1L)
  176.                   printf (cant_process, zoolength - currpos);              
  177.          goto givesummary;
  178.       }
  179.    
  180.       if (direntry.next == 0L)      /* EXIT on end of chain */
  181.          break;                                 
  182.       else
  183.          entrycount++;              /* Number of directory entries */
  184.    
  185.       if (direntry.deleted)
  186.          ++del_count;
  187.       
  188.       combine (whichname,
  189.                direntry.dirlen > 0 ? direntry.dirname : "", 
  190.                (direntry.namlen > 0) ? direntry.lfname : direntry.fname
  191.               );
  192. #ifdef DEBUG
  193.       printf("matching against [%s] and [%s]\n", 
  194.                nameptr(whichname), whichname);
  195. #endif
  196.  
  197.       if ( ( (list_deleted && direntry.deleted) ||
  198.                (list_deleted < 2 && !direntry.deleted)
  199.            ) 
  200.               && (biglist || needed(whichname))) {
  201.    
  202.          file_count++;
  203.    
  204.          if (direntry.packing_method > MAX_PACK) {
  205.             bad_pack = 1;
  206.             expl_ver = 1;
  207.          }  else
  208.             bad_pack = 0;
  209.       
  210.          size_factor = cfactor (direntry.org_size, direntry.size_now);
  211.    
  212.          year  =  ((unsigned int) direntry.date >> 9) & 0x7f;
  213.          month =  ((unsigned int) direntry.date >> 5) & 0x0f;
  214.          day   =  direntry.date        & 0x1f;
  215.    
  216.          hours =  ((unsigned int) direntry.time >> 11)& 0x1f;
  217.          min   =  ((unsigned int) direntry.time >> 5) & 0x3f;
  218.          sec   =  ((unsigned int) direntry.time & 0x1f) * 2;
  219.    
  220.          if (fast) {
  221.             if ((column++ % 5) == 0 && !first_time)
  222.                fputchar ('\n');
  223.             printf("%-12s  ", direntry.fname);
  224.    
  225.          } else {
  226.             if (first_time && !show_name) {     /* print archive header */
  227.                printf ("Length    CF  Size Now  Date      Time\n");
  228.                printf (tot_line);
  229.             }
  230.             printf ("%8lu %3u%% %8lu  %2d %-.3s %02d %02d:%02d:%02d",  
  231.                      direntry.org_size, 
  232.                      size_factor, direntry.size_now, 
  233.                      day, &month_list[month*3], 
  234.                      (day && month) ?  (year+80) % 100 : 0,
  235.                      hours, min, sec);
  236.                tot_org_siz += direntry.org_size;
  237.                tot_siz_now += direntry.size_now;
  238.    
  239.             if (direntry.cmt_size) {
  240.                expl_comment++;
  241.                printf ("C");
  242.             } else
  243.                printf (" ");
  244.    
  245.             if (direntry.deleted) {
  246.                expl_deleted++;
  247.                printf ("D");
  248.             }  else
  249.                printf (" ");
  250.             if (list_deleted)
  251.                printf (" ");
  252.             if (show_name)
  253.                printf ("%-*s ", longest, this_zoo);
  254.             printf ("%s%s", 
  255.                      whichname,
  256.                      (direntry.dir_crc == 0) ? "" : (expl_star++, "*")
  257.                    );
  258.             if (bad_pack)
  259.                printf (" (V%d.%d)", direntry.major_ver, direntry.minor_ver);
  260.             printf ("\n");
  261.          }
  262.          first_time = 0;
  263.    
  264.          /* if verbose listing requested show any comment.  f overrrides v */
  265.          if (verb_list && !fast)
  266.             show_comment (&direntry, zoo_file, 0, NULL);
  267.       }
  268.    
  269.       fseek (zoo_file, direntry.next, 0); /* ..seek to next dir entry */
  270.    } /* end while */
  271.    
  272.    givesummary:
  273.    
  274.    if (!show_name) {
  275.       if (fast) {
  276.          if (file_count) {
  277.             if (del_count)
  278.                printf ("\n-----\n");
  279.             else
  280.                fputchar ('\n');
  281.          }
  282.          if (del_count)
  283.             printf ("%d deleted.\n", del_count);
  284.       }
  285.       if (!fast && file_count) {
  286.          tot_sf = cfactor (tot_org_siz, tot_siz_now);
  287.          printf (tot_line);
  288.       
  289.          printf (tot_fmt, tot_org_siz, tot_sf, tot_siz_now, file_count,
  290.             (file_count > 1) ? "s" : "");
  291.       /* printf (tot_fmt, file_count, tot_org_siz, tot_sf, tot_siz_now); */
  292.          
  293.          if (del_count || expl_ver || expl_deleted || expl_comment)
  294.             printf (dashes);
  295.       }
  296.    
  297.       if (!fast) {
  298.          if (del_count) {
  299.             if (expl_deleted)
  300.                printf ("D: deleted file.\n");
  301.             else {
  302.                if (del_count == 1)
  303.                   printf ("There is 1 deleted file.\n");
  304.                else
  305.                   printf ("There are %d deleted files.\n", del_count);
  306.             }
  307.          }
  308.       }
  309.       if (expl_comment && !fast && !verb_list) 
  310.          printf ("C: file has attached comment.\n");
  311.       if (expl_ver && !fast)
  312.          printf ("V: minimum version of Zoo needed to extract this file.\n");
  313.       if (expl_star && !fast)
  314.          printf ("*: directory entry may be corrupted.\n");
  315.       if (!file_count)
  316.          printf ("Zoo:  %s", no_match);
  317.       
  318.       if (!entrycount && !fiz_ofs)
  319.          printf ("(The archive is empty.)\n");
  320.    } /* end if (show_name) */
  321. loop_end:            /* jump here on badly structured archive */
  322.    fclose (zoo_file);
  323. } /* end for */
  324.  
  325. if (show_name) {
  326.    if (file_count) {
  327.       tot_sf = cfactor (tot_org_siz, tot_siz_now);
  328.       printf (tot_line);
  329.       printf (tot_fmt, tot_org_siz, tot_sf, tot_siz_now, file_count);
  330.    /* printf (tot_fmt, file_count, tot_org_siz, tot_sf, tot_siz_now); */
  331.    } 
  332. }
  333.  
  334. if (!file_count)
  335.    exit (1);            /* Consider it an error if there were no files */
  336. } /* zoolist() */
  337.  
  338.