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