do the chown first; under VFS chown loses setid bits
[unix-history] / usr / src / usr.bin / xinstall / xinstall.c
index 26772c5..127005c 100644 (file)
@@ -22,7 +22,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)xinstall.c 5.12 (Berkeley) %G%";
+static char sccsid[] = "@(#)xinstall.c 5.15 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -33,21 +33,17 @@ static char sccsid[] = "@(#)xinstall.c      5.12 (Berkeley) %G%";
 #include <pwd.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <ctype.h>
-
-#define        YES     1                       /* yes/true */
-#define        NO      0                       /* no/false */
+#include <paths.h>
 
 #define        PERROR(head, msg) { \
        fputs(head, stderr); \
        perror(msg); \
 }
 
 
 #define        PERROR(head, msg) { \
        fputs(head, stderr); \
        perror(msg); \
 }
 
-static struct passwd   *pp;
-static struct group    *gp;
-static int     docopy, dostrip,
-               mode = 0755;
-static char    *group, *owner,
-               pathbuf[MAXPATHLEN];
+static struct passwd *pp;
+static struct group *gp;
+static int docopy, dostrip, mode = 0755;
+static char *group, *owner, pathbuf[MAXPATHLEN];
 
 main(argc, argv)
        int argc;
 
 main(argc, argv)
        int argc;
@@ -62,7 +58,7 @@ main(argc, argv)
        while ((ch = getopt(argc, argv, "cg:m:o:s")) != EOF)
                switch((char)ch) {
                case 'c':
        while ((ch = getopt(argc, argv, "cg:m:o:s")) != EOF)
                switch((char)ch) {
                case 'c':
-                       docopy = YES;
+                       docopy = 1;
                        break;
                case 'g':
                        group = optarg;
                        break;
                case 'g':
                        group = optarg;
@@ -74,7 +70,7 @@ main(argc, argv)
                        owner = optarg;
                        break;
                case 's':
                        owner = optarg;
                        break;
                case 's':
-                       dostrip = YES;
+                       dostrip = 1;
                        break;
                case '?':
                default:
                        break;
                case '?':
                default:
@@ -98,7 +94,7 @@ main(argc, argv)
        no_target = stat(to_name = argv[argc - 1], &to_sb);
        if (!no_target && (to_sb.st_mode & S_IFMT) == S_IFDIR) {
                for (; *argv != to_name; ++argv)
        no_target = stat(to_name = argv[argc - 1], &to_sb);
        if (!no_target && (to_sb.st_mode & S_IFMT) == S_IFDIR) {
                for (; *argv != to_name; ++argv)
-                       install(*argv, to_name, YES);
+                       install(*argv, to_name, 1);
                exit(0);
        }
 
                exit(0);
        }
 
@@ -122,7 +118,7 @@ main(argc, argv)
                /* unlink now... avoid ETXTBSY errors later */
                (void)unlink(to_name);
        }
                /* unlink now... avoid ETXTBSY errors later */
                (void)unlink(to_name);
        }
-       install(*argv, to_name, NO);
+       install(*argv, to_name, 0);
        exit(0);
 }
 
        exit(0);
 }
 
@@ -130,7 +126,6 @@ main(argc, argv)
  * install --
  *     build a path name and install the file
  */
  * install --
  *     build a path name and install the file
  */
-static
 install(from_name, to_name, isdir)
        char *from_name, *to_name;
        int isdir;
 install(from_name, to_name, isdir)
        char *from_name, *to_name;
        int isdir;
@@ -139,8 +134,8 @@ install(from_name, to_name, isdir)
        int devnull, from_fd, to_fd;
        char *C, *rindex();
 
        int devnull, from_fd, to_fd;
        char *C, *rindex();
 
