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();
75 extern char *strsave();
81 typedef struct _menu {
87 MENU *main_menu, *help_menu;
89 int position[2], oldpos[2];
90 int level, found_some, currow, page, num_members;
91 int moreflg, toggle, first_time;
94 /* This crock is because the original code was very broken and this makes
95 * it work. Someday, we should abandon the code or fix it right.
97 #define mvcur(oy,ox,ny,nx) move(ny,nx)
99 /****************************************************/
107 void (*old_hook)(const char *, long, const char *, va_list);
112 char buf[BUFSIZ], *motd;
114 if ((whoami = strrchr(argv[0], '/')) == NULL)
118 uname = calloc(20, 1);
119 if ((current_li = (List_info *) malloc(sizeof(List_info)))
120 == (List_info *) NULL) {
121 (void) sprintf(buf, ": allocating list info");
125 current_li->acl_type = (char *) NULL;
126 current_li->acl_name = (char *) NULL;
127 current_li->desc = (char *) NULL;
128 current_li->modtime = (char *) NULL;
129 current_li->modby = (char *) NULL;
130 current_li->modwith = (char *) NULL;
132 if ((uname = getlogin()) == NULL) {
133 struct passwd *getpwuid();
135 uname = getpwuid((int) getuid())->pw_name;
137 uname = (uname && strlen(uname)) ? strsave(uname) : "";
139 printf("Connecting to database for %s...please hold on.\n", uname);
141 status = mr_connect(NULL);
143 (void) sprintf(buf, "\nConnection to Moira server failed");
147 status = mr_motd(&motd);
149 com_err(whoami, status, " unable to check server status");
154 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
158 status = mr_auth("mailmaint");
160 (void) sprintf(buf, "\nAuthorization failed.\n");
166 if ((LINES < 24) || (COLS < 60)) {
167 display_buff("Display window too small.\n\n");
168 (void) sprintf(buf, "Current window parameters are (%d \
169 lines, %d columns)\n", LINES, COLS);
171 display_buff("Please resize your window\n");
172 display_buff("to at least 24 lines and 60 columns.\n");
177 old_hook = set_com_err_hook(menu_err_hook);
178 position[0] = oldpos[0] = 1;
182 display_menu(main_menu);
186 set_com_err_hook(old_hook);
191 com_err(whoami, status, buf);
195 /****************************************************/
202 oldpos[level] = position[level];
204 currow = DISPROW + 2;
206 toggle = num_members = moreflg = 0;
207 c = getchar() & 0x7f; /* mask parity bit */
208 if (c == '\r' || c == '\n') {
209 if (position[level] == 7)
212 c = ascbuff[position[level]];
216 case 'L' & 037: /* clear screen */
217 display_menu(main_menu);
222 highlight(main_menu);
228 case '1': /* show all lists */
234 case '2': /* get all members of a list */
237 (void) list_members();
240 case '3': /* display list which user is a recipient */
246 case '4': /* show description */
252 case '5': /* add to list */
258 case '6': /* delete */
264 case 27: /* up arrow */
265 c = getchar() & 0x7f;
267 c = getchar() & 0x7f;
270 if (!position[level])
276 if (position[level] > 7)
286 highlight(main_menu);
290 /****************************************************/
295 show_text(DISPROW, STARTCOL, "Show information about a list.\n");
296 buf = calloc((unsigned)1024, 1);
297 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
299 if (fetch_list_info(buf, current_li) == 0) {
300 (void) sprintf(buf, "Description: %s\n", current_li->desc);
301 if (strlen(buf) > 60)
302 (void) display_buff(buf);
304 show_text(currow, STARTCOL, buf);
306 (void) sprintf(buf, "List Administrator: %s %s",
307 current_li->acl_type, current_li->acl_name);
308 show_text(currow, STARTCOL, buf);
310 (void) sprintf(buf, "Modified on %s by user %s with %s",
311 current_li->modtime, current_li->modby,
312 current_li->modwith);
313 show_text(currow, STARTCOL, buf);
317 show_text(currow, STARTCOL, "mailmaint: No such list found.");
320 show_text(currow, STARTCOL, "Press any Key to continue...");
326 /****************************************************/
339 printbuf = calloc((unsigned)maxcol, 1);
340 for (i = 0; i <= strlen(buf); i++) {
341 printbuf[cnt] = buf[i];
344 (void) start_display_buff(printbuf);
347 printbuf = calloc((unsigned)maxcol, 1);
350 if (strlen(buf) % maxcol != 0) {
351 (void) start_display_buff(printbuf);
357 /****************************************************/
358 start_display_buff(buff)
366 if (currow >= LINES - 2) {
369 mvcur(0, 0, currow, STARTCOL);
371 if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
372 display_buff("Flushing query...");
377 currow = DISPROW + 2;
378 show_text(currow, STARTCOL, "continued");
381 show_text(currow, STARTCOL, buff);
386 /****************************************************/
392 show_text(DISPROW, STARTCOL, "Add yourself to a list\n");
393 buf = calloc(LISTMAX, 1);
394 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
396 argv[0] = strsave(buf);
397 argv[1] = strsave("user");
398 argv[2] = strsave(uname);
399 if (status = mr_query("add_member_to_list", 3, argv,
400 scream, (char *) NULL)) {
402 com_err(whoami, status, " found.\n");
405 (void) sprintf(buf, "User %s added to list\n", uname);
406 show_text(DISPROW + 3, STARTCOL, buf);
408 currow = DISPROW + 4;
409 show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
415 /****************************************************/
421 show_text(DISPROW, STARTCOL, "Remove yourself from a list\n");
422 buf = calloc(LISTMAX, 1);
423 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
425 argv[0] = strsave(buf);
426 argv[1] = strsave("user");
427 argv[2] = strsave(uname);
428 if (status = mr_query("delete_member_from_list", 3, argv,
429 scream, (char *) NULL)) {
431 com_err(whoami, status, " found.\n");
434 (void) sprintf(buf, "User %s deleted from list\n", uname);
435 show_text(DISPROW + 3, STARTCOL, buf);
437 currow = DISPROW + 4;
438 show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
444 /****************************************************/
450 nargv[1] = strsave("ruser");
451 nargv[2] = strsave(uname);
452 buf = calloc(BUFSIZ, 1);
453 (void) sprintf(buf, "%s is on the following lists:\n", uname);
454 show_text(DISPROW, STARTCOL, buf);
455 mvcur(0, 0, currow, STARTCOL);
457 if (status = mr_query("get_lists_of_member", 2, nargv + 1,
458 print_1, (char *) NULL)) {
460 com_err(whoami, status, " in get_lists_of_member");
463 show_text(currow, STARTCOL, "Press any Key to continue...");
469 /****************************************************/
474 show_text(DISPROW, STARTCOL, "This function may take a \
475 while... proceed? [y] ");
476 c = getchar() & 0x7f;
477 if (c == 'y' || c == 'Y' || c == '\n') {
478 move(DISPROW + 1, STARTCOL);
479 addstr("Processing query...please hold");
481 (void) list_all_groups();
484 erase_line(DISPROW, STARTCOL);
489 /****************************************************/
492 print_1(argc, argv, callback)
494 char *argv[], *callback;
498 /* no newline 'cause display_buff adds one */
499 (void) sprintf(buf, "%s\n", argv[0]);
500 (void) start_display(buf);
505 /****************************************************/
508 print_all(argc, argv, callback)
510 char *argv[], *callback;
517 erase_line(DISPROW + 1, STARTCOL);
518 show_text(DISPROW + 1, STARTCOL, "All mailing lists:");
521 (void) sprintf(buf, "%s\n", argv[0]);
522 (void) start_display(buf);
527 /****************************************************/
531 argv[0] = argv[1] = argv[3] = "true";
532 argv[4] = "dontcare";
535 if (status = mr_query("qualified_get_lists", 5, argv,
536 print_all, (char *) NULL)) {
538 com_err(whoami, status, " in list_all_groups\n");
545 /****************************************************/
553 move(DISPROW, STARTCOL);
554 mvcur(0, 0, DISPROW, STARTCOL);
556 buf = calloc(LISTMAX, 1);
557 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
558 (void) sprintf(buffer, "The members of list '%s' are:", buf);
559 show_text(DISPROW + 1, STARTCOL, buffer);
561 if (status = mr_query("get_members_of_list", 1, argv,
562 print_2, (char *) NULL)) {
564 com_err(whoami, status, " found.\n");
568 show_text(currow, STARTCOL, "List is empty (no members).");
570 show_text(currow, STARTCOL, "Press any key to continue...");
582 /****************************************************/
585 print_2(argc, argv, callback)
587 char *argv[], *callback;
592 (void) sprintf(buf, "%s %s", argv[0], argv[1]);
593 (void) start_display(buf);
598 /****************************************************/
607 buffer = calloc(50, 1);
608 if (currow >= LINES - 2) {
610 mvcur(0, 0, currow, STARTCOL);
612 if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
613 display_buff("Flushing query...");
618 currow = DISPROW + 2;
619 (void) sprintf(buffer, "Continued (Page %d)", page);
620 show_text(currow, STARTCOL, buffer);
625 show_text(currow, STARTCOL, buff);
627 show_text(currow, SECONDCOL, buff);
634 /****************************************************/
644 buffer = calloc(50, 1);
646 (void) sprintf(buffer, "End of List. %d Total Members\n", num_members - 1);
647 show_text(currow, STARTCOL, buffer);
649 show_text(currow, STARTCOL, "Press any key to continue...");
655 /****************************************************/
663 mvcur(0, 0, STARTROW, STARTCOL);
665 for (i = 0; i <= menu->num_items - 1; i++) {
666 move(STARTROW + i, STARTCOL);
668 addstr(menu->items[i]);
671 center_text(STARTROW + menu->num_items + 2,
672 "Enter a number, <up arrow>, or <down arrow>.");
674 center_text(STARTROW + menu->num_items + 3,
675 "Press 'q' to exit, <return> to confirm choice.");
677 center_text(STARTROW + menu->num_items + 3,
678 "Press 'q' to exit, 'r' for main menu, <return> to confirm choice.");
681 highlight(main_menu);
684 /****************************************************/
689 main_menu = (MENU *) malloc((unsigned) sizeof(MENU));
690 main_menu->num_items = 7;
691 main_menu->items = (char **) malloc((unsigned) sizeof(char *) * main_menu->num_items);
694 (void) sprintf(buf, "Mail List Program for %s", uname);
695 main_menu->title = strsave(buf);
696 main_menu->items[0] = strsave("1. Show all public mailing lists.");
697 main_menu->items[1] = strsave("2. Get all members of a mailing list.");
698 main_menu->items[2] = strsave("3. Display lists of which you are a member.");
699 main_menu->items[3] = strsave("4. Show description of list.");
700 main_menu->items[4] = strsave("5. Add yourself to a mailing list.");
701 main_menu->items[5] = strsave("6. Delete yourself from a mailing list.");
702 main_menu->items[6] = strsave("q. Quit.");
705 /****************************************************/
708 help_menu = (MENU *) malloc((unsigned) sizeof(MENU));
709 help_menu->num_items = 5;
710 help_menu->items = (char **) malloc((unsigned) sizeof(char *) * help_menu->num_items);
712 help_menu->title = strsave("mailmaint is designed as a basic mail list administration program.");
713 help_menu->items[0] = strsave("if you need to perform more advanced list manipulation like");
714 help_menu->items[1] = strsave("adding lists, or changing list characteristics, refer to the");
715 help_menu->items[2] = strsave("program listmaint.");
716 help_menu->items[3] = strsave(" ");
717 help_menu->items[4] = strsave("Press any key to continue.");
720 /****************************************************/
726 if (oldpos[level] != position[level]) {
727 move(STARTROW + oldpos[level] - 1, STARTCOL);
729 addstr(menu->items[oldpos[level] - 1]);
733 move(STARTROW + position[level] - 1, STARTCOL);
735 addstr(menu->items[position[level] - 1]);
741 /****************************************************/
745 move(0, MAX(0, (COLS - strlen(buff)) >> 1));
752 /****************************************************/
753 center_text(row, buff)
757 move(row, MAX(0, (COLS - strlen(buff)) >> 1));
762 /****************************************************/
763 show_text(row, col, buff)
767 mvcur(0, 0, row, col);
772 /****************************************************/
779 buff = calloc((unsigned)COLS, 1);
780 for (i = 0; i <= COLS - 2; i++)
782 buff[i] = 0; /* just to be sure ! */
784 mvcur(0, 0, row, col);
789 /****************************************************/
796 /****************************************************/
806 maxcol = 80; /* limit width */
808 buff = calloc((unsigned)maxcol + 1, 1);
809 for (i = 0; i <= maxcol - 1; i++)
811 buff[i] = 0; /* just to be sure ! */
812 mvcur(0, 0, erase_row, STARTCOL);
814 for (i = erase_row; i <= currow - 1; i++) {
818 mvcur(erase_row, STARTCOL, STARTROW + oldpos[level] - 1, STARTCOL);
822 /****************************************************/
827 com_err(whoami, status, "\nA Moira update returned a value -- programmer \
831 return(0); /* to keep compiler happy */
834 /****************************************************/
837 fetch_list_info(list, li)
844 return mr_query("get_list_info", 1, argv, get_list_info, (char *) NULL);
849 get_list_info(argc, argv)
854 if (current_li->acl_type)
855 free(current_li->acl_type);
856 current_li->acl_type = strsave(argv[7]);
857 if (current_li->acl_name)
858 free(current_li->acl_name);
859 current_li->acl_name = strsave(argv[8]);
860 if (current_li->desc)
861 free(current_li->desc);
862 current_li->desc = strsave(argv[9]);
863 if (current_li->modtime)
864 free(current_li->modtime);
865 current_li->modtime = strsave(argv[10]);
866 if (current_li->modby)
867 free(current_li->modby);
868 current_li->modby = strsave(argv[11]);
869 if (current_li->modwith)
870 free(current_li->modwith);
871 current_li->modwith = strsave(argv[12]);
878 /****************************************************/
879 /* Prompt the user for input */
881 Prompt(prompt, buf, buflen, crok)
892 for (p = buf; abs(strlen(p) - strlen(buf)) <= buflen;) {
894 c = getchar() & 0x7f;
902 display_menu(main_menu);
909 if (strlen(buf) < 1)/* only \n or \r in buff */
928 if (abs(strlen(p) - strlen(buf)) >= buflen) {
937 (void) putchar(CTL('G'));
946 * Hook function to cause error messages to be printed through
947 * curses instead of around it.
951 menu_err_hook(who, code, fmt, args)
957 char buf[BUFSIZ], *cp;
959 (void) strcpy(buf, who);
960 for (cp = buf; *cp; cp++);
964 (void) strcpy(cp, error_message(code));
968 #if defined(AIX386) || defined(sun)
969 vsprintf(cp, fmt, args);
971 /* can do this because we never pass more than 1 arg here anyway... */
972 sprintf(cp, fmt, args);