dammit, learn to spell
[citadel.git] / citadel / server / internet_addressing.c
index 9cfbe3b8ad1f32077870904c793ef239fcb4ac7c..f9bd07309c38e8b1e171d08f6fcbda27e3a4839a 100644 (file)
@@ -1,7 +1,7 @@
 // This file contains functions which handle the mapping of Internet addresses
 // to users on the Citadel system.
 //
-// Copyright (c) 1987-2022 by the citadel.org team
+// Copyright (c) 1987-2024 by the citadel.org team
 //
 // This program is open source software.  Use, duplication, or disclosure
 // is subject to the terms of the GNU General Public License, version 3.
@@ -36,7 +36,6 @@
 #include "ctdl_module.h"
 
 
-
 char *inetcfg = NULL;
 
 // Return nonzero if the supplied name is an alias for this host.
@@ -429,7 +428,8 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
                        }
 
                        // This handles the most common case, which is mail to a user's inbox.
-                       else if (CtdlGetUser(&tempUS, this_recp) == 0) {
+                       // (the next line depends on left-to-right evaluation)
+                       else if ((CtdlGetUser(&tempUS, this_recp) == 0) && (tempUS.usernum > 0)) {
                                ++ret->num_local;
                                strcpy(this_recp, tempUS.fullname);
                                if (!IsEmptyStr(ret->recp_local)) {
@@ -527,7 +527,7 @@ void free_recipients(struct recptypes *valid) {
 
        if (valid->recptypes_magic != RECPTYPES_MAGIC) {
                syslog(LOG_ERR, "internet_addressing: attempt to call free_recipients() on some other data type!");
-               abort();
+               exit(CTDLEXIT_BAD_MAGIC);
        }
 
        if (valid->errormsg != NULL)            free(valid->errormsg);
@@ -833,7 +833,7 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) {
                if (*pos == ':') colonpos = pos;
        }
 
-       if (colonpos == NULL) return(0);        /* no colon? not a valid header line */
+       if (colonpos == NULL) return(0);        // no colon? not a valid header line
 
        len = end - beg;
        key = malloc(len + 2);
@@ -865,35 +865,35 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) {
                syslog(LOG_DEBUG, "internet_addressing: converted to <%s@%s> (%s)", user, node, name);
                snprintf(addr, sizeof(addr), "%s@%s", user, node);
                if (CM_IsEmpty(msg, eAuthor) && !IsEmptyStr(name)) {
-                       CM_SetField(msg, eAuthor, name, -1);
+                       CM_SetField(msg, eAuthor, name);
                }
                if (CM_IsEmpty(msg, erFc822Addr) && !IsEmptyStr(addr)) {
-                       CM_SetField(msg, erFc822Addr, addr, -1);
+                       CM_SetField(msg, erFc822Addr, addr);
                }
                processed = 1;
        }
 
        else if (!strcasecmp(key, "Subject")) {
                if (CM_IsEmpty(msg, eMsgSubject))
-                       CM_SetField(msg, eMsgSubject, value, valuelen);
+                       CM_SetField(msg, eMsgSubject, value);
                processed = 1;
        }
 
        else if (!strcasecmp(key, "List-ID")) {
                if (CM_IsEmpty(msg, eListID))
-                       CM_SetField(msg, eListID, value, valuelen);
+                       CM_SetField(msg, eListID, value);
                processed = 1;
        }
 
        else if (!strcasecmp(key, "To")) {
                if (CM_IsEmpty(msg, eRecipient))
-                       CM_SetField(msg, eRecipient, value, valuelen);
+                       CM_SetField(msg, eRecipient, value);
                processed = 1;
        }
 
        else if (!strcasecmp(key, "CC")) {
                if (CM_IsEmpty(msg, eCarbonCopY))
-                       CM_SetField(msg, eCarbonCopY, value, valuelen);
+                       CM_SetField(msg, eCarbonCopY, value);
                processed = 1;
        }
 
@@ -919,7 +919,7 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) {
                                        break;
                                }
 
-                       CM_SetField(msg, emessageId, pValue, pValueLen);
+                       CM_SetField(msg, emessageId, pValue);
                }
 
                processed = 1;
