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