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 >
Wrap
Text File
|
1998-01-15
|
49KB
|
2,135 lines
#ifndef __DEFCONF_H
#include "defconf.h"
#endif
#ifdef MSC
#include <fcntl.h>
#endif
/*
This file was hacked for kmtar for WIN32
at 1996-09-22.
by tantan SGL00213@niftyserve.or.jp
*/
/*
* tar - UN*X tar(1) imitation for MS-DOS.
*
* Written by Koichiro Mori (kmori)
*/
#ifdef RCSID
static char rcsid[] = "$Header: RCS/main.c 2.10 91/02/19 14:27:48 kmori Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef WIN32
#include <direct.h>
#include <io.h>
#include <errno.h>
#include <sys\utime.h>
#define mkdir _mkdir
#include <windows.h>
#endif
#include "defs.h"
#include "tar.h"
#include "getdir.h"
#include "archio.h"
#include "tapeio.h"
#include "misc.h"
#include "tardir.h"
#include "version.h"
#include "chkfname.h"
#include "zip.h"
#include "setarg.h"
/* この3つは???_static_init()関数のため*/
#include "main.h"
/* #include "gzip.h"*/
extern void gzip_static_init(void);
/* #include "compress.h"*/
extern void compapi_static_init(void);
#ifdef DLL
#include <wtypes.h>
#include "tar32.h"
#endif
#include "tarwin.h"
#include "dlgconf.h"
/* 間接ファイル(レスポンス(response)ファイル)の展開を普通の方法で行うか?*/
/* 行う場合は定義する*/
/* 普通の方法とは,@filenameで,単にfilenameの中身が引数に含まれる*/
/* by tsuneo */
#define STANDARD_INDIRECT_EXPAND
/* ディレクトリ名を除いた(純粋な(?))ファイル名のみでマッチするかを決める */
/* これを定義すると,"*.*"ですべてファイルにマッチする。 */
/* これを定義しないとサブディレクトリ(* / *)やfoo.boo.txt(*.*.*)は含まれない */
/* 現在の仕様ではlong.file.nameは*.name とはマッチしない(*.file.nameとマッチする) */
/* と思ったらマッチしてる。。よかったよかった。。(おひ)*/
/* by tsuneo */
#define NEW_NEW_WILD_RULE
global char *Progname = "tar";
global int Exitcode=0;
global bool Veflag;
global bool Vflag;
global bool Sflag;
global bool Aflag;
#ifdef WIN32
global bool Stealth_read_flag = NO;
#endif
global bool NewNameFlag = 0; /* 0:overwrite 1:unique */
global bool Mflag;
global bool Yflag;
global bool Gflag;
global bool Iflag;
#if P_up_V >=4
global bool Pflag;
global bool GZflag;
#endif
global jmp_buf jmp_env;
global bool wild_flag = NO;
global bool nomes_flag = 0;
global char g_command;
global bool EucFlag=0;
global bool IFAflag=0;
global int attri_flag=0; /* kmtar 0.96->0.97*/
global char *Archives[10];
global char MACHINE = -1;
static char *terget_path=NULL;
global int gzip_flag = 0;
extern int level;
global bool Limitflag = 0;
global long w_limit = 0;
#ifdef USE_NKF_DLL
/* ファイル名設定時のnkfの漢字コード変換オプション */
/* EUCに変換する場合は"-Se"とする。*/
/* 詳しくはnkfのオプションを参照してください。 */
/* なお、変換を行わない場合は「""」としてください。*/
#define DEFAULT_OPTION_nkf_set_filename_conversion ""
global char OPTION_nkf_set_filename_conversion[100]
=DEFAULT_OPTION_nkf_set_filename_conversion;
/*ファイル名取得時のnkfの漢字コード変換オプション*/
#define DEFAULT_OPTION_nkf_get_filename_conversion "-s"
global char OPTION_nkf_get_filename_conversion[100]
=DEFAULT_OPTION_nkf_get_filename_conversion;
#endif /* USE_NKF_DLL */
global bool OPTION_use_directory=1; /* ディレクトリ付き圧縮/展開をするか? by tsuneo*/
/* ファイル名の検索時に全パスを検索するか? by tsuneo*/
/* これを1にすると、*.*ではfooにはマッチするが、foo/barにはマッチしなくなる*/
global bool OPTION_check_all_path=0;
global bool OPTION_display_dialog=1; /* Window表示を行うか? by tsuneo...*/
#ifdef WIN32
int NTFS_flag=0;
FILE *psec_fp=0;
char *security_file=NULL; /* NTFS security file name */
int getFStype(char *name); /* get file system type */
void restore_sec(char *name,FILE *fp);
void backup_sec(char *name,FILE *fp);
#endif
static time_t From_when=1L; /* unsigned type */
#define height(a) (sizeof(a) / sizeof((a)[0]))
static bool Done[MAXARG];
static void expand_wild_card(char **argv,char ***xargv);
void usage()
{
version();
fprintf(stderr, "Usage: %s command[option...] [#rule-file] file...\n", Progname);
fprintf(stderr, "command:");
fprintf(stderr, "-c\tcreates new tape and writes files to tape\n");
fprintf(stderr, "\t-k\tcompares files in tape & files in disk\n");
fprintf(stderr, "\t-r\tadds files to tape\n");
fprintf(stderr, "\t-t\tprints table of contents\n");
fprintf(stderr, "\t-x\textracts files from tape\n");
fprintf(stderr, "option:");
fprintf(stderr, "\t-a\tdoes ASCII conversion\n");
fprintf(stderr, "\t-A{A|H}\tset file attribute (with c command)\n");
fprintf(stderr, "\t-b N\tsets blocking factor N\n");
fprintf(stderr, "\t-e\tconverts from EUC code.(with x command)\n");
fprintf(stderr, "\t-f X\tchanges archive's name as X (default $TAPE)\n");
fprintf(stderr, "\t-g\tcreates GNUtar compatible header\n");
fprintf(stderr, "\t-i\tinspects file name.(with t command)\n");
fprintf(stderr, "\t-I\tignores file attrbiute.(with x command)\n");
fprintf(stderr, "\t-M\tstores files into multiple volumes\n");
fprintf(stderr, "\t-n\tno message.(with t command)\n");
fprintf(stderr, "\t-N F\tstores files newer than file F\n");
fprintf(stderr, "\t-N mm/dd/yyyy\tstores files newer than given date\n");
fprintf(stderr, "\t-o P\textracts to path P.(with x command)\n");
fprintf(stderr, "\t-q\tmake unique name. Do not overwrite.\n");
#ifndef WIN32
fprintf(stderr, "\t-p{A|9|F}\tsets bios type. (default auto recog.)\n");
#endif
#ifdef WIN32
fprintf(stderr, "\t-s X\tSet X as security file. (only NTFS system)\n");
fprintf(stderr, "\t-S\tfile read with no change for last-access-time\n");
#endif
fprintf(stderr, "\t-v\tverbose mode\n");
fprintf(stderr, "\t-y\tsuppresses waiting user resp.\n");
#if defined(GZIP)
fprintf(stderr, "\t-z[n] \tcompresses the output file by gzip. (with c command)\n");
#endif
}
static int regcmp(char *t, char *p);
bool match(char *name, char *argv[])
{
int i;
int len;
if (*argv == NULL)
return (YES);
for (i = 0; argv[i]; i++) {
len = strlen(argv[i]);
if (strncmp(name, argv[i], len) == 0 &&
(name[len] == '\0' || name[len] == '/')) {
Done[i] = YES;
return (YES);
} else if (regcmp(name,argv[i]) == 1) {
Done[i] = YES;
return (YES);
}
}
return (NO);
}
#ifdef DLL
bool main_match(char *name, char *argv[]){
return match(name,argv);
}
#endif
#ifndef DOT_DLM
#define DOT_DLM 1
#endif
#ifndef IGNORE_CASE
#define IGNORE_CASE 0
#endif
#define LBRACE '{'
#define NEW_WILD_RULE 1 /* "*.*" dose not match to subdirectory */
#ifdef DOT_DLM
/* is_delimiter及びmatchで使う変数
すべての.にマッチした場合はそれ以上探さない */
static int dot_dlm;
#endif
static int is_delimiter(int c)
{
/* #if DOT_DLM*/
#define is_delimiter1(c) ((c) == '\0' || (c) == '.' || (c) == '/')
/* #else */
#define is_delimiter2(c) ((c) == '\0' || (c) == '/')
/* #endif */
#if DOT_DLM
if(dot_dlm){
return is_delimiter1(c);
}else{
return is_delimiter2(c);
}
#else
return is_delimiter2(c);
#endif
}
#if IGNORE_CASE
#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
#define tolower(c) ((c) | 0x20)
#endif
#ifdef isspace
#undef isspace
#endif
#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' )
static int regcmp_itr(char *t, char *p)
{
int r, include, exclude;
unsigned int ks, ke, kp, kt;
char *s, *u;
while (*p) {
switch (*p) {
case LBRACE:
if (is_delimiter(*t)) {
return 0;
}
s = t;
u = s;
p++;
do {
t = s;
r = 1;
do {
if (is_delimiter(*p)) {
return -1;
}
kt = UCH(*t++);
if (isk1(kt) && isk2(*t)) {
kt = (kt << 8) + UCH(*t++);
}
kp = UCH(*p++);
if (isk1(kp) && isk2(*p)) {
kp = (kp << 8) + UCH(*p++);
}
#if IGNORE_CASE
if (isupper(kt)) {
kt = tolower(kt);
}
if (isupper(kp)) {
kp = tolower(kp);
}
#endif
if (kt != kp) {
r = 0;
}
} while (*p != ',' && *p != '}');
if (r == 1 && t - s > u - s) {
u = t;
}
if (*p == ',') {
p++;
}
} while (*p != '}');
if (u == s) {
return 0;
}
p++;
t = u;
break;
case '?':
if (is_delimiter(*t)) {
return 0;
}
if (isk1(*t) && isk2(*(t + 1))) {
t++;
}
t++;
p++;
break;
case '*':
while (!((r = regcmp_itr(t, p + 1)) != 0
|| is_delimiter(*t))) {
if (isk1(*t) && isk2(*(t + 1))) {
t++;
}
t++;
}
return r;
case '[':
if (is_delimiter(*t)) {
return 0;
}
include = 0;
exclude = 0;
p++;
if (*p == '^') {
exclude = 1;
p++;
}
kt = UCH(*t++);
if (isk1(kt) && isk2(*t)) {
kt = (kt << 8) + UCH(*t++);
}
#if IGNORE_CASE
if (isupper(kt)) {
kt = tolower(kt);
}
#endif
do {
if (is_delimiter(*p)) {
return -1;
}
ks = UCH(*p++);
if (isk1(ks) && isk2(*p)) {
ks = (ks << 8) + UCH(*p++);
}
ke = ks;
if (*p == '-' && *(p + 1) != ']') {
p++;
if (is_delimiter(*p)) {
return -1;
}
ke = UCH(*p++);
if (isk1(ke) && isk2(*p)) {
ke = (ke << 8) + UCH(*p++);
}
}
#if IGNORE_CASE
if (isupper(ks)) {
ks = tolower(ks);
}
if (isupper(ke)) {
ke = tolower(ke);
}
#endif
if (kt >= ks && kt <= ke) {
include = 1;
}
} while (*p != ']');
if (include == exclude) {
return 0;
}
p++;
break;
#if DOT_DLM
case '.':
if(dot_dlm){
if (!(is_delimiter(*t))) {
return 0;
}
if (*t == '.') {
t++;
#ifdef NEW_NEW_WILD_RULE
/* 全部マッチした場合は,それ以上マッチしなくていい。*/
if(strchr(p+1,'.')==NULL){
dot_dlm=0;
}
#endif
}
p++;
}else{
goto defaultlabel;
}
break;
#endif
case '\\':
if (t[1] != '\0') {
t++;
}
/* NOBREAK */
default:
defaultlabel:
kt = UCH(*t++);
if (isk1(kt) && isk2(*t)) {
kt = (kt << 8) + UCH(*t++);
}
kp = UCH(*p++);
if (isk1(kp) && isk2(*p)) {
kp = (kp << 8) + UCH(*p++);
}
#if IGNORE_CASE
if (isupper(kt)) {
kt = tolower(kt);
}
if (isupper(kp)) {
kp = tolower(kp);
}
#endif
if (kt != kp) {
return 0;
}
}
}
#if NEW_WILD_RULE
return (*t == '\0') ? 1 : 0;
#else
return (*t == '\0' || *t == '/') ? 1 : 0;
#endif
}
/* 文字列tが(ワイルドカードを含んだ)文字列pにマッチするかを調べる*/
static int regcmp(char *t, char *p)
{
#ifdef DOT_DLM
dot_dlm=1;
#endif
#ifdef NEW_NEW_WILD_RULE
if(OPTION_check_all_path==0){
if(strchr(p,'/')==NULL){
if(strrchr(t,'/')!=NULL){
t=strrchr(t,'/')+1;
}
}
}
if(strncmp(p,"./",2)==0){
if(strncmp(t,"./",2)!=0){
p+=2;
}
}
#endif
return regcmp_itr(t,p);
}
int mkdir_withdir(char *file)
{
char *p, buff[FNAME_BUF];
int r;
/* if(OPTION_use_directory==0){return 0;}*/
if (mkdir(file) == 0)
return (0);
if (errno == EACCES) /* already exist */
return 0;
/* make subdirectories */
for (p = file; (p = strchr(p, '/')) != NULL; p++) {
memcpy(buff, file, p - file);
buff[p - file] = '\0';
mkdir(buff); /* ignore return code */
}
r = mkdir(file);
if (r == 0 || errno == EACCES) /* already exist */
return 0; /* success */
return r;
}
int creat_withdir(char *file, int mode)
{
int fd;
char *p, buff[FNAME_BUF];
if(Pflag){return 1; /* stdout file descriptor */}
/* if(OPTION_use_directory==0){
if((p=strrchr(file,'/'))!=NULL){
file=p+1;
}
return creat(file,mode);
}*/
if ((fd = creat(file, mode)) >= 0)
return (fd);
/* make subdirectories */
for (p = file; (p = strchr(p, '/')) != NULL; p++) {
memcpy(buff, file, p - file);
buff[p - file] = '\0';
/*if(OPTION_use_directory)*/mkdir(buff); /* ...tsuneo*/
}
return (creat(file, mode));
}
char *noabsolute(char *s)
{
if (*s && s[1] == ':')
s += 2;
if (*s == '/' || *s == '\\')
s++;
return (s);
}
char *unixfn(char *s)
{
char *p;
p = s;
for (; *s; s++) {
if (iskanji(*s) && iskanji2(s[1])) {
s++;
} else if (*s == '\\')
*s = '/';
#ifndef WIN32
/* force to small letter */
else if (isascii(*s) && isupper(*s)) {
*s = (char)tolower(*s);
}
#endif
}
return p;
}
void skip_file(void)
{
int n, m;
m = (int)(-Current_file_left & (TBLOCK - 1));
while (Current_file_left > 0) {
n = read_arch(Current_file_left, NULL);
if (n == 0)
return;
Current_file_left -= n;
}
while (m) {
n = read_arch(m, NULL);
if (n == 0)
return;
m -= n;
}
}
void read_longlink_name(int st_size,char *name)
{
int m;
char name2[FNAME_BUF];
void get_filename_conversion(char *dest,char *src); /* in tardir.c */
m = (int)(-st_size & (TBLOCK - 1));
// Current_file_left = statbuf.st_size;
if (Current_file_left > 0) {
int n;
char *p;
if ((n = read_arch(Current_file_left, &p)) == 0){
Exitcode=ERROR_CANNOT_READ;
fatal(NULL, "Unexpected EOF");
}
/* strcpy(name2,p);*/
strncpy2(name2,p,FNAME_BUF);/* ...tsuneo*/
Current_file_left -= n;
}
while (m) {
int n;
n = read_arch(m, NULL);
if (n == 0)
break;
m -= n;
}
get_filename_conversion(name,name2);
}
/*
* process -x command
*/
void do_x_com(char **argv)
{
struct stat statbuf;
struct utimbuf filedates;
char namebuf[FNAME_BUF], tmpname[FNAME_BUF],longlink_name[FNAME_BUF];
char tmpbuf[FNAME_BUF*2];
char *name;
char type;
HEADER *head;
int fd;
int i,longlink=0;
int m;
tarwin_executing_dialog_display();
#if P_up_V>=4
if (GZflag){
if(argv[1]!=NULL){
Exitcode=ERROR_COMMAND_NAME;
fatal("do_x_com","gzip file(G option) can extract 1 file only");
}
gunzip_file(Archives[0],argv[0]);
return;
}
#endif
read_res_file(&argv);
open_arch("r");
#ifdef WIN32
strcpy(tmpbuf," ");
if (terget_path)
strcpy(tmpbuf,terget_path);
NTFS_flag = getFStype(tmpbuf);
if (NTFS_flag && security_file){
psec_fp = fopen(security_file,"rb");
if (psec_fp == NULL){
fatal(security_file,"Fail to open security description file");
}
}
#endif
while (read_arch(TBLOCK, (char **)&head) == TBLOCK) {
if (eofblock(head->dummy))
break;
type = decode_dir(namebuf, &statbuf, head);
if (longlink){
longlink = 0;
strcpy(namebuf,longlink_name);
}
name = noabsolute(namebuf);
Current_file_name = name;
Current_file_mode = statbuf.st_mode;
Current_file_mtime = statbuf.st_mtime;
Current_file_size = statbuf.st_size;
if(tarwin_executing_dialog_display_info()==-1){
Exitcode=ERROR_USER_CANCEL;
break;
}
switch (type) {
default:
if (match(name, argv))
break;
else{
if(Sflag)
printf("%-79s\r",name);
}
goto skip;
case VOLTYPE:
check_vol(name, &statbuf);
/* fall thru */
case MULTYPE:
skip:
Current_file_left = statbuf.st_size;
skip_file();
continue;
case LONGLINK:
longlink = 1;
Current_file_left = statbuf.st_size;
read_longlink_name(statbuf.st_size,longlink_name);
continue;
case LNKTYPE:
case SYMTYPE:
error(name, "Can't handle linked file");
continue;
}
/* upsidedown "check_fname" and "if(terget_path){" by tsuneo */
check_fname(tmpname, name, NewNameFlag,
type == DIRTYPE || name[strlen(name) - 1] == '/');
#ifdef WIN32
if (terget_path){
char *nameptr=tmpname;
if(OPTION_use_directory==0){
char *p;
if((p=strrchr(nameptr,'/'))!=NULL){
nameptr=p+1;
}
}
sprintf(tmpbuf,"%s/%s",terget_path,nameptr /* name*/);
strcpy(tmpname,tmpbuf);
/* strcpy(name,tmpbuf);*/ /* comment out by tsuneo */
}
#endif
if (Vflag) {
if (strcmp(name, tmpname) == 0) {
fprintf(stderr, "extract %s, %ld bytes\n",
tmpname, statbuf.st_size);
} else {
fprintf(stderr, "extract %s(%s), %ld bytes\n",
tmpname, name, statbuf.st_size);
}
}
if (tmpname[strlen(tmpname) - 1] == '/') {
tmpname[strlen(tmpname) - 1] = '\0'; /* remove / */
type = DIRTYPE;
}
#if 0
if(OPTION_use_directory==0){
/* tmpnameからパス名を除き、ファイル名だけにする。*/
char *p,*p2=tmpname;
if((p=strchr(tmpname,'/'))!=NULL){
p++;
while(*p2++=*p++)
;
}
}
#endif
if (type == DIRTYPE) {
if (OPTION_use_directory){
if (mkdir_withdir(tmpname))
error(tmpname, NULL);
}
} else {
if ((fd = creat_withdir(tmpname, ~0)) < 0) {
error(tmpname, NULL);
Current_file_left = statbuf.st_size;
skip_file();
continue;
}
m = (int)(-statbuf.st_size & (TBLOCK - 1));
Current_file_left = statbuf.st_size;
while (Current_file_left > 0) {
int n;
char *p;
if ((n = read_arch(Current_file_left, &p)) == 0){
Exitcode=ERROR_CANNOT_READ;
fatal(tmpname, "Unexpected EOF");
}
if (write_a(fd, p, n) < n){
Exitcode=ERROR_CANNOT_WRITE;
fatal(tmpname, "No space");
}
Current_file_left -= n;
}
if(fd>2){
/* 標準出力などの場合は閉じない。*/
close(fd);
}
while (m) {
int n;
n = read_arch(m, NULL);
if (n == 0)
break;
m -= n;
}
#if defined(WIN32)
filedates.actime = NTFS_flag ? statbuf.st_atime: statbuf.st_mtime;
filedates.modtime = statbuf.st_mtime;
if (utime(tmpname, &filedates))
printf("warning: utime can not change time-stamp\n");
if (psec_fp)
restore_sec(tmpname,psec_fp);
#endif
if (!IFAflag)
chmod(tmpname, statbuf.st_mode);
}
}
if (Sflag)
printf("%-79s\r"," ");
close_arch('x');
for (i = 0; argv[i]; i++) {
if (! Done[i])
error(argv[i], "not in archive");
}
}
/*
* process -k command
*/
void do_k_com(char **argv)
{
struct stat statbuf, stat2;
char namebuf[FNAME_BUF], tmpname[FNAME_BUF],longlink_name[FNAME_BUF];
char *name;
char type;
HEADER *head;
int fd;
bool diff;
int i,longlink=0;
int ndiff;
char c;
int m;
read_res_file(&argv);
ndiff = 0;
open_arch("r");
while (read_arch(TBLOCK, (char **)&head) == TBLOCK) {
if (eofblock(head->dummy))
break;
type = decode_dir(namebuf, &statbuf, head);
if (longlink){
longlink = 0;
strcpy(namebuf,longlink_name);
}
name = noabsolute(namebuf);
Current_file_name = name;
Current_file_mode = statbuf.st_mode;
Current_file_mtime = statbuf.st_mtime;
Current_file_size = statbuf.st_size;
switch (type) {
default:
if (match(name, argv))
break;
goto skip;
case VOLTYPE:
check_vol(name, &statbuf);
/* fall thru */
case MULTYPE:
skip:
Current_file_left = statbuf.st_size;
skip_file();
continue;
case LONGLINK:
longlink = 1;
Current_file_left = statbuf.st_size;
read_longlink_name(statbuf.st_size,longlink_name);
continue;
case LNKTYPE:
case SYMTYPE:
error(name, "Can't handle linked file");
continue;
}
check_fname(tmpname, name, 0,
type == DIRTYPE || name[strlen(name) - 1] == '/');
if (Vflag) {
if (strcmp(name, tmpname) == 0) {
fprintf(stderr, "compare %s, %ld bytes\n",
tmpname, statbuf.st_size);
} else {
fprintf(stderr, "cpmpare %s(%s), %ld bytes\n",
tmpname, name, statbuf.st_size);
}
}
if (tmpname[strlen(tmpname) - 1] == '/') {
tmpname[strlen(tmpname) - 1] = '\0'; /* remove / */
type = DIRTYPE;
}
if (type == DIRTYPE) {
if (stat(tmpname, &stat2) ||
(statbuf.st_mode & S_IFMT) != S_IFDIR)
fprintf(stderr, "%s is different\n", tmpname);
} else {
if ((fd = open(tmpname, 0)) < 0) {
error(tmpname, NULL);
Current_file_left = statbuf.st_size;
skip_file();
continue;
}
diff = NO;
m = (int)(-statbuf.st_size & (TBLOCK - 1));
Current_file_left = statbuf.st_size;
while (Current_file_left > 0) {
int n;
char *p;
if ((n = read_arch(Current_file_left, &p)) == 0)
break;
if (compare_a(fd, p, n))
diff = YES;
Current_file_left -= n;
}
if (read(fd, &c, 1) != 0)
diff = YES;
close(fd);
while (m) {
int n;
n = read_arch(m, NULL);
if (n == 0)
break;
m -= n;
}
if (diff) {
ndiff++;
error(tmpname, "different");
} else {
stat(tmpname, &stat2);
if (stat2.st_mtime != (stat2.st_mtime & ~1))
error(tmpname, "only time is different");
}
}
}
for (i = 0; argv[i]; i++) {
if (! Done[i])
error(argv[i], "not in archive");
}
fprintf(stderr, ndiff ? "%d files different\n"
: "No differences found\n", ndiff);
}
void putmode(unsigned mode)
{
putchar(mode & S_IREAD ? 'r' : '-');
putchar(mode & S_IWRITE ? 'w' : '-');
putchar(mode & S_IEXEC ? 'x' : '-');
}
/*
* process -t command
*/
void do_t_com(char **argv)
{
struct tm *tp;
static char *months[] =
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
struct stat statbuf;
char name[FNAME_BUF],longlink_name[FNAME_BUF];
HEADER *head;
int i,longlink=0;
char type;
bool ustar;
long total_file_size=0;
void recode_names(char *n);
read_res_file(&argv);
open_arch("r");
while (read_arch(TBLOCK, (char **)&head) == TBLOCK) {
if (eofblock(head->dummy))
break;
type = decode_dir(name, &statbuf, head);
if (longlink){
strcpy(name,longlink_name);
longlink = 0;
}
if (type == VOLTYPE)
check_vol(name, &statbuf);
Current_file_name = name;
Current_file_mode = statbuf.st_mode;
Current_file_mtime = statbuf.st_mtime;
Current_file_size = Current_file_left = statbuf.st_size;
if(tarwin_executing_dialog_display_info()==-1){
Exitcode=ERROR_USER_CANCEL;
break;
}
if (match(name, argv) && strcmp(name,"././@LongLink")) {
if (Vflag && !Iflag) {
/* print detail information */
switch (type) {
default:
putchar('-');
break;
case DIRTYPE:
putchar('d');
break;
case CHRTYPE:
putchar('c');
break;
case BLKTYPE:
putchar('b');
break;
case FIFOTYPE:
putchar('p');
break;
case VOLTYPE:
putchar('V');
break;
case MULTYPE:
putchar('M');
break;
case SYMTYPE:
putchar('l');
break;
}
putmode(statbuf.st_mode);
putmode(statbuf.st_mode << 3);
putmode(statbuf.st_mode << 6);
ustar = (bool)(memcmp(head->dbuf.magic, TMAGIC, TMAGLEN) == 0
|| memcmp(head->dbuf.magic, TOMAGIC, TOMAGLEN) == 0);
if (ustar && head->dbuf.uname[0])
printf(" %s/", head->dbuf.uname);
else
printf(" %d/", statbuf.st_uid);
if (ustar && head->dbuf.gname[0])
printf("%s", head->dbuf.gname);
else
printf("%d", statbuf.st_gid);
tp = localtime(&statbuf.st_mtime);
printf(" %8ld %s %2d %4d %02d:%02d",
statbuf.st_size,
months[tp->tm_mon],
tp->tm_mday,
tp->tm_year + 1900,
tp->tm_hour,
tp->tm_min);
total_file_size += statbuf.st_size;
if (Sflag)
printf(":%02d", tp->tm_sec);
putchar(' ');
}
if (Iflag)
recode_names(name);
else
switch (type) {
case AREGTYPE:
case REGTYPE:
case DIRTYPE:
case CHRTYPE:
case BLKTYPE:
case FIFOTYPE:
case CONTTYPE:
case VOLTYPE:
case MULTYPE:
#ifdef MINIX
case ' ':
#endif
if (!nomes_flag)
printf("%s\n", name);
break;
case LONGLINK:
break;
case LNKTYPE:
if (!nomes_flag)
printf("%s -> %s\n", name, head->dbuf.linkname);
break;
case SYMTYPE:
if (!nomes_flag)
printf("%s -> %s@\n", name, head->dbuf.linkname);
break;
default:
Exitcode=ERROR_HEADER_BROKEN;
fatal(name, "bad typeflag");
}
}else{
if(Sflag)
printf("%-79s\r",name);
}
switch (type) {
case LNKTYPE:
case SYMTYPE:
break;
case LONGLINK:
longlink = 1;
read_longlink_name(statbuf.st_size,longlink_name);
break;
default:
skip_file();
break;
}
Current_file_left = 0;
}
close_arch('t');
for (i = 0; argv[i]; i++) {
if (! Done[i])
error(argv[i], "not in archive");
}
if (Iflag)
inspect_fname_list();
if (Vflag && !Iflag)
printf("Total file size = %ld\n",total_file_size);
}
#ifdef DLL
/*
* process -T command
*/
/* デバッグ用隠し関数 */
void do_T_com(char **argv)
{
HARC harc;
int r;
INDIVIDUALINFO info;
// jmp_buf old_start_env;
// int i;
printf("dwOriginalSize:dwCompressedSize:dwCRC:uFlag:uOSType:wRatio:wDate:wTime:szFileName:szAttribute:szMode\n");
// harc=TarOpenArchive(0,"c:\\tmp\\tst3.tgz",0);
harc=TarOpenArchive(0,Archives[0],0);
if (harc==0)return ;
r=TarFindFirst(harc,"",&info);
while(r==0){
printf("%d:%d:%d:%d:%d:%d:%d:%d:%s:%s:%s\n"
,info.dwOriginalSize
,info.dwCompressedSize
,info.dwCRC
,info.uFlag
,info.uOSType
,info.wRatio
,info.wDate
,info.wTime
,info.szFileName
,info.szAttribute
,info.szMode
);
r=TarFindNext(harc,&info);
}
TarCloseArchive(harc);
}
#endif /* #ifdef DLL */
/*
add Long File Name
*/
void addfile_lname(char *file, char *alias,struct stat statbuf)
{
int n, m;
char *buff;
char wname[FNAME_BUF], walias[FNAME_BUF];
char file2[FNAME_BUF];
char *lname="././@LongLink";
extern void set_filename_conversion(char *dest,char *src);/* in tardir.c */
set_filename_conversion(file2,file);
memset(wname,0,FNAME_BUF);
memcpy(wname,file2,NAMSIZ-1);
if (alias){
memset(walias,0,FNAME_BUF);
memcpy(walias,alias,NAMSIZ-1);
}
if (statbuf.st_mtime < From_when)
return;
buff_arch(TBLOCK, &buff);
memset(buff, 0, TBLOCK);
statbuf.st_size = FNAME_BUF;
encode_dir((HEADER *)buff, lname, &statbuf, LONGLINK);
write_arch(TBLOCK);
Current_file_name = lname;
Current_file_size = Current_file_left = strlen(alias == NULL ? file2 : alias);
Current_file_mode = statbuf.st_mode;
Current_file_mtime = statbuf.st_mtime;
m = 0;
n = buff_arch(-1, &buff);
strcpy(buff,noabsolute(alias == NULL ? file2 : alias));
n = Current_file_left;
write_arch(n);
/* printf("n = %d\n",n);*/
Current_file_left -= n;
m += n;
n = buff_arch(-1, &buff);
Current_file_left = 0;
n = -m & (TBLOCK - 1);
buff_arch(n, &buff);
memset(buff, 0, n);
write_arch(n);
}
/*
* Add a file or directory to archive
*/
void addfile(char *file_arg, char *alias)
{
int n, m;
int fd;
FLIST *dirs, *dp;
char *buff;
struct stat statbuf;
char file[FNAME_BUF];
char wname[FNAME_BUF], walias[FNAME_BUF];
{
/* 圧縮時に基準ディレクトリを考慮 (by tsuneo...) */
/* (例)下のような構成の場合、
C:\ <Root>
+ data\ <DIR>
+ data1.txt <FILE>
+ data2.txt <FILE>
+ data3.txt <FILE>
cvfz6 c:\test.tgz c:\data\ data1.txt data2.txt
と入れることで、data1.txt,data2.txtを圧縮する。 */
if(terget_path!=NULL){
if(make_filename(file,FNAME_BUF,terget_path,file_arg)==NULL){
Exitcode = ERROR_LONG_FILE_NAME;
fatal("addfile","cat't add basedirectory and filename(too long).");
}
if(alias==NULL){
alias=file_arg;
}
}else{
strcpy(file,file_arg);
}
}
if(OPTION_use_directory==0){
char *p;
/* ディレクトリ構造を保存しない場合*/
if((alias!=NULL) && (p=strrchr(alias,'/'))){
alias=p+1;
}else if((alias==NULL) && (p=strrchr(file,'/'))){
alias=p+1;
}
}
unixfn(file);
if (!stricmp(Archives[0],file)) /* at 1993-10-31 by tantan */
return;
else if (!strncmp(file,"./",2) && !stricmp(Archives[0],file+2))
return;
if (stat(file, &statbuf)) {
strcat(addsl(strcpy(wname, file)), "nul");
if (stat(wname, &statbuf)) {
error(file, NULL);
return;
}
/* maybe directory, like "", "/", "." at root */
statbuf.st_mode = S_IFDIR | 0755;
statbuf.st_size = 0;
statbuf.st_mtime = 0L; /* Not need */
}
if (alias == NULL)
alias = get_orgname(file);
if (strlen(file) >= NAMSIZ -1 || (alias != NULL && strlen(alias) >= NAMSIZ -1))
addfile_lname(file,alias,statbuf);
switch (statbuf.st_mode & S_IFMT) {
case S_IFDIR: /* directory */
statbuf.st_size = 0; /* for CD-ROM */
if (statbuf.st_mtime >= From_when && strlen(file) > 0) { /* 1995-3-1 by tantan */
if (Vflag) {
if (alias == NULL) {
fprintf(stderr, "add %s\n", file);
} else {
fprintf(stderr, "add %s(%s)\n", file, alias);
}
}
buff_arch(TBLOCK, &buff);
memset(buff, 0, TBLOCK);
encode_dir((HEADER *)buff, noabsolute(alias == NULL ? file : alias), &statbuf, DIRTYPE);
write_arch(TBLOCK);
#ifdef WIN32
if (psec_fp)
backup_sec(file,psec_fp);
#endif
}
dirs = get_dir(file);
if (dirs == NULL) {
error(file, NULL);
return;
}
for (dp = dirs; dp != NULL; dp = dp->next) {
if (strcmp(dp->name, ".") == 0
|| strcmp(dp->name, "..") == 0)
continue;
strcat(addsl(strcpy(wname, file)), dp->name);
if (alias == NULL) {
addfile(wname, NULL);
} else {
char *tmp; /* Add 4 line at 1993-10-31 by tantan */
if (tmp = get_orgname(wname))
strcpy(walias,alias = tmp);
else
strcat(addsl(strcpy(walias, alias)), dp->name);
addfile(wname, walias);
}
}
free_dir(dirs);
break;
case S_IFREG: /* Regular file */
if (statbuf.st_mtime < From_when)
return;
if ((fd = open(file, 0)) < 0) {
error(file, NULL);
return;
}
if (Aflag)
statbuf.st_size = realsize(fd);
if (Vflag) {
if (alias == NULL) {
fprintf(stderr, "%sadd %s, %ld bytes\n", gzip_flag ? "z_":"",
file, statbuf.st_size);
} else {
fprintf(stderr, "%sadd %s(%s), %ld bytes\n", gzip_flag ? "z_":"",
file, alias, statbuf.st_size);
}
}
buff_arch(TBLOCK, &buff);
memset(buff, 0, TBLOCK);
encode_dir((HEADER *)buff, noabsolute(alias == NULL ? file : alias), &statbuf, REGTYPE);
write_arch(TBLOCK);
#ifdef WIN32
if (psec_fp)
backup_sec(file,psec_fp);
#endif
Current_file_name = noabsolute(alias == NULL ? file : alias);
Current_file_size = Current_file_left = statbuf.st_size;
Current_file_mode = statbuf.st_mode;
Current_file_mtime = statbuf.st_mtime;
if(tarwin_executing_dialog_display_info()==-1){
Exitcode=ERROR_USER_CANCEL;
close(fd);
fatal("addfile","User Canceled");
}
m = 0;
for (;;) {
n = buff_arch(-1, &buff);
if ((n = read_a(fd, buff, n)) <= 0)
break;
write_arch(n);
/* printf("n = %d\n",n);*/
Current_file_left -= n;
m += n;
}
Current_file_left = 0;
close(fd);
#ifdef WIN32
{ /* restore last access time */
struct utimbuf ubuf;
if (Stealth_read_flag && NTFS_flag){
ubuf.actime = statbuf.st_atime;
ubuf.modtime = statbuf.st_mtime;
if (utime(file, &ubuf))
printf("Warning: utime can not change timestamp of %s\n",file);
}
}
#endif
n = -m & (TBLOCK - 1);
buff_arch(n, &buff);
memset(buff, 0, n);
write_arch(n);
/* printf("n = %d\n",n);*/
break;
default:
error(file, "Special file not added.");
break;
}
}
/*
* process -c, -r command
*/
char cao_flag=0; /* check over write flag */
void do_cr_com(char command, char **argv)
{
struct stat statbuf;
char *buff;
char name[FNAME_BUF];
char type;
char *p;
tarwin_executing_dialog_display();
#if P_up_V >=4
if(GZflag){
if(argv[0]==NULL){
Exitcode=ERROR_NOT_ARC_FILE;
fatal("do_cr_com","gzip file isn't specified");
}
if(argv[1]!=NULL){
Exitcode=ERROR_COMMAND_NAME;
fatal("do_cr_com","gzip file(G option) can archive 1 file only");
}
gzip_file(Archives[0],argv[0]);
return;
}
#endif
if (wild_flag){ /* by tantan at 1995-04-25 */
Exitcode=ERROR_COMMAND_NAME;
fatal("t command","Cant' use wild-card in this mode");
}
if ((p = get_dev_alias(".CHK_ARCHIVE_OVERWRITE")) != NULL){
if (stricmp(p,"YES") == 0)
cao_flag = YES;
}
if (Vflag && From_when != 1L)
fprintf(stderr, "Add files created/modified after %s", ctime(&From_when));
if(command=='r' && !existfile(Archives[0])){ /* ...tsuneo */
command='c';
}
open_arch(command == 'c' ? "w": "a");
if (command == 'r') {
/* seek to end of archive */
while (read_arch(TBLOCK, &buff) == TBLOCK) {
if (eofblock(buff))
break;
type = decode_dir(name, &statbuf, (HEADER *)buff);
if (type == VOLTYPE)
check_vol(name, &statbuf);
Current_file_name = name;
Current_file_mode = statbuf.st_mode;
Current_file_mtime = statbuf.st_mtime;
switch (type) {
case LNKTYPE:
case SYMTYPE:
break;
default:
Current_file_size = Current_file_left = statbuf.st_size;
skip_file();
break;
}
Current_file_left = 0;
}
if (start_write_arch(TBLOCK))
fatal("main", "Can't r");
}
if (*argv) {
char **xargv,**sargv;
expand_wild_card(argv,&xargv);
sargv = xargv;
#ifdef WIN32
NTFS_flag = getFStype(*xargv);
if (NTFS_flag && security_file ){
psec_fp = fopen(security_file,"wb");
if (psec_fp == NULL){
fatal(security_file,"Fail to open security descripsion file");
exit(1);
}
}
#endif
for (; *xargv; xargv++) {
FILE *fh;
char line[256], *p, *q, *fname, *alias;
/* kmtar のオリジナルの「@」引数のことは考えるのをやめ。*/
if (**xargv == '@' && (fh = fopen(*xargv + 1, "r")) != NULL) {
while (fgets(line, sizeof(line), fh) != NULL) {
p = line;
while (*p != '\0' && (unsigned char)*p <= ' ') {
p++;
}
if (*p == '\0') {
continue;
}
fname = p;
while (*p != '\0' && (unsigned char)*p > ' ') {
p++;
}
q = p;
while (*p != '\0' && (unsigned char)*p <= ' ') {
p++;
}
alias = p;
while (*p != '\0' && (unsigned char)*p > ' ') {
p++;
}
*q = '\0';
*p = '\0';
if (*alias == '\0') {
alias = NULL;
}
addfile(fname, alias);
}
fclose(fh);
} else {
addfile(*xargv, NULL);
}
}
/* sargv=xargvをcurrent_file_nameがさしている時free(*sargv)すると不定になるバグを訂正
by tsuneo(special thanks to Masaki Yasue)(1997/08/29)*/
if(Current_file_name){
Current_file_name=strcpy(name,Current_file_name);
}
for(;*sargv;sargv++)
free(*sargv);
} else {
addfile("", NULL);
}
/* write EOF mark */
buff_arch(TBLOCK, &buff);
memset(buff, 0, TBLOCK);
write_arch(TBLOCK);
buff_arch(TBLOCK, &buff);
memset(buff, 0, TBLOCK);
write_arch(TBLOCK);
close_arch(command);
Current_file_name=NULL;
}
char *wild_card(char *str, WIN32_FIND_DATA *buf)
{
char *p,*ss;
static char name_buf[FNAME_BUF];
unixfn(strcpy(name_buf,str));
ss = name_buf - 1;
for(p = name_buf;*p;p++){ /* serach last '\' ,'/', ':' */
if (*p =='/' || *p == ':')
ss = p;
}
sprintf(ss+1,"%s\x0",buf->cFileName);
return name_buf;
}
void *xrealloc(char *str,size_t ss)
{
void *p;
if ((p = realloc(str,ss)) == NULL){
Exitcode=ERROR_ENOUGH_MEMORY;
fatal("realloc","Out of memeory");
}
return p;
}
char *xstrdup(char *str)
{
char *p;
if ((p = strdup(str)) == NULL){
Exitcode=ERROR_ENOUGH_MEMORY;
fatal("strdup","Out of memeory");
}
return p;
}
static void expand_wild_card(char **argv,char ***xargv)
{
int i;
HANDLE hFile=INVALID_HANDLE_VALUE;
/*struct stat stbuf;*/
WIN32_FIND_DATA fbuf;
*xargv = NULL;
/* printf("%s\n",fbuf.name);*/
for(i=2;*argv;argv++,i++){ /* 1 余分にとっている */
*xargv = (char **)xrealloc((char *)*xargv,i*sizeof(char **));
if (strpbrk("*?",*argv)){
int ii= 0;
char abs_argv[FNAME_BUF];
/* 基準ディレクトリを考慮に入れ、*argv->abs_argvと変更する。by tsuneo... */
if(make_filename(abs_argv,FNAME_BUF,terget_path,*argv)==NULL){
Exitcode = ERROR_LONG_FILE_NAME;
fatal("addfile","cat't add basedirectory and filename(too long).");
}
/*argv -> abs_argv by tsuneo */
if ((hFile = FindFirstFile(abs_argv,&fbuf)) != INVALID_HANDLE_VALUE){
do{
if ( (fbuf.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN |
/* FILE_ATTRIBUTE_DIRECTORY | (commentout by tsuneo)*/FILE_ATTRIBUTE_SYSTEM)) != 0 )
continue;
/* by tsuneo (1997.8.28) */
if(strcmp(fbuf.cFileName,".")==0 || strcmp(fbuf.cFileName,"..")==0){
continue;
}
/* OPTION_use_directory=1のときは、ワイルドカードもディレクトリにマッチする(再起圧縮) */
/* by tsuneo (1997.8.28) */
if ( (OPTION_use_directory==0) && (fbuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
continue;
}
/*
意味不明につき削除... by tsuneo (1997.08.28)
if (fbuf.nFileSizeLow == 0){
stat(fbuf.cFileName,&stbuf);
if (stbuf.st_size != 0)
continue;
}
*/
if (ii == 0)
ii =1;
else
i++;
*xargv = (char **)xrealloc((char *)*xargv,i*sizeof(char **));
(*xargv)[i-2] = xstrdup(wild_card(*argv,&fbuf));
}while(FindNextFile(hFile,&fbuf)==TRUE);
}else{
(*xargv)[i-2] = xstrdup(*argv);
continue;
}
/* kmtar 0.96->0.97*/
if (hFile != INVALID_HANDLE_VALUE)
FindClose(hFile);
}else
(*xargv)[i-2] = xstrdup(*argv);
}
if (i==2)
*xargv = (char **)xrealloc((char *)*xargv,2*sizeof(char **));
(*xargv)[i-2] = NULL;
/* FindClose(hFile); remove kmtar 0.96->0.97*/
}
void erase_alloced_mem(void)
{
extern void erase_rename_table(void);
erase_rename_table();
}
/*
* Entry point
*/
/* main関数はmainmain.cに移動する。*/
#ifdef DLL
int tar_main(int argc,char *argv[]){
#else
void main(int argc, char *argv[]){
#endif
volatile char *p,*stok_wildcard=0;
volatile char **archp;
volatile char command;
extern void free_io_buff(void);
extern unsigned long innerbuf_len;
HANDLE hFile;
WIN32_FIND_DATA find_buf;
#ifdef DLL
{
int return_value=setjmp(start_env);
if(return_value!=0){
ioctrl_output_end();
return return_value;
}
ioctrl_output_init_test();
static_init_all();
}
#endif
if (argc < 2) {
usage();
exit(ERROR_COMMAND_NAME);
}
#ifdef STANDARD_INDIRECT_EXPAND
setup_arguments(&argc,&argv);
#endif
#ifdef FORSE_BINARY_MODE
_fmode = _O_BINARY;
#endif
command = '\0';
archp = Archives;
for (argv++; *argv; ) {
p = *argv++;
if(strncmp((char *)p,"--",2)==0){
/* 長いオプション(「--」で始まるもの)はここで処理する。*/
char *key,*cont;
char tmparg[100];
char *p2;
/* --foo=bar を key="foo",cont="bar"とする。*/
p+=2;
if(strlen((char *)p)>=100){
Exitcode=ERROR_COMMAND_NAME;
fatal(argv[-1],"Illegal Long Option");
}
strcpy(tmparg,(char *)p);
key=tmparg;
if((p2=strchr(tmparg,'='))!=NULL){
*p2='\0';
cont=(char *)p2+1;
}else{
cont=NULL;
}
if(strcmp(key,"long-option-test")==0 && cont){
printf("long-option-test:cont=[%s]\n",cont);
}else if(strcmp(key,"nkf-set-filename-conversion")==0 && cont){
strcpy(OPTION_nkf_set_filename_conversion,cont);
}else if(strcmp(key,"nkf-get-filename-conversion")==0 && cont){
strcpy(OPTION_nkf_get_filename_conversion,cont);
}else if(strcmp(key,"use-directory")==0 && cont){
OPTION_use_directory=atoi(cont);
}else if(strcmp(key,"check-all-path")==0 && cont){
OPTION_check_all_path=atoi(cont);
}else if(strcmp(key,"display-dialog")==0 && cont){
OPTION_check_all_path=atoi(cont);
}else{
printf("key=[%s],contents=[%s] is incorrect\n",key,cont==NULL?"":cont);
Exitcode=ERROR_COMMAND_NAME;
fatal(argv[-1],"Invalid Long Option");
}
continue;
}
if (*p == '-')
p++;
for (; *p; p++) {
switch (*p) {
case 'c':
case 'r':
case 'x':
case 't':
#ifdef DLL
case 'T':
#endif
case 'k':
if (command){
Exitcode=ERROR_COMMAND_NAME;
fatal(argv[-1], "2 or more commands");
}
command = *p;
break;
case 'V':
Sflag = YES;
/* fall thru */
case 'v':
Vflag = YES;
break;
case 'a':
Aflag = YES;
break;
case 'A': /* Attribute flag */
switch (p[1]){
case 'A':
attri_flag = FILE_ATTRIBUTE_ARCHIVE;
p++;
break;
case 'H':
attri_flag = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
p++;
break;
}
break;
case 'm':
case 'M':
Mflag = YES;
break;
case 'y':
Yflag = YES;
break;
case 'i':
Iflag = YES;
break;
case 'I':
IFAflag = YES;
break;
case 'E':
Veflag = YES;
break;
case 'l':
Limitflag = YES;
if (p[1] >= '1' && p[1] <= '9'){
w_limit = atoi((const char *)&p[1]);
p++;
}
break;
case 'Z': /* gzip flag */
level = 1; /* -Z means fast compress */
case 'z': /* gzip flag */
#if defined(GZIP)
gzip_flag=1;
if (p[1] >= '1' && p[1] <= '9'){
level = p[1] - '0';
p++;
}
#endif
break;
case 'e':
EucFlag = YES;
break;
#if P_up_V>=4
case 'G': /* Only gzip or gunzip or compress -d ...tsuneo */
GZflag=YES;
break;
case 'p': /* print out to stdout ...tsuneo */
Pflag=YES;
break;
#else
case 'p':
#endif
case 'P': /* define PC type */
switch (p[1]){
case 'A':
MACHINE = AT;
p++;
break;
case '9':
MACHINE = PC98;
p++;
break;
case 'F':
MACHINE = FM;
p++;
break;
}
break;
case 'n':
nomes_flag = YES;
break;
case 'f':
if (*argv == NULL)
goto opterr;
if (archp >= Archives + height(Archives) - 1){
Exitcode=ERROR_COMMAND_NAME;
fatal("main", "Too many -f");
}
unixfn(*argv); /* at 1993-10-31 by tantan */
*archp++ = *argv++;
break;
case 'b':
if (*argv == NULL)
goto opterr;
Nblocks = atoi(*argv++);
break;
case 'q':
NewNameFlag = 1;
break;
#ifdef WIN32
case 'S':
Stealth_read_flag = YES;
break;
case 's':{ /* security description file */
int n;
if (*argv == NULL)
goto opterr;
security_file = unixfn(*argv++);
n = strlen(security_file);
if (n < 1)
goto opterr;
break;
}
#endif
case 'o':{
int n;
case_o:
if (*argv == NULL)
goto opterr;
terget_path = unixfn(*argv++);
n = strlen(terget_path);
if (n < 1)
goto opterr;
--n;
if (terget_path[n] == '/')
terget_path[n] = '\0';
break;
}
case 'N': {
struct stat statbuf;
if (*argv == NULL)
goto opterr;
if (stat(*argv, &statbuf) == 0)
From_when = statbuf.st_mtime;
else
From_when = __getdate(*argv);
if (From_when < 1L)
fatal(*argv, "Bad date");
argv++;
break;
}
case 'g':
Gflag = YES;
break;
opterr:
default:
Exitcode=ERROR_COMMAND_NAME;
fatal(argv[-1], "Bad option");
}
}
if (*argv == NULL || **argv != '-' || (*argv)[1] == '\0'){
if(*argv!=NULL && strchr("\\/",(*argv)[strlen(*argv)-1])!=NULL){
/* \か/で終わってる時は、基準ディレクトリとして設定する。*/
if( (command == 'x')
|| ((command=='r' || command=='c') && (*(argv+1)!=NULL))){
argv++;
argv--; /* -o オプションと同じように、argvに基準ディレクトリが入るようにする*/
p=(*argv)+strlen(*argv)-1;/* *(p+1)=='\0'とする*/
goto case_o; /* またgotoを使ってしまった...*/
}
}
break;
}
}
*archp = NULL;
if (Archives[0] == NULL) {
Archives[0] = getenv("TAPE");
if (Archives[0] == NULL)
Archives[0] = getenv("TARDEV");
#ifndef WIN32
if (Archives[0] == NULL)
Archives[0] = get_dev_alias(".DEFAULT");
#endif
#if 0 /* this code sleeping */
if (Archives[0] == NULL)
Archives[0] = "/dev/rfd1";
#else
if (Archives[0] == NULL){
fprintf(stderr,"tar:Archive file not set\n");
exit(ERROR_NOT_ARC_FILE);
}
#endif
Archives[1] = NULL;
}
read_rule_file(argv);
/* fprintf(stderr,"Archives[0] = %s\n",Archives[0]);*/
if (strpbrk(Archives[0],"*?") != NULL){ /* check wild caed */
wild_flag = YES;
stok_wildcard = Archives[0];
g_command = command;
}
if (wild_flag == YES && (hFile = FindFirstFile((char *)stok_wildcard, &find_buf)) == INVALID_HANDLE_VALUE )
wild_flag = NO;
#ifdef DLL
{
/* 残りの引数(ファイル名リスト)の「\」を「/」に変換 */
char **ptr;
for(ptr=argv;*ptr;ptr++){
unixfn(*ptr);
}
}
#endif
do {
if (wild_flag){
/* kmtar 0.96->0.97 */
if (find_buf.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_TEMPORARY))
continue;
if ((attri_flag & FILE_ATTRIBUTE_SYSTEM) == 0 &&
find_buf.dwFileAttributes & (FILE_ATTRIBUTE_SYSTEM |FILE_ATTRIBUTE_HIDDEN) )
continue;
if ((attri_flag & FILE_ATTRIBUTE_ARCHIVE) &&
!(find_buf.dwFileAttributes & (FILE_ATTRIBUTE_ARCHIVE)))
continue;
if (command == 't' && setjmp(jmp_env) != 0){
erase_alloced_mem();
continue;
}
Archives[0] = wild_card((char *)stok_wildcard,&find_buf);
printf("Archive name=%s\t",Archives[0]);
if (command != 't' || nomes_flag==0)
printf("\n");
}
switch (command) {
case 'c':
case 'r':
do_cr_com(command, argv);
break;
case 'x':
do_x_com(argv);
break;
case 't':
do_t_com(argv);
break;
#ifdef DLL
case 'T':
do_T_com(argv);
break;
#endif
case 'k':
do_k_com(argv);
break;
default:
Exitcode=ERROR_COMMAND_NAME;
fatal("main", "No command specified");
}
erase_alloced_mem();
if (command == 't' && nomes_flag && wild_flag)
printf("\r%80s\r"," ");
}while(wild_flag != 0 && FindNextFile(hFile,&find_buf)==TRUE);
if (wild_flag && hFile != INVALID_HANDLE_VALUE) /* kmtar 0.96->0.97 */
FindClose(hFile);
free_io_buff();
#ifdef DLL
/* APIを使ってるデバッグ用のTコマンドだけ特別。。
(すでにsetjmpは使ってるので。。) */
if(command=='T'){
ioctrl_output_end();
return Exitcode;
}
#endif
exit(Exitcode);
}
#ifdef DLL
void main_static_init(void){
/* global char *Progname = "tar";*/
Exitcode=0;
Veflag=0;
Vflag=0;
Sflag=0;
Aflag=0;
#ifdef WIN32
Stealth_read_flag = NO;
#endif
NewNameFlag = 0; /* 0:overwrite 1:unique */
Mflag=0;
Yflag=0;
Gflag=0;
Iflag=0;
#if P_up_V >=4
Pflag=0;
GZflag=0;
#endif
/* global jmp_buf jmp_env;*/
wild_flag = NO;
nomes_flag = 0;
g_command=0;
EucFlag=0;
IFAflag=0;
attri_flag=0; /* kmtar 0.96->0.97*/
memset(Archives,0,sizeof(char *)*10);
MACHINE = -1;
terget_path=NULL;
gzip_flag = 0;
//extern int level;
Limitflag = 0;
w_limit = 0;
#ifdef USE_NKF_DLL
/* ファイル名設定時のnkfの漢字コード変換オプション */
strcpy(OPTION_nkf_set_filename_conversion
,DEFAULT_OPTION_nkf_set_filename_conversion);
/*ファイル名取得時のnkfの漢字コード変換オプション*/
strcpy(OPTION_nkf_get_filename_conversion
,DEFAULT_OPTION_nkf_get_filename_conversion);
#endif
OPTION_use_directory=1; /* ディレクトリ付き圧縮/展開をするか?*/
OPTION_check_all_path=0;
OPTION_display_dialog=1; /* Window表示を行うか? by tsuneo */
#ifdef WIN32
NTFS_flag=0;
psec_fp=0;
security_file=NULL; /* NTFS security file name */
//int getFStype(char *name); /* get file system type */
//void restore_sec(char *name,FILE *fp);
//void backup_sec(char *name,FILE *fp);
#endif
From_when=1L; /* unsigned type */
//#define height(a) (sizeof(a) / sizeof((a)[0]))
memset(Done,0,sizeof(bool)*MAXARG);
cao_flag=0; /* check over write flag */
}
/* すべての静的変数(グローバル変数も)を初期化する。*/
void static_init_all(void)
{
extern void trees_static_init(void);
extern void deflate_static_init(void);
main_static_init();
arch_static_init();
chkfname_static_init();
zip_static_init();
gzip_static_init();
compapi_static_init();
deflate_static_init();
trees_static_init();
load_registry_info();
}
/* 終了時処理(主にメモリの開放)
(関数名が変になってしまった(^^; )
*/
void static_free_all(void)
{
}
#endif