- Patch nine bugs:

#79 - INTERNALDATE reponses do not conform to RFC
  #145 - LMTP loses return-path
  #177 - Compile Fails on FreeBSD
         (fixes compilation on FreeBSD 4.X)
  #184 - socklen_t issue
  #190 - huge load if database crash
  #198 - DBMail processes killing each other
  #199 - spare child creates zombie
  #214 - dbmail-smtp dumps core with double free
  #216 - malformed header prevents delivery

- Fix RC_SUBR usage

PR:		ports/83437, also ports/80736, ports/82437, ports/83575
Submitted by:	Mark Starovoytov <mark@kikg.ifmo.ru>,
		parts also by: Radim Kolar <hsn@netmag.cz>, thompsa,
		Marcus Grando <marcus@corp.grupos.com.br>
Approved by:	maintainer timeout (2 months on oldest PR)
This commit is contained in:
Pav Lucistnik 2005-07-18 16:04:16 +00:00
parent 679f73e91c
commit 05065d99c7
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=139510
81 changed files with 6676 additions and 116 deletions

View file

@ -7,6 +7,7 @@
PORTNAME= dbmail PORTNAME= dbmail
PORTVERSION= 2.0.4 PORTVERSION= 2.0.4
PORTREVISION= 1
CATEGORIES= mail CATEGORIES= mail
MASTER_SITES= http://www.dbmail.org/download/ MASTER_SITES= http://www.dbmail.org/download/
PKGNAMESUFFIX= -${DATABASE} PKGNAMESUFFIX= -${DATABASE}
@ -20,14 +21,10 @@ GNU_CONFIGURE= YES
CONFIGURE_ARGS= --prefix=${PREFIX} CONFIGURE_ARGS= --prefix=${PREFIX}
USE_GMAKE= YES USE_GMAKE= YES
USE_OPENSSL= YES USE_OPENSSL= YES
USE_RC_SUBR= dbmail-pop3d.sh dbmail-lmtpd.sh dbmail-imapd.sh
CFLAGS += -fPIC CFLAGS += -fPIC
SED_SCRIPT+= -e 's|%%RC_SUBR%%|${RC_SUBR}|g' \
-e 's|%%PREFIX%%|${PREFIX}|g' \
-e 's|%%RC_DIR%%|${RC_DIR}|g' \
-e 's|%%RC_SUFX%%|${RC_SUFX}|g'
.if defined(WITH_POSTGRESQL) .if defined(WITH_POSTGRESQL)
CONFIGURE_ARGS+= --with-pgsql CONFIGURE_ARGS+= --with-pgsql
USE_PGSQL= yes USE_PGSQL= yes
@ -68,16 +65,8 @@ post-configure:
@${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \ @${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \
${WRKSRC}/dbmail.h ${WRKSRC}/dbmail.h
post-build:
.for f in imap lmtp pop3
@${SED} ${SED_SCRIPT} ${FILESDIR}/dbmail-${f}d.sh > ${WRKDIR}/dbmail-${f}d.sh
.endfor
post-install: post-install:
@${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist @${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist
.for f in imap lmtp pop3
@${INSTALL_SCRIPT} ${WRKDIR}/dbmail-${f}d.sh ${DESTDIR}${PREFIX}/etc/rc.d/dbmail-${f}d.sh
.endfor
@${MKDIR} ${DATADIR}/sql @${MKDIR} ${DATADIR}/sql
@${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql @${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql
@cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1 @cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1

View file

@ -0,0 +1,66 @@
Index: lmtp.c
===================================================================
--- lmtp.c (revision 1559)
+++ lmtp.c (revision 1700)
@@ -77,8 +77,9 @@
* - -1 on error
* - 1 on success
*/
-static int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size);
+static int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...) PRINTF_ARGS(4, 5);
/**
* \function lmtp_error
@@ -624,7 +625,9 @@
if (read_whole_message_network(
(FILE *) instream,
&whole_message,
- &whole_message_size) < 0) {
+ &whole_message_size,
+ "Return-Path: %s\r\n",
+ (char *)(list_getstart(&from)->data)) < 0) {
trace(TRACE_ERROR,
"%s,%s: read_whole_message_network() failed",
__FILE__, __func__);
@@ -755,8 +758,9 @@
return 1;
}
-int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size)
+int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...)
{
char *tmpmessage = NULL;
char tmpline[MESSAGE_MAX_LINE_SIZE + 1];
@@ -765,9 +769,17 @@
size_t total_size = 0;
size_t current_pos = 0;
int error = 0;
+ va_list argp;
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
- while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL) {
+
+ /* This adds the Return-Path header and any other
+ * important headers we might need; see RFC 2076. */
+ va_start(argp, prepend_format);
+ line_size = vsnprintf(tmpline, MESSAGE_MAX_LINE_SIZE, prepend_format, argp);
+ va_end(argp);
+
+ do {
line_size = strlen(tmpline);
/* It sometimes happens that we read a line of size 0,
@@ -798,6 +810,7 @@
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
}
+ while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL);
if (ferror(instream)) {
trace(TRACE_ERROR, "%s,%s: error reading instream",

View file

@ -0,0 +1,575 @@
Index: user.c
===================================================================
--- user.c (revision 1711)
+++ user.c (revision 1712)
@@ -202,8 +202,8 @@
memset(&change_flags, 0, sizeof(change_flags));
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-a:d:c:e:l::x:" /* Major modes */
"W::w:P::p:u:g:m:t:s:S:T:" /* Minor options */
"i" "f:qnyvVh" /* Common options */ )) != -1) {
@@ -223,16 +223,16 @@
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- user = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ user = dm_strdup(dm_optarg);
break;
case 'x':
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- alias = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ alias = dm_strdup(dm_optarg);
break;
case 'l':
@@ -241,8 +241,8 @@
if (mode != 0 && mode != 'l')
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- userspec = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ userspec = dm_strdup(dm_optarg);
break;
case 'i':
@@ -253,13 +253,13 @@
/* Minor options */
case 'w':
change_flags.newpasswd = 1;
- passwd = dm_strdup(optarg);
+ passwd = dm_strdup(dm_optarg);
break;
case 'W':
change_flags.newpasswd = 1;
- if (optarg && strlen(optarg)) {
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg)) {
+ passwdfile = dm_strdup(dm_optarg);
change_flags.newpasswdfile = 1;
} else {
change_flags.newpasswdstdin = 1;
@@ -268,20 +268,20 @@
case 'u':
change_flags.newuser = 1;
- newuser = dm_strdup(optarg);
+ newuser = dm_strdup(dm_optarg);
break;
case 'p':
if (!passwdtype)
- passwdtype = dm_strdup(optarg);
+ passwdtype = dm_strdup(dm_optarg);
// else
// Complain about only one type allowed.
break;
case 'P':
change_flags.newpasswdshadow = 1;
- if (optarg && strlen(optarg))
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ passwdfile = dm_strdup(dm_optarg);
else
passwdfile = SHADOWFILE;
passwdtype = "shadow";
@@ -289,42 +289,42 @@
case 'g':
change_flags.newclientid = 1;
- clientid = strtoull(optarg, NULL, 10);
+ clientid = strtoull(dm_optarg, NULL, 10);
break;
case 'm':
change_flags.newmaxmail = 1;
- maxmail = strtomaxmail(optarg);
+ maxmail = strtomaxmail(dm_optarg);
break;
case 's':
// Add this item to the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_add, dm_optarg, len+1);
break;
case 'S':
// Delete this item from the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_del, dm_optarg, len+1);
break;
case 't':
// Add this item to the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_add, dm_optarg, len+1);
break;
case 'T':
// Delete this item from the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_del, dm_optarg, len+1);
break;
/* Common options */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-users: -f requires a filename\n\n");
result = 1;
Index: lmtpd.c
===================================================================
--- lmtpd.c (revision 1711)
+++ lmtpd.c (revision 1712)
@@ -100,8 +100,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -121,8 +121,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -p requires a filename "
@@ -131,8 +131,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -f requires a filename "
Index: dm_getopt.c
===================================================================
--- dm_getopt.c (revision 1711)
+++ dm_getopt.c (revision 1712)
@@ -135,7 +135,7 @@
*/
int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only)
{
char mode, colon_mode = *shortopts;
@@ -261,13 +261,13 @@
}
int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 0);
}
int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 1);
}
Index: maintenance.c
===================================================================
--- maintenance.c (revision 1711)
+++ maintenance.c (revision 1712)
@@ -121,8 +121,8 @@
setvbuf(stdout, 0, _IONBF, 0);
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-acrtl:pudb" /* Main options */
"i" /* Maybe later options */
"f:qnyvVh")) != -1) { /* Common options */
@@ -173,8 +173,8 @@
case 'l':
check_iplog = 1;
do_nothing = 0;
- if (optarg)
- strncpy(timespec, optarg, LEN);
+ if (dm_optarg)
+ strncpy(timespec, dm_optarg, LEN);
else
timespec[0] = 0;
@@ -209,8 +209,8 @@
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-util: -f requires a filename\n\n" );
return 1;
Index: dm_getopt.h
===================================================================
--- dm_getopt.h (revision 1711)
+++ dm_getopt.h (revision 1712)
@@ -26,38 +26,23 @@
*/
#include "config.h"
+#ifndef DM_GETOPT_H
+#define DM_GETOPT_H
-#ifndef USE_DM_GETOPT
-# include <getopt.h>
-#endif
+# ifndef USE_DM_GETOPT
+# include <getopt.h>
+# define dm_getopt getopt
+# define dm_getopt_long getopt_long
+# define dm_getopt_long_only getopt_long_only
+# define _dm_getopt_internal _getopt_internal
+# define dm_opterr opterr
+# define dm_optind optind
+# define dm_optopt optopt
+# define dm_optarg optarg
+# endif
-#ifdef USE_DM_GETOPT
+# ifdef USE_DM_GETOPT
-# ifndef DM_GETOPT_H
- /* Our include guard first. */
-# define DM_GETOPT_H
- /* Try to kill the system getopt.h */
-# define _GETOPT_DECLARED
-# define _GETOPT_H
-# define GETOPT_H
-
-# undef getopt
-# define getopt dm_getopt
-# undef getopt_long
-# define getopt_long dm_getopt_long
-# undef getopt_long_only
-# define getopt_long_only dm_getopt_long_only
-# undef _getopt_internal
-# define _getopt_internal _dm_getopt_internal
-# undef opterr
-# define opterr dm_opterr
-# undef optind
-# define optind dm_optind
-# undef optopt
-# define optopt dm_optopt
-# undef optarg
-# define optarg dm_optarg
-
# ifdef __cplusplus
extern "C" {
# endif
@@ -68,7 +53,7 @@
extern int dm_optind, dm_opterr, dm_optopt;
extern char *dm_optarg;
-struct option {
+struct dm_option {
const char *name;
int has_arg;
int *flag;
@@ -76,28 +61,25 @@
};
/* human-readable values for has_arg */
-# undef no_argument
-# define no_argument 0
-# undef required_argument
-# define required_argument 1
-# undef optional_argument
-# define optional_argument 2
+# define dm_getopt_no_argument 0
+# define dm_getopt_required_argument 1
+# define dm_getopt_optional_argument 2
/* GNU-style long-argument parsers */
extern int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only);
# ifdef __cplusplus
}
# endif
-# endif /* DM_GETOPT_H */
+# endif /* USE_DM_GETOPT */
-#endif /* USE_DM_GETOPT */
+#endif /* DM_GETOPT_H */
Index: timsieved.c
===================================================================
--- timsieved.c (revision 1711)
+++ timsieved.c (revision 1712)
@@ -99,8 +99,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -120,8 +120,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -p requires a filename "
@@ -130,8 +130,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -f requires a filename "
Index: pop3d.c
===================================================================
--- pop3d.c (revision 1711)
+++ pop3d.c (revision 1712)
@@ -103,8 +103,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -124,8 +124,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -p requires a filename "
@@ -134,8 +134,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -f requires a filename "
Index: imapd.c
===================================================================
--- imapd.c (revision 1711)
+++ imapd.c (revision 1712)
@@ -97,8 +97,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -118,8 +118,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -p requires a filename "
@@ -128,8 +128,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -f requires a filename "
Index: sievecmd.c
===================================================================
--- sievecmd.c (revision 1711)
+++ sievecmd.c (revision 1712)
@@ -57,7 +57,7 @@
char *user_name = NULL;
char *name = NULL;
FILE *source = NULL;
- extern char *optarg;
+ extern char *dm_optarg;
openlog(PNAME, LOG_PID, LOG_MAIL);
@@ -70,7 +70,7 @@
configure_debug(TRACE_ERROR, 1, 0);
while (opt != -1 && act != 'h') {
- opt = getopt(argc, argv, "a:d:i:r:u:l");
+ opt = dm_getopt(argc, argv, "a:d:i:r:u:l");
switch (opt) {
case -1:
@@ -84,11 +84,11 @@
act = 'h';
else
act = opt;
- name = optarg;
+ name = dm_optarg;
source = stdin; // FIXME to take files as input, too
break;
case 'u':
- user_name = dm_strdup(optarg);
+ user_name = dm_strdup(dm_optarg);
break;
case 'l':
if (act != 0)
Index: main.c
===================================================================
--- main.c (revision 1711)
+++ main.c (revision 1712)
@@ -189,7 +189,7 @@
* with an immediately preceding option are return with option
* value '1'. We will use this to allow for multiple values to
* follow after each of the supported options. */
- while ((c = getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
+ while ((c = dm_getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
/* Received an n-th value following the last option,
* so recall the last known option to be used in the switch. */
if (c == 1)
@@ -200,13 +200,13 @@
case 't':
trace(TRACE_INFO, "main(): using NORMAL_DELIVERY");
- if (optarg) {
+ if (dm_optarg) {
if (deliver_to_header) {
printf
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_header = optarg;
+ deliver_to_header = dm_optarg;
} else
deliver_to_header = "deliver-to";
@@ -221,7 +221,7 @@
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_mailbox = optarg;
+ deliver_to_mailbox = dm_optarg;
break;
@@ -231,8 +231,8 @@
/* Add argument onto the returnpath list. */
if (list_nodeadd
- (&returnpath, optarg,
- strlen(optarg) + 1) == 0) {
+ (&returnpath, dm_optarg,
+ strlen(dm_optarg) + 1) == 0) {
trace(TRACE_ERROR,
"main(): list_nodeadd reports out of memory"
" while adding to returnpath");
@@ -247,7 +247,7 @@
"main(): using SPECIAL_DELIVERY to usernames");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -267,7 +267,7 @@
"main(): using SPECIAL_DELIVERY to email addresses");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -284,8 +284,8 @@
/* Common command line options. */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-smtp: -f requires a filename\n\n" );

View file

@ -0,0 +1,66 @@
Index: configure.in
===================================================================
--- configure.in (revision 1751)
+++ configure.in (revision 1761)
@@ -42,6 +42,7 @@
DBMAIL_CHECK_SIEVE_LIBS
DBMAIL_CHECK_GC
DBMAIL_CHECK_GETOPT
+DBMAIL_CHECK_SOCKLEN_T
AC_PROG_CC
AC_COMPILE_WARNINGS
Index: acinclude.m4
===================================================================
--- acinclude.m4 (revision 1751)
+++ acinclude.m4 (revision 1761)
@@ -513,3 +513,49 @@
# Prerequisites of lib/getopt*.
AC_DEFUN([CHECK_PREREQ_GETOPT], [:])
+
+#
+# socklen_t
+# from curl
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+AC_DEFUN([DBMAIL_CHECK_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+ ],[
+ $t len;
+ getpeername(0,0,&len);
+ ],[
+ socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$socklen_t_equiv" = x; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_MSG_RESULT($socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+

View file

@ -0,0 +1,126 @@
Index: pool.c
===================================================================
--- pool.c (revision 1600)
+++ pool.c (revision 1758)
@@ -73,8 +73,10 @@
void scoreboard_new(serverConfig_t * conf)
{
int serr;
- if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1)
- trace(TRACE_FATAL, "%s,%s: shmget failed",__FILE__,__func__);
+ if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1) {
+ serr = errno;
+ trace(TRACE_FATAL, "%s,%s: shmget failed [%s]",__FILE__,__func__, strerror(serr));
+ }
scoreboard = shmat(shmid, (void *) 0, 0);
serr=errno;
if (scoreboard == (Scoreboard_t *) (-1)) {
@@ -222,7 +236,7 @@
}
scoreboard_unlck();
trace(TRACE_FATAL,
- "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __FUNCTION__, pid);
+ "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __func__, pid);
return -1;
}
@@ -238,25 +252,25 @@
{
int i;
trace(TRACE_MESSAGE, "%s,%s: register child [%d]",
- __FILE__, __FUNCTION__, getpid());
+ __FILE__, __func__, getpid());
scoreboard_wrlck();
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
if (scoreboard->child[i].pid == -1)
break;
if (scoreboard->child[i].pid == getpid()) {
- trace(TRACE_ERROR,
+ scoreboard_unlck();
+ trace(TRACE_FATAL,
"%s,%s: child already registered.",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
}
if (i == scoreboard->conf->maxChildren) {
+ scoreboard_unlck();
trace(TRACE_WARNING,
"%s,%s: no empty slot found",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
@@ -264,8 +278,8 @@
scoreboard->child[i].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_INFO, "%s,%s: initializing child_state [%d] using slot [%d]",
- __FILE__, __FUNCTION__, getpid(), i);
+ trace(TRACE_MESSAGE, "%s,%s: initializing child_state [%d] using slot [%d]",
+ __FILE__, __func__, getpid(), i);
return 0;
}
@@ -281,7 +295,7 @@
scoreboard->child[key].status = STATE_CONNECTED;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -297,7 +311,7 @@
scoreboard->child[key].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -320,7 +334,7 @@
scoreboard_unlck();
trace(TRACE_MESSAGE,
- "%s,%s: child [%d] unregistered", __FILE__, __FUNCTION__,
+ "%s,%s: child [%d] unregistered", __FILE__, __func__,
getpid());
}
@@ -346,7 +360,7 @@
manage_stop_children();
trace(TRACE_FATAL,
"%s,%s: could not create children. Fatal.",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
}
@@ -360,10 +374,17 @@
if (chpid == -1)
continue;
if (waitpid(chpid, NULL, WNOHANG|WUNTRACED) == chpid) {
+ scoreboard_release(chpid);
trace(TRACE_MESSAGE,"%s,%s: child [%d] exited. Restarting...",
- __FILE__, __FUNCTION__, chpid);
- scoreboard_release(chpid);
- CreateChild(&childinfo);
+ __FILE__, __func__, chpid);
+ if (CreateChild(&childinfo)== -1) {
+ trace(TRACE_ERROR,"%s,%s: createchild failed. Bailout...",
+ __FILE__, __func__);
+ GeneralStopRequested=1;
+ manage_stop_children();
+
+ exit(1);
+ }
}
}
sleep(1);

View file

@ -0,0 +1,41 @@
Index: server.c
===================================================================
--- server.c (revision 1600)
+++ server.c (revision 1758)
@@ -119,9 +119,15 @@
alarm(10);
trace(TRACE_DEBUG, "StartServer(): children created, starting main service loop");
- while (!GeneralStopRequested)
- manage_restart_children();
-
+ while (!GeneralStopRequested) {
+ if (db_connect() != 0) {
+ GeneralStopRequested=1;
+ } else {
+ db_disconnect();
+ manage_restart_children();
+ }
+ }
+
manage_stop_children();
scoreboard_delete();
@@ -131,6 +137,8 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ int saved_errno = errno;
+
if (ParentPID != getpid()) {
trace(TRACE_INFO,
"ParentSigHandler(): i'm no longer father");
@@ -162,6 +170,8 @@
default:
GeneralStopRequested = 1;
}
+
+ errno = saved_errno;
}

View file

@ -0,0 +1,267 @@
Index: serverchild.c
===================================================================
--- serverchild.c (revision 1600)
+++ serverchild.c (revision 1758)
@@ -66,13 +66,13 @@
void client_close(void)
{
if (client.tx) {
- trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__func__);
fflush(client.tx);
fclose(client.tx); /* closes clientSocket as well */
client.tx = NULL;
}
if (client.rx) {
- trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__func__);
shutdown(fileno(client.rx), SHUT_RDWR);
fclose(client.rx);
client.rx = NULL;
@@ -86,7 +86,7 @@
trace(TRACE_DEBUG,
"%s,%s: database connection still open, closing",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
db_disconnect();
auth_disconnect();
connected = 0; /* FIXME a signal between this line and the previous one
@@ -99,18 +99,22 @@
void noop_child_sig_handler(int sig, siginfo_t *info UNUSED, void *data UNUSED)
{
- trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __FUNCTION__, sig);
+ int saved_errno = errno;
+ trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __func__, sig);
+ errno = saved_errno;
}
void active_child_sig_handler(int sig, siginfo_t * info UNUSED, void *data UNUSED)
{
+ int saved_errno = errno;
+
static int triedDisconnect = 0;
#ifdef _USE_STR_SIGNAL
- trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __FUNCTION__,
+ trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __func__,
strsignal(sig));
#else
- trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __FUNCTION__, sig);
+ trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __func__, sig);
#endif
/* perform reinit at SIGHUP otherwise exit, but do nothing on
@@ -118,10 +122,10 @@
switch (sig) {
case SIGCHLD:
trace(TRACE_DEBUG, "%s,%s: SIGCHLD received... ignoring",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
break;
case SIGALRM:
- trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __func__);
client_close();
break;
@@ -132,23 +136,23 @@
if (ChildStopRequested) {
trace(TRACE_DEBUG,
"%s,%s: already caught a stop request. Closing right now",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
/* already caught this signal, exit the hard way now */
client_close();
disconnect_all();
child_unregister();
- trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__func__);
exit(1);
}
- trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__func__);
DelChildSigHandler();
ChildStopRequested = 1;
break;
default:
/* bad shtuff, exit */
trace(TRACE_DEBUG,
- "%s,%s: cannot ignore this. Terminating",__FILE__,__FUNCTION__);
+ "%s,%s: cannot ignore this. Terminating",__FILE__,__func__);
/*
* For some reason i have not yet determined the process starts eating up
@@ -164,10 +168,12 @@
disconnect_all();
}
- trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __func__);
child_unregister();
exit(1);
}
+
+ errno = saved_errno;
}
@@ -239,16 +245,19 @@
if (! pid) {
if (child_register() == -1) {
trace(TRACE_FATAL, "%s,%s: child_register failed",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
ChildStopRequested = 0;
SetChildSigHandler();
- trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
- __FILE__, __FUNCTION__);
- PerformChildTask(info);
+
+ trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
+ __FILE__, __func__);
+
+ if (PerformChildTask(info)== -1)
+ return -1;
child_unregister();
exit(0);
} else {
@@ -269,22 +278,22 @@
struct hostent *clientHost;
if (!info) {
- trace(TRACE_ERROR,
- "PerformChildTask(): NULL info supplied");
+ trace(TRACE_ERROR, "%s,%s: NULL info supplied",
+ __FILE__, __func__);
return -1;
}
if (db_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to database");
+ trace(TRACE_ERROR, "%s,%s: could not connect to database",
+ __FILE__, __func__);
return -1;
}
if (db_check_version() != 0)
return -1;
if (auth_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to authentication");
+ trace(TRACE_ERROR, "%s,%s: could not connect to authentication",
+ __FILE__, __func__);
return -1;
}
@@ -294,12 +303,13 @@
for (i = 0; i < info->maxConnect && !ChildStopRequested; i++) {
if (db_check_connection()) {
- trace(TRACE_ERROR, "%s,%s: database has gone away", __FILE__, __func__);
+ trace(TRACE_ERROR, "%s,%s: database has gone away",
+ __FILE__, __func__);
return -1;
}
- trace(TRACE_INFO,
- "PerformChildTask(): waiting for connection");
+ trace(TRACE_INFO, "%s,%s: waiting for connection",
+ __FILE__, __func__);
child_reg_disconnected();
@@ -312,8 +322,8 @@
if (clientSocket == -1) {
i--; /* don't count this as a connect */
- trace(TRACE_INFO,
- "PerformChildTask(): accept failed");
+ trace(TRACE_INFO, "%s,%s: accept failed",
+ __FILE__, __func__);
continue; /* accept failed, refuse connection & continue */
}
@@ -337,30 +347,29 @@
strncpy(client.clientname,
clientHost->h_name, FIELDSIZE);
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s (%s)]",
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s (%s)]",
+ __FILE__, __func__,
client.ip,
client.clientname[0] ? client.
clientname : "Lookup failed");
} else {
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s]",
- client.ip);
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s]",
+ __FILE__, __func__, client.ip);
}
/* make streams */
if (!(client.rx = fdopen(dup(clientSocket), "r"))) {
/* read-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening read file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening read file stream",
+ __FILE__, __func__);
close(clientSocket);
continue;
}
if (!(client.tx = fdopen(clientSocket, "w"))) {
/* write-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening write file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening write file stream",
+ __FILE__, __func__);
fclose(client.rx);
close(clientSocket);
memset(&client, 0, sizeof(client));
@@ -370,8 +379,8 @@
setvbuf(client.tx, (char *) NULL, _IOLBF, 0);
setvbuf(client.rx, (char *) NULL, _IOLBF, 0);
- trace(TRACE_DEBUG,
- "PerformChildTask(): client info init complete, calling client handler");
+ trace(TRACE_DEBUG, "%s,%s: client info init complete, calling client handler",
+ __FILE__, __func__);
/* streams are ready, perform handling */
info->ClientHandler(&client);
@@ -379,17 +388,19 @@
set_proc_title("%s", "Idle");
#endif
- trace(TRACE_DEBUG,
- "PerformChildTask(): client handling complete, closing streams");
+ trace(TRACE_DEBUG, "%s,%s: client handling complete, closing streams",
+ __FILE__, __func__);
client_close();
- trace(TRACE_INFO, "PerformChildTask(): connection closed");
+ trace(TRACE_INFO, "%s,%s: connection closed",
+ __FILE__, __func__);
}
if (!ChildStopRequested)
- trace(TRACE_ERROR,
- "PerformChildTask(): maximum number of connections reached, stopping now");
+ trace(TRACE_ERROR, "%s,%s: maximum number of connections reached, stopping now",
+ __FILE__, __func__);
else
- trace(TRACE_ERROR, "PerformChildTask(): stop requested");
+ trace(TRACE_ERROR, "%s,%s: stop requested",
+ __FILE__, __func__);
child_reg_disconnected();
disconnect_all();

