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