Index: head/lib/libutil/pw_util.c =================================================================== --- head/lib/libutil/pw_util.c (revision 62987) +++ head/lib/libutil/pw_util.c (revision 62988) @@ -1,262 +1,262 @@ /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ /* * This file is used by all the "password" programs; vipw(8), chpass(1), * and passwd(1). */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pw_util.h" extern char *tempname; static pid_t editpid = -1; static int lockfd; char *mppath = _PATH_PWD; char *masterpasswd = _PATH_MASTERPASSWD; void pw_cont(sig) int sig; { if (editpid != -1) kill(editpid, sig); } void pw_init() { struct rlimit rlim; /* Unlimited resource limits. */ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &rlim); (void)setrlimit(RLIMIT_FSIZE, &rlim); (void)setrlimit(RLIMIT_STACK, &rlim); (void)setrlimit(RLIMIT_DATA, &rlim); (void)setrlimit(RLIMIT_RSS, &rlim); /* Don't drop core (not really necessary, but GP's). */ rlim.rlim_cur = rlim.rlim_max = 0; (void)setrlimit(RLIMIT_CORE, &rlim); /* Turn off signals. */ (void)signal(SIGALRM, SIG_IGN); (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGPIPE, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGTERM, SIG_IGN); (void)signal(SIGCONT, pw_cont); /* Create with exact permissions. */ (void)umask(0); } int pw_lock() { /* * If the master password file doesn't exist, the system is hosed. * Might as well try to build one. Set the close-on-exec bit so * that users can't get at the encrypted passwords while editing. * Open should allow flock'ing the file; see 4.4BSD. XXX */ for (;;) { struct stat st; lockfd = open(masterpasswd, O_RDONLY, 0); if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1) err(1, "%s", masterpasswd); if (flock(lockfd, LOCK_EX|LOCK_NB)) errx(1, "the password db file is busy"); /* * If the password file was replaced while we were trying to * get the lock, our hardlink count will be 0 and we have to * close and retry. */ if (fstat(lockfd, &st) < 0) errx(1, "fstat() failed"); if (st.st_nlink != 0) break; close(lockfd); lockfd = -1; } return (lockfd); } int pw_tmp() { static char path[MAXPATHLEN]; int fd; char *p; strncpy(path, masterpasswd, MAXPATHLEN - 1); path[MAXPATHLEN] = '\0'; if ((p = strrchr(path, '/'))) ++p; else p = path; strcpy(p, "pw.XXXXXX"); if ((fd = mkstemp(path)) == -1) err(1, "%s", path); tempname = path; return (fd); } int pw_mkdb(username) char *username; { int pstat; pid_t pid; (void)fflush(stderr); if (!(pid = fork())) { if(!username) { warnx("rebuilding the database..."); execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath, tempname, NULL); } else { warnx("updating the database..."); execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath, "-u", username, tempname, NULL); } pw_error(_PATH_PWD_MKDB, 1, 1); } pid = waitpid(pid, &pstat, 0); if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) return (0); warnx("done"); return (1); } void pw_edit(notsetuid) int notsetuid; { int pstat; char *p, *editor; if (!(editor = getenv("EDITOR"))) editor = _PATH_VI; if ((p = strrchr(editor, '/'))) ++p; else p = editor; if (!(editpid = fork())) { if (notsetuid) { (void)setgid(getgid()); (void)setuid(getuid()); } errno = 0; execlp(editor, p, tempname, NULL); _exit(errno); } for (;;) { editpid = waitpid(editpid, (int *)&pstat, WUNTRACED); errno = WEXITSTATUS(pstat); if (editpid == -1) pw_error(editor, 1, 1); else if (WIFSTOPPED(pstat)) raise(WSTOPSIG(pstat)); else if (WIFEXITED(pstat) && errno == 0) break; else pw_error(editor, 1, 1); } editpid = -1; } void pw_prompt() { int c, first; (void)printf("re-edit the password file? [y]: "); (void)fflush(stdout); first = c = getchar(); while (c != '\n' && c != EOF) c = getchar(); if (first == 'n') pw_error(NULL, 0, 0); } void pw_error(name, err, eval) char *name; int err, eval; { #ifdef YP extern int _use_yp; #endif /* YP */ if (err) - warn(name); + warn("%s", name); #ifdef YP if (_use_yp) warnx("NIS information unchanged"); else #endif /* YP */ warnx("%s: unchanged", masterpasswd); (void)unlink(tempname); exit(eval); } Index: head/usr.sbin/vipw/pw_util.c =================================================================== --- head/usr.sbin/vipw/pw_util.c (revision 62987) +++ head/usr.sbin/vipw/pw_util.c (revision 62988) @@ -1,262 +1,262 @@ /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ /* * This file is used by all the "password" programs; vipw(8), chpass(1), * and passwd(1). */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pw_util.h" extern char *tempname; static pid_t editpid = -1; static int lockfd; char *mppath = _PATH_PWD; char *masterpasswd = _PATH_MASTERPASSWD; void pw_cont(sig) int sig; { if (editpid != -1) kill(editpid, sig); } void pw_init() { struct rlimit rlim; /* Unlimited resource limits. */ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &rlim); (void)setrlimit(RLIMIT_FSIZE, &rlim); (void)setrlimit(RLIMIT_STACK, &rlim); (void)setrlimit(RLIMIT_DATA, &rlim); (void)setrlimit(RLIMIT_RSS, &rlim); /* Don't drop core (not really necessary, but GP's). */ rlim.rlim_cur = rlim.rlim_max = 0; (void)setrlimit(RLIMIT_CORE, &rlim); /* Turn off signals. */ (void)signal(SIGALRM, SIG_IGN); (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGPIPE, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGTERM, SIG_IGN); (void)signal(SIGCONT, pw_cont); /* Create with exact permissions. */ (void)umask(0); } int pw_lock() { /* * If the master password file doesn't exist, the system is hosed. * Might as well try to build one. Set the close-on-exec bit so * that users can't get at the encrypted passwords while editing. * Open should allow flock'ing the file; see 4.4BSD. XXX */ for (;;) { struct stat st; lockfd = open(masterpasswd, O_RDONLY, 0); if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1) err(1, "%s", masterpasswd); if (flock(lockfd, LOCK_EX|LOCK_NB)) errx(1, "the password db file is busy"); /* * If the password file was replaced while we were trying to * get the lock, our hardlink count will be 0 and we have to * close and retry. */ if (fstat(lockfd, &st) < 0) errx(1, "fstat() failed"); if (st.st_nlink != 0) break; close(lockfd); lockfd = -1; } return (lockfd); } int pw_tmp() { static char path[MAXPATHLEN]; int fd; char *p; strncpy(path, masterpasswd, MAXPATHLEN - 1); path[MAXPATHLEN] = '\0'; if ((p = strrchr(path, '/'))) ++p; else p = path; strcpy(p, "pw.XXXXXX"); if ((fd = mkstemp(path)) == -1) err(1, "%s", path); tempname = path; return (fd); } int pw_mkdb(username) char *username; { int pstat; pid_t pid; (void)fflush(stderr); if (!(pid = fork())) { if(!username) { warnx("rebuilding the database..."); execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath, tempname, NULL); } else { warnx("updating the database..."); execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath, "-u", username, tempname, NULL); } pw_error(_PATH_PWD_MKDB, 1, 1); } pid = waitpid(pid, &pstat, 0); if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) return (0); warnx("done"); return (1); } void pw_edit(notsetuid) int notsetuid; { int pstat; char *p, *editor; if (!(editor = getenv("EDITOR"))) editor = _PATH_VI; if ((p = strrchr(editor, '/'))) ++p; else p = editor; if (!(editpid = fork())) { if (notsetuid) { (void)setgid(getgid()); (void)setuid(getuid()); } errno = 0; execlp(editor, p, tempname, NULL); _exit(errno); } for (;;) { editpid = waitpid(editpid, (int *)&pstat, WUNTRACED); errno = WEXITSTATUS(pstat); if (editpid == -1) pw_error(editor, 1, 1); else if (WIFSTOPPED(pstat)) raise(WSTOPSIG(pstat)); else if (WIFEXITED(pstat) && errno == 0) break; else pw_error(editor, 1, 1); } editpid = -1; } void pw_prompt() { int c, first; (void)printf("re-edit the password file? [y]: "); (void)fflush(stdout); first = c = getchar(); while (c != '\n' && c != EOF) c = getchar(); if (first == 'n') pw_error(NULL, 0, 0); } void pw_error(name, err, eval) char *name; int err, eval; { #ifdef YP extern int _use_yp; #endif /* YP */ if (err) - warn(name); + warn("%s", name); #ifdef YP if (_use_yp) warnx("NIS information unchanged"); else #endif /* YP */ warnx("%s: unchanged", masterpasswd); (void)unlink(tempname); exit(eval); } Index: head/usr.sbin/vnconfig/vnconfig.c =================================================================== --- head/usr.sbin/vnconfig/vnconfig.c (revision 62987) +++ head/usr.sbin/vnconfig/vnconfig.c (revision 62988) @@ -1,637 +1,637 @@ /* * Copyright (c) 1993 University of Utah. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: Utah $Hdr: vnconfig.c 1.1 93/12/15$ */ #ifndef lint #if 0 static char sccsid[] = "@(#)vnconfig.c 8.1 (Berkeley) 12/15/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAXVNDISK 16 #define LINESIZE 1024 #define ZBUFSIZE 32768 struct vndisk { char *dev; char *file; char *autolabel; int flags; int size; char *oarg; } vndisks[MAXVNDISK]; #define VN_CONFIG 0x01 #define VN_UNCONFIG 0x02 #define VN_ENABLE 0x04 #define VN_DISABLE 0x08 #define VN_SWAP 0x10 #define VN_MOUNTRO 0x20 #define VN_MOUNTRW 0x40 #define VN_IGNORE 0x80 #define VN_SET 0x100 #define VN_RESET 0x200 #define VN_TRUNCATE 0x400 #define VN_ZERO 0x800 int nvndisks; int all = 0; int verbose = 0; int global = 0; u_long setopt = 0; u_long resetopt = 0; char *configfile; int config __P((struct vndisk *)); void getoptions __P((struct vndisk *, char *)); char *rawdevice __P((char *)); void readconfig __P((int)); static void usage __P((void)); static int getsize(const char *arg); static void do_autolabel(const char *dev, const char *label); int what_opt __P((char *, u_long *)); int main(argc, argv) char **argv; { register int i, rv; int flags = 0; int size = 0; char *autolabel = NULL; char *s; configfile = _PATH_VNTAB; while ((i = getopt(argc, argv, "acdef:gr:s:S:TZL:uv")) != -1) switch (i) { /* all -- use config file */ case 'a': all++; break; /* configure */ case 'c': flags |= VN_CONFIG; flags &= ~VN_UNCONFIG; break; /* disable */ case 'd': flags |= VN_DISABLE; flags &= ~VN_ENABLE; break; /* enable */ case 'e': flags |= (VN_ENABLE|VN_CONFIG); flags &= ~(VN_DISABLE|VN_UNCONFIG); break; /* alternate config file */ case 'f': configfile = optarg; break; /* fiddle global options */ case 'g': global = 1 - global; break; /* reset options */ case 'r': for (s = strtok(optarg, ","); s; s = strtok(NULL, ",")) { if (what_opt(s, &resetopt)) errx(1, "invalid options '%s'", s); } flags |= VN_RESET; break; /* set options */ case 's': for (s = strtok(optarg, ","); s; s = strtok(NULL, ",")) { if (what_opt(s, &setopt)) errx(1, "invalid options '%s'", s); } flags |= VN_SET; break; /* unconfigure */ case 'u': flags |= (VN_DISABLE|VN_UNCONFIG); flags &= ~(VN_ENABLE|VN_CONFIG); break; /* verbose */ case 'v': verbose++; break; case 'S': size = getsize(optarg); break; case 'T': flags |= VN_TRUNCATE; break; case 'Z': flags |= VN_ZERO; break; case 'L': autolabel = optarg; break; default: usage(); } if (modfind("vn") < 0) if (kldload("vn") < 0 || modfind("vn") < 0) warnx( "cannot find or load \"vn\" kernel module"); if (flags == 0) flags = VN_CONFIG; if (all) { readconfig(flags); } else { if (argc < optind + 1) usage(); vndisks[0].dev = argv[optind++]; vndisks[0].file = argv[optind++]; /* may be NULL */ vndisks[0].flags = flags; vndisks[0].size = size; vndisks[0].autolabel = autolabel; if (optind < argc) getoptions(&vndisks[0], argv[optind]); nvndisks = 1; } rv = 0; for (i = 0; i < nvndisks; i++) rv += config(&vndisks[i]); exit(rv); } int what_opt(str,p) char *str; u_long *p; { if (!strcmp(str,"reserve")) { *p |= VN_RESERVE; return 0; } if (!strcmp(str,"labels")) { *p |= VN_LABELS; return 0; } if (!strcmp(str,"follow")) { *p |= VN_FOLLOW; return 0; } if (!strcmp(str,"debug")) { *p |= VN_DEBUG; return 0; } if (!strcmp(str,"io")) { *p |= VN_IO; return 0; } if (!strcmp(str,"all")) { *p |= ~0; return 0; } if (!strcmp(str,"none")) { *p |= 0; return 0; } return 1; } int config(vnp) struct vndisk *vnp; { char *dev, *file, *oarg; int flags; struct vn_ioctl vnio; register int rv; char *rdev; FILE *f; u_long l; int pgsize = getpagesize(); rv = 0; /* * Prepend "/dev/" to the specified device name, if necessary. * Operate on vnp->dev because it is used later. */ if (vnp->dev[0] != '/' && vnp->dev[0] != '.') (void)asprintf(&vnp->dev, "/dev/%s", vnp->dev); dev = vnp->dev; file = vnp->file; flags = vnp->flags; oarg = vnp->oarg; if (flags & VN_IGNORE) return(0); /* * When a regular file has been specified, do any requested setup * of the file. Truncation (also creates the file if necessary), * sizing, and zeroing. */ if (file && vnp->size != 0 && (flags & VN_CONFIG)) { int fd; struct stat st; if (flags & VN_TRUNCATE) fd = open(file, O_RDWR|O_CREAT|O_TRUNC); else fd = open(file, O_RDWR); if (fd >= 0 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { if (st.st_size < (off_t)vnp->size * pgsize) ftruncate(fd, (off_t)vnp->size * pgsize); if (vnp->size != 0) st.st_size = (off_t)vnp->size * pgsize; if (flags & VN_ZERO) { char *buf = malloc(ZBUFSIZE); bzero(buf, ZBUFSIZE); while (st.st_size > 0) { int n = (st.st_size > ZBUFSIZE) ? ZBUFSIZE : (int)st.st_size; if (write(fd, buf, n) != n) { ftruncate(fd, 0); printf("Unable to ZERO file %s\n", file); return(0); } st.st_size -= (off_t)n; } } close(fd); } else { printf("Unable to open file %s\n", file); return(0); } } rdev = rawdevice(dev); f = fopen(rdev, "rw"); if (f == NULL) { - warn(dev); + warn("%s", dev); return(1); } vnio.vn_file = file; vnio.vn_size = vnp->size; /* non-zero only if swap backed */ /* * Disable the device */ if (flags & VN_DISABLE) { if (flags & (VN_MOUNTRO|VN_MOUNTRW)) { rv = unmount(oarg, 0); if (rv) { if (errno == EBUSY) flags &= ~VN_UNCONFIG; if ((flags & VN_UNCONFIG) == 0) warn("umount"); } else if (verbose) printf("%s: unmounted\n", dev); } } /* * Clear (un-configure) the device */ if (flags & VN_UNCONFIG) { rv = ioctl(fileno(f), VNIOCDETACH, &vnio); if (rv) { if (errno == ENODEV) { if (verbose) printf("%s: not configured\n", dev); rv = 0; } else warn("VNIOCDETACH"); } else if (verbose) printf("%s: cleared\n", dev); } /* * Set specified options */ if (flags & VN_SET) { l = setopt; if (global) rv = ioctl(fileno(f), VNIOCGSET, &l); else rv = ioctl(fileno(f), VNIOCUSET, &l); if (rv) { warn("VNIO[GU]SET"); } else if (verbose) printf("%s: flags now=%08x\n",dev,l); } /* * Reset specified options */ if (flags & VN_RESET) { l = resetopt; if (global) rv = ioctl(fileno(f), VNIOCGCLEAR, &l); else rv = ioctl(fileno(f), VNIOCUCLEAR, &l); if (rv) { warn("VNIO[GU]CLEAR"); } else if (verbose) printf("%s: flags now=%08x\n",dev,l); } /* * Configure the device */ if (flags & VN_CONFIG) { rv = ioctl(fileno(f), VNIOCATTACH, &vnio); if (rv) { warn("VNIOCATTACH"); flags &= ~VN_ENABLE; } else { if (verbose) { printf( "%s: %d bytes on %s\n", dev, vnio.vn_size, file ); } /* * autolabel */ if (vnp->autolabel) { do_autolabel(vnp->dev, vnp->autolabel); } } } /* * Set an option */ if (flags & VN_SET) { l = setopt; if (global) rv = ioctl(fileno(f), VNIOCGSET, &l); else rv = ioctl(fileno(f), VNIOCUSET, &l); if (rv) { warn("VNIO[GU]SET"); } else if (verbose) printf("%s: flags now=%08lx\n",dev,l); } /* * Reset an option */ if (flags & VN_RESET) { l = resetopt; if (global) rv = ioctl(fileno(f), VNIOCGCLEAR, &l); else rv = ioctl(fileno(f), VNIOCUCLEAR, &l); if (rv) { warn("VNIO[GU]CLEAR"); } else if (verbose) printf("%s: flags now=%08lx\n",dev,l); } /* * Enable special functions on the device */ if (flags & VN_ENABLE) { if (flags & VN_SWAP) { rv = swapon(dev); if (rv) warn("swapon"); else if (verbose) printf("%s: swapping enabled\n", dev); } if (flags & (VN_MOUNTRO|VN_MOUNTRW)) { struct ufs_args args; int mflags; args.fspec = dev; mflags = (flags & VN_MOUNTRO) ? MNT_RDONLY : 0; rv = mount("ufs", oarg, mflags, &args); if (rv) warn("mount"); else if (verbose) printf("%s: mounted on %s\n", dev, oarg); } } /* done: */ fclose(f); fflush(stdout); return(rv < 0); } #define EOL(c) ((c) == '\0' || (c) == '\n') #define WHITE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') void readconfig(flags) int flags; { char buf[LINESIZE]; FILE *f; register char *cp, *sp; register int ix; f = fopen(configfile, "r"); if (f == NULL) err(1, "%s", configfile); ix = 0; while (fgets(buf, LINESIZE, f) != NULL) { cp = buf; if (*cp == '#') continue; while (!EOL(*cp) && WHITE(*cp)) cp++; if (EOL(*cp)) continue; sp = cp; while (!EOL(*cp) && !WHITE(*cp)) cp++; if (EOL(*cp)) continue; *cp++ = '\0'; vndisks[ix].dev = malloc(cp - sp); strcpy(vndisks[ix].dev, sp); while (!EOL(*cp) && WHITE(*cp)) cp++; if (EOL(*cp)) continue; sp = cp; while (!EOL(*cp) && !WHITE(*cp)) cp++; *cp++ = '\0'; if (*sp == '%' && strtol(sp + 1, NULL, 0) > 0) { vndisks[ix].size = getsize(sp + 1); } else { vndisks[ix].file = malloc(cp - sp); strcpy(vndisks[ix].file, sp); } while (!EOL(*cp) && WHITE(*cp)) cp++; vndisks[ix].flags = flags; if (!EOL(*cp)) { sp = cp; while (!EOL(*cp) && !WHITE(*cp)) cp++; *cp++ = '\0'; getoptions(&vndisks[ix], sp); } nvndisks++; ix++; } } void getoptions(vnp, fstr) struct vndisk *vnp; char *fstr; { int flags = 0; char *oarg = NULL; if (strcmp(fstr, "swap") == 0) flags |= VN_SWAP; else if (strncmp(fstr, "mount=", 6) == 0) { flags |= VN_MOUNTRW; oarg = &fstr[6]; } else if (strncmp(fstr, "mountrw=", 8) == 0) { flags |= VN_MOUNTRW; oarg = &fstr[8]; } else if (strncmp(fstr, "mountro=", 8) == 0) { flags |= VN_MOUNTRO; oarg = &fstr[8]; } else if (strcmp(fstr, "ignore") == 0) flags |= VN_IGNORE; vnp->flags |= flags; if (oarg) { vnp->oarg = malloc(strlen(oarg) + 1); strcpy(vnp->oarg, oarg); } else vnp->oarg = NULL; } char * rawdevice(dev) char *dev; { register char *rawbuf, *dp, *ep; struct stat sb; int len; len = strlen(dev); rawbuf = malloc(len + 2); strcpy(rawbuf, dev); if (stat(rawbuf, &sb) != 0 || !S_ISCHR(sb.st_mode)) { dp = rindex(rawbuf, '/'); if (dp) { for (ep = &rawbuf[len]; ep > dp; --ep) *(ep+1) = *ep; *++ep = 'r'; } } return (rawbuf); } static void usage() { fprintf(stderr, "%s\n%s\n%s\n", "usage: vnconfig [-cdeguv] [-s option] [-r option] [-S value] special_file", " [regular_file] [feature]", " vnconfig -a [-cdeguv] [-s option] [-r option] [-f config_file]"); exit(1); } static int getsize(const char *arg) { char *ptr; int pgsize = getpagesize(); quad_t size = strtoq(arg, &ptr, 0); switch(tolower(*ptr)) { case 't': /* * GULP! Terrabytes. It's actually possible to create * a 7.9 TB VN device, though newfs can't handle any single * filesystem larger then 1 TB. */ size *= 1024; /* fall through */ case 'g': size *= 1024; /* fall through */ default: case 'm': size *= 1024; /* fall through */ case 'k': size *= 1024; /* fall through */ case 'c': break; } size = (size + pgsize - 1) / pgsize; return((int)size); } /* * DO_AUTOLABEL * * Automatically label the device. This will wipe any preexisting * label. */ static void do_autolabel(const char *dev, const char *label) { /* XXX not yet implemented */ fprintf(stderr, "autolabel not yet implemented, sorry\n"); exit(1); }