Increase size of space for ACL in "up" command.
[openafs.git] / src / venus / up.c
index 31d0d6a..9334f0f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
+#include <roken.h>
 
-/* missing type from C language */
-
-#include <errno.h>
-#ifdef AFS_AIX32_ENV
-#include <signal.h>
-#undef _NONSTD_TYPES
-#endif
-#include <stdio.h>
 #include <afs/afs_args.h>
-#include <sys/param.h>
-#ifdef AFS_SUN5_ENV
-#include <fcntl.h>
-#endif
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <sys/time.h>
 #define VIRTUE
 #define VICE
-#include <sys/ioctl.h>
 #include <afs/vice.h>
 #undef VIRTUE
 #undef VICE
-#include <sys/ioctl.h>
-#include <netdb.h>
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
 #include <afs/venus.h>
+#include <afs/sys_prototypes.h>
+#include <afs/afsutil.h>
+#include <afs/afs_consts.h>
 
 /* ************************************************************* */
 
-#define MAXACL 400
-
-#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
-extern sys_nerr;
-extern char *sys_errlist[];
-#endif
+#define MAXACL AFS_PIOCTL_MAXSIZE
 
 short verbose = 0;
 short renameTargets = 0;
@@ -68,13 +34,11 @@ short preserveDate = 1;
 short preserveMountPoints = 0;
 short forceOverwrite = 0;
 
-int pageSize;
 short setacl = 1;
 short oldAcl = 0;
 char file1[MAXPATHLEN], file2[MAXPATHLEN];
 
