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