pax could create a archive with just a trailer if no files selected.
authorKeith Muller <muller@ucbvax.Berkeley.EDU>
Sun, 17 Jan 1993 15:48:40 +0000 (07:48 -0800)
committerKeith Muller <muller@ucbvax.Berkeley.EDU>
Sun, 17 Jan 1993 15:48:40 +0000 (07:48 -0800)
SCCS-vsn: bin/pax/ar_subs.c 1.4
SCCS-vsn: bin/pax/ar_io.c 1.4

usr/src/bin/pax/ar_io.c
usr/src/bin/pax/ar_subs.c

index 48283dd..a872c47 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ar_io.c    1.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)ar_io.c    1.4 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/types.h>
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -41,7 +41,7 @@ static char sccsid[] = "@(#)ar_io.c   1.3 (Berkeley) %G%";
 #define STDO           "<STDOUT>"      /* psuedo name for stdout */
 #define STDN           "<STDIN>"       /* psuedo name for stdin */
 static int arfd = -1;                  /* archive file descriptor */
 #define STDO           "<STDOUT>"      /* psuedo name for stdout */
 #define STDN           "<STDIN>"       /* psuedo name for stdin */
 static int arfd = -1;                  /* archive file descriptor */
-static int artyp;                      /* archive type: file/FIFO/tape */
+static int artyp = ISREG;              /* archive type: file/FIFO/tape */
 static int arvol = 1;                  /* archive volume number */
 static int lstrval = -1;               /* return value from last i/o */
 static int io_ok;                      /* i/o worked on volume after resync */
 static int arvol = 1;                  /* archive volume number */
 static int lstrval = -1;               /* return value from last i/o */
 static int io_ok;                      /* i/o worked on volume after resync */
@@ -51,6 +51,7 @@ static struct stat arsb;              /* stat of archive device at open */
 static int invld_rec;                  /* tape has out of spec record size */
 static int phyblk;                     /* size of physical block on TAPE */
 static int wr_trail = 1;               /* trailer was rewritten in append */
 static int invld_rec;                  /* tape has out of spec record size */
 static int phyblk;                     /* size of physical block on TAPE */
 static int wr_trail = 1;               /* trailer was rewritten in append */
+static int can_unlnk = 0;              /* do we unlink null archives?  */
 char *arcname;                         /* printable name of archive */
 
 static int get_phys __P((void));
 char *arcname;                         /* printable name of archive */
 
 static int get_phys __P((void));
@@ -79,7 +80,8 @@ ar_open(name)
        if (arfd != -1)
                (void)close(arfd);
        arfd = -1;
        if (arfd != -1)
                (void)close(arfd);
        arfd = -1;
-       phyblk = did_io = io_ok = invld_rec = 0;
+       can_unlnk = phyblk = did_io = io_ok = invld_rec = 0;
+       artyp = ISREG;
        flcnt = 0;
 
        /*
        flcnt = 0;
 
        /*
@@ -100,6 +102,8 @@ ar_open(name)
                        arcname = STDO;
                } else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
                        syswarn(0, errno, "Failed open to write on %s", name);
                        arcname = STDO;
                } else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
                        syswarn(0, errno, "Failed open to write on %s", name);
+               else
+                       can_unlnk = 1;
                break;
        case APPND:
                if (name == NULL) {
                break;
        case APPND:
                if (name == NULL) {
@@ -125,13 +129,20 @@ ar_open(name)
         */
        if (fstat(arfd, &arsb) < 0) {
                syswarn(0, errno, "Failed stat on %s", arcname);
         */
        if (fstat(arfd, &arsb) < 0) {
                syswarn(0, errno, "Failed stat on %s", arcname);
+               (void)close(arfd);
+               arfd = -1;
+               can_unlnk = 0;
                return(-1);
        }
        if (S_ISDIR(arsb.st_mode)) {
                warn(0, "Cannot write an archive on top of a directory %s",
                    arcname);
                return(-1);
        }
        if (S_ISDIR(arsb.st_mode)) {
                warn(0, "Cannot write an archive on top of a directory %s",
                    arcname);
+               (void)close(arfd);
+               arfd = -1;
+               can_unlnk = 0;
                return(-1);
        }
                return(-1);
        }
+
        if (S_ISCHR(arsb.st_mode))
                artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
        else if (S_ISBLK(arsb.st_mode))
        if (S_ISCHR(arsb.st_mode))
                artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
        else if (S_ISBLK(arsb.st_mode))
