/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* ** Netscape portable install command. ** ** Brendan Eich, 7/20/95
*/ #include <stdio.h> /* OSF/1 requires this before grp.h, so put it first */ #include <assert.h> #include <fcntl.h> #include <errno.h> #include <dirent.h> #include <limits.h> #include <grp.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <utime.h> #include <sys/types.h> #include <sys/stat.h> #include"pathsub.h"
fromfd = open(name, O_RDONLY); if (fromfd < 0 || fstat(fromfd, &sb) < 0) fail("cannot access %s", name); if (exists) { if (S_ISREG(tosb.st_mode)) { /* See if we can open it. This is more reliable than 'access'. */
tofd = open(toname, O_CREAT | O_WRONLY, 0666);
} if (tofd < 0) {
(void)(S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
}
} if (tofd < 0) {
tofd = open(toname, O_CREAT | O_WRONLY, 0666); if (tofd < 0) fail("cannot create %s", toname);
}
bp = buf; while ((cc = read(fromfd, bp, sizeof buf)) > 0) { while ((wc = write(tofd, bp, (unsignedint)cc)) > 0) { if ((cc -= wc) == 0) break;
bp += wc;
} if (wc < 0) fail("cannot write to %s", toname);
} if (cc < 0) fail("cannot read from %s", name);
if (ftruncate(tofd, sb.st_size) < 0) fail("cannot truncate %s", toname); #if !defined(VMS) if (dotimes) {
utb.actime = sb.st_atime;
utb.modtime = sb.st_mtime; if (utime(toname, &utb) < 0) fail("cannot set times of %s", toname);
} # ifdef HAVE_FCHMOD if (fchmod(tofd, mode) < 0) # else if (chmod(toname, mode) < 0) # endif
fail("cannot change mode of %s", toname); #endif if ((owner || group) && fchown(tofd, uid, gid) < 0)
fail("cannot change owner of %s", toname);
/* Must check for delayed (NFS) write errors on close. */ if (close(tofd) < 0) fail("cannot write to %s", toname);
close(fromfd); #ifdefined(VMS) if (chmod(toname, (mode & (S_IREAD | S_IWRITE))) < 0)
fail("cannot change mode of %s", toname); if (dotimes) {
utb.actime = sb.st_atime;
utb.modtime = sb.st_mtime; if (utime(toname, &utb) < 0) fail("cannot set times of %s", toname);
} #endif
}
while (--argc > 0) {
name = *argv++;
len = strlen(name);
base = xbasename(name);
bnlen = strlen(base);
toname = xmalloc((unsignedint)(tdlen + 1 + bnlen + 1));
sprintf(toname, "%s%s%s", todir, _DIRECTORY_SEPARATOR, base);
exists = (lstat(toname, &tosb) == 0);
if (dodir) { /* -d means create a directory, always */ if (exists && !S_ISDIR(tosb.st_mode)) {
(void)unlink(toname);
exists = 0;
} if (!exists && mkdir(toname, mode) < 0)
fail("cannot make directory %s", toname); if ((owner || group) && chown(toname, uid, gid) < 0)
fail("cannot change owner of %s", toname);
} elseif (dolink) { if (access(name, R_OK) != 0) {
fail("cannot access %s", name);
} if (*name == '/') { /* source is absolute pathname, link to it directly */
linkname = 0;
} else { if (linkprefix) { /* -L prefixes names with a $cwd arg. */
len += lplen + 1;
linkname = xmalloc((unsignedint)(len + 1));
sprintf(linkname, "%s/%s", linkprefix, name);
} elseif (dorelsymlink) { /* Symlink the relative path from todir to source name. */
linkname = xmalloc(PATH_MAX);
if (*todir == '/') { /* todir is absolute: skip over common prefix. */
lplen = relatepaths(todir, cwd, linkname);
strcpy(linkname + lplen, name);
} else { /* todir is named by a relative path: reverse it. */
reversepath(todir, name, len, linkname);
xchdir(cwd);
}
len = strlen(linkname);
}
name = linkname;
}
/* Check for a pre-existing symlink with identical content. */ if (exists &&
(!S_ISLNK(tosb.st_mode) || readlink(toname, buf, sizeof buf) != len ||
strncmp(buf, name, (unsignedint)len) != 0 ||
((stat(name, &fromsb) == 0) && (fromsb.st_mtime > tosb.st_mtime)))) {
(void)(S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
exists = 0;
} if (!exists && symlink(name, toname) < 0)
fail("cannot make symbolic link %s", toname); #ifdef HAVE_LCHOWN if ((owner || group) && lchown(toname, uid, gid) < 0)
fail("cannot change owner of %s", toname); #endif
if (linkname) {
free(linkname);
linkname = 0;
}
} else { /* Copy from name to toname, which might be the same file. */ if (stat(name, &sb) == 0 && S_IFDIR & sb.st_mode) { /* then is directory: must explicitly create destination dir */ /* and manually copy files over */
copydir(name, todir, mode, group, owner, dotimes, uid, gid);
} else {
copyfile(name, toname, mode, group, owner, dotimes, uid, gid);
}
}
free(toname);
}
free(cwd);
free(todir); return 0;
}
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.