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