1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: arg.c 900 2008-01-05 01:13:26Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2008 University of Washington
8 * Copyright 2013-2014 Eduardo Chappa
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
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 /*======================================================================
20 Command line argument parsing functions
26 #include "../pith/state.h"
27 #include "../pith/init.h"
28 #include "../pith/conf.h"
29 #include "../pith/list.h"
30 #include "../pith/util.h"
31 #include "../pith/help.h"
38 int process_debug_str(char *);
39 void args_add_attach(PATMT
**, char *, int);
40 int pinerc_cmdline_opt(char *);
44 * Name started as to invoke function key mode
46 #define ALPINE_FKEY_NAME "alpinef"
49 * Various error and informational strings..
51 /* TRANSLATORS: This is a list of errors printed when something goes wrong
52 early on with the argument list. Be careful not to change literal
53 option names mentioned in the strings. */
54 static char args_err_missing_pinerc
[] = N_("missing argument for option \"-pinerc\" (use - for standard out)");
55 #if defined(DOS) || defined(OS2)
56 static char args_err_missing_aux
[] = N_("missing argument for option \"-aux\"");
59 static char args_err_missing_passfile
[] = N_("missing argument for option \"-passfile\"");
60 static char args_err_non_abs_passfile
[] = N_("argument to \"-passfile\" should be fully-qualified");
62 static char args_err_missing_pwdcertdir
[] = N_("missing argument for option \"-pwdcertdir\"");
63 static char args_err_non_abs_pwdcertdir
[] = N_("argument to \"-pwdcertdir\" should be fully-qualified");
64 #endif /* SMIME inside PASSFILE */
66 static char args_err_missing_sort
[] = N_("missing argument for option \"-sort\"");
67 static char args_err_missing_flag_arg
[] = N_("missing argument for flag \"%c\"");
68 static char args_err_missing_flag_num
[] = N_("Non numeric argument for flag \"%c\"");
69 static char args_err_missing_debug_num
[] = N_("Non numeric argument for \"%s\"");
70 static char args_err_missing_url
[] = N_("missing URL for \"-url\"");
71 static char args_err_missing_attachment
[] = N_("missing attachment for \"%s\"");
72 static char args_err_conflict
[] = N_("conflicting action: \"%s\"");
73 static char args_err_unknown
[] = N_("unknown flag \"%c\"");
74 static char args_err_I_error
[] = N_("-I argument \"%s\": %s");
75 static char args_err_d_error
[] = N_("-d argument \"%s\": %s");
76 static char args_err_internal
[] = "%s";
77 static char args_err_missing_copyprc
[] = N_("missing argument for option \"-copy_pinerc\"\nUsage: pine -copy_pinerc <local_pinerc> <remote_pinerc>");
78 static char args_err_missing_copyabook
[] = N_("missing argument for option \"-copy_abook\"\nUsage: pine -copy_abook <local_abook> <remote_abook>");
81 static char *args_pine_args
[] = {
82 N_("Possible Starting Arguments for Alpine program:"),
84 N_(" Argument\tMeaning"),
85 N_(" <addrs>...\tGo directly into composer sending to given address"),
86 N_("\t\tList multiple addresses with a single space between them."),
87 N_("\t\tStandard input redirection is allowed with addresses."),
88 N_("\t\tNote: Places addresses in the \"To\" field only."),
89 N_(" -attach <file>\tGo directly into composer with given file"),
90 N_(" -attachlist <file-list>"),
91 N_(" -attach_and_delete <file>"),
92 N_("\t\tGo to composer, attach file, delete when finished"),
93 N_("\t\tNote: Attach options can't be used if -f, -F"),
94 N_("\t\tadded to Attachment list. Attachlist must be the last"),
95 N_("\t\toption on the command line"),
96 N_(" -bail\t\tExit if pinerc file doesn't already exist"),
98 N_(" -d n\t\tDebug - set debug level to 'n', or use the following:"),
99 N_(" -d keywords...\tflush,timestamp,imap=0..4,tcp,numfiles=0..31,verbose=0..9"),
101 N_(" -f <folder>\tFolder - give folder name to open"),
102 N_(" -c <number>\tContext - which context to apply to -f arg"),
103 N_(" -F <file>\tFile - give file name to open and page through and"),
104 N_("\t\tforward as email."),
105 N_(" -h \t\tHelp - give this list of options"),
106 N_(" -k \t\tKeys - Force use of function keys"),
107 N_(" -z \t\tSuspend - allow use of ^Z suspension"),
108 N_(" -r \t\tRestricted - can only send mail to oneself"),
109 N_(" -sort <sort>\tSort - Specify sort order of folder:"),
110 N_("\t\t\tarrival, subject, threaded, orderedsubject, date,"),
111 N_("\t\t\tfrom, size, score, to, cc, /reverse"),
112 N_(" -i\t\tIndex - Go directly to index, bypassing main menu"),
113 N_(" -I <keystroke_list> Initial keystrokes to be executed"),
114 N_(" -n <number>\tEntry in index to begin on"),
115 N_(" -o \t\tReadOnly - Open first folder read-only"),
116 N_(" -conf\t\tConfiguration - Print out fresh global configuration. The"),
117 N_("\t\tvalues of your global configuration affect all Alpine users"),
118 N_("\t\ton your system unless they have overridden the values in their"),
119 N_("\t\tpinerc files."),
120 N_(" -pinerc <file>\tConfiguration - Put fresh pinerc configuration in <file>"),
121 N_(" -p <pinerc>\tUse alternate .pinerc file"),
122 #if !defined(DOS) && !defined(OS2)
123 N_(" -P <pine.conf>\tUse alternate pine.conf file"),
125 N_(" -aux <aux_files_dir>\tUse this with remote pinerc"),
126 N_(" -P <pine.conf>\tUse pine.conf file for default settings"),
127 N_(" -nosplash \tDisable the PC-Alpine splash screen"),
130 #if defined(APPLEKEYCHAIN) || (WINCRED > 0)
131 N_(" -erase_stored_passwords\tEliminate any stored passwords"),
135 N_(" -passfile <fully_qualified_filename>\tSet the password file to something other"),
136 N_("\t\tthan the default"),
138 N_(" -pwdcertdir <fully_qualified_path>\tSet the directory to store a personal"),
139 N_("\t\tkey and certificate to encrypt and decrypt your password file."),
140 #endif /* SMIME inside PASSFILE */
141 #endif /* PASSFILE */
143 #ifdef LOCAL_PASSWD_CACHE
144 N_(" -nowrite_password_cache\tRead from a password cache if there is one, but"),
145 N_("\t\t\t\tnever offer to write a password to the cache"),
146 #endif /* LOCAL_PASSWD_CACHE */
148 N_(" -x <config>\tUse configuration exceptions in <config>."),
149 N_("\t\tExceptions are used to override your default pinerc"),
150 N_("\t\tsettings for a particular platform, can be a local file or"),
151 N_("\t\ta remote folder."),
152 N_(" -v \t\tVersion - show version information"),
153 N_(" -version\tVersion - show version information"),
154 N_(" -supported\tList supported options"),
155 N_(" -url <url>\tOpen the given URL"),
156 N_("\t\tNote: Can't be used if -f, -F"),
157 N_("\t\tStandard input redirection is not allowed with URLs."),
158 N_("\t\tFor mailto URLs, 'body='text should be used in place of"),
159 N_("\t\tinput redirection."),
160 N_(" -copy_pinerc <local_pinerc> <remote_pinerc> copy local pinerc to remote"),
161 N_(" -copy_abook <local_abook> <remote_abook> copy local addressbook to remote"),
162 N_(" -convert_sigs -p <pinerc> convert signatures to literal signatures"),
163 #if defined(_WINDOWS)
164 N_(" -install \tPrompt for some basic setup information"),
165 N_(" -uninstall \tRemove traces of Alpine from Windows system settings"),
166 N_(" -registry <cmd>\tWhere cmd is set,noset,clear,clearsilent,dump"),
168 " -<option>=<value> Assign <value> to the pinerc option <option>",
169 "\t\t e.g. -signature-file=sig1",
170 "\t\t e.g. -color-style=no-color",
171 "\t\t e.g. -feature-list=enable-sigdashes",
172 "\t\t Note: feature-list is additive.",
173 "\t\t You may leave off the \"feature-list=\" part of that,",
174 "\t\t e.g. -enable-sigdashes",
181 * Parse the command line args.
183 * Args: pine_state -- The pine_state structure to put results in
184 * argc, argv -- The obvious
185 * addrs -- Pointer to address list that we set for caller
187 * Result: command arguments parsed
188 * possible printing of help for command line
189 * various flags in pine_state set
190 * returns the string name of the first folder to open
194 pine_args(struct pine
*pine_state
, int argc
, char **argv
, ARGDATA_S
*args
)
200 char *cmd_list
= NULL
;
201 char *debug_str
= NULL
;
203 char *pinerc_file
= NULL
;
209 int do_can_suspend
= 0;
211 struct variable
*vars
= pine_state
->vars
;
215 memset(args
, 0, sizeof(ARGDATA_S
));
216 args
->action
= aaFolder
;
218 pine_state
->pine_name
= (lc
= last_cmpnt(argv
[0])) ? lc
: (lc
= argv
[0]);
220 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, "%.*s", pine_state
->pine_name
- argv
[0], argv
[0]);
221 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
222 pine_state
->pine_dir
= cpystr(tmp_20k_buf
);
225 /* while more arguments with leading - */
226 Loop
: while(--ac
> 0)
228 /* while more chars in this argument */
230 /* check for pinerc options */
231 if(pinerc_cmdline_opt(*av
)){
232 goto Loop
; /* done with this arg, go to next */
234 /* then other multi-char options */
235 else if(strcmp(*av
, "conf") == 0){
237 goto Loop
; /* done with this arg, go to next */
239 else if(strcmp(*av
, "pinerc") == 0){
243 display_args_err(_(args_err_missing_pinerc
), NULL
, 1);
249 #if defined(DOS) || defined(OS2)
250 else if(strcmp(*av
, "aux") == 0){
252 if((str
= *++av
) != NULL
)
253 pine_state
->aux_files_dir
= cpystr(str
);
256 display_args_err(_(args_err_missing_aux
), NULL
, 1);
262 else if(strcmp(*av
, "nosplash") == 0)
263 goto Loop
; /* already taken care of in WinMain */
266 #if defined(APPLEKEYCHAIN) || (WINCRED > 0)
267 else if(strcmp(*av
, "erase_stored_passwords") == 0){
269 erase_windows_credentials();
271 macos_erase_keychain();
275 #endif /* defined(APPLEKEYCHAIN) || (WINCRED > 0) */
278 else if(strcmp(*av
, "passfile") == 0){
280 if((str
= *++av
) != NULL
){
281 if(!is_absolute_path(str
)){
282 display_args_err(_(args_err_non_abs_passfile
),
287 if(pine_state
->passfile
)
288 fs_give((void **)&pine_state
->passfile
);
290 pine_state
->passfile
= cpystr(str
);
295 display_args_err(_(args_err_missing_passfile
), NULL
, 1);
302 else if(strcmp(*av
, "pwdcertdir") == 0){
304 if((str
= *++av
) != NULL
){
305 if(!is_absolute_path(str
)){
306 display_args_err(_(args_err_non_abs_pwdcertdir
),
311 if(pine_state
->pwdcertdir
)
312 fs_give((void **)&pine_state
->pwdcertdir
);
314 pine_state
->pwdcertdir
= cpystr(str
);
319 display_args_err(_(args_err_missing_pwdcertdir
), NULL
, 1);
325 #endif /* SMIME inside PASSFILE */
326 #endif /* PASSFILE */
328 #ifdef LOCAL_PASSWD_CACHE
329 else if(strcmp(*av
, "nowrite_password_cache") == 0){
330 ps_global
->nowrite_password_cache
= 1;
333 #endif /* LOCAL_PASSWD_CACHE */
335 else if(strcmp(*av
, "convert_sigs") == 0){
336 ps_global
->convert_sigs
= 1;
339 else if(strcmp(*av
, "supported") == 0){
340 ps_global
->dump_supported_options
= 1;
343 else if(strcmp(*av
, "copy_pinerc") == 0){
344 if(args
->action
== aaFolder
&& !args
->data
.folder
){
345 args
->action
= aaPrcCopy
;
348 args
->data
.copy
.local
= *++av
;
349 args
->data
.copy
.remote
= *++av
;
352 display_args_err(_(args_err_missing_copyprc
), NULL
, 1);
357 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), "-copy_pinerc");
358 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
359 display_args_err(tmp_20k_buf
, NULL
, 1);
365 else if(strcmp(*av
, "copy_abook") == 0){
366 if(args
->action
== aaFolder
&& !args
->data
.folder
){
367 args
->action
= aaAbookCopy
;
370 args
->data
.copy
.local
= *++av
;
371 args
->data
.copy
.remote
= *++av
;
374 display_args_err(_(args_err_missing_copyabook
), NULL
, 1);
379 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), "-copy_abook");
380 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
381 display_args_err(tmp_20k_buf
, NULL
, 1);
387 else if(strcmp(*av
, "sort") == 0){
390 COM_SORT_KEY
= cpystr(sort
);
393 display_args_err(_(args_err_missing_sort
), NULL
, 1);
399 else if(strcmp(*av
, "url") == 0){
400 if(args
->action
== aaFolder
&& !args
->data
.folder
){
401 args
->action
= aaURL
;
403 args
->url
= cpystr(*++av
);
406 display_args_err(_(args_err_missing_url
), NULL
, 1);
411 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), "-url");
412 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
413 display_args_err(tmp_20k_buf
, NULL
, 1);
419 else if(strcmp(*av
, "attach") == 0){
420 if((args
->action
== aaFolder
&& !args
->data
.folder
)
421 || args
->action
== aaMail
422 || args
->action
== aaURL
){
423 if(args
->action
!= aaURL
)
424 args
->action
= aaMail
;
426 args_add_attach(&args
->data
.mail
.attachlist
,
430 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_attachment
), "-attach");
431 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
432 display_args_err(tmp_20k_buf
, NULL
, 1);
437 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), "-attach");
438 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
439 display_args_err(tmp_20k_buf
, NULL
, 1);
445 else if(strcmp(*av
, "attachlist") == 0){
446 if((args
->action
== aaFolder
&& !args
->data
.folder
)
447 || args
->action
== aaMail
448 || args
->action
== aaURL
){
449 if(args
->action
!= aaURL
)
450 args
->action
= aaMail
;
453 if(can_access(*(av
+1), READ_ACCESS
) == 0){
455 args_add_attach(&args
->data
.mail
.attachlist
,
464 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_attachment
), "-attachList");
465 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
466 display_args_err(tmp_20k_buf
, NULL
, 1);
471 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), "-attachList");
472 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
473 display_args_err(tmp_20k_buf
, NULL
, 1);
479 else if(strcmp(*av
, "attach_and_delete") == 0){
480 if((args
->action
== aaFolder
&& !args
->data
.folder
)
481 || args
->action
== aaMail
482 || args
->action
== aaURL
){
483 if(args
->action
!= aaURL
)
484 args
->action
= aaMail
;
486 args_add_attach(&args
->data
.mail
.attachlist
,
490 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_attachment
), "-attach_and_delete");
491 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
492 display_args_err(tmp_20k_buf
, NULL
, 1);
497 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), "-attach_and_delete");
498 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
499 display_args_err(tmp_20k_buf
, NULL
, 1);
505 else if(strcmp(*av
, "bail") == 0){
506 pine_state
->exit_if_no_pinerc
= 1;
509 else if(strcmp(*av
, "version") == 0){
514 else if(strcmp(*av
, "install") == 0){
515 pine_state
->install_flag
= 1;
516 pine_state
->update_registry
= UREG_ALWAYS_SET
;
519 else if(strcmp(*av
, "uninstall") == 0){
521 * Blast password cache, clear registry settings
524 erase_windows_credentials();
526 mswin_reg(MSWR_OP_BLAST
, MSWR_NULL
, NULL
, 0);
529 else if(strcmp(*av
, "registry") == 0){
531 if(!strucmp(*++av
, "set")){
532 pine_state
->update_registry
= UREG_ALWAYS_SET
;
534 else if(!strucmp(*av
, "noset")){
535 pine_state
->update_registry
= UREG_NEVER_SET
;
537 else if(!strucmp(*av
, "clear")){
538 if(!mswin_reg(MSWR_OP_BLAST
, MSWR_NULL
, NULL
, 0))
540 _("Alpine related Registry values removed."),
544 _("Not all Alpine related Registry values could be removed"),
548 else if(!strucmp(*av
, "clearsilent")){
549 mswin_reg(MSWR_OP_BLAST
, MSWR_NULL
, NULL
, 0);
552 else if(!strucmp(*av
, "dump")){
553 char **pRegistry
= mswin_reg_dump();
556 display_args_err(NULL
, pRegistry
, 0);
557 free_list_array(&pRegistry
);
562 display_args_err(_("unknown registry command"),
568 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_flag_arg
), c
);
569 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
570 display_args_err(tmp_20k_buf
, NULL
, 1);
577 /* single char flags */
582 break; /* break back to inner-while */
590 pine_state
->restricted
= 1;
593 pine_state
->open_readonly_on_startup
= 1;
596 pine_state
->start_in_index
= 1;
600 break; /* break back to inner-while */
601 /* these take arguments */
602 case 'f': case 'F': case 'p': case 'I':
603 case 'c': case 'd': case 'P': case 'x': /* string args */
604 case 'n': /* integer args */
609 else if(c
== 'f' || c
== 'F')
612 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_flag_arg
), c
);
613 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
614 display_args_err(tmp_20k_buf
, NULL
, 1);
621 if(args
->action
== aaFolder
&& !args
->data
.folder
){
622 args
->data
.folder
= cpystr(str
);
625 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), "-f");
626 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
627 display_args_err(tmp_20k_buf
, NULL
, 1);
633 if(args
->action
== aaFolder
&& !args
->data
.folder
){
634 args
->action
= aaMore
;
635 args
->data
.file
= cpystr(str
);
638 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), "-F");
639 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
640 display_args_err(tmp_20k_buf
, NULL
, 1);
653 char path
[MAXPATH
], dir
[MAXPATH
];
655 if(IS_REMOTE(str
) || is_absolute_path(str
)){
656 strncpy(path
, str
, sizeof(path
)-1);
657 path
[sizeof(path
)-1] = '\0';
660 getcwd(dir
, sizeof(path
));
661 build_path(path
, dir
, str
, sizeof(path
));
665 * Pinerc used to be the name of the pinerc
666 * file. Now, since the pinerc can be remote,
667 * we've replaced the variable pinerc with the
668 * structure prc. Unfortunately, other parts of
669 * pine rely on the fact that pinerc is the
670 * name of the pinerc _file_, and use the
671 * directory that the pinerc file is located
672 * in for their own purposes. We keep that so
673 * things will keep working.
676 if(!IS_REMOTE(path
)){
677 if(pine_state
->pinerc
)
678 fs_give((void **)&pine_state
->pinerc
);
680 pine_state
->pinerc
= cpystr(path
);
684 * Last one wins. This would be the place where
685 * we put multiple pinercs in a list if we
686 * were to allow that.
689 free_pinerc_s(&pine_state
->prc
);
691 pine_state
->prc
= new_pinerc_s(path
);
697 char path
[MAXPATH
], dir
[MAXPATH
];
699 if(IS_REMOTE(str
) || is_absolute_path(str
)){
700 strncpy(path
, str
, sizeof(path
)-1);
701 path
[sizeof(path
)-1] = '\0';
704 getcwd(dir
, sizeof(path
));
705 build_path(path
, dir
, str
, sizeof(path
));
708 if(pine_state
->pconf
)
709 free_pinerc_s(&pine_state
->pconf
);
711 pine_state
->pconf
= new_pinerc_s(path
);
717 pine_state
->exceptions
= cpystr(str
);
721 if(!isdigit((unsigned char)str
[0])){
722 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
,
723 _(args_err_missing_flag_num
), c
);
724 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
725 display_args_err(tmp_20k_buf
, NULL
, 1);
730 pine_state
->init_context
= (short) atoi(str
);
734 if(!isdigit((unsigned char)str
[0])){
735 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
,
736 _(args_err_missing_flag_num
), c
);
737 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
738 display_args_err(tmp_20k_buf
, NULL
, 1);
743 pine_state
->start_entry
= atoi(str
);
744 if(pine_state
->start_entry
< 1)
745 pine_state
->start_entry
= 1;
753 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_unknown
), c
);
754 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
755 display_args_err(tmp_20k_buf
, NULL
, 1);
762 else if(args
->action
== aaMail
763 || (args
->action
== aaFolder
&& !args
->data
.folder
)){
764 STRLIST_S
*stp
, **slp
;
766 args
->action
= aaMail
;
768 stp
= new_strlist(*av
);
770 for(slp
= &args
->data
.mail
.addrlist
; *slp
; slp
= &(*slp
)->next
)
776 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_conflict
), *av
);
777 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
778 display_args_err(tmp_20k_buf
, NULL
, 1);
791 COM_INIT_CMD_LIST
= parse_list(cmd_list
, commas
+1, 0, &error
);
793 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_I_error
), cmd_list
, error
);
794 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
795 display_args_err(tmp_20k_buf
, NULL
, 1);
801 pine_state
->debug_nfiles
= NUMDEBUGFILES
;
803 if(debug_str
&& process_debug_str(debug_str
))
806 if(lc
&& strncmp(lc
, ALPINE_FKEY_NAME
, sizeof(ALPINE_FKEY_NAME
) - 1) == 0)
809 if(do_use_fk
|| do_can_suspend
){
819 strncat(list
, ",", sizeof(list
)-strlen(list
)-1);
820 list
[sizeof(list
)-1] = '\0';
823 strncat(list
, "use-function-keys", sizeof(list
)-strlen(list
)-1);
824 list
[sizeof(list
)-1] = '\0';
829 strncat(list
, ",", sizeof(list
)-strlen(list
)-1);
830 list
[sizeof(list
)-1] = '\0';
833 strncat(list
, "enable-suspend", sizeof(list
)-strlen(list
)-1);
834 list
[sizeof(list
)-1] = '\0';
841 pine_state
->feat_list_back_compat
= parse_list(list
,commas
+1,0,&error
);
843 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, args_err_internal
, error
);
844 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
845 display_args_err(tmp_20k_buf
, NULL
, 1);
850 if(((do_conf
? 1 : 0)+(pinerc_file
? 1 : 0)) > 1){
851 display_args_err(_("May only have one of -conf and -pinerc"),
863 extern char datestamp
[], hoststamp
[];
866 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, "Alpine %s (%s %s) built %s on %s",
868 SYSTYPE
? SYSTYPE
: "?",
869 get_alpine_revision_string(rev
, sizeof(rev
)),
870 datestamp
, hoststamp
);
871 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
872 display_args_err(tmp_20k_buf
, NULL
, 0);
880 dump_new_pinerc(pinerc_file
);
883 * Don't NULL out argv[0] or we might crash in unexpected ways. In OS X, we were
884 * crashing when opening attachments because of this.
886 if(ac
<= 0 && av
!= argv
)
892 * Returns 0 if ok, -1 if error.
895 process_debug_str(char *debug_str
)
899 int new_style_debug_arg
= 0;
906 if(!isdigit((unsigned char)debug_str
[0]))
907 new_style_debug_arg
++;
909 if(new_style_debug_arg
){
914 list
= parse_list(debug_str
, commas
+1, 0, &error
);
916 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_d_error
), debug_str
, error
);
917 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
918 display_args_err(tmp_20k_buf
, NULL
, 1);
923 for(p
= list
; *p
; p
++){
924 if(struncmp(*p
, "timestamp", 9) == 0){
925 ps_global
->debug_timestamp
= 1;
927 else if(struncmp(*p
, "imap", 4) == 0){
929 if(!*q
|| !*(q
+1) || *q
!= '=' ||
930 !isdigit((unsigned char)*(q
+1))){
931 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_debug_num
), *p
);
932 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
933 display_args_err(tmp_20k_buf
, NULL
, 1);
938 ps_global
->debug_imap
= MIN(5,MAX(0,i
));
941 else if(struncmp(*p
, "flush", 5) == 0){
942 ps_global
->debug_flush
= 1;
944 else if(struncmp(*p
, "tcp", 3) == 0){
945 ps_global
->debug_tcp
= 1;
947 else if(struncmp(*p
, "verbose", 7) == 0){
949 if(!*q
|| !*(q
+1) || *q
!= '=' ||
950 !isdigit((unsigned char)*(q
+1))){
951 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_debug_num
), *p
);
952 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
953 display_args_err(tmp_20k_buf
, NULL
, 1);
959 else if(struncmp(*p
, "numfiles", 8) == 0){
961 if(!*q
|| !*(q
+1) || *q
!= '=' ||
962 !isdigit((unsigned char)*(q
+1))){
963 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_debug_num
), *p
);
964 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
965 display_args_err(tmp_20k_buf
, NULL
, 1);
970 ps_global
->debug_nfiles
= MIN(31,MAX(0,i
));
973 else if(struncmp(*p
, "malloc", 6) == 0){
975 if(!*q
|| !*(q
+1) || *q
!= '=' ||
976 !isdigit((unsigned char)*(q
+1))){
977 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_debug_num
), *p
);
978 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
979 display_args_err(tmp_20k_buf
, NULL
, 1);
984 ps_global
->debug_malloc
= MIN(63,MAX(0,i
));
987 #if defined(ENABLE_LDAP) && defined(LDAP_DEBUG)
988 else if(struncmp(*p
, "ldap", 4) == 0){
990 if(!*q
|| !*(q
+1) || *q
!= '=' ||
991 !isdigit((unsigned char)*(q
+1))){
992 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _(args_err_missing_debug_num
), *p
);
993 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
994 display_args_err(tmp_20k_buf
, NULL
, 1);
1004 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _("unknown debug keyword \"%s\""), *p
);
1005 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
1006 display_args_err(tmp_20k_buf
, NULL
, 1);
1011 free_list_array(&list
);
1015 debug
= atoi(debug_str
);
1017 ps_global
->debug_imap
= 5;
1019 ps_global
->debug_imap
= 4;
1021 ps_global
->debug_imap
= 3;
1023 ps_global
->debug_imap
= 2;
1025 ps_global
->debug_imap
= 1;
1028 ps_global
->debug_timestamp
= 1;
1031 ps_global
->debug_flush
= 1;
1035 if(!new_style_debug_arg
){
1037 ps_global
->debug_malloc
=
1038 (debug
<= DEFAULT_DEBUG
) ? 1 : (debug
< 9) ? 2 : 3;
1039 #else /* !CSRIMALLOC */
1042 ps_global
->debug_malloc
= 2;
1043 #else /* !HAVE_SMALLOC */
1046 ps_global
->debug_malloc
= 32;
1048 #endif /* HAVE_SMALLOC */
1049 #endif /* CSRIMALLOC */
1054 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, _("unknown flag \"d\", debugging not compiled in"));
1055 tmp_20k_buf
[SIZEOF_20KBUF
-1] = '\0';
1056 display_args_err(tmp_20k_buf
, NULL
, 1);
1066 args_add_attach(PATMT
**alpp
, char *s
, int deleted
)
1068 PATMT
*atmp
, **atmpp
;
1070 atmp
= (PATMT
*) fs_get(sizeof(PATMT
));
1071 memset(atmp
, 0, sizeof(PATMT
));
1072 atmp
->filename
= cpystr(s
);
1074 #if defined(DOS) || defined(OS2)
1075 (void) removing_quotes(atmp
->filename
);
1079 atmp
->flags
|= A_TMP
;
1081 for(atmpp
= alpp
; *atmpp
; atmpp
= &(*atmpp
)->next
)
1088 /*----------------------------------------------------------------------
1089 print a few lines of help for command line arguments
1093 Result: prints help messages
1094 ----------------------------------------------------------------------*/
1105 /** print out possible starting arguments... **/
1108 * display_args_err expects already translated input
1109 * so we need to translate a line at a time. Since
1110 * the 1st and 3rd args are zero it is ok to call it
1113 * Windows expects the full block of text so we'll pass
1117 for(a
=args_pine_args
; a
&& *a
; a
++){
1119 display_args_err(NULL
, pp
, 0);
1122 display_args_err(NULL
, args_pine_args
, 0);
1129 /*----------------------------------------------------------------------
1130 write argument error to the display...
1134 Result: prints help messages
1135 ----------------------------------------------------------------------*/
1137 display_args_err(char *s
, char **a
, int err
)
1139 char errstr
[256], *errp
;
1140 FILE *fp
= err
? stderr
: stdout
;
1144 snprintf(errp
= errstr
, sizeof(errstr
), "%s: %s", _("Argument Error"), s
);
1145 errstr
[sizeof(errstr
)-1] = '\0';
1152 mswin_messagebox(errp
, err
);
1159 fprintf(fp
, "%s\n", errp
);
1162 fprintf(fp
, "%s\n", *a
++);
1168 * The argument is an argument from the command line. We check to see
1169 * if it is specifying an alternate value for one of the options that is
1170 * normally set in pinerc. If so, we return 1 and set the appropriate
1171 * values in the variables array.
1174 * varname=value1,value2,value3
1175 * feature-list=featurename these are just a special
1176 * feature-list=featurename1,featurename2 case of above
1177 * featurename This is equivalent to above
1181 pinerc_cmdline_opt(char *arg
)
1193 for(v
= ps_global
->vars
; v
->name
!= NULL
; v
++){
1194 if(v
->is_used
&& struncmp(v
->name
, arg
, strlen(v
->name
)) == 0){
1195 p1
= arg
+ strlen(v
->name
);
1197 /*----- Skip to '=' -----*/
1198 while(*p1
&& (*p1
== '\t' || *p1
== ' '))
1202 char buf
[MAILTMPLEN
];
1204 snprintf(buf
, sizeof(buf
), _("Missing \"=\" after -%s\n"), v
->name
);
1205 buf
[sizeof(buf
)-1] = '\0';
1206 exceptional_exit(buf
, -1);
1214 /* no match, check for a feature name used directly */
1215 if(v
->name
== NULL
){
1219 if(struncmp(arg
, "no-", 3) == 0)
1224 for(i
= 0; (feat
= feature_list(i
)) != NULL
; i
++){
1225 if(strucmp(featname
, feat
->name
) == 0){
1226 v
= &(ps_global
->vars
)[V_FEATURE_LIST
];
1236 if(v
->is_obsolete
|| !v
->is_user
){
1237 char buf
[MAILTMPLEN
];
1240 snprintf(buf
, sizeof(buf
), _("Option \"%s\" is obsolete\n"), v
->name
);
1242 snprintf(buf
, sizeof(buf
), _("Option \"%s\" is not user settable\n"), v
->name
);
1244 exceptional_exit(buf
, -1);
1249 oldlvalue
= v
->cmdline_val
.l
;
1250 v
->cmdline_val
.l
= NULL
;
1252 else if(v
->cmdline_val
.p
)
1253 fs_give((void **) &(v
->cmdline_val
.p
));
1255 /*----- Matched a variable, get its value ----*/
1256 while(*p1
== ' ' || *p1
== '\t')
1262 v
->cmdline_val
.l
= (char **)fs_get(2 * sizeof(char *));
1264 * we let people leave off the quotes on command line so that
1265 * they don't have to mess with shell quoting
1267 v
->cmdline_val
.l
[0] = cpystr("");
1268 v
->cmdline_val
.l
[1] = NULL
;
1270 free_list_array(&oldlvalue
);
1273 v
->cmdline_val
.p
= cpystr("");
1278 /*--value is non-empty--*/
1279 if(*value
== '"' && !v
->is_list
){
1281 for(p1
= value
; *p1
&& *p1
!= '"'; p1
++);
1285 removing_trailing_white_space(value
);
1287 removing_trailing_white_space(value
);
1295 for(p1
=value
; *p1
; p1
++){ /* generous count of list elements */
1296 if(*p1
== '"') /* ignore ',' if quoted */
1297 was_quoted
= (was_quoted
) ? 0 : 1;
1299 if(*p1
== ',' && !was_quoted
)
1303 lvalue
= parse_list(value
, count
, 0, &error
);
1305 char buf
[MAILTMPLEN
];
1307 snprintf(buf
, sizeof(buf
), "%s in %s = \"%s\"\n", error
, v
->name
, value
);
1308 buf
[sizeof(buf
)-1] = '\0';
1309 exceptional_exit(buf
, -1);
1312 * Special case: turn "" strings into empty strings.
1313 * This allows users to turn off default lists. For example,
1314 * if smtp-server is set then a user could override smtp-server
1315 * with smtp-server="".
1317 for(i
= 0; lvalue
[i
]; i
++)
1318 if(lvalue
[i
][0] == '"' &&
1319 lvalue
[i
][1] == '"' &&
1320 lvalue
[i
][2] == '\0')
1321 lvalue
[i
][0] = '\0';
1326 char **combinedlvalue
;
1329 /* combine old and new cmdline lists */
1330 for(count
= 0, i
= 0; oldlvalue
[i
]; i
++, count
++)
1333 for(i
= 0; lvalue
&& lvalue
[i
]; i
++, count
++)
1336 combinedlvalue
= (char **) fs_get((count
+1) * sizeof(char *));
1337 memset(combinedlvalue
, 0, (count
+1) * sizeof(*combinedlvalue
));
1339 for(i
= 0, j
= 0; oldlvalue
[i
]; i
++, j
++)
1340 combinedlvalue
[j
] = cpystr(oldlvalue
[i
]);
1342 for(i
= 0; lvalue
&& lvalue
[i
]; i
++, j
++)
1343 combinedlvalue
[j
] = cpystr(lvalue
[i
]);
1345 v
->cmdline_val
.l
= combinedlvalue
;
1347 fs_give((void **) &oldlvalue
);
1349 fs_give((void **) &lvalue
);
1352 v
->cmdline_val
.l
= lvalue
;
1355 v
->cmdline_val
.p
= cpystr(value
);