From e0e892370401431821a22abbf60ac79ed59273d7 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Wed, 22 Dec 1999 03:03:39 +0000 Subject: [PATCH] * Got some more parsing in there --- citadel/Makefile.in | 2 +- citadel/internet_addressing.c | 85 ++++++++++++++++++++++++++++------- citadel/msgbase.c | 30 +++++++++++-- citadel/parsedate.c | 64 +++++++++++++------------- citadel/parsedate.h | 1 + citadel/parsedate.y | 4 +- citadel/serv_smtp.c | 7 ++- 7 files changed, 135 insertions(+), 58 deletions(-) create mode 100644 citadel/parsedate.h diff --git a/citadel/Makefile.in b/citadel/Makefile.in index 733ff118b..c6418adf0 100644 --- a/citadel/Makefile.in +++ b/citadel/Makefile.in @@ -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) diff --git a/citadel/internet_addressing.c b/citadel/internet_addressing.c index 043909343..99c834753 100644 --- a/citadel/internet_addressing.c +++ b/citadel/internet_addressing.c @@ -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)= 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; diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 045e38e86..61488f1fa 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -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; acm_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); diff --git a/citadel/parsedate.c b/citadel/parsedate.c index e25be1173..f2927093e 100644 --- a/citadel/parsedate.c +++ b/citadel/parsedate.c @@ -32,6 +32,7 @@ static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; #include #include #include +#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 index 000000000..eb7851d82 --- /dev/null +++ b/citadel/parsedate.h @@ -0,0 +1 @@ +time_t parsedate(char *); diff --git a/citadel/parsedate.y b/citadel/parsedate.y index 5663c6d21..f703ef47b 100644 --- a/citadel/parsedate.y +++ b/citadel/parsedate.y @@ -22,6 +22,7 @@ #include #include #include +#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 */ } diff --git a/citadel/serv_smtp.c b/citadel/serv_smtp.c index fe7859288..ec7b9ae2e 100644 --- a/citadel/serv_smtp.c +++ b/citadel/serv_smtp.c @@ -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"); } -- 2.30.2