-/* $Id: mmpop3d.c,v 1.41 2007/03/13 20:28:22 mmondor Exp $ */
+/* $Id: mmpop3d.c,v 1.41.4.1 2007/03/15 04:41:09 mmondor Exp $ */
/*
* Copyright (C) 2001-2004, Matthew Mondor
MMCOPYRIGHT("@(#) Copyright (c) 2001-2004\n\
\tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmpop3d.c,v 1.41 2007/03/13 20:28:22 mmondor Exp $");
+MMRCSID("$Id: mmpop3d.c,v 1.41.4.1 2007/03/15 04:41:09 mmondor Exp $");
unsigned long *lengths;
/* Query mysql server */
-#if defined(MMMAIL_MYSQL)
- snprintf(line, 1023,
- "SELECT mail_id,mail_size FROM mail WHERE mail_box='%s'",
- clenv->mailbox);
- numfields = 2;
-#elif defined(MMMAIL_FILE)
snprintf(line, 1023,
"SELECT mail_id,mail_size,mail_file FROM mail WHERE "
"mail_box='%s'", clenv->mailbox);
numfields = 3;
-#else
-#error "One of MMMAIL_FILE or MMMAIL_MYSQL must be #defined!"
-#endif
if ((mysqlres = mmsql_query(line, mm_strlen(line))) != NULL) {
ok = FALSE;
break;
}
-#if defined(MMMAIL_FILE)
if (row[2] != NULL) {
mm_memcpy(mnode[i].file, row[2],
lengths[2]);
ok = FALSE;
break;
}
-#endif
} else {
ok = FALSE;
break;
static bool
do_message_load(msgdata *mdata, msgnode *mnode)
{
-#if defined(MMMAIL_MYSQL)
-
- char line[1024];
- MYSQL_RES *mysqlres;
- MYSQL_ROW *row;
- unsigned long *lengths;
-
- snprintf(line, 1024, "SELECT mail_data FROM mail WHERE mail_id=%s",
- mnode->id);
- if ((mysqlres = mmsql_query(line, mm_strlen(line))) != NULL) {
- if ((mysql_num_rows(mysqlres)) == 1) {
- if ((row = (MYSQL_ROW *)mysql_fetch_row(mysqlres)) != NULL) {
- if ((mysql_num_fields(mysqlres)) == 1) {
- lengths = mysql_fetch_lengths(mysqlres);
- if (row[0] != NULL) {
- mdata->internal = mysqlres;
- mdata->body = (char *)row[0];
- mdata->size = lengths[0];
-
- return TRUE;
- } else
- DEBUG_PRINTF("do_message_load", "row[0] == NULL");
- } else
- DEBUG_PRINTF("do_message_load", "mysql_num_fields != 1");
- } else
- DEBUG_PRINTF("do_message_load", "mysql_fetch_row()");
- } else
- DEBUG_PRINTF("do_message_load", "mysql_num_rows != 1");
- mmsql_free_result(mysqlres);
- } else
- DEBUG_PRINTF("do_message_load", "mmsql_query(%s)", line);
-
-#elif defined(MMMAIL_FILE)
-
int fd;
if ((fd = open(mnode->file, O_RDONLY)) != -1) {
DEBUG_PRINTF("do_message_load", "open(%s) == %s", mnode->file,
strerror(errno));
-#endif
-
mdata->internal = NULL;
mdata->body = NULL;
mdata->size = 0;
static void
do_message_free(msgdata *mdata)
{
-#if defined(MMMAIL_MYSQL)
- mmsql_free_result(mdata->internal);
-#elif defined(MMMAIL_FILE)
(void) munmap(mdata->internal, mdata->size);
-#endif
mdata->internal = NULL;
mdata->body = NULL;
ok = FALSE;
break;
} else {
-#if defined(MMMAIL_FILE)
/* Also unlink associated file */
if (unlink(mnode[i].file) == -1)
mmsyslog(0, LOGLEVEL, "unlink(%s) == %s",
mnode[i].file, strerror(errno));
-#endif
messages++;
size += mnode[i].size;
}
-/* $Id: mmsmtpd.c,v 1.75 2007/03/13 20:28:22 mmondor Exp $ */
+/* $Id: mmsmtpd.c,v 1.75.4.1 2007/03/15 04:41:12 mmondor Exp $ */
/*
* Copyright (C) 2001-2004, Matthew Mondor
MMCOPYRIGHT("@(#) Copyright (c) 2001-2004\n\
\tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmsmtpd.c,v 1.75 2007/03/13 20:28:22 mmondor Exp $");
+MMRCSID("$Id: mmsmtpd.c,v 1.75.4.1 2007/03/15 04:41:12 mmondor Exp $");
printf("\nMAIL_DIR must be an absolute pathname to a directory\n\n");
exit(-1);
} else {
-#if defined(MMMAIL_FILE)
struct stat st;
if (stat(CONF.MAIL_DIR, &st) == -1) {
printf("\nMAIL_DIR not a directory: '%s'\n\n", CONF.MAIL_DIR);
exit(-1);
}
-#endif /* defined(MMMAIL_FILE) */
}
/* Finally init everything */
}
if (!valid)
reason = RCPT_UNKNOWN;
-#if defined(MMMAIL_FILE)
if (CONF.RELAYING && !valid) {
/* Address is not local. If relaying is allowed, we must be
* able to verify that the address indeed belongs to a
relay = TRUE;
}
}
-#endif /* defined(MMMAIL_FILE) */
if (!valid) {
switch (reason) {
case RCPT_RELAY:
}
if (ok) {
-
/* XXX The following could easily simply be provided by separately
* compiled mmsmtpd modules, designed to support multple storage
* methods, as do_data_store() or such. But, we only support MySQL
* and file storage for now... Which suffices for me.
*/
-#if defined(MMMAIL_MYSQL)
-
- ok = do_data_mysql(clenv, fdbrb);
-
-#elif defined(MMMAIL_FILE)
-
ok = do_data_file(clenv, fdbrb);
-
-#else
-#error "One of MMMAIL_MYSQL or MMMAIL_FILE must be #defined!"
-#endif
-
}
fdbfreebuf(&fdbrb); /* Internally only frees if not already freed */
}
-#if defined(MMMAIL_MYSQL)
-
-static bool
-do_data_mysql(clientenv *clenv, struct fdbrb_buffer *fdbrb)
-{
- char line[1024], line2[2048], smtptime[32], *tmp, *query;
- rcptnode *rnode;
- bool ok = TRUE;
-
- /* Allocate query buffer for mysql_real_query(), should be large
- * enough to handle the worst of cases where each character would
- * be escaped to two chars, and must also hold the rest of the
- * query string. We first process the message data through
- * mysql_escape_string(), leaving enough room for the query and our
- * "Received:" line, which will be copied before the message buffer
- * for each RCPT. The message buffer will start at offset 2048
- * to make sure that there is enough room to insert the
- * RCPT-specific data (query+received).
- */
- if ((query = malloc((fdbrb->current * 2) + 2053)) != NULL) {
- size_t len, qlen, tlen, clen;
-
- /* Prepare message buffer for mysql query */
- clen = fdbrb->current; /* Used after freeing buffer as well */
- tmp = &query[2048];
- tmp += mysql_escape_string(tmp, fdbrb->array, clen);
- *tmp++ = '\'';
- *tmp++ = ')';
- *tmp++ = '\0';
- qlen = tmp - &query[2048];
- rfc_time(smtptime);
-
- /* For each RCPT, create query and execute it */
- DLIST_FOREACH(&clenv->rcpt, rnode) {
- /* Use the common message buffer, but append the query and
- * message line before it (in it's 2048 bytes free area)
- */
- do_data_received(line, 1024, clenv, rnode, smtptime);
- tlen = mm_strlen(line) + clen;
- snprintf(line2, 255,
- "INSERT INTO mail (mail_box,mail_created,mail_size,"
- "mail_data) VALUES('%s',NOW(),%ld,'",
- rnode->address, (long)tlen);
- tmp = line2 + mm_strlen(line2);
- tmp += mysql_escape_string(tmp, line, mm_strlen(line));
- len = tmp - line2;
- tmp = &query[2048 - len];
- mm_memcpy(tmp, line2, len);
-
- /* Query buffer prepared, execute query. This glock is
- * required for safety between the two queries which have
- * to be performed within a single transaction. See
- * mmlib/mmsql.c for implementation details; Currently uses
- * MySQL GET_LOCK() and RELEASE_LOCK(), which contrary to
- * table locking will permit to only cause the current thread
- * to sleep rather than the whole process in this case.
- */
- mmsql_glock("mmmail_boxmail");
- if (!mmsql_command(tmp, qlen + len)) {
- mmsyslog(0, LOGLEVEL, "mmsql_command(%s)", tmp);
- ok = FALSE;
- break;
- } else {
- u_int64_t id;
-
- /* Obtain auto-increment value usd in last command */
- id = mmsql_last_auto_id();
-
- if (!(ok = do_data_update(rnode, tlen))) {
- /* Delete previous successful entry, since updating quota
- * information did not succeed, and it must always be
- * accurate according to actual mail data.
- */
- snprintf(line, 1023,
- "DELETE FROM mail WHERE mail_id=%llu", id);
- (void) mmsql_command(line, mm_strlen(line));
- }
- }
- mmsql_gunlock("mmmail_boxmail");
-
- if (!ok)
- break;
-
- /* Everything successful, record statistics */
- do_data_stats(clenv, rnode, tlen);
- }
-
- free(query);
- } else {
- DEBUG_PRINTF("do_data",
- "malloc(%d)", (int)(fdbrb->current * 2) + 2053);
- REGISTER_ERROR(clenv);
- ok = FALSE;
- }
-
- return ok;
-}
-
-#elif defined(MMMAIL_FILE)
-
/* Returns TRUE if the client address/hostname is allowed to relay messages
* for non-local addresses, or FALSE otherwise, with reason set to either
* RCPT_UNKNOWN (destination address on a locally handled domain but
return fd;
}
-#else
-#error "One of MMMAIL_MYSQL or MMMAIL_FILE must be #defined!"
-#endif
-
/* This is the main function that is called to serve a client.
* It comports the main loop and state switcher.
* ones. We also don't need to do anything if we are not
* using files for message storage.
*/
-#if defined(MMMAIL_FILE)
if (valid_address(NULL, deladdr, 64, addr, HOST_NORES)) {
MYSQL_RES *mysqlres2;
(void) mmsql_free_result(mysqlres2);
}
}
-#endif /* defined(MMMAIL_FILE) */
/* Delete db entry unconditionally */
(void) snprintf(query, 1023,
"DELETE FROM boxdelete WHERE "