]>
Commit | Line | Data |
---|---|---|
c441a31a | 1 | /* $Id$ |
7ac48069 | 2 | * |
3 | * This is the file lists.c for the Moira Client, which allows users | |
59ec8dae | 4 | * to quickly and easily maintain most parts of the Moira database. |
0a2c64cb | 5 | * It Contains: All list manipulation functions, except delete. |
5eaef520 | 6 | * |
0a2c64cb | 7 | * Created: 4/12/88 |
8 | * By: Chris D. Peterson | |
08345b74 | 9 | * |
7ac48069 | 10 | * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology. |
11 | * For copying and distribution information, please see the file | |
12 | * <mit-copyright.h>. | |
08345b74 | 13 | */ |
14 | ||
7ac48069 | 15 | #include <mit-copyright.h> |
8defc06b | 16 | #include <moira.h> |
17 | #include <moira_site.h> | |
0a2c64cb | 18 | #include "defs.h" |
19 | #include "f_defs.h" | |
08345b74 | 20 | #include "globals.h" |
08345b74 | 21 | |
7ac48069 | 22 | #include <stdio.h> |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | ||
26 | RCSID("$Header$"); | |
27 | ||
600b459e | 28 | struct mqelem *GetListInfo(int type, char *name1, char *name2); |
7ac48069 | 29 | char **AskListInfo(char **info, Bool name); |
30 | int AddList(int argc, char **argv); | |
17bbb3bc | 31 | void ListMembersByType(char *type, int tags); |
7ac48069 | 32 | int GetMemberInfo(char *action, char **ret_argv); |
33 | ||
08345b74 | 34 | #define LIST 0 |
35 | #define MEMBERS 1 | |
36 | #define GLOM 2 | |
075fe5bb | 37 | #define ACE_USE 3 |
08345b74 | 38 | |
85ca828a | 39 | #define DEFAULT_ACTIVE DEFAULT_YES |
40 | #define DEFAULT_PUBLIC DEFAULT_YES | |
41 | #define DEFAULT_HIDDEN DEFAULT_NO | |
42 | #define DEFAULT_MAILLIST DEFAULT_YES | |
43 | #define DEFAULT_GROUP DEFAULT_NO | |
44 | #define DEFAULT_GID UNIQUE_GID | |
075fe5bb | 45 | #define DEFAULT_ACE_TYPE "user" |
46 | #define DEFAULT_ACE_NAME (user) | |
85ca828a | 47 | #define DEFAULT_DESCRIPTION DEFAULT_COMMENT |
48 | ||
461c03b6 | 49 | /* globals only for this file. */ |
50 | ||
85ca828a | 51 | static char current_list[BUFSIZ]; |
461c03b6 | 52 | |
17bbb3bc | 53 | |
075fe5bb | 54 | /* Function Name: PrintListAce |
55 | * Description: This function prints the list ace information. | |
402461ad | 56 | * Arguments: info - an info structure. |
57 | * Returns: none. | |
58 | */ | |
59 | ||
5eaef520 | 60 | static void PrintListAce(char **info) |
402461ad | 61 | { |
5eaef520 | 62 | char buf[BUFSIZ]; |
402461ad | 63 | |
5eaef520 | 64 | sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]); |
65 | Put_message(buf); | |
402461ad | 66 | } |
67 | ||
08345b74 | 68 | /* Function Name: PrintListInfo |
69 | * Description: This function Prints out the List info in a coherent form. | |
70 | * Arguments: info - the List info. | |
71 | * Returns: none. | |
72 | */ | |
73 | ||
5eaef520 | 74 | static void PrintListInfo(char **info) |
08345b74 | 75 | { |
5eaef520 | 76 | char buf[BUFSIZ]; |
77 | ||
78 | Put_message(" "); | |
79 | sprintf(buf, "%20sList: %s", "", info[L_NAME]); | |
80 | Put_message(buf); | |
81 | sprintf(buf, "Description: %s", info[L_DESC]); | |
82 | Put_message(buf); | |
83 | if (atoi(info[L_MAILLIST])) | |
84 | Put_message("This list is a mailing list."); | |
85 | else | |
86 | Put_message("This list is NOT a mailing list."); | |
87 | if (atoi(info[L_GROUP])) | |
88 | { | |
89 | sprintf(buf, "This list is a Group and its ID number is %s", | |
90 | info[L_GID]); | |
91 | Put_message(buf); | |
08345b74 | 92 | } |
5eaef520 | 93 | else |
94 | Put_message("This list is NOT a Group."); | |
95 | ||
96 | if (!strcmp(info[L_ACE_TYPE], "NONE")) | |
97 | Put_message("This list has no Administrator, how strange?!"); | |
98 | else | |
99 | { | |
100 | sprintf(buf, "The Administrator of this list is the %s: %s", | |
101 | info[L_ACE_TYPE], info[L_ACE_NAME]); | |
102 | Put_message(buf); | |
08345b74 | 103 | } |
104 | ||
5eaef520 | 105 | sprintf(buf, "This list is: %s, %s, and %s", |
106 | atoi(info[L_ACTIVE]) ? "active" : "inactive", | |
107 | atoi(info[L_PUBLIC]) ? "public" : "private", | |
108 | atoi(info[L_HIDDEN]) ? "hidden" : "visible"); | |
109 | Put_message(buf); | |
110 | sprintf(buf, MOD_FORMAT, info[L_MODBY], info[L_MODTIME], info[L_MODWITH]); | |
111 | Put_message(buf); | |
08345b74 | 112 | } |
113 | ||
114 | /* Function Name: GetListInfo | |
115 | * Description: Stores all info about a group of lists in a queue. | |
116 | * Arguments: type - type of info to store. | |
117 | * name - name of the info. | |
118 | * Returns: the first element in the queue. | |
119 | */ | |
120 | ||
600b459e | 121 | struct mqelem *GetListInfo(int type, char *name1, char *name2) |
08345b74 | 122 | { |
5eaef520 | 123 | char *args[2]; |
600b459e | 124 | struct mqelem *elem = NULL; |
44d12d58 | 125 | int status; |
08345b74 | 126 | |
5eaef520 | 127 | switch (type) |
128 | { | |
08345b74 | 129 | case LIST: |
5eaef520 | 130 | args[0] = name1; |
7ac48069 | 131 | if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem))) |
5eaef520 | 132 | { |
133 | com_err(program_name, status, " in get_list_info"); | |
134 | return NULL; | |
08345b74 | 135 | } |
5eaef520 | 136 | break; |
08345b74 | 137 | case MEMBERS: |
5eaef520 | 138 | args[0] = name1; |
139 | if ((status = do_mr_query("get_members_of_list", 1, args, | |
7ac48069 | 140 | StoreInfo, &elem))) |
5eaef520 | 141 | { |
142 | com_err(program_name, status, " in get_members_of_list"); | |
143 | return NULL; | |
08345b74 | 144 | } |
5eaef520 | 145 | break; |
08345b74 | 146 | case GLOM: |
5eaef520 | 147 | args[0] = name1; |
148 | args[1] = name2; | |
149 | if ((status = do_mr_query("get_lists_of_member", 2, args, | |
7ac48069 | 150 | StoreInfo, &elem))) |
5eaef520 | 151 | { |
152 | com_err(program_name, status, " in get_list_of_members"); | |
153 | return NULL; | |
08345b74 | 154 | } |
5eaef520 | 155 | break; |
075fe5bb | 156 | case ACE_USE: |
5eaef520 | 157 | args[0] = name1; |
158 | args[1] = name2; | |
7ac48069 | 159 | if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &elem))) |
5eaef520 | 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 | { | |
7ac48069 | 191 | newname = strdup(info[L_NAME]); |
5eaef520 | 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 | { |
600b459e | 257 | struct mqelem *top, *list; |
08345b74 | 258 | |
5eaef520 | 259 | top = list = GetListInfo(LIST, argv[1], NULL); |
260 | while (list) | |
261 | { | |
7ac48069 | 262 | PrintListInfo(list->q_data); |
5eaef520 | 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; |
600b459e | 281 | struct mqelem *elem = NULL; |
5eaef520 | 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, | |
7ac48069 | 295 | StoreInfo, &elem) != MR_NO_MATCH) |
5eaef520 | 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, | |
7ac48069 | 313 | NULL, NULL)) != MR_SUCCESS) |
5eaef520 | 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 | { |
600b459e | 330 | struct mqelem *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 | { |
7ac48069 | 348 | info[L_NAME] = strdup(name); |
349 | info[L_ACTIVE] = strdup(DEFAULT_ACTIVE); | |
350 | info[L_PUBLIC] = strdup(DEFAULT_PUBLIC); | |
351 | info[L_HIDDEN] = strdup(DEFAULT_HIDDEN); | |
352 | info[L_MAILLIST] = strdup(DEFAULT_MAILLIST); | |
353 | info[L_GROUP] = strdup(DEFAULT_GROUP); | |
354 | info[L_GID] = strdup(DEFAULT_GID); | |
355 | info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE); | |
356 | info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME); | |
357 | info[L_DESC] = strdup(DEFAULT_DESCRIPTION); | |
5eaef520 | 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; | |
600b459e | 372 | struct mqelem *elem = NULL; |
5eaef520 | 373 | |
374 | if (!ValidName(argv[1])) | |
375 | return DM_NORMAL; | |
7ac48069 | 376 | status = do_mr_query("get_list_info", 1, argv + 1, NULL, NULL); |
5eaef520 | 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, | |
7ac48069 | 392 | StoreInfo, &elem) != MR_NO_MATCH) |
5eaef520 | 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); | |
f4169f25 | 401 | if (YesNoQuestion("Create a list with the same name", FALSE) != TRUE) |
5eaef520 | 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, |
7ac48069 | 412 | NULL, NULL)) != MR_SUCCESS) |
5eaef520 | 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 | ||
7ac48069 | 429 | int ListHelp(int argc, char **argv) |
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, | |
7ac48069 | 479 | NULL, NULL))) |
5eaef520 | 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); | |
7ac48069 | 495 | m->m_title = strdup(temp_buf); |
5eaef520 | 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". | |
17bbb3bc | 517 | * tags - whether or not to display tags |
08345b74 | 518 | * Returns: none. |
519 | * NOTE: if type is NULL, all lists members are listed. | |
520 | */ | |
521 | ||
17bbb3bc | 522 | void ListMembersByType(char *type, int tags) |
08345b74 | 523 | { |
5eaef520 | 524 | char temp_buf[BUFSIZ]; |
44d12d58 | 525 | int status; |
5eaef520 | 526 | char *args[10]; |
527 | ||
528 | args[0] = current_list; | |
529 | args[1] = NULL; | |
530 | ||
531 | found_some = FALSE; | |
17bbb3bc | 532 | if ((status = do_mr_query(tags ? "get_tagged_members_of_list" : |
533 | "get_members_of_list", CountArgs(args), | |
534 | args, PrintByType, type))) | |
7ac48069 | 535 | com_err(program_name, status, " in ListMembersByType"); |
5eaef520 | 536 | if (!found_some) |
537 | { | |
538 | if (!type) | |
539 | Put_message("List is empty (no members)."); | |
540 | else | |
541 | { | |
542 | sprintf(temp_buf, "No %s Members", type); | |
543 | Put_message(temp_buf); | |
08345b74 | 544 | } |
545 | } | |
546 | } | |
547 | ||
548 | /* Function Name: ListAllMembers | |
549 | * Description: lists all members of the current list. | |
5eaef520 | 550 | * Arguments: |
08345b74 | 551 | * Returns: DM_NORMAL |
552 | */ | |
553 | ||
7ac48069 | 554 | int ListAllMembers(int argc, char **argv) |
08345b74 | 555 | { |
17bbb3bc | 556 | ListMembersByType(NULL, 0); |
5eaef520 | 557 | return DM_NORMAL; |
08345b74 | 558 | } |
559 | ||
560 | /* Function Name: ListUserMembers | |
561 | * Description: This function lists all members of a list of type "USER". | |
562 | * Arguments: none | |
563 | * Returns: DM_NORMAL. | |
564 | */ | |
565 | ||
7ac48069 | 566 | int ListUserMembers(int argc, char **argv) |
08345b74 | 567 | { |
17bbb3bc | 568 | ListMembersByType("USER", 0); |
5eaef520 | 569 | return DM_NORMAL; |
08345b74 | 570 | } |
571 | ||
572 | /* Function Name: ListListMembers | |
573 | * Description: This function lists all members of a list of type "LIST". | |
574 | * Arguments: none | |
575 | * Returns: DM_NORMAL. | |
576 | */ | |
577 | ||
7ac48069 | 578 | int ListListMembers(int argc, char **argv) |
08345b74 | 579 | { |
17bbb3bc | 580 | ListMembersByType("LIST", 0); |
5eaef520 | 581 | return DM_NORMAL; |
08345b74 | 582 | } |
583 | ||
584 | /* Function Name: ListStringMembers | |
585 | * Description:This function lists all members of a list of type "STRING". | |
586 | * Arguments: none | |
587 | * Returns: DM_NORMAL. | |
588 | */ | |
589 | ||
7ac48069 | 590 | int ListStringMembers(int argc, char **argv) |
08345b74 | 591 | { |
17bbb3bc | 592 | ListMembersByType("STRING", 0); |
5eaef520 | 593 | return DM_NORMAL; |
08345b74 | 594 | } |
595 | ||
596 | /* Function Name: GetMemberInfo | |
597 | * Description: This function gets the information needed to | |
598 | * add or delete a user from a list. | |
599 | * Arguments: argc, argv - standard. | |
600 | * action - name of the action to be performed either | |
601 | * "add" or "delete". | |
602 | * ret_argc, ret_argv - the returned value of argc and argv. | |
603 | * Returns: SUB_ERROR or SUB_NORMAL. | |
604 | */ | |
605 | ||
5eaef520 | 606 | int GetMemberInfo(char *action, char **ret_argv) |
08345b74 | 607 | { |
5eaef520 | 608 | char temp_buf[BUFSIZ]; |
609 | ||
7ac48069 | 610 | ret_argv[LM_LIST] = strdup(current_list); |
5eaef520 | 611 | |
7ac48069 | 612 | ret_argv[LM_TYPE] = strdup("user"); |
5eaef520 | 613 | if (GetTypeFromUser("Type of member", "member", &ret_argv[LM_TYPE]) == |
614 | SUB_ERROR) | |
615 | return SUB_ERROR; | |
616 | ||
617 | sprintf(temp_buf, "Name of %s to %s", ret_argv[LM_TYPE], action); | |
7ac48069 | 618 | ret_argv[LM_MEMBER] = strdup(user); |
5eaef520 | 619 | if (GetValueFromUser(temp_buf, &ret_argv[LM_MEMBER]) == SUB_ERROR) |
620 | return SUB_ERROR; | |
621 | ret_argv[LM_END] = NULL; /* NULL terminate this list. */ | |
622 | ||
623 | if (strcasecmp(ret_argv[LM_TYPE], "string") && | |
624 | !ValidName(ret_argv[LM_MEMBER])) | |
625 | { | |
626 | FreeInfo(ret_argv); | |
627 | return SUB_ERROR; | |
402461ad | 628 | } |
5eaef520 | 629 | return SUB_NORMAL; |
08345b74 | 630 | } |
631 | ||
632 | /* Function Name: AddMember | |
633 | * Description: This function adds a member to a list. | |
634 | * Arguments: none. | |
635 | * Returns: DM_NORMAL. | |
636 | */ | |
637 | ||
7ac48069 | 638 | int AddMember(int argc, char **argv) |
08345b74 | 639 | { |
5eaef520 | 640 | char *args[10], temp_buf[BUFSIZ], *p; |
44d12d58 | 641 | int status; |
600b459e | 642 | struct mqelem *mailhubs, *elem; |
5eaef520 | 643 | |
644 | if (GetMemberInfo("add", args) == SUB_ERROR) | |
645 | return DM_NORMAL; | |
646 | ||
647 | if (!strcmp(args[LM_TYPE], "STRING")) | |
648 | { | |
649 | if ((p = strchr(args[LM_MEMBER], '@'))) | |
650 | { | |
7ac48069 | 651 | char *host = canonicalize_hostname(strdup(++p)); |
5eaef520 | 652 | mailhubs = GetTypeValues("mailhub"); |
653 | for (elem = mailhubs; elem; elem = elem->q_forw) | |
654 | { | |
655 | if (!strcasecmp(host, elem->q_data)) | |
656 | { | |
657 | free(host); | |
7ac48069 | 658 | host = strdup(args[LM_MEMBER]); |
5eaef520 | 659 | *(--p) = 0; |
660 | sprintf(temp_buf, "String \"%s\" should be USER or LIST " | |
661 | "\"%s\" because it is a local name.", host, | |
662 | args[LM_MEMBER]); | |
663 | Put_message(temp_buf); | |
664 | free(args[LM_TYPE]); | |
665 | free(host); | |
666 | return DM_NORMAL; | |
fc2df2d9 | 667 | } |
668 | } | |
5eaef520 | 669 | free(host); |
670 | } | |
671 | else if (!strchr(args[LM_MEMBER], '!')) | |
672 | { | |
673 | Put_message("Member which is not a foreign mail address " | |
674 | "should not be type STRING."); | |
675 | return DM_NORMAL; | |
fc2df2d9 | 676 | } |
677 | } | |
678 | ||
5eaef520 | 679 | if ((status = do_mr_query("add_member_to_list", CountArgs(args), args, |
7ac48069 | 680 | NULL, NULL)) != MR_SUCCESS) |
5eaef520 | 681 | { |
682 | if (status == MR_EXISTS) | |
683 | { | |
684 | sprintf(temp_buf, "The %s %s is already a member of LIST %s.", | |
685 | args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]); | |
686 | Put_message(temp_buf); | |
402461ad | 687 | } |
5eaef520 | 688 | else |
689 | com_err(program_name, status, " in AddMember"); | |
402461ad | 690 | } |
08345b74 | 691 | |
5eaef520 | 692 | FreeInfo(args); |
693 | return DM_NORMAL; | |
08345b74 | 694 | } |
695 | ||
696 | /* Function Name: DeleteMember | |
697 | * Description: This function deletes a member from a list. | |
698 | * Arguments: none. | |
699 | * Returns: DM_NORMAL | |
700 | */ | |
701 | ||
7ac48069 | 702 | int DeleteMember(int argc, char **argv) |
08345b74 | 703 | { |
5eaef520 | 704 | char *args[10]; |
44d12d58 | 705 | int status; |
5eaef520 | 706 | |
707 | if (GetMemberInfo("delete", args) == SUB_ERROR) | |
708 | return DM_NORMAL; | |
709 | ||
710 | if (Confirm("Are you sure you want to delete this member?")) | |
711 | { | |
712 | if ((status = do_mr_query("delete_member_from_list", CountArgs(args), | |
7ac48069 | 713 | args, NULL, NULL))) |
5eaef520 | 714 | com_err(program_name, status, " in DeleteMember"); |
715 | else | |
716 | Put_message("Deletion Completed."); | |
08345b74 | 717 | } |
5eaef520 | 718 | else |
719 | Put_message("Deletion has been Aborted."); | |
08345b74 | 720 | |
5eaef520 | 721 | FreeInfo(args); |
722 | return DM_NORMAL; | |
08345b74 | 723 | } |
724 | ||
17bbb3bc | 725 | /* Function Name: TagMember |
726 | * Description: Add a tag to a list member | |
727 | * Arguments: | |
728 | * Returns: DM_NORMAL | |
729 | */ | |
730 | ||
731 | int TagMember(int argc, char **argv) | |
732 | { | |
733 | char *args[10]; | |
734 | int status; | |
17bbb3bc | 735 | |
736 | if (GetMemberInfo("tag", args) == SUB_ERROR) | |
737 | return DM_NORMAL; | |
738 | ||
739 | args[LM_TAG] = strdup(""); | |
740 | if (GetValueFromUser("Tag" , &args[LM_TAG]) == SUB_ERROR) | |
741 | { | |
742 | Put_message("Aborted."); | |
743 | return DM_NORMAL; | |
744 | } | |
745 | args[LM_TAG_END] = NULL; /* NULL terminate this list. */ | |
746 | ||
747 | if ((status = do_mr_query("tag_member_of_list", CountArgs(args), | |
748 | args, NULL, NULL))) | |
749 | com_err(program_name, status, " in TagMember"); | |
750 | ||
751 | FreeInfo(args); | |
752 | return DM_NORMAL; | |
753 | } | |
754 | ||
755 | /* Function Name: ListAllMembers | |
756 | * Description: lists all members of the current list. | |
757 | * Arguments: | |
758 | * Returns: DM_NORMAL | |
759 | */ | |
760 | ||
761 | int ListMembersWithTags(int argc, char **argv) | |
762 | { | |
763 | ListMembersByType(NULL, 1); | |
764 | return DM_NORMAL; | |
765 | } | |
766 | ||
08345b74 | 767 | /* Function Name: InterRemoveItemFromLists |
768 | * Description: This function allows interactive removal of an item | |
769 | * (user, string, list) for all list that it is on. | |
770 | * Arguments: none. | |
771 | * Returns: DM_NORMAL. | |
402461ad | 772 | * NOTES: QueryLoop() does not work here because info does not have |
773 | * enough information in it to delete the member from the list. | |
08345b74 | 774 | */ |
775 | ||
7ac48069 | 776 | int InterRemoveItemFromLists(int argc, char **argv) |
08345b74 | 777 | { |
44d12d58 | 778 | int status; |
5eaef520 | 779 | char *type, *name, *args[10], buf[BUFSIZ]; |
600b459e | 780 | struct mqelem *top, *elem; |
5eaef520 | 781 | |
7ac48069 | 782 | type = strdup("USER"); |
5eaef520 | 783 | if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) |
784 | return DM_NORMAL; | |
785 | ||
786 | sprintf(buf, "Name of %s", type); | |
7ac48069 | 787 | name = strdup(user); |
5eaef520 | 788 | if (GetValueFromUser(buf, &name) == SUB_ERROR) |
789 | return DM_NORMAL; | |
790 | ||
791 | if (!ValidName(name)) | |
792 | return DM_NORMAL; | |
793 | ||
794 | top = elem = GetListInfo(GLOM, type, name); | |
795 | ||
796 | while (elem) | |
797 | { | |
798 | char line[BUFSIZ]; | |
7ac48069 | 799 | char **info = elem->q_data; |
5eaef520 | 800 | sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type, |
801 | name, info[GLOM_NAME]); | |
802 | switch (YesNoQuitQuestion(line, FALSE)) | |
803 | { | |
402461ad | 804 | case TRUE: |
5eaef520 | 805 | Put_message("deleting..."); |
806 | args[DM_LIST] = info[GLOM_NAME]; | |
807 | args[DM_TYPE] = type; | |
808 | args[DM_MEMBER] = name; | |
809 | if ((status = do_mr_query("delete_member_from_list", 3, args, | |
7ac48069 | 810 | NULL, NULL))) |
5eaef520 | 811 | { |
812 | /* should probabally check to delete list. */ | |
813 | com_err(program_name, status, " in delete_member"); | |
814 | } | |
815 | break; | |
402461ad | 816 | case FALSE: |
5eaef520 | 817 | break; |
402461ad | 818 | default: |
5eaef520 | 819 | Put_message("Aborting..."); |
820 | FreeQueue(top); | |
821 | return DM_NORMAL; | |
08345b74 | 822 | } |
5eaef520 | 823 | elem = elem->q_forw; |
08345b74 | 824 | } |
5eaef520 | 825 | FreeQueue(top); |
826 | return DM_NORMAL; | |
08345b74 | 827 | } |
828 | ||
829 | /*-*-* LIST MENU *-*-*/ | |
830 | ||
831 | /* Function Name: ListByMember | |
832 | * Description: This gets all lists that a given member is a member of. | |
461c03b6 | 833 | * Arguments: none. |
08345b74 | 834 | * Returns: DM_NORMAL. |
835 | */ | |
836 | ||
7ac48069 | 837 | int ListByMember(int argc, char **argv) |
08345b74 | 838 | { |
5eaef520 | 839 | char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info; |
840 | Bool maillist, group; | |
600b459e | 841 | struct mqelem *top, *elem; |
5eaef520 | 842 | |
7ac48069 | 843 | type = strdup("USER"); |
5eaef520 | 844 | if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) |
845 | return DM_NORMAL; | |
846 | ||
847 | sprintf(buf, "Name of %s", type); | |
7ac48069 | 848 | name = strdup(user); |
5eaef520 | 849 | if (GetValueFromUser(buf, &name) == SUB_ERROR) |
850 | return DM_NORMAL; | |
851 | ||
852 | /* What we really want is a recursive search */ | |
853 | sprintf(temp_buf, "R%s", type); | |
854 | free(type); | |
7ac48069 | 855 | type = strdup(temp_buf); |
5eaef520 | 856 | |
857 | if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?", | |
858 | TRUE)) == -1) | |
859 | return DM_NORMAL; | |
860 | if ((group = YesNoQuestion("Show Lists that are Groups (y/n) ?", | |
861 | TRUE)) == -1) | |
862 | return DM_NORMAL; | |
863 | ||
864 | elem = top = GetListInfo(GLOM, type, name); | |
865 | ||
866 | while (elem) | |
867 | { | |
7ac48069 | 868 | info = elem->q_data; |
5eaef520 | 869 | if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) || |
870 | (group == TRUE && !strcmp(info[GLOM_GROUP], "1"))) | |
871 | Put_message(info[GLOM_NAME]); | |
872 | elem = elem->q_forw; | |
08345b74 | 873 | } |
5eaef520 | 874 | FreeQueue(top); |
875 | return DM_NORMAL; | |
08345b74 | 876 | } |
877 | ||
878 | /* Function Name: ListByAdministrator | |
879 | * Description: This function prints all lists which a given user or | |
880 | * group administers. | |
461c03b6 | 881 | * Arguments: none. |
08345b74 | 882 | * Returns: DM_NORMAL. |
883 | */ | |
884 | ||
7ac48069 | 885 | int ListByAdministrator(int argc, char **argv) |
08345b74 | 886 | { |
5eaef520 | 887 | char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name; |
600b459e | 888 | struct mqelem *top; |
5eaef520 | 889 | |
7ac48069 | 890 | type = strdup("USER"); |
5eaef520 | 891 | if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) |
892 | return DM_NORMAL; | |
893 | ||
894 | sprintf(buf, "Name of %s", type); | |
7ac48069 | 895 | name = strdup(user); |
5eaef520 | 896 | if (GetValueFromUser(buf, &name) == SUB_ERROR) |
897 | return DM_NORMAL; | |
898 | ||
899 | switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE)) | |
900 | { | |
eb5eb5de | 901 | case TRUE: |
5eaef520 | 902 | sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */ |
903 | free(type); | |
7ac48069 | 904 | type = strdup(temp_buf); |
5eaef520 | 905 | break; |
eb5eb5de | 906 | case FALSE: |
5eaef520 | 907 | break; |
eb5eb5de | 908 | default: |
5eaef520 | 909 | return DM_NORMAL; |
08345b74 | 910 | } |
402461ad | 911 | |
5eaef520 | 912 | top = GetListInfo(ACE_USE, type, name); |
913 | Loop(top, PrintListAce); | |
914 | ||
915 | FreeQueue(top); | |
916 | return DM_NORMAL; | |
08345b74 | 917 | } |
918 | ||
08345b74 | 919 | /* Function Name: ListAllPublicMailLists |
920 | * Description: This function lists all public mailing lists. | |
921 | * Arguments: none | |
922 | * Returns: DM_NORMAL. | |
923 | */ | |
924 | ||
7ac48069 | 925 | int ListAllPublicMailLists(int argc, char **argv) |
08345b74 | 926 | { |
44d12d58 | 927 | int status; |
5eaef520 | 928 | static char *args[] = { |
929 | "TRUE", /* active */ | |
930 | "TRUE", /* public */ | |
931 | "FALSE", /* hidden */ | |
932 | "TRUE", /* maillist */ | |
933 | "DONTCARE", /* group. */ | |
934 | }; | |
935 | ||
936 | if (YesNoQuestion("This query will take a while. Do you wish to continue?", | |
937 | TRUE) == TRUE) | |
938 | { | |
7ac48069 | 939 | if ((status = do_mr_query("qualified_get_lists", 5, args, |
940 | Print, NULL)) != MR_SUCCESS) | |
5eaef520 | 941 | com_err(program_name, status, " in ListAllGroups"); |
942 | } | |
943 | ||
944 | return DM_NORMAL; | |
08345b74 | 945 | } |