* Implemented new data type "CtdlMessage" which will eventually be used as
authorArt Cancro <ajc@citadel.org>
Tue, 27 Jul 1999 22:47:26 +0000 (22:47 +0000)
committerArt Cancro <ajc@citadel.org>
Tue, 27 Jul 1999 22:47:26 +0000 (22:47 +0000)
  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.

citadel/ChangeLog
citadel/msgbase.c
citadel/msgbase.h
citadel/server.h

index 6ab1bc45c70685cde9dc183377e3c725b1149cf7..2a4f4b39f225ae28b419031cfb42a45ca35e70f9 100644 (file)
@@ -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 <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
        * Initial CVS import
+
index 534bf17613f8eef01a3ce15c7ea0d3b3bc8c275f..449102910c92ac03abc950870f31dd18a2ddab5e 100644 (file)
@@ -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)
  * 
index f4f8660e5b80ff70218c248e6192e4b40762832e..98341c57c140e7f87e62cf1b6187cbb34c83d14c 100644 (file)
@@ -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);
index 46233912a70129f4227e0251423ec67f7003790a..b3835f9b86f44cc5c86d6214e43fd50c5cfcc1ee 100644 (file)
@@ -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 */
+};