]> andersk Git - moira.git/blob - clients/mailmaint/mailmaint.c
update for the new com_err library
[moira.git] / clients / mailmaint / mailmaint.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5
6 /*  (c) Copyright 1988 by the Massachusetts Institute of Technology. */
7 /*  For copying and distribution information, please see the file */
8 /*  <mit-copyright.h>. */
9
10 #ifndef lint
11 static char rcsid_mailmaint_c[] = "$Header$";
12 #endif lint
13
14 /***********************************************************************/
15 /*  mailmaint.c - pjlevine - 20 August 1987 
16     
17 */
18 /***********************************************************************/
19 #include <stdio.h>
20 #include <pwd.h>
21 #include <menu.h>
22 #include <signal.h>
23 #include <strings.h>
24 #include <curses.h>
25 #include <sys/types.h>
26 #include <varargs.h>
27 #include <com_err.h>
28 #include <ctype.h>
29 #include <sms.h>
30 #include <sms_app.h>
31 #include <mit-copyright.h>
32
33 #define STARTCOL 0
34 #define STARTROW 3
35 #define SECONDCOL 30
36 #define DISPROW 15
37 #define LISTMAX 50
38 #define LISTSIZE 32
39 #define CTL(ch)  ((ch) & 037)
40 #define MAX(A,B) ((A) > (B) ? (A) : (B))
41
42 char *whoami;           /* should not be static, for logging package */
43 static int status;
44 static int scream();
45 extern char *strsave();
46 #ifdef __STDC__
47 void menu_err_hook(const char *who, long code, const char *fmt, va_list args);
48 #else
49 void menu_err_hook();
50 #define const
51 #endif
52
53 typedef struct list_info {
54     int active;
55     int public;
56     int hidden;
57     int maillist;
58     int group;
59     char *acl_type;
60     char *acl_name;
61     char *desc;
62     char *modtime;
63     char *modby;
64     char *modwith;
65 }         List_info;
66
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();
72
73 char *malloc();
74 char *rindex();
75 char *getlogin();
76 extern char *strsave();
77 char *getenv();
78 char *calloc();
79
80 uid_t getuid();
81
82 typedef struct _menu {
83     int num_items;
84     char *title;
85     char **items;
86 }     MENU;
87
88 MENU *main_menu, *help_menu;
89
90 int position[2], oldpos[2];
91 int level, found_some, currow, page, num_members;
92 int moreflg, toggle, first_time;
93 char *uname;
94
95
96 /****************************************************/
97 /*ARGSUSED*/
98 main(argc, argv)
99     int argc;
100     char *argv[];
101
102 {
103 #ifdef __STDC__
104     void (*old_hook)(const char *, long, const char *, va_list);
105 #else
106     void (*old_hook)();
107 #endif
108     int use_menu = 1;
109     char buf[BUFSIZ];
110
111     if ((whoami = rindex(argv[0], '/')) == NULL)
112         whoami = argv[0];
113     else
114         whoami++;
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");
119         goto punt;
120     }
121     else {
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;
128     }
129     if ((uname = getlogin()) == NULL) {
130         struct passwd *getpwuid();
131
132         uname = getpwuid((int) getuid())->pw_name;
133     }
134     uname = (uname && strlen(uname)) ? strsave(uname) : "";
135
136     printf("Connecting to database for %s...please hold on.\n", uname);
137
138     status = sms_connect(SMS_SERVER);
139     if (status) {
140         (void) sprintf(buf, "\nConnection to SMS server failed");
141         goto punt;
142     }
143
144     status = sms_auth("mailmaint");
145     if (status) {
146         (void) sprintf(buf, "\nAuthorization failed.\n");
147         goto punt;
148     }
149
150     if (use_menu) {
151         (void) initscr();
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);
156             Put_message(buf);
157             Put_message("Please resize your window\n");
158             Put_message("to at least 24 lines and 60 columns.\n");
159             exit(0);
160         }
161         raw();
162         noecho();
163         old_hook = set_com_err_hook(menu_err_hook);
164         position[0] = oldpos[0] = 1;
165         level = 0;
166         pack_main_menu();
167         pack_help_menu();
168         display_menu(main_menu);
169         get_main_input();
170         cls();
171         endwin();
172         set_com_err_hook(old_hook);
173     }
174     exit(0);
175
176 punt:
177     com_err(whoami, status, buf);
178     exit(1);
179 }
180
181 /****************************************************/
182 get_main_input()
183 {
184     int c;
185     int retflg;
186
187     while (1) {
188         oldpos[level] = position[level];
189         retflg = 0;
190         currow = DISPROW + 2;
191         page = 1;
192         toggle = num_members = moreflg = 0;
193         c = getchar();
194         if (c == 13) {
195             if (position[level] == 7)
196                 c = 'q';
197             else
198                 c = ascbuff[position[level]];
199             retflg = 1;
200         }
201         switch (c) {
202         case 'L' & 037: /* clear screen */
203             display_menu(main_menu);
204             break;
205         case 'q':
206         case 'Q':               /* quit */
207             position[level] = 7;
208             highlight(main_menu);
209             if (retflg) {
210                 cls();
211                 return;
212             }
213             break;
214         case '1':               /* show all lists */
215             position[level] = 1;
216             if (retflg) {
217                 show_all();
218             }
219             break;
220         case '2':               /* get all members of a list */
221             position[level] = 2;
222             if (retflg) {
223                 (void) list_members();
224             }
225             break;
226         case '3':               /* display list which user is a recipient */
227             position[level] = 3;
228             if (retflg) {
229                 list_by_member();
230             }
231             break;
232         case '4':               /* show description */
233             position[level] = 4;
234             if (retflg) {
235                 show_list_info();
236             }
237             break;
238         case '5':               /* add to list */
239             position[level] = 5;
240             if (retflg) {
241                 add_member();
242             }
243             break;
244         case '6':               /* delete */
245             position[level] = 6;
246             if (retflg) {
247                 delete_member();
248             }
249             break;
250         case 27:                /* up arrow */
251             c = getchar();
252             if (c == 91) {
253                 c = getchar();
254                 if (c == 65) {
255                     position[level]--;
256                     if (!position[level])
257                         position[level] = 7;
258                 }
259                 else {
260                     if (c == 66) {
261                         position[level]++;
262                         if (position[level] > 7)
263                             position[level] = 1;
264                     }
265                 }
266             }
267             break;
268         default:
269             printf("%c", 7);
270             break;
271         }
272         highlight(main_menu);
273     }
274 }
275
276 /****************************************************/
277 show_list_info()
278 {
279     char *buf;
280
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) {
284         Put_message("\n\r");
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);
289             else
290                 show_text(currow, STARTCOL, buf);
291             currow++;
292             (void) sprintf(buf, "List Administrator: %s %s",
293                            current_li->acl_type, current_li->acl_name);
294             show_text(currow, STARTCOL, buf);
295             currow++;
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);
300             currow++;
301         }
302         else {
303             show_text(currow, STARTCOL, "mailmaint: No such list found.");
304             currow++;
305         }
306         show_text(currow, STARTCOL, "Press any Key to continue...");
307         (void) getchar();
308     }
309     clrwin(DISPROW);
310 }
311
312 /****************************************************/
313 display_buff(buf)
314     char *buf;
315 {
316     int i, cnt;
317     char *printbuf;
318     int maxcol;
319
320     maxcol = COLS;
321     if (maxcol >= 80)
322         maxcol = 80;
323
324     cnt = 0;
325     printbuf = calloc((unsigned)maxcol, 1);
326     for (i = 0; i <= strlen(buf); i++) {
327         printbuf[cnt] = buf[i];
328         cnt++;
329         if (cnt >= maxcol) {
330             (void) start_display_buff(printbuf);
331             cnt = 0;
332             free(printbuf);
333             printbuf = calloc((unsigned)maxcol, 1);
334         }
335     }
336     if (strlen(buf) % maxcol != 0) {
337         (void) start_display_buff(printbuf);
338         free(printbuf);
339     }
340     return (0);
341 }
342
343 /****************************************************/
344 start_display_buff(buff)
345     char *buff;
346 {
347     char buffer[5];
348
349     num_members++;
350     if (moreflg)
351         return (0);
352     if (currow >= LINES - 2) {
353         page++;
354         currow++;
355         mvcur(0, 0, currow, STARTCOL);
356         refresh();
357         if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
358             Put_message("Flushing query...");
359             moreflg = 1;
360             return (0);
361         }
362         clrwin(DISPROW + 2);
363         currow = DISPROW + 2;
364         show_text(currow, STARTCOL, "continued");
365         currow++;
366     }
367     show_text(currow, STARTCOL, buff);
368     currow++;
369     return (0);
370 }
371
372 /****************************************************/
373 add_member()
374 {
375     char *argv[3];
376     char *buf;
377
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) {
381         Put_message("\r\n");
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)) {
387             Put_message("\r\n");
388             com_err(whoami, status, " found.\n");
389         }
390         else {
391             (void) sprintf(buf, "User %s added to list\r", uname);
392             show_text(DISPROW + 3, STARTCOL, buf);
393         }
394         currow = DISPROW + 4;
395         show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
396         (void) getchar();
397     }
398     clrwin(DISPROW);
399 }
400
401 /****************************************************/
402 delete_member()
403 {
404     char *argv[3];
405     char *buf;
406
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) {
410         Put_message("\r\n");
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)) {
416             Put_message("\r\n");
417             com_err(whoami, status, " found.\n");
418         }
419         else {
420             (void) sprintf(buf, "User %s deleted from list\r", uname);
421             show_text(DISPROW + 3, STARTCOL, buf);
422         }
423         currow = DISPROW + 4;
424         show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
425         (void) getchar();
426     }
427     clrwin(DISPROW);
428 }
429
430 /****************************************************/
431 list_by_member()
432 {
433     char *nargv[3];
434     char *buf;
435
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);
442     refresh();
443     if (status = sms_query("get_lists_of_member", 2, nargv + 1,
444                            print_1, (char *) NULL)) {
445         Put_message("\r\n");
446         com_err(whoami, status, " in get_lists_of_member");
447     }
448     currow++;
449     show_text(currow, STARTCOL, "Press any Key to continue...");
450     (void) getchar();
451     clrwin(DISPROW);
452     return;
453 }
454
455 /****************************************************/
456 show_all()
457 {
458     char c;
459
460     show_text(DISPROW, STARTCOL, "This function may take a \
461 while... proceed? [y] ");
462     c = getchar();
463     if (c == 'y' || c == 'Y' || c == '\n') {
464         move(DISPROW + 1, STARTCOL);
465         addstr("Processing query...please hold");
466         refresh();
467         (void) list_all_groups();
468     }
469     else
470         erase_line(DISPROW, STARTCOL);
471     return;
472
473 }
474
475 /****************************************************/
476 /*ARGSUSED*/
477 static int
478 print_1(argc, argv, callback)
479     int argc;
480     char *argv[], *callback;
481 {
482     char buf[BUFSIZ];
483
484     /* no newline 'cause Put_message adds one */
485     (void) sprintf(buf, "%s\r", argv[0]);
486     (void) start_display(buf);
487
488     return (0);
489 }
490
491 /****************************************************/
492 /*ARGSUSED*/
493 static int
494 print_all(argc, argv, callback)
495     int argc;
496     char *argv[], *callback;
497 {
498     char buf[BUFSIZ];
499
500     if (moreflg)
501         return (0);
502     if (first_time) {
503         erase_line(DISPROW + 1, STARTCOL);
504         show_text(DISPROW + 1, STARTCOL, "All mailing lists:");
505         first_time = 0;
506     }
507     (void) sprintf(buf, "%s\r", argv[0]);
508     (void) start_display(buf);
509
510     return (0);
511 }
512
513 /****************************************************/
514 list_all_groups()
515 {
516     char *argv[5];
517     argv[0] = argv[3] = "true";
518     argv[1] = argv[4] = "dontcare";
519     argv[2] = "false";
520     first_time = 1;
521     if (status = sms_query("qualified_get_lists", 5, argv,
522                            print_all, (char *) NULL)) {
523         Put_message("\r\n");
524         com_err(whoami, status, " in list_all_groups\n");
525     }
526     end_display();
527
528     return (DM_NORMAL);         /* HA! */
529 }
530
531 /****************************************************/
532 list_members()
533 {
534     char *argv[1];
535     char *buf;
536     char buffer[80];
537
538     found_some = 0;
539     move(DISPROW, STARTCOL);
540     mvcur(0, 0, DISPROW, STARTCOL);
541     refresh();
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);
546         argv[0] = buf;
547         if (status = sms_query("get_members_of_list", 1, argv,
548                                print_2, (char *) NULL)) {
549             Put_message("\r\n");
550             com_err(whoami, status, " found.\n");
551             currow++;
552         }
553         if (!found_some) {
554             show_text(currow, STARTCOL, "List is empty (no members).");
555             currow++;
556             show_text(currow, STARTCOL, "Press any key to continue...");
557             getchar();
558             clrwin(DISPROW);
559             return;
560         }
561         end_display();
562         return(0);
563     }
564     clrwin(DISPROW);
565     return (DM_NORMAL);         /* HA! */
566 }
567
568 /****************************************************/
569 /*ARGSUSED*/
570 static int
571 print_2(argc, argv, callback)
572     int argc;
573     char *argv[], *callback;
574 {
575     char buf[BUFSIZ];
576
577     found_some = 1;
578     (void) sprintf(buf, "%s %s", argv[0], argv[1]);
579     (void) start_display(buf);
580
581     return (0);
582 }
583
584 /****************************************************/
585 start_display(buff)
586     char *buff;
587 {
588     char *buffer;
589
590     num_members++;
591     if (moreflg)
592         return(0);
593     buffer = calloc(50, 1);
594     if (currow >= LINES - 2) {
595         page++;
596         currow++;
597         mvcur(0, 0, currow, STARTCOL);
598         refresh();
599         if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0) {
600             Put_message("Flushing query...");
601             moreflg = 1;
602             return (0);
603         }
604         clrwin(DISPROW + 2);
605         currow = DISPROW + 2;
606         (void) sprintf(buffer, "Continued (Page %d)", page);
607         show_text(currow, STARTCOL, buffer);
608         currow++;
609         toggle = 0;
610     }
611     if (!toggle)
612         show_text(currow, STARTCOL, buff);
613     else {
614         show_text(currow, SECONDCOL, buff);
615         currow++;
616     }
617     toggle = !toggle;
618     return(0);
619 }
620
621 /****************************************************/
622 end_display()
623 {
624     char *buffer;
625
626     if (moreflg) {
627         clrwin(DISPROW);
628         return;
629     }
630
631     buffer = calloc(50, 1);
632     currow++;
633     (void) sprintf(buffer, "End of List. %d Total Members\r", num_members);
634     show_text(currow, STARTCOL, buffer);
635     currow++;
636     show_text(currow, STARTCOL, "Press any key to continue...");
637     (void) getchar();
638     clrwin(DISPROW);
639
640 }
641
642 /****************************************************/
643 display_menu(menu)
644     MENU *menu;
645 {
646     int i;
647
648     cls();
649     title(menu->title);
650     mvcur(0, 0, STARTROW, STARTCOL);
651     refresh();
652     for (i = 0; i <= menu->num_items - 1; i++) {
653         move(STARTROW + i, STARTCOL);
654         standend();
655         addstr(menu->items[i]);
656         refresh();
657     }
658     center_text(STARTROW + menu->num_items + 2,
659                 "Enter a number, <up arrow>, or <down arrow>.");
660     if (!level)
661         center_text(STARTROW + menu->num_items + 3,
662                     "Press 'q' to exit, <return> to confirm choice.");
663     else
664         center_text(STARTROW + menu->num_items + 3,
665         "Press 'q' to exit, 'r' for main menu, <return> to confirm choice.");
666
667     if (!level)
668         highlight(main_menu);
669 }
670
671 /****************************************************/
672 pack_main_menu()
673 {
674     char *buf;
675
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);
679
680     buf = calloc(50, 1);
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.");
690 }
691
692 /****************************************************/
693 pack_help_menu()
694 {
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);
698
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.");
705 }
706
707 /****************************************************/
708 highlight(menu)
709     MENU *menu;
710 {
711
712
713     if (oldpos[level] != position[level]) {
714         move(STARTROW + oldpos[level] - 1, STARTCOL);
715         standend();
716         addstr(menu->items[oldpos[level] - 1]);
717         refresh();
718     }
719
720     move(STARTROW + position[level] - 1, STARTCOL);
721     standout();
722     addstr(menu->items[position[level] - 1]);
723     refresh();
724     standend();
725     refresh();
726 }
727
728 /****************************************************/
729 title(buff)
730     char *buff;
731 {
732     move(0, MAX(0, (COLS - strlen(buff)) >> 1));
733     standout();
734     addstr(buff);
735     refresh();
736     standend();
737 }
738
739 /****************************************************/
740 center_text(row, buff)
741     int row;
742     char *buff;
743 {
744     move(row, MAX(0, (COLS - strlen(buff)) >> 1));
745     addstr(buff);
746     refresh();
747 }
748
749 /****************************************************/
750 show_text(row, col, buff)
751     int row, col;
752     char *buff;
753 {
754     mvcur(0, 0, row, col);
755     refresh();
756     printf("%s", buff);
757 }
758
759 /****************************************************/
760 erase_line(row, col)
761     int row, col;
762 {
763     char *buff;
764     int i;
765
766     buff = calloc((unsigned)COLS, 1);
767     for (i = 0; i <= COLS - 2; i++)
768         buff[i] = ' ';
769     buff[i] = 0;                /* just to be sure ! */
770     move(row, col);
771     mvcur(0, 0, row, col);
772     printf("%s", buff);
773     refresh();
774 }
775
776 /****************************************************/
777 cls()
778 {
779     clear();
780     refresh();
781 }
782
783 /****************************************************/
784 clrwin(erase_row)
785     int erase_row;
786 {
787     int i;
788     char *buff;
789     int maxcol;
790
791     maxcol = COLS;
792     if (maxcol > 80)
793         maxcol = 80;            /* limit width */
794
795     buff = calloc((unsigned)maxcol + 1, 1);
796     for (i = 0; i <= maxcol - 1; i++)
797         buff[i] = ' ';
798     buff[i] = 0;                /* just to be sure ! */
799     mvcur(0, 0, erase_row, STARTCOL);
800     refresh();
801     for (i = erase_row; i <= currow - 1; i++) {
802         printf("%s\n\r", buff);
803     }
804     printf("%s", buff);
805     mvcur(erase_row, STARTCOL, STARTROW + oldpos[level] - 1, STARTCOL);
806     refresh();
807 }
808
809 /****************************************************/
810
811 static int
812 scream()
813 {
814     com_err(whoami, status, "\nAn SMS update returned a value -- programmer \
815 botch\n");
816     sms_disconnect();
817     exit(1);
818     return(0);  /* to keep compiler happy */
819 }
820
821 /****************************************************/
822 /*ARGSUSED*/
823 static int 
824 fetch_list_info(list, li)
825     char *list;
826     List_info *li;
827 {
828     char *argv[1];
829
830     argv[0] = list;
831     return sms_query("get_list_info", 1, argv, get_list_info, (char *) NULL);
832 }
833
834 /* ARGSUSED */
835 static int 
836 get_list_info(argc, argv)
837     int argc;
838     char **argv;
839 {
840
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]);
859     return (0);
860 }
861
862
863
864
865 /****************************************************/
866 /* Prompt the user for input */
867 int 
868 Prompt(prompt, buf, buflen, crok)
869     char *prompt;
870     char *buf;
871     int buflen;
872     int crok;
873 {
874     int c;
875     char *p;
876
877     printf("%s", prompt);
878     refresh();
879     for (p = buf; abs(strlen(p) - strlen(buf)) <= buflen;) {
880         refresh();
881         c = getchar();
882         switch (c) {
883         case CTL('C'):
884             return 0;
885         case CTL('Z'):
886             return 0;
887         case CTL('L'):
888             cls();
889             display_menu(main_menu);
890             return (0);
891         case '\n':
892         case '\r':
893             if (crok)
894                 Put_message("\r");
895             *p = '\0';
896             if (strlen(buf) < 1)/* only \n or \r in buff */
897                 return (-1);
898             else
899                 return (1);
900         case '\b':
901         case '\177':
902             if (p > buf) {
903                 p--;
904                 printf("\b \b");
905             }
906             break;
907         case CTL('U'):
908         case CTL('G'):
909         case CTL('['):
910             while (p-- > buf)
911                 printf("\b \b");
912             p = buf;
913             break;
914         default:
915             if (abs(strlen(p) - strlen(buf)) >= buflen) {
916                 printf("%c", 7);
917                 break;
918             }
919             if (isprint(c)) {
920                 (void) addch(c);
921                 *p++ = c;
922             }
923             else
924                 (void) putchar(CTL('G'));
925             break;
926         }
927     }
928     return(0);
929 }
930
931
932 /*
933  * Hook function to cause error messages to be printed through
934  * curses instead of around it.
935  */
936
937 void
938 menu_err_hook(who, code, fmt, args)
939     const char *who;
940     long code;
941     const char *fmt;
942     va_list args;
943 {
944     char buf[BUFSIZ], *cp;
945
946     FILE _strbuf;
947
948     (void) strcpy(buf, who);
949     for (cp = buf; *cp; cp++);
950     *cp++ = ':';
951     *cp++ = ' ';
952     if (code) {
953         (void) strcpy(cp, error_message(code));
954         while (*cp)
955             cp++;
956     }
957     _strbuf._flag = _IOWRT + _IOSTRG;
958     _strbuf._ptr = cp;
959     _strbuf._cnt = BUFSIZ - (cp - buf);
960     _doprnt(fmt, args, &_strbuf);
961     (void) putc('\0', &_strbuf);
962     Put_message(buf);
963 }
This page took 1.246076 seconds and 5 git commands to generate.