1 /***************************************************************************
2  *  Pinfo is a ncurses based lynx style info documentation browser
3  *
4  *  Copyright (C) 1999  Przemek Borys <pborys@dione.ids.pl>
5  *  Copyright (C) 2005  Bas Zoetekouw <bas@debian.org>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of version 2 of the GNU General Public License as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful, but
12  *  WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
19  *  USA
20  ***************************************************************************/
21 
22 #include "common_includes.h"
23 
24 #include <ctype.h>
25 
26 #ifdef HAVE_DECL_USE_DEFAULT_COLORS
27 # define COLOR_DEFAULT (-1)	/* ncurses extension to use default color, see default_colors(3NCURSES) */
28 #endif
29 
30 regex_t *h_regexp = 0;	/* regexps to highlight */
31 int h_regexp_num = 0;	/* number of those regexps */
32 
33 struct keybindings keys =
34 {
35 	's',		'S',		/* regexp search */
36 	'/',		'/',		/* regexp search, this page */
37 	'g',		'G',		/* goto node */
38 	'p',		'P',		/* previous node */
39 	'n',		'N',		/* next node */
40 	'u',		'U',		/* up node */
41 	KEY_UP,		'k',		/* up one line */
42 #ifdef KEY_END
43 	KEY_END
44 #else
45 	'E'
46 #endif
47 		,'e',			/* end */
48 	KEY_NPAGE,	' ',		/* down one page */
49 	KEY_HOME,	'H',		/* home */
50 	KEY_PPAGE,	'-',		/* up one page */
51 	KEY_DOWN,	'j',		/* down one line */
52 	't',		'T',		/* top */
53 	KEY_LEFT,	'h',		/* back */
54 	KEY_RIGHT,	'\n',		/* follow link */
55 	'Q',		'q',		/* quit */
56 	12,			'~',		/* refresh screen -- 12 is C-L */
57 	'!',		'!',		/* shell feed */
58 	'D',		'd',		/* goto dir page */
59 	0,			' ',		/* pgdn_auto */
60 	0,			'-',		/* pgup_auto */
61 	'f',		0,			/* search again */
62 	'l',		0,			/* go to line */
63 	KEY_IC,		0,			/* two lines up */
64 	KEY_DC,		1,			/* two lines down */
65 	']',		0, 			/* print */
66 	'4',		0,			/* scroll left */
67 	'6',		0			/* scroll right */
68 };
69 
70 #ifdef HAVE_CURSES_COLOR
71 struct colours cols =
72 {
73 	COLOR_WHITE,	COLOR_BLACK,	NO_BOLD,	NO_BLINK,	/* normal */
74 	COLOR_GREEN,	COLOR_WHITE,	BOLD,		NO_BLINK,	/* selected menu */
75 	COLOR_GREEN,	COLOR_BLACK,	BOLD,		NO_BLINK,	/* menu */
76 	COLOR_BLUE,		COLOR_WHITE,	BOLD,		NO_BLINK,	/* selected note */
77 	COLOR_BLUE,		COLOR_BLACK,	BOLD,		NO_BLINK,	/* note */
78 	COLOR_GREEN,	COLOR_BLUE,		BOLD,		NO_BLINK,	/* top line */
79 	COLOR_GREEN,	COLOR_BLUE,		BOLD,		NO_BLINK,	/* bottom line */
80 	COLOR_YELLOW,	COLOR_BLACK,	BOLD,		NO_BLINK,	/* manual bold */
81 	COLOR_WHITE,	COLOR_BLACK,	BOLD,		NO_BLINK,	/* manual italic */
82 	COLOR_MAGENTA,	COLOR_BLACK,	BOLD,		NO_BLINK,	/* url */
83 	COLOR_MAGENTA,	COLOR_GREEN,	NO_BOLD,	NO_BLINK,	/* url selected */
84 	COLOR_WHITE,	COLOR_BLACK,	BOLD,		NO_BLINK,	/* info highlight(quoted text) */
85 	COLOR_YELLOW,	COLOR_BLACK,	BOLD,		NO_BLINK	/* search highlight */
86 };
87 #endif /* HAVE_CURSES_COLOR */
88 
89 int
parse_config(void)90 parse_config(void)
91 {
92 	char config_file_name[256], *home = 0;
93 	char line[256];
94 	FILE *f;
95 	int line_number = 0;
96 	if (rcfile != NULL)
97 	{
98 		f = fopen(rcfile, "r");
99 		if (f == NULL)
100 		{
101 			fprintf(stderr, _("Can't open config file!\n"));
102 			exit(1);
103 		}
104 	}
105 	else
106 	{
107 		if (rcfile == NULL)
108 		{
109 			if (getenv("HOME"))
110 				home = strdup(getenv("HOME"));
111 			else
112 				home = 0;
113 		}
114 		if (home)
115 		{
116 			strcpy(config_file_name, home);
117 			strcat(config_file_name, "/.pinforc");
118 			if (!(f = fopen(config_file_name, "r")))
119 			{
120 				strcpy(config_file_name, CONFIGDIR);
121 				if (!(f = fopen(config_file_name, "r")))
122 				{
123 					free(home);	/* home is nonzero; see if (home) above */
124 					return 0;	/* no config file available */
125 				}
126 			}
127 		}
128 		else
129 		{
130 			strcpy(config_file_name, CONFIGDIR);
131 			if (!(f = fopen(config_file_name, "r")))
132 			{
133 				/* free(home);    home is unallocated; see if (home) above */
134 				return 0;
135 			}
136 		}
137 	}
138 	while (!feof(f))
139 	{
140 		if (!(fgets(line, 255, f)))
141 		{
142 			fclose(f);
143 			if (home)
144 				free(home);
145 			return 0;
146 		}
147 		if (parse_line(line))
148 		{
149 			line_number++;
150 			fclose(f);
151 			fprintf(stderr, _("Parse error in config file on line %d\n"), line_number);
152 			exit(1);
153 		}
154 		else
155 			line_number++;
156 	}
157 
158 	fclose(f);
159 	if (home)
160 		free(home);
161 	return 0;
162 }
163 
164 int
parse_line(char * line)165 parse_line(char *line)
166 {
167 	char *temp;
168 	int *fore = NULL;
169 	int *key = NULL;
170 	int *back = NULL, *bold = NULL, *blink = NULL, *p = NULL;
171 	int i;
172 
173 	if (line[0] == '#')
174 		return 0;
175 
176 	if (!(temp = skip_whitespace(strtok(line, "="))))
177 		return 1;
178 
179 	temp = str_toupper(temp);
180 
181 	if (strlen(temp) < 1)
182 		return 0;
183 
184 	if (!strncmp(temp, "KEY", 3))
185 	{
186 		fore = NULL;
187 		if (!strncmp(temp + 4, "TOTALSEARCH_1", 13))
188 			key = &keys.totalsearch_1;
189 		else if (!strncmp(temp + 4, "PGDN_AUTO_1", 11))
190 			key = &keys.pgdn_auto_1;
191 		else if (!strncmp(temp + 4, "PGDN_AUTO_2", 11))
192 			key = &keys.pgdn_auto_2;
193 		else if (!strncmp(temp + 4, "PGUP_AUTO_1", 11))
194 			key = &keys.pgup_auto_1;
195 		else if (!strncmp(temp + 4, "PGUP_AUTO_2", 11))
196 			key = &keys.pgup_auto_2;
197 		else if (!strncmp(temp + 4, "TOTALSEARCH_2", 13))
198 			key = &keys.totalsearch_2;
199 		else if (!strncmp(temp + 4, "SEARCH_AGAIN_1", 14))
200 			key = &keys.search_again_1;
201 		else if (!strncmp(temp + 4, "SEARCH_AGAIN_2", 14))
202 			key = &keys.search_again_2;
203 		else if (!strncmp(temp + 4, "SEARCH_1", 8))
204 			key = &keys.search_1;
205 		else if (!strncmp(temp + 4, "SEARCH_2", 8))
206 			key = &keys.search_2;
207 		else if (!strncmp(temp + 4, "GOTO_1", 6))
208 			key = &keys.goto_1;
209 		else if (!strncmp(temp + 4, "GOTO_2", 6))
210 			key = &keys.goto_2;
211 		else if (!strncmp(temp + 4, "PREVNODE_1", 10))
212 			key = &keys.prevnode_1;
213 		else if (!strncmp(temp + 4, "PREVNODE_2", 10))
214 			key = &keys.prevnode_2;
215 		else if (!strncmp(temp + 4, "NEXTNODE_1", 10))
216 			key = &keys.nextnode_1;
217 		else if (!strncmp(temp + 4, "NEXTNODE_2", 10))
218 			key = &keys.nextnode_2;
219 		else if (!strncmp(temp + 4, "UPNODE_1", 8))
220 			key = &keys.upnode_1;
221 		else if (!strncmp(temp + 4, "UPNODE_2", 8))
222 			key = &keys.upnode_2;
223 		else if (!strncmp(temp + 4, "UP_1", 4))
224 			key = &keys.up_1;
225 		else if (!strncmp(temp + 4, "UP_2", 4))
226 			key = &keys.up_2;
227 		else if (!strncmp(temp + 4, "TWOUP_1", 7))
228 			key = &keys.twoup_1;
229 		else if (!strncmp(temp + 4, "TWOUP_2", 7))
230 			key = &keys.twoup_2;
231 		else if (!strncmp(temp + 4, "END_1", 5))
232 			key = &keys.end_1;
233 		else if (!strncmp(temp + 4, "END_2", 5))
234 			key = &keys.end_2;
235 		else if (!strncmp(temp + 4, "PGDN_1", 6))
236 			key = &keys.pgdn_1;
237 		else if (!strncmp(temp + 4, "PGDN_2", 6))
238 			key = &keys.pgdn_2;
239 		else if (!strncmp(temp + 4, "HOME_1", 6))
240 			key = &keys.home_1;
241 		else if (!strncmp(temp + 4, "HOME_2", 6))
242 			key = &keys.home_2;
243 		else if (!strncmp(temp + 4, "PGUP_1", 6))
244 			key = &keys.pgup_1;
245 		else if (!strncmp(temp + 4, "PGUP_2", 6))
246 			key = &keys.pgup_2;
247 		else if (!strncmp(temp + 4, "DOWN_1", 6))
248 			key = &keys.down_1;
249 		else if (!strncmp(temp + 4, "DOWN_2", 6))
250 			key = &keys.down_2;
251 		else if (!strncmp(temp + 4, "TWODOWN_1", 9))
252 			key = &keys.twodown_1;
253 		else if (!strncmp(temp + 4, "TWODOWN_2", 9))
254 			key = &keys.twodown_2;
255 		else if (!strncmp(temp + 4, "TOP_1", 5))
256 			key = &keys.top_1;
257 		else if (!strncmp(temp + 4, "TOP_2", 5))
258 			key = &keys.top_2;
259 		else if (!strncmp(temp + 4, "BACK_1", 6))
260 			key = &keys.back_1;
261 		else if (!strncmp(temp + 4, "BACK_2", 6))
262 			key = &keys.back_2;
263 		else if (!strncmp(temp + 4, "FOLLOWLINK_1", 12))
264 			key = &keys.followlink_1;
265 		else if (!strncmp(temp + 4, "FOLLOWLINK_2", 12))
266 			key = &keys.followlink_2;
267 		else if (!strncmp(temp + 4, "REFRESH_1", 9))
268 			key = &keys.refresh_1;
269 		else if (!strncmp(temp + 4, "REFRESH_2", 9))
270 			key = &keys.refresh_2;
271 		else if (!strncmp(temp + 4, "SHELLFEED_1", 11))
272 			key = &keys.shellfeed_1;
273 		else if (!strncmp(temp + 4, "SHELLFEED_2", 11))
274 			key = &keys.shellfeed_2;
275 		else if (!strncmp(temp + 4, "QUIT_1", 6))
276 			key = &keys.quit_1;
277 		else if (!strncmp(temp + 4, "QUIT_2", 6))
278 			key = &keys.quit_2;
279 		else if (!strncmp(temp + 4, "DIRPAGE_1", 9))
280 			key = &keys.dirpage_1;
281 		else if (!strncmp(temp + 4, "DIRPAGE_2", 9))
282 			key = &keys.dirpage_2;
283 		else if (!strncmp(temp + 4, "GOLINE_1", 8))
284 			key = &keys.goline_1;
285 		else if (!strncmp(temp + 4, "GOLINE_2", 8))
286 			key = &keys.goline_2;
287 		else if (!strncmp(temp + 4, "PRINT_1", 7))
288 			key = &keys.print_1;
289 		else if (!strncmp(temp + 4, "PRINT_2", 7))
290 			key = &keys.print_2;
291 		else if (!strncmp(temp + 4, "LEFT_1", 6))
292 			key = &keys.left_1;
293 		else if (!strncmp(temp + 4, "LEFT_2", 6))
294 			key = &keys.left_2;
295 		else if (!strncmp(temp + 4, "RIGHT_1", 7))
296 			key = &keys.right_1;
297 		else if (!strncmp(temp + 4, "RIGHT_2", 7))
298 			key = &keys.right_2;
299 		else
300 			return 1;
301 	}
302 #ifdef HAVE_CURSES_COLOR
303 	else if (!strncmp(temp, "COL", 3))
304 	{
305 		key = NULL;
306 		if (!strncmp(temp + 4, "NORMAL", 6))
307 		{
308 			fore = &cols.normal_fore;
309 			back = &cols.normal_back;
310 			bold = &cols.normal_bold;
311 			blink = &cols.normal_blink;
312 		}
313 		else if (!strncmp(temp + 4, "MENUSELECTED", 12))
314 		{
315 			fore = &cols.menuselected_fore;
316 			back = &cols.menuselected_back;
317 			bold = &cols.menuselected_bold;
318 			blink = &cols.menuselected_blink;
319 		}
320 		else if (!strncmp(temp + 4, "MENU", 4))
321 		{
322 			fore = &cols.menu_fore;
323 			back = &cols.menu_back;
324 			bold = &cols.menu_bold;
325 			blink = &cols.menu_blink;
326 		}
327 		else if (!strncmp(temp + 4, "NOTESELECTED", 12))
328 		{
329 			fore = &cols.noteselected_fore;
330 			back = &cols.noteselected_back;
331 			bold = &cols.noteselected_bold;
332 			blink = &cols.noteselected_blink;
333 		}
334 		else if (!strncmp(temp + 4, "NOTE", 4))
335 		{
336 			fore = &cols.note_fore;
337 			back = &cols.note_back;
338 			bold = &cols.note_bold;
339 			blink = &cols.note_blink;
340 		}
341 		else if (!strncmp(temp + 4, "TOPLINE", 7))
342 		{
343 			fore = &cols.topline_fore;
344 			back = &cols.topline_back;
345 			bold = &cols.topline_bold;
346 			blink = &cols.topline_blink;
347 		}
348 		else if (!strncmp(temp + 4, "BOTTOMLINE", 10))
349 		{
350 			fore = &cols.bottomline_fore;
351 			back = &cols.bottomline_back;
352 			bold = &cols.bottomline_bold;
353 			blink = &cols.bottomline_blink;
354 		}
355 		else if (!strncmp(temp + 4, "MANUALBOLD", 10))
356 		{
357 			fore = &cols.manualbold_fore;
358 			back = &cols.manualbold_back;
359 			bold = &cols.manualbold_bold;
360 			blink = &cols.manualbold_blink;
361 		}
362 		else if (!strncmp(temp + 4, "MANUALITALIC", 12))
363 		{
364 			fore = &cols.manualitalic_fore;
365 			back = &cols.manualitalic_back;
366 			bold = &cols.manualitalic_bold;
367 			blink = &cols.manualitalic_blink;
368 		}
369 		else if (!strncmp(temp + 4, "URLSELECTED", 11))
370 		{
371 			fore = &cols.urlselected_fore;
372 			back = &cols.urlselected_back;
373 			bold = &cols.urlselected_bold;
374 			blink = &cols.urlselected_blink;
375 		}
376 		else if (!strncmp(temp + 4, "URL", 3))
377 		{
378 			fore = &cols.url_fore;
379 			back = &cols.url_back;
380 			bold = &cols.url_bold;
381 			blink = &cols.url_blink;
382 		}
383 		else if (!strncmp(temp + 4, "INFOHIGHLIGHT", 13))
384 		{
385 			fore = &cols.infohighlight_fore;
386 			back = &cols.infohighlight_back;
387 			bold = &cols.infohighlight_bold;
388 			blink = &cols.infohighlight_blink;
389 		}
390 		else if (!strncmp(temp + 4, "SEARCHHIGHLIGHT", 15))
391 		{
392 			fore = &cols.searchhighlight_fore;
393 			back = &cols.searchhighlight_back;
394 			bold = &cols.searchhighlight_bold;
395 			blink = &cols.searchhighlight_blink;
396 		}
397 		else
398 			return 1;
399 	}
400 #endif /* HAVE_CURSES_COLOR */
401 	else if (!strncmp(temp, "MANUAL", 6))
402 	{
403 		temp = strtok(NULL, "=");
404 		if (temp)
405 		{
406 			if (!(temp = str_toupper(skip_whitespace(temp))))
407 				return 1;
408 			if (!strncmp(temp, "TRUE", 4))
409 				use_manual = 1;
410 			else if (!strncmp(temp, "FALSE", 5))
411 				use_manual = 0;
412 			else
413 				return 1;
414 		}
415 	}
416 	else if (!strncmp(temp, "GRAB-MOUSE", 10))
417 	{
418 		temp = strtok(NULL, "=");
419 		if (temp)
420 		{
421 			if (!(temp = str_toupper(skip_whitespace(temp))))
422 				return 1;
423 			if (!strncmp(temp, "TRUE", 4))
424 				grab_mouse = 1;
425 			else if (!strncmp(temp, "FALSE", 5))
426 				grab_mouse = 0;
427 			else
428 				return 1;
429 		}
430 	}
431 	else if (!strncmp(temp, "RAW-FILENAME", 12))
432 	{
433 		temp = strtok(NULL, "=");
434 		if (temp)
435 		{
436 			if (!(temp = str_toupper(skip_whitespace(temp))))
437 				return 1;
438 			if (!strncmp(temp, "TRUE", 4))
439 				use_raw_filename = 1;
440 			else if (!strncmp(temp, "FALSE", 5))
441 				use_raw_filename = 0;
442 			else
443 				return 1;
444 		}
445 	}
446 	else if (!strncmp(temp, "APROPOS", 7))
447 	{
448 		temp = strtok(NULL, "=");
449 		if (temp)
450 		{
451 			if (!(temp = str_toupper(skip_whitespace(temp))))
452 				return 1;
453 			if (!strncmp(temp, "TRUE", 4))
454 				use_apropos = 1;
455 			else if (!strncmp(temp, "FALSE", 5))
456 				use_apropos = 0;
457 			else
458 				return 1;
459 		}
460 	}
461 	else if (!strncmp(temp, "VERBOSE", 7))
462 	{
463 		temp = strtok(NULL, "=");
464 		if (temp)
465 		{
466 			if (!(temp = str_toupper(skip_whitespace(temp))))
467 				return 1;
468 			if (!strncmp(temp, "TRUE", 4))
469 				verbose = 1;
470 			else if (!strncmp(temp, "FALSE", 5))
471 				verbose = 0;
472 			else
473 				return 1;
474 		}
475 	}
476 	else if (!strncmp(temp, "QUIT-CONFIRMATION", 17))
477 	{
478 		temp = strtok(NULL, "=");
479 		if (temp)
480 		{
481 			if (!(temp = str_toupper(skip_whitespace(temp))))
482 				return 1;
483 			if (!strncmp(temp, "TRUE", 4))
484 				ConfirmQuit = 1;
485 			else if (!strncmp(temp, "FALSE", 5))
486 				ConfirmQuit = 0;
487 			else
488 				return 1;
489 		}
490 	}
491 	else if (!strncmp(temp, "QUIT-CONFIRM-DEFAULT", 20))
492 	{
493 		temp = strtok(NULL, "=");
494 		if (temp)
495 		{
496 			if (!(temp = str_toupper(skip_whitespace(temp))))
497 				return 1;
498 			if (!strncmp(temp, "YES", 3))
499 				QuitConfirmDefault = 1;
500 			else if (!strncmp(temp, "NO", 2))
501 				QuitConfirmDefault = 0;
502 			else
503 				return 1;
504 		}
505 	}
506 	else if (!strncmp(temp, "CUT-MAN-HEADERS", 15))
507 	{
508 		temp = strtok(NULL, "=");
509 		if (temp)
510 		{
511 			if (!(temp = str_toupper(skip_whitespace(temp))))
512 				return 1;
513 			if (!strncmp(temp, "TRUE", 4))
514 				CutManHeaders = 1;
515 			else if (!strncmp(temp, "FALSE", 5))
516 				CutManHeaders = 0;
517 			else
518 				return 1;
519 		}
520 	}
521 	else if (!strncmp(temp, "CLEAR-SCREEN-AT-EXIT", 20))
522 	{
523 		temp = strtok(NULL, "=");
524 		if (temp)
525 		{
526 			if (!(temp = str_toupper(skip_whitespace(temp))))
527 				return 1;
528 			if (!strncmp(temp, "TRUE", 4))
529 				ClearScreenAtExit = 1;
530 			else if (!strncmp(temp, "FALSE", 5))
531 				ClearScreenAtExit = 0;
532 			else
533 				return 1;
534 		}
535 	}
536 	else if (!strncmp(temp, "CALL-READLINE-HISTORY", 21))
537 	{
538 		temp = strtok(NULL, "=");
539 		if (temp)
540 		{
541 			if (!(temp = str_toupper(skip_whitespace(temp))))
542 				return 1;
543 			if (!strncmp(temp, "TRUE", 4))
544 				CallReadlineHistory = 1;
545 			else if (!strncmp(temp, "FALSE", 5))
546 				CallReadlineHistory = 0;
547 			else
548 				return 1;
549 		}
550 	}
551 	else if (!strncmp(temp, "CUT-EMPTY-MAN-LINES", 19))
552 	{
553 		temp = strtok(NULL, "=");
554 		if (temp)
555 		{
556 			if (!(temp = str_toupper(skip_whitespace(temp))))
557 				return 1;
558 			if (!strncmp(temp, "TRUE", 4))
559 				CutEmptyManLines = 1;
560 			else if (!strncmp(temp, "FALSE", 5))
561 				CutEmptyManLines = 0;
562 			else
563 				return 1;
564 		}
565 	}
566 	else if (!strncmp(temp, "DONT-HANDLE-WITHOUT-TAG-TABLE", 28))
567 	{
568 		temp = strtok(NULL, "=");
569 		if (temp)
570 		{
571 			if (!(temp = str_toupper(skip_whitespace(temp))))
572 				return 1;
573 			if (!strncmp(temp, "TRUE", 4))
574 				DontHandleWithoutTagTable = 1;
575 			else if (!strncmp(temp, "FALSE", 5))
576 				DontHandleWithoutTagTable = 0;
577 			else
578 				return 1;
579 		}
580 	}
581 	else if (!strncmp(temp, "LONG-MANUAL-LINKS", 17))
582 	{
583 		temp = strtok(NULL, "=");
584 		if (temp)
585 		{
586 			if (!(temp = str_toupper(skip_whitespace(temp))))
587 				return 1;
588 			if (!strncmp(temp, "TRUE", 4))
589 				LongManualLinks = 1;
590 			else if (!strncmp(temp, "FALSE", 5))
591 				LongManualLinks = 0;
592 			else
593 				return 1;
594 		}
595 	}
596 	else if (!strncmp(temp, "HTTPVIEWER", 10))
597 	{
598 		temp = strtok(NULL, "\n");
599 		if (temp)
600 		{
601 			httpviewer = strdup(temp);
602 			remove_quotes(httpviewer);
603 		}
604 		else
605 			return 1;
606 	}
607 	else if (!strncmp(temp, "FTPVIEWER", 9))
608 	{
609 		temp = strtok(NULL, "\n");
610 		if (temp)
611 		{
612 			ftpviewer = strdup(temp);
613 			remove_quotes(ftpviewer);
614 		}
615 		else
616 			return 1;
617 	}
618 	else if (!strncmp(temp, "MAILEDITOR", 10))
619 	{
620 		temp = strtok(NULL, "\n");
621 		if (temp)
622 		{
623 			maileditor = strdup(temp);
624 			remove_quotes(maileditor);
625 		}
626 		else
627 			return 1;
628 	}
629 	else if (!strncmp(temp, "PRINTUTILITY", 12))
630 	{
631 		temp = strtok(NULL, "\n");
632 		if (temp)
633 		{
634 			printutility = strdup(temp);
635 			remove_quotes(printutility);
636 		}
637 		else
638 			return 1;
639 	}
640 	else if (!strncmp(temp, "MAN-OPTIONS", 11))
641 	{
642 		temp = strtok(NULL, "\n");
643 		if (temp)
644 		{
645 			ManOptions = strdup(temp);
646 			remove_quotes(ManOptions);
647 		}
648 		else
649 			return 1;
650 	}
651 	else if (!strncmp(temp, "STDERR-REDIRECTION", 18))
652 	{
653 		temp = strtok(NULL, "\n");
654 		if (temp)
655 		{
656 			StderrRedirection = strdup(temp);
657 			remove_quotes(StderrRedirection);
658 		}
659 		else
660 			return 1;
661 	}
662 	else if (!strncmp(temp, "FILTER-0XB7", 11))
663 	{
664 		temp = strtok(NULL, "=");
665 		if (temp)
666 		{
667 			if (!(temp = str_toupper(skip_whitespace(temp))))
668 				return 1;
669 			if (!strncmp(temp, "TRUE", 4))
670 				FilterB7 = 1;
671 			else if (!strncmp(temp, "FALSE", 5))
672 				FilterB7 = 0;
673 			else
674 				return 1;
675 		}
676 	}
677 	else if (!strncmp(temp, "MANLINKS", 8))
678 	{
679 		temp = strtok(NULL, "\n");
680 		if (temp)
681 		{
682 			manlinks = strdup(temp);
683 			remove_quotes(manlinks);
684 		}
685 		else
686 			return 1;
687 	}
688 	else if (!strncmp(temp, "INFOPATH", 8))
689 	{
690 		temp = strtok(NULL, "\n");
691 		if (temp)
692 		{
693 			configuredinfopath = strdup(temp);
694 			remove_quotes(configuredinfopath);
695 		}
696 		else
697 			return 1;
698 	}
699 #ifndef ___DONT_USE_REGEXP_SEARCH___
700 	else if (!strncmp(temp, "HIGHLIGHTREGEXP", 15))
701 	{
702 		temp = strtok(NULL, "\n");
703 		if (temp)
704 		{
705 			char *tmp = strdup(temp);
706 			remove_quotes(tmp);
707 			if (!h_regexp_num)
708 				h_regexp = malloc(sizeof(regex_t));
709 			else
710 				h_regexp = realloc(h_regexp, sizeof(regex_t) *(h_regexp_num + 1));
711 			regcomp(&h_regexp[h_regexp_num], tmp, 0);
712 			free(tmp);
713 			h_regexp_num++;
714 		}
715 		else
716 			return 1;
717 	}
718 #endif
719 	else if (!strncmp(temp, "SAFE-USER", 9))
720 	{
721 		temp = strtok(NULL, "\n");
722 		if (temp)
723 		{
724 			char *tmp = strdup(temp);
725 			remove_quotes(tmp);
726 			safe_user = tmp;
727 		}
728 		else
729 			return 1;
730 	}
731 	else if (!strncmp(temp, "SAFE-GROUP", 10))
732 	{
733 		temp = strtok(NULL, "\n");
734 		if (temp)
735 		{
736 			char *tmp = strdup(temp);
737 			remove_quotes(tmp);
738 			safe_group = tmp;
739 		}
740 		else
741 			return 1;
742 	}
743 	else if (!strncmp(temp, "QUOTE-IGNORED-MACROS", 20))
744 	{
745 		temp = strtok(NULL, "=");
746 		if (temp)
747 		{
748 			if (!(temp = str_toupper(skip_whitespace(temp))))
749 				return 1;
750 			if (!strncmp(temp, "TRUE", 4))
751 				quote_ignored = 1;
752 			else if (!strncmp(temp, "FALSE", 5))
753 				quote_ignored = 0;
754 			else
755 				return 1;
756 		}
757 	}
758 
759 	else if (!strncmp(temp, "IGNORE-MACROS", 8))
760 	{
761 		temp = strtok(NULL, "\n");
762 		if (temp)
763 		{
764 			ignoredmacros = strdup(temp);
765 			remove_quotes(ignoredmacros);
766 			if (ignoredmacros[0] == '\t' || ignoredmacros[0] == ' '
767 					|| !strncasecmp(ignoredmacros, "FALSE", 5))
768 				ignoredmacros[0] = '\0';
769 		}
770 		else
771 			return 1;
772 	}
773 	else
774 		return 1;
775 #ifdef HAVE_CURSES_COLOR
776 	if (fore)
777 	{
778 		for (i = 0; i < 4; i++)
779 		{
780 			if (i == 0)
781 				p = fore;
782 			else if (i == 1)
783 				p = back;
784 			else if (i == 2)
785 				p = bold;
786 			else
787 				p = blink;
788 
789 			if (!(temp = skip_whitespace(strtok(NULL, ","))))
790 				return 1;
791 
792 			temp = str_toupper(temp);
793 
794 			if (!(strncmp(temp, "COLOR_BLACK", 11)))
795 				*p = COLOR_BLACK;
796 			else if (!(strncmp(temp, "COLOR_RED", 9)))
797 				*p = COLOR_RED;
798 			else if (!(strncmp(temp, "COLOR_GREEN", 11)))
799 				*p = COLOR_GREEN;
800 			else if (!(strncmp(temp, "COLOR_BLUE", 10)))
801 				*p = COLOR_BLUE;
802 			else if (!(strncmp(temp, "COLOR_WHITE", 11)))
803 				*p = COLOR_WHITE;
804 			else if (!(strncmp(temp, "COLOR_YELLOW", 12)))
805 				*p = COLOR_YELLOW;
806 			else if (!(strncmp(temp, "COLOR_CYAN", 10)))
807 				*p = COLOR_CYAN;
808 			else if (!(strncmp(temp, "COLOR_MAGENTA", 13)))
809 				*p = COLOR_MAGENTA;
810 			else if (!(strncmp(temp, "COLOR_DEFAULT", 13)))
811 			{
812 #ifdef HAVE_DECL_USE_DEFAULT_COLORS
813 				*p = COLOR_DEFAULT;
814 #else
815 				fprintf(stderr, "COLOR_DEFAULT is not supported on this system\n");
816 				return 1;
817 #endif
818 			}
819 			else if (!(strncmp(temp, "BOLD", 4)))
820 				*p = BOLD;
821 			else if (!(strncmp(temp, "NO_BOLD", 7)))
822 				*p = 0;
823 			else if (!(strncmp(temp, "BLINK", 4)))
824 				*p = BOLD;
825 			else if (!(strncmp(temp, "NO_BLINK", 7)))
826 				*p = 0;
827 			else
828 				return 1;
829 		}
830 	}
831 	else
832 #endif /* HAVE_CURSES_COLOR */
833 		if (key)
834 		{
835 			if (!(temp = skip_whitespace(strtok(NULL, "="))))
836 				return 0;
837 			if (!(strncmp(temp, "KEY_", 4)) ||
838 					!(strncmp(temp, "key_", 4)))
839 			{
840 				str_toupper(temp);
841 				/* what other keys should be interesting?  all in curs_getch? */
842 				if (!(strncmp(temp + 4, "BREAK", 5)))
843 					*key = KEY_BREAK;
844 				else if (!(strncmp(temp + 4, "DOWN", 4)))
845 					*key = KEY_DOWN;
846 				else if (!(strncmp(temp + 4, "UP", 2)))
847 					*key = KEY_UP;
848 				else if (!(strncmp(temp + 4, "LEFT", 4)))
849 					*key = KEY_LEFT;
850 				else if (!(strncmp(temp + 4, "RIGHT", 5)))
851 					*key = KEY_RIGHT;
852 				else if (!(strncmp(temp + 4, "IC", 2)))
853 					*key = KEY_IC;
854 				else if (!(strncmp(temp + 4, "DC", 2)))
855 					*key = KEY_DC;
856 				else if (!(strncmp(temp + 4, "HOME", 4)))
857 					*key = KEY_HOME;
858 				else if (!(strncmp(temp + 4, "BACKSPACE", 9)))
859 					*key = KEY_BACKSPACE;
860 				else if (!(strncmp(temp + 4, "NPAGE", 5)))
861 					*key = KEY_NPAGE;
862 				else if (!(strncmp(temp + 4, "PPAGE", 5)))
863 					*key = KEY_PPAGE;
864 				else if (!(strncmp(temp + 4, "F(1)", 4)))
865 					*key = KEY_F(1);
866 				else if (!(strncmp(temp + 4, "F(2)", 4)))
867 					*key = KEY_F(2);
868 				else if (!(strncmp(temp + 4, "F(3)", 4)))
869 					*key = KEY_F(3);
870 				else if (!(strncmp(temp + 4, "F(4)", 4)))
871 					*key = KEY_F(4);
872 				else if (!(strncmp(temp + 4, "F(5)", 4)))
873 					*key = KEY_F(5);
874 				else if (!(strncmp(temp + 4, "F(6)", 4)))
875 					*key = KEY_F(6);
876 				else if (!(strncmp(temp + 4, "F(7)", 4)))
877 					*key = KEY_F(7);
878 				else if (!(strncmp(temp + 4, "F(8)", 4)))
879 					*key = KEY_F(8);
880 				else if (!(strncmp(temp + 4, "(F9)", 4)))
881 					*key = KEY_F(9);
882 				else if (!(strncmp(temp + 4, "(F10)", 5)))
883 					*key = KEY_F(10);
884 				else if (!(strncmp(temp + 4, "F(11)", 5)))
885 					*key = KEY_F(11);
886 				else if (!(strncmp(temp + 4, "F(12)", 5)))
887 					*key = KEY_F(12);
888 				else if (!(strncmp(temp + 4, "END", 3)))
889 					*key = KEY_END;
890 				else if (!(strncmp(temp + 4, "CTRL", 4)))
891 				{
892 					if (!(temp = skip_whitespace(temp + 8)))
893 						return 1;
894 					if (temp[0] == '(')
895 					{
896 						if (temp[1] == '\'')
897 							*key = KEY_CTRL(temp[2]);
898 						else if (isdigit(temp[1]))
899 						{
900 							char *tail = temp +(strlen(temp));
901 							*key = KEY_CTRL((int) strtol(temp + 1, &tail, 10));
902 						}
903 						else
904 							return 1;
905 					}
906 					else
907 						return 1;
908 				}
909 				else if (!(strncmp(temp + 4, "ALT", 3)))
910 				{
911 					if (!(temp = skip_whitespace(temp + 7)))
912 						return 1;
913 					if (temp[0] == '(')
914 					{
915 						if (temp[1] == '\'')
916 							*key = KEY_ALT(tolower(temp[2]));
917 						else if (isdigit(temp[1]))
918 						{
919 							char *tail = temp +(strlen(temp));
920 							*key = KEY_ALT((int) strtol(temp + 1, &tail, 10));
921 						}
922 						else
923 							return 1;
924 					}
925 					else
926 						return 1;
927 				}
928 				else
929 					return 1;
930 			}
931 			else if (!(strncmp(temp, "\'", 1)))
932 			{
933 				if (!(strncmp(temp + 1, "\\", 1)))
934 				{
935 					if (temp[2] == 'n')
936 						*key = '\n';
937 					else if (temp[2] == '\\')
938 						*key = '\\';
939 					else if (temp[2] == 't')
940 						*key = '\t';
941 					else if (temp[2] == '\'')
942 						*key = '\'';
943 					else
944 						*key = temp[2];
945 				}
946 				else
947 				{
948 					*key = temp[1];
949 				}
950 			}
951 			else if (isdigit(temp[0]))
952 			{
953 				char *tail = temp +(strlen(temp));
954 				*key =(int) strtol(temp, &tail, 10);
955 			}
956 		}
957 
958 	return 0;
959 }
960 
961 char *
str_toupper(char * str)962 str_toupper(char *str)
963 {
964 	unsigned int i;
965 	for (i = 0; i < strlen(str); ++i)
966 		if (islower(str[i]))
967 			str[i] = toupper(str[i]);
968 
969 	return str;
970 }
971 
972 char *
skip_whitespace(char * str)973 skip_whitespace(char *str)
974 {
975 	int i = 0;
976 
977 	if (!str)
978 		return NULL;
979 
980 	while (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
981 		i++;
982 
983 	return str + i;
984 }
985 
986 char *
remove_quotes(char * str)987 remove_quotes(char *str)
988 {
989 	size_t i = 0;
990 
991 	for (i = 0; i < strlen(str); i++)
992 		if (str[i] == '\"')
993 			str[i] = ' ';
994 
995 	return str;
996 }
997