View file

@ -0,0 +1,13 @@
Index: pool.c
===================================================================
--- pool.c (revision 1763)
+++ pool.c (revision 1787)
@@ -433,7 +433,7 @@
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
chpid = scoreboard->child[i].pid;
- if (chpid != 0)
+ if (chpid > 0)
kill(chpid, SIGKILL);;
scoreboard_release(chpid);
}

View file

@ -0,0 +1,35 @@
Index: server.c
===================================================================
--- server.c (revision 1763)
+++ server.c (revision 1787)
@@ -69,7 +69,7 @@
act.sa_sigaction = ParentSigHandler;
sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
+ act.sa_flags = SA_SIGINFO | SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, 0);
sigaction(SIGINT, &act, 0);
@@ -152,6 +152,7 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ pid_t chpid;
int saved_errno = errno;
if (ParentPID != getpid()) {
@@ -175,7 +176,12 @@
break;
case SIGCHLD:
- break; /* ignore, wait for child in main loop */
+ /* ignore, wait for child in main loop */
+ /* but we need to catch zombie */
+ if ((chpid = waitpid(-1,&sig,WNOHANG)) > 0)
+ scoreboard_release(chpid);
+
+ break;
case SIGHUP:
trace(TRACE_DEBUG,

View file

@ -0,0 +1,20 @@
Index: main.c
===================================================================
--- main.c (revision 1793)
+++ main.c (revision 1796)
@@ -133,6 +133,7 @@
trace(TRACE_ERROR, "%s,%s: error reading message",
__FILE__, __func__);
dm_free(tmpmessage);
+ tmpmessage=NULL;
return -1;
}
@@ -371,6 +372,7 @@
trace(TRACE_ERROR, "%s,%s splitmessage failed",
__FILE__, __func__);
dm_free(whole_message);
+ whole_message=NULL;
exitcode = EX_TEMPFAIL;
goto freeall;
}

View file

@ -0,0 +1,37 @@
Index: header.c
===================================================================
--- header.c (revision 1796)
+++ header.c (revision 1813)
@@ -176,15 +176,17 @@
if (message_content[line_content_size] == '\n') {
tmp_line_size = line_content_size + 1;
tmp_line_rfcsize = tmp_line_size + 1;
- } else {
- if (message_content[line_content_size] == '\r' &&
- message_content[line_content_size + 1] == '\n') {
+ } else if (message_content[line_content_size] == '\r') {
+ if (message_content[line_content_size + 1] == '\n') {
+ /* This is the right behaviour */
tmp_line_size = line_content_size + 2;
tmp_line_rfcsize = tmp_line_size;
} else {
- trace(TRACE_ERROR, "%s,%s: error reading header line",
- __FILE__, __func__);
- return -1;
+ /* This is broken behaviour, but it's better
+ * than not handling it at all.
+ */
+ tmp_line_size = line_content_size + 1;
+ tmp_line_rfcsize = tmp_line_size + 1;
}
}
}
@@ -197,7 +199,6 @@
__FILE__, __func__);
return 0;
}
- else
- return 1;
+ return 1;
}

View file

