venus: Tidy up header includes
[openafs.git] / src / venus / up.c
index 957ec0e..522dc08 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 */
-#define Boolean short
-#define true 1
-#define false 0
-
-#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
-
-Boolean verbose = false;
-Boolean renameTargets = false;
-Boolean oneLevel = false;
-Boolean preserveDate = true;
-Boolean preserveMountPoints = false;
-Boolean forceOverwrite = false;
+short verbose = 0;
+short renameTargets = 0;
+short oneLevel = 0;
+short preserveDate = 1;
+short preserveMountPoints = 0;
+short forceOverwrite = 0;
 
-int pageSize;
-Boolean setacl = true;
-Boolean oldAcl = false;
+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;
@@ -86,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                                                         */
@@ -94,15 +61,13 @@ struct OldAcl {
 
 #include "AFS_component_version_number.c"
 
-main(argc, argv)
-     int argc;
-     char *argv[];
-
+int
+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.
      */
@@ -113,23 +78,19 @@ main(argc, 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);
 }
 
 
-ScanArgs(argc, argv)
-     int argc;
-     char *argv[];
-
+#define USAGE "usage: up [-v1frxm] from to\n"
+static void
+ScanArgs(int argc, char *argv[])
 {
     /* skip program name */
     argc--, argv++;
@@ -138,41 +99,48 @@ ScanArgs(argc, argv)
     while (argc > 0 && *argv[0] == '-') {
        char *cp = *argv;
 
+       if (strlen(cp) > 2) {
+           goto badoption;
+       }
+
        switch (*++cp) {
        case 'v':
-           verbose = true;
+           verbose = 1;
            break;
 
        case '1':
-           oneLevel = true;
+           oneLevel = 1;
            break;
 
        case 'r':
-           renameTargets = true;
+           renameTargets = 1;
            break;
 
        case 'f':
-           forceOverwrite = true;
+           forceOverwrite = 1;
            break;
 
        case 'x':
-           preserveDate = false;
+           preserveDate = 0;
            break;
 
        case 'm':
-           preserveMountPoints = true;
+           preserveMountPoints = 1;
            break;
 
        default:
-           fprintf(stderr, "Unknown option: '%c'\n", *cp);
-           fprintf(stderr, "usage: up [-v1frxm] from to\n");
+           cp--;
+
+ badoption:
+           fprintf(stderr, "Unknown option: '%s'\n", cp);
+           fprintf(stderr, USAGE);
            exit(1);
        }
        argc--, argv++;
     }
 
     if (argc != 2) {
-       fprintf(stderr, "usage: up [-v1frx] from to\n");
+       fprintf(stderr, USAGE);
        exit(1);
     }
 
@@ -186,23 +154,21 @@ ScanArgs(argc, argv)
 /*
  * MakeParent
  *     Make sure the parent directory of this file exists.  Returns
- *     true if it exists, false otherwise.  Note: the owner argument
+ *     1 if it exists, 0 otherwise.  Note: the owner argument
  *     is a hack.  All directories made will have this owner.
  */
-Boolean
-MakeParent(file, owner)
-     char *file;
-     afs_int32 owner;
+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 {
@@ -211,7 +177,7 @@ MakeParent(file, owner)
 
     if (stat(parent, &s) < 0) {
        if (!MakeParent(parent, owner))
-           return (false);
+           return (0);
 
        if (verbose) {
            printf("Creating directory %s\n", parent);
@@ -221,7 +187,7 @@ MakeParent(file, owner)
        mkdir(parent, 0777);
        chown(parent, owner, -1);
     }
-    return (true);
+    return (1);
 }                              /*MakeParent */
 
 
@@ -230,12 +196,8 @@ MakeParent(file, owner)
  *     This does the bulk of the work of the program.  Handle one file,
  *     possibly copying subfiles if this is a directory
  */
-Copy(file1, file2, recursive, level)
-     char *file1;              /* input file name */
-     char *file2;              /* output file name */
-     Boolean recursive;                /* true if directory should be copied */
-     int level;                        /* level of recursion: 0, 1, ... */
-
+static int
+Copy(char *file1, char *file2, short recursive, int level)
 {
     struct stat s1, s2;                /*Stat blocks */
     struct ViceIoctl blob;
@@ -289,32 +251,26 @@ Copy(file1, file2, recursive, 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;
@@ -348,8 +304,8 @@ Copy(file1, file2, recursive, 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);
@@ -378,7 +334,8 @@ Copy(file1, file2, recursive, 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);
            }
        }
 
@@ -528,6 +485,7 @@ Copy(file1, file2, recursive, 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);
@@ -542,8 +500,8 @@ Copy(file1, file2, recursive, 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] != '/')
@@ -560,8 +518,8 @@ Copy(file1, file2, recursive, 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 */
@@ -614,7 +572,7 @@ Copy(file1, file2, recursive, level)
            rcode = 1;
        }
 
-       if (setacl == true) {
+       if (setacl == 1) {
            if (verbose) {
                printf("  Set acls for %s\n", file2);
                fflush(stdout);
@@ -635,7 +593,7 @@ Copy(file1, file2, recursive, 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,7 +605,7 @@ Copy(file1, file2, recursive, level)
                close(tfd);
                if (code < 0) {
                    if (errno == EINVAL) {
-                       setacl = false;
+                       setacl = 0;
                         if (verbose) {
                             printf("  _VICEIOCTL(4) returns EINVAL\n");
                             fflush(stdout);
@@ -659,8 +617,8 @@ Copy(file1, file2, recursive, 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 */
@@ -672,7 +630,7 @@ Copy(file1, file2, recursive, level)
                code = pioctl(file1, _VICEIOCTL(2), &blob, 1);
                if (code < 0) {
                    if (errno == EINVAL) {
-                       setacl = false;
+                       setacl = 0;
                         if (verbose) {
                             printf("  _VICEIOCTL(2) returns EINVAL\n");
                             fflush(stdout);
@@ -687,7 +645,7 @@ Copy(file1, file2, recursive, level)
            /*
             * Now, set the new-style ACL.
             */
-           if (setacl == true) {
+           if (setacl == 1) {
                 if (verbose) {
                     printf("  Setting new style acl\n");
                     fflush(stdout);
@@ -699,7 +657,7 @@ Copy(file1, file2, recursive, level)
                code = pioctl(file2, _VICEIOCTL(1), &blob, 1);
                if (code) {
                    if (errno == EINVAL) {
-                       setacl = false;
+                       setacl = 0;
                         if (verbose) {
                             printf("  _VICEIOCTL(1) returns EINVAL\n");
                             fflush(stdout);
@@ -711,20 +669,27 @@ Copy(file1, file2, recursive, level)
                }
            }
 
-           if (setacl == false) {
+           if (setacl == 0) {
                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
-isMountPoint(name, blob)
-     char *name;
-     struct ViceIoctl *blob;
+static int
+isMountPoint(char *name, struct ViceIoctl *blob)
 {
     afs_int32 code;
     char true_name[1024];      /*dirname */
@@ -750,7 +715,7 @@ isMountPoint(name, 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;
     }
 
@@ -763,9 +728,9 @@ isMountPoint(name, 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);
 
@@ -787,5 +752,4 @@ isMountPoint(name, blob)
             */
        }
     }
-    return 4;
 }