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