*** vipw.c.orig Tue Oct 31 23:06:55 2000 --- vipw.c Mon Nov 6 19:10:09 2000 *************** *** 57,65 **** --- 57,69 ---- #include "pw_util.h" + #define PROG_VIPW "vipw" + #define PROG_PWLOCK "pw_lock" + extern char *mppath; extern char *masterpasswd; char *tempname; + char *progname; void copyfile __P((int, int)); static void usage __P((void)); *************** *** 73,78 **** --- 77,90 ---- struct stat begin, end; int ch; + /* Strip the path, if present, from the program name */ + progname = strrchr(argv[0], '/'); + if (progname == NULL) { + progname = argv[0]; + } else { + progname++; /* Skip past the '/' */ + } + while ((ch = getopt(argc, argv, "d:")) != -1) switch (ch) { case 'd': *************** *** 97,104 **** argc -= optind; argv += optind; ! if (argc != 0) usage(); pw_init(); pfd = pw_lock(); --- 109,117 ---- argc -= optind; argv += optind; ! if (argc != 0 && strcmp(progname, PROG_VIPW) == 0) { usage(); + } pw_init(); pfd = pw_lock(); *************** *** 111,117 **** for (;;) { if (stat(tempname, &begin)) pw_error(tempname, 1, 1); ! pw_edit(0); if (stat(tempname, &end)) pw_error(tempname, 1, 1); if (begin.st_mtime == end.st_mtime) { --- 124,137 ---- for (;;) { if (stat(tempname, &begin)) pw_error(tempname, 1, 1); ! if (strcmp(progname, PROG_VIPW) == 0) { ! pw_edit(0); ! } else if (strcmp(progname, PROG_PWLOCK) == 0) { ! pw_runcmd(argv); ! } else { ! warnx("Unknown invocation mode '%s'", progname); ! pw_error((char *)NULL, 0, 0); ! } if (stat(tempname, &end)) pw_error(tempname, 1, 1); if (begin.st_mtime == end.st_mtime) { *** pw_util.h.org Sun Nov 5 12:10:42 2000 --- pw_util.h Sun Nov 5 12:28:21 2000 *************** *** 40,42 **** --- 40,43 ---- int pw_mkdb __P((char *)); void pw_prompt __P((void)); int pw_tmp __P((void)); + int pw_runcmd __P((char **argv)); *** pw_util.c.org Sun Nov 5 12:08:15 2000 --- pw_util.c Mon Nov 6 19:24:53 2000 *************** *** 260,262 **** --- 260,290 ---- (void)unlink(tempname); exit(eval); } + + int + pw_runcmd(char **argv) + { + union wait pstat; + pid_t pid; + char *progname; + + /* Strip the path, if present, from the program name */ + progname = strrchr(argv[0], '/'); + if (progname == NULL) { + progname = argv[0]; + } else { + progname++; /* Skip past the '/' */ + } + + if (!(pid = vfork())) { + execl(argv[0], progname, tempname, (char *)NULL); + warn("Command '%s' failed", argv[0]); + pw_error((char *)NULL, 0, 0); + } + pid = waitpid(pid, (int *)&pstat, 0); + if (pid == -1 || pstat.w_status) { + return(0); + } + (void)printf("%s: done\n", argv[0]); + return(1); + } *** Makefile.orig Fri Sep 7 15:08:10 2001 --- Makefile Fri Sep 7 15:08:54 2001 *************** *** 2,7 **** --- 2,8 ---- # $FreeBSD: src/usr.sbin/vipw/Makefile,v 1.2.14.1 2001/04/25 12:11:09 ru Exp $ PROG= vipw + LINKS= ${BINDIR}/vipw ${BINDIR}/pw_lock SRCS= pw_util.c vipw.c MAN= vipw.8 *** vipw.8.orig Fri Sep 7 15:10:22 2001 --- vipw.8 Fri Sep 7 15:22:57 2001 *************** *** 41,46 **** --- 41,48 ---- .Sh SYNOPSIS .Nm .Op Fl d Ar directory + .Nm pw_lock + .Ar command arg ... .Sh DESCRIPTION .Nm Vipw edits the password file after setting the appropriate locks, *************** *** 83,88 **** --- 85,95 ---- at very large sites could take several minutes. Until this update is completed, the password file is unavailable for other updates and the new information is not available to programs. + .Pp + If invoked as + .Nm pw_lock + , the user database is locked, the command is run, and then the user + database is updated as above. .Sh ENVIRONMENT If the following environment variable exists it will be utilized by .Nm :