1 #if	!defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: pilot.c 1184 2008-12-16 23:52:15Z hubert@u.washington.edu $";
3 #endif
4 
5 /*
6  * ========================================================================
7  * Copyright 2006-2008 University of Washington
8  * Copyright 2013-2021 Eduardo Chappa
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *     http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * ========================================================================
17  */
18 
19 /*
20  * Program:	Main stand-alone Pine File Browser routines
21  *
22  *
23  * BROWSER NOTES:
24  *
25  * 30 Sep 92 - Stand alone PIne's "Lister of Things" came into being.
26  *	       It's built against libpico.a from a command line like:
27  *
28  *		       cc pilot.c libpico.a -ltermcap -lc -o pilot
29  *
30  *	       should it become a fleshed out tool, we'll move it into
31  *	       the normal build process.
32  */
33 
34 #include	"headers.h"
35 #include	"../c-client/mail.h"
36 #include	"../c-client/rfc822.h"
37 #include	"../pith/osdep/collate.h"
38 #include	"../pith/charconv/filesys.h"
39 #include	"../pith/charconv/utf8.h"
40 #include	"../pith/conf.h"
41 
42 
43 #define		PILOT_VERSION	"UW PILOT 2.99"
44 
45 
46 extern char *gethomedir(int *);
47 
48 char *pilot_args(int, char **, int *);
49 void  pilot_args_help(void);
50 void  pilot_display_args_err(char *, char **, int);
51 
52 char  args_pilot_missing_flag[]  = N_("unknown flag \"%c\"");
53 char  args_pilot_missing_arg[]   = N_("missing or empty argument to \"%c\" flag");
54 char  args_pilot_missing_num[]   = N_("non numeric argument for \"%c\" flag");
55 char  args_pilot_missing_color[] = N_("missing color for \"%s\" flag");
56 char  args_pilot_missing_charset[] = N_("missing character set for \"%s\" flag");
57 char  args_pilot_input_charset[] = N_("input character set \"%s\" is unsupported");
58 char  args_pilot_output_charset[] = N_("output character set \"%s\" is unsupported");
59 
60 char *args_pilot_args[] = {
61 /* TRANSLATORS: little help printed out when incorrect arguments are
62    given for pilot program. */
63 N_("Possible Starting Arguments for Pilot file browser:"),
64 "",
65 N_("\tArgument\t\tMeaning"),
66 N_("\t -a \t\tShowDot - show dot files in file browser"),
67 N_("\t -j \t\tGoto - allow 'Goto' command in file browser"),
68 N_("\t -g \t\tShow - show cursor in file browser"),
69 N_("\t -m \t\tMouse - turn on mouse support"),
70 N_("\t -v \t\tOneColumn - use single column display"),
71 N_("\t -x \t\tNoKeyhelp - suppress keyhelp"),
72 N_("\t -q \t\tTermdefWins - termcap or terminfo takes precedence over defaults"),
73 N_("\t -f \t\tKeys - force use of function keys"),
74 N_("\t -h \t\tHelp - give this list of options"),
75 #ifndef	_WINDOWS
76 N_("\t -dcs <display_character_set> \tdefault uses LANG or LC_CTYPE from environment"),
77 N_("\t -kcs <keyboard_character_set> \tdefaults to display_character_set"),
78 N_("\t -syscs\t\tuse system-supplied translation routines"),
79 #endif	/* ! _WINDOWS */
80 N_("\t -n[#s] \tMail - notify about new mail every #s seconds, default=180"),
81 N_("\t -t \t\tShutdown - enable special shutdown mode"),
82 N_("\t -o <dir>\tOperation - specify the operating directory"),
83 N_("\t -z \t\tSuspend - allow use of ^Z suspension"),
84 #ifdef	_WINDOWS
85 N_("\t -cnf color \tforeground color"),
86 N_("\t -cnb color \tbackground color"),
87 N_("\t -crf color \treverse foreground color"),
88 N_("\t -crb color \treverse background color"),
89 #endif	/* _WINDOWS */
90 N_("\t -no_setlocale_collate\tdo not do setlocale(LC_COLLATE)"),
91 "",
92 N_("\t All arguments may be followed by a directory name to start in."),
93 "",
94 NULL
95 };
96 
97 
98 /*
99  * main standalone browser routine
100  */
101 int
main(int argc,char * argv[])102 main(int argc, char *argv[])
103 {
104     char  bname[NBUFN];		/* buffer name of file to read	*/
105     char  filename[NSTRING];
106     char  filedir[NSTRING];
107     char *dir;
108     char *display_charmap = NULL, *dc;
109     char *keyboard_charmap = NULL;
110     int   use_system = 0;
111     char *err = NULL;
112     int   setlocale_collate = 1;
113 
114     set_input_timeout(0);
115     Pmaster = NULL;			/* turn OFF composer functionality */
116     km_popped = 0;
117     opertree[0] = '\0'; opertree[NLINE] = '\0';
118     filename[0] ='\0';
119     gmode |= MDBRONLY;			/* turn on exclusive browser mode */
120 
121     /*
122      * Read command line flags before initializing, otherwise, we never
123      * know to init for f_keys...
124      */
125     if((dir = pilot_args(argc, argv, &setlocale_collate)) != NULL){
126 	strncpy(filedir, dir, sizeof(filedir));
127 	filedir[sizeof(filedir)-1] = '\0';
128 	fixpath(filedir, sizeof(filedir));
129     }
130     else{
131       strncpy(filedir, gethomedir(NULL), sizeof(filedir));
132       filedir[sizeof(filedir)-1] = '\0';
133     }
134 
135     set_collation(setlocale_collate, 1);
136 
137 #ifdef	_WINDOWS
138     init_utf8_display(1, NULL);
139 #else	/* UNIX */
140 
141 #define cpstr(s) strcpy((char *)fs_get(1+strlen(s)), s)
142 
143     if(display_character_set)
144       display_charmap = cpstr(display_character_set);
145 #if   HAVE_LANGINFO_H && defined(CODESET)
146     else if((dc = nl_langinfo_codeset_wrapper()) != NULL)
147       display_charmap = cpstr(dc);
148 #endif
149 
150     if(!display_charmap)
151       display_charmap = cpstr("US-ASCII");
152 
153     if(keyboard_character_set)
154       keyboard_charmap = cpstr(keyboard_character_set);
155     else
156       keyboard_charmap = cpstr(display_charmap);
157 
158 #undef cpstr
159 
160     if(use_system_translation){
161 #if	PREREQ_FOR_SYS_TRANSLATION
162 	use_system++;
163 	/* This modifies its arguments */
164 	if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
165 				  &input_cs, &err) == -1){
166 	    fprintf(stderr, "%s\n", err ? err : "trouble with character set");
167 	    exit(1);
168 	}
169 	else if(err){
170 	    fprintf(stderr, "%s\n", err);
171 	    fs_give((void **) &err);
172 	}
173 #endif
174     }
175 
176     if(!use_system){
177 	if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
178 				  &input_cs, &err) == -1){
179 	    fprintf(stderr, "%s\n", err ? err : "trouble with character set");
180 	    exit(1);
181 	}
182 	else if(err){
183 	    fprintf(stderr, "%s\n", err);
184 	    fs_give((void **) &err);
185 	}
186     }
187 
188     if(keyboard_charmap){
189 	set_locale_charmap(keyboard_charmap);
190 	free((void *) keyboard_charmap);
191     }
192 
193     if(display_charmap)
194       free((void *) display_charmap);
195 
196 #endif	/* UNIX */
197 
198     if(!vtinit())			/* Displays.            */
199       exit(1);
200 
201     strncpy(bname, "main", sizeof(bname));		/* default buffer name */
202     bname[sizeof(bname)-1] = '\0';
203     edinit(bname);			/* Buffers, windows.   */
204 #if	defined(USE_TERMCAP) || defined(USE_TERMINFO) || defined(VMS)
205     if(kbesc == NULL){			/* will arrow keys work ? */
206 	(*term.t_putchar)('\007');
207 	emlwrite("Warning: keypad keys may be non-functional", NULL);
208     }
209 #endif	/* USE_TERMCAP/USE_TERMINFO/VMS */
210 
211     curbp->b_mode |= gmode;		/* and set default modes*/
212     if(get_input_timeout()){
213 	EML eml;
214 
215 	eml.s = comatose(get_input_timeout());
216 	emlwrite(_("Checking for new mail every %s seconds"), &eml);
217     }
218 
219 
220     set_browser_title(PILOT_VERSION);
221     FileBrowse(filedir, sizeof(filedir), filename, sizeof(filename), NULL, 0, 0, NULL);
222     wquit(1, 0);
223     exit(0);
224 }
225 
226 
227 /*
228  *  Parse the command line args.
229  *
230  * Args      ac
231  *           av
232  *
233  * Result: command arguments parsed
234  *       possible printing of help for command line
235  *       various global flags set
236  *       returns the name of directory to start in if specified, else NULL
237  */
238 char *
pilot_args(int ac,char ** av,int * setlocale_collate)239 pilot_args(int ac, char **av, int *setlocale_collate)
240 {
241     int   c, usage = 0;
242     char *str;
243     char  tmp_1k_buf[1000];     /* tmp buf to contain err msgs  */
244 
245 Loop:
246     /* while more arguments with leading - */
247     while(--ac > 0 && **++av == '-'){
248       /* while more chars in this argument */
249       while(*++*av){
250 
251 	if(strcmp(*av, "no_setlocale_collate") == 0){
252 	    *setlocale_collate = 0;
253 	    goto Loop;
254 	}
255 #ifndef	_WINDOWS
256 	else if(strcmp(*av, "syscs") == 0){
257 	    use_system_translation = !use_system_translation;
258 	    goto Loop;
259 	}
260 #endif	/* ! _WINDOWS */
261 #ifdef	_WINDOWS
262 	if(strcmp(*av, "cnf") == 0
263 	   || strcmp(*av, "cnb") == 0
264 	   || strcmp(*av, "crf") == 0
265 	   || strcmp(*av, "crb") == 0){
266 
267 	    char *cmd = *av; /* save it to use below */
268 
269 	    if(--ac){
270 		str = *++av;
271 		if(cmd[1] == 'n'){
272 		    if(cmd[2] == 'f')
273 		      pico_nfcolor(str);
274 		    else if(cmd[2] == 'b')
275 		      pico_nbcolor(str);
276 		}
277 		else if(cmd[1] == 'r'){
278 		    if(cmd[2] == 'f')
279 		      pico_rfcolor(str);
280 		    else if(cmd[2] == 'b')
281 		      pico_rbcolor(str);
282 		}
283 	    }
284 	    else{
285 		snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pilot_missing_color), cmd);
286 		pilot_display_args_err(tmp_1k_buf, NULL, 1);
287 	        usage++;
288 	    }
289 
290 	    goto Loop;
291 	}
292 #endif	/* _WINDOWS */
293 #ifndef	_WINDOWS
294 	else if(strcmp(*av, "dcs") == 0 || strcmp(*av, "kcs") == 0){
295 	    char *cmd = *av;
296 
297 	    if(--ac){
298 		if(strcmp(*av, "dcs") == 0){
299 		    display_character_set = *++av;
300 		    if(!output_charset_is_supported(display_character_set)){
301 			snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pilot_output_charset), display_character_set);
302 			pilot_display_args_err(tmp_1k_buf, NULL, 1);
303 			usage++;
304 		    }
305 		}
306 		else{
307 		    keyboard_character_set = *++av;
308 		    if(!input_charset_is_supported(keyboard_character_set)){
309 			snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pilot_input_charset), keyboard_character_set);
310 			pilot_display_args_err(tmp_1k_buf, NULL, 1);
311 			usage++;
312 		    }
313 		}
314 	    }
315 	    else{
316 		snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pilot_missing_charset), cmd);
317 		pilot_display_args_err(tmp_1k_buf, NULL, 1);
318 	        usage++;
319 	    }
320 
321 	    goto Loop;
322 	}
323 #endif	/* ! _WINDOWS */
324 
325 	/*
326 	 * Single char options.
327 	 */
328 	switch(c = **av){
329 	  /*
330 	   * These don't take arguments.
331 	   */
332 	  case 'a':
333 	    gmode ^= MDDOTSOK;		/* show dot files */
334 	    break;
335 	  case 'f':			/* -f for function key use */
336 	    gmode ^= MDFKEY;
337 	    break;
338 	  case 'j':			/* allow "Goto" in file browser */
339 	    gmode ^= MDGOTO;
340 	    break;
341 	  case 'g':			/* show-cursor in file browser */
342 	    gmode ^= MDSHOCUR;
343 	    break;
344 	  case 'm':			/* turn on mouse support */
345 	    gmode ^= MDMOUSE;
346 	    break;
347 	  case 'v':			/* single column display */
348 	    gmode ^= MDONECOL;
349 	    break;			/* break back to inner-while */
350 	  case 'x':			/* suppress keyhelp */
351 	    sup_keyhelp = !sup_keyhelp;
352 	    break;
353 	  case 'q':			/* -q for termcap takes precedence */
354 	    gmode ^= MDTCAPWINS;
355 	    break;
356 	  case 'z':			/* -z to suspend */
357 	    gmode ^= MDSSPD;
358 	    break;
359 	  case 'h':
360 	    usage++;
361 	    break;
362 
363 	  /*
364 	   * These do take arguments.
365 	   */
366 	  case 'n':			/* -n for new mail notification */
367 	  case 'o' :			/* operating tree */
368 	    if(*++*av)
369 	      str = *av;
370 	    else if(--ac)
371 	      str = *++av;
372 	    else{
373 	      snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pilot_missing_arg), c);
374 	      pilot_display_args_err(tmp_1k_buf, NULL, 1);
375 	      usage++;
376 	      goto Loop;
377 	    }
378 
379 	    switch(c){
380 	      case 'o':
381 		strncpy(opertree, str, NLINE);
382 		gmode ^= MDTREE;
383 		break;
384 
385 	/* numeric args */
386 	      case 'n':
387 		if(!isdigit((unsigned char)str[0])){
388 		  snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pilot_missing_num), c);
389 		  pilot_display_args_err(tmp_1k_buf, NULL, 1);
390 		  usage++;
391 		}
392 
393 		set_input_timeout(180);
394 
395 		if(set_input_timeout(atoi(str)) < 30)
396 		  set_input_timeout(180);
397 
398 		break;
399 	    }
400 
401 	    goto Loop;
402 
403 	  default:			/* huh? */
404 	    snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pilot_missing_flag), c);
405 	    pilot_display_args_err(tmp_1k_buf, NULL, 1);
406 	    usage++;
407 	    break;
408 	}
409       }
410     }
411 
412     if(usage)
413       pilot_args_help();
414 
415     /* return the directory */
416     if(ac > 0)
417       return(*av);
418     else
419       return(NULL);
420 }
421 
422 
423 /*----------------------------------------------------------------------
424     print a few lines of help for command line arguments
425 
426   Args:  none
427 
428  Result: prints help messages
429   ----------------------------------------------------------------------*/
430 void
pilot_args_help(void)431 pilot_args_help(void)
432 {
433     char **a;
434     char *pp[2];
435 
436     pp[1] = NULL;
437 
438     /**  print out possible starting arguments... **/
439 
440     for(a=args_pilot_args; a && *a; a++){
441 	pp[0] = _(*a);
442 	pilot_display_args_err(NULL, pp, 0);
443     }
444 
445     exit(1);
446 }
447 
448 
449 /*----------------------------------------------------------------------
450    write argument error to the display...
451 
452   Args:  none
453 
454  Result: prints help messages
455   ----------------------------------------------------------------------*/
456 void
pilot_display_args_err(char * s,char ** a,int err)457 pilot_display_args_err(char *s, char **a, int err)
458 {
459     char  errstr[256], *errp;
460     FILE *fp = err ? stderr : stdout;
461 
462     if(err && s)
463       snprintf(errp = errstr, sizeof(errstr), _("Argument Error: %.200s"), s);
464     else
465       errp = s;
466 
467     if(errp)
468       fprintf(fp, "%s\n", errp);
469 
470     while(a && *a)
471       fprintf(fp, "%s\n", *a++);
472 }
473