From 08d9413c8e440aa38d7cee33dc035b2a2cd232c8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 7 Jan 1997 03:03:00 +0000 Subject: Add netrc parsing. svn path=/trunk/; revision=715 --- Makefile.in | 7 ++- NEWS | 5 +- fetchmail.c | 37 +++++++++++-- fetchmail.man | 19 +++++++ netrc.c | 175 +++------------------------------------------------------- 5 files changed, 65 insertions(+), 178 deletions(-) diff --git a/Makefile.in b/Makefile.in index d90d907d..7347c33e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -79,7 +79,7 @@ CTAGS = ctags -tw protobjs = socket.o getpass.o pop2.o pop3.o imap.o fetchmail.o options.o \ rcfile_l.o rcfile_y.o daemon.o smtp.o driver.o rfc822.o xmalloc.o \ - uid.o mxget.o md5c.o md5ify.o interface.o error.o + uid.o mxget.o md5c.o md5ify.o interface.o netrc.o error.o objs = $(protobjs) $(extras) $(EXTRAOBJ) @@ -88,7 +88,8 @@ srcs = $(srcdir)/socket.c $(srcdir)/getpass.c $(srcdir)/pop2.c \ $(srcdir)/options.c $(srcdir)/daemon.c $(srcdir)/driver.c \ $(srcdir)/rfc822.c $(srcdir)/smtp.c $(srcdir)/xmalloc.c \ $(srcdir)/uid.c $(srcdir)/mxget.c $(srcdir)/md5c.c \ - $(srcdir)/md5ify.c $(srcdir)/interface.c $(srcdir)/error.c + $(srcdir)/md5ify.c $(srcdir)/interface.c $(srcdir)/netrc.c \ + $(srcdir)/error.c .SUFFIXES: .SUFFIXES: .o .c .h .y .l .ps .dvi .info .texi @@ -195,7 +196,7 @@ $(srcdir)/rcfile_y.c: $(srcdir)/rcfile_y.y parser = $(srcdir)/rcfile_l.l $(srcdir)/rcfile_y.y headers = $(srcdir)/fetchmail.h $(srcdir)/socket.h $(srcdir)/smtp.h \ $(srcdir)/mx.h $(srcdir)/md5.h $(srcdir)/md5global.h \ - $(srcdir)/tunable.h + $(srcdir)/netrc.h $(srcdir)/tunable.h extra = $(srcdir)/alloca.c $(srcdir)/getopt.[ch] $(srcdir)/getopt1.c \ $(srcdir)/strcasecmp.c docs = $(srcdir)/COPYING $(srcdir)/README $(srcdir)/INSTALL $(srcdir)/NEWS \ diff --git a/NEWS b/NEWS index 3890e11d..7ce7965b 100644 --- a/NEWS +++ b/NEWS @@ -7,11 +7,14 @@ features -- * New --syslog option by Dave Bodenstab. +* Automatic parsing of ~/.netrc for a mailserver password if necessary, thanks + to Gordon Matzigkeit. + bugs -- * Fixed a minor bug introduced into From handling by 2.6. -There are 169 people on the fetchmail-friends list. +There are 173 people on the fetchmail-friends list. ------------------------------------------------------------------------------ fetchmail-2.6 (Fri Dec 27 12:42:56 EST 1996) diff --git a/fetchmail.c b/fetchmail.c index 37ceb0d8..e21b7b65 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -37,6 +37,7 @@ #include "tunable.h" #include "smtp.h" #include "getopt.h" +#include "netrc.h" #define DROPDEAD 6 /* maximum bad socket opens */ @@ -94,6 +95,8 @@ int main (int argc, char **argv) struct passwd *pw; struct query *ctl; FILE *lockfp; + netrc_entry *netrc_list; + char *netrc_file; pid_t pid; if ((program_name = strrchr(argv[0], '/')) != NULL) @@ -291,22 +294,44 @@ int main (int argc, char **argv) } } + /* parse the ~/.netrc file, for future password lookups. */ + netrc_file = (char *) xmalloc (strlen (home) + 8); + strcpy (netrc_file, home); + strcat (netrc_file, "/.netrc"); + + netrc_list = parse_netrc (netrc_file); + /* pick up interactively any passwords we need but don't have */ for (ctl = querylist; ctl; ctl = ctl->next) if (ctl->active && !(implicitmode && ctl->skip) && !ctl->password[0]) { if (ctl->authenticate == A_KERBEROS) - /* Server won't care what the password is, but there - must be some non-null string here. */ - (void) strncpy(ctl->password, - ctl->remotename, PASSWORDLEN-1); + /* Server won't care what the password is, but there + must be some non-null string here. */ + (void) strncpy(ctl->password, + ctl->remotename, PASSWORDLEN-1); else - { + { + /* Look up the host and account in the .netrc file. */ + netrc_entry *p = search_netrc(netrc_list,ctl->servernames->id); + while (p && strcmp (p->account, ctl->remotename)) + p = search_netrc (p->next, ctl->remotename); + + if (p) + { + /* We found the entry, so use the password. */ + (void) strncpy (ctl->password, p->password, + PASSWORDLEN - 1); + } + } + + if (!ctl->password[0]) + { (void) sprintf(tmpbuf, "Enter password for %s@%s: ", ctl->remotename, ctl->servernames->id); (void) strncpy(ctl->password, (char *)getpassword(tmpbuf),PASSWORDLEN-1); - } + } } /* diff --git a/fetchmail.man b/fetchmail.man index a6ea4142..03fa6b52 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -290,6 +290,21 @@ file. This is convenient when using .I fetchmail in daemon mode or with scripts. .PP +If you do not specify a password, and +.I fetchmail +cannot extract one from your +.I .fetchmailrc +file, it will look for a +.I .netrc +file in your home directory before requesting one interactively; if an +entry matching the mailserver is found in that file, the password will +be used. See the +.IR ftp (1) +man page for details of the syntax of the +.I .netrc +file. (This feature may allow you to avoid duplicating password +information in more than one file.) +.PP On mailservers that do not provide ordinary user accounts, your user-id and password are usually assigned by the server administrator when you apply for a mailbox on the server. Contact your server administrator if you don't know @@ -843,6 +858,10 @@ default location of file associating hosts with last message IDs seen (used only with newer RFC1725-compliant POP3 servers supporting the UIDL command). .TP 5 +~/.netrc your FTP run control file, which (if present) will be +searched for passwords as a last resort before prompting for one +interactively. +.TP 5 ~/.fetchmail lock file to help prevent concurrent runs (non-root mode). .TP 5 diff --git a/netrc.c b/netrc.c index 92adfa77..27c5427f 100644 --- a/netrc.c +++ b/netrc.c @@ -18,26 +18,6 @@ /* Compile with -DSTANDALONE to test this module. */ -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -/* If SYSTEM_WGETRC is defined in config.h, then we assume we are being - compiled as a part of Wget. That means we make special Wget-specific - modifications to the code (at least until we settle on a cleaner - library interface). */ -/* FIXME - eliminate all WGET_HACKS conditionals by massaging Wget. */ -#ifdef SYSTEM_WGETRC -# define WGET_HACKS 1 -#endif - -/* If CLIENT_TIMEOUT is defined in config.h, then we assume we are being - compiled as a part of fetchmail. */ -/* FIXME - eliminate all FETCHMAIL_HACKS conditionals by fixing fetchmail. */ -#ifdef CLIENT_TIMEOUT -# define FETCHMAIL_HACKS 1 -#endif - #include #include #include @@ -47,14 +27,8 @@ # include #endif -#if ENABLE_NLS -# include -# define _(Text) gettext (Text) -#else -# define textdomain(Domain) -# define _(Text) Text -#endif - +#include "config.h" +#include "fetchmail.h" #include "netrc.h" #ifdef STANDALONE @@ -66,141 +40,9 @@ # define xrealloc realloc #endif -#if defined(STANDALONE) || defined(WGET_HACKS) || defined(FETCHMAIL_HACKS) -/* We need to implement our own dynamic strings. */ -typedef struct -{ - int ds_length; - char *ds_string; -} dynamic_string; -#else -/* We must be part of libit, or another GNU program, so assume that we have - the ERROR function */ -# define HAVE_ERROR 1 -# include "error.h" -# include "dstring.h" -#endif - -#define DS_INIT_LENGTH 40 - -#ifdef WGET_HACKS -/* Wget uses different naming conventions. */ -# define xmalloc nmalloc -# define xstrdup nstrdup -# define xrealloc nrealloc - -/* Wget has read_whole_line defined in utils.c */ -# include "utils.h" - -/* Temporary dynamic string (dstring.c from libit)-like interface to - using read_whole_line. */ -#define ds_init(string, size) ((string)->ds_string = NULL) -#define ds_destroy(string) free ((string)->ds_string) - -/* We use read_whole_line to implement ds_fgets. */ -static char * -ds_fgets (FILE *f, dynamic_string *s) -{ - free (s->ds_string); - s->ds_string = read_whole_line (f); - return s->ds_string; -} -#endif /* WGET_HACKS */ - -#ifdef FETCHMAIL_HACKS -/* fetchmail, too, is not consistent with the xmalloc functions. */ +/* fetchmail is not consistent with the xmalloc functions. */ # define xrealloc realloc # define xstrdup strdup -#endif - -#if defined(STANDALONE) || defined(FETCHMAIL_HACKS) -/* Bits and pieces of Tom Tromey's dstring.c, taken from libit-0.2. */ - -/* Initialize dynamic string STRING with space for SIZE characters. */ - -void -ds_init (string, size) - dynamic_string *string; - int size; -{ - string->ds_length = size; - string->ds_string = (char *) xmalloc (size); -} - -/* Expand dynamic string STRING, if necessary, to hold SIZE characters. */ - -void -ds_resize (string, size) - dynamic_string *string; - int size; -{ - if (size > string->ds_length) - { - string->ds_length = size; - string->ds_string = (char *) xrealloc ((char *) string->ds_string, size); - } -} - -/* Delete dynamic string. */ - -void -ds_destroy (string) - dynamic_string *string; -{ - free (string->ds_string); - string->ds_string = NULL; -} - -/* Dynamic string S gets a string terminated by the EOS character - (which is removed) from file F. S will increase - in size during the function if the string from F is longer than - the current size of S. - Return NULL if end of file is detected. Otherwise, - Return a pointer to the null-terminated string in S. */ - -char * -ds_fgetstr (f, s, eos) - FILE *f; - dynamic_string *s; - char eos; -{ - int insize; /* Amount needed for line. */ - int strsize; /* Amount allocated for S. */ - int next_ch; - - /* Initialize. */ - insize = 0; - strsize = s->ds_length; - - /* Read the input string. */ - next_ch = getc (f); - while (next_ch != eos && next_ch != EOF) - { - if (insize >= strsize - 1) - { - ds_resize (s, strsize * 2 + 2); - strsize = s->ds_length; - } - s->ds_string[insize++] = next_ch; - next_ch = getc (f); - } - s->ds_string[insize++] = '\0'; - - if (insize == 1 && next_ch == EOF) - return NULL; - else - return s->ds_string; -} - -char * -ds_fgets (f, s) - FILE *f; - dynamic_string *s; -{ - return ds_fgetstr (f, s, '\n'); -} -#endif /* !STANDALONE */ - /* Maybe add NEWENTRY to the account information list, LIST. NEWENTRY is set to a ready-to-use netrc_entry, in any event. */ @@ -252,9 +94,8 @@ parse_netrc (file) char *file; { FILE *fp; - char *p, *tok, *premature_token; + char buf[POPBUFSIZE+1], *p, *tok, *premature_token; netrc_entry *current, *retval; - dynamic_string line; int ln; /* The latest token we've seen in the file. */ @@ -277,13 +118,12 @@ parse_netrc (file) premature_token = NULL; /* While there are lines in the file... */ - ds_init (&line, DS_INIT_LENGTH); - while (ds_fgets (fp, &line)) + while (fgets(buf, POPBUFSIZE, fp)) { ln ++; /* Parse the line. */ - p = line.ds_string; + p = buf; /* If the line is empty, then end any macro definition. */ if (last_token == tok_macdef && !*p) @@ -391,14 +231,13 @@ parse_netrc (file) else { - fprintf (stderr, _("%s:%d: warning: unknown token \"%s\"\n"), + fprintf (stderr, "%s:%d: warning: unknown token \"%s\"\n", file, ln, tok); } } } } - ds_destroy (&line); fclose (fp); /* Finalize the last machine entry we found. */ -- cgit v1.2.3