@@ -141,6 +152,12 @@ ar_open(name)
        else
                artyp = ISREG;
 
        else
                artyp = ISREG;
 
+       /*
+        * make sure we beyond any doubt that we only can unlink regular files
+        * we created
+        */
+       if (artyp != ISREG)
+               can_unlnk = 0;
        /*
         * if we are writing, we are done
         */
        /*
         * if we are writing, we are done
         */
@@ -281,6 +298,16 @@ ar_close()
                (void)fflush(outf);
        }
 
                (void)fflush(outf);
        }
 
+       /*
+        * if nothing was written to the archive (and we created it), we remove
+        * it
+        */
+       if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
+           (arsb.st_size == 0)) {
+               (void)unlink(arcname);
+               can_unlnk = 0;
+       }
+
        (void)close(arfd);
 
        if (vflag && (artyp == ISTAPE)) {
        (void)close(arfd);
 
        if (vflag && (artyp == ISTAPE)) {
index fb3cd02..cd6bff2 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ar_subs.c  1.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)ar_subs.c  1.4 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/types.h>
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -28,7 +28,7 @@ static char sccsid[] = "@(#)ar_subs.c 1.3 (Berkeley) %G%";
 #include "pax.h"
 #include "extern.h"
 
 #include "pax.h"
 #include "extern.h"
 
-static void wr_archive __P((register ARCHD *));
+static void wr_archive __P((register ARCHD *, int is_app));
 static int get_arc __P((void));
 static int next_head __P((register ARCHD *));
 extern sigset_t s_mask;
 static int get_arc __P((void));
 static int next_head __P((register ARCHD *));
 extern sigset_t s_mask;
@@ -319,15 +319,17 @@ extract()
 
 #if __STDC__
 static void
 
 #if __STDC__
 static void
-wr_archive(register ARCHD *arcn)
+wr_archive(register ARCHD *arcn, int is_app)
 #else
 static void
 #else
 static void
-wr_archive(arcn)
+wr_archive(arcn, is_app)
        register ARCHD *arcn;
        register ARCHD *arcn;
+       int is_app;
 #endif
 {
        register int res;
        register int hlk;
 #endif
 {
        register int res;
        register int hlk;
+       register int wr_one;
        off_t cnt;
        int (*wrf)();
        int fd = -1;
        off_t cnt;
        int (*wrf)();
        int fd = -1;
@@ -353,6 +355,11 @@ wr_archive(arcn)
        if (iflag && (name_start() < 0))
                return;
 
        if (iflag && (name_start() < 0))
                return;
 
+       /*
+        * if this not append, and there are no files, we do no write a trailer
+        */
+       wr_one = is_app;
+
        /*
         * while there are files to archive, process them one at at time
         */
        /*
         * while there are files to archive, process them one at at time
         */
@@ -435,6 +442,7 @@ wr_archive(arcn)
                        rdfile_close(arcn, &fd);
                        break;
                }
                        rdfile_close(arcn, &fd);
                        break;
                }
+               wr_one = 1;
                if (res > 0) {
                        /* 
                         * format write says no file data needs to be stored
                if (res > 0) {
                        /* 
                         * format write says no file data needs to be stored
@@ -479,8 +487,10 @@ wr_archive(arcn)
         * were matched. block off signals to avoid chance for multiple entry
         * into the cleanup code
         */
         * were matched. block off signals to avoid chance for multiple entry
         * into the cleanup code
         */
-       (*frmt->end_wr)();
-       wr_fin();
+       if (wr_one) {
+               (*frmt->end_wr)();
+               wr_fin();
+       }
        (void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL);
        ar_close();
        if (tflag)
        (void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL);
        ar_close();
        if (tflag)
@@ -643,7 +653,7 @@ append()
        /*
         * go to the writing phase to add the new members
         */
        /*
         * go to the writing phase to add the new members
         */
-       wr_archive(arcn);
+       wr_archive(arcn, 1);
 }
 
 /*
 }
 
 /*
@@ -671,7 +681,7 @@ archive()
        if ((*frmt->options)() < 0)
                return;
 
        if ((*frmt->options)() < 0)
                return;
 
-       wr_archive(&archd);
+       wr_archive(&archd, 0);
 }
 
 /*
 }
 
 /*