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