home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 June / Vpr9806a.iso / OLS / Windows / TAR32031 / tar32031.exe / SRC / SRC / MAIN.BAK < prev    next >
Text File  |  1998-01-15  |  49KB  |  2,135 lines

  1. #ifndef __DEFCONF_H
  2. #include "defconf.h"
  3. #endif
  4. #ifdef MSC
  5. #include <fcntl.h>
  6. #endif
  7. /*
  8.    This file was hacked for kmtar for WIN32
  9.                                     at 1996-09-22.
  10.                                     by tantan SGL00213@niftyserve.or.jp 
  11. */
  12. /*
  13.  *    tar - UN*X tar(1) imitation for MS-DOS.
  14.  *
  15.  *    Written by Koichiro Mori (kmori)
  16.  */
  17.  
  18. #ifdef RCSID
  19. static char rcsid[] = "$Header: RCS/main.c 2.10 91/02/19 14:27:48 kmori Exp $";
  20. #endif
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <setjmp.h>
  26. #include <ctype.h>
  27. #include <time.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #ifdef    WIN32
  31.     #include    <direct.h>
  32.     #include    <io.h>
  33.     #include    <errno.h>
  34.     #include    <sys\utime.h>
  35.     #define mkdir _mkdir
  36.     #include    <windows.h>
  37. #endif
  38.  
  39. #include "defs.h"
  40. #include "tar.h"
  41. #include "getdir.h"
  42. #include "archio.h"
  43. #include "tapeio.h"
  44. #include "misc.h"
  45. #include "tardir.h"
  46. #include "version.h"
  47. #include "chkfname.h"
  48.  
  49. #include "zip.h"
  50.  
  51. #include "setarg.h"
  52.  
  53. /* この3つは???_static_init()関数のため*/
  54. #include "main.h"
  55. /* #include "gzip.h"*/
  56. extern void gzip_static_init(void);
  57. /* #include "compress.h"*/
  58. extern void compapi_static_init(void);
  59.  
  60. #ifdef DLL
  61. #include <wtypes.h>
  62. #include "tar32.h"
  63. #endif
  64.  
  65. #include "tarwin.h"
  66. #include "dlgconf.h"
  67.  
  68. /* 間接ファイル(レスポンス(response)ファイル)の展開を普通の方法で行うか?*/
  69. /* 行う場合は定義する*/
  70. /* 普通の方法とは,@filenameで,単にfilenameの中身が引数に含まれる*/
  71. /* by tsuneo */
  72. #define STANDARD_INDIRECT_EXPAND
  73.  
  74. /* ディレクトリ名を除いた(純粋な(?))ファイル名のみでマッチするかを決める */
  75. /* これを定義すると,"*.*"ですべてファイルにマッチする。 */
  76. /* これを定義しないとサブディレクトリ(* / *)やfoo.boo.txt(*.*.*)は含まれない */
  77. /* 現在の仕様ではlong.file.nameは*.name とはマッチしない(*.file.nameとマッチする) */
  78. /* と思ったらマッチしてる。。よかったよかった。。(おひ)*/
  79. /* by tsuneo */
  80. #define NEW_NEW_WILD_RULE
  81.  
  82. global char *Progname = "tar";
  83. global int Exitcode=0;
  84.  
  85. global bool Veflag;
  86. global bool Vflag;
  87. global bool Sflag;
  88. global bool Aflag;
  89. #ifdef    WIN32
  90. global bool Stealth_read_flag = NO;
  91. #endif
  92. global bool NewNameFlag = 0; /* 0:overwrite 1:unique */
  93.  
  94. global bool Mflag;
  95. global bool Yflag;
  96. global bool Gflag;
  97. global bool Iflag;
  98. #if P_up_V >=4
  99. global bool Pflag;
  100. global bool GZflag;
  101. #endif
  102. global jmp_buf    jmp_env;
  103. global bool wild_flag = NO;
  104. global bool nomes_flag = 0;
  105. global char    g_command;
  106. global bool EucFlag=0;
  107. global bool IFAflag=0;
  108. global int attri_flag=0; /* kmtar 0.96->0.97*/
  109.  
  110. global char *Archives[10];
  111. global char    MACHINE = -1;
  112. static char *terget_path=NULL;
  113. global int    gzip_flag = 0;
  114. extern int    level;
  115. global bool Limitflag = 0;
  116. global long w_limit = 0;
  117.  
  118. #ifdef USE_NKF_DLL
  119. /* ファイル名設定時のnkfの漢字コード変換オプション */
  120. /* EUCに変換する場合は"-Se"とする。*/
  121. /* 詳しくはnkfのオプションを参照してください。 */
  122. /* なお、変換を行わない場合は「""」としてください。*/
  123. #define DEFAULT_OPTION_nkf_set_filename_conversion ""
  124. global char OPTION_nkf_set_filename_conversion[100]
  125.     =DEFAULT_OPTION_nkf_set_filename_conversion;
  126. /*ファイル名取得時のnkfの漢字コード変換オプション*/
  127. #define DEFAULT_OPTION_nkf_get_filename_conversion "-s"
  128. global char OPTION_nkf_get_filename_conversion[100]
  129.     =DEFAULT_OPTION_nkf_get_filename_conversion;
  130. #endif    /* USE_NKF_DLL */
  131.  
  132. global bool OPTION_use_directory=1;    /* ディレクトリ付き圧縮/展開をするか? by tsuneo*/
  133.  
  134. /* ファイル名の検索時に全パスを検索するか? by tsuneo*/
  135. /* これを1にすると、*.*ではfooにはマッチするが、foo/barにはマッチしなくなる*/
  136. global bool OPTION_check_all_path=0;    
  137.  
  138. global bool OPTION_display_dialog=1;    /* Window表示を行うか? by tsuneo...*/
  139.  
  140. #ifdef    WIN32
  141. int NTFS_flag=0;
  142. FILE *psec_fp=0;
  143. char *security_file=NULL;  /* NTFS security file name */
  144. int getFStype(char *name); /* get file system type */
  145. void restore_sec(char *name,FILE *fp);
  146. void backup_sec(char *name,FILE *fp);
  147. #endif
  148.  
  149. static time_t From_when=1L; /* unsigned type */
  150.  
  151.  
  152. #define height(a)    (sizeof(a) / sizeof((a)[0]))
  153.  
  154.  
  155. static bool Done[MAXARG];
  156. static void expand_wild_card(char **argv,char ***xargv);
  157.  
  158. void usage()
  159. {
  160.     version();
  161.     fprintf(stderr, "Usage: %s command[option...] [#rule-file] file...\n", Progname);
  162.     fprintf(stderr, "command:");
  163.     fprintf(stderr, "-c\tcreates new tape and writes files to tape\n");
  164.     fprintf(stderr, "\t-k\tcompares files in tape & files in disk\n");
  165.     fprintf(stderr, "\t-r\tadds files to tape\n");
  166.     fprintf(stderr, "\t-t\tprints table of contents\n");
  167.     fprintf(stderr, "\t-x\textracts files from tape\n");
  168.     fprintf(stderr, "option:");
  169.     fprintf(stderr, "\t-a\tdoes ASCII conversion\n");
  170.     fprintf(stderr, "\t-A{A|H}\tset file attribute (with c command)\n");
  171.     fprintf(stderr, "\t-b N\tsets blocking factor N\n");
  172.     fprintf(stderr, "\t-e\tconverts from EUC code.(with x command)\n");
  173.     fprintf(stderr, "\t-f X\tchanges archive's name as X (default $TAPE)\n");
  174.     fprintf(stderr, "\t-g\tcreates GNUtar compatible header\n");
  175.     fprintf(stderr, "\t-i\tinspects file name.(with t command)\n");
  176.     fprintf(stderr, "\t-I\tignores file attrbiute.(with x command)\n");
  177.     fprintf(stderr, "\t-M\tstores files into multiple volumes\n");
  178.     fprintf(stderr, "\t-n\tno message.(with t command)\n");
  179.     fprintf(stderr, "\t-N F\tstores files newer than file F\n");
  180.     fprintf(stderr, "\t-N mm/dd/yyyy\tstores files newer than given date\n");
  181.     fprintf(stderr, "\t-o P\textracts to path P.(with x command)\n");
  182.     fprintf(stderr, "\t-q\tmake unique name. Do not overwrite.\n");
  183. #ifndef WIN32
  184.     fprintf(stderr, "\t-p{A|9|F}\tsets bios type. (default auto recog.)\n");
  185. #endif
  186. #ifdef WIN32
  187.     fprintf(stderr, "\t-s X\tSet X as security file. (only NTFS system)\n");
  188.     fprintf(stderr, "\t-S\tfile read with no change for last-access-time\n");
  189. #endif
  190.     fprintf(stderr, "\t-v\tverbose mode\n");
  191.     fprintf(stderr, "\t-y\tsuppresses waiting user resp.\n");
  192.  
  193. #if defined(GZIP)
  194.     fprintf(stderr, "\t-z[n] \tcompresses the output file by gzip. (with c command)\n");
  195. #endif
  196. }
  197.  
  198. static int regcmp(char *t, char *p);
  199.  
  200. bool match(char *name, char *argv[])
  201. {
  202.     int i;
  203.     int len;
  204.  
  205.     if (*argv == NULL)
  206.         return (YES);
  207.     for (i = 0; argv[i]; i++) {
  208.         len = strlen(argv[i]);
  209.         if (strncmp(name, argv[i], len) == 0 &&
  210.                 (name[len] == '\0' || name[len] == '/')) {
  211.             Done[i] = YES;
  212.             return (YES);
  213.         } else if (regcmp(name,argv[i]) == 1) {
  214.             Done[i] = YES;
  215.             return (YES);
  216.         }
  217.     }
  218.     return (NO);
  219. }
  220. #ifdef DLL
  221. bool main_match(char *name, char *argv[]){
  222.     return match(name,argv);
  223. }
  224. #endif
  225.  
  226. #ifndef DOT_DLM
  227. #define DOT_DLM 1
  228. #endif
  229. #ifndef IGNORE_CASE
  230. #define IGNORE_CASE 0
  231. #endif
  232.  
  233. #define LBRACE    '{'
  234. #define NEW_WILD_RULE    1   /* "*.*" dose not match to subdirectory */
  235.  
  236. #ifdef DOT_DLM
  237. /* is_delimiter及びmatchで使う変数 
  238. すべての.にマッチした場合はそれ以上探さない */
  239. static int dot_dlm;    
  240. #endif
  241. static int is_delimiter(int c)
  242. {
  243. /* #if DOT_DLM*/
  244. #define is_delimiter1(c)    ((c) == '\0' || (c) == '.' || (c) == '/')
  245. /* #else */
  246. #define is_delimiter2(c)    ((c) == '\0' || (c) == '/')
  247. /* #endif */
  248. #if DOT_DLM
  249.     if(dot_dlm){
  250.         return is_delimiter1(c);
  251.     }else{
  252.         return is_delimiter2(c);
  253.     }
  254. #else
  255.     return  is_delimiter2(c);
  256. #endif
  257. }
  258.  
  259. #if IGNORE_CASE
  260. #define isupper(c)    ((c) >= 'A' && (c) <= 'Z')
  261. #define tolower(c)    ((c) | 0x20)
  262. #endif
  263.  
  264. #ifdef    isspace  
  265.     #undef    isspace
  266. #endif
  267. #define isspace(c)    ((c) == ' ' || (c) == '\t' || (c) == '\n' )
  268.  
  269.  
  270. static int regcmp_itr(char *t, char *p)
  271. {
  272.     int r, include, exclude;
  273.     unsigned int ks, ke, kp, kt;
  274.     char *s, *u;
  275.  
  276.     while (*p) {
  277.         switch (*p) {
  278.         case LBRACE:
  279.             if (is_delimiter(*t)) {
  280.                 return 0;
  281.             }
  282.             s = t;
  283.             u = s;
  284.             p++;
  285.             do {
  286.                 t = s;
  287.                 r = 1;
  288.                 do {
  289.                     if (is_delimiter(*p)) {
  290.                         return -1;
  291.                     }
  292.                     kt = UCH(*t++);
  293.                     if (isk1(kt) && isk2(*t)) {
  294.                         kt = (kt << 8) + UCH(*t++);
  295.                     }
  296.                     kp = UCH(*p++);
  297.                     if (isk1(kp) && isk2(*p)) {
  298.                         kp = (kp << 8) + UCH(*p++);
  299.                     }
  300. #if IGNORE_CASE
  301.                     if (isupper(kt)) {
  302.                         kt = tolower(kt);
  303.                     }
  304.                     if (isupper(kp)) {
  305.                         kp = tolower(kp);
  306.                     }
  307. #endif
  308.                     if (kt != kp) {
  309.                         r = 0;
  310.                     }
  311.                 } while (*p != ',' && *p != '}');
  312.                 if (r == 1 && t - s > u - s) {
  313.                     u = t;
  314.                 }
  315.                 if (*p == ',') {
  316.                     p++;
  317.                 }
  318.             } while (*p != '}');
  319.             if (u == s) {
  320.                 return 0;
  321.             }
  322.             p++;
  323.             t = u;
  324.             break;
  325.         case '?':
  326.             if (is_delimiter(*t)) {
  327.                 return 0;
  328.             }
  329.             if (isk1(*t) && isk2(*(t + 1))) {
  330.                 t++;
  331.             }
  332.             t++;
  333.             p++;
  334.             break;
  335.         case '*':
  336.             while (!((r = regcmp_itr(t, p + 1)) != 0
  337.                      || is_delimiter(*t))) {
  338.                 if (isk1(*t) && isk2(*(t + 1))) {
  339.                     t++;
  340.                 }
  341.                 t++;
  342.             }
  343.             return r;
  344.         case '[':
  345.             if (is_delimiter(*t)) {
  346.                 return 0;
  347.             }
  348.             include = 0;
  349.             exclude = 0;
  350.             p++;
  351.             if (*p == '^') {
  352.                 exclude = 1;
  353.                 p++;
  354.             }
  355.             kt = UCH(*t++);
  356.             if (isk1(kt) && isk2(*t)) {
  357.                 kt = (kt << 8) + UCH(*t++);
  358.             }
  359. #if IGNORE_CASE
  360.             if (isupper(kt)) {
  361.                 kt = tolower(kt);
  362.             }
  363. #endif
  364.             do {
  365.                 if (is_delimiter(*p)) {
  366.                     return -1;
  367.                 }
  368.                 ks = UCH(*p++);
  369.                 if (isk1(ks) && isk2(*p)) {
  370.                     ks = (ks << 8) + UCH(*p++);
  371.                 }
  372.                 ke = ks;
  373.                 if (*p == '-' && *(p + 1) != ']') {
  374.                     p++;
  375.                     if (is_delimiter(*p)) {
  376.                         return -1;
  377.                     }
  378.                     ke = UCH(*p++);
  379.                     if (isk1(ke) && isk2(*p)) {
  380.                         ke = (ke << 8) + UCH(*p++);
  381.                     }
  382.                 }
  383. #if IGNORE_CASE
  384.                 if (isupper(ks)) {
  385.                     ks = tolower(ks);
  386.                 }
  387.                 if (isupper(ke)) {
  388.                     ke = tolower(ke);
  389.                 }
  390. #endif
  391.                 if (kt >= ks && kt <= ke) {
  392.                     include = 1;
  393.                 }
  394.             } while (*p != ']');
  395.             if (include == exclude) {
  396.                 return 0;
  397.             }
  398.             p++;
  399.             break;
  400. #if DOT_DLM
  401.         case '.':
  402.             if(dot_dlm){
  403.                 if (!(is_delimiter(*t))) {
  404.                     return 0;
  405.                 }
  406.                 if (*t == '.') {
  407.                     t++;
  408. #ifdef NEW_NEW_WILD_RULE
  409.                     /* 全部マッチした場合は,それ以上マッチしなくていい。*/
  410.                     if(strchr(p+1,'.')==NULL){
  411.                         dot_dlm=0;
  412.                     }
  413. #endif
  414.                 }
  415.                 p++;
  416.             }else{
  417.                 goto defaultlabel;
  418.             }
  419.             break;
  420. #endif
  421.         case '\\':
  422.             if (t[1] != '\0') {
  423.                 t++;
  424.             }
  425.             /* NOBREAK */
  426.         default:
  427. defaultlabel:
  428.             kt = UCH(*t++);
  429.             if (isk1(kt) && isk2(*t)) {
  430.                 kt = (kt << 8) + UCH(*t++);
  431.             }
  432.             kp = UCH(*p++);
  433.             if (isk1(kp) && isk2(*p)) {
  434.                 kp = (kp << 8) + UCH(*p++);
  435.             }
  436. #if IGNORE_CASE
  437.             if (isupper(kt)) {
  438.                 kt = tolower(kt);
  439.             }
  440.             if (isupper(kp)) {
  441.                 kp = tolower(kp);
  442.             }
  443. #endif
  444.             if (kt != kp) {
  445.                 return 0;
  446.             }
  447.         }
  448.     }
  449. #if NEW_WILD_RULE
  450.     return (*t == '\0') ? 1 : 0;
  451. #else
  452.     return (*t == '\0' || *t == '/') ? 1 : 0;
  453. #endif
  454. }
  455. /* 文字列tが(ワイルドカードを含んだ)文字列pにマッチするかを調べる*/
  456. static int regcmp(char *t, char *p)
  457. {
  458. #ifdef DOT_DLM
  459.     dot_dlm=1;
  460. #endif
  461.  
  462. #ifdef NEW_NEW_WILD_RULE
  463.     if(OPTION_check_all_path==0){
  464.         if(strchr(p,'/')==NULL){
  465.             if(strrchr(t,'/')!=NULL){
  466.                 t=strrchr(t,'/')+1;    
  467.             }
  468.         }
  469.     }
  470.     if(strncmp(p,"./",2)==0){
  471.         if(strncmp(t,"./",2)!=0){
  472.             p+=2;
  473.         }
  474.     }
  475. #endif
  476.     return regcmp_itr(t,p);
  477. }
  478.  
  479.  
  480. int mkdir_withdir(char *file)
  481. {
  482.     char *p, buff[FNAME_BUF];
  483.     int r;
  484.     
  485.     /* if(OPTION_use_directory==0){return 0;}*/
  486.  
  487.     if (mkdir(file) == 0)
  488.         return (0);
  489.         if (errno == EACCES) /* already exist */
  490.                 return 0;
  491.  
  492.     /* make subdirectories */
  493.     for (p = file; (p = strchr(p, '/')) != NULL; p++) {
  494.         memcpy(buff, file, p - file);
  495.         buff[p - file] = '\0';
  496.         mkdir(buff);    /* ignore return code */
  497.     }
  498.     r = mkdir(file);
  499.          
  500.         if (r == 0 || errno == EACCES) /* already exist */
  501.                 return 0;    /* success */
  502.         return r;
  503.  
  504. }
  505.  
  506.  
  507.  
  508. int creat_withdir(char *file, int mode)
  509. {
  510.     int fd;
  511.     char *p, buff[FNAME_BUF];
  512.  
  513.     if(Pflag){return 1; /* stdout file descriptor */}
  514.     
  515. /*    if(OPTION_use_directory==0){
  516.         if((p=strrchr(file,'/'))!=NULL){
  517.             file=p+1;
  518.         }
  519.         return creat(file,mode);
  520.     }*/
  521.     if ((fd = creat(file, mode)) >= 0)
  522.         return (fd);
  523.     /* make subdirectories */
  524.     for (p = file; (p = strchr(p, '/')) != NULL; p++) {
  525.         memcpy(buff, file, p - file);
  526.         buff[p - file] = '\0';
  527.         /*if(OPTION_use_directory)*/mkdir(buff);    /* ...tsuneo*/
  528.     }
  529.     return (creat(file, mode));
  530. }
  531.  
  532.  
  533.  
  534. char *noabsolute(char *s)
  535. {
  536.     if (*s && s[1] == ':')
  537.         s += 2;
  538.     if (*s == '/' || *s == '\\')
  539.         s++;
  540.     return (s);
  541. }
  542.  
  543.  
  544.  
  545. char *unixfn(char *s)
  546. {
  547.     char *p;
  548.     
  549.     p = s;
  550.     for (; *s; s++) {
  551.         if (iskanji(*s) && iskanji2(s[1])) {
  552.             s++;
  553.         } else if (*s == '\\')
  554.             *s = '/';
  555. #ifndef WIN32
  556. /*  force to small letter */
  557.         else if (isascii(*s) && isupper(*s)) {
  558.             *s = (char)tolower(*s);
  559.         }
  560. #endif
  561.     }
  562.     return p;
  563. }
  564.  
  565.  
  566.  
  567. void skip_file(void)
  568. {
  569.     int n, m;
  570.  
  571.     m = (int)(-Current_file_left & (TBLOCK - 1));
  572.     while (Current_file_left > 0) {
  573.         n = read_arch(Current_file_left, NULL);
  574.         if (n == 0)
  575.             return;
  576.         Current_file_left -= n;
  577.     }
  578.     while (m) {
  579.         n = read_arch(m, NULL);
  580.         if (n == 0)
  581.             return;
  582.         m -= n;
  583.     }
  584. }
  585.  
  586. void read_longlink_name(int st_size,char *name)
  587. {
  588.     int m;
  589.     char name2[FNAME_BUF];
  590.     void get_filename_conversion(char *dest,char *src);    /* in tardir.c */
  591.  
  592.  
  593.         m = (int)(-st_size & (TBLOCK - 1));
  594. //        Current_file_left = statbuf.st_size;
  595.         if (Current_file_left > 0) {
  596.             int n;
  597.             char *p;
  598.  
  599.             if ((n = read_arch(Current_file_left, &p)) == 0){
  600.                 Exitcode=ERROR_CANNOT_READ;
  601.                 fatal(NULL, "Unexpected EOF");
  602.             }
  603.             /* strcpy(name2,p);*/
  604.             strncpy2(name2,p,FNAME_BUF);/* ...tsuneo*/
  605.             Current_file_left -= n;
  606.         }
  607.         while (m) {
  608.             int n;
  609.  
  610.             n = read_arch(m, NULL);
  611.             if (n == 0)
  612.                 break;
  613.             m -= n;
  614.         }
  615.     get_filename_conversion(name,name2);
  616. }
  617.  
  618.  
  619. /*
  620.  * process -x command
  621.  */
  622. void do_x_com(char **argv)
  623. {
  624.     struct stat statbuf;
  625.  
  626.  
  627.     struct utimbuf    filedates;
  628.     char namebuf[FNAME_BUF], tmpname[FNAME_BUF],longlink_name[FNAME_BUF];
  629.     char tmpbuf[FNAME_BUF*2];
  630.     char *name;
  631.     char type;
  632.     HEADER *head;
  633.     int fd;
  634.     int i,longlink=0;
  635.     int m;
  636.  
  637.     tarwin_executing_dialog_display();
  638. #if P_up_V>=4
  639.     if (GZflag){
  640.         if(argv[1]!=NULL){
  641.             Exitcode=ERROR_COMMAND_NAME;
  642.             fatal("do_x_com","gzip file(G option) can extract 1 file only");
  643.         }
  644.         gunzip_file(Archives[0],argv[0]);
  645.         return;
  646.     }
  647. #endif
  648.     read_res_file(&argv);
  649.     open_arch("r");
  650.  
  651. #ifdef    WIN32
  652.     strcpy(tmpbuf,"   ");
  653.     if (terget_path)
  654.         strcpy(tmpbuf,terget_path);
  655.     NTFS_flag = getFStype(tmpbuf);
  656.     if (NTFS_flag && security_file){
  657.         psec_fp = fopen(security_file,"rb");
  658.         if (psec_fp == NULL){
  659.             fatal(security_file,"Fail to open security description file");
  660.         }
  661.       }
  662. #endif
  663.  
  664.     while (read_arch(TBLOCK, (char **)&head) == TBLOCK) {
  665.         if (eofblock(head->dummy))
  666.             break;
  667.         type = decode_dir(namebuf, &statbuf, head);
  668.         if (longlink){
  669.             longlink = 0;
  670.             strcpy(namebuf,longlink_name);
  671.         }
  672.         name = noabsolute(namebuf);
  673.         Current_file_name = name;
  674.         Current_file_mode = statbuf.st_mode;
  675.         Current_file_mtime = statbuf.st_mtime;
  676.         Current_file_size = statbuf.st_size;
  677.  
  678.         if(tarwin_executing_dialog_display_info()==-1){
  679.             Exitcode=ERROR_USER_CANCEL;
  680.             break;
  681.         }
  682.  
  683.         switch (type) {
  684.         default:
  685.             if (match(name, argv))
  686.                 break;
  687.             else{
  688.                 if(Sflag)
  689.                     printf("%-79s\r",name);
  690.             }
  691.             goto skip;
  692.         case VOLTYPE:
  693.             check_vol(name, &statbuf);
  694.             /* fall thru */
  695.         case MULTYPE:
  696.         skip:
  697.             Current_file_left = statbuf.st_size;
  698.             skip_file();
  699.             continue;
  700.         case LONGLINK:
  701.             longlink = 1;
  702.             Current_file_left = statbuf.st_size;
  703.             read_longlink_name(statbuf.st_size,longlink_name);
  704.             continue;
  705.         case LNKTYPE:
  706.         case SYMTYPE:
  707.             error(name, "Can't handle linked file");
  708.             continue;
  709.         }
  710.  
  711.         /* upsidedown "check_fname" and "if(terget_path){" by tsuneo */
  712.         check_fname(tmpname, name, NewNameFlag,
  713.                 type == DIRTYPE || name[strlen(name) - 1] == '/');
  714.  
  715. #ifdef    WIN32
  716.         if (terget_path){
  717.             char *nameptr=tmpname;
  718.  
  719.             if(OPTION_use_directory==0){
  720.                 char *p;
  721.                 if((p=strrchr(nameptr,'/'))!=NULL){
  722.                     nameptr=p+1;
  723.                 }
  724.             }
  725.             sprintf(tmpbuf,"%s/%s",terget_path,nameptr /* name*/);
  726.             strcpy(tmpname,tmpbuf);
  727.             /* strcpy(name,tmpbuf);*/ /* comment out by tsuneo */
  728.         }
  729. #endif
  730.  
  731.  
  732.  
  733.         if (Vflag) {
  734.             if (strcmp(name, tmpname) == 0) {
  735.                 fprintf(stderr, "extract %s, %ld bytes\n",
  736.                             tmpname, statbuf.st_size);
  737.             } else {
  738.                 fprintf(stderr, "extract %s(%s), %ld bytes\n",
  739.                             tmpname, name, statbuf.st_size);
  740.             }
  741.         }
  742.         if (tmpname[strlen(tmpname) - 1] == '/') {
  743.             tmpname[strlen(tmpname) - 1] = '\0';    /* remove / */
  744.             type = DIRTYPE;
  745.         }
  746.     
  747. #if 0
  748.         if(OPTION_use_directory==0){
  749.         /* tmpnameからパス名を除き、ファイル名だけにする。*/
  750.             char *p,*p2=tmpname;
  751.             if((p=strchr(tmpname,'/'))!=NULL){
  752.                 p++;
  753.                 while(*p2++=*p++)
  754.                     ;
  755.             }
  756.         }
  757. #endif
  758.         if (type == DIRTYPE) {
  759.             if (OPTION_use_directory){
  760.                 if (mkdir_withdir(tmpname))
  761.                     error(tmpname, NULL);
  762.             }
  763.         } else {
  764.             if ((fd = creat_withdir(tmpname, ~0)) < 0) {
  765.                 error(tmpname, NULL);
  766.                 Current_file_left = statbuf.st_size;
  767.                 skip_file();
  768.                 continue;
  769.             }
  770.             m = (int)(-statbuf.st_size & (TBLOCK - 1));
  771.             Current_file_left = statbuf.st_size;
  772.             while (Current_file_left > 0) {
  773.                 int n;
  774.                 char *p;
  775.  
  776.                 if ((n = read_arch(Current_file_left, &p)) == 0){
  777.                     Exitcode=ERROR_CANNOT_READ;
  778.                     fatal(tmpname, "Unexpected EOF");
  779.                 }
  780.                 if (write_a(fd, p, n) < n){
  781.                     Exitcode=ERROR_CANNOT_WRITE;
  782.                     fatal(tmpname, "No space");
  783.                 }
  784.                 Current_file_left -= n;
  785.             }
  786.             if(fd>2){
  787.                 /* 標準出力などの場合は閉じない。*/
  788.                 close(fd);
  789.             }
  790.             while (m) {
  791.                 int n;
  792.  
  793.                 n = read_arch(m, NULL);
  794.                 if (n == 0)
  795.                     break;
  796.                 m -= n;
  797.             }
  798. #if defined(WIN32)
  799.             filedates.actime = NTFS_flag ? statbuf.st_atime: statbuf.st_mtime;
  800.             filedates.modtime = statbuf.st_mtime;
  801.             if (utime(tmpname, &filedates))
  802.                 printf("warning: utime can not change time-stamp\n");
  803.             if (psec_fp)
  804.                restore_sec(tmpname,psec_fp);
  805. #endif
  806.         if (!IFAflag)
  807.             chmod(tmpname, statbuf.st_mode);
  808.         }
  809.     }
  810.     if (Sflag)
  811.         printf("%-79s\r"," ");
  812.     close_arch('x');
  813.     for (i = 0; argv[i]; i++) {
  814.         if (! Done[i])
  815.             error(argv[i], "not in archive");
  816.     }
  817. }
  818.  
  819.  
  820.  
  821. /*
  822.  * process -k command
  823.  */
  824. void    do_k_com(char **argv)
  825. {
  826.     struct stat statbuf, stat2;
  827.     char namebuf[FNAME_BUF], tmpname[FNAME_BUF],longlink_name[FNAME_BUF];
  828.     char *name;
  829.     char type;
  830.     HEADER *head;
  831.     int fd;
  832.     bool diff;
  833.     int i,longlink=0;
  834.     int ndiff;
  835.     char c;
  836.     int m;
  837.  
  838.  
  839.     read_res_file(&argv);
  840.  
  841.     ndiff = 0;
  842.     open_arch("r");
  843.     while (read_arch(TBLOCK, (char **)&head) == TBLOCK) {
  844.         if (eofblock(head->dummy))
  845.             break;
  846.         type = decode_dir(namebuf, &statbuf, head);
  847.         if (longlink){
  848.             longlink = 0;
  849.             strcpy(namebuf,longlink_name);
  850.         }
  851.  
  852.         name = noabsolute(namebuf);
  853.         Current_file_name = name;
  854.         Current_file_mode = statbuf.st_mode;
  855.         Current_file_mtime = statbuf.st_mtime;
  856.         Current_file_size = statbuf.st_size;
  857.         switch (type) {
  858.         default:
  859.             if (match(name, argv))
  860.                 break;
  861.             goto skip;
  862.         case VOLTYPE:
  863.             check_vol(name, &statbuf);
  864.             /* fall thru */
  865.         case MULTYPE:
  866.         skip:
  867.             Current_file_left = statbuf.st_size;
  868.             skip_file();
  869.             continue;
  870.         case LONGLINK:
  871.             longlink = 1;
  872.             Current_file_left = statbuf.st_size;
  873.             read_longlink_name(statbuf.st_size,longlink_name);
  874.             continue;
  875.         case LNKTYPE:
  876.         case SYMTYPE:
  877.             error(name, "Can't handle linked file");
  878.             continue;
  879.         }
  880.  
  881.         check_fname(tmpname, name, 0,
  882.                 type == DIRTYPE || name[strlen(name) - 1] == '/');
  883.  
  884.         if (Vflag) {
  885.             if (strcmp(name, tmpname) == 0) {
  886.                 fprintf(stderr, "compare %s, %ld bytes\n",
  887.                             tmpname, statbuf.st_size);
  888.             } else {
  889.                 fprintf(stderr, "cpmpare %s(%s), %ld bytes\n",
  890.                             tmpname, name, statbuf.st_size);
  891.             }
  892.         }
  893.  
  894.         if (tmpname[strlen(tmpname) - 1] == '/') {
  895.             tmpname[strlen(tmpname) - 1] = '\0';    /* remove / */
  896.             type = DIRTYPE;
  897.         }
  898.         if (type == DIRTYPE) {
  899.             if (stat(tmpname, &stat2) ||
  900.                 (statbuf.st_mode & S_IFMT) != S_IFDIR)
  901.                 fprintf(stderr, "%s is different\n", tmpname);
  902.         } else {
  903.             if ((fd = open(tmpname, 0)) < 0) {
  904.                 error(tmpname, NULL);
  905.                 Current_file_left = statbuf.st_size;
  906.                 skip_file();
  907.                 continue;
  908.             }
  909.             diff = NO;
  910.             m = (int)(-statbuf.st_size & (TBLOCK - 1));
  911.             Current_file_left = statbuf.st_size;
  912.             while (Current_file_left > 0) {
  913.                 int n;
  914.                 char *p;
  915.  
  916.                 if ((n = read_arch(Current_file_left, &p)) == 0)
  917.                     break;
  918.                 if (compare_a(fd, p, n))
  919.                     diff = YES;
  920.                 Current_file_left -= n;
  921.             }
  922.             if (read(fd, &c, 1) != 0)
  923.                 diff = YES;
  924.             close(fd);
  925.             while (m) {
  926.                 int n;
  927.  
  928.                 n = read_arch(m, NULL);
  929.                 if (n == 0)
  930.                     break;
  931.                 m -= n;
  932.             }
  933.             if (diff) {
  934.                 ndiff++;
  935.                 error(tmpname, "different");
  936.             } else {
  937.                 stat(tmpname, &stat2);
  938.                 if (stat2.st_mtime != (stat2.st_mtime & ~1))
  939.                     error(tmpname, "only time is different");
  940.             }
  941.         }
  942.     }
  943.     for (i = 0; argv[i]; i++) {
  944.         if (! Done[i])
  945.             error(argv[i], "not in archive");
  946.     }
  947.     fprintf(stderr, ndiff    ? "%d files different\n"
  948.                 : "No differences found\n", ndiff);
  949. }
  950.  
  951.  
  952.  
  953. void    putmode(unsigned mode)
  954. {
  955.     putchar(mode & S_IREAD  ? 'r' : '-');
  956.     putchar(mode & S_IWRITE ? 'w' : '-');
  957.     putchar(mode & S_IEXEC  ? 'x' : '-');
  958. }
  959.  
  960.  
  961. /*
  962.  * process -t command
  963.  */
  964. void do_t_com(char **argv)
  965. {
  966.     struct tm *tp;
  967.     static char *months[] =
  968.         { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  969.           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  970.     struct stat statbuf;
  971.     char name[FNAME_BUF],longlink_name[FNAME_BUF];
  972.     HEADER *head;
  973.     int i,longlink=0;
  974.     char type;
  975.     bool ustar;
  976.     long total_file_size=0;
  977.     void recode_names(char *n);
  978.  
  979.     read_res_file(&argv);
  980.     open_arch("r");
  981.  
  982.     while (read_arch(TBLOCK, (char **)&head) == TBLOCK) {
  983.         if (eofblock(head->dummy))
  984.             break;
  985.         type = decode_dir(name, &statbuf, head);
  986.  
  987.         if (longlink){
  988.             strcpy(name,longlink_name);
  989.             longlink = 0;
  990.         }
  991.  
  992.         if (type == VOLTYPE)
  993.             check_vol(name, &statbuf);
  994.         Current_file_name = name;
  995.         Current_file_mode = statbuf.st_mode;
  996.         Current_file_mtime = statbuf.st_mtime;
  997.         Current_file_size = Current_file_left = statbuf.st_size;
  998.  
  999.         if(tarwin_executing_dialog_display_info()==-1){
  1000.             Exitcode=ERROR_USER_CANCEL;
  1001.             break;
  1002.         }
  1003.  
  1004.         if (match(name, argv) && strcmp(name,"././@LongLink")) {
  1005.             if (Vflag && !Iflag) {
  1006.                 /* print detail information */
  1007.                 switch (type) {
  1008.                 default:
  1009.                     putchar('-');
  1010.                     break;
  1011.                 case DIRTYPE:
  1012.                     putchar('d');
  1013.                     break;
  1014.                 case CHRTYPE:
  1015.                     putchar('c');
  1016.                     break;
  1017.                 case BLKTYPE:
  1018.                     putchar('b');
  1019.                     break;
  1020.                 case FIFOTYPE:
  1021.                     putchar('p');
  1022.                     break;
  1023.                 case VOLTYPE:
  1024.                     putchar('V');
  1025.                     break;
  1026.                 case MULTYPE:
  1027.                     putchar('M');
  1028.                     break;
  1029.                 case SYMTYPE:
  1030.                     putchar('l');
  1031.                     break;
  1032.                 }
  1033.                 putmode(statbuf.st_mode);
  1034.                 putmode(statbuf.st_mode << 3);
  1035.                 putmode(statbuf.st_mode << 6);
  1036.                 ustar = (bool)(memcmp(head->dbuf.magic, TMAGIC, TMAGLEN) == 0
  1037.                     || memcmp(head->dbuf.magic, TOMAGIC, TOMAGLEN) == 0);
  1038.                 if (ustar && head->dbuf.uname[0])
  1039.                     printf(" %s/", head->dbuf.uname);
  1040.                 else
  1041.                     printf(" %d/", statbuf.st_uid);
  1042.                 if (ustar && head->dbuf.gname[0])
  1043.                     printf("%s", head->dbuf.gname);
  1044.                 else
  1045.                     printf("%d", statbuf.st_gid);
  1046.                 tp = localtime(&statbuf.st_mtime);
  1047.                 printf(" %8ld %s %2d %4d %02d:%02d",
  1048.                     statbuf.st_size,
  1049.                     months[tp->tm_mon],
  1050.                     tp->tm_mday,
  1051.                     tp->tm_year + 1900,
  1052.                     tp->tm_hour,
  1053.                     tp->tm_min);
  1054.                 total_file_size += statbuf.st_size;
  1055.                 if (Sflag)
  1056.                     printf(":%02d", tp->tm_sec);
  1057.                 putchar(' ');
  1058.             }
  1059.             if (Iflag)
  1060.                 recode_names(name);
  1061.             else
  1062.             switch (type) {
  1063.             case AREGTYPE:
  1064.             case REGTYPE:
  1065.             case DIRTYPE:
  1066.             case CHRTYPE:
  1067.             case BLKTYPE:
  1068.             case FIFOTYPE:
  1069.             case CONTTYPE:
  1070.             case VOLTYPE:
  1071.             case MULTYPE:
  1072. #ifdef MINIX
  1073.             case ' ':
  1074. #endif
  1075.                 if (!nomes_flag)
  1076.                     printf("%s\n", name);
  1077.                 break;
  1078.             case LONGLINK:
  1079.                 break;
  1080.             case LNKTYPE:
  1081.                 if (!nomes_flag)
  1082.                   printf("%s -> %s\n", name, head->dbuf.linkname);
  1083.                 break;
  1084.             case SYMTYPE:
  1085.                 if (!nomes_flag)
  1086.                   printf("%s -> %s@\n", name, head->dbuf.linkname);
  1087.                 break;
  1088.             default:
  1089.                 Exitcode=ERROR_HEADER_BROKEN;
  1090.                 fatal(name, "bad typeflag");
  1091.             }
  1092.         }else{
  1093.             if(Sflag)
  1094.                 printf("%-79s\r",name);
  1095.         }
  1096.         switch (type) {
  1097.     
  1098.         case LNKTYPE:
  1099.         case SYMTYPE:
  1100.             break;
  1101.         case LONGLINK:
  1102.             longlink = 1;
  1103.             read_longlink_name(statbuf.st_size,longlink_name);
  1104.             break;
  1105.         default:
  1106.             skip_file();
  1107.             break;
  1108.         }
  1109.         Current_file_left = 0;
  1110.     }
  1111.     close_arch('t');
  1112.     for (i = 0; argv[i]; i++) {
  1113.         if (! Done[i])
  1114.             error(argv[i], "not in archive");
  1115.     }
  1116.     if (Iflag)
  1117.         inspect_fname_list();
  1118.     if (Vflag && !Iflag)
  1119.         printf("Total file size = %ld\n",total_file_size);
  1120. }
  1121. #ifdef DLL
  1122. /*
  1123.  * process -T command
  1124.  */
  1125. /* デバッグ用隠し関数 */
  1126.  void do_T_com(char **argv)
  1127. {
  1128.     HARC harc;
  1129.     int r;
  1130.     INDIVIDUALINFO info;
  1131.     // jmp_buf old_start_env;
  1132.     // int i;
  1133.  
  1134.     printf("dwOriginalSize:dwCompressedSize:dwCRC:uFlag:uOSType:wRatio:wDate:wTime:szFileName:szAttribute:szMode\n");
  1135.     //  harc=TarOpenArchive(0,"c:\\tmp\\tst3.tgz",0);
  1136.     harc=TarOpenArchive(0,Archives[0],0);
  1137.     if (harc==0)return ;
  1138.     r=TarFindFirst(harc,"",&info);
  1139.     while(r==0){
  1140.         printf("%d:%d:%d:%d:%d:%d:%d:%d:%s:%s:%s\n"
  1141.             ,info.dwOriginalSize
  1142.             ,info.dwCompressedSize
  1143.             ,info.dwCRC
  1144.             ,info.uFlag
  1145.             ,info.uOSType
  1146.             ,info.wRatio
  1147.             ,info.wDate
  1148.             ,info.wTime
  1149.             ,info.szFileName
  1150.             ,info.szAttribute
  1151.             ,info.szMode
  1152.             );
  1153.         r=TarFindNext(harc,&info);
  1154.     }
  1155.     TarCloseArchive(harc);
  1156. }
  1157. #endif    /* #ifdef DLL */
  1158.  
  1159.  
  1160. /*
  1161.   add Long File Name
  1162. */
  1163. void addfile_lname(char *file, char *alias,struct stat statbuf)
  1164. {
  1165.     int n, m;
  1166.     char *buff;
  1167.     char wname[FNAME_BUF], walias[FNAME_BUF];
  1168.     char file2[FNAME_BUF];
  1169.     char *lname="././@LongLink";
  1170.     extern void set_filename_conversion(char *dest,char *src);/* in tardir.c */
  1171.  
  1172.     set_filename_conversion(file2,file);
  1173.  
  1174.     memset(wname,0,FNAME_BUF);
  1175.     memcpy(wname,file2,NAMSIZ-1);
  1176.     if (alias){
  1177.         memset(walias,0,FNAME_BUF);
  1178.         memcpy(walias,alias,NAMSIZ-1);
  1179.     }
  1180.  
  1181.     if (statbuf.st_mtime < From_when)
  1182.         return;
  1183.  
  1184.     buff_arch(TBLOCK, &buff);
  1185.     memset(buff, 0, TBLOCK);
  1186.     statbuf.st_size = FNAME_BUF;
  1187.     encode_dir((HEADER *)buff, lname, &statbuf, LONGLINK);
  1188.     write_arch(TBLOCK);
  1189.     Current_file_name = lname;
  1190.     Current_file_size = Current_file_left = strlen(alias == NULL ? file2 : alias);
  1191.     Current_file_mode = statbuf.st_mode;
  1192.     Current_file_mtime = statbuf.st_mtime;
  1193.     
  1194.  
  1195.     m = 0;
  1196.     n = buff_arch(-1, &buff);
  1197.     strcpy(buff,noabsolute(alias == NULL ? file2 : alias));
  1198.     n = Current_file_left;
  1199.     write_arch(n);
  1200. /*        printf("n = %d\n",n);*/
  1201.     Current_file_left -= n;
  1202.     m += n;
  1203.  
  1204.     n = buff_arch(-1, &buff);
  1205.     Current_file_left = 0;
  1206.  
  1207.     n = -m & (TBLOCK - 1);
  1208.     buff_arch(n, &buff);
  1209.     memset(buff, 0, n);
  1210.     write_arch(n);
  1211.  
  1212. }
  1213.  
  1214.  
  1215. /*
  1216.  * Add a file or directory to archive
  1217.  */
  1218. void addfile(char *file_arg, char *alias)
  1219. {
  1220.     int n, m;
  1221.     int fd;
  1222.     FLIST *dirs, *dp;
  1223.     char *buff;
  1224.     struct stat statbuf;
  1225.  
  1226.     char file[FNAME_BUF];
  1227.     char wname[FNAME_BUF], walias[FNAME_BUF];
  1228.     
  1229.     {
  1230.         /* 圧縮時に基準ディレクトリを考慮 (by tsuneo...) */
  1231.         /* (例)下のような構成の場合、
  1232.             C:\              <Root>
  1233.                + data\           <DIR>
  1234.                  + data1.txt   <FILE>
  1235.                  + data2.txt   <FILE>
  1236.                  + data3.txt   <FILE>
  1237.          cvfz6  c:\test.tgz  c:\data\  data1.txt  data2.txt 
  1238.          と入れることで、data1.txt,data2.txtを圧縮する。 */
  1239.  
  1240.         if(terget_path!=NULL){
  1241.             if(make_filename(file,FNAME_BUF,terget_path,file_arg)==NULL){
  1242.                 Exitcode = ERROR_LONG_FILE_NAME;
  1243.                 fatal("addfile","cat't add basedirectory and filename(too long).");
  1244.             }
  1245.             if(alias==NULL){
  1246.                 alias=file_arg;
  1247.             }
  1248.         }else{
  1249.             strcpy(file,file_arg);
  1250.         }
  1251.     }
  1252.     
  1253.     if(OPTION_use_directory==0){
  1254.         char *p;
  1255.         /* ディレクトリ構造を保存しない場合*/
  1256.         if((alias!=NULL) && (p=strrchr(alias,'/'))){
  1257.             alias=p+1;
  1258.         }else if((alias==NULL) && (p=strrchr(file,'/'))){
  1259.             alias=p+1;
  1260.         }
  1261.     }
  1262.     unixfn(file);
  1263.     if (!stricmp(Archives[0],file))        /* at 1993-10-31 by tantan */
  1264.         return;
  1265.     else if (!strncmp(file,"./",2) && !stricmp(Archives[0],file+2))
  1266.         return;
  1267.     if (stat(file, &statbuf)) {
  1268.         strcat(addsl(strcpy(wname, file)), "nul");
  1269.         if (stat(wname, &statbuf)) {
  1270.             error(file, NULL);
  1271.             return;
  1272.         }
  1273.         /* maybe directory, like "", "/", "." at root */
  1274.         statbuf.st_mode = S_IFDIR | 0755;
  1275.         statbuf.st_size = 0;
  1276.         statbuf.st_mtime = 0L; /* Not need */
  1277.     }
  1278.  
  1279.     if (alias == NULL)
  1280.         alias = get_orgname(file);
  1281.  
  1282.     if (strlen(file) >= NAMSIZ -1 || (alias != NULL && strlen(alias) >= NAMSIZ -1))
  1283.         addfile_lname(file,alias,statbuf);
  1284.  
  1285.     switch (statbuf.st_mode & S_IFMT) {
  1286.     case S_IFDIR:    /* directory */
  1287.         statbuf.st_size = 0;  /* for CD-ROM */
  1288.         if (statbuf.st_mtime >= From_when && strlen(file) > 0) { /* 1995-3-1 by tantan */
  1289.             if (Vflag) {
  1290.                 if (alias == NULL) {
  1291.                     fprintf(stderr, "add %s\n", file);
  1292.                 } else {
  1293.                     fprintf(stderr, "add %s(%s)\n", file, alias);
  1294.                 }
  1295.             }
  1296.             buff_arch(TBLOCK, &buff);
  1297.             memset(buff, 0, TBLOCK);
  1298.             encode_dir((HEADER *)buff, noabsolute(alias == NULL ? file : alias), &statbuf, DIRTYPE);
  1299.             write_arch(TBLOCK);
  1300. #ifdef    WIN32
  1301.             if (psec_fp)
  1302.                 backup_sec(file,psec_fp);
  1303. #endif            
  1304.         }
  1305.         dirs = get_dir(file);
  1306.         if (dirs == NULL) {
  1307.             error(file, NULL);
  1308.             return;
  1309.         }
  1310.         for (dp = dirs; dp != NULL; dp = dp->next) {
  1311.             if (strcmp(dp->name, ".") == 0
  1312.                 || strcmp(dp->name, "..") == 0)
  1313.                 continue;
  1314.             strcat(addsl(strcpy(wname, file)), dp->name);
  1315.             if (alias == NULL) {
  1316.                 addfile(wname, NULL);
  1317.             } else {
  1318.                 char *tmp;        /* Add 4 line at 1993-10-31 by tantan */
  1319.                 if (tmp = get_orgname(wname))
  1320.                     strcpy(walias,alias = tmp);
  1321.                 else
  1322.                     strcat(addsl(strcpy(walias, alias)), dp->name);
  1323.                 addfile(wname, walias);
  1324.             }
  1325.         }
  1326.         free_dir(dirs);
  1327.         break;
  1328.     case S_IFREG:    /* Regular file */
  1329.         if (statbuf.st_mtime < From_when)
  1330.             return;
  1331.         if ((fd = open(file, 0)) < 0) {
  1332.             error(file, NULL);
  1333.             return;
  1334.         }
  1335.         if (Aflag)
  1336.             statbuf.st_size = realsize(fd);
  1337.         if (Vflag) {
  1338.             if (alias == NULL) {
  1339.                 fprintf(stderr, "%sadd %s, %ld bytes\n", gzip_flag ? "z_":"",
  1340.                         file, statbuf.st_size);
  1341.             } else {
  1342.                 fprintf(stderr, "%sadd %s(%s), %ld bytes\n", gzip_flag ? "z_":"",
  1343.                         file, alias, statbuf.st_size);
  1344.             }
  1345.         }
  1346.         buff_arch(TBLOCK, &buff);
  1347.         memset(buff, 0, TBLOCK);
  1348.         encode_dir((HEADER *)buff, noabsolute(alias == NULL ? file : alias), &statbuf, REGTYPE);
  1349.         write_arch(TBLOCK);
  1350. #ifdef    WIN32
  1351.         if (psec_fp)
  1352.             backup_sec(file,psec_fp);
  1353. #endif
  1354.         Current_file_name = noabsolute(alias == NULL ? file : alias);
  1355.         Current_file_size = Current_file_left = statbuf.st_size;
  1356.         Current_file_mode = statbuf.st_mode;
  1357.         Current_file_mtime = statbuf.st_mtime;
  1358.  
  1359.         if(tarwin_executing_dialog_display_info()==-1){
  1360.             Exitcode=ERROR_USER_CANCEL;
  1361.             close(fd);
  1362.             fatal("addfile","User Canceled");
  1363.         }
  1364.  
  1365.         m = 0;
  1366.         for (;;) {
  1367.             n = buff_arch(-1, &buff);
  1368.             if ((n = read_a(fd, buff, n)) <= 0)
  1369.                 break;
  1370.             write_arch(n);
  1371. /*        printf("n = %d\n",n);*/
  1372.             Current_file_left -= n;
  1373.             m += n;
  1374.         }
  1375.         Current_file_left = 0;
  1376.         close(fd);
  1377. #ifdef    WIN32
  1378.         {    /* restore last access time */
  1379.             struct utimbuf ubuf;
  1380.  
  1381.             if (Stealth_read_flag && NTFS_flag){
  1382.               ubuf.actime = statbuf.st_atime;
  1383.               ubuf.modtime = statbuf.st_mtime;
  1384.               if (utime(file, &ubuf))
  1385.                 printf("Warning: utime can not change timestamp of %s\n",file);
  1386.             }
  1387.         }
  1388. #endif
  1389.         n = -m & (TBLOCK - 1);
  1390.         buff_arch(n, &buff);
  1391.         memset(buff, 0, n);
  1392.         write_arch(n);
  1393. /*        printf("n = %d\n",n);*/
  1394.         break;
  1395.     default:
  1396.         error(file, "Special file not added.");
  1397.         break;
  1398.     }
  1399. }
  1400.  
  1401.  
  1402.  
  1403. /*
  1404.  * process -c, -r command
  1405.  */
  1406.     char cao_flag=0;  /* check over write flag */
  1407. void do_cr_com(char command, char **argv)
  1408. {
  1409.     struct stat statbuf;
  1410.     char *buff;
  1411.     char name[FNAME_BUF];
  1412.     char type;
  1413.     char *p;
  1414.  
  1415.     tarwin_executing_dialog_display();
  1416. #if P_up_V >=4
  1417.     if(GZflag){
  1418.         if(argv[0]==NULL){
  1419.             Exitcode=ERROR_NOT_ARC_FILE;
  1420.             fatal("do_cr_com","gzip file isn't specified");
  1421.         }
  1422.         if(argv[1]!=NULL){
  1423.             Exitcode=ERROR_COMMAND_NAME;
  1424.             fatal("do_cr_com","gzip file(G option) can archive 1 file only");
  1425.         }
  1426.  
  1427.         gzip_file(Archives[0],argv[0]);
  1428.         return;
  1429.     }
  1430. #endif
  1431.  
  1432.     if (wild_flag){  /* by tantan at 1995-04-25  */
  1433.         Exitcode=ERROR_COMMAND_NAME;
  1434.         fatal("t command","Cant' use wild-card in this mode");
  1435.     }
  1436.     if ((p = get_dev_alias(".CHK_ARCHIVE_OVERWRITE")) != NULL){
  1437.         if (stricmp(p,"YES") == 0)
  1438.             cao_flag = YES;
  1439.     }
  1440.  
  1441.     if (Vflag && From_when != 1L)
  1442.         fprintf(stderr, "Add files created/modified after %s", ctime(&From_when));
  1443.     if(command=='r' && !existfile(Archives[0])){    /* ...tsuneo */
  1444.         command='c';
  1445.     }
  1446.     open_arch(command == 'c' ? "w": "a");
  1447.     if (command == 'r') {
  1448.         /* seek to end of archive */
  1449.             
  1450.         while (read_arch(TBLOCK, &buff) == TBLOCK) {
  1451.             if (eofblock(buff))
  1452.                 break;
  1453.             type = decode_dir(name, &statbuf, (HEADER *)buff);
  1454.             if (type == VOLTYPE)
  1455.                 check_vol(name, &statbuf);
  1456.             Current_file_name = name;
  1457.             Current_file_mode = statbuf.st_mode;
  1458.             Current_file_mtime = statbuf.st_mtime;
  1459.             switch (type) {
  1460.             case LNKTYPE:
  1461.             case SYMTYPE:
  1462.                 break;
  1463.             default:
  1464.                 Current_file_size = Current_file_left = statbuf.st_size;
  1465.                 skip_file();
  1466.                 break;
  1467.             }
  1468.             Current_file_left = 0;
  1469.         }
  1470.         if (start_write_arch(TBLOCK))
  1471.             fatal("main", "Can't r");
  1472.     }
  1473.     if (*argv) {
  1474.         char **xargv,**sargv;
  1475.         expand_wild_card(argv,&xargv);
  1476.         sargv = xargv;
  1477. #ifdef    WIN32
  1478.     NTFS_flag = getFStype(*xargv);
  1479.     if (NTFS_flag && security_file ){
  1480.         psec_fp = fopen(security_file,"wb");
  1481.         if (psec_fp == NULL){
  1482.             fatal(security_file,"Fail to open security descripsion file");
  1483.             exit(1);
  1484.         }
  1485.     }
  1486. #endif
  1487.         for (; *xargv; xargv++) {
  1488.             FILE *fh;
  1489.             char line[256], *p, *q, *fname, *alias;
  1490.             
  1491.             /* kmtar のオリジナルの「@」引数のことは考えるのをやめ。*/
  1492.             if (**xargv == '@' && (fh = fopen(*xargv + 1, "r")) != NULL) {
  1493.                 while (fgets(line, sizeof(line), fh) != NULL) {
  1494.                     p = line;
  1495.                     while (*p != '\0' && (unsigned char)*p <= ' ') {
  1496.                         p++;
  1497.                     }
  1498.                     if (*p == '\0') {
  1499.                         continue;
  1500.                     }
  1501.                     fname = p;
  1502.                     while (*p != '\0' && (unsigned char)*p > ' ') {
  1503.                         p++;
  1504.                     }
  1505.                     q = p;
  1506.                     while (*p != '\0' && (unsigned char)*p <= ' ') {
  1507.                         p++;
  1508.                     }
  1509.                     alias = p;
  1510.                     while (*p != '\0' && (unsigned char)*p > ' ') {
  1511.                         p++;
  1512.                     }
  1513.                     *q = '\0';
  1514.                     *p = '\0';
  1515.                     if (*alias == '\0') {
  1516.                         alias = NULL;
  1517.                     }
  1518.                     addfile(fname, alias);
  1519.                 }
  1520.                 fclose(fh);
  1521.             } else {
  1522.                 addfile(*xargv, NULL);
  1523.             }
  1524.         }
  1525.         /* sargv=xargvをcurrent_file_nameがさしている時free(*sargv)すると不定になるバグを訂正
  1526.             by tsuneo(special thanks to Masaki Yasue)(1997/08/29)*/
  1527.         if(Current_file_name){
  1528.             Current_file_name=strcpy(name,Current_file_name);
  1529.         }
  1530.         for(;*sargv;sargv++)
  1531.             free(*sargv);
  1532.  
  1533.     } else {
  1534.         addfile("", NULL);
  1535.     }
  1536.     /* write EOF mark */
  1537.     buff_arch(TBLOCK, &buff);
  1538.     memset(buff, 0, TBLOCK);
  1539.     write_arch(TBLOCK);
  1540.     buff_arch(TBLOCK, &buff);
  1541.     memset(buff, 0, TBLOCK);
  1542.     write_arch(TBLOCK);
  1543.  
  1544.     close_arch(command);
  1545.     Current_file_name=NULL;
  1546. }
  1547.  
  1548. char *wild_card(char *str, WIN32_FIND_DATA *buf)
  1549. {
  1550.     char *p,*ss;
  1551.     static char name_buf[FNAME_BUF];
  1552.  
  1553.     unixfn(strcpy(name_buf,str));
  1554.     ss = name_buf - 1;
  1555.     for(p = name_buf;*p;p++){    /* serach last '\' ,'/', ':' */
  1556.         if (*p =='/' || *p == ':')
  1557.             ss = p;
  1558.     }
  1559.     sprintf(ss+1,"%s\x0",buf->cFileName);
  1560.     return name_buf;
  1561. }
  1562.  
  1563. void *xrealloc(char *str,size_t ss)
  1564. {
  1565.     void *p;
  1566.     
  1567.     if ((p = realloc(str,ss)) == NULL){
  1568.         Exitcode=ERROR_ENOUGH_MEMORY;
  1569.         fatal("realloc","Out of memeory");
  1570.     }
  1571.     return p;
  1572. }
  1573.  
  1574. char *xstrdup(char *str)
  1575. {
  1576.     char *p;
  1577.     
  1578.     if ((p = strdup(str)) == NULL){
  1579.         Exitcode=ERROR_ENOUGH_MEMORY;
  1580.         fatal("strdup","Out of memeory");
  1581.     }
  1582.     return p;
  1583. }
  1584.  
  1585. static void expand_wild_card(char **argv,char ***xargv)
  1586. {
  1587.     int i;
  1588.  
  1589.     HANDLE hFile=INVALID_HANDLE_VALUE;
  1590.     /*struct stat stbuf;*/
  1591.     WIN32_FIND_DATA fbuf;
  1592.     *xargv = NULL;
  1593.  
  1594. /*    printf("%s\n",fbuf.name);*/
  1595.     for(i=2;*argv;argv++,i++){  /* 1 余分にとっている */
  1596.         *xargv = (char **)xrealloc((char *)*xargv,i*sizeof(char **));
  1597.         if (strpbrk("*?",*argv)){
  1598.             int ii= 0;
  1599.             char abs_argv[FNAME_BUF];
  1600.  
  1601.             /* 基準ディレクトリを考慮に入れ、*argv->abs_argvと変更する。by tsuneo... */
  1602.             if(make_filename(abs_argv,FNAME_BUF,terget_path,*argv)==NULL){
  1603.                 Exitcode = ERROR_LONG_FILE_NAME;
  1604.                 fatal("addfile","cat't add basedirectory and filename(too long).");
  1605.             }
  1606.  
  1607.                                     /*argv -> abs_argv by tsuneo */
  1608.             if ((hFile = FindFirstFile(abs_argv,&fbuf)) !=  INVALID_HANDLE_VALUE){
  1609.                 do{
  1610.                    if ( (fbuf.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN     |
  1611.                       /* FILE_ATTRIBUTE_DIRECTORY | (commentout by tsuneo)*/FILE_ATTRIBUTE_SYSTEM)) != 0 )
  1612.                       continue;
  1613.                     /* by tsuneo (1997.8.28) */
  1614.                    if(strcmp(fbuf.cFileName,".")==0 || strcmp(fbuf.cFileName,"..")==0){
  1615.                        continue;
  1616.                    }
  1617.                    /* OPTION_use_directory=1のときは、ワイルドカードもディレクトリにマッチする(再起圧縮) */
  1618.                    /* by tsuneo (1997.8.28) */
  1619.                    if ( (OPTION_use_directory==0) && (fbuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
  1620.                        continue;
  1621.                    }
  1622.                    /*
  1623.                     意味不明につき削除... by tsuneo (1997.08.28) 
  1624.                    if (fbuf.nFileSizeLow == 0){
  1625.                       stat(fbuf.cFileName,&stbuf);
  1626.                       if (stbuf.st_size != 0)
  1627.                             continue;
  1628.                     }
  1629.                     */
  1630.                    if (ii == 0)
  1631.                       ii =1;                   
  1632.                     else
  1633.                       i++;
  1634.                    *xargv = (char **)xrealloc((char *)*xargv,i*sizeof(char **));
  1635.                    (*xargv)[i-2] = xstrdup(wild_card(*argv,&fbuf));
  1636.                 }while(FindNextFile(hFile,&fbuf)==TRUE);
  1637.             }else{
  1638.                 (*xargv)[i-2] = xstrdup(*argv);
  1639.                 continue;
  1640.             }
  1641.             /* kmtar 0.96->0.97*/
  1642.             if (hFile != INVALID_HANDLE_VALUE)
  1643.                 FindClose(hFile); 
  1644.         }else
  1645.             (*xargv)[i-2] = xstrdup(*argv);
  1646.     }
  1647.     if (i==2)
  1648.         *xargv = (char **)xrealloc((char *)*xargv,2*sizeof(char **));
  1649.     (*xargv)[i-2] = NULL;
  1650.  
  1651.     /* FindClose(hFile); remove kmtar 0.96->0.97*/
  1652. }
  1653.  
  1654.  
  1655. void erase_alloced_mem(void)
  1656. {
  1657.     extern void erase_rename_table(void);
  1658.     erase_rename_table();
  1659. }
  1660.  
  1661. /*
  1662.  * Entry point
  1663.  */
  1664. /* main関数はmainmain.cに移動する。*/
  1665. #ifdef DLL
  1666. int tar_main(int argc,char *argv[]){
  1667. #else
  1668. void main(int argc, char *argv[]){
  1669. #endif
  1670.     volatile char *p,*stok_wildcard=0;
  1671.     volatile char **archp;
  1672.     volatile char command;
  1673.     extern void free_io_buff(void);
  1674.     extern unsigned long innerbuf_len;
  1675.     HANDLE hFile;
  1676.     WIN32_FIND_DATA find_buf;
  1677.  
  1678. #ifdef DLL
  1679.     {
  1680.         int return_value=setjmp(start_env);
  1681.         if(return_value!=0){
  1682.             ioctrl_output_end();
  1683.             return return_value;
  1684.         }
  1685.         ioctrl_output_init_test();
  1686.         static_init_all();
  1687.     }
  1688. #endif
  1689.     if (argc < 2) {
  1690.         usage();
  1691.         exit(ERROR_COMMAND_NAME);
  1692.     }
  1693. #ifdef STANDARD_INDIRECT_EXPAND
  1694.     setup_arguments(&argc,&argv);
  1695. #endif
  1696.     
  1697. #ifdef FORSE_BINARY_MODE
  1698.     _fmode = _O_BINARY;
  1699. #endif
  1700.     command = '\0';
  1701.     archp = Archives;
  1702.     for (argv++; *argv; ) {
  1703.         p = *argv++;
  1704.         
  1705.         if(strncmp((char *)p,"--",2)==0){
  1706.             /* 長いオプション(「--」で始まるもの)はここで処理する。*/
  1707.             char *key,*cont;
  1708.             char tmparg[100];
  1709.             char *p2;
  1710.  
  1711.             /* --foo=bar を key="foo",cont="bar"とする。*/
  1712.             p+=2;
  1713.             if(strlen((char *)p)>=100){
  1714.                 Exitcode=ERROR_COMMAND_NAME;
  1715.                 fatal(argv[-1],"Illegal Long Option");
  1716.             }
  1717.             strcpy(tmparg,(char *)p);
  1718.             key=tmparg;
  1719.             if((p2=strchr(tmparg,'='))!=NULL){
  1720.                 *p2='\0';
  1721.                 cont=(char *)p2+1;
  1722.             }else{
  1723.                 cont=NULL;
  1724.             }
  1725.             if(strcmp(key,"long-option-test")==0 && cont){
  1726.                 printf("long-option-test:cont=[%s]\n",cont);
  1727.             }else if(strcmp(key,"nkf-set-filename-conversion")==0 && cont){
  1728.                 strcpy(OPTION_nkf_set_filename_conversion,cont);
  1729.             }else if(strcmp(key,"nkf-get-filename-conversion")==0 && cont){
  1730.                 strcpy(OPTION_nkf_get_filename_conversion,cont);
  1731.             }else if(strcmp(key,"use-directory")==0 && cont){
  1732.                 OPTION_use_directory=atoi(cont);
  1733.             }else if(strcmp(key,"check-all-path")==0 && cont){
  1734.                 OPTION_check_all_path=atoi(cont);
  1735.             }else if(strcmp(key,"display-dialog")==0 && cont){
  1736.                 OPTION_check_all_path=atoi(cont);
  1737.             }else{
  1738.                 printf("key=[%s],contents=[%s] is incorrect\n",key,cont==NULL?"":cont);
  1739.                 Exitcode=ERROR_COMMAND_NAME;
  1740.                 fatal(argv[-1],"Invalid Long Option");
  1741.             }
  1742.             continue;
  1743.         }
  1744.         if (*p == '-')
  1745.             p++;
  1746.         for (; *p; p++) {
  1747.             switch (*p) {
  1748.             case 'c':
  1749.             case 'r':
  1750.             case 'x':
  1751.             case 't':
  1752. #ifdef DLL
  1753.             case 'T':
  1754. #endif
  1755.             case 'k':
  1756.                 if (command){
  1757.                     Exitcode=ERROR_COMMAND_NAME;
  1758.                     fatal(argv[-1], "2 or more commands");
  1759.                 }
  1760.                 command = *p;
  1761.                 break;
  1762.             case 'V':
  1763.                 Sflag = YES;
  1764.                 /* fall thru */
  1765.             case 'v':
  1766.                 Vflag = YES;
  1767.                 break;
  1768.             case 'a':
  1769.                 Aflag = YES;
  1770.                 break;
  1771.             case 'A':    /* Attribute flag */
  1772.                 switch (p[1]){
  1773.                     case 'A':
  1774.                         attri_flag = FILE_ATTRIBUTE_ARCHIVE;
  1775.                         p++;
  1776.                         break;
  1777.                     case 'H':
  1778.                         attri_flag = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
  1779.                         p++;
  1780.                         break;
  1781.                 }
  1782.                 break;
  1783.             case 'm':
  1784.             case 'M':
  1785.                 Mflag = YES;
  1786.                 break;
  1787.             case 'y':
  1788.                 Yflag = YES;
  1789.                 break;
  1790.             case 'i':
  1791.                 Iflag = YES;
  1792.                 break;
  1793.             case 'I':
  1794.                 IFAflag = YES;
  1795.                 break;
  1796.             case 'E':
  1797.                 Veflag = YES;
  1798.                 break;
  1799.             case 'l':
  1800.                 Limitflag = YES;
  1801.                 if (p[1] >= '1' && p[1] <= '9'){
  1802.                     w_limit = atoi((const char *)&p[1]);
  1803.                     p++;
  1804.                 }
  1805.                 break;
  1806.             case 'Z':    /* gzip flag */
  1807.                 level = 1;        /* -Z means fast compress */
  1808.             case 'z':    /* gzip flag */
  1809. #if    defined(GZIP)
  1810.                 gzip_flag=1;
  1811.                 if (p[1] >= '1' && p[1] <= '9'){
  1812.                     level = p[1] - '0';
  1813.                     p++;
  1814.                 }
  1815. #endif
  1816.                 break;
  1817.             case 'e':
  1818.                 EucFlag = YES;
  1819.                 break;
  1820. #if P_up_V>=4
  1821.             case 'G':    /* Only gzip or gunzip or compress -d ...tsuneo */
  1822.                 GZflag=YES;
  1823.                 break;
  1824.             case 'p':    /* print out to stdout ...tsuneo */
  1825.                 Pflag=YES;
  1826.                 break;
  1827. #else
  1828.             case 'p':
  1829. #endif
  1830.             case 'P':    /* define PC type */
  1831.                 switch (p[1]){
  1832.                     case 'A':
  1833.                         MACHINE = AT;
  1834.                         p++;
  1835.                         break;
  1836.                     case '9':
  1837.                         MACHINE = PC98;
  1838.                         p++;
  1839.                         break;
  1840.                     case 'F':
  1841.                         MACHINE = FM;
  1842.                         p++;
  1843.                         break;
  1844.                 }
  1845.                 break;
  1846.             case 'n':
  1847.                 nomes_flag = YES;
  1848.                 break;
  1849.             case 'f':
  1850.                 if (*argv == NULL)
  1851.                     goto opterr;
  1852.                 if (archp >= Archives + height(Archives) - 1){
  1853.                     Exitcode=ERROR_COMMAND_NAME;
  1854.                     fatal("main", "Too many -f");
  1855.                 }
  1856.                 unixfn(*argv);    /* at 1993-10-31 by tantan */
  1857.                 *archp++ = *argv++;
  1858.                 break;
  1859.             case 'b':
  1860.                 if (*argv == NULL)
  1861.                     goto opterr;
  1862.                 Nblocks = atoi(*argv++);
  1863.                 break;
  1864.  
  1865.             case 'q':
  1866.                 NewNameFlag = 1;
  1867.                 break;
  1868. #ifdef    WIN32
  1869.             case 'S':
  1870.                 Stealth_read_flag = YES;
  1871.                 break;
  1872.  
  1873.             case 's':{   /* security description file */
  1874.                 int n;
  1875.                 if (*argv == NULL)
  1876.                     goto opterr;
  1877.                 security_file = unixfn(*argv++);
  1878.                 n = strlen(security_file);
  1879.                 if (n < 1)
  1880.                     goto opterr;
  1881.                 break;
  1882.                 }
  1883. #endif
  1884.             case 'o':{
  1885.                 int n;
  1886. case_o:
  1887.                 if (*argv == NULL)
  1888.                     goto opterr;
  1889.                 terget_path = unixfn(*argv++);
  1890.                 n = strlen(terget_path);
  1891.                 if (n < 1)
  1892.                     goto opterr;
  1893.                 --n;
  1894.                 if (terget_path[n] == '/')
  1895.                     terget_path[n] = '\0';
  1896.                 break;
  1897.                 }
  1898.             case 'N': {
  1899.                 struct stat statbuf;
  1900.  
  1901.                 if (*argv == NULL)
  1902.                     goto opterr;
  1903.                 if (stat(*argv, &statbuf) == 0)
  1904.                     From_when = statbuf.st_mtime;
  1905.                 else
  1906.                     From_when = __getdate(*argv);
  1907.                 if (From_when < 1L)
  1908.                     fatal(*argv, "Bad date");
  1909.                 argv++;
  1910.                 break;
  1911.                 }
  1912.             case 'g':
  1913.                 Gflag = YES;
  1914.                 break;
  1915.             opterr:
  1916.             default:
  1917.                 Exitcode=ERROR_COMMAND_NAME;
  1918.                 fatal(argv[-1], "Bad option");
  1919.             }
  1920.         }
  1921.         if (*argv == NULL || **argv != '-' || (*argv)[1] == '\0'){
  1922.             if(*argv!=NULL && strchr("\\/",(*argv)[strlen(*argv)-1])!=NULL){
  1923.                 /* \か/で終わってる時は、基準ディレクトリとして設定する。*/
  1924.                 if( (command == 'x')
  1925.                     || ((command=='r' || command=='c') && (*(argv+1)!=NULL))){
  1926.                     argv++;    
  1927.                     argv--;    /* -o オプションと同じように、argvに基準ディレクトリが入るようにする*/
  1928.                     p=(*argv)+strlen(*argv)-1;/* *(p+1)=='\0'とする*/
  1929.                     goto case_o;    /* またgotoを使ってしまった...*/
  1930.                 }
  1931.             }
  1932.             break;
  1933.         }
  1934.     }
  1935.     *archp = NULL;
  1936.     if (Archives[0] == NULL) {
  1937.         Archives[0] = getenv("TAPE");
  1938.         if (Archives[0] == NULL)
  1939.             Archives[0] = getenv("TARDEV");
  1940. #ifndef WIN32
  1941.         if (Archives[0] == NULL)
  1942.             Archives[0] = get_dev_alias(".DEFAULT");
  1943. #endif
  1944. #if 0  /* this code sleeping */
  1945.         if (Archives[0] == NULL)
  1946.             Archives[0] = "/dev/rfd1";
  1947. #else
  1948.         if (Archives[0] == NULL){
  1949.             fprintf(stderr,"tar:Archive file not set\n");
  1950.             exit(ERROR_NOT_ARC_FILE);
  1951.         }
  1952. #endif
  1953.         Archives[1] = NULL;
  1954.     }
  1955.     read_rule_file(argv);
  1956.  
  1957. /*    fprintf(stderr,"Archives[0] = %s\n",Archives[0]);*/
  1958.     if (strpbrk(Archives[0],"*?") != NULL){ /* check wild caed */
  1959.         wild_flag = YES;
  1960.         stok_wildcard = Archives[0];
  1961.         g_command = command;
  1962.     }
  1963.     
  1964.     if (wild_flag == YES && (hFile = FindFirstFile((char *)stok_wildcard, &find_buf)) ==  INVALID_HANDLE_VALUE )
  1965.         wild_flag = NO;
  1966. #ifdef DLL
  1967.     {
  1968.         /* 残りの引数(ファイル名リスト)の「\」を「/」に変換 */
  1969.         char **ptr;
  1970.         for(ptr=argv;*ptr;ptr++){
  1971.             unixfn(*ptr);
  1972.         }
  1973.     }
  1974. #endif
  1975.     do {
  1976.         if (wild_flag){
  1977.             /* kmtar 0.96->0.97 */
  1978.             if (find_buf.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_TEMPORARY))
  1979.                 continue;
  1980.             if ((attri_flag & FILE_ATTRIBUTE_SYSTEM) == 0 &&
  1981.                find_buf.dwFileAttributes & (FILE_ATTRIBUTE_SYSTEM |FILE_ATTRIBUTE_HIDDEN) )
  1982.                 continue;
  1983.             if ((attri_flag & FILE_ATTRIBUTE_ARCHIVE) && 
  1984.                 !(find_buf.dwFileAttributes & (FILE_ATTRIBUTE_ARCHIVE)))
  1985.                 continue;
  1986.             if (command == 't' && setjmp(jmp_env) != 0){
  1987.                 erase_alloced_mem();
  1988.                 continue;
  1989.             }
  1990.             Archives[0] = wild_card((char *)stok_wildcard,&find_buf);
  1991.             printf("Archive name=%s\t",Archives[0]);
  1992.             if (command != 't' || nomes_flag==0)
  1993.                 printf("\n");
  1994.         }
  1995.         switch (command) {
  1996.         case 'c':
  1997.         case 'r':
  1998.             do_cr_com(command, argv);
  1999.             break;
  2000.         case 'x':
  2001.             do_x_com(argv);
  2002.             break;
  2003.         case 't':
  2004.             do_t_com(argv);
  2005.             break;
  2006.     #ifdef DLL
  2007.         case 'T':
  2008.             do_T_com(argv);
  2009.             break;
  2010.     #endif
  2011.         case 'k':
  2012.             do_k_com(argv);
  2013.             break;
  2014.         default:
  2015.             Exitcode=ERROR_COMMAND_NAME;
  2016.             fatal("main", "No command specified");
  2017.         }
  2018.         erase_alloced_mem();
  2019.         if (command == 't' && nomes_flag && wild_flag)
  2020.             printf("\r%80s\r"," ");
  2021.  
  2022.     }while(wild_flag != 0 && FindNextFile(hFile,&find_buf)==TRUE);
  2023.     if (wild_flag && hFile != INVALID_HANDLE_VALUE) /* kmtar 0.96->0.97 */
  2024.        FindClose(hFile);
  2025.     free_io_buff();
  2026. #ifdef DLL
  2027.     /* APIを使ってるデバッグ用のTコマンドだけ特別。。
  2028.         (すでにsetjmpは使ってるので。。) */
  2029.     if(command=='T'){
  2030.         ioctrl_output_end();
  2031.         return Exitcode;
  2032.     }
  2033. #endif
  2034.     exit(Exitcode);
  2035. }
  2036.  
  2037. #ifdef DLL
  2038.  
  2039. void main_static_init(void){
  2040.     /* global char *Progname = "tar";*/
  2041.     Exitcode=0;
  2042.  
  2043.     Veflag=0;
  2044.     Vflag=0;
  2045.     Sflag=0;
  2046.     Aflag=0;
  2047.     #ifdef    WIN32
  2048.     Stealth_read_flag = NO;
  2049.     #endif
  2050.     NewNameFlag = 0; /* 0:overwrite 1:unique */
  2051.  
  2052.     Mflag=0;
  2053.     Yflag=0;
  2054.     Gflag=0;
  2055.     Iflag=0;
  2056.     #if P_up_V >=4
  2057.     Pflag=0;
  2058.     GZflag=0;
  2059.     #endif
  2060.     /* global jmp_buf    jmp_env;*/
  2061.     wild_flag = NO;
  2062.     nomes_flag = 0;
  2063.     g_command=0;
  2064.     EucFlag=0;
  2065.     IFAflag=0;
  2066.     attri_flag=0; /* kmtar 0.96->0.97*/
  2067.  
  2068.     memset(Archives,0,sizeof(char *)*10);
  2069.     MACHINE = -1;
  2070.     terget_path=NULL;
  2071.     gzip_flag = 0;
  2072.     //extern int    level;
  2073.     Limitflag = 0;
  2074.     w_limit = 0;
  2075.  
  2076. #ifdef USE_NKF_DLL
  2077. /* ファイル名設定時のnkfの漢字コード変換オプション */
  2078. strcpy(OPTION_nkf_set_filename_conversion
  2079.        ,DEFAULT_OPTION_nkf_set_filename_conversion);
  2080. /*ファイル名取得時のnkfの漢字コード変換オプション*/
  2081. strcpy(OPTION_nkf_get_filename_conversion
  2082.        ,DEFAULT_OPTION_nkf_get_filename_conversion);
  2083. #endif
  2084.  
  2085.     OPTION_use_directory=1;    /* ディレクトリ付き圧縮/展開をするか?*/
  2086.  
  2087.     OPTION_check_all_path=0;    
  2088.     OPTION_display_dialog=1;    /* Window表示を行うか? by tsuneo */
  2089.  
  2090.     #ifdef    WIN32
  2091.     NTFS_flag=0;
  2092.     psec_fp=0;
  2093.     security_file=NULL;  /* NTFS security file name */
  2094.     //int getFStype(char *name); /* get file system type */
  2095.     //void restore_sec(char *name,FILE *fp);
  2096.     //void backup_sec(char *name,FILE *fp);
  2097.     #endif
  2098.  
  2099.     From_when=1L; /* unsigned type */
  2100.  
  2101.  
  2102.     //#define height(a)    (sizeof(a) / sizeof((a)[0]))
  2103.  
  2104.  
  2105.     memset(Done,0,sizeof(bool)*MAXARG);
  2106.  
  2107.     cao_flag=0;  /* check over write flag */
  2108.  
  2109. }
  2110.  
  2111. /* すべての静的変数(グローバル変数も)を初期化する。*/
  2112. void static_init_all(void)
  2113. {
  2114.     extern void trees_static_init(void);
  2115.     extern void deflate_static_init(void);
  2116.     main_static_init();
  2117.     arch_static_init();
  2118.     chkfname_static_init();
  2119.     zip_static_init();
  2120.     gzip_static_init();
  2121.     compapi_static_init();
  2122.     deflate_static_init();
  2123.  
  2124.     trees_static_init();
  2125.  
  2126.     load_registry_info();
  2127. }
  2128. /* 終了時処理(主にメモリの開放) 
  2129. (関数名が変になってしまった(^^; )
  2130. */
  2131. void static_free_all(void)
  2132. {
  2133. }
  2134. #endif
  2135.