]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/progs/ali.c
Removed unnecessary warning about missing semicolon.
[nmh] / docs / historical / mh-jun-1982 / progs / ali.c
1 #ifdef COMMENT
2 Proprietary Rand Corporation, 1981.
3 Further distribution of this software
4 subject to the terms of the Rand
5 license agreement.
6 #endif
7
8 #include "../mh.h"
9 #include <stdio.h>
10 #include <ctype.h>
11 #include <pwd.h>
12 #include <sys/types.h>
13
14 extern char *index();
15
16 #define EVERYONE 10
17
18 struct shome { /* Internal name/uid/home database */
19 struct shome *h_next;
20 char *h_name;
21 int h_uid;
22 int h_gid;
23 char *h_home;
24 } *homes, *home();
25
26 struct mailname {
27 struct mailname *m_next;
28 char *m_name;
29 } addrlist;
30
31 char *malloc();
32
33 extern char _sobuf[]; /* MLW standard out buffer */
34
35 main(argc, argv)
36 char **argv;
37 {
38 register int i, list = 0;
39 register struct mailname *lp;
40
41 invo_name = argv[0];
42 if(argc < 2) {
43 printf("Usage: ali [-l] name ...\n");
44 exit(1);
45 }
46 if(argc > 1 && strcmp(argv[1], "-l") == 0) {
47 list++;
48 argc--; argv++;
49 }
50 setbuf(stdout, _sobuf);
51 gethomes();
52 for(i = 1; i < argc; i++)
53 insert(argv[i]);
54 alias(); /* Map names if needed */
55 for(lp = addrlist.m_next; lp; lp = lp->m_next) {
56 if(home(lp->m_name)) {
57 if(list)
58 printf("%s\n", lp->m_name);
59 else {
60 printf("%s%s", lp->m_name, lp->m_next?", ":"");
61 if(stdout->_cnt < BUFSIZ - 65) {
62 printf("\n"); VOID fflush(stdout);
63 }
64 }
65 }
66 }
67 if(!list && stdout->_cnt && stdout->_cnt < BUFSIZ) {
68 printf("\n"); VOID fflush(stdout);
69 }
70 for(lp = addrlist.m_next; lp; lp = lp->m_next)
71 if(home(lp->m_name) == NULL)
72 fprintf(stderr, "Ali: Unknown User: %s.\n", lp->m_name);
73
74 }
75
76 insert(name)
77 char *name;
78 {
79 register struct mailname *mp;
80 char *getcpy();
81
82 /*** printf("insert(%s)\n", name); ***/
83
84 for(mp = &addrlist; mp->m_next; mp = mp->m_next)
85 if(uleq(name, mp->m_next->m_name))
86 return; /* Don't insert existing name! */
87 mp->m_next = (struct mailname *) malloc(sizeof *mp->m_next);
88 mp = mp->m_next;
89 mp->m_next = 0;
90 mp->m_name = getcpy(name);
91 }
92
93 gethomes()
94 {
95 register struct passwd *pw;
96 register struct shome *h, *ph;
97 struct passwd *getpwent();
98 char *strcpy();
99
100 ph = (struct shome *) &homes;
101 while((pw = getpwent()) != NULL) {
102 h = (struct shome *) malloc(sizeof *h);
103 h->h_next = NULL;
104 h->h_name = malloc((unsigned)strlen(pw->pw_name)+1);
105 strcpy(h->h_name, pw->pw_name);
106 h->h_uid = pw->pw_uid;
107 h->h_gid = pw->pw_gid;
108 h->h_home = malloc((unsigned)strlen(pw->pw_dir)+1);
109 strcpy(h->h_home, pw->pw_dir);
110 ph->h_next = h;
111 ph = h;
112 }
113 }
114
115 struct shome *
116 home(name)
117 register char *name;
118 {
119 register struct shome *h;
120
121 if (index(name, '@') ||
122 index(name, ' ') ||
123 index(name, '!'))
124 return (homes); /* WARNING! Depends on return value */
125 /* being indifferent! */
126
127 for(h = homes; h; h = h->h_next)
128 if(uleq(name, h->h_name))
129 return(h);
130 return(NULL);
131 }
132
133 aleq(string, aliasent)
134 register char *string, *aliasent;
135 {
136 register int c;
137
138 while(c = *string++)
139 if(*aliasent == '*')
140 return 1;
141 else if((c|040) != (*aliasent|040))
142 return(0);
143 else
144 aliasent++;
145 return(*aliasent == 0 | *aliasent == '*');
146 }
147
148
149 /* alias implementation below...
150 */
151
152
153
154 #define GROUP "/etc/group"
155 char *AliasFile = "/etc/MailAliases";
156
157 char *termptr;
158
159 char *
160 parse(ptr, buf)
161 register char *ptr;
162 char *buf;
163 {
164 register char *cp;
165
166 cp = buf;
167 while(isspace(*ptr) || *ptr == ',' || *ptr == ':')
168 ptr++;
169 while(isalnum(*ptr) || *ptr == '/' || *ptr == '-' ||
170 *ptr == '!' || *ptr == '@' || *ptr == ' ' ||
171 *ptr == '.' || *ptr == '*')
172 *cp++ = *ptr++;
173 if(cp == buf) {
174 switch(*ptr) {
175 case '<':
176 case '=':
177 *cp++ = *ptr++;
178 }
179 }
180 *cp = 0;
181 if(cp == buf)
182 return 0;
183 termptr = ptr;
184 return buf;
185 }
186
187 char *
188 advance()
189 {
190 return(termptr);
191 }
192
193 alias()
194 {
195 register char *cp, *pp;
196 register struct mailname *lp;
197 char line[256], pbuf[64];
198 FILE *a;
199
200 if((a = fopen(AliasFile, "r")) == NULL) {
201 fprintf(stderr, "Can't open alias file ");
202 perror(AliasFile);
203 done(1);
204 }
205 while(fgets(line, sizeof line, a)) {
206 if(line[0] == ';' || line[0] == '\n') /* Comment Line */
207 continue;
208 if((pp = parse(line, pbuf)) == NULL) {
209 oops: fprintf(stderr, "Bad alias file %s\n", AliasFile);
210 fprintf(stderr, "Line: %s", line);
211 done(1);
212 }
213 for(lp = &addrlist; lp->m_next; lp = lp->m_next) {
214 if(aleq(lp->m_next->m_name, pp)) {
215 remove(lp);
216 if(!(cp = advance()) ||
217 !(pp = parse(cp, pbuf)))
218 goto oops;
219 switch(*pp) {
220 case '<': /* From file */
221 cp = advance();
222 if((pp = parse(cp, pbuf)) == NULL)
223 goto oops;
224 addfile(pp);
225 break;
226 case '=': /* UNIX group */
227 cp = advance();
228 if((pp = parse(cp, pbuf)) == NULL)
229 goto oops;
230 addgroup(pp);
231 break;
232 case '*': /* ALL Users */
233 addall();
234 break;
235 default: /* Simple list */
236 for(;;) {
237 insert(pp);
238 if(!(cp = advance()) ||
239 !(pp = parse(cp, pbuf)))
240 break;
241 }
242 }
243 break;
244 }
245 }
246 }
247 }
248
249
250 addfile(file)
251 char *file;
252 {
253 register char *cp, *pp;
254 char line[128], pbuf[64];
255 FILE *f;
256
257 /*** printf("addfile(%s)\n", file); ***/
258 if((f = fopen(file, "r")) == NULL) {
259 fprintf(stderr, "Can't open ");
260 perror(file);
261 done(1);
262 }
263 while(fgets(line, sizeof line, f)) {
264 cp = line;
265 while(pp = parse(cp, pbuf)) {
266 insert(pp);
267 cp = advance();
268 }
269 }
270 VOID fclose(f);
271 }
272
273 addgroup(group)
274 char *group;
275 {
276 register char *cp, *pp;
277 int found = 0;
278 char line[128], pbuf[64], *rindex();
279 FILE *f;
280
281 /*** printf("addgroup(%s)\n", group); ***/
282 if((f = fopen(GROUP, "r")) == NULL) {
283 fprintf(stderr, "Can't open ");
284 perror(GROUP);
285 done(1);
286 }
287 while(fgets(line, sizeof line, f)) {
288 pp = parse(line, pbuf);
289 if(strcmp(pp, group) == 0) {
290 cp = rindex(line, ':');
291 while(pp = parse(cp, pbuf)) {
292 insert(pp);
293 cp = advance();
294 }
295 found++;
296 }
297 }
298 if(!found) {
299 fprintf(stderr, "Group: %s non-existent\n", group);
300 done(1);
301 }
302 VOID fclose(f);
303 }
304
305 addall()
306 {
307 register struct shome *h;
308
309 /*** printf("addall()\n"); ***/
310 for(h = homes; h; h = h->h_next)
311 if(h->h_uid >= EVERYONE)
312 insert(h->h_name);
313 }
314
315 remove(mp) /* Remove NEXT from argument node! */
316 register struct mailname *mp;
317 {
318 register struct mailname *rp;
319
320 rp = mp->m_next;
321 mp->m_next = rp->m_next;
322 cndfree((char *)rp->m_name);
323 cndfree((char *