xref: /original-bsd/usr.bin/chpass/pw_copy.c (revision 7e5c8007)
1 /*-
2  * Copyright (c) 1990, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)pw_copy.c	8.4 (Berkeley) 04/02/94";
10 #endif /* not lint */
11 
12 /*
13  * This module is used to copy the master password file, replacing a single
14  * record, by chpass(1) and passwd(1).
15  */
16 
17 #include <err.h>
18 #include <pwd.h>
19 #include <stdio.h>
20 #include <string.h>
21 
22 #include <pw_util.h>
23 #include "pw_copy.h"
24 
25 extern char *tempname;
26 
27 void
28 pw_copy(ffd, tfd, pw)
29 	int ffd, tfd;
30 	struct passwd *pw;
31 {
32 	FILE *from, *to;
33 	int done;
34 	char *p, buf[8192];
35 
36 	if (!(from = fdopen(ffd, "r")))
37 		pw_error(_PATH_MASTERPASSWD, 1, 1);
38 	if (!(to = fdopen(tfd, "w")))
39 		pw_error(tempname, 1, 1);
40 
41 	for (done = 0; fgets(buf, sizeof(buf), from);) {
42 		if (!strchr(buf, '\n')) {
43 			warnx("%s: line too long", _PATH_MASTERPASSWD);
44 			pw_error(NULL, 0, 1);
45 		}
46 		if (done) {
47 			(void)fprintf(to, "%s", buf);
48 			if (ferror(to))
49 				goto err;
50 			continue;
51 		}
52 		if (!(p = strchr(buf, ':'))) {
53 			warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
54 			pw_error(NULL, 0, 1);
55 		}
56 		*p = '\0';
57 		if (strcmp(buf, pw->pw_name)) {
58 			*p = ':';
59 			(void)fprintf(to, "%s", buf);
60 			if (ferror(to))
61 				goto err;
62 			continue;
63 		}
64 		(void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
65 		    pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
66 		    pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
67 		    pw->pw_dir, pw->pw_shell);
68 		done = 1;
69 		if (ferror(to))
70 			goto err;
71 	}
72 	if (!done)
73 		(void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
74 		    pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
75 		    pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
76 		    pw->pw_dir, pw->pw_shell);
77 
78 	if (ferror(to))
79 err:		pw_error(NULL, 1, 1);
80 	(void)fclose(to);
81 }
82