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