Redone synchronet support

This commit is contained in:
Alexander S. Aganichev
2001-10-27 06:57:20 +00:00
parent fe06bc1747
commit a1e5aba0dd
17 changed files with 3536 additions and 1577 deletions

View File

@@ -2,7 +2,8 @@
TOP=../..
TARGET=gmb3
INCS=-I$(TOP)/goldlib/gall -I$(TOP)/goldlib/gcfg -I$(TOP)/goldlib/gmb3
INCS=-I$(TOP)/goldlib/gall -I$(TOP)/goldlib/gcfg -I$(TOP)/goldlib/gmb3 -I$(TOP)/goldlib/smblib
CFLAGS=-DGOLDEDPLUS
include $(TOP)/GNUmakef.inc
ifeq ($(PLATFORM),emx)

View File

@@ -46,7 +46,6 @@ gmopcbd4 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg
gmopcbd5 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg
gmosmb1 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
gmosmb2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
gmosmb3 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
gmosqsh1 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
gmosqsh2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
gmosqsh3 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg

View File

@@ -31,396 +31,22 @@
// ------------------------------------------------------------------
#include <smblib.h>
#include <gmoarea.h>
// ------------------------------------------------------------------
// SMB library version used as reference (1.21a)
const int SMB_VERSION = 0x0121; // SMB format version (High byte major, low byte minor)
// ------------------------------------------------------------------
const int SDT_BLOCK_LEN = 256; // Size of data blocks
const int SHD_BLOCK_LEN = 256; // Size of header blocks
const int SMB_SELFPACK = 0; // Self-packing storage allocation
const int SMB_FASTALLOC = 1; // Fast allocation
const int SMB_HYPERALLOC = 2; // No allocation
const int SMB_EMAIL = 1; // User numbers stored in Indexes
// Time zone macros for when_t.zone
const int DAYLIGHT = 0x8000; // Daylight savings is active
const int US_ZONE = 0x4000; // U.S. time zone
const int WESTERN_ZONE = 0x2000; // Non-standard zone west of UT
const int EASTERN_ZONE = 0x1000; // Non-standard zone east of UT
// Valid hfield_t.types
const int SENDER = 0x00;
const int SENDERAGENT = 0x01;
const int SENDERNETTYPE = 0x02;
const int SENDERNETADDR = 0x03;
const int SENDEREXT = 0x04;
const int SENDERPOS = 0x05;
const int SENDERORG = 0x06;
const int AUTHOR = 0x10;
const int AUTHORAGENT = 0x11;
const int AUTHORNETTYPE = 0x12;
const int AUTHORNETADDR = 0x13;
const int AUTHOREXT = 0x14;
const int AUTHORPOS = 0x15;
const int AUTHORORG = 0x16;
const int REPLYTO = 0x20;
const int REPLYTOAGENT = 0x21;
const int REPLYTONETTYPE = 0x22;
const int REPLYTONETADDR = 0x23;
const int REPLYTOEXT = 0x24;
const int REPLYTOPOS = 0x25;
const int REPLYTOORG = 0x26;
const int RECIPIENT = 0x30;
const int RECIPIENTAGENT = 0x31;
const int RECIPIENTNETTYPE = 0x32;
const int RECIPIENTNETADDR = 0x33;
const int RECIPIENTEXT = 0x34;
const int RECIPIENTPOS = 0x35;
const int RECIPIENTORG = 0x36;
const int FORWARDTO = 0x40;
const int FORWARDTOAGENT = 0x41;
const int FORWARDTONETTYPE = 0x42;
const int FORWARDTONETADDR = 0x43;
const int FORWARDTOEXT = 0x44;
const int FORWARDTOPOS = 0x45;
const int FORWARDTOORG = 0x46;
const int FORWARDED = 0x48;
const int RECEIVEDBY = 0x50;
const int RECEIVEDBYAGENT = 0x51;
const int RECEIVEDBYNETTYPE = 0x52;
const int RECEIVEDBYNETADDR = 0x53;
const int RECEIVEDBYEXT = 0x54;
const int RECEIVEDBYPOS = 0x55;
const int RECEIVEDBYORG = 0x56;
const int RECEIVED = 0x58;
const int SUBJECT = 0x60;
const int SUMMARY = 0x61;
const int SMBCOMMENT = 0x62;
const int CARBONCOPY = 0x63;
const int GROUP = 0x64;
const int EXPIRATION = 0x65;
const int PRIORITY = 0x66;
const int FILEATTACH = 0x70;
const int DESTFILE = 0x71;
const int FILEATTACHLIST = 0x72;
const int DESTFILELIST = 0x73;
const int FILEREQUEST = 0x74;
const int FILEPASSWORD = 0x75;
const int FILEREQUESTLIST = 0x76;
const int FILEPASSWORDLIST = 0x77;
const int IMAGEATTACH = 0x80;
const int ANIMATTACH = 0x81;
const int FONTATTACH = 0x82;
const int SOUNDATTACH = 0x83;
const int PRESENTATTACH = 0x84;
const int VIDEOATTACH = 0x85;
const int APPDATAATTACH = 0x86;
const int IMAGETRIGGER = 0x90;
const int ANIMTRIGGER = 0x91;
const int FONTTRIGGER = 0x92;
const int SOUNDTRIGGER = 0x93;
const int PRESENTTRIGGER = 0x94;
const int VIDEOTRIGGER = 0x95;
const int APPDATATRIGGER = 0x96;
const int FIDOCTRL = 0xa0;
const int FIDOAREA = 0xa1;
const int FIDOSEENBY = 0xa2;
const int FIDOPATH = 0xa3;
const int FIDOMSGID = 0xa4;
const int FIDOREPLYID = 0xa5;
const int FIDOPID = 0xa6;
const int FIDOFLAGS = 0xa7;
const int RFC822HEADER = 0xb0;
const int RFC822MSGID = 0xb1;
const int RFC822REPLYID = 0xb2;
const int UNKNOWN = 0xf1;
const int UNKNOWNASCII = 0xf2;
const int UNUSED = 0xff;
// Valid dfield_t.types
const int TEXT_BODY = 0x00;
const int TEXT_SOUL = 0x01;
const int TEXT_TAIL = 0x02;
const int TEXT_WING = 0x03;
const int IMAGEEMBED = 0x20;
const int ANIMEMBED = 0x21;
const int FONTEMBED = 0x22;
const int SOUNDEMBED = 0x23;
const int PRESENTEMBED = 0x24;
const int VIDEOEMBED = 0x25;
const int APPDATAEMBED = 0x26;
//const int UNUSED = 0xff;
// Message attributes
const int MSG_PRIVATE = (1<<0);
const int MSG_READ = (1<<1);
const int MSG_PERMANENT = (1<<2);
const int MSG_LOCKED = (1<<3);
const int MSG_DELETE = (1<<4);
const int MSG_ANONYMOUS = (1<<5);
const int MSG_KILLREAD = (1<<6);
const int MSG_MODERATED = (1<<7);
const int MSG_VALIDATED = (1<<8);
// Auxillary header attributes
const int MSG_FILEREQUEST = (1<<0); // File request
const int MSG_FILEATTACH = (1<<1); // File(s) attached to Msg
const int MSG_TRUNCFILE = (1<<2); // Truncate file(s) when sent
const int MSG_KILLFILE = (1<<3); // Delete file(s) when sent
const int MSG_RECEIPTREQ = (1<<4); // Return receipt requested
const int MSG_CONFIRMREQ = (1<<5); // Confirmation receipt requested
const int MSG_NODISP = (1<<6); // Msg may not be displayed to user
// Message network attributes
const int MSG_LOCAL = (1<<0); // Msg created locally
const int MSG_INTRANSIT = (1<<1); // Msg is in-transit
const int MSG_SENT = (1<<2); // Sent to remote
const int MSG_KILLSENT = (1<<3); // Kill when sent
const int MSG_ARCHIVESENT = (1<<4); // Archive when sent
const int MSG_HOLD = (1<<5); // Hold for pick-up
const int MSG_CRASH = (1<<6); // Crash
const int MSG_IMMEDIATE = (1<<7); // Send Msg now, ignore restrictions
const int MSG_DIRECT = (1<<8); // Send directly to destination
const int MSG_GATE = (1<<9); // Send via gateway
const int MSG_ORPHAN = (1<<10); // Unknown destination
const int MSG_FPU = (1<<11); // Force pickup
const int MSG_TYPELOCAL = (1<<12); // Msg is for local use only
const int MSG_TYPEECHO = (1<<13); // Msg is for conference distribution
const int MSG_TYPENET = (1<<14); // Msg is direct network mail
enum {
NET_NONE,
NET_UNKNOWN,
NET_FIDO,
NET_POSTLINK,
NET_QWK,
NET_INTERNET,
NET_WWIV,
NET_MHS,
// Add new ones here
NET_TYPES
};
enum {
AGENT_PERSON,
AGENT_PROCESS,
// Add new ones here
AGENT_TYPES
};
enum {
XLAT_NONE, // No translation/End of translation list
XLAT_ENCRYPT, // Encrypted data
XLAT_ESCAPED, // 7-bit ASCII escaping for ctrl and 8-bit data
XLAT_HUFFMAN, // Static and adaptive Huffman coding compression
XLAT_LZW, // Limpel/Ziv/Welch compression
XLAT_MLZ78, // Modified LZ78 compression
XLAT_RLE, // Run length encoding compression
XLAT_IMPLODE, // Implode compression (PkZIP)
XLAT_SHRINK, // Shrink compression (PkZIP)
XLAT_LZH, // LHarc (LHA) Dynamic Huffman coding
// Add new ones here
XLAT_TYPES
};
// ------------------------------------------------------------------
#if defined(GOLD_CANPACK)
#pragma pack(1)
#endif
// ------------------------------------------------------------------
typedef struct {
time_t time; // Local time (unix format)
sword zone; // Time zone
} when_t;
typedef struct {
word to; // 16-bit CRC of recipient name (lower case)
word from; // 16-bit CRC of sender name (lower case)
word subj; // 16-bit CRC of subject (lower case, w/o RE:)
word attr; // attributes (read, permanent, etc.)
dword offset; // offset into header file
dword number; // number of message (1 based)
time_t time; // time/date message was imported/posted
} idxrec_t;
typedef struct {
uchar id[4]; // text or binary unique hdr ID
word version; // version number (initially 100h for 1.00)
word length; // length including this struct
} smbhdr_t;
typedef struct {
dword last_msg; // last message number
dword total_msgs; // total messages
dword header_offset; // byte offset to first header record
dword max_crcs; // Maximum number of CRCs to keep in history
dword max_msgs; // Maximum number of message to keep in sub
word max_age; // Maximum age of message to keep in sub (in days)
word attr; // Attributes for this message base (SMB_HYPER, etc)
} smbstatus_t;
typedef struct {
uchar id[4]; // SHD<^Z>
word type; // Message type (normally 0)
word version; // Version of type (initially 100h for 1.00)
word length; // Total length of fixed record + all fields
word attr; // Attributes (bit field) (duped in SID)
dword auxattr; // Auxillary attributes (bit field)
dword netattr; // Network attributes
when_t when_written; // Time message was written (unix format)
when_t when_imported; // Time message was imported
dword number; // Message number
dword thread_orig; // Original message number in thread
dword thread_next; // Next message in thread
dword thread_first; // First reply to this message
uchar reserved[16]; // Reserved for future use
dword offset; // Offset for buffer into data file (0 or mod 256)
word total_dfields; // Total number of data fields
} msghdr_t;
typedef struct {
word type; // Type of data field
dword offset; // Offset into buffer
dword length; // Length of data field
} dfield_t;
typedef struct {
word type;
word length; // Length of buffer
} hfield_t;
typedef struct {
word zone, net, node, point;
} fidoaddr_t;
typedef struct {
word type;
void *addr;
} net_t;
// ------------------------------------------------------------------
#if defined(GOLD_CANPACK)
#pragma pack()
#endif
// ------------------------------------------------------------------
typedef struct {
idxrec_t idx; // Index
msghdr_t hdr; // Header record (fixed portion)
uchar *to, // To name
*to_ext, // To extension
*from, // From name
*from_ext, // From extension
*replyto, // Reply-to name
*replyto_ext, // Reply-to extension */
*subj; // Subject
word 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
net_t to_net, // Destination network type and address
from_net, // Origin network address
replyto_net; // Network type and address for replies
word total_hfields; // Total number of header fields
hfield_t *hfield; // Header fields (fixed length portion)
void **hfield_dat; // Header fields (variable length portion)
dfield_t *dfield; // Data fields (fixed length portion)
dword offset; // Offset (number of records) into index
uchar forwarded; // Forwarded from agent to another
} smbmsg_t;
// ------------------------------------------------------------------
struct SMBData {
char shd_buf[SHD_BLOCK_LEN];
FILE *sdt_fp, *shd_fp, *sid_fp, *sda_fp, *sha_fp;
};
// ------------------------------------------------------------------
class SMBArea : public gmo_area {
protected:
SMBData* data;
smb_t *data;
void data_open();
void data_close();
void raw_scan(bool keep_index=false, bool scanpm=false);
FILE* smb_openexlusively(const char *file, int retry_time);
int smb_openexlusively2(const char *file, int retry_time);
int smb_open(int retry_time);
void smb_close(void);
int smb_open_da(int retry_time);
int smb_open_ha(int retry_time);
int smb_create(dword max_crcs, dword max_msgs, word max_age, word attr, int retry_time);
int smb_trunchdr(int retry_time);
int smb_locksmbhdr(int retry_time);
int smb_getstatus(smbstatus_t *status);
int smb_putstatus(smbstatus_t status);
int smb_unlocksmbhdr(void);
int smb_getmsgidx(smbmsg_t *msg);
int smb_getlastidx(idxrec_t *idx);
uint smb_getmsghdrlen(smbmsg_t msg);
dword smb_getmsgdatlen(smbmsg_t msg);
int smb_lockmsghdr(smbmsg_t msg, int retry_time);
int smb_getmsghdr(smbmsg_t *msg);
int smb_unlockmsghdr(smbmsg_t msg);
int smb_addcrc(dword max_crcs, dword crc, int retry_time);
int smb_hfield(smbmsg_t *msg, word type, word length, void *data);
int smb_dfield(smbmsg_t *msg, word type, dword length);
int smb_addmsghdr(smbmsg_t *msg, smbstatus_t *status, int storage, int retry_time);
int smb_putmsg(smbmsg_t msg);
int smb_putmsgidx(smbmsg_t msg);
int smb_putmsghdr(smbmsg_t msg);
void smb_freemsgmem(smbmsg_t msg);
dword smb_hdrblocks(dword length);
dword smb_datblocks(dword length);
long smb_allochdr(dword length);
long smb_fallochdr(dword length);
long smb_hallochdr(dword header_offset);
long smb_allocdat(dword length, word headers);
long smb_fallocdat(dword length, word headers);
long smb_hallocdat(void);
int smb_incdat(dword offset, dword length, word headers);
int smb_freemsg(smbmsg_t msg, smbstatus_t status);
int smb_freemsgdat(dword offset, dword length, word headers);
int smb_freemsghdr(dword offset, dword length);
int load_hdr(gmsg* __msg, smbmsg_t *msg);
public:
@@ -464,7 +90,7 @@ public:
// ------------------------------------------------------------------
extern SMBData* smbdata;
extern smb_t *smbdata;
extern int smbdatano;

View File

@@ -30,13 +30,12 @@
#include <gmemdbg.h>
#include <gdbgerr.h>
#include <gdbgtrk.h>
#include <glzh.h>
#include <gmosmb.h>
// ------------------------------------------------------------------
SMBData* smbdata = NULL;
smb_t* smbdata = NULL;
int smbdatano = 0;
@@ -52,71 +51,7 @@ void SMBExit() {
void SMBInit() {
smbdata = (SMBData*)throw_calloc(3, sizeof(SMBData));
}
// ------------------------------------------------------------------
FILE* SMBArea::smb_openexlusively(const char *__file, int retry_time) {
FILE *_f;
long _tries = 0;
do {
_f = fsopen(__file, "rb+", SH_DENYRW);
if(_f == NULL) {
if((errno != EACCES) or (PopupLocked(++_tries, false, __file) == false)) {
// User requested to exit
WideLog->ErrOpen();
WideLog->printf("! Synchronet message base could not be opened (exclusively).");
WideLog->printf(": %s", __file);
WideLog->ErrOSInfo();
OpenErrorExit();
}
}
} while(_f == NULL);
// Remove the popup window
if(_tries)
PopupLocked(0, 0, NULL);
return _f;
}
// ------------------------------------------------------------------
int SMBArea::smb_openexlusively2(const char *__file, int retry_time) {
int _fh;
long _tries = 0;
do {
_fh = ::sopen(__file, O_RDWR|O_CREAT|O_BINARY, SH_DENYRW, S_STDRW);
if(_fh == -1) {
if((errno != EACCES) or (PopupLocked(++_tries, false, __file) == false)) {
// User requested to exit
WideLog->ErrOpen();
WideLog->printf("! Synchronet message base could not be opened (exclusively).");
WideLog->printf(": %s", __file);
WideLog->ErrOSInfo();
OpenErrorExit();
}
}
} while(_fh == -1);
// Remove the popup window
if(_tries)
PopupLocked(0, 0, NULL);
return _fh;
smbdata = (smb_t *)throw_calloc(3, sizeof(smb_t));
}
@@ -125,7 +60,10 @@ int SMBArea::smb_openexlusively2(const char *__file, int retry_time) {
void SMBArea::data_open() {
data = smbdata + (smbdatano++);
strxcpy(data->file, path(), sizeof(data->file) - 3);
data->sdt_fp = data->shd_fp = data->sid_fp = data->sda_fp = data->sha_fp = NULL;
data->retry_time = 1;
data->last_error[0] = NUL;
}
@@ -156,9 +94,45 @@ void SMBArea::open() {
}
if(isopen == 1) {
data_open();
smb_open(10);
if(not fsize(data->shd_fp))
smb_create(2000, 2000, 0, 0, 10);
int _tries = 0;
for(;;) {
if(smb_open(data) != 0) {
if((errno != EACCES) or (PopupLocked(++_tries, false, data->file) == false)) {
// User requested to exit
WideLog->ErrOpen();
WideLog->printf("! Synchronet message base could not be opened (%s).", data->last_error);
WideLog->printf(": %s", path());
WideLog->ErrOSInfo();
OpenErrorExit();
}
}
else
break;
};
// Remove the popup window
if(_tries)
PopupLocked(0, 0, NULL);
if(not fsize(data->shd_fp)) {
data->status.max_crcs = 0;
data->status.max_age = 0;
data->status.max_msgs = 1000;
data->status.attr = 0;
if(smb_create(data) != 0) {
smb_close(data);
WideLog->ErrOpen();
WideLog->printf("! Synchronet message base could not be created (%s).", data->last_error);
WideLog->printf(": %s", path());
WideLog->ErrOSInfo();
OpenErrorExit();
}
}
scan();
}
@@ -174,7 +148,7 @@ void SMBArea::close()
if(isopen) {
if(isopen == 1) {
smb_close();
smb_close(data);
data_close();
}
isopen--;
@@ -196,7 +170,7 @@ void SMBArea::close()
void SMBArea::suspend()
{
smb_close();
smb_close(data);
}
@@ -204,9 +178,44 @@ void SMBArea::suspend()
void SMBArea::resume()
{
smb_open(10);
if(not fsize(data->shd_fp))
smb_create(2000, 2000, 0, 0, 10);
int _tries = 0;
for(;;) {
if(smb_open(data) != 0) {
if((errno != EACCES) or (PopupLocked(++_tries, false, data->file) == false)) {
// User requested to exit
WideLog->ErrOpen();
WideLog->printf("! Synchronet message base could not be opened (%s).", data->last_error);
WideLog->printf(": %s", path());
WideLog->ErrOSInfo();
OpenErrorExit();
}
}
else
break;
};
// Remove the popup window
if(_tries)
PopupLocked(0, 0, NULL);
if(not fsize(data->shd_fp)) {
data->status.max_crcs = 0;
data->status.max_age = 0;
data->status.max_msgs = 1000;
data->status.attr = 0;
if(smb_create(data) != 0) {
smb_close(data);
WideLog->ErrOpen();
WideLog->printf("! Synchronet message base could not be created (%s).", data->last_error);
WideLog->printf(": %s", path());
WideLog->ErrOSInfo();
OpenErrorExit();
}
}
}
@@ -238,12 +247,12 @@ int SMBArea::load_hdr(gmsg* __msg, smbmsg_t *smsg)
return false;
}
fseek(data->sid_fp, (reln - 1L) * sizeof(idxrec_t), SEEK_SET);
if(not fread(&smsgp->idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(*smsgp, 10) != 0)) {
if(not fread(&smsgp->idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(data, smsgp) != 0)) {
GFTRK(NULL);
return false;
}
int rv = smb_getmsghdr(smsgp);
smb_unlockmsghdr(*smsgp);
int rv = smb_getmsghdr(data, smsgp);
smb_unlockmsghdr(data, smsgp);
if(rv != 0) {
GFTRK(NULL);
return false;
@@ -315,7 +324,7 @@ int SMBArea::load_hdr(gmsg* __msg, smbmsg_t *smsg)
__msg->received = 0;
if(not smsg)
smb_freemsgmem(*smsgp);
smb_freemsgmem(smsgp);
GFTRK(NULL);
return true;
}
@@ -327,7 +336,7 @@ int SMBArea::load_msg(gmsg* msg)
{
smbmsg_t smsg;
ushort xlat;
char *inbuf;
uchar *inbuf;
long outlen;
char buf[512];
int i;
@@ -425,11 +434,11 @@ common:
l += 2;
}
if(lzh) {
inbuf = (char *)throw_xmalloc(smsg.dfield[i].length);
inbuf = (uchar *)throw_xmalloc(smsg.dfield[i].length);
fread(inbuf, smsg.dfield[i].length - l, 1, data->sdt_fp);
outlen = *(long *)inbuf;
msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen);
glzh_decode(inbuf, smsg.dfield[i].length - l, msg->txt+txt_len-1);
lzh_decode(inbuf, smsg.dfield[i].length - l, (uchar *)(msg->txt+txt_len-1));
throw_xfree(inbuf);
} else {
outlen = smsg.dfield[i].length - l;
@@ -464,7 +473,7 @@ add2:
}
smb_freemsgmem(smsg);
smb_freemsgmem(&smsg);
GFTRK(NULL);
return true;
@@ -482,12 +491,11 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
char *fbuf, *sbody, *stail;
char buf[256];
smbmsg_t smsg;
smbstatus_t status;
fidoaddr_t destaddr, origaddr;
GFTRK("SMBSaveHdr");
smb_getstatus(&status);
smb_getstatus(data);
memset(&smsg, 0, sizeof(smbmsg_t));
if(not (mode & GMSG_NEW)) {
ulong reln = Msgn->ToReln(msg->msgno);
@@ -496,12 +504,12 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
return;
}
fseek(data->sid_fp, (reln - 1L) * sizeof(idxrec_t), SEEK_SET);
if(not fread(&smsg.idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(smsg, 10) != 0)) {
if(not fread(&smsg.idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(data, &smsg) != 0)) {
GFTRK(NULL);
return;
}
int rv = smb_getmsghdr(&smsg);
smb_unlockmsghdr(smsg);
int rv = smb_getmsghdr(data, &smsg);
smb_unlockmsghdr(data, &smsg);
if(rv != 0) {
GFTRK(NULL);
return;
@@ -512,7 +520,7 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
}
else {
memcpy(smsg.hdr.id, "SHD\x1a", 4);
smsg.hdr.version = SMB_VERSION;
smsg.hdr.version = smb_ver();
struct tm *tp = gmtime(&msg->written);
tp->tm_isdst = -1;
smsg.hdr.when_written.time = mktime(tp);
@@ -548,23 +556,28 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
if((mode & GMSG_UPDATE) and not (mode & GMSG_TXT)) {
if(mode & GMSG_NEW)
smb_addmsghdr(&smsg, &status, 1, 10);
smb_addmsghdr(data, &smsg, data->status.attr & SMB_HYPERALLOC);
else
smb_putmsghdr(smsg);
smb_freemsgmem(smsg);
smb_putmsghdr(data, &smsg);
smb_freemsgmem(&smsg);
GFTRK(NULL);
return;
}
if(not (mode & GMSG_NEW)) {
if(smb_open_da(10) == 0) {
if(smb_open_ha(10) == 0) {
smb_freemsg(smsg, status);
fclose(data->sha_fp);
if(not (data->status.attr & SMB_HYPERALLOC)) {
if(smb_open_da(data) == 0) {
if(smb_open_ha(data) == 0) {
smb_freemsg(data, &smsg);
smb_close_ha(data);
}
smb_close_da(data);
}
fclose(data->sda_fp);
}
smb_freemsgmem(smsg);
else {
smb_freemsg(data, &smsg);
}
smb_freemsgmem(&smsg);
smsg.dfield = NULL;
smsg.hdr.total_dfields = 0;
smsg.total_hfields = 0;
@@ -703,44 +716,53 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
bodylen-=2; // remove last CRLF if present
crc = ~memCrc32(sbody, bodylen, false, CRC32_MASK_CCITT);
rv = smb_addcrc(status.max_crcs, crc, 10);
rv = smb_addcrc(data, crc);
while(taillen and (iscntrl(stail[taillen-1]) or isspace(stail[taillen-1])))
taillen--;
if(smb_open_da(10) == 0) {
l = bodylen+2;
if(taillen)
l += (taillen+2);
smsg.hdr.offset = smb_fallocdat(l, 1);
fclose(data->sda_fp);
if(not (smsg.hdr.offset and smsg.hdr.offset<1L)) {
fseek(data->sdt_fp, smsg.hdr.offset, SEEK_SET);
ushort xlat = XLAT_NONE;
fwrite(&xlat, 2, 1, data->sdt_fp);
l = ftell(data->sdt_fp);
fwrite(sbody, SDT_BLOCK_LEN, smb_datblocks(bodylen), data->sdt_fp);
if(taillen) {
fseek(data->sdt_fp, l+bodylen, SEEK_SET);
fwrite(&xlat, 2, 1, data->sdt_fp);
fwrite(stail, SDT_BLOCK_LEN, smb_datblocks(taillen), data->sdt_fp);
}
fflush(data->sdt_fp);
smb_dfield(&smsg, TEXT_BODY, bodylen+2);
if(taillen)
smb_dfield(&smsg, TEXT_TAIL, taillen+2);
l = bodylen+2;
if(taillen)
l += (taillen+2);
if(mode & GMSG_NEW) {
smb_addmsghdr(&smsg, &status, 1, 10);
Msgn->Append(smsg.hdr.number);
}
else
smb_putmsghdr(smsg);
if(not (data->status.attr & SMB_HYPERALLOC)) {
if(smb_open_da(data) == 0) {
smsg.hdr.offset = smb_allocdat(data, l, 1);
smb_close_da(data);
}
else
smsg.hdr.offset = -1L;
}
else {
smsg.hdr.offset = smb_hallocdat(data);
}
if(smsg.hdr.offset >= 0) {
fseek(data->sdt_fp, smsg.hdr.offset, SEEK_SET);
ushort xlat = XLAT_NONE;
fwrite(&xlat, 2, 1, data->sdt_fp);
l = ftell(data->sdt_fp);
fwrite(sbody, SDT_BLOCK_LEN, smb_datblocks(bodylen), data->sdt_fp);
if(taillen) {
fseek(data->sdt_fp, l+bodylen, SEEK_SET);
fwrite(&xlat, 2, 1, data->sdt_fp);
fwrite(stail, SDT_BLOCK_LEN, smb_datblocks(taillen), data->sdt_fp);
}
fflush(data->sdt_fp);
smb_dfield(&smsg, TEXT_BODY, bodylen+2);
if(taillen)
smb_dfield(&smsg, TEXT_TAIL, taillen+2);
if(mode & GMSG_NEW) {
smb_addmsghdr(data, &smsg, data->status.attr & SMB_HYPERALLOC);
Msgn->Append(smsg.hdr.number);
}
else
smb_putmsghdr(data, &smsg);
}
throw_xfree(sbody);
throw_xfree(stail);
smb_freemsgmem(smsg);
smb_freemsgmem(&smsg);
GFTRK(NULL);
}
@@ -771,20 +793,20 @@ void SMBArea::del_msg(gmsg* msg)
return;
}
fseek(data->sid_fp, (reln - 1L) * sizeof(idxrec_t), SEEK_SET);
if(not fread(&smsg.idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(smsg, 10) != 0)) {
if(not fread(&smsg.idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(data, &smsg) != 0)) {
GFTRK(NULL);
return;
}
if(smb_getmsghdr(&smsg) == 0) {
if(smb_getmsghdr(data, &smsg) == 0) {
smsg.hdr.attr |= MSG_DELETE;
int rv = smb_putmsghdr(smsg);
smb_unlockmsghdr(smsg);
int rv = smb_putmsghdr(data, &smsg);
smb_unlockmsghdr(data, &smsg);
if(rv == 0)
msg->attr.del1();
}
else
smb_unlockmsghdr(smsg);
smb_freemsgmem(smsg);
smb_unlockmsghdr(data, &smsg);
smb_freemsgmem(&smsg);
GFTRK(NULL);
}
@@ -794,10 +816,9 @@ void SMBArea::del_msg(gmsg* msg)
void SMBArea::new_msgno(gmsg* msg)
{
smbstatus_t status;
int res = smb_getstatus(&status);
smb_unlocksmbhdr();
msg->msgno = (res == 0) ? status.last_msg+1 : 0;
int res = smb_getstatus(data);
smb_unlocksmbhdr(data);
msg->msgno = (res == 0) ? data->status.last_msg+1 : 0;
}
@@ -971,7 +992,7 @@ Line* SMBArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head)
line = AddLine(line, buf);
ushort xlat;
char *inbuf;
uchar *inbuf;
long outlen;
bool lzh;
bool tail = true;
@@ -1004,11 +1025,11 @@ common:
l += 2;
}
if(lzh) {
inbuf = (char *)throw_xmalloc(smsg.dfield[i].length);
inbuf = (uchar *)throw_xmalloc(smsg.dfield[i].length);
fread(inbuf, smsg.dfield[i].length - l, 1, data->sdt_fp);
outlen = *(long *)inbuf;
msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen);
glzh_decode(inbuf, smsg.dfield[i].length - l, msg->txt+txt_len-1);
lzh_decode(inbuf, smsg.dfield[i].length - l, (uchar *)(msg->txt+txt_len-1));
throw_xfree(inbuf);
} else {
outlen = smsg.dfield[i].length - l;
@@ -1020,7 +1041,7 @@ common:
break;
}
smb_freemsgmem(smsg);
smb_freemsgmem(&smsg);
GFTRK(NULL);

View File

@@ -35,22 +35,21 @@ void SMBArea::raw_scan(bool keep_index, bool scanpm)
{
GFTRK("SMBArea::raw_scan");
SMBData* _was_data = data;
smb_t *_was_data = data;
if(_was_data == NULL)
data_open();
ulong firstmsgno = 0;
ulong lastmsgno = 0;
Msgn->Reset();
PMrk->Reset();
if(isopen or smb_open(10) == 0) {
if(smb_locksmbhdr(10) == 0) {
smbstatus_t status;
int res = smb_getstatus(&status);
smb_unlocksmbhdr();
if(isopen or smb_open(data) == 0) {
if(smb_locksmbhdr(data) == 0) {
int res = smb_getstatus(data);
smb_unlocksmbhdr(data);
ulong total_msgs = 0;
if(res == 0) {
total_msgs = status.total_msgs;
lastmsgno = status.last_msg;
total_msgs = data->status.total_msgs;
lastmsgno = data->status.last_msg;
if(keep_index or scanpm) {
smbmsg_t msg;
int umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1;
@@ -59,9 +58,9 @@ void SMBArea::raw_scan(bool keep_index, bool scanpm)
while(l <= total_msgs) {
if(not fread(&msg.idx, 1, sizeof(idxrec_t), data->sid_fp))
break;
if(smb_lockmsghdr(msg, 10) == 0) {
int rc = smb_getmsghdr(&msg);
smb_unlockmsghdr(msg);
if(smb_lockmsghdr(data, &msg) == 0) {
int rc = smb_getmsghdr(data, &msg);
smb_unlockmsghdr(data, &msg);
if(rc == 0) {
if(firstmsgno == 0)
firstmsgno = msg.hdr.number;
@@ -81,7 +80,7 @@ void SMBArea::raw_scan(bool keep_index, bool scanpm)
gotpm = false;
}
}
smb_freemsgmem(msg);
smb_freemsgmem(&msg);
}
}
l++;
@@ -90,7 +89,7 @@ void SMBArea::raw_scan(bool keep_index, bool scanpm)
}
}
if(not isopen)
smb_close();
smb_close(data);
Msgn->SetCount(total_msgs);
}
}

File diff suppressed because it is too large Load Diff