]> git.cameronkatri.com Git - pw-darwin.git/blobdiff - libutil/pw_util.c
Use correct macro for path name
[pw-darwin.git] / libutil / pw_util.c
index 6283b95bdcf1520ae800d4f9c121bc936401cbad..fe99d7171b346371370781e1ecaa0e77a957fbaf 100644 (file)
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)pw_util.c  8.3 (Berkeley) 4/2/94";
+#if 0
+static const char sccsid[] = "@(#)pw_util.c    8.3 (Berkeley) 4/2/94";
+#endif
+static const char rcsid[] =
+  "$FreeBSD$";
 #endif /* not lint */
 
 /*
@@ -41,13 +45,13 @@ static char sccsid[] = "@(#)pw_util.c       8.3 (Berkeley) 4/2/94";
  */
 
 #include <sys/param.h>
+#include <sys/errno.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 
 #include <err.h>
-#include <errno.h>
 #include <fcntl.h>
 #include <paths.h>
 #include <pwd.h>
@@ -62,6 +66,8 @@ static char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
 extern char *tempname;
 static pid_t editpid = -1;
 static int lockfd;
+char *mppath = _PATH_PWD;
+char *masterpasswd = _PATH_MASTERPASSWD;
 
 void
 pw_cont(sig)
@@ -111,22 +117,41 @@ pw_lock()
         * that users can't get at the encrypted passwords while editing.
         * Open should allow flock'ing the file; see 4.4BSD.    XXX
         */
-       lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
-       if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
-               err(1, "%s", _PATH_MASTERPASSWD);
-       if (flock(lockfd, LOCK_EX|LOCK_NB))
-               errx(1, "the password db file is busy");
+       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] = _PATH_MASTERPASSWD;
+       static char path[MAXPATHLEN];
        int fd;
        char *p;
 
-       if (p = strrchr(path, '/'))
+       strncpy(path, masterpasswd, MAXPATHLEN - 1);
+       path[MAXPATHLEN] = '\0';
+
+       if ((p = strrchr(path, '/')))
                ++p;
        else
                p = path;
@@ -145,14 +170,15 @@ char *username;
        pid_t pid;
 
        (void)fflush(stderr);
-       if (!(pid = vfork())) {
+       if (!(pid = fork())) {
                if(!username) {
                        warnx("rebuilding the database...");
-                       execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
+                       execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath,
+                           tempname, NULL);
                } else {
                        warnx("updating the database...");
-                       execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-u", 
-                                       username, tempname, NULL);
+                       execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath,
+                           "-u", username, tempname, NULL);
                }
                pw_error(_PATH_PWD_MKDB, 1, 1);
        }
@@ -172,26 +198,28 @@ pw_edit(notsetuid)
 
        if (!(editor = getenv("EDITOR")))
                editor = _PATH_VI;
-       if (p = strrchr(editor, '/'))
+       if ((p = strrchr(editor, '/')))
                ++p;
        else
                p = editor;
 
-       if (!(editpid = vfork())) {
+       if (!(editpid = fork())) {
                if (notsetuid) {
                        (void)setgid(getgid());
                        (void)setuid(getuid());
                }
+               errno = 0;
                execlp(editor, p, tempname, NULL);
-               _exit(1);
+               _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) && WEXITSTATUS(pstat) == 0)
+               else if (WIFEXITED(pstat) && errno == 0)
                        break;
                else
                        pw_error(editor, 1, 1);
@@ -202,14 +230,14 @@ pw_edit(notsetuid)
 void
 pw_prompt()
 {
-       int c;
+       int c, first;
 
        (void)printf("re-edit the password file? [y]: ");
        (void)fflush(stdout);
-       c = getchar();
-       if (c != EOF && c != '\n')
-               while (getchar() != '\n');
-       if (c == 'n')
+       first = c = getchar();
+       while (c != '\n' && c != EOF)
+               c = getchar();
+       if (first == 'n')
                pw_error(NULL, 0, 0);
 }
 
@@ -222,13 +250,13 @@ pw_error(name, err, eval)
        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", _PATH_MASTERPASSWD);
+       warnx("%s: unchanged", masterpasswd);
        (void)unlink(tempname);
        exit(eval);
 }