#include "modern.h" #ifdef MODERN # include # include # ifdef ZMEM # define MEMCPY(d,s,n) strcpy(d,s) # endif # ifdef NOMEMCPY # define MEMCPY(d,s,n) strcpy(d,s) # endif # ifndef MEMCPY # define MEMCPY(d,s,n) memcpy(d,s,n) # endif # ifdef __TURBOC__ # include # endif #else # define MEMCPY(d,s,n) strcpy(d,s) char *strcpy(), *getenv(), *malloc(), *realloc(); int strlen(); #endif #include #include "define.h" #include "lzwbits.h" #ifdef MSDOS # define switchar(c) ((c)=='-' || (c)=='/') #else # define switchar(c) ((c)=='/') #endif void revector(argc, argv, n) char ***argv; { register i; /* create new argument vector */ i = (int)((argc + n) * sizeof(char *)); if (argvector) { free(argvector); if ((argvector=(char**)realloc(argvector, i)) == NULL) outmem(stderr); } else { argvector = (char **)salloc(i); /* copy origin arguments */ for (i=0; i= INDMAX) { (void)fprintf(stderr, "Tar: \'%s\' exceeds limit in size\n", fname); done(ERRARG); } p = salloc((l = (int)st.st_size) + 1); /* Note: effective text file size differs from the real one under MS-DOS */ if ((l = read(i, p, l)) < 1) { (void)fprintf(stderr, "Tar: can\'t read \'%s\'\n", fname); done(ERRARG); } (void)close(i); } else if ((st.st_mode & S_IFMT) == S_IFCHR || /* character device */ (st.st_mode & S_IFMT) == S_IFIFO) { /* pipe */ int j, m; long s; for (s=0, m=INDMAX+1; m>=INDMIN; ) { if ((p = malloc(m)) != NULL) goto ok; m = ((m+INDLOW) & ~INDLOW) / 2; } outmem(stderr); ok: s = 0; do { l = (int)s; j = read(i, p+l, m-l); s += j; } while (j>0 && s= m) { if (m < INDMAX) { outmem(stderr); } else { (void)fprintf(stderr,"Tar: \'%s\' exceeds limit in size\n",fname); done(ERRARG); } } if (l+1 < m) { free(p); if ((p = realloc(p, l+1)) == NULL) { (void)fprintf(stderr, "Tar: error shrinking memory block\n"); done(ERRARG); } } } else { (void)fprintf(stderr, "Tar: \'%s\' not a file\n", fname); done(ERRARG); } p[l] = '\0'; return buildarg(argc, argv, (*buf=p)); } int envbuild(argc, argv) char ***argv; { register i; register char *p; if ((p = getenv("TARCMD")) == NULL) return 0; i = strlen(p); if (!i) return 0; #ifdef UNIX # define ARGFILE if (p[0] == '/') #endif #ifdef MSDOS # define ARGFILE if (((p[0] <= 'A' && p[0] >= 'Z') || (p[0] <= 'a' && p[0] >= 'z')) && p[1] == ':' && p[2] == '\\' || p[0]=='\\') #endif #ifdef ARGFILE return argfile(argc, argv, p, &tarcmd); #endif #if 0 /*ndef MSDOS*/ /* Make a copy of environment variable to avoid protection problems */ tarcmd = salloc(i+1); (void)MEMCPY(tarcmd, p, i+1); p = tarcmd; #endif return buildarg(argc, argv, p); } /* ARGSUSED */ static void readblk(p, argv, i) char **p, **argv; int *i; { register char *s; register n; if (cblock) { (void)fprintf(stderr, "Tar: blocksize multiply defined\n"); done(ERRARG); } s = argv[++*i]; for (cblock=0,n=0; digit(*s) && n<3; ++n,s++) cblock = *s-'0' + 10*cblock; if (n>0 && n<=2) { if (*s == 'k' || *s == 'K') { cblock *= 2; s++; } else if (*s == 'b' || *s == 'B') s++; if (*s=='\0' && cblock>0 && cblock<=MAXBLOCK) /* blocksize ok */ return; } (void)fprintf(stderr, "Tar: bad blocksize (max is %d)\n", MAXBLOCK); done(ERRARG); #ifdef __TURBOC__ (void)p; #endif } #ifdef MSDOS static void readvol(p, argv, i) char **p, **argv; int *i; { register char *s; register n; if (k_flag || tapename) { (void)fprintf(stderr, "Tar: tape device multiply defined\n"); done(ERRARG); } k_flag = TRUE; s = argv[++*i]; for (volume=0, n=0; digit(*s) && n<7; ++n,s++) volume = *s-'0' + 10*volume; if (n>0 && n<=6) { if (*s == 'm' || *s == 'M') { volume <<= 11; ++s; } else if (*s == 'k' || *s == 'K') { volume += volume; ++s; } else if (*s == 'b' || *s == 'B') ++s; else volume += volume; if ((volume & ~0x7FFE) == 0) if (*s=='\0' && argdisk((int)volume >> 1) == 0) /* diskette size ok */ return; } (void)fprintf(stderr, "Tar: Invalid diskette size\n"); done(ERRARG); #ifdef __TURBOC__ (void)p; #endif } #endif /* ARGSUSED */ static void readpk(p, argv, i) char **p, **argv; int *i; { register c; c = (*p)[0]; if (c>='A' && c<='Z') c += 'z'-'Z'; if (pktype != PKNONE) { (void)fprintf(stderr,"Tar: compression method multiply defined\n"); done(ERRARG); } if (c == 'z' || c == ',') { pktype = c==',' ? PKpLZW : PKfLZW; lzwbits = BITS; if ((*p)[1] == '9') { *p += 1; lzwbits = 9; } else if ((*p)[1] == '1') { *p += 2; lzwbits = 10 + **p - '0'; if (lzwbits < 10 || lzwbits > BITS) { (void)fprintf(stderr, "Tar: Invalid bits factor\n"); done(ERRARG); } } } else { pktype = c=='.' ? PKZIP : PKDEF; ziplevel = 6; /* default */ if (digit((*p)[1])) { *p += 1; ziplevel = **p - '0'; } } #ifdef __TURBOC__ (void)argv; (void)i; #endif } #ifdef MSDOS /* ARGSUSED */ static void devno(p, argv, i) char **p, **argv; int *i; { ndrive = **p & 7; setdrive = TRUE; #ifdef __TURBOC__ (void)argv; (void)i; #endif } #endif static void readxcl(p, argv, i) char **p, **argv; int *i; { if (xcnt >= XMAX) { (void)fprintf(stderr,"Tar: too many \'%s\'s\n", **p ? "#" : argv[*i]); done(ERRARG); } xarg[xcnt++] = argv[++*i]; } #define TO_APP '\377' #define TO_INC '\376' #define TO_REM '\375' #define TO_CALL '\374' #define MAXOPT 8 #ifdef MODERN # ifdef __MEDIUM__ # define NF void far * # else # define NF void * # endif #endif static struct { union { #ifdef NF NF __dummy__; #endif char *flag; char **str; void (*fun) __ARGS__((char**, char**, int*)); } p; char longop[MAXOPT], shortop; char optype, xflag; } oplist[] = { { &a_flag, "append", 'a', TRUE, 0}, { &a_flag, "append", 'r', TRUE, 0}, { &c_flag, "create", 'c', TRUE, 0}, { &x_flag, "extract", 'x', TRUE, 0}, { &t_flag, "list", 't', TO_INC, 0}, { &y_flag, "move", 'y', TRUE, 0}, { &u_flag, "update", 'u', TRUE, 0}, { &d_flag, "delete", 'd', TRUE, 0}, { &v_flag, "verbose", 'v', TO_INC, 0}, { &w_flag, "interact",'w', TRUE, 0}, { &i_flag, "inhibit", 'i', TRUE, 0}, { &s_flag, "strict", 's', TRUE, 0}, { &m_flag, "modifica",'m', TRUE, 0}, { &j_flag, "comment", 'j', TRUE, 0}, { &nonest, "nonest", 'n', TRUE, 0}, { &o_flag, "", 'o', TRUE, 0}, #ifdef UNIX { &dslash, "", '/', TRUE, 0}, { &l_flag, "link-war",'l', TRUE, 0}, { &p_flag, "permissi",'p', TRUE, 0}, { &ndrive, "", '0', 0, 0}, { &ndrive, "", '1', 1, 0}, { &ndrive, "", '2', 2, 0}, { &ndrive, "", '3', 3, 0}, { &ndrive, "", '4', 4, 0}, { &ndrive, "", '5', 5, 0}, { &ndrive, "", '6', 6, 0}, { &ndrive, "", '7', 7, 0}, #endif #ifdef MSDOS { &dslash, "", '\\',TRUE, 0}, { &l_flag, "link-cop",'l', TRUE, 0}, { readvol, "", 'k', TO_CALL, 0}, { &deldrv, "", ':', TRUE, 0}, { devno, "", '0', TO_CALL, 0}, { devno, "", '1', TO_CALL, 0}, { devno, "", '2', TO_CALL, 0}, { devno, "", '3', TO_CALL, 0}, #endif { &tapename,"file", 'f', TO_REM, 0}, { readblk, "block-si",'b', TO_CALL, 0}, { NULL, "", '@', TO_APP, 0}, { readxcl, "exclude", '#', TO_CALL, 0}, { readpk, "", ',', TO_CALL, 0}, { readpk, "", '.', TO_CALL, 0}, { readpk, "", 'e', TO_CALL, 0}, { readpk, "", 'z', TO_CALL, 0}, { &pktype, "compress", 0, PKpLZW, 0}, { &pktype, "zip-arch", 0, PKZIP, 0}, { &pktype, "zip-file", 0, PKDEF, 0}, { &gnuzip, "gzip", 0, TRUE, 0}, { &gnuzip, "gnu", 0, TRUE, 0}, }; void cleanopt() { register i; for (i=0; i1 || x1>1) { (void)fprintf(stderr, "Tar: ambiguous options\n"); if (to_break) done(ERRARG); } } int readopt(argc, argv, aux) int *argc; char ***argv; { register c; register j, k; char lex[MAXOPT]; char *p; int i; char *fl[5]; if (*argc < 1) { (void)fprintf(stderr, "Tar: no options to read\n"); done(ERRARG); } for (i=0; i<*argc; i++) { p = (*argv)[i]; if (switchar(*p)) { if (p[1] == '\0') goto end; if (p[1] != '-' || p[0] != '-') ++p; } else if (*p != '+' && i) goto end; if (p[0]!='+' && (p[0]!='-' || p[1]!='-')) { for (;*p; p++) { c = *p; if (switchar(c)) goto end; if (c>='A' && c<='Z') c += 'z'-'Z'; for (k=0; k='A' && c<='Z') c += 'z'-'Z'; lex[j++] = c; } } if (!j) goto end; for (k=0; k