diff src/libpst.c @ 52:034641c26ab9

code cleanup
author carl
date Thu, 31 Jan 2008 08:03:30 -0800
parents 06c0262ad689
children a8b772313ff4
line wrap: on
line diff
--- a/src/libpst.c	Tue Jan 22 14:39:02 2008 -0800
+++ b/src/libpst.c	Thu Jan 31 08:03:30 2008 -0800
@@ -40,21 +40,21 @@
 #define INDEX_BACK32            (off_t)0xC0
 #define SECOND_POINTER32        (off_t)0xBC
 #define SECOND_BACK32           (off_t)0xB8
-#define ENC_OFFSET32            (off_t)0x1CD
+#define ENC_TYPE32              (off_t)0x1CD
 
 #define FILE_SIZE_POINTER64     (off_t)0xB8
 #define INDEX_POINTER64         (off_t)0xF0
 #define INDEX_BACK64            (off_t)0xE8
 #define SECOND_POINTER64        (off_t)0xE0
 #define SECOND_BACK64           (off_t)0xD8
-#define ENC_OFFSET64            (off_t)0x201
+#define ENC_TYPE64              (off_t)0x201
 
 #define FILE_SIZE_POINTER ((pf->do_read64) ? FILE_SIZE_POINTER64 : FILE_SIZE_POINTER32)
 #define INDEX_POINTER     ((pf->do_read64) ? INDEX_POINTER64     : INDEX_POINTER32)
 #define INDEX_BACK        ((pf->do_read64) ? INDEX_BACK64        : INDEX_BACK32)
 #define SECOND_POINTER    ((pf->do_read64) ? SECOND_POINTER64    : SECOND_POINTER32)
 #define SECOND_BACK       ((pf->do_read64) ? SECOND_BACK64       : SECOND_BACK32)
-#define ENC_OFFSET        ((pf->do_read64) ? ENC_OFFSET64        : ENC_OFFSET32)
+#define ENC_TYPE          ((pf->do_read64) ? ENC_TYPE64          : ENC_TYPE32)
 
 #define PST_SIGNATURE 0x4E444221
 
@@ -176,7 +176,7 @@
     }
 
     // Check pst file magic
-    if (fread(&sig, sizeof(sig), (size_t)1, pf->fp) == 0) {
+    if (pst_getAtPos(pf, 0, &sig, sizeof(sig)) != sizeof(sig)) {
         (void)fclose(pf->fp);
         WARN(("cannot read signature from PST file. Closing on error\n"));
         DEBUG_RET();
@@ -192,7 +192,7 @@
     }
 
     // read index type
-    (void)pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(pf->ind_type));
+    (void)pst_getAtPos(pf, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(pf->ind_type));
     DEBUG_INFO(("index_type = %i\n", pf->ind_type));
     switch (pf->ind_type) {
         case INDEX_TYPE32 :
@@ -208,7 +208,7 @@
     }
 
     // read encryption setting
-    (void)pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(pf->encryption));
+    (void)pst_getAtPos(pf, ENC_TYPE, &(pf->encryption), sizeof(pf->encryption));
     DEBUG_INFO(("encrypt = %i\n", pf->encryption));
 
     pf->index2_back  = pst_getIntAtPos(pf, SECOND_BACK);
@@ -264,7 +264,7 @@
 }
 
 
