/* store.c - storying files into (tape) archive * This is the part of the Tar program (see file tar.c) * Author: T.V.Shaporev * Creation date 14 Dec 1990 */ #include #include "sysup.h" #include "nodedef.h" #include "modern.h" #include "define.h" char longname[] = "Tar: \'%s\' name too long%s"; #ifdef unix # ifdef sun # ifndef STDDIR # define STDDIR # endif # include # define DIRENT struct dirent # define namelen(d) strlen((d)->d_name) # endif # ifdef i386 # ifndef STDDIR # define STDDIR # endif # include # define DIRENT struct dirent # define namelen(d) strlen((d)->d_name) # else # ifdef M_XENIX # ifndef STDDIR # define STDDIR # endif # include # define DIRENT DIR # define namelen(d) ((d)->d_namlen) # endif # endif #endif #ifdef UNIX # ifndef STDDIR # include # endif #endif #ifdef MSDOS # include # ifdef __TURBOC__ # include # else # include # endif # include #else int strlen(); char *strcpy(), *strcat(), *strncpy(); int open(), read(), close(); # ifdef RMKDIR int rmdir(); # endif long lseek(); #endif #define dotname(n) ((n)[0]=='.' && ((n)[1]=='\0'||((n)[1]=='.'&&(n)[2]=='\0'))) void proctl __ARGS__(( char *, long )); void procts __ARGS__(( char *, short, char )); void prcsum __ARGS__(( register header * )); void newhead __ARGS__(( char *, long )); char *deleft __ARGS__(( char * )); void nullblock(h) header *h; { register i; for (i=0; i0 && (l>>=3)!=0); while (i>0) dest[--i] = ' '; } void procts(dest, s, suffix) char dest[]; short s; char suffix; { register int i; dest[7] = 0; dest[i = 6] = suffix; do dest[--i] = (s & 7) | '0'; while (i>0 && (s>>=3)!=0); while (i>0) dest[--i] = ' '; } void prcsum(h) register header *h; { register i; /* for the sake of compatibility */ for (i=0; i<8; i++) (h->m.chksum)[i] = ' '; procts(h->m.chksum, headsum(h), 0); } void newhead(filename, filesize) char *filename; long filesize; { nullblock(hblock = steptape()); procts(hblock->m.mode, (short)st.st_mode & 07777, ' '); procts(hblock->m.uid, (short)st.st_uid, ' '); procts(hblock->m.gid, (short)st.st_gid, ' '); proctl(hblock->m.size, filesize); proctl(hblock->m.mtime, st.st_mtime); (void)strncpy(hblock->m.name, filename, MAXTNAME); } char *deleft(p) register char *p; { #ifdef MSDOS if (deldrv && p[1] == ':' && (p[0]>='A' && p[0]<='Z' || p[0]>='a' && p[0]<='z')) p += 2; #endif if (dslash && *p == '/') ++p; return p; } void store(fname) char *fname; { register i; register j; register unsigned m; static level = 0; #ifdef UNIX register char *p; # ifdef STDDIR register DIR *d0; register DIRENT *dp; # else register char *q; struct direct d_buf; int infile; # endif #endif #ifdef MSDOS register k; struct ffblk ff; #endif if (cbreak) done(EXIT); ++level; if (strlen(fname) > MAXTNAME) { (void)fprintf(myout, longname, fname, "\n"); goto end; } #ifdef MSDOS i = FALSE; for (j=strlen(fname); j>0 && fname[j-1]!='/' && fname[j-1]!=':'; j--) { if (fname[j-1]=='?' || fname[j-1]=='*') i = TRUE; } if (i) { k = findfirst(fname, &ff, filemask); while (k==0 && dotname(ff.ff_name)) k = findnext(&ff); if (k) { if (level < 2) (void)fprintf(myout,"Tar: can\'t find \'%s\'\n",fname); goto end; } do { takename(fname+j, ff.ff_name); store(fname); } while (findnext(&ff) == 0); goto end; } #endif for (i=0; i 1) goto end; #ifdef UNIX if (p_flag) {/* save directory & permissions */ newhead((p = deleft(fname)), 0L); if ((j = strlen(p)) < MAXTNAME-1) { hblock->m.name[j+1] = '\0'; } else { j = MAXTNAME-1; } hblock->m.name[j] = '/'; prcsum(hblock); } # ifdef STDDIR if ((d0 = opendir(fname)) == NULL) { (void)fprintf(myout, "Tar: can\'t open directory \'%s\'\n", fname); goto end; } fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0; for (dp=readdir(d0); dp; dp=readdir(d0)) { j = namelen(dp); if (j==0 || (j==1 && (dp->d_name)[0]=='.') || (j==2 && (dp->d_name)[0]=='.' && (dp->d_name[1])=='.')) continue; for (i=0; id_name)[i]; p[j] = 0; store(fname); } closedir(d0); # else if ((infile = open(fname, O_RDONLY)) < 0) { (void)fprintf(myout, "Tar: can\'t open file \'%s\'\n", fname); goto end; } fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0; i = 0; while (read(infile, (char*)&d_buf, sizeof(d_buf)) > 0 && !cbreak) { if (d_buf.d_ino!=0 && !dotname(d_buf.d_name)) { q = p; for (j=0; jm.filetype = TF_QUE; } else { hblock->m.filetype = m == S_IFBLK ? TF_BLK : TF_CHR; procts(hblock->x.devmajor, major(st.st_rdev), ' '); procts(hblock->x.devminor, minor(st.st_rdev), ' '); } prcsum(hblock); } else #endif (void)fprintf(myout, "Tar: \'%s\' not a file\n", fname); } end: --level; }