aboutsummaryrefslogtreecommitdiffstats
path: root/options.c
diff options
context:
space:
mode:
Diffstat (limited to 'options.c')
-rw-r--r--options.c381
1 files changed, 381 insertions, 0 deletions
diff --git a/options.c b/options.c
new file mode 100644
index 00000000..f8bda4b2
--- /dev/null
+++ b/options.c
@@ -0,0 +1,381 @@
+/* Copyright 1993-95 by Carl Harris, Jr.
+ * All rights reserved
+ *
+ * Distribute freely, except: don't remove my name from the source or
+ * documentation (don't take credit for my work), mark your changes (don't
+ * get me blamed for your possible bugs), don't alter or remove this
+ * notice. May be sold if buildable source is provided to buyer. No
+ * warrantee of any kind, express or implied, is included with this
+ * software; use at your own risk, responsibility for damages (if any) to
+ * anyone resulting from the use of this software rests entirely with the
+ * user.
+ *
+ * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
+ * I'll try to keep a version up to date. I can be reached as follows:
+ * Carl Harris <ceharris@mal.com>
+ */
+
+/***********************************************************************
+ module: options.c
+ project: popclient
+ programmer: Carl Harris, ceharris@mal.com
+ description: command-line option processing
+
+ $Log: options.c,v $
+ Revision 1.1 1996/06/24 18:11:08 esr
+ Initial revision
+
+ Revision 1.4 1995/08/14 18:36:39 ceharris
+ Patches to support POP3's LAST command.
+ Final revisions for beta3 release.
+
+ Revision 1.3 1995/08/10 00:32:34 ceharris
+ Preparation for 3.0b3 beta release:
+ - added code for --kill/--keep, --limit, --protocol, --flush
+ options; --pop2 and --pop3 options now obsoleted by --protocol.
+ - added support for APOP authentication, including --with-APOP
+ argument for configure.
+ - provisional and broken support for RPOP
+ - added buffering to SockGets and SockRead functions.
+ - fixed problem of command-line options not being correctly
+ carried into the merged options record.
+
+ Revision 1.2 1995/08/09 01:32:51 ceharris
+ Version 3.0 beta 2 release.
+ Added
+ - .poprc functionality
+ - GNU long options
+ - multiple servers on the command line.
+ Fixed
+ - Passwords showing up in ps output.
+
+ Revision 1.1 1995/08/08 01:01:21 ceharris
+ Added GNU-style long options processing.
+ Fixed password in 'ps' output problem.
+ Fixed various RCS tag blunders.
+ Integrated .poprc parser, lexer, etc into Makefile processing.
+
+ ***********************************************************************/
+
+#include <config.h>
+#include <stdio.h>
+
+#include <pwd.h>
+#include "getopt.h"
+#include "popclient.h"
+#include "bzero.h"
+
+/* XXX -- Would like to use 'enum' here, but it causes type mismatch
+ problems many compilers */
+#define LA_VERSION 1
+#define LA_ALL 2
+#define LA_KILL 3
+#define LA_KEEP 4
+#define LA_VERBOSE 5
+#define LA_SILENT 6
+#define LA_STDOUT 7
+#define LA_LIMIT 8
+#define LA_FLUSH 9
+#define LA_PROTOCOL 10
+#define LA_DAEMON 11
+#define LA_POPRC 12
+#define LA_USERNAME 13
+#define LA_PASSWORD 14
+#define LA_REMOTEFILE 15
+#define LA_LOCALFILE 16
+
+
+static char *shortoptions = "23VaKkvscl:Fd:f:u:p:r:o:";
+static struct option longoptions[] = {
+ {"version", no_argument, (int *) 0, LA_VERSION },
+ {"all", no_argument, (int *) 0, LA_ALL },
+ {"kill", no_argument, (int *) 0, LA_KILL },
+ {"keep", no_argument, (int *) 0, LA_KEEP },
+ {"verbose", no_argument, (int *) 0, LA_VERBOSE },
+ {"silent", no_argument, (int *) 0, LA_SILENT },
+ {"stdout", no_argument, (int *) 0, LA_STDOUT },
+ {"limit", required_argument, (int *) 0, LA_LIMIT },
+ {"flush", no_argument, (int *) 0, LA_FLUSH },
+ {"protocol", required_argument, (int *) 0, LA_PROTOCOL },
+ {"proto", required_argument, (int *) 0, LA_PROTOCOL },
+ {"daemon", required_argument, (int *) 0, LA_DAEMON },
+ {"poprc", required_argument, (int *) 0, LA_POPRC },
+ {"user", required_argument, (int *) 0, LA_USERNAME },
+ {"username", required_argument, (int *) 0, LA_USERNAME },
+ {"password", required_argument, (int *) 0, LA_PASSWORD },
+ {"remote", required_argument, (int *) 0, LA_REMOTEFILE },
+ {"local", required_argument, (int *) 0, LA_LOCALFILE },
+ {(char *) 0, no_argument, (int *) 0, 0 }
+};
+
+
+/*********************************************************************
+ function: parsecmdline
+ description: parse/validate the command line options.
+ arguments:
+ argc argument count.
+ argv argument strings.
+ options pointer to a struct optrec to receive the parsed
+ options.
+
+ return value: if positive, argv index of last parsed option + 1
+ (presumes one or more server names follows).
+ if zero, the command line switches are such that
+ no server names are required (e.g. --version).
+ if negative, the command line is has one or more
+ syntax errors.
+ calls: none.
+ globals: none.
+ *********************************************************************/
+
+int parsecmdline (argc,argv,options)
+int argc;
+char **argv;
+struct optrec *options;
+{
+ int c,i;
+ int fflag = 0; /* TRUE when -o or -c has been specified */
+ int errflag = 0; /* TRUE when a syntax error is detected */
+ int option_index;
+ int got_kill = 0; /* TRUE when --kill is specified */
+
+ extern int optind, opterr; /* defined in getopt(2) */
+ extern char *optarg; /* defined in getopt(2) */
+
+ bzero(options,sizeof(struct optrec)); /* start clean */
+
+ while (!errflag &&
+ (c = getopt_long(argc,argv,shortoptions,
+ longoptions,&option_index)) != -1) {
+
+ switch (c) {
+ case '2':
+ options->whichpop = P_POP2;
+ break;
+ case '3':
+ options->whichpop = P_POP3;
+ break;
+ case 'V':
+ case LA_VERSION:
+ options->versioninfo = !0;
+ break;
+ case 'a':
+ case LA_ALL:
+ options->fetchall = !0;
+ break;
+ case 'K':
+ case LA_KILL:
+ options->keep = 0;
+ got_kill = 1;
+ break;
+ case 'k':
+ case LA_KEEP:
+ options->keep = !0;
+ got_kill = 0;
+ break;
+ case 'v':
+ case LA_VERBOSE:
+ options->verbose = !0;
+ break;
+ case 's':
+ case LA_SILENT:
+ options->silent = !0;
+ break;
+ case 'c':
+ case LA_STDOUT:
+ if (fflag)
+ errflag++;
+ else {
+ fflag++;
+ options->foldertype = OF_STDOUT;
+ }
+ break;
+ case 'l':
+ case LA_LIMIT:
+ options->limit = atoi(optarg);
+ if (options->limit < 0) {
+ fprintf(stderr,"Line count limit must be non-negative");
+ errflag++;
+ }
+ break;
+ case 'F':
+ case LA_FLUSH:
+ options->flush = !0;
+ break;
+ case LA_PROTOCOL:
+ /* XXX -- should probably use a table lookup here */
+ if (strcasecmp(optarg,"pop2") == 0)
+ options->whichpop = P_POP2;
+ else if (strcasecmp(optarg,"pop3") == 0)
+ options->whichpop = P_POP3;
+ else if (strcasecmp(optarg,"imap") == 0)
+ options->whichpop = P_IMAP;
+ else if (strcasecmp(optarg,"apop") == 0)
+ options->whichpop = P_APOP;
+ else if (strcasecmp(optarg,"rpop") == 0)
+ options->whichpop = P_RPOP;
+ else {
+ fprintf(stderr,"Invalid protocol '%s'\n specified.\n", optarg);
+ errflag++;
+ }
+ break;
+ case 'd':
+ case LA_DAEMON:
+ fprintf(stderr,"Got daemonize option with argument '%s'\n",optarg);
+ break;
+ case 'f':
+ case LA_POPRC:
+ options->poprcfile = (char *) xmalloc(strlen(optarg)+1);
+ strcpy(options->poprcfile,optarg);
+ break;
+ case 'u':
+ case LA_USERNAME:
+ strncpy(options->userid,optarg,sizeof(options->userid)-1);
+ break;
+ case 'p':
+ case LA_PASSWORD:
+ strncpy(options->password,optarg,sizeof(options->password)-1);
+ for (i = strlen(options->password)-1; i >= 0; i--)
+ argv[optind-1][i] = '*';
+ break;
+ case 'o':
+ case LA_LOCALFILE:
+ if (fflag)
+ errflag++;
+ else {
+ fflag++;
+ options->foldertype = OF_USERMBOX;
+ strncpy(options->userfolder,optarg,sizeof(options->userfolder)-1);
+ }
+ break;
+ case 'r':
+ case LA_REMOTEFILE:
+ strncpy(options->remotefolder,optarg,sizeof(options->remotefolder)-1);
+ break;
+ default:
+ errflag++;
+ }
+ }
+
+ if (!options->versioninfo)
+ /* if options don't obviate the need, we must have server name(s)
+ left on the command line. */
+ if (optind >= argc)
+ errflag++;
+ else
+ ;
+ else
+ optind = 0;
+
+ if (errflag) {
+ /* squawk if syntax errors were detected */
+ fputs("usage: popclient [options] server [server ...]\n", stderr);
+ fputs(" options\n",stderr);
+ fputs(" -2 use POP2 protocol\n", stderr);
+ fputs(" -3 use POP3 protocol\n", stderr);
+ fputs(" --protocol specify pop2, pop3, imap, apop, or rpop\n",
+ stderr);
+ fputs(" -V, --version display version info\n", stderr);
+ fputs(" -a, --all retrieve old and new messages\n", stderr);
+ fputs(" -F, --flush delete old messages from server\n", stderr);
+ fputs(" -K, --kill delete new messages after retrieval\n", stderr);
+ fputs(" -k, --keep save new messages after retrieval\n", stderr);
+ fputs(" -l, --limit retrieve at most n message lines\n", stderr);
+ fputs(" -s, --silent work silently\n", stderr);
+ fputs(" -v, --verbose work noisily (diagnostic output)\n", stderr);
+ fputs(" -d, --daemon run as a daemon\n", stderr);
+ fputs(" -f, --poprc specify alternate config file\n", stderr);
+ fputs(" -u, --username specify server user ID\n", stderr);
+ fputs(" -p, --password specify server password\n", stderr);
+ fputs(" -c, --stdout write received mail to stdout\n", stderr);
+ fputs(" -o, --local specify filename for received mail\n", stderr);
+ fputs(" -r, --remote specify remote folder name\n", stderr);
+ return(-1);
+ }
+ else {
+ if (options->limit && !got_kill)
+ options->keep = !0;
+ else
+ ;
+ return(optind);
+ }
+}
+
+
+/*********************************************************************
+ function: setdefaults
+ description: set reasonable default values for unspecified options.
+ arguments:
+ options option values parsed from the command-line; unspeci-
+ fied options must be filled with zero.
+
+ return value: zero if defaults were successfully set, else non-zero
+ (indicates a problem reading /etc/passwd).
+ calls: none.
+ globals: writes outlevel.
+ *********************************************************************/
+
+int setdefaults (options)
+struct optrec *options;
+{
+ int uid;
+ struct passwd *pw;
+ char *mailvar;
+
+ bzero(options,sizeof(*options));
+
+ if ((pw = getpwuid(uid = getuid())) == NULL) {
+ fprintf(stderr,"No passwd entry for uid %d\n",uid);
+ return(-1);
+ }
+ /* save the login name for delivery use */
+ strcpy(options->loginid,pw->pw_name);
+
+ options->whichpop = DEF_PROTOCOL;
+ options->foldertype = OF_SYSMBOX;
+
+#if defined(KEEP_IS_DEFAULT)
+ options->keep = 1;
+#else
+ options->keep = 0;
+#endif
+
+ strcpy(options->userid,pw->pw_name);
+
+ options->poprcfile =
+ (char *) xmalloc(strlen(pw->pw_dir)+strlen(POPRC_NAME)+2);
+
+ strcpy(options->poprcfile, pw->pw_dir);
+ strcat(options->poprcfile, "/");
+ strcat(options->poprcfile, POPRC_NAME);
+
+ return(0);
+}
+
+
+
+/******************************************************************
+ function: getnextserver
+ description: read next server name from the command line.
+ arguments:
+ argc from main()
+ argv from main()
+ optind as returned by parsecmdline and this function.
+
+ ret. value: next server name from command line or NULL if all
+ server names have been retrieved.
+ globals: none.
+ calls: none.
+ *****************************************************************/
+char *getnextserver (argc,argv,optind)
+int argc;
+char **argv;
+int *optind;
+{
+ if (*optind >= argc) {
+ /* no more servers */
+ return((char *) 0);
+ }
+ else
+ return(argv[(*optind)++]);
+}