]> code.citadel.org Git - citadel.git/blobdiff - citadel/internet_addressing.c
While hunting for an internet address bug, cleaning up more style.
[citadel.git] / citadel / internet_addressing.c
index 4a73bc016e81df6b4c76c600e5f10500028e79d1..e67a9dc12c7a482f5e07a5a74d7c3f79a9da2e24 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-2021 by the citadel.org team
+// Copyright (c) 1987-2022 by the citadel.org team
 //
 // This program is open source software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 3.
@@ -325,8 +325,7 @@ int CtdlIsMe(char *addr, int addr_buf_len) {
 
 // If the last item in a list of recipients was truncated to a partial address,
 // remove it completely in order to avoid choking library functions.
-void sanitize_truncated_recipient(char *str)
-{
+void sanitize_truncated_recipient(char *str) {
        if (!str) return;
        if (num_tokens(str, ',') < 2) return;
 
@@ -470,7 +469,8 @@ Array *split_recps(char *addresses, Array *append_to) {
        } while (r > l);
 
        // Transform all qualifying delimiters to commas
-       for (char *t=a; t[0]; ++t) {
+       char *t;
+       for (t=a; t[0]; ++t) {
                if ((t[0]==';') || (t[0]=='|')) {
                        t[0]=',';
                }
@@ -486,7 +486,8 @@ Array *split_recps(char *addresses, Array *append_to) {
        }
 
        int num_addresses = num_tokens(a, ',');
-       for (int i=0; i<num_addresses; ++i) {
+       int i;
+       for (i=0; i<num_addresses; ++i) {
                char this_address[256];
                extract_token(this_address, a, i, ',', sizeof this_address);
                striplt(this_address);                          // strip leading and trailing whitespace
@@ -554,11 +555,13 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
 
        char *aliases = CtdlGetSysConfig(GLOBAL_ALIASES);                               // First hit the Global Alias Table
 
-       for (int r=0; (recp_array && r<array_len(recp_array)); ++r) {
+       int r;
+       for (r=0; (recp_array && r<array_len(recp_array)); ++r) {
                org_recp = (char *)array_get_element_at(recp_array, r);
                strncpy(this_recp, org_recp, sizeof this_recp);
 
-               for (int i=0; i<3; ++i) {                                               // pass three times through the aliaser
+               int i;
+               for (i=0; i<3; ++i) {                                           // pass three times through the aliaser
                        mailtype = expand_aliases(this_recp, aliases);
        
                        // If an alias expanded to multiple recipients, strip off those recipients and append them
@@ -568,13 +571,15 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
                        }
                }
 
-               for (int j=0; j<r; ++j) {
-                       if (!strcasecmp(this_recp , (char *)array_get_element_at(recp_array, j) )) {
+               // This loop searches for duplicate recipients in the final list and marks them to be skipped.
+               int j;
+               for (j=0; j<r; ++j) {
+                       if (!strcasecmp(this_recp, (char *)array_get_element_at(recp_array, j) )) {
                                mailtype = EA_SKIP;
                        }
                }
-               syslog(LOG_DEBUG, "Recipient #%d of type %d is <%s>", r, mailtype, this_recp);
 
+               syslog(LOG_DEBUG, "Recipient #%d of type %d is <%s>", r, mailtype, this_recp);
                invalid = 0;
                errmsg[0] = 0;
                switch(mailtype) {
@@ -618,12 +623,12 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
                                                if (!IsEmptyStr(ret->recp_room)) {
                                                        strcat(ret->recp_room, "|");
                                                }
-                                               strcat(ret->recp_room, &this_recp[5]);
+                                               strcat(ret->recp_room, CC->room.QRname);
        
                                                if (!IsEmptyStr(ret->recp_orgroom)) {
                                                        strcat(ret->recp_orgroom, "|");
                                                }
-                                               strcat(ret->recp_orgroom, org_recp);
+                                               strcat(ret->recp_orgroom, this_recp);
        
                                        }
                                }
@@ -1613,22 +1618,19 @@ void CtdlRebuildDirectoryIndex(void) {
 }
 
 
-/*
- * Configure Internet email addresses for a user account, updating the Directory Index in the process
- */
-void CtdlSetEmailAddressesForUser(char *requested_user, char *new_emailaddrs)
-{
+// Configure Internet email addresses for a user account, updating the Directory Index in the process
+void CtdlSetEmailAddressesForUser(char *requested_user, char *new_emailaddrs) {
        struct ctdluser usbuf;
        int i;
        char buf[SIZ];
 
-       if (CtdlGetUserLock(&usbuf, requested_user) != 0) {     // We are relying on the fact that the DirectoryIndex functions don't lock.
-               return;                                         // Silently fail here if we can't acquire a lock on the user record.
+       if (CtdlGetUserLock(&usbuf, requested_user) != 0) {     // We can lock because the DirectoryIndex functions don't lock.
+               return;                                         // Silently fail here if the specified user does not exist.
        }
 
        syslog(LOG_DEBUG, "internet_addressing: setting email addresses for <%s> to <%s>", usbuf.fullname, new_emailaddrs);
 
-       /* Delete all of the existing directory index records for the user (easier this way) */
+       // Delete all of the existing directory index records for the user (easier this way)
        for (i=0; i<num_tokens(usbuf.emailaddrs, '|'); ++i) {
                extract_token(buf, usbuf.emailaddrs, i, '|', sizeof buf);
                CtdlDirectoryDelUser(buf, requested_user);
@@ -1636,7 +1638,7 @@ void CtdlSetEmailAddressesForUser(char *requested_user, char *new_emailaddrs)
 
        strcpy(usbuf.emailaddrs, new_emailaddrs);               // make it official.
 
-       /* Index all of the new email addresses (they've already been sanitized) */
+       // Index all of the new email addresses (they've already been sanitized)
        for (i=0; i<num_tokens(usbuf.emailaddrs, '|'); ++i) {
                extract_token(buf, usbuf.emailaddrs, i, '|', sizeof buf);
                CtdlDirectoryAddUser(buf, requested_user);
@@ -1649,8 +1651,7 @@ void CtdlSetEmailAddressesForUser(char *requested_user, char *new_emailaddrs)
 /*
  * Auto-generate an Internet email address for a user account
  */
-void AutoGenerateEmailAddressForUser(struct ctdluser *user)
-{
+void AutoGenerateEmailAddressForUser(struct ctdluser *user) {
        char synthetic_email_addr[1024];
        int i, j;
        int u = 0;
@@ -1682,3 +1683,39 @@ void AutoGenerateEmailAddressForUser(struct ctdluser *user)
        strncpy(CC->user.emailaddrs, synthetic_email_addr, sizeof(user->emailaddrs));
        syslog(LOG_DEBUG, "user_ops: auto-generated email address <%s> for <%s>", synthetic_email_addr, user->fullname);
 }
+
+
+// Determine whether the supplied email address is subscribed to the supplied room's mailing list service.
+int is_email_subscribed_to_list(char *email, char *room_name) {
+       struct ctdlroom room;
+       long roomnum;
+       char *roomnetconfig;
+       int found_it = 0;
+
+       if (CtdlGetRoom(&room, room_name)) {
+               return(0);                                      // room not found, so definitely not subscribed
+       }
+
+       // If this room has the QR2_SMTP_PUBLIC flag set, anyone may email a post to this room, even non-subscribers.
+       if (room.QRflags2 & QR2_SMTP_PUBLIC) {
+               return(1);
+       }
+
+       roomnum = room.QRnumber;
+       roomnetconfig = LoadRoomNetConfigFile(roomnum);
+       if (roomnetconfig == NULL) {
+               return(0);
+       }
+
+       // We're going to do a very sloppy match here and simply search for the specified email address
+       // anywhere in the room's netconfig.  If you don't like this, fix it yourself.
+       if (bmstrcasestr(roomnetconfig, email)) {
+               found_it = 1;
+       }
+       else {
+               found_it = 0;
+       }
+
+       free(roomnetconfig);
+       return(found_it);
+}