Commit b72813e8 authored by Rob Swindell's avatar Rob Swindell 💬
Browse files

Support files > 4MB in SMB filebase indexes

Used the reserved 16-bits in the file index record to extend the supported index-file-size from 4294967295 (4GB) to 281474976710655 (281TB). I think that's big enough for the foreseeable future. :-)
parent 939d7e6e
Pipeline #2912 passed with stage
in 11 minutes and 42 seconds
......@@ -44,7 +44,7 @@ void sbbs_t::showfileinfo(file_t* f, bool show_extdesc)
bprintf(P_TRUNCATE, text[FiCredits]
,(cfg.dir[f->dir]->misc&DIR_FREE || !f->cost) ? "FREE" : ultoac((ulong)f->cost,tmp));
if(getfilesize(&cfg, f) > 0 && f->size == f->file_idx.idx.size) {
if(getfilesize(&cfg, f) > 0 && f->size == smb_getfilesize(&f->idx)) {
#if 0 // I don't think anyone cares about the CRC-16 checksum value of a file
if(f->file_idx.hash.flags & SMB_HASH_CRC16) {
SAFEPRINTF(tmp, "%04x", f->file_idx.hash.data.crc16);
......
......@@ -310,7 +310,12 @@ static int file_compare_size_a(const void* v1, const void* v2)
file_t* f1 = (file_t*)v1;
file_t* f2 = (file_t*)v2;
return f1->idx.size - f2->idx.size;
int64_t diff = smb_getfilesize(&f1->idx) - smb_getfilesize(&f2->idx);
if(diff < 0)
return -1;
if(diff > 0)
return 1;
return 0;
}
static int file_compare_size_d(const void* v1, const void* v2)
......@@ -318,7 +323,12 @@ static int file_compare_size_d(const void* v1, const void* v2)
file_t* f1 = (file_t*)v1;
file_t* f2 = (file_t*)v2;
return f2->idx.size - f1->idx.size;
int64_t diff = smb_getfilesize(&f2->idx) - smb_getfilesize(&f1->idx);
if(diff < 0)
return -1;
if(diff > 0)
return 1;
return 0;
}
void sortfiles(file_t* filelist, size_t count, enum file_sort order)
......
......@@ -254,7 +254,7 @@ set_file_properties(JSContext *cx, JSObject* obj, file_t* f, enum file_detail de
if(is_valid_dirnum(scfg, f->dir) && (scfg->dir[f->dir]->misc & DIR_FCHK) && detail >= file_detail_normal)
val = DOUBLE_TO_JSVAL((double)getfilesize(scfg, f));
else
val = UINT_TO_JSVAL(f->idx.size);
val = DOUBLE_TO_JSVAL((double)smb_getfilesize(&f->idx));
if(!JS_DefineProperty(cx, obj, "size", val, NULL, NULL, flags))
return false;
......@@ -328,11 +328,7 @@ parse_file_index_properties(JSContext *cx, JSObject* obj, fileidxrec_t* idx)
SAFECOPY(idx->name, cp);
}
if(JS_GetProperty(cx, obj, prop_name = "size", &val) && !JSVAL_NULL_OR_VOID(val)) {
if(!JS_ValueToECMAUint32(cx, val, &idx->idx.size)) {
free(cp);
JS_ReportError(cx, "Error converting adding '%s' property to Uint32", prop_name);
return FALSE;
}
smb_setfilesize(&idx->idx, (uint64_t)JSVAL_TO_DOUBLE(val));
}
if(JS_GetProperty(cx, obj, prop_name = "crc16", &val) && !JSVAL_NULL_OR_VOID(val)) {
idx->hash.data.crc16 = JSVAL_TO_INT(val);
......@@ -675,7 +671,7 @@ js_hash_file(JSContext *cx, uintN argc, jsval *arglist)
if(size == -1)
JS_ReportError(cx, "File does not exist: %s", path);
else {
file.idx.size = (uint32_t)size;
smb_setfilesize(&file.idx, size);
if((p->smb_result = smb_hashfile(path, size, &file.file_idx.hash.data)) > 0) {
file.file_idx.hash.flags = p->smb_result;
file.hdr.when_written.time = (uint32_t)fdate(path);
......
......@@ -581,7 +581,7 @@ void dumpindex(ulong start, ulong count)
printf("%10"PRIu32" ", idx.number);
switch(smb_msg_type(idx.attr)) {
case SMB_MSG_TYPE_FILE:
printf("F %10lu ", (ulong)idx.size);
printf("F %10"PRIu64" ", smb_getfilesize(&idx));
break;
case SMB_MSG_TYPE_BALLOT:
printf("V %04hX %-10"PRIu32, idx.votes,idx.remsg);
......
......@@ -393,7 +393,7 @@ typedef struct { /* Index record */
};
struct { /* when msg.type == FILE */
uint32_t size;
uint16_t unused; /* possibly store additional 16-bits of file size here */
uint16_t size_ext; /* store additional 16-bits of file size here */
};
};
smb_msg_attr_t attr; /* attributes (read, permanent, etc.) */
......
......@@ -221,6 +221,7 @@ int smb_findfile(smb_t* smb, const char* filename, smbfile_t* file)
smbfile_t file_ = {0};
if(f == NULL)
f = &file_;
uint64_t fsize;
char fname[SMB_FILEIDX_NAMELEN + 1] = "";
if(filename != NULL)
smb_fileidxname(filename, fname, sizeof(fname));
......@@ -249,8 +250,9 @@ int smb_findfile(smb_t* smb, const char* filename, smbfile_t* file)
if(file == NULL)
continue;
if((f->file_idx.hash.flags & SMB_HASH_MASK) != 0 || f->file_idx.idx.size > 0) {
if(f->file_idx.idx.size > 0 && f->file_idx.idx.size != fidx.idx.size)
fsize = smb_getfilesize(&f->idx);
if((f->file_idx.hash.flags & SMB_HASH_MASK) != 0 || fsize > 0) {
if(fsize > 0 && fsize != smb_getfilesize(&fidx.idx))
continue;
if((f->file_idx.hash.flags & SMB_HASH_CRC16) && f->file_idx.hash.data.crc16 != fidx.hash.data.crc16)
continue;
......@@ -460,3 +462,19 @@ int smb_removefile(smb_t* smb, smbfile_t* file)
smb_unlocksmbhdr(smb);
return result;
}
uint64_t smb_getfilesize(idxrec_t* idx)
{
return ((uint64_t)idx->size) | (((uint64_t)idx->size_ext) << 32);
}
int smb_setfilesize(idxrec_t* idx, uint64_t size)
{
if(size > 0xffffffffffffULL)
return SMB_ERR_FILE_LEN;
idx->size = (uint32_t)size;
idx->size_ext = (uint16_t)(size >> 32);
return SMB_SUCCESS;
}
......@@ -1730,7 +1730,7 @@ int smb_init_idx(smb_t* smb, smbmsg_t* msg)
if(msg->name != NULL)
smb_fileidxname(msg->name, msg->file_idx.name, sizeof(msg->file_idx.name));
if(msg->size > 0)
msg->idx.size = (uint32_t)msg->size;
smb_setfilesize(&msg->idx, msg->size);
} else {
msg->idx.subj = smb_subject_crc(msg->subj);
if(smb->status.attr & SMB_EMAIL) {
......
......@@ -295,6 +295,8 @@ SMBEXPORT int smb_loadfile(smb_t*, const char* filename, smbfile_t*, enum file_
SMBEXPORT void smb_freefilemem(smbfile_t*);
SMBEXPORT int smb_removefile(smb_t*, smbfile_t*);
SMBEXPORT char* smb_fileidxname(const char* filename, char* buf, size_t);
SMBEXPORT uint64_t smb_getfilesize(idxrec_t*);
SMBEXPORT int smb_setfilesize(idxrec_t*, uint64_t);
#ifdef __cplusplus
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment