BSD 4_2 release
[unix-history] / usr / src / bin / ar.c
index 1932e45..e07e875 100644 (file)
@@ -1,22 +1,26 @@
-static char sccsid[] = "@(#)ar.c 4.1 10/1/80";
+#ifndef lint
+static char sccsid[] = "@(#)ar.c       4.5 (Berkeley) 9/25/83";
+#endif
+
 /*
  * ar - portable (ascii) format version
  */
 /*
  * ar - portable (ascii) format version
  */
-#include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/time.h>
+
+#include <stdio.h>
 #include <ar.h>
 #include <signal.h>
 
 #include <ar.h>
 #include <signal.h>
 
-typedef        unsigned short ushort;
 struct stat    stbuf;
 struct ar_hdr  arbuf;
 struct lar_hdr {
        char    lar_name[16];
        long    lar_date;
 struct stat    stbuf;
 struct ar_hdr  arbuf;
 struct lar_hdr {
        char    lar_name[16];
        long    lar_date;
-       ushort  lar_uid;
-       ushort  lar_gid;
-       ushort  lar_mode;
+       u_short lar_uid;
+       u_short lar_gid;
+       u_short lar_mode;
        long    lar_size;
 } larbuf;
 
        long    lar_size;
 } larbuf;
 
@@ -26,7 +30,7 @@ struct        lar_hdr {
 #define        HEAD    8
 
 char   *man    =       { "mrxtdpq" };
 #define        HEAD    8
 
 char   *man    =       { "mrxtdpq" };
-char   *opt    =       { "uvnbail" };
+char   *opt    =       { "uvnbailo" };
 
 int    signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
 int    sigdone();
 
 int    signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
 int    sigdone();
@@ -59,6 +63,7 @@ int   tf2;
 int    qf;
 int    bastate;
 char   buf[BUFSIZ];
 int    qf;
 int    bastate;
 char   buf[BUFSIZ];
+int    truncate;                       /* ok to truncate argument filenames */
 
 char   *trim();
 char   *mktemp();
 
 char   *trim();
 char   *mktemp();
@@ -78,6 +83,7 @@ char *argv[];
        cp = argv[1];
        for(cp = argv[1]; *cp; cp++)
        switch(*cp) {
        cp = argv[1];
        for(cp = argv[1]; *cp; cp++)
        switch(*cp) {
+       case 'o':
        case 'l':
        case 'v':
        case 'u':
        case 'l':
        case 'v':
        case 'u':
@@ -214,6 +220,7 @@ dcmd()
 xcmd()
 {
        register f;
 xcmd()
 {
        register f;
+       struct timeval tv[2];
 
        if(getaf())
                noar();
 
        if(getaf())
                noar();
@@ -227,6 +234,11 @@ xcmd()
                        mesg('x');
                        copyfil(af, f, IODD);
                        close(f);
                        mesg('x');
                        copyfil(af, f, IODD);
                        close(f);
+                       if (flg['o'-'a']) {
+                               tv[0].tv_sec = tv[1].tv_sec = larbuf.lar_date;
+                               tv[0].tv_usec = tv[1].tv_usec = 0;
+                               utimes(file, tv);
+                       }
                        continue;
                }
        sk:
                        continue;
                }
        sk:
@@ -304,6 +316,7 @@ qcmd()
                fprintf(stderr, "ar: abi not allowed with q\n");
                done(1);
        }
                fprintf(stderr, "ar: abi not allowed with q\n");
                done(1);
        }
+       truncate++;
        getqf();
        for(i=0; signum[i]; i++)
                signal(signum[i], SIG_IGN);
        getqf();
        for(i=0; signum[i]; i++)
                signal(signum[i], SIG_IGN);
@@ -375,7 +388,7 @@ getqf()
 
 usage()
 {
 
 usage()
 {
-       printf("usage: ar [%s][%s] archive files ...\n", opt, man);
+       printf("usage: ar [%s][%s] archive files ...\n", man, opt);
        done(1);
 }
 
        done(1);
 }
 
@@ -431,6 +444,7 @@ cleanup()
 {
        register i, f;
 
 {
        register i, f;
 
+       truncate++;
        for(i=0; i<namc; i++) {
                file = namv[i];
                if(file == 0)
        for(i=0; i<namc; i++) {
                file = namv[i];
                if(file == 0)
@@ -659,6 +673,7 @@ char *s;
 {
        register char *p1, *p2;
 
 {
        register char *p1, *p2;
 
+       /* Strip trailing slashes */
        for(p1 = s; *p1; p1++)
                ;
        while(p1 > s) {
        for(p1 = s; *p1; p1++)
                ;
        while(p1 > s) {
@@ -666,10 +681,25 @@ char *s;
                        break;
                *p1 = 0;
        }
                        break;
                *p1 = 0;
        }
+
+       /* Find last component of path; do not zap the path */
        p2 = s;
        for(p1 = s; *p1; p1++)
                if(*p1 == '/')
                        p2 = p1+1;
        p2 = s;
        for(p1 = s; *p1; p1++)
                if(*p1 == '/')
                        p2 = p1+1;
+
+       /*
+        * Truncate name if too long, only if we are doing an 'add'
+        * type operation. We only allow 15 cause rest of ar
+        * isn't smart enough to deal with non-null terminated
+        * names.  Need an exit status convention...
+        * Need yet another new archive format...
+        */
+       if (truncate && strlen(p2) > sizeof(arbuf.ar_name) - 1) {
+               fprintf(stderr, "ar: filename %s truncated to ", p2);
+               *(p2 + sizeof(arbuf.ar_name) - 1) = '\0';
+               fprintf(stderr, "%s\n", p2);
+       }
        return(p2);
 }
 
        return(p2);
 }