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 /***********************************************************************/
25 #include <sys/types.h>
31 #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);
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 = sms_connect(SMS_SERVER);
140 (void) sprintf(buf, "\nConnection to SMS server failed");
144 status = sms_auth("mailmaint");
146 (void) sprintf(buf, "\nAuthorization failed.\n");
152 if ((LINES < 24) || (COLS < 60)) {
153 Put_message("Display window too small.\n\n");
154 (void) sprintf(buf, "Current window parameters are (%d \
155 lines, %d columns)\n", LINES, COLS);
157 Put_message("Please resize your window\n");
158 Put_message("to at least 24 lines and 60 columns.\n");
163 old_hook = set_com_err_hook(menu_err_hook);
164 position[0] = oldpos[0] = 1;
168 display_menu(main_menu);
172 set_com_err_hook(old_hook);
177 com_err(whoami, status, buf);
181 /****************************************************/
188 oldpos[level] = position[level];
190 currow = DISPROW + 2;
192 toggle = num_members = moreflg = 0;
195 if (position[level] == 7)
198 c = ascbuff[position[level]];
202 case 'L' & 037: /* clear screen */
203 display_menu(main_menu);
208 highlight(main_menu);
214 case '1': /* show all lists */
220 case '2': /* get all members of a list */
223 (void) list_members();
226 case '3': /* display list which user is a recipient */
232 case '4': /* show description */
238 case '5': /* add to list */
244 case '6': /* delete */
250 case 27: /* up arrow */
256 if (!position[level])
262 if (position[level] > 7)
272 highlight(main_menu);
276 /****************************************************/
281 show_text(DISPROW, STARTCOL, "Show information about a list.\n\r");
282 buf = calloc((unsigned)1024, 1);
283 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
285 if (fetch_list_info(buf, current_li) == 0) {
286 (void) sprintf(buf, "Description: %s\n\r", current_li->desc);
287 if (strlen(buf) > 60)
288 (void) display_buff(buf);
290 show_text(currow, STARTCOL, buf);
292 (void) sprintf(buf, "List Administrator: %s %s",
293 current_li->acl_type, current_li->acl_name);
294 show_text(currow, STARTCOL, buf);
296 (void) sprintf(buf, "Modified on %s by user %s with %s",
297 current_li->modtime, current_li->modby,
298 current_li->modwith);
299 show_text(currow, STARTCOL, buf);
303 show_text(currow, STARTCOL, "mailmaint: No such list found.");
306 show_text(currow, STARTCOL, "Press any Key to continue...");
312 /****************************************************/
325 printbuf = calloc((unsigned)maxcol, 1);
326 for (i = 0; i <= strlen(buf); i++) {
327 printbuf[cnt] = buf[i];
330 (void) start_display_buff(printbuf);
333 printbuf = calloc((unsigned)maxcol, 1);
336 if (strlen(buf) % maxcol != 0) {
337 (void) start_display_buff(printbuf);
343 /****************************************************/
344 start_display_buff(buff)
352 if (currow >= LINES - 2) {
355 mvcur(0, 0, currow, STARTCOL);
357 if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
358 Put_message("Flushing query...");
363 currow = DISPROW + 2;
364 show_text(currow, STARTCOL, "continued");
367 show_text(currow, STARTCOL, buff);
372 /****************************************************/
378 show_text(DISPROW, STARTCOL, "Add yourself to a list\n\r");
379 buf = calloc(LISTMAX, 1);
380 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
382 argv[0] = strsave(buf);
383 argv[1] = strsave("user");
384 argv[2] = strsave(uname);
385 if (status = sms_query("add_member_to_list", 3, argv,
386 scream, (char *) NULL)) {
388 com_err(whoami, status, " found.\n");
391 (void) sprintf(buf, "User %s added to list\r", uname);
392 show_text(DISPROW + 3, STARTCOL, buf);
394 currow = DISPROW + 4;
395 show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
401 /****************************************************/
407 show_text(DISPROW, STARTCOL, "Remove yourself from a list\n\r");
408 buf = calloc(LISTMAX, 1);
409 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
411 argv[0] = strsave(buf);
412 argv[1] = strsave("user");
413 argv[2] = strsave(uname);
414 if (status = sms_query("delete_member_from_list", 3, argv,
415 scream, (char *) NULL)) {
417 com_err(whoami, status, " found.\n");
420 (void) sprintf(buf, "User %s deleted from list\r", uname);
421 show_text(DISPROW + 3, STARTCOL, buf);
423 currow = DISPROW + 4;
424 show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
430 /****************************************************/
436 nargv[1] = strsave("ruser");
437 nargv[2] = strsave(uname);
438 buf = calloc(BUFSIZ, 1);
439 (void) sprintf(buf, "%s is on the following lists:\r", uname);
440 show_text(DISPROW, STARTCOL, buf);
441 mvcur(0, 0, currow, STARTCOL);
443 if (status = sms_query("get_lists_of_member", 2, nargv + 1,
444 print_1, (char *) NULL)) {
446 com_err(whoami, status, " in get_lists_of_member");
449 show_text(currow, STARTCOL, "Press any Key to continue...");
455 /****************************************************/
460 show_text(DISPROW, STARTCOL, "This function may take a \
461 while... proceed? [y] ");
463 if (c == 'y' || c == 'Y' || c == '\n') {
464 move(DISPROW + 1, STARTCOL);
465 addstr("Processing query...please hold");
467 (void) list_all_groups();
470 erase_line(DISPROW, STARTCOL);
475 /****************************************************/
478 print_1(argc, argv, callback)
480 char *argv[], *callback;
484 /* no newline 'cause Put_message adds one */
485 (void) sprintf(buf, "%s\r", argv[0]);
486 (void) start_display(buf);
491 /****************************************************/
494 print_all(argc, argv, callback)
496 char *argv[], *callback;
503 erase_line(DISPROW + 1, STARTCOL);
504 show_text(DISPROW + 1, STARTCOL, "All mailing lists:");
507 (void) sprintf(buf, "%s\r", argv[0]);
508 (void) start_display(buf);
513 /****************************************************/
517 argv[0] = argv[3] = "true";
518 argv[1] = argv[4] = "dontcare";
521 if (status = sms_query("qualified_get_lists", 5, argv,
522 print_all, (char *) NULL)) {
524 com_err(whoami, status, " in list_all_groups\n");
528 return (DM_NORMAL); /* HA! */
531 /****************************************************/
539 move(DISPROW, STARTCOL);
540 mvcur(0, 0, DISPROW, STARTCOL);
542 buf = calloc(LISTMAX, 1);
543 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
544 (void) sprintf(buffer, "The members of list '%s' are:", buf);
545 show_text(DISPROW + 1, STARTCOL, buffer);
547 if (status = sms_query("get_members_of_list", 1, argv,
548 print_2, (char *) NULL)) {
550 com_err(whoami, status, " found.\n");
554 show_text(currow, STARTCOL, "List is empty (no members).");
556 show_text(currow, STARTCOL, "Press any key to continue...");
565 return (DM_NORMAL); /* HA! */
568 /****************************************************/
571 print_2(argc, argv, callback)
573 char *argv[], *callback;
578 (void) sprintf(buf, "%s %s", argv[0], argv[1]);
579 (void) start_display(buf);
584 /****************************************************/
593 buffer = calloc(50, 1);
594 if (currow >= LINES - 2) {
597 mvcur(0, 0, currow, STARTCOL);
599 if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
600 Put_message("Flushing query...");
605 currow = DISPROW + 2;
606 (void) sprintf(buffer, "Continued (Page %d)", page);
607 show_text(currow, STARTCOL, buffer);
612 show_text(currow, STARTCOL, buff);
614 show_text(currow, SECONDCOL, buff);
621 /****************************************************/
631 buffer = calloc(50, 1);
633 (void) sprintf(buffer, "End of List. %d Total Members\r", num_members);
634 show_text(currow, STARTCOL, buffer);
636 show_text(currow, STARTCOL, "Press any key to continue...");
642 /****************************************************/
650 mvcur(0, 0, STARTROW, STARTCOL);
652 for (i = 0; i <= menu->num_items - 1; i++) {
653 move(STARTROW + i, STARTCOL);
655 addstr(menu->items[i]);
658 center_text(STARTROW + menu->num_items + 2,
659 "Enter a number, <up arrow>, or <down arrow>.");
661 center_text(STARTROW + menu->num_items + 3,
662 "Press 'q' to exit, <return> to confirm choice.");
664 center_text(STARTROW + menu->num_items + 3,
665 "Press 'q' to exit, 'r' for main menu, <return> to confirm choice.");
668 highlight(main_menu);
671 /****************************************************/
676 main_menu = (MENU *) malloc((unsigned) sizeof(MENU));
677 main_menu->num_items = 7;
678 main_menu->items = (char **) malloc((unsigned) sizeof(char *) * main_menu->num_items);
681 (void) sprintf(buf, "Mail List Program for %s", uname);
682 main_menu->title = strsave(buf);
683 main_menu->items[0] = strsave("1. Show all mailing lists.");
684 main_menu->items[1] = strsave("2. Get all members of a mailing list.");
685 main_menu->items[2] = strsave("3. Display lists of which you are a member.");
686 main_menu->items[3] = strsave("4. Show description of list.");
687 main_menu->items[4] = strsave("5. Add yourself to a mailing list.");
688 main_menu->items[5] = strsave("6. Delete yourself from a mailing list.");
689 main_menu->items[6] = strsave("q. Quit.");
692 /****************************************************/
695 help_menu = (MENU *) malloc((unsigned) sizeof(MENU));
696 help_menu->num_items = 5;
697 help_menu->items = (char **) malloc((unsigned) sizeof(char *) * help_menu->num_items);
699 help_menu->title = strsave("mailmaint is designed as a basic mail list administration program.");
700 help_menu->items[0] = strsave("if you need to perform more advanced list manipulation like");
701 help_menu->items[1] = strsave("adding lists, or changing list characteristics, refer to the");
702 help_menu->items[2] = strsave("program listmaint.");
703 help_menu->items[3] = strsave(" ");
704 help_menu->items[4] = strsave("Press any key to continue.");
707 /****************************************************/
713 if (oldpos[level] != position[level]) {
714 move(STARTROW + oldpos[level] - 1, STARTCOL);
716 addstr(menu->items[oldpos[level] - 1]);
720 move(STARTROW + position[level] - 1, STARTCOL);
722 addstr(menu->items[position[level] - 1]);
728 /****************************************************/
732 move(0, MAX(0, (COLS - strlen(buff)) >> 1));
739 /****************************************************/
740 center_text(row, buff)
744 move(row, MAX(0, (COLS - strlen(buff)) >> 1));
749 /****************************************************/
750 show_text(row, col, buff)
754 mvcur(0, 0, row, col);
759 /****************************************************/
766 buff = calloc((unsigned)COLS, 1);
767 for (i = 0; i <= COLS - 2; i++)
769 buff[i] = 0; /* just to be sure ! */
771 mvcur(0, 0, row, col);
776 /****************************************************/
783 /****************************************************/
793 maxcol = 80; /* limit width */
795 buff = calloc((unsigned)maxcol + 1, 1);
796 for (i = 0; i <= maxcol - 1; i++)
798 buff[i] = 0; /* just to be sure ! */
799 mvcur(0, 0, erase_row, STARTCOL);
801 for (i = erase_row; i <= currow - 1; i++) {
802 printf("%s\n\r", buff);
805 mvcur(erase_row, STARTCOL, STARTROW + oldpos[level] - 1, STARTCOL);
809 /****************************************************/
814 com_err(whoami, status, "\nAn SMS update returned a value -- programmer \
818 return(0); /* to keep compiler happy */
821 /****************************************************/
824 fetch_list_info(list, li)
831 return sms_query("get_list_info", 1, argv, get_list_info, (char *) NULL);
836 get_list_info(argc, argv)
841 if (current_li->acl_type)
842 free(current_li->acl_type);
843 current_li->acl_type = strsave(argv[7]);
844 if (current_li->acl_name)
845 free(current_li->acl_name);
846 current_li->acl_name = strsave(argv[8]);
847 if (current_li->desc)
848 free(current_li->desc);
849 current_li->desc = strsave(argv[9]);
850 if (current_li->modtime)
851 free(current_li->modtime);
852 current_li->modtime = strsave(argv[10]);
853 if (current_li->modby)
854 free(current_li->modby);
855 current_li->modby = strsave(argv[11]);
856 if (current_li->modwith)
857 free(current_li->modwith);
858 current_li->modwith = strsave(argv[12]);
865 /****************************************************/
866 /* Prompt the user for input */
868 Prompt(prompt, buf, buflen, crok)
877 printf("%s", prompt);
879 for (p = buf; abs(strlen(p) - strlen(buf)) <= buflen;) {
889 display_menu(main_menu);
896 if (strlen(buf) < 1)/* only \n or \r in buff */
915 if (abs(strlen(p) - strlen(buf)) >= buflen) {
924 (void) putchar(CTL('G'));
933 * Hook function to cause error messages to be printed through
934 * curses instead of around it.
938 menu_err_hook(who, code, fmt, args)
944 char buf[BUFSIZ], *cp;
948 (void) strcpy(buf, who);
949 for (cp = buf; *cp; cp++);
953 (void) strcpy(cp, error_message(code));
957 _strbuf._flag = _IOWRT + _IOSTRG;
959 _strbuf._cnt = BUFSIZ - (cp - buf);
960 _doprnt(fmt, args, &_strbuf);
961 (void) putc('\0', &_strbuf);