* to users on the Citadel system.
*/
-#ifdef DLL_EXPORT
-#define IN_LIBCIT
-#endif
-
#include "sysdep.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
-#include "serv_extensions.h"
#include "sysdep_decls.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
-#include "tools.h"
#include "msgbase.h"
#include "internet_addressing.h"
#include "user_ops.h"
char host[256], type[256];
if (fqdn == NULL) return(hostalias_nomatch);
- if (strlen(fqdn) == 0) return(hostalias_nomatch);
+ if (IsEmptyStr(fqdn)) return(hostalias_nomatch);
if (!strcasecmp(fqdn, "localhost")) return(hostalias_localhost);
if (!strcasecmp(fqdn, config.c_fqdn)) return(hostalias_localhost);
if (!strcasecmp(fqdn, config.c_nodename)) return(hostalias_localhost);
&& (!strcasecmp(&fqdn[strlen(fqdn)-strlen(host)], host)))
return(hostalias_directory);
+ if ( (!strcasecmp(type, "masqdomain"))
+ && (!strcasecmp(&fqdn[strlen(fqdn)-strlen(host)], host)))
+ return(hostalias_masq);
+
}
return(hostalias_nomatch);
*/
int fuzzy_match(struct ctdluser *us, char *matchstring) {
int a;
+ long len;
if ( (!strncasecmp(matchstring, "cit", 3))
&& (atol(&matchstring[3]) == us->usernum)) {
return 0;
}
-
- for (a=0; a<strlen(us->fullname); ++a) {
+ len = strlen(matchstring);
+ for (a=0; !IsEmptyStr(&us->fullname[a]); ++a) {
if (!strncasecmp(&us->fullname[a],
- matchstring, strlen(matchstring))) {
+ matchstring, len)) {
return 0;
}
}
strcpy(node, config.c_fqdn);
strcpy(name, "");
+ if (rfc822 == NULL) return;
+
/* extract full name - first, it's From minus <userid> */
strcpy(name, rfc822);
stripout(name, '<', '>');
/* strip anything to the left of a bang */
- while ((strlen(name) > 0) && (haschar(name, '!') > 0))
+ while ((!IsEmptyStr(name)) && (haschar(name, '!') > 0))
strcpy(name, &name[1]);
/* and anything to the right of a @ or % */
/* but if there are a set of quotes, that supersedes everything */
if (haschar(rfc822, 34) == 2) {
strcpy(name, rfc822);
- while ((strlen(name) > 0) && (name[0] != 34)) {
+ while ((!IsEmptyStr(name)) && (name[0] != 34)) {
strcpy(&name[0], &name[1]);
}
strcpy(&name[0], &name[1]);
}
/* strip anything to the left of a bang */
- while ((strlen(user) > 0) && (haschar(user, '!') > 0))
+ while ((!IsEmptyStr(user)) && (haschar(user, '!') > 0))
strcpy(user, &user[1]);
/* and anything to the right of a @ or % */
else {
/* strip anything to the left of a @ */
- while ((strlen(node) > 0) && (haschar(node, '@') > 0))
+ while ((!IsEmptyStr(node)) && (haschar(node, '@') > 0))
strcpy(node, &node[1]);
/* strip anything to the left of a % */
- while ((strlen(node) > 0) && (haschar(node, '%') > 0))
+ while ((!IsEmptyStr(node)) && (haschar(node, '%') > 0))
strcpy(node, &node[1]);
/* reduce multiple system bang paths to node!user */
- while ((strlen(node) > 0) && (haschar(node, '!') > 1))
+ while ((!IsEmptyStr(node)) && (haschar(node, '!') > 1))
strcpy(node, &node[1]);
/* now get rid of the user portion of a node!user string */
* but no name outside the brackets, we now have an empty name. In
* this case, use the user portion of the address as the name.
*/
- if ((strlen(name) == 0) && (strlen(user) > 0)) {
+ if ((IsEmptyStr(name)) && (!IsEmptyStr(user))) {
strcpy(name, user);
}
}
processed = 1;
}
+ else if (!strcasecmp(key, "CC")) {
+ if (msg->cm_fields['Y'] == NULL)
+ msg->cm_fields['Y'] = strdup(value);
+ processed = 1;
+ }
+
else if (!strcasecmp(key, "Message-ID")) {
if (msg->cm_fields['I'] != NULL) {
lprintf(CTDL_WARNING, "duplicate message id\n");
processed = 1;
}
+ else if (!strcasecmp(key, "Return-Path")) {
+ if (msg->cm_fields['P'] == NULL)
+ msg->cm_fields['P'] = strdup(value);
+ processed = 1;
+ }
+
+ else if (!strcasecmp(key, "Envelope-To")) {
+ if (msg->cm_fields['V'] == NULL)
+ msg->cm_fields['V'] = strdup(value);
+ processed = 1;
+ }
+
/* Clean up and move on. */
free(key); /* Don't free 'value', it's actually the same buffer */
return(processed);
snprintf(fieldhdr, sizeof fieldhdr, "%s:", fieldname);
/* Locate the end of the headers, so we don't run past that point */
- end_of_headers = strcasestr(rfc822, "\n\r\n");
+ end_of_headers = bmstrcasestr(rfc822, "\n\r\n");
if (end_of_headers == NULL) {
- end_of_headers = strcasestr(rfc822, "\n\n");
+ end_of_headers = bmstrcasestr(rfc822, "\n\n");
}
if (end_of_headers == NULL) return (NULL);
- field_start = strcasestr(rfc822, fieldhdr);
+ field_start = bmstrcasestr(rfc822, fieldhdr);
if (field_start == NULL) return(NULL);
if (field_start > end_of_headers) return(NULL);
int i;
int keylen = 0;
- for (i=0; i<strlen(addr); ++i) {
+ for (i=0; !IsEmptyStr(&addr[i]); ++i) {
if (!isspace(addr[i])) {
key[keylen++] = tolower(addr[i]);
}
/* Return nonzero if the supplied address is in a domain we keep in
* the directory
*/
-int IsDirectory(char *addr) {
+int IsDirectory(char *addr, int allow_masq_domains) {
char domain[256];
int h;
h = CtdlHostAlias(domain);
+ if ( (h == hostalias_masq) && allow_masq_domains)
+ return(1);
+
if ( (h == hostalias_localhost) || (h == hostalias_directory) ) {
return(1);
}
lprintf(CTDL_DEBUG, "Dir: %s --> %s\n",
internet_addr, citadel_addr);
- if (IsDirectory(internet_addr) == 0) return;
+ if (IsDirectory(internet_addr, 0) == 0) return;
directory_key(key, internet_addr);
if (num_tokens(internet_addr, '@') != 2) return(-1);
/* Only do lookups for domains in the directory */
- if (IsDirectory(internet_addr) == 0) return(-1);
+ if (IsDirectory(internet_addr, 0) == 0) return(-1);
directory_key(key, internet_addr);
cdbrec = cdb_fetch(CDB_DIRECTORY, key, strlen(key) );
return(-1);
}
+
+
+/*
+ * Harvest any email addresses that someone might want to have in their
+ * "collected addresses" book.
+ */
+char *harvest_collected_addresses(struct CtdlMessage *msg) {
+ char *coll = NULL;
+ char addr[256];
+ char user[256], node[256], name[256];
+ int is_harvestable;
+ int i, j, h;
+ int field = 0;
+
+ if (msg == NULL) return(NULL);
+
+ is_harvestable = 1;
+ strcpy(addr, "");
+ if (msg->cm_fields['A'] != NULL) {
+ strcat(addr, msg->cm_fields['A']);
+ }
+ if (msg->cm_fields['F'] != NULL) {
+ strcat(addr, " <");
+ strcat(addr, msg->cm_fields['F']);
+ strcat(addr, ">");
+ if (IsDirectory(msg->cm_fields['F'], 0)) {
+ is_harvestable = 0;
+ }
+ }
+
+ if (is_harvestable) {
+ coll = strdup(addr);
+ }
+ else {
+ coll = strdup("");
+ }
+
+ if (coll == NULL) return(NULL);
+
+ /* Scan both the R (To) and Y (CC) fields */
+ for (i = 0; i < 2; ++i) {
+ if (i == 0) field = 'R' ;
+ if (i == 1) field = 'Y' ;
+
+ if (msg->cm_fields[field] != NULL) {
+ for (j=0; j<num_tokens(msg->cm_fields[field], ','); ++j) {
+ extract_token(addr, msg->cm_fields[field], j, ',', sizeof addr);
+ process_rfc822_addr(addr, user, node, name);
+ h = CtdlHostAlias(node);
+ if ( (h != hostalias_localhost) && (h != hostalias_directory) ) {
+ coll = realloc(coll, strlen(coll) + strlen(addr) + 4);
+ if (coll == NULL) return(NULL);
+ if (!IsEmptyStr(coll)) {
+ strcat(coll, ",");
+ }
+ striplt(addr);
+ strcat(coll, addr);
+ }
+ }
+ }
+ }
+
+ if (IsEmptyStr(coll)) {
+ free(coll);
+ return(NULL);
+ }
+ return(coll);
+}