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