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