home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / msdos / opus / fvsrc620.arc / ARC_VIEW.C next >
C/C++ Source or Header  |  1989-05-26  |  22KB  |  655 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /* Copyright 1989, Doug Boone.  FidoNet 119/5                               */
  4. /*                              (916) 893-9019 Data                         */
  5. /*                              (916) 891-0748 voice                        */
  6. /*                              P.O. Box 5108, Chico, CA. 95928             */
  7. /*                                                                          */
  8. /* This program is not for sale. It is for the free use with Opus systems.  */
  9. /* You may not sell it in ANY way. If you have an access charge to your     */
  10. /* Bulletin Board, consider this to be like Opus, you can ONLY make it      */
  11. /* available for download in an open area, where non-members can get access */
  12. /*                                                                          */
  13. /* If you need to modify this source code, please send me a copy of the     */
  14. /* changes you've made so that everyone can share in the updates.           */
  15. /*                                                                          */
  16. /* "Don't rip me off!" -- Tom Jennings, FidoNet's founder                   */
  17. /*                                                                          */
  18. /*--------------------------------------------------------------------------*/
  19.  
  20. #include    <stdio.h>
  21. #include    <string.h>
  22. #include    <ctype.h>
  23. #include    <time.h>
  24. #include    <signal.h>
  25. #include    <dos.h>
  26. #ifdef TURBOC
  27. #include    <dir.h>
  28. #include    <alloc.h>
  29. #else
  30. #include    <malloc.h>
  31. #endif
  32. #include    <io.h>
  33. #include    <fcntl.h>
  34. #include    <dos.h>
  35. #include    <conio.h>
  36. #include    <sys\types.h>
  37. #include    <sys\stat.h>
  38. #include    <opus.h>
  39. #include    <process.h>
  40. #include    "archdr.h"
  41. #include    "arc_view.h"
  42.  
  43. /* ====================================================================
  44.  * start a new screen full while listing the contents of an arc file
  45.  * ====================================================================
  46.  */
  47. void arc_header(char *packer,char *name)
  48.  
  49. {
  50.     char    temp[80];
  51.     char    *check;
  52.  
  53.     if (!ctrl_err)
  54.         return;
  55.  
  56.     if ((check = strchr(name,'\\')) != NULL)
  57.         check++;
  58.     else
  59.         check =name;
  60.     sprintf(temp,"\n %s  Contents of %s\n",packer,check);
  61.     sdisplay(temp);
  62.     sdisplay("Filename        Length   Method     Size   Ratio    Date      Time\n");
  63.     sdisplay("--------        ------   ------    ------  -----    ----      ----\n");
  64.     return;
  65. }
  66.  
  67. /*--------------------------------------------------------------------------*/
  68. /* Print out one line of archives                                           */
  69. /*--------------------------------------------------------------------------*/
  70.  
  71. void one_line(char *name,long org_len,long new_len,char *pack,char *date,char *time)
  72. {
  73.     int     factor;
  74.     char    temp[80];
  75.  
  76.     if (!ctrl_err)
  77.         return;
  78.  
  79.     if (new_len > 0)
  80.         factor = ((int) ((100 * new_len)/org_len));
  81.     if (strlen(name) < 13)
  82.         sprintf(temp,"%-12s",name);
  83.     else
  84.         sprintf(temp,"%s\n            ",name);
  85.     sdisplay(temp);
  86.  
  87.     sprintf(temp,"  %8ld %10s%8ld   %3d%%",org_len,pack,new_len,factor);
  88.     sdisplay(temp);
  89.     sprintf(temp,"  %8s  %8s\n",date,time);
  90.     sdisplay(temp);
  91.     return;
  92. }
  93. /*--------------------------------------------------------------------------*/
  94. /* Show grand totals for successful archives                                */
  95. /*--------------------------------------------------------------------------*/
  96.  
  97. void do_totals(int totmbrs,long totlen,long totsize,int totsf)
  98. {
  99.     char    temp[81];
  100.  
  101.     if (!ctrl_err)
  102.         return;
  103.  
  104.     sdisplay("----\t\t------\t\t   ------  -----\n");
  105.     sprintf(temp,"Total %6d  %8ld  ",totmbrs,totlen);
  106.     sdisplay(temp);
  107.     sprintf(temp,"\t %8ld   %3d%%\n",totsize,totsf);
  108.     sdisplay(temp);
  109.     return;
  110. }
  111.  
  112. /* ====================================================================
  113.  * start of list arc contents processing
  114.  * ====================================================================
  115.  */
  116. int lstarc(char *arcname)        /* list files in archive */
  117. {
  118.     struct     heads *hdr;        /* header data */
  119.     int     totmbrs = 0;        /* total members in arc */
  120.     long    totlen = 0L;            /* total of file lengths */
  121.     long    totsize = 0L;        /* total of file sizes */
  122.     int        totsf;
  123.     int        ver;
  124.     FILE      *arc;            /* archive file */
  125.     char    date[9];
  126.     char    time[9];
  127.     char    method[11];
  128.  
  129.  
  130.     hdr = (struct heads *) malloc(sizeof(struct heads));
  131.  
  132.     if((arc=fopen(arcname,"rb")) == NULL ) {
  133.         perror("  Cannot read archive: ");
  134.         return(-1);
  135.         }
  136.     mem_used = 0;
  137.     fseek(arc,1L,SEEK_SET);
  138.     ver = fgetc(arc);
  139.     if (!(flags & VIEW))
  140.         arc_header("ARC/PAK",arcname);
  141.     while (ver > 0 && ver < 11) {
  142.         fread(hdr,sizeof(struct heads),1,arc);
  143.         if (!(flags & VIEW)) {
  144.             totlen += hdr->mbrlen;
  145.             totsize += hdr->mbrsize;
  146.             totmbrs++;
  147.             sprintf(date,"%02d-%02d-%02d",
  148.                 ((hdr->mbrdate >> MONTH_SHIFT) & MONTH_MASK),
  149.                     (hdr->mbrdate & DAY_MASK),
  150.                         ((hdr->mbrdate >> YEAR_SHIFT) + DOS_EPOCH));
  151.  
  152.             sprintf(time,"%02d:%02d:%02d",
  153.                 ((hdr->mbrtime >> HOUR_SHIFT) & HOUR_MASK),
  154.                 ((hdr->mbrtime >> MINUTE_SHIFT) & MINUTE_MASK),
  155.                     (hdr->mbrtime & HOUR_MASK)*2);
  156.             switch(ver) {
  157.                 case 1:    strcpy(method,"    --    ");    /* 1 - old, no compression */
  158.                         break;
  159.                 case 2: strcpy(method,"  Stored  ");    /* 2 - new, no compression */
  160.                         break;
  161.                 case 3: strcpy(method,"  Packed  ");    /* 3 - dle for repeat chars */
  162.                         break;
  163.                 case 4: strcpy(method," Squeezed ");    /* 4 - huffman encodeing */
  164.                         break;
  165.                 case 5: strcpy(method," Crunched ");    /* 5 - lz, no dle */
  166.                         break;
  167.                 case 6: strcpy(method," Crunched ");    /* 6 - lz with dle */
  168.                         break;
  169.                 case 7: strcpy(method," Crunched ");    /* 7 - lz with readjust */
  170.                         break;
  171.                 case 8: strcpy(method," Crunched ");    /* 8 - lz with readjust and dle */
  172.                         break;
  173.                 case 9: strcpy(method," Squashed ");    /* 9 - modified lzw, no dle */
  174.                         break;
  175.                 case 10: strcpy(method,"  Crushed ");    /* PAK's new method */
  176.                             break;
  177.                 default: strcpy(method," Unknown! ");/* future? */
  178.                         break;
  179.                 }        /* End of version switch */
  180.             one_line(hdr->mbrname,hdr->mbrlen,hdr->mbrsize,method,date,time);
  181.             }
  182.         strcpy(member[mem_used].name,hdr->mbrname);
  183.         member[mem_used].size = ((unsigned int) (hdr->mbrsize/1024L));
  184.         if (mem_used < MAX_NAMES)
  185.             mem_used++;
  186.         fseek(arc,hdr->mbrsize+1L,SEEK_CUR);
  187.         ver = fgetc(arc);
  188.         if (!(ctrl_err))
  189.             ver = 0;
  190.         };        /* End of while loop */
  191.     fclose(arc);        /* then close it */
  192.     if (!(flags & VIEW)) {
  193.         totsf = 0;
  194.         if(totlen>0L)
  195.             totsf = (int)(100L - ((100L*totsize)/totlen));
  196.         do_totals(totmbrs,totlen,totsize,totsf);
  197.         }
  198.     free(hdr);
  199.     if (mem_used >0) {
  200.         mem_used--;
  201.         if (ctrl_err)
  202.             return(0);
  203.         }
  204.     return(-1);
  205. }
  206.  
  207. /*--------------------------------------------------------------------------*/
  208. /* Handle a ZOO archive                                                     */
  209. /*--------------------------------------------------------------------------*/
  210.  
  211. int do_zoo(char *filename)
  212. {
  213.     FILE    *fhandle;
  214.     struct    zoo_header    *main_head;
  215.     struct    direntry    *one_head;
  216.     int     result;
  217.     unsigned    totmbrs=0;        /* number of members in Zoo */
  218.     long    totlen=0L;        /* total of all file sizes */
  219.     long    totsize = 0L;
  220.     int     totsf;
  221.     char    method[11];
  222.     char    time[9];
  223.     char    date[9];
  224.  
  225.     main_head = (struct zoo_header *) malloc(sizeof(struct zoo_header));
  226.     one_head = (struct direntry *) malloc(sizeof(struct direntry));
  227.  
  228.     fhandle = fopen(filename,"rb");
  229.     result = fread(main_head,sizeof(struct zoo_header),1,fhandle);
  230.     if ((strnicmp(main_head->text,"ZOO",3)) != 0) {
  231.         sdisplay("  Not a Zoo archive!  ");
  232.         fclose(fhandle);
  233.         return(-1);
  234.         }
  235.     mem_used = 0;
  236.     if (!(flags & VIEW))
  237.         arc_header("ZOO",filename);
  238.     fseek(fhandle,main_head->zoo_start,SEEK_SET);
  239.     result = fread(one_head,sizeof(struct direntry),1,fhandle);
  240.     do {
  241.         if (result == 1) {
  242.             if (!(flags & VIEW)) {
  243.                 totmbrs++;
  244.                 totsize += one_head->org_size;
  245.                 totlen += one_head->size_now;
  246.                 switch(one_head->packing_method) {
  247.                     case 0:
  248.                                 strcpy(method,"  Stored  ");
  249.                                 break;
  250.                     case 1:
  251.                                 strcpy(method," Norm LZW ");
  252.                                 break;
  253.                     default:
  254.                                 strcpy(method,"  Unknown ");
  255.                                 break;
  256.                     }
  257.                 sprintf(date,"%02d-%02d-%02d",
  258.                     ((one_head->date >> MONTH_SHIFT) & MONTH_MASK),
  259.                         (one_head->date & DAY_MASK),
  260.                             ((one_head->date >> YEAR_SHIFT) + DOS_EPOCH));
  261.  
  262.                 sprintf(time,"%02d:%02d:%02d",
  263.                     ((one_head->time >> HOUR_SHIFT) & HOUR_MASK),
  264.                     ((one_head->time >> MINUTE_SHIFT) & MINUTE_MASK),
  265.                         (one_head->time & HOUR_MASK)*2);
  266.                 one_line(one_head->fname,one_head->org_size,one_head->size_now,
  267.                     method,date,time);
  268.                 }
  269.             strcpy(member[mem_used].name,one_head->fname);
  270.             member[mem_used].size = ((unsigned int) (one_head->org_size/1024L));
  271.             if (mem_used < MAX_NAMES)
  272.                 mem_used++;
  273.             fseek(fhandle,one_head->next,SEEK_SET);
  274.             }
  275.         result = fread(one_head,sizeof(struct direntry),1,fhandle);
  276.         if (!(ctrl_err))
  277.             result = 0;
  278.         } while ((one_head->offset != 0L) &&
  279.             (result == 1));
  280.     free(one_head);
  281.     free(main_head);
  282.     if (mem_used > 0)
  283.         mem_used--;
  284.     result = fclose(fhandle);
  285.     if (!(flags & VIEW)) {
  286.         if (totlen>0)
  287.             totsf=(int)(100L - ((100L*totlen)/totsize));
  288.         else
  289.             totsf = 0;
  290.         do_totals(totmbrs,totlen,totsize,totsf);
  291.         }
  292.     return(0);
  293. }
  294.  
  295. /*--------------------------------------------------------------------------*/
  296. /* Read a DWC archive. These are the hardest ones to get into.              */
  297. /*--------------------------------------------------------------------------*/
  298.  
  299. int read_dwc(char *name)
  300. {
  301.     long    size;
  302.     int        infile;
  303.     unsigned    int        result;
  304.     struct    dwc_entry    *one_entry;
  305.     struct    dwc_arc    *one_archive;
  306.     struct  tm *t;
  307.     char    junkbuffer[256];
  308.     char    *dwc;
  309.     unsigned int    junkoffset;
  310.     int        count;  /* total number of files in this archive */
  311.     long    totsize = 0L;
  312.     long    totlen = 0L;
  313.     int     totmbrs = 0;
  314.     int     totsf;
  315.     char    date[9];
  316.     char    time[9];
  317.     char    method[11];
  318.  
  319.     if((infile = open(name,O_BINARY|O_RDONLY)) < 0) {
  320.         sprintf(junkbuffer,"Couldn't open file %s\n",name);
  321.         sdisplay(junkbuffer);
  322.         return(-1);
  323.         }
  324.     one_entry = (struct dwc_entry *) malloc(sizeof(struct dwc_entry));
  325.     one_archive = (struct dwc_arc *) malloc(sizeof(struct dwc_arc));
  326.     count = 0;
  327.     mem_used = 0;
  328.     do {
  329.         totlen = (long) (++count * sizeof(junkbuffer));
  330.         size = lseek(infile,-totlen,SEEK_END);
  331.         if (size > 0L)
  332.             result = read(infile,junkbuffer,sizeof(junkbuffer));
  333.         else result = 0;
  334.         } while ((count < 20) && (result == sizeof(junkbuffer)) &&
  335.             ((dwc = memrstr(junkbuffer,"DWC",result)) == NULL));
  336.  
  337.     if ((result < sizeof(junkbuffer)) ||
  338.         (count > 19)) { /* Failed to find "DWC", not DWC file */
  339.         close (infile);
  340.         free(one_archive);
  341.         free(one_entry);
  342.         return(-1);
  343.         }
  344.     junkoffset = count * sizeof(junkbuffer)  /* start of this buffer block */
  345.         - (dwc-junkbuffer)  /* minus the offset to the "DWC" in the buffer */
  346.         + sizeof(struct dwc_arc) - 3;
  347.     size = lseek (infile,-(long)junkoffset,SEEK_END);
  348.     result = read(infile,(void *) one_archive,sizeof(struct dwc_arc));
  349.     if (one_archive->size != sizeof(struct dwc_arc)) {
  350.         close(infile);
  351.         free(one_archive);
  352.         free(one_entry);
  353.         return(-1);
  354.         }
  355.     flags |= DWC;
  356.     if (!(flags & VIEW))
  357.         arc_header("DWC",name);
  358.     count = (int) one_archive->entries;
  359.     totmbrs = count;
  360.     totlen = 0L;
  361.     size = lseek(infile,-(long)(count*one_archive->ent_sz+junkoffset),SEEK_END);
  362.     while (count>0) {
  363.         result = read(infile,(void *) one_entry,sizeof(struct dwc_entry));
  364.         totsize += one_entry->size;
  365.         totlen += one_entry->new_size;
  366.         switch(one_entry->method) {
  367.             case 0:
  368.                         strcpy(method,"  Stored  ");
  369.                         break;
  370.             case 1:
  371.                         strcpy(method," Norm LZW ");
  372.                         break;
  373.             default:
  374.                         strcpy(method,"  Unknown ");
  375.                         break;
  376.             }
  377.         totsf = 0;
  378.         t = localtime(&one_entry->time);
  379.         sprintf(time,"%02d-%02d-%02d",
  380.             (t->tm_mon+1),t->tm_mday,t->tm_year);
  381.  
  382.         sprintf(date,"%02d:%02d:%02d",
  383.             t->tm_hour,t->tm_min,t->tm_sec);
  384.  
  385.         strcpy(member[mem_used].name,one_entry->name);
  386.         member[mem_used].size = ((unsigned int) (one_entry->size/1024L));
  387.         if (!(flags & VIEW))
  388.             one_line(one_entry->name,one_entry->size,one_entry->new_size,
  389.                 method,time,date);
  390.         count--;
  391.         if (!(ctrl_err))
  392.             count = 0;
  393.         if (mem_used < MAX_NAMES)
  394.             mem_used++;
  395.         };
  396.     close (infile);
  397.     free(one_archive);
  398.     free(one_entry);
  399.     if (mem_used > 0)
  400.         mem_used--;
  401.     if (!(flags & VIEW)) {
  402.         if (totlen>0)
  403.             totsf=(int)(100L - ((100L*totlen)/totsize));
  404.         else
  405.             totsf = 0;
  406.         do_totals(totmbrs,totlen,totsize,totsf);
  407.         }
  408.     return(0);
  409. }
  410.  
  411. /*--------------------------------------------------------------------------*/
  412. /* memrstr searches backwards through a chunk of memory called "buffer"     */
  413. /* that is "buflen" long, looking for a string "target". The search is from */
  414. /* the end of "buffer" forward. It returns a pointer to the start of the    */
  415. /* target string                                                            */
  416. /*--------------------------------------------------------------------------*/
  417.  
  418. char *memrstr(char *buffer,char *target,int buflen)
  419. {
  420.  
  421.     char    c = ' ';
  422.     char    *ptr;
  423.     int        found = 1;
  424.  
  425.     c = target[strlen(target)-1];
  426.     ptr = buffer+buflen;
  427.     do {
  428.         if (c != *ptr)
  429.             ptr--;
  430.         else {
  431.             ptr -= strlen(target)-1;
  432.             found = strnicmp(target,ptr,sizeof(target));
  433.             if (found != 0)
  434.                 ptr += strlen(target) - 2;
  435.             }
  436.         if (ptr < buffer)
  437.             ptr = NULL;
  438.         } while (found !=0 && ptr != NULL);
  439.     return(ptr);
  440. }
  441.  
  442. /*--------------------------------------------------------------------------*/
  443. /* Do ZIP Archives                                                          */
  444. /*--------------------------------------------------------------------------*/
  445.  
  446. do_zip(char *name)
  447. {
  448.     struct  ID_Hdr          *ID;
  449.     struct  Local_Hdr       *local;
  450.     char    *mbrname;
  451.     long    totsize = 0L;
  452.     long    totlen = 0L;
  453.     int     totmbrs = 0;
  454.     int     totsf;
  455.     char    date[9];
  456.     char    time[9];
  457.     char    method[11];
  458.     int     handle;
  459.     int        check;
  460.  
  461.     ID = (struct ID_Hdr *) malloc(sizeof(struct ID_Hdr));
  462.     local = (struct Local_Hdr *) malloc(sizeof(struct Local_Hdr));
  463.     mbrname = (char *) malloc(80);
  464.  
  465.     if (!(flags & VIEW))
  466.         arc_header("ZIP",name);
  467.     mem_used = 0;
  468.     handle = open(name,O_BINARY|O_RDONLY);
  469.     do {
  470.         check = read(handle,(void *)ID,sizeof(struct ID_Hdr));
  471.         if (ID->Head_Type == LOCAL_HEADER) {
  472.             if ((check = read(handle,(void *)local,sizeof(struct Local_Hdr))) != -1) {
  473.                 if (!(flags & VIEW)) {
  474.                     sprintf(date,"%02d-%02d-%02d",
  475.                         ((local->mod_date >> MONTH_SHIFT) & MONTH_MASK),
  476.                             (local->mod_date & DAY_MASK),
  477.                                 ((local->mod_date >> YEAR_SHIFT) + DOS_EPOCH));
  478.  
  479.                     sprintf(time,"%02d:%02d:%02d",
  480.                         ((local->mod_time >> HOUR_SHIFT) & HOUR_MASK),
  481.                         ((local->mod_time >> MINUTE_SHIFT) & MINUTE_MASK),
  482.                             (local->mod_time & HOUR_MASK)*2);
  483.  
  484.                     switch(local->compression) {
  485.                         case 0: strcpy(method,"  Stored  ");    break;
  486.                         case 1: strcpy(method,"  Shrunk  ");    break;
  487.                         case 2: strcpy(method," Reduce(1)");    break;
  488.                         case 3: strcpy(method," Reduce(2)");    break;
  489.                         case 4: strcpy(method," Reduce(3)");    break;
  490.                         case 5: strcpy(method," Reduce(4)");    break;
  491.                         }
  492.                     totsize += local->size_now;
  493.                     totlen += local->real_size;
  494.                     totmbrs++;
  495.                     }
  496.                 memset(mbrname,EOS,80);
  497.                 check = read(handle,mbrname,local->name_length);
  498.                 strcpy(member[mem_used].name,mbrname);
  499.                 member[mem_used].size = ((unsigned int) (local->real_size/1024L));
  500.                 if (!(flags & VIEW))
  501.                     one_line(mbrname,local->real_size,local->size_now,method,date,time);
  502.                 lseek(handle,local->size_now,SEEK_CUR);
  503.                 if (!(ctrl_err))
  504.                     check = 0;
  505.                 if (mem_used < MAX_NAMES)
  506.                     mem_used++;
  507.                 }        /* End of one entry */
  508.             }        /* End of grabbing local directory entries */
  509.         else
  510.             check = -1;
  511.         } while(check >0 && !eof(handle));        /* End of file */
  512.     if (mem_used > 0) {
  513.         mem_used--;
  514.         check = 0;
  515.         }
  516.     if (!(flags & VIEW)) {
  517.         if (totsize>0)
  518.             totsf=(int)(100L - ((100L*totsize)/totlen));
  519.         else
  520.             totsf = 0;
  521.         do_totals(totmbrs,totlen,totsize,totsf);
  522.         }
  523.     close(handle);
  524.     free(local);
  525.     free(mbrname);
  526.     free(ID);
  527.     return(check);
  528. }
  529.  
  530. /*--------------------------------------------------------------------------*/
  531. /* Do LZH (LHARC) files                                                     */
  532. /*--------------------------------------------------------------------------*/
  533.  
  534. int read_lzh(char *name)
  535. {
  536.     struct  Lharc_Hdr   *local;
  537.     long    totsize = 0L;
  538.     long    totlen = 0L;
  539.     int     totmbr = 0;
  540.     int     totsf;
  541.     char    date[9];
  542.     char    time[9];
  543.     char    method[11];
  544.     char    *mbrname;
  545.     int     handle;
  546.     int        check;
  547.  
  548.     local = (struct Lharc_Hdr *) malloc(sizeof(struct Lharc_Hdr));
  549.     mbrname = (char *) malloc(80);
  550.     mem_used = 0;
  551.  
  552.     handle = open(name,O_BINARY|O_RDONLY);
  553.  
  554.     if ((check = read(handle,(void *)local,sizeof(struct Lharc_Hdr))) ==
  555.         sizeof(struct Lharc_Hdr)) {
  556.             if (!((strncmp(local->type,"-lh",3) == 0) &&
  557.                 (local->type[4] == '-'))) {
  558.                 close(handle);
  559.                 free(local);
  560.                 free(mbrname);
  561.                 return(-1);
  562.                 }
  563.             }
  564.     else {
  565.         close(handle);
  566.         free(local);
  567.         free(mbrname);
  568.         return(-1);
  569.         }
  570.     flags |= LZH;
  571.     if (!(flags & VIEW))
  572.         arc_header("LHARC",name);
  573.  
  574.     do {
  575.         if (!(flags & VIEW)) {
  576.             sprintf(date,"%02d-%02d-%02d",
  577.                 ((local->date >> MONTH_SHIFT) & MONTH_MASK),
  578.                     (local->date & DAY_MASK),
  579.                         ((local->date >> YEAR_SHIFT) + DOS_EPOCH));
  580.  
  581.             sprintf(time,"%02d:%02d:%02d",
  582.                 ((local->time >> HOUR_SHIFT) & HOUR_MASK),
  583.                 ((local->time >> MINUTE_SHIFT) & MINUTE_MASK),
  584.                     (local->time & HOUR_MASK)*2);
  585.             strcpy(method,"  ");
  586.             strcat(method,local->type);
  587.             method[7] = EOS;
  588.             strcat(method,"  ");
  589.             totsize += local->size_now;
  590.             totlen += local->orig_size;
  591.             totmbr++;
  592.             }        /* End of listing stuff */
  593.         memset(mbrname,EOS,80);
  594.         check = read(handle,mbrname,local->name_len);
  595.         strcpy(member[mem_used].name,mbrname);
  596.         member[mem_used].size = ((unsigned int) (local->orig_size/1024L));
  597.  
  598.         if (!(flags & VIEW))
  599.             one_line(mbrname,local->orig_size,local->size_now,method,date,time);
  600.         lseek(handle,local->size_now + 2L,SEEK_CUR);
  601.         check = read(handle,(void *)local,sizeof(struct Lharc_Hdr));
  602.         if (!(ctrl_err))
  603.             check = 0;
  604.         if (mem_used < MAX_NAMES)
  605.             mem_used++;
  606.         } while(check >1 && !eof(handle));        /* End of file */
  607.  
  608.     close(handle);
  609.     free(local);
  610.     free(mbrname);
  611.     if (mem_used > 0) {
  612.         mem_used--;
  613.         check = 0;
  614.         }
  615.  
  616.     if (!(flags & VIEW)) {
  617.         if (totsize>0)
  618.             totsf=(int)(100L - ((100L*totsize)/totlen));
  619.         else
  620.             totsf = 0;
  621.         printf("----\t\t------\t\t   ------  -----\n");
  622.         printf("Total %6d  %8ld  ",totmbr,totlen);
  623.         printf("\t %8ld   %3d%%\n",totsize,totsf);
  624.         }
  625.     return(check);
  626. }
  627.  
  628. void unpack(int input_handle,int output_handle,long size)
  629. {
  630.     char        *buf;
  631.     unsigned    done;
  632.     unsigned    do_what = 8096;
  633.  
  634.     if (size < (long)8096) {
  635.         do_what = (unsigned) size;
  636.         buf = (char *) malloc(do_what);
  637.         read(input_handle,buf,do_what);
  638.         write(output_handle,buf,do_what);
  639.         free(buf);
  640.         }
  641.     else {
  642.         buf = (char *) malloc(do_what);
  643.         while (size > 0L) {
  644.             done = read(input_handle,buf,do_what);
  645.             write(output_handle,buf,do_what);
  646.             size -= (long) done;
  647.             if (size < do_what)
  648.                 do_what = (unsigned) size;
  649.             }
  650.         free(buf);
  651.         }
  652.     return;
  653. }
  654.  
  655.