@ -0,0 +1,80 @@
Index: imaputil.c
===================================================================
--- imaputil.c (revision 1726)
+++ imaputil.c (revision 1793)
@@ -65,7 +65,7 @@
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* returned by date_sql2imap() */
-#define IMAP_STANDARD_DATE "03-Nov-1979 00:00:00 +0000"
+#define IMAP_STANDARD_DATE "Sat, 03-Nov-1979 00:00:00 +0000"
char _imapdate[IMAP_INTERNALDATE_LEN] = IMAP_STANDARD_DATE;
/* returned by date_imap2sql() */
@@ -1776,50 +1776,35 @@
/*
* convert a mySQL date (yyyy-mm-dd hh:mm:ss) to a valid IMAP internal date:
- * 0123456789012345678
- * dd-mon-yyyy hh:mm:ss with mon characters (i.e. 'Apr' for april)
- * 01234567890123456789
+ * [Mon, 30 May 2005 10:01:55 +0100] with mon characters (i.e. 'Apr' for april)
* return value is valid until next function call.
* NOTE: if date is not valid, IMAP_STANDARD_DATE is returned
*/
char *date_sql2imap(const char *sqldate)
{
- char *last_char;
- struct tm tm_localtime, tm_sqldate;
- time_t td;
+ struct tm tm_sql_date;
+ struct tm *tm_imap_date;
+
+ time_t ltime;
+ char *last;
- /* we need to get the localtime to get the current timezone */
- if (time(&td) == -1) {
- trace(TRACE_ERROR, "%s,%s: error getting time()",
- __FILE__, __func__);
- return IMAP_STANDARD_DATE;
- }
- tm_localtime = *localtime(&td);
+ last = strptime(sqldate,"%Y-%m-%d %T", &tm_sql_date);
+ if ( (last == NULL) || (*last != '\0') ) {
+ strcpy(_imapdate, IMAP_STANDARD_DATE);
+ return _imapdate;
+ }
- /* parse sqldate */
- last_char = strptime(sqldate, "%Y-%m-%d %T", &tm_sqldate);
- if (last_char == NULL || *last_char != '\0') {
- trace(TRACE_DEBUG, "%s,%s, error parsing date [%s]",
- __FILE__, __func__, sqldate);
- strcpy(_imapdate, IMAP_STANDARD_DATE);
- return _imapdate;
- }
- /* copy DST information from localtime */
- tm_sqldate.tm_gmtoff = tm_localtime.tm_gmtoff;
- tm_sqldate.tm_isdst = tm_localtime.tm_isdst;
+ /* FIXME: this works fine on linux, but may cause dst offsets in netbsd. */
+ ltime = mktime (&tm_sql_date);
+ tm_imap_date = localtime(&ltime);
- (void) strftime(_imapdate, IMAP_INTERNALDATE_LEN,
- "%d-%b-%Y %T %z", &tm_sqldate);
-
- return _imapdate;
+ strftime(_imapdate, sizeof(_imapdate), "%a, %d %b %Y %H:%M:%S %z", tm_imap_date);
+ return _imapdate;
}
-
/*
* convert TO a mySQL date (yyyy-mm-dd) FROM a valid IMAP internal date:
- * 0123456789
* dd-mon-yyyy with mon characters (i.e. 'Apr' for april)
- * 01234567890
* OR
* d-mon-yyyy
* return value is valid until next function call.

View file

@ -1,7 +1,4 @@
etc/dbmail.conf-dist etc/dbmail.conf-dist
etc/rc.d/dbmail-imapd.sh
etc/rc.d/dbmail-lmtpd.sh
etc/rc.d/dbmail-pop3d.sh
lib/dbmail/libauthdbmail.0 lib/dbmail/libauthdbmail.0
lib/dbmail/libauthdbmail.a lib/dbmail/libauthdbmail.a
lib/dbmail/libauthdbmail.la lib/dbmail/libauthdbmail.la

View file

@ -7,6 +7,7 @@
PORTNAME= dbmail PORTNAME= dbmail
PORTVERSION= 2.0.4 PORTVERSION= 2.0.4
PORTREVISION= 1
CATEGORIES= mail CATEGORIES= mail
MASTER_SITES= http://www.dbmail.org/download/ MASTER_SITES= http://www.dbmail.org/download/
PKGNAMESUFFIX= -${DATABASE} PKGNAMESUFFIX= -${DATABASE}
@ -20,14 +21,10 @@ GNU_CONFIGURE= YES
CONFIGURE_ARGS= --prefix=${PREFIX} CONFIGURE_ARGS= --prefix=${PREFIX}
USE_GMAKE= YES USE_GMAKE= YES
USE_OPENSSL= YES USE_OPENSSL= YES
USE_RC_SUBR= dbmail-pop3d.sh dbmail-lmtpd.sh dbmail-imapd.sh
CFLAGS += -fPIC CFLAGS += -fPIC
SED_SCRIPT+= -e 's|%%RC_SUBR%%|${RC_SUBR}|g' \
-e 's|%%PREFIX%%|${PREFIX}|g' \
-e 's|%%RC_DIR%%|${RC_DIR}|g' \
-e 's|%%RC_SUFX%%|${RC_SUFX}|g'
.if defined(WITH_POSTGRESQL) .if defined(WITH_POSTGRESQL)
CONFIGURE_ARGS+= --with-pgsql CONFIGURE_ARGS+= --with-pgsql
USE_PGSQL= yes USE_PGSQL= yes
@ -68,16 +65,8 @@ post-configure:
@${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \ @${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \
${WRKSRC}/dbmail.h ${WRKSRC}/dbmail.h
post-build:
.for f in imap lmtp pop3
@${SED} ${SED_SCRIPT} ${FILESDIR}/dbmail-${f}d.sh > ${WRKDIR}/dbmail-${f}d.sh
.endfor
post-install: post-install:
@${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist @${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist
.for f in imap lmtp pop3
@${INSTALL_SCRIPT} ${WRKDIR}/dbmail-${f}d.sh ${DESTDIR}${PREFIX}/etc/rc.d/dbmail-${f}d.sh
.endfor
@${MKDIR} ${DATADIR}/sql @${MKDIR} ${DATADIR}/sql
@${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql @${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql
@cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1 @cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1

View file

@ -0,0 +1,66 @@
Index: lmtp.c
===================================================================
--- lmtp.c (revision 1559)
+++ lmtp.c (revision 1700)
@@ -77,8 +77,9 @@
* - -1 on error
* - 1 on success
*/
-static int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size);
+static int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...) PRINTF_ARGS(4, 5);
/**
* \function lmtp_error
@@ -624,7 +625,9 @@
if (read_whole_message_network(
(FILE *) instream,
&whole_message,
- &whole_message_size) < 0) {
+ &whole_message_size,
+ "Return-Path: %s\r\n",
+ (char *)(list_getstart(&from)->data)) < 0) {
trace(TRACE_ERROR,
"%s,%s: read_whole_message_network() failed",
__FILE__, __func__);
@@ -755,8 +758,9 @@
return 1;
}
-int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size)
+int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...)
{
char *tmpmessage = NULL;
char tmpline[MESSAGE_MAX_LINE_SIZE + 1];
@@ -765,9 +769,17 @@
size_t total_size = 0;
size_t current_pos = 0;
int error = 0;
+ va_list argp;
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
- while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL) {
+
+ /* This adds the Return-Path header and any other
+ * important headers we might need; see RFC 2076. */
+ va_start(argp, prepend_format);
+ line_size = vsnprintf(tmpline, MESSAGE_MAX_LINE_SIZE, prepend_format, argp);
+ va_end(argp);
+
+ do {
line_size = strlen(tmpline);
/* It sometimes happens that we read a line of size 0,
@@ -798,6 +810,7 @@
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
}
+ while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL);
if (ferror(instream)) {
trace(TRACE_ERROR, "%s,%s: error reading instream",

View file

@ -0,0 +1,575 @@
Index: user.c
===================================================================
--- user.c (revision 1711)
+++ user.c (revision 1712)
@@ -202,8 +202,8 @@
memset(&change_flags, 0, sizeof(change_flags));
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-a:d:c:e:l::x:" /* Major modes */
"W::w:P::p:u:g:m:t:s:S:T:" /* Minor options */
"i" "f:qnyvVh" /* Common options */ )) != -1) {
@@ -223,16 +223,16 @@
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- user = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ user = dm_strdup(dm_optarg);
break;
case 'x':
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- alias = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ alias = dm_strdup(dm_optarg);
break;
case 'l':
@@ -241,8 +241,8 @@
if (mode != 0 && mode != 'l')
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- userspec = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ userspec = dm_strdup(dm_optarg);
break;
case 'i':
@@ -253,13 +253,13 @@
/* Minor options */
case 'w':
change_flags.newpasswd = 1;
- passwd = dm_strdup(optarg);
+ passwd = dm_strdup(dm_optarg);
break;
case 'W':
change_flags.newpasswd = 1;
- if (optarg && strlen(optarg)) {
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg)) {
+ passwdfile = dm_strdup(dm_optarg);
change_flags.newpasswdfile = 1;
} else {
change_flags.newpasswdstdin = 1;
@@ -268,20 +268,20 @@
case 'u':
change_flags.newuser = 1;
- newuser = dm_strdup(optarg);
+ newuser = dm_strdup(dm_optarg);
break;
case 'p':
if (!passwdtype)
- passwdtype = dm_strdup(optarg);
+ passwdtype = dm_strdup(dm_optarg);
// else
// Complain about only one type allowed.
break;
case 'P':
change_flags.newpasswdshadow = 1;
- if (optarg && strlen(optarg))
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ passwdfile = dm_strdup(dm_optarg);
else
passwdfile = SHADOWFILE;
passwdtype = "shadow";
@@ -289,42 +289,42 @@
case 'g':
change_flags.newclientid = 1;
- clientid = strtoull(optarg, NULL, 10);
+ clientid = strtoull(dm_optarg, NULL, 10);
break;
case 'm':
change_flags.newmaxmail = 1;
- maxmail = strtomaxmail(optarg);
+ maxmail = strtomaxmail(dm_optarg);
break;
case 's':
// Add this item to the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_add, dm_optarg, len+1);
break;
case 'S':
// Delete this item from the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_del, dm_optarg, len+1);
break;
case 't':
// Add this item to the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_add, dm_optarg, len+1);
break;
case 'T':
// Delete this item from the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_del, dm_optarg, len+1);
break;
/* Common options */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-users: -f requires a filename\n\n");
result = 1;
Index: lmtpd.c
===================================================================
--- lmtpd.c (revision 1711)
+++ lmtpd.c (revision 1712)
@@ -100,8 +100,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -121,8 +121,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -p requires a filename "
@@ -131,8 +131,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -f requires a filename "
Index: dm_getopt.c
===================================================================
--- dm_getopt.c (revision 1711)
+++ dm_getopt.c (revision 1712)
@@ -135,7 +135,7 @@
*/
int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only)
{
char mode, colon_mode = *shortopts;
@@ -261,13 +261,13 @@
}
int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 0);
}
int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 1);
}
Index: maintenance.c
===================================================================
--- maintenance.c (revision 1711)
+++ maintenance.c (revision 1712)
@@ -121,8 +121,8 @@
setvbuf(stdout, 0, _IONBF, 0);
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-acrtl:pudb" /* Main options */
"i" /* Maybe later options */
"f:qnyvVh")) != -1) { /* Common options */
@@ -173,8 +173,8 @@
case 'l':
check_iplog = 1;
do_nothing = 0;
- if (optarg)
- strncpy(timespec, optarg, LEN);
+ if (dm_optarg)
+ strncpy(timespec, dm_optarg, LEN);
else
timespec[0] = 0;
@@ -209,8 +209,8 @@
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-util: -f requires a filename\n\n" );
return 1;
Index: dm_getopt.h
===================================================================
--- dm_getopt.h (revision 1711)
+++ dm_getopt.h (revision 1712)
@@ -26,38 +26,23 @@
*/
#include "config.h"
+#ifndef DM_GETOPT_H
+#define DM_GETOPT_H
-#ifndef USE_DM_GETOPT
-# include <getopt.h>
-#endif
+# ifndef USE_DM_GETOPT
+# include <getopt.h>
+# define dm_getopt getopt
+# define dm_getopt_long getopt_long
+# define dm_getopt_long_only getopt_long_only
+# define _dm_getopt_internal _getopt_internal
+# define dm_opterr opterr
+# define dm_optind optind
+# define dm_optopt optopt
+# define dm_optarg optarg
+# endif
-#ifdef USE_DM_GETOPT
+# ifdef USE_DM_GETOPT
-# ifndef DM_GETOPT_H
- /* Our include guard first. */
-# define DM_GETOPT_H
- /* Try to kill the system getopt.h */
-# define _GETOPT_DECLARED
-# define _GETOPT_H
-# define GETOPT_H
-
-# undef getopt
-# define getopt dm_getopt
-# undef getopt_long
-# define getopt_long dm_getopt_long
-# undef getopt_long_only
-# define getopt_long_only dm_getopt_long_only
-# undef _getopt_internal
-# define _getopt_internal _dm_getopt_internal
-# undef opterr
-# define opterr dm_opterr
-# undef optind
-# define optind dm_optind
-# undef optopt
-# define optopt dm_optopt
-# undef optarg
-# define optarg dm_optarg
-
# ifdef __cplusplus
extern "C" {
# endif
@@ -68,7 +53,7 @@
extern int dm_optind, dm_opterr, dm_optopt;
extern char *dm_optarg;
-struct option {
+struct dm_option {
const char *name;
int has_arg;
int *flag;
@@ -76,28 +61,25 @@
};
/* human-readable values for has_arg */
-# undef no_argument
-# define no_argument 0
-# undef required_argument
-# define required_argument 1
-# undef optional_argument
-# define optional_argument 2
+# define dm_getopt_no_argument 0
+# define dm_getopt_required_argument 1
+# define dm_getopt_optional_argument 2
/* GNU-style long-argument parsers */
extern int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only);
# ifdef __cplusplus
}
# endif
-# endif /* DM_GETOPT_H */
+# endif /* USE_DM_GETOPT */
-#endif /* USE_DM_GETOPT */
+#endif /* DM_GETOPT_H */
Index: timsieved.c
===================================================================
--- timsieved.c (revision 1711)
+++ timsieved.c (revision 1712)
@@ -99,8 +99,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -120,8 +120,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -p requires a filename "
@@ -130,8 +130,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -f requires a filename "
Index: pop3d.c
===================================================================
--- pop3d.c (revision 1711)
+++ pop3d.c (revision 1712)
@@ -103,8 +103,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -124,8 +124,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -p requires a filename "
@@ -134,8 +134,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -f requires a filename "
Index: imapd.c
===================================================================
--- imapd.c (revision 1711)
+++ imapd.c (revision 1712)
@@ -97,8 +97,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -118,8 +118,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -p requires a filename "
@@ -128,8 +128,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -f requires a filename "
Index: sievecmd.c
===================================================================
--- sievecmd.c (revision 1711)
+++ sievecmd.c (revision 1712)
@@ -57,7 +57,7 @@
char *user_name = NULL;
char *name = NULL;
FILE *source = NULL;
- extern char *optarg;
+ extern char *dm_optarg;
openlog(PNAME, LOG_PID, LOG_MAIL);
@@ -70,7 +70,7 @@
configure_debug(TRACE_ERROR, 1, 0);
while (opt != -1 && act != 'h') {
- opt = getopt(argc, argv, "a:d:i:r:u:l");
+ opt = dm_getopt(argc, argv, "a:d:i:r:u:l");
switch (opt) {
case -1:
@@ -84,11 +84,11 @@
act = 'h';
else
act = opt;
- name = optarg;
+ name = dm_optarg;
source = stdin; // FIXME to take files as input, too
break;
case 'u':
- user_name = dm_strdup(optarg);
+ user_name = dm_strdup(dm_optarg);
break;
case 'l':
if (act != 0)
Index: main.c
===================================================================
--- main.c (revision 1711)
+++ main.c (revision 1712)
@@ -189,7 +189,7 @@
* with an immediately preceding option are return with option
* value '1'. We will use this to allow for multiple values to
* follow after each of the supported options. */
- while ((c = getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
+ while ((c = dm_getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
/* Received an n-th value following the last option,
* so recall the last known option to be used in the switch. */
if (c == 1)
@@ -200,13 +200,13 @@
case 't':
trace(TRACE_INFO, "main(): using NORMAL_DELIVERY");
- if (optarg) {
+ if (dm_optarg) {
if (deliver_to_header) {
printf
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_header = optarg;
+ deliver_to_header = dm_optarg;
} else
deliver_to_header = "deliver-to";
@@ -221,7 +221,7 @@
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_mailbox = optarg;
+ deliver_to_mailbox = dm_optarg;
break;
@@ -231,8 +231,8 @@
/* Add argument onto the returnpath list. */
if (list_nodeadd
- (&returnpath, optarg,
- strlen(optarg) + 1) == 0) {
+ (&returnpath, dm_optarg,
+ strlen(dm_optarg) + 1) == 0) {
trace(TRACE_ERROR,
"main(): list_nodeadd reports out of memory"
" while adding to returnpath");
@@ -247,7 +247,7 @@
"main(): using SPECIAL_DELIVERY to usernames");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -267,7 +267,7 @@
"main(): using SPECIAL_DELIVERY to email addresses");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -284,8 +284,8 @@
/* Common command line options. */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-smtp: -f requires a filename\n\n" );

View file

@ -0,0 +1,66 @@
Index: configure.in
===================================================================
--- configure.in (revision 1751)
+++ configure.in (revision 1761)
@@ -42,6 +42,7 @@
DBMAIL_CHECK_SIEVE_LIBS
DBMAIL_CHECK_GC
DBMAIL_CHECK_GETOPT
+DBMAIL_CHECK_SOCKLEN_T
AC_PROG_CC
AC_COMPILE_WARNINGS
Index: acinclude.m4
===================================================================
--- acinclude.m4 (revision 1751)
+++ acinclude.m4 (revision 1761)
@@ -513,3 +513,49 @@
# Prerequisites of lib/getopt*.
AC_DEFUN([CHECK_PREREQ_GETOPT], [:])
+
+#
+# socklen_t
+# from curl
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+AC_DEFUN([DBMAIL_CHECK_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+ ],[
+ $t len;
+ getpeername(0,0,&len);
+ ],[
+ socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$socklen_t_equiv" = x; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_MSG_RESULT($socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+

View file

@ -0,0 +1,126 @@
Index: pool.c
===================================================================
--- pool.c (revision 1600)
+++ pool.c (revision 1758)
@@ -73,8 +73,10 @@
void scoreboard_new(serverConfig_t * conf)
{
int serr;
- if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1)
- trace(TRACE_FATAL, "%s,%s: shmget failed",__FILE__,__func__);
+ if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1) {
+ serr = errno;
+ trace(TRACE_FATAL, "%s,%s: shmget failed [%s]",__FILE__,__func__, strerror(serr));
+ }
scoreboard = shmat(shmid, (void *) 0, 0);
serr=errno;
if (scoreboard == (Scoreboard_t *) (-1)) {
@@ -222,7 +236,7 @@
}
scoreboard_unlck();
trace(TRACE_FATAL,
- "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __FUNCTION__, pid);
+ "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __func__, pid);
return -1;
}
@@ -238,25 +252,25 @@
{
int i;
trace(TRACE_MESSAGE, "%s,%s: register child [%d]",
- __FILE__, __FUNCTION__, getpid());
+ __FILE__, __func__, getpid());
scoreboard_wrlck();
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
if (scoreboard->child[i].pid == -1)
break;
if (scoreboard->child[i].pid == getpid()) {
- trace(TRACE_ERROR,
+ scoreboard_unlck();
+ trace(TRACE_FATAL,
"%s,%s: child already registered.",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
}
if (i == scoreboard->conf->maxChildren) {
+ scoreboard_unlck();
trace(TRACE_WARNING,
"%s,%s: no empty slot found",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
@@ -264,8 +278,8 @@
scoreboard->child[i].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_INFO, "%s,%s: initializing child_state [%d] using slot [%d]",
- __FILE__, __FUNCTION__, getpid(), i);
+ trace(TRACE_MESSAGE, "%s,%s: initializing child_state [%d] using slot [%d]",
+ __FILE__, __func__, getpid(), i);
return 0;
}
@@ -281,7 +295,7 @@
scoreboard->child[key].status = STATE_CONNECTED;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -297,7 +311,7 @@
scoreboard->child[key].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -320,7 +334,7 @@
scoreboard_unlck();
trace(TRACE_MESSAGE,
- "%s,%s: child [%d] unregistered", __FILE__, __FUNCTION__,
+ "%s,%s: child [%d] unregistered", __FILE__, __func__,
getpid());
}
@@ -346,7 +360,7 @@
manage_stop_children();
trace(TRACE_FATAL,
"%s,%s: could not create children. Fatal.",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
}
@@ -360,10 +374,17 @@
if (chpid == -1)
continue;
if (waitpid(chpid, NULL, WNOHANG|WUNTRACED) == chpid) {
+ scoreboard_release(chpid);
trace(TRACE_MESSAGE,"%s,%s: child [%d] exited. Restarting...",
- __FILE__, __FUNCTION__, chpid);
- scoreboard_release(chpid);
- CreateChild(&childinfo);
+ __FILE__, __func__, chpid);
+ if (CreateChild(&childinfo)== -1) {
+ trace(TRACE_ERROR,"%s,%s: createchild failed. Bailout...",
+ __FILE__, __func__);
+ GeneralStopRequested=1;
+ manage_stop_children();
+
+ exit(1);
+ }
}
}
sleep(1);

View file

@ -0,0 +1,41 @@
Index: server.c
===================================================================
--- server.c (revision 1600)
+++ server.c (revision 1758)
@@ -119,9 +119,15 @@
alarm(10);
trace(TRACE_DEBUG, "StartServer(): children created, starting main service loop");
- while (!GeneralStopRequested)
- manage_restart_children();
-
+ while (!GeneralStopRequested) {
+ if (db_connect() != 0) {
+ GeneralStopRequested=1;
+ } else {
+ db_disconnect();
+ manage_restart_children();
+ }
+ }
+
manage_stop_children();
scoreboard_delete();
@@ -131,6 +137,8 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ int saved_errno = errno;
+
if (ParentPID != getpid()) {
trace(TRACE_INFO,
"ParentSigHandler(): i'm no longer father");
@@ -162,6 +170,8 @@
default:
GeneralStopRequested = 1;
}
+
+ errno = saved_errno;
}

View file

@ -0,0 +1,267 @@
Index: serverchild.c
===================================================================
--- serverchild.c (revision 1600)
+++ serverchild.c (revision 1758)
@@ -66,13 +66,13 @@
void client_close(void)
{
if (client.tx) {
- trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__func__);
fflush(client.tx);
fclose(client.tx); /* closes clientSocket as well */
client.tx = NULL;
}
if (client.rx) {
- trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__func__);
shutdown(fileno(client.rx), SHUT_RDWR);
fclose(client.rx);
client.rx = NULL;
@@ -86,7 +86,7 @@
trace(TRACE_DEBUG,
"%s,%s: database connection still open, closing",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
db_disconnect();
auth_disconnect();
connected = 0; /* FIXME a signal between this line and the previous one
@@ -99,18 +99,22 @@
void noop_child_sig_handler(int sig, siginfo_t *info UNUSED, void *data UNUSED)
{
- trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __FUNCTION__, sig);
+ int saved_errno = errno;
+ trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __func__, sig);
+ errno = saved_errno;
}
void active_child_sig_handler(int sig, siginfo_t * info UNUSED, void *data UNUSED)
{
+ int saved_errno = errno;
+
static int triedDisconnect = 0;
#ifdef _USE_STR_SIGNAL
- trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __FUNCTION__,
+ trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __func__,
strsignal(sig));
#else
- trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __FUNCTION__, sig);
+ trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __func__, sig);
#endif
/* perform reinit at SIGHUP otherwise exit, but do nothing on
@@ -118,10 +122,10 @@
switch (sig) {
case SIGCHLD:
trace(TRACE_DEBUG, "%s,%s: SIGCHLD received... ignoring",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
break;
case SIGALRM:
- trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __func__);
client_close();
break;
@@ -132,23 +136,23 @@
if (ChildStopRequested) {
trace(TRACE_DEBUG,
"%s,%s: already caught a stop request. Closing right now",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
/* already caught this signal, exit the hard way now */
client_close();
disconnect_all();
child_unregister();
- trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__func__);
exit(1);
}
- trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__func__);
DelChildSigHandler();
ChildStopRequested = 1;
break;
default:
/* bad shtuff, exit */
trace(TRACE_DEBUG,
- "%s,%s: cannot ignore this. Terminating",__FILE__,__FUNCTION__);
+ "%s,%s: cannot ignore this. Terminating",__FILE__,__func__);
/*
* For some reason i have not yet determined the process starts eating up
@@ -164,10 +168,12 @@
disconnect_all();
}
- trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __func__);
child_unregister();
exit(1);
}
+
+ errno = saved_errno;
}
@@ -239,16 +245,19 @@
if (! pid) {
if (child_register() == -1) {
trace(TRACE_FATAL, "%s,%s: child_register failed",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
ChildStopRequested = 0;
SetChildSigHandler();
- trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
- __FILE__, __FUNCTION__);
- PerformChildTask(info);
+
+ trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
+ __FILE__, __func__);
+
+ if (PerformChildTask(info)== -1)
+ return -1;
child_unregister();
exit(0);
} else {
@@ -269,22 +278,22 @@
struct hostent *clientHost;
if (!info) {
- trace(TRACE_ERROR,
- "PerformChildTask(): NULL info supplied");
+ trace(TRACE_ERROR, "%s,%s: NULL info supplied",
+ __FILE__, __func__);
return -1;
}
if (db_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to database");
+ trace(TRACE_ERROR, "%s,%s: could not connect to database",
+ __FILE__, __func__);
return -1;
}
if (db_check_version() != 0)
return -1;
if (auth_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to authentication");
+ trace(TRACE_ERROR, "%s,%s: could not connect to authentication",
+ __FILE__, __func__);
return -1;
}
@@ -294,12 +303,13 @@
for (i = 0; i < info->maxConnect && !ChildStopRequested; i++) {
if (db_check_connection()) {
- trace(TRACE_ERROR, "%s,%s: database has gone away", __FILE__, __func__);
+ trace(TRACE_ERROR, "%s,%s: database has gone away",
+ __FILE__, __func__);
return -1;
}
- trace(TRACE_INFO,
- "PerformChildTask(): waiting for connection");
+ trace(TRACE_INFO, "%s,%s: waiting for connection",
+ __FILE__, __func__);
child_reg_disconnected();
@@ -312,8 +322,8 @@
if (clientSocket == -1) {
i--; /* don't count this as a connect */
- trace(TRACE_INFO,
- "PerformChildTask(): accept failed");
+ trace(TRACE_INFO, "%s,%s: accept failed",
+ __FILE__, __func__);
continue; /* accept failed, refuse connection & continue */
}
@@ -337,30 +347,29 @@
strncpy(client.clientname,
clientHost->h_name, FIELDSIZE);
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s (%s)]",
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s (%s)]",
+ __FILE__, __func__,
client.ip,
client.clientname[0] ? client.
clientname : "Lookup failed");
} else {
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s]",
- client.ip);
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s]",
+ __FILE__, __func__, client.ip);
}
/* make streams */
if (!(client.rx = fdopen(dup(clientSocket), "r"))) {
/* read-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening read file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening read file stream",
+ __FILE__, __func__);
close(clientSocket);
continue;
}
if (!(client.tx = fdopen(clientSocket, "w"))) {
/* write-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening write file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening write file stream",
+ __FILE__, __func__);
fclose(client.rx);
close(clientSocket);
memset(&client, 0, sizeof(client));
@@ -370,8 +379,8 @@
setvbuf(client.tx, (char *) NULL, _IOLBF, 0);
setvbuf(client.rx, (char *) NULL, _IOLBF, 0);
- trace(TRACE_DEBUG,
- "PerformChildTask(): client info init complete, calling client handler");
+ trace(TRACE_DEBUG, "%s,%s: client info init complete, calling client handler",
+ __FILE__, __func__);
/* streams are ready, perform handling */
info->ClientHandler(&client);
@@ -379,17 +388,19 @@
set_proc_title("%s", "Idle");
#endif
- trace(TRACE_DEBUG,
- "PerformChildTask(): client handling complete, closing streams");
+ trace(TRACE_DEBUG, "%s,%s: client handling complete, closing streams",
+ __FILE__, __func__);
client_close();
- trace(TRACE_INFO, "PerformChildTask(): connection closed");
+ trace(TRACE_INFO, "%s,%s: connection closed",
+ __FILE__, __func__);
}
if (!ChildStopRequested)
- trace(TRACE_ERROR,
- "PerformChildTask(): maximum number of connections reached, stopping now");
+ trace(TRACE_ERROR, "%s,%s: maximum number of connections reached, stopping now",
+ __FILE__, __func__);
else
- trace(TRACE_ERROR, "PerformChildTask(): stop requested");
+ trace(TRACE_ERROR, "%s,%s: stop requested",
+ __FILE__, __func__);
child_reg_disconnected();
disconnect_all();

View file

@ -0,0 +1,13 @@
Index: pool.c
===================================================================
--- pool.c (revision 1763)
+++ pool.c (revision 1787)
@@ -433,7 +433,7 @@
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
chpid = scoreboard->child[i].pid;
- if (chpid != 0)
+ if (chpid > 0)
kill(chpid, SIGKILL);;
scoreboard_release(chpid);
}

View file

@ -0,0 +1,35 @@
Index: server.c
===================================================================
--- server.c (revision 1763)
+++ server.c (revision 1787)
@@ -69,7 +69,7 @@
act.sa_sigaction = ParentSigHandler;
sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
+ act.sa_flags = SA_SIGINFO | SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, 0);
sigaction(SIGINT, &act, 0);
@@ -152,6 +152,7 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ pid_t chpid;
int saved_errno = errno;
if (ParentPID != getpid()) {
@@ -175,7 +176,12 @@
break;
case SIGCHLD:
- break; /* ignore, wait for child in main loop */
+ /* ignore, wait for child in main loop */
+ /* but we need to catch zombie */
+ if ((chpid = waitpid(-1,&sig,WNOHANG)) > 0)
+ scoreboard_release(chpid);
+
+ break;
case SIGHUP:
trace(TRACE_DEBUG,

View file

@ -0,0 +1,20 @@
Index: main.c
===================================================================
--- main.c (revision 1793)
+++ main.c (revision 1796)
@@ -133,6 +133,7 @@
trace(TRACE_ERROR, "%s,%s: error reading message",
__FILE__, __func__);
dm_free(tmpmessage);
+ tmpmessage=NULL;
return -1;
}
@@ -371,6 +372,7 @@
trace(TRACE_ERROR, "%s,%s splitmessage failed",
__FILE__, __func__);
dm_free(whole_message);
+ whole_message=NULL;
exitcode = EX_TEMPFAIL;
goto freeall;
}

View file

@ -0,0 +1,37 @@
Index: header.c
===================================================================
--- header.c (revision 1796)
+++ header.c (revision 1813)
@@ -176,15 +176,17 @@
if (message_content[line_content_size] == '\n') {
tmp_line_size = line_content_size + 1;
tmp_line_rfcsize = tmp_line_size + 1;
- } else {
- if (message_content[line_content_size] == '\r' &&
- message_content[line_content_size + 1] == '\n') {
+ } else if (message_content[line_content_size] == '\r') {
+ if (message_content[line_content_size + 1] == '\n') {
+ /* This is the right behaviour */
tmp_line_size = line_content_size + 2;
tmp_line_rfcsize = tmp_line_size;
} else {
- trace(TRACE_ERROR, "%s,%s: error reading header line",
- __FILE__, __func__);
- return -1;
+ /* This is broken behaviour, but it's better
+ * than not handling it at all.
+ */
+ tmp_line_size = line_content_size + 1;
+ tmp_line_rfcsize = tmp_line_size + 1;
}
}
}
@@ -197,7 +199,6 @@
__FILE__, __func__);
return 0;
}
- else
- return 1;
+ return 1;
}

View file

