[fetchmail] Re: directory change
Sunil Shetye <shetye <at> bombay.retortsoft.com>
2002-07-02 08:09:00 GMT
Quoting from Sunil Shetye's mail on Mon, Jul 01, 2002 at 05:45:41PM +0530:
> All this can be traced back to the innocuous looking chdir("/") in the
> daemonize() function. There are several possible alternatives:
Here is a solution which is different from the solutions suggested
before:
1) save the current directory.
2) parse the command line arguments. any relative file mentioned
should be expanded with respect to the current directory.
3) parse the rcfile. any relative file mentioned should be expanded
with respect to the location of the rcfile.
4) do a chdir("/").
5) when reexecing, restore to the saved directory first.
Note that "fetchmail -V" should now always show the full pathnames!
When getcwd() is not available, steps 1, 4, and 5 above are skipped.
So, reexecing will not cause any problems as chdir() is now skipped.
Please ignore the previous patches in this thread while applying this
patch.
e.g.:
If rcfile has
set logfile "tmp/fetchmail.logs"
$ echo $HOME
/home/shetye
$ pwd
/var
$ fetchmail
(logs to "/home/shetye/tmp/fetchmail.logs")
(previously logged to "/var/tmp/fetchmail.logs")
$ touch ~/.fetchmailrc
$ fetchmail
(continues logging there)
(previously logged to "/tmp/fetchmail.logs")
$ fetchmail -q
$ fetchmail -L tmp/fetchmail.logs
(logs to "/var/tmp/fetchmail.logs")
(previously logged to "/var/tmp/fetchmail.logs")
$ touch ~/.fetchmailrc
$ fetchmail
(continues logging there)
(previously logged to "/tmp/fetchmail.logs")
Sunil Shetye.
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
<at> <at> -252,8 +252,10 <at> <at>
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
<at> <at> -154,10 +154,7 <at> <at>
}
#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;
<at> <at> -171,6 +168,14 <at> <at>
*/
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);
<at> <at> -276,10 +281,7 <at> <at>
#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
<at> <at> -541,6 +543,13 <at> <at>
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
<at> <at> -863,6 +872,7 <at> <at>
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 */
<at> <at> -884,6 +894,17 <at> <at>
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
<at> <at> -588,8 +588,13 <at> <at>
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
<at> <at> -313,7 +313,7 <at> <at>
break;
case 'L':
case LA_LOGFILE:
- rctl->logfile = optarg;
+ rctl->logfile = prependdir (optarg, currentwd);
break;
case LA_INVISIBLE:
rctl->invisible = TRUE;
<at> <at> -323,11 +323,11 <at> <at>
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);
<at> <at> -538,7 +538,7 <at> <at>
ocount++;
break;
case LA_BSMTP:
- ctl->bsmtp = xstrdup(optarg);
+ ctl->bsmtp = prependdir (optarg, currentwd);
ocount++;
break;
case LA_LMTP:
<at> <at> -578,11 +578,11 <at> <at>
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
<at> <at> -47,6 +47,9 <at> <at>
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)
<at> <at> -90,8 +93,8 <at> <at>
optmap : MAP | /* EMPTY */;
/* future global options should also have the form SET <name> optmap <value> */
-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;}
<at> <at> -323,7 +326,7 <at> <at>
| 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);}
<at> <at> -347,8 +350,8 <at> <at>
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);}
<at> <at> -568,6 +571,22 <at> <at>
{
(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 */
_______________________________________________
Fetchmail-friends mailing list
Fetchmail-friends <at> lists.ccil.org
http://lists.ccil.org/mailman/listinfo/fetchmail-friends