]> code.citadel.org Git - citadel.git/blobdiff - citadel/msgbase.c
* Re-introduced the ability to enter IGnet mail into the system.
[citadel.git] / citadel / msgbase.c
index bd02692ab15cc7a26fd7a2a910b1a153a5fca77a..2f5c10128f0c7fe1bbd872a8025cdfb009eacac1 100644 (file)
@@ -121,16 +121,24 @@ void remove_any_whitespace_to_the_left_or_right_of_at_symbol(char *name)
 int alias(char *name)
 {                              /* process alias and routing info for mail */
        FILE *fp;
-       int a, b;
-       char aaa[300], bbb[300];
+       int a, i;
+       char aaa[SIZ], bbb[SIZ];
+       char *ignetcfg = NULL;
+       char *ignetmap = NULL;
+       int at = 0;
+       char node[SIZ];
+       char testnode[SIZ];
+       char buf[SIZ];
 
        remove_any_whitespace_to_the_left_or_right_of_at_symbol(name);
 
        fp = fopen("network/mail.aliases", "r");
-       if (fp == NULL)
+       if (fp == NULL) {
                fp = fopen("/dev/null", "r");
-       if (fp == NULL)
+       }
+       if (fp == NULL) {
                return (MES_ERROR);
+       }
        strcpy(aaa, "");
        strcpy(bbb, "");
        while (fgets(aaa, sizeof aaa, fp) != NULL) {
@@ -161,76 +169,53 @@ int alias(char *name)
        }
 
        /* determine local or remote type, see citadel.h */
-       for (a = 0; a < strlen(name); ++a)
-               if (name[a] == '!')
-                       return (MES_INTERNET);
-       for (a = 0; a < strlen(name); ++a)
-               if (name[a] == '@')
-                       for (b = a; b < strlen(name); ++b)
-                               if (name[b] == '.')
-                                       return (MES_INTERNET);
-       b = 0;
-       for (a = 0; a < strlen(name); ++a)
-               if (name[a] == '@')
-                       ++b;
-       if (b > 1) {
-               lprintf(7, "Too many @'s in address\n");
-               return (MES_ERROR);
+
+       at = haschar(name, '@');
+       if (at == 0) return(MES_LOCAL);         /* no @'s - local address */
+       if (at > 1) return(MES_ERROR);          /* >1 @'s - invalid address */
+       remove_any_whitespace_to_the_left_or_right_of_at_symbol(name);
+
+       /* figure out the delivery mode */
+
+       extract_token(node, name, 1, '@');
+
+       /* If there are one or more dots in the nodename, we assume that it
+        * is an FQDN and will attempt SMTP delivery to the Internet.
+        */
+       if (haschar(node, '.') > 0) {
+               return(MES_INTERNET);
        }
-       if (b == 1) {
-               for (a = 0; a < strlen(name); ++a)
-                       if (name[a] == '@')
-                               strcpy(bbb, &name[a + 1]);
-               while (bbb[0] == 32)
-                       strcpy(bbb, &bbb[1]);
-               fp = fopen("network/mail.sysinfo", "r");
-               if (fp == NULL)
-                       return (MES_ERROR);    
-GETSN:         do {
-                       a = getstring(fp, aaa);
-               } while ((a >= 0) && (strcasecmp(aaa, bbb)));
-               a = getstring(fp, aaa);
-               if (!strncmp(aaa, "use ", 4)) {
-                       strcpy(bbb, &aaa[4]);
-                       fseek(fp, 0L, 0);
-                       goto GETSN;
+
+       /* Otherwise we look in the IGnet maps for a valid Citadel node.
+        * Try directly-connected nodes first...
+        */
+       ignetcfg = CtdlGetSysConfig(IGNETCFG);
+       for (i=0; i<num_tokens(ignetcfg, '\n'); ++i) {
+               extract_token(buf, ignetcfg, i, '\n');
+               extract_token(testnode, buf, 0, '|');
+               if (!strcasecmp(node, testnode)) {
+                       phree(ignetcfg);
+                       return(MES_IGNET);
                }
-               fclose(fp);
-               if (!strncmp(aaa, "uum", 3)) {
-                       strcpy(bbb, name);
-                       for (a = 0; a < strlen(bbb); ++a) {
-                               if (bbb[a] == '@')
-                                       bbb[a] = 0;
-                               if (bbb[a] == ' ')
-                                       bbb[a] = '_';
-                       }
-                       while (bbb[strlen(bbb) - 1] == '_')
-                               bbb[strlen(bbb) - 1] = 0;
-                       sprintf(name, &aaa[4], bbb);
-                       lprintf(9, "returning MES_INTERNET\n");
-                       return (MES_INTERNET);
-               }
-               if (!strncmp(aaa, "bin", 3)) {
-                       strcpy(aaa, name);
-                       strcpy(bbb, name);
-                       while (aaa[strlen(aaa) - 1] != '@')
-                               aaa[strlen(aaa) - 1] = 0;
-                       aaa[strlen(aaa) - 1] = 0;
-                       while (aaa[strlen(aaa) - 1] == ' ')
-                               aaa[strlen(aaa) - 1] = 0;
-                       while (bbb[0] != '@')
-                               strcpy(bbb, &bbb[1]);
-                       strcpy(bbb, &bbb[1]);
-                       while (bbb[0] == ' ')
-                               strcpy(bbb, &bbb[1]);
-                       sprintf(name, "%s @%s", aaa, bbb);
-                       lprintf(9, "returning MES_BINARY\n");
-                       return (MES_BINARY);
+       }
+       phree(ignetcfg);
+
+       /*
+        * Then try nodes that are two or more hops away.
+        */
+       ignetmap = CtdlGetSysConfig(IGNETMAP);
+       for (i=0; i<num_tokens(ignetmap, '\n'); ++i) {
+               extract_token(buf, ignetmap, i, '\n');
+               extract_token(testnode, buf, 0, '|');
+               if (!strcasecmp(node, testnode)) {
+                       phree(ignetmap);
+                       return(MES_IGNET);
                }
-               return (MES_ERROR);
        }
-       lprintf(9, "returning MES_LOCAL\n");
-       return (MES_LOCAL);
+       phree(ignetmap);
+
+       /* If we get to this point it's an invalid node name */
+       return (MES_ERROR);
 }
 
 
@@ -377,7 +362,7 @@ int CtdlForEachMessage(int mode, long ref,
        int num_msgs = 0;
        int num_processed = 0;
        long thismsg;
-       struct SuppMsgInfo smi;
+       struct MetaData smi;
        struct CtdlMessage *msg;
        int is_seen;
        long lastold = 0L;
@@ -404,12 +389,12 @@ int CtdlForEachMessage(int mode, long ref,
         * Now begin the traversal.
         */
        if (num_msgs > 0) for (a = 0; a < num_msgs; ++a) {
-               GetSuppMsgInfo(&smi, msglist[a]);
+               GetMetaData(&smi, msglist[a]);
 
                /* Filter out messages that are moderated below the level
                 * currently being viewed at.
                 */
-               if (smi.smi_mod < moderation_level) {
+               if (smi.meta_mod < moderation_level) {
                        msglist[a] = 0L;
                }
 
@@ -417,7 +402,7 @@ int CtdlForEachMessage(int mode, long ref,
                 * out all messages which are not of the type requested.
                 */
                if (content_type != NULL) if (strlen(content_type) > 0) {
-                       if (strcasecmp(smi.smi_content_type, content_type)) {
+                       if (strcasecmp(smi.meta_content_type, content_type)) {
                                msglist[a] = 0L;
                        }
                }
@@ -1693,7 +1678,7 @@ long CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
        char *mptr = NULL;
        struct usersupp userbuf;
        int a;
-       struct SuppMsgInfo smi;
+       struct MetaData smi;
        FILE *network_fp = NULL;
        static int seqnum = 1;
        struct CtdlMessage *imsg;
@@ -1828,7 +1813,7 @@ long CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
        if (ReplicationChecks(msg) > 0) return(-1);
 
        /* Network mail - send a copy to the network program. */
-       if ((strlen(recipient) > 0) && (mailtype == MES_BINARY)) {
+       if ((strlen(recipient) > 0) && (mailtype == MES_IGNET)) {
                lprintf(9, "Sending network spool\n");
                sprintf(aaa, "./network/spoolin/netmail.%04lx.%04x.%04x",
                        (long) getpid(), CC->cs_pid, ++seqnum);
@@ -1852,12 +1837,12 @@ long CtdlSaveMsg(struct CtdlMessage *msg,       /* message to save */
         * be a critical section because nobody else knows about this message
         * yet.
         */
-       lprintf(9, "Creating SuppMsgInfo record\n");
-       memset(&smi, 0, sizeof(struct SuppMsgInfo));
-       smi.smi_msgnum = newmsgid;
-       smi.smi_refcount = 0;
-       safestrncpy(smi.smi_content_type, content_type, 64);
-       PutSuppMsgInfo(&smi);
+       lprintf(9, "Creating MetaData record\n");
+       memset(&smi, 0, sizeof(struct MetaData));
+       smi.meta_msgnum = newmsgid;
+       smi.meta_refcount = 0;
+       safestrncpy(smi.meta_content_type, content_type, 64);
+       PutMetaData(&smi);
 
        /* Now figure out where to store the pointers */
        lprintf(9, "Storing pointers\n");
@@ -2069,8 +2054,8 @@ static struct CtdlMessage *make_message(
        /* Don't confuse the poor folks if it's not routed mail. */
        strcpy(dest_node, "");
 
-       /* If net_type is MES_BINARY, split out the destination node. */
-       if (net_type == MES_BINARY) {
+       /* If net_type is MES_IGNET, split out the destination node. */
+       if (net_type == MES_IGNET) {
                strcpy(dest_node, NODENAME);
                for (a = 0; a < strlen(recipient); ++a) {
                        if (recipient[a] == '@') {
@@ -2413,7 +2398,7 @@ int CtdlDeleteMessages(char *room_name,           /* which room */
        int i;
        int num_deleted = 0;
        int delete_this;
-       struct SuppMsgInfo smi;
+       struct MetaData smi;
 
        lprintf(9, "CtdlDeleteMessages(%s, %ld, %s)\n",
                room_name, dmsgnum, content_type);
@@ -2444,8 +2429,8 @@ int CtdlDeleteMessages(char *room_name,           /* which room */
                        if (strlen(content_type) == 0) {
                                delete_this |= 0x02;
                        } else {
-                               GetSuppMsgInfo(&smi, msglist[i]);
-                               if (!strcasecmp(smi.smi_content_type,
+                               GetMetaData(&smi, msglist[i]);
+                               if (!strcasecmp(smi.meta_content_type,
                                                content_type)) {
                                        delete_this |= 0x02;
                                }
@@ -2578,17 +2563,17 @@ void cmd_move(char *args)
 
 
 /*
- * GetSuppMsgInfo()  -  Get the supplementary record for a message
+ * GetMetaData()  -  Get the supplementary record for a message
  */
-void GetSuppMsgInfo(struct SuppMsgInfo *smibuf, long msgnum)
+void GetMetaData(struct MetaData *smibuf, long msgnum)
 {
 
        struct cdbdata *cdbsmi;
        long TheIndex;
 
-       memset(smibuf, 0, sizeof(struct SuppMsgInfo));
-       smibuf->smi_msgnum = msgnum;
-       smibuf->smi_refcount = 1;       /* Default reference count is 1 */
+       memset(smibuf, 0, sizeof(struct MetaData));
+       smibuf->meta_msgnum = msgnum;
+       smibuf->meta_refcount = 1;      /* Default reference count is 1 */
 
        /* Use the negative of the message number for its supp record index */
        TheIndex = (0L - msgnum);
@@ -2598,29 +2583,29 @@ void GetSuppMsgInfo(struct SuppMsgInfo *smibuf, long msgnum)
                return;         /* record not found; go with defaults */
        }
        memcpy(smibuf, cdbsmi->ptr,
-              ((cdbsmi->len > sizeof(struct SuppMsgInfo)) ?
-               sizeof(struct SuppMsgInfo) : cdbsmi->len));
+              ((cdbsmi->len > sizeof(struct MetaData)) ?
+               sizeof(struct MetaData) : cdbsmi->len));
        cdb_free(cdbsmi);
        return;
 }
 
 
 /*
- * PutSuppMsgInfo()  -  (re)write supplementary record for a message
+ * PutMetaData()  -  (re)write supplementary record for a message
  */
-void PutSuppMsgInfo(struct SuppMsgInfo *smibuf)
+void PutMetaData(struct MetaData *smibuf)
 {
        long TheIndex;
 
        /* Use the negative of the message number for its supp record index */
-       TheIndex = (0L - smibuf->smi_msgnum);
+       TheIndex = (0L - smibuf->meta_msgnum);
 
-       lprintf(9, "PuttSuppMsgInfo(%ld) - ref count is %d\n",
-               smibuf->smi_msgnum, smibuf->smi_refcount);
+       lprintf(9, "PuttMetaData(%ld) - ref count is %d\n",
+               smibuf->meta_msgnum, smibuf->meta_refcount);
 
        cdb_store(CDB_MSGMAIN,
                  &TheIndex, sizeof(long),
-                 smibuf, sizeof(struct SuppMsgInfo));
+                 smibuf, sizeof(struct MetaData));
 
 }
 
@@ -2631,7 +2616,7 @@ void PutSuppMsgInfo(struct SuppMsgInfo *smibuf)
 void AdjRefCount(long msgnum, int incr)
 {
 
-       struct SuppMsgInfo smi;
+       struct MetaData smi;
        long delnum;
 
        /* This is a *tight* critical section; please keep it that way, as
@@ -2639,19 +2624,19 @@ void AdjRefCount(long msgnum, int incr)
         * Complicating this any further will surely cause deadlock!
         */
        begin_critical_section(S_SUPPMSGMAIN);
-       GetSuppMsgInfo(&smi, msgnum);
+       GetMetaData(&smi, msgnum);
        lprintf(9, "Ref count for message <%ld> before write is <%d>\n",
-               msgnum, smi.smi_refcount);
-       smi.smi_refcount += incr;
-       PutSuppMsgInfo(&smi);
+               msgnum, smi.meta_refcount);
+       smi.meta_refcount += incr;
+       PutMetaData(&smi);
        end_critical_section(S_SUPPMSGMAIN);
        lprintf(9, "Ref count for message <%ld> after write is <%d>\n",
-               msgnum, smi.smi_refcount);
+               msgnum, smi.meta_refcount);
 
        /* If the reference count is now zero, delete the message
         * (and its supplementary record as well).
         */
-       if (smi.smi_refcount == 0) {
+       if (smi.meta_refcount == 0) {
                lprintf(9, "Deleting message <%ld>\n", msgnum);
                delnum = msgnum;
                cdb_delete(CDB_MSGMAIN, &delnum, sizeof(long));