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