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