diff options
-rw-r--r-- | fetchmail.h | 156 | ||||
-rw-r--r-- | options.c | 381 | ||||
-rw-r--r-- | rcfile_l.l | 89 | ||||
-rw-r--r-- | rcfile_y.y | 121 |
4 files changed, 747 insertions, 0 deletions
diff --git a/fetchmail.h b/fetchmail.h new file mode 100644 index 00000000..63b8ca70 --- /dev/null +++ b/fetchmail.h @@ -0,0 +1,156 @@ +/* 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: popclient.h + project: popclient + programmer: Carl Harris, ceharris@mal.com + description: global constant, type, and variable definitions. + + $Log: fetchmail.h,v $ + Revision 1.1 1996/06/24 18:14:08 esr + Initial revision + + Revision 1.6 1995/09/07 22:37:35 ceharris + Preparation for 3.0b4 release. + + Revision 1.5 1995/08/14 18:36:44 ceharris + Patches to support POP3's LAST command. + Final revisions for beta3 release. + + Revision 1.4 1995/08/10 00:32:40 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.3 1995/08/09 01:32:57 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.2 1995/08/08 01:01:27 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. + + ***********************************************************************/ + + + +/* definitions for buffer sizes -- somewhat arbitrary */ +#define POPBUFSIZE 512 /* per RFC 937 */ +#define MSGBUFSIZE 1024 /* size of message read buffer */ +#define HOSTLEN 128 /* max hostname length */ +#define USERIDLEN 32 /* max user-length */ +#define PASSWORDLEN MAX_PASSWORD_LENGTH +#define FOLDERLEN 256 /* max folder name length */ +#define DIGESTLEN 33 /* length of MD5 digest */ + +/* exit code values */ +#define PS_SUCCESS 0 /* successful receipt of messages */ +#define PS_NOMAIL 1 /* no mail available */ +#define PS_SOCKET 2 /* socket I/O woes */ +#define PS_AUTHFAIL 3 /* user authorization failed */ +#define PS_PROTOCOL 4 /* protocol violation */ +#define PS_SYNTAX 5 /* command-line syntax error */ +#define PS_IOERR 6 /* local folder I/O woes */ +#define PS_ERROR 7 /* some kind of POP3 error condition */ +#define PS_UNDEFINED 9 /* something I hadn't thought of */ + +/* output noise level */ +#define O_SILENT 0 /* mute, max squelch, etc. */ +#define O_NORMAL 1 /* user-friendly */ +#define O_VERBOSE 2 /* excessive */ + +/* output folder type, used in options record */ +#define OF_SYSMBOX 1 /* use system default mailbox */ +#define OF_USERMBOX 2 /* use user's specified mailbox */ +#define OF_STDOUT 3 /* use stdout */ + +/* Command-line arguments are passed in this structure type */ +struct optrec { + int versioninfo; + int keep; + int verbose; + int whichpop; + int silent; + int limit; + int fetchall; + int flush; + int foldertype; + char loginid [USERIDLEN]; + char *poprcfile; + char userid [USERIDLEN]; + char password [PASSWORDLEN]; +#if defined(HAVE_APOP_SUPPORT) + char digest [DIGESTLEN]; +#endif + char userfolder [FOLDERLEN]; + char remotefolder [FOLDERLEN]; +}; + + +/* .poprc records are passed in this structure type */ +struct prc_server { + char *server; + int protocol; + char *username; + char *password; + char *remotefolder; + char *localfolder; +}; + + +/* Controls the detail of status/progress messages written to stderr */ +extern int outlevel; /* see the O_.* constants above */ + +#ifdef HAVE_PROTOTYPES + +/* prototypes for globally callable functions */ +int doPOP2 (char *servername, struct optrec *options); +int doPOP3 (char *servername, struct optrec *options); + +int parsecmdline (int argc, char **argv, struct optrec *options); +int setdefaults (struct optrec *options); +char *getnextserver (int argc, char **argv, int *optind); +int openuserfolder (struct optrec *options); +int closeuserfolder (int fd); +int openmailpipe (struct optrec *options); +int closemailpipe (int fd); +char *MD5Digest (char *); +char *prc_getpathname (struct optrec *cmd_opts, struct optrec *def_opts); + +#else + +char *getnextserver(); +char *MD5Digest (); +char *prc_getpathname(); + +#endif + 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)++]); +} diff --git a/rcfile_l.l b/rcfile_l.l new file mode 100644 index 00000000..9b37da55 --- /dev/null +++ b/rcfile_l.l @@ -0,0 +1,89 @@ +%{ + +/* 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: poprc_l.l + project: popclient + programmer: Carl Harris, ceharris@mal.com + description: .poprc lexer + + $Log: rcfile_l.l,v $ + Revision 1.1 1996/06/24 18:16:08 esr + Initial revision + + Revision 1.4 1995/08/10 00:32:43 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.3 1995/08/09 01:33:01 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.2 1995/08/08 01:01:34 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 "poproto.h" +#include "poprc_y.h" + +int prc_lineno = 0; +%} + + +%% + +server { return KW_SERVER; } +proto(col)? { return KW_PROTOCOL; } +user(name)? { return KW_USERNAME; } +pass(word)? { return KW_PASSWORD; } +remote(folder)? { return KW_REMOTEFOLDER; } +local(folder)? { return KW_LOCALFOLDER; } + +(pop2)|(POP2) { yylval.proto = P_POP2; return PROTO_POP2; } +(pop3)|(POP3) { yylval.proto = P_POP3; return PROTO_POP3; } +(imap)|(IMAP) { yylval.proto = P_IMAP; return PROTO_IMAP; } +(apop)|(APOP) { yylval.proto = P_APOP; return PROTO_APOP; } +(rpop)|(RPOP) { yylval.proto = P_RPOP; return PROTO_RPOP; } + +(#.*)?\\\n { prc_lineno++; } /* escaped newline is ignored */ + +(#.*)?\n { prc_lineno++; return KW_EOL; } + +[^ \t\r\n#]+ { yylval.sval = (char *) strdup(yytext); return PARAM_STRING; } + +[ \t\r]+ ; /* whitespace */ + diff --git a/rcfile_y.y b/rcfile_y.y new file mode 100644 index 00000000..f3adc0e8 --- /dev/null +++ b/rcfile_y.y @@ -0,0 +1,121 @@ +%{ +/* 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: poprc_y.y + project: popclient + programmer: Carl Harris, ceharris@mal.com + description: .poprc parser + + $Log: rcfile_y.y,v $ + Revision 1.1 1996/06/24 18:17:24 esr + Initial revision + + Revision 1.4 1995/08/10 00:32:45 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.3 1995/08/09 01:33:02 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.2 1995/08/08 01:01:36 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> +extern char *prc_pathname; +extern int prc_lineno; +extern int prc_errflag; +extern char yytext[]; +%} + +%union { + int proto; + char *sval; +} + +%token KW_SERVER KW_PROTOCOL KW_USERNAME KW_PASSWORD +%token KW_REMOTEFOLDER KW_LOCALFOLDER KW_EOL +%token <proto> PROTO_POP2 PROTO_POP3 PROTO_IMAP PROTO_APOP PROTO_RPOP +%token <sval> PARAM_STRING +%type <proto> proto; + +%% + +rcfile: rcline + | rcfile rcline + ; + +rcline: statement KW_EOL + ; + +statement: + | define_server {prc_register(); prc_reset();} + ; + +define_server: KW_SERVER PARAM_STRING server_options {prc_setserver($2);} + | KW_SERVER PARAM_STRING {prc_setserver($2);} + ; + +server_options: serv_option_clause + | server_options serv_option_clause + ; + +serv_option_clause: + KW_PROTOCOL proto {prc_setproto($2);} + | KW_USERNAME PARAM_STRING {prc_setusername($2);} + | KW_PASSWORD PARAM_STRING {prc_setpassword($2);} + | KW_REMOTEFOLDER PARAM_STRING {prc_setremote($2);} + | KW_LOCALFOLDER PARAM_STRING {prc_setlocal($2);} + ; + +proto: PROTO_POP2 + | PROTO_POP3 + | PROTO_IMAP + | PROTO_APOP + | PROTO_RPOP + ; + +%% + + +yyerror (s) +char *s; +{ + fprintf(stderr,"%s line %d: %s at %s\n", prc_pathname, prc_lineno, s, yytext); + prc_errflag++; +} |