1 
2 static char rcsid[] = "@(#)$Id: options.c,v 1.5 1996/03/14 17:29:43 wfp5p Exp $";
3 
4 /*******************************************************************************
5  *  The Elm Mail System  -  $Revision: 1.5 $   $State: Exp $
6  *
7  * 			Copyright (c) 1986,1987 Dave Taylor
8  *                      Copyright (c) 1988-1995 USENET Community Trust
9  *******************************************************************************
10  * Bug reports, patches, comments, suggestions should be sent to:
11  *
12  *      Bill Pemberton, Elm Coordinator
13  *      flash@virginia.edu
14  *
15  *******************************************************************************
16  * $Log: options.c,v $
17  * Revision 1.5  1996/03/14  17:29:43  wfp5p
18  * Alpha 9
19  *
20  * Revision 1.4  1995/09/29  17:42:19  wfp5p
21  * Alpha 8 (Chip's big changes)
22  *
23  * Revision 1.3  1995/07/18  19:00:00  wfp5p
24  * Alpha 6
25  *
26  * Revision 1.2  1995/04/26  15:23:17  wfp5p
27  * If DONT_ADD_FROM is defined the Your name option doesn't do anything so it
28  * now doesn't show up (from Larry Schwimmer <rosebud@cyclone.Stanford.EDU>).
29  *
30  * There were a couple places in mailmsg2 that strincmp was called with only 2
31  * parameters.
32  *
33  * Revision 1.1.1.1  1995/04/19  20:38:37  wfp5p
34  * Initial import of elm 2.4 PL0 as base for elm 2.5.
35  *
36  ******************************************************************************/
37 
38 /** This set of routines allows the alteration of a number of paramaters
39     in the Elm mailer, including the following;
40 
41 
42     a)  arrow-cursor	<on or off>
43     b)  border for copy <string for left margin>
44     c)  calendar-file	<where to put calendar entries>
45     d)  display pager	<how to page messages>
46     e)  editor		<name of primary editor or "builtin">
47     f)  folder-dir	<folder directory>
48     h)  hold sent msgs  <on or off>
49   * i) (internal: quit to index screen)
50     j)  reply editor    <name of editor for replies>
51     k)  pause pager     <on or off>
52     l)  alias sort      <how to sort the alias display>
53     m)  menu-display    <on or off>
54     n)  names-only      <on or off>
55     o)  sent-mail	<file to save outbound message copies to>
56     p)  printmail	<how to print messages>
57   * q) (internal: quit to previous screen)
58     r)  reply copy      <on or off>
59     s)  sort-by		<how to sort folders>
60     t)  text editor     <name of ~e editor>
61     u)  user-level	<BEGINNER|INTERMEDIATE|EXPERT>
62     v)  visual editor	<name of ~v editor>
63     w)  want CC prompt  <on or off>
64   * x) (internal: exit ELM now)
65     y)  full_username	<your full user name for outgoing mail>
66     z)  zap sign dashes <on or off>
67 
68     And others as they seem useful.
69 
70     Formatting parameters:
71 
72     _)		Add a blank line
73     ^)		Put the title on this line
74 
75     A subset of the above parameters may be selected as the
76     o)ptions screen using the parameter "configoptions" which is
77     a string of letters representing the "key" letter for each
78     item as listed above.  The current default is "^_cdefsopyv_am_un".
79     The order of the options displayed is as listed in the string.
80 
81 **/
82 
83 #include "elm_defs.h"
84 #include "elm_globals.h"
85 #include "save_opts.h"
86 #include "s_elm.h"
87 
88 #undef onoff
89 #define   onoff(n)	(n == 1? on_name : off_name)
90 
91 #ifdef ENABLE_CALENDAR
92 # ifdef DONT_ADD_FROM
93 #define CONFIG_OPTIONS "^_cdefsopv_am_un"
94 # else
95 #define CONFIG_OPTIONS "^_cdefsopyv_am_un"
96 # endif
97 #else
98 # ifdef DONT_ADD_FROM
99 #define CONFIG_OPTIONS "^_defsopv_am_un"
100 # else
101 #define CONFIG_OPTIONS "^_defsopyv_am_un"
102 # endif
103 #endif
104 
105 
106 extern char *alias_sort_name(), *sort_name();
107 
108 char *level_name();
109 static char *on_name = NULL;
110 static char *off_name = NULL;
111 static int resort = 0;
112 
113 
post_cal(f)114 static post_cal(f)
115 int f;
116 {
117     (void) expand_env(calendar_file, raw_calendar_file, sizeof(calendar_file));
118 }
119 
post_editor(f)120 static post_editor(f)
121 int f;
122 {
123     (void) expand_env(editor, raw_editor, sizeof(editor));
124 }
125 
post_pager(f)126 static post_pager(f)
127 int f;
128 {
129     (void) expand_env(pager, raw_pager, sizeof(pager));
130     clear_pages = (streq(pager, "builtin+") || streq(pager, "internal+"));
131 }
132 
post_folder(f)133 static post_folder(f)
134 int f;
135 {
136     (void) expand_env(folders, raw_folders, sizeof(folders));
137 }
138 
post_sort(f)139 static post_sort(f)
140 int f;
141 {
142     if (f)
143 	resort++;
144 }
145 
post_sent(f)146 static post_sent(f)
147 int f;
148 {
149     (void) expand_env(sent_mail, raw_sentmail, sizeof(sent_mail));
150 }
151 
post_print(f)152 static post_print(f)
153 int f;
154 {
155     (void) expand_env(printout, raw_printout, sizeof(printout));
156 }
157 
post_menu(f)158 static post_menu(f)
159 int f;
160 {
161     headers_per_page = LINES - (mini_menu ? 13 : 8);
162 }
163 
164 opts_menu cfg_opts[] = {
165 
166 {'a', "A)rrow cursor",	ElmOptionArrowMenu,  "arrow",	NULL,
167 "This defines whether the ELM cursor is an arrow or a highlight bar.", ElmOptionArrowHelp},
168 
169 {'b', "B)order on copy", ElmOptionBorderMenu,	"prefix",	NULL,
170 "Left margin string (prefix) for reply and forward.", ElmOptionBorderHelp},
171 
172 #ifdef ENABLE_CALENDAR
173 {'c', "C)alendar file", ElmOptionCalendarMenu,	"calendar",	post_cal,
174 "This is the file where calendar entries from messages are saved.", ElmOptionCalendarHelp},
175 #endif
176 
177 {'d', "D)isplay mail using", ElmOptionDisplayMenu,	"pager",	post_pager,
178 "This is the program invoked to display individual messages (try 'builtin').", ElmOptionDisplayHelp},
179 
180 {'e', "E)ditor (primary)", ElmOptionEditorMenu,	"editor",	post_editor,
181 "This is the editor used for all outbound messages (may be 'builtin').", ElmOptionEditorHelp},
182 
183 {'f', "F)older directory", ElmOptionFolderMenu,	"maildir",	post_folder,
184 "This is the folders directory used when '=' (etc) is used in filenames.", ElmOptionFolderHelp},
185 
186 {'h', "H)old sent message", ElmOptionHoldMenu,	"copy",		NULL,
187 "Whether to save a copy of outbound messages in O)utbound folder.", ElmOptionHoldHelp},
188 
189 {'j', "J) reply editor", ElmOptionJreplyMenu,	"alteditor",	NULL,
190 "This is the editor that will be used for replies (Editor=\"builtin\").", ElmOptionJreplyHelp},
191 
192 {'k', "K) pause after pager", ElmOptionKpauseMenu, "promptafter",	NULL,
193 "Whether to pause (prompt) at end of message with display message pager.", ElmOptionKpauseHelp},
194 
195 {'l', "A(l)ias Sorting", ElmOptionaLiasMenu,	"aliassortby",	post_sort,
196 "This is used to specify the sorting criteria for the alias display.", ElmOptionaLiasHelp},
197 
198 {'m', "M)enu display", ElmOptionMenuMenu,	"menu",		post_menu,
199 "This determines if you have the mini-menu displayed or not.", ElmOptionMenuHelp},
200 
201 {'n', "N)ames only", ElmOptionNameMenu,		"names",	NULL,
202 "Whether to display the names and addresses on mail, or names only.", ElmOptionNameHelp},
203 
204 {'o', "O)utbound mail saved", ElmOptionOutboundMenu, "sentmail",	post_sent,
205 "This is where copies of outbound messages are saved automatically.", ElmOptionOutboundHelp},
206 
207 {'p', "P)rint mail using", ElmOptionPrintMenu,	"print",	post_print,
208 "This is the command used to print mail messages.", ElmOptionPrintHelp},
209 
210 {'r', "R)eply copies msg", ElmOptionReplyMenu,	"replycopy",	NULL,
211 "Whether to copy the message being replied to into the reply.", ElmOptionReplyHelp},
212 
213 {'s', "S)orting criteria", ElmOptionSortMenu,	"sortby",	post_sort,
214 "This is used to specify the sorting criteria for the folders.", ElmOptionSortHelp},
215 
216 {'t', "T)ext editor (~e)", ElmOptionTextMenu,	"easyeditor",	NULL,
217 "This is the editor that will be used by the ~e command (Editor=\"builtin\").", ElmOptionTextHelp},
218 
219 {'u', "U)ser level", ElmOptionUserMenu,		"userlevel",	NULL,
220 "The level of knowledge you have about the ELM mail system.", ElmOptionUserHelp},
221 
222 {'v', "V)isual Editor (~v)", ElmOptionVisualMenu,	"visualeditor",	NULL,
223 "This is the editor that will be used by the ~v command (Editor=\"builtin\").", ElmOptionVisualHelp},
224 
225 {'w', "W)ant Cc: prompt", ElmOptionWantMenu,	"askcc",	NULL,
226 "Whether to ask for \"Copies to:\" list when sending messages.", ElmOptionWantHelp},
227 
228 {'y', "Y)our full name", ElmOptionYourMenu,	"fullname",	NULL,
229 "When mail is sent out, this is what your full name will be recorded as.", ElmOptionYourHelp},
230 
231 {'z', "Z) signature dashes", ElmOptionZdashMenu,	"sigdashes",	NULL,
232 "Whether to print dashes before including signature on outbound messages.", ElmOptionZdashHelp},
233 
234 { 0 } };
235 
init_opts_menu()236 void init_opts_menu()
237 {
238 	register char *c;
239 	register opts_menu *o;
240 
241 	/* FOO - this is breaking my catgets scanner */
242 	for (o = cfg_opts; o->parm; o++) {
243 		c = catgets(elm_msg_cat, ElmSet, o->menu_msg, "~");
244 		if (*c != '~')
245 			o->menu = c;
246 
247 		c = catgets(elm_msg_cat, ElmSet, o->one_liner_msg, "~");
248 		if (*c != '~')
249 			o->one_liner = c;
250 	}
251 }
252 
253 
254 opts_menu *
find_cfg_opts(c)255 find_cfg_opts(c)
256 int c;
257 {
258 	register opts_menu *o;
259 
260 	for (o = cfg_opts; o->parm; o++) {
261 	if (c == o->letter)
262 	    break;
263     }
264 
265     return(o->parm ? o : NULL);
266 }
267 
268 
269 char *
one_liner_for(c)270 one_liner_for(c)
271 char c;
272 {
273     opts_menu *o;
274 
275     o = find_cfg_opts(c);
276 
277     if (o)
278 	return(o->one_liner);
279     else
280 	return(NULL);
281 }
282 
283 
284 void
display_options()285 display_options()
286 {
287 	/** Display all the available options.. **/
288 
289 	int printed_title = FALSE;
290 	register int y;
291 	register opts_menu *o;
292 	register char *s;
293 	char buf[SLEN];
294 	extern char *str_opt_nam();
295 
296 	ClearScreen();
297 
298 	for (s = config_options, y = 0; *s; s++, y++) {
299 	    if (*s == '^') {
300 		printed_title = TRUE;
301 		CenterLine(y, catgets(elm_msg_cat, ElmSet, ElmOptionsEditor,
302 		    "-- ELM Options Editor --"));
303 		continue;
304 	    }
305 	    if (*s == '_') {
306 		continue;
307 	    }
308             o = find_cfg_opts(*s);
309             if (o != NULL && y<LINES-5) {
310 		sprintf(buf,"%-20.20s : %%s", o->menu);
311 		PutLine1(y, 0, buf, str_opt_nam(o->parm, TRUE));
312 	    }
313 	}
314 	if (!printed_title) {
315 	    CenterLine(LINES-5, catgets(elm_msg_cat, ElmSet, ElmOptionsEditor,
316 		"-- ELM Options Editor --"));
317 	}
318 }
319 
320 
321 void
options_help()322 options_help()
323 {
324 	/** help menu for the options screen... **/
325 
326 	char	*ptr, *prompt;
327 	int	c;
328 
329 	ClearLine(LINES-2);		/* clear option prompt message */
330 	CenterLine(LINES-3, catgets(elm_msg_cat, ElmSet, ElmPressKeyHelp,
331   "Press the key you want help for, '?' for a key list, or '.' to exit help"));
332 
333 	lower_prompt(prompt = catgets(elm_msg_cat, ElmSet, ElmKeyPrompt, "Key : "));
334 
335 	while ((c = ReadCh()) != '.') {
336 
337 	  c = tolower(c);
338 
339 	  if (c == '?') {
340 	     display_helpfile("options");
341 	     display_options();
342 	     return;
343 	  }
344 
345 	  if ((ptr = one_liner_for(c)) != NULL)
346 	    error2("%c = %s", c, ptr);
347 	  else
348 	    switch (c) {
349 	      case ctrl('L'): error(catgets(elm_msg_cat, ElmSet,
350 				  ElmOptionCtrlLHelp,
351 				  "^L = Rewrite the screen."));		break;
352 
353 	      case '>' : error(catgets(elm_msg_cat, ElmSet,ElmOptionGreaterHelp,
354 				"> = Save to elmrc file."));		break;
355 
356 	      case 'q' :
357 	      case 'i' : error(catgets(elm_msg_cat, ElmSet, ElmOptionReturnHelp,
358 				"i,q = Return from option menu."));	break;
359 
360 	      case 'x' : error(catgets(elm_msg_cat, ElmSet, ElmHelpQuickExit,
361 				"X = Exit leaving the folder untouched, unconditionally."));
362 				break;
363 
364 	      default: error(catgets(elm_msg_cat, ElmSet, ElmKeyIsntUsed,
365 				"That key isn't used in this section."));
366 	    }
367 	  lower_prompt(prompt);
368 	}
369 	ClearLine(LINES-3);		/* clear Press help key message */
370 	ClearLine(LINES-1);		/* clear lower prompt message */
371 }
372 
373 
374 char *
level_name(n)375 level_name(n)
376 int n;
377 {
378 	/** return the 'name' of the level... **/
379 
380 	switch (n) {
381 	  case 0 : return(catgets(elm_msg_cat, ElmSet, ElmBeginningUser,
382 			"Beginning User   "));
383 	  case 1 : return(catgets(elm_msg_cat, ElmSet, ElmIntermediateUser,
384 			"Intermediate User"));
385 	  default: return(catgets(elm_msg_cat, ElmSet, ElmExpertUser,
386 			"Expert User      "));
387 	}
388 }
389 
390 int
options()391 options()
392 {
393 	/** change options... **/
394 	/* return:
395 	 *	> 0	if resort was done - to indicate we might need to
396 	 *	 	change the page of our headers as a consequence
397 	 *		of the new sort order
398 	 *	0	otherwise
399 	 */
400 
401 	int ch;
402 	char *opos;
403 
404 	if (on_name == NULL) {
405 		on_name = catgets(elm_msg_cat, ElmSet, ElmOn, "ON ");
406 		off_name = catgets(elm_msg_cat, ElmSet, ElmOff, "OFF");
407 	}
408 	if (!config_options[0]) {
409 	    strcpy(config_options,CONFIG_OPTIONS);
410 	}
411 
412 	resort = 0;
413 	display_options();
414 
415 	while(1) {
416 
417 	  ClearLine(LINES-4);
418 	  CenterLine(LINES-4, catgets(elm_msg_cat, ElmSet, ElmSelectOptionLetter,
419  "Select letter of option line, '>' to save, or 'i' to return to index."));
420 
421 	  ClearLine(LINES-2);
422 	  PutLine0(LINES-2, 0, catgets(elm_msg_cat, ElmSet, ElmPrompt,
423 		"Command: "));
424 	  ch = ReadCh();
425 	  ch = tolower(ch);
426 	  clear_error();
427 
428 	  if ((opos = index(config_options, ch)) != NULL) {
429 	      int y = opos - config_options;
430 	      opts_menu *o = find_cfg_opts(ch);
431               if (o != NULL && y < LINES-5) {
432 		  one_liner(o->one_liner);
433 		  y = info_enter(o->parm, y, 23);
434 		  if (o->post)
435 		      (o->post)(y);
436 	      } else {
437 	          error(catgets(elm_msg_cat, ElmSet, ElmCommandUnknown,
438 			"Command unknown!"));
439 	      }
440 	      continue;
441 	  }
442 
443 	  one_liner(NULL);
444 	  switch (ch) {
445 
446 	  case '?':
447 	    options_help();
448 	    break;
449 
450 	  case '>':
451 	    PutLine0(-1, -1, catgets(elm_msg_cat, ElmSet, ElmSaveOptions,
452 		  "Save options in .elm/elmrc..."));
453 	    FlushOutput();
454 	    save_options();
455 	    break;
456 
457 	  case 'x':
458 	    quit_abandon(TRUE);
459 	    break;
460 
461 	  case 'q':
462 	  case 'i' :
463 	    return (resort ? 1 : 0);
464 
465 	  case ctrl('L'):
466 	    display_options();
467 	    break;
468 
469 	  default:
470 	    error(catgets(elm_msg_cat, ElmSet, ElmCommandUnknown,
471 		  "Command unknown!"));
472 	  }
473 
474 	}
475 
476 	/*NOTREACHED*/
477 }
478 
479 
480 
on_or_off(var,x,y)481 on_or_off(var, x, y)
482 int *var, x,y;
483 {
484 	/** 'var' field at x.y toggles between on and off... **/
485 
486 	int ch;
487 
488      	PutLine0(x, y+6, catgets(elm_msg_cat, ElmSet, ElmUseSpaceToToggle,
489 		"(use <space> to toggle, any other key to leave)"));
490 
491 	MoveCursor(x,y+3);	/* at end of value... */
492 
493 	do {
494 	  ch = ReadCh();
495 
496 	  if (ch == ' ') {
497 	    *var = ! *var;
498 	    PutLine0(x,y, onoff(*var));
499 	  }
500 	} while (ch == ' ');
501 
502 	MoveCursor(x,y+4); 	CleartoEOLN();	/* remove help prompt */
503 }
504 
505 
switch_user_level(ulevel,x,y)506 switch_user_level(ulevel, x, y)
507 int *ulevel, x, y;
508 {
509 	/** step through possible user levels... **/
510 
511      	PutLine0(x, y+20, catgets(elm_msg_cat, ElmSet, ElmSpaceToChange,
512 		"<space> to change"));
513 
514 	MoveCursor(x,y);	/* at end of value... */
515 
516 	while (ReadCh() == ' ') {
517 	  *ulevel = (*ulevel >= 2? 0 : *ulevel + 1);
518 	  PutLine1(x,y, "%s", level_name(*ulevel));
519 	}
520 
521 	MoveCursor(x,y+20); 	CleartoEOLN();	/* remove help prompt */
522 }
523 
524 
change_sort(var,x,y)525 change_sort(var, x, y)
526 int *var;
527 int x,y;
528 {
529 	/** change the sorting scheme... **/
530 	/** return !0 if new sort order, else 0 **/
531 
532 	int last_sortby,	/* so we know if it changes... */
533 	    sign = 1;		/* are we reverse sorting??    */
534 	int ch;			/* character typed in ...      */
535 
536 /*	*var = sortby; 	or...	*var == sortby; 	*/
537 	last_sortby = sortby;	/* remember current ordering   */
538 
539 	PutLine0(x, COLS-29, catgets(elm_msg_cat, ElmSet, ElmSpaceForNext,
540 		"(SPACE for next, or R)everse)"));
541 	sort_one_liner(sortby);
542 	MoveCursor(x, y);
543 
544 	do {
545 	  ch = ReadCh();
546 	  ch = tolower(ch);
547 	  switch (ch) {
548 	    case ' ' : if (sortby < 0) {
549 	    		   sign = -1;
550 	    		   sortby = - sortby;
551 	  		 }
552 			 else sign = 1;		/* insurance! */
553 	  		 sortby = sign * ((sortby + 1) % (STATUS+2));
554 			 if (sortby == 0) sortby = sign;  /* snicker */
555 	  		 PutLine1(x, y, "%-24s", sort_name(TRUE));
556 			 sort_one_liner(sortby);
557 	  		 MoveCursor(x, y);
558 			 break;
559 
560 	    case 'r'   : sortby = - sortby;
561 	  		 PutLine1(x, y, "%-24s", sort_name(TRUE));
562 			 sort_one_liner(sortby);
563 	  		 MoveCursor(x, y);
564 	 }
565         } while (ch == ' ' || ch == 'r');
566 
567 	MoveCursor(x, COLS-30);	CleartoEOLN();
568 
569 	if (sortby != last_sortby) {
570 	  error(catgets(elm_msg_cat, ElmSet, ElmResortingFolder,
571 		"Resorting folder..."));
572 	  if (sleepmsg > 0)
573 		sleep((sleepmsg + 1) / 2);
574 	  sort_mailbox(curr_folder.num_mssgs, 0);
575 	}
576 	ClearLine(LINES-2);		/* clear sort_one_liner()! */
577 	*var=sortby;
578 	sortby=last_sortby;
579 	return(*var-sortby);
580 }
581 
582 
one_liner(string)583 one_liner(string)
584 char *string;
585 {
586 	/** A single-line description of the selected item... **/
587 
588 	ClearLine(LINES-4);
589 	if (string)
590 		CenterLine(LINES-4, string);
591 }
592 
593 
sort_one_liner(sorting_by)594 sort_one_liner(sorting_by)
595 int sorting_by;
596 {
597 	/** A one line summary of the particular sorting scheme... **/
598 
599 	ClearLine(LINES-2);
600 
601 	switch (sorting_by) {
602 
603 	  case REVERSE SENT_DATE:	CenterLine(LINES-2,
604 				catgets(elm_msg_cat, ElmSet, ElmSortRSentDate,
605 "This sort will order most-recently-sent to least-recently-sent"));
606 				break;
607 	  case REVERSE RECEIVED_DATE:	CenterLine(LINES-2,
608 				catgets(elm_msg_cat, ElmSet, ElmSortRRecvDate,
609 "This sort will order most-recently-received to least-recently-received"));
610 				break;
611 	  case REVERSE MAILBOX_ORDER:	CenterLine(LINES-2,
612 				catgets(elm_msg_cat, ElmSet, ElmSortRMailbox,
613 "This sort will order most-recently-added-to-folder to least-recently"));
614 				break;
615 	  case REVERSE SENDER:		CenterLine(LINES-2,
616 				catgets(elm_msg_cat, ElmSet, ElmSortRSender,
617 "This sort will order by sender name, in reverse alphabetical order"));
618 				break;
619 	  case REVERSE SIZE:		CenterLine(LINES-2,
620 				catgets(elm_msg_cat, ElmSet, ElmSortRSize,
621 "This sort will order messages by longest to shortest"));
622 				break;
623 	  case REVERSE SUBJECT:		CenterLine(LINES-2,
624 				catgets(elm_msg_cat, ElmSet, ElmSortRSubject,
625 "This sort will order by subject, in reverse alphabetical order"));
626 				break;
627 	  case REVERSE STATUS:		CenterLine(LINES-2,
628 				catgets(elm_msg_cat, ElmSet, ElmSortRStatus,
629 "This sort will order by reverse status - Deleted through Tagged..."));
630 				break;
631 	  case SENT_DATE:		CenterLine(LINES-2,
632 				catgets(elm_msg_cat, ElmSet, ElmSortSentDate,
633 "This sort will order least-recently-sent to most-recently-sent"));
634 				break;
635 	  case RECEIVED_DATE:		CenterLine(LINES-2,
636 				catgets(elm_msg_cat, ElmSet, ElmSortRecvDate,
637 "This sort will order least-recently-received to most-recently-received"));
638 				break;
639 	  case MAILBOX_ORDER:		CenterLine(LINES-2,
640 				catgets(elm_msg_cat, ElmSet, ElmSortMailbox,
641 "This sort will order least-recently-added-to-folder to most-recently"));
642 				break;
643 	  case SENDER:			CenterLine(LINES-2,
644 				catgets(elm_msg_cat, ElmSet, ElmSortSender,
645 "This sort will order by sender name"));
646 				break;
647 	  case SIZE:			CenterLine(LINES-2,
648 				catgets(elm_msg_cat, ElmSet, ElmSortSize,
649 "This sort will order messages by shortest to longest"));
650 				break;
651 	  case SUBJECT:			CenterLine(LINES-2,
652 				catgets(elm_msg_cat, ElmSet, ElmSortSubject,
653 "This sort will order messages by subject"));
654 				break;
655 	  case STATUS:			CenterLine(LINES-2,
656 				catgets(elm_msg_cat, ElmSet, ElmSortStatus,
657 "This sort will order by status - Tagged through Deleted..."));
658 				break;
659 	}
660 }
661 
662 
663 
change_alias_sort(var,x,y)664 change_alias_sort(var, x, y)
665 int *var;
666 int x,y;
667 {
668 	/** change the sorting scheme... **/
669 	/** return !0 if new sort order, else 0 **/
670 
671 	int last_sortby,	/* so we know if it changes... */
672 	    sign = 1;		/* are we reverse sorting??    */
673 	int ch;			/* character typed in ...      */
674 
675 /*	*var = alias_sortby; 	or...	*var == alias_sortby; 	*/
676 	last_sortby = alias_sortby;	/* remember current ordering   */
677 
678 	PutLine0(x, COLS-29, catgets(elm_msg_cat, ElmSet, ElmSpaceForNext,
679 		"(SPACE for next, or R)everse)"));
680 	alias_sort_one_liner(alias_sortby);
681 	MoveCursor(x, y);
682 
683 	do {
684 	  ch = ReadCh();
685 	  ch = tolower(ch);
686 	  switch (ch) {
687 	    case ' ' : if (alias_sortby < 0) {
688 	    		   sign = -1;
689 	    		   alias_sortby = - alias_sortby;
690 	  		 }
691 			 else sign = 1;		/* insurance! */
692 	  		 alias_sortby = sign * ((alias_sortby + 1)
693 	                                % (LAST_ALIAS_SORT+1));
694 			 if (alias_sortby == 0) alias_sortby = sign;
695 	  		 PutLine1(x, y, "%-24s", alias_sort_name(TRUE));
696 			 alias_sort_one_liner(alias_sortby);
697 	  		 MoveCursor(x, y);
698 			 break;
699 
700 	    case 'r'   : alias_sortby = - alias_sortby;
701 	  		 PutLine1(x, y, "%-24s", alias_sort_name(TRUE));
702 			 alias_sort_one_liner(alias_sortby);
703 	  		 MoveCursor(x, y);
704 	 }
705         } while (ch == ' ' || ch == 'r');
706 
707 	MoveCursor(x, COLS-30);	CleartoEOLN();
708 
709 	if (alias_sortby != last_sortby) {
710 	  error(catgets(elm_msg_cat, ElmSet, ElmResortingAliases,
711 			"Resorting aliases..."));
712 	  if (sleepmsg > 0)
713 		sleep((sleepmsg + 1) / 2);
714 	  main_state();
715 	  sort_aliases(num_aliases, FALSE, FALSE);
716 	  main_state();
717 	}
718 	ClearLine(LINES-2);		/* clear alias_sort_one_liner()! */
719 	*var=alias_sortby;
720 	alias_sortby=last_sortby;
721 	return(*var-alias_sortby);
722 }
723 
alias_sort_one_liner(sorting_by)724 alias_sort_one_liner(sorting_by)
725 int sorting_by;
726 {
727 	/** A one line summary of the particular sorting scheme... **/
728 
729 	ClearLine(LINES-2);
730 
731 	switch (sorting_by) {
732 
733 	  case REVERSE ALIAS_SORT:	CenterLine(LINES-2,
734 				catgets(elm_msg_cat, ElmSet, ElmASortRAlias,
735 "This sort will order by alias name, in reverse alphabetical order"));
736 					break;
737 	  case REVERSE NAME_SORT:	CenterLine(LINES-2,
738 				catgets(elm_msg_cat, ElmSet, ElmASortRName,
739 "This sort will order by user (real) name, in reverse alphabetical order"));
740 					break;
741 	  case REVERSE TEXT_SORT:	CenterLine(LINES-2,
742 				catgets(elm_msg_cat, ElmSet, ElmASortRText,
743 "This sort will order aliases in the reverse order as listed in aliases.text"));
744 					break;
745 
746 	  case ALIAS_SORT:		CenterLine(LINES-2,
747 				catgets(elm_msg_cat, ElmSet, ElmASortAlias,
748 "This sort will order by alias name"));
749 					break;
750 	  case NAME_SORT:		CenterLine(LINES-2,
751 				catgets(elm_msg_cat, ElmSet, ElmASortName,
752 "This sort will order by user (real) name"));
753 					break;
754 	  case TEXT_SORT:		CenterLine(LINES-2,
755 				catgets(elm_msg_cat, ElmSet, ElmASortText,
756 "This sort will order aliases in the order as listed in aliases.text"));
757 					break;
758 
759 	}
760 }
761 
762 /*
763  * This routine is a "shell" to enter_string(), etc. so that
764  * we can use save_info structure and tag the param as being changed
765  * locally (so we know to save it to the .elm/elmrc file).
766  */
info_enter(name,ypos,xpos)767 info_enter(name, ypos, xpos)
768 char *name;
769 int ypos, xpos;
770 {
771 	register int x,q;
772 	char buffer[SLEN];
773 	int number;
774 
775 	for (x = 0; x < NUMBER_OF_SAVEABLE_OPTIONS; x++) {
776 		q = strcmp(name, save_info[x].name);
777 		if (q <= 0)
778 			break;
779 	}
780 
781 	if (q)
782 	    return(1);
783 
784 	switch(save_info[x].flags & DT_MASK) {
785 
786 	case DT_STR:
787 	    strcpy(buffer, SAVE_INFO_STR(x));
788 	    if (save_info[x].flags & FL_NOSPC) {
789 		register char *s;
790 		for (s = buffer; *s; ++s)
791 		    if (*s==' ')
792 			*s='_';
793 	    }
794 
795 	    /* FOO - this is not handling enter_string() abort properly */
796 	    enter_string(buffer, sizeof(buffer), ypos, xpos, ESTR_REPLACE);
797 
798 	    if (save_info[x].flags & FL_NOSPC) {
799 		register char *s;
800 		for (s=buffer; *s; ++s)
801 		    if (*s=='_')
802 			*s=' ';
803 	    }
804 
805 	    if (streq(buffer, SAVE_INFO_STR(x)))
806 		break;
807 
808 	    strcpy(SAVE_INFO_STR(x), buffer);
809 	    q++;
810 	    break;
811 
812 	case DT_SRT:
813 	    number = *SAVE_INFO_SRT(x);
814 	    if (change_sort(&number, ypos, xpos) != 0) {
815 		*SAVE_INFO_SRT(x) = number;
816 		++q;
817 	    }
818 	    break;
819 
820 	case DT_ASR:
821 	    number = *SAVE_INFO_ASR(x);
822 	    if (change_alias_sort(&number, ypos, xpos) != 0) {
823 		*SAVE_INFO_ASR(x) = number;
824 		++q;
825 	    }
826 	    break;
827 
828 	case DT_NUM:
829 	    number = *SAVE_INFO_NUM(x);
830 	    if (streq(name, "userlevel")) {
831 		switch_user_level(&number, ypos, xpos);
832 	    }
833 
834 	    if (number == *SAVE_INFO_NUM(x))
835 		break;
836 
837 	    *SAVE_INFO_NUM(x) = number;
838 	    ++q;
839 	    break;
840 
841 	case DT_BOL:
842 	    number = *SAVE_INFO_BOL(x);
843 	    on_or_off(&number, ypos, xpos);
844 	    if (number == *SAVE_INFO_BOL(x))
845 		break;
846 
847 	    *SAVE_INFO_BOL(x) = number;
848 	    ++q;
849 	    break;
850 
851 	default:
852 	    break;
853 
854 	}
855 
856 	if (q)
857 	    save_info[x].flags |= FL_LOCAL;
858 
859 	return(q != 0);
860 }
861 
862