home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2001 January / VPR0101A.BIN / OLS / TAR32053 / tar32053.exe / SRC / ARCHIO.C next >
C/C++ Source or Header  |  1999-05-23  |  25KB  |  1,096 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. #include "bz2dll.h"
  48.  
  49. #ifdef USE_BZ2LIB
  50. #include "bzlib.h"
  51. #endif
  52.  
  53. #ifdef USE_ZLIB
  54. #include "zlib.h"
  55. #endif
  56.  
  57. global int Nblocks;
  58. global char *Current_file_name;    /* Name of current file */
  59. global long Current_file_size;    /* Size of current file */
  60. global int Current_file_mode;    /* Size of current file */
  61. global time_t Current_file_mtime; /* Modified time of current file */
  62. global long Current_file_left;    /* Left bytes in current file */
  63.  
  64. static int Withlabel;
  65. static time_t Volume_time;    /* Time Stamp */
  66. static int Volno;        /* Tape volume No. */
  67. static int Nthdisk;        /* Nth disk */
  68.  
  69. static char Save_file_name[FNAME_BUF];
  70. static long Save_file_size;
  71. static int Save_file_mode;
  72. static time_t Save_file_mtime;
  73. static long Save_file_left;
  74.  
  75.  
  76. static char Mode;    /* 'r'ead or 'w'rite */
  77. int Afd;        /* Archive file descriptor */
  78. static bool Dev;    /* Archive file is physical device */
  79. static char *Buff=NULL;    /* Archive I/O buffer */
  80. static char *Ptr;    /* Pointer to the next rd/wr data */
  81. static int Buffsize;    /* Size of Buff */
  82. static int Left;    /* Left bytes in Buff */
  83. static int access_method;    /* Aechive file access method */
  84. extern HWND api_hwnd;
  85.  
  86. #define    BUFFMARGIN    (TBLOCK * 2)
  87.  
  88. void chk_exist(char *file)  /* by tantan */
  89. {
  90.     char buf[20];
  91.     if (access(file,0) != 0)
  92.         return;
  93.     fprintf(stderr,"File [%s] already exist. Do you OVER WRITE ? (y/n) ",file);
  94.     gets(buf);
  95.     strlwr(buf);
  96.     if (buf[0] != 'y')
  97.         exit(1);
  98. }
  99.  
  100. /*
  101.  * Open device/file
  102.  */
  103. int open_dev(char *file, char mode)
  104. {
  105.     extern bool Veflag;
  106.     extern char cao_flag;
  107.  
  108.     Dev = NO;
  109.     if (*file == ':' || strmatch(file, "/dev/rfd")) {
  110.         Dev = YES;
  111.         return (open_tape(file, mode));
  112.     } else if (strcmp(file, "-") == 0) {
  113.         /* set stdio  to binary mode */
  114.         switch (mode) {
  115.         case 'r':
  116.             setmode(fileno(stdin),O_BINARY);
  117.             return (fileno(stdin));
  118.         case 'w':
  119.             setmode(fileno(stdout),O_BINARY);
  120.             return (fileno(stdout));
  121.         case 'a':
  122.             errno = EINVAL;
  123.             return (-1);
  124.         }
  125.     } else {
  126.         switch (mode) {
  127.         case 'r':
  128.                 return (open(file, O_RDONLY|O_BINARY));
  129.         case 'w':
  130.             if (Pflag){
  131.                 return 1;/* stdout file descriptor */
  132.             }else{
  133.                 if (cao_flag)
  134.                     chk_exist(file);
  135.                 if (Veflag){
  136.                    printf("[-- Write verify switch ON --]\n");
  137.                     return (open(file,O_RDWR | O_CREAT | O_TRUNC | O_BINARY, ~0));
  138.                 }else
  139.                    return (creat(file, ~0));
  140.             }
  141.         case 'a':
  142.             if (cao_flag)
  143.                 chk_exist(file);
  144.             return (open(file, O_RDWR | O_CREAT | O_BINARY, ~0));
  145.         }
  146.     }
  147. }
  148.  
  149.  
  150.  
  151. /*
  152.  * Request next volume
  153.  */
  154. void request_volume(int vol, int n, bool go)
  155. {
  156.     int m;
  157.  
  158.     if (Dev)
  159.         close_tape();
  160.     else {
  161.         if (Afd == 0 || Afd == 1) /* `tar cf -' or `tar xf -' */
  162.             fatal(NULL, "Missing end mark");
  163.         close(Afd);
  164.     }
  165.     for (m = 0; Archives[m]; m++)
  166.         ;
  167.     if (go && m > 1) {
  168.         if (Vflag)
  169.             fprintf(stderr, "\aVolume %d in %s\n",
  170.                     vol, Archives[n % m]);
  171.         goto noask;
  172.     }
  173.     for (;;) {
  174.         for (;;) {
  175.             char message[1000];
  176.  
  177.             sprintf(message,
  178.                 "This file is broken or MultiVolume file. Insert volume %d in %s and hit return: ",
  179.                 vol, Archives[n % m]);
  180.  
  181. #ifdef DLL
  182.             {
  183.                 int r;
  184.                 extern HWND api_hwnd;
  185.  
  186.                 r=MessageBox(api_hwnd,message,"TAR32.DLL",MB_OKCANCEL);
  187.                 switch(r){
  188.                 case IDOK:
  189.                     goto noask;
  190.                     break;
  191.                 case IDCANCEL:
  192.                     Exitcode=ERROR_USER_CANCEL;
  193.                     fatal("request_volume","user cancel");
  194.                     break;
  195.                 }
  196.             
  197.             }
  198. #else
  199.             {
  200.                 int s;
  201.                 char line[80];
  202.                 fputs(message,stderr);
  203.                 /*fprintf(stderr,
  204.                     "Insert volume %d in %s and hit return: ",
  205.                     vol, Archives[n % m]);*/
  206.                 s = read(0, line, sizeof line);
  207.                 line[s] = '\0';
  208.                 switch (line[0]) {
  209.                 case '!':
  210.                     system(line + 1);
  211.                     break;
  212.                 case 'q':
  213.                     error(NULL, "aborted");
  214.                     exit(1);
  215.                 case '\0':
  216.                 case '\r':
  217.                 case '\n':
  218.                     goto noask;
  219.                 }
  220.             }
  221. #endif
  222.         }
  223.  
  224. noask:
  225.         Afd = open_dev(Archives[n % m], Mode);
  226.         if (Afd >= 0)
  227.             return;
  228.         error(Archives[n % m], NULL);
  229.     }
  230. }
  231.  
  232.  
  233.  
  234. void set_vol(char *p)
  235. {
  236.     struct stat statbuf;
  237.     char name[80];
  238.  
  239.     memset(p, 0, TBLOCK);
  240.     memset(&statbuf, 0, sizeof statbuf);
  241.     statbuf.st_mtime = Volume_time;
  242.     sprintf(name, "tar Volume %d", Volno);
  243.     encode_dir((HEADER *)p, name, &statbuf, VOLTYPE);
  244. }
  245.  
  246.  
  247.  
  248. int get_volno(char *name)
  249. {
  250.     char *s;
  251.  
  252.     s = strstr(name, "Volume");
  253.     if (s == NULL)
  254.         return (-1);
  255.     s += 7;
  256.     return (atoi(s));
  257. }
  258.  
  259.  
  260.  
  261. global void check_vol(char *name, struct stat *p)
  262. {
  263.     int n;
  264.  
  265.     if ((n = get_volno(name)) < 0) {
  266.         error(name, "Bad volume ID");
  267.         return;
  268.     }
  269.     Volno = n;
  270.     Volume_time = p->st_mtime;
  271.     Withlabel = 1;
  272. }
  273.  
  274.  
  275.  
  276. /*
  277.  * Read over multiple volume
  278.  */
  279. global int fill_buff(ARCH_FILE *arch_fp)
  280. {
  281.     int n, volno;
  282.     char name[FNAME_BUF];
  283.     struct stat fs;
  284.     bool go;
  285.     extern bool divi_flag,compress_flag,divi_eof_flag;
  286.     // extern int read_zZ(int fd,char *Buff,int Buffsize);
  287.  
  288.     Ptr = Buff;
  289.     if (Dev)
  290.         n = read_tape(Buff, Buffsize);
  291.     else
  292.         n = read_zZ(arch_fp/*Afd*/, Buff, Buffsize);
  293.  
  294.     if (n > 0 /* || !Mflag */)
  295.         return (n);
  296. #if    (Miner_V >= 2)
  297.     if (wild_flag)
  298.         fatal(NULL,"Multi volume not allowed");
  299. #endif
  300.     Volno++;
  301.     Nthdisk++;
  302.     go = Yflag;
  303. again:
  304. #if 0
  305. #ifdef DLL
  306.     if(Dev==NO){
  307.         Exitcode=ERROR_CANNOT_READ;
  308.         fatal("fill_buff","can't read at reading archive");
  309.     }
  310. #endif
  311. #endif
  312.     request_volume(Volno, Nthdisk, go);
  313.     go = NO;
  314.     if (Dev)
  315.         n = read_tape(Buff, Buffsize);
  316.     else
  317.         n = read_zZ(arch_fp/*Afd*/, Buff, Buffsize);
  318.     if (n <= 0){
  319.         Exitcode=ERROR_CANNOT_READ;
  320.         fatal(NULL, "can't read");
  321.     }
  322.     Ptr = Buff;
  323.     if (Withlabel) {
  324.         if (decode_dir_e(name, &fs, (HEADER *)Buff) != VOLTYPE) {
  325.             fprintf(stderr, "No volume header\n");
  326.             goto again;
  327.         }
  328. #if 0
  329.         if (fs.st_mtime != Volume_time) {
  330.             fprintf(stderr, "Volume timestamp doesn't match\n");
  331.             goto again;
  332.         }
  333. #endif
  334.         volno = get_volno(name);
  335.         if (volno != Volno) {
  336.             fprintf(stderr, "Expecting #%d, but #%d\n", Volno, volno);
  337.             goto again;
  338.         }
  339.         Ptr += TBLOCK;
  340.         n -= TBLOCK;
  341.     }
  342.     if (Current_file_left) {
  343.         if (decode_dir_e(name, &fs, (HEADER *)Ptr) != MULTYPE ||
  344.             strcmp(name, Current_file_name) != 0) {
  345.             fprintf(stderr, "%s doesn't continue\n", Current_file_name);
  346.             goto again;
  347.         }
  348.         if (fs.st_size != Current_file_left ||
  349.             fs.st_size + strtol(((HEADER *)Ptr)->dbuf.offset, NULL, 8)
  350.                 != Current_file_size) {
  351.             fprintf(stderr, "%s file size different\n", Current_file_name);
  352.             goto again;
  353.         }
  354.         Ptr += TBLOCK;
  355.         return (n - TBLOCK);
  356.     }
  357.     return (n);
  358. }
  359.  
  360.  
  361.  
  362. /*
  363.  * Read [m-n] bytes from archive and set data address to *ptr
  364.  */
  365. global int read_arch(ARCH_FILE *arch_fp, long n, char **ptr)
  366. {
  367.     if (Left == 0)
  368.         Left = fill_buff(arch_fp);
  369.     if (n < 0 || n > Left)
  370.         n = Left;
  371.     if (ptr)
  372.         *ptr = Ptr;
  373.     Ptr += n;
  374.     Left -= (int)n;
  375.     return ((int)n);
  376. }
  377.  
  378.  
  379.  
  380. /*
  381.  * Move tape head backward and change 'read' mode to 'write' mode
  382.  */
  383. global int start_write_arch(int n)
  384. {
  385.     long rc;
  386.  
  387.     if (Ptr - Buff < n)
  388.         return (-1);
  389.     if (Dev)
  390.         rc = back_tape((int)(Ptr - Buff + Left));
  391.     else
  392.         rc = lseek(Afd, -(long)(Ptr - Buff + Left), 1);
  393.     Left += n;
  394.     Ptr -= n;
  395.     return (rc < 0 ? -1 : 0);
  396. }
  397.  
  398.  
  399.  
  400. /*
  401.  * Write Buff to Ptr
  402.  */
  403. int flush_buff(ARCH_FILE *arch_fp)
  404. {
  405.     int size, n;
  406.     struct stat fs;
  407.     char *p;
  408.     // extern int write_z(int Afd,char *Buff,int size);
  409.  
  410.     size = Ptr - Buff;
  411.     if (Dev)
  412.         n = write_tape(Buff, size);
  413.     else
  414.         n = write_z(arch_fp/*Afd*/, Buff, size);
  415.     if (n == size) {
  416.         if (Current_file_name != NULL)
  417.             strcpy(Save_file_name, Current_file_name);
  418.         Save_file_size = Current_file_size;
  419.         Save_file_mode = Current_file_mode;
  420.         Save_file_mtime = Current_file_mtime;
  421.         Save_file_left = Current_file_left;
  422.         Ptr = Buff;
  423.         return 0;
  424.     }
  425.     if (!Mflag)
  426.         fatal(NULL, "Out of tape (Use -m)");
  427.     Volno++;
  428.     Nthdisk++;
  429. #if 0
  430. #ifdef DLL
  431.     if(Dev==NO){
  432.         Exitcode=ERROR_CANNOT_WRITE;
  433.         fatal("flush_buff","can't write at making archive");
  434.         return -1;
  435.     }
  436. #endif
  437. #endif
  438.     request_volume(Volno, Nthdisk, Yflag);
  439.     p = Buff;
  440.     if (Save_file_left) {
  441.         p -= TBLOCK;
  442.         if (size + TBLOCK <= Buffsize)
  443.             size += TBLOCK;
  444.         fs.st_mode = Save_file_mode;
  445.         fs.st_mtime = Save_file_mtime;
  446.         fs.st_size = Save_file_left;
  447.         memset(p, 0, TBLOCK);
  448.         sprintf(((HEADER *)p)->dbuf.offset, "%11lo ",
  449.                 Save_file_size - Save_file_left);
  450.         encode_dir((HEADER *)p, Save_file_name, &fs, MULTYPE);
  451.     }
  452.     p -= TBLOCK;
  453.     if (size + TBLOCK <= Buffsize)
  454.         size += TBLOCK;
  455.     set_vol(p);
  456.     if (Dev)
  457.         n = write_tape(p, size);
  458.     else
  459.         n = write_z(arch_fp/*Afd*/, p, size);
  460.     if (n != size){
  461.         fatal(NULL, "can't write");
  462.         return -1;
  463.     }
  464.     if (p + size < Ptr) {
  465.         memcpy(Buff, p + size, (unsigned)(Ptr - (p + size)));
  466.         Ptr = Buff + (Ptr - (p + size));
  467.     } else
  468.         Ptr = Buff;
  469.     return 0;
  470. }
  471.  
  472.  
  473.  
  474. /*
  475.  * Return next write-buffer address
  476.  */
  477. global int buff_arch(ARCH_FILE *arch_fp, int n, char **ptr)
  478. {
  479.     long left;
  480.     int ret;
  481.  
  482.     left = Buff + Buffsize - Ptr;
  483.     if (left <= 0) {
  484.         ret = flush_buff(arch_fp);
  485.         if(ret != 0){return -1;}
  486.         left = Buff + Buffsize - Ptr;
  487.     }
  488.     if (n < 0 || n > (int)left)
  489.         n = (int)left;
  490.     if (ptr)
  491.         *ptr = Ptr;
  492.     return (n);
  493. }
  494.  
  495.  
  496.  
  497. /*
  498.  * Write n bytes
  499.  */
  500. global int write_arch(int n)
  501. {
  502.     if (Ptr + n > Buff + Buffsize)
  503.         fatal("write_arch", "Can't happen.");
  504.     Ptr += n;
  505.     return (n);
  506. }
  507.  
  508.  
  509.  
  510. /*
  511.  * Open archive file
  512.  */
  513. global ARCH_FILE *open_arch(char *fname, char *mode)
  514. {
  515.     int writing = 0;
  516.     int appending = 0;
  517.     // int compress_level;
  518.     ARCH_FILE *arch_fp;
  519.     
  520.     extern long sfx_header_length;// used get_method()([gzip.c])
  521.     extern int gzip_flag;
  522.  
  523.     access_method = 0;
  524.     sfx_header_length = 0;
  525.     /* init all variables */
  526.     arch_static_init();        /* archio.c (this file) */
  527.     zip_static_init();        /* zip.c */
  528.     gzip_static_init();        /* gzip.c */
  529.     init_unzip();            /* unzip.c */
  530.     init_comp();            /* compress.c */
  531.     compapi_static_init();    /* compapi.c */
  532.     deflate_static_init();    /* deflate.c */
  533.  
  534.     Nthdisk = 0;
  535.     Volno = 1;
  536.     Mode = *mode;
  537.     // level = LevelFlag;
  538.     Afd = -1;
  539.     Afd = open_dev(fname/*Archives[0]*/, Mode);
  540.     if(Afd < 0){goto error_label;}
  541.  
  542.     while(*mode){
  543.         if(*mode == 'w'){
  544.             writing = 1;
  545.         }else if(*mode == 'r'){
  546.             writing = 0;
  547.         }else if(*mode == 'a'){
  548.             writing = 1;
  549.             appending = 1;
  550.         }else{
  551.             if(isdigit(*mode)){
  552.                 level = 0;
  553.                 while(isdigit(*mode)){
  554.                     level = level*10 + (*mode-'0');
  555.                     mode++;
  556.                 }
  557.                 mode--;
  558.             }
  559.         }
  560.         mode++;
  561.     }
  562.     /* for kmtarsef (SFX) by tsuneo... */
  563.     if(Mode=='w' && OPTION_self_extracting){
  564.         char *ptr;
  565.         char fname[1001];
  566.  
  567.         if(SearchPath(NULL,"kmtarsef.exe",NULL,1000,fname,&ptr)!=0){
  568.             FILE *fp;
  569.             char buf[OUTBUFSIZ];
  570.             long n;
  571.  
  572.             if((fp=fopen(fname,"rb"))!=NULL){
  573.                     while((n=fread(buf,1,OUTBUFSIZ,fp))>0){
  574.                         write(Afd,buf,n);
  575.                     }
  576.                     fclose(fp);
  577.                     puts("making self-extracting...");
  578.             }else{
  579.                 char str[1000];
  580.  
  581.                 sprintf(str,"can't open [%s]",fname);
  582.                 MessageBox(api_hwnd,str,"TAR32.DLL",MB_ICONWARNING);
  583.             }
  584.         }else{
  585.             MessageBox(api_hwnd,"can't find kmtarsef.exe.","TAR32.DLL",MB_ICONWARNING);
  586.             close(Afd);Afd=-1;
  587.         }
  588.     }
  589.  
  590.     if (Nblocks <= 0)
  591.         Nblocks = 20;
  592.     Buffsize = Nblocks * TBLOCK;
  593.     if (Afd < 0){
  594.         Exitcode=ERROR_NOT_FIND_ARC_FILE;
  595.         fatal(Archives[0], NULL);
  596.     }
  597.     init_read_buf();    /* init */
  598. /*    printf("buff size = %d\n",BUFFMARGIN + Buffsize);*/
  599.     if (Buff == NULL){
  600.         Buff = malloc(BUFFMARGIN + Buffsize);
  601.         if (Buff == NULL){
  602.             Exitcode=ERROR_ENOUGH_MEMORY;
  603.             fatal(NULL, "Out of memory");
  604.         }
  605.         Buff += BUFFMARGIN;
  606.     }
  607.     Ptr = Buff;
  608.     Left = 0;
  609.  
  610.     if (!Dev && Mode != 'w') {
  611.     /* check file type */
  612.         gzip_flag = 0;
  613.         BZ2flag = 0;
  614.         access_method = get_method(Afd);
  615.         if (Mode == 'a' && access_method != 100)
  616.             fatal("open_arch","compress file cannot append!");
  617.         if(access_method == BZIP2ED){
  618.             BZ2flag = 1;
  619.         }
  620.         if(access_method == DEFLATED){
  621.             gzip_flag = 1;
  622.         }
  623.     }
  624.  
  625.     if(BZ2flag){
  626.         access_method = BZIP2ED;
  627. #ifdef USE_BZ2LIB
  628.         if(BZ2LIBflag){
  629.             char modestr[100]="\0\0\0\0\0\0\0\0\0\0";
  630.             BZFILE *bzfp;
  631.             if(Mode == 'r'){
  632.                 int ret;
  633.  
  634.                 modestr[0] = 'r';
  635.                 ret = lseek(Afd,sfx_header_length,SEEK_SET);
  636.             }else if(Mode == 'w'){
  637.                 modestr[0] = 'w';
  638.                 itoa(level,modestr+1,10);                
  639.             }else{
  640.                 fatal("open_arch","Can't append with bzip2.(libbz2)");
  641.             }
  642.             bzfp = bzdopen(Afd,modestr);
  643.             if(bzfp==NULL){
  644.                 // close(Afd);
  645.                 goto error_label;
  646.             }
  647.             Afd = (int)bzfp;
  648.         }else
  649. #endif
  650.         {
  651.             if(BZ2DLLLoadLibrary()==-1){
  652.                 fatal("open_arch","Can't load 'bz2lib.dll'. please copy bz2lib.dll to windows-system folder(e.g.'C:\\Windows\\System').");
  653.             }
  654.             if(Mode == 'r'){
  655.                 Afd = (int)BZ2Open(Archives[0],"r");
  656.             }else if(Mode=='w'){
  657.                 char modestr[10];    /* "w6" by default */
  658.                 modestr[0]='w';
  659.                 itoa(level,modestr+1,10);
  660.                 Afd = (int)BZ2Open(Archives[0],modestr);
  661.             }else if(Mode == 'a'){
  662.                 fatal("open_arch","Can't append with bzip2.");
  663.             }
  664.         }
  665.     }
  666.     if(gzip_flag){
  667.         access_method = GZIPED;
  668.     }
  669. #ifdef USE_ZLIB
  670.     if(!Dev && gzip_flag && ZLIBflag){
  671.         char modestr[100]="\0\0\0\0\0\0\0\0\0\0";
  672.         gzFile gzfh;
  673.  
  674.         if(Mode == 'r'){
  675.             int ret;
  676.  
  677.             modestr[0]='r';
  678.             ret = lseek(Afd,sfx_header_length,SEEK_SET);
  679.         }else if(Mode == 'w'){
  680.             modestr[0]='w';
  681.             itoa(level,modestr+1,10);
  682.         }else if(Mode == 'a'){
  683.             fatal("open_arch","Can't append with gzip(zlib).");
  684.         }
  685.         gzfh = gzdopen(Afd,modestr);
  686.         if(gzfh==NULL){
  687.             goto error_label;
  688.             //close(Afd);
  689.         }
  690.         Afd = (int)gzfh;
  691.     }
  692. #endif
  693.  
  694.     /****************************/
  695.     arch_fp = malloc(sizeof(*arch_fp));
  696.     memset(arch_fp,0,sizeof(*arch_fp));
  697.     arch_fp->fd = Afd;
  698.     arch_fp->writing = writing;
  699.     arch_fp->appending = appending;
  700.     arch_fp->level = level;
  701.     arch_fp->method = access_method;
  702.     /****************************/
  703.  
  704.     if (Mflag && Mode == 'w') {
  705.     /* Write volume header */
  706.         char *p;
  707.         Volume_time = time(NULL);
  708.         buff_arch(arch_fp, TBLOCK, &p);
  709.         set_vol(p);
  710.         write_arch(TBLOCK);
  711.     }
  712.  
  713.     return arch_fp;
  714.     // return (Afd);
  715. error_label:
  716.     if(Afd>=0){close(Afd);Afd=-1;}
  717.     if(arch_fp){free(arch_fp);arch_fp=NULL;}
  718.     return NULL;
  719.     //return -1;
  720. }
  721.  
  722.  
  723. /*
  724.  * Close archive file
  725.  */
  726. global int close_arch(ARCH_FILE *arch_fp/* char command */)
  727. {
  728.    extern int gzip_flag;
  729.    extern void zip_end(void);
  730.     int ret=0;
  731.  
  732.     // if (Mode != 'r') {
  733.     if (arch_fp->writing) {
  734.         flush_buff(arch_fp);
  735.         flush_buff(arch_fp);
  736.     }
  737.  
  738. #if    defined(GZIP)
  739. #ifdef USE_ZLIB
  740.     if (!Dev && ZLIBflag && arch_fp->method == GZIPED/* gzip_flag */){
  741.         ret = gzclose(arch_fp->fd/*Afd*/);
  742.         goto endlabel;
  743.     }
  744. #endif
  745. //    if (command == 'c' && gzip_flag)
  746.     if (arch_fp->writing && arch_fp->method == GZIPED)
  747.         zip_end();
  748. #endif
  749.  
  750. #ifdef USE_BZ2LIB
  751.     if(BZ2LIBflag && arch_fp->method == BZIP2ED){
  752.         bzclose((BZFILE *)Afd);
  753.         goto endlabel;
  754.     }
  755. #endif
  756.  
  757.     if(Pflag && arch_fp->fd == 1/*Afd==1*/){
  758.         goto endlabel;
  759.     }else{
  760.         if(!BZ2LIBflag && arch_fp->method == BZIP2ED /* BZ2flag */){
  761.             BZ2Close((BZ2FILE *)arch_fp->fd /*Afd*/);
  762.             BZ2DLLFreeLibrary();
  763.         }else{
  764.             ret = (Dev ? close_tape() : close(Afd));
  765.         }
  766.         Afd=0;
  767.     }
  768. endlabel:
  769.     if(arch_fp){
  770.         free(arch_fp);
  771.         arch_fp = NULL;
  772.     }
  773.     return ret;
  774. }
  775.  
  776. global void free_io_buff()
  777. {
  778.     if (Buff > (char *)BUFFMARGIN){
  779.         free(Buff - BUFFMARGIN);
  780.         Buff=NULL;
  781.     }else if(Buff!=NULL){
  782.         fprintf(stderr,"Not satisfy Buff > BUFFMARGIN or Buff==NULL\n");
  783.         exit(1);
  784.     }
  785. }
  786.  
  787. /* for gzip Buffer pointer */
  788. unsigned long innerbuf_len = 0;
  789. char *innerbuf = NULL; /* for unzip */
  790. int inner_file=-1;
  791.  
  792. /* read_zZの内部静的変数 */
  793.     static unsigned long read_zZ_icp; /* innerbuf current read opint */
  794.     static read_zZ_read_counter=0;
  795. /*
  796.  * raed from compressed file
  797.  */
  798. global int read_zZ(ARCH_FILE *arch_fp/*int Afd*/,char *Buff,int Buffsize)
  799. {
  800.     int len=0,ret;
  801.     extern int (*work)(void); /* function to call */
  802.     // static unsigned long icp; /* innerbuf current read opint */
  803.     extern unsigned insize;
  804. #ifdef    DYN_ALLOC
  805.     extern unsigned char *inbuf;
  806. #else
  807.     extern unsigned char inbuf[];
  808. #endif
  809.     // static read_counter=0;
  810.     extern int gzip_flag;
  811.  
  812.     if (arch_fp->method == NO_COMP/*100*/ /*access_method == 100*/){    /* normal file */
  813.         if (insize){
  814.             if ((int)insize >= Buffsize){
  815.                 memcpy(Buff,inbuf+read_zZ_read_counter,Buffsize);
  816.                 insize -=Buffsize;
  817.                 read_zZ_read_counter +=Buffsize;
  818.                 ret = Buffsize;
  819.             }else{
  820.                 int r;
  821.                 memcpy(Buff,inbuf+read_zZ_read_counter,insize);
  822.                 r = read(arch_fp->fd/*Afd*/,Buff+insize,Buffsize-insize);
  823.                 ret = insize + r;
  824.                 insize =0;
  825.             }
  826.             return ret;  /* at v3.6 */
  827.         }else
  828.             return read(arch_fp->fd/*Afd*/,Buff,Buffsize);
  829. #ifdef USE_ZLIB
  830.     }else if(!Dev && gzip_flag/*access_method == DEFLATED*/ && ZLIBflag){
  831.         return gzread((gzFile)arch_fp->fd/*Afd*/,Buff,Buffsize);
  832. #endif
  833. #ifdef USE_BZ2LIB
  834.     }else if(access_method == BZIP2ED && BZ2LIBflag){    /* BZIP2ED is defined at gzip.h */
  835.         return bzread((BZFILE *)arch_fp->fd/*Afd*/,Buff,Buffsize);
  836. #endif
  837.     }else if(access_method == BZIP2ED){    /* BZIP2ED is defined at gzip.h */
  838.         return BZ2Read((BZ2FILE *)arch_fp->fd/*Afd*/,Buff,Buffsize);
  839.     }
  840.     
  841.     while(1){
  842.         if (innerbuf_len == 0){
  843.             if ((ret = (*work)()) != 0) {
  844.                     return  (ret == EOF) ? len : -1;
  845.             }
  846. /*
  847.             printf("archio:innerbuf_len=%u %Fp \n",innerbuf_len &innerbuf_len);
  848. */
  849.             if (innerbuf_len == 0)
  850.                 continue;
  851.             read_zZ_icp = 0;
  852.         }
  853.         if ((int)(innerbuf_len - read_zZ_icp) > Buffsize){
  854.             memcpy(Buff,innerbuf+read_zZ_icp, Buffsize);
  855.             len += Buffsize;
  856.             read_zZ_icp += Buffsize;
  857.             break;
  858.         }else{
  859.             memcpy(Buff,innerbuf+read_zZ_icp, innerbuf_len - read_zZ_icp);
  860.             len += (int)(innerbuf_len - read_zZ_icp);
  861.             Buffsize -= (int)(innerbuf_len - read_zZ_icp);
  862.             Buff += (int)(innerbuf_len - read_zZ_icp);
  863.             innerbuf_len = 0L;
  864.         }
  865.     }
  866.  
  867.     return len;
  868. }
  869.  
  870.  
  871. #if defined(GZIP)
  872.  
  873. int write_z(ARCH_FILE *arch_fp/*int fh*/,char *buf,int bufsize)
  874. {
  875.     extern int gzip_flag;
  876.     extern bool Veflag;
  877.     int len;
  878.     extern int zip_write(int h,char *buf,int size);
  879.  
  880. #ifdef USE_BZ2LIB
  881.     if(BZ2flag && BZ2LIBflag){
  882.         return bzwrite((BZFILE *)arch_fp->fd/*fh*/,buf,bufsize);
  883.     }
  884. #endif
  885.     if(BZ2flag){
  886.         return BZ2Write((BZ2FILE *)arch_fp->fd/*fh*/,buf,bufsize);
  887. #ifdef USE_ZLIB
  888.     }else if(!Dev && gzip_flag && ZLIBflag){
  889.         return gzwrite((gzFile)arch_fp->fd/*fh*/,buf,bufsize);
  890. #endif
  891.     }else if (!gzip_flag){
  892.         len = write(arch_fp->fd/*fh*/,buf,bufsize);
  893.         if (Veflag && len > 0){
  894.             char buffer[OUTBUFSIZ*2];
  895.             
  896.             if (OUTBUFSIZ*2 < bufsize)
  897.                 fatal("write_z","Verify inner error");
  898.             lseek(arch_fp->fd/*fh*/,-len,SEEK_CUR);
  899.             read(arch_fp->fd/*fh*/,buffer,len);
  900.             if (memcmp(buffer,buf,len) )
  901.                 fatal("write","verify error");
  902.         }
  903.         return len;
  904.     }
  905.  
  906.     zip_write(arch_fp->fd/*fh*/,buf,bufsize);
  907.     return bufsize;
  908.  
  909. }
  910. #if P_up_V>=4
  911. /* gzip file */
  912. void gzip_file(char *pack,char *unpack)
  913. {
  914.     FILE *fp_unpk;
  915.     ARCH_FILE *fh_pk;
  916.     int n;
  917.     char buf[OUTBUFSIZ];
  918.     char mode[100];
  919.  
  920.     if (Vflag){
  921.         printf("gzip:packfile is [%s] and unpack file is [%s]\n",pack,unpack);
  922.     }
  923.     if((fp_unpk=fopen(unpack,"rb"))==NULL){
  924.         fatal("gzip_file","can't open unpack file");
  925.     }
  926.     sprintf(mode,"w%d",LEVELflag);
  927.     if((fh_pk=open_arch(pack, mode))==NULL){
  928.         fatal("gzip_file","can't open pack file");
  929.     }
  930.     while((n=fread(buf,1,OUTBUFSIZ,fp_unpk))>0){
  931.         write_z(fh_pk,buf,n);
  932.     }
  933.     close_arch(fh_pk/*'c'*/);fh_pk = NULL;
  934.     fclose(fp_unpk);
  935. }
  936. int get_gunzip_fname(char *unpackfn,char *packfn)
  937. {
  938.     int packlen;
  939.  
  940.     packlen=strlen(packfn);
  941.     /*
  942.     if(packlen>=FNAME_BUF){
  943.         return -1;
  944.         fatal("archio.c:get_gunzip_fname","Too Long FileName is Specified");
  945.     }
  946.     */
  947.     if(unpackfn!=packfn){strcpy(unpackfn,packfn);}
  948.     if(packlen>2 
  949.         && (stricmp(packfn+packlen-2,".z")==0 || stricmp(packfn+packlen-2,"_z")==0)){
  950.         unpackfn[packlen-2]='\0';
  951.     }else if(packlen>3 
  952.         && (stricmp(packfn+packlen-3,".gz")==0 || stricmp(packfn+packlen-3,"_gz")==0)){
  953.         unpackfn[packlen-3]='\0';
  954.     }else if(packlen>4 
  955.         && (stricmp(packfn+packlen-4,".bz2")==0 || stricmp(packfn+packlen-4,"_bz2")==0)){
  956.         unpackfn[packlen-4]='\0';
  957.     }else if(packlen>4 && stricmp(packfn+packlen-4,".tgz")==0){
  958.         strcpy(unpackfn+packlen-4,".tar");
  959.     }else if(packlen>4 && stricmp(packfn+packlen-4,".taz")==0){
  960.         strcpy(unpackfn+packlen-4,".tar");
  961.     }else{
  962.         /* I can't know how to set....*/
  963.         strcat(unpackfn,"_extracted");
  964.         /*return -1;*/
  965.  
  966.         /* fatal("main.c:do_x_com()","Can't found gunziped/compressed file name.");*/
  967.     }
  968.     return 0;
  969. }
  970. /* gunzip or compress -d file */
  971. void gunzip_file(char *pack,char *unpack_tmp)
  972. {
  973.     /*FILE *fp_unpk;*/
  974.     int fd_unpk;
  975.  
  976.     ARCH_FILE *fh_pk;
  977.     int n;
  978.     char buf[OUTBUFSIZ];
  979.     char unpack_tmp2[FNAME_BUF]="";
  980.     char unpack[FNAME_BUF]="";
  981.     extern char *terget_path;
  982.  
  983.     if(unpack_tmp!=NULL && *unpack_tmp!='\0'){
  984.         if(strlen(unpack_tmp)>=FNAME_BUF){
  985.             Exitcode=ERROR_COMMAND_NAME;
  986.             fatal("gunzip_file","Too Long Filename.");
  987.         }
  988.         strcat(unpack_tmp2,unpack_tmp);
  989.     }else{
  990.         if(get_gunzip_fname(unpack_tmp2,pack)<0){
  991.             Exitcode=ERROR_COMMAND_NAME;
  992.             fatal("guzip_file","Can't find gunzip/compress -d filename.");
  993.         }
  994.     }
  995.     if(terget_path==NULL
  996.         || (isalpha((unsigned char)unpack_tmp2[0]) && unpack_tmp2[1]==':' && (unpack_tmp2[2]=='\\' || unpack_tmp2[2]=='/'))){
  997.         strcpy(unpack,unpack_tmp2);
  998.     }else{
  999.         strcpy(unpack,terget_path);
  1000.         strcat(unpack,"/");
  1001.         strcat(unpack,unpack_tmp2);
  1002.     }
  1003.  
  1004.     if(Vflag){
  1005.         printf("gunzip:packfile is [%s] and unpack file is [%s]\n",pack,unpack);
  1006.     }
  1007.     if(Pflag){
  1008.         /*fp_unpk=stdout;*/
  1009.         fd_unpk = 1;
  1010.     }else{
  1011.         /*if((fp_unpk=fopen(unpack,"wb"))==NULL){
  1012.             fatal("gzip_file","can't open pack file");
  1013.         }*/
  1014.         if((fd_unpk = open(unpack,O_BINARY|O_CREAT|O_WRONLY|O_TRUNC,~0))==-1){
  1015.             fatal("gzip_file","can't open unpack file");
  1016.         }
  1017.     }
  1018.     if((fh_pk=open_arch(pack, "r"))==NULL){
  1019.         fatal("gzip_file","can't open pack file");
  1020.     }
  1021.  
  1022.     while((n=read_zZ(fh_pk,buf,OUTBUFSIZ))>0){
  1023.         /*fwrite(buf,1,n,fp_unpk);*/
  1024.         write(fd_unpk,buf,n);
  1025.     }
  1026.     close_arch(fh_pk/*'x'*/);fh_pk = NULL;
  1027.     if(Pflag && /*fp_unpk==stdout*/ fd_unpk == 1){
  1028.         ;
  1029.     }else{
  1030.         /*fclose(fp_unpk);*/
  1031.         close(fd_unpk);
  1032.     }
  1033. }
  1034. int get_access_method(void)
  1035. {
  1036.     return access_method;
  1037. }
  1038.  
  1039.  
  1040. #endif /* P_up_V>=4 */
  1041. #endif /* GZIP */
  1042. #ifdef DLL
  1043. void arch_SetAfd(int fh){
  1044.     Afd=fh;
  1045. }
  1046. int arch_GetAfd(void){
  1047.     return Afd;
  1048. }
  1049. #endif /*DLL*/
  1050. #ifdef DLL
  1051.  
  1052. void arch_static_init(void)
  1053. {
  1054.     Nblocks=0;
  1055.     Current_file_name=NULL;    /* Name of current file */
  1056.     Current_file_size=0;    /* Size of current file */
  1057.     Current_file_mode=0;    /* Size of current file */
  1058.     Current_file_mtime=0; /* Modified time of current file */
  1059.     Current_file_left=0;    /* Left bytes in current file */
  1060.  
  1061.     Withlabel=0;
  1062.     Volume_time=0;    /* Time Stamp */
  1063.     Volno=0;        /* Tape volume No. */
  1064.     Nthdisk=0;        /* Nth disk */
  1065.  
  1066.     memset(Save_file_name,0,sizeof(char)*FNAME_BUF);
  1067.     Save_file_size=0;
  1068.     Save_file_mode=0;
  1069.     Save_file_mtime=0;
  1070.     Save_file_left=0;
  1071.  
  1072.  
  1073.     Mode=0;    /* 'r'ead or 'w'rite */
  1074.     Afd=0;        /* Archive file descriptor */
  1075.     Dev=0;    /* Archive file is physical device */
  1076.     /*Buff=NULL;*/    /* Archive I/O buffer */
  1077.     if(Buff!=NULL){
  1078.         free_io_buff();
  1079.     }
  1080.     Ptr=NULL;    /* Pointer to the next rd/wr data */
  1081.     Buffsize=0;    /* Size of Buff */
  1082.     Left=0;    /* Left bytes in Buff */
  1083.     access_method=0;    /* Aechive file access method */
  1084.  
  1085.     /* for gzip Buffer pointer */
  1086.     innerbuf_len = 0;
  1087.     innerbuf = NULL; /* for unzip */
  1088.     inner_file=-1;
  1089.  
  1090. /* read_zZの内部静的変数 */
  1091.     read_zZ_icp=0; /* innerbuf current read opint */
  1092.     read_zZ_read_counter=0;
  1093.  
  1094. }
  1095.  
  1096. #endif /* DLL (in arch_static_init)*/