@@ -927,29 +927,29 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) {
 
        else if (!strcasecmp(key, "Return-Path")) {
                if (CM_IsEmpty(msg, eMessagePath))
-                       CM_SetField(msg, eMessagePath, value, valuelen);
+                       CM_SetField(msg, eMessagePath, value);
                processed = 1;
        }
 
        else if (!strcasecmp(key, "Envelope-To")) {
                if (CM_IsEmpty(msg, eenVelopeTo))
-                       CM_SetField(msg, eenVelopeTo, value, valuelen);
+                       CM_SetField(msg, eenVelopeTo, value);
                processed = 1;
        }
 
        else if (!strcasecmp(key, "References")) {
-               CM_SetField(msg, eWeferences, value, valuelen);
+               CM_SetField(msg, eWeferences, value);
                processed = 1;
        }
 
        else if (!strcasecmp(key, "Reply-To")) {
-               CM_SetField(msg, eReplyTo, value, valuelen);
+               CM_SetField(msg, eReplyTo, value);
                processed = 1;
        }
 
        else if (!strcasecmp(key, "In-reply-to")) {
                if (CM_IsEmpty(msg, eWeferences)) // References: supersedes In-reply-to:
-                       CM_SetField(msg, eWeferences, value, valuelen);
+                       CM_SetField(msg, eWeferences, value);
                processed = 1;
        }
 
@@ -1006,8 +1006,7 @@ struct CtdlMessage *convert_internet_message(char *rfc822) {
 }
 
 
-struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822)
-{
+struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822) {
        struct CtdlMessage *msg;
        const char *pos, *beg, *end, *totalend;
        int done, alldone = 0;
@@ -1029,31 +1028,22 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822)
 
        while (!alldone) {
 
-               /* Locate beginning and end of field, keeping in mind that
-                * some fields might be multiline
-                */
+               // Locate beginning and end of field, keeping in mind that
+               // some fields might be multiline
                end = beg = pos;
 
-               while ((end < totalend) && 
-                      (end == beg) && 
-                      (done == 0) ) 
-               {
+               while ((end < totalend) && (end == beg) && (done == 0) ) {
 
-                       if ( (*pos=='\n') && ((*(pos+1))!=0x20) && ((*(pos+1))!=0x09) )
-                       {
+                       if ( (*pos=='\n') && ((*(pos+1))!=0x20) && ((*(pos+1))!=0x09) ) {
                                end = pos;
                        }
 
-                       /* done with headers? */
-                       if ((*pos=='\n') &&
-                           ( (*(pos+1)=='\n') ||
-                             (*(pos+1)=='\r')) ) 
-                       {
+                       // done with headers?
+                       if ((*pos=='\n') && ( (*(pos+1)=='\n') || (*(pos+1)=='\r')) ) {
                                alldone = 1;
                        }
 
-                       if (pos >= (totalend - 1) )
-                       {
+                       if (pos >= (totalend - 1) ) {
                                end = pos;
                                done = 1;
                        }
@@ -1062,16 +1052,16 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822)
 
                }
 
-               /* At this point we have a field.  Are we interested in it? */
+               // At this point we have a field.  Are we interested in it?
                converted = convert_field(msg, beg, end);
 
-               /* Strip the field out of the RFC822 header if we used it */
+               // Strip the field out of the RFC822 header if we used it
                if (!converted) {
                        StrBufAppendBufPlain(OtherHeaders, beg, end - beg, 0);
                        StrBufAppendBufPlain(OtherHeaders, HKEY("\n"), 0);
                }
 
-               /* If we've hit the end of the message, bail out */
+               // If we've hit the end of the message, bail out
                if (pos >= totalend)
                        alldone = 1;
        }
@@ -1079,18 +1069,17 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822)
        if (pos < totalend)
                StrBufAppendBufPlain(OtherHeaders, pos, totalend - pos, 0);
        FreeStrBuf(rfc822);
-       CM_SetAsFieldSB(msg, eMesageText, &OtherHeaders);
+       CM_SetAsFieldSB(msg, eMessageText, &OtherHeaders);
 
-       /* Follow-up sanity checks... */
+       // Follow-up sanity checks...
 
-       /* If there's no timestamp on this message, set it to now. */
+       // If there's no timestamp on this message, set it to now.
        if (CM_IsEmpty(msg, eTimestamp)) {
                CM_SetFieldLONG(msg, eTimestamp, time(NULL));
        }
 
-       /* If a W (references, or rather, Wefewences) field is present, we
-        * have to convert it from RFC822 format to Citadel format.
-        */
+       // If a W (references, or rather, Wefewences) field is present, we
+       // have to convert it from RFC822 format to Citadel format.
        if (!CM_IsEmpty(msg, eWeferences)) {
                /// todo: API!
                convert_references_to_wefewences(msg->cm_fields[eWeferences]);
@@ -1100,13 +1089,11 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822)
 }
 
 
-/*
- * Look for a particular header field in an RFC822 message text.  If the
- * requested field is found, it is unfolded (if necessary) and returned to
- * the caller.  The field name is stripped out, leaving only its contents.
- * The caller is responsible for freeing the returned buffer.  If the requested
- * field is not present, or anything else goes wrong, it returns NULL.
- */
+// Look for a particular header field in an RFC822 message text.  If the
+// requested field is found, it is unfolded (if necessary) and returned to
+// the caller.  The field name is stripped out, leaving only its contents.
+// The caller is responsible for freeing the returned buffer.  If the requested
+// field is not present, or anything else goes wrong, it returns NULL.
 char *rfc822_fetch_field(const char *rfc822, const char *fieldname) {
        char *fieldbuf = NULL;
        const char *end_of_headers;
@@ -1115,13 +1102,13 @@ char *rfc822_fetch_field(const char *rfc822, const char *fieldname) {
        char *cont;
        char fieldhdr[SIZ];
 
-       /* Should never happen, but sometimes we get stupid */
+       // Should never happen, but sometimes we get stupid
        if (rfc822 == NULL) return(NULL);
        if (fieldname == NULL) return(NULL);
 
        snprintf(fieldhdr, sizeof fieldhdr, "%s:", fieldname);
 
-       /* Locate the end of the headers, so we don't run past that point */
+       // Locate the end of the headers, so we don't run past that point
        end_of_headers = cbmstrcasestr(rfc822, "\n\r\n");
        if (end_of_headers == NULL) {
                end_of_headers = cbmstrcasestr(rfc822, "\n\n");
@@ -1151,14 +1138,12 @@ char *rfc822_fetch_field(const char *rfc822, const char *fieldname) {
 }
 
 
-/*****************************************************************************
- *                      DIRECTORY MANAGEMENT FUNCTIONS                       *
- *****************************************************************************/
+//     *****************************************************************************
+//                          DIRECTORY MANAGEMENT FUNCTIONS                       
+//     *****************************************************************************
 
-/*
- * Generate the index key for an Internet e-mail address to be looked up
- * in the database.
- */
+// Generate the index key for an Internet e-mail address to be looked up
+// in the database.
 void directory_key(char *key, char *addr) {
        int i;
        int keylen = 0;
@@ -1169,14 +1154,11 @@ void directory_key(char *key, char *addr) {
                }
        }
        key[keylen++] = 0;
-
        syslog(LOG_DEBUG, "internet_addressing: directory key is <%s>", key);
 }
 
 
-/*
- * Return nonzero if the supplied address is in one of "our" domains
- */
+// Return nonzero if the supplied address is in one of "our" domains
 int IsDirectory(char *addr, int allow_masq_domains) {
        char domain[256];
        int h;
@@ -1198,9 +1180,7 @@ int IsDirectory(char *addr, int allow_masq_domains) {
 }
 
 
-/*
- * Add an Internet e-mail address to the directory for a user
- */
+// Add an Internet e-mail address to the directory for a user
 int CtdlDirectoryAddUser(char *internet_addr, char *citadel_addr) {
        char key[SIZ];
 
@@ -1214,12 +1194,10 @@ int CtdlDirectoryAddUser(char *internet_addr, char *citadel_addr) {
 }
 
 
-/*
- * Delete an Internet e-mail address from the directory.
- *
- * (NOTE: we don't actually use or need the citadel_addr variable; it's merely
- * here because the callback API expects to be able to send it.)
- */
+// Delete an Internet e-mail address from the directory.
+//
+// (NOTE: we don't actually use or need the citadel_addr variable; it's merely
+// here because the callback API expects to be able to send it.)
 int CtdlDirectoryDelUser(char *internet_addr, char *citadel_addr) {
        char key[SIZ];
        
@@ -1229,33 +1207,30 @@ int CtdlDirectoryDelUser(char *internet_addr, char *citadel_addr) {
 }
 
 
-/*
- * Look up an Internet e-mail address in the directory.
- * On success: returns 0, and Citadel address stored in 'target'
- * On failure: returns nonzero
- */
+// Look up an Internet e-mail address in the directory.
+// On success: returns 0, and Citadel address stored in 'target'
+// On failure: returns nonzero
 int CtdlDirectoryLookup(char *target, char *internet_addr, size_t targbuflen) {
-       struct cdbdata *cdbrec;
+       struct cdbdata cdbrec;
        char key[SIZ];
 
-       /* Dump it in there unchanged, just for kicks */
+       // Dump it in there unchanged, just for kicks
        if (target != NULL) {
                safestrncpy(target, internet_addr, targbuflen);
        }
 
-       /* Only do lookups for addresses with hostnames in them */
+       // Only do lookups for addresses with hostnames in them
        if (num_tokens(internet_addr, '@') != 2) return(-1);
 
-       /* Only do lookups for domains in the directory */
+       // Only do lookups for domains in the directory
        if (IsDirectory(internet_addr, 0) == 0) return(-1);
 
        directory_key(key, internet_addr);
-       cdbrec = cdb_fetch(CDB_DIRECTORY, key, strlen(key) );
-       if (cdbrec != NULL) {
+       cdbrec = cdb_fetch(CDB_DIRECTORY, key, strlen(key));
+       if (cdbrec.ptr != NULL) {
                if (target != NULL) {
-                       safestrncpy(target, cdbrec->ptr, targbuflen);
+                       safestrncpy(target, cdbrec.ptr, targbuflen);
                }
-               cdb_free(cdbrec);
                return(0);
        }
 
@@ -1263,10 +1238,8 @@ int CtdlDirectoryLookup(char *target, char *internet_addr, size_t targbuflen) {
 }
 
 
-/*
- * Harvest any email addresses that someone might want to have in their
- * "collected addresses" book.
- */
+// 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];
@@ -1300,7 +1273,7 @@ char *harvest_collected_addresses(struct CtdlMessage *msg) {
 
        if (coll == NULL) return(NULL);
 
-       /* Scan both the R (To) and Y (CC) fields */
+       // Scan both the R (To) and Y (CC) fields
        for (i = 0; i < 2; ++i) {
                if (i == 0) field = eRecipient;
                if (i == 1) field = eCarbonCopY;
@@ -1334,9 +1307,7 @@ char *harvest_collected_addresses(struct CtdlMessage *msg) {
 }
 
 
-/*
- * Helper function for CtdlRebuildDirectoryIndex()
- */
+// Helper function for CtdlRebuildDirectoryIndex()
 void CtdlRebuildDirectoryIndex_backend(char *username, void *data) {
 
        int j = 0;
@@ -1356,9 +1327,7 @@ void CtdlRebuildDirectoryIndex_backend(char *username, void *data) {
 }
 
 
-/*
- * Initialize the directory database (erasing anything already there)
- */
+// Initialize the directory database (erasing anything already there)
 void CtdlRebuildDirectoryIndex(void) {
        syslog(LOG_INFO, "internet_addressing: rebuilding email address directory index");
        cdb_trunc(CDB_DIRECTORY);
@@ -1396,9 +1365,7 @@ void CtdlSetEmailAddressesForUser(char *requested_user, char *new_emailaddrs) {
 }
 
 
-/*
- * Auto-generate an Internet email address for a user account
- */
+// Auto-generate an Internet email address for a user account
 void AutoGenerateEmailAddressForUser(struct ctdluser *user) {
        char synthetic_email_addr[1024];
        int i, j;