]> andersk Git - moira.git/blame - clients/moira/lists.c
Don't free that; we're still using it.
[moira.git] / clients / moira / lists.c
CommitLineData
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>
375e818a 17#include <mrclient.h>
8defc06b 18#include <moira_site.h>
0a2c64cb 19#include "defs.h"
20#include "f_defs.h"
08345b74 21#include "globals.h"
08345b74 22
7ac48069 23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27RCSID("$Header$");
28
600b459e 29struct mqelem *GetListInfo(int type, char *name1, char *name2);
7ac48069 30char **AskListInfo(char **info, Bool name);
31int AddList(int argc, char **argv);
17bbb3bc 32void ListMembersByType(char *type, int tags);
7ac48069 33int GetMemberInfo(char *action, char **ret_argv);
34
08345b74 35#define LIST 0
36#define MEMBERS 1
37#define GLOM 2
075fe5bb 38#define ACE_USE 3
08345b74 39
e363e948 40#define DEFAULT_ACTIVE DEFAULT_YES
41#define DEFAULT_PUBLIC DEFAULT_YES
42#define DEFAULT_HIDDEN DEFAULT_NO
43#define DEFAULT_MAILLIST DEFAULT_YES
44#define DEFAULT_GROUP DEFAULT_NO
45#define DEFAULT_GID UNIQUE_GID
46#define DEFAULT_NFSGROUP DEFAULT_NO
47#define DEFAULT_MAILMAN DEFAULT_NO
48#define DEFAULT_MAILMAN_SERVER "[ANY]"
49#define DEFAULT_ACE_TYPE "user"
50#define DEFAULT_ACE_NAME (user)
51#define DEFAULT_MEMACE_TYPE "NONE"
52#define DEFAULT_MEMACE_NAME "NONE"
53#define DEFAULT_DESCRIPTION DEFAULT_COMMENT
85ca828a 54
461c03b6 55/* globals only for this file. */
56
85ca828a 57static char current_list[BUFSIZ];
461c03b6 58
17bbb3bc 59
075fe5bb 60/* Function Name: PrintListAce
61 * Description: This function prints the list ace information.
402461ad 62 * Arguments: info - an info structure.
63 * Returns: none.
64 */
65
5eaef520 66static void PrintListAce(char **info)
402461ad 67{
5eaef520 68 char buf[BUFSIZ];
402461ad 69
5eaef520 70 sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]);
71 Put_message(buf);
402461ad 72}
73
08345b74 74/* Function Name: PrintListInfo
75 * Description: This function Prints out the List info in a coherent form.
76 * Arguments: info - the List info.
77 * Returns: none.
78 */
79
5eaef520 80static void PrintListInfo(char **info)
08345b74 81{
5eaef520 82 char buf[BUFSIZ];
83
84 Put_message(" ");
85 sprintf(buf, "%20sList: %s", "", info[L_NAME]);
86 Put_message(buf);
87 sprintf(buf, "Description: %s", info[L_DESC]);
88 Put_message(buf);
89 if (atoi(info[L_MAILLIST]))
90 Put_message("This list is a mailing list.");
91 else
92 Put_message("This list is NOT a mailing list.");
93 if (atoi(info[L_GROUP]))
94 {
c55f98d2 95 sprintf(buf, "This list is a Group%s and its ID number is %s",
96 atoi(info[L_NFSGROUP]) ? " and an NFS Group," : "",
5eaef520 97 info[L_GID]);
98 Put_message(buf);
08345b74 99 }
5eaef520 100 else
101 Put_message("This list is NOT a Group.");
102
e363e948 103 if (atoi(info[L_MAILMAN]))
104 {
105 sprintf(buf, "This list is a Mailman list on server %s",
106 info[L_MAILMAN_SERVER]);
107 Put_message(buf);
108 }
109
5eaef520 110 if (!strcmp(info[L_ACE_TYPE], "NONE"))
111 Put_message("This list has no Administrator, how strange?!");
112 else
113 {
114 sprintf(buf, "The Administrator of this list is the %s: %s",
115 info[L_ACE_TYPE], info[L_ACE_NAME]);
116 Put_message(buf);
08345b74 117 }
118
c9bbc3e4 119 if (strcmp(info[L_MEMACE_TYPE], "NONE"))
120 {
121 sprintf(buf, "The Membership Administrator of this list is the %s: %s",
122 info[L_MEMACE_TYPE], info[L_MEMACE_NAME]);
123 Put_message(buf);
124 }
125
5eaef520 126 sprintf(buf, "This list is: %s, %s, and %s",
127 atoi(info[L_ACTIVE]) ? "active" : "inactive",
128 atoi(info[L_PUBLIC]) ? "public" : "private",
129 atoi(info[L_HIDDEN]) ? "hidden" : "visible");
130 Put_message(buf);
131 sprintf(buf, MOD_FORMAT, info[L_MODBY], info[L_MODTIME], info[L_MODWITH]);
132 Put_message(buf);
08345b74 133}
134
135/* Function Name: GetListInfo
136 * Description: Stores all info about a group of lists in a queue.
137 * Arguments: type - type of info to store.
138 * name - name of the info.
139 * Returns: the first element in the queue.
140 */
141
600b459e 142struct mqelem *GetListInfo(int type, char *name1, char *name2)
08345b74 143{
5eaef520 144 char *args[2];
600b459e 145 struct mqelem *elem = NULL;
44d12d58 146 int status;
08345b74 147
5eaef520 148 switch (type)
149 {
08345b74 150 case LIST:
5eaef520 151 args[0] = name1;
7ac48069 152 if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem)))
5eaef520 153 {
154 com_err(program_name, status, " in get_list_info");
155 return NULL;
08345b74 156 }
5eaef520 157 break;
08345b74 158 case MEMBERS:
5eaef520 159 args[0] = name1;
160 if ((status = do_mr_query("get_members_of_list", 1, args,
7ac48069 161 StoreInfo, &elem)))
5eaef520 162 {
163 com_err(program_name, status, " in get_members_of_list");
164 return NULL;
08345b74 165 }
5eaef520 166 break;
08345b74 167 case GLOM:
5eaef520 168 args[0] = name1;
169 args[1] = name2;
5f7b0741 170 if (!strcmp(name1, "MACHINE"))
171 args[1] = canonicalize_hostname(strdup(name2));
5eaef520 172 if ((status = do_mr_query("get_lists_of_member", 2, args,
7ac48069 173 StoreInfo, &elem)))
5eaef520 174 {
175 com_err(program_name, status, " in get_list_of_members");
176 return NULL;
08345b74 177 }
5eaef520 178 break;
075fe5bb 179 case ACE_USE:
5eaef520 180 args[0] = name1;
181 args[1] = name2;
7ac48069 182 if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &elem)))
5eaef520 183 {
184 com_err(program_name, status, " in get_ace_use");
185 return NULL;
08345b74 186 }
5eaef520 187 break;
08345b74 188 }
5eaef520 189 return QueueTop(elem);
190}
08345b74 191
192/* Function Name: AskListInfo.
5eaef520 193 * Description: This function askes the user for information about a
08345b74 194 * machine and saves it into a structure.
195 * Arguments: info - a pointer the the structure to put the
196 * info into.
197 * name - add a newname field? (T/F)
198 * Returns: SUB_ERROR or SUB_NORMAL.
199 */
200
5eaef520 201char **AskListInfo(char **info, Bool name)
08345b74 202{
5eaef520 203 char temp_buf[BUFSIZ], *newname;
138b81d7 204 int status;
5eaef520 205
206 Put_message(" ");
207 sprintf(temp_buf, "Setting information of list %s.", info[L_NAME]);
208 Put_message(temp_buf);
209 Put_message(" ");
210
211 if (name)
212 {
213 while (1)
214 {
7ac48069 215 newname = strdup(info[L_NAME]);
5eaef520 216 if (GetValueFromUser("The new name for this list", &newname) ==
217 SUB_ERROR)
218 return NULL;
219 if (ValidName(newname))
220 break;
5df6f171 221 }
08345b74 222 }
5eaef520 223 if (GetYesNoValueFromUser("Is this an active list", &info[L_ACTIVE]) ==
224 SUB_ERROR)
225 return NULL;
226 if (GetYesNoValueFromUser("Is this a public list", &info[L_PUBLIC]) ==
227 SUB_ERROR)
228 return NULL;
229 if (GetYesNoValueFromUser("Is this a hidden list", &info[L_HIDDEN]) ==
230 SUB_ERROR)
231 return NULL;
232 if (GetYesNoValueFromUser("Is this a maillist", &info[L_MAILLIST]) ==
233 SUB_ERROR)
234 return NULL;
235 if (GetYesNoValueFromUser("Is this a group", &info[L_GROUP]) == SUB_ERROR)
236 return NULL;
237 if (atoi(info[L_GROUP]))
238 {
c55f98d2 239 if (GetYesNoValueFromUser("Is this an NFS group", &info[L_NFSGROUP]) ==
240 SUB_ERROR)
241 return NULL;
eb5eb5de 242 if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) ==
243 SUB_ERROR)
5eaef520 244 return NULL;
20b2d2f0 245 }
08345b74 246
e363e948 247 if (GetYesNoValueFromUser("Is this a Mailman list", &info[L_MAILMAN]) ==
248 SUB_ERROR)
249 return NULL;
250 if (atoi(info[L_MAILMAN]))
251 {
252 if (GetValueFromUser("Mailman server", &info[L_MAILMAN_SERVER]) ==
253 SUB_ERROR)
254 return NULL;
255 info[L_MAILMAN_SERVER] = canonicalize_hostname(info[L_MAILMAN_SERVER]);
9f10c586 256
257 /* Change default owner */
258 strcpy(info[L_ACE_TYPE], "LIST");
259 strcpy(info[L_ACE_NAME], "mailman");
e363e948 260 }
261
66e5e450 262 do {
263 if (GetTypeFromUser("What Type of Administrator", "ace_type",
264 &info[L_ACE_TYPE]) == SUB_ERROR)
265 return NULL;
266 if (strcasecmp(info[L_ACE_TYPE], "none"))
267 {
268 sprintf(temp_buf, "Which %s will be the administrator of this list: ",
269 info[L_ACE_TYPE]);
270 if (GetValueFromUser(temp_buf, &info[L_ACE_NAME]) == SUB_ERROR)
271 return NULL;
272 }
273 else
274 {
275 Put_message("Setting the administrator of this list to 'NONE'");
276 Put_message("will make you unable to further modify the list.");
277 if (YesNoQuestion("Do you really want to do this?", FALSE) == TRUE)
278 break;
279 }
280 } while (!strcasecmp(info[L_ACE_TYPE], "none"));
281
5cef9ecf 282 if (!strcasecmp(info[L_ACE_TYPE], "kerberos"))
283 {
284 char *canon;
285
138b81d7 286 status = mrcl_validate_kerberos_member(info[L_ACE_NAME], &canon);
5cef9ecf 287 if (mrcl_get_message())
288 Put_message(mrcl_get_message());
138b81d7 289 if (status == MRCL_REJECT)
290 return NULL;
5cef9ecf 291 free(info[L_ACE_NAME]);
292 info[L_ACE_NAME] = canon;
293 }
9f10c586 294
295 do {
296 if (GetTypeFromUser("What Type of Membership Administrator", "ace_type",
297 &info[L_MEMACE_TYPE]) == SUB_ERROR)
298 return NULL;
299 if (strcasecmp(info[L_MEMACE_TYPE], "none"))
300 {
301 sprintf(temp_buf, "Which %s will be the membership administrator of this list: ",
302 info[L_MEMACE_TYPE]);
303 if (GetValueFromUser(temp_buf, &info[L_MEMACE_NAME]) == SUB_ERROR)
304 return NULL;
305 }
9a54adaa 306 else if (atoi(info[L_MAILMAN]))
9f10c586 307 {
308 Put_message("Setting the Membership Administrator of a Mailman list to 'NONE'");
309 Put_message("means no one will receive the list administrator password.");
310 if (YesNoQuestion("Do you really want to do this?", FALSE) == TRUE)
311 break;
312 }
313 } while ((!strcasecmp(info[L_MEMACE_TYPE], "none")) &&
314 atoi(info[L_MAILMAN]));
315
5cef9ecf 316 if (!strcasecmp(info[L_MEMACE_TYPE], "kerberos"))
317 {
318 char *canon;
c9bbc3e4 319
138b81d7 320 status = mrcl_validate_kerberos_member(info[L_MEMACE_NAME], &canon);
5cef9ecf 321 if (mrcl_get_message())
322 Put_message(mrcl_get_message());
138b81d7 323 if (status == MRCL_REJECT)
324 return NULL;
5cef9ecf 325 free(info[L_MEMACE_NAME]);
326 info[L_MEMACE_NAME] = canon;
327 }
5eaef520 328 if (GetValueFromUser("Description: ", &info[L_DESC]) == SUB_ERROR)
329 return NULL;
330
331 FreeAndClear(&info[L_MODTIME], TRUE);
332 FreeAndClear(&info[L_MODBY], TRUE);
333 FreeAndClear(&info[L_MODWITH], TRUE);
334 /*
335 * Slide the newname into the #2 slot, this screws up all future references
336 * to this list.
337 */
338 if (name) /* slide the newname into the #2 slot. */
339 SlipInNewName(info, newname);
340
341 return info;
08345b74 342}
343
344/* -------------- List functions. -------------- */
345
346/* Function Name: ShowListInfo.
347 * Description: shows info on a list.
461c03b6 348 * Arguments: argc, argv - name of list in argv[1].
08345b74 349 * Returns: DM status code.
350 */
351
5eaef520 352int ShowListInfo(int argc, char **argv)
08345b74 353{
600b459e 354 struct mqelem *top, *list;
08345b74 355
5eaef520 356 top = list = GetListInfo(LIST, argv[1], NULL);
357 while (list)
358 {
7ac48069 359 PrintListInfo(list->q_data);
5eaef520 360 list = list->q_forw;
08345b74 361 }
5eaef520 362
363 FreeQueue(top);
364 return DM_NORMAL;
08345b74 365}
366
402461ad 367/* Function Name: RealUpdateList
368 * Description: performs the actual update of the list.
369 * Arguments: info - all information needed to update the list.
370 * junk - an UNUSED boolean.
371 * Returns: none.
372 */
5eaef520 373
374static void RealUpdateList(char **info, Bool junk)
402461ad 375{
44d12d58 376 int stat;
5eaef520 377 char **args;
600b459e 378 struct mqelem *elem = NULL;
5eaef520 379
380 if (!(args = AskListInfo(info, TRUE)))
381 {
382 Put_message("Aborted.");
383 return;
eb5eb5de 384 }
6825fe39 385
5eaef520 386 /*
387 * If the new list name is less than 8 characters, make sure it doesn't
388 * collide with a username.
389 */
390 if ((strlen(args[2]) <= 8) &&
391 do_mr_query("get_user_account_by_login", 1, args + 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 args[1]);
398 Put_message(buf);
399 Loop(QueueTop(elem), FreeInfo);
400 FreeQueue(elem);
401 if (YesNoQuestion("Do you still want to rename this list to that name",
402 FALSE) != TRUE)
403 {
404 Put_message("List ** NOT ** Updated.");
405 return;
406 }
6825fe39 407 }
5eaef520 408
409 if ((stat = do_mr_query("update_list", CountArgs(args), args,
7ac48069 410 NULL, NULL)) != MR_SUCCESS)
5eaef520 411 {
412 com_err(program_name, stat, " in UpdateList.");
413 Put_message("List ** NOT ** Updated.");
402461ad 414 }
5eaef520 415 else
416 Put_message("List successfully updated.");
402461ad 417}
418
08345b74 419/* Function Name: UpdateList
85ca828a 420 * Description: updates the information on a list.
08345b74 421 * Arguments: argc, argv - name of list in argv[1].
422 * Returns: DM Status code.
423 */
424
5eaef520 425int UpdateList(int argc, char **argv)
08345b74 426{
600b459e 427 struct mqelem *top;
402461ad 428
5eaef520 429 top = GetListInfo(LIST, argv[1], (char *) NULL);
430 QueryLoop(top, NullPrint, RealUpdateList, "Update the list");
08345b74 431
5eaef520 432 FreeQueue(top);
433 return DM_NORMAL;
08345b74 434}
435
85ca828a 436/* Function Name: SetDefaults
437 * Description: sets defaults for AddList function
438 * Arguments: info - the array to add them to.
439 * name - name of the program to add.
440 * Returns: defaults - the default information.
441 */
442
5eaef520 443static char **SetDefaults(char **info, char *name)
85ca828a 444{
7ac48069 445 info[L_NAME] = strdup(name);
446 info[L_ACTIVE] = strdup(DEFAULT_ACTIVE);
447 info[L_PUBLIC] = strdup(DEFAULT_PUBLIC);
448 info[L_HIDDEN] = strdup(DEFAULT_HIDDEN);
449 info[L_MAILLIST] = strdup(DEFAULT_MAILLIST);
450 info[L_GROUP] = strdup(DEFAULT_GROUP);
451 info[L_GID] = strdup(DEFAULT_GID);
c55f98d2 452 info[L_NFSGROUP] = strdup(DEFAULT_NFSGROUP);
e363e948 453 info[L_MAILMAN] = strdup(DEFAULT_MAILMAN);
454 info[L_MAILMAN_SERVER] = strdup(DEFAULT_MAILMAN_SERVER);
7ac48069 455 info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE);
456 info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME);
c9bbc3e4 457 info[L_MEMACE_TYPE] = strdup(DEFAULT_MEMACE_TYPE);
458 info[L_MEMACE_NAME] = strdup(DEFAULT_MEMACE_NAME);
7ac48069 459 info[L_DESC] = strdup(DEFAULT_DESCRIPTION);
5eaef520 460 info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL;
461 return info;
85ca828a 462}
463
08345b74 464/* Function Name: AddList
5eaef520 465 * Description:
08345b74 466 * Arguments: argc, argv - name of list in argv[1].
402461ad 467 * Returns: SUB_ERROR if list not created.
08345b74 468 */
469
5eaef520 470int AddList(int argc, char **argv)
08345b74 471{
5eaef520 472 static char *info[MAX_ARGS_SIZE], **add_args;
473 int status, ret_code = SUB_NORMAL;
600b459e 474 struct mqelem *elem = NULL;
5eaef520 475
476 if (!ValidName(argv[1]))
477 return DM_NORMAL;
7ac48069 478 status = do_mr_query("get_list_info", 1, argv + 1, NULL, NULL);
5eaef520 479 if (status != MR_NO_MATCH)
480 {
481 if (status == MR_SUCCESS)
482 Put_message("This list already exists.");
483 else
484 com_err(program_name, status, " in AddList.");
485 return SUB_ERROR;
08345b74 486 }
487
094277d2 488 if (status = mr_access("add_list", L_MODTIME, SetDefaults(info, argv[1])))
489 {
490 com_err(program_name, status, " in AddList.");
491 return SUB_ERROR;
492 }
493
5eaef520 494 /*
495 * If the listname is less than 8 characters, make sure it doesn't
496 * collide with a username.
497 */
498 if ((strlen(argv[1]) <= 8) &&
499 do_mr_query("get_user_account_by_login", 1, argv + 1,
7ac48069 500 StoreInfo, &elem) != MR_NO_MATCH)
5eaef520 501 {
502 char buf[256];
503
504 sprintf(buf, "\nA user by the name `%s' already exists in the database.",
505 argv[1]);
506 Put_message(buf);
507 Loop(QueueTop(elem), FreeInfo);
508 FreeQueue(elem);
f4169f25 509 if (YesNoQuestion("Create a list with the same name", FALSE) != TRUE)
5eaef520 510 return SUB_ERROR;
dcc803de 511 }
5eaef520 512
513 if (!(add_args = AskListInfo(SetDefaults(info, argv[1]), FALSE)))
514 {
515 Put_message("Aborted.");
516 return SUB_ERROR;
eb5eb5de 517 }
08345b74 518
5eaef520 519 if ((status = do_mr_query("add_list", CountArgs(add_args), add_args,
7ac48069 520 NULL, NULL)) != MR_SUCCESS)
5eaef520 521 {
522 com_err(program_name, status, " in AddList.");
523 Put_message("List Not Created.");
524 ret_code = SUB_ERROR;
08345b74 525 }
526
9f10c586 527 if (atoi(add_args[L_MAILMAN]))
528 {
529 char mailman_address[256], buf[1024];
530
531 status = do_mr_query("get_list_info", 1, add_args, StoreInfo, &elem);
532 if (status)
533 com_err(program_name, status, "while retrieving list information.");
534 else
535 {
536 strcpy(mailman_address, add_args[0]);
537 strcat(mailman_address, "@");
538 strcat(mailman_address, ((char **)elem->q_data)[L_MAILMAN_SERVER]);
539 sprintf(buf, "Add STRING %s to LIST %s", mailman_address,
540 add_args[0]);
541 if (YesNoQuestion(buf, TRUE) == TRUE)
542 {
543 char *args[3];
544 args[0] = add_args[0];
545 args[1] = "STRING";
546 args[2] = mailman_address;
547
548 status = do_mr_query("add_member_to_list", CountArgs(args), args,
549 NULL, NULL);
550 if (status)
551 com_err(program_name, status, "while adding member to list.");
552 }
553 }
554 }
555
5eaef520 556 FreeInfo(info);
557 return ret_code;
08345b74 558}
559
560/* Function Name: Instructions
561 * Description: This func prints out instruction on manipulating lists.
562 * Arguments: none
563 * Returns: DM Status Code.
564 */
565
7ac48069 566int ListHelp(int argc, char **argv)
08345b74 567{
5eaef520 568 static char *message[] = {
569 "Listmaint handles the creation, deletion, and updating of lists.",
570 "A list can be a mailing list, a group list, or both.",
571 "The concept behind lists is that a list has an owner",
572 "- administrator - and members.",
573 "The administrator of a list may be another list.",
574 "The members of a list can be users (login names), other lists,",
575 "or address strings.",
576 "You can use certain keys to do the following:",
577 " Refresh the screen - Type ctrl-L.",
578 " Escape from a function - Type ctrl-C.",
579 " Suspend the program (temporarily) - Type ctrl-Z.",
580 NULL,
581 };
582
583 return PrintHelp(message);
08345b74 584}
585
586/*-*-* LISTMAINT UPDATE MENU *-*-*/
587
588/* Function Name: ListmaintMemberMenuEntry
589 * Description: entry routine into the listmaint member menu.
590 * Arguments: m - the member menu.
591 * argc, argv - name of the list in argv[1].
592 * Returns: none.
593 */
594
5eaef520 595int ListmaintMemberMenuEntry(Menu *m, int argc, char **argv)
08345b74 596{
5eaef520 597 char temp_buf[BUFSIZ];
598 char *list_name = argv[1];
44d12d58 599 int stat;
5eaef520 600
601 if (!ValidName(list_name))
602 return DM_QUIT;
603
604 if (*argv[0] == 'a')
605 { /* add_list */
606 if (AddList(argc, argv) == SUB_ERROR)
607 return DM_QUIT;
608 sprintf(temp_buf, "List '%s' created. Do you want to %s", list_name,
609 "change its membership (y/n)? ");
610 if (YesNoQuestion(temp_buf, TRUE) != TRUE)
611 return DM_QUIT;
08345b74 612 }
5eaef520 613 else
614 /* All we want to know is if it exists. */
615 switch ((stat = do_mr_query("count_members_of_list", 1, argv + 1,
7ac48069 616 NULL, NULL)))
5eaef520 617 {
618 case MR_SUCCESS:
619 break;
620 case MR_LIST:
621 Put_message("This list does not exist.");
622 return DM_QUIT;
623 case MR_PERM:
624 Put_message("You are not allowed to view this list.");
625 break;
626 default:
627 com_err(program_name, stat, " in get_list_info");
628 return DM_QUIT;
629 }
630
631 sprintf(temp_buf, "Change/Display membership of '%s'", list_name);
7ac48069 632 m->m_title = strdup(temp_buf);
5eaef520 633 strcpy(current_list, list_name);
634 return DM_NORMAL;
08345b74 635}
636
637/* Function Name: ListmaintMemberMenuExit
638 * Description: This is the function called when the member menu is
639 * exited, it frees the memory that is storing the name.
640 * Arguments: m - the menu
5eaef520 641 * Returns: DM_NORMAL
08345b74 642 */
643
5eaef520 644int ListmaintMemberMenuExit(Menu *m)
08345b74 645{
5eaef520 646 free(m->m_title);
647 strcpy(current_list, "");
648 return DM_NORMAL;
08345b74 649}
650
651/* Function Name: ListMembersByType
652 * Description: This function lists the users of a list by type.
653 * Arguments: type - the type of the list "USER", "LIST", or "STRING".
17bbb3bc 654 * tags - whether or not to display tags
08345b74 655 * Returns: none.
656 * NOTE: if type is NULL, all lists members are listed.
657 */
658
17bbb3bc 659void ListMembersByType(char *type, int tags)
08345b74 660{
5eaef520 661 char temp_buf[BUFSIZ];
44d12d58 662 int status;
5eaef520 663 char *args[10];
664
665 args[0] = current_list;
666 args[1] = NULL;
667
668 found_some = FALSE;
17bbb3bc 669 if ((status = do_mr_query(tags ? "get_tagged_members_of_list" :
670 "get_members_of_list", CountArgs(args),
671 args, PrintByType, type)))
7ac48069 672 com_err(program_name, status, " in ListMembersByType");
5eaef520 673 if (!found_some)
674 {
675 if (!type)
676 Put_message("List is empty (no members).");
677 else
678 {
679 sprintf(temp_buf, "No %s Members", type);
680 Put_message(temp_buf);
08345b74 681 }
682 }
683}
684
685/* Function Name: ListAllMembers
686 * Description: lists all members of the current list.
5eaef520 687 * Arguments:
08345b74 688 * Returns: DM_NORMAL
689 */
690
7ac48069 691int ListAllMembers(int argc, char **argv)
08345b74 692{
17bbb3bc 693 ListMembersByType(NULL, 0);
5eaef520 694 return DM_NORMAL;
08345b74 695}
696
697/* Function Name: ListUserMembers
698 * Description: This function lists all members of a list of type "USER".
699 * Arguments: none
700 * Returns: DM_NORMAL.
701 */
702
7ac48069 703int ListUserMembers(int argc, char **argv)
08345b74 704{
17bbb3bc 705 ListMembersByType("USER", 0);
5eaef520 706 return DM_NORMAL;
08345b74 707}
708
709/* Function Name: ListListMembers
710 * Description: This function lists all members of a list of type "LIST".
711 * Arguments: none
712 * Returns: DM_NORMAL.
713 */
714
7ac48069 715int ListListMembers(int argc, char **argv)
08345b74 716{
17bbb3bc 717 ListMembersByType("LIST", 0);
5eaef520 718 return DM_NORMAL;
08345b74 719}
720
721/* Function Name: ListStringMembers
722 * Description:This function lists all members of a list of type "STRING".
723 * Arguments: none
724 * Returns: DM_NORMAL.
725 */
726
7ac48069 727int ListStringMembers(int argc, char **argv)
08345b74 728{
17bbb3bc 729 ListMembersByType("STRING", 0);
5eaef520 730 return DM_NORMAL;
08345b74 731}
732
733/* Function Name: GetMemberInfo
734 * Description: This function gets the information needed to
735 * add or delete a user from a list.
736 * Arguments: argc, argv - standard.
737 * action - name of the action to be performed either
738 * "add" or "delete".
739 * ret_argc, ret_argv - the returned value of argc and argv.
740 * Returns: SUB_ERROR or SUB_NORMAL.
741 */
742
5eaef520 743int GetMemberInfo(char *action, char **ret_argv)
08345b74 744{
5eaef520 745 char temp_buf[BUFSIZ];
746
7ac48069 747 ret_argv[LM_LIST] = strdup(current_list);
5eaef520 748
7ac48069 749 ret_argv[LM_TYPE] = strdup("user");
5eaef520 750 if (GetTypeFromUser("Type of member", "member", &ret_argv[LM_TYPE]) ==
751 SUB_ERROR)
752 return SUB_ERROR;
753
754 sprintf(temp_buf, "Name of %s to %s", ret_argv[LM_TYPE], action);
7ac48069 755 ret_argv[LM_MEMBER] = strdup(user);
5eaef520 756 if (GetValueFromUser(temp_buf, &ret_argv[LM_MEMBER]) == SUB_ERROR)
757 return SUB_ERROR;
758 ret_argv[LM_END] = NULL; /* NULL terminate this list. */
759
760 if (strcasecmp(ret_argv[LM_TYPE], "string") &&
761 !ValidName(ret_argv[LM_MEMBER]))
762 {
763 FreeInfo(ret_argv);
764 return SUB_ERROR;
402461ad 765 }
5eaef520 766 return SUB_NORMAL;
08345b74 767}
768
769/* Function Name: AddMember
770 * Description: This function adds a member to a list.
771 * Arguments: none.
772 * Returns: DM_NORMAL.
773 */
774
7ac48069 775int AddMember(int argc, char **argv)
08345b74 776{
5eaef520 777 char *args[10], temp_buf[BUFSIZ], *p;
44d12d58 778 int status;
600b459e 779 struct mqelem *mailhubs, *elem;
5eaef520 780
781 if (GetMemberInfo("add", args) == SUB_ERROR)
782 return DM_NORMAL;
783
784 if (!strcmp(args[LM_TYPE], "STRING"))
785 {
12ca8430 786 status = mrcl_validate_string_member(args[LM_MEMBER]);
787 if (status != MRCL_SUCCESS)
788 Put_message(mrcl_get_message());
789 if (status == MRCL_REJECT)
790 return DM_NORMAL;
fc2df2d9 791 }
375e818a 792 else if (!strcmp(args[LM_TYPE], "KERBEROS"))
793 {
794 char *canon;
795
138b81d7 796 status = mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
375e818a 797 if (mrcl_get_message())
798 Put_message(mrcl_get_message());
138b81d7 799 if (status == MRCL_REJECT)
800 return DM_NORMAL;
375e818a 801 free(args[LM_MEMBER]);
802 args[LM_MEMBER] = canon;
803 }
5f7b0741 804 else if (!strcmp(args[LM_TYPE], "MACHINE"))
805 {
806 char *canon;
807 canon = canonicalize_hostname(strdup(args[LM_MEMBER]));
808 free(args[LM_MEMBER]);
809 args[LM_MEMBER] = canon;
810 }
fc2df2d9 811
5eaef520 812 if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
7ac48069 813 NULL, NULL)) != MR_SUCCESS)
5eaef520 814 {
815 if (status == MR_EXISTS)
816 {
817 sprintf(temp_buf, "The %s %s is already a member of LIST %s.",
818 args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]);
819 Put_message(temp_buf);
402461ad 820 }
5eaef520 821 else
822 com_err(program_name, status, " in AddMember");
402461ad 823 }
08345b74 824
5eaef520 825 FreeInfo(args);
826 return DM_NORMAL;
08345b74 827}
828
829/* Function Name: DeleteMember
830 * Description: This function deletes a member from a list.
831 * Arguments: none.
832 * Returns: DM_NORMAL
833 */
834
7ac48069 835int DeleteMember(int argc, char **argv)
08345b74 836{
5eaef520 837 char *args[10];
44d12d58 838 int status;
5eaef520 839
840 if (GetMemberInfo("delete", args) == SUB_ERROR)
841 return DM_NORMAL;
842
843 if (Confirm("Are you sure you want to delete this member?"))
844 {
845 if ((status = do_mr_query("delete_member_from_list", CountArgs(args),
7ac48069 846 args, NULL, NULL)))
375e818a 847 {
848 if ((status == MR_STRING || status == MR_NO_MATCH) &&
849 !strcmp(args[LM_TYPE], "KERBEROS"))
850 {
851 char *canon;
852 mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
853 if (mrcl_get_message())
854 {
855 free(args[LM_MEMBER]);
856 args[LM_MEMBER] = canon;
857 if (do_mr_query("delete_member_from_list", CountArgs(args),
858 args, NULL, NULL) == MR_SUCCESS)
859 {
860 Put_message(mrcl_get_message());
861 status = MR_SUCCESS;
862 }
863 }
864 }
5f7b0741 865 else if ((status == MR_MACHINE || status == MR_NO_MATCH) &&
866 !strcmp(args[LM_TYPE], "MACHINE"))
867 {
868 char *canon;
869 canon = canonicalize_hostname(args[LM_MEMBER]);
5f7b0741 870 args[LM_MEMBER] = canon;
871 if (do_mr_query("delete_member_from_list", CountArgs(args),
872 args, NULL, NULL) == MR_SUCCESS)
873 status = MR_SUCCESS;
874 }
375e818a 875 }
876 if (status)
5eaef520 877 com_err(program_name, status, " in DeleteMember");
878 else
879 Put_message("Deletion Completed.");
08345b74 880 }
5eaef520 881 else
882 Put_message("Deletion has been Aborted.");
08345b74 883
5eaef520 884 FreeInfo(args);
885 return DM_NORMAL;
08345b74 886}
887
17bbb3bc 888/* Function Name: TagMember
889 * Description: Add a tag to a list member
890 * Arguments:
891 * Returns: DM_NORMAL
892 */
893
894int TagMember(int argc, char **argv)
895{
896 char *args[10];
897 int status;
17bbb3bc 898
899 if (GetMemberInfo("tag", args) == SUB_ERROR)
900 return DM_NORMAL;
901
902 args[LM_TAG] = strdup("");
903 if (GetValueFromUser("Tag" , &args[LM_TAG]) == SUB_ERROR)
904 {
905 Put_message("Aborted.");
906 return DM_NORMAL;
907 }
908 args[LM_TAG_END] = NULL; /* NULL terminate this list. */
909
910 if ((status = do_mr_query("tag_member_of_list", CountArgs(args),
911 args, NULL, NULL)))
912 com_err(program_name, status, " in TagMember");
913
914 FreeInfo(args);
915 return DM_NORMAL;
916}
917
918/* Function Name: ListAllMembers
919 * Description: lists all members of the current list.
920 * Arguments:
921 * Returns: DM_NORMAL
922 */
923
924int ListMembersWithTags(int argc, char **argv)
925{
926 ListMembersByType(NULL, 1);
927 return DM_NORMAL;
928}
929
08345b74 930/* Function Name: InterRemoveItemFromLists
931 * Description: This function allows interactive removal of an item
932 * (user, string, list) for all list that it is on.
933 * Arguments: none.
934 * Returns: DM_NORMAL.
402461ad 935 * NOTES: QueryLoop() does not work here because info does not have
936 * enough information in it to delete the member from the list.
08345b74 937 */
938
7ac48069 939int InterRemoveItemFromLists(int argc, char **argv)
08345b74 940{
44d12d58 941 int status;
5eaef520 942 char *type, *name, *args[10], buf[BUFSIZ];
600b459e 943 struct mqelem *top, *elem;
5eaef520 944
7ac48069 945 type = strdup("USER");
5eaef520 946 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
947 return DM_NORMAL;
948
949 sprintf(buf, "Name of %s", type);
7ac48069 950 name = strdup(user);
5eaef520 951 if (GetValueFromUser(buf, &name) == SUB_ERROR)
952 return DM_NORMAL;
953
954 if (!ValidName(name))
955 return DM_NORMAL;
956
957 top = elem = GetListInfo(GLOM, type, name);
958
959 while (elem)
960 {
961 char line[BUFSIZ];
7ac48069 962 char **info = elem->q_data;
5eaef520 963 sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type,
964 name, info[GLOM_NAME]);
965 switch (YesNoQuitQuestion(line, FALSE))
966 {
402461ad 967 case TRUE:
5eaef520 968 Put_message("deleting...");
969 args[DM_LIST] = info[GLOM_NAME];
970 args[DM_TYPE] = type;
971 args[DM_MEMBER] = name;
5f7b0741 972 if (!strcmp("MACHINE", type))
973 args[DM_MEMBER] = canonicalize_hostname(strdup(name));
5eaef520 974 if ((status = do_mr_query("delete_member_from_list", 3, args,
7ac48069 975 NULL, NULL)))
5eaef520 976 {
977 /* should probabally check to delete list. */
978 com_err(program_name, status, " in delete_member");
979 }
980 break;
402461ad 981 case FALSE:
5eaef520 982 break;
402461ad 983 default:
5eaef520 984 Put_message("Aborting...");
985 FreeQueue(top);
986 return DM_NORMAL;
08345b74 987 }
5eaef520 988 elem = elem->q_forw;
08345b74 989 }
5eaef520 990 FreeQueue(top);
991 return DM_NORMAL;
08345b74 992}
993
994/*-*-* LIST MENU *-*-*/
995
996/* Function Name: ListByMember
997 * Description: This gets all lists that a given member is a member of.
461c03b6 998 * Arguments: none.
08345b74 999 * Returns: DM_NORMAL.
1000 */
1001
7ac48069 1002int ListByMember(int argc, char **argv)
08345b74 1003{
5eaef520 1004 char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info;
8647d909 1005 Bool maillist, group, neither;
600b459e 1006 struct mqelem *top, *elem;
5eaef520 1007
7ac48069 1008 type = strdup("USER");
5eaef520 1009 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
1010 return DM_NORMAL;
1011
1012 sprintf(buf, "Name of %s", type);
7ac48069 1013 name = strdup(user);
5eaef520 1014 if (GetValueFromUser(buf, &name) == SUB_ERROR)
1015 return DM_NORMAL;
1016
165ecbb0 1017 switch (YesNoQuestion("Do you want a recursive search (y/n)", TRUE))
1018 {
1019 case TRUE:
1020 sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */
1021 free(type);
1022 type = strdup(temp_buf);
1023 break;
1024 case FALSE:
1025 break;
1026 default:
1027 return DM_NORMAL;
1028 }
5eaef520 1029
1030 if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?",
1031 TRUE)) == -1)
1032 return DM_NORMAL;
1033 if ((group = YesNoQuestion("Show Lists that are Groups (y/n) ?",
1034 TRUE)) == -1)
1035 return DM_NORMAL;
1036
8647d909 1037 if ((neither = YesNoQuestion("Show Lists that are neither Maillists nor Groups (y/n) ?",
1038 TRUE)) == -1)
1039 return DM_NORMAL;
1040
5eaef520 1041 elem = top = GetListInfo(GLOM, type, name);
1042
1043 while (elem)
1044 {
7ac48069 1045 info = elem->q_data;
5eaef520 1046 if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) ||
1047 (group == TRUE && !strcmp(info[GLOM_GROUP], "1")))
1048 Put_message(info[GLOM_NAME]);
8647d909 1049 if (neither == TRUE && !strcmp(info[GLOM_MAILLIST], "0") &&
1050 !strcmp(info[GLOM_GROUP], "0"))
1051 Put_message(info[GLOM_NAME]);
5eaef520 1052 elem = elem->q_forw;
08345b74 1053 }
5eaef520 1054 FreeQueue(top);
1055 return DM_NORMAL;
08345b74 1056}
1057
1058/* Function Name: ListByAdministrator
1059 * Description: This function prints all lists which a given user or
1060 * group administers.
461c03b6 1061 * Arguments: none.
08345b74 1062 * Returns: DM_NORMAL.
1063 */
1064
7ac48069 1065int ListByAdministrator(int argc, char **argv)
08345b74 1066{
5eaef520 1067 char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name;
600b459e 1068 struct mqelem *top;
5eaef520 1069
7ac48069 1070 type = strdup("USER");
5eaef520 1071 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
1072 return DM_NORMAL;
1073
1074 sprintf(buf, "Name of %s", type);
7ac48069 1075 name = strdup(user);
5eaef520 1076 if (GetValueFromUser(buf, &name) == SUB_ERROR)
1077 return DM_NORMAL;
1078
1079 switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE))
1080 {
eb5eb5de 1081 case TRUE:
5eaef520 1082 sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */
1083 free(type);
7ac48069 1084 type = strdup(temp_buf);
5eaef520 1085 break;
eb5eb5de 1086 case FALSE:
5eaef520 1087 break;
eb5eb5de 1088 default:
5eaef520 1089 return DM_NORMAL;
08345b74 1090 }
402461ad 1091
5eaef520 1092 top = GetListInfo(ACE_USE, type, name);
1093 Loop(top, PrintListAce);
1094
1095 FreeQueue(top);
1096 return DM_NORMAL;
08345b74 1097}
1098
08345b74 1099/* Function Name: ListAllPublicMailLists
1100 * Description: This function lists all public mailing lists.
1101 * Arguments: none
1102 * Returns: DM_NORMAL.
1103 */
1104
7ac48069 1105int ListAllPublicMailLists(int argc, char **argv)
08345b74 1106{
44d12d58 1107 int status;
5eaef520 1108 static char *args[] = {
1109 "TRUE", /* active */
1110 "TRUE", /* public */
1111 "FALSE", /* hidden */
1112 "TRUE", /* maillist */
1113 "DONTCARE", /* group. */
1114 };
1115
1116 if (YesNoQuestion("This query will take a while. Do you wish to continue?",
1117 TRUE) == TRUE)
1118 {
7ac48069 1119 if ((status = do_mr_query("qualified_get_lists", 5, args,
1120 Print, NULL)) != MR_SUCCESS)
5eaef520 1121 com_err(program_name, status, " in ListAllGroups");
1122 }
1123
1124 return DM_NORMAL;
08345b74 1125}
This page took 0.286602 seconds and 5 git commands to generate.