]> code.citadel.org Git - citadel.git/blobdiff - citadel/internet_addressing.c
The overhaul of recipient parsing code is complete. We can now handle a global alias...
[citadel.git] / citadel / internet_addressing.c
index 82214e4e860e258f2b9e3f4df1c3e84857a9af79..a38601d957903e5d46c7adb34dbe592ad9b15048 100644 (file)
@@ -390,6 +390,12 @@ enum {
        EA_LOCAL,               // Local message, do no network processing
        EA_INTERNET             // Convert msg and send as Internet mail
 };
+char *killo[] = {              // FIXME remove this when diags are complete
+       "error",
+       "multiple",
+       "local",
+       "internet"
+};
 
 
 /*
@@ -404,6 +410,9 @@ int expand_aliases(char *name) {                            /* process alias and routing info for mail *
 
 
 
+       // FIXME write a "real" alias table here
+
+
        // temporary test of expansion
        if (!strcasecmp(name, "root")) {
                strcpy(name, "root");
@@ -526,8 +535,7 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
        int mailtype;
        int invalid;
        struct ctdluser tempUS;
-       struct ctdlroom tempQR;
-       struct ctdlroom tempQR2;
+       struct ctdlroom original_room;
        int err = 0;
        char errmsg[SIZ];
        char *org_recp;
@@ -535,7 +543,6 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
 
        ret = (struct recptypes *) malloc(sizeof(struct recptypes));                    // Initialize
        if (ret == NULL) return(NULL);
-
        memset(ret, 0, sizeof(struct recptypes));                                       // set all values to null/zero
 
        if (supplied_recipients == NULL) {
@@ -575,7 +582,7 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
                if (mailtype == EA_MULTIPLE) {
                        if (r < original_array_len) {
                                char *comma;
-                               while (comma = strrchr(this_recp, ',')) {
+                               while ((comma = strrchr(this_recp, ','))) {
                                        comma[0] = 0;
                                        array_append(recp_array, &comma[1]);
                                        strcpy(org_recp, this_recp);
@@ -586,12 +593,17 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
                        }
                }
 
-               syslog(LOG_DEBUG, "org_recp: \033[31m%-30s\033[0m   this_recp: \033[32m%s\033[0m", org_recp, this_recp);
+               mailtype = expand_aliases(this_recp);           // do it ONCE again to handle alias expansions
+               if (mailtype == EA_MULTIPLE) {
+                       mailtype = EA_ERROR;                    // and fail if it wants to expand a second time
+               }
 
                invalid = 0;
                errmsg[0] = 0;
                switch(mailtype) {
-               case EA_LOCAL:
+               case EA_LOCAL:                                  // There are several types of "local" recipients.
+
+                       // Old BBS conventions require mail to "sysop" to go somewhere.  Send it to the admin room.
                        if (!strcasecmp(this_recp, "sysop")) {
                                ++ret->num_room;
                                strcpy(this_recp, CtdlGetConfigStr("c_aideroom"));
@@ -600,45 +612,55 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
                                }
                                strcat(ret->recp_room, this_recp);
                        }
-                       else if ( (!strncasecmp(this_recp, "room_", 5)) && (!CtdlGetRoom(&tempQR, &this_recp[5])) ) {
-
-
-                               // FIXME -- handle the underscores
 
+                       // This handles rooms which can receive posts via email.
+                       else if (!strncasecmp(this_recp, "room_", 5)) {
+                               original_room = CC->room;                               // Remember where we parked
 
-                                                                                       // Save room so we can restore it later
-                               tempQR2 = CC->room;
-                               CC->room = tempQR;
-                                       
-                               err = CtdlDoIHavePermissionToPostInThisRoom(            // check for write permissions to room
-                                       errmsg, 
-                                       sizeof errmsg, 
-                                       RemoteIdentifier,
-                                       Flags,
-                                       0                                               // 0 means "not a reply"
-                               );
-                               if (err) {
+                               char mail_to_room[ROOMNAMELEN];
+                               char *m;
+                               strncpy(mail_to_room, &this_recp[5], sizeof mail_to_room);
+                               for (m = mail_to_room; *m; ++m) {
+                                       if (m[0] == '_') m[0]=' ';
+                               }
+                               if (!CtdlGetRoom(&CC->room, mail_to_room)) {            // Find the room they asked for
+
+                                       err = CtdlDoIHavePermissionToPostInThisRoom(    // check for write permissions to room
+                                               errmsg, 
+                                               sizeof errmsg, 
+                                               RemoteIdentifier,
+                                               Flags,
+                                               0                                       // 0 means "this is not a reply"
+                                       );
+                                       if (err) {
+                                               ++ret->num_error;
+                                               invalid = 1;
+                                       } 
+                                       else {
+                                               ++ret->num_room;
+                                               if (!IsEmptyStr(ret->recp_room)) {
+                                                       strcat(ret->recp_room, "|");
+                                               }
+                                               strcat(ret->recp_room, &this_recp[5]);
+       
+                                               if (!IsEmptyStr(ret->recp_orgroom)) {
+                                                       strcat(ret->recp_orgroom, "|");
+                                               }
+                                               strcat(ret->recp_orgroom, org_recp);
+       
+                                       }
+                               }
+                               else {                                                  // no such room exists
                                        ++ret->num_error;
                                        invalid = 1;
-                               } 
-                               else {
-                                       ++ret->num_room;
-                                       if (!IsEmptyStr(ret->recp_room)) {
-                                               strcat(ret->recp_room, "|");
-                                       }
-                                       strcat(ret->recp_room, &this_recp[5]);
-
-                                       if (!IsEmptyStr(ret->recp_orgroom)) {
-                                               strcat(ret->recp_orgroom, "|");
-                                       }
-                                       strcat(ret->recp_orgroom, org_recp);
-
                                }
-                                       
-                               /* Restore room in case something needs it */
-                               CC->room = tempQR2;
+                                               
+                               // Restore this session's original room location.
+                               CC->room = original_room;
 
                        }
+
+                       // This handles the most common case, which is mail to a user's inbox.
                        else if (CtdlGetUser(&tempUS, this_recp) == 0) {
                                ++ret->num_local;
                                strcpy(this_recp, tempUS.fullname);
@@ -647,18 +669,17 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
                                }
                                strcat(ret->recp_local, this_recp);
                        }
+
+                       // No match for this recipient
                        else {
                                ++ret->num_error;
                                invalid = 1;
                        }
                        break;
                case EA_INTERNET:
-                       /* Yes, you're reading this correctly: if the target
-                        * domain points back to the local system,
-                        * the address is invalid.  That's
-                        * because if the address were valid, we would have
-                        * already translated it to a local address by now.
-                        */
+                       // Yes, you're reading this correctly: if the target domain points back to the local system,
+                       // the address is invalid.  That's because if the address were valid, we would have
+                       // already translated it to a local address by now.
                        if (IsDirectory(this_recp, 0)) {
                                ++ret->num_error;
                                invalid = 1;
@@ -701,6 +722,7 @@ struct recptypes *validate_recipients(char *supplied_recipients, const char *Rem
                                strcat(ret->display_recp, append);
                        }
                }
+               syslog(LOG_DEBUG, "org_recp: \033[31m%-30s\033[0m   this_recp: \033[32m%-30s\033[0m   mailtype: %s", org_recp, this_recp, killo[mailtype]);
        }
 
        if ( (ret->num_local + ret->num_internet + ret->num_room + ret->num_error) == 0) {