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