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