errx(EXIT_FAILURE, "gid %d is already in use", up->u_uid);
errx(EXIT_FAILURE, "gid %u is already in use", up->u_uid);
moduser(char *login, char *newlogin, user_t *up){	struct passwd	*pwp;	struct group	*grp;	struct tm	tm;	const char	*homedir;	char		newdir[MaxFileNameLen];	char		buf[LINE_MAX];	size_t		colonc, len, loginc;	FILE		*master;	char		*colon, *line;	int		masterfd;	int		ptmpfd;	int		rval;	if (!valid_login(newlogin)) {		errx(EXIT_FAILURE, "`%s' is not a valid login name", login);	}	if ((pwp = getpwnam(login)) == NULL) {		errx(EXIT_FAILURE, "No such user `%s'", login);	}	/* keep dir name in case we need it for '-m' */	homedir = pwp->pw_dir;	if ((masterfd = open(_PATH_MASTERPASSWD, O_RDONLY)) < 0) {		err(EXIT_FAILURE, "can't open `%s'", _PATH_MASTERPASSWD);	}	if (flock(masterfd, LOCK_EX | LOCK_NB) < 0) {		err(EXIT_FAILURE, "can't lock `%s'", _PATH_MASTERPASSWD);	}	pw_init();	if ((ptmpfd = pw_lock(WAITSECS)) < 0) {		(void) close(masterfd);		err(EXIT_FAILURE, "can't obtain pw_lock");	}	if ((master = fdopen(masterfd, "r")) == NULL) {		(void) close(masterfd);		(void) close(ptmpfd);		(void) pw_abort();		err(EXIT_FAILURE, "can't fdopen fd for %s", _PATH_MASTERPASSWD);	}	if (up != NULL) {		if (up->u_flags & F_USERNAME) {			/* if changing name, check new name isn't already in use */			if (strcmp(login, newlogin) != 0 && getpwnam(newlogin) != NULL) {				(void) close(ptmpfd);				(void) pw_abort();				errx(EXIT_FAILURE, "already a `%s' user", newlogin);			}			pwp->pw_name = newlogin;			/*			 * Provide a new directory name in case the			 * home directory is to be moved.			 */			if (up->u_flags & F_MKDIR) {				(void) snprintf(newdir, sizeof(newdir),				    "%s/%s", up->u_basedir, newlogin);				pwp->pw_dir = newdir;			}		}		if (up->u_flags & F_PASSWORD) {			if (up->u_password != NULL && strlen(up->u_password) <= PasswordLength)				pwp->pw_passwd = up->u_password;		}		if (up->u_flags & F_UID) {			/* check uid isn't already allocated */			if (!(up->u_flags & F_DUPUID) && getpwuid((uid_t)(up->u_uid)) != NULL) {				(void) close(ptmpfd);				(void) pw_abort();				errx(EXIT_FAILURE, "uid %d is already in use", up->u_uid);			}			pwp->pw_uid = up->u_uid;		}		if (up->u_flags & F_GROUP) {			/* if -g=uid was specified, check gid is unused */			if (strcmp(up->u_primgrp, "=uid") == 0) {				if (getgrgid((gid_t)(up->u_uid)) != NULL) {					(void) close(ptmpfd);					(void) pw_abort();					errx(EXIT_FAILURE, "gid %d is already in use", up->u_uid);				}				pwp->pw_gid = up->u_uid;			} else if ((grp = getgrnam(up->u_primgrp)) != NULL) {				pwp->pw_gid = grp->gr_gid;			} else if (is_number(up->u_primgrp) &&				   (grp = getgrgid((gid_t)atoi(up->u_primgrp))) != NULL) {				pwp->pw_gid = grp->gr_gid;			} else {				(void) close(ptmpfd);				(void) pw_abort();				errx(EXIT_FAILURE, "group %s not found", up->u_primgrp);			}		}		if (up->u_flags |= F_INACTIVE)			pwp->pw_change = up->u_inactive;		if (up->u_flags & F_EXPIRE) {			(void) memset(&tm, 0, sizeof(tm));			if (strptime(up->u_expire, "%c", &tm) == NULL)				warnx("invalid time format `%s'", optarg);			else				pwp->pw_expire = mktime(&tm);		}		if (up->u_flags & F_COMMENT)			pwp->pw_gecos = up->u_comment;		if (up->u_flags & F_HOMEDIR)			pwp->pw_dir = up->u_home;		if (up->u_flags & F_SHELL)			pwp->pw_shell = up->u_shell;#ifdef EXTENSIONS		if (up->u_flags & F_CLASS)			pwp->pw_class = up->u_class;#endif	}	loginc = strlen(login);	while ((line = fgetln(master, &len)) != NULL) {		if ((colon = strchr(line, ':')) == NULL) {			warnx("Malformed entry `%s'. Skipping", line);			continue;		}		colonc = (size_t)(colon - line);		if (strncmp(login, line, loginc) == 0 && loginc == colonc) {			if (up != NULL) {				len = snprintf(buf, sizeof(buf),					"%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",					newlogin,					pwp->pw_passwd,					pwp->pw_uid,					pwp->pw_gid,#ifdef EXTENSIONS					pwp->pw_class,#else					"",#endif					(long)pwp->pw_change,					(long)pwp->pw_expire,					pwp->pw_gecos,					pwp->pw_dir,					pwp->pw_shell);				if (len >= sizeof(buf) ||				    (strchr(up->u_comment, '&') != NULL &&				    len + strlen(newlogin) >= sizeof(buf))) {					(void) close(ptmpfd);					(void) pw_abort();					errx(EXIT_FAILURE, "can't add `%s', line too long (%d bytes)", buf, len + strlen(newlogin));				}				if (write(ptmpfd, buf, len) != len) {					(void) close(ptmpfd);					(void) pw_abort();					err(EXIT_FAILURE, "can't add `%s'", buf);				}			}		} else if ((colonc = write(ptmpfd, line, len)) != len) {			(void) close(masterfd);			(void) close(ptmpfd);			(void) pw_abort();			err(EXIT_FAILURE, "short write to /etc/ptmp (%lld not %lld chars)",			    (long long)colonc, (long long)len);		}	}	if (up != NULL) {		if ((up->u_flags & F_MKDIR) &&		    asystem("%s %s %s", MV, homedir, pwp->pw_dir) != 0) {			(void) close(ptmpfd);			(void) pw_abort();			err(EXIT_FAILURE, "can't move `%s' to `%s'",			    homedir, pwp->pw_dir);		}		if (up->u_groupc > 0 &&		    !append_group(newlogin, up->u_groupc, up->u_groupv)) {			(void) close(ptmpfd);			 (void) pw_abort();			 errx(EXIT_FAILURE, "can't append `%s' to new groups",			    newlogin);		}	}	(void) close(ptmpfd);	if (up != NULL && strcmp(login, newlogin) == 0)		rval = pw_mkdb(login, 0);	else		rval = pw_mkdb(NULL, 0);	if (rval == -1)		err(EXIT_FAILURE, "pw_mkdb failed");	return 1;}