[hackers] [sbase] install: bsd make compatibility || Eivind Uggedal

From: <git_AT_suckless.org>
Date: Mon, 15 Feb 2016 10:42:02 +0100 (CET)

commit 2f128ab050b39ced864fa24c6afc0eb6e6225f55
Author: Eivind Uggedal <eivind_AT_uggedal.com>
AuthorDate: Mon Feb 15 09:44:35 2016 +0100
Commit: sin <sin_AT_2f30.org>
CommitDate: Mon Feb 15 09:41:58 2016 +0000

    install: bsd make compatibility

diff --git a/Makefile b/Makefile
index b17d19f..9f473dd 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -103,7 +103,6 @@ BIN =\
         getconf\
         grep\
         head\
- install.out\
         join\
         hostname\
         kill\
_AT_@ -162,13 +161,14 @@ BIN =\
         which\
         whoami\
         xargs\
+ xinstall\
         yes
 
 LIBUTFOBJ = $(LIBUTFSRC:.c=.o)
 LIBUTILOBJ = $(LIBUTILSRC:.c=.o)
 OBJ = $(BIN:=.o) $(LIBUTFOBJ) $(LIBUTILOBJ)
-SRC = $(foreach F,$(BIN:.out=),$(F:=.c))
-MAN = $(foreach F,$(BIN:.out=),$(F:=.1))
+SRC = $(BIN:=.c)
+MAN = $(BIN:=.1)
 
 all: $(BIN)
 
_AT_@ -179,9 +179,6 @@ $(OBJ): $(HDR) config.mk
 .o:
         $(CC) $(LDFLAGS) -o $_AT_ $< $(LIB)
 
-install.out: install.o
- $(CC) $(LDFLAGS) -o $_AT_ $^ $(LIB)
-
 .c.o:
         $(CC) $(CFLAGS) $(CPPFLAGS) -o $_AT_ -c $<
 
_AT_@ -201,14 +198,15 @@ confstr_l.h limits_l.h sysconf_l.h pathconf_l.h: getconf.sh
 install: all
         mkdir -p $(DESTDIR)$(PREFIX)/bin
         cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin
- mv -f $(DESTDIR)$(PREFIX)/bin/install.out $(DESTDIR)$(PREFIX)/bin/install
- cd $(DESTDIR)$(PREFIX)/bin && ln -f test [ && chmod 755 $(BIN:.out=)
+ cd $(DESTDIR)$(PREFIX)/bin && ln -f test [ && chmod 755 $(BIN)
+ mv -f $(DESTDIR)$(PREFIX)/bin/xinstall $(DESTDIR)$(PREFIX)/bin/install
         mkdir -p $(DESTDIR)$(MANPREFIX)/man1
         for m in $(MAN); do sed "s/^\.Os sbase/.Os sbase $(VERSION)/g" < "$$m" > $(DESTDIR)$(MANPREFIX)/man1/"$$m"; done
         cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN)
+ mv -f $(DESTDIR)$(MANPREFIX)/man1/xinstall.1 $(DESTDIR)$(MANPREFIX)/man1/install.1
 
 uninstall:
- cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN:.out=) [
+ cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) [ xinstall
         cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN)
 
 dist: clean
_AT_@ -231,6 +229,7 @@ sbase-box: $(LIB) $(SRC)
         for f in $(SRC); do echo "int $${f%.c}_main(int, char **);"; done >> build/$_AT_.c
         echo 'int main(int argc, char *argv[]) { char *s = basename(argv[0]);' >> build/$_AT_.c
         echo 'if(!strcmp(s,"sbase-box")) { argc--; argv++; s = basename(argv[0]); } if(0) ;' >> build/$_AT_.c
+ echo "else if (!strcmp(s, \"install\")) return xinstall_main(argc, argv);" >> build/$_AT_.c
         echo "else if (!strcmp(s, \"[\")) return test_main(argc, argv);" >> build/$_AT_.c
         for f in $(SRC); do echo "else if(!strcmp(s, \"$${f%.c}\")) return $${f%.c}_main(argc, argv);"; done >> build/$_AT_.c
         echo 'else { fputs("[ ", stdout);' >> build/$_AT_.c