@ -0,0 +1,80 @@
Index: imaputil.c
===================================================================
--- imaputil.c (revision 1726)
+++ imaputil.c (revision 1793)
@@ -65,7 +65,7 @@
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* returned by date_sql2imap() */
-#define IMAP_STANDARD_DATE "03-Nov-1979 00:00:00 +0000"
+#define IMAP_STANDARD_DATE "Sat, 03-Nov-1979 00:00:00 +0000"
char _imapdate[IMAP_INTERNALDATE_LEN] = IMAP_STANDARD_DATE;
/* returned by date_imap2sql() */
@@ -1776,50 +1776,35 @@
/*
* convert a mySQL date (yyyy-mm-dd hh:mm:ss) to a valid IMAP internal date:
- * 0123456789012345678
- * dd-mon-yyyy hh:mm:ss with mon characters (i.e. 'Apr' for april)
- * 01234567890123456789
+ * [Mon, 30 May 2005 10:01:55 +0100] with mon characters (i.e. 'Apr' for april)
* return value is valid until next function call.
* NOTE: if date is not valid, IMAP_STANDARD_DATE is returned
*/
char *date_sql2imap(const char *sqldate)
{
- char *last_char;
- struct tm tm_localtime, tm_sqldate;
- time_t td;
+ struct tm tm_sql_date;
+ struct tm *tm_imap_date;
+
+ time_t ltime;
+ char *last;
- /* we need to get the localtime to get the current timezone */
- if (time(&td) == -1) {
- trace(TRACE_ERROR, "%s,%s: error getting time()",
- __FILE__, __func__);
- return IMAP_STANDARD_DATE;
- }
- tm_localtime = *localtime(&td);
+ last = strptime(sqldate,"%Y-%m-%d %T", &tm_sql_date);
+ if ( (last == NULL) || (*last != '\0') ) {
+ strcpy(_imapdate, IMAP_STANDARD_DATE);
+ return _imapdate;
+ }
- /* parse sqldate */
- last_char = strptime(sqldate, "%Y-%m-%d %T", &tm_sqldate);
- if (last_char == NULL || *last_char != '\0') {
- trace(TRACE_DEBUG, "%s,%s, error parsing date [%s]",
- __FILE__, __func__, sqldate);
- strcpy(_imapdate, IMAP_STANDARD_DATE);
- return _imapdate;
- }
- /* copy DST information from localtime */
- tm_sqldate.tm_gmtoff = tm_localtime.tm_gmtoff;
- tm_sqldate.tm_isdst = tm_localtime.tm_isdst;
+ /* FIXME: this works fine on linux, but may cause dst offsets in netbsd. */
+ ltime = mktime (&tm_sql_date);
+ tm_imap_date = localtime(&ltime);
- (void) strftime(_imapdate, IMAP_INTERNALDATE_LEN,
- "%d-%b-%Y %T %z", &tm_sqldate);
-
- return _imapdate;
+ strftime(_imapdate, sizeof(_imapdate), "%a, %d %b %Y %H:%M:%S %z", tm_imap_date);
+ return _imapdate;
}
-
/*
* convert TO a mySQL date (yyyy-mm-dd) FROM a valid IMAP internal date:
- * 0123456789
* dd-mon-yyyy with mon characters (i.e. 'Apr' for april)
- * 01234567890
* OR
* d-mon-yyyy
* return value is valid until next function call.

View file

@ -1,7 +1,4 @@
etc/dbmail.conf-dist etc/dbmail.conf-dist
etc/rc.d/dbmail-imapd.sh
etc/rc.d/dbmail-lmtpd.sh
etc/rc.d/dbmail-pop3d.sh
lib/dbmail/libauthdbmail.0 lib/dbmail/libauthdbmail.0
lib/dbmail/libauthdbmail.a lib/dbmail/libauthdbmail.a
lib/dbmail/libauthdbmail.la lib/dbmail/libauthdbmail.la

View file

@ -7,6 +7,7 @@
PORTNAME= dbmail PORTNAME= dbmail
PORTVERSION= 2.0.4 PORTVERSION= 2.0.4
PORTREVISION= 1
CATEGORIES= mail CATEGORIES= mail
MASTER_SITES= http://www.dbmail.org/download/ MASTER_SITES= http://www.dbmail.org/download/
PKGNAMESUFFIX= -${DATABASE} PKGNAMESUFFIX= -${DATABASE}
@ -20,14 +21,10 @@ GNU_CONFIGURE= YES
CONFIGURE_ARGS= --prefix=${PREFIX} CONFIGURE_ARGS= --prefix=${PREFIX}
USE_GMAKE= YES USE_GMAKE= YES
USE_OPENSSL= YES USE_OPENSSL= YES
USE_RC_SUBR= dbmail-pop3d.sh dbmail-lmtpd.sh dbmail-imapd.sh
CFLAGS += -fPIC CFLAGS += -fPIC
SED_SCRIPT+= -e 's|%%RC_SUBR%%|${RC_SUBR}|g' \
-e 's|%%PREFIX%%|${PREFIX}|g' \
-e 's|%%RC_DIR%%|${RC_DIR}|g' \
-e 's|%%RC_SUFX%%|${RC_SUFX}|g'
.if defined(WITH_POSTGRESQL) .if defined(WITH_POSTGRESQL)
CONFIGURE_ARGS+= --with-pgsql CONFIGURE_ARGS+= --with-pgsql
USE_PGSQL= yes USE_PGSQL= yes
@ -68,16 +65,8 @@ post-configure:
@${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \ @${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \
${WRKSRC}/dbmail.h ${WRKSRC}/dbmail.h
post-build:
.for f in imap lmtp pop3
@${SED} ${SED_SCRIPT} ${FILESDIR}/dbmail-${f}d.sh > ${WRKDIR}/dbmail-${f}d.sh
.endfor
post-install: post-install:
@${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist @${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist
.for f in imap lmtp pop3
@${INSTALL_SCRIPT} ${WRKDIR}/dbmail-${f}d.sh ${DESTDIR}${PREFIX}/etc/rc.d/dbmail-${f}d.sh
.endfor
@${MKDIR} ${DATADIR}/sql @${MKDIR} ${DATADIR}/sql
@${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql @${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql
@cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1 @cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1

View file

@ -0,0 +1,66 @@
Index: lmtp.c
===================================================================
--- lmtp.c (revision 1559)
+++ lmtp.c (revision 1700)
@@ -77,8 +77,9 @@
* - -1 on error
* - 1 on success
*/
-static int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size);
+static int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...) PRINTF_ARGS(4, 5);
/**
* \function lmtp_error
@@ -624,7 +625,9 @@
if (read_whole_message_network(
(FILE *) instream,
&whole_message,
- &whole_message_size) < 0) {
+ &whole_message_size,
+ "Return-Path: %s\r\n",
+ (char *)(list_getstart(&from)->data)) < 0) {
trace(TRACE_ERROR,
"%s,%s: read_whole_message_network() failed",
__FILE__, __func__);
@@ -755,8 +758,9 @@
return 1;
}
-int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size)
+int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...)
{
char *tmpmessage = NULL;
char tmpline[MESSAGE_MAX_LINE_SIZE + 1];
@@ -765,9 +769,17 @@
size_t total_size = 0;
size_t current_pos = 0;
int error = 0;
+ va_list argp;
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
- while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL) {
+
+ /* This adds the Return-Path header and any other
+ * important headers we might need; see RFC 2076. */
+ va_start(argp, prepend_format);
+ line_size = vsnprintf(tmpline, MESSAGE_MAX_LINE_SIZE, prepend_format, argp);
+ va_end(argp);
+
+ do {
line_size = strlen(tmpline);
/* It sometimes happens that we read a line of size 0,
@@ -798,6 +810,7 @@
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
}
+ while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL);
if (ferror(instream)) {
trace(TRACE_ERROR, "%s,%s: error reading instream",

View file

@ -0,0 +1,575 @@
Index: user.c
===================================================================
--- user.c (revision 1711)
+++ user.c (revision 1712)
@@ -202,8 +202,8 @@
memset(&change_flags, 0, sizeof(change_flags));
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-a:d:c:e:l::x:" /* Major modes */
"W::w:P::p:u:g:m:t:s:S:T:" /* Minor options */
"i" "f:qnyvVh" /* Common options */ )) != -1) {
@@ -223,16 +223,16 @@
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- user = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ user = dm_strdup(dm_optarg);
break;
case 'x':
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- alias = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ alias = dm_strdup(dm_optarg);
break;
case 'l':
@@ -241,8 +241,8 @@
if (mode != 0 && mode != 'l')
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- userspec = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ userspec = dm_strdup(dm_optarg);
break;
case 'i':
@@ -253,13 +253,13 @@
/* Minor options */
case 'w':
change_flags.newpasswd = 1;
- passwd = dm_strdup(optarg);
+ passwd = dm_strdup(dm_optarg);
break;
case 'W':
change_flags.newpasswd = 1;
- if (optarg && strlen(optarg)) {
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg)) {
+ passwdfile = dm_strdup(dm_optarg);
change_flags.newpasswdfile = 1;
} else {
change_flags.newpasswdstdin = 1;
@@ -268,20 +268,20 @@
case 'u':
change_flags.newuser = 1;
- newuser = dm_strdup(optarg);
+ newuser = dm_strdup(dm_optarg);
break;
case 'p':
if (!passwdtype)
- passwdtype = dm_strdup(optarg);
+ passwdtype = dm_strdup(dm_optarg);
// else
// Complain about only one type allowed.
break;
case 'P':
change_flags.newpasswdshadow = 1;
- if (optarg && strlen(optarg))
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ passwdfile = dm_strdup(dm_optarg);
else
passwdfile = SHADOWFILE;
passwdtype = "shadow";
@@ -289,42 +289,42 @@
case 'g':
change_flags.newclientid = 1;
- clientid = strtoull(optarg, NULL, 10);
+ clientid = strtoull(dm_optarg, NULL, 10);
break;
case 'm':
change_flags.newmaxmail = 1;
- maxmail = strtomaxmail(optarg);
+ maxmail = strtomaxmail(dm_optarg);
break;
case 's':
// Add this item to the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_add, dm_optarg, len+1);
break;
case 'S':
// Delete this item from the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_del, dm_optarg, len+1);
break;
case 't':
// Add this item to the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_add, dm_optarg, len+1);
break;
case 'T':
// Delete this item from the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_del, dm_optarg, len+1);
break;
/* Common options */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-users: -f requires a filename\n\n");
result = 1;
Index: lmtpd.c
===================================================================
--- lmtpd.c (revision 1711)
+++ lmtpd.c (revision 1712)
@@ -100,8 +100,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -121,8 +121,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -p requires a filename "
@@ -131,8 +131,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -f requires a filename "
Index: dm_getopt.c
===================================================================
--- dm_getopt.c (revision 1711)
+++ dm_getopt.c (revision 1712)
@@ -135,7 +135,7 @@
*/
int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only)
{
char mode, colon_mode = *shortopts;
@@ -261,13 +261,13 @@
}
int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 0);
}
int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 1);
}
Index: maintenance.c
===================================================================
--- maintenance.c (revision 1711)
+++ maintenance.c (revision 1712)
@@ -121,8 +121,8 @@
setvbuf(stdout, 0, _IONBF, 0);
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-acrtl:pudb" /* Main options */
"i" /* Maybe later options */
"f:qnyvVh")) != -1) { /* Common options */
@@ -173,8 +173,8 @@
case 'l':
check_iplog = 1;
do_nothing = 0;
- if (optarg)
- strncpy(timespec, optarg, LEN);
+ if (dm_optarg)
+ strncpy(timespec, dm_optarg, LEN);
else
timespec[0] = 0;
@@ -209,8 +209,8 @@
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-util: -f requires a filename\n\n" );
return 1;
Index: dm_getopt.h
===================================================================
--- dm_getopt.h (revision 1711)
+++ dm_getopt.h (revision 1712)
@@ -26,38 +26,23 @@
*/
#include "config.h"
+#ifndef DM_GETOPT_H
+#define DM_GETOPT_H
-#ifndef USE_DM_GETOPT
-# include <getopt.h>
-#endif
+# ifndef USE_DM_GETOPT
+# include <getopt.h>
+# define dm_getopt getopt
+# define dm_getopt_long getopt_long
+# define dm_getopt_long_only getopt_long_only
+# define _dm_getopt_internal _getopt_internal
+# define dm_opterr opterr
+# define dm_optind optind
+# define dm_optopt optopt
+# define dm_optarg optarg
+# endif
-#ifdef USE_DM_GETOPT
+# ifdef USE_DM_GETOPT
-# ifndef DM_GETOPT_H
- /* Our include guard first. */
-# define DM_GETOPT_H
- /* Try to kill the system getopt.h */
-# define _GETOPT_DECLARED
-# define _GETOPT_H
-# define GETOPT_H
-
-# undef getopt
-# define getopt dm_getopt
-# undef getopt_long
-# define getopt_long dm_getopt_long
-# undef getopt_long_only
-# define getopt_long_only dm_getopt_long_only
-# undef _getopt_internal
-# define _getopt_internal _dm_getopt_internal
-# undef opterr
-# define opterr dm_opterr
-# undef optind
-# define optind dm_optind
-# undef optopt
-# define optopt dm_optopt
-# undef optarg
-# define optarg dm_optarg
-
# ifdef __cplusplus
extern "C" {
# endif
@@ -68,7 +53,7 @@
extern int dm_optind, dm_opterr, dm_optopt;
extern char *dm_optarg;
-struct option {
+struct dm_option {
const char *name;
int has_arg;
int *flag;
@@ -76,28 +61,25 @@
};
/* human-readable values for has_arg */
-# undef no_argument
-# define no_argument 0
-# undef required_argument
-# define required_argument 1
-# undef optional_argument
-# define optional_argument 2
+# define dm_getopt_no_argument 0
+# define dm_getopt_required_argument 1
+# define dm_getopt_optional_argument 2
/* GNU-style long-argument parsers */
extern int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only);
# ifdef __cplusplus
}
# endif
-# endif /* DM_GETOPT_H */
+# endif /* USE_DM_GETOPT */
-#endif /* USE_DM_GETOPT */
+#endif /* DM_GETOPT_H */
Index: timsieved.c
===================================================================
--- timsieved.c (revision 1711)
+++ timsieved.c (revision 1712)
@@ -99,8 +99,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -120,8 +120,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -p requires a filename "
@@ -130,8 +130,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -f requires a filename "
Index: pop3d.c
===================================================================
--- pop3d.c (revision 1711)
+++ pop3d.c (revision 1712)
@@ -103,8 +103,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -124,8 +124,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -p requires a filename "
@@ -134,8 +134,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -f requires a filename "
Index: imapd.c
===================================================================
--- imapd.c (revision 1711)
+++ imapd.c (revision 1712)
@@ -97,8 +97,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -118,8 +118,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -p requires a filename "
@@ -128,8 +128,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -f requires a filename "
Index: sievecmd.c
===================================================================
--- sievecmd.c (revision 1711)
+++ sievecmd.c (revision 1712)
@@ -57,7 +57,7 @@
char *user_name = NULL;
char *name = NULL;
FILE *source = NULL;
- extern char *optarg;
+ extern char *dm_optarg;
openlog(PNAME, LOG_PID, LOG_MAIL);
@@ -70,7 +70,7 @@
configure_debug(TRACE_ERROR, 1, 0);
while (opt != -1 && act != 'h') {
- opt = getopt(argc, argv, "a:d:i:r:u:l");
+ opt = dm_getopt(argc, argv, "a:d:i:r:u:l");
switch (opt) {
case -1:
@@ -84,11 +84,11 @@
act = 'h';
else
act = opt;
- name = optarg;
+ name = dm_optarg;
source = stdin; // FIXME to take files as input, too
break;
case 'u':
- user_name = dm_strdup(optarg);
+ user_name = dm_strdup(dm_optarg);
break;
case 'l':
if (act != 0)
Index: main.c
===================================================================
--- main.c (revision 1711)
+++ main.c (revision 1712)
@@ -189,7 +189,7 @@
* with an immediately preceding option are return with option
* value '1'. We will use this to allow for multiple values to
* follow after each of the supported options. */
- while ((c = getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
+ while ((c = dm_getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
/* Received an n-th value following the last option,
* so recall the last known option to be used in the switch. */
if (c == 1)
@@ -200,13 +200,13 @@
case 't':
trace(TRACE_INFO, "main(): using NORMAL_DELIVERY");
- if (optarg) {
+ if (dm_optarg) {
if (deliver_to_header) {
printf
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_header = optarg;
+ deliver_to_header = dm_optarg;
} else
deliver_to_header = "deliver-to";
@@ -221,7 +221,7 @@
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_mailbox = optarg;
+ deliver_to_mailbox = dm_optarg;
break;
@@ -231,8 +231,8 @@
/* Add argument onto the returnpath list. */
if (list_nodeadd
- (&returnpath, optarg,
- strlen(optarg) + 1) == 0) {
+ (&returnpath, dm_optarg,
+ strlen(dm_optarg) + 1) == 0) {
trace(TRACE_ERROR,
"main(): list_nodeadd reports out of memory"
" while adding to returnpath");
@@ -247,7 +247,7 @@
"main(): using SPECIAL_DELIVERY to usernames");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -267,7 +267,7 @@
"main(): using SPECIAL_DELIVERY to email addresses");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -284,8 +284,8 @@
/* Common command line options. */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-smtp: -f requires a filename\n\n" );

View file

@ -0,0 +1,66 @@
Index: configure.in
===================================================================
--- configure.in (revision 1751)
+++ configure.in (revision 1761)
@@ -42,6 +42,7 @@
DBMAIL_CHECK_SIEVE_LIBS
DBMAIL_CHECK_GC
DBMAIL_CHECK_GETOPT
+DBMAIL_CHECK_SOCKLEN_T
AC_PROG_CC
AC_COMPILE_WARNINGS
Index: acinclude.m4
===================================================================
--- acinclude.m4 (revision 1751)
+++ acinclude.m4 (revision 1761)
@@ -513,3 +513,49 @@
# Prerequisites of lib/getopt*.
AC_DEFUN([CHECK_PREREQ_GETOPT], [:])
+
+#
+# socklen_t
+# from curl
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+AC_DEFUN([DBMAIL_CHECK_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+ ],[
+ $t len;
+ getpeername(0,0,&len);
+ ],[
+ socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$socklen_t_equiv" = x; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_MSG_RESULT($socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+

View file

@ -0,0 +1,126 @@
Index: pool.c
===================================================================
--- pool.c (revision 1600)
+++ pool.c (revision 1758)
@@ -73,8 +73,10 @@
void scoreboard_new(serverConfig_t * conf)
{
int serr;
- if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1)
- trace(TRACE_FATAL, "%s,%s: shmget failed",__FILE__,__func__);
+ if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1) {
+ serr = errno;
+ trace(TRACE_FATAL, "%s,%s: shmget failed [%s]",__FILE__,__func__, strerror(serr));
+ }
scoreboard = shmat(shmid, (void *) 0, 0);
serr=errno;
if (scoreboard == (Scoreboard_t *) (-1)) {
@@ -222,7 +236,7 @@
}
scoreboard_unlck();
trace(TRACE_FATAL,
- "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __FUNCTION__, pid);
+ "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __func__, pid);
return -1;
}
@@ -238,25 +252,25 @@
{
int i;
trace(TRACE_MESSAGE, "%s,%s: register child [%d]",
- __FILE__, __FUNCTION__, getpid());
+ __FILE__, __func__, getpid());
scoreboard_wrlck();
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
if (scoreboard->child[i].pid == -1)
break;
if (scoreboard->child[i].pid == getpid()) {
- trace(TRACE_ERROR,
+ scoreboard_unlck();
+ trace(TRACE_FATAL,
"%s,%s: child already registered.",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
}
if (i == scoreboard->conf->maxChildren) {
+ scoreboard_unlck();
trace(TRACE_WARNING,
"%s,%s: no empty slot found",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
@@ -264,8 +278,8 @@
scoreboard->child[i].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_INFO, "%s,%s: initializing child_state [%d] using slot [%d]",
- __FILE__, __FUNCTION__, getpid(), i);
+ trace(TRACE_MESSAGE, "%s,%s: initializing child_state [%d] using slot [%d]",
+ __FILE__, __func__, getpid(), i);
return 0;
}
@@ -281,7 +295,7 @@
scoreboard->child[key].status = STATE_CONNECTED;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -297,7 +311,7 @@
scoreboard->child[key].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -320,7 +334,7 @@
scoreboard_unlck();
trace(TRACE_MESSAGE,
- "%s,%s: child [%d] unregistered", __FILE__, __FUNCTION__,
+ "%s,%s: child [%d] unregistered", __FILE__, __func__,
getpid());
}
@@ -346,7 +360,7 @@
manage_stop_children();
trace(TRACE_FATAL,
"%s,%s: could not create children. Fatal.",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
}
@@ -360,10 +374,17 @@
if (chpid == -1)
continue;
if (waitpid(chpid, NULL, WNOHANG|WUNTRACED) == chpid) {
+ scoreboard_release(chpid);
trace(TRACE_MESSAGE,"%s,%s: child [%d] exited. Restarting...",
- __FILE__, __FUNCTION__, chpid);
- scoreboard_release(chpid);
- CreateChild(&childinfo);
+ __FILE__, __func__, chpid);
+ if (CreateChild(&childinfo)== -1) {
+ trace(TRACE_ERROR,"%s,%s: createchild failed. Bailout...",
+ __FILE__, __func__);
+ GeneralStopRequested=1;
+ manage_stop_children();
+
+ exit(1);
+ }
}
}
sleep(1);

View file

@ -0,0 +1,41 @@
Index: server.c
===================================================================
--- server.c (revision 1600)
+++ server.c (revision 1758)
@@ -119,9 +119,15 @@
alarm(10);
trace(TRACE_DEBUG, "StartServer(): children created, starting main service loop");
- while (!GeneralStopRequested)
- manage_restart_children();
-
+ while (!GeneralStopRequested) {
+ if (db_connect() != 0) {
+ GeneralStopRequested=1;
+ } else {
+ db_disconnect();
+ manage_restart_children();
+ }
+ }
+
manage_stop_children();
scoreboard_delete();
@@ -131,6 +137,8 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ int saved_errno = errno;
+
if (ParentPID != getpid()) {
trace(TRACE_INFO,
"ParentSigHandler(): i'm no longer father");
@@ -162,6 +170,8 @@
default:
GeneralStopRequested = 1;
}
+
+ errno = saved_errno;
}

View file

@ -0,0 +1,267 @@
Index: serverchild.c
===================================================================
--- serverchild.c (revision 1600)
+++ serverchild.c (revision 1758)
@@ -66,13 +66,13 @@
void client_close(void)
{
if (client.tx) {
- trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__func__);
fflush(client.tx);
fclose(client.tx); /* closes clientSocket as well */
client.tx = NULL;
}
if (client.rx) {
- trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__func__);
shutdown(fileno(client.rx), SHUT_RDWR);
fclose(client.rx);
client.rx = NULL;
@@ -86,7 +86,7 @@
trace(TRACE_DEBUG,
"%s,%s: database connection still open, closing",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
db_disconnect();
auth_disconnect();
connected = 0; /* FIXME a signal between this line and the previous one
@@ -99,18 +99,22 @@
void noop_child_sig_handler(int sig, siginfo_t *info UNUSED, void *data UNUSED)
{
- trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __FUNCTION__, sig);
+ int saved_errno = errno;
+ trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __func__, sig);
+ errno = saved_errno;
}
void active_child_sig_handler(int sig, siginfo_t * info UNUSED, void *data UNUSED)
{
+ int saved_errno = errno;
+
static int triedDisconnect = 0;
#ifdef _USE_STR_SIGNAL
- trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __FUNCTION__,
+ trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __func__,
strsignal(sig));
#else
- trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __FUNCTION__, sig);
+ trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __func__, sig);
#endif
/* perform reinit at SIGHUP otherwise exit, but do nothing on
@@ -118,10 +122,10 @@
switch (sig) {
case SIGCHLD:
trace(TRACE_DEBUG, "%s,%s: SIGCHLD received... ignoring",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
break;
case SIGALRM:
- trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __func__);
client_close();
break;
@@ -132,23 +136,23 @@
if (ChildStopRequested) {
trace(TRACE_DEBUG,
"%s,%s: already caught a stop request. Closing right now",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
/* already caught this signal, exit the hard way now */
client_close();
disconnect_all();
child_unregister();
- trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__func__);
exit(1);
}
- trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__func__);
DelChildSigHandler();
ChildStopRequested = 1;
break;
default:
/* bad shtuff, exit */
trace(TRACE_DEBUG,
- "%s,%s: cannot ignore this. Terminating",__FILE__,__FUNCTION__);
+ "%s,%s: cannot ignore this. Terminating",__FILE__,__func__);
/*
* For some reason i have not yet determined the process starts eating up
@@ -164,10 +168,12 @@
disconnect_all();
}
- trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __func__);
child_unregister();
exit(1);
}
+
+ errno = saved_errno;
}
@@ -239,16 +245,19 @@
if (! pid) {
if (child_register() == -1) {
trace(TRACE_FATAL, "%s,%s: child_register failed",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
ChildStopRequested = 0;
SetChildSigHandler();
- trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
- __FILE__, __FUNCTION__);
- PerformChildTask(info);
+
+ trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
+ __FILE__, __func__);
+
+ if (PerformChildTask(info)== -1)
+ return -1;
child_unregister();
exit(0);
} else {
@@ -269,22 +278,22 @@
struct hostent *clientHost;
if (!info) {
- trace(TRACE_ERROR,
- "PerformChildTask(): NULL info supplied");
+ trace(TRACE_ERROR, "%s,%s: NULL info supplied",
+ __FILE__, __func__);
return -1;
}
if (db_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to database");
+ trace(TRACE_ERROR, "%s,%s: could not connect to database",
+ __FILE__, __func__);
return -1;
}
if (db_check_version() != 0)
return -1;
if (auth_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to authentication");
+ trace(TRACE_ERROR, "%s,%s: could not connect to authentication",
+ __FILE__, __func__);
return -1;
}
@@ -294,12 +303,13 @@
for (i = 0; i < info->maxConnect && !ChildStopRequested; i++) {
if (db_check_connection()) {
- trace(TRACE_ERROR, "%s,%s: database has gone away", __FILE__, __func__);
+ trace(TRACE_ERROR, "%s,%s: database has gone away",
+ __FILE__, __func__);
return -1;
}
- trace(TRACE_INFO,
- "PerformChildTask(): waiting for connection");
+ trace(TRACE_INFO, "%s,%s: waiting for connection",
+ __FILE__, __func__);
child_reg_disconnected();
@@ -312,8 +322,8 @@
if (clientSocket == -1) {
i--; /* don't count this as a connect */
- trace(TRACE_INFO,
- "PerformChildTask(): accept failed");
+ trace(TRACE_INFO, "%s,%s: accept failed",
+ __FILE__, __func__);
continue; /* accept failed, refuse connection & continue */
}
@@ -337,30 +347,29 @@
strncpy(client.clientname,
clientHost->h_name, FIELDSIZE);
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s (%s)]",
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s (%s)]",
+ __FILE__, __func__,
client.ip,
client.clientname[0] ? client.
clientname : "Lookup failed");
} else {
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s]",
- client.ip);
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s]",
+ __FILE__, __func__, client.ip);
}
/* make streams */
if (!(client.rx = fdopen(dup(clientSocket), "r"))) {
/* read-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening read file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening read file stream",
+ __FILE__, __func__);
close(clientSocket);
continue;
}
if (!(client.tx = fdopen(clientSocket, "w"))) {
/* write-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening write file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening write file stream",
+ __FILE__, __func__);
fclose(client.rx);
close(clientSocket);
memset(&client, 0, sizeof(client));
@@ -370,8 +379,8 @@
setvbuf(client.tx, (char *) NULL, _IOLBF, 0);
setvbuf(client.rx, (char *) NULL, _IOLBF, 0);
- trace(TRACE_DEBUG,
- "PerformChildTask(): client info init complete, calling client handler");
+ trace(TRACE_DEBUG, "%s,%s: client info init complete, calling client handler",
+ __FILE__, __func__);
/* streams are ready, perform handling */
info->ClientHandler(&client);
@@ -379,17 +388,19 @@
set_proc_title("%s", "Idle");
#endif
- trace(TRACE_DEBUG,
- "PerformChildTask(): client handling complete, closing streams");
+ trace(TRACE_DEBUG, "%s,%s: client handling complete, closing streams",
+ __FILE__, __func__);
client_close();
- trace(TRACE_INFO, "PerformChildTask(): connection closed");
+ trace(TRACE_INFO, "%s,%s: connection closed",
+ __FILE__, __func__);
}
if (!ChildStopRequested)
- trace(TRACE_ERROR,
- "PerformChildTask(): maximum number of connections reached, stopping now");
+ trace(TRACE_ERROR, "%s,%s: maximum number of connections reached, stopping now",
+ __FILE__, __func__);
else
- trace(TRACE_ERROR, "PerformChildTask(): stop requested");
+ trace(TRACE_ERROR, "%s,%s: stop requested",
+ __FILE__, __func__);
child_reg_disconnected();
disconnect_all();

