#include #include #include "ndir.h" #include "ftw.h" #include "detar.h" extern FILE *ftar; extern int qblk, blocks; extern char *tbuf; extern char *tounix(); /* char * */ extern void tooct(),calc_chksum(); extern int tfile, type, verbos; static union record tar_rec; static struct stat *stbuf; /* calculate number of blocks that are left in the buffer for a file read */ /* operation. Limit the block count to under 128 (64K) though */ char *getblks(rbytes) long *rbytes; { int btd; if(tfile) { *rbytes = 512L; return(&tbuf[0]); } btd = blocks - qblk; *rbytes = (long)(btd) * 512L; return(&tbuf[(long)(qblk) * 512L]); } static void dump_header(name,x) char *name;int x; { long dummy; extern char *getblks(); lzero(tar_rec.charptr,(RECORDSIZE >> 2)); strncpy(tar_rec.header.name,tounix(name),NAMSIZ); tooct(0644L,8,tar_rec.header.mode); tooct(0L,8,tar_rec.header.uid); tooct(0L,8,tar_rec.header.gid); tooct(stbuf->st_size,12,tar_rec.header.size); tooct(stbuf->st_mtime,12,tar_rec.header.mtime); strncpy(tar_rec.header.magic,TMAGIC,8); strncpy(tar_rec.header.chksum,CHKBLANKS,8); tar_rec.header.linkflag=x+'0'; calc_chksum(&tar_rec); if(tfile) { fwrite(tar_rec.charptr, 1, RECORDSIZE, ftar); qblk = 0; } else { lcopy(tar_rec.charptr, getblks(&dummy), RECORDSIZE >> 2); qblk += 1; if(qblk >= blocks) twritef(qblk); } } static void dump_file(name) char *name; { FILE *fin; long rbytes, n, blks; char *bptr; extern char *getblks(); fin=fopen(name,"rb"); if(type || verbos) { printf("a %s", tar_rec.header.name); if(verbos) { printf(" %8ld", stbuf->st_size); blks = stbuf->st_size >> 9; if(stbuf->st_size % 512L) blks += 1L; printf(" %8ld blocks", blks); } printf("\n"); } if(!tfile) { do { bptr = getblks(&rbytes); n = Fread((int)(fin->_fd), rbytes, bptr); qblk += hmbr(n); if(qblk >= blocks) twritef(qblk); } while(n==rbytes); } else { do { n=fread(tar_rec.charptr,1,RECORDSIZE,fin); if(n < RECORDSIZE) bzero(tar_rec.charptr+(long)(n), RECORDSIZE-n); fwrite(tar_rec.charptr,1,RECORDSIZE,ftar); }while(n==RECORDSIZE); } fclose(fin); } int create_tar(name,sbuf,flag) char *name; struct stat *sbuf; int flag; { stbuf=sbuf; switch(flag) { case FTW_NS: fprintf(stderr,"tar:can't stat %s\n",name); return -1; case FTW_DNR: fprintf(stderr,"tar:can't open directory %s\n"); return -2; case FTW_F: dump_header(name,0); dump_file(name); return 0; case FTW_D: strcat(name,"\\"); dump_header(name,5); return 0; } } /* get the acutal number of bytes read and convert to block count */ int hmbr(bread) long bread; { int btb; if(!bread) return(0); btb = bread >> 9; if(bread % 512L) btb += 1; return(btb); }