-size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, unsigned char **b){
+size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, char **b){
     size_t size=0;
     pst_index_ll *ptr;
     pst_holder h = {b, NULL, 0, "", 0};
@@ -395,14 +395,15 @@
     pst_desc_ll *p;
     pst_num_array *na;
     pst_index2_ll *id2_head = NULL;
-    unsigned char *buffer=NULL, *headerbuffer=NULL;
+    char *buffer=NULL, *headerbuffer=NULL;
     size_t bsize=0, hsize=0, bptr=0;
     pst_x_attrib xattrib;
     int32_t tint, err=0, x;
     pst_x_attrib_ll *ptr, *p_head=NULL, *p_sh=NULL, *p_sh2=NULL;
 
     DEBUG_ENT("pst_loadExtendedAttributes");
-    if ((p = pst_getDptr(pf, (uint64_t)0x61)) == NULL) {
+    p = pst_getDptr(pf, (uint64_t)0x61);
+    if (!p) {
         DEBUG_WARN(("Cannot find DescID 0x61 for loading the Extended Attributes\n"));
         DEBUG_RET();
         return 0;
@@ -527,8 +528,7 @@
     return 1;
 }
 
-#define BLOCK_SIZE32               516      // index blocks
-#define DESC_BLOCK_SIZE32          516      // descriptor blocks
+
 #define ITEM_COUNT_OFFSET32        0x1f0    // count byte
 #define LEVEL_INDICATOR_OFFSET32   0x1f3    // node or leaf
 #define BACKLINK_OFFSET32          0x1f8    // backlink u1 value
@@ -537,8 +537,6 @@
 #define INDEX_COUNT_MAX32          41       // max active items
 #define DESC_COUNT_MAX32           31       // max active items
 
-#define BLOCK_SIZE64               512      // index blocks
-#define DESC_BLOCK_SIZE64          512      // descriptor blocks
 #define ITEM_COUNT_OFFSET64        0x1e8    // count byte
 #define LEVEL_INDICATOR_OFFSET64   0x1eb    // node or leaf
 #define BACKLINK_OFFSET64          0x1f8    // backlink u1 value
@@ -547,8 +545,8 @@
 #define INDEX_COUNT_MAX64          20       // max active items
 #define DESC_COUNT_MAX64           15       // max active items
 
-#define BLOCK_SIZE               (size_t)((pf->do_read64) ? BLOCK_SIZE64             : BLOCK_SIZE32)
-#define DESC_BLOCK_SIZE          (size_t)((pf->do_read64) ? DESC_BLOCK_SIZE64        : DESC_BLOCK_SIZE32)
+#define BLOCK_SIZE                 512      // index blocks
+#define DESC_BLOCK_SIZE            512      // descriptor blocks
 #define ITEM_COUNT_OFFSET        (size_t)((pf->do_read64) ? ITEM_COUNT_OFFSET64      : ITEM_COUNT_OFFSET32)
 #define LEVEL_INDICATOR_OFFSET   (size_t)((pf->do_read64) ? LEVEL_INDICATOR_OFFSET64 : LEVEL_INDICATOR_OFFSET32)
 #define BACKLINK_OFFSET          (size_t)((pf->do_read64) ? BACKLINK_OFFSET64        : BACKLINK_OFFSET32)
@@ -1296,8 +1294,8 @@
 
 
 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) {
-    unsigned char *buf = NULL;
-    size_t         read_size = 0;
+    char  *buf       = NULL;
+    size_t read_size = 0;
     pst_subblocks  subblocks;
     pst_num_array *na_ptr = NULL;
     pst_block_offset_pointer block_offset1;
@@ -4005,7 +4003,7 @@
 }
 
 
-int pst_getBlockOffset(unsigned char *buf, size_t read_size, uint32_t i_offset, uint32_t offset, pst_block_offset *p) {
+int pst_getBlockOffset(char *buf, size_t read_size, uint32_t i_offset, uint32_t offset, pst_block_offset *p) {
     uint32_t low = offset & 0xf;
     uint32_t of1 = offset >> 4;
     DEBUG_ENT("pst_getBlockOffset");
@@ -4021,6 +4019,7 @@
     DEBUG_WARN(("get block offset finds from=%i(%#x), to=%i(%#x)\n", p->from, p->from, p->to, p->to));
     if (p->from > p->to) {
         DEBUG_WARN(("get block offset from > to"));
+        DEBUG_RET();
         return 0;
     }
     DEBUG_RET();
@@ -4054,8 +4053,7 @@
 
 pst_index_ll * pst_getID2(pst_index2_ll *ptr, uint64_t id) {
     DEBUG_ENT("pst_getID2");
-    DEBUG_INDEX(("Head = %p\n", ptr));
-    DEBUG_INDEX(("Trying to find %#x\n", id));
+    DEBUG_INDEX(("Head = %p id = %#llx\n", ptr, id));
     while (ptr && (ptr->id2 != id)) {
         ptr = ptr->next;
     }
@@ -4133,24 +4131,29 @@
 }
 
 
+/**
+ * Read a block of data from file into memory
+ * @param pf     PST file
+ * @param offset offset in the pst file of the data
+ * @param size   size of the block to be read
+ * @param buf    reference to pointer to buffer. If this pointer
+                 is non-NULL, it will first be free()d
+ * @return       size of block read into memory
+ */
 size_t pst_read_block_size(pst_file *pf, off_t offset, size_t size, char **buf) {
-    off_t fpos;
     size_t rsize;
-
     DEBUG_ENT("pst_read_block_size");
     DEBUG_READ(("Reading block from %#x, %i bytes\n", offset, size));
 
-    fpos = ftell(pf->fp);
-    (void)fseek(pf->fp, offset, SEEK_SET);
     if (*buf) {
         DEBUG_READ(("Freeing old memory\n"));
         free(*buf);
     }
-
-    *buf = (void*) xmalloc(size);
-    rsize = fread(*buf, (size_t)1, size, pf->fp);
+    *buf = (char*) xmalloc(size);
+
+    rsize = pst_getAtPos(pf, offset, *buf, size);
     if (rsize != size) {
-        DEBUG_WARN(("Didn't read all that I could. fread returned less [%i instead of %i]\n", rsize, size));
+        DEBUG_WARN(("Didn't read all the data. fread returned less [%i instead of %i]\n", rsize, size));
         if (feof(pf->fp)) {
             DEBUG_WARN(("We tried to read past the end of the file at [offset %#x, size %#x]\n", offset, size));
         } else if (ferror(pf->fp)) {
@@ -4158,12 +4161,10 @@
         } else {
             DEBUG_WARN(("I can't tell why it failed\n"));
         }
-        size = rsize;
     }
 
-    (void)fseek(pf->fp, fpos, SEEK_SET);
     DEBUG_RET();
-    return size;
+    return rsize;
 }
 
 
@@ -4214,51 +4215,81 @@
     uint64_t buf64;
     uint32_t buf32;
     if (pf->do_read64) {
-        (void)pst_getAtPos(pf->fp, pos, &buf64, sizeof(buf64));
+        (void)pst_getAtPos(pf, pos, &buf64, sizeof(buf64));
         LE64_CPU(buf64);
         return buf64;
     }
     else {
-        (void)pst_getAtPos(pf->fp, pos, &buf32, sizeof(buf32));
+        (void)pst_getAtPos(pf, pos, &buf32, sizeof(buf32));
         LE32_CPU(buf32);
         return buf32;
     }
 }
 
-
-int pst_getAtPos(FILE *fp, off_t pos, void* buf, size_t size) {
+/**
+ * Read part of the pst file.
+ *
+ * @param pf   PST file structure
+ * @param pos  offset of the data in the pst file
+ * @param buf  buffer to contain the data
+ * @param size size of the buffer and the amount of data to be read
+ * @return     actual read size, 0 if seek error
+ */
+
+size_t pst_getAtPos(pst_file *pf, off_t pos, void* buf, size_t size) {
+    size_t rc;
     DEBUG_ENT("pst_getAtPos");
-    if (fseek(fp, pos, SEEK_SET) == -1) {
+//  pst_block_recorder **t = &pf->block_head;
+//  pst_block_recorder *p = pf->block_head;
+//  while (p && ((p->offset+p->size) <= pos)) {
+//      t = &p->next;
+//      p = p->next;
+//  }
+//  if (p && (p->offset <= pos) && (pos < (p->offset+p->size))) {
+//      // bump the count
+//      p->readcount++;
+//  } else {
+//      // add a new block
+//      pst_block_recorder *tail = *t;
+//      p = (pst_block_recorder*)xmalloc(sizeof(*p));
+//      *t = p;
+//      p->next      = tail;
+//      p->offset    = pos;
+//      p->size      = size;
+//      p->readcount = 1;
+//  }
+//  DEBUG_MAIN(("pst file old offset %#llx old size %#x read count %i offset %#llx size %#x\n",
+//              p->offset, p->size, p->readcount, pos, size));
+
+    if (fseek(pf->fp, pos, SEEK_SET) == -1) {
         DEBUG_RET();
-        return 1;
+        return 0;
     }
-    if (fread(buf, (size_t)1, size, fp) < size) {
-        DEBUG_RET();
-        return 2;
-    }
+    rc = fread(buf, (size_t)1, size, pf->fp);
     DEBUG_RET();
-    return 0;
+    return rc;
 }
 
 
 /**
  * Get an ID block from file using _pst_ff_getIDblock and decrypt if necessary
- * @param pf PST file structure
- * @param id ID of block to retrieve
- * @param b  Reference to pointer that will be set to new block. Any memory
-             pointed to by buffer will be free()d beforehand
- * @return   Size of block pointed to by *b
+ *
+ * @param pf   PST file structure
+ * @param id   ID of block to retrieve
+ * @param buf  Reference to pointer that will be set to new block. Any memory
+               pointed to by buffer will be free()d beforehand
+ * @return     Size of block pointed to by *b
  */
-size_t pst_ff_getIDblock_dec(pst_file *pf, uint64_t id, unsigned char **b) {
+size_t pst_ff_getIDblock_dec(pst_file *pf, uint64_t id, char **buf) {
     size_t r;
     int noenc = (int)(id & 2);   // disable encryption
     DEBUG_ENT("pst_ff_getIDblock_dec");
     DEBUG_INDEX(("for id %#x\n", id));
-    r = pst_ff_getIDblock(pf, id, b);
+    r = pst_ff_getIDblock(pf, id, buf);
     if ((pf->encryption) && !(noenc)) {
-        (void)pst_decrypt(*b, r, pf->encryption);
+        (void)pst_decrypt(*buf, r, pf->encryption);
     }
-    DEBUG_HEXDUMPC(*b, r, 16);
+    DEBUG_HEXDUMPC(*buf, r, 16);
     DEBUG_RET();
     return r;
 }
@@ -4266,47 +4297,31 @@
 
 /**
  * Read a block of data from file into memory
- * @param pf PST file
- * @param id identifier of block to read
- * @param b  reference to pointer to buffer. If this pointer
-             is non-NULL, it will first be free()d
- * @return   size of block read into memory
+ * @param pf   PST file
+ * @param id   identifier of block to read
+ * @param buf  reference to pointer to buffer. If this pointer
+               is non-NULL, it will first be free()d
+ * @return     size of block read into memory
  */
-size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) {
+size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, char** buf) {
     pst_index_ll *rec;
-    size_t rsize = 0;
+    size_t rsize;
     DEBUG_ENT("pst_ff_getIDblock");
-    if ((rec = pst_getID(pf, id)) == NULL) {
+    rec = pst_getID(pf, id);
+    if (!rec) {
         DEBUG_INDEX(("Cannot find ID %#llx\n", id));
         DEBUG_RET();
         return 0;
     }
-    (void)fseek(pf->fp, rec->offset, SEEK_SET);
-    if (*b) {
-        DEBUG_INDEX(("freeing old memory in b\n"));
-        free(*b);
-    }
-
     DEBUG_INDEX(("id = %#llx, record size = %#x, offset = %#x\n", id, rec->size, rec->offset));
-    *b = (char*) xmalloc(rec->size+1);
-    rsize = fread(*b, (size_t)1, rec->size, pf->fp);
-    if (rsize != rec->size) {
-        DEBUG_WARN(("Didn't read all the size. fread returned less [%i instead of %i]\n", rsize, rec->size));
-        if (feof(pf->fp)) {
-            DEBUG_WARN(("We tried to read past the end of the file [offset %#x, size %#x]\n", rec->offset, rec->size));
-        } else if (ferror(pf->fp)) {
-            DEBUG_WARN(("Some error occured on the file stream\n"));
-        } else {
-            DEBUG_WARN(("No error has been set on the file stream\n"));
-        }
-    }
+    rsize = pst_read_block_size(pf, rec->offset, rec->size, buf);
     DEBUG_RET();
     return rsize;
 }
 
 
 #define PST_PTR_BLOCK_SIZE 0x120
-size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) {
+size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, char** buf) {
     size_t ret;
     pst_index_ll* ptr;
     pst_holder h = {buf, NULL, 0, "", 0};
@@ -4326,7 +4341,7 @@
 
 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) {
     size_t ret;
-    unsigned char *b = NULL, *t;
+    char *b = NULL, *t;
     DEBUG_ENT("pst_ff_getID2data");
     if (!(ptr->id & 0x02)) {
         ret = pst_ff_getIDblock_dec(pf, ptr->id, &b);
@@ -4351,8 +4366,8 @@
         DEBUG_READ(("Assuming it is a multi-block record because of it's id\n"));
         ret = pst_ff_compile_ID(pf, ptr->id, h, (size_t)0);
     }
-    if (h->buf && *h->buf)
-        (*(h->buf))[ret]='\0';
+    // bogus null termination off the end of the buffer!!
+    //if (h->buf && *h->buf) (*(h->buf))[ret]='\0';
     DEBUG_RET();
     return ret;
 }
@@ -4361,8 +4376,8 @@
 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, pst_holder *h, size_t size) {
     size_t z, a, b;
     uint16_t count, y;
-    unsigned char * buf3 = NULL, *buf2 = NULL, *t;
-    unsigned char *b_ptr;
+    char * buf3 = NULL, *buf2 = NULL, *t;
+    char *b_ptr;
     pst_block_hdr  block_hdr;
     pst_table3_rec table3_rec;  //for type 3 (0x0101) blocks
 
@@ -4370,6 +4385,7 @@
     a = pst_ff_getIDblock(pf, id, &buf3);
     if (!a) {
         if (buf3) free(buf3);
+        DEBUG_RET();
         return 0;
     }
     DEBUG_HEXDUMPC(buf3, a, 0x10);
@@ -4409,6 +4425,7 @@
             DEBUG_WARN(("call to getIDblock returned zero %i\n", z));
             if (buf2) free(buf2);
             free(buf3);
+            DEBUG_RET();
             return z;
         }
         if (h->buf) {