View file

@ -0,0 +1,13 @@
Index: pool.c
===================================================================
--- pool.c (revision 1763)
+++ pool.c (revision 1787)
@@ -433,7 +433,7 @@
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
chpid = scoreboard->child[i].pid;
- if (chpid != 0)
+ if (chpid > 0)
kill(chpid, SIGKILL);;
scoreboard_release(chpid);
}

View file

@ -0,0 +1,35 @@
Index: server.c
===================================================================
--- server.c (revision 1763)
+++ server.c (revision 1787)
@@ -69,7 +69,7 @@
act.sa_sigaction = ParentSigHandler;
sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
+ act.sa_flags = SA_SIGINFO | SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, 0);
sigaction(SIGINT, &act, 0);
@@ -152,6 +152,7 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ pid_t chpid;
int saved_errno = errno;
if (ParentPID != getpid()) {
@@ -175,7 +176,12 @@
break;
case SIGCHLD:
- break; /* ignore, wait for child in main loop */
+ /* ignore, wait for child in main loop */
+ /* but we need to catch zombie */
+ if ((chpid = waitpid(-1,&sig,WNOHANG)) > 0)
+ scoreboard_release(chpid);
+
+ break;
case SIGHUP:
trace(TRACE_DEBUG,

View file

@ -0,0 +1,20 @@
Index: main.c
===================================================================
--- main.c (revision 1793)
+++ main.c (revision 1796)
@@ -133,6 +133,7 @@
trace(TRACE_ERROR, "%s,%s: error reading message",
__FILE__, __func__);
dm_free(tmpmessage);
+ tmpmessage=NULL;
return -1;
}
@@ -371,6 +372,7 @@
trace(TRACE_ERROR, "%s,%s splitmessage failed",
__FILE__, __func__);
dm_free(whole_message);
+ whole_message=NULL;
exitcode = EX_TEMPFAIL;
goto freeall;
}

View file

@ -0,0 +1,37 @@
Index: header.c
===================================================================
--- header.c (revision 1796)
+++ header.c (revision 1813)
@@ -176,15 +176,17 @@
if (message_content[line_content_size] == '\n') {
tmp_line_size = line_content_size + 1;
tmp_line_rfcsize = tmp_line_size + 1;
- } else {
- if (message_content[line_content_size] == '\r' &&
- message_content[line_content_size + 1] == '\n') {
+ } else if (message_content[line_content_size] == '\r') {
+ if (message_content[line_content_size + 1] == '\n') {
+ /* This is the right behaviour */
tmp_line_size = line_content_size + 2;
tmp_line_rfcsize = tmp_line_size;
} else {
- trace(TRACE_ERROR, "%s,%s: error reading header line",
- __FILE__, __func__);
- return -1;
+ /* This is broken behaviour, but it's better
+ * than not handling it at all.
+ */
+ tmp_line_size = line_content_size + 1;
+ tmp_line_rfcsize = tmp_line_size + 1;
}
}
}
@@ -197,7 +199,6 @@
__FILE__, __func__);
return 0;
}
- else
- return 1;
+ return 1;
}

View file

