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