* Got some more parsing in there
authorArt Cancro <ajc@citadel.org>
Wed, 22 Dec 1999 03:03:39 +0000 (03:03 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 22 Dec 1999 03:03:39 +0000 (03:03 +0000)
citadel/Makefile.in
citadel/internet_addressing.c
citadel/msgbase.c
citadel/parsedate.c
citadel/parsedate.h [new file with mode: 0644]
citadel/parsedate.y
citadel/serv_smtp.c

index 733ff118b6dd67a5889690876e28c30e1ac5cdb9..c6418adf0be4a6dabeffc8878af1894a5f28475d 100644 (file)
@@ -107,7 +107,7 @@ netpoll: netpoll.o config.o ipc_c_tcp.o tools.o $(LIBOBJS)
 SERV_OBJS = citserver.ro user_ops.ro support.ro room_ops.ro file_ops.ro \
        msgbase.ro config.ro sysdep.ro locate_host.ro housekeeping.ro \
        database.ro control.ro logging.ro policy.ro dynloader.ro tools.ro \
-       mime_parser.ro html.ro internet_addressing.ro \
+       mime_parser.ro html.ro internet_addressing.ro parsedate.ro \
        $(AUTH) $(LIBOBJS:.o=.ro)
 
 citserver: $(SERV_OBJS)
index 043909343b9f130c7b994b987597b7ddff9ea538..99c834753b9ae76a1423ecb58234fd4895f39479 100644 (file)
@@ -29,6 +29,7 @@
 #include "tools.h"
 #include "internet_addressing.h"
 #include "user_ops.h"
+#include "parsedate.h"
 
 
 /*
@@ -281,29 +282,74 @@ int convert_internet_address(char *destuser, char *desthost, char *source)
 /*
  * convert_field() is a helper function for convert_internet_message().
  * Given start/end positions for an rfc822 field, it converts it to a Citadel
- * field if it wants to, and unfolds it if necessary
+ * field if it wants to, and unfolds it if necessary.
+ *
+ * Returns 1 if the field was converted and inserted into the Citadel message
+ * structure, implying that the source field should be removed from the
+ * message text.
  */
-void convert_field(struct CtdlMessage *msg, int beg, int end) {
+int convert_field(struct CtdlMessage *msg, int beg, int end) {
        char *rfc822;
-       char *fieldbuf;
-       char field[256];
+       char *key, *value;
        int i;
+       int colonpos = (-1);
+       int processed = 0;
+       char buf[256];
+       char *user, *node, *name;
 
        rfc822 = msg->cm_fields['M'];   /* M field contains rfc822 text */
-       strcpy(field, "");
-       for (i = beg; i <= end; ++i) {
-               if ((rfc822[i] == ':') && ((i-beg)<sizeof(field))) {
-                       if (strlen(field)==0) {
-                          safestrncpy(field, &rfc822[beg], i-beg+1);
-                       }
-               }
+       for (i = end; i >= beg; --i) {
+               if (rfc822[i] == ':') colonpos = i;
+       }
+
+       if (colonpos < 0) return(0);    /* no colon? not a valid header line */
+
+       value = mallok((end - beg) + 2);
+       safestrncpy(value, &rfc822[beg], (end-beg)+1);
+       key = value;
+       key[colonpos - beg] = 0;
+       value = &key[(colonpos - beg) + 1];
+       unfold_rfc822_field(value);
+
+       /* Here's the big rfc822-to-citadel loop. */
+
+       if (!strcasecmp(key, "Date")) {
+               lprintf(9, "converting date <%s>\n", value);
+               sprintf(buf, "%ld", parsedate(value) );
+               lprintf(9, "parsed value is <%s>\n", buf);
+               if (msg->cm_fields['T'] != NULL)
+                       msg->cm_fields['T'] = strdoop(buf);
+               processed = 1;
+       }
+
+       else if (!strcasecmp(key, "From")) {
+               user = mallok(strlen(value));
+               node = mallok(strlen(value));
+               name = mallok(strlen(value));
+               process_rfc822_addr(value, user, node, name);
+               if (msg->cm_fields['A'] != NULL)
+                       msg->cm_fields['A'] = strdoop(user);
+               if (msg->cm_fields['N'] != NULL)
+                       msg->cm_fields['N'] = strdoop(node);
+               if (msg->cm_fields['H'] != NULL)
+                       msg->cm_fields['H'] = strdoop(name);
+               phree(user);
+               phree(node);
+               phree(name);
+               processed = 1;
        }
 
-       fieldbuf = mallok(end - beg + 2);
-       safestrncpy(fieldbuf, &rfc822[beg], end-beg+1);
-       unfold_rfc822_field(fieldbuf);
-       lprintf(9, "Field: key=<%s> value=<%s>\n", field, fieldbuf);
-       phree(fieldbuf);
+       else if (!strcasecmp(key, "Subject")) {
+               if (msg->cm_fields['U'] != NULL)
+                       msg->cm_fields['U'] = strdoop(key);
+               processed = 1;
+       }
+
+       /* Clean up and move on. */
+       lprintf(9, "Field: key=<%s> value=<%s> processed=%d\n",
+               key, value, processed);
+       phree(key);     /* Don't free 'value', it's actually the same buffer */
+       return(processed);
 }
 
 
@@ -317,6 +363,7 @@ struct CtdlMessage *convert_internet_message(char *rfc822) {
        int msglen;
        int done;
        char buf[256];
+       int converted;
 
        msg = mallok(sizeof(struct CtdlMessage));
        if (msg == NULL) return msg;
@@ -354,7 +401,11 @@ struct CtdlMessage *convert_internet_message(char *rfc822) {
                }
 
                /* At this point we have a field.  Are we interested in it? */
-               convert_field(msg, beg, end);
+               converted = convert_field(msg, beg, end);
+               if (converted) {
+                       strcpy(&rfc822[beg], &rfc822[pos]);
+                       pos = beg;
+               }
 
                /* If we've hit the end of the message, bail out */
                if (pos > strlen(rfc822)) done = 1;
index 045e38e86c22bedf0f9cf586d0618a69bff3952a..61488f1faf6a7fd178874e0f29a88cf302d0d2e4 100644 (file)
@@ -1424,8 +1424,12 @@ void CtdlSaveMsg(struct CtdlMessage *msg,        /* message to save */
                msg->cm_fields['T'] = strdoop(aaa);
        }
 
+       lprintf(9, "checkpoint 1      \n");
        /* If this message has no path, we generate one.
         */
+       if (msg->cm_fields['A'] == NULL) {
+               msg->cm_fields['A'] = strdoop("unknown user");
+       }
        if (msg->cm_fields['P'] == NULL) {
                msg->cm_fields['P'] = strdoop(msg->cm_fields['A']);
                for (a=0; a<strlen(msg->cm_fields['P']); ++a) {
@@ -1437,6 +1441,7 @@ void CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
 
        strcpy(force_room, force);
 
+       lprintf(9, "checkpoint 2      \n");
        /* Strip non-printable characters out of the recipient name */
        strcpy(recipient, rec);
        for (a = 0; a < strlen(recipient); ++a)
@@ -1445,6 +1450,7 @@ void CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
 
        /* Learn about what's inside, because it's what's inside that counts */
 
+       lprintf(9, "checkpoint 3      \n");
        switch (msg->cm_format_type) {
        case 0:
                strcpy(content_type, "text/x-citadel-variformat");
@@ -1474,32 +1480,39 @@ void CtdlSaveMsg(struct CtdlMessage *msg,       /* message to save */
                }
        }
 
+       lprintf(9, "checkpoint 4      \n");
        /* Goto the correct room */
        strcpy(hold_rm, CC->quickroom.QRname);
        strcpy(actual_rm, CC->quickroom.QRname);
 
+       lprintf(9, "checkpoint 5      \n");
        /* If the user is a twit, move to the twit room for posting */
-       if (TWITDETECT) {
+       if ( (CC->logged_in) && (TWITDETECT) ) {
                if (CC->usersupp.axlevel == 2) {
                        strcpy(hold_rm, actual_rm);
                        strcpy(actual_rm, config.c_twitroom);
                }
        }
 
+       lprintf(9, "checkpoint 6      \n");
        /* ...or if this message is destined for Aide> then go there. */
        if (strlen(force_room) > 0) {
                strcpy(actual_rm, force_room);
        }
 
+       lprintf(9, "checkpoint 7      \n");
        if (strcasecmp(actual_rm, CC->quickroom.QRname))
                getroom(&CC->quickroom, actual_rm);
 
+       lprintf(9, "checkpoint 8      \n");
        /* Perform "before save" hooks (aborting if any return nonzero) */
        if (PerformMessageHooks(msg, EVT_BEFORESAVE) > 0) return;
 
+       lprintf(9, "checkpoint 9      \n");
        /* If this message has an Extended ID, perform replication checks */
        if (ReplicationChecks(msg) > 0) return;
 
+       lprintf(9, "checkpoint 10     \n");
        /* Network mail - send a copy to the network program. */
        if ((strlen(recipient) > 0) && (mailtype != MES_LOCAL)) {
                sprintf(aaa, "./network/spoolin/netmail.%04lx.%04x.%04x",
@@ -1510,6 +1523,7 @@ void CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
                        lprintf(2, "ERROR: %s\n", strerror(errno));
        }
 
+       lprintf(9, "checkpoint 11     \n");
        /* Save it to disk */
        newmsgid = send_message(msg, generate_id, network_fp);
        if (network_fp != NULL) {
@@ -1519,6 +1533,7 @@ void CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
 
        if (newmsgid <= 0L) return;
 
+       lprintf(9, "checkpoint 12     \n");
        /* Write a supplemental message info record.  This doesn't have to
         * be a critical section because nobody else knows about this message
         * yet.
@@ -1532,6 +1547,7 @@ void CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
        /* Now figure out where to store the pointers */
 
 
+       lprintf(9, "checkpoint 13     \n");
        /* If this is being done by the networker delivering a private
         * message, we want to BYPASS saving the sender's copy (because there
         * is no local sender; it would otherwise go to the Trashcan).
@@ -1540,11 +1556,15 @@ void CtdlSaveMsg(struct CtdlMessage *msg,       /* message to save */
                CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 0);
        }
 
+       lprintf(9, "checkpoint 14     \n");
        /* Bump this user's messages posted counter. */
-       lgetuser(&CC->usersupp, CC->curr_user);
-       CC->usersupp.posted = CC->usersupp.posted + 1;
-       lputuser(&CC->usersupp);
+       if (CC->logged_in) {
+               lgetuser(&CC->usersupp, CC->curr_user);
+               CC->usersupp.posted = CC->usersupp.posted + 1;
+               lputuser(&CC->usersupp);
+       }
 
+       lprintf(9, "checkpoint 15     \n");
        /* If this is private, local mail, make a copy in the
         * recipient's mailbox and bump the reference count.
         */
@@ -1555,9 +1575,11 @@ void CtdlSaveMsg(struct CtdlMessage *msg,        /* message to save */
                }
        }
 
+       lprintf(9, "checkpoint 16     \n");
        /* Perform "after save" hooks */
        PerformMessageHooks(msg, EVT_AFTERSAVE);
 
+       lprintf(9, "checkpoint 17     \n");
        /* */
        if (strcasecmp(hold_rm, CC->quickroom.QRname))
                getroom(&CC->quickroom, hold_rm);
index e25be117359bd174e83df6578864660e02bfec35..f2927093ea3c60d65f37754c0685df834002c5d7 100644 (file)
@@ -32,6 +32,7 @@ static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
 #include <sys/types.h>
 #include <ctype.h>
 #include <time.h>
+#include "parsedate.h"
 
 int date_lex(void);
 
@@ -104,12 +105,12 @@ static time_t     yyRelSeconds;
 
 
 static void            date_error(char *);
-#line 99 "parsedate.y"
+#line 100 "parsedate.y"
 typedef union {
     time_t             Number;
     enum _MERIDIAN     Meridian;
 } YYSTYPE;
-#line 113 "y.tab.c"
+#line 114 "y.tab.c"
 #define tDAY 257
 #define tDAYZONE 258
 #define tMERIDIAN 259
@@ -293,7 +294,7 @@ YYSTYPE yylval;
 short yyss[YYSTACKSIZE];
 YYSTYPE yyvs[YYSTACKSIZE];
 #define yystacksize YYSTACKSIZE
-#line 286 "parsedate.y"
+#line 287 "parsedate.y"
 
 /* Month and day table. */
 static TABLE   MonthDayTable[] = {
@@ -448,8 +449,7 @@ static TABLE        TimezoneTable[] = {
 
 /* ARGSUSED */
 static void
-date_error(s)
-    char       *s;
+date_error(char *s)
 {
     /* NOTREACHED */
 }
@@ -943,7 +943,7 @@ yyreduce:
     switch (yyn)
     {
 case 3:
-#line 117 "parsedate.y"
+#line 118 "parsedate.y"
 {
            yyHaveTime++;
 #ifdef lint
@@ -955,26 +955,26 @@ case 3:
        }
 break;
 case 4:
-#line 126 "parsedate.y"
+#line 127 "parsedate.y"
 {
            yyHaveTime++;
            yyTimezone = yyvsp[0].Number;
        }
 break;
 case 5:
-#line 130 "parsedate.y"
+#line 131 "parsedate.y"
 {
            yyHaveDate++;
        }
 break;
 case 6:
-#line 133 "parsedate.y"
+#line 134 "parsedate.y"
 {
            yyHaveRel = 1;
        }
 break;
 case 7:
-#line 138 "parsedate.y"
+#line 139 "parsedate.y"
 {
            if (yyvsp[-1].Number < 100) {
                yyHour = yyvsp[-1].Number;
@@ -989,7 +989,7 @@ case 7:
        }
 break;
 case 8:
-#line 150 "parsedate.y"
+#line 151 "parsedate.y"
 {
            yyHour = yyvsp[-3].Number;
            yyMinutes = yyvsp[-1].Number;
@@ -998,7 +998,7 @@ case 8:
        }
 break;
 case 9:
-#line 156 "parsedate.y"
+#line 157 "parsedate.y"
 {
            yyHour = yyvsp[-3].Number;
            yyMinutes = yyvsp[-1].Number;
@@ -1008,7 +1008,7 @@ case 9:
        }
 break;
 case 10:
-#line 163 "parsedate.y"
+#line 164 "parsedate.y"
 {
            yyHour = yyvsp[-5].Number;
            yyMinutes = yyvsp[-3].Number;
@@ -1017,7 +1017,7 @@ case 10:
        }
 break;
 case 11:
-#line 169 "parsedate.y"
+#line 170 "parsedate.y"
 {
            yyHour = yyvsp[-5].Number;
            yyMinutes = yyvsp[-3].Number;
@@ -1028,21 +1028,21 @@ case 11:
        }
 break;
 case 12:
-#line 179 "parsedate.y"
+#line 180 "parsedate.y"
 {
            yyval.Number = yyvsp[0].Number;
            yyDSTmode = DSToff;
        }
 break;
 case 13:
-#line 183 "parsedate.y"
+#line 184 "parsedate.y"
 {
            yyval.Number = yyvsp[0].Number;
            yyDSTmode = DSTon;
        }
 break;
 case 14:
-#line 187 "parsedate.y"
+#line 188 "parsedate.y"
 {
            /* Only allow "GMT+300" and "GMT-0800" */
            if (yyvsp[-1].Number != 0) {
@@ -1053,14 +1053,14 @@ case 14:
        }
 break;
 case 15:
-#line 195 "parsedate.y"
+#line 196 "parsedate.y"
 {
            yyval.Number = yyvsp[0].Number;
            yyDSTmode = DSToff;
        }
 break;
 case 16:
-#line 201 "parsedate.y"
+#line 202 "parsedate.y"
 {
            int         i;
 
@@ -1082,14 +1082,14 @@ case 16:
        }
 break;
 case 17:
-#line 222 "parsedate.y"
+#line 223 "parsedate.y"
 {
            yyMonth = yyvsp[-2].Number;
            yyDay = yyvsp[0].Number;
        }
 break;
 case 18:
-#line 226 "parsedate.y"
+#line 227 "parsedate.y"
 {
            if (yyvsp[-4].Number > 100) {
                yyYear = yyvsp[-4].Number;
@@ -1104,14 +1104,14 @@ case 18:
        }
 break;
 case 19:
-#line 238 "parsedate.y"
+#line 239 "parsedate.y"
 {
            yyMonth = yyvsp[-1].Number;
            yyDay = yyvsp[0].Number;
        }
 break;
 case 20:
-#line 242 "parsedate.y"
+#line 243 "parsedate.y"
 {
            yyMonth = yyvsp[-3].Number;
            yyDay = yyvsp[-2].Number;
@@ -1119,14 +1119,14 @@ case 20:
        }
 break;
 case 21:
-#line 247 "parsedate.y"
+#line 248 "parsedate.y"
 {
            yyDay = yyvsp[-1].Number;
            yyMonth = yyvsp[0].Number;
        }
 break;
 case 22:
-#line 251 "parsedate.y"
+#line 252 "parsedate.y"
 {
            yyDay = yyvsp[-2].Number;
            yyMonth = yyvsp[-1].Number;
@@ -1134,7 +1134,7 @@ case 22:
        }
 break;
 case 23:
-#line 256 "parsedate.y"
+#line 257 "parsedate.y"
 {
            yyDay = yyvsp[-2].Number;
            yyMonth = yyvsp[-1].Number;
@@ -1142,37 +1142,37 @@ case 23:
        }
 break;
 case 24:
-#line 263 "parsedate.y"
+#line 264 "parsedate.y"
 {
            yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
        }
 break;
 case 25:
-#line 266 "parsedate.y"
+#line 267 "parsedate.y"
 {
            yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
        }
 break;
 case 26:
-#line 269 "parsedate.y"
+#line 270 "parsedate.y"
 {
            yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
        }
 break;
 case 27:
-#line 272 "parsedate.y"
+#line 273 "parsedate.y"
 {
            yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
        }
 break;
 case 28:
-#line 277 "parsedate.y"
+#line 278 "parsedate.y"
 {
            yyval.Meridian = MER24;
        }
 break;
 case 29:
-#line 280 "parsedate.y"
+#line 281 "parsedate.y"
 {
            yyval.Meridian = yyvsp[0].Meridian;
        }
diff --git a/citadel/parsedate.h b/citadel/parsedate.h
new file mode 100644 (file)
index 0000000..eb7851d
--- /dev/null
@@ -0,0 +1 @@
+time_t parsedate(char *);
index 5663c6d21fe285aa5573389fb64a13fc6aa82831..f703ef47be25cccd3ef7e692c28c8e36910a5b05 100644 (file)
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 #include <ctype.h>
 #include <time.h>
+#include "parsedate.h"
 
 int date_lex(void);
 
@@ -437,8 +438,7 @@ static TABLE        TimezoneTable[] = {
 
 /* ARGSUSED */
 static void
-date_error(s)
-    char       *s;
+date_error(char *s)
 {
     /* NOTREACHED */
 }
index fe78592880f2579947df6272b069b8c32dc1f07f..ec7b9ae2e0a5aae699b98e7f1be3dd34a7727a23 100644 (file)
@@ -392,9 +392,12 @@ void smtp_data(void) {
 
        fprintf(stderr, "Converting message...\n");
        msg = convert_internet_message(body);
-
        phree(body);
-       cprintf("599 command unfinished\n");
+
+       CtdlSaveMsg(msg, "", BASEROOM, MES_LOCAL, 1);   /* FIX temporary */
+       CtdlFreeMessage(msg);
+
+       cprintf("599 command unfinished but message saved\n");
 }