@ -0,0 +1,80 @@
Index: imaputil.c
===================================================================
--- imaputil.c (revision 1726)
+++ imaputil.c (revision 1793)
@@ -65,7 +65,7 @@
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* returned by date_sql2imap() */
-#define IMAP_STANDARD_DATE "03-Nov-1979 00:00:00 +0000"
+#define IMAP_STANDARD_DATE "Sat, 03-Nov-1979 00:00:00 +0000"
char _imapdate[IMAP_INTERNALDATE_LEN] = IMAP_STANDARD_DATE;
/* returned by date_imap2sql() */
@@ -1776,50 +1776,35 @@
/*
* convert a mySQL date (yyyy-mm-dd hh:mm:ss) to a valid IMAP internal date:
- * 0123456789012345678
- * dd-mon-yyyy hh:mm:ss with mon characters (i.e. 'Apr' for april)
- * 01234567890123456789
+ * [Mon, 30 May 2005 10:01:55 +0100] with mon characters (i.e. 'Apr' for april)
* return value is valid until next function call.
* NOTE: if date is not valid, IMAP_STANDARD_DATE is returned
*/
char *date_sql2imap(const char *sqldate)
{
- char *last_char;
- struct tm tm_localtime, tm_sqldate;
- time_t td;
+ struct tm tm_sql_date;
+ struct tm *tm_imap_date;
+
+ time_t ltime;
+ char *last;
- /* we need to get the localtime to get the current timezone */
- if (time(&td) == -1) {
- trace(TRACE_ERROR, "%s,%s: error getting time()",
- __FILE__, __func__);
- return IMAP_STANDARD_DATE;
- }
- tm_localtime = *localtime(&td);
+ last = strptime(sqldate,"%Y-%m-%d %T", &tm_sql_date);
+ if ( (last == NULL) || (*last != '\0') ) {
+ strcpy(_imapdate, IMAP_STANDARD_DATE);
+ return _imapdate;
+ }
- /* parse sqldate */
- last_char = strptime(sqldate, "%Y-%m-%d %T", &tm_sqldate);
- if (last_char == NULL || *last_char != '\0') {
- trace(TRACE_DEBUG, "%s,%s, error parsing date [%s]",
- __FILE__, __func__, sqldate);
- strcpy(_imapdate, IMAP_STANDARD_DATE);
- return _imapdate;
- }
- /* copy DST information from localtime */
- tm_sqldate.tm_gmtoff = tm_localtime.tm_gmtoff;
- tm_sqldate.tm_isdst = tm_localtime.tm_isdst;
+ /* FIXME: this works fine on linux, but may cause dst offsets in netbsd. */
+ ltime = mktime (&tm_sql_date);
+ tm_imap_date = localtime(&ltime);
- (void) strftime(_imapdate, IMAP_INTERNALDATE_LEN,
- "%d-%b-%Y %T %z", &tm_sqldate);
-
- return _imapdate;
+ strftime(_imapdate, sizeof(_imapdate), "%a, %d %b %Y %H:%M:%S %z", tm_imap_date);
+ return _imapdate;
}
-
/*
* convert TO a mySQL date (yyyy-mm-dd) FROM a valid IMAP internal date:
- * 0123456789
* dd-mon-yyyy with mon characters (i.e. 'Apr' for april)
- * 01234567890
* OR
* d-mon-yyyy
* return value is valid until next function call.

View file

@ -1,7 +1,4 @@
etc/dbmail.conf-dist etc/dbmail.conf-dist
etc/rc.d/dbmail-imapd.sh
etc/rc.d/dbmail-lmtpd.sh
etc/rc.d/dbmail-pop3d.sh
lib/dbmail/libauthdbmail.0 lib/dbmail/libauthdbmail.0
lib/dbmail/libauthdbmail.a lib/dbmail/libauthdbmail.a
lib/dbmail/libauthdbmail.la lib/dbmail/libauthdbmail.la

View file

@ -7,6 +7,7 @@
PORTNAME= dbmail PORTNAME= dbmail
PORTVERSION= 2.0.4 PORTVERSION= 2.0.4
PORTREVISION= 1
CATEGORIES= mail CATEGORIES= mail
MASTER_SITES= http://www.dbmail.org/download/ MASTER_SITES= http://www.dbmail.org/download/
PKGNAMESUFFIX= -${DATABASE} PKGNAMESUFFIX= -${DATABASE}
@ -20,14 +21,10 @@ GNU_CONFIGURE= YES
CONFIGURE_ARGS= --prefix=${PREFIX} CONFIGURE_ARGS= --prefix=${PREFIX}
USE_GMAKE= YES USE_GMAKE= YES
USE_OPENSSL= YES USE_OPENSSL= YES
USE_RC_SUBR= dbmail-pop3d.sh dbmail-lmtpd.sh dbmail-imapd.sh
CFLAGS += -fPIC CFLAGS += -fPIC
SED_SCRIPT+= -e 's|%%RC_SUBR%%|${RC_SUBR}|g' \
-e 's|%%PREFIX%%|${PREFIX}|g' \
-e 's|%%RC_DIR%%|${RC_DIR}|g' \
-e 's|%%RC_SUFX%%|${RC_SUFX}|g'
.if defined(WITH_POSTGRESQL) .if defined(WITH_POSTGRESQL)
CONFIGURE_ARGS+= --with-pgsql CONFIGURE_ARGS+= --with-pgsql
USE_PGSQL= yes USE_PGSQL= yes
@ -68,16 +65,8 @@ post-configure:
@${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \ @${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \
${WRKSRC}/dbmail.h ${WRKSRC}/dbmail.h
post-build:
.for f in imap lmtp pop3
@${SED} ${SED_SCRIPT} ${FILESDIR}/dbmail-${f}d.sh > ${WRKDIR}/dbmail-${f}d.sh
.endfor
post-install: post-install:
@${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist @${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist
.for f in imap lmtp pop3
@${INSTALL_SCRIPT} ${WRKDIR}/dbmail-${f}d.sh ${DESTDIR}${PREFIX}/etc/rc.d/dbmail-${f}d.sh
.endfor
@${MKDIR} ${DATADIR}/sql @${MKDIR} ${DATADIR}/sql
@${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql @${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql
@cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1 @cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1

View file

@ -0,0 +1,66 @@
Index: lmtp.c
===================================================================
--- lmtp.c (revision 1559)
+++ lmtp.c (revision 1700)
@@ -77,8 +77,9 @@
* - -1 on error
* - 1 on success
*/
-static int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size);
+static int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...) PRINTF_ARGS(4, 5);
/**
* \function lmtp_error
@@ -624,7 +625,9 @@
if (read_whole_message_network(
(FILE *) instream,
&whole_message,
- &whole_message_size) < 0) {
+ &whole_message_size,
+ "Return-Path: %s\r\n",
+ (char *)(list_getstart(&from)->data)) < 0) {
trace(TRACE_ERROR,
"%s,%s: read_whole_message_network() failed",
__FILE__, __func__);
@@ -755,8 +758,9 @@
return 1;
}
-int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size)
+int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...)
{
char *tmpmessage = NULL;
char tmpline[MESSAGE_MAX_LINE_SIZE + 1];
@@ -765,9 +769,17 @@
size_t total_size = 0;
size_t current_pos = 0;
int error = 0;
+ va_list argp;
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
- while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL) {
+
+ /* This adds the Return-Path header and any other
+ * important headers we might need; see RFC 2076. */
+ va_start(argp, prepend_format);
+ line_size = vsnprintf(tmpline, MESSAGE_MAX_LINE_SIZE, prepend_format, argp);
+ va_end(argp);
+
+ do {
line_size = strlen(tmpline);
/* It sometimes happens that we read a line of size 0,
@@ -798,6 +810,7 @@
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
}
+ while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL);
if (ferror(instream)) {
trace(TRACE_ERROR, "%s,%s: error reading instream",

View file

@ -0,0 +1,575 @@
Index: user.c
===================================================================
--- user.c (revision 1711)
+++ user.c (revision 1712)
@@ -202,8 +202,8 @@
memset(&change_flags, 0, sizeof(change_flags));
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-a:d:c:e:l::x:" /* Major modes */
"W::w:P::p:u:g:m:t:s:S:T:" /* Minor options */
"i" "f:qnyvVh" /* Common options */ )) != -1) {
@@ -223,16 +223,16 @@
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- user = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ user = dm_strdup(dm_optarg);
break;
case 'x':
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- alias = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ alias = dm_strdup(dm_optarg);
break;
case 'l':
@@ -241,8 +241,8 @@
if (mode != 0 && mode != 'l')
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- userspec = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ userspec = dm_strdup(dm_optarg);
break;
case 'i':
@@ -253,13 +253,13 @@
/* Minor options */
case 'w':
change_flags.newpasswd = 1;
- passwd = dm_strdup(optarg);
+ passwd = dm_strdup(dm_optarg);
break;
case 'W':
change_flags.newpasswd = 1;
- if (optarg && strlen(optarg)) {
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg)) {
+ passwdfile = dm_strdup(dm_optarg);
change_flags.newpasswdfile = 1;
} else {
change_flags.newpasswdstdin = 1;
@@ -268,20 +268,20 @@
case 'u':
change_flags.newuser = 1;
- newuser = dm_strdup(optarg);
+ newuser = dm_strdup(dm_optarg);
break;
case 'p':
if (!passwdtype)
- passwdtype = dm_strdup(optarg);
+ passwdtype = dm_strdup(dm_optarg);
// else
// Complain about only one type allowed.
break;
case 'P':
change_flags.newpasswdshadow = 1;
- if (optarg && strlen(optarg))
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ passwdfile = dm_strdup(dm_optarg);
else
passwdfile = SHADOWFILE;
passwdtype = "shadow";
@@ -289,42 +289,42 @@
case 'g':
change_flags.newclientid = 1;
- clientid = strtoull(optarg, NULL, 10);
+ clientid = strtoull(dm_optarg, NULL, 10);
break;
case 'm':
change_flags.newmaxmail = 1;
- maxmail = strtomaxmail(optarg);
+ maxmail = strtomaxmail(dm_optarg);
break;
case 's':
// Add this item to the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_add, dm_optarg, len+1);
break;
case 'S':
// Delete this item from the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_del, dm_optarg, len+1);
break;
case 't':
// Add this item to the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_add, dm_optarg, len+1);
break;
case 'T':
// Delete this item from the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_del, dm_optarg, len+1);
break;
/* Common options */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-users: -f requires a filename\n\n");
result = 1;
Index: lmtpd.c
===================================================================
--- lmtpd.c (revision 1711)
+++ lmtpd.c (revision 1712)
@@ -100,8 +100,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -121,8 +121,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -p requires a filename "
@@ -131,8 +131,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -f requires a filename "
Index: dm_getopt.c
===================================================================
--- dm_getopt.c (revision 1711)
+++ dm_getopt.c (revision 1712)
@@ -135,7 +135,7 @@
*/
int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only)
{
char mode, colon_mode = *shortopts;
@@ -261,13 +261,13 @@
}
int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 0);
}
int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 1);
}
Index: maintenance.c
===================================================================
--- maintenance.c (revision 1711)
+++ maintenance.c (revision 1712)
@@ -121,8 +121,8 @@
setvbuf(stdout, 0, _IONBF, 0);
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-acrtl:pudb" /* Main options */
"i" /* Maybe later options */
"f:qnyvVh")) != -1) { /* Common options */
@@ -173,8 +173,8 @@
case 'l':
check_iplog = 1;
do_nothing = 0;
- if (optarg)
- strncpy(timespec, optarg, LEN);
+ if (dm_optarg)
+ strncpy(timespec, dm_optarg, LEN);
else
timespec[0] = 0;
@@ -209,8 +209,8 @@
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-util: -f requires a filename\n\n" );
return 1;
Index: dm_getopt.h
===================================================================
--- dm_getopt.h (revision 1711)
+++ dm_getopt.h (revision 1712)
@@ -26,38 +26,23 @@
*/
#include "config.h"
+#ifndef DM_GETOPT_H
+#define DM_GETOPT_H
-#ifndef USE_DM_GETOPT
-# include <getopt.h>
-#endif
+# ifndef USE_DM_GETOPT
+# include <getopt.h>
+# define dm_getopt getopt
+# define dm_getopt_long getopt_long
+# define dm_getopt_long_only getopt_long_only
+# define _dm_getopt_internal _getopt_internal
+# define dm_opterr opterr
+# define dm_optind optind
+# define dm_optopt optopt
+# define dm_optarg optarg
+# endif
-#ifdef USE_DM_GETOPT
+# ifdef USE_DM_GETOPT
-# ifndef DM_GETOPT_H
- /* Our include guard first. */
-# define DM_GETOPT_H
- /* Try to kill the system getopt.h */
-# define _GETOPT_DECLARED
-# define _GETOPT_H
-# define GETOPT_H
-
-# undef getopt
-# define getopt dm_getopt
-# undef getopt_long
-# define getopt_long dm_getopt_long
-# undef getopt_long_only
-# define getopt_long_only dm_getopt_long_only
-# undef _getopt_internal
-# define _getopt_internal _dm_getopt_internal
-# undef opterr
-# define opterr dm_opterr
-# undef optind
-# define optind dm_optind
-# undef optopt
-# define optopt dm_optopt
-# undef optarg
-# define optarg dm_optarg
-
# ifdef __cplusplus
extern "C" {
# endif
@@ -68,7 +53,7 @@
extern int dm_optind, dm_opterr, dm_optopt;
extern char *dm_optarg;
-struct option {
+struct dm_option {
const char *name;
int has_arg;
int *flag;
@@ -76,28 +61,25 @@
};
/* human-readable values for has_arg */
-# undef no_argument
-# define no_argument 0
-# undef required_argument
-# define required_argument 1
-# undef optional_argument
-# define optional_argument 2
+# define dm_getopt_no_argument 0
+# define dm_getopt_required_argument 1
+# define dm_getopt_optional_argument 2
/* GNU-style long-argument parsers */
extern int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only);
# ifdef __cplusplus
}
# endif
-# endif /* DM_GETOPT_H */
+# endif /* USE_DM_GETOPT */
-#endif /* USE_DM_GETOPT */
+#endif /* DM_GETOPT_H */
Index: timsieved.c
===================================================================
--- timsieved.c (revision 1711)
+++ timsieved.c (revision 1712)
@@ -99,8 +99,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -120,8 +120,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -p requires a filename "
@@ -130,8 +130,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -f requires a filename "
Index: pop3d.c
===================================================================
--- pop3d.c (revision 1711)
+++ pop3d.c (revision 1712)
@@ -103,8 +103,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -124,8 +124,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -p requires a filename "
@@ -134,8 +134,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -f requires a filename "
Index: imapd.c
===================================================================
--- imapd.c (revision 1711)
+++ imapd.c (revision 1712)
@@ -97,8 +97,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -118,8 +118,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -p requires a filename "
@@ -128,8 +128,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -f requires a filename "
Index: sievecmd.c
===================================================================
--- sievecmd.c (revision 1711)
+++ sievecmd.c (revision 1712)
@@ -57,7 +57,7 @@
char *user_name = NULL;
char *name = NULL;
FILE *source = NULL;
- extern char *optarg;
+ extern char *dm_optarg;
openlog(PNAME, LOG_PID, LOG_MAIL);
@@ -70,7 +70,7 @@
configure_debug(TRACE_ERROR, 1, 0);
while (opt != -1 && act != 'h') {
- opt = getopt(argc, argv, "a:d:i:r:u:l");
+ opt = dm_getopt(argc, argv, "a:d:i:r:u:l");
switch (opt) {
case -1:
@@ -84,11 +84,11 @@
act = 'h';
else
act = opt;
- name = optarg;
+ name = dm_optarg;
source = stdin; // FIXME to take files as input, too
break;
case 'u':
- user_name = dm_strdup(optarg);
+ user_name = dm_strdup(dm_optarg);
break;
case 'l':
if (act != 0)
Index: main.c
===================================================================
--- main.c (revision 1711)
+++ main.c (revision 1712)
@@ -189,7 +189,7 @@
* with an immediately preceding option are return with option
* value '1'. We will use this to allow for multiple values to
* follow after each of the supported options. */
- while ((c = getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
+ while ((c = dm_getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
/* Received an n-th value following the last option,
* so recall the last known option to be used in the switch. */
if (c == 1)
@@ -200,13 +200,13 @@
case 't':
trace(TRACE_INFO, "main(): using NORMAL_DELIVERY");
- if (optarg) {
+ if (dm_optarg) {
if (deliver_to_header) {
printf
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_header = optarg;
+ deliver_to_header = dm_optarg;
} else
deliver_to_header = "deliver-to";
@@ -221,7 +221,7 @@
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_mailbox = optarg;
+ deliver_to_mailbox = dm_optarg;
break;
@@ -231,8 +231,8 @@
/* Add argument onto the returnpath list. */
if (list_nodeadd
- (&returnpath, optarg,
- strlen(optarg) + 1) == 0) {
+ (&returnpath, dm_optarg,
+ strlen(dm_optarg) + 1) == 0) {
trace(TRACE_ERROR,
"main(): list_nodeadd reports out of memory"
" while adding to returnpath");
@@ -247,7 +247,7 @@
"main(): using SPECIAL_DELIVERY to usernames");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -267,7 +267,7 @@
"main(): using SPECIAL_DELIVERY to email addresses");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -284,8 +284,8 @@
/* Common command line options. */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-smtp: -f requires a filename\n\n" );

View file

@ -0,0 +1,66 @@
Index: configure.in
===================================================================
--- configure.in (revision 1751)
+++ configure.in (revision 1761)
@@ -42,6 +42,7 @@
DBMAIL_CHECK_SIEVE_LIBS
DBMAIL_CHECK_GC
DBMAIL_CHECK_GETOPT
+DBMAIL_CHECK_SOCKLEN_T
AC_PROG_CC
AC_COMPILE_WARNINGS
Index: acinclude.m4
===================================================================
--- acinclude.m4 (revision 1751)
+++ acinclude.m4 (revision 1761)
@@ -513,3 +513,49 @@
# Prerequisites of lib/getopt*.
AC_DEFUN([CHECK_PREREQ_GETOPT], [:])
+
+#
+# socklen_t
+# from curl
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+AC_DEFUN([DBMAIL_CHECK_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+ ],[
+ $t len;
+ getpeername(0,0,&len);
+ ],[
+ socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$socklen_t_equiv" = x; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_MSG_RESULT($socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+

View file

@ -0,0 +1,126 @@
Index: pool.c
===================================================================
--- pool.c (revision 1600)
+++ pool.c (revision 1758)
@@ -73,8 +73,10 @@
void scoreboard_new(serverConfig_t * conf)
{
int serr;
- if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1)
- trace(TRACE_FATAL, "%s,%s: shmget failed",__FILE__,__func__);
+ if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1) {
+ serr = errno;
+ trace(TRACE_FATAL, "%s,%s: shmget failed [%s]",__FILE__,__func__, strerror(serr));
+ }
scoreboard = shmat(shmid, (void *) 0, 0);
serr=errno;
if (scoreboard == (Scoreboard_t *) (-1)) {
@@ -222,7 +236,7 @@
}
scoreboard_unlck();
trace(TRACE_FATAL,
- "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __FUNCTION__, pid);
+ "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __func__, pid);
return -1;
}
@@ -238,25 +252,25 @@
{
int i;
trace(TRACE_MESSAGE, "%s,%s: register child [%d]",
- __FILE__, __FUNCTION__, getpid());
+ __FILE__, __func__, getpid());
scoreboard_wrlck();
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
if (scoreboard->child[i].pid == -1)
break;
if (scoreboard->child[i].pid == getpid()) {
- trace(TRACE_ERROR,
+ scoreboard_unlck();
+ trace(TRACE_FATAL,
"%s,%s: child already registered.",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
}
if (i == scoreboard->conf->maxChildren) {
+ scoreboard_unlck();
trace(TRACE_WARNING,
"%s,%s: no empty slot found",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
@@ -264,8 +278,8 @@
scoreboard->child[i].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_INFO, "%s,%s: initializing child_state [%d] using slot [%d]",
- __FILE__, __FUNCTION__, getpid(), i);
+ trace(TRACE_MESSAGE, "%s,%s: initializing child_state [%d] using slot [%d]",
+ __FILE__, __func__, getpid(), i);
return 0;
}
@@ -281,7 +295,7 @@
scoreboard->child[key].status = STATE_CONNECTED;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -297,7 +311,7 @@
scoreboard->child[key].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -320,7 +334,7 @@
scoreboard_unlck();
trace(TRACE_MESSAGE,
- "%s,%s: child [%d] unregistered", __FILE__, __FUNCTION__,
+ "%s,%s: child [%d] unregistered", __FILE__, __func__,
getpid());
}
@@ -346,7 +360,7 @@
manage_stop_children();
trace(TRACE_FATAL,
"%s,%s: could not create children. Fatal.",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
}
@@ -360,10 +374,17 @@
if (chpid == -1)
continue;
if (waitpid(chpid, NULL, WNOHANG|WUNTRACED) == chpid) {
+ scoreboard_release(chpid);
trace(TRACE_MESSAGE,"%s,%s: child [%d] exited. Restarting...",
- __FILE__, __FUNCTION__, chpid);
- scoreboard_release(chpid);
- CreateChild(&childinfo);
+ __FILE__, __func__, chpid);
+ if (CreateChild(&childinfo)== -1) {
+ trace(TRACE_ERROR,"%s,%s: createchild failed. Bailout...",
+ __FILE__, __func__);
+ GeneralStopRequested=1;
+ manage_stop_children();
+
+ exit(1);
+ }
}
}
sleep(1);

View file

@ -0,0 +1,41 @@
Index: server.c
===================================================================
--- server.c (revision 1600)
+++ server.c (revision 1758)
@@ -119,9 +119,15 @@
alarm(10);
trace(TRACE_DEBUG, "StartServer(): children created, starting main service loop");
- while (!GeneralStopRequested)
- manage_restart_children();
-
+ while (!GeneralStopRequested) {
+ if (db_connect() != 0) {
+ GeneralStopRequested=1;
+ } else {
+ db_disconnect();
+ manage_restart_children();
+ }
+ }
+
manage_stop_children();
scoreboard_delete();
@@ -131,6 +137,8 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ int saved_errno = errno;
+
if (ParentPID != getpid()) {
trace(TRACE_INFO,
"ParentSigHandler(): i'm no longer father");
@@ -162,6 +170,8 @@
default:
GeneralStopRequested = 1;
}
+
+ errno = saved_errno;
}

View file

@ -0,0 +1,267 @@
Index: serverchild.c
===================================================================
--- serverchild.c (revision 1600)
+++ serverchild.c (revision 1758)
@@ -66,13 +66,13 @@
void client_close(void)
{
if (client.tx) {
- trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__func__);
fflush(client.tx);
fclose(client.tx); /* closes clientSocket as well */
client.tx = NULL;
}
if (client.rx) {
- trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__func__);
shutdown(fileno(client.rx), SHUT_RDWR);
fclose(client.rx);
client.rx = NULL;
@@ -86,7 +86,7 @@
trace(TRACE_DEBUG,
"%s,%s: database connection still open, closing",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
db_disconnect();
auth_disconnect();
connected = 0; /* FIXME a signal between this line and the previous one
@@ -99,18 +99,22 @@
void noop_child_sig_handler(int sig, siginfo_t *info UNUSED, void *data UNUSED)
{
- trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __FUNCTION__, sig);
+ int saved_errno = errno;
+ trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __func__, sig);
+ errno = saved_errno;
}
void active_child_sig_handler(int sig, siginfo_t * info UNUSED, void *data UNUSED)
{
+ int saved_errno = errno;
+
static int triedDisconnect = 0;
#ifdef _USE_STR_SIGNAL
- trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __FUNCTION__,
+ trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __func__,
strsignal(sig));
#else
- trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __FUNCTION__, sig);
+ trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __func__, sig);
#endif
/* perform reinit at SIGHUP otherwise exit, but do nothing on
@@ -118,10 +122,10 @@
switch (sig) {
case SIGCHLD:
trace(TRACE_DEBUG, "%s,%s: SIGCHLD received... ignoring",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
break;
case SIGALRM:
- trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __func__);
client_close();
break;
@@ -132,23 +136,23 @@
if (ChildStopRequested) {
trace(TRACE_DEBUG,
"%s,%s: already caught a stop request. Closing right now",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
/* already caught this signal, exit the hard way now */
client_close();
disconnect_all();
child_unregister();
- trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__func__);
exit(1);
}
- trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__func__);
DelChildSigHandler();
ChildStopRequested = 1;
break;
default:
/* bad shtuff, exit */
trace(TRACE_DEBUG,
- "%s,%s: cannot ignore this. Terminating",__FILE__,__FUNCTION__);
+ "%s,%s: cannot ignore this. Terminating",__FILE__,__func__);
/*
* For some reason i have not yet determined the process starts eating up
@@ -164,10 +168,12 @@
disconnect_all();
}
- trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __func__);
child_unregister();
exit(1);
}
+
+ errno = saved_errno;
}
@@ -239,16 +245,19 @@
if (! pid) {
if (child_register() == -1) {
trace(TRACE_FATAL, "%s,%s: child_register failed",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
ChildStopRequested = 0;
SetChildSigHandler();
- trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
- __FILE__, __FUNCTION__);
- PerformChildTask(info);
+
+ trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
+ __FILE__, __func__);
+
+ if (PerformChildTask(info)== -1)
+ return -1;
child_unregister();
exit(0);
} else {
@@ -269,22 +278,22 @@
struct hostent *clientHost;
if (!info) {
- trace(TRACE_ERROR,
- "PerformChildTask(): NULL info supplied");
+ trace(TRACE_ERROR, "%s,%s: NULL info supplied",
+ __FILE__, __func__);
return -1;
}
if (db_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to database");
+ trace(TRACE_ERROR, "%s,%s: could not connect to database",
+ __FILE__, __func__);
return -1;
}
if (db_check_version() != 0)
return -1;
if (auth_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to authentication");
+ trace(TRACE_ERROR, "%s,%s: could not connect to authentication",
+ __FILE__, __func__);
return -1;
}
@@ -294,12 +303,13 @@
for (i = 0; i < info->maxConnect && !ChildStopRequested; i++) {
if (db_check_connection()) {
- trace(TRACE_ERROR, "%s,%s: database has gone away", __FILE__, __func__);
+ trace(TRACE_ERROR, "%s,%s: database has gone away",
+ __FILE__, __func__);
return -1;
}
- trace(TRACE_INFO,
- "PerformChildTask(): waiting for connection");
+ trace(TRACE_INFO, "%s,%s: waiting for connection",
+ __FILE__, __func__);
child_reg_disconnected();
@@ -312,8 +322,8 @@
if (clientSocket == -1) {
i--; /* don't count this as a connect */
- trace(TRACE_INFO,
- "PerformChildTask(): accept failed");
+ trace(TRACE_INFO, "%s,%s: accept failed",
+ __FILE__, __func__);
continue; /* accept failed, refuse connection & continue */
}
@@ -337,30 +347,29 @@
strncpy(client.clientname,
clientHost->h_name, FIELDSIZE);
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s (%s)]",
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s (%s)]",
+ __FILE__, __func__,
client.ip,
client.clientname[0] ? client.
clientname : "Lookup failed");
} else {
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s]",
- client.ip);
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s]",
+ __FILE__, __func__, client.ip);
}
/* make streams */
if (!(client.rx = fdopen(dup(clientSocket), "r"))) {
/* read-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening read file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening read file stream",
+ __FILE__, __func__);
close(clientSocket);
continue;
}
if (!(client.tx = fdopen(clientSocket, "w"))) {
/* write-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening write file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening write file stream",
+ __FILE__, __func__);
fclose(client.rx);
close(clientSocket);
memset(&client, 0, sizeof(client));
@@ -370,8 +379,8 @@
setvbuf(client.tx, (char *) NULL, _IOLBF, 0);
setvbuf(client.rx, (char *) NULL, _IOLBF, 0);
- trace(TRACE_DEBUG,
- "PerformChildTask(): client info init complete, calling client handler");
+ trace(TRACE_DEBUG, "%s,%s: client info init complete, calling client handler",
+ __FILE__, __func__);
/* streams are ready, perform handling */
info->ClientHandler(&client);
@@ -379,17 +388,19 @@
set_proc_title("%s", "Idle");
#endif
- trace(TRACE_DEBUG,
- "PerformChildTask(): client handling complete, closing streams");
+ trace(TRACE_DEBUG, "%s,%s: client handling complete, closing streams",
+ __FILE__, __func__);
client_close();
- trace(TRACE_INFO, "PerformChildTask(): connection closed");
+ trace(TRACE_INFO, "%s,%s: connection closed",
+ __FILE__, __func__);
}
if (!ChildStopRequested)
- trace(TRACE_ERROR,
- "PerformChildTask(): maximum number of connections reached, stopping now");
+ trace(TRACE_ERROR, "%s,%s: maximum number of connections reached, stopping now",
+ __FILE__, __func__);
else
- trace(TRACE_ERROR, "PerformChildTask(): stop requested");
+ trace(TRACE_ERROR, "%s,%s: stop requested",
+ __FILE__, __func__);
child_reg_disconnected();
disconnect_all();

View file

@ -0,0 +1,13 @@
Index: pool.c
===================================================================
--- pool.c (revision 1763)
+++ pool.c (revision 1787)
@@ -433,7 +433,7 @@
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
chpid = scoreboard->child[i].pid;
- if (chpid != 0)
+ if (chpid > 0)
kill(chpid, SIGKILL);;
scoreboard_release(chpid);
}

View file

@ -0,0 +1,35 @@
Index: server.c
===================================================================
--- server.c (revision 1763)
+++ server.c (revision 1787)
@@ -69,7 +69,7 @@
act.sa_sigaction = ParentSigHandler;
sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
+ act.sa_flags = SA_SIGINFO | SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, 0);
sigaction(SIGINT, &act, 0);
@@ -152,6 +152,7 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ pid_t chpid;
int saved_errno = errno;
if (ParentPID != getpid()) {
@@ -175,7 +176,12 @@
break;
case SIGCHLD:
- break; /* ignore, wait for child in main loop */
+ /* ignore, wait for child in main loop */
+ /* but we need to catch zombie */
+ if ((chpid = waitpid(-1,&sig,WNOHANG)) > 0)
+ scoreboard_release(chpid);
+
+ break;
case SIGHUP:
trace(TRACE_DEBUG,

View file

@ -0,0 +1,20 @@
Index: main.c
===================================================================
--- main.c (revision 1793)
+++ main.c (revision 1796)
@@ -133,6 +133,7 @@
trace(TRACE_ERROR, "%s,%s: error reading message",
__FILE__, __func__);
dm_free(tmpmessage);
+ tmpmessage=NULL;
return -1;
}
@@ -371,6 +372,7 @@
trace(TRACE_ERROR, "%s,%s splitmessage failed",
__FILE__, __func__);
dm_free(whole_message);
+ whole_message=NULL;
exitcode = EX_TEMPFAIL;
goto freeall;
}

View file

@ -0,0 +1,37 @@
Index: header.c
===================================================================
--- header.c (revision 1796)
+++ header.c (revision 1813)
@@ -176,15 +176,17 @@
if (message_content[line_content_size] == '\n') {
tmp_line_size = line_content_size + 1;
tmp_line_rfcsize = tmp_line_size + 1;
- } else {
- if (message_content[line_content_size] == '\r' &&
- message_content[line_content_size + 1] == '\n') {
+ } else if (message_content[line_content_size] == '\r') {
+ if (message_content[line_content_size + 1] == '\n') {
+ /* This is the right behaviour */
tmp_line_size = line_content_size + 2;
tmp_line_rfcsize = tmp_line_size;
} else {
- trace(TRACE_ERROR, "%s,%s: error reading header line",
- __FILE__, __func__);
- return -1;
+ /* This is broken behaviour, but it's better
+ * than not handling it at all.
+ */
+ tmp_line_size = line_content_size + 1;
+ tmp_line_rfcsize = tmp_line_size + 1;
}
}
}
@@ -197,7 +199,6 @@
__FILE__, __func__);
return 0;
}
- else
- return 1;
+ return 1;
}

View file

