int rflag
, xflag
, vflag
, tflag
, mt
, cflag
, mflag
;
int term
, chksum
, wflag
, recno
, first
, linkerrok
;
char tname
[] = "/tmp/tarXXXXXX";
char magtape
[] = "/dev/mt1";
int onintr(), onquit(), onhup(), onterm();
for (cp
= *argv
++; *cp
; cp
++)
if ((tfile
= fopen(tname
, "w")) == NULL
) {
fprintf(stderr
, "Tar: cannot create temporary file (%s)\n", tname
);
fprintf(tfile
, "!!!!!/!/!/!/!/!/!/! 000\n");
if (nblock
!= 1 && cflag
== 0) {
fprintf(stderr
, "Tar: Blocked tapes cannot be updated (yet)\n");
if (nblock
> NBLOCK
|| nblock
<= 0) {
fprintf(stderr
, "Invalid blocksize. (Max %d)\n", NBLOCK
);
fprintf(stderr
, "tar: %c: unknown option\n", *cp
);
if (cflag
&& tfile
!= NULL
) {
if (signal(SIGINT
, SIG_IGN
) != SIG_IGN
)
if (signal(SIGHUP
, SIG_IGN
) != SIG_IGN
)
if (signal(SIGQUIT
, SIG_IGN
) != SIG_IGN
)
if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
if (strcmp(usefile
, "-") == 0) {
fprintf(stderr
, "Can only create standard output archives\n");
else if ((mt
= open(usefile
, 2)) < 0) {
if (cflag
== 0 || (mt
= creat(usefile
, 0666)) < 0) {
fprintf(stderr
, "tar: cannot open %s\n", usefile
);
if (cflag
== 0 && nblock
== 0)
if (strcmp(usefile
, "-") == 0) {
else if ((mt
= open(usefile
, 0)) < 0) {
fprintf(stderr
, "tar: cannot open %s\n", usefile
);
if (strcmp(usefile
, "-") == 0) {
else if ((mt
= open(usefile
, 0)) < 0) {
fprintf(stderr
, "tar: cannot open %s\n", usefile
);
fprintf(stderr
, "tar: usage tar -{txru}[cvfblm] [tapefile] [blocksize] file1 file2...\n");
strcat(buf
, "sort +0 -1 +1nr ");
sprintf(buf
, "sort +0 -1 +1nr %s -o %s; awk '$1 != prev {print; prev=$1}' %s >%sX;mv %sX %s",
tname
, tname
, tname
, tname
, tname
, tname
);
freopen(tname
, "r", tfile
);
fstat(fileno(tfile
), &stbuf
);
while (*argv
&& ! term
) {
for (cp
= *argv
; *cp
; cp
++)
for (; ihead
!= NULL
; ihead
= ihead
->nextp
)
fprintf(stderr
, "Missing links to %s\n", ihead
->pathname
);
if (dblock
.dbuf
.name
[0] == '\0') {
register struct stat
*sp
;
readtape( (char *) &dblock
);
if (dblock
.dbuf
.name
[0] == '\0')
sscanf(dblock
.dbuf
.mode
, "%o", &i
);
sscanf(dblock
.dbuf
.uid
, "%o", &i
);
sscanf(dblock
.dbuf
.gid
, "%o", &i
);
sscanf(dblock
.dbuf
.size
, "%lo", &sp
->st_size
);
sscanf(dblock
.dbuf
.mtime
, "%lo", &sp
->st_mtime
);
sscanf(dblock
.dbuf
.chksum
, "%o", &chksum
);
if (chksum
!= checksum()) {
fprintf(stderr
, "directory checksum error\n");
fprintf(tfile
, "%s %s\n", dblock
.dbuf
.name
, dblock
.dbuf
.mtime
);
if (dblock
.dbuf
.linkflag
== '1')
putfile(longname
, shortname
)
infile
= open(shortname
, 0);
fprintf(stderr
, "tar: %s: cannot open file\n", longname
);
if (tfile
!= NULL
&& checkupdate(longname
) == 0) {
if (checkw('r', longname
) == 0) {
if ((stbuf
.st_mode
& S_IFMT
) == S_IFDIR
) {
for (i
= 0, cp
= buf
; *cp
++ = longname
[i
++];);
while (read(infile
, (char *)&dbuf
, sizeof(dbuf
)) > 0 && !term
) {
if (strcmp(".", dbuf
.d_name
) == 0 || strcmp("..", dbuf
.d_name
) == 0) {
for (j
=0; j
< DIRSIZ
; j
++)
lseek(infile
, (long) (sizeof(dbuf
) * i
), 0);
if ((stbuf
.st_mode
& S_IFMT
) != S_IFREG
) {
fprintf(stderr
, "tar: %s is not a file. Not dumped\n", longname
);
for (cp
= dblock
.dbuf
.name
, i
=0; (*cp
++ = *cp2
++) && i
< NAMSIZ
; i
++);
fprintf(stderr
, "%s: file name too long\n", longname
);
if (stbuf
.st_nlink
> 1) {
for (lp
= ihead
; lp
!= NULL
; lp
= lp
->nextp
) {
if (lp
->inum
== stbuf
.st_ino
&& lp
->devnum
== stbuf
.st_dev
) {
strcpy(dblock
.dbuf
.linkname
, lp
->pathname
);
dblock
.dbuf
.linkflag
= '1';
sprintf(dblock
.dbuf
.chksum
, "%6o", checksum());
writetape( (char *) &dblock
);
fprintf(stderr
, "a %s ", longname
);
fprintf(stderr
, "link to %s\n", lp
->pathname
);
lp
= (struct linkbuf
*) malloc(sizeof(*lp
));
fprintf(stderr
, "Out of memory. Link information lost\n");
lp
->devnum
= stbuf
.st_dev
;
lp
->count
= stbuf
.st_nlink
- 1;
strcpy(lp
->pathname
, longname
);
blocks
= (stbuf
.st_size
+ (TBLOCK
-1)) / TBLOCK
;
fprintf(stderr
, "a %s ", longname
);
fprintf(stderr
, "%ld blocks\n", blocks
);
sprintf(dblock
.dbuf
.chksum
, "%6o", checksum());
writetape( (char *) &dblock
);
while ((i
= read(infile
, buf
, TBLOCK
)) > 0 && blocks
> 0) {
if (blocks
!= 0 || i
!= 0)
fprintf(stderr
, "%s: file changed size\n", longname
);
for (cp
= argv
; *cp
; cp
++)
if (prefix(*cp
, dblock
.dbuf
.name
))
if (checkw('x', dblock
.dbuf
.name
) == 0) {
checkdir(dblock
.dbuf
.name
);
if (dblock
.dbuf
.linkflag
== '1') {
unlink(dblock
.dbuf
.name
);
if (link(dblock
.dbuf
.linkname
, dblock
.dbuf
.name
) < 0) {
fprintf(stderr
, "%s: cannot link\n", dblock
.dbuf
.name
);
fprintf(stderr
, "%s linked to %s\n", dblock
.dbuf
.name
, dblock
.dbuf
.linkname
);
if ((ofile
= creat(dblock
.dbuf
.name
, stbuf
.st_mode
& 07777)) < 0) {
fprintf(stderr
, "tar: %s - cannot create\n", dblock
.dbuf
.name
);
chown(dblock
.dbuf
.name
, stbuf
.st_uid
, stbuf
.st_gid
);
blocks
= ((bytes
= stbuf
.st_size
) + TBLOCK
-1)/TBLOCK
;
fprintf(stderr
, "x %s, %ld bytes, %ld tape blocks\n", dblock
.dbuf
.name
, bytes
, blocks
);
if (write(ofile
, buf
, TBLOCK
) < 0) {
fprintf(stderr
, "tar: %s: HELP - extract write error\n", dblock
.dbuf
.name
);
if (write(ofile
, buf
, (int) bytes
) < 0) {
fprintf(stderr
, "tar: %s: HELP - extract write error\n", dblock
.dbuf
.name
);
timep
[1] = stbuf
.st_mtime
;
utime(dblock
.dbuf
.name
, timep
);
printf("%s", dblock
.dbuf
.name
);
if (dblock
.dbuf
.linkflag
== '1')
printf(" linked to %s", dblock
.dbuf
.linkname
);
for (cp
= buf
; cp
< &buf
[TBLOCK
]; )
register struct stat
*st
;
printf("%3d/%1d", st
->st_uid
, st
->st_gid
);
printf("%7D", st
->st_size
);
cp
= ctime(&st
->st_mtime
);
printf(" %-12.12s %-4.4s ", cp
+4, cp
+20);
int m1
[] = { 1, ROWN
, 'r', '-' };
int m2
[] = { 1, WOWN
, 'w', '-' };
int m3
[] = { 2, SUID
, 's', XOWN
, 'x', '-' };
int m4
[] = { 1, RGRP
, 'r', '-' };
int m5
[] = { 1, WGRP
, 'w', '-' };
int m6
[] = { 2, SGID
, 's', XGRP
, 'x', '-' };
int m7
[] = { 1, ROTH
, 'r', '-' };
int m8
[] = { 1, WOTH
, 'w', '-' };
int m9
[] = { 2, STXT
, 't', XOTH
, 'x', '-' };
int *m
[] = { m1
, m2
, m3
, m4
, m5
, m6
, m7
, m8
, m9
};
register struct stat
*st
;
for (mp
= &m
[0]; mp
< &m
[9];)
while (--n
>=0 && (st
->st_mode
&*ap
++)==0)
for (cp
= name
; *cp
; cp
++) {
if (access(name
, 01) < 0) {
execl("/bin/mkdir", "mkdir", name
, 0);
execl("/usr/bin/mkdir", "mkdir", name
, 0);
fprintf(stderr
, "tar: cannot find mkdir!\n");
chown(name
, stbuf
.st_uid
, stbuf
.st_gid
);
signal(SIGQUIT
, SIG_IGN
);
signal(SIGTERM
, SIG_IGN
);
register struct stat
*sp
;
for (cp
= dblock
.dummy
; cp
< &dblock
.dummy
[TBLOCK
]; cp
++)
sprintf(dblock
.dbuf
.mode
, "%6o ", sp
->st_mode
& 07777);
sprintf(dblock
.dbuf
.uid
, "%6o ", sp
->st_uid
);
sprintf(dblock
.dbuf
.gid
, "%6o ", sp
->st_gid
);
sprintf(dblock
.dbuf
.size
, "%11lo ", sp
->st_size
);
sprintf(dblock
.dbuf
.mtime
, "%11lo ", sp
->st_mtime
);
for (cp
= dblock
.dbuf
.chksum
; cp
< &dblock
.dbuf
.chksum
[sizeof(dblock
.dbuf
.chksum
)]; cp
++)
for (cp
= dblock
.dummy
; cp
< &dblock
.dummy
[TBLOCK
]; cp
++)
while (getchar() != '\n');
if ((seekp
= lookup(arg
)) < 0)
fscanf(tfile
, "%s %lo", name
, &mtime
);
if (stbuf
.st_mtime
> mtime
)
execl("/bin/pwd", "pwd", 0);
execl("/usr/bin/pwd", "pwd", 0);
fprintf(stderr
, "pwd failed!\n");
while (wait((int *)NULL
) != -1)
a
= bsrch(s
, i
, low
, high
);
return(b
[i
+1] == ' '? 0 : -1);
if (recno
>= nblock
|| first
== 0) {
if (first
== 0 && nblock
== 0)
if ((i
= read(mt
, tbuf
, TBLOCK
*j
)) < 0) {
fprintf(stderr
, "Tar: tape read error\n");
fprintf(stderr
, "Tar: tape blocksize error\n");
fprintf(stderr
, "Tar: Cannot update blocked tapes (yet)\n");
if (i
!= nblock
&& i
!= 1) {
fprintf(stderr
, "Tar: blocksize = %d\n", i
);
copy(buffer
, &tbuf
[recno
++]);
if (write(mt
, tbuf
, TBLOCK
*nblock
) < 0) {
fprintf(stderr
, "Tar: tape write error\n");
copy(&tbuf
[recno
++], buffer
);
if (write(mt
, tbuf
, TBLOCK
*nblock
) < 0) {
fprintf(stderr
, "Tar: tape write error\n");
lseek(mt
, (long) -TBLOCK
, 1);
if (read(mt
, tbuf
, TBLOCK
*nblock
) < 0) {
fprintf(stderr
, "Tar: tape read error after seek\n");
lseek(mt
, (long) -TBLOCK
, 1);
write(mt
, tbuf
, TBLOCK
*nblock
);
register char *to
, *from
;