6 /* (c) Copyright 1988 by the Massachusetts Institute of Technology. */
7 /* For copying and distribution information, please see the file */
8 /* <mit-copyright.h>. */
11 static char rcsid_mailmaint_c[] = "$Header$";
14 /***********************************************************************/
15 /* mailmaint.c - pjlevine - 20 August 1987
18 /***********************************************************************/
24 #include <sys/types.h>
29 #include <moira_site.h>
30 #include <mit-copyright.h>
39 #define CTL(ch) ((ch) & 037)
40 #define MAX(A,B) ((A) > (B) ? (A) : (B))
42 char *whoami; /* should not be static, for logging package */
45 extern char *strsave();
47 void menu_err_hook(const char *who, long code, const char *fmt, va_list args);
53 typedef struct list_info {
67 static char *ascbuff = {"0123456789"};
68 static int print_2(), print_1();
69 static List_info *current_li = (List_info *) NULL;
70 static int get_list_info();
71 static int fetch_list_info();
76 extern char *strsave();
82 typedef struct _menu {
88 MENU *main_menu, *help_menu;
90 int position[2], oldpos[2];
91 int level, found_some, currow, page, num_members;
92 int moreflg, toggle, first_time;
96 /****************************************************/
104 void (*old_hook)(const char *, long, const char *, va_list);
109 char buf[BUFSIZ], *motd;
111 if ((whoami = rindex(argv[0], '/')) == NULL)
115 uname = calloc(20, 1);
116 if ((current_li = (List_info *) malloc(sizeof(List_info)))
117 == (List_info *) NULL) {
118 (void) sprintf(buf, ": allocating list info");
122 current_li->acl_type = (char *) NULL;
123 current_li->acl_name = (char *) NULL;
124 current_li->desc = (char *) NULL;
125 current_li->modtime = (char *) NULL;
126 current_li->modby = (char *) NULL;
127 current_li->modwith = (char *) NULL;
129 if ((uname = getlogin()) == NULL) {
130 struct passwd *getpwuid();
132 uname = getpwuid((int) getuid())->pw_name;
134 uname = (uname && strlen(uname)) ? strsave(uname) : "";
136 printf("Connecting to database for %s...please hold on.\n", uname);
138 status = mr_connect(NULL);
140 (void) sprintf(buf, "\nConnection to Moira server failed");
144 status = mr_motd(&motd);
146 com_err(whoami, status, " unable to check server status");
151 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
155 status = mr_auth("mailmaint");
157 (void) sprintf(buf, "\nAuthorization failed.\n");
163 if ((LINES < 24) || (COLS < 60)) {
164 display_buff("Display window too small.\n\n");
165 (void) sprintf(buf, "Current window parameters are (%d \
166 lines, %d columns)\n", LINES, COLS);
168 display_buff("Please resize your window\n");
169 display_buff("to at least 24 lines and 60 columns.\n");
174 old_hook = set_com_err_hook(menu_err_hook);
175 position[0] = oldpos[0] = 1;
179 display_menu(main_menu);
183 set_com_err_hook(old_hook);
188 com_err(whoami, status, buf);
192 /****************************************************/
199 oldpos[level] = position[level];
201 currow = DISPROW + 2;
203 toggle = num_members = moreflg = 0;
206 if (position[level] == 7)
209 c = ascbuff[position[level]];
213 case 'L' & 037: /* clear screen */
214 display_menu(main_menu);
219 highlight(main_menu);
225 case '1': /* show all lists */
231 case '2': /* get all members of a list */
234 (void) list_members();
237 case '3': /* display list which user is a recipient */
243 case '4': /* show description */
249 case '5': /* add to list */
255 case '6': /* delete */
261 case 27: /* up arrow */
267 if (!position[level])
273 if (position[level] > 7)
283 highlight(main_menu);
287 /****************************************************/
292 show_text(DISPROW, STARTCOL, "Show information about a list.\n\r");
293 buf = calloc((unsigned)1024, 1);
294 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
295 display_buff("\n\r");
296 if (fetch_list_info(buf, current_li) == 0) {
297 (void) sprintf(buf, "Description: %s\n\r", current_li->desc);
298 if (strlen(buf) > 60)
299 (void) display_buff(buf);
301 show_text(currow, STARTCOL, buf);
303 (void) sprintf(buf, "List Administrator: %s %s",
304 current_li->acl_type, current_li->acl_name);
305 show_text(currow, STARTCOL, buf);
307 (void) sprintf(buf, "Modified on %s by user %s with %s",
308 current_li->modtime, current_li->modby,
309 current_li->modwith);
310 show_text(currow, STARTCOL, buf);
314 show_text(currow, STARTCOL, "mailmaint: No such list found.");
317 show_text(currow, STARTCOL, "Press any Key to continue...");
323 /****************************************************/
336 printbuf = calloc((unsigned)maxcol, 1);
337 for (i = 0; i <= strlen(buf); i++) {
338 printbuf[cnt] = buf[i];
341 (void) start_display_buff(printbuf);
344 printbuf = calloc((unsigned)maxcol, 1);
347 if (strlen(buf) % maxcol != 0) {
348 (void) start_display_buff(printbuf);
354 /****************************************************/
355 start_display_buff(buff)
363 if (currow >= LINES - 2) {
366 mvcur(0, 0, currow, STARTCOL);
368 if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
369 display_buff("Flushing query...");
374 currow = DISPROW + 2;
375 show_text(currow, STARTCOL, "continued");
378 show_text(currow, STARTCOL, buff);
383 /****************************************************/
389 show_text(DISPROW, STARTCOL, "Add yourself to a list\n\r");
390 buf = calloc(LISTMAX, 1);
391 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
392 display_buff("\r\n");
393 argv[0] = strsave(buf);
394 argv[1] = strsave("user");
395 argv[2] = strsave(uname);
396 if (status = mr_query("add_member_to_list", 3, argv,
397 scream, (char *) NULL)) {
398 display_buff("\r\n");
399 com_err(whoami, status, " found.\n");
402 (void) sprintf(buf, "User %s added to list\r", uname);
403 show_text(DISPROW + 3, STARTCOL, buf);
405 currow = DISPROW + 4;
406 show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
412 /****************************************************/
418 show_text(DISPROW, STARTCOL, "Remove yourself from a list\n\r");
419 buf = calloc(LISTMAX, 1);
420 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
421 display_buff("\r\n");
422 argv[0] = strsave(buf);
423 argv[1] = strsave("user");
424 argv[2] = strsave(uname);
425 if (status = mr_query("delete_member_from_list", 3, argv,
426 scream, (char *) NULL)) {
427 display_buff("\r\n");
428 com_err(whoami, status, " found.\n");
431 (void) sprintf(buf, "User %s deleted from list\r", uname);
432 show_text(DISPROW + 3, STARTCOL, buf);
434 currow = DISPROW + 4;
435 show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
441 /****************************************************/
447 nargv[1] = strsave("ruser");
448 nargv[2] = strsave(uname);
449 buf = calloc(BUFSIZ, 1);
450 (void) sprintf(buf, "%s is on the following lists:\r", uname);
451 show_text(DISPROW, STARTCOL, buf);
452 mvcur(0, 0, currow, STARTCOL);
454 if (status = mr_query("get_lists_of_member", 2, nargv + 1,
455 print_1, (char *) NULL)) {
456 display_buff("\r\n");
457 com_err(whoami, status, " in get_lists_of_member");
460 show_text(currow, STARTCOL, "Press any Key to continue...");
466 /****************************************************/
471 show_text(DISPROW, STARTCOL, "This function may take a \
472 while... proceed? [y] ");
474 if (c == 'y' || c == 'Y' || c == '\n') {
475 move(DISPROW + 1, STARTCOL);
476 addstr("Processing query...please hold");
478 (void) list_all_groups();
481 erase_line(DISPROW, STARTCOL);
486 /****************************************************/
489 print_1(argc, argv, callback)
491 char *argv[], *callback;
495 /* no newline 'cause display_buff adds one */
496 (void) sprintf(buf, "%s\r", argv[0]);
497 (void) start_display(buf);
502 /****************************************************/
505 print_all(argc, argv, callback)
507 char *argv[], *callback;
514 erase_line(DISPROW + 1, STARTCOL);
515 show_text(DISPROW + 1, STARTCOL, "All mailing lists:");
518 (void) sprintf(buf, "%s\r", argv[0]);
519 (void) start_display(buf);
524 /****************************************************/
528 argv[0] = argv[3] = "true";
529 argv[1] = argv[4] = "dontcare";
532 if (status = mr_query("qualified_get_lists", 5, argv,
533 print_all, (char *) NULL)) {
534 display_buff("\r\n");
535 com_err(whoami, status, " in list_all_groups\n");
542 /****************************************************/
550 move(DISPROW, STARTCOL);
551 mvcur(0, 0, DISPROW, STARTCOL);
553 buf = calloc(LISTMAX, 1);
554 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
555 (void) sprintf(buffer, "The members of list '%s' are:", buf);
556 show_text(DISPROW + 1, STARTCOL, buffer);
558 if (status = mr_query("get_members_of_list", 1, argv,
559 print_2, (char *) NULL)) {
560 display_buff("\r\n");
561 com_err(whoami, status, " found.\n");
565 show_text(currow, STARTCOL, "List is empty (no members).");
567 show_text(currow, STARTCOL, "Press any key to continue...");
579 /****************************************************/
582 print_2(argc, argv, callback)
584 char *argv[], *callback;
589 (void) sprintf(buf, "%s %s", argv[0], argv[1]);
590 (void) start_display(buf);
595 /****************************************************/
604 buffer = calloc(50, 1);
605 if (currow >= LINES - 2) {
608 mvcur(0, 0, currow, STARTCOL);
610 if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
611 display_buff("Flushing query...");
616 currow = DISPROW + 2;
617 (void) sprintf(buffer, "Continued (Page %d)", page);
618 show_text(currow, STARTCOL, buffer);
623 show_text(currow, STARTCOL, buff);
625 show_text(currow, SECONDCOL, buff);
632 /****************************************************/
642 buffer = calloc(50, 1);
644 (void) sprintf(buffer, "End of List. %d Total Members\r", num_members);
645 show_text(currow, STARTCOL, buffer);
647 show_text(currow, STARTCOL, "Press any key to continue...");
653 /****************************************************/
661 mvcur(0, 0, STARTROW, STARTCOL);
663 for (i = 0; i <= menu->num_items - 1; i++) {
664 move(STARTROW + i, STARTCOL);
666 addstr(menu->items[i]);
669 center_text(STARTROW + menu->num_items + 2,
670 "Enter a number, <up arrow>, or <down arrow>.");
672 center_text(STARTROW + menu->num_items + 3,
673 "Press 'q' to exit, <return> to confirm choice.");
675 center_text(STARTROW + menu->num_items + 3,
676 "Press 'q' to exit, 'r' for main menu, <return> to confirm choice.");
679 highlight(main_menu);
682 /****************************************************/
687 main_menu = (MENU *) malloc((unsigned) sizeof(MENU));
688 main_menu->num_items = 7;
689 main_menu->items = (char **) malloc((unsigned) sizeof(char *) * main_menu->num_items);
692 (void) sprintf(buf, "Mail List Program for %s", uname);
693 main_menu->title = strsave(buf);
694 main_menu->items[0] = strsave("1. Show all mailing lists.");
695 main_menu->items[1] = strsave("2. Get all members of a mailing list.");
696 main_menu->items[2] = strsave("3. Display lists of which you are a member.");
697 main_menu->items[3] = strsave("4. Show description of list.");
698 main_menu->items[4] = strsave("5. Add yourself to a mailing list.");
699 main_menu->items[5] = strsave("6. Delete yourself from a mailing list.");
700 main_menu->items[6] = strsave("q. Quit.");
703 /****************************************************/
706 help_menu = (MENU *) malloc((unsigned) sizeof(MENU));
707 help_menu->num_items = 5;
708 help_menu->items = (char **) malloc((unsigned) sizeof(char *) * help_menu->num_items);
710 help_menu->title = strsave("mailmaint is designed as a basic mail list administration program.");
711 help_menu->items[0] = strsave("if you need to perform more advanced list manipulation like");
712 help_menu->items[1] = strsave("adding lists, or changing list characteristics, refer to the");
713 help_menu->items[2] = strsave("program listmaint.");
714 help_menu->items[3] = strsave(" ");
715 help_menu->items[4] = strsave("Press any key to continue.");
718 /****************************************************/
724 if (oldpos[level] != position[level]) {
725 move(STARTROW + oldpos[level] - 1, STARTCOL);
727 addstr(menu->items[oldpos[level] - 1]);
731 move(STARTROW + position[level] - 1, STARTCOL);
733 addstr(menu->items[position[level] - 1]);
739 /****************************************************/
743 move(0, MAX(0, (COLS - strlen(buff)) >> 1));
750 /****************************************************/
751 center_text(row, buff)
755 move(row, MAX(0, (COLS - strlen(buff)) >> 1));
760 /****************************************************/
761 show_text(row, col, buff)
765 mvcur(0, 0, row, col);
770 /****************************************************/
777 buff = calloc((unsigned)COLS, 1);
778 for (i = 0; i <= COLS - 2; i++)
780 buff[i] = 0; /* just to be sure ! */
782 mvcur(0, 0, row, col);
787 /****************************************************/
794 /****************************************************/
804 maxcol = 80; /* limit width */
806 buff = calloc((unsigned)maxcol + 1, 1);
807 for (i = 0; i <= maxcol - 1; i++)
809 buff[i] = 0; /* just to be sure ! */
810 mvcur(0, 0, erase_row, STARTCOL);
812 for (i = erase_row; i <= currow - 1; i++) {
813 printf("%s\n\r", buff);
816 mvcur(erase_row, STARTCOL, STARTROW + oldpos[level] - 1, STARTCOL);
820 /****************************************************/
825 com_err(whoami, status, "\nA Moira update returned a value -- programmer \
829 return(0); /* to keep compiler happy */
832 /****************************************************/
835 fetch_list_info(list, li)
842 return mr_query("get_list_info", 1, argv, get_list_info, (char *) NULL);
847 get_list_info(argc, argv)
852 if (current_li->acl_type)
853 free(current_li->acl_type);
854 current_li->acl_type = strsave(argv[7]);
855 if (current_li->acl_name)
856 free(current_li->acl_name);
857 current_li->acl_name = strsave(argv[8]);
858 if (current_li->desc)
859 free(current_li->desc);
860 current_li->desc = strsave(argv[9]);
861 if (current_li->modtime)
862 free(current_li->modtime);
863 current_li->modtime = strsave(argv[10]);
864 if (current_li->modby)
865 free(current_li->modby);
866 current_li->modby = strsave(argv[11]);
867 if (current_li->modwith)
868 free(current_li->modwith);
869 current_li->modwith = strsave(argv[12]);
876 /****************************************************/
877 /* Prompt the user for input */
879 Prompt(prompt, buf, buflen, crok)
888 printf("%s", prompt);
890 for (p = buf; abs(strlen(p) - strlen(buf)) <= buflen;) {
900 display_menu(main_menu);
907 if (strlen(buf) < 1)/* only \n or \r in buff */
926 if (abs(strlen(p) - strlen(buf)) >= buflen) {
935 (void) putchar(CTL('G'));
944 * Hook function to cause error messages to be printed through
945 * curses instead of around it.
949 menu_err_hook(who, code, fmt, args)
955 char buf[BUFSIZ], *cp;
957 (void) strcpy(buf, who);
958 for (cp = buf; *cp; cp++);
962 (void) strcpy(cp, error_message(code));
966 #if defined(AIX386) || defined(sun)
967 vsprintf(cp, fmt, args);
969 /* can do this because we never pass more than 1 arg here anyway... */
970 sprintf(cp, fmt, args);