@ -0,0 +1,80 @@
Index: imaputil.c
===================================================================
--- imaputil.c (revision 1726)
+++ imaputil.c (revision 1793)
@@ -65,7 +65,7 @@
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* returned by date_sql2imap() */
-#define IMAP_STANDARD_DATE "03-Nov-1979 00:00:00 +0000"
+#define IMAP_STANDARD_DATE "Sat, 03-Nov-1979 00:00:00 +0000"
char _imapdate[IMAP_INTERNALDATE_LEN] = IMAP_STANDARD_DATE;
/* returned by date_imap2sql() */
@@ -1776,50 +1776,35 @@
/*
* convert a mySQL date (yyyy-mm-dd hh:mm:ss) to a valid IMAP internal date:
- * 0123456789012345678
- * dd-mon-yyyy hh:mm:ss with mon characters (i.e. 'Apr' for april)
- * 01234567890123456789
+ * [Mon, 30 May 2005 10:01:55 +0100] with mon characters (i.e. 'Apr' for april)
* return value is valid until next function call.
* NOTE: if date is not valid, IMAP_STANDARD_DATE is returned
*/
char *date_sql2imap(const char *sqldate)
{
- char *last_char;
- struct tm tm_localtime, tm_sqldate;
- time_t td;
+ struct tm tm_sql_date;
+ struct tm *tm_imap_date;
+
+ time_t ltime;
+ char *last;
- /* we need to get the localtime to get the current timezone */
- if (time(&td) == -1) {
- trace(TRACE_ERROR, "%s,%s: error getting time()",
- __FILE__, __func__);
- return IMAP_STANDARD_DATE;
- }
- tm_localtime = *localtime(&td);
+ last = strptime(sqldate,"%Y-%m-%d %T", &tm_sql_date);
+ if ( (last == NULL) || (*last != '\0') ) {
+ strcpy(_imapdate, IMAP_STANDARD_DATE);
+ return _imapdate;
+ }
- /* parse sqldate */
- last_char = strptime(sqldate, "%Y-%m-%d %T", &tm_sqldate);
- if (last_char == NULL || *last_char != '\0') {
- trace(TRACE_DEBUG, "%s,%s, error parsing date [%s]",
- __FILE__, __func__, sqldate);
- strcpy(_imapdate, IMAP_STANDARD_DATE);
- return _imapdate;
- }
- /* copy DST information from localtime */
- tm_sqldate.tm_gmtoff = tm_localtime.tm_gmtoff;
- tm_sqldate.tm_isdst = tm_localtime.tm_isdst;
+ /* FIXME: this works fine on linux, but may cause dst offsets in netbsd. */
+ ltime = mktime (&tm_sql_date);
+ tm_imap_date = localtime(&ltime);
- (void) strftime(_imapdate, IMAP_INTERNALDATE_LEN,
- "%d-%b-%Y %T %z", &tm_sqldate);
-
- return _imapdate;
+ strftime(_imapdate, sizeof(_imapdate), "%a, %d %b %Y %H:%M:%S %z", tm_imap_date);
+ return _imapdate;
}
-
/*
* convert TO a mySQL date (yyyy-mm-dd) FROM a valid IMAP internal date:
- * 0123456789
* dd-mon-yyyy with mon characters (i.e. 'Apr' for april)
- * 01234567890
* OR
* d-mon-yyyy
* return value is valid until next function call.

View file

@ -1,7 +1,4 @@
etc/dbmail.conf-dist etc/dbmail.conf-dist
etc/rc.d/dbmail-imapd.sh
etc/rc.d/dbmail-lmtpd.sh
etc/rc.d/dbmail-pop3d.sh
lib/dbmail/libauthdbmail.0 lib/dbmail/libauthdbmail.0
lib/dbmail/libauthdbmail.a lib/dbmail/libauthdbmail.a
lib/dbmail/libauthdbmail.la lib/dbmail/libauthdbmail.la

View file

@ -7,6 +7,7 @@
PORTNAME= dbmail PORTNAME= dbmail
PORTVERSION= 2.0.4 PORTVERSION= 2.0.4
PORTREVISION= 1
CATEGORIES= mail CATEGORIES= mail
MASTER_SITES= http://www.dbmail.org/download/ MASTER_SITES= http://www.dbmail.org/download/
PKGNAMESUFFIX= -${DATABASE} PKGNAMESUFFIX= -${DATABASE}
@ -20,14 +21,10 @@ GNU_CONFIGURE= YES
CONFIGURE_ARGS= --prefix=${PREFIX} CONFIGURE_ARGS= --prefix=${PREFIX}
USE_GMAKE= YES USE_GMAKE= YES
USE_OPENSSL= YES USE_OPENSSL= YES
USE_RC_SUBR= dbmail-pop3d.sh dbmail-lmtpd.sh dbmail-imapd.sh
CFLAGS += -fPIC CFLAGS += -fPIC
SED_SCRIPT+= -e 's|%%RC_SUBR%%|${RC_SUBR}|g' \
-e 's|%%PREFIX%%|${PREFIX}|g' \
-e 's|%%RC_DIR%%|${RC_DIR}|g' \
-e 's|%%RC_SUFX%%|${RC_SUFX}|g'
.if defined(WITH_POSTGRESQL) .if defined(WITH_POSTGRESQL)
CONFIGURE_ARGS+= --with-pgsql CONFIGURE_ARGS+= --with-pgsql
USE_PGSQL= yes USE_PGSQL= yes
@ -68,16 +65,8 @@ post-configure:
@${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \ @${REINPLACE_CMD} -i.orig 's!/etc/dbmail.conf!${PREFIX}/etc/dbmail.conf!g' \
${WRKSRC}/dbmail.h ${WRKSRC}/dbmail.h
post-build:
.for f in imap lmtp pop3
@${SED} ${SED_SCRIPT} ${FILESDIR}/dbmail-${f}d.sh > ${WRKDIR}/dbmail-${f}d.sh
.endfor
post-install: post-install:
@${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist @${INSTALL_DATA} ${WRKSRC}/dbmail.conf ${PREFIX}/etc/dbmail.conf-dist
.for f in imap lmtp pop3
@${INSTALL_SCRIPT} ${WRKDIR}/dbmail-${f}d.sh ${DESTDIR}${PREFIX}/etc/rc.d/dbmail-${f}d.sh
.endfor
@${MKDIR} ${DATADIR}/sql @${MKDIR} ${DATADIR}/sql
@${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql @${INSTALL_DATA} ${WRKSRC}/sql/${DATABASE}/* ${DATADIR}/sql
@cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1 @cd ${WRKSRC}/man && ${INSTALL_MAN} ${MAN1} ${MAN1PREFIX}/man/man1

View file

@ -1,32 +0,0 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: dbmail-pop3d
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf to enable dbmail-pop3d:
#
#dbmail_pop3d_enable="YES"
#
# See dbmail-pop3d(8) for flags
#
. %%RC_SUBR%%
name=dbmail_pop3d
rcvar=`set_rcvar`
command=%%PREFIX%%/sbin/dbmail-pop3d
pidfile=/var/run/dbmail-pop3d.pid
required_files=%%PREFIX%%/etc/dbmail.conf
# read settings, set default values
load_rc_config "$name"
: ${dbmail_pop3d_enable="NO"}
: ${dbmail_pop3d_flags=""}
run_rc_command "$1"

View file

@ -0,0 +1,32 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: dbmail-pop3d
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf to enable dbmail-pop3d:
#
#dbmail_pop3d_enable="YES"
#
# See dbmail-pop3d(8) for flags
#
. %%RC_SUBR%%
name=dbmail_pop3d
rcvar=`set_rcvar`
command=%%PREFIX%%/sbin/dbmail-pop3d
pidfile=/var/run/dbmail-pop3d.pid
required_files=%%PREFIX%%/etc/dbmail.conf
# read settings, set default values
load_rc_config "$name"
: ${dbmail_pop3d_enable="NO"}
: ${dbmail_pop3d_flags=""}
run_rc_command "$1"

View file

@ -0,0 +1,66 @@
Index: lmtp.c
===================================================================
--- lmtp.c (revision 1559)
+++ lmtp.c (revision 1700)
@@ -77,8 +77,9 @@
* - -1 on error
* - 1 on success
*/
-static int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size);
+static int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...) PRINTF_ARGS(4, 5);
/**
* \function lmtp_error
@@ -624,7 +625,9 @@
if (read_whole_message_network(
(FILE *) instream,
&whole_message,
- &whole_message_size) < 0) {
+ &whole_message_size,
+ "Return-Path: %s\r\n",
+ (char *)(list_getstart(&from)->data)) < 0) {
trace(TRACE_ERROR,
"%s,%s: read_whole_message_network() failed",
__FILE__, __func__);
@@ -755,8 +758,9 @@
return 1;
}
-int read_whole_message_network(FILE *instream, char **whole_message,
- u64_t *whole_message_size)
+int read_whole_message_network(FILE *instream,
+ char **whole_message, u64_t *whole_message_size,
+ const char *prepend_format, ...)
{
char *tmpmessage = NULL;
char tmpline[MESSAGE_MAX_LINE_SIZE + 1];
@@ -765,9 +769,17 @@
size_t total_size = 0;
size_t current_pos = 0;
int error = 0;
+ va_list argp;
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
- while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL) {
+
+ /* This adds the Return-Path header and any other
+ * important headers we might need; see RFC 2076. */
+ va_start(argp, prepend_format);
+ line_size = vsnprintf(tmpline, MESSAGE_MAX_LINE_SIZE, prepend_format, argp);
+ va_end(argp);
+
+ do {
line_size = strlen(tmpline);
/* It sometimes happens that we read a line of size 0,
@@ -798,6 +810,7 @@
memset(tmpline, '\0', MESSAGE_MAX_LINE_SIZE + 1);
}
+ while (fgets(tmpline, MESSAGE_MAX_LINE_SIZE, instream) != NULL);
if (ferror(instream)) {
trace(TRACE_ERROR, "%s,%s: error reading instream",

View file

@ -0,0 +1,575 @@
Index: user.c
===================================================================
--- user.c (revision 1711)
+++ user.c (revision 1712)
@@ -202,8 +202,8 @@
memset(&change_flags, 0, sizeof(change_flags));
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-a:d:c:e:l::x:" /* Major modes */
"W::w:P::p:u:g:m:t:s:S:T:" /* Minor options */
"i" "f:qnyvVh" /* Common options */ )) != -1) {
@@ -223,16 +223,16 @@
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- user = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ user = dm_strdup(dm_optarg);
break;
case 'x':
if (mode)
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- alias = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ alias = dm_strdup(dm_optarg);
break;
case 'l':
@@ -241,8 +241,8 @@
if (mode != 0 && mode != 'l')
mode_toomany = 1;
mode = opt;
- if (optarg && strlen(optarg))
- userspec = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ userspec = dm_strdup(dm_optarg);
break;
case 'i':
@@ -253,13 +253,13 @@
/* Minor options */
case 'w':
change_flags.newpasswd = 1;
- passwd = dm_strdup(optarg);
+ passwd = dm_strdup(dm_optarg);
break;
case 'W':
change_flags.newpasswd = 1;
- if (optarg && strlen(optarg)) {
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg)) {
+ passwdfile = dm_strdup(dm_optarg);
change_flags.newpasswdfile = 1;
} else {
change_flags.newpasswdstdin = 1;
@@ -268,20 +268,20 @@
case 'u':
change_flags.newuser = 1;
- newuser = dm_strdup(optarg);
+ newuser = dm_strdup(dm_optarg);
break;
case 'p':
if (!passwdtype)
- passwdtype = dm_strdup(optarg);
+ passwdtype = dm_strdup(dm_optarg);
// else
// Complain about only one type allowed.
break;
case 'P':
change_flags.newpasswdshadow = 1;
- if (optarg && strlen(optarg))
- passwdfile = dm_strdup(optarg);
+ if (dm_optarg && strlen(dm_optarg))
+ passwdfile = dm_strdup(dm_optarg);
else
passwdfile = SHADOWFILE;
passwdtype = "shadow";
@@ -289,42 +289,42 @@
case 'g':
change_flags.newclientid = 1;
- clientid = strtoull(optarg, NULL, 10);
+ clientid = strtoull(dm_optarg, NULL, 10);
break;
case 'm':
change_flags.newmaxmail = 1;
- maxmail = strtomaxmail(optarg);
+ maxmail = strtomaxmail(dm_optarg);
break;
case 's':
// Add this item to the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_add, dm_optarg, len+1);
break;
case 'S':
// Delete this item from the user's aliases.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&alias_del, dm_optarg, len+1);
break;
case 't':
// Add this item to the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_add, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_add, dm_optarg, len+1);
break;
case 'T':
// Delete this item from the alias's forwards.
- if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_del, optarg, len+1);
+ if (dm_optarg && (len = strlen(dm_optarg)))
+ list_nodeadd(&fwds_del, dm_optarg, len+1);
break;
/* Common options */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-users: -f requires a filename\n\n");
result = 1;
Index: lmtpd.c
===================================================================
--- lmtpd.c (revision 1711)
+++ lmtpd.c (revision 1712)
@@ -100,8 +100,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -121,8 +121,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -p requires a filename "
@@ -131,8 +131,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-lmtpd: -f requires a filename "
Index: dm_getopt.c
===================================================================
--- dm_getopt.c (revision 1711)
+++ dm_getopt.c (revision 1712)
@@ -135,7 +135,7 @@
*/
int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only)
{
char mode, colon_mode = *shortopts;
@@ -261,13 +261,13 @@
}
int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 0);
}
int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind)
+ const struct dm_option *longopts, int *longind)
{
return _dm_getopt_internal(argc, argv, shortopts, longopts, longind, 1);
}
Index: maintenance.c
===================================================================
--- maintenance.c (revision 1711)
+++ maintenance.c (revision 1712)
@@ -121,8 +121,8 @@
setvbuf(stdout, 0, _IONBF, 0);
/* get options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv,
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv,
"-acrtl:pudb" /* Main options */
"i" /* Maybe later options */
"f:qnyvVh")) != -1) { /* Common options */
@@ -173,8 +173,8 @@
case 'l':
check_iplog = 1;
do_nothing = 0;
- if (optarg)
- strncpy(timespec, optarg, LEN);
+ if (dm_optarg)
+ strncpy(timespec, dm_optarg, LEN);
else
timespec[0] = 0;
@@ -209,8 +209,8 @@
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
qerrorf("dbmail-util: -f requires a filename\n\n" );
return 1;
Index: dm_getopt.h
===================================================================
--- dm_getopt.h (revision 1711)
+++ dm_getopt.h (revision 1712)
@@ -26,38 +26,23 @@
*/
#include "config.h"
+#ifndef DM_GETOPT_H
+#define DM_GETOPT_H
-#ifndef USE_DM_GETOPT
-# include <getopt.h>
-#endif
+# ifndef USE_DM_GETOPT
+# include <getopt.h>
+# define dm_getopt getopt
+# define dm_getopt_long getopt_long
+# define dm_getopt_long_only getopt_long_only
+# define _dm_getopt_internal _getopt_internal
+# define dm_opterr opterr
+# define dm_optind optind
+# define dm_optopt optopt
+# define dm_optarg optarg
+# endif
-#ifdef USE_DM_GETOPT
+# ifdef USE_DM_GETOPT
-# ifndef DM_GETOPT_H
- /* Our include guard first. */
-# define DM_GETOPT_H
- /* Try to kill the system getopt.h */
-# define _GETOPT_DECLARED
-# define _GETOPT_H
-# define GETOPT_H
-
-# undef getopt
-# define getopt dm_getopt
-# undef getopt_long
-# define getopt_long dm_getopt_long
-# undef getopt_long_only
-# define getopt_long_only dm_getopt_long_only
-# undef _getopt_internal
-# define _getopt_internal _dm_getopt_internal
-# undef opterr
-# define opterr dm_opterr
-# undef optind
-# define optind dm_optind
-# undef optopt
-# define optopt dm_optopt
-# undef optarg
-# define optarg dm_optarg
-
# ifdef __cplusplus
extern "C" {
# endif
@@ -68,7 +53,7 @@
extern int dm_optind, dm_opterr, dm_optopt;
extern char *dm_optarg;
-struct option {
+struct dm_option {
const char *name;
int has_arg;
int *flag;
@@ -76,28 +61,25 @@
};
/* human-readable values for has_arg */
-# undef no_argument
-# define no_argument 0
-# undef required_argument
-# define required_argument 1
-# undef optional_argument
-# define optional_argument 2
+# define dm_getopt_no_argument 0
+# define dm_getopt_required_argument 1
+# define dm_getopt_optional_argument 2
/* GNU-style long-argument parsers */
extern int dm_getopt_long(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int dm_getopt_long_only(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind);
+ const struct dm_option *longopts, int *longind);
extern int _dm_getopt_internal(int argc, char * argv[], const char *shortopts,
- const struct option *longopts, int *longind,
+ const struct dm_option *longopts, int *longind,
int long_only);
# ifdef __cplusplus
}
# endif
-# endif /* DM_GETOPT_H */
+# endif /* USE_DM_GETOPT */
-#endif /* USE_DM_GETOPT */
+#endif /* DM_GETOPT_H */
Index: timsieved.c
===================================================================
--- timsieved.c (revision 1711)
+++ timsieved.c (revision 1712)
@@ -99,8 +99,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -120,8 +120,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -p requires a filename "
@@ -130,8 +130,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-timsieved: -f requires a filename "
Index: pop3d.c
===================================================================
--- pop3d.c (revision 1711)
+++ pop3d.c (revision 1712)
@@ -103,8 +103,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -124,8 +124,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -p requires a filename "
@@ -134,8 +134,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-pop3d: -f requires a filename "
Index: imapd.c
===================================================================
--- imapd.c (revision 1711)
+++ imapd.c (revision 1712)
@@ -97,8 +97,8 @@
openlog(PNAME, LOG_PID, LOG_MAIL);
/* get command-line options */
- opterr = 0; /* suppress error message from getopt() */
- while ((opt = getopt(argc, argv, "vVhqnf:p:")) != -1) {
+ dm_opterr = 0; /* suppress error message from getopt() */
+ while ((opt = dm_getopt(argc, argv, "vVhqnf:p:")) != -1) {
switch (opt) {
case 'v':
/* TODO: Perhaps verbose should log to the console with -n? */
@@ -118,8 +118,8 @@
do_showhelp();
return 0;
case 'p':
- if (optarg && strlen(optarg) > 0)
- pidFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ pidFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -p requires a filename "
@@ -128,8 +128,8 @@
}
break;
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-imapd: -f requires a filename "
Index: sievecmd.c
===================================================================
--- sievecmd.c (revision 1711)
+++ sievecmd.c (revision 1712)
@@ -57,7 +57,7 @@
char *user_name = NULL;
char *name = NULL;
FILE *source = NULL;
- extern char *optarg;
+ extern char *dm_optarg;
openlog(PNAME, LOG_PID, LOG_MAIL);
@@ -70,7 +70,7 @@
configure_debug(TRACE_ERROR, 1, 0);
while (opt != -1 && act != 'h') {
- opt = getopt(argc, argv, "a:d:i:r:u:l");
+ opt = dm_getopt(argc, argv, "a:d:i:r:u:l");
switch (opt) {
case -1:
@@ -84,11 +84,11 @@
act = 'h';
else
act = opt;
- name = optarg;
+ name = dm_optarg;
source = stdin; // FIXME to take files as input, too
break;
case 'u':
- user_name = dm_strdup(optarg);
+ user_name = dm_strdup(dm_optarg);
break;
case 'l':
if (act != 0)
Index: main.c
===================================================================
--- main.c (revision 1711)
+++ main.c (revision 1712)
@@ -189,7 +189,7 @@
* with an immediately preceding option are return with option
* value '1'. We will use this to allow for multiple values to
* follow after each of the supported options. */
- while ((c = getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
+ while ((c = dm_getopt(argc, argv, "-t::m:u:d:r: f:qnyvVh")) != EOF) {
/* Received an n-th value following the last option,
* so recall the last known option to be used in the switch. */
if (c == 1)
@@ -200,13 +200,13 @@
case 't':
trace(TRACE_INFO, "main(): using NORMAL_DELIVERY");
- if (optarg) {
+ if (dm_optarg) {
if (deliver_to_header) {
printf
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_header = optarg;
+ deliver_to_header = dm_optarg;
} else
deliver_to_header = "deliver-to";
@@ -221,7 +221,7 @@
("Only one header field may be specified.\n");
usage_error = 1;
} else
- deliver_to_mailbox = optarg;
+ deliver_to_mailbox = dm_optarg;
break;
@@ -231,8 +231,8 @@
/* Add argument onto the returnpath list. */
if (list_nodeadd
- (&returnpath, optarg,
- strlen(optarg) + 1) == 0) {
+ (&returnpath, dm_optarg,
+ strlen(dm_optarg) + 1) == 0) {
trace(TRACE_ERROR,
"main(): list_nodeadd reports out of memory"
" while adding to returnpath");
@@ -247,7 +247,7 @@
"main(): using SPECIAL_DELIVERY to usernames");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -267,7 +267,7 @@
"main(): using SPECIAL_DELIVERY to email addresses");
dsnuser_init(&dsnuser);
- dsnuser.address = dm_strdup(optarg);
+ dsnuser.address = dm_strdup(dm_optarg);
/* Add argument onto the users list. */
if (list_nodeadd
@@ -284,8 +284,8 @@
/* Common command line options. */
case 'f':
- if (optarg && strlen(optarg) > 0)
- configFile = optarg;
+ if (dm_optarg && strlen(dm_optarg) > 0)
+ configFile = dm_optarg;
else {
fprintf(stderr,
"dbmail-smtp: -f requires a filename\n\n" );

View file

@ -0,0 +1,66 @@
Index: configure.in
===================================================================
--- configure.in (revision 1751)
+++ configure.in (revision 1761)
@@ -42,6 +42,7 @@
DBMAIL_CHECK_SIEVE_LIBS
DBMAIL_CHECK_GC
DBMAIL_CHECK_GETOPT
+DBMAIL_CHECK_SOCKLEN_T
AC_PROG_CC
AC_COMPILE_WARNINGS
Index: acinclude.m4
===================================================================
--- acinclude.m4 (revision 1751)
+++ acinclude.m4 (revision 1761)
@@ -513,3 +513,49 @@
# Prerequisites of lib/getopt*.
AC_DEFUN([CHECK_PREREQ_GETOPT], [:])
+
+#
+# socklen_t
+# from curl
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+AC_DEFUN([DBMAIL_CHECK_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+ ],[
+ $t len;
+ getpeername(0,0,&len);
+ ],[
+ socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$socklen_t_equiv" = x; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_MSG_RESULT($socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+

View file

@ -0,0 +1,126 @@
Index: pool.c
===================================================================
--- pool.c (revision 1600)
+++ pool.c (revision 1758)
@@ -73,8 +73,10 @@
void scoreboard_new(serverConfig_t * conf)
{
int serr;
- if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1)
- trace(TRACE_FATAL, "%s,%s: shmget failed",__FILE__,__func__);
+ if ((shmid = shmget(IPC_PRIVATE, P_SIZE, 0644 | IPC_CREAT)) == -1) {
+ serr = errno;
+ trace(TRACE_FATAL, "%s,%s: shmget failed [%s]",__FILE__,__func__, strerror(serr));
+ }
scoreboard = shmat(shmid, (void *) 0, 0);
serr=errno;
if (scoreboard == (Scoreboard_t *) (-1)) {
@@ -222,7 +236,7 @@
}
scoreboard_unlck();
trace(TRACE_FATAL,
- "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __FUNCTION__, pid);
+ "%s,%s: pid NOT found on scoreboard [%d]", __FILE__, __func__, pid);
return -1;
}
@@ -238,25 +252,25 @@
{
int i;
trace(TRACE_MESSAGE, "%s,%s: register child [%d]",
- __FILE__, __FUNCTION__, getpid());
+ __FILE__, __func__, getpid());
scoreboard_wrlck();
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
if (scoreboard->child[i].pid == -1)
break;
if (scoreboard->child[i].pid == getpid()) {
- trace(TRACE_ERROR,
+ scoreboard_unlck();
+ trace(TRACE_FATAL,
"%s,%s: child already registered.",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
}
if (i == scoreboard->conf->maxChildren) {
+ scoreboard_unlck();
trace(TRACE_WARNING,
"%s,%s: no empty slot found",
- __FILE__, __FUNCTION__);
- scoreboard_unlck();
+ __FILE__, __func__);
return -1;
}
@@ -264,8 +278,8 @@
scoreboard->child[i].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_INFO, "%s,%s: initializing child_state [%d] using slot [%d]",
- __FILE__, __FUNCTION__, getpid(), i);
+ trace(TRACE_MESSAGE, "%s,%s: initializing child_state [%d] using slot [%d]",
+ __FILE__, __func__, getpid(), i);
return 0;
}
@@ -281,7 +295,7 @@
scoreboard->child[key].status = STATE_CONNECTED;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -297,7 +311,7 @@
scoreboard->child[key].status = STATE_IDLE;
scoreboard_unlck();
- trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __FUNCTION__,
+ trace(TRACE_DEBUG, "%s,%s: [%d]", __FILE__, __func__,
getpid());
}
@@ -320,7 +334,7 @@
scoreboard_unlck();
trace(TRACE_MESSAGE,
- "%s,%s: child [%d] unregistered", __FILE__, __FUNCTION__,
+ "%s,%s: child [%d] unregistered", __FILE__, __func__,
getpid());
}
@@ -346,7 +360,7 @@
manage_stop_children();
trace(TRACE_FATAL,
"%s,%s: could not create children. Fatal.",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
}
@@ -360,10 +374,17 @@
if (chpid == -1)
continue;
if (waitpid(chpid, NULL, WNOHANG|WUNTRACED) == chpid) {
+ scoreboard_release(chpid);
trace(TRACE_MESSAGE,"%s,%s: child [%d] exited. Restarting...",
- __FILE__, __FUNCTION__, chpid);
- scoreboard_release(chpid);
- CreateChild(&childinfo);
+ __FILE__, __func__, chpid);
+ if (CreateChild(&childinfo)== -1) {
+ trace(TRACE_ERROR,"%s,%s: createchild failed. Bailout...",
+ __FILE__, __func__);
+ GeneralStopRequested=1;
+ manage_stop_children();
+
+ exit(1);
+ }
}
}
sleep(1);

View file

@ -0,0 +1,41 @@
Index: server.c
===================================================================
--- server.c (revision 1600)
+++ server.c (revision 1758)
@@ -119,9 +119,15 @@
alarm(10);
trace(TRACE_DEBUG, "StartServer(): children created, starting main service loop");
- while (!GeneralStopRequested)
- manage_restart_children();
-
+ while (!GeneralStopRequested) {
+ if (db_connect() != 0) {
+ GeneralStopRequested=1;
+ } else {
+ db_disconnect();
+ manage_restart_children();
+ }
+ }
+
manage_stop_children();
scoreboard_delete();
@@ -131,6 +137,8 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ int saved_errno = errno;
+
if (ParentPID != getpid()) {
trace(TRACE_INFO,
"ParentSigHandler(): i'm no longer father");
@@ -162,6 +170,8 @@
default:
GeneralStopRequested = 1;
}
+
+ errno = saved_errno;
}

View file

@ -0,0 +1,267 @@
Index: serverchild.c
===================================================================
--- serverchild.c (revision 1600)
+++ serverchild.c (revision 1758)
@@ -66,13 +66,13 @@
void client_close(void)
{
if (client.tx) {
- trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing write stream", __FILE__,__func__);
fflush(client.tx);
fclose(client.tx); /* closes clientSocket as well */
client.tx = NULL;
}
if (client.rx) {
- trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG,"%s,%s: closing read stream", __FILE__,__func__);
shutdown(fileno(client.rx), SHUT_RDWR);
fclose(client.rx);
client.rx = NULL;
@@ -86,7 +86,7 @@
trace(TRACE_DEBUG,
"%s,%s: database connection still open, closing",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
db_disconnect();
auth_disconnect();
connected = 0; /* FIXME a signal between this line and the previous one
@@ -99,18 +99,22 @@
void noop_child_sig_handler(int sig, siginfo_t *info UNUSED, void *data UNUSED)
{
- trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __FUNCTION__, sig);
+ int saved_errno = errno;
+ trace(TRACE_DEBUG, "%s,%s: ignoring signal [%d]", __FILE__, __func__, sig);
+ errno = saved_errno;
}
void active_child_sig_handler(int sig, siginfo_t * info UNUSED, void *data UNUSED)
{
+ int saved_errno = errno;
+
static int triedDisconnect = 0;
#ifdef _USE_STR_SIGNAL
- trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __FUNCTION__,
+ trace(TRACE_ERROR, "%s,%s: got signal [%s]", __FILE__, __func__,
strsignal(sig));
#else
- trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __FUNCTION__, sig);
+ trace(TRACE_ERROR, "%s,%s: got signal [%d]", __FILE__, __func__, sig);
#endif
/* perform reinit at SIGHUP otherwise exit, but do nothing on
@@ -118,10 +122,10 @@
switch (sig) {
case SIGCHLD:
trace(TRACE_DEBUG, "%s,%s: SIGCHLD received... ignoring",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
break;
case SIGALRM:
- trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: timeout received", __FILE__, __func__);
client_close();
break;
@@ -132,23 +136,23 @@
if (ChildStopRequested) {
trace(TRACE_DEBUG,
"%s,%s: already caught a stop request. Closing right now",
- __FILE__,__FUNCTION__);
+ __FILE__,__func__);
/* already caught this signal, exit the hard way now */
client_close();
disconnect_all();
child_unregister();
- trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit",__FILE__,__func__);
exit(1);
}
- trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: setting stop request",__FILE__,__func__);
DelChildSigHandler();
ChildStopRequested = 1;
break;
default:
/* bad shtuff, exit */
trace(TRACE_DEBUG,
- "%s,%s: cannot ignore this. Terminating",__FILE__,__FUNCTION__);
+ "%s,%s: cannot ignore this. Terminating",__FILE__,__func__);
/*
* For some reason i have not yet determined the process starts eating up
@@ -164,10 +168,12 @@
disconnect_all();
}
- trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __FUNCTION__);
+ trace(TRACE_DEBUG, "%s,%s: exit", __FILE__, __func__);
child_unregister();
exit(1);
}
+
+ errno = saved_errno;
}
@@ -239,16 +245,19 @@
if (! pid) {
if (child_register() == -1) {
trace(TRACE_FATAL, "%s,%s: child_register failed",
- __FILE__, __FUNCTION__);
+ __FILE__, __func__);
exit(0);
}
ChildStopRequested = 0;
SetChildSigHandler();
- trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
- __FILE__, __FUNCTION__);
- PerformChildTask(info);
+
+ trace(TRACE_INFO, "%s,%s: signal handler placed, going to perform task now",
+ __FILE__, __func__);
+
+ if (PerformChildTask(info)== -1)
+ return -1;
child_unregister();
exit(0);
} else {
@@ -269,22 +278,22 @@
struct hostent *clientHost;
if (!info) {
- trace(TRACE_ERROR,
- "PerformChildTask(): NULL info supplied");
+ trace(TRACE_ERROR, "%s,%s: NULL info supplied",
+ __FILE__, __func__);
return -1;
}
if (db_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to database");
+ trace(TRACE_ERROR, "%s,%s: could not connect to database",
+ __FILE__, __func__);
return -1;
}
if (db_check_version() != 0)
return -1;
if (auth_connect() != 0) {
- trace(TRACE_ERROR,
- "PerformChildTask(): could not connect to authentication");
+ trace(TRACE_ERROR, "%s,%s: could not connect to authentication",
+ __FILE__, __func__);
return -1;
}
@@ -294,12 +303,13 @@
for (i = 0; i < info->maxConnect && !ChildStopRequested; i++) {
if (db_check_connection()) {
- trace(TRACE_ERROR, "%s,%s: database has gone away", __FILE__, __func__);
+ trace(TRACE_ERROR, "%s,%s: database has gone away",
+ __FILE__, __func__);
return -1;
}
- trace(TRACE_INFO,
- "PerformChildTask(): waiting for connection");
+ trace(TRACE_INFO, "%s,%s: waiting for connection",
+ __FILE__, __func__);
child_reg_disconnected();
@@ -312,8 +322,8 @@
if (clientSocket == -1) {
i--; /* don't count this as a connect */
- trace(TRACE_INFO,
- "PerformChildTask(): accept failed");
+ trace(TRACE_INFO, "%s,%s: accept failed",
+ __FILE__, __func__);
continue; /* accept failed, refuse connection & continue */
}
@@ -337,30 +347,29 @@
strncpy(client.clientname,
clientHost->h_name, FIELDSIZE);
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s (%s)]",
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s (%s)]",
+ __FILE__, __func__,
client.ip,
client.clientname[0] ? client.
clientname : "Lookup failed");
} else {
- trace(TRACE_MESSAGE,
- "PerformChildTask(): incoming connection from [%s]",
- client.ip);
+ trace(TRACE_MESSAGE, "%s,%s: incoming connection from [%s]",
+ __FILE__, __func__, client.ip);
}
/* make streams */
if (!(client.rx = fdopen(dup(clientSocket), "r"))) {
/* read-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening read file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening read file stream",
+ __FILE__, __func__);
close(clientSocket);
continue;
}
if (!(client.tx = fdopen(clientSocket, "w"))) {
/* write-FILE opening failure */
- trace(TRACE_ERROR,
- "PerformChildTask(): error opening write file stream");
+ trace(TRACE_ERROR, "%s,%s: error opening write file stream",
+ __FILE__, __func__);
fclose(client.rx);
close(clientSocket);
memset(&client, 0, sizeof(client));
@@ -370,8 +379,8 @@
setvbuf(client.tx, (char *) NULL, _IOLBF, 0);
setvbuf(client.rx, (char *) NULL, _IOLBF, 0);
- trace(TRACE_DEBUG,
- "PerformChildTask(): client info init complete, calling client handler");
+ trace(TRACE_DEBUG, "%s,%s: client info init complete, calling client handler",
+ __FILE__, __func__);
/* streams are ready, perform handling */
info->ClientHandler(&client);
@@ -379,17 +388,19 @@
set_proc_title("%s", "Idle");
#endif
- trace(TRACE_DEBUG,
- "PerformChildTask(): client handling complete, closing streams");
+ trace(TRACE_DEBUG, "%s,%s: client handling complete, closing streams",
+ __FILE__, __func__);
client_close();
- trace(TRACE_INFO, "PerformChildTask(): connection closed");
+ trace(TRACE_INFO, "%s,%s: connection closed",
+ __FILE__, __func__);
}
if (!ChildStopRequested)
- trace(TRACE_ERROR,
- "PerformChildTask(): maximum number of connections reached, stopping now");
+ trace(TRACE_ERROR, "%s,%s: maximum number of connections reached, stopping now",
+ __FILE__, __func__);
else
- trace(TRACE_ERROR, "PerformChildTask(): stop requested");
+ trace(TRACE_ERROR, "%s,%s: stop requested",
+ __FILE__, __func__);
child_reg_disconnected();
disconnect_all();

View file

@ -0,0 +1,13 @@
Index: pool.c
===================================================================
--- pool.c (revision 1763)
+++ pool.c (revision 1787)
@@ -433,7 +433,7 @@
for (i = 0; i < scoreboard->conf->maxChildren; i++) {
chpid = scoreboard->child[i].pid;
- if (chpid != 0)
+ if (chpid > 0)
kill(chpid, SIGKILL);;
scoreboard_release(chpid);
}

View file

@ -0,0 +1,35 @@
Index: server.c
===================================================================
--- server.c (revision 1763)
+++ server.c (revision 1787)
@@ -69,7 +69,7 @@
act.sa_sigaction = ParentSigHandler;
sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
+ act.sa_flags = SA_SIGINFO | SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, 0);
sigaction(SIGINT, &act, 0);
@@ -152,6 +152,7 @@
void ParentSigHandler(int sig, siginfo_t * info, void *data)
{
+ pid_t chpid;
int saved_errno = errno;
if (ParentPID != getpid()) {
@@ -175,7 +176,12 @@
break;
case SIGCHLD:
- break; /* ignore, wait for child in main loop */
+ /* ignore, wait for child in main loop */
+ /* but we need to catch zombie */
+ if ((chpid = waitpid(-1,&sig,WNOHANG)) > 0)
+ scoreboard_release(chpid);
+
+ break;
case SIGHUP:
trace(TRACE_DEBUG,

View file

@ -0,0 +1,20 @@
Index: main.c
===================================================================
--- main.c (revision 1793)
+++ main.c (revision 1796)
@@ -133,6 +133,7 @@
trace(TRACE_ERROR, "%s,%s: error reading message",
__FILE__, __func__);
dm_free(tmpmessage);
+ tmpmessage=NULL;
return -1;
}
@@ -371,6 +372,7 @@
trace(TRACE_ERROR, "%s,%s splitmessage failed",
__FILE__, __func__);
dm_free(whole_message);
+ whole_message=NULL;
exitcode = EX_TEMPFAIL;
goto freeall;
}

View file

@ -0,0 +1,37 @@
Index: header.c
===================================================================
--- header.c (revision 1796)
+++ header.c (revision 1813)
@@ -176,15 +176,17 @@
if (message_content[line_content_size] == '\n') {
tmp_line_size = line_content_size + 1;
tmp_line_rfcsize = tmp_line_size + 1;
- } else {
- if (message_content[line_content_size] == '\r' &&
- message_content[line_content_size + 1] == '\n') {
+ } else if (message_content[line_content_size] == '\r') {
+ if (message_content[line_content_size + 1] == '\n') {
+ /* This is the right behaviour */
tmp_line_size = line_content_size + 2;
tmp_line_rfcsize = tmp_line_size;
} else {
- trace(TRACE_ERROR, "%s,%s: error reading header line",
- __FILE__, __func__);
- return -1;
+ /* This is broken behaviour, but it's better
+ * than not handling it at all.
+ */
+ tmp_line_size = line_content_size + 1;
+ tmp_line_rfcsize = tmp_line_size + 1;
}
}
}
@@ -197,7 +199,6 @@
__FILE__, __func__);
return 0;
}
- else
- return 1;
+ return 1;
}

