/* Buffer management for tar.
- Copyright (C) 1988, 1992 Free Software Foundation
+ Copyright (C) 1988, 1992, 1993 Free Software Foundation
This file is part of GNU Tar.
#include <sys/types.h> /* For non-Berkeley systems */
#include <signal.h>
#include <time.h>
-time_t time();
+time_t time ();
#ifdef HAVE_SYS_MTIO_H
#include <sys/ioctl.h>
it can't exec. We hope compress/sh
never return this status! */
-char *valloc();
+void *valloc ();
-void writeerror();
-void readerror();
+void writeerror ();
+void readerror ();
-void ck_pipe();
-void ck_close();
+void ck_pipe ();
+void ck_close ();
-int backspace_output();
-extern void finish_header();
-void flush_archive();
-int isfile();
-int new_volume();
-void verify_volume();
-extern void to_oct();
+int backspace_output ();
+extern void finish_header ();
+void flush_archive ();
+int isfile ();
+int new_volume ();
+void verify_volume ();
+extern void to_oct ();
#ifndef __MSDOS__
/* Obnoxious test to see if dimwit is trying to dump the archive */
* header record.
*/
static union record **save_rec;
- union record record_save_area;
-static long saved_recno;
+union record record_save_area;
+static long saved_recno;
/*
* PID of child program, if f_compress or remote archive access.
*/
-static int childpid = 0;
+static int childpid = 0;
/*
* Record number of the start of this block of records
*/
-long baserec;
+long baserec;
/*
* Error recovery stuff
*/
-static int r_error_count;
+static int r_error_count;
/*
* Have we hit EOF yet?
*/
-static int hit_eof;
+static int hit_eof;
/* Checkpointing counter */
static int checkpoint;
/* JF we're reading, but we just read the last record and its time to update */
extern time_to_start_writing;
-int file_to_switch_to= -1; /* If remote update, close archive, and use
+int file_to_switch_to = -1; /* If remote update, close archive, and use
this descriptor to write to */
static int volno = 1; /* JF which volume of a multi-volume tape
/* Reset the EOF flag (if set), and re-set ar_record, etc */
void
-reset_eof()
+reset_eof ()
{
- if(hit_eof) {
- hit_eof=0;
- ar_record=ar_block;
- ar_last=ar_block+blocking;
- ar_reading=0;
- }
+ if (hit_eof)
+ {
+ hit_eof = 0;
+ ar_record = ar_block;
+ ar_last = ar_block + blocking;
+ ar_reading = 0;
+ }
}
/*
* it, to avoid accidentally going on to the next file on the "tape".
*/
union record *
-findrec()
+findrec ()
{
- if (ar_record == ar_last) {
- if (hit_eof)
- return (union record *)NULL; /* EOF */
- flush_archive();
- if (ar_record == ar_last) {
- hit_eof++;
- return (union record *)NULL; /* EOF */
- }
+ if (ar_record == ar_last)
+ {
+ if (hit_eof)
+ return (union record *) NULL; /* EOF */
+ flush_archive ();
+ if (ar_record == ar_last)
+ {
+ hit_eof++;
+ return (union record *) NULL; /* EOF */
}
- return ar_record;
+ }
+ return ar_record;
}
* (should the arg have an off-by-1? XXX FIXME)
*/
void
-userec(rec)
- union record *rec;
+userec (rec)
+ union record *rec;
{
- while(rec >= ar_record)
- ar_record++;
- /*
+ while (rec >= ar_record)
+ ar_record++;
+ /*
* Do NOT flush the archive here. If we do, the same
* argument to userec() could mean the next record (if the
* input block is exactly one record long), which is not what
* is intended.
*/
- if (ar_record > ar_last)
- abort();
+ if (ar_record > ar_last)
+ abort ();
}
* for filling with data, or taking data from.
*/
union record *
-endofrecs()
+endofrecs ()
{
- return ar_last;
+ return ar_last;
}
* Equivalent to BSD "dup2" with error reporting.
*/
void
-dupto(from, to, msg)
- int from, to;
- char *msg;
+dupto (from, to, msg)
+ int from, to;
+ char *msg;
{
- int err;
+ int err;
- if (from != to) {
- err=close(to);
- if(err<0 && errno!=EBADF) {
- msg_perror("Cannot close descriptor %d",to);
- exit(EX_SYSTEM);
- }
- err = dup(from);
- if (err != to) {
- msg_perror("cannot dup %s",msg);
- exit(EX_SYSTEM);
- }
- ck_close(from);
+ if (from != to)
+ {
+ err = close (to);
+ if (err < 0 && errno != EBADF)
+ {
+ msg_perror ("Cannot close descriptor %d", to);
+ exit (EX_SYSTEM);
+ }
+ err = dup (from);
+ if (err != to)
+ {
+ msg_perror ("cannot dup %s", msg);
+ exit (EX_SYSTEM);
}
+ ck_close (from);
+ }
}
#ifdef __MSDOS__
void
-child_open()
+child_open ()
{
- fprintf(stderr,"MS-DOS %s can't use compressed or remote archives\n",tar);
- exit(EX_ARGSBAD);
+ fprintf (stderr, "MS-DOS %s can't use compressed or remote archives\n", tar);
+ exit (EX_ARGSBAD);
}
+
#else
void
-child_open()
+child_open ()
{
- int pipe[2];
- int err = 0;
- int nar;
+ int pipe[2];
+ int err = 0;
- int kidpipe[2];
- int kidchildpid;
+ int kidpipe[2];
+ int kidchildpid;
#define READ 0
#define WRITE 1
- ck_pipe(pipe);
+ ck_pipe (pipe);
+
+ childpid = fork ();
+ if (childpid < 0)
+ {
+ msg_perror ("cannot fork");
+ exit (EX_SYSTEM);
+ }
+ if (childpid > 0)
+ {
+ /* We're the parent. Clean up and be happy */
+ /* This, at least, is easy */
- childpid=fork();
- if(childpid<0) {
- msg_perror("cannot fork");
- exit(EX_SYSTEM);
+ if (ar_reading)
+ {
+ f_reblock++;
+ archive = pipe[READ];
+ ck_close (pipe[WRITE]);
}
- if(childpid>0) {
- /* We're the parent. Clean up and be happy */
- /* This, at least, is easy */
-
- if(ar_reading) {
- f_reblock++;
- archive=pipe[READ];
- ck_close(pipe[WRITE]);
- } else {
- archive = pipe[WRITE];
- ck_close(pipe[READ]);
- }
- return;
+ else
+ {
+ archive = pipe[WRITE];
+ ck_close (pipe[READ]);
}
+ return;
+ }
- /* We're the kid */
- if(ar_reading) {
- dupto(pipe[WRITE],STDOUT,"(child) pipe to stdout");
- ck_close(pipe[READ]);
- } else {
- dupto(pipe[READ],STDIN,"(child) pipe to stdin");
- ck_close(pipe[WRITE]);
- }
+ /* We're the kid */
+ if (ar_reading)
+ {
+ dupto (pipe[WRITE], STDOUT, "(child) pipe to stdout");
+ ck_close (pipe[READ]);
+ }
+ else
+ {
+ dupto (pipe[READ], STDIN, "(child) pipe to stdin");
+ ck_close (pipe[WRITE]);
+ }
- /* We need a child tar only if
+ /* We need a child tar only if
1: we're reading/writing stdin/out (to force reblocking)
2: the file is to be accessed by rmt (compress doesn't know how)
3: the file is not a plain file */
#ifdef NO_REMOTE
- if(!(ar_files[0][0]=='-' && ar_files[0][1]=='\0') && isfile(ar_files[0]))
+ if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && isfile (ar_files[0]))
#else
- if(!(ar_files[0][0]=='-' && ar_files[0][1]=='\0') && !_remdev(ar_files[0]) && isfile(ar_files[0]))
+ if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && !_remdev (ar_files[0]) && isfile (ar_files[0]))
#endif
+ {
+ /* We don't need a child tar. Open the archive */
+ if (ar_reading)
{
- /* We don't need a child tar. Open the archive */
- if(ar_reading) {
- archive=open(ar_files[0], O_RDONLY|O_BINARY, 0666);
- if(archive<0) {
- msg_perror("can't open archive %s",ar_files[0]);
- exit(EX_BADARCH);
- }
- dupto(archive,STDIN,"archive to stdin");
- /* close(archive); */
- } else {
- archive=creat(ar_files[0],0666);
- if(archive<0) {
- msg_perror("can't open archive %s",ar_files[0]);
- exit(EX_BADARCH);
- }
- dupto(archive,STDOUT,"archive to stdout");
- /* close(archive); */
- }
- } else {
- /* We need a child tar */
- ck_pipe(kidpipe);
-
- kidchildpid=fork();
- if(kidchildpid<0) {
- msg_perror("child can't fork");
- exit(EX_SYSTEM);
- }
+ archive = open (ar_files[0], O_RDONLY | O_BINARY, 0666);
+ if (archive < 0)
+ {
+ msg_perror ("can't open archive %s", ar_files[0]);
+ exit (EX_BADARCH);
+ }
+ dupto (archive, STDIN, "archive to stdin");
+ /* close(archive); */
+ }
+ else
+ {
+ archive = creat (ar_files[0], 0666);
+ if (archive < 0)
+ {
+ msg_perror ("can't open archive %s", ar_files[0]);
+ exit (EX_BADARCH);
+ }
+ dupto (archive, STDOUT, "archive to stdout");
+ /* close(archive); */
+ }
+ }
+ else
+ {
+ /* We need a child tar */
+ ck_pipe (kidpipe);
- if(kidchildpid>0) {
- /* About to exec compress: set up the files */
- if(ar_reading) {
- dupto(kidpipe[READ],STDIN,"((child)) pipe to stdin");
- ck_close(kidpipe[WRITE]);
- /* dup2(pipe[WRITE],STDOUT); */
- } else {
- /* dup2(pipe[READ],STDIN); */
- dupto(kidpipe[WRITE],STDOUT,"((child)) pipe to stdout");
- ck_close(kidpipe[READ]);
- }
- /* ck_close(pipe[READ]); */
- /* ck_close(pipe[WRITE]); */
- /* ck_close(kidpipe[READ]);
+ kidchildpid = fork ();
+ if (kidchildpid < 0)
+ {
+ msg_perror ("child can't fork");
+ exit (EX_SYSTEM);
+ }
+
+ if (kidchildpid > 0)
+ {
+ /* About to exec compress: set up the files */
+ if (ar_reading)
+ {
+ dupto (kidpipe[READ], STDIN, "((child)) pipe to stdin");
+ ck_close (kidpipe[WRITE]);
+ /* dup2(pipe[WRITE],STDOUT); */
+ }
+ else
+ {
+ /* dup2(pipe[READ],STDIN); */
+ dupto (kidpipe[WRITE], STDOUT, "((child)) pipe to stdout");
+ ck_close (kidpipe[READ]);
+ }
+ /* ck_close(pipe[READ]); */
+ /* ck_close(pipe[WRITE]); */
+ /* ck_close(kidpipe[READ]);
ck_close(kidpipe[WRITE]); */
- } else {
- /* Grandchild. Do the right thing, namely sit here and
+ }
+ else
+ {
+ /* Grandchild. Do the right thing, namely sit here and
read/write the archive, and feed stuff back to compress */
- tar="tar (child)";
- if(ar_reading) {
- dupto(kidpipe[WRITE],STDOUT,"[child] pipe to stdout");
- ck_close(kidpipe[READ]);
- } else {
- dupto(kidpipe[READ],STDIN,"[child] pipe to stdin");
- ck_close(kidpipe[WRITE]);
- }
-
- if (ar_files[0][0] == '-' && ar_files[0][1] == '\0') {
- if (ar_reading)
- archive = STDIN;
- else
- archive = STDOUT;
- } else /* This can't happen if (ar_reading==2)
+ tar = "tar (child)";
+ if (ar_reading)
+ {
+ dupto (kidpipe[WRITE], STDOUT, "[child] pipe to stdout");
+ ck_close (kidpipe[READ]);
+ }
+ else
+ {
+ dupto (kidpipe[READ], STDIN, "[child] pipe to stdin");
+ ck_close (kidpipe[WRITE]);
+ }
+
+ if (ar_files[0][0] == '-' && ar_files[0][1] == '\0')
+ {
+ if (ar_reading)
+ archive = STDIN;
+ else
+ archive = STDOUT;
+ }
+ else /* This can't happen if (ar_reading==2)
archive = rmtopen(ar_files[0], O_RDWR|O_CREAT|O_BINARY, 0666);
- else */if(ar_reading)
- archive = rmtopen(ar_files[0], O_RDONLY|O_BINARY, 0666);
- else
- archive = rmtcreat(ar_files[0], 0666);
-
- if (archive < 0) {
- msg_perror("can't open archive %s",ar_files[0]);
- exit(EX_BADARCH);
- }
-
- if(ar_reading) {
- for(;;) {
- char *ptr;
- int max,count;
-
- r_error_count = 0;
- error_loop:
- err=rmtread(archive, ar_block->charptr,(int)(blocksize));
- if(err<0) {
- readerror();
- goto error_loop;
- }
- if(err==0)
- break;
- ptr = ar_block->charptr;
- max = err;
- while(max) {
- count = (max<RECORDSIZE) ? max : RECORDSIZE;
- err=write(STDOUT,ptr,count);
- if(err!=count) {
- if(err<0) {
- msg_perror("can't write to compress");
- exit(EX_SYSTEM);
- } else
- msg("write to compress short %d bytes",count-err);
- count = (err<0) ? 0 : err;
- }
- ptr+=count;
- max-=count;
- }
- }
- } else {
- for(;;) {
- int n;
- char *ptr;
-
- n=blocksize;
- ptr = ar_block->charptr;
- while(n) {
- err=read(STDIN,ptr,(n<RECORDSIZE) ? n : RECORDSIZE);
- if(err<=0)
- break;
- n-=err;
- ptr+=err;
- }
- /* EOF */
- if(err==0) {
- if(f_compress<2)
- blocksize-=n;
- else
- bzero(ar_block->charptr+blocksize-n,n);
- err=rmtwrite(archive,ar_block->charptr,blocksize);
- if(err!=(blocksize))
- writeerror(err);
- if(f_compress<2)
- blocksize+=n;
- break;
- }
- if(n) {
- msg_perror("can't read from compress");
- exit(EX_SYSTEM);
- }
- err=rmtwrite(archive, ar_block->charptr, (int)blocksize);
- if(err!=blocksize)
- writeerror(err);
- }
+ else */ if (ar_reading)
+ archive = rmtopen (ar_files[0], O_RDONLY | O_BINARY, 0666);
+ else
+ archive = rmtcreat (ar_files[0], 0666);
+
+ if (archive < 0)
+ {
+ msg_perror ("can't open archive %s", ar_files[0]);
+ exit (EX_BADARCH);
+ }
+
+ if (ar_reading)
+ {
+ for (;;)
+ {
+ char *ptr;
+ int max, count;
+
+ r_error_count = 0;
+ error_loop:
+ err = rmtread (archive, ar_block->charptr, (int) (blocksize));
+ if (err < 0)
+ {
+ readerror ();
+ goto error_loop;
+ }
+ if (err == 0)
+ break;
+ ptr = ar_block->charptr;
+ max = err;
+ while (max)
+ {
+ count = (max < RECORDSIZE) ? max : RECORDSIZE;
+ err = write (STDOUT, ptr, count);
+ if (err != count)
+ {
+ if (err < 0)
+ {
+ msg_perror ("can't write to compression program");
+ exit (EX_SYSTEM);
+ }
+ else
+ msg ("write to compression program short %d bytes",
+ count - err);
+ count = (err < 0) ? 0 : err;
}
-
- /* close_archive(); */
- exit(0);
+ ptr += count;
+ max -= count;
+ }
}
+ }
+ else
+ {
+ for (;;)
+ {
+ int n;
+ char *ptr;
+
+ n = blocksize;
+ ptr = ar_block->charptr;
+ while (n)
+ {
+ err = read (STDIN, ptr, (n < RECORDSIZE) ? n : RECORDSIZE);
+ if (err <= 0)
+ break;
+ n -= err;
+ ptr += err;
+ }
+ /* EOF */
+ if (err == 0)
+ {
+ if (!f_compress_block)
+ blocksize -= n;
+ else
+ bzero (ar_block->charptr + blocksize - n, n);
+ err = rmtwrite (archive, ar_block->charptr, blocksize);
+ if (err != (blocksize))
+ writeerror (err);
+ if (!f_compress_block)
+ blocksize += n;
+ break;
+ }
+ if (n)
+ {
+ msg_perror ("can't read from compression program");
+ exit (EX_SYSTEM);
+ }
+ err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
+ if (err != blocksize)
+ writeerror (err);
+ }
+ }
+
+ /* close_archive(); */
+ exit (0);
}
- /* So we should exec compress (-d) */
- if(ar_reading)
- execlp("compress", "compress", "-d", (char *)0);
- else
- execlp("compress", "compress", (char *)0);
- msg_perror("can't exec compress");
- _exit(EX_SYSTEM);
+ }
+ /* So we should exec compress (-d) */
+ if (ar_reading)
+ execlp (f_compressprog, f_compressprog, "-d", (char *) 0);
+ else
+ execlp (f_compressprog, f_compressprog, (char *) 0);
+ msg_perror ("can't exec %s", f_compressprog);
+ _exit (EX_SYSTEM);
}
/* return non-zero if p is the name of a directory */
int
-isfile(p)
-char *p;
+isfile (p)
+ char *p;
{
- struct stat stbuf;
+ struct stat stbuf;
- if(stat(p,&stbuf)<0)
- return 1;
- if(S_ISREG(stbuf.st_mode))
- return 1;
- return 0;
+ if (stat (p, &stbuf) < 0)
+ return 1;
+ if (S_ISREG (stbuf.st_mode))
+ return 1;
+ return 0;
}
#endif
*/
/* JF if the arg is 2, open for reading and writing. */
void
-open_archive(reading)
- int reading;
+open_archive (reading)
+ int reading;
{
- msg_file = f_exstdout ? stderr : stdout;
+ msg_file = f_exstdout ? stderr : stdout;
- if (blocksize == 0) {
- msg("invalid value for blocksize");
- exit(EX_ARGSBAD);
- }
+ if (blocksize == 0)
+ {
+ msg ("invalid value for blocksize");
+ exit (EX_ARGSBAD);
+ }
- if(n_ar_files==0) {
- msg("No archive name given, what should I do?");
- exit(EX_BADARCH);
- }
+ if (n_ar_files == 0)
+ {
+ msg ("No archive name given, what should I do?");
+ exit (EX_BADARCH);
+ }
- /*NOSTRICT*/
- if(f_multivol) {
- ar_block = (union record *) valloc((unsigned)(blocksize+(2*RECORDSIZE)));
- if(ar_block)
- ar_block += 2;
- } else
- ar_block = (union record *) valloc((unsigned)blocksize);
- if (!ar_block) {
- msg("could not allocate memory for blocking factor %d",
- blocking);
- exit(EX_ARGSBAD);
- }
+ /*NOSTRICT*/
+ if (f_multivol)
+ {
+ ar_block = (union record *) valloc ((unsigned) (blocksize + (2 * RECORDSIZE)));
+ if (ar_block)
+ ar_block += 2;
+ }
+ else
+ ar_block = (union record *) valloc ((unsigned) blocksize);
+ if (!ar_block)
+ {
+ msg ("could not allocate memory for blocking factor %d",
+ blocking);
+ exit (EX_ARGSBAD);
+ }
- ar_record = ar_block;
- ar_last = ar_block + blocking;
- ar_reading = reading;
+ ar_record = ar_block;
+ ar_last = ar_block + blocking;
+ ar_reading = reading;
- if (f_multivol && f_verify)
- {
- msg ("cannot verify multi-volume archives");
- exit (EX_ARGSBAD);
- }
-
- if (f_compress) {
- if(reading==2 || f_verify) {
- msg("cannot update or verify compressed archives");
- exit(EX_ARGSBAD);
- }
- if (f_multivol) {
- msg ("cannot use multi-volume compressed archives");
- exit (EX_ARGSBAD);
- }
- child_open();
- if(!reading && ar_files[0][0]=='-' && ar_files[0][1]=='\0')
- msg_file = stderr;
- /* child_open(rem_host, rem_file); */
- } else if (ar_files[0][0] == '-' && ar_files[0][1] == '\0') {
- f_reblock++; /* Could be a pipe, be safe */
- if(f_verify) {
- msg("can't verify stdin/stdout archive");
- exit(EX_ARGSBAD);
- }
- if(reading==2) {
- archive=STDIN;
- msg_file=stderr;
- write_archive_to_stdout++;
- } else if (reading)
- archive = STDIN;
- else {
- archive = STDOUT;
- msg_file = stderr;
- }
- } else if (reading==2 || f_verify) {
- archive = rmtopen(ar_files[0], O_RDWR|O_CREAT|O_BINARY, 0666);
- } else if(reading) {
- archive = rmtopen(ar_files[0], O_RDONLY|O_BINARY, 0666);
- } else {
- archive = rmtcreat(ar_files[0], 0666);
+ if (f_multivol && f_verify)
+ {
+ msg ("cannot verify multi-volume archives");
+ exit (EX_ARGSBAD);
+ }
+
+ if (f_compressprog)
+ {
+ if (reading == 2 || f_verify)
+ {
+ msg ("cannot update or verify compressed archives");
+ exit (EX_ARGSBAD);
}
- if (archive < 0) {
- msg_perror("can't open %s",ar_files[0]);
- exit(EX_BADARCH);
+ if (f_multivol)
+ {
+ msg ("cannot use multi-volume compressed archives");
+ exit (EX_ARGSBAD);
}
+ child_open ();
+ if (!reading && ar_files[0][0] == '-' && ar_files[0][1] == '\0')
+ msg_file = stderr;
+ /* child_open(rem_host, rem_file); */
+ }
+ else if (ar_files[0][0] == '-' && ar_files[0][1] == '\0')
+ {
+ f_reblock++; /* Could be a pipe, be safe */
+ if (f_verify)
+ {
+ msg ("can't verify stdin/stdout archive");
+ exit (EX_ARGSBAD);
+ }
+ if (reading == 2)
+ {
+ archive = STDIN;
+ msg_file = stderr;
+ write_archive_to_stdout++;
+ }
+ else if (reading)
+ archive = STDIN;
+ else
+ {
+ archive = STDOUT;
+ msg_file = stderr;
+ }
+ }
+ else if (reading == 2 || f_verify)
+ {
+ archive = rmtopen (ar_files[0], O_RDWR | O_CREAT | O_BINARY, 0666);
+ }
+ else if (reading)
+ {
+ archive = rmtopen (ar_files[0], O_RDONLY | O_BINARY, 0666);
+ }
+ else
+ {
+ archive = rmtcreat (ar_files[0], 0666);
+ }
+ if (archive < 0)
+ {
+ msg_perror ("can't open %s", ar_files[0]);
+ exit (EX_BADARCH);
+ }
#ifndef __MSDOS__
- if(!_isrmt(archive)) {
- struct stat tmp_stat;
+ if (!_isrmt (archive))
+ {
+ struct stat tmp_stat;
- fstat(archive,&tmp_stat);
- if(S_ISREG(tmp_stat.st_mode)) {
- ar_dev=tmp_stat.st_dev;
- ar_ino=tmp_stat.st_ino;
- }
+ fstat (archive, &tmp_stat);
+ if (S_ISREG (tmp_stat.st_mode))
+ {
+ ar_dev = tmp_stat.st_dev;
+ ar_ino = tmp_stat.st_ino;
}
+ }
#endif
#ifdef __MSDOS__
- setmode(archive, O_BINARY);
+ setmode (archive, O_BINARY);
#endif
- if (reading) {
- ar_last = ar_block; /* Set up for 1st block = # 0 */
- (void) findrec(); /* Read it in, check for EOF */
+ if (reading)
+ {
+ ar_last = ar_block; /* Set up for 1st block = # 0 */
+ (void) findrec (); /* Read it in, check for EOF */
- if(f_volhdr) {
- union record *head;
+ if (f_volhdr)
+ {
+ union record *head;
#if 0
- char *ptr;
-
- if(f_multivol) {
- ptr=malloc(strlen(f_volhdr)+20);
- sprintf(ptr,"%s Volume %d",f_volhdr,1);
- } else
- ptr=f_volhdr;
+ char *ptr;
+
+ if (f_multivol)
+ {
+ ptr = malloc (strlen (f_volhdr) + 20);
+ sprintf (ptr, "%s Volume %d", f_volhdr, 1);
+ }
+ else
+ ptr = f_volhdr;
#endif
- head=findrec();
- if(!head) {
- msg("Archive not labelled to match %s",f_volhdr);
- exit(EX_BADVOL);
- }
- if (re_match (label_pattern, head->header.name,
- strlen (head->header.name), 0, 0) < 0) {
- msg ("Volume mismatch! %s!=%s", f_volhdr,
- head->header.name);
- exit (EX_BADVOL);
- }
-#if 0
- if(strcmp(ptr,head->header.name)) {
- msg("Volume mismatch! %s!=%s",ptr,head->header.name);
- exit(EX_BADVOL);
- }
- if(ptr!=f_volhdr)
- free(ptr);
+ head = findrec ();
+ if (!head)
+ {
+ msg ("Archive not labelled to match %s", f_volhdr);
+ exit (EX_BADVOL);
+ }
+ if (re_match (label_pattern, head->header.arch_name,
+ strlen (head->header.arch_name), 0, 0) < 0)
+ {
+ msg ("Volume mismatch! %s!=%s", f_volhdr,
+ head->header.arch_name);
+ exit (EX_BADVOL);
+ }
+#if 0
+ if (strcmp (ptr, head->header.name))
+ {
+ msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
+ exit (EX_BADVOL);
+ }
+ if (ptr != f_volhdr)
+ free (ptr);
#endif
- }
- } else if(f_volhdr) {
- bzero((void *)ar_block,RECORDSIZE);
- if(f_multivol)
- sprintf(ar_block->header.name,"%s Volume 1",f_volhdr);
- else
- strcpy(ar_block->header.name,f_volhdr);
- ar_block->header.linkflag = LF_VOLHDR;
- to_oct(time(0), 1+12, ar_block->header.mtime);
- finish_header(ar_block);
- /* ar_record++; */
}
+ }
+ else if (f_volhdr)
+ {
+ bzero ((void *) ar_block, RECORDSIZE);
+ if (f_multivol)
+ sprintf (ar_block->header.arch_name, "%s Volume 1", f_volhdr);
+ else
+ strcpy (ar_block->header.arch_name, f_volhdr);
+ current_file_name = ar_block->header.arch_name;
+ ar_block->header.linkflag = LF_VOLHDR;
+ to_oct (time (0), 1 + 12, ar_block->header.mtime);
+ finish_header (ar_block);
+ /* ar_record++; */
+ }
}
* subtracting ar_block from that, shifting it back, losing the top 9 bits.
*/
void
-saverec(pointer)
- union record **pointer;
+saverec (pointer)
+ union record **pointer;
{
- long offset;
+ long offset;
- save_rec = pointer;
- offset = ar_record - ar_block;
- saved_recno = baserec + offset;
+ save_rec = pointer;
+ offset = ar_record - ar_block;
+ saved_recno = baserec + offset;
}
/*
*/
void
-fl_write()
+fl_write ()
{
- int err;
- int copy_back;
- static long bytes_written = 0;
-
- if (f_checkpoint && ! (++checkpoint % 10))
- msg ("Write checkpoint %d\n", checkpoint);
- if(tape_length && bytes_written >= tape_length * 1024) {
- errno = ENOSPC;
- err = 0;
- } else
- err = rmtwrite(archive, ar_block->charptr,(int) blocksize);
- if(err!=blocksize && !f_multivol)
- writeerror(err);
- else if (f_totals)
- tot_written += blocksize;
-
- if(err>0)
- bytes_written+=err;
- if (err == blocksize) {
- if(f_multivol) {
- if(!save_name) {
- real_s_name[0]='\0';
- real_s_totsize=0;
- real_s_sizeleft = 0;
- return;
- }
+ int err;
+ int copy_back;
+ static long bytes_written = 0;
+
+ if (f_checkpoint && !(++checkpoint % 10))
+ msg ("Write checkpoint %d\n", checkpoint);
+ if (tape_length && bytes_written >= tape_length * 1024)
+ {
+ errno = ENOSPC;
+ err = 0;
+ }
+ else
+ err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
+ if (err != blocksize && !f_multivol)
+ writeerror (err);
+ else if (f_totals)
+ tot_written += blocksize;
+
+ if (err > 0)
+ bytes_written += err;
+ if (err == blocksize)
+ {
+ if (f_multivol)
+ {
+ if (!save_name)
+ {
+ real_s_name[0] = '\0';
+ real_s_totsize = 0;
+ real_s_sizeleft = 0;
+ return;
+ }
#ifdef __MSDOS__
- if(save_name[1]==':')
- save_name+=2;
+ if (save_name[1] == ':')
+ save_name += 2;
#endif
- while(*save_name=='/')
- save_name++;
+ while (*save_name == '/')
+ save_name++;
- strcpy(real_s_name,save_name);
- real_s_totsize = save_totsize;
- real_s_sizeleft = save_sizeleft;
- }
- return;
+ strcpy (real_s_name, save_name);
+ real_s_totsize = save_totsize;
+ real_s_sizeleft = save_sizeleft;
}
+ return;
+ }
- /* We're multivol Panic if we didn't get the right kind of response */
- /* ENXIO is for the UNIX PC */
- if(err<0 && errno!=ENOSPC && errno!=EIO && errno!=ENXIO)
- writeerror(err);
-
- /* If error indicates a short write, we just move to the next tape. */
-
- if(new_volume(0)<0)
- return;
- bytes_written=0;
- if(f_volhdr && real_s_name[0]) {
- copy_back=2;
- ar_block-=2;
- } else if(f_volhdr || real_s_name[0]) {
- copy_back = 1;
- ar_block--;
- } else
- copy_back = 0;
- if(f_volhdr) {
- bzero((void *)ar_block,RECORDSIZE);
- sprintf(ar_block->header.name,"%s Volume %d",f_volhdr,volno);
- to_oct(time(0), 1+12, ar_block->header.mtime);
- ar_block->header.linkflag = LF_VOLHDR;
- finish_header(ar_block);
- }
- if(real_s_name[0]) {
- int tmp;
-
- if(f_volhdr)
- ar_block++;
- bzero((void *)ar_block,RECORDSIZE);
- strcpy(ar_block->header.name,real_s_name);
- ar_block->header.linkflag = LF_MULTIVOL;
- to_oct((long)real_s_sizeleft,1+12,
- ar_block->header.size);
- to_oct((long)real_s_totsize-real_s_sizeleft,
- 1+12,ar_block->header.offset);
- tmp=f_verbose;
- f_verbose=0;
- finish_header(ar_block);
- f_verbose=tmp;
- if(f_volhdr)
- ar_block--;
- }
+ /* We're multivol Panic if we didn't get the right kind of response */
+ /* ENXIO is for the UNIX PC */
+ if (err < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
+ writeerror (err);
+
+ /* If error indicates a short write, we just move to the next tape. */
+
+ if (new_volume (0) < 0)
+ return;
+ bytes_written = 0;
+ if (f_volhdr && real_s_name[0])
+ {
+ copy_back = 2;
+ ar_block -= 2;
+ }
+ else if (f_volhdr || real_s_name[0])
+ {
+ copy_back = 1;
+ ar_block--;
+ }
+ else
+ copy_back = 0;
+ if (f_volhdr)
+ {
+ bzero ((void *) ar_block, RECORDSIZE);
+ sprintf (ar_block->header.arch_name, "%s Volume %d", f_volhdr, volno);
+ to_oct (time (0), 1 + 12, ar_block->header.mtime);
+ ar_block->header.linkflag = LF_VOLHDR;
+ finish_header (ar_block);
+ }
+ if (real_s_name[0])
+ {
+ int tmp;
+
+ if (f_volhdr)
+ ar_block++;
+ bzero ((void *) ar_block, RECORDSIZE);
+ strcpy (ar_block->header.arch_name, real_s_name);
+ ar_block->header.linkflag = LF_MULTIVOL;
+ to_oct ((long) real_s_sizeleft, 1 + 12,
+ ar_block->header.size);
+ to_oct ((long) real_s_totsize - real_s_sizeleft,
+ 1 + 12, ar_block->header.offset);
+ tmp = f_verbose;
+ f_verbose = 0;
+ finish_header (ar_block);
+ f_verbose = tmp;
+ if (f_volhdr)
+ ar_block--;
+ }
+
+ err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
+ if (err != blocksize)
+ writeerror (err);
+ else if (f_totals)
+ tot_written += blocksize;
- err = rmtwrite(archive, ar_block->charptr,(int) blocksize);
- if(err!=blocksize)
- writeerror(err);
- else if (f_totals)
- tot_written += blocksize;
-
-
- bytes_written = blocksize;
- if(copy_back) {
- ar_block+=copy_back;
- bcopy((void *)(ar_block+blocking-copy_back),
- (void *)ar_record,
- copy_back*RECORDSIZE);
- ar_record+=copy_back;
-
- if(real_s_sizeleft>=copy_back*RECORDSIZE)
- real_s_sizeleft-=copy_back*RECORDSIZE;
- else if((real_s_sizeleft+RECORDSIZE-1)/RECORDSIZE<=copy_back)
- real_s_name[0] = '\0';
- else {
+
+ bytes_written = blocksize;
+ if (copy_back)
+ {
+ ar_block += copy_back;
+ bcopy ((void *) (ar_block + blocking - copy_back),
+ (void *) ar_record,
+ copy_back * RECORDSIZE);
+ ar_record += copy_back;
+
+ if (real_s_sizeleft >= copy_back * RECORDSIZE)
+ real_s_sizeleft -= copy_back * RECORDSIZE;
+ else if ((real_s_sizeleft + RECORDSIZE - 1) / RECORDSIZE <= copy_back)
+ real_s_name[0] = '\0';
+ else
+ {
#ifdef __MSDOS__
- if(save_name[1]==':')
- save_name+=2;
+ if (save_name[1] == ':')
+ save_name += 2;
#endif
- while(*save_name=='/')
- save_name++;
+ while (*save_name == '/')
+ save_name++;
- strcpy(real_s_name,save_name);
- real_s_sizeleft = save_sizeleft;
- real_s_totsize=save_totsize;
- }
- copy_back = 0;
+ strcpy (real_s_name, save_name);
+ real_s_sizeleft = save_sizeleft;
+ real_s_totsize = save_totsize;
}
+ copy_back = 0;
+ }
}
/* Handle write errors on the archive. Write errors are always fatal */
* was the first block of the volume */
void
-writeerror(err)
-int err;
+writeerror (err)
+ int err;
{
- if (err < 0) {
- msg_perror("can't write to %s",ar_files[cur_ar_file]);
- exit(EX_BADARCH);
- } else {
- msg("only wrote %u of %u bytes to %s",err,blocksize,ar_files[cur_ar_file]);
- exit(EX_BADARCH);
- }
+ if (err < 0)
+ {
+ msg_perror ("can't write to %s", ar_files[cur_ar_file]);
+ exit (EX_BADARCH);
+ }
+ else
+ {
+ msg ("only wrote %u of %u bytes to %s", err, blocksize, ar_files[cur_ar_file]);
+ exit (EX_BADARCH);
+ }
}
/*
* If the read should be retried, readerror() returns to the caller.
*/
void
-readerror()
+readerror ()
{
# define READ_ERROR_MAX 10
- read_error_flag++; /* Tell callers */
+ read_error_flag++; /* Tell callers */
- msg_perror("read error on %s",ar_files[cur_ar_file]);
+ msg_perror ("read error on %s", ar_files[cur_ar_file]);
- if (baserec == 0) {
- /* First block of tape. Probably stupidity error */
- exit(EX_BADARCH);
- }
+ if (baserec == 0)
+ {
+ /* First block of tape. Probably stupidity error */
+ exit (EX_BADARCH);
+ }
- /*
+ /*
* Read error in mid archive. We retry up to READ_ERROR_MAX times
* and then give up on reading the archive. We set read_error_flag
* for our callers, so they can cope if they want.
*/
- if (r_error_count++ > READ_ERROR_MAX) {
- msg("Too many errors, quitting.");
- exit(EX_BADARCH);
- }
- return;
+ if (r_error_count++ > READ_ERROR_MAX)
+ {
+ msg ("Too many errors, quitting.");
+ exit (EX_BADARCH);
+ }
+ return;
}
* Perform a read to flush the buffer.
*/
void
-fl_read()
+fl_read ()
{
- int err; /* Result from system call */
- int left; /* Bytes left */
- char *more; /* Pointer to next byte to read */
+ int err; /* Result from system call */
+ int left; /* Bytes left */
+ char *more; /* Pointer to next byte to read */
- if (f_checkpoint && ! (++checkpoint % 10))
- msg ("Read checkpoint %d\n", checkpoint);
+ if (f_checkpoint && !(++checkpoint % 10))
+ msg ("Read checkpoint %d\n", checkpoint);
- /*
+ /*
* Clear the count of errors. This only applies to a single
* call to fl_read. We leave read_error_flag alone; it is
* only turned off by higher level software.
*/
- r_error_count = 0; /* Clear error count */
+ r_error_count = 0; /* Clear error count */
- /*
+ /*
* If we are about to wipe out a record that
* somebody needs to keep, copy it out to a holding
* area and adjust somebody's pointer to it.
*/
- if (save_rec &&
- *save_rec >= ar_record &&
- *save_rec < ar_last) {
- record_save_area = **save_rec;
- *save_rec = &record_save_area;
- }
- if(write_archive_to_stdout && baserec!=0) {
- err=rmtwrite(1, ar_block->charptr, blocksize);
- if(err!=blocksize)
- writeerror(err);
- }
- if(f_multivol) {
- if(save_name) {
- if(save_name!=real_s_name) {
+ if (save_rec &&
+ *save_rec >= ar_record &&
+ *save_rec < ar_last)
+ {
+ record_save_area = **save_rec;
+ *save_rec = &record_save_area;
+ }
+ if (write_archive_to_stdout && baserec != 0)
+ {
+ err = rmtwrite (1, ar_block->charptr, blocksize);
+ if (err != blocksize)
+ writeerror (err);
+ }
+ if (f_multivol)
+ {
+ if (save_name)
+ {
+ if (save_name != real_s_name)
+ {
#ifdef __MSDOS__
- if(save_name[1]==':')
- save_name+=2;
+ if (save_name[1] == ':')
+ save_name += 2;
#endif
- while(*save_name=='/')
- save_name++;
+ while (*save_name == '/')
+ save_name++;
- strcpy(real_s_name,save_name);
- save_name=real_s_name;
- }
- real_s_totsize = save_totsize;
- real_s_sizeleft = save_sizeleft;
-
- } else {
- real_s_name[0]='\0';
- real_s_totsize=0;
- real_s_sizeleft = 0;
- }
+ strcpy (real_s_name, save_name);
+ save_name = real_s_name;
+ }
+ real_s_totsize = save_totsize;
+ real_s_sizeleft = save_sizeleft;
+
+ }
+ else
+ {
+ real_s_name[0] = '\0';
+ real_s_totsize = 0;
+ real_s_sizeleft = 0;
}
+ }
error_loop:
- err = rmtread(archive, ar_block->charptr, (int)blocksize);
- if (err == blocksize)
- return;
-
- if((err == 0 || (err<0 && errno==ENOSPC) || (err > 0 && !f_reblock)) && f_multivol) {
- union record *head;
-
- try_volume:
- if(new_volume((cmd_mode==CMD_APPEND || cmd_mode==CMD_CAT || cmd_mode==CMD_UPDATE) ? 2 : 1)<0)
- return;
- vol_error:
- err = rmtread(archive, ar_block->charptr,(int) blocksize);
- if(err < 0) {
- readerror();
- goto vol_error;
- }
- if(err!=blocksize)
- goto short_read;
+ err = rmtread (archive, ar_block->charptr, (int) blocksize);
+ if (err == blocksize)
+ return;
- head=ar_block;
+ if ((err == 0 || (err < 0 && errno == ENOSPC) || (err > 0 && !f_reblock)) && f_multivol)
+ {
+ union record *head;
- if(head->header.linkflag==LF_VOLHDR) {
- if(f_volhdr) {
-#if 0
- char *ptr;
+ try_volume:
+ if (new_volume ((cmd_mode == CMD_APPEND || cmd_mode == CMD_CAT || cmd_mode == CMD_UPDATE) ? 2 : 1) < 0)
+ return;
+ vol_error:
+ err = rmtread (archive, ar_block->charptr, (int) blocksize);
+ if (err < 0)
+ {
+ readerror ();
+ goto vol_error;
+ }
+ if (err != blocksize)
+ goto short_read;
- ptr=(char *)malloc(strlen(f_volhdr)+20);
- sprintf(ptr,"%s Volume %d",f_volhdr,volno);
-#endif
- if (re_match (label_pattern, head->header.name,
- strlen (head->header.name),
- 0, 0) < 0) {
- msg("Volume mismatch! %s!=%s",f_volhdr,
- head->header.name);
- --volno;
- --global_volno;
- goto try_volume;
- }
-
+ head = ar_block;
+
+ if (head->header.linkflag == LF_VOLHDR)
+ {
+ if (f_volhdr)
+ {
#if 0
- if(strcmp(ptr,head->header.name)) {
- msg("Volume mismatch! %s!=%s",ptr,head->header.name);
- --volno;
- --global_volno;
- free(ptr);
- goto try_volume;
- }
- free(ptr);
+ char *ptr;
+
+ ptr = (char *) malloc (strlen (f_volhdr) + 20);
+ sprintf (ptr, "%s Volume %d", f_volhdr, volno);
#endif
- }
- if(f_verbose)
- fprintf(msg_file,"Reading %s\n",head->header.name);
- head++;
- } else if(f_volhdr) {
- msg("Warning: No volume header!");
+ if (re_match (label_pattern, head->header.arch_name,
+ strlen (head->header.arch_name),
+ 0, 0) < 0)
+ {
+ msg ("Volume mismatch! %s!=%s", f_volhdr,
+ head->header.arch_name);
+ --volno;
+ --global_volno;
+ goto try_volume;
}
- if(real_s_name[0]) {
- long from_oct();
-
- if(head->header.linkflag!=LF_MULTIVOL || strcmp(head->header.name,real_s_name)) {
- msg("%s is not continued on this volume!",real_s_name);
- --volno;
- --global_volno;
- goto try_volume;
- }
- if(real_s_totsize!=from_oct(1+12,head->header.size)+from_oct(1+12,head->header.offset)) {
- msg("%s is the wrong size (%ld!=%ld+%ld)",
- head->header.name,save_totsize,
- from_oct(1+12,head->header.size),
- from_oct(1+12,head->header.offset));
- --volno;
- --global_volno;
- goto try_volume;
- }
- if(real_s_totsize-real_s_sizeleft!=from_oct(1+12,head->header.offset)) {
- msg("This volume is out of sequence");
- --volno;
- --global_volno;
- goto try_volume;
- }
- head++;
+#if 0
+ if (strcmp (ptr, head->header.name))
+ {
+ msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
+ --volno;
+ --global_volno;
+ free (ptr);
+ goto try_volume;
}
- ar_record=head;
- return;
- } else if (err < 0) {
- readerror();
- goto error_loop; /* Try again */
+ free (ptr);
+#endif
+ }
+ if (f_verbose)
+ fprintf (msg_file, "Reading %s\n", head->header.arch_name);
+ head++;
+ }
+ else if (f_volhdr)
+ {
+ msg ("Warning: No volume header!");
}
- short_read:
- more = ar_block->charptr + err;
- left = blocksize - err;
+ if (real_s_name[0])
+ {
+ long from_oct ();
+
+ if (head->header.linkflag != LF_MULTIVOL || strcmp (head->header.arch_name, real_s_name))
+ {
+ msg ("%s is not continued on this volume!", real_s_name);
+ --volno;
+ --global_volno;
+ goto try_volume;
+ }
+ if (real_s_totsize != from_oct (1 + 12, head->header.size) + from_oct (1 + 12, head->header.offset))
+ {
+ msg ("%s is the wrong size (%ld!=%ld+%ld)",
+ head->header.arch_name, save_totsize,
+ from_oct (1 + 12, head->header.size),
+ from_oct (1 + 12, head->header.offset));
+ --volno;
+ --global_volno;
+ goto try_volume;
+ }
+ if (real_s_totsize - real_s_sizeleft != from_oct (1 + 12, head->header.offset))
+ {
+ msg ("This volume is out of sequence");
+ --volno;
+ --global_volno;
+ goto try_volume;
+ }
+ head++;
+ }
+ ar_record = head;
+ return;
+ }
+ else if (err < 0)
+ {
+ readerror ();
+ goto error_loop; /* Try again */
+ }
+
+short_read:
+ more = ar_block->charptr + err;
+ left = blocksize - err;
again:
- if (0 == (((unsigned)left) % RECORDSIZE)) {
- /* FIXME, for size=0, multi vol support */
- /* On the first block, warn about the problem */
- if (!f_reblock && baserec == 0 && f_verbose && err > 0) {
- /* msg("Blocksize = %d record%s",
+ if (0 == (((unsigned) left) % RECORDSIZE))
+ {
+ /* FIXME, for size=0, multi vol support */
+ /* On the first block, warn about the problem */
+ if (!f_reblock && baserec == 0 && f_verbose && err > 0)
+ {
+ /* msg("Blocksize = %d record%s",
err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
- msg("Blocksize = %d records", err / RECORDSIZE);
- }
- ar_last = ar_block + ((unsigned)(blocksize - left))/RECORDSIZE;
- return;
+ msg ("Blocksize = %d records", err / RECORDSIZE);
}
- if (f_reblock) {
- /*
+ ar_last = ar_block + ((unsigned) (blocksize - left)) / RECORDSIZE;
+ return;
+ }
+ if (f_reblock)
+ {
+ /*
* User warned us about this. Fix up.
*/
- if (left > 0) {
-error2loop:
- err = rmtread(archive, more, (int)left);
- if (err < 0) {
- readerror();
- goto error2loop; /* Try again */
- }
- if (err == 0) {
- msg("archive %s EOF not on block boundary",ar_files[cur_ar_file]);
- exit(EX_BADARCH);
- }
- left -= err;
- more += err;
- goto again;
- }
- } else {
- msg("only read %d bytes from archive %s",err,ar_files[cur_ar_file]);
- exit(EX_BADARCH);
+ if (left > 0)
+ {
+ error2loop:
+ err = rmtread (archive, more, (int) left);
+ if (err < 0)
+ {
+ readerror ();
+ goto error2loop; /* Try again */
+ }
+ if (err == 0)
+ {
+ msg ("archive %s EOF not on block boundary", ar_files[cur_ar_file]);
+ exit (EX_BADARCH);
+ }
+ left -= err;
+ more += err;
+ goto again;
}
+ }
+ else
+ {
+ msg ("only read %d bytes from archive %s", err, ar_files[cur_ar_file]);
+ exit (EX_BADARCH);
+ }
}
* Flush the current buffer to/from the archive.
*/
void
-flush_archive()
+flush_archive ()
{
- int c;
-
- baserec += ar_last - ar_block; /* Keep track of block #s */
- ar_record = ar_block; /* Restore pointer to start */
- ar_last = ar_block + blocking; /* Restore pointer to end */
-
- if (ar_reading) {
- if(time_to_start_writing) {
- time_to_start_writing=0;
- ar_reading=0;
-
- if(file_to_switch_to>=0) {
- if((c=rmtclose(archive))<0)
- msg_perror("Warning: can't close %s(%d,%d)",ar_files[cur_ar_file],archive,c);
-
- archive=file_to_switch_to;
- } else
- (void)backspace_output();
- fl_write();
- } else
- fl_read();
- } else {
- fl_write();
+ int c;
+
+ baserec += ar_last - ar_block;/* Keep track of block #s */
+ ar_record = ar_block; /* Restore pointer to start */
+ ar_last = ar_block + blocking;/* Restore pointer to end */
+
+ if (ar_reading)
+ {
+ if (time_to_start_writing)
+ {
+ time_to_start_writing = 0;
+ ar_reading = 0;
+
+ if (file_to_switch_to >= 0)
+ {
+ if ((c = rmtclose (archive)) < 0)
+ msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
+
+ archive = file_to_switch_to;
+ }
+ else
+ (void) backspace_output ();
+ fl_write ();
}
+ else
+ fl_read ();
+ }
+ else
+ {
+ fl_write ();
+ }
}
/* Backspace the archive descriptor by one blocks worth.
If its a tape, MTIOCTOP will work. If its something else,
we try to seek on it. If we can't seek, we lose! */
int
-backspace_output()
+backspace_output ()
{
- long cur;
- /* int er; */
- extern char *output_start;
+ long cur;
+ /* int er; */
+ extern char *output_start;
#ifdef MTIOCTOP
- struct mtop t;
-
- t.mt_op = MTBSR;
- t.mt_count = 1;
- if((rmtioctl(archive,MTIOCTOP,&t))>=0)
- return 1;
- if(errno==EIO && (rmtioctl(archive,MTIOCTOP,&t))>=0)
- return 1;
+ struct mtop t;
+
+ t.mt_op = MTBSR;
+ t.mt_count = 1;
+ if ((rmtioctl (archive, MTIOCTOP, &t)) >= 0)
+ return 1;
+ if (errno == EIO && (rmtioctl (archive, MTIOCTOP, &t)) >= 0)
+ return 1;
#endif
- cur=rmtlseek(archive,0L,1);
- cur-=blocksize;
- /* Seek back to the beginning of this block and
+ cur = rmtlseek (archive, 0L, 1);
+ cur -= blocksize;
+ /* Seek back to the beginning of this block and
start writing there. */
- if(rmtlseek(archive,cur,0)!=cur) {
- /* Lseek failed. Try a different method */
- msg("Couldn't backspace archive file. It may be unreadable without -i.");
- /* Replace the first part of the block with nulls */
- if(ar_block->charptr!=output_start)
- bzero(ar_block->charptr,output_start-ar_block->charptr);
- return 2;
- }
- return 3;
+ if (rmtlseek (archive, cur, 0) != cur)
+ {
+ /* Lseek failed. Try a different method */
+ msg ("Couldn't backspace archive file. It may be unreadable without -i.");
+ /* Replace the first part of the block with nulls */
+ if (ar_block->charptr != output_start)
+ bzero (ar_block->charptr, output_start - ar_block->charptr);
+ return 2;
+ }
+ return 3;
}
* Close the archive file.
*/
void
-close_archive()
+close_archive ()
{
- int child;
- int status;
- int c;
+ int child;
+ int status;
+ int c;
- if (time_to_start_writing || !ar_reading)
- flush_archive();
- if(cmd_mode==CMD_DELETE) {
- off_t pos;
+ if (time_to_start_writing || !ar_reading)
+ flush_archive ();
+ if (cmd_mode == CMD_DELETE)
+ {
+ off_t pos;
- pos = rmtlseek(archive,0L,1);
+ pos = rmtlseek (archive, 0L, 1);
#ifndef __MSDOS__
- (void) ftruncate(archive,pos);
+ (void) ftruncate (archive, pos);
#else
- (void)rmtwrite(archive,"",0);
+ (void) rmtwrite (archive, "", 0);
#endif
- }
- if(f_verify)
- verify_volume();
+ }
+ if (f_verify)
+ verify_volume ();
- if((c=rmtclose(archive))<0)
- msg_perror("Warning: can't close %s(%d,%d)",ar_files[cur_ar_file],archive,c);
+ if ((c = rmtclose (archive)) < 0)
+ msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
#ifndef __MSDOS__
- if (childpid) {
- /*
- * Loop waiting for the right child to die, or for
- * no more kids.
- */
- while (((child = wait(&status)) != childpid) && child != -1)
- ;
-
- if (child != -1) {
- switch (WTERMSIG(status)) {
- case 0:
- /* Child voluntarily terminated -- but why? */
- if (WEXITSTATUS(status) == MAGIC_STAT) {
- exit(EX_SYSTEM);/* Child had trouble */
- }
- if (WEXITSTATUS(status) == (SIGPIPE + 128)) {
- /*
- * /bin/sh returns this if its child
- * dies with SIGPIPE. 'Sok.
- */
- break;
- } else if (WEXITSTATUS(status))
- msg("child returned status %d",
- WEXITSTATUS(status));
- case SIGPIPE:
- break; /* This is OK. */
-
- default:
- msg("child died with signal %d%s",
- WTERMSIG(status),
- WIFCOREDUMPED(status)? " (core dumped)": "");
- }
+ if (childpid)
+ {
+ /*
+ * Loop waiting for the right child to die, or for
+ * no more kids.
+ */
+ while (((child = wait (&status)) != childpid) && child != -1)
+ ;
+
+ if (child != -1)
+ {
+ if (WIFSIGNALED (status))
+ {
+ /* SIGPIPE is OK, everything else is a problem. */
+ if (WTERMSIG (status) != SIGPIPE)
+ msg ("child died with signal %d%s", WTERMSIG (status),
+ WIFCOREDUMPED (status) ? " (core dumped)" : "");
+ }
+ else
+ {
+ /* Child voluntarily terminated -- but why? */
+ if (WEXITSTATUS (status) == MAGIC_STAT)
+ {
+ exit (EX_SYSTEM); /* Child had trouble */
+ }
+ if (WEXITSTATUS (status) == (SIGPIPE + 128))
+ {
+ /*
+ * /bin/sh returns this if its child
+ * dies with SIGPIPE. 'Sok.
+ */
+ /* Do nothing. */
}
+ else if (WEXITSTATUS (status))
+ msg ("child returned status %d",
+ WEXITSTATUS (status));
+ }
}
-#endif /* __MSDOS__ */
+ }
+#endif /* __MSDOS__ */
}
* "current" record # is used.
*/
void
-anno(stream, prefix, savedp)
- FILE *stream;
- char *prefix;
- int savedp;
+anno (stream, prefix, savedp)
+ FILE *stream;
+ char *prefix;
+ int savedp;
{
# define MAXANNO 50
- char buffer[MAXANNO]; /* Holds annorecment */
+ char buffer[MAXANNO]; /* Holds annorecment */
# define ANNOWIDTH 13
- int space;
- long offset;
- int save_e;
-
- save_e=errno;
- /* Make sure previous output gets out in sequence */
- if (stream == stderr)
- fflush(stdout);
- if (f_sayblock) {
- if (prefix) {
- fputs(prefix, stream);
- putc(' ', stream);
- }
- offset = ar_record - ar_block;
- (void) sprintf(buffer, "rec %d: ",
- savedp? saved_recno:
- baserec + offset);
- fputs(buffer, stream);
- space = ANNOWIDTH - strlen(buffer);
- if (space > 0) {
- fprintf(stream, "%*s", space, "");
- }
- } else if (prefix) {
- fputs(prefix, stream);
- fputs(": ", stream);
+ int space;
+ long offset;
+ int save_e;
+
+ save_e = errno;
+ /* Make sure previous output gets out in sequence */
+ if (stream == stderr)
+ fflush (stdout);
+ if (f_sayblock)
+ {
+ if (prefix)
+ {
+ fputs (prefix, stream);
+ putc (' ', stream);
+ }
+ offset = ar_record - ar_block;
+ (void) sprintf (buffer, "rec %d: ",
+ savedp ? saved_recno :
+ baserec + offset);
+ fputs (buffer, stream);
+ space = ANNOWIDTH - strlen (buffer);
+ if (space > 0)
+ {
+ fprintf (stream, "%*s", space, "");
}
- errno=save_e;
+ }
+ else if (prefix)
+ {
+ fputs (prefix, stream);
+ fputs (": ", stream);
+ }
+ errno = save_e;
}
+
#endif
/* Called to initialize the global volume number. */
-int
+void
init_volume_number ()
{
FILE *vf;
-
+
vf = fopen (f_volno_file, "r");
if (!vf && errno != ENOENT)
msg_perror ("%s", f_volno_file);
-
+
if (vf)
{
fscanf (vf, "%d", &global_volno);
}
/* Called to write out the closing global volume number. */
-int
+void
closeout_volume_number ()
{
FILE *vf;
-
+
vf = fopen (f_volno_file, "w");
if (!vf)
msg_perror ("%s", f_volno_file);
fclose (vf);
}
}
-
+
/* We've hit the end of the old volume. Close it and open the next one */
/* Values for type: 0: writing 1: reading 2: updating */
int
-new_volume(type)
-int type;
+new_volume (type)
+ int type;
{
- int c;
- char inbuf[80];
- char *p;
- static FILE *read_file = 0;
- extern int now_verifying;
- extern char TTY_NAME[];
- char *getenv();
- static int looped = 0;
-
- if(!read_file && !f_run_script_at_end)
- read_file = (archive==0) ? fopen(TTY_NAME, "r") : stdin;
-
- if(now_verifying)
- return -1;
- if(f_verify)
- verify_volume();
- if((c=rmtclose(archive))<0)
- msg_perror("Warning: can't close %s(%d,%d)",ar_files[cur_ar_file],archive,c);
-
- global_volno++;
- volno++;
- cur_ar_file++;
- if (cur_ar_file == n_ar_files)
- {
- cur_ar_file = 0;
- looped = 1;
- }
-
- tryagain:
- if (looped)
- {
- /* We have to prompt from now on. */
- if (f_run_script_at_end)
- system(info_script);
- else for(;;) {
- fprintf(msg_file,"\007Prepare volume #%d for %s and hit return: ",global_volno, ar_files[cur_ar_file]);
- fflush(msg_file);
- if(fgets(inbuf,sizeof(inbuf),read_file)==0) {
- fprintf(msg_file,"EOF? What does that mean?");
- if(cmd_mode!=CMD_EXTRACT && cmd_mode!=CMD_LIST && cmd_mode!=CMD_DIFF)
- msg("Warning: Archive is INCOMPLETE!");
- exit(EX_BADARCH);
- }
- if(inbuf[0]=='\n' || inbuf[0]=='y' || inbuf[0]=='Y')
- break;
+ int c;
+ char inbuf[80];
+ char *p;
+ static FILE *read_file = 0;
+ extern int now_verifying;
+ extern char TTY_NAME[];
+ static int looped = 0;
+
+ if (!read_file && !f_run_script_at_end)
+ read_file = (archive == 0) ? fopen (TTY_NAME, "r") : stdin;
+
+ if (now_verifying)
+ return -1;
+ if (f_verify)
+ verify_volume ();
+ if ((c = rmtclose (archive)) < 0)
+ msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
+
+ global_volno++;
+ volno++;
+ cur_ar_file++;
+ if (cur_ar_file == n_ar_files)
+ {
+ cur_ar_file = 0;
+ looped = 1;
+ }
- switch(inbuf[0]) {
- case '?':
- {
- fprintf(msg_file,"\
+tryagain:
+ if (looped)
+ {
+ /* We have to prompt from now on. */
+ if (f_run_script_at_end)
+ {
+ closeout_volume_number ();
+ system (info_script);
+ }
+ else
+ for (;;)
+ {
+ fprintf (msg_file, "\007Prepare volume #%d for %s and hit return: ", global_volno, ar_files[cur_ar_file]);
+ fflush (msg_file);
+ if (fgets (inbuf, sizeof (inbuf), read_file) == 0)
+ {
+ fprintf (msg_file, "EOF? What does that mean?");
+ if (cmd_mode != CMD_EXTRACT && cmd_mode != CMD_LIST && cmd_mode != CMD_DIFF)
+ msg ("Warning: Archive is INCOMPLETE!");
+ exit (EX_BADARCH);
+ }
+ if (inbuf[0] == '\n' || inbuf[0] == 'y' || inbuf[0] == 'Y')
+ break;
+
+ switch (inbuf[0])
+ {
+ case '?':
+ {
+ fprintf (msg_file, "\
n [name] Give a new filename for the next (and subsequent) volume(s)\n\
q Abort tar\n\
! Spawn a subshell\n\
? Print this list\n");
- }
- break;
-
- case 'q': /* Quit */
- fprintf(msg_file,"No new volume; exiting.\n");
- if(cmd_mode!=CMD_EXTRACT && cmd_mode!=CMD_LIST && cmd_mode!=CMD_DIFF)
- msg("Warning: Archive is INCOMPLETE!");
- exit(EX_BADARCH);
-
- case 'n': /* Get new file name */
+ }
+ break;
+
+ case 'q': /* Quit */
+ fprintf (msg_file, "No new volume; exiting.\n");
+ if (cmd_mode != CMD_EXTRACT && cmd_mode != CMD_LIST && cmd_mode != CMD_DIFF)
+ msg ("Warning: Archive is INCOMPLETE!");
+ exit (EX_BADARCH);
+
+ case 'n': /* Get new file name */
+ {
+ char *q, *r;
+ static char *old_name;
+
+ for (q = &inbuf[1]; *q == ' ' || *q == '\t'; q++)
+ ;
+ for (r = q; *r; r++)
+ if (*r == '\n')
+ *r = '\0';
+ old_name = p = (char *) malloc ((unsigned) (strlen (q) + 2));
+ if (p == 0)
{
- char *q,*r;
- static char *old_name;
-
- for(q= &inbuf[1];*q==' ' || *q=='\t';q++)
- ;
- for(r=q;*r;r++)
- if(*r=='\n')
- *r='\0';
- old_name=p=(char *)malloc((unsigned)(strlen(q)+2));
- if(p==0) {
- msg("Can't allocate memory for name");
- exit(EX_SYSTEM);
- }
- (void) strcpy(p,q);
- ar_files[cur_ar_file]=p;
+ msg ("Can't allocate memory for name");
+ exit (EX_SYSTEM);
}
- break;
-
- case '!':
- #ifdef __MSDOS__
- spawnl(P_WAIT,getenv("COMSPEC"),"-",0);
- #else
- /* JF this needs work! */
- switch(fork()) {
- case -1:
- msg_perror("can't fork!");
- break;
- case 0:
- p=getenv("SHELL");
- if(p==0) p="/bin/sh";
- execlp(p,"-sh","-i",0);
- msg_perror("can't exec a shell %s",p);
- _exit(55);
- default:
- wait(0);
- break;
- }
- #endif
- break;
- }
+ (void) strcpy (p, q);
+ ar_files[cur_ar_file] = p;
+ }
+ break;
+
+ case '!':
+#ifdef __MSDOS__
+ spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
+#else
+ /* JF this needs work! */
+ switch (fork ())
+ {
+ case -1:
+ msg_perror ("can't fork!");
+ break;
+ case 0:
+ p = getenv ("SHELL");
+ if (p == 0)
+ p = "/bin/sh";
+ execlp (p, "-sh", "-i", 0);
+ msg_perror ("can't exec a shell %s", p);
+ _exit (55);
+ default:
+ wait (0);
+ break;
}
- }
-
-
- if(type==2 || f_verify)
- archive=rmtopen(ar_files[cur_ar_file],O_RDWR|O_CREAT,0666);
- else if(type==1)
- archive=rmtopen(ar_files[cur_ar_file],O_RDONLY,0666);
- else if(type==0)
- archive=rmtcreat(ar_files[cur_ar_file],0666);
- else
- archive= -1;
-
- if(archive<0) {
- msg_perror("can't open %s",ar_files[cur_ar_file]);
- goto tryagain;
- }
+#endif
+ break;
+ }
+ }
+ }
+
+
+ if (type == 2 || f_verify)
+ archive = rmtopen (ar_files[cur_ar_file], O_RDWR | O_CREAT, 0666);
+ else if (type == 1)
+ archive = rmtopen (ar_files[cur_ar_file], O_RDONLY, 0666);
+ else if (type == 0)
+ archive = rmtcreat (ar_files[cur_ar_file], 0666);
+ else
+ archive = -1;
+
+ if (archive < 0)
+ {
+ msg_perror ("can't open %s", ar_files[cur_ar_file]);
+ goto tryagain;
+ }
#ifdef __MSDOS__
- setmode(archive,O_BINARY);
+ setmode (archive, O_BINARY);
#endif
- return 0;
+ return 0;
}
/* this is a useless function that takes a buffer returned by wantbytes
the file.
*/
int
-no_op(size,data)
-int size;
-char *data;
+no_op (size, data)
+ int size;
+ char *data;
{
- return 0;
+ return 0;
}
/* Some other routine wants SIZE bytes in the archive. For each chunk of
the chunk it can work with.
*/
int
-wantbytes(size,func)
-long size;
-int (*func)();
+wantbytes (size, func)
+ long size;
+ int (*func) ();
{
- char *data;
- long data_size;
-
- while(size) {
- data = findrec()->charptr;
- if (data == NULL) { /* Check it... */
- msg("Unexpected EOF on archive file");
- return -1;
- }
- data_size = endofrecs()->charptr - data;
- if(data_size>size)
- data_size=size;
- if((*func)(data_size,data))
- func=no_op;
- userec((union record *)(data + data_size - 1));
- size-=data_size;
+ char *data;
+ long data_size;
+
+ while (size)
+ {
+ data = findrec ()->charptr;
+ if (data == NULL)
+ { /* Check it... */
+ msg ("Unexpected EOF on archive file");
+ return -1;
}
- return 0;
+ data_size = endofrecs ()->charptr - data;
+ if (data_size > size)
+ data_size = size;
+ if ((*func) (data_size, data))
+ func = no_op;
+ userec ((union record *) (data + data_size - 1));
+ size -= data_size;
+ }
+ return 0;
}