From 17a8513e17af9e65ff2faad922c649859c8bcc3e Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Sun, 30 Aug 2020 22:04:19 -0700 Subject: [PATCH] SMBLIB support for filebases With very little change, SMB can accommodate file bases in addition to message bases. --- src/smblib/smbadd.c | 15 ++++- src/smblib/smbdefs.h | 103 +++++++++++++++++++++--------- src/smblib/smblib.c | 145 +++++++++++++++++++++++++++++-------------- src/smblib/smblib.h | 4 ++ 4 files changed, 189 insertions(+), 78 deletions(-) diff --git a/src/smblib/smbadd.c b/src/smblib/smbadd.c index 3ba1ac5d02..1af2a17b71 100644 --- a/src/smblib/smbadd.c +++ b/src/smblib/smbadd.c @@ -168,7 +168,11 @@ int SMBCALL smb_addmsg(smb_t* smb, smbmsg_t* msg, int storage, long dupechk_hash } msg->hdr.offset=offset; - smb_fseek(smb->sdt_fp,offset,SEEK_SET); + if(smb_fseek(smb->sdt_fp,offset,SEEK_SET) != 0) { + sprintf(smb->last_error, "%s seek error %d", __FUNCTION__, errno); + retval=SMB_ERR_SEEK; + break; + } if(bodylen) { if((retval=smb_dfield(msg,TEXT_BODY,bodylen))!=SMB_SUCCESS) @@ -300,7 +304,7 @@ int SMBCALL smb_addmsg(smb_t* smb, smbmsg_t* msg, int storage, long dupechk_hash if(!(smb->status.attr&(SMB_EMAIL|SMB_NOHASH)) && smb_addhashes(smb,hashes,/* skip_marked? */FALSE)==SMB_SUCCESS) msg->flags|=MSG_FLAG_HASHED; - if(msg->to==NULL) /* no recipient, don't add header (required for bulkmail) */ + if(msg->hdr.type == SMB_MSG_TYPE_NORMAL && msg->to == NULL) /* no recipient, don't add header (required for bulkmail) */ break; retval=smb_addmsghdr(smb,msg,storage); /* calls smb_unlocksmbhdr() */ @@ -463,3 +467,10 @@ int SMBCALL smb_addpollclosure(smb_t* smb, smbmsg_t* msg, int storage) return retval; } + +int SMBCALL smb_addfile(smb_t* smb, smbfile_t* file, int storage, const uchar* extdesc) +{ + file->hdr.type = SMB_MSG_TYPE_FILE; + + return smb_addmsg(smb, file, storage, SMB_HASH_SOURCE_NONE, XLAT_NONE, /* body: */extdesc, /* tail: */NULL); +} diff --git a/src/smblib/smbdefs.h b/src/smblib/smbdefs.h index 96cf8c9b31..59d6e37db8 100644 --- a/src/smblib/smbdefs.h +++ b/src/smblib/smbdefs.h @@ -92,9 +92,10 @@ #define SMB_FASTALLOC 1 /* Fast allocation */ /* status.attr bit flags: */ -#define SMB_EMAIL 1 /* User numbers stored in Indexes */ -#define SMB_HYPERALLOC 2 /* No allocation (also storage value for smb_addmsghdr) */ -#define SMB_NOHASH 4 /* Do not calculate or store hashes */ +#define SMB_EMAIL (1<<0) /* User numbers stored in Indexes */ +#define SMB_HYPERALLOC (1<<1) /* No allocation (also storage value for smb_addmsghdr) */ +#define SMB_NOHASH (1<<2) /* Do not calculate or store hashes */ +#define SMB_FILE_DIRECTORY (1<<3) /* Storage for a file area (for file transfers/downloads) */ /* Time zone macros for when_t.zone */ #define DAYLIGHT 0x8000 /* Daylight savings is active */ @@ -236,6 +237,9 @@ #define SMB_TAGS 0x69 /* List of tags (ala hash-tags) related to this message */ #define SMB_TAG_DELIMITER " " +#define SMB_FILENAME SUBJECT +#define SMB_FILEDESC SMB_SUMMARY + #define FILEATTACH 0x70 #define DESTFILE 0x71 #define FILEATTACHLIST 0x72 @@ -290,8 +294,8 @@ #define SMB_POLL_ANSWER 0xe0 /* the subject is the question */ -#define UNKNOWN 0xf1 -#define UNKNOWNASCII 0xf2 +#define UNKNOWN 0xf1 /* specified as 0xf0 in smb.txt/html - oops */ +#define UNKNOWNASCII 0xf2 /* specified as 0xf1 in smb.txt/html - oops */ #define UNUSED 0xff /* Valid dfield_t.types */ @@ -439,14 +443,14 @@ typedef struct _PACK { /* Time with time-zone */ typedef struct _PACK { /* Index record */ union { - struct _PACK { - uint16_t to; /* 16-bit CRC of recipient name (lower case) or user # */ - uint16_t from; /* 16-bit CRC of sender name (lower case) or user # */ - uint16_t subj; /* 16-bit CRC of subject (lower case, w/o RE:) */ + struct _PACK { /* when msg.type != BALLOT */ + uint16_t to; /* 16-bit CRC of recipient name (lower case) or user # */ + uint16_t from; /* 16-bit CRC of sender name (lower case) or user # */ + uint16_t subj; /* 16-bit CRC of subject (lower case, w/o RE:) */ }; - struct _PACK { - uint16_t votes; /* votes value */ - uint32_t remsg; /* number of message this vote is in response to */ + struct _PACK { /* when msg.type == BALLOT */ + uint16_t votes; /* votes value */ + uint32_t remsg; /* number of message this vote is in response to */ }; }; uint16_t attr; /* attributes (read, permanent, etc.) */ @@ -456,6 +460,15 @@ typedef struct _PACK { /* Index record */ } idxrec_t; +typedef struct _PACK { /* File index record */ + union { + struct { + idxrec_t idx; + char filename[64]; + }; + uint8_t padding[128]; + }; +} smbfileidxrec_t; /* valid bits in hash_t.flags */ #define SMB_HASH_CRC16 (1<<0) /* CRC-16 hash is valid */ #define SMB_HASH_CRC32 (1<<1) /* CRC-32 hash is valid */ @@ -511,15 +524,24 @@ typedef struct _PACK { /* Message base header (fixed portion) */ } smbhdr_t; -typedef struct _PACK { /* Message base status header */ +typedef struct _PACK { /* Message/File base status header */ - uint32_t last_msg; /* last message number */ - uint32_t total_msgs; /* total messages */ + union { + uint32_t last_msg; /* last message number */ + uint32_t last_file; /* last file number */ + }; + union { + uint32_t total_msgs; /* total messages */ + uint32_t total_files; /* total files */ + }; uint32_t header_offset; /* byte offset to first header record */ uint32_t max_crcs; /* Maximum number of CRCs to keep in history */ - uint32_t max_msgs; /* Maximum number of message to keep in sub */ - uint16_t max_age; /* Maximum age of message to keep in sub (in days) */ - uint16_t attr; /* Attributes for this message base (SMB_HYPER,etc) */ + union { + uint32_t max_msgs; /* Maximum number of message to keep in sub */ + uint32_t max_files; /* Maximum number of files to keep in dir */ + }; + uint16_t max_age; /* Maximum age of message/file to keep in sub (in days) */ + uint16_t attr; /* Attributes for this message/file base (SMB_HYPER,etc) */ } smbstatus_t; @@ -528,9 +550,10 @@ enum smb_msg_type { ,SMB_MSG_TYPE_POLL /* A poll question */ ,SMB_MSG_TYPE_BALLOT /* Voter response to poll or normal message */ ,SMB_MSG_TYPE_POLL_CLOSURE /* Closure of an existing poll */ + ,SMB_MSG_TYPE_FILE /* A file (e.g. for download) */ }; -typedef struct _PACK { /* Message header */ +typedef struct _PACK { /* Message/File header */ /* 00 */ uchar id[LEN_HEADER_ID]; /* SHD<^Z> */ /* 04 */ uint16_t type; /* Message type (enum smb_msg_type) */ @@ -545,7 +568,10 @@ typedef struct _PACK { /* Message header */ /* 24 */ uint32_t thread_back; /* Message number for backwards threading (aka thread_orig) */ /* 28 */ uint32_t thread_next; /* Next message in thread */ /* 2c */ uint32_t thread_first; /* First reply to this message */ - /* 30 */ uint16_t delivery_attempts; /* Delivery attempt counter */ + union { + /* 30 */ uint16_t delivery_attempts; /* Delivery attempt counter (for SMTP) */ + /* 30 */ uint16_t altpath; /* Alternate file storage path (when non-zero) */ + }; /* 32 */ int16_t votes; /* Votes value (response to poll) or maximum votes per ballot (poll) */ /* 34 */ uint32_t thread_id; /* Number of original message in thread (or 0 if unknown) */ /* 38 */ uint32_t times_downloaded; /* Total number of times downloaded (moved Mar-6-2012) */ @@ -597,7 +623,7 @@ typedef struct { /* Network (type and address) */ /* Valid bits in smbmsg_t.flags */ #define MSG_FLAG_HASHED (1<<0) /* Message has been hashed with smb_hashmsg() */ -typedef struct { /* Message */ +typedef struct { /* Message or File */ idxrec_t idx; /* Index */ msghdr_t hdr; /* Header record (fixed portion) */ @@ -623,9 +649,18 @@ typedef struct { /* Message */ *ftn_flags, /* FTN FLAGS */ *ftn_msgid, /* FTN MSGID */ *ftn_reply; /* FTN REPLY */ - char* summary; /* Summary */ - char* subj; /* Subject */ - char* tags; /* Message tags (space-delimited) */ + union { + char* summary; /* Message Summary */ + char* desc; /* File description */ + }; + union { + char* subj; /* Subject */ + char* filename; /* Filename */ + }; + union { + uchar* text; /* Message body text (optional) */ + uchar* extdesc; /* File extended description */ + }; uint16_t to_agent, /* Type of agent message is to */ from_agent, /* Type of agent message is from */ replyto_agent; /* Type of agent replies should be sent to */ @@ -646,10 +681,14 @@ typedef struct { /* Message */ uint32_t upvotes; /* Vote tally for this message */ uint32_t downvotes; /* Vote tally for this message */ uint32_t total_votes; /* Total votes for this message or poll */ + /* Not written to the database: */ + uint32_t dir; /* Directory number */ + off_t size; /* File size */ + time_t date; /* File date/timestamp (current) */ -} smbmsg_t; +} smbmsg_t, smbfile_t; -typedef struct { /* Message base */ +typedef struct { /* Message/File base */ char file[128]; /* Path and base filename (no extension) */ FILE* sdt_fp; /* File pointer for data (.sdt) file */ @@ -662,12 +701,18 @@ typedef struct { /* Message base */ uint32_t retry_delay; /* Time-slice yield (milliseconds) while retrying */ smbstatus_t status; /* Status header record */ BOOL locked; /* SMB header is locked */ - BOOL continue_on_error; /* Attempt recovery after some normaly fatal errors */ + BOOL continue_on_error; /* Attempt recovery after some normally fatal errors */ char last_error[MAX_PATH*2]; /* Last error message */ /* Private member variables (not initialized by or used by smblib) */ - uint32_t subnum; /* Sub-board number */ - uint32_t msgs; /* Number of messages loaded (for user) */ + union { + uint32_t subnum; /* Sub-board number */ + uint32_t dirnum; /* Directory number */ + }; + union { + uint32_t msgs; /* Number of messages loaded (for user) */ + uint32_t files; /* Number of files loaded */ + }; uint32_t curmsg; /* Current message number (for user, 0-based) */ } smb_t; diff --git a/src/smblib/smblib.c b/src/smblib/smblib.c index 45f82a701f..89ec363b7f 100644 --- a/src/smblib/smblib.c +++ b/src/smblib/smblib.c @@ -505,6 +505,7 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg) long byte_offset; ulong l,total,bot,top; long length; + size_t idxreclen = smb_idxreclen(smb); if(smb->sid_fp==NULL) { safe_snprintf(smb->last_error,sizeof(smb->last_error),"%s index not open", __FUNCTION__); @@ -513,12 +514,12 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg) clearerr(smb->sid_fp); length=filelength(fileno(smb->sid_fp)); - if(length<(long)sizeof(idxrec_t)) { + if(length<(long)idxreclen) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s invalid index file length: %ld", __FUNCTION__,length); return(SMB_ERR_FILE_LEN); } - total=length/sizeof(idxrec_t); + total=length/idxreclen; if(!total) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s invalid index file length: %ld", __FUNCTION__,length); @@ -527,9 +528,9 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg) if(!msg->hdr.number) { if(msg->offset<0) - byte_offset=length-((-msg->offset)*sizeof(idxrec_t)); + byte_offset=length-((-msg->offset)*idxreclen); else - byte_offset=msg->offset*sizeof(idxrec_t); + byte_offset=msg->offset*idxreclen; if(byte_offset>=length) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s invalid index offset: %ld, byte offset: %ld, length: %ld", __FUNCTION__ @@ -543,14 +544,14 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg) ,msg->offset,byte_offset); return(SMB_ERR_SEEK); } - if(smb_fread(smb,&msg->idx,sizeof(idxrec_t),smb->sid_fp)!=sizeof(idxrec_t)) { + if(smb_fread(smb,&msg->idx,sizeof(msg->idx),smb->sid_fp)!=sizeof(msg->idx)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s reading index at offset %ld (byte %lu)", __FUNCTION__ ,msg->offset,byte_offset); return(SMB_ERR_READ); } /* Save the correct offset (from the beginning of the file) */ - msg->offset=byte_offset/sizeof(idxrec_t); + msg->offset=byte_offset/idxreclen; return(SMB_SUCCESS); } @@ -563,17 +564,17 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg) , __FUNCTION__,msg->hdr.number); return(SMB_ERR_NOT_FOUND); } - if(fseek(smb->sid_fp,l*sizeof(idxrec_t),SEEK_SET)) { + if(fseek(smb->sid_fp,l*idxreclen,SEEK_SET)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s %d '%s' seeking to offset %lu (byte %lu) in index file", __FUNCTION__ ,get_errno(),STRERROR(get_errno()) - ,l,l*sizeof(idxrec_t)); + ,l,l*idxreclen); return(SMB_ERR_SEEK); } - if(smb_fread(smb,&idx,sizeof(idxrec_t),smb->sid_fp)!=sizeof(idxrec_t)) { + if(smb_fread(smb,&idx,sizeof(idx),smb->sid_fp)!=sizeof(idx)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s reading index at offset %lu (byte %lu)", __FUNCTION__ - ,l,l*sizeof(idxrec_t)); + ,l,l*sizeof(idx)); return(SMB_ERR_READ); } if(bot==top-1 && idx.number!=msg->hdr.number) { @@ -598,6 +599,35 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg) return(SMB_SUCCESS); } +/****************************************************************************/ +/* Count the number of msg index records with specific attribute flags */ +/****************************************************************************/ +uint32_t SMBCALL smb_count_idx_records(smb_t* smb, uint16_t mask, uint16_t cmp) +{ + int32_t offset = 0; + uint32_t count = 0; + for(offset = 0; ;offset++) { + smbmsg_t msg; + memset(&msg, 0, sizeof(msg)); + msg.offset = offset; + if(smb_getmsgidx(smb, &msg) != SMB_SUCCESS) + break; + if((msg.idx.attr & mask) == cmp) + count++; + } + return count; +} + +/****************************************************************************/ +/* Returns the length (in bytes) of the SMB's index records */ +/****************************************************************************/ +size_t SMBCALL smb_idxreclen(smb_t* smb) +{ + if(smb->status.attr&SMB_FILE_DIRECTORY) + return sizeof(smbfileidxrec_t); + return sizeof(idxrec_t); +} + /****************************************************************************/ /* Reads the first index record in the open message base */ /****************************************************************************/ @@ -614,7 +644,7 @@ int SMBCALL smb_getfirstidx(smb_t* smb, idxrec_t *idx) ,get_errno(),STRERROR(get_errno())); return(SMB_ERR_SEEK); } - if(smb_fread(smb,idx,sizeof(idxrec_t),smb->sid_fp)!=sizeof(idxrec_t)) { + if(smb_fread(smb,idx,sizeof(*idx),smb->sid_fp)!=sizeof(*idx)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s reading first index", __FUNCTION__); return(SMB_ERR_READ); @@ -628,6 +658,7 @@ int SMBCALL smb_getfirstidx(smb_t* smb, idxrec_t *idx) int SMBCALL smb_getlastidx(smb_t* smb, idxrec_t *idx) { long length; + size_t idxreclen = smb_idxreclen(smb); if(smb->sid_fp==NULL) { safe_snprintf(smb->last_error,sizeof(smb->last_error),"%s index not open", __FUNCTION__); @@ -635,19 +666,19 @@ int SMBCALL smb_getlastidx(smb_t* smb, idxrec_t *idx) } clearerr(smb->sid_fp); length=filelength(fileno(smb->sid_fp)); - if(length<(long)sizeof(idxrec_t)) { + if(length<(long)idxreclen) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s invalid index file length: %ld", __FUNCTION__,length); return(SMB_ERR_FILE_LEN); } - if(fseek(smb->sid_fp,length-sizeof(idxrec_t),SEEK_SET)) { + if(fseek(smb->sid_fp,length-idxreclen,SEEK_SET)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s %d '%s' seeking to %u in index file", __FUNCTION__ ,get_errno(),STRERROR(get_errno()) ,(unsigned)(length-sizeof(idxrec_t))); return(SMB_ERR_SEEK); } - if(smb_fread(smb,idx,sizeof(idxrec_t),smb->sid_fp)!=sizeof(idxrec_t)) { + if(smb_fread(smb,idx,sizeof(*idx),smb->sid_fp)!=sizeof(*idx)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s reading last index", __FUNCTION__); return(SMB_ERR_READ); @@ -667,6 +698,7 @@ long SMBCALL smb_getmsgidx_by_time(smb_t* smb, idxrec_t* match, time_t t) long match_offset; ulong total, bot, top; idxrec_t idx; + size_t idxreclen = smb_idxreclen(smb); if(match == NULL) return SMB_BAD_PARAMETER; @@ -676,7 +708,7 @@ long SMBCALL smb_getmsgidx_by_time(smb_t* smb, idxrec_t* match, time_t t) if(t <= 0) return SMB_BAD_PARAMETER; - total = filelength(fileno(smb->sid_fp))/sizeof(idxrec_t); + total = filelength(fileno(smb->sid_fp))/idxreclen; if(!total) /* Empty base */ return SMB_ERR_NOT_FOUND; @@ -696,9 +728,9 @@ long SMBCALL smb_getmsgidx_by_time(smb_t* smb, idxrec_t* match, time_t t) clearerr(smb->sid_fp); while(bot <= top) { long idx_offset = (bot + top) / 2; - if(fseek(smb->sid_fp, idx_offset * sizeof(idxrec_t), SEEK_SET) != 0) + if(fseek(smb->sid_fp, idx_offset * idxreclen, SEEK_SET) != 0) return SMB_ERR_SEEK; - if(fread(&idx, 1, sizeof(idx), smb->sid_fp) != sizeof(idxrec_t)) + if(fread(&idx, 1, sizeof(idx), smb->sid_fp) != sizeof(idx)) return SMB_ERR_READ; if((time_t)idx.time < t) { bot = idx_offset + 1; @@ -961,7 +993,7 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg) rewind(smb->shd_fp); if(fseek(smb->shd_fp,msg->idx.offset,SEEK_SET)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) - ,"%s %d '%s' seeking to %lu in header file", __FUNCTION__ + ,"%s %d '%s' seeking to offset %lu in header file", __FUNCTION__ ,get_errno(),STRERROR(get_errno()) ,msg->idx.offset); return(SMB_ERR_SEEK); @@ -974,7 +1006,7 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg) msg->offset=offset; if(smb_fread(smb,&msg->hdr,sizeof(msghdr_t),smb->shd_fp)!=sizeof(msghdr_t)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) - ,"%s reading msg header", __FUNCTION__); + ,"%s reading msg header at offset %lu", __FUNCTION__, msg->idx.offset); return(SMB_ERR_READ); } if(memcmp(msg->hdr.id,SHD_HEADER_ID,LEN_HEADER_ID)) { @@ -989,8 +1021,8 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg) } if(msg->hdr.version<0x110) { safe_snprintf(smb->last_error,sizeof(smb->last_error) - ,"%s insufficient header version: %X", __FUNCTION__ - ,msg->hdr.version); + ,"%s insufficient header version: %X at offset %lu", __FUNCTION__ + ,msg->hdr.version, msg->idx.offset); return(SMB_ERR_HDR_VER); } l=sizeof(msghdr_t); @@ -1116,6 +1148,10 @@ void SMBCALL smb_freemsgmem(smbmsg_t* msg) } msg->hdr.total_dfields=0; smb_freemsghdrmem(msg); + if(msg->text != NULL) { + free(msg->text); + msg->text = NULL; + } } /****************************************************************************/ @@ -1538,6 +1574,7 @@ int SMBCALL smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage) long l; ulong hdrlen; long idxlen; + size_t idxreclen = smb_idxreclen(smb); if(smb->shd_fp==NULL) { safe_snprintf(smb->last_error,sizeof(smb->last_error),"%s msgbase not open", __FUNCTION__); @@ -1562,10 +1599,10 @@ int SMBCALL smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage) } idxlen = filelength(fileno(smb->sid_fp)); - if(idxlen != (smb->status.total_msgs * sizeof(idxrec_t))) { + if(idxlen != (smb->status.total_msgs * idxreclen)) { safe_snprintf(smb->last_error, sizeof(smb->last_error) - ,"%s index file length (%ld) unexpected (%ld)", __FUNCTION__ - ,idxlen, smb->status.total_msgs * sizeof(idxrec_t)); + ,"%s index file length (%ld), expected (%ld)", __FUNCTION__ + ,idxlen, smb->status.total_msgs * idxreclen); smb_unlocksmbhdr(smb); return SMB_ERR_FILE_LEN; } @@ -1660,25 +1697,25 @@ int SMBCALL smb_putmsg(smb_t* smb, smbmsg_t* msg) /****************************************************************************/ int SMBCALL smb_init_idx(smb_t* smb, smbmsg_t* msg) { - msg->idx.subj=smb_subject_crc(msg->subj); - - if(smb->status.attr&SMB_EMAIL) { - if(msg->to_ext) - msg->idx.to=atoi(msg->to_ext); - else - msg->idx.to=0; - if(msg->from_ext) - msg->idx.from=atoi(msg->from_ext); - else - msg->idx.from=0; - } else if(msg->hdr.type == SMB_MSG_TYPE_BALLOT) { + if(msg->hdr.type == SMB_MSG_TYPE_BALLOT) { msg->idx.votes = msg->hdr.votes; msg->idx.remsg = msg->hdr.thread_back; } else { - msg->idx.to=smb_name_crc(msg->to); - msg->idx.from=smb_name_crc(msg->from); + msg->idx.subj = smb_subject_crc(msg->subj); + if(smb->status.attr&(SMB_EMAIL|SMB_FILE_DIRECTORY)) { + if(msg->to_ext) + msg->idx.to = atoi(msg->to_ext); + else + msg->idx.to = 0; + if(msg->from_ext) + msg->idx.from = atoi(msg->from_ext); + else + msg->idx.from = 0; + } else { + msg->idx.to = smb_name_crc(msg->to); + msg->idx.from = smb_name_crc(msg->from); + } } - /* Make sure these index/header fields are always *nsync */ msg->idx.number = msg->hdr.number; msg->idx.attr = msg->hdr.attr; @@ -1722,6 +1759,7 @@ uint16_t SMBCALL smb_voted_already(smb_t* smb, uint32_t msgnum, const char* name ,get_errno(), STRERROR(get_errno())); return SMB_ERR_SEEK; } + memset(&msg, 0, sizeof(msg)); while(!votes && smb_fread(smb, &msg.idx, sizeof(msg.idx), smb->sid_fp) == sizeof(msg.idx)) { if(!(msg.idx.attr&MSG_VOTE) || msg.idx.attr&MSG_POLL) continue; @@ -1756,6 +1794,7 @@ uint16_t SMBCALL smb_voted_already(smb_t* smb, uint32_t msgnum, const char* name int SMBCALL smb_putmsgidx(smb_t* smb, smbmsg_t* msg) { long length; + size_t idxreclen = smb_idxreclen(smb); if(smb->sid_fp==NULL) { safe_snprintf(smb->last_error,sizeof(smb->last_error),"%s index not open", __FUNCTION__); @@ -1763,23 +1802,35 @@ int SMBCALL smb_putmsgidx(smb_t* smb, smbmsg_t* msg) } clearerr(smb->sid_fp); length = filelength(fileno(smb->sid_fp)); - if(length < (long)(msg->offset*sizeof(idxrec_t))) { + if(length < (long)(msg->offset*idxreclen)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s invalid index offset: %ld, byte offset: %lu, length: %lu", __FUNCTION__ - ,msg->offset, msg->offset*sizeof(idxrec_t), length); + ,msg->offset, msg->offset*idxreclen, length); return(SMB_ERR_HDR_OFFSET); } - if(fseek(smb->sid_fp,msg->offset*sizeof(idxrec_t),SEEK_SET)) { + if(fseek(smb->sid_fp,msg->offset*idxreclen,SEEK_SET)) { safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"%s %d '%s' seeking to %u in index file", __FUNCTION__ ,get_errno(),STRERROR(get_errno()) - ,(unsigned)(msg->offset*sizeof(idxrec_t))); + ,(unsigned)(msg->offset*idxreclen)); return(SMB_ERR_SEEK); } - if(!fwrite(&msg->idx,sizeof(idxrec_t),1,smb->sid_fp)) { - safe_snprintf(smb->last_error,sizeof(smb->last_error) - ,"%s writing index", __FUNCTION__); - return(SMB_ERR_WRITE); + if(msg->hdr.type == SMB_MSG_TYPE_FILE) { + smbfileidxrec_t fidx = {0}; + fidx.idx = msg->idx; + strncpy(fidx.filename, msg->filename, sizeof(fidx.filename)); + if(!fwrite(&fidx, sizeof(fidx), 1, smb->sid_fp)) { + safe_snprintf(smb->last_error,sizeof(smb->last_error) + ,"%s %d '%s' writing index", __FUNCTION__ + ,get_errno(),STRERROR(get_errno())); + return(SMB_ERR_WRITE); + } + } else { + if(!fwrite(&msg->idx,sizeof(msg->idx),1,smb->sid_fp)) { + safe_snprintf(smb->last_error,sizeof(smb->last_error) + ,"%s writing index", __FUNCTION__); + return(SMB_ERR_WRITE); + } } return fflush(smb->sid_fp); /* SMB_SUCCESS == 0 */ } diff --git a/src/smblib/smblib.h b/src/smblib/smblib.h index eb58628b09..9e6731fbc1 100644 --- a/src/smblib/smblib.h +++ b/src/smblib/smblib.h @@ -71,6 +71,7 @@ #define SMB_SUCCESS 0 /* Successful result/return code */ #define SMB_FAILURE -1 /* Generic error (discouraged) */ #define SMB_BAD_PARAMETER -2 /* Invalid API function parameter value */ + /* Standard smblib errors values */ #define SMB_ERR_NOT_OPEN -100 /* Message base not open */ #define SMB_ERR_HDR_LEN -101 /* Invalid message header length (>64k) */ @@ -193,6 +194,8 @@ SMBEXPORT uint32_t SMBCALL smb_first_in_thread(smb_t*, smbmsg_t*, msghdr_t*); SMBEXPORT uint32_t SMBCALL smb_next_in_thread(smb_t*, smbmsg_t*, msghdr_t*); SMBEXPORT uint32_t SMBCALL smb_last_in_branch(smb_t*, smbmsg_t*); SMBEXPORT uint32_t SMBCALL smb_last_in_thread(smb_t*, smbmsg_t*); +SMBEXPORT size_t SMBCALL smb_idxreclen(smb_t*); +SMBEXPORT uint32_t SMBCALL smb_count_idx_records(smb_t*, uint16_t mask, uint16_t cmp); /* smbadd.c */ SMBEXPORT int SMBCALL smb_addmsg(smb_t* smb, smbmsg_t* msg, int storage, long dupechk_hashes @@ -200,6 +203,7 @@ SMBEXPORT int SMBCALL smb_addmsg(smb_t* smb, smbmsg_t* msg, int storage, long d SMBEXPORT int SMBCALL smb_addvote(smb_t* smb, smbmsg_t* msg, int storage); SMBEXPORT int SMBCALL smb_addpoll(smb_t* smb, smbmsg_t* msg, int storage); SMBEXPORT int SMBCALL smb_addpollclosure(smb_t* smb, smbmsg_t* msg, int storage); +SMBEXPORT int SMBCALL smb_addfile(smb_t* smb, smbfile_t* file, int storage, const uchar* extdesc); /* smballoc.c */ SMBEXPORT long SMBCALL smb_allochdr(smb_t* smb, ulong length); -- GitLab