]> andersk Git - moira.git/blame - clients/blanche/blanche.c
added copyright message
[moira.git] / clients / blanche / blanche.c
CommitLineData
2d7360ca 1/* $Header$
2 *
3 * Command line oriented SMS List tool.
4 *
5 * by Mark Rosenstein, September 1988.
6 *
7 * Copyright 1989 by the Massachusetts Institute of Technology.
8 */
9
10#include <mit-copyright.h>
11#include <stdio.h>
12#include <ctype.h>
13#include <sms.h>
14#include <sms_app.h>
15
16#ifndef LINT
17static char smslist_rcsid[] = "$Header$";
18#endif
19
20
21struct member {
22 int type;
23 char *name;
24};
25
26/* member types */
27#define M_ANY 0
28#define M_USER 1
29#define M_LIST 2
30#define M_STRING 3
31
32/* flags from command line */
33int infoflg, verbose, syncflg, memberflg, debugflg;
34
35/* various member lists */
36struct save_queue *addlist, *dellist, *memberlist, *synclist;
37
38char *listname, *whoami;
39
40extern char *index();
41extern int errno;
42
43int show_list_info(), show_list_count(), get_list_members(), scream();
44struct member *parse_member();
45
46
47
48main(argc, argv)
49int argc;
50char **argv;
51{
52 int status;
53 char **arg = argv;
54 char *membervec[3];
55 struct member *memberstruct;
56
57 /* clear all flags & lists */
58 infoflg = verbose = syncflg = memberflg = debugflg = 0;
59 listname = NULL;
60 addlist = sq_create();
61 dellist = sq_create();
62 memberlist = sq_create();
63 synclist = sq_create();
64 whoami = argv[0];
65
66 /* parse args, building addlist, dellist, & synclist */
67 while (++arg - argv < argc) {
68 if (**arg == '-')
69 switch((*arg)[1]) {
70 case 'm':
71 memberflg++;
72 break;
73 case 'D':
74 debugflg++;
75 break;
76 case 'i':
77 infoflg++;
78 break;
79 case 'v':
80 verbose++;
81 break;
82 case 'a':
83 if (arg - argv < argc - 1) {
84 ++arg;
85 if (memberstruct = parse_member(*arg))
86 sq_save_data(addlist, memberstruct);
87 } else
88 usage(argv);
89 break;
90 case 'd':
91 if (arg - argv < argc - 1) {
92 ++arg;
93 if (memberstruct = parse_member(*arg))
94 sq_save_data(dellist, memberstruct);
95 } else
96 usage(argv);
97 break;
98 case 'f':
99 if (arg - argv < argc - 1) {
100 FILE *in;
101 char buf[BUFSIZ];
102
103 syncflg++;
104 ++arg;
105 if (!strcmp(*arg, "-"))
106 in = stdin;
107 else {
108 in = fopen(*arg, "r");
109 if (!in) {
110 com_err(whoami, errno, " while opening %s for input",
111 *arg);
112 exit(2);
113 }
114 }
115 while (fgets(buf, BUFSIZ, in))
116 if (memberstruct = parse_member(buf))
117 sq_save_data(synclist, memberstruct);
118 if (!feof(in))
119 com_err(whoami, errno, " while reading from %s", *arg);
120 } else
121 usage(argv);
122 break;
123 default:
124 usage(argv);
125 }
126 else if (listname == NULL)
127 listname = *arg;
128 else
129 usage(argv);
130 }
131 if (listname == NULL)
132 usage(argv);
133
134 /* if no other options specified, turn on list members flag */
135 if (!(infoflg || syncflg ||
136 addlist->q_next != addlist || dellist->q_next != dellist))
137 memberflg++;
138
139 /* fire up SMS */
140 if (status = sms_connect()) {
141 com_err(whoami, status, " unable to connect to SMS");
142 exit(2);
143 }
144 if (status = sms_auth("blanche")) {
145 com_err(whoami, status, " unable to authenticate to SMS");
146 exit(2);
147 }
148
149 /* display list info if requested to */
150 if (infoflg) {
151 status = sms_query("get_list_info", 1, &listname, show_list_info,NULL);
152 if (status)
153 com_err(whoami, status, " while getting list information");
154 if (verbose && !memberflg) {
155 status = sms_query("count_members_of_list", 1, &listname,
156 show_list_count, NULL);
157 if (status)
158 com_err(whoami, status, " while getting list count");
159 }
160 }
161
162 /* if we're synchronizing to a file, we need to:
163 * get the current members of the list
164 * for each member of the sync file
165 * if they are on the list, remove them from the in-memory copy
166 * if they're not on the list, add them to add-list
167 * if anyone is left on the in-memory copy, put them on the delete-list
168 * lastly, reset memberlist so we can use it again later
169 */
170 if (syncflg) {
171 status = sms_query("get_members_of_list", 1, &listname,
172 get_list_members, memberlist);
173 if (status)
174 com_err(whoami, status, " while getting members of list");
175 while (sq_get_data(synclist, &memberstruct)) {
176 struct save_queue *q;
177 int removed = 0;
178
179 for (q = memberlist->q_next; q != memberlist; q = q->q_next) {
180 if (membermatch(q->q_data, memberstruct)) {
181 q->q_prev->q_next = q->q_next;
182 q->q_next->q_prev = q->q_prev;
183 removed++;
184 break;
185 }
186 }
187 if (!removed)
188 sq_save_data(addlist, memberstruct);
189 }
190 while (sq_get_data(memberlist, &memberstruct))
191 sq_save_data(dellist, memberstruct);
192 sq_destroy(memberlist);
193 memberlist = sq_create();
194 }
195
196 /* Process the add list */
197 while (sq_get_data(addlist, &memberstruct)) {
198 membervec[0] = listname;
199 membervec[2] = memberstruct->name;
200 switch (memberstruct->type) {
201 case M_ANY:
202 case M_USER:
203 membervec[1] = "USER";
204 status = sms_query("add_member_to_list", 3, membervec, scream, NULL);
205 if (status == SMS_SUCCESS)
206 break;
207 else if (status != SMS_USER || memberstruct->type != M_ANY) {
208 com_err(whoami, status, " while adding member %s to %s",
209 memberstruct->name, listname);
210 break;
211 }
212 case M_LIST:
213 membervec[1] = "LIST";
214 status = sms_query("add_member_to_list", 3, membervec,
215 scream, NULL);
216 if (status == SMS_SUCCESS)
217 break;
218 else if (status != SMS_LIST || memberstruct->type != M_ANY) {
219 com_err(whoami, status, " while adding member %s to %s",
220 memberstruct->name, listname);
221 break;
222 }
223 case M_STRING:
224 membervec[1] = "STRING";
225 status = sms_query("add_member_to_list", 3, membervec,
226 scream, NULL);
227 if (status != SMS_SUCCESS)
228 com_err(whoami, status, " while adding member %s to %s",
229 memberstruct->name, listname);
230 }
231 }
232
233 /* Process the delete list */
234 while (sq_get_data(dellist, &memberstruct)) {
235 membervec[0] = listname;
236 membervec[2] = memberstruct->name;
237 switch (memberstruct->type) {
238 case M_ANY:
239 case M_USER:
240 membervec[1] = "USER";
241 status = sms_query("delete_member_from_list", 3, membervec,
242 scream, NULL);
243 if (status == SMS_SUCCESS)
244 break;
245 else if ((status != SMS_USER && status != SMS_NO_MATCH) ||
246 memberstruct->type != M_ANY) {
247 com_err(whoami, status, " while deleteing member %s from %s",
248 memberstruct->name, listname);
249 break;
250 }
251 case M_LIST:
252 membervec[1] = "LIST";
253 status = sms_query("delete_member_from_list", 3, membervec,
254 scream, NULL);
255 if (status == SMS_SUCCESS)
256 break;
257 else if ((status != SMS_LIST && status != SMS_NO_MATCH) ||
258 memberstruct->type != M_ANY) {
259 com_err(whoami, status, " while deleteing member %s from %s",
260 memberstruct->name, listname);
261 break;
262 }
263 case M_STRING:
264 membervec[1] = "STRING";
265 status = sms_query("delete_member_from_list", 3, membervec,
266 scream, NULL);
267 if (status == SMS_STRING && memberstruct->type == M_ANY)
268 com_err(whoami, 0, "Unable to find member %s to delete from %s",
269 memberstruct->name, listname);
270 else if (status != SMS_SUCCESS)
271 com_err(whoami, status, " while deleteing member %s from %s",
272 memberstruct->name, listname);
273 }
274 }
275
276 /* Display the members of the list now, if requested */
277 if (memberflg) {
278 status = sms_query("get_members_of_list", 1, &listname,
279 get_list_members, memberlist);
280 if (status)
281 com_err(whoami, status, " while getting members of list");
282 while (sq_get_data(memberlist, &memberstruct)) {
283 if (verbose) {
284 char *s;
285 switch (memberstruct->type) {
286 case M_USER:
287 s = "USER";
288 break;
289 case M_LIST:
290 s = "LIST";
291 break;
292 case M_STRING:
293 s = "STRING";
294 break;
295 }
296 printf("%s: %s\n", s, memberstruct->name);
297 } else {
298 if (memberstruct->type == M_LIST)
299 printf("LIST:%s\n", memberstruct->name);
300 else if (memberstruct->type == M_STRING &&
301 !index(memberstruct->name, '@'))
302 printf("STRING:%s\n", memberstruct->name);
303 else
304 printf("%s\n", memberstruct->name);
305 }
306 }
307 }
308
309 /* We're done! */
310 sms_disconnect();
311 exit(0);
312}
313
314usage(argv)
315char **argv;
316{
317 printf("Usage: %s [-i] [-v] [-m] listname [-a member] [-d member] [-f file]\n",
318 argv[0]);
319 exit(1);
320}
321
322
323show_list_info(argc, argv, hint)
324int argc;
325char **argv;
326int hint;
327{
328 printf("List: %s\n", argv[0]);
329 printf("Description: %s\n", argv[9]);
330 printf("Flags: %s, %s, and %s\n",
331 atoi(argv[1]) ? "active" : "inactive",
332 atoi(argv[2]) ? "public" : "private",
333 atoi(argv[3]) ? "hidden" : "visible");
334 printf("%s is %sa maillist, and is %sa group", argv[0],
335 atoi(argv[4]) ? "" : "not ",
336 atoi(argv[5]) ? "" : "not ");
337 if (atoi(argv[5]))
338 printf(" with GID %d\n", atoi(argv[6]));
339 else
340 printf("\n");
341 printf("Owner: %s %s\n", argv[7], argv[8]);
342 printf("Last modified by %s with %s on %s\n", argv[11], argv[12], argv[10]);
343 return(SMS_CONT);
344}
345
346
347show_list_count(argc, argv, hint)
348int argc;
349char **argv;
350int hint;
351{
352 printf("Members: %s\n", argv[0]);
353}
354
355
356get_list_members(argc, argv, q)
357int argc;
358char **argv;
359struct save_queue *q;
360{
361 struct member *m;
362
363 m = (struct member *) malloc(sizeof(struct member));
364 switch (argv[0][0]) {
365 case 'U':
366 m->type = M_USER;
367 break;
368 case 'L':
369 m->type = M_LIST;
370 break;
371 case 'S':
372 m->type = M_STRING;
373 break;
374 }
375 m->name = strsave(argv[1]);
376 sq_save_data(q, m);
377 return(SMS_CONT);
378}
379
380
381scream()
382{
383 fprintf(stderr, "Programmer botch\n");
384 exit(3);
385}
386
387
388struct member *parse_member(s)
389register char *s;
390{
391 register struct member *m;
392 char *p;
393
394 while (*s && isspace(*s))
395 s++;
396 p = s;
397 while (*p && isprint(*p) && !isspace(*p) && *p != ';')
398 p++;
399 *p = 0;
400 if (p == s || strlen(s) == 0)
401 return(NULL);
402
403 if ((m = (struct member *) malloc(sizeof(struct member))) == NULL)
404 return(NULL);
405
406 if (p = index(s, ':')) {
407 *p = 0;
408 m->name = ++p;
409 if (!strcasecmp("user", s))
410 m->type = M_USER;
411 else if (!strcasecmp("list", s))
412 m->type = M_LIST;
413 else if (!strcasecmp("string", s))
414 m->type = M_STRING;
415 else {
416 m->type = M_STRING;
417 *(--p) = ':';
418 m->name = s;
419 }
420 m->name = strsave(m->name);
421 return(m);
422 }
423 m->name = strsave(s);
424 if (index(s, '@') || index(s, '!') || index(s, '%'))
425 m->type = M_STRING;
426 else
427 m->type = M_ANY;
428 return(m);
429}
430
431
432int membermatch(m1, m2)
433struct member *m1, *m2;
434{
435 if (strcmp(m1->name, m2->name))
436 return(0);
437 if (m1->type == M_ANY || m2->type == M_ANY)
438 return(1);
439 if (m1->type == m2->type)
440 return(1);
441 else
442 return(0);
443}
This page took 0.120424 seconds and 5 git commands to generate.