home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 June / Vpr9806a.iso / OLS / Windows / TAR32031 / tar32031.exe / SRC / SRC / ARCHIO.C next >
C/C++ Source or Header  |  1998-01-15  |  18KB  |  863 lines

  1. #ifndef __DEFCONF_H
  2. #include "defconf.h"
  3. #endif
  4. /*
  5.    This file was hacked for kmtar for WIN32
  6.                                     at 1996-05-06.
  7.                                     by tantan SGL00213@niftyserve.or.jp 
  8. */
  9. /*
  10.  *    archio - archive I/O functions
  11.  *
  12.  *    Written by Koichiro Mori (kmori)
  13.  */
  14.  
  15. #ifdef RCSID
  16. static char rcsid[] = "$Header: RCS/archio.c 2.9 91/02/19 14:27:33 kmori Exp $";
  17. #endif
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #include <errno.h>
  24. #include <fcntl.h>
  25. #include <time.h>
  26. #include <dos.h>
  27. #ifdef WIN32
  28.     #include <sys/types.h>
  29.     #include <io.h>
  30. #endif
  31. #include <sys/stat.h>
  32. #include "defs.h"
  33.  
  34. #include "tar.h"
  35. #include "main.h"
  36. #include "misc.h"
  37. #include "archio.h"
  38. #include "tapeio.h"
  39. #include "tardir.h"
  40. #if defined(GZIP)
  41. #include "gzip.h"
  42. #endif
  43. #ifdef DLL
  44. #include <wtypes.h>
  45. #include "tar32.h"
  46. #endif
  47. global int Nblocks;
  48. global char *Current_file_name;    /* Name of current file */
  49. global long Current_file_size;    /* Size of current file */
  50. global int Current_file_mode;    /* Size of current file */
  51. global time_t Current_file_mtime; /* Modified time of current file */
  52. global long Current_file_left;    /* Left bytes in current file */
  53.  
  54. static int Withlabel;
  55. static time_t Volume_time;    /* Time Stamp */
  56. static int Volno;        /* Tape volume No. */
  57. static int Nthdisk;        /* Nth disk */
  58.  
  59. static char Save_file_name[FNAME_BUF];
  60. static long Save_file_size;
  61. static int Save_file_mode;
  62. static time_t Save_file_mtime;
  63. static long Save_file_left;
  64.  
  65.  
  66. static char Mode;    /* 'r'ead or 'w'rite */
  67. int Afd;        /* Archive file descriptor */
  68. static bool Dev;    /* Archive file is physical device */
  69. static char *Buff=NULL;    /* Archive I/O buffer */
  70. static char *Ptr;    /* Pointer to the next rd/wr data */
  71. static int Buffsize;    /* Size of Buff */
  72. static int Left;    /* Left bytes in Buff */
  73. static int access_method;    /* Aechive file access method */
  74. extern HWND api_hwnd;
  75.  
  76. #define    BUFFMARGIN    (TBLOCK * 2)
  77.  
  78. void chk_exist(char *file)  /* by tantan */
  79. {
  80.     char buf[20];
  81.     if (access(file,0) != 0)
  82.         return;
  83.     fprintf(stderr,"File [%s] already exist. Do you OVER WRITE ? (y/n) ",file);
  84.     gets(buf);
  85.     strlwr(buf);
  86.     if (buf[0] != 'y')
  87.         exit(1);
  88. }
  89.  
  90. /*
  91.  * Open device/file
  92.  */
  93. int open_dev(char *file, char mode)
  94. {
  95.     extern bool Veflag;
  96.     extern char cao_flag;
  97.  
  98.     Dev = NO;
  99.     if (*file == ':' || strmatch(file, "/dev/rfd")) {
  100.         Dev = YES;
  101.         return (open_tape(file, mode));
  102.     } else if (strcmp(file, "-") == 0) {
  103.         /* set stdio  to binary mode */
  104.         switch (mode) {
  105.         case 'r':
  106.             setmode(fileno(stdin),O_BINARY);
  107.             return (fileno(stdin));
  108.         case 'w':
  109.             setmode(fileno(stdout),O_BINARY);
  110.             return (fileno(stdout));
  111.         case 'a':
  112.             errno = EINVAL;
  113.             return (-1);
  114.         }
  115.     } else {
  116.         switch (mode) {
  117.         case 'r':
  118.             return (open(file, O_RDONLY|O_BINARY));
  119.         case 'w':
  120.             if (Pflag){
  121.                 return 1;/* stdout file descriptor */
  122.             }else{
  123.                 if (cao_flag)
  124.                     chk_exist(file);
  125.                 if (Veflag){
  126.                    printf("[-- Write verify switch ON --]\n");
  127.                    return (open(file,O_RDWR | O_CREAT | O_TRUNC | O_BINARY, ~0));
  128.                 }else
  129.                    return (creat(file, ~0));
  130.             }
  131.         case 'a':
  132.             if (cao_flag)
  133.                 chk_exist(file);
  134.             return (open(file, O_RDWR | O_CREAT | O_BINARY, ~0));
  135.         }
  136.     }
  137. }
  138.  
  139.  
  140.  
  141. /*
  142.  * Request next volume
  143.  */
  144. void request_volume(int vol, int n, bool go)
  145. {
  146.     int m;
  147.  
  148.     if (Dev)
  149.         close_tape();
  150.     else {
  151.         if (Afd == 0 || Afd == 1) /* `tar cf -' or `tar xf -' */
  152.             fatal(NULL, "Missing end mark");
  153.         close(Afd);
  154.     }
  155.     for (m = 0; Archives[m]; m++)
  156.         ;
  157.     if (go && m > 1) {
  158.         if (Vflag)
  159.             fprintf(stderr, "\aVolume %d in %s\n",
  160.                     vol, Archives[n % m]);
  161.         goto noask;
  162.     }
  163.     for (;;) {
  164.         for (;;) {
  165.             char message[1000];
  166.  
  167.             sprintf(message,
  168.                 "Insert volume %d in %s and hit return: ",
  169.                 vol, Archives[n % m]);
  170.  
  171. #ifdef DLL
  172.             {
  173.                 int r;
  174.                 extern HWND api_hwnd;
  175.  
  176.                 r=MessageBox(api_hwnd,message,"TAR32.DLL",MB_OKCANCEL);
  177.                 switch(r){
  178.                 case IDOK:
  179.                     goto noask;
  180.                     break;
  181.                 case IDCANCEL:
  182.                     Exitcode=ERROR_USER_CANCEL;
  183.                     fatal("request_volume","user cancel");
  184.                     break;
  185.                 }
  186.             
  187.             }
  188. #else
  189.             {
  190.                 int s;
  191.                 char line[80];
  192.                 fputs(message,stderr);
  193.                 /*fprintf(stderr,
  194.                     "Insert volume %d in %s and hit return: ",
  195.                     vol, Archives[n % m]);*/
  196.                 s = read(0, line, sizeof line);
  197.                 line[s] = '\0';
  198.                 switch (line[0]) {
  199.                 case '!':
  200.                     system(line + 1);
  201.                     break;
  202.                 case 'q':
  203.                     error(NULL, "aborted");
  204.                     exit(1);
  205.                 case '\0':
  206.                 case '\r':
  207.                 case '\n':
  208.                     goto noask;
  209.                 }
  210.             }
  211. #endif
  212.         }
  213.  
  214. noask:
  215.         Afd = open_dev(Archives[n % m], Mode);
  216.         if (Afd >= 0)
  217.             return;
  218.         error(Archives[n % m], NULL);
  219.     }
  220. }
  221.  
  222.  
  223.  
  224. void set_vol(char *p)
  225. {
  226.     struct stat statbuf;
  227.     char name[80];
  228.  
  229.     memset(p, 0, TBLOCK);
  230.     memset(&statbuf, 0, sizeof statbuf);
  231.     statbuf.st_mtime = Volume_time;
  232.     sprintf(name, "tar Volume %d", Volno);
  233.     encode_dir((HEADER *)p, name, &statbuf, VOLTYPE);
  234. }
  235.  
  236.  
  237.  
  238. int get_volno(char *name)
  239. {
  240.     char *s;
  241.  
  242.     s = strstr(name, "Volume");
  243.     if (s == NULL)
  244.         return (-1);
  245.     s += 7;
  246.     return (atoi(s));
  247. }
  248.  
  249.  
  250.  
  251. global void check_vol(char *name, struct stat *p)
  252. {
  253.     int n;
  254.  
  255.     if ((n = get_volno(name)) < 0) {
  256.         error(name, "Bad volume ID");
  257.         return;
  258.     }
  259.     Volno = n;
  260.     Volume_time = p->st_mtime;
  261.     Withlabel = 1;
  262. }
  263.  
  264.  
  265.  
  266. /*
  267.  * Read over multiple volume
  268.  */
  269. global int fill_buff(void)
  270. {
  271.     int n, volno;
  272.     char name[FNAME_BUF];
  273.     struct stat fs;
  274.     bool go;
  275.     extern bool divi_flag,compress_flag,divi_eof_flag;
  276.     extern int read_zZ(int fd,char *Buff,int Buffsize);
  277.  
  278.     Ptr = Buff;
  279.     if (Dev)
  280.         n = read_tape(Buff, Buffsize);
  281.     else
  282.         n = read_zZ(Afd, Buff, Buffsize);
  283.  
  284.     if (n > 0 /* || !Mflag */)
  285.         return (n);
  286. #if    (Miner_V >= 2)
  287.     if (wild_flag)
  288.         fatal(NULL,"Multi volume not allowed");
  289. #endif
  290.     Volno++;
  291.     Nthdisk++;
  292.     go = Yflag;
  293. again:
  294. #if 0
  295. #ifdef DLL
  296.     if(Dev==NO){
  297.         Exitcode=ERROR_CANNOT_READ;
  298.         fatal("fill_buff","can't read at reading archive");
  299.     }
  300. #endif
  301. #endif
  302.     request_volume(Volno, Nthdisk, go);
  303.     go = NO;
  304.     if (Dev)
  305.         n = read_tape(Buff, Buffsize);
  306.     else
  307.         n = read_zZ(Afd, Buff, Buffsize);
  308.     if (n <= 0){
  309.         Exitcode=ERROR_CANNOT_READ;
  310.         fatal(NULL, "can't read");
  311.     }
  312.     Ptr = Buff;
  313.     if (Withlabel) {
  314.         if (decode_dir_e(name, &fs, (HEADER *)Buff) != VOLTYPE) {
  315.             fprintf(stderr, "No volume header\n");
  316.             goto again;
  317.         }
  318. #if 0
  319.         if (fs.st_mtime != Volume_time) {
  320.             fprintf(stderr, "Volume timestamp doesn't match\n");
  321.             goto again;
  322.         }
  323. #endif
  324.         volno = get_volno(name);
  325.         if (volno != Volno) {
  326.             fprintf(stderr, "Expecting #%d, but #%d\n", Volno, volno);
  327.             goto again;
  328.         }
  329.         Ptr += TBLOCK;
  330.         n -= TBLOCK;
  331.     }
  332.     if (Current_file_left) {
  333.         if (decode_dir_e(name, &fs, (HEADER *)Ptr) != MULTYPE ||
  334.             strcmp(name, Current_file_name) != 0) {
  335.             fprintf(stderr, "%s doesn't continue\n", Current_file_name);
  336.             goto again;
  337.         }
  338.         if (fs.st_size != Current_file_left ||
  339.             fs.st_size + strtol(((HEADER *)Ptr)->dbuf.offset, NULL, 8)
  340.                 != Current_file_size) {
  341.             fprintf(stderr, "%s file size different\n", Current_file_name);
  342.             goto again;
  343.         }
  344.         Ptr += TBLOCK;
  345.         return (n - TBLOCK);
  346.     }
  347.     return (n);
  348. }
  349.  
  350.  
  351.  
  352. /*
  353.  * Read [m-n] bytes from archive and set data address to *ptr
  354.  */
  355. global int read_arch(long n, char **ptr)
  356. {
  357.     if (Left == 0)
  358.         Left = fill_buff();
  359.     if (n < 0 || n > Left)
  360.         n = Left;
  361.     if (ptr)
  362.         *ptr = Ptr;
  363.     Ptr += n;
  364.     Left -= (int)n;
  365.     return ((int)n);
  366. }
  367.  
  368.  
  369.  
  370. /*
  371.  * Move tape head backward and change 'read' mode to 'write' mode
  372.  */
  373. global int start_write_arch(int n)
  374. {
  375.     long rc;
  376.  
  377.     if (Ptr - Buff < n)
  378.         return (-1);
  379.     if (Dev)
  380.         rc = back_tape((int)(Ptr - Buff + Left));
  381.     else
  382.         rc = lseek(Afd, -(long)(Ptr - Buff + Left), 1);
  383.     Left += n;
  384.     Ptr -= n;
  385.     return (rc < 0 ? -1 : 0);
  386. }
  387.  
  388.  
  389.  
  390. /*
  391.  * Write Buff to Ptr
  392.  */
  393. void flush_buff()
  394. {
  395.     int size, n;
  396.     struct stat fs;
  397.     char *p;
  398.     extern int write_z(int Afd,char *Buff,int size);
  399.  
  400.     size = Ptr - Buff;
  401.     if (Dev)
  402.         n = write_tape(Buff, size);
  403.     else
  404.         n = write_z(Afd, Buff, size);
  405.     if (n == size) {
  406.         if (Current_file_name != NULL)
  407.             strcpy(Save_file_name, Current_file_name);
  408.         Save_file_size = Current_file_size;
  409.         Save_file_mode = Current_file_mode;
  410.         Save_file_mtime = Current_file_mtime;
  411.         Save_file_left = Current_file_left;
  412.         Ptr = Buff;
  413.         return;
  414.     }
  415.     if (!Mflag)
  416.         fatal(NULL, "Out of tape (Use -m)");
  417.     Volno++;
  418.     Nthdisk++;
  419. #if 0
  420. #ifdef DLL
  421.     if(Dev==NO){
  422.         Exitcode=ERROR_CANNOT_WRITE;
  423.         fatal("flush_buff","can't write at making archive");
  424.     }
  425. #endif
  426. #endif
  427.     request_volume(Volno, Nthdisk, Yflag);
  428.     p = Buff;
  429.     if (Save_file_left) {
  430.         p -= TBLOCK;
  431.         if (size + TBLOCK <= Buffsize)
  432.             size += TBLOCK;
  433.         fs.st_mode = Save_file_mode;
  434.         fs.st_mtime = Save_file_mtime;
  435.         fs.st_size = Save_file_left;
  436.         memset(p, 0, TBLOCK);
  437.         sprintf(((HEADER *)p)->dbuf.offset, "%11lo ",
  438.                 Save_file_size - Save_file_left);
  439.         encode_dir((HEADER *)p, Save_file_name, &fs, MULTYPE);
  440.     }
  441.     p -= TBLOCK;
  442.     if (size + TBLOCK <= Buffsize)
  443.         size += TBLOCK;
  444.     set_vol(p);
  445.     if (Dev)
  446.         n = write_tape(p, size);
  447.     else
  448.         n = write_z(Afd, p, size);
  449.     if (n != size)
  450.         fatal(NULL, "can't write");
  451.     if (p + size < Ptr) {
  452.         memcpy(Buff, p + size, (unsigned)(Ptr - (p + size)));
  453.         Ptr = Buff + (Ptr - (p + size));
  454.     } else
  455.         Ptr = Buff;
  456. }
  457.  
  458.  
  459.  
  460. /*
  461.  * Return next write-buffer address
  462.  */
  463. global int buff_arch(int n, char **ptr)
  464. {
  465.     long left;
  466.  
  467.     left = Buff + Buffsize - Ptr;
  468.     if (left <= 0) {
  469.         flush_buff();
  470.         left = Buff + Buffsize - Ptr;
  471.     }
  472.     if (n < 0 || n > (int)left)
  473.         n = (int)left;
  474.     if (ptr)
  475.         *ptr = Ptr;
  476.     return (n);
  477. }
  478.  
  479.  
  480.  
  481. /*
  482.  * Write n bytes
  483.  */
  484. global int write_arch(int n)
  485. {
  486.     if (Ptr + n > Buff + Buffsize)
  487.         fatal("write_arch", "Can't happen.");
  488.     Ptr += n;
  489.     return (n);
  490. }
  491.  
  492.  
  493.  
  494. /*
  495.  * Open archive file
  496.  */
  497. global int open_arch(char *mode)
  498. {
  499.     Nthdisk = 0;
  500.     Volno = 1;
  501.     Mode = *mode;
  502.     Afd = open_dev(Archives[0], Mode);
  503.  
  504.     /* for kmtarsef (SFX) by tsuneo... */
  505.     if(Mode=='w' && OPTION_self_extracting){
  506.         char *ptr;
  507.         char fname[1001];
  508.  
  509.         if(SearchPath(NULL,"kmtarsef.exe",NULL,1000,fname,&ptr)!=0){
  510.             FILE *fp;
  511.             char buf[OUTBUFSIZ];
  512.             long n;
  513.  
  514.             if((fp=fopen(fname,"rb"))!=NULL){
  515.                     while((n=fread(buf,1,OUTBUFSIZ,fp))>0){
  516.                         write(Afd,buf,n);
  517.                     }
  518.                     fclose(fp);
  519.                     puts("making self-extracting...");
  520.             }else{
  521.                 char str[1000];
  522.  
  523.                 sprintf(str,"can't open [%s]",fname);
  524.                 MessageBox(api_hwnd,str,"TAR32.DLL",MB_ICONWARNING);
  525.             }
  526.         }else{
  527.             MessageBox(api_hwnd,"can't find kmtarsef.exe.","TAR32.DLL",MB_ICONWARNING);
  528.             close(Afd);Afd<0;
  529.         }
  530.     }
  531.  
  532.     if (Nblocks <= 0)
  533.         Nblocks = 20;
  534.     Buffsize = Nblocks * TBLOCK;
  535.     if (Afd < 0){
  536.         Exitcode=ERROR_NOT_FIND_ARC_FILE;
  537.         fatal(Archives[0], NULL);
  538.     }
  539.     init_read_buf();    /* init */
  540. /*    printf("buff size = %d\n",BUFFMARGIN + Buffsize);*/
  541.     if (Buff == NULL){
  542.         Buff = malloc(BUFFMARGIN + Buffsize);
  543.         if (Buff == NULL){
  544.             Exitcode=ERROR_ENOUGH_MEMORY;
  545.             fatal(NULL, "Out of memory");
  546.         }
  547.         Buff += BUFFMARGIN;
  548.     }
  549.     Ptr = Buff;
  550.     Left = 0;
  551.  
  552.     if (Mflag && Mode == 'w') {
  553.     /* Write volume header */
  554.         char *p;
  555.         Volume_time = time(NULL);
  556.         buff_arch(TBLOCK, &p);
  557.         set_vol(p);
  558.         write_arch(TBLOCK);
  559.     }
  560.     if (!Dev && Mode != 'w') {
  561.     /* check file type */
  562.         access_method = get_method(Afd);
  563.         if (Mode == 'a' && access_method != 100)
  564.             fatal("open_arch","compress file cannot append!");
  565.     }
  566.     return (Afd);
  567. }
  568.  
  569.  
  570. /*
  571.  * Close archive file
  572.  */
  573. global int close_arch(char command)
  574. {
  575.    extern int gzip_flag;
  576.    extern void zip_end(void);
  577.  
  578.     if (Mode != 'r') {
  579.         flush_buff();
  580.         flush_buff();
  581.     }
  582.  
  583. #if    defined(GZIP)
  584.     if (command == 'c' && gzip_flag)
  585.         zip_end();
  586. #endif
  587.     if(Pflag && Afd==1){
  588.         return 0;
  589.     }else{
  590.         return (Dev ? close_tape() : close(Afd));
  591.     }
  592. }
  593.  
  594. global void free_io_buff()
  595. {
  596.     if (Buff > (char *)BUFFMARGIN){
  597.         free(Buff - BUFFMARGIN);
  598.         Buff=NULL;
  599.     }else if(Buff!=NULL){
  600.         fprintf(stderr,"Not satisfy Buff > BUFFMARGIN or Buff==NULL\n");
  601.         exit(1);
  602.     }
  603. }
  604.  
  605. /* for gzip Buffer pointer */
  606. unsigned long innerbuf_len = 0;
  607. char *innerbuf = NULL; /* for unzip */
  608. int inner_file=-1;
  609.  
  610. /* read_zZの内部静的変数 */
  611.     static unsigned long read_zZ_icp; /* innerbuf current read opint */
  612.     static read_zZ_read_counter=0;
  613. /*
  614.  * raed from compressed file
  615.  */
  616. global int read_zZ(int Afd,char *Buff,int Buffsize)
  617. {
  618.     int len=0,ret;
  619.     extern int (*work)(void); /* function to call */
  620.     // static unsigned long icp; /* innerbuf current read opint */
  621.     extern unsigned insize;
  622. #ifdef    DYN_ALLOC
  623.     extern unsigned char *inbuf;
  624. #else
  625.     extern unsigned char inbuf[];
  626. #endif
  627.     // static read_counter=0;
  628.  
  629.     if (access_method == 100){    /* normal file */
  630.         if (insize){
  631.             if ((int)insize >= Buffsize){
  632.                 memcpy(Buff,inbuf+read_zZ_read_counter,Buffsize);
  633.                 insize -=Buffsize;
  634.                 read_zZ_read_counter +=Buffsize;
  635.                 ret = Buffsize;
  636.             }else{
  637.                 int r;
  638.                 memcpy(Buff,inbuf+read_zZ_read_counter,insize);
  639.                 r = read(Afd,Buff+insize,Buffsize-insize);
  640.                 ret = insize + r;
  641.                 insize =0;
  642.             }
  643.             return ret;  /* at v3.6 */
  644.         }else
  645.             return read(Afd,Buff,Buffsize);
  646.     }
  647.     
  648.     while(1){
  649.         if (innerbuf_len == 0){
  650.             if ((ret = (*work)()) != 0) {
  651.                     return  (ret == EOF) ? len : -1;
  652.             }
  653. /*
  654.             printf("archio:innerbuf_len=%u %Fp \n",innerbuf_len &innerbuf_len);
  655. */
  656.             if (innerbuf_len == 0)
  657.                 continue;
  658.             read_zZ_icp = 0;
  659.         }
  660.         if ((int)(innerbuf_len - read_zZ_icp) > Buffsize){
  661.             memcpy(Buff,innerbuf+read_zZ_icp, Buffsize);
  662.             len += Buffsize;
  663.             read_zZ_icp += Buffsize;
  664.             break;
  665.         }else{
  666.             memcpy(Buff,innerbuf+read_zZ_icp, innerbuf_len - read_zZ_icp);
  667.             len += (int)(innerbuf_len - read_zZ_icp);
  668.             Buffsize -= (int)(innerbuf_len - read_zZ_icp);
  669.             Buff += (int)(innerbuf_len - read_zZ_icp);
  670.             innerbuf_len = 0L;
  671.         }
  672.     }
  673.  
  674.     return len;
  675. }
  676.  
  677.  
  678. #if defined(GZIP)
  679.  
  680. int write_z(int fh,char *buf,int bufsize)
  681. {
  682.     extern int gzip_flag;
  683.     extern bool Veflag;
  684.     int len;
  685.     extern int zip_write(int h,char *buf,int size);
  686.  
  687.     if (!gzip_flag){
  688.         len = write(fh,buf,bufsize);
  689.         if (Veflag && len > 0){
  690.             char buffer[OUTBUFSIZ*2];
  691.             
  692.             if (OUTBUFSIZ*2 < bufsize)
  693.                 fatal("write_z","Verify inner error");
  694.             lseek(fh,-len,SEEK_CUR);
  695.             read(fh,buffer,len);
  696.             if (memcmp(buffer,buf,len) )
  697.                 fatal("write","verify error");
  698.         }
  699.         return len;
  700.     }
  701.  
  702.     zip_write(fh,buf,bufsize);
  703.     return bufsize;
  704.  
  705. }
  706. #if P_up_V>=4
  707. /* gzip file */
  708. void gzip_file(char *pack,char *unpack)
  709. {
  710.     FILE *fp_unpk;
  711.     int fh_pk;
  712.     int n;
  713.     char buf[OUTBUFSIZ];
  714.  
  715.     if (Vflag){
  716.         printf("gzip:packfile is [%s] and unpack file is [%s]\n",pack,unpack);
  717.     }
  718.     if((fp_unpk=fopen(unpack,"rb"))==NULL){
  719.         fatal("gzip_file","can't open unpack file");
  720.     }
  721.     if((fh_pk=open_arch("w"))<0){
  722.         fatal("gzip_file","can't open pack file");
  723.     }
  724.     while((n=fread(buf,1,OUTBUFSIZ,fp_unpk))>0){
  725.         write_z(fh_pk,buf,n);
  726.     }
  727.     close_arch('c');
  728.     fclose(fp_unpk);
  729. }
  730. int get_gunzip_fname(char *unpackfn,char *packfn)
  731. {
  732.     int packlen;
  733.  
  734.     packlen=strlen(packfn);
  735.     /*
  736.     if(packlen>=FNAME_BUF){
  737.         return -1;
  738.         fatal("archio.c:get_gunzip_fname","Too Long FileName is Specified");
  739.     }
  740.     */
  741.     strcpy(unpackfn,packfn);
  742.     if(packlen>2 && stricmp(packfn+packlen-2,".z")==0){
  743.         unpackfn[packlen-2]='\0';
  744.     }else if(packlen>3 && stricmp(packfn+packlen-3,".gz")==0){
  745.         unpackfn[packlen-3]='\0';
  746.     }else if(packlen>4 && stricmp(packfn+packlen-4,".tgz")==0){
  747.         strcpy(unpackfn+packlen-4,".tar");
  748.     }else if(packlen>4 && stricmp(packfn+packlen-4,".taz")==0){
  749.         strcpy(unpackfn+packlen-4,".tar");
  750.     }else{
  751.         return -1;
  752.         /* fatal("main.c:do_x_com()","Can't found gunziped/compressed file name.");*/
  753.     }
  754.     return 0;
  755. }
  756. /* gunzip or compress -d file */
  757. void gunzip_file(char *pack,char *unpack_tmp)
  758. {
  759.     FILE *fp_unpk;
  760.     int fh_pk;
  761.     int n;
  762.     char buf[OUTBUFSIZ];
  763.     char unpack[FNAME_BUF];
  764.  
  765.     if(unpack_tmp!=NULL){
  766.         if(strlen(unpack_tmp)>=FNAME_BUF){
  767.             Exitcode=ERROR_COMMAND_NAME;
  768.             fatal("gunzip_file","Too Long Filename.");
  769.         }
  770.         strcpy(unpack,unpack_tmp);
  771.     }else{
  772.         if(get_gunzip_fname(unpack,pack)<0){
  773.             Exitcode=ERROR_COMMAND_NAME;
  774.             fatal("guzip_file","Can't find gunzip/compress -d filename.");
  775.         }
  776.     }
  777.     if(Vflag){
  778.         printf("gunzip:packfile is [%s] and unpack file is [%s]\n",pack,unpack);
  779.     }
  780.     if(Pflag){
  781.         fp_unpk=stdout;
  782.     }else{
  783.         if((fp_unpk=fopen(unpack,"wb"))==NULL){
  784.             fatal("gzip_file","can't open pack file");
  785.         }
  786.     }
  787.     if((fh_pk=open_arch("r"))<0){
  788.         fatal("gzip_file","can't open unpack file");
  789.     }
  790.  
  791.     while((n=read_zZ(fh_pk,buf,OUTBUFSIZ))>0){
  792.         fwrite(buf,1,n,fp_unpk);
  793.     }
  794.     close_arch('x');
  795.     if(Pflag && fp_unpk==stdout){
  796.         ;
  797.     }else{
  798.         fclose(fp_unpk);
  799.     }
  800. }
  801. int get_access_method(void)
  802. {
  803.     return access_method;
  804. }
  805.  
  806.  
  807. #endif /* P_up_V>=4 */
  808. #endif /* GZIP */
  809. #ifdef DLL
  810. void arch_SetAfd(int fh){
  811.     Afd=fh;
  812. }
  813. int arch_GetAfd(void){
  814.     return Afd;
  815. }
  816. #endif /*DLL*/
  817. #ifdef DLL
  818.  
  819. void arch_static_init(void)
  820. {
  821.     Nblocks=0;
  822.     Current_file_name=NULL;    /* Name of current file */
  823.     Current_file_size=0;    /* Size of current file */
  824.     Current_file_mode=0;    /* Size of current file */
  825.     Current_file_mtime=0; /* Modified time of current file */
  826.     Current_file_left=0;    /* Left bytes in current file */
  827.  
  828.     Withlabel=0;
  829.     Volume_time=0;    /* Time Stamp */
  830.     Volno=0;        /* Tape volume No. */
  831.     Nthdisk=0;        /* Nth disk */
  832.  
  833.     memset(Save_file_name,0,sizeof(char)*FNAME_BUF);
  834.     Save_file_size=0;
  835.     Save_file_mode=0;
  836.     Save_file_mtime=0;
  837.     Save_file_left=0;
  838.  
  839.  
  840.     Mode=0;    /* 'r'ead or 'w'rite */
  841.     Afd=0;        /* Archive file descriptor */
  842.     Dev=0;    /* Archive file is physical device */
  843.     /*Buff=NULL;*/    /* Archive I/O buffer */
  844.     if(Buff!=NULL){
  845.         free_io_buff();
  846.     }
  847.     Ptr=NULL;    /* Pointer to the next rd/wr data */
  848.     Buffsize=0;    /* Size of Buff */
  849.     Left=0;    /* Left bytes in Buff */
  850.     access_method=0;    /* Aechive file access method */
  851.  
  852.     /* for gzip Buffer pointer */
  853.     innerbuf_len = 0;
  854.     innerbuf = NULL; /* for unzip */
  855.     inner_file=-1;
  856.  
  857. /* read_zZの内部静的変数 */
  858.     read_zZ_icp=0; /* innerbuf current read opint */
  859.     read_zZ_read_counter=0;
  860.  
  861. }
  862.  
  863. #endif /* DLL (in arch_static_init)*/