View file

@ -0,0 +1,80 @@
Index: imaputil.c
===================================================================
--- imaputil.c (revision 1726)
+++ imaputil.c (revision 1793)
@@ -65,7 +65,7 @@
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* returned by date_sql2imap() */
-#define IMAP_STANDARD_DATE "03-Nov-1979 00:00:00 +0000"
+#define IMAP_STANDARD_DATE "Sat, 03-Nov-1979 00:00:00 +0000"
char _imapdate[IMAP_INTERNALDATE_LEN] = IMAP_STANDARD_DATE;
/* returned by date_imap2sql() */
@@ -1776,50 +1776,35 @@
/*
* convert a mySQL date (yyyy-mm-dd hh:mm:ss) to a valid IMAP internal date:
- * 0123456789012345678
- * dd-mon-yyyy hh:mm:ss with mon characters (i.e. 'Apr' for april)
- * 01234567890123456789
+ * [Mon, 30 May 2005 10:01:55 +0100] with mon characters (i.e. 'Apr' for april)
* return value is valid until next function call.
* NOTE: if date is not valid, IMAP_STANDARD_DATE is returned
*/
char *date_sql2imap(const char *sqldate)
{
- char *last_char;
- struct tm tm_localtime, tm_sqldate;
- time_t td;
+ struct tm tm_sql_date;
+ struct tm *tm_imap_date;
+
+ time_t ltime;
+ char *last;
- /* we need to get the localtime to get the current timezone */
- if (time(&td) == -1) {
- trace(TRACE_ERROR, "%s,%s: error getting time()",
- __FILE__, __func__);
- return IMAP_STANDARD_DATE;
- }
- tm_localtime = *localtime(&td);
+ last = strptime(sqldate,"%Y-%m-%d %T", &tm_sql_date);
+ if ( (last == NULL) || (*last != '\0') ) {
+ strcpy(_imapdate, IMAP_STANDARD_DATE);
+ return _imapdate;
+ }
- /* parse sqldate */
- last_char = strptime(sqldate, "%Y-%m-%d %T", &tm_sqldate);
- if (last_char == NULL || *last_char != '\0') {
- trace(TRACE_DEBUG, "%s,%s, error parsing date [%s]",
- __FILE__, __func__, sqldate);
- strcpy(_imapdate, IMAP_STANDARD_DATE);
- return _imapdate;
- }
- /* copy DST information from localtime */
- tm_sqldate.tm_gmtoff = tm_localtime.tm_gmtoff;
- tm_sqldate.tm_isdst = tm_localtime.tm_isdst;
+ /* FIXME: this works fine on linux, but may cause dst offsets in netbsd. */
+ ltime = mktime (&tm_sql_date);
+ tm_imap_date = localtime(&ltime);
- (void) strftime(_imapdate, IMAP_INTERNALDATE_LEN,
- "%d-%b-%Y %T %z", &tm_sqldate);
-
- return _imapdate;
+ strftime(_imapdate, sizeof(_imapdate), "%a, %d %b %Y %H:%M:%S %z", tm_imap_date);
+ return _imapdate;
}
-
/*
* convert TO a mySQL date (yyyy-mm-dd) FROM a valid IMAP internal date:
- * 0123456789
* dd-mon-yyyy with mon characters (i.e. 'Apr' for april)
- * 01234567890
* OR
* d-mon-yyyy
* return value is valid until next function call.

View file

@ -1,7 +1,4 @@
etc/dbmail.conf-dist etc/dbmail.conf-dist
etc/rc.d/dbmail-imapd.sh
etc/rc.d/dbmail-lmtpd.sh
etc/rc.d/dbmail-pop3d.sh
lib/dbmail/libauthdbmail.0 lib/dbmail/libauthdbmail.0
lib/dbmail/libauthdbmail.a lib/dbmail/libauthdbmail.a
lib/dbmail/libauthdbmail.la lib/dbmail/libauthdbmail.la