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