]> andersk Git - moira.git/blob - clients/mailmaint/mailmaint.c
Switch from Imake-based build system to autoconf-based.
[moira.git] / clients / mailmaint / mailmaint.c
1 /* $Id$
2  *
3  * Simple add-me-to/remove-me-from list client
4  *
5  *  mailmaint.c - pjlevine - 20 August 1987
6  *
7  * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
8  * For copying and distribution information, please see the file
9  * <mit-copyright.h>.
10  */
11
12 #include <mit-copyright.h>
13 #include <moira.h>
14 #include <moira_site.h>
15
16 #include <ctype.h>
17 #ifdef HAVE_CURSES
18 #include <curses.h>
19 #endif
20 #include <pwd.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 #include <krb.h>
27
28 RCSID("$Header$");
29
30 #define STARTCOL 0
31 #define STARTROW 3
32 #define DISPROW 15
33 #define LISTMAX 50
34 #define LISTSIZE 32
35 #define CTL(ch) ((ch) & 037)
36 #define MAX(A, B) ((A) > (B) ? (A) : (B))
37
38 char *whoami;           /* should not be static, for logging package */
39 static int status;
40
41 typedef struct list_info {
42   int active;
43   int public;
44   int hidden;
45   int maillist;
46   int group;
47   char *acl_type;
48   char *acl_name;
49   char *desc;
50   char *modtime;
51   char *modby;
52   char *modwith;
53 } List_info;
54
55 static char *ascbuff = {"0123456789"};
56 static List_info *current_li = (List_info *) NULL;
57
58 typedef struct _menu {
59   int num_items;
60   char *title;
61   char **items;
62 } MENU;
63
64 MENU *main_menu, *help_menu;
65
66 int position[2], oldpos[2];
67 int level, found_some, currow, page, num_members;
68 int moreflg, toggle, first_time;
69 char *username;
70
71 void get_main_input(void);
72 void show_list_info(void);
73 void display_buff(char *buf);
74 void start_display_buff(char *buff);
75 void add_member(void);
76 void delete_member(void);
77 void list_by_member(void);
78 void show_all(void);
79 static int print_1(int argc, char *argv[], void *callback);
80 static int print_all(int argc, char *argv[], void *callback);
81 void list_all_groups(void);
82 void list_members(void);
83 static int print_2(int argc, char *argv[], void *callback);
84 void start_display(char *buff);
85 void end_display(void);
86 void display_menu(MENU *menu);
87 void pack_main_menu(void);
88 void pack_help_menu(void);
89 void highlight(MENU *menu);
90 void title(char *buff);
91 void center_text(int row, char *buff);
92 void show_text(int row, int col, char *buff);
93 void erase_line(int row, int col);
94 void cls(void);
95 void clrwin(int erase_row);
96 static int fetch_list_info(char *list, List_info *li);
97 static int get_list_info(int argc, char **argv, void *hint);
98 int Prompt(char *prompt, char *buf, int buflen, int crok);
99 void menu_err_hook(const char *who, long code, const char *fmt, va_list args);
100
101 /* This crock is because the original code was very broken and this makes
102  * it work.  Someday, we should abandon the code or fix it right.
103  */
104 #define mvcur(oy, ox, ny, nx) move(ny, nx)
105
106 /****************************************************/
107
108 int main(int argc, char *argv[])
109 {
110   void (*old_hook)(const char *, long, const char *, va_list);
111   int use_menu = 1, k_errno;
112   char buf[BUFSIZ], pname[ANAME_SZ], *motd;
113
114   if ((whoami = strrchr(argv[0], '/')) == NULL)
115     whoami = argv[0];
116   else
117     whoami++;
118   if (!(current_li = malloc(sizeof(List_info))))
119     {
120       sprintf(buf, ": allocating list info");
121       goto punt;
122     }
123   else
124     {
125       current_li->acl_type = NULL;
126       current_li->acl_name = NULL;
127       current_li->desc = NULL;
128       current_li->modtime = NULL;
129       current_li->modby = NULL;
130       current_li->modwith = NULL;
131     }
132
133   if ((k_errno = tf_init(TKT_FILE, R_TKT_FIL)) ||
134       (k_errno = tf_get_pname(pname)))
135     {
136       com_err(whoami, k_errno, "reading Kerberos ticket file");
137       exit(1);
138     }
139   tf_close();
140   username = pname;
141
142   printf("Connecting to database for %s...please hold on.\n", username);
143
144   status = mr_connect(NULL);
145   if (status)
146     {
147       sprintf(buf, "\nConnection to Moira server failed");
148       goto punt;
149     }
150
151   status = mr_motd(&motd);
152   if (status)
153     {
154       com_err(whoami, status, " unable to check server status");
155       mr_disconnect();
156       exit(2);
157     }
158   if (motd)
159     {
160       fprintf(stderr, "The Moira server is currently unavailable:\n%s\n",
161               motd);
162       mr_disconnect();
163       exit(2);
164     }
165   status = mr_auth("mailmaint");
166   if (status)
167     {
168       sprintf(buf, "\nAuthorization failed.\n");
169       goto punt;
170     }
171
172   initscr();
173   if ((LINES < 24) || (COLS < 60))
174     {
175       display_buff("Display window too small.\n\n");
176       sprintf(buf, "Current window parameters are (%d lines, %d columns)\n",
177               LINES, COLS);
178       display_buff(buf);
179       display_buff("Please resize your window\n");
180       display_buff("to at least 24 lines and 60 columns.\n");
181       exit(0);
182     }
183   raw();
184   noecho();
185   old_hook = set_com_err_hook(menu_err_hook);
186   position[0] = oldpos[0] = 1;
187   level = 0;
188   pack_main_menu();
189   pack_help_menu();
190   display_menu(main_menu);
191   get_main_input();
192   cls();
193   endwin();
194   set_com_err_hook(old_hook);
195   exit(0);
196
197 punt:
198   com_err(whoami, status, buf);
199   exit(1);
200 }
201
202 /****************************************************/
203 void get_main_input(void)
204 {
205   int c;
206   int retflg;
207
208   while (1)
209     {
210       oldpos[level] = position[level];
211       retflg = 0;
212       currow = DISPROW + 2;
213       page = 1;
214       toggle = num_members = moreflg = 0;
215       c = getchar() & 0x7f;     /* mask parity bit */
216       if (c == '\r' || c == '\n')
217         {
218           if (position[level] == 7)
219             c = 'q';
220           else
221             c = ascbuff[position[level]];
222           retflg = 1;
223         }
224       switch (c)
225         {
226         case 'L' & 037: /* clear screen */
227           display_menu(main_menu);
228           break;
229         case 'q':
230         case 'Q':               /* quit */
231           position[level] = 7;
232           highlight(main_menu);
233           if (retflg)
234             {
235               cls();
236               return;
237             }
238           break;
239         case '1':               /* show all lists */
240           position[level] = 1;
241           if (retflg)
242             show_all();
243           break;
244         case '2':               /* get all members of a list */
245           position[level] = 2;
246           if (retflg)
247             list_members();
248           break;
249         case '3':               /* display list which user is a recipient */
250           position[level] = 3;
251           if (retflg)
252             list_by_member();
253           break;
254         case '4':               /* show description */
255           position[level] = 4;
256           if (retflg)
257             show_list_info();
258           break;
259         case '5':               /* add to list */
260           position[level] = 5;
261           if (retflg)
262             add_member();
263           break;
264         case '6':               /* delete */
265           position[level] = 6;
266           if (retflg)
267             delete_member();
268           break;
269         case 27:                /* escape */
270           c = getchar() & 0x7f;
271           if (c == 91)
272             {
273               c = getchar() & 0x7f;
274               if (c == 65)      /* up arrow */
275                 {
276                   position[level]--;
277                   if (!position[level])
278                     position[level] = 7;
279                 }
280               else
281                 {
282                   if (c == 66)  /* down arrow */
283                     {
284                       position[level]++;
285                       if (position[level] > 7)
286                         position[level] = 1;
287                     }
288                 }
289             }
290           break;
291         default:
292           printf("%c", 7);
293           break;
294         }
295       highlight(main_menu);
296     }
297 }
298
299 /****************************************************/
300 void show_list_info(void)
301 {
302   char *buf;
303
304   show_text(DISPROW, STARTCOL, "Show information about a list.\n");
305   buf = calloc(1024, 1);
306   if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1)
307     {
308       display_buff("\n");
309       if (fetch_list_info(buf, current_li) == 0)
310         {
311           sprintf(buf, "Description: %s\n", current_li->desc);
312           if (strlen(buf) > 60)
313             display_buff(buf);
314           else
315             show_text(currow, STARTCOL, buf);
316           currow++;
317           sprintf(buf, "List Administrator: %s %s",
318                   current_li->acl_type, current_li->acl_name);
319           show_text(currow, STARTCOL, buf);
320           currow++;
321           sprintf(buf, "Modified on %s by user %s with %s",
322                   current_li->modtime, current_li->modby,
323                   current_li->modwith);
324           show_text(currow, STARTCOL, buf);
325           currow++;
326         }
327       else
328         {
329           show_text(currow, STARTCOL, "mailmaint: No such list found.");
330           currow++;
331         }
332       show_text(currow, STARTCOL, "Press any Key to continue...");
333       getchar();
334     }
335   clrwin(DISPROW);
336 }
337
338 /****************************************************/
339 void display_buff(char *buf)
340 {
341   int i, cnt;
342   char *printbuf;
343   int maxcol;
344
345   maxcol = COLS;
346
347   cnt = 0;
348   printbuf = calloc(maxcol, 1);
349   for (i = 0; i <= strlen(buf); i++)
350     {
351       printbuf[cnt] = buf[i];
352       cnt++;
353       if (cnt >= maxcol)
354         {
355           start_display_buff(printbuf);
356           cnt = 0;
357           free(printbuf);
358           printbuf = calloc(maxcol, 1);
359         }
360     }
361   if (strlen(buf) % maxcol != 0)
362     {
363       start_display_buff(printbuf);
364       free(printbuf);
365     }
366   return;
367 }
368
369 /****************************************************/
370 void start_display_buff(char *buff)
371 {
372   char buffer[5];
373
374   num_members++;
375   if (moreflg)
376     return;
377   if (currow >= LINES - 2)
378     {
379       page++;
380       currow++;
381       mvcur(0, 0, currow, STARTCOL);
382       refresh();
383       if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0)
384         {
385           erase_line(currow, STARTCOL);
386           show_text(currow, STARTCOL, "Flushing query...");
387           moreflg = 1;
388           return;
389         }
390       clrwin(DISPROW + 2);
391       currow = DISPROW + 2;
392       show_text(currow, STARTCOL, "continued");
393       currow++;
394     }
395   show_text(currow, STARTCOL, buff);
396   currow++;
397   return;
398 }
399
400 /****************************************************/
401 void add_member(void)
402 {
403   char *argv[3];
404   char *buf;
405
406   show_text(DISPROW, STARTCOL, "Add yourself to a list\n");
407   buf = calloc(LISTMAX, 1);
408   if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1)
409     {
410       display_buff("\n");
411       argv[0] = strdup(buf);
412       argv[1] = strdup("user");
413       argv[2] = strdup(username);
414       if ((status = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
415         {
416           display_buff("\n");
417           com_err(whoami, status, " found.\n");
418         }
419       else
420         {
421           sprintf(buf, "User %s added to list\n", username);
422           show_text(DISPROW + 3, STARTCOL, buf);
423         }
424       currow = DISPROW + 4;
425       show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
426       getchar();
427     }
428   clrwin(DISPROW);
429 }
430
431 /****************************************************/
432 void delete_member(void)
433 {
434   char *argv[3];
435   char *buf;
436
437   show_text(DISPROW, STARTCOL, "Remove yourself from a list\n");
438   buf = calloc(LISTMAX, 1);
439   if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1)
440     {
441       display_buff("\n");
442       argv[0] = strdup(buf);
443       argv[1] = strdup("user");
444       argv[2] = strdup(username);
445       if ((status = mr_query("delete_member_from_list", 3, argv, NULL, NULL)))
446         {
447           display_buff("\n");
448           com_err(whoami, status, " found.\n");
449         }
450       else
451         {
452           sprintf(buf, "User %s deleted from list\n", username);
453           show_text(DISPROW + 3, STARTCOL, buf);
454         }
455       currow = DISPROW + 4;
456       show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
457       getchar();
458     }
459   clrwin(DISPROW);
460 }
461
462 /****************************************************/
463 void list_by_member(void)
464 {
465   char *nargv[3];
466   char *buf;
467
468   nargv[1] = strdup("ruser");
469   nargv[2] = strdup(username);
470   buf = calloc(BUFSIZ, 1);
471   sprintf(buf, "%s is on the following lists:\n", username);
472   show_text(DISPROW, STARTCOL, buf);
473   mvcur(0, 0, currow, STARTCOL);
474   refresh();
475   if ((status = mr_query("get_lists_of_member", 2, nargv + 1, print_1, NULL)))
476     {
477       display_buff("\n");
478       com_err(whoami, status, " in get_lists_of_member");
479     }
480   currow++;
481   show_text(currow, STARTCOL, "Press any Key to continue...");
482   getchar();
483   clrwin(DISPROW);
484 }
485
486 /****************************************************/
487 void show_all(void)
488 {
489   char c;
490
491   show_text(DISPROW, STARTCOL, "This function may take a while... proceed? [n] ");
492   c = getchar() & 0x7f;
493   if (c == 'y' || c == 'Y')
494     {
495       move(DISPROW + 1, STARTCOL);
496       addstr("Processing query...please hold");
497       refresh();
498       list_all_groups();
499     }
500   else
501     erase_line(DISPROW, STARTCOL);
502 }
503
504 /****************************************************/
505 static int print_1(int argc, char *argv[], void *callback)
506 {
507   char buf[BUFSIZ];
508
509   /* no newline 'cause display_buff adds one */
510   sprintf(buf, "%s\n", argv[0]);
511   start_display(buf);
512
513   return MR_CONT;
514 }
515
516 /****************************************************/
517 static int print_all(int argc, char *argv[], void *callback)
518 {
519   char buf[BUFSIZ];
520
521   if (moreflg)
522     return 0;
523   if (first_time)
524     {
525       erase_line(DISPROW + 1, STARTCOL);
526       show_text(DISPROW + 1, STARTCOL, "All mailing lists:");
527       first_time = 0;
528     }
529   sprintf(buf, "%s\n", argv[0]);
530   start_display(buf);
531
532   return MR_CONT;
533 }
534
535 /****************************************************/
536 void list_all_groups(void)
537 {
538   char *argv[5];
539   argv[0] = argv[1] = argv[3] = "true";
540   argv[4] = "dontcare";
541   argv[2] = "false";
542   first_time = 1;
543   if ((status = mr_query("qualified_get_lists", 5, argv, print_all, NULL)))
544     {
545       display_buff("\n");
546       com_err(whoami, status, " in list_all_groups\n");
547     }
548   end_display();
549 }
550
551 /****************************************************/
552 void list_members(void)
553 {
554   char *argv[1];
555   char *buf;
556   char buffer[80];
557
558   found_some = 0;
559   move(DISPROW, STARTCOL);
560   mvcur(0, 0, DISPROW, STARTCOL);
561   refresh();
562   buf = calloc(LISTMAX, 1);
563   if (Prompt("Enter List Name: ", buf, LISTSIZE, 1) == 1)
564     {
565       sprintf(buffer, "The members of list '%s' are:", buf);
566       show_text(DISPROW + 1, STARTCOL, buffer);
567       argv[0] = buf;
568       if ((status = mr_query("get_members_of_list", 1, argv, print_2, NULL)))
569         {
570           display_buff("\n");
571           com_err(whoami, status, " found.\n");
572           currow++;
573         }
574       if (!found_some)
575         {
576           show_text(currow, STARTCOL, "List is empty (no members).");
577           currow++;
578           show_text(currow, STARTCOL, "Press any key to continue...");
579           getchar();
580           clrwin(DISPROW);
581           return;
582         }
583       end_display();
584       return;
585     }
586   clrwin(DISPROW);
587 }
588
589 /****************************************************/
590 static int print_2(int argc, char *argv[], void *callback)
591 {
592   char buf[BUFSIZ];
593
594   found_some = 1;
595   sprintf(buf, "%s %s", argv[0], argv[1]);
596   start_display(buf);
597
598   return MR_CONT;
599 }
600
601 /****************************************************/
602 void start_display(char *buff)
603 {
604   char *buffer;
605   int secondcol;   /* where to start the second column of text */
606
607   secondcol = (COLS / 2);  /* 1/2 was accross the screen */
608   num_members++;
609   if (moreflg)
610     return;
611   buffer = calloc(50, 1);
612   if (currow >= LINES - 2)
613     {
614       page++;
615       mvcur(0, 0, currow, STARTCOL);
616       refresh();
617       if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1, 0) == 0)
618         {
619           erase_line(currow, STARTCOL);
620           show_text(currow, STARTCOL, "Flushing query...");
621           moreflg = 1;
622           return;
623         }
624       clrwin(DISPROW + 2);
625       currow = DISPROW + 2;
626       sprintf(buffer, "Continued (Page %d)", page);
627       show_text(currow, STARTCOL, buffer);
628       currow++;
629       toggle = 0;
630     }
631   if (!toggle)
632     show_text(currow, STARTCOL, buff);
633   else
634     {
635       erase_line(currow, secondcol - 1);  /* in case the 1st col is too long */
636       show_text(currow, secondcol, buff);
637       currow++;
638     }
639   toggle = !toggle;
640 }
641
642 /****************************************************/
643 void end_display(void)
644 {
645   char *buffer;
646
647   if (moreflg)
648     {
649       clrwin(DISPROW);
650       return;
651     }
652
653   buffer = calloc(50, 1);
654   currow++;
655   sprintf(buffer, "End of List. %d Total Members\n", num_members - 1);
656   show_text(currow, STARTCOL, buffer);
657   currow++;
658   show_text(currow, STARTCOL, "Press any key to continue...");
659   getchar();
660   clrwin(DISPROW);
661 }
662
663 /****************************************************/
664 void display_menu(MENU *menu)
665 {
666   int i;
667
668   cls();
669   title(menu->title);
670   mvcur(0, 0, STARTROW, STARTCOL);
671   refresh();
672   for (i = 0; i <= menu->num_items - 1; i++)
673     {
674       move(STARTROW + i, STARTCOL);
675       standend();
676       addstr(menu->items[i]);
677       refresh();
678     }
679   center_text(STARTROW + menu->num_items + 2,
680               "Enter a number, <up arrow>, or <down arrow>.");
681   if (!level)
682     {
683       center_text(STARTROW + menu->num_items + 3,
684                   "Press 'q' to exit, <return> to confirm choice.");
685     }
686   else
687     {
688       center_text(STARTROW + menu->num_items + 3,
689                   "Press 'q' to exit, 'r' for main menu, "
690                   "<return> to confirm choice.");
691     }
692
693   if (!level)
694     highlight(main_menu);
695 }
696
697 /****************************************************/
698 void pack_main_menu(void)
699 {
700   char *buf;
701
702   main_menu = malloc(sizeof(MENU));
703   main_menu->num_items = 7;
704   main_menu->items = malloc(sizeof(char *) * main_menu->num_items);
705
706   buf = calloc(50, 1);
707   sprintf(buf, "Mail List Program for %s", username);
708   main_menu->title = strdup(buf);
709   main_menu->items[0] = strdup("1.  Show all public mailing lists.");
710   main_menu->items[1] = strdup("2.  Get all members of a mailing list.");
711   main_menu->items[2] = strdup("3.  Display lists of which you are a member.");
712   main_menu->items[3] = strdup("4.  Show description of list.");
713   main_menu->items[4] = strdup("5.  Add yourself to a mailing list.");
714   main_menu->items[5] = strdup("6.  Delete yourself from a mailing list.");
715   main_menu->items[6] = strdup("q.  Quit.");
716 }
717
718 /****************************************************/
719 void pack_help_menu(void)
720 {
721   help_menu = malloc(sizeof(MENU));
722   help_menu->num_items = 5;
723   help_menu->items = malloc(sizeof(char *) * help_menu->num_items);
724
725   help_menu->title = strdup("mailmaint is designed as a basic mail list administration program.");
726   help_menu->items[0] = strdup("if you need to perform more advanced list manipulation like");
727   help_menu->items[1] = strdup("adding lists, or changing list characteristics, refer to the");
728   help_menu->items[2] = strdup("program listmaint.");
729   help_menu->items[3] = strdup(" ");
730   help_menu->items[4] = strdup("Press any key to continue.");
731 }
732
733 /****************************************************/
734 void highlight(MENU *menu)
735 {
736   if (oldpos[level] != position[level])
737     {
738       move(STARTROW + oldpos[level] - 1, STARTCOL);
739       standend();
740       addstr(menu->items[oldpos[level] - 1]);
741       refresh();
742     }
743
744   move(STARTROW + position[level] - 1, STARTCOL);
745   standout();
746   addstr(menu->items[position[level] - 1]);
747   refresh();
748   standend();
749   refresh();
750 }
751
752 /****************************************************/
753 void title(char *buff)
754 {
755   move(0, MAX(0, (COLS - strlen(buff)) >> 1));
756   standout();
757   addstr(buff);
758   refresh();
759   standend();
760 }
761
762 /****************************************************/
763 void center_text(int row, char *buff)
764 {
765   move(row, MAX(0, (COLS - strlen(buff)) >> 1));
766   addstr(buff);
767   refresh();
768 }
769
770 /****************************************************/
771 void show_text(int row, int col, char *buff)
772 {
773   mvcur(0, 0, row, col);
774   addstr(buff);
775   refresh();
776 }
777
778 /****************************************************/
779 void erase_line(int row, int col)
780 {
781   char *buff;
782   int i;
783
784   buff = calloc(COLS, 1);
785   for (i = 0; i <= COLS - 2; i++)
786     buff[i] = ' ';
787   buff[i] = 0;          /* just to be sure ! */
788   move(row, col);
789   mvcur(0, 0, row, col);
790   addstr(buff);
791   refresh();
792   free(buff);  /* close mem. leak */
793 }
794
795 /****************************************************/
796 void cls(void)
797 {
798   clear();
799   refresh();
800 }
801
802 /****************************************************/
803 void clrwin(int erase_row)
804 {
805   int i;
806   char *buff;
807   int maxcol;
808
809   maxcol = COLS;
810
811   buff = calloc(maxcol + 1, 1);
812   for (i = 0; i <= maxcol - 1; i++)
813     buff[i] = ' ';
814   buff[i] = 0;          /* just to be sure ! */
815   mvcur(0, 0, erase_row, STARTCOL);
816   refresh();
817   for (i = erase_row; i <= currow - 1; i++)
818     addstr(buff);
819   addstr(buff);
820   mvcur(erase_row, STARTCOL, STARTROW + oldpos[level] - 1, STARTCOL);
821   refresh();
822   free(buff);
823 }
824
825 /****************************************************/
826 static int fetch_list_info(char *list, List_info *li)
827 {
828   char *argv[1];
829
830   argv[0] = list;
831   return mr_query("get_list_info", 1, argv, get_list_info, NULL);
832 }
833
834 static int get_list_info(int argc, char **argv, void *hint)
835 {
836   if (current_li->acl_type)
837     free(current_li->acl_type);
838   current_li->acl_type = strdup(argv[7]);
839   if (current_li->acl_name)
840     free(current_li->acl_name);
841   current_li->acl_name = strdup(argv[8]);
842   if (current_li->desc)
843     free(current_li->desc);
844   current_li->desc = strdup(argv[9]);
845   if (current_li->modtime)
846     free(current_li->modtime);
847   current_li->modtime = strdup(argv[10]);
848   if (current_li->modby)
849     free(current_li->modby);
850   current_li->modby = strdup(argv[11]);
851   if (current_li->modwith)
852     free(current_li->modwith);
853   current_li->modwith = strdup(argv[12]);
854   return MR_CONT;
855 }
856
857
858 /****************************************************/
859 /* Prompt the user for input */
860 int Prompt(char *prompt, char *buf, int buflen, int crok)
861 {
862   int c;
863   char *p;
864
865   addstr(prompt);
866   refresh();
867   for (p = buf; abs(strlen(p) - strlen(buf)) <= buflen;)
868     {
869       refresh();
870       c = getchar() & 0x7f;
871       switch (c)
872         {
873         case CTL('C'):
874           return 0;
875         case CTL('Z'):
876           return 0;
877         case CTL('L'):
878           cls();
879           display_menu(main_menu);
880           return 0;
881         case '\n':
882         case '\r':
883           if (crok)
884             display_buff("\n");
885           *p = '\0';
886           if (strlen(buf) < 1)  /* only \n or \r in buff */
887             return -1;
888           else
889             return 1;
890         case '\b':
891         case '\177':
892           if (p > buf)
893             {
894               p--;
895               printf("\b \b");
896             }
897           break;
898         case CTL('U'):
899         case CTL('G'):
900         case CTL('['):
901           while (p-- > buf)
902             printf("\b \b");
903           p = buf;
904           break;
905         default:
906           if (abs(strlen(p) - strlen(buf)) >= buflen)
907             {
908               printf("%c", 7);
909               break;
910             }
911           if (isprint(c))
912             {
913               addch(c);
914               *p++ = c;
915             }
916           else
917             putchar(CTL('G'));
918           break;
919         }
920     }
921   return 0;
922 }
923
924
925 /*
926  * Hook function to cause error messages to be printed through
927  * curses instead of around it.
928  */
929
930 void menu_err_hook(const char *who, long code, const char *fmt, va_list args)
931 {
932   char buf[BUFSIZ], *cp;
933
934   strcpy(buf, who);
935   for (cp = buf; *cp; cp++)
936     ;
937   *cp++ = ':';
938   *cp++ = ' ';
939   if (code)
940     {
941       strcpy(cp, error_message(code));
942       while (*cp)
943         cp++;
944     }
945   vsprintf(cp, fmt, args);
946   display_buff(buf);
947 }
This page took 0.109658 seconds and 5 git commands to generate.