]>
Commit | Line | Data |
---|---|---|
402461ad | 1 | #if (!defined(lint) && !defined(SABER)) |
08345b74 | 2 | static char rcsid_module_c[] = "$Header$"; |
7798ebc3 | 3 | #endif |
08345b74 | 4 | |
59ec8dae | 5 | /* This is the file lists.c for the Moira Client, which allows users |
6 | * to quickly and easily maintain most parts of the Moira database. | |
0a2c64cb | 7 | * It Contains: All list manipulation functions, except delete. |
5eaef520 | 8 | * |
0a2c64cb | 9 | * Created: 4/12/88 |
10 | * By: Chris D. Peterson | |
08345b74 | 11 | * |
12 | * $Source$ | |
13 | * $Author$ | |
14 | * $Header$ | |
5eaef520 | 15 | * |
0a2c64cb | 16 | * Copyright 1988 by the Massachusetts Institute of Technology. |
08345b74 | 17 | * |
5eaef520 | 18 | * For further information on copyright and distribution |
08345b74 | 19 | * see the file mit-copyright.h |
20 | */ | |
21 | ||
22 | #include <stdio.h> | |
f071d8a7 | 23 | #include <string.h> |
8defc06b | 24 | #include <moira.h> |
25 | #include <moira_site.h> | |
08345b74 | 26 | #include <menu.h> |
27 | ||
28 | #include "mit-copyright.h" | |
0a2c64cb | 29 | #include "defs.h" |
30 | #include "f_defs.h" | |
08345b74 | 31 | #include "globals.h" |
08345b74 | 32 | |
33 | #define LIST 0 | |
34 | #define MEMBERS 1 | |
35 | #define GLOM 2 | |
075fe5bb | 36 | #define ACE_USE 3 |
08345b74 | 37 | |
85ca828a | 38 | #define DEFAULT_ACTIVE DEFAULT_YES |
39 | #define DEFAULT_PUBLIC DEFAULT_YES | |
40 | #define DEFAULT_HIDDEN DEFAULT_NO | |
41 | #define DEFAULT_MAILLIST DEFAULT_YES | |
42 | #define DEFAULT_GROUP DEFAULT_NO | |
43 | #define DEFAULT_GID UNIQUE_GID | |
075fe5bb | 44 | #define DEFAULT_ACE_TYPE "user" |
45 | #define DEFAULT_ACE_NAME (user) | |
85ca828a | 46 | #define DEFAULT_DESCRIPTION DEFAULT_COMMENT |
47 | ||
461c03b6 | 48 | /* globals only for this file. */ |
49 | ||
85ca828a | 50 | static char current_list[BUFSIZ]; |
461c03b6 | 51 | |
075fe5bb | 52 | /* Function Name: PrintListAce |
53 | * Description: This function prints the list ace information. | |
402461ad | 54 | * Arguments: info - an info structure. |
55 | * Returns: none. | |
56 | */ | |
57 | ||
5eaef520 | 58 | static void PrintListAce(char **info) |
402461ad | 59 | { |
5eaef520 | 60 | char buf[BUFSIZ]; |
402461ad | 61 | |
5eaef520 | 62 | sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]); |
63 | Put_message(buf); | |
402461ad | 64 | } |
65 | ||
08345b74 | 66 | /* Function Name: PrintListInfo |
67 | * Description: This function Prints out the List info in a coherent form. | |
68 | * Arguments: info - the List info. | |
69 | * Returns: none. | |
70 | */ | |
71 | ||
5eaef520 | 72 | static void PrintListInfo(char **info) |
08345b74 | 73 | { |
5eaef520 | 74 | char buf[BUFSIZ]; |
75 | ||
76 | Put_message(" "); | |
77 | sprintf(buf, "%20sList: %s", "", info[L_NAME]); | |
78 | Put_message(buf); | |
79 | sprintf(buf, "Description: %s", info[L_DESC]); | |
80 | Put_message(buf); | |
81 | if (atoi(info[L_MAILLIST])) | |
82 | Put_message("This list is a mailing list."); | |
83 | else | |
84 | Put_message("This list is NOT a mailing list."); | |
85 | if (atoi(info[L_GROUP])) | |
86 | { | |
87 | sprintf(buf, "This list is a Group and its ID number is %s", | |
88 | info[L_GID]); | |
89 | Put_message(buf); | |
08345b74 | 90 | } |
5eaef520 | 91 | else |
92 | Put_message("This list is NOT a Group."); | |
93 | ||
94 | if (!strcmp(info[L_ACE_TYPE], "NONE")) | |
95 | Put_message("This list has no Administrator, how strange?!"); | |
96 | else | |
97 | { | |
98 | sprintf(buf, "The Administrator of this list is the %s: %s", | |
99 | info[L_ACE_TYPE], info[L_ACE_NAME]); | |
100 | Put_message(buf); | |
08345b74 | 101 | } |
102 | ||
5eaef520 | 103 | sprintf(buf, "This list is: %s, %s, and %s", |
104 | atoi(info[L_ACTIVE]) ? "active" : "inactive", | |
105 | atoi(info[L_PUBLIC]) ? "public" : "private", | |
106 | atoi(info[L_HIDDEN]) ? "hidden" : "visible"); | |
107 | Put_message(buf); | |
108 | sprintf(buf, MOD_FORMAT, info[L_MODBY], info[L_MODTIME], info[L_MODWITH]); | |
109 | Put_message(buf); | |
08345b74 | 110 | } |
111 | ||
112 | /* Function Name: GetListInfo | |
113 | * Description: Stores all info about a group of lists in a queue. | |
114 | * Arguments: type - type of info to store. | |
115 | * name - name of the info. | |
116 | * Returns: the first element in the queue. | |
117 | */ | |
118 | ||
5eaef520 | 119 | struct qelem *GetListInfo(int type, char *name1, char *name2) |
08345b74 | 120 | { |
5eaef520 | 121 | char *args[2]; |
122 | struct qelem *elem = NULL; | |
44d12d58 | 123 | int status; |
08345b74 | 124 | |
5eaef520 | 125 | switch (type) |
126 | { | |
08345b74 | 127 | case LIST: |
5eaef520 | 128 | args[0] = name1; |
129 | if ((status = do_mr_query("get_list_info", 1, args, | |
130 | StoreInfo, (char *) &elem))) | |
131 | { | |
132 | com_err(program_name, status, " in get_list_info"); | |
133 | return NULL; | |
08345b74 | 134 | } |
5eaef520 | 135 | break; |
08345b74 | 136 | case MEMBERS: |
5eaef520 | 137 | args[0] = name1; |
138 | if ((status = do_mr_query("get_members_of_list", 1, args, | |
139 | StoreInfo, (char *) &elem))) | |
140 | { | |
141 | com_err(program_name, status, " in get_members_of_list"); | |
142 | return NULL; | |
08345b74 | 143 | } |
5eaef520 | 144 | break; |
08345b74 | 145 | case GLOM: |
5eaef520 | 146 | args[0] = name1; |
147 | args[1] = name2; | |
148 | if ((status = do_mr_query("get_lists_of_member", 2, args, | |
149 | StoreInfo, (char *) &elem))) | |
150 | { | |
151 | com_err(program_name, status, " in get_list_of_members"); | |
152 | return NULL; | |
08345b74 | 153 | } |
5eaef520 | 154 | break; |
075fe5bb | 155 | case ACE_USE: |
5eaef520 | 156 | args[0] = name1; |
157 | args[1] = name2; | |
158 | if ((status = do_mr_query("get_ace_use", 2, args, | |
159 | StoreInfo, (char *) &elem))) | |
160 | { | |
161 | com_err(program_name, status, " in get_ace_use"); | |
162 | return NULL; | |
08345b74 | 163 | } |
5eaef520 | 164 | break; |
08345b74 | 165 | } |
5eaef520 | 166 | return QueueTop(elem); |
167 | } | |
08345b74 | 168 | |
169 | /* Function Name: AskListInfo. | |
5eaef520 | 170 | * Description: This function askes the user for information about a |
08345b74 | 171 | * machine and saves it into a structure. |
172 | * Arguments: info - a pointer the the structure to put the | |
173 | * info into. | |
174 | * name - add a newname field? (T/F) | |
175 | * Returns: SUB_ERROR or SUB_NORMAL. | |
176 | */ | |
177 | ||
5eaef520 | 178 | char **AskListInfo(char **info, Bool name) |
08345b74 | 179 | { |
5eaef520 | 180 | char temp_buf[BUFSIZ], *newname; |
181 | ||
182 | Put_message(" "); | |
183 | sprintf(temp_buf, "Setting information of list %s.", info[L_NAME]); | |
184 | Put_message(temp_buf); | |
185 | Put_message(" "); | |
186 | ||
187 | if (name) | |
188 | { | |
189 | while (1) | |
190 | { | |
191 | newname = Strsave(info[L_NAME]); | |
192 | if (GetValueFromUser("The new name for this list", &newname) == | |
193 | SUB_ERROR) | |
194 | return NULL; | |
195 | if (ValidName(newname)) | |
196 | break; | |
5df6f171 | 197 | } |
08345b74 | 198 | } |
5eaef520 | 199 | if (GetYesNoValueFromUser("Is this an active list", &info[L_ACTIVE]) == |
200 | SUB_ERROR) | |
201 | return NULL; | |
202 | if (GetYesNoValueFromUser("Is this a public list", &info[L_PUBLIC]) == | |
203 | SUB_ERROR) | |
204 | return NULL; | |
205 | if (GetYesNoValueFromUser("Is this a hidden list", &info[L_HIDDEN]) == | |
206 | SUB_ERROR) | |
207 | return NULL; | |
208 | if (GetYesNoValueFromUser("Is this a maillist", &info[L_MAILLIST]) == | |
209 | SUB_ERROR) | |
210 | return NULL; | |
211 | if (GetYesNoValueFromUser("Is this a group", &info[L_GROUP]) == SUB_ERROR) | |
212 | return NULL; | |
213 | if (atoi(info[L_GROUP])) | |
214 | { | |
eb5eb5de | 215 | if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) == |
216 | SUB_ERROR) | |
5eaef520 | 217 | return NULL; |
20b2d2f0 | 218 | } |
08345b74 | 219 | |
5eaef520 | 220 | if (GetTypeFromUser("What Type of Administrator", "ace_type", |
221 | &info[L_ACE_TYPE]) == SUB_ERROR) | |
222 | return NULL; | |
223 | if (strcasecmp(info[L_ACE_TYPE], "NONE") && | |
224 | strcasecmp(info[L_ACE_TYPE], "none")) | |
225 | { | |
226 | sprintf(temp_buf, "Which %s will be the administrator of this list: ", | |
227 | info[L_ACE_TYPE]); | |
228 | if (GetValueFromUser(temp_buf, &info[L_ACE_NAME]) == SUB_ERROR) | |
229 | return NULL; | |
230 | } | |
231 | if (GetValueFromUser("Description: ", &info[L_DESC]) == SUB_ERROR) | |
232 | return NULL; | |
233 | ||
234 | FreeAndClear(&info[L_MODTIME], TRUE); | |
235 | FreeAndClear(&info[L_MODBY], TRUE); | |
236 | FreeAndClear(&info[L_MODWITH], TRUE); | |
237 | /* | |
238 | * Slide the newname into the #2 slot, this screws up all future references | |
239 | * to this list. | |
240 | */ | |
241 | if (name) /* slide the newname into the #2 slot. */ | |
242 | SlipInNewName(info, newname); | |
243 | ||
244 | return info; | |
08345b74 | 245 | } |
246 | ||
247 | /* -------------- List functions. -------------- */ | |
248 | ||
249 | /* Function Name: ShowListInfo. | |
250 | * Description: shows info on a list. | |
461c03b6 | 251 | * Arguments: argc, argv - name of list in argv[1]. |
08345b74 | 252 | * Returns: DM status code. |
253 | */ | |
254 | ||
5eaef520 | 255 | int ShowListInfo(int argc, char **argv) |
08345b74 | 256 | { |
5eaef520 | 257 | struct qelem *top, *list; |
08345b74 | 258 | |
5eaef520 | 259 | top = list = GetListInfo(LIST, argv[1], NULL); |
260 | while (list) | |
261 | { | |
262 | PrintListInfo((char **) list->q_data); | |
263 | list = list->q_forw; | |
08345b74 | 264 | } |
5eaef520 | 265 | |
266 | FreeQueue(top); | |
267 | return DM_NORMAL; | |
08345b74 | 268 | } |
269 | ||
402461ad | 270 | /* Function Name: RealUpdateList |
271 | * Description: performs the actual update of the list. | |
272 | * Arguments: info - all information needed to update the list. | |
273 | * junk - an UNUSED boolean. | |
274 | * Returns: none. | |
275 | */ | |
5eaef520 | 276 | |
277 | static void RealUpdateList(char **info, Bool junk) | |
402461ad | 278 | { |
44d12d58 | 279 | int stat; |
5eaef520 | 280 | char **args; |
281 | struct qelem *elem = NULL; | |
282 | ||
283 | if (!(args = AskListInfo(info, TRUE))) | |
284 | { | |
285 | Put_message("Aborted."); | |
286 | return; | |
eb5eb5de | 287 | } |
6825fe39 | 288 | |
5eaef520 | 289 | /* |
290 | * If the new list name is less than 8 characters, make sure it doesn't | |
291 | * collide with a username. | |
292 | */ | |
293 | if ((strlen(args[2]) <= 8) && | |
294 | do_mr_query("get_user_account_by_login", 1, args + 1, | |
295 | StoreInfo, (char *) &elem) != MR_NO_MATCH) | |
296 | { | |
297 | char buf[256]; | |
298 | ||
299 | sprintf(buf, "\nA user by the name `%s' already exists in the database.", | |
300 | args[1]); | |
301 | Put_message(buf); | |
302 | Loop(QueueTop(elem), FreeInfo); | |
303 | FreeQueue(elem); | |
304 | if (YesNoQuestion("Do you still want to rename this list to that name", | |
305 | FALSE) != TRUE) | |
306 | { | |
307 | Put_message("List ** NOT ** Updated."); | |
308 | return; | |
309 | } | |
6825fe39 | 310 | } |
5eaef520 | 311 | |
312 | if ((stat = do_mr_query("update_list", CountArgs(args), args, | |
313 | Scream, (char *) NULL)) != MR_SUCCESS) | |
314 | { | |
315 | com_err(program_name, stat, " in UpdateList."); | |
316 | Put_message("List ** NOT ** Updated."); | |
402461ad | 317 | } |
5eaef520 | 318 | else |
319 | Put_message("List successfully updated."); | |
402461ad | 320 | } |
321 | ||
08345b74 | 322 | /* Function Name: UpdateList |
85ca828a | 323 | * Description: updates the information on a list. |
08345b74 | 324 | * Arguments: argc, argv - name of list in argv[1]. |
325 | * Returns: DM Status code. | |
326 | */ | |
327 | ||
5eaef520 | 328 | int UpdateList(int argc, char **argv) |
08345b74 | 329 | { |
5eaef520 | 330 | struct qelem *top; |
402461ad | 331 | |
5eaef520 | 332 | top = GetListInfo(LIST, argv[1], (char *) NULL); |
333 | QueryLoop(top, NullPrint, RealUpdateList, "Update the list"); | |
08345b74 | 334 | |
5eaef520 | 335 | FreeQueue(top); |
336 | return DM_NORMAL; | |
08345b74 | 337 | } |
338 | ||
85ca828a | 339 | /* Function Name: SetDefaults |
340 | * Description: sets defaults for AddList function | |
341 | * Arguments: info - the array to add them to. | |
342 | * name - name of the program to add. | |
343 | * Returns: defaults - the default information. | |
344 | */ | |
345 | ||
5eaef520 | 346 | static char **SetDefaults(char **info, char *name) |
85ca828a | 347 | { |
5eaef520 | 348 | info[L_NAME] = Strsave(name); |
349 | info[L_ACTIVE] = Strsave(DEFAULT_ACTIVE); | |
350 | info[L_PUBLIC] = Strsave(DEFAULT_PUBLIC); | |
351 | info[L_HIDDEN] = Strsave(DEFAULT_HIDDEN); | |
352 | info[L_MAILLIST] = Strsave(DEFAULT_MAILLIST); | |
353 | info[L_GROUP] = Strsave(DEFAULT_GROUP); | |
354 | info[L_GID] = Strsave(DEFAULT_GID); | |
355 | info[L_ACE_TYPE] = Strsave(DEFAULT_ACE_TYPE); | |
356 | info[L_ACE_NAME] = Strsave(DEFAULT_ACE_NAME); | |
357 | info[L_DESC] = Strsave(DEFAULT_DESCRIPTION); | |
358 | info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL; | |
359 | return info; | |
85ca828a | 360 | } |
361 | ||
08345b74 | 362 | /* Function Name: AddList |
5eaef520 | 363 | * Description: |
08345b74 | 364 | * Arguments: argc, argv - name of list in argv[1]. |
402461ad | 365 | * Returns: SUB_ERROR if list not created. |
08345b74 | 366 | */ |
367 | ||
5eaef520 | 368 | int AddList(int argc, char **argv) |
08345b74 | 369 | { |
5eaef520 | 370 | static char *info[MAX_ARGS_SIZE], **add_args; |
371 | int status, ret_code = SUB_NORMAL; | |
372 | struct qelem *elem = NULL; | |
373 | ||
374 | if (!ValidName(argv[1])) | |
375 | return DM_NORMAL; | |
376 | status = do_mr_query("get_list_info", 1, argv + 1, NullFunc, NULL); | |
377 | if (status != MR_NO_MATCH) | |
378 | { | |
379 | if (status == MR_SUCCESS) | |
380 | Put_message("This list already exists."); | |
381 | else | |
382 | com_err(program_name, status, " in AddList."); | |
383 | return SUB_ERROR; | |
08345b74 | 384 | } |
385 | ||
5eaef520 | 386 | /* |
387 | * If the listname is less than 8 characters, make sure it doesn't | |
388 | * collide with a username. | |
389 | */ | |
390 | if ((strlen(argv[1]) <= 8) && | |
391 | do_mr_query("get_user_account_by_login", 1, argv + 1, | |
392 | StoreInfo, (char *) &elem) != MR_NO_MATCH) | |
393 | { | |
394 | char buf[256]; | |
395 | ||
396 | sprintf(buf, "\nA user by the name `%s' already exists in the database.", | |
397 | argv[1]); | |
398 | Put_message(buf); | |
399 | Loop(QueueTop(elem), FreeInfo); | |
400 | FreeQueue(elem); | |
401 | if (YesNoQuestion("Crate a list with the same name", FALSE) != TRUE) | |
402 | return SUB_ERROR; | |
dcc803de | 403 | } |
5eaef520 | 404 | |
405 | if (!(add_args = AskListInfo(SetDefaults(info, argv[1]), FALSE))) | |
406 | { | |
407 | Put_message("Aborted."); | |
408 | return SUB_ERROR; | |
eb5eb5de | 409 | } |
08345b74 | 410 | |
5eaef520 | 411 | if ((status = do_mr_query("add_list", CountArgs(add_args), add_args, |
412 | Scream, (char *) NULL)) != MR_SUCCESS) | |
413 | { | |
414 | com_err(program_name, status, " in AddList."); | |
415 | Put_message("List Not Created."); | |
416 | ret_code = SUB_ERROR; | |
08345b74 | 417 | } |
418 | ||
5eaef520 | 419 | FreeInfo(info); |
420 | return ret_code; | |
08345b74 | 421 | } |
422 | ||
423 | /* Function Name: Instructions | |
424 | * Description: This func prints out instruction on manipulating lists. | |
425 | * Arguments: none | |
426 | * Returns: DM Status Code. | |
427 | */ | |
428 | ||
5eaef520 | 429 | int ListHelp(void) |
08345b74 | 430 | { |
5eaef520 | 431 | static char *message[] = { |
432 | "Listmaint handles the creation, deletion, and updating of lists.", | |
433 | "A list can be a mailing list, a group list, or both.", | |
434 | "The concept behind lists is that a list has an owner", | |
435 | "- administrator - and members.", | |
436 | "The administrator of a list may be another list.", | |
437 | "The members of a list can be users (login names), other lists,", | |
438 | "or address strings.", | |
439 | "You can use certain keys to do the following:", | |
440 | " Refresh the screen - Type ctrl-L.", | |
441 | " Escape from a function - Type ctrl-C.", | |
442 | " Suspend the program (temporarily) - Type ctrl-Z.", | |
443 | NULL, | |
444 | }; | |
445 | ||
446 | return PrintHelp(message); | |
08345b74 | 447 | } |
448 | ||
449 | /*-*-* LISTMAINT UPDATE MENU *-*-*/ | |
450 | ||
451 | /* Function Name: ListmaintMemberMenuEntry | |
452 | * Description: entry routine into the listmaint member menu. | |
453 | * Arguments: m - the member menu. | |
454 | * argc, argv - name of the list in argv[1]. | |
455 | * Returns: none. | |
456 | */ | |
457 | ||
5eaef520 | 458 | int ListmaintMemberMenuEntry(Menu *m, int argc, char **argv) |
08345b74 | 459 | { |
5eaef520 | 460 | char temp_buf[BUFSIZ]; |
461 | char *list_name = argv[1]; | |
44d12d58 | 462 | int stat; |
5eaef520 | 463 | |
464 | if (!ValidName(list_name)) | |
465 | return DM_QUIT; | |
466 | ||
467 | if (*argv[0] == 'a') | |
468 | { /* add_list */ | |
469 | if (AddList(argc, argv) == SUB_ERROR) | |
470 | return DM_QUIT; | |
471 | sprintf(temp_buf, "List '%s' created. Do you want to %s", list_name, | |
472 | "change its membership (y/n)? "); | |
473 | if (YesNoQuestion(temp_buf, TRUE) != TRUE) | |
474 | return DM_QUIT; | |
08345b74 | 475 | } |
5eaef520 | 476 | else |
477 | /* All we want to know is if it exists. */ | |
478 | switch ((stat = do_mr_query("count_members_of_list", 1, argv + 1, | |
479 | NullFunc, NULL))) | |
480 | { | |
481 | case MR_SUCCESS: | |
482 | break; | |
483 | case MR_LIST: | |
484 | Put_message("This list does not exist."); | |
485 | return DM_QUIT; | |
486 | case MR_PERM: | |
487 | Put_message("You are not allowed to view this list."); | |
488 | break; | |
489 | default: | |
490 | com_err(program_name, stat, " in get_list_info"); | |
491 | return DM_QUIT; | |
492 | } | |
493 | ||
494 | sprintf(temp_buf, "Change/Display membership of '%s'", list_name); | |
495 | m->m_title = Strsave(temp_buf); | |
496 | strcpy(current_list, list_name); | |
497 | return DM_NORMAL; | |
08345b74 | 498 | } |
499 | ||
500 | /* Function Name: ListmaintMemberMenuExit | |
501 | * Description: This is the function called when the member menu is | |
502 | * exited, it frees the memory that is storing the name. | |
503 | * Arguments: m - the menu | |
5eaef520 | 504 | * Returns: DM_NORMAL |
08345b74 | 505 | */ |
506 | ||
5eaef520 | 507 | int ListmaintMemberMenuExit(Menu *m) |
08345b74 | 508 | { |
5eaef520 | 509 | free(m->m_title); |
510 | strcpy(current_list, ""); | |
511 | return DM_NORMAL; | |
08345b74 | 512 | } |
513 | ||
514 | /* Function Name: ListMembersByType | |
515 | * Description: This function lists the users of a list by type. | |
516 | * Arguments: type - the type of the list "USER", "LIST", or "STRING". | |
517 | * Returns: none. | |
518 | * NOTE: if type is NULL, all lists members are listed. | |
519 | */ | |
520 | ||
5eaef520 | 521 | int ListMembersByType(char *type) |
08345b74 | 522 | { |
5eaef520 | 523 | char temp_buf[BUFSIZ]; |
44d12d58 | 524 | int status; |
5eaef520 | 525 | char *args[10]; |
526 | ||
527 | args[0] = current_list; | |
528 | args[1] = NULL; | |
529 | ||
530 | found_some = FALSE; | |
531 | if ((status = do_mr_query("get_members_of_list", CountArgs(args), args, | |
532 | PrintByType, type))) | |
533 | { | |
534 | com_err(program_name, status, " in ListMembersByType"); | |
535 | return DM_NORMAL; | |
a42a06d7 | 536 | } |
5eaef520 | 537 | if (!found_some) |
538 | { | |
539 | if (!type) | |
540 | Put_message("List is empty (no members)."); | |
541 | else | |
542 | { | |
543 | sprintf(temp_buf, "No %s Members", type); | |
544 | Put_message(temp_buf); | |
08345b74 | 545 | } |
546 | } | |
547 | } | |
548 | ||
549 | /* Function Name: ListAllMembers | |
550 | * Description: lists all members of the current list. | |
5eaef520 | 551 | * Arguments: |
08345b74 | 552 | * Returns: DM_NORMAL |
553 | */ | |
554 | ||
5eaef520 | 555 | int ListAllMembers(void) |
08345b74 | 556 | { |
5eaef520 | 557 | ListMembersByType(NULL); |
558 | return DM_NORMAL; | |
08345b74 | 559 | } |
560 | ||
561 | /* Function Name: ListUserMembers | |
562 | * Description: This function lists all members of a list of type "USER". | |
563 | * Arguments: none | |
564 | * Returns: DM_NORMAL. | |
565 | */ | |
566 | ||
5eaef520 | 567 | int ListUserMembers(void) |
08345b74 | 568 | { |
5eaef520 | 569 | ListMembersByType("USER"); |
570 | return DM_NORMAL; | |
08345b74 | 571 | } |
572 | ||
573 | /* Function Name: ListListMembers | |
574 | * Description: This function lists all members of a list of type "LIST". | |
575 | * Arguments: none | |
576 | * Returns: DM_NORMAL. | |
577 | */ | |
578 | ||
5eaef520 | 579 | int ListListMembers(void) |
08345b74 | 580 | { |
5eaef520 | 581 | ListMembersByType("LIST"); |
582 | return DM_NORMAL; | |
08345b74 | 583 | } |
584 | ||
585 | /* Function Name: ListStringMembers | |
586 | * Description:This function lists all members of a list of type "STRING". | |
587 | * Arguments: none | |
588 | * Returns: DM_NORMAL. | |
589 | */ | |
590 | ||
5eaef520 | 591 | int ListStringMembers(void) |
08345b74 | 592 | { |
5eaef520 | 593 | ListMembersByType("STRING"); |
594 | return DM_NORMAL; | |
08345b74 | 595 | } |
596 | ||
597 | /* Function Name: GetMemberInfo | |
598 | * Description: This function gets the information needed to | |
599 | * add or delete a user from a list. | |
600 | * Arguments: argc, argv - standard. | |
601 | * action - name of the action to be performed either | |
602 | * "add" or "delete". | |
603 | * ret_argc, ret_argv - the returned value of argc and argv. | |
604 | * Returns: SUB_ERROR or SUB_NORMAL. | |
605 | */ | |
606 | ||
5eaef520 | 607 | int GetMemberInfo(char *action, char **ret_argv) |
08345b74 | 608 | { |
5eaef520 | 609 | char temp_buf[BUFSIZ]; |
610 | ||
611 | ret_argv[LM_LIST] = Strsave(current_list); | |
612 | ||
613 | ret_argv[LM_TYPE] = Strsave("user"); | |
614 | if (GetTypeFromUser("Type of member", "member", &ret_argv[LM_TYPE]) == | |
615 | SUB_ERROR) | |
616 | return SUB_ERROR; | |
617 | ||
618 | sprintf(temp_buf, "Name of %s to %s", ret_argv[LM_TYPE], action); | |
619 | ret_argv[LM_MEMBER] = Strsave(user); | |
620 | if (GetValueFromUser(temp_buf, &ret_argv[LM_MEMBER]) == SUB_ERROR) | |
621 | return SUB_ERROR; | |
622 | ret_argv[LM_END] = NULL; /* NULL terminate this list. */ | |
623 | ||
624 | if (strcasecmp(ret_argv[LM_TYPE], "string") && | |
625 | !ValidName(ret_argv[LM_MEMBER])) | |
626 | { | |
627 | FreeInfo(ret_argv); | |
628 | return SUB_ERROR; | |
402461ad | 629 | } |
5eaef520 | 630 | return SUB_NORMAL; |
08345b74 | 631 | } |
632 | ||
633 | /* Function Name: AddMember | |
634 | * Description: This function adds a member to a list. | |
635 | * Arguments: none. | |
636 | * Returns: DM_NORMAL. | |
637 | */ | |
638 | ||
5eaef520 | 639 | int AddMember(void) |
08345b74 | 640 | { |
5eaef520 | 641 | char *args[10], temp_buf[BUFSIZ], *p; |
44d12d58 | 642 | int status; |
5eaef520 | 643 | struct qelem *mailhubs, *elem, *GetTypeValues(); |
644 | ||
645 | if (GetMemberInfo("add", args) == SUB_ERROR) | |
646 | return DM_NORMAL; | |
647 | ||
648 | if (!strcmp(args[LM_TYPE], "STRING")) | |
649 | { | |
650 | if ((p = strchr(args[LM_MEMBER], '@'))) | |
651 | { | |
652 | char *host = canonicalize_hostname(strsave(++p)); | |
653 | mailhubs = GetTypeValues("mailhub"); | |
654 | for (elem = mailhubs; elem; elem = elem->q_forw) | |
655 | { | |
656 | if (!strcasecmp(host, elem->q_data)) | |
657 | { | |
658 | free(host); | |
659 | host = strsave(args[LM_MEMBER]); | |
660 | *(--p) = 0; | |
661 | sprintf(temp_buf, "String \"%s\" should be USER or LIST " | |
662 | "\"%s\" because it is a local name.", host, | |
663 | args[LM_MEMBER]); | |
664 | Put_message(temp_buf); | |
665 | free(args[LM_TYPE]); | |
666 | free(host); | |
667 | return DM_NORMAL; | |
fc2df2d9 | 668 | } |
669 | } | |
5eaef520 | 670 | free(host); |
671 | } | |
672 | else if (!strchr(args[LM_MEMBER], '!')) | |
673 | { | |
674 | Put_message("Member which is not a foreign mail address " | |
675 | "should not be type STRING."); | |
676 | return DM_NORMAL; | |
fc2df2d9 | 677 | } |
678 | } | |
679 | ||
5eaef520 | 680 | if ((status = do_mr_query("add_member_to_list", CountArgs(args), args, |
681 | Scream, NULL)) != MR_SUCCESS) | |
682 | { | |
683 | if (status == MR_EXISTS) | |
684 | { | |
685 | sprintf(temp_buf, "The %s %s is already a member of LIST %s.", | |
686 | args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]); | |
687 | Put_message(temp_buf); | |
402461ad | 688 | } |
5eaef520 | 689 | else |
690 | com_err(program_name, status, " in AddMember"); | |
402461ad | 691 | } |
08345b74 | 692 | |
5eaef520 | 693 | FreeInfo(args); |
694 | return DM_NORMAL; | |
08345b74 | 695 | } |
696 | ||
697 | /* Function Name: DeleteMember | |
698 | * Description: This function deletes a member from a list. | |
699 | * Arguments: none. | |
700 | * Returns: DM_NORMAL | |
701 | */ | |
702 | ||
5eaef520 | 703 | int DeleteMember(void) |
08345b74 | 704 | { |
5eaef520 | 705 | char *args[10]; |
44d12d58 | 706 | int status; |
5eaef520 | 707 | |
708 | if (GetMemberInfo("delete", args) == SUB_ERROR) | |
709 | return DM_NORMAL; | |
710 | ||
711 | if (Confirm("Are you sure you want to delete this member?")) | |
712 | { | |
713 | if ((status = do_mr_query("delete_member_from_list", CountArgs(args), | |
714 | args, Scream, NULL))) | |
715 | com_err(program_name, status, " in DeleteMember"); | |
716 | else | |
717 | Put_message("Deletion Completed."); | |
08345b74 | 718 | } |
5eaef520 | 719 | else |
720 | Put_message("Deletion has been Aborted."); | |
08345b74 | 721 | |
5eaef520 | 722 | FreeInfo(args); |
723 | return DM_NORMAL; | |
08345b74 | 724 | } |
725 | ||
08345b74 | 726 | /* Function Name: InterRemoveItemFromLists |
727 | * Description: This function allows interactive removal of an item | |
728 | * (user, string, list) for all list that it is on. | |
729 | * Arguments: none. | |
730 | * Returns: DM_NORMAL. | |
402461ad | 731 | * NOTES: QueryLoop() does not work here because info does not have |
732 | * enough information in it to delete the member from the list. | |
08345b74 | 733 | */ |
734 | ||
5eaef520 | 735 | int InterRemoveItemFromLists(void) |
08345b74 | 736 | { |
44d12d58 | 737 | int status; |
5eaef520 | 738 | char *type, *name, *args[10], buf[BUFSIZ]; |
739 | struct qelem *top, *elem; | |
740 | ||
741 | type = strsave("USER"); | |
742 | if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) | |
743 | return DM_NORMAL; | |
744 | ||
745 | sprintf(buf, "Name of %s", type); | |
746 | name = strsave(user); | |
747 | if (GetValueFromUser(buf, &name) == SUB_ERROR) | |
748 | return DM_NORMAL; | |
749 | ||
750 | if (!ValidName(name)) | |
751 | return DM_NORMAL; | |
752 | ||
753 | top = elem = GetListInfo(GLOM, type, name); | |
754 | ||
755 | while (elem) | |
756 | { | |
757 | char line[BUFSIZ]; | |
758 | char **info = (char **) elem->q_data; | |
759 | sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type, | |
760 | name, info[GLOM_NAME]); | |
761 | switch (YesNoQuitQuestion(line, FALSE)) | |
762 | { | |
402461ad | 763 | case TRUE: |
5eaef520 | 764 | Put_message("deleting..."); |
765 | args[DM_LIST] = info[GLOM_NAME]; | |
766 | args[DM_TYPE] = type; | |
767 | args[DM_MEMBER] = name; | |
768 | if ((status = do_mr_query("delete_member_from_list", 3, args, | |
769 | Scream, (char *) NULL))) | |
770 | { | |
771 | /* should probabally check to delete list. */ | |
772 | com_err(program_name, status, " in delete_member"); | |
773 | } | |
774 | break; | |
402461ad | 775 | case FALSE: |
5eaef520 | 776 | break; |
402461ad | 777 | default: |
5eaef520 | 778 | Put_message("Aborting..."); |
779 | FreeQueue(top); | |
780 | return DM_NORMAL; | |
08345b74 | 781 | } |
5eaef520 | 782 | elem = elem->q_forw; |
08345b74 | 783 | } |
5eaef520 | 784 | FreeQueue(top); |
785 | return DM_NORMAL; | |
08345b74 | 786 | } |
787 | ||
788 | /*-*-* LIST MENU *-*-*/ | |
789 | ||
790 | /* Function Name: ListByMember | |
791 | * Description: This gets all lists that a given member is a member of. | |
461c03b6 | 792 | * Arguments: none. |
08345b74 | 793 | * Returns: DM_NORMAL. |
794 | */ | |
795 | ||
5eaef520 | 796 | int ListByMember(void) |
08345b74 | 797 | { |
5eaef520 | 798 | char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info; |
799 | Bool maillist, group; | |
800 | struct qelem *top, *elem; | |
801 | ||
802 | type = strsave("USER"); | |
803 | if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) | |
804 | return DM_NORMAL; | |
805 | ||
806 | sprintf(buf, "Name of %s", type); | |
807 | name = strsave(user); | |
808 | if (GetValueFromUser(buf, &name) == SUB_ERROR) | |
809 | return DM_NORMAL; | |
810 | ||
811 | /* What we really want is a recursive search */ | |
812 | sprintf(temp_buf, "R%s", type); | |
813 | free(type); | |
814 | type = Strsave(temp_buf); | |
815 | ||
816 | if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?", | |
817 | TRUE)) == -1) | |
818 | return DM_NORMAL; | |
819 | if ((group = YesNoQuestion("Show Lists that are Groups (y/n) ?", | |
820 | TRUE)) == -1) | |
821 | return DM_NORMAL; | |
822 | ||
823 | elem = top = GetListInfo(GLOM, type, name); | |
824 | ||
825 | while (elem) | |
826 | { | |
827 | info = (char **) elem->q_data; | |
828 | if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) || | |
829 | (group == TRUE && !strcmp(info[GLOM_GROUP], "1"))) | |
830 | Put_message(info[GLOM_NAME]); | |
831 | elem = elem->q_forw; | |
08345b74 | 832 | } |
5eaef520 | 833 | FreeQueue(top); |
834 | return DM_NORMAL; | |
08345b74 | 835 | } |
836 | ||
837 | /* Function Name: ListByAdministrator | |
838 | * Description: This function prints all lists which a given user or | |
839 | * group administers. | |
461c03b6 | 840 | * Arguments: none. |
08345b74 | 841 | * Returns: DM_NORMAL. |
842 | */ | |
843 | ||
5eaef520 | 844 | int ListByAdministrator(void) |
08345b74 | 845 | { |
5eaef520 | 846 | char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name; |
847 | struct qelem *top; | |
848 | ||
849 | type = strsave("USER"); | |
850 | if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) | |
851 | return DM_NORMAL; | |
852 | ||
853 | sprintf(buf, "Name of %s", type); | |
854 | name = strsave(user); | |
855 | if (GetValueFromUser(buf, &name) == SUB_ERROR) | |
856 | return DM_NORMAL; | |
857 | ||
858 | switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE)) | |
859 | { | |
eb5eb5de | 860 | case TRUE: |
5eaef520 | 861 | sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */ |
862 | free(type); | |
863 | type = Strsave(temp_buf); | |
864 | break; | |
eb5eb5de | 865 | case FALSE: |
5eaef520 | 866 | break; |
eb5eb5de | 867 | default: |
5eaef520 | 868 | return DM_NORMAL; |
08345b74 | 869 | } |
402461ad | 870 | |
5eaef520 | 871 | top = GetListInfo(ACE_USE, type, name); |
872 | Loop(top, PrintListAce); | |
873 | ||
874 | FreeQueue(top); | |
875 | return DM_NORMAL; | |
08345b74 | 876 | } |
877 | ||
08345b74 | 878 | /* Function Name: ListAllPublicMailLists |
879 | * Description: This function lists all public mailing lists. | |
880 | * Arguments: none | |
881 | * Returns: DM_NORMAL. | |
882 | */ | |
883 | ||
5eaef520 | 884 | int ListAllPublicMailLists(void) |
08345b74 | 885 | { |
44d12d58 | 886 | int status; |
5eaef520 | 887 | static char *args[] = { |
888 | "TRUE", /* active */ | |
889 | "TRUE", /* public */ | |
890 | "FALSE", /* hidden */ | |
891 | "TRUE", /* maillist */ | |
892 | "DONTCARE", /* group. */ | |
893 | }; | |
894 | ||
895 | if (YesNoQuestion("This query will take a while. Do you wish to continue?", | |
896 | TRUE) == TRUE) | |
897 | { | |
898 | if (status = do_mr_query("qualified_get_lists", 5, args, | |
899 | Print, NULL) != MR_SUCCESS) | |
900 | com_err(program_name, status, " in ListAllGroups"); | |
901 | } | |
902 | ||
903 | return DM_NORMAL; | |
08345b74 | 904 | } |