-       /* if try to install "/dev/null" to a directory, fails */
-       if (isdir || strcmp(from_name, "/dev/null")) {
+       /* if try to install NULL file to a directory, fails */
+       if (isdir || strcmp(from_name, _PATH_DEVNULL)) {
                if (stat(from_name, &from_sb)) {
                        fprintf(stderr, "install: can't find %s.\n", from_name);
                        exit(1);
                if (stat(from_name, &from_sb)) {
                        fprintf(stderr, "install: can't find %s.\n", from_name);
                        exit(1);
@@ -154,10 +149,10 @@ install(from_name, to_name, isdir)
                        (void)sprintf(pathbuf, "%s/%s", to_name, (C = rindex(from_name, '/')) ? ++C : from_name);
                        to_name = pathbuf;
                }
                        (void)sprintf(pathbuf, "%s/%s", to_name, (C = rindex(from_name, '/')) ? ++C : from_name);
                        to_name = pathbuf;
                }
-               devnull = NO;
+               devnull = 0;
        }
        else
        }
        else
-               devnull = YES;
+               devnull = 1;
 
        /* unlink now... avoid ETXTBSY errors later */
        (void)unlink(to_name);
 
        /* unlink now... avoid ETXTBSY errors later */
        (void)unlink(to_name);
@@ -181,16 +176,16 @@ install(from_name, to_name, isdir)
                if (!docopy)
                        (void)unlink(from_name);
        }
                if (!docopy)
                        (void)unlink(from_name);
        }
-       /* set owner, group, mode for target */
-       if (fchmod(to_fd, mode)) {
-               PERROR("install: fchmod: ", to_name);
-               bad();
-       }
        if ((group || owner) && fchown(to_fd, owner ? pp->pw_uid : -1,
            group ? gp->gr_gid : -1)) {
                PERROR("install: fchown: ", to_name);
                bad();
        }
        if ((group || owner) && fchown(to_fd, owner ? pp->pw_uid : -1,
            group ? gp->gr_gid : -1)) {
                PERROR("install: fchown: ", to_name);
                bad();
        }
+       /* set owner, group, mode for target */
+       if (fchmod(to_fd, mode)) {
+               PERROR("install: fchmod: ", to_name);
+               bad();
+       }
        (void)close(to_fd);
 }
 
        (void)close(to_fd);
 }
 
@@ -198,7 +193,6 @@ install(from_name, to_name, isdir)
  * strip --
  *     copy file, strip(1)'ing it at the same time
  */
  * strip --
  *     copy file, strip(1)'ing it at the same time
  */
-static
 strip(from_fd, from_name, to_fd, to_name)
        register int from_fd, to_fd;
        char *from_name, *to_name;
 strip(from_fd, from_name, to_fd, to_name)
        register int from_fd, to_fd;
        char *from_name, *to_name;
@@ -250,7 +244,6 @@ strip(from_fd, from_name, to_fd, to_name)
  * copy --
  *     copy from one file to another
  */
  * copy --
  *     copy from one file to another
  */
-static
 copy(from_fd, from_name, to_fd, to_name)
        register int from_fd, to_fd;
        char *from_name, *to_name;
 copy(from_fd, from_name, to_fd, to_name)
        register int from_fd, to_fd;
        char *from_name, *to_name;
@@ -273,7 +266,6 @@ copy(from_fd, from_name, to_fd, to_name)
  * atoo --
  *     octal string to int
  */
  * atoo --
  *     octal string to int
  */
-static
 atoo(str)
        register char *str;
 {
 atoo(str)
        register char *str;
 {
@@ -288,7 +280,6 @@ atoo(str)
  * bad --
  *     remove created target and die
  */
  * bad --
  *     remove created target and die
  */
-static
 bad()
 {
        (void)unlink(pathbuf);
 bad()
 {
        (void)unlink(pathbuf);
@@ -299,7 +290,6 @@ bad()
  * usage --
  *     print a usage message and die
  */
  * usage --
  *     print a usage message and die
  */
-static
 usage()
 {
        fputs("usage: install [-cs] [-g group] [-m mode] [-o owner] file1 file2;\n\tor file1 ... fileN directory\n", stderr);
 usage()
 {
        fputs("usage: install [-cs] [-g group] [-m mode] [-o owner] file1 file2;\n\tor file1 ... fileN directory\n", stderr);