int _dbx_getBody(FILE *fp, char** x, int ptr) { int bufsize = 0; struct _dbx_block_hdrstruct hdr; *x = NULL; while (ptr != 0) { RET_ERROR(_dbx_getAtPos(fp, ptr, &hdr, sizeof(hdr)), DBX_DATA_READ); LE32_CPU(hdr.self); LE32_CPU(hdr.nextaddressoffset); LE16_CPU(hdr.blocksize); LE32_CPU(hdr.nextaddress); /* this plus one will not be accumulative cause we don't add it to * bufsize but we need it so we can terminate the buffer */ *x = realloc(*x, bufsize + hdr.blocksize + 1); RET_ERROR(_dbx_get(fp, (*x)+bufsize, hdr.blocksize), DBX_DATA_READ); bufsize += hdr.blocksize; ptr = hdr.nextaddress; } if (*x) (*x)[bufsize] = '\0'; /* terminate the buffer */ /* size of data read */ return bufsize; }
int _dbx_getIndexes (FILE* fp, DBX *dbx) { int indexptr; int itemcount; /* first table of indexes */ if (_dbx_getAtPos(fp, INDEX_POINTER, &indexptr, sizeof(indexptr))) { dbx_errno = DBX_INDEX_READ; return 2; } LE32_CPU(indexptr); /* count of items */ if (_dbx_getAtPos(fp, ITEM_COUNT, &itemcount, sizeof(itemcount))) { dbx_errno = DBX_ITEMCOUNT; return 1; } LE32_CPU(itemcount); dbx->indexes = (int*) malloc(itemcount * sizeof(int)); dbx->indexCount = itemcount; if (_dbx_getindex(fp, indexptr, dbx)) { return 4; } if (dbx->indexCount != 0) { dbx_errno = DBX_INDEX_UNDERREAD; return 3; } /* reassign itemcount after call cause it should equal zero now */ dbx->indexCount = itemcount; return 0; }
void * dbx_get(DBX *dbx, int index, int flags) { int size; void * ret = NULL; if (!dbx || !dbx->fd) { dbx_errno = DBX_BADFILE; return NULL; } if (index >= dbx->indexCount || index < 0) { dbx_errno = DBX_INDEXCOUNT; return NULL; } if (dbx->type == DBX_TYPE_EMAIL || dbx->type == DBX_TYPE_FOLDER) { size = _dbx_getitem(dbx->fd, dbx->indexes[index], &ret, dbx->type, flags); ((DBXEMAIL*)ret)->num = index; } else { dbx_errno = DBX_BADFILE; return NULL; } dbx_errno = DBX_NOERROR; if (dbx->type == DBX_TYPE_EMAIL) { /* we explicitely need to swap the filetime */ LE32_CPU(((DBXEMAIL*)ret)->date.dwLowDateTime); LE32_CPU(((DBXEMAIL*)ret)->date.dwHighDateTime); /* we weren't allowed to swap 'flag' because it * is treated rather like a char */ LE32_CPU(((DBXEMAIL*)ret)->flag); } return ret; }
static void parse_header(uint8_t *header_data, lzfuheader *header) { memcpy(header, header_data, sizeof(*header)); LE32_CPU(header->cbSize); LE32_CPU(header->cbRawSize); LE32_CPU(header->dwMagic); LE32_CPU(header->dwCRC); /* OC_DEBUG(2, ("COMPSIZE = 0x%x", header->cbSize); OC_DEBUG(2, ("RAWSIZE = 0x%x", header->cbRawSize); OC_DEBUG(2, ("COMPTYPE = 0x%08x", header->dwMagic); // TODO: make this look like MS-OXRTFCP examples OC_DEBUG(2, ("CRC = 0x%08x", header->dwCRC); */ }
DBX *dbx_open_stream(FILE *fp) { DBX *dbx = (DBX*) malloc (sizeof(DBX)); int signature[4]; dbx->fd = fp; /* SIGNATURE */ _dbx_getAtPos(dbx->fd, 0x0, &signature, 16); LE32_CPU(signature[0]); LE32_CPU(signature[1]); LE32_CPU(signature[2]); LE32_CPU(signature[3]); if ( signature[0] == 0xFE12ADCF && signature[1] == 0x6F74FDC5 && signature[2] == 0x11D1E366 && signature[3] == 0xC0004E9A ) { /* OE 5 & OE 5 BETA SIGNATURE */ dbx->type = DBX_TYPE_EMAIL; } else if ( signature[0] == 0x36464D4A && signature[1] == 0x00010003 ) { /*It is an OE4 dbx file*/ dbx_errno = DBX_BADFILE; return NULL; } else if ( signature[0] == 0xFE12ADCF && signature[1] == 0x6F74FDC6 && /*Difference is C6 instead of C5*/ signature[2] == 0x11D1E366 && signature[3] == 0xC0004E9A ) { /*It is a Folders.dbx type file*/ dbx->type = DBX_TYPE_FOLDER; } else { dbx_errno = DBX_BADFILE; return NULL; } if (_dbx_getIndexes(dbx->fd, dbx)) { /* dbx_errno is already set by getIndexes */ return NULL; } dbx_errno = DBX_NOERROR; return dbx; }
int _dbx_getstruct(FILE *fp, int pos, DBXFOLDER* folder) { struct _dbx_folder_hdrstruct hdr; struct _dbx_folderstruct fol; char *buf, *fname; int msgoffset, blockpos=0; folder->name = NULL; RET_ERROR(_dbx_getAtPos(fp, pos, &hdr, sizeof(hdr)), DBX_DATA_READ); LE32_CPU(hdr.self); LE32_CPU(hdr.blocksize); LE16_CPU(hdr.unknown2); RET_ERROR(_dbx_get(fp, &fol, sizeof(fol)), DBX_DATA_READ); LE32_CPU(fol.id); LE32_CPU(fol.parent); LE32_CPU(fol.unknown6) blockpos += sizeof(hdr); buf = (char*) malloc(fol.length1); msgoffset = hdr.intcount * sizeof(int); RET_ERROR(_dbx_getAtPos(fp, pos+blockpos+msgoffset, buf, fol.length1), DBX_DATA_READ); if (strlen(buf) != fol.length1 - 1) { } /* Allocate space big enough to hold remainder of block */ fname = (char*) malloc(hdr.blocksize - blockpos); if (!fname) { return -1; } RET_ERROR(_dbx_get(fp, fname, hdr.blocksize-blockpos), DBX_DATA_READ); folder->name = buf; folder->fname = fname; folder->id = fol.id; folder->parentid = fol.parent; dbx_errno = DBX_NOERROR; return strlen(buf); }
int _dbx_getindex(FILE* fp, int pos, DBX *dbx) { int x; struct _dbx_tableindexstruct tindex; struct _dbx_indexstruct index; RET_ERROR(_dbx_getAtPos(fp, pos, &tindex, sizeof(tindex)), DBX_INDEX_READ); LE32_CPU(tindex.self); LE32_CPU(tindex.unknown1); LE32_CPU(tindex.anotherTablePtr); LE32_CPU(tindex.parent); LE32_CPU(tindex.indexCount); if (tindex.indexCount > 0) { _dbx_getindex (fp, tindex.anotherTablePtr, dbx); } pos += sizeof(struct _dbx_tableindexstruct); for (x = 1; x <= tindex.ptrCount; x++) { RET_ERROR(_dbx_getAtPos(fp, pos, &index, sizeof(struct _dbx_indexstruct)), DBX_INDEX_READ); LE32_CPU(index.indexptr); LE32_CPU(index.anotherTablePtr); LE32_CPU(index.indexCount); RET_ERROR(dbx->indexCount < 0, DBX_INDEX_OVERREAD); dbx->indexes[--dbx->indexCount] = index.indexptr; pos += sizeof(struct _dbx_indexstruct); if (index.indexCount > 0) _dbx_getindex(fp, index.anotherTablePtr, dbx); } return 0; }
int _dbx_getitem (FILE *fp, int pos, void **item, int type, int flags) { int x; char *bufptr, *buffer; void **bufx; int readtype=STRING_TYPE; DBXEMAIL *email = NULL; DBXFOLDER *folder = NULL; struct _dbx_email_headerstruct blockhdr; struct _dbx_email_pointerstruct blockp; int body = (flags&DBX_FLAG_BODY?1:0); if (type == DBX_TYPE_EMAIL) { email = (DBXEMAIL*) malloc(sizeof(DBXEMAIL)); memset (email, 0, sizeof(DBXEMAIL)); email->type = DBX_TYPE_EMAIL; *item = email; email->email = NULL; } else { folder = (DBXFOLDER*) malloc(sizeof(DBXFOLDER)); memset (folder, 0, sizeof(DBXFOLDER)); folder->type = DBX_TYPE_FOLDER; *item = folder; } RET_ERROR(_dbx_getAtPos(fp, pos, &blockhdr, sizeof(blockhdr)), DBX_INDEX_READ); LE32_CPU(blockhdr.self); LE32_CPU(blockhdr.size); LE32_CPU(blockhdr.u1); /* we will load all the block into memory * as we will be accessing it byte by byte */ buffer = (char*) malloc(blockhdr.size); RET_ERROR(_dbx_get(fp, buffer, blockhdr.size), DBX_DATA_READ); bufptr = buffer; if (email) email->data_offset = -1; for (x = 0; x < blockhdr.count; x++) { blockp.val = 0; memcpy(&(blockp.type), bufptr, 1); /* this will copy the type */ memcpy(&(blockp.val), bufptr+1, 3); /* and the 3 byte int */ /* we pretend it's a four byte integer */ LE32_CPU(blockp.val); if (type == DBX_TYPE_EMAIL) { switch (blockp.type) { case 0x01: /* pointer to flag */ email->flag = 0; bufx = (void**)&(email->flag); readtype = CHAR_TYPE; break; case 0x04: /*pointer to dataptr */ bufx = (void**)&(email->data_offset); readtype = INT_TYPE; break; case 0x05: /* asciiz string of subject (without RE: or FWD: etc...) */ bufx = (void**)&(email->psubject); readtype = STRING_TYPE; break; case 0x07: /* message id of email */ bufx = (void**)&(email->messageid); readtype = STRING_TYPE; break; case 0x08: /* second copy of subject. Original text (with RE: etc...) */ bufx = (void**)&(email->subject); readtype = STRING_TYPE; break; case 0x0A: /* msg-id of parent(s) */ bufx = (void**)&(email->parent_message_ids); readtype = STRING_TYPE; break; case 0x0C: /* name of server used to fetch email */ bufx = (void**)&(email->fetched_server); readtype = STRING_TYPE; break; case 0x0D: /* Sender's name */ bufx = (void**)&(email->sender_name); readtype = STRING_TYPE; break; case 0x0E: /* Sender's email address */ bufx = (void**)&(email->sender_address); readtype = STRING_TYPE; break; case 0x12: /* date - of what i'm not sure. * It is in a win32 FILETIME structure. * needs converting to something */ bufx = (void**)&(email->date); readtype = W32FT_TYPE; break; case 0x13: /* recipient's name */ bufx = (void**)&(email->recip_name); readtype = STRING_TYPE; break; case 0x14: /* recipient's email address */ bufx = (void**)&(email->recip_address); readtype = STRING_TYPE; break; case 0x1A: /* Name of Account used to fetch email */ bufx = (void**)&(email->oe_account_name); readtype = STRING_TYPE; break; case 0x1B: /* String version of account number * used to fetch email (eg "00000001") */ bufx = (void**)&(email->oe_account_num); readtype = STRING_TYPE; break; case 0x80: /* email's ID */ bufx = NULL; email->id = blockp.val; break; case 0x81: /* email's flag */ bufx=NULL; email->flag = blockp.val; break; case 0x84: /* direct offset of first email data block */ email->data_offset = blockp.val; bufx = NULL; break; /* case 0x02: //currently unknown case 0x06: //currently unknown case 0x09: case 0x0B: case 0x0C: case 0x11: //currently unknown case 0x1A: case 0x1B: case 0x1C: //currently unknown case 0x81: //currently unknown case 0x90: //currently unknown case 0x91: //currently unknown bufx = NULL; break; */ default: bufx = NULL; } } else { switch(blockp.type) { case 0x02: /* descriptive name */ bufx = (void**)&(folder->name); readtype = STRING_TYPE; break; case 0x03: /* filename */ bufx = (void**)&(folder->fname); readtype = STRING_TYPE; break; case 0x80: /* current id */ bufx = NULL; folder->id = blockp.val; break; case 0x81: /* parent id */ bufx = NULL; folder->parentid = blockp.val; break; /* case 0x86: //unknown case 0x87: //unknown case 0x88: //unknown case 0x8A: //unknown case 0x8B: //unknown bufx = NULL; break;*/ default: bufx = NULL; } } if (bufx) if (_dbx_get_from_buf(buffer, blockp.val + (blockhdr.count*4), bufx, readtype, blockhdr.size)) return 1; /* an error occured */ bufptr += 4; /* size of data */ } free (buffer); /* if we are doing folder types, we have now finished */ if (type == DBX_TYPE_FOLDER || body == 0) return 0; RET_ERROR(email->data_offset == -1, DBX_DATA_READ); return _dbx_getBody(fp, &(email->email), email->data_offset); }