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>
29 #include <mit-copyright.h>
37 #define CTL(ch) ((ch) & 037)
38 #define MAX(A,B) ((A) > (B) ? (A) : (B))
40 char *whoami; /* should not be static, for logging package */
43 extern char *strsave();
46 typedef struct list_info {
60 static char *ascbuff = {"0123456789"};
63 static List_info *current_li = (List_info *) NULL;
64 static int get_list_info();
65 static int fetch_list_info();
70 extern char *strsave();
76 typedef struct _menu {
82 MENU *main_menu, *help_menu;
84 int position[2], oldpos[2];
85 int level, found_some, currow, page, num_members;
86 int moreflg, toggle, first_time;
90 /****************************************************/
104 if ((whoami = rindex(argv[0], '/')) == NULL)
108 uname = calloc(20, 1);
109 if ((current_li = (List_info *) malloc(sizeof(List_info)))
110 == (List_info *) NULL) {
111 (void) sprintf(buf, ": allocating list info");
115 current_li->acl_type = (char *) NULL;
116 current_li->acl_name = (char *) NULL;
117 current_li->desc = (char *) NULL;
118 current_li->modtime = (char *) NULL;
119 current_li->modby = (char *) NULL;
120 current_li->modwith = (char *) NULL;
122 if ((uname = getlogin()) == NULL) {
123 struct passwd *getpwuid();
125 uname = getpwuid((int) getuid())->pw_name;
127 uname = (uname && strlen(uname)) ? strsave(uname) : "";
129 printf("Connecting to database for %s...please hold on.\n", uname);
131 status = sms_connect();
133 (void) sprintf(buf, "\nConnection to SMS server failed");
137 status = sms_auth("mailmaint");
139 (void) sprintf(buf, "\nAuthorization failed.\n");
145 if ((LINES < 24) || (COLS < 60)) {
146 Put_message("Display window too small.\n\n");
147 (void) sprintf(buf, "Current window parameters are (%d \
148 lines, %d columns)\n", LINES, COLS);
150 Put_message("Please resize your window\n");
151 Put_message("to at least 24 lines and 60 columns.\n");
156 old_hook = set_com_err_hook(menu_err_hook);
157 position[0] = oldpos[0] = 1;
161 display_menu(main_menu);
165 set_com_err_hook(old_hook);
170 com_err(whoami, status, buf);
174 /****************************************************/
181 oldpos[level] = position[level];
183 currow = DISPROW + 2;
185 toggle = num_members = moreflg = 0;
188 if (position[level] == 7)
191 c = ascbuff[position[level]];
195 case 'L' & 037: /* clear screen */
196 display_menu(main_menu);
201 highlight(main_menu);
207 case '1': /* show all lists */
213 case '2': /* get all members of a list */
216 (void) list_members();
219 case '3': /* display list which user is a recipient */
225 case '4': /* show description */
231 case '5': /* add to list */
237 case '6': /* delete */
243 case 27: /* up arrow */
249 if (!position[level])
255 if (position[level] > 7)
265 highlight(main_menu);
269 /****************************************************/
275 show_text(DISPROW, STARTCOL, "Show information about a list.\n\r");
276 buf = calloc((unsigned)1024, 1);
277 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
279 if (fetch_list_info(buf, current_li) == 0) {
280 (void) sprintf(buf, "Description: %s\n\r", current_li->desc);
281 if (strlen(buf) > 60)
282 (void) display_buff(buf);
284 show_text(currow, STARTCOL, buf);
286 (void) sprintf(buf, "List Administrator: %s %s",
287 current_li->acl_type, current_li->acl_name);
288 show_text(currow, STARTCOL, buf);
290 (void) sprintf(buf, "Modified on %s by user %s with %s",
291 current_li->modtime, current_li->modby,
292 current_li->modwith);
293 show_text(currow, STARTCOL, buf);
297 show_text(currow, STARTCOL, "mailmaint: No such list found.");
300 show_text(currow, STARTCOL, "Press any Key to continue...");
306 /****************************************************/
319 printbuf = calloc((unsigned)maxcol, 1);
320 for (i = 0; i <= strlen(buf); i++) {
321 printbuf[cnt] = buf[i];
324 (void) start_display_buff(printbuf);
327 printbuf = calloc((unsigned)maxcol, 1);
330 if (strlen(buf) % maxcol != 0) {
331 (void) start_display_buff(printbuf);
337 /****************************************************/
338 start_display_buff(buff)
346 if (currow >= LINES - 2) {
349 mvcur(0, 0, currow, STARTCOL);
351 if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
352 Put_message("Flushing query...");
357 currow = DISPROW + 2;
358 show_text(currow, STARTCOL, "continued");
361 show_text(currow, STARTCOL, buff);
366 /****************************************************/
373 show_text(DISPROW, STARTCOL, "Add yourself to a list\n\r");
374 buf = calloc(LISTMAX, 1);
375 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
377 argv[0] = strsave(buf);
378 argv[1] = strsave("user");
379 argv[2] = strsave(uname);
380 if (status = sms_query("add_member_to_list", 3, argv,
381 scream, (char *) NULL)) {
383 com_err(whoami, status, " found.\n");
386 (void) sprintf(buf, "User %s added to list\r", uname);
387 show_text(DISPROW + 3, STARTCOL, buf);
389 currow = DISPROW + 4;
390 show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
396 /****************************************************/
403 show_text(DISPROW, STARTCOL, "Remove yourself from a list\n\r");
404 buf = calloc(LISTMAX, 1);
405 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
407 argv[0] = strsave(buf);
408 argv[1] = strsave("user");
409 argv[2] = strsave(uname);
410 if (status = sms_query("delete_member_from_list", 3, argv,
411 scream, (char *) NULL)) {
413 com_err(whoami, status, " found.\n");
416 (void) sprintf(buf, "User %s deleted from list\r", uname);
417 show_text(DISPROW + 3, STARTCOL, buf);
419 currow = DISPROW + 4;
420 show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
426 /****************************************************/
433 nargv[1] = strsave("ruser");
434 nargv[2] = strsave(uname);
435 buf = calloc(BUFSIZ, 1);
436 (void) sprintf(buf, "%s is on the following lists:\r", uname);
437 show_text(DISPROW, STARTCOL, buf);
438 mvcur(0, 0, currow, STARTCOL);
440 if (status = sms_query("get_lists_of_member", 2, nargv + 1,
441 print_1, (char *) NULL)) {
443 com_err(whoami, status, " in get_lists_of_member");
445 show_text(currow, STARTCOL, "Press any Key to continue...");
451 /****************************************************/
456 show_text(DISPROW, STARTCOL, "This function may take a \
457 while... proceed? [y] ");
459 if (c == 'y' || c == 'Y' || c == '\n') {
460 move(DISPROW + 1, STARTCOL);
461 addstr("Processing query...please hold");
463 (void) list_all_groups();
466 erase_line(DISPROW, STARTCOL);
471 /****************************************************/
474 print_1(argc, argv, callback)
476 char *argv[], *callback;
480 /* no newline 'cause Put_message adds one */
481 (void) sprintf(buf, "%s\r", argv[0]);
482 (void) start_display(buf);
487 /****************************************************/
490 print_all(argc, argv, callback)
492 char *argv[], *callback;
499 erase_line(DISPROW + 1, STARTCOL);
500 show_text(DISPROW + 1, STARTCOL, "All mailing lists:");
503 (void) sprintf(buf, "%s\r", argv[0]);
504 (void) start_display(buf);
509 /****************************************************/
513 argv[0] = argv[3] = "true";
514 argv[1] = argv[4] = "dontcare";
517 if (status = sms_query("qualified_get_lists", 5, argv,
518 print_all, (char *) NULL)) {
520 com_err(whoami, status, " in list_all_groups\n");
524 return (DM_NORMAL); /* HA! */
527 /****************************************************/
535 move(DISPROW, STARTCOL);
536 mvcur(0, 0, DISPROW, STARTCOL);
538 buf = calloc(LISTMAX, 1);
539 if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1) {
540 (void) sprintf(buffer, "The members of list '%s' are:", buf);
541 show_text(DISPROW + 1, STARTCOL, buffer);
543 if (status = sms_query("get_members_of_list", 1, argv,
544 print_2, (char *) NULL)) {
546 com_err(whoami, status, " found.\n");
550 show_text(currow, STARTCOL, "List is empty (no members).");
552 show_text(currow, STARTCOL, "Press any key to continue...");
561 return (DM_NORMAL); /* HA! */
564 /****************************************************/
567 print_2(argc, argv, callback)
569 char *argv[], *callback;
574 (void) sprintf(buf, "%s %s", argv[0], argv[1]);
575 (void) start_display(buf);
580 /****************************************************/
589 buffer = calloc(50, 1);
590 if (currow >= LINES - 2) {
593 mvcur(0, 0, currow, STARTCOL);
595 if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
596 Put_message("Flushing query...");
601 currow = DISPROW + 2;
602 (void) sprintf(buffer, "Continued (Page %d)", page);
603 show_text(currow, STARTCOL, buffer);
608 show_text(currow, STARTCOL, buff);
610 show_text(currow, SECONDCOL, buff);
617 /****************************************************/
627 buffer = calloc(50, 1);
629 (void) sprintf(buffer, "End of List. %d Total Members\r", num_members);
630 show_text(currow, STARTCOL, buffer);
632 show_text(currow, STARTCOL, "Press any key to continue...");
638 /****************************************************/
646 mvcur(0, 0, STARTROW, STARTCOL);
648 for (i = 0; i <= menu->num_items - 1; i++) {
649 move(STARTROW + i, STARTCOL);
651 addstr(menu->items[i]);
654 center_text(STARTROW + menu->num_items + 2,
655 "Enter a number, <up arrow>, or <down arrow>.");
657 center_text(STARTROW + menu->num_items + 3,
658 "Press 'q' to exit, <return> to confirm choice.");
660 center_text(STARTROW + menu->num_items + 3,
661 "Press 'q' to exit, 'r' for main menu, <return> to confirm choice.");
664 highlight(main_menu);
667 /****************************************************/
672 main_menu = (MENU *) malloc((unsigned) sizeof(MENU));
673 main_menu->num_items = 7;
674 main_menu->items = (char **) malloc((unsigned) sizeof(char *) * main_menu->num_items);
677 (void) sprintf(buf, "Mail List Program for %s", uname);
678 main_menu->title = strsave(buf);
679 main_menu->items[0] = strsave("1. Show all mailing lists.");
680 main_menu->items[1] = strsave("2. Get all members of a mailing list.");
681 main_menu->items[2] = strsave("3. Display lists of which you are a member.");
682 main_menu->items[3] = strsave("4. Show description of list.");
683 main_menu->items[4] = strsave("5. Add yourself to a mailing list.");
684 main_menu->items[5] = strsave("6. Delete yourself from a mailing list.");
685 main_menu->items[6] = strsave("q. Quit.");
688 /****************************************************/
691 help_menu = (MENU *) malloc((unsigned) sizeof(MENU));
692 help_menu->num_items = 5;
693 help_menu->items = (char **) malloc((unsigned) sizeof(char *) * help_menu->num_items);
695 help_menu->title = strsave("mailmaint is designed as a basic mail list administration program.");
696 help_menu->items[0] = strsave("if you need to perform more advanced list manipulation like");
697 help_menu->items[1] = strsave("adding lists, or changing list characteristics, refer to the");
698 help_menu->items[2] = strsave("program listmaint.");
699 help_menu->items[3] = strsave(" ");
700 help_menu->items[4] = strsave("Press any key to continue.");
703 /****************************************************/
709 if (oldpos[level] != position[level]) {
710 move(STARTROW + oldpos[level] - 1, STARTCOL);
712 addstr(menu->items[oldpos[level] - 1]);
716 move(STARTROW + position[level] - 1, STARTCOL);
718 addstr(menu->items[position[level] - 1]);
724 /****************************************************/
728 move(0, MAX(0, (COLS - strlen(buff)) >> 1));
735 /****************************************************/
736 center_text(row, buff)
740 move(row, MAX(0, (COLS - strlen(buff)) >> 1));
745 /****************************************************/
746 show_text(row, col, buff)
750 mvcur(0, 0, row, col);
755 /****************************************************/
762 buff = calloc((unsigned)COLS, 1);
763 for (i = 0; i <= COLS - 2; i++)
765 buff[i] = 0; /* just to be sure ! */
767 mvcur(0, 0, row, col);
772 /****************************************************/
779 /****************************************************/
789 maxcol = 80; /* limit width */
791 buff = calloc((unsigned)maxcol + 1, 1);
792 for (i = 0; i <= maxcol - 1; i++)
794 buff[i] = 0; /* just to be sure ! */
795 mvcur(0, 0, erase_row, STARTCOL);
797 for (i = erase_row; i <= currow - 1; i++) {
798 printf("%s\n\r", buff);
801 mvcur(erase_row, STARTCOL, STARTROW + oldpos[level] - 1, STARTCOL);
805 /****************************************************/
810 com_err(whoami, status, "\nAn SMS update returned a value -- programmer \
816 /****************************************************/
819 fetch_list_info(list, li)
826 return sms_query("get_list_info", 1, argv, get_list_info, (char *) NULL);
831 get_list_info(argc, argv)
836 if (current_li->acl_type)
837 free(current_li->acl_type);
838 current_li->acl_type = strsave(argv[7]);
839 if (current_li->acl_name)
840 free(current_li->acl_name);
841 current_li->acl_name = strsave(argv[8]);
842 if (current_li->desc)
843 free(current_li->desc);
844 current_li->desc = strsave(argv[9]);
845 if (current_li->modtime)
846 free(current_li->modtime);
847 current_li->modtime = strsave(argv[10]);
848 if (current_li->modby)
849 free(current_li->modby);
850 current_li->modby = strsave(argv[11]);
851 if (current_li->modwith)
852 free(current_li->modwith);
853 current_li->modwith = strsave(argv[12]);
860 /****************************************************/
861 /* Prompt the user for input */
863 Prompt(prompt, buf, buflen, crok)
873 printf("%s", prompt);
875 for (p = buf; abs(strlen(p) - strlen(buf)) <= buflen;) {
885 display_menu(main_menu);
892 if (strlen(buf) < 1)/* only \n or \r in buff */
913 if (abs(strlen(p) - strlen(buf)) >= buflen) {
923 (void) putchar(CTL('G'));
932 * Hook function to cause error messages to be printed through
933 * curses instead of around it.
937 menu_err_hook(who, code, fmt, args)
943 char buf[BUFSIZ], *cp;
947 (void) strcpy(buf, who);
948 for (cp = buf; *cp; cp++);
952 (void) strcpy(cp, error_message(code));
956 _strbuf._flag = _IOWRT + _IOSTRG;
958 _strbuf._cnt = BUFSIZ - (cp - buf);
959 _doprnt(fmt, args, &_strbuf);
960 (void) putc('\0', &_strbuf);
969 * c-continued-statement-offset: 4
971 * c-argdecl-indent: 4