* Copyright (c) 1987 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1987 Regents of the University of California.\n\
static char sccsid
[] = "@(#)vipw.c 5.3 (Berkeley) %G%";
#include <machine/machparam.h>
* Password file editor with locking.
static char *passwd
= "/etc/passwd", buf
[BUFSIZ
];
register int n
, fd_passwd
, fd_temp
;
static char *temp
= "/etc/ptmp";
(void)signal(SIGHUP
, SIG_IGN
);
(void)signal(SIGINT
, SIG_IGN
);
(void)signal(SIGQUIT
, SIG_IGN
);
setbuf(stderr
, (char *)NULL
);
if ((fd_passwd
= open(passwd
, O_RDONLY
, 0)) < 0) {
if ((fd_temp
= open(temp
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644)) < 0) {
fputs("vipw: password file busy.\n", stderr
);
while ((n
= read(fd_passwd
, buf
, sizeof(buf
))) > 0)
if (write(fd_temp
, buf
, n
) != n
) {
if (fstat(fd_temp
, &s1
)) {
if (!(editor
= getenv("EDITOR")))
(void)sprintf(buf
, "%s %s", editor
, temp
);
if (!freopen(temp
, "r", stdin
)) {
fprintf(stderr
, "vipw: can't reopen temp file; %s unchanged.\n", passwd
);
if (fstat(fileno(stdin
), &s2
)) {
fprintf(stderr
, "vipw: can't stat temp file; %s unchanged.\n", passwd
);
if (s1
.st_mtime
== s2
.st_mtime
) {
fprintf(stderr
, "vipw: %s unchanged.\n", passwd
);
fprintf(stderr
, "vipw: bad temp file; %s unchanged.\n", passwd
);
static char *temp_pag
= "/etc/ptmp.pag",
*temp_dir
= "/etc/ptmp.dir",
*passwd_pag
= "/etc/passwd.pag",
*passwd_dir
= "/etc/passwd.dir";
fputs("vipw: mkpasswd failed.\n", stderr
);
else if (rename(temp_pag
, passwd_pag
) < 0) {
fprintf(stderr
, "vipw: ");
else if (rename(temp_dir
, passwd_dir
) < 0) {
fprintf(stderr
, "vipw: ");
else if (rename(temp
, passwd
) < 0) {
fprintf(stderr
, "vipw: ");
#define CHN ((char *)NULL)
char *token(), *getusershell();
for (root
= 0; gets(buf
); root
= 0) {
fputs("vipw: empty line.\n", stderr
);
if (!(cp
= token(buf
)) || !*cp
) /* login */
(void)token(CHN
); /* passwd */
if (!(cp
= token(CHN
)) || !*cp
) /* uid */
fprintf(stderr
, "vipw: root uid should be 0; %s unchanged.\n", passwd
);
fprintf(stderr
, "vipw: %s > max uid value (%u); %s unchanged.\n", cp
, USHRT_MAX
, passwd
);
if (!(cp
= token(CHN
)) || !*cp
) /* gid */
fprintf(stderr
, "vipw: %s > max gid value (%u); %s unchanged.\n", cp
, USHRT_MAX
, passwd
);
(void)token(CHN
); /* gcos */
if (!token(CHN
)) /* home directory */
if (!(cp
= token(CHN
))) /* shell */
if (root
&& *cp
) /* empty == /bin/sh */
if (!(sh
= getusershell())) {
fprintf(stderr
, "vipw: illegal shell (%s) for root; %s unchanged.\n", cp
, passwd
);
else if (!strcmp(cp
, sh
))
if (token(CHN
)) { /* too many fields */
bad
: fprintf(stderr
, "vipw: corrupted entry; %s unchanged.\n", passwd
);
execl("/etc/mkpasswd", "mkpasswd", file
, 0);
while ((w
= wait(&status
)) != pid
&& w
!= -1);
if (bfr
) /* re-init string */
else if (!cp
) /* check if hit EOS last time */
else if (!bfr
) /* start at next char after ':' */
if (!*cp
) { /* found EOS; mark it for next time */
else if (*cp
== ':') { /* found ':'; end token */
return(start
); /* return token */