]> andersk Git - moira.git/blame_incremental - clients/moira/lists.c
Command line printer manipulation client, and build goo.
[moira.git] / clients / moira / lists.c
... / ...
CommitLineData
1/* $Id$
2 *
3 * This is the file lists.c for the Moira Client, which allows users
4 * to quickly and easily maintain most parts of the Moira database.
5 * It Contains: All list manipulation functions, except delete.
6 *
7 * Created: 4/12/88
8 * By: Chris D. Peterson
9 *
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>.
13 */
14
15#include <mit-copyright.h>
16#include <moira.h>
17#include <mrclient.h>
18#include <moira_site.h>
19#include "defs.h"
20#include "f_defs.h"
21#include "globals.h"
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27RCSID("$Header$");
28
29struct mqelem *GetListInfo(int type, char *name1, char *name2);
30char **AskListInfo(char **info, Bool name);
31int AddList(int argc, char **argv);
32void ListMembersByType(char *type, int tags);
33int GetMemberInfo(char *action, char **ret_argv);
34
35#define LIST 0
36#define MEMBERS 1
37#define GLOM 2
38#define ACE_USE 3
39
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
54
55/* globals only for this file. */
56
57static char current_list[BUFSIZ];
58
59
60/* Function Name: PrintListAce
61 * Description: This function prints the list ace information.
62 * Arguments: info - an info structure.
63 * Returns: none.
64 */
65
66static void PrintListAce(char **info)
67{
68 char buf[BUFSIZ];
69
70 sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]);
71 Put_message(buf);
72}
73
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
80static void PrintListInfo(char **info)
81{
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 {
95 sprintf(buf, "This list is a Group%s and its ID number is %s",
96 atoi(info[L_NFSGROUP]) ? " and an NFS Group," : "",
97 info[L_GID]);
98 Put_message(buf);
99 }
100 else
101 Put_message("This list is NOT a Group.");
102
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
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);
117 }
118
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
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);
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
142struct mqelem *GetListInfo(int type, char *name1, char *name2)
143{
144 char *args[2];
145 struct mqelem *elem = NULL;
146 int status;
147
148 switch (type)
149 {
150 case LIST:
151 args[0] = name1;
152 if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem)))
153 {
154 com_err(program_name, status, " in get_list_info");
155 return NULL;
156 }
157 break;
158 case MEMBERS:
159 args[0] = name1;
160 if ((status = do_mr_query("get_members_of_list", 1, args,
161 StoreInfo, &elem)))
162 {
163 com_err(program_name, status, " in get_members_of_list");
164 return NULL;
165 }
166 break;
167 case GLOM:
168 args[0] = name1;
169 args[1] = name2;
170 if (!strcmp(name1, "MACHINE"))
171 args[1] = canonicalize_hostname(strdup(name2));
172 if ((status = do_mr_query("get_lists_of_member", 2, args,
173 StoreInfo, &elem)))
174 {
175 com_err(program_name, status, " in get_list_of_members");
176 return NULL;
177 }
178 break;
179 case ACE_USE:
180 args[0] = name1;
181 args[1] = name2;
182 if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &elem)))
183 {
184 com_err(program_name, status, " in get_ace_use");
185 return NULL;
186 }
187 break;
188 }
189 return QueueTop(elem);
190}
191
192/* Function Name: AskListInfo.
193 * Description: This function askes the user for information about a
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
201char **AskListInfo(char **info, Bool name)
202{
203 char temp_buf[BUFSIZ], *newname;
204 int status;
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 {
215 newname = strdup(info[L_NAME]);
216 if (GetValueFromUser("The new name for this list", &newname) ==
217 SUB_ERROR)
218 return NULL;
219 if (ValidName(newname))
220 break;
221 }
222 }
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 {
239 if (GetYesNoValueFromUser("Is this an NFS group", &info[L_NFSGROUP]) ==
240 SUB_ERROR)
241 return NULL;
242 if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) ==
243 SUB_ERROR)
244 return NULL;
245 }
246
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]);
256
257 /* Change default owner */
258 strcpy(info[L_ACE_TYPE], "LIST");
259 strcpy(info[L_ACE_NAME], "mailman");
260 }
261
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
282 if (!strcasecmp(info[L_ACE_TYPE], "kerberos"))
283 {
284 char *canon;
285
286 status = mrcl_validate_kerberos_member(info[L_ACE_NAME], &canon);
287 if (mrcl_get_message())
288 Put_message(mrcl_get_message());
289 if (status == MRCL_REJECT)
290 return NULL;
291 free(info[L_ACE_NAME]);
292 info[L_ACE_NAME] = canon;
293 }
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 }
306 else if (atoi(info[L_MAILMAN]))
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
316 if (!strcasecmp(info[L_MEMACE_TYPE], "kerberos"))
317 {
318 char *canon;
319
320 status = mrcl_validate_kerberos_member(info[L_MEMACE_NAME], &canon);
321 if (mrcl_get_message())
322 Put_message(mrcl_get_message());
323 if (status == MRCL_REJECT)
324 return NULL;
325 free(info[L_MEMACE_NAME]);
326 info[L_MEMACE_NAME] = canon;
327 }
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;
342}
343
344/* -------------- List functions. -------------- */
345
346/* Function Name: ShowListInfo.
347 * Description: shows info on a list.
348 * Arguments: argc, argv - name of list in argv[1].
349 * Returns: DM status code.
350 */
351
352int ShowListInfo(int argc, char **argv)
353{
354 struct mqelem *top, *list;
355
356 top = list = GetListInfo(LIST, argv[1], NULL);
357 while (list)
358 {
359 PrintListInfo(list->q_data);
360 list = list->q_forw;
361 }
362
363 FreeQueue(top);
364 return DM_NORMAL;
365}
366
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 */
373
374static void RealUpdateList(char **info, Bool junk)
375{
376 int stat;
377 char **args;
378 struct mqelem *elem = NULL;
379
380 if (!(args = AskListInfo(info, TRUE)))
381 {
382 Put_message("Aborted.");
383 return;
384 }
385
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,
392 StoreInfo, &elem) != MR_NO_MATCH)
393 {
394 char buf[256];
395
396 sprintf(buf, "\nA user by the name `%s' already exists in the database.",
397 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 }
407 }
408
409 if ((stat = do_mr_query("update_list", CountArgs(args), args,
410 NULL, NULL)) != MR_SUCCESS)
411 {
412 com_err(program_name, stat, " in UpdateList.");
413 Put_message("List ** NOT ** Updated.");
414 }
415 else
416 Put_message("List successfully updated.");
417}
418
419/* Function Name: UpdateList
420 * Description: updates the information on a list.
421 * Arguments: argc, argv - name of list in argv[1].
422 * Returns: DM Status code.
423 */
424
425int UpdateList(int argc, char **argv)
426{
427 struct mqelem *top;
428
429 top = GetListInfo(LIST, argv[1], (char *) NULL);
430 QueryLoop(top, NullPrint, RealUpdateList, "Update the list");
431
432 FreeQueue(top);
433 return DM_NORMAL;
434}
435
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
443static char **SetDefaults(char **info, char *name)
444{
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);
452 info[L_NFSGROUP] = strdup(DEFAULT_NFSGROUP);
453 info[L_MAILMAN] = strdup(DEFAULT_MAILMAN);
454 info[L_MAILMAN_SERVER] = strdup(DEFAULT_MAILMAN_SERVER);
455 info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE);
456 info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME);
457 info[L_MEMACE_TYPE] = strdup(DEFAULT_MEMACE_TYPE);
458 info[L_MEMACE_NAME] = strdup(DEFAULT_MEMACE_NAME);
459 info[L_DESC] = strdup(DEFAULT_DESCRIPTION);
460 info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL;
461 return info;
462}
463
464/* Function Name: AddList
465 * Description:
466 * Arguments: argc, argv - name of list in argv[1].
467 * Returns: SUB_ERROR if list not created.
468 */
469
470int AddList(int argc, char **argv)
471{
472 static char *info[MAX_ARGS_SIZE], **add_args;
473 int status, ret_code = SUB_NORMAL;
474 struct mqelem *elem = NULL;
475
476 if (!ValidName(argv[1]))
477 return DM_NORMAL;
478 status = do_mr_query("get_list_info", 1, argv + 1, NULL, NULL);
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;
486 }
487
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
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,
500 StoreInfo, &elem) != MR_NO_MATCH)
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);
509 if (YesNoQuestion("Create a list with the same name", FALSE) != TRUE)
510 return SUB_ERROR;
511 }
512
513 if (!(add_args = AskListInfo(SetDefaults(info, argv[1]), FALSE)))
514 {
515 Put_message("Aborted.");
516 return SUB_ERROR;
517 }
518
519 if ((status = do_mr_query("add_list", CountArgs(add_args), add_args,
520 NULL, NULL)) != MR_SUCCESS)
521 {
522 com_err(program_name, status, " in AddList.");
523 Put_message("List Not Created.");
524 ret_code = SUB_ERROR;
525 }
526
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
556 FreeInfo(info);
557 return ret_code;
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
566int ListHelp(int argc, char **argv)
567{
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);
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
595int ListmaintMemberMenuEntry(Menu *m, int argc, char **argv)
596{
597 char temp_buf[BUFSIZ];
598 char *list_name = argv[1];
599 int stat;
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;
612 }
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,
616 NULL, NULL)))
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);
632 m->m_title = strdup(temp_buf);
633 strcpy(current_list, list_name);
634 return DM_NORMAL;
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
641 * Returns: DM_NORMAL
642 */
643
644int ListmaintMemberMenuExit(Menu *m)
645{
646 free(m->m_title);
647 strcpy(current_list, "");
648 return DM_NORMAL;
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".
654 * tags - whether or not to display tags
655 * Returns: none.
656 * NOTE: if type is NULL, all lists members are listed.
657 */
658
659void ListMembersByType(char *type, int tags)
660{
661 char temp_buf[BUFSIZ];
662 int status;
663 char *args[10];
664
665 args[0] = current_list;
666 args[1] = NULL;
667
668 found_some = FALSE;
669 if ((status = do_mr_query(tags ? "get_tagged_members_of_list" :
670 "get_members_of_list", CountArgs(args),
671 args, PrintByType, type)))
672 com_err(program_name, status, " in ListMembersByType");
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);
681 }
682 }
683}
684
685/* Function Name: ListAllMembers
686 * Description: lists all members of the current list.
687 * Arguments:
688 * Returns: DM_NORMAL
689 */
690
691int ListAllMembers(int argc, char **argv)
692{
693 ListMembersByType(NULL, 0);
694 return DM_NORMAL;
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
703int ListUserMembers(int argc, char **argv)
704{
705 ListMembersByType("USER", 0);
706 return DM_NORMAL;
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
715int ListListMembers(int argc, char **argv)
716{
717 ListMembersByType("LIST", 0);
718 return DM_NORMAL;
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
727int ListStringMembers(int argc, char **argv)
728{
729 ListMembersByType("STRING", 0);
730 return DM_NORMAL;
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
743int GetMemberInfo(char *action, char **ret_argv)
744{
745 char temp_buf[BUFSIZ];
746
747 ret_argv[LM_LIST] = strdup(current_list);
748
749 ret_argv[LM_TYPE] = strdup("user");
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);
755 ret_argv[LM_MEMBER] = strdup(user);
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;
765 }
766 return SUB_NORMAL;
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
775int AddMember(int argc, char **argv)
776{
777 char *args[10], temp_buf[BUFSIZ], *p;
778 int status;
779 struct mqelem *mailhubs, *elem;
780
781 if (GetMemberInfo("add", args) == SUB_ERROR)
782 return DM_NORMAL;
783
784 if (!strcmp(args[LM_TYPE], "STRING"))
785 {
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;
791 }
792 else if (!strcmp(args[LM_TYPE], "KERBEROS"))
793 {
794 char *canon;
795
796 status = mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
797 if (mrcl_get_message())
798 Put_message(mrcl_get_message());
799 if (status == MRCL_REJECT)
800 return DM_NORMAL;
801 free(args[LM_MEMBER]);
802 args[LM_MEMBER] = canon;
803 }
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 }
811
812 if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
813 NULL, NULL)) != MR_SUCCESS)
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);
820 }
821 else
822 com_err(program_name, status, " in AddMember");
823 }
824
825 FreeInfo(args);
826 return DM_NORMAL;
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
835int DeleteMember(int argc, char **argv)
836{
837 char *args[10];
838 int status;
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),
846 args, NULL, NULL)))
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 }
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]);
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 }
875 }
876 if (status)
877 com_err(program_name, status, " in DeleteMember");
878 else
879 Put_message("Deletion Completed.");
880 }
881 else
882 Put_message("Deletion has been Aborted.");
883
884 FreeInfo(args);
885 return DM_NORMAL;
886}
887
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;
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
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.
935 * NOTES: QueryLoop() does not work here because info does not have
936 * enough information in it to delete the member from the list.
937 */
938
939int InterRemoveItemFromLists(int argc, char **argv)
940{
941 int status;
942 char *type, *name, *args[10], buf[BUFSIZ];
943 struct mqelem *top, *elem;
944
945 type = strdup("USER");
946 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
947 return DM_NORMAL;
948
949 sprintf(buf, "Name of %s", type);
950 name = strdup(user);
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];
962 char **info = elem->q_data;
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 {
967 case TRUE:
968 Put_message("deleting...");
969 args[DM_LIST] = info[GLOM_NAME];
970 args[DM_TYPE] = type;
971 args[DM_MEMBER] = name;
972 if (!strcmp("MACHINE", type))
973 args[DM_MEMBER] = canonicalize_hostname(strdup(name));
974 if ((status = do_mr_query("delete_member_from_list", 3, args,
975 NULL, NULL)))
976 {
977 /* should probabally check to delete list. */
978 com_err(program_name, status, " in delete_member");
979 }
980 break;
981 case FALSE:
982 break;
983 default:
984 Put_message("Aborting...");
985 FreeQueue(top);
986 return DM_NORMAL;
987 }
988 elem = elem->q_forw;
989 }
990 FreeQueue(top);
991 return DM_NORMAL;
992}
993
994/*-*-* LIST MENU *-*-*/
995
996/* Function Name: ListByMember
997 * Description: This gets all lists that a given member is a member of.
998 * Arguments: none.
999 * Returns: DM_NORMAL.
1000 */
1001
1002int ListByMember(int argc, char **argv)
1003{
1004 char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info;
1005 Bool maillist, group, neither;
1006 struct mqelem *top, *elem;
1007
1008 type = strdup("USER");
1009 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
1010 return DM_NORMAL;
1011
1012 sprintf(buf, "Name of %s", type);
1013 name = strdup(user);
1014 if (GetValueFromUser(buf, &name) == SUB_ERROR)
1015 return DM_NORMAL;
1016
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 }
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
1037 if ((neither = YesNoQuestion("Show Lists that are neither Maillists nor Groups (y/n) ?",
1038 TRUE)) == -1)
1039 return DM_NORMAL;
1040
1041 elem = top = GetListInfo(GLOM, type, name);
1042
1043 while (elem)
1044 {
1045 info = elem->q_data;
1046 if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) ||
1047 (group == TRUE && !strcmp(info[GLOM_GROUP], "1")))
1048 Put_message(info[GLOM_NAME]);
1049 if (neither == TRUE && !strcmp(info[GLOM_MAILLIST], "0") &&
1050 !strcmp(info[GLOM_GROUP], "0"))
1051 Put_message(info[GLOM_NAME]);
1052 elem = elem->q_forw;
1053 }
1054 FreeQueue(top);
1055 return DM_NORMAL;
1056}
1057
1058/* Function Name: ListByAdministrator
1059 * Description: This function prints all lists which a given user or
1060 * group administers.
1061 * Arguments: none.
1062 * Returns: DM_NORMAL.
1063 */
1064
1065int ListByAdministrator(int argc, char **argv)
1066{
1067 char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name;
1068 struct mqelem *top;
1069
1070 type = strdup("USER");
1071 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
1072 return DM_NORMAL;
1073
1074 sprintf(buf, "Name of %s", type);
1075 name = strdup(user);
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 {
1081 case TRUE:
1082 sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */
1083 free(type);
1084 type = strdup(temp_buf);
1085 break;
1086 case FALSE:
1087 break;
1088 default:
1089 return DM_NORMAL;
1090 }
1091
1092 top = GetListInfo(ACE_USE, type, name);
1093 Loop(top, PrintListAce);
1094
1095 FreeQueue(top);
1096 return DM_NORMAL;
1097}
1098
1099/* Function Name: ListAllPublicMailLists
1100 * Description: This function lists all public mailing lists.
1101 * Arguments: none
1102 * Returns: DM_NORMAL.
1103 */
1104
1105int ListAllPublicMailLists(int argc, char **argv)
1106{
1107 int status;
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 {
1119 if ((status = do_mr_query("qualified_get_lists", 5, args,
1120 Print, NULL)) != MR_SUCCESS)
1121 com_err(program_name, status, " in ListAllGroups");
1122 }
1123
1124 return DM_NORMAL;
1125}
This page took 0.050588 seconds and 6 git commands to generate.