-#define        MAXSIZE 2048
-static char space[MAXSIZE];
+static char space[AFS_PIOCTL_MAXSIZE];
 
 struct OldAcl {
     int nplus;
@@ -83,6 +47,12 @@ struct OldAcl {
     char data[1];
 };
 
+static void ScanArgs(int argc, char *argv[]);
+static short MakeParent(char *file, afs_int32 owner);
+static int Copy(char *file1, char *file2, short recursive, int level);
+static int isMountPoint(char *name, struct ViceIoctl *blob);
+
+
 /* ************************************************************ */
 /*                                                              */
 /* main program                                                         */
@@ -96,8 +66,8 @@ main(int argc, char *argv[])
 {
 #ifdef AFS_AIX32_ENV
     /*
-     * The following signal action for AIX is necessary so that in case of a 
-     * crash (i.e. core is generated) we can include the user's data section 
+     * The following signal action for AIX is necessary so that in case of a
+     * crash (i.e. core is generated) we can include the user's data section
      * in the core dump. Unfortunately, by default, only a partial core is
      * generated which, in many cases, isn't too useful.
      */
@@ -108,21 +78,18 @@ main(int argc, char *argv[])
     nsa.sa_flags = SA_FULLDUMP;
     sigaction(SIGSEGV, &nsa, NULL);
 #endif
-#if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
-    pageSize = getpagesize();
-#endif
     ScanArgs(argc, argv);
 
     /* now read each line of the CopyList */
     if (Copy(file1, file2, !oneLevel, 0))
-       exit(1);                /* some type of failure */
+       return(1);              /* some type of failure */
 
-    exit(0);
+    return(0);
 }
 
 
 #define USAGE "usage: up [-v1frxm] from to\n"
-void
+static void
 ScanArgs(int argc, char *argv[])
 {
     /* skip program name */
@@ -132,6 +99,10 @@ ScanArgs(int argc, char *argv[])
     while (argc > 0 && *argv[0] == '-') {
        char *cp = *argv;
 
+       if (strlen(cp) > 2) {
+           goto badoption;
+       }
+
        switch (*++cp) {
        case 'v':
            verbose = 1;
@@ -158,7 +129,10 @@ ScanArgs(int argc, char *argv[])
            break;
 
        default:
-           fprintf(stderr, "Unknown option: '%c'\n", *cp);
+           cp--;
+
+ badoption:
+           fprintf(stderr, "Unknown option: '%s'\n", cp);
            fprintf(stderr, USAGE);
            exit(1);
        }
@@ -183,18 +157,18 @@ ScanArgs(int argc, char *argv[])
  *     1 if it exists, 0 otherwise.  Note: the owner argument
  *     is a hack.  All directories made will have this owner.
  */
-short
+static short
 MakeParent(char *file, afs_int32 owner)
 {
     char parent[MAXPATHLEN];
     char *p;
     struct stat s;
 
-    strcpy(parent, file);
+    strlcpy(parent, file, sizeof parent);
 
     p = strrchr(parent, '/');
     if (!p) {
-       strcpy(parent, ".");
+       strlcpy(parent, ".", sizeof parent);
     } else if (p > parent) {
        *p = '\0';
     } else {
@@ -222,7 +196,7 @@ MakeParent(char *file, afs_int32 owner)
  *     This does the bulk of the work of the program.  Handle one file,
  *     possibly copying subfiles if this is a directory
  */
-int
+static int
 Copy(char *file1, char *file2, short recursive, int level)
 {
     struct stat s1, s2;                /*Stat blocks */
@@ -277,32 +251,26 @@ Copy(char *file1, char *file2, short recursive, int level)
 
            if (verbose) {
                printf("  Copy file %s to %s (%u Bytes)\n", file1, file2,
-                      s1.st_size);
+                      (unsigned int) s1.st_size);
                fflush(stdout);
            }
 
-           strcpy(tmpfile, file2);     /* Name of temporary file */
-           strcat(tmpfile, ".UPD");
+           strlcpy(tmpfile, file2, sizeof tmpfile);    /* Name of temporary file */
+           strlcat(tmpfile, ".UPD", sizeof tmpfile);
 
            /* open file1 for input */
            f1 = open(file1, O_RDONLY);
            if (f1 < 0) {
-               fprintf(stderr, "Unable to open input file %s, ", file1);
-               if (errno >= sys_nerr)
-                   fprintf(stderr, "error code = %d\n", errno);
-               else
-                   fprintf(stderr, "%s\n", sys_errlist[errno]);
+               fprintf(stderr, "Unable to open input file %s: %s\n",
+                       file1, strerror(errno));
                return 1;
            }
 
            /* open temporary output file */
            f2 = open(tmpfile, (O_WRONLY | O_CREAT | O_TRUNC), s1.st_mode);
            if (f2 < 0) {
-               fprintf(stderr, "Unable to open output file %s, ", tmpfile);
-               if (errno >= sys_nerr)
-                   fprintf(stderr, "error code = %d\n", errno);
-               else
-                   fprintf(stderr, "%s\n", sys_errlist[errno]);
+               fprintf(stderr, "Unable to open output file %s: %s\n",
+                       tmpfile, strerror(errno));
                fflush(stdout);
                close(f1);
                return 1;
@@ -328,6 +296,10 @@ Copy(char *file1, char *file2, short recursive, int level)
 
            /* Close the files */
            code = close(f1);
+           if (code < 0) {
+               perror("close ");
+               rcode = 1;
+           }
            code = close(f2);
            if (code < 0) {
                perror("close ");
@@ -336,8 +308,8 @@ Copy(char *file1, char *file2, short recursive, int level)
 
            /* Rename file2 to file2.old. [-r] */
            if (renameTargets && goods2) {
-               strcpy(newName, file2);
-               strcat(newName, ".old");
+               strlcpy(newName, file2, sizeof newName);
+               strlcat(newName, ".old", sizeof newName);
                if (verbose) {
                    printf("  Renaming %s to %s\n", file2, newName);
                    fflush(stdout);
@@ -366,7 +338,8 @@ Copy(char *file1, char *file2, short recursive, int level)
            if (s1.st_size != s2.st_size) {
                fprintf(stderr,
                        "WARNING: New file %s is %u bytes long; should be %u\n",
-                       file2, s2.st_size, s1.st_size);
+                       file2, (unsigned int) s2.st_size,
+                       (unsigned int) s1.st_size);
            }
        }
 
@@ -445,7 +418,7 @@ Copy(char *file1, char *file2, short recursive, int level)
            fflush(stdout);
        }
 
-       n = readlink(file1, linkvalue, sizeof(linkvalue));
+       n = readlink(file1, linkvalue, sizeof(linkvalue)-1);
        if (n == -1) {
            fprintf(stderr, "Could not read symbolic link %s\n", file1);
            perror("read link ");
@@ -516,6 +489,7 @@ Copy(char *file1, char *file2, short recursive, int level)
        char f1[MAXPATHLEN], f2[MAXPATHLEN];
        char *p1, *p2;
        struct dirent *d;
+       struct timeval tv[2];
 
        if (verbose) {
            printf("Level %d: Directory %s to %s\n", level, file1, file2);
@@ -530,8 +504,8 @@ Copy(char *file1, char *file2, short recursive, int level)
            return 1;
        }
 
-       strcpy(f1, file1);
-       strcpy(f2, file2);
+       strlcpy(f1, file1, sizeof f1);
+       strlcpy(f2, file2, sizeof f2);
        p1 = f1 + strlen(f1);
        p2 = f2 + strlen(f2);
        if (p1 == f1 || p1[-1] != '/')
@@ -548,8 +522,8 @@ Copy(char *file1, char *file2, short recursive, int level)
        while ((d = readdir(dir)) != NULL) {
            if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0)
                continue;
-           strcpy(p1, d->d_name);
-           strcpy(p2, d->d_name);
+           strlcpy(p1, d->d_name, sizeof f1 - (p1 - f1));
+           strlcpy(p2, d->d_name, sizeof f2 - (p2 - f2));
            code = Copy(f1, f2, recursive, level + 1);
            if (code && !rcode)
                rcode = 1;      /* remember errors */
@@ -623,7 +597,7 @@ Copy(char *file1, char *file2, short recursive, int level)
                for (i = 1; i < strlen(file1); i++)
                    if (file1[i] == '/')
                        break;
-               strcpy(aclspace, &file1[i]);
+               strlcpy(aclspace, &file1[i], sizeof aclspace);
 
                blob.in_size = 1 + strlen(aclspace);
                tfd = open(file1, O_RDONLY, 0);
@@ -647,8 +621,8 @@ Copy(char *file1, char *file2, short recursive, int level)
                /* Now convert the thing. */
                oacl = (struct OldAcl *)(aclspace + 4);
                sprintf(tacl, "%d\n%d\n", oacl->nplus, oacl->nminus);
-               strcat(tacl, oacl->data);
-               strcpy(aclspace, tacl);
+               strlcat(tacl, oacl->data, sizeof tacl);
+               strlcpy(aclspace, tacl, sizeof aclspace);
            } /*Grab and convert old-style ACL */
            else {
                /* Get a new-style ACL */
@@ -703,13 +677,22 @@ Copy(char *file1, char *file2, short recursive, int level)
                printf("Not setting acls\n");
            }
        }
+
+        /* preserve access and modification times: ("-x" disables) */
+        if (preserveDate) {
+            tv[0].tv_sec = s1.st_atime;
+            tv[0].tv_usec = 0;
+            tv[1].tv_sec = s1.st_mtime;
+            tv[1].tv_usec = 0;
+            utimes(file2, tv);
+        }
     }
 
     return rcode;
 }                              /*Copy */
 
 
-int
+static int
 isMountPoint(char *name, struct ViceIoctl *blob)
 {
     afs_int32 code;
@@ -736,7 +719,7 @@ isMountPoint(char *name, struct ViceIoctl *blob)
         * No slash appears in the given file name.  Set parent_dir to the current
         * directory, and the last component as the given name.
         */
-       strcpy(parent_dir, ".");
+       strlcpy(parent_dir, ".", sizeof parent_dir);
        last_component = true_name;
     }
 
@@ -749,9 +732,9 @@ isMountPoint(char *name, struct ViceIoctl *blob)
 
     blob->in = last_component;
     blob->in_size = strlen(last_component) + 1;
-    blob->out_size = MAXSIZE;
+    blob->out_size = AFS_PIOCTL_MAXSIZE;
     blob->out = space;
-    memset(space, 0, MAXSIZE);
+    memset(space, 0, AFS_PIOCTL_MAXSIZE);
 
     code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, blob, 0);
 
@@ -773,5 +756,4 @@ isMountPoint(char *name, struct ViceIoctl *blob)
             */
        }
     }
-    return 4;
 }