diff -Naur fetchmail-5.9.13.orig/daemon.c fetchmail-5.9.13/daemon.c --- fetchmail-5.9.13.orig/daemon.c Mon Apr 1 13:25:18 2002 +++ fetchmail-5.9.13/daemon.c Tue Jul 2 12:42:04 2002 @@ -252,8 +252,10 @@ return(PS_IOERR); } +#ifdef HAVE_GETCWD /* move to root directory, so we don't prevent filesystem unmounts */ chdir("/"); +#endif /* set our umask to something reasonable (we hope) */ #if defined(DEF_UMASK) diff -Naur fetchmail-5.9.13.orig/fetchmail.c fetchmail-5.9.13/fetchmail.c --- fetchmail-5.9.13.orig/fetchmail.c Sun Jun 23 01:33:11 2002 +++ fetchmail-5.9.13/fetchmail.c Tue Jul 2 12:53:25 2002 @@ -154,10 +154,7 @@ } #define IDFILE_NAME ".fetchids" - run.idfile = (char *) xmalloc(strlen(fmhome)+sizeof(IDFILE_NAME)+2); - strcpy(run.idfile, fmhome); - strcat(run.idfile, "/"); - strcat(run.idfile, IDFILE_NAME); + run.idfile = prependdir (IDFILE_NAME, fmhome); outlevel = O_NORMAL; @@ -171,6 +168,14 @@ */ lock_dispose(); +#ifdef HAVE_GETCWD + /* save the current directory */ + if (getcwd (currentwd, sizeof (currentwd)) == NULL) { + report(stderr, GT_("could not get current working directory\n")); + currentwd[0] = 0; + } +#endif + if ((parsestatus = parsecmdline(argc,argv, &cmd_run, &cmd_opts)) < 0) exit(PS_SYNTAX); @@ -276,10 +281,7 @@ #define NETRC_FILE ".netrc" /* parse the ~/.netrc file (if present) for future password lookups. */ - xalloca(netrc_file, char *, strlen(home) + sizeof(NETRC_FILE) + 2); - strcpy (netrc_file, home); - strcat (netrc_file, "/"); - strcat (netrc_file, NETRC_FILE); + netrc_file = prependdir (NETRC_FILE, home); netrc_list = parse_netrc(netrc_file); #undef NETRC_FILE @@ -541,6 +543,13 @@ else if (rcstat.st_mtime > parsetime) { report(stdout, GT_("restarting fetchmail (%s changed)\n"), rcfile); + +#ifdef HAVE_GETCWD + /* restore the startup directory */ + if (!currentwd[0] || chdir (currentwd) == -1) + report(stderr, GT_("attempt to re-exec may fail as directory has not been restored\n")); +#endif + /* * Matthias Andree: Isn't this prone to introduction of * "false" programs by interfering with PATH? Those @@ -863,6 +872,7 @@ struct passwd *pw; struct query def_opts, *ctl; struct stat rcstat; + char *p; run.bouncemail = TRUE; run.spambounce = FALSE; /* don't bounce back to innocent bystanders */ @@ -884,6 +894,17 @@ def_opts.warnings = WARNING_INTERVAL; def_opts.remotename = user; def_opts.listener = SMTP_MODE; + + /* get the location of rcfile */ + rcfiledir[0] = 0; + p = strrchr (rcfile, '/'); + if (p && (p - rcfile) < sizeof (rcfiledir)) { + *p = 0; /* replace '/' by '0' */ + strcpy (rcfiledir, rcfile); + *p = '/'; /* restore '/' */ + if (!rcfiledir[0]) /* "/.fetchmailrc" case */ + strcpy (rcfiledir, "/"); + } /* note the parse time, so we can pick up on modifications */ parsetime = 0; /* foil compiler warnings */ diff -Naur fetchmail-5.9.13.orig/fetchmail.h fetchmail-5.9.13/fetchmail.h --- fetchmail-5.9.13.orig/fetchmail.h Thu Jun 27 10:59:11 2002 +++ fetchmail-5.9.13/fetchmail.h Tue Jul 2 12:42:04 2002 @@ -588,8 +588,13 @@ int do_otp(int sock, char *command, struct query *ctl); /* miscellanea */ + +/* these should be of size PATH_MAX */ +extern char currentwd[1024], rcfiledir[1024]; + struct query *hostalloc(struct query *); int parsecmdline (int, char **, struct runctl *, struct query *); +char *prependdir (const char *, const char *); char *MD5Digest (unsigned char *); void hmac_md5 (unsigned char *, size_t, unsigned char *, size_t, unsigned char *, size_t); int POP3_auth_rpa(unsigned char *, unsigned char *, int socket); diff -Naur fetchmail-5.9.13.orig/options.c fetchmail-5.9.13/options.c --- fetchmail-5.9.13.orig/options.c Sun Sep 30 20:00:51 2001 +++ fetchmail-5.9.13/options.c Tue Jul 2 12:42:04 2002 @@ -313,7 +313,7 @@ break; case 'L': case LA_LOGFILE: - rctl->logfile = optarg; + rctl->logfile = prependdir (optarg, currentwd); break; case LA_INVISIBLE: rctl->invisible = TRUE; @@ -323,11 +323,11 @@ break; case 'f': case LA_RCFILE: - rcfile = (char *) xstrdup(optarg); + rcfile = prependdir (optarg, currentwd); break; case 'i': case LA_IDFILE: - rctl->idfile = (char *) xstrdup(optarg); + rctl->idfile = prependdir (optarg, currentwd); break; case LA_POSTMASTER: rctl->postmaster = (char *) xstrdup(optarg); @@ -538,7 +538,7 @@ ocount++; break; case LA_BSMTP: - ctl->bsmtp = xstrdup(optarg); + ctl->bsmtp = prependdir (optarg, currentwd); ocount++; break; case LA_LMTP: @@ -578,11 +578,11 @@ break; case LA_SSLKEY: - ctl->sslkey = xstrdup(optarg); + ctl->sslkey = prependdir (optarg, currentwd); break; case LA_SSLCERT: - ctl->sslcert = xstrdup(optarg); + ctl->sslcert = prependdir (optarg, currentwd); break; case LA_SSLPROTO: diff -Naur fetchmail-5.9.13.orig/rcfile_y.y fetchmail-5.9.13/rcfile_y.y --- fetchmail-5.9.13.orig/rcfile_y.y Mon Apr 1 13:17:00 2002 +++ fetchmail-5.9.13/rcfile_y.y Tue Jul 2 12:55:11 2002 @@ -47,6 +47,9 @@ static void user_reset(void); static void reset_server(const char *name, int skip); +/* these should be of size PATH_MAX */ +char currentwd[1024] = "", rcfiledir[1024] = ""; + /* using Bison, this arranges that yydebug messages will show actual tokens */ extern char * yytext; #define YYPRINT(fp, type, val) fprintf(fp, " = \"%s\"", yytext) @@ -90,8 +93,8 @@ optmap : MAP | /* EMPTY */; /* future global options should also have the form SET optmap */ -statement : SET LOGFILE optmap STRING {run.logfile = xstrdup($4);} - | SET IDFILE optmap STRING {run.idfile = xstrdup($4);} +statement : SET LOGFILE optmap STRING {run.logfile = prependdir ($4, rcfiledir);} + | SET IDFILE optmap STRING {run.idfile = prependdir ($4, rcfiledir);} | SET DAEMON optmap NUMBER {run.poll_interval = $4;} | SET POSTMASTER optmap STRING {run.postmaster = xstrdup($4);} | SET BOUNCEMAIL {run.bouncemail = TRUE;} @@ -323,7 +326,7 @@ | SMTPNAME STRING {current.smtpname = xstrdup($2);} | SPAMRESPONSE num_list | MDA STRING {current.mda = xstrdup($2);} - | BSMTP STRING {current.bsmtp = xstrdup($2);} + | BSMTP STRING {current.bsmtp = prependdir ($2, rcfiledir);} | LMTP {current.listener = LMTP_MODE;} | PRECONNECT STRING {current.preconnect = xstrdup($2);} | POSTCONNECT STRING {current.postconnect = xstrdup($2);} @@ -347,8 +350,8 @@ yyerror(GT_("SSL is not enabled")); #endif } - | SSLKEY STRING {current.sslkey = xstrdup($2);} - | SSLCERT STRING {current.sslcert = xstrdup($2);} + | SSLKEY STRING {current.sslkey = prependdir ($2, rcfiledir);} + | SSLCERT STRING {current.sslcert = prependdir ($2, rcfiledir);} | SSLPROTO STRING {current.sslproto = xstrdup($2);} | SSLCERTCK {current.sslcertck = FLAG_TRUE;} | SSLCERTPATH STRING {current.sslcertpath = xstrdup($2);} @@ -568,6 +571,22 @@ { (void) hostalloc(¤t); trailer = TRUE; +} + +char *prependdir (const char *file, const char *dir) +/* if a filename is relative to dir, convert it to an absolute path */ +{ + char *newfile; + if (!file[0] || /* null path */ + file[0] == '/' || /* absolute path */ + !dir[0]) /* we don't HAVE_GETCWD */ + return xstrdup (file); + newfile = xmalloc (strlen (dir) + 1 + strlen (file) + 1); + if (dir[strlen(dir) - 1] != '/') + sprintf (newfile, "%s/%s", dir, file); + else + sprintf (newfile, "%s%s", dir, file); + return newfile; } /* easier to do this than cope with variations in where the library lives */