From: Art Cancro Date: Tue, 27 Jul 1999 22:47:26 +0000 (+0000) Subject: * Implemented new data type "CtdlMessage" which will eventually be used as X-Git-Tag: v7.86~7611 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=7fc1fad7be2e597e538d37ace95f415de598e15b * Implemented new data type "CtdlMessage" which will eventually be used as widely as possible to represent a message in memory. * Implemented CtdlFetchMessage() which is intended to become the back-end to output_message() as well as a bunch of other things. --- diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 6ab1bc45c..2a4f4b39f 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,10 @@ $Log$ +Revision 1.334 1999/07/27 22:47:26 ajc +* Implemented new data type "CtdlMessage" which will eventually be used as + widely as possible to represent a message in memory. +* Implemented CtdlFetchMessage() which is intended to become the back-end to + output_message() as well as a bunch of other things. + Revision 1.333 1999/07/27 20:00:24 ajc Removed all references to CC->msglist and CC->num_msgs, and all utility functions which relied upon them. Citadel Is Now Better. @@ -1122,3 +1128,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 534bf1761..449102910 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -193,6 +193,7 @@ void simple_listing(long msgnum) { * current room. */ void CtdlForEachMessage(int mode, long ref, + char *content_type, void (*CallBack) (long msgnum) ) { int a; @@ -201,11 +202,14 @@ void CtdlForEachMessage(int mode, long ref, long *msglist = NULL; int num_msgs = 0; long thismsg; + struct SuppMsgInfo smi; + /* Learn about the user and room in question */ get_mm(); getuser(&CC->usersupp, CC->curr_user); CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom); + /* Load the message list */ cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->quickroom.QRnumber, sizeof(long)); if (cdbfr != NULL) { msglist = mallok(cdbfr->len); @@ -213,12 +217,29 @@ void CtdlForEachMessage(int mode, long ref, num_msgs = cdbfr->len / sizeof(long); cdb_free(cdbfr); } else { - return; + return; /* No messages at all? No further action. */ + } + + + /* If the caller is looking for a specific MIME type, then filter + * out all messages which are not of the type requested. + */ + if (num_msgs > 0) + if (content_type != NULL) + if (strlen(content_type) > 0) for (a = 0; a < num_msgs; ++a) { + GetSuppMsgInfo(&smi, msglist[a]); + if (strcasecmp(smi.smi_content_type, content_type)) { + msglist[a] = 0L; + } } - if (num_msgs > 0) for (a = 0; a < (num_msgs); ++a) { + + /* + * Now iterate through the message list, according to the + * criteria supplied by the caller. + */ + if (num_msgs > 0) for (a = 0; a < num_msgs; ++a) { thismsg = msglist[a]; - lprintf(9, "CtdlForEachMessage() iterating msg %ld\n", thismsg); if ((thismsg >= 0) && ( @@ -235,7 +256,8 @@ void CtdlForEachMessage(int mode, long ref, CallBack(thismsg); } } - phree(msglist); + + phree(msglist); /* Clean up */ } @@ -272,7 +294,7 @@ void cmd_msgs(char *cmdbuf) } cprintf("%d Message list...\n", LISTING_FOLLOWS); - CtdlForEachMessage(mode, cm_ref, simple_listing); + CtdlForEachMessage(mode, cm_ref, NULL, simple_listing); cprintf("000\n"); } @@ -457,6 +479,71 @@ void mime_download(char *name, char *filename, char *partnum, char *disp, +/* + * Load a message from disk into memory. + * (This will replace a big piece of output_message() eventually) + * + * NOTE: Caller is responsible for _recursively_ freeing the returned + * CtdlMessage data structure! + */ +struct CtdlMessage *CtdlFetchMessage(long msgnum) { + struct cdbdata *dmsgtext; + struct CtdlMessage *ret = NULL; + char *mptr; + CIT_UBYTE ch; + CIT_UBYTE field_header; + size_t field_length; + + + dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long)); + if (dmsgtext == NULL) { + lprintf(9, "CtdlMessage(%ld) failed.\n"); + return NULL; + } + + mptr = dmsgtext->ptr; + + /* Parse the three bytes that begin EVERY message on disk. + * The first is always 0xFF, the universal start-of-message byte. + * The second is the anonymous/public type byte. + * The third is the format type byte (vari, fixed, or MIME). + */ + ch = *mptr++; + if (ch != 255) { + lprintf(5, "Message %ld appears to be corrupted.\n", msgnum); + cdb_free(dmsgtext); + return NULL; + } + + ret = (struct CtdlMessage *) mallok(sizeof(struct CtdlMessage)); + memset(ret, 0, sizeof(struct CtdlMessage)); + + ret->cm_anon_type = *mptr++; /* Anon type byte */ + ret->cm_format_type = *mptr++; /* Format type byte */ + + /* + * The rest is zero or more arbitrary fields. Load them in. + * We're done when we encounter either a zero-length field or + * have just processed the 'M' (message text) field. + */ + do { + field_length = strlen(mptr); + if (field_length == 0) break; + field_header = *mptr++; + ret->cm_fields[field_header] = mallok(field_length); + strcpy(ret->cm_fields[field_header], mptr); + + while (*mptr++ != 0) ; /* advance to next field */ + + } while ( (field_length > 0) && (field_header != 'M') ); + + cdb_free(dmsgtext); + return(ret); +} + + + + /* * Get a message off disk. (return value is the message's timestamp) * diff --git a/citadel/msgbase.h b/citadel/msgbase.h index f4f8660e5..98341c57c 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -30,6 +30,8 @@ void PutSuppMsgInfo(struct SuppMsgInfo *); void AdjRefCount(long, int); void simple_listing(long); void CtdlForEachMessage(int mode, long ref, + char *content_type, void (*CallBack) (long msgnum) ); int CtdlDeleteMessages(char *, long, char *); void CtdlWriteObject(char *, char *, char *, int, int, int); +struct CtdlMessage *CtdlFetchMessage(long msgnum); diff --git a/citadel/server.h b/citadel/server.h index 46233912a..b3835f9b8 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -300,3 +300,13 @@ extern struct TheHeap *heap; #define reallok(whichptr,howbig) realloc(whichptr,howbig) #endif + + +/* + * New format for a message in memory + */ +struct CtdlMessage { + char cm_anon_type; /* Anonymous or author-visible */ + char cm_format_type; /* Format type */ + char *cm_fields[256]; /* Data fields */ +};