CtdlSubmitMsg(msg, recp, room);
CtdlFreeMessage(msg);
- if (recp != NULL) free(recp);
+ if (recp != NULL) free_recipients(recp);
}
/*
* Validate recipients, count delivery types and errors, and handle aliasing
* FIXME check for dupes!!!!!
+ *
* Returns 0 if all addresses are ok, ret->num_error = -1 if no addresses
* were specified, or the number of addresses found invalid.
- * caller needs to free the result.
+ *
+ * Caller needs to free the result using free_recipients()
*/
struct recptypes *validate_recipients(char *supplied_recipients) {
struct recptypes *ret;
- char recipients[SIZ];
+ char *recipients = NULL;
char this_recp[256];
char this_recp_cooked[256];
char append[SIZ];
/* Initialize */
ret = (struct recptypes *) malloc(sizeof(struct recptypes));
if (ret == NULL) return(NULL);
- memset(ret, 0, sizeof(struct recptypes));
- ret->num_local = 0;
- ret->num_internet = 0;
- ret->num_ignet = 0;
- ret->num_error = 0;
- ret->num_room = 0;
+ /* Set all strings to null and numeric values to zero */
+ memset(ret, 0, sizeof(struct recptypes));
if (supplied_recipients == NULL) {
- strcpy(recipients, "");
+ recipients = strdup("");
}
else {
- safestrncpy(recipients, supplied_recipients, sizeof recipients);
+ recipients = strdup(supplied_recipients);
}
+ /* Allocate some memory. Yes, this allocates 500% more memory than we will
+ * actually need, but it's healthier for the heap than doing lots of tiny
+ * realloc() calls instead.
+ */
+
+ ret->errormsg = malloc(strlen(recipients) + 1024);
+ ret->recp_local = malloc(strlen(recipients) + 1024);
+ ret->recp_internet = malloc(strlen(recipients) + 1024);
+ ret->recp_ignet = malloc(strlen(recipients) + 1024);
+ ret->recp_room = malloc(strlen(recipients) + 1024);
+ ret->display_recp = malloc(strlen(recipients) + 1024);
+
+ ret->errormsg[0] = 0;
+ ret->recp_local[0] = 0;
+ ret->recp_internet[0] = 0;
+ ret->recp_ignet[0] = 0;
+ ret->recp_room[0] = 0;
+ ret->display_recp[0] = 0;
+
+ ret->recptypes_magic = RECPTYPES_MAGIC;
+
/* Change all valid separator characters to commas */
for (i=0; i<strlen(recipients); ++i) {
if ((recipients[i] == ';') || (recipients[i] == '|')) {
this_recp);
}
else {
- snprintf(append, sizeof append,
- ", %s", this_recp);
+ snprintf(append, sizeof append, ", %s", this_recp);
}
if ( (strlen(ret->errormsg) + strlen(append)) < SIZ) {
strcat(ret->errormsg, append);
strcpy(append, this_recp);
}
else {
- snprintf(append, sizeof append, ", %s",
- this_recp);
+ snprintf(append, sizeof append, ", %s", this_recp);
}
if ( (strlen(ret->display_recp)+strlen(append)) < SIZ) {
strcat(ret->display_recp, append);
lprintf(CTDL_DEBUG, " ignet: %d <%s>\n", ret->num_ignet, ret->recp_ignet);
lprintf(CTDL_DEBUG, " error: %d <%s>\n", ret->num_error, ret->errormsg);
+ free(recipients);
return(ret);
}
+/*
+ * Destructor for struct recptypes
+ */
+void free_recipients(struct recptypes *valid) {
+
+ if (valid == NULL) {
+ return;
+ }
+
+ if (valid->recptypes_magic != RECPTYPES_MAGIC) {
+ lprintf(CTDL_EMERG, "Attempt to call free_recipients() on some other data type!\n");
+ abort();
+ }
+
+ if (valid->errormsg != NULL) free(valid->errormsg);
+ if (valid->recp_local != NULL) free(valid->recp_local);
+ if (valid->recp_internet != NULL) free(valid->recp_internet);
+ if (valid->recp_ignet != NULL) free(valid->recp_ignet);
+ if (valid->recp_room != NULL) free(valid->recp_room);
+ if (valid->display_recp != NULL) free(valid->display_recp);
+ free(valid);
+}
+
+
/*
* message entry - mode 0 (normal)
valid_to = validate_recipients(recp);
if (valid_to->num_error > 0) {
cprintf("%d Invalid recipient (To)\n", ERROR + NO_SUCH_USER);
- free(valid_to);
+ free_recipients(valid_to);
return;
}
valid_cc = validate_recipients(cc);
if (valid_cc->num_error > 0) {
cprintf("%d Invalid recipient (CC)\n", ERROR + NO_SUCH_USER);
- free(valid_to);
- free(valid_cc);
+ free_recipients(valid_to);
+ free_recipients(valid_cc);
return;
}
valid_bcc = validate_recipients(bcc);
if (valid_bcc->num_error > 0) {
cprintf("%d Invalid recipient (BCC)\n", ERROR + NO_SUCH_USER);
- free(valid_to);
- free(valid_cc);
- free(valid_bcc);
+ free_recipients(valid_to);
+ free_recipients(valid_cc);
+ free_recipients(valid_bcc);
return;
}
/* Recipient required, but none were specified */
if ( (valid_to->num_error < 0) && (valid_cc->num_error < 0) && (valid_bcc->num_error < 0) ) {
- free(valid_to);
- free(valid_cc);
- free(valid_bcc);
+ free_recipients(valid_to);
+ free_recipients(valid_cc);
+ free_recipients(valid_bcc);
cprintf("%d At least one recipient is required.\n", ERROR + NO_SUCH_USER);
return;
}
cprintf("%d You do not have permission "
"to send Internet mail.\n",
ERROR + HIGHER_ACCESS_REQUIRED);
- free(valid_to);
- free(valid_cc);
- free(valid_bcc);
+ free_recipients(valid_to);
+ free_recipients(valid_cc);
+ free_recipients(valid_bcc);
return;
}
}
&& (CC->user.axlevel < 4) ) {
cprintf("%d Higher access required for network mail.\n",
ERROR + HIGHER_ACCESS_REQUIRED);
- free(valid_to);
- free(valid_cc);
- free(valid_bcc);
+ free_recipients(valid_to);
+ free_recipients(valid_cc);
+ free_recipients(valid_bcc);
return;
}
&& (!CC->internal_pgm)) {
cprintf("%d You don't have access to Internet mail.\n",
ERROR + HIGHER_ACCESS_REQUIRED);
- free(valid_to);
- free(valid_cc);
- free(valid_bcc);
+ free_recipients(valid_to);
+ free_recipients(valid_cc);
+ free_recipients(valid_bcc);
return;
}
if (post == 0) {
cprintf("%d %s\n", CIT_OK,
((valid_to != NULL) ? valid_to->display_recp : "") );
- free(valid_to);
- free(valid_cc);
- free(valid_bcc);
+ free_recipients(valid_to);
+ free_recipients(valid_cc);
+ free_recipients(valid_bcc);
return;
}
/* We don't need these anymore because we'll do it differently below */
- free(valid_to);
- free(valid_cc);
- free(valid_bcc);
+ free_recipients(valid_to);
+ free_recipients(valid_cc);
+ free_recipients(valid_bcc);
/* Read in the message from the client. */
if (do_confirm) {
CtdlFreeMessage(msg);
}
if (valid != NULL) {
- free(valid);
+ free_recipients(valid);
}
return;
}
if (recp == NULL) return(0);
if (recp->num_local == 0) {
- free(recp);
+ free_recipients(recp);
return(0);
}
for (i=0; i<recp->num_local; ++i) {
extract_token(addr, recp->recp_local, i, '|', addr_buf_len);
if (!strcasecmp(addr, CC->user.fullname)) {
- free(recp);
+ free_recipients(recp);
return(1);
}
}
- free(recp);
+ free_recipients(recp);
return(0);
}
if (rbl_check(message_to_spammer)) {
cprintf("550 %s\r\n", message_to_spammer);
CC->kill_me = 1;
- /* no need to free(valid), it's not allocated yet */
+ /* no need to free_recipients(valid), it's not allocated yet */
return;
}
}
config.c_maxsessions
);
CC->kill_me = 1;
- /* no need to free(valid), it's not allocated yet */
+ /* no need to free_recipients(valid), it's not allocated yet */
return;
}
if (config.c_rbl_at_greeting == 0) { /* Don't RBL again if we already did it */
if (rbl_check(message_to_spammer)) {
cprintf("550 %s\r\n", message_to_spammer);
- /* no need to free(valid), it's not allocated yet */
+ /* no need to free_recipients(valid), it's not allocated yet */
return;
}
}
valid = validate_recipients(recp);
if (valid->num_error != 0) {
cprintf("599 5.1.1 Error: %s\r\n", valid->errormsg);
- free(valid);
+ free_recipients(valid);
return;
}
if (CC->logged_in) {
if (CtdlCheckInternetMailPermission(&CC->user)==0) {
cprintf("551 5.7.1 <%s> - you do not have permission to send Internet mail\r\n", recp);
- free(valid);
+ free_recipients(valid);
return;
}
}
if ( (SMTP->message_originated_locally == 0)
&& (SMTP->is_lmtp == 0) ) {
cprintf("551 5.7.1 <%s> - relaying denied\r\n", recp);
- free(valid);
+ free_recipients(valid);
return;
}
}
strcat(SMTP->recipients, recp);
SMTP->number_of_recipients += 1;
if (valid != NULL)
- free(valid);
+ free_recipients(valid);
}
/* Clean up */
CtdlFreeMessage(msg);
- free(valid);
+ free_recipients(valid);
smtp_data_clear(); /* clear out the buffers now */
}
/* Free up the memory we used */
if (valid != NULL) {
- free(valid);
+ free_recipients(valid);
}
}