Mercurial > hg > Applications > mh
comparison support/pop/popwrd.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children | a6481689f99c |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
1 /* popwrd.c - set password for a POP subscriber */ | |
2 #ifndef lint | |
3 static char ident[] = "@(#)$Id$"; | |
4 #endif /* lint */ | |
5 | |
6 #include "../h/strings.h" | |
7 #include "../zotnet/bboards.h" | |
8 #include <errno.h> | |
9 #include <pwd.h> | |
10 #include <signal.h> | |
11 #include <stdio.h> | |
12 #include <sys/types.h> | |
13 #include <sys/file.h> | |
14 #ifdef SYS5 | |
15 #include <fcntl.h> | |
16 #endif /* SYS5 */ | |
17 | |
18 #ifndef __STDC__ | |
19 #ifdef SYS5 | |
20 struct passwd *getpwnam(); | |
21 #endif | |
22 #endif | |
23 | |
24 static char temp[] = "ptmp"; | |
25 static char home[BUFSIZ]; | |
26 | |
27 extern int errno; | |
28 | |
29 char *crypt (), *getpass (), *tail (); | |
30 time_t time (); | |
31 | |
32 #define compar(s,t) (strcmp (s, t) ? s : "") | |
33 | |
34 /* */ | |
35 | |
36 /* ARGSUSED */ | |
37 | |
38 main (argc, argv) | |
39 int argc; | |
40 char **argv; | |
41 { | |
42 int i, | |
43 fd, | |
44 flags, | |
45 insist; | |
46 time_t salt; | |
47 char c, | |
48 *cp, | |
49 buffer[BUFSIZ], | |
50 saltc[2], | |
51 **ap; | |
52 struct bboard *bb, | |
53 *bp; | |
54 struct passwd *pw; | |
55 FILE * fp; | |
56 | |
57 if ((pw = getpwnam (POPUID)) == NULL) { | |
58 fprintf (stderr, "no entry for ~%s.\n", POPUID); | |
59 exit (1); | |
60 } | |
61 if (chdir (strcpy (home, pw -> pw_dir)) < 0) { | |
62 fprintf (stderr, "no home directory for ~%s.\n", POPUID); | |
63 exit (1); | |
64 } | |
65 if (!setpwinfo (pw, POPDB, 0)) { | |
66 fprintf (stderr, "setbbinfo(%s, %s, 0) failed -- %s.\n", | |
67 pw -> pw_name, POPDB, getbberr ()); | |
68 exit (1); | |
69 } | |
70 | |
71 if (argc != 2) { | |
72 fprintf (stderr, "usage: %s pop-subscriber\n", *argv); | |
73 exit (1); | |
74 } | |
75 if ((bb = getbbnam (argv[1])) == NULL | |
76 && (bb = getbbaka (argv[1])) == NULL) { | |
77 fprintf (stderr, "Permission denied.\n"); | |
78 exit (1); | |
79 } | |
80 | |
81 if (!ldrbb (bb) && getuid () && !ldrchk (bb)) | |
82 exit (1); | |
83 | |
84 if ((bp = getbbcpy (bb)) == NULL) { | |
85 fprintf (stderr, "getbbcpy loses.\n"); | |
86 exit (1); | |
87 } | |
88 | |
89 (void) endbbent (); | |
90 | |
91 #ifdef lint | |
92 flags = 0; | |
93 #endif /* lint */ | |
94 for (insist = 0; insist < 2; insist++) { | |
95 if (insist) | |
96 printf ("Please use %s.\n", | |
97 flags == 1 ? "at least one non-numeric character" | |
98 : "a longer password"); | |
99 | |
100 if ((i = strlen (strcpy (buffer, getpass ("New password:")))) == 0) { | |
101 fprintf (stderr, "Password unchanged.\n"); | |
102 exit (1); | |
103 } | |
104 | |
105 flags = 0; | |
106 for (cp = buffer; c = *cp++;) | |
107 if (c >= 'a' && c <= 'z') | |
108 flags |= 2; | |
109 else | |
110 if (c >= 'A' && c <= 'Z') | |
111 flags |= 4; | |
112 else | |
113 if (c >= '0' && c <= '9') | |
114 flags |= 1; | |
115 else | |
116 flags |= 8; | |
117 | |
118 if ((flags >= 7 && i >= 4) | |
119 || ((flags == 2 || flags == 4) && i >= 6) | |
120 || ((flags == 3 || flags == 5 || flags == 6) && i >= 5)) | |
121 break; | |
122 } | |
123 | |
124 if (strcmp (buffer, getpass ("Retype new password:"))) { | |
125 fprintf (stderr, "Mismatch - password unchanged.\n"); | |
126 exit (1); | |
127 } | |
128 | |
129 (void) time (&salt); | |
130 salt ^= 9 * getpid (); | |
131 saltc[0] = salt & 077; | |
132 saltc[1] = (salt >> 6) & 077; | |
133 for (i = 0; i < 2; i++) { | |
134 c = saltc[i] + '.'; | |
135 if (c > '9') | |
136 c += 7; | |
137 if (c > 'Z') | |
138 c += 6; | |
139 saltc[i] = c; | |
140 } | |
141 cp = crypt (buffer, saltc); | |
142 | |
143 (void) signal (SIGHUP, SIG_IGN); | |
144 (void) signal (SIGINT, SIG_IGN); | |
145 (void) signal (SIGQUIT, SIG_IGN); | |
146 | |
147 (void) umask (0); | |
148 if ((fd = open (temp, O_WRONLY | O_CREAT | O_EXCL, 0644)) < 0) { | |
149 switch (errno) { | |
150 case EEXIST: | |
151 fprintf (stderr, "POP file busy - try again later.\n"); | |
152 break; | |
153 | |
154 default: | |
155 perror (temp); | |
156 break; | |
157 } | |
158 exit (1); | |
159 } | |
160 | |
161 #ifdef SIGTSTP | |
162 (void) signal (SIGTSTP, SIG_IGN); | |
163 #endif /* SIGTSTP */ | |
164 if ((fp = fdopen (fd, "w")) == NULL) { | |
165 fprintf (stderr, "fdopen loses.\n"); | |
166 (void) unlink (temp); | |
167 exit (1); | |
168 } | |
169 | |
170 (void) setbbent (SB_STAY | SB_FAST); | |
171 while (bb = getbbent ()) { | |
172 if (strcmp (bb -> bb_name, bp -> bb_name) == 0) | |
173 bb -> bb_passwd = cp; | |
174 fprintf (fp, "%s:", bb -> bb_name); | |
175 if (ap = bb -> bb_aka) | |
176 for (; *ap; ap++) | |
177 fprintf (fp, "%s%s", ap != bb -> bb_aka ? "," : "", *ap); | |
178 fprintf (fp, ":%s:%s:", tail (bb -> bb_file), bb -> bb_passwd); | |
179 if ((ap = bb -> bb_leader) != NULL | |
180 && (strcmp (*ap, POPUID) != 0 || ap[1] != NULL)) | |
181 for (; *ap; ap++) | |
182 fprintf (fp, "%s%s", ap != bb -> bb_leader ? "," : "", *ap); | |
183 fprintf (fp, ":%s:%s:%s:", | |
184 compar (bb -> bb_addr, bb -> bb_name), | |
185 compar (bb -> bb_request, POPUID), | |
186 bb -> bb_relay); | |
187 if (ap = bb -> bb_dist) | |
188 for (; *ap; ap++) | |
189 fprintf (fp, "%s%s", ap != bb -> bb_dist ? "," : "", *ap); | |
190 fprintf (fp, ":%o\n", bb -> bb_flags); | |
191 } | |
192 (void) endbbent (); | |
193 | |
194 if (rename (temp, POPDB) < 0) { | |
195 perror ("rename"); | |
196 (void) unlink (temp); | |
197 exit (1); | |
198 } | |
199 (void) fclose (fp); | |
200 | |
201 exit (0); | |
202 } | |
203 | |
204 /* */ | |
205 | |
206 char *tail (s) | |
207 char *s; | |
208 { | |
209 int i; | |
210 char *cp; | |
211 | |
212 if (strncmp (s, home, i = strlen (home)) == 0 | |
213 && *(cp = s + i) == '/' | |
214 && *++cp) | |
215 return cp; | |
216 | |
217 return s; | |
218 } |