_AT_@ -243,11 +242,13 @@ sbase-box-install: sbase-box
         mkdir -p $(DESTDIR)$(PREFIX)/bin
         cp -f sbase-box $(DESTDIR)$(PREFIX)/bin
         chmod 755 $(DESTDIR)$(PREFIX)/bin/sbase-box
- for f in $(BIN:.out=); do ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/"$$f"; done
+ for f in $(BIN); do ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/"$$f"; done
         ln -sf sbase-box $(DESTDIR)$(PREFIX)/bin/[
+ mv -f $(DESTDIR)$(PREFIX)/bin/xinstall $(DESTDIR)$(PREFIX)/bin/install
         mkdir -p $(DESTDIR)$(MANPREFIX)/man1
         for m in $(MAN); do sed "s/^\.Os sbase/.Os sbase $(VERSION)/g" < "$$m" > $(DESTDIR)$(MANPREFIX)/man1/"$$m"; done
         cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN)
+ mv -f $(DESTDIR)$(MANPREFIX)/man1/xinstall.1 $(DESTDIR)$(MANPREFIX)/man1/install.1
 
 clean:
         rm -f $(BIN) $(OBJ) $(LIB) sbase-box sbase-$(VERSION).tar.gz
diff --git a/install.1 b/install.1
deleted file mode 100644
index 99eff81..0000000
--- a/install.1
+++ /dev/null
_AT_@ -1,88 +0,0 @@
-.Dd 2016-02-12
-.Dt INSTALL 1
-.Os sbase
-.Sh NAME
-.Nm install
-.Nd copy files and set attributes
-.Sh SYNOPSIS
-.Nm
-.Op Fl g Ar group
-.Op Fl o Ar owner
-.Op Fl m Ar mode
-.Po
-.Fl d Ar dir ...
-|
-.Op Fl sD
-.Po
-.Fl t Ar dest
-.Ar source ...
-|
-.Ar source ...
-.Ar dest
-.Pc
-.Pc
-.Sh DESCRIPTION
-.Nm
-copies
-.Ar source
-to
-.Ar dest .
-If more than one
-.Ar source
-is given
-.Ar dest
-has to be a directory.
-.Nm
-can also change the attributes of the copies.
-.Sh OPTIONS
-.Bl -tag -width Ds
-.It Fl d
-Create the directories
-.Ar dir .
-.It Fl D
-Create missing parent directories to
-.Ar dest .
-If
-.Fl t
-is used, the
-.Ar dest
-itself is also created if missing.
-.It Fl g Ar group
-Change the installed files' group to
-.Ar group .
-This may be a group name or a group identifier.
-.It Fl m Ar mode
-Change the file modes. Both numerical and symbolic
-values are supported. See
-.Xr chmod 1
-for the syntex.
-Default mode 0755. If a file has the mode 0644 and
-is copied with
-.It Fl o Ar owner
-Change the installed files' owner to
-.Ar owner .
-This may be a user name or a user identifier.
-.It Fl s
-Remove unnecessary symbols using
-.Xr strip 1 .
-Failure to strip a file does not imply failure to install the file.
-.It Fl t Ar dest
-Copy files into the directory
-.Ar dest .
-.Nm install ,
-the copy's mode will be 0755 unless
-.Fl m
-is used to select another mode. When the symbolic
-notation is used, the base mode is 0000.
-.Sh SEE ALSO
-.Xr chmod 1 ,
-.Xr chown 1 ,
-.Xr cp 1 ,
-.Xr mkdir 1 ,
-.Xr strip 1
-.Sh STANDARDS
-The
-.Nm
-utility is not standardized. This implementation is a subset
-of the GNU implementation and a subset with extensions to
-the FreeBSD implementation.
diff --git a/install.c b/install.c
deleted file mode 100644
index ec96c05..0000000
--- a/install.c
+++ /dev/null
_AT_@ -1,257 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <grp.h>
-#include <pwd.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include "util.h"
-#include "text.h"
-
-static int Dflag = 0;
-static int sflag = 0;
-static gid_t group;
-static uid_t owner;
-static mode_t mode = 0755;
-
-static void
-make_dir(char *dir, int was_missing)
-{
- if (!mkdir(dir, was_missing ? 0755 : mode)) {
- if (!was_missing && (lchown(dir, owner, group) < 0))
- eprintf("lchmod %s:", dir);
- } else if (errno != EEXIST) {
- eprintf("mkdir %s:", dir);
- }
-}
-
-static void
-make_dirs(char *dir, int was_missing)
-{
- char *p;
- for (p = strchr(dir + (dir[0] == '/'), '/'); p; p = strchr(p + 1, '/')) {
- *p = '\0';
- make_dir(dir, was_missing);
- *p = '/';
- }
- make_dir(dir, was_missing);
-}
-
-static void
-strip(const char *filename)
-{
- pid_t pid = fork();
- switch (pid) {
- case -1:
- eprintf("fork:");
- case 0:
- execlp("strip", "strip", "--", filename, (char *)0);
- eprintf("exec: strip:");
- default:
- waitpid(pid, NULL, 0);
- break;
- }
-}
-
-static int
-install(const char *s1, const char *s2, int depth)
-{
- DIR *dp;
- FILE *f1, *f2;
- struct dirent *d;
- struct stat st;
- ssize_t r;
- char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX];
-
- if (stat(s1, &st) < 0)
- eprintf("stat %s:", s1);
-
- if (S_ISLNK(st.st_mode)) {
- if ((r = readlink(s1, target, sizeof(target) - 1)) >= 0) {
- target[r] = '\0';
- if (unlink(s2) < 0 && errno != ENOENT)
- eprintf("unlink %s:", s2);
- else if (symlink(target, s2) < 0)
- eprintf("symlink %s -> %s:", s2, target);
- }
- } else if (S_ISDIR(st.st_mode)) {
- if (!(dp = opendir(s1)))
- eprintf("opendir %s:", s1);
- if (mkdir(s2, mode | 0111) < 0 && errno != EEXIST)
- eprintf("mkdir %s:", s2);
-
- while ((d = readdir(dp))) {
- if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
- continue;
-
- estrlcpy(ns1, s1, sizeof(ns1));
- if (s1[strlen(s1) - 1] != '/')
- estrlcat(ns1, "/", sizeof(ns1));
- estrlcat(ns1, d->d_name, sizeof(ns1));
-
- estrlcpy(ns2, s2, sizeof(ns2));
- if (s2[strlen(s2) - 1] != '/')
- estrlcat(ns2, "/", sizeof(ns2));
- estrlcat(ns2, d->d_name, sizeof(ns2));
-
- fnck(ns1, ns2, install, depth + 1);
- }
-
- closedir(dp);
- } else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) ||
- S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode)) {
- if (unlink(s2) < 0 && errno != ENOENT)
- eprintf("unlink %s:", s2);
- else if (mknod(s2, (st.st_mode & ~07777) | mode, st.st_rdev) < 0)
- eprintf("mknod %s:", s2);
- } else {
- if (!(f1 = fopen(s1, "r")))
- eprintf("fopen %s:", s1);
- if (!(f2 = fopen(s2, "w"))) {
- if (unlink(s2) < 0 && errno != ENOENT)
- eprintf("unlink %s:", s2);
- else if (!(f2 = fopen(s2, "w")))
- eprintf("fopen %s:", s2);
- }
- concat(f1, s1, f2, s2);
-
- fchmod(fileno(f2), mode);
-
- if (fclose(f2) == EOF)
- eprintf("fclose %s:", s2);
- if (fclose(f1) == EOF)
- eprintf("fclose %s:", s1);
-
- if (sflag)
- strip(s2);
- }
-
- if (lchown(s2, owner, group) < 0)
- eprintf("lchown %s:", s2);
-
- return 0;
-}
-
-static void
-usage(void)
-{
- eprintf("usage: %s [-g group] [-o owner] [-m mode] (-d dir ... | [-Ds] (-t dest source ... | source ... dest))\n", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- int dflag = 0;
- char *gflag = 0;
- char *oflag = 0;
- char *mflag = 0;
- char *tflag = 0;
- struct group *gr;
- struct passwd *pw;
- struct stat st;
- char *p;
-
- ARGBEGIN {
- case 'd':
- dflag = 1;
- break;
- case 'D':
- Dflag = 1;
- break;
- case 's':
- sflag = 1;
- break;
- case 'g':
- gflag = EARGF(usage());
- break;
- case 'o':
- oflag = EARGF(usage());
- break;
- case 'm':
- mflag = EARGF(usage());
- break;
- case 't':
- tflag = EARGF(usage());
- break;
- default:
- usage();
- } ARGEND
-
- if (argc < 1 + (!tflag & !dflag) || dflag & (Dflag | sflag | !!tflag))
- usage();
-
- if (gflag) {
- errno = 0;
- gr = getgrnam(gflag);
- if (gr) {
- group = gr->gr_gid;
- } else {
- if (errno)
- eprintf("getgrnam %s:", gflag);
- group = estrtonum(gflag, 0, UINT_MAX);
- }
- } else {
- group = getgid();
- }
-
- if (oflag) {
- errno = 0;
- pw = getpwnam(oflag);
- if (pw) {
- owner = pw->pw_uid;
- } else {
- if (errno)
- eprintf("getpwnam %s:", oflag);
- owner = estrtonum(oflag, 0, UINT_MAX);
- }
- } else {
- owner = getuid();
- }
-
- if (mflag) {
- mode = parsemode(mflag, mode, 0);
- if (mode < 0)
- return 1;
- }
-
- if (tflag) {
- memmove(argv - 1, argv, argc);
- argv[argc++] = tflag;
- }
- if (tflag || argc > 2) {
- if (stat(argv[argc - 1], &st) < 0) {
- if ((errno == ENOENT) && Dflag) {
- make_dirs(argv[argc - 1], 1);
- } else {
- eprintf("stat %s:", argv[argc - 1]);
- }
- } else if (!S_ISDIR(st.st_mode)) {
- eprintf("%s: not a directory\n", argv[argc - 1]);
- }
- }
-
- if (dflag) {
- for (; *argv; argc--, argv++)
- make_dirs(*argv, 0);
- } else {
- if (stat(argv[argc - 1], &st) < 0) {
- if (errno != ENOENT)
- eprintf("stat %s:", argv[argc - 1]);
- if (tflag || argc > 2) {
- p = strrchr(argv[argc - 1], '/');
- *p = '\0';
- make_dirs(argv[argc - 1], 1);
- *p = '/';
- } else {
- make_dirs(argv[argc - 1], 1);
- }
- }
- enmasse(argc, argv, install);
- }
-
- return 0;
-}
diff --git a/xinstall.1 b/xinstall.1
new file mode 100644
index 0000000..99eff81
--- /dev/null
+++ b/xinstall.1
_AT_@ -0,0 +1,88 @@
+.Dd 2016-02-12
+.Dt INSTALL 1
+.Os sbase
+.Sh NAME
+.Nm install
+.Nd copy files and set attributes
+.Sh SYNOPSIS
+.Nm
+.Op Fl g Ar group
+.Op Fl o Ar owner
+.Op Fl m Ar mode
+.Po
+.Fl d Ar dir ...
+|
+.Op Fl sD
+.Po
+.Fl t Ar dest
+.Ar source ...
+|
+.Ar source ...
+.Ar dest
+.Pc
+.Pc
+.Sh DESCRIPTION
+.Nm
+copies
+.Ar source
+to
+.Ar dest .
+If more than one
+.Ar source
+is given
+.Ar dest
+has to be a directory.
+.Nm
+can also change the attributes of the copies.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl d
+Create the directories
+.Ar dir .
+.It Fl D
+Create missing parent directories to
+.Ar dest .
+If
+.Fl t
+is used, the
+.Ar dest
+itself is also created if missing.
+.It Fl g Ar group
+Change the installed files' group to
+.Ar group .
+This may be a group name or a group identifier.
+.It Fl m Ar mode
+Change the file modes. Both numerical and symbolic
+values are supported. See
+.Xr chmod 1
+for the syntex.
+Default mode 0755. If a file has the mode 0644 and
+is copied with
+.It Fl o Ar owner
+Change the installed files' owner to
+.Ar owner .
+This may be a user name or a user identifier.
+.It Fl s
+Remove unnecessary symbols using
+.Xr strip 1 .
+Failure to strip a file does not imply failure to install the file.
+.It Fl t Ar dest
+Copy files into the directory
+.Ar dest .
+.Nm install ,
+the copy's mode will be 0755 unless
+.Fl m
+is used to select another mode. When the symbolic
+notation is used, the base mode is 0000.
+.Sh SEE ALSO
+.Xr chmod 1 ,
+.Xr chown 1 ,
+.Xr cp 1 ,
+.Xr mkdir 1 ,
+.Xr strip 1
+.Sh STANDARDS
+The
+.Nm
+utility is not standardized. This implementation is a subset
+of the GNU implementation and a subset with extensions to
+the FreeBSD implementation.
diff --git a/xinstall.c b/xinstall.c
new file mode 100644
index 0000000..ec96c05
--- /dev/null
+++ b/xinstall.c
_AT_@ -0,0 +1,257 @@
+/* See LICENSE file for copyright and license details. */
+#include <grp.h>
+#include <pwd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include "util.h"
+#include "text.h"
+
+static int Dflag = 0;
+static int sflag = 0;
+static gid_t group;
+static uid_t owner;
+static mode_t mode = 0755;
+
+static void
+make_dir(char *dir, int was_missing)
+{
+ if (!mkdir(dir, was_missing ? 0755 : mode)) {
+ if (!was_missing && (lchown(dir, owner, group) < 0))
+ eprintf("lchmod %s:", dir);
+ } else if (errno != EEXIST) {
+ eprintf("mkdir %s:", dir);
+ }
+}
+
+static void
+make_dirs(char *dir, int was_missing)
+{
+ char *p;
+ for (p = strchr(dir + (dir[0] == '/'), '/'); p; p = strchr(p + 1, '/')) {
+ *p = '\0';
+ make_dir(dir, was_missing);
+ *p = '/';
+ }
+ make_dir(dir, was_missing);
+}
+
+static void
+strip(const char *filename)
+{
+ pid_t pid = fork();
+ switch (pid) {
+ case -1:
+ eprintf("fork:");
+ case 0:
+ execlp("strip", "strip", "--", filename, (char *)0);
+ eprintf("exec: strip:");
+ default:
+ waitpid(pid, NULL, 0);
+ break;
+ }
+}
+
+static int
+install(const char *s1, const char *s2, int depth)
+{
+ DIR *dp;
+ FILE *f1, *f2;
+ struct dirent *d;
+ struct stat st;
+ ssize_t r;
+ char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX];
+
+ if (stat(s1, &st) < 0)
+ eprintf("stat %s:", s1);
+
+ if (S_ISLNK(st.st_mode)) {
+ if ((r = readlink(s1, target, sizeof(target) - 1)) >= 0) {
+ target[r] = '\0';
+ if (unlink(s2) < 0 && errno != ENOENT)
+ eprintf("unlink %s:", s2);
+ else if (symlink(target, s2) < 0)
+ eprintf("symlink %s -> %s:", s2, target);
+ }
+ } else if (S_ISDIR(st.st_mode)) {
+ if (!(dp = opendir(s1)))
+ eprintf("opendir %s:", s1);
+ if (mkdir(s2, mode | 0111) < 0 && errno != EEXIST)
+ eprintf("mkdir %s:", s2);
+
+ while ((d = readdir(dp))) {
+ if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
+ continue;
+
+ estrlcpy(ns1, s1, sizeof(ns1));
+ if (s1[strlen(s1) - 1] != '/')
+ estrlcat(ns1, "/", sizeof(ns1));
+ estrlcat(ns1, d->d_name, sizeof(ns1));
+
+ estrlcpy(ns2, s2, sizeof(ns2));
+ if (s2[strlen(s2) - 1] != '/')
+ estrlcat(ns2, "/", sizeof(ns2));
+ estrlcat(ns2, d->d_name, sizeof(ns2));
+
+ fnck(ns1, ns2, install, depth + 1);
+ }
+
+ closedir(dp);
+ } else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) ||
+ S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode)) {
+ if (unlink(s2) < 0 && errno != ENOENT)
+ eprintf("unlink %s:", s2);
+ else if (mknod(s2, (st.st_mode & ~07777) | mode, st.st_rdev) < 0)
+ eprintf("mknod %s:", s2);
+ } else {
+ if (!(f1 = fopen(s1, "r")))
+ eprintf("fopen %s:", s1);
+ if (!(f2 = fopen(s2, "w"))) {
+ if (unlink(s2) < 0 && errno != ENOENT)
+ eprintf("unlink %s:", s2);
+ else if (!(f2 = fopen(s2, "w")))
+ eprintf("fopen %s:", s2);
+ }
+ concat(f1, s1, f2, s2);
+
+ fchmod(fileno(f2), mode);
+
+ if (fclose(f2) == EOF)
+ eprintf("fclose %s:", s2);
+ if (fclose(f1) == EOF)
+ eprintf("fclose %s:", s1);
+
+ if (sflag)
+ strip(s2);
+ }
+
+ if (lchown(s2, owner, group) < 0)
+ eprintf("lchown %s:", s2);
+
+ return 0;
+}
+
+static void
+usage(void)
+{
+ eprintf("usage: %s [-g group] [-o owner] [-m mode] (-d dir ... | [-Ds] (-t dest source ... | source ... dest))\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int dflag = 0;
+ char *gflag = 0;
+ char *oflag = 0;
+ char *mflag = 0;
+ char *tflag = 0;
+ struct group *gr;
+ struct passwd *pw;
+ struct stat st;
+ char *p;
+
+ ARGBEGIN {
+ case 'd':
+ dflag = 1;
+ break;
+ case 'D':
+ Dflag = 1;
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case 'g':
+ gflag = EARGF(usage());
+ break;
+ case 'o':
+ oflag = EARGF(usage());
+ break;
+ case 'm':
+ mflag = EARGF(usage());
+ break;
+ case 't':
+ tflag = EARGF(usage());
+ break;
+ default:
+ usage();
+ } ARGEND
+
+ if (argc < 1 + (!tflag & !dflag) || dflag & (Dflag | sflag | !!tflag))
+ usage();
+
+ if (gflag) {
+ errno = 0;
+ gr = getgrnam(gflag);
+ if (gr) {
+ group = gr->gr_gid;
+ } else {
+ if (errno)
+ eprintf("getgrnam %s:", gflag);
+ group = estrtonum(gflag, 0, UINT_MAX);
+ }
+ } else {
+ group = getgid();
+ }
+
+ if (oflag) {
+ errno = 0;
+ pw = getpwnam(oflag);
+ if (pw) {
+ owner = pw->pw_uid;
+ } else {
+ if (errno)
+ eprintf("getpwnam %s:", oflag);
+ owner = estrtonum(oflag, 0, UINT_MAX);
+ }
+ } else {
+ owner = getuid();
+ }
+
+ if (mflag) {
+ mode = parsemode(mflag, mode, 0);
+ if (mode < 0)
+ return 1;
+ }
+
+ if (tflag) {
+ memmove(argv - 1, argv, argc);
+ argv[argc++] = tflag;
+ }
+ if (tflag || argc > 2) {
+ if (stat(argv[argc - 1], &st) < 0) {
+ if ((errno == ENOENT) && Dflag) {
+ make_dirs(argv[argc - 1], 1);
+ } else {
+ eprintf("stat %s:", argv[argc - 1]);
+ }
+ } else if (!S_ISDIR(st.st_mode)) {
+ eprintf("%s: not a directory\n", argv[argc - 1]);
+ }
+ }
+
+ if (dflag) {
+ for (; *argv; argc--, argv++)
+ make_dirs(*argv, 0);
+ } else {
+ if (stat(argv[argc - 1], &st) < 0) {
+ if (errno != ENOENT)
+ eprintf("stat %s:", argv[argc - 1]);
+ if (tflag || argc > 2) {
+ p = strrchr(argv[argc - 1], '/');
+ *p = '\0';
+ make_dirs(argv[argc - 1], 1);
+ *p = '/';
+ } else {
+ make_dirs(argv[argc - 1], 1);
+ }
+ }
+ enmasse(argc, argv, install);
+ }
+
+ return 0;
+}
Received on Mon Feb 15 2016 - 10:42:02 CET

This archive was generated by hypermail 2.3.0 : Mon Feb 15 2016 - 10:48:20 CET