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