+/*
+ * 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);
+}
+
+
+
+