Redone synchronet support
This commit is contained in:
parent
fe06bc1747
commit
a1e5aba0dd
@ -12,6 +12,9 @@ ______________________________________________________________________
|
||||
Notes for GoldED+ 1.1.5, /snapshot/
|
||||
______________________________________________________________________
|
||||
|
||||
! Completely redone Synchronet support. Should be more stable and
|
||||
adequate.
|
||||
|
||||
+ Added support for SpaceToss areafile. WARNING: there's no known way
|
||||
to obtain primary AKA for echo areas from tosser config ver 1.10 so
|
||||
you'll need to define them manually. Main AKA will be used by
|
||||
|
@ -3,8 +3,8 @@
|
||||
TOP=..
|
||||
SHORTTARGET=ged
|
||||
TARGET=golded3
|
||||
GLIBS=gmb3 gall gcfg uulib
|
||||
INCS=-I. -I$(TOP)/goldlib/gall -I$(TOP)/goldlib/gcfg -I$(TOP)/goldlib/gmb3 -I$(TOP)/goldlib/uulib
|
||||
GLIBS=gmb3 gall gcfg uulib smblib
|
||||
INCS=-I. -I$(TOP)/goldlib/gall -I$(TOP)/goldlib/gcfg -I$(TOP)/goldlib/gmb3 -I$(TOP)/goldlib/uulib -I$(TOP)/goldlib/smblib
|
||||
|
||||
ifeq ($(findstring EMX, $(PATH)), EMX)
|
||||
STDLIBS=-los2me -lstdcpp
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
9
goldlib/smblib/Makefile
Normal file
9
goldlib/smblib/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# -*- makefile -*-
|
||||
|
||||
TOP=../..
|
||||
TARGET=smblib
|
||||
INCS=-I$(TOP)/goldlib/smblib -I$(TOP)/goldlib/gall
|
||||
CFLAGS=-DGOLDEDPLUS
|
||||
|
||||
include $(TOP)/GNUmakef.inc
|
||||
include $(TOP)/GNUmakef.lib
|
9
goldlib/smblib/crc32.h
Normal file
9
goldlib/smblib/crc32.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* crc32.h */
|
||||
|
||||
/* wrapper for gall library */
|
||||
|
||||
#include <gcrcall.h>
|
||||
|
||||
#define ucrc32(ch,crc) updCrc32(ch,crc)
|
||||
|
||||
|
808
goldlib/smblib/lzh.cpp
Normal file
808
goldlib/smblib/lzh.cpp
Normal file
@ -0,0 +1,808 @@
|
||||
/* lzh.c */
|
||||
|
||||
/* Synchronet LZH compression library */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/****************************************************************************
|
||||
* @format.tab-size 4 (Plain Text/Source Code File Header) *
|
||||
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
|
||||
* *
|
||||
* Rob Swindell's conversion of 1988 LZH (LHarc) encoding functions *
|
||||
* Based on Japanese version 29-NOV-1988 *
|
||||
* LZSS coded by Haruhiko Okumura *
|
||||
* Adaptive Huffman Coding coded by Haruyasu Yoshizaki *
|
||||
* *
|
||||
* Anonymous FTP access to the most recent released source is available at *
|
||||
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
|
||||
* *
|
||||
* Anonymous CVS access to the development source and modification history *
|
||||
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
|
||||
* (just hit return, no password is necessary) *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
|
||||
* *
|
||||
* For Synchronet coding style and modification guidelines, see *
|
||||
* http://www.synchro.net/source.html *
|
||||
* *
|
||||
* You are encouraged to submit any modifications (preferably in Unix diff *
|
||||
* format) via e-mail to mods@synchro.net *
|
||||
* *
|
||||
* Note: If this box doesn't appear square, then you need to fix your tabs. *
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <malloc.h>
|
||||
#include "lzh.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* Memory allocation macros for various compilers and environments */
|
||||
/* MALLOC is used for allocations of 64k or less */
|
||||
/* FREE is used to free buffers allocated with MALLOC */
|
||||
/* LMALLOC is used for allocations of possibly larger than 64k */
|
||||
/* LFREE is used to free buffers allocated with LMALLOC */
|
||||
/* REALLOC is used to re-size a previously MALLOCed or LMALLOCed buffer */
|
||||
/****************************************************************************/
|
||||
#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
|
||||
#if defined(__TURBOC__)
|
||||
#define REALLOC(x,y) farrealloc(x,y)
|
||||
#define LMALLOC(x) farmalloc(x)
|
||||
#define MALLOC(x) farmalloc(x)
|
||||
#define LFREE(x) farfree(x)
|
||||
#define FREE(x) farfree(x)
|
||||
#elif defined(__WATCOMC__)
|
||||
#define REALLOC realloc
|
||||
#define LMALLOC(x) halloc(x,1) /* far heap, but slow */
|
||||
#define MALLOC malloc /* far heap, but 64k max */
|
||||
#define LFREE hfree
|
||||
#define FREE free
|
||||
#else /* Other 16-bit Compiler */
|
||||
#define REALLOC realloc
|
||||
#define LMALLOC malloc
|
||||
#define MALLOC malloc
|
||||
#define LFREE free
|
||||
#define FREE free
|
||||
#endif
|
||||
#else /* 32-bit Compiler or Small Memory Model */
|
||||
#define REALLOC realloc
|
||||
#define LMALLOC malloc
|
||||
#define MALLOC malloc
|
||||
#define LFREE free
|
||||
#define FREE free
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* LZSS Parameters */
|
||||
|
||||
#define LZH_N 4096 /* Size of string buffer */
|
||||
#define LZH_F 60 /* Size of look-ahead buffer */
|
||||
#define LZH_THRESHOLD 2
|
||||
#define LZH_NIL LZH_N /* End of tree's node */
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
|
||||
unsigned char *lzh_text_buf;
|
||||
short int lzh_match_position, lzh_match_length,
|
||||
*lzh_lson, *lzh_rson, *lzh_dad;
|
||||
|
||||
#else
|
||||
|
||||
unsigned char lzh_text_buf[LZH_N + LZH_F - 1];
|
||||
short int lzh_match_position, lzh_match_length,
|
||||
lzh_lson[LZH_N + 1], lzh_rson[LZH_N + 257], lzh_dad[LZH_N + 1];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void lzh_init_tree(void) /* Initializing tree */
|
||||
{
|
||||
short int i;
|
||||
|
||||
for (i = LZH_N + 1; i <= LZH_N + 256; i++)
|
||||
lzh_rson[i] = LZH_NIL; /* root */
|
||||
for (i = 0; i < LZH_N; i++)
|
||||
lzh_dad[i] = LZH_NIL; /* node */
|
||||
}
|
||||
|
||||
/******************************/
|
||||
/* Inserting node to the tree */
|
||||
/* Only used during encoding */
|
||||
/******************************/
|
||||
void lzh_insert_node(short int r)
|
||||
{
|
||||
short int i, p, cmp;
|
||||
unsigned char *key;
|
||||
unsigned c;
|
||||
|
||||
cmp = 1;
|
||||
key = lzh_text_buf+r;
|
||||
p = LZH_N + 1 + key[0];
|
||||
lzh_rson[r] = lzh_lson[r] = LZH_NIL;
|
||||
lzh_match_length = 0;
|
||||
for ( ; ; ) {
|
||||
if (cmp >= 0) {
|
||||
if (lzh_rson[p] != LZH_NIL)
|
||||
p = lzh_rson[p];
|
||||
else {
|
||||
lzh_rson[p] = r;
|
||||
lzh_dad[r] = p;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (lzh_lson[p] != LZH_NIL)
|
||||
p = lzh_lson[p];
|
||||
else {
|
||||
lzh_lson[p] = r;
|
||||
lzh_dad[r] = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i = 1; i < LZH_F; i++)
|
||||
if ((cmp = key[i] - lzh_text_buf[p + i]) != 0)
|
||||
break;
|
||||
if (i > LZH_THRESHOLD) {
|
||||
if (i > lzh_match_length) {
|
||||
lzh_match_position = ((r - p) & (LZH_N - 1)) - 1;
|
||||
if ((lzh_match_length = i) >= LZH_F)
|
||||
break;
|
||||
}
|
||||
if (i == lzh_match_length) {
|
||||
if ((c = ((r - p) & (LZH_N - 1)) - 1)
|
||||
< (unsigned)lzh_match_position) {
|
||||
lzh_match_position = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lzh_dad[r] = lzh_dad[p];
|
||||
lzh_lson[r] = lzh_lson[p];
|
||||
lzh_rson[r] = lzh_rson[p];
|
||||
lzh_dad[lzh_lson[p]] = r;
|
||||
lzh_dad[lzh_rson[p]] = r;
|
||||
if (lzh_rson[lzh_dad[p]] == p)
|
||||
lzh_rson[lzh_dad[p]] = r;
|
||||
else
|
||||
lzh_lson[lzh_dad[p]] = r;
|
||||
lzh_dad[p] = LZH_NIL; /* remove p */
|
||||
}
|
||||
|
||||
void lzh_delete_node(short int p) /* Deleting node from the tree */
|
||||
{
|
||||
short int q;
|
||||
|
||||
if (lzh_dad[p] == LZH_NIL)
|
||||
return; /* unregistered */
|
||||
if (lzh_rson[p] == LZH_NIL)
|
||||
q = lzh_lson[p];
|
||||
else
|
||||
if (lzh_lson[p] == LZH_NIL)
|
||||
q = lzh_rson[p];
|
||||
else {
|
||||
q = lzh_lson[p];
|
||||
if (lzh_rson[q] != LZH_NIL) {
|
||||
do {
|
||||
q = lzh_rson[q];
|
||||
} while (lzh_rson[q] != LZH_NIL);
|
||||
lzh_rson[lzh_dad[q]] = lzh_lson[q];
|
||||
lzh_dad[lzh_lson[q]] = lzh_dad[q];
|
||||
lzh_lson[q] = lzh_lson[p];
|
||||
lzh_dad[lzh_lson[p]] = q;
|
||||
}
|
||||
lzh_rson[q] = lzh_rson[p];
|
||||
lzh_dad[lzh_rson[p]] = q;
|
||||
}
|
||||
lzh_dad[q] = lzh_dad[p];
|
||||
if (lzh_rson[lzh_dad[p]] == p)
|
||||
lzh_rson[lzh_dad[p]] = q;
|
||||
else
|
||||
lzh_lson[lzh_dad[p]] = q;
|
||||
lzh_dad[p] = LZH_NIL;
|
||||
}
|
||||
|
||||
/* Huffman coding parameters */
|
||||
|
||||
#define LZH_N_CHAR (256 - LZH_THRESHOLD + LZH_F)
|
||||
/* character code (= 0..LZH_N_CHAR-1) */
|
||||
#define LZH_T (LZH_N_CHAR * 2 - 1) /* Size of table */
|
||||
#define LZH_R (LZH_T - 1) /* root position */
|
||||
#define MAX_FREQ 0x8000
|
||||
/* update when cumulative frequency */
|
||||
/* reaches to this value */
|
||||
|
||||
/*
|
||||
* Tables for encoding/decoding upper 6 bits of
|
||||
* sliding dictionary pointer
|
||||
*/
|
||||
/* encoder table */
|
||||
uchar lzh_p_len[64] = {
|
||||
0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
|
||||
};
|
||||
|
||||
uchar lzh_p_code[64] = {
|
||||
0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
|
||||
0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
|
||||
0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
|
||||
0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
|
||||
0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
|
||||
0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
|
||||
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
|
||||
/* decoder table */
|
||||
uchar lzh_d_code[256] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
|
||||
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
|
||||
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
|
||||
0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
|
||||
0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
|
||||
0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
|
||||
0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
|
||||
0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
|
||||
0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
|
||||
0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
|
||||
0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
|
||||
0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
};
|
||||
|
||||
uchar lzh_d_len[256] = {
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
};
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
|
||||
unsigned short *lzh_freq=NULL; /* cumulative freq table */
|
||||
|
||||
/*
|
||||
* pointing parent nodes.
|
||||
* area [LZH_T..(LZH_T + LZH_N_CHAR - 1)] are pointers for leaves
|
||||
*/
|
||||
short int *lzh_prnt=NULL;
|
||||
|
||||
/* pointing children nodes (son[], son[] + 1)*/
|
||||
short int *lzh_son=NULL;
|
||||
|
||||
#else /* STATIC */
|
||||
|
||||
unsigned short lzh_freq[LZH_T + 1]; /* cumulative freq table */
|
||||
short int lzh_prnt[LZH_T + LZH_N_CHAR];
|
||||
short int lzh_son[LZH_T + 1]; /* bug fixed by Digital Dynamics */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
unsigned short lzh_getbuf = 0; /* Was just "unsigned" fixed 04/12/95 */
|
||||
uchar lzh_getlen = 0;
|
||||
|
||||
int lzh_getbit(uchar *inbuf, long *incnt, long inlen) /* get one bit */
|
||||
{
|
||||
short int i;
|
||||
|
||||
while (lzh_getlen <= 8) {
|
||||
if((*incnt)>=inlen)
|
||||
i=0;
|
||||
else
|
||||
i=inbuf[(*incnt)++];
|
||||
lzh_getbuf |= i << (8 - lzh_getlen);
|
||||
lzh_getlen += 8;
|
||||
}
|
||||
i = lzh_getbuf;
|
||||
lzh_getbuf <<= 1;
|
||||
lzh_getlen--;
|
||||
return (i < 0);
|
||||
}
|
||||
|
||||
short int lzh_getbyte(uchar *inbuf, long *incnt, long inlen) /* get a byte */
|
||||
{
|
||||
unsigned short i;
|
||||
|
||||
while (lzh_getlen <= 8) {
|
||||
if((*incnt)>=inlen)
|
||||
i=0;
|
||||
else
|
||||
i=inbuf[(*incnt)++];
|
||||
lzh_getbuf |= i << (8 - lzh_getlen);
|
||||
lzh_getlen += 8;
|
||||
}
|
||||
i = lzh_getbuf;
|
||||
lzh_getbuf <<= 8;
|
||||
lzh_getlen -= 8;
|
||||
return i >> 8;
|
||||
}
|
||||
|
||||
unsigned lzh_putbuf = 0;
|
||||
uchar lzh_putlen = 0;
|
||||
|
||||
/* output c bits */
|
||||
void lzh_putcode(short int l, unsigned short c, uchar *outbuf, long *outlen)
|
||||
{
|
||||
lzh_putbuf |= c >> lzh_putlen;
|
||||
if ((lzh_putlen += l) >= 8) {
|
||||
outbuf[(*outlen)++]=(lzh_putbuf >> 8);
|
||||
if ((lzh_putlen -= 8) >= 8) {
|
||||
outbuf[(*outlen)++]=lzh_putbuf;
|
||||
lzh_putlen -= 8;
|
||||
lzh_putbuf = c << (l - lzh_putlen);
|
||||
} else {
|
||||
lzh_putbuf <<= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* initialize freq tree */
|
||||
|
||||
void lzh_start_huff(void)
|
||||
{
|
||||
short int i, j;
|
||||
|
||||
lzh_getbuf = 0; /* Added by Digital Dynamics for repeating operations */
|
||||
lzh_getlen = 0;
|
||||
lzh_putbuf = 0;
|
||||
lzh_putlen = 0;
|
||||
|
||||
for (i = 0; i < LZH_N_CHAR; i++) {
|
||||
lzh_freq[i] = 1;
|
||||
lzh_son[i] = i + LZH_T;
|
||||
lzh_prnt[i + LZH_T] = i;
|
||||
}
|
||||
i = 0; j = LZH_N_CHAR;
|
||||
while (j <= LZH_R) {
|
||||
lzh_freq[j] = lzh_freq[i] + lzh_freq[i + 1];
|
||||
lzh_son[j] = i;
|
||||
lzh_prnt[i] = lzh_prnt[i + 1] = j;
|
||||
i += 2; j++;
|
||||
}
|
||||
lzh_freq[LZH_T] = 0xffff;
|
||||
lzh_prnt[LZH_R] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* reconstruct freq tree */
|
||||
|
||||
void lzh_reconst(void)
|
||||
{
|
||||
short int i, j, k;
|
||||
unsigned short f, l;
|
||||
|
||||
/* halven cumulative freq for leaf nodes */
|
||||
j = 0;
|
||||
for (i = 0; i < LZH_T; i++) {
|
||||
if (lzh_son[i] >= LZH_T) {
|
||||
lzh_freq[j] = (lzh_freq[i] + 1) / 2;
|
||||
lzh_son[j] = lzh_son[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
/* make a tree : first, connect children nodes */
|
||||
for (i = 0, j = LZH_N_CHAR; j < LZH_T; i += 2, j++) {
|
||||
k = i + 1;
|
||||
f = lzh_freq[j] = lzh_freq[i] + lzh_freq[k];
|
||||
for (k = j - 1; f < lzh_freq[k]; k--);
|
||||
k++;
|
||||
l = (j - k) * 2;
|
||||
|
||||
/* movmem() is Turbo-C dependent
|
||||
rewritten to memmove() by Kenji */
|
||||
|
||||
/* movmem(&lzh_freq[k], &lzh_freq[k + 1], l); */
|
||||
(void)memmove(lzh_freq+k+1,lzh_freq+k, l);
|
||||
lzh_freq[k] = f;
|
||||
/* movmem(&lzh_son[k], &lzh_son[k + 1], l); */
|
||||
(void)memmove(lzh_son+k+1,lzh_son+k, l);
|
||||
lzh_son[k] = i;
|
||||
}
|
||||
/* connect parent nodes */
|
||||
for (i = 0; i < LZH_T; i++) {
|
||||
if ((k = lzh_son[i]) >= LZH_T) {
|
||||
lzh_prnt[k] = i;
|
||||
} else {
|
||||
lzh_prnt[k] = lzh_prnt[k + 1] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update freq tree */
|
||||
|
||||
void lzh_update(short int c)
|
||||
{
|
||||
short int i, j, k, l;
|
||||
|
||||
if (lzh_freq[LZH_R] == MAX_FREQ) {
|
||||
lzh_reconst();
|
||||
}
|
||||
c = lzh_prnt[c + LZH_T];
|
||||
do {
|
||||
k = ++lzh_freq[c];
|
||||
|
||||
/* swap nodes to keep the tree freq-ordered */
|
||||
if (k > lzh_freq[l = c + 1]) {
|
||||
while (k > lzh_freq[++l]);
|
||||
l--;
|
||||
lzh_freq[c] = lzh_freq[l];
|
||||
lzh_freq[l] = k;
|
||||
|
||||
i = lzh_son[c];
|
||||
lzh_prnt[i] = l;
|
||||
if (i < LZH_T) lzh_prnt[i + 1] = l;
|
||||
|
||||
j = lzh_son[l];
|
||||
lzh_son[l] = i;
|
||||
|
||||
lzh_prnt[j] = c;
|
||||
if (j < LZH_T) lzh_prnt[j + 1] = c;
|
||||
lzh_son[c] = j;
|
||||
|
||||
c = l;
|
||||
}
|
||||
} while ((c = lzh_prnt[c]) != 0); /* do it until reaching the root */
|
||||
}
|
||||
|
||||
unsigned short lzh_code, lzh_len;
|
||||
|
||||
void lzh_encode_char(unsigned short c, uchar *outbuf, long *outlen)
|
||||
{
|
||||
unsigned short i;
|
||||
short int j, k;
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
k = lzh_prnt[c + LZH_T];
|
||||
|
||||
/* search connections from leaf node to the root */
|
||||
do {
|
||||
i >>= 1;
|
||||
|
||||
/*
|
||||
if node's address is odd, output 1
|
||||
else output 0
|
||||
*/
|
||||
if (k & 1) i += 0x8000;
|
||||
|
||||
j++;
|
||||
} while ((k = lzh_prnt[k]) != LZH_R);
|
||||
lzh_putcode(j, i, outbuf, outlen);
|
||||
lzh_code = i;
|
||||
lzh_len = j;
|
||||
lzh_update(c);
|
||||
}
|
||||
|
||||
void lzh_encode_position(unsigned short c, uchar *outbuf, long *outlen)
|
||||
{
|
||||
unsigned short i;
|
||||
|
||||
/* output upper 6 bits with encoding */
|
||||
i = c >> 6;
|
||||
lzh_putcode(lzh_p_len[i], (unsigned short)(lzh_p_code[i] << 8), outbuf, outlen);
|
||||
|
||||
/* output lower 6 bits directly */
|
||||
lzh_putcode(6, (unsigned short)((c & 0x3f) << 10), outbuf, outlen);
|
||||
}
|
||||
|
||||
void lzh_encode_end(uchar *outbuf, long *outlen)
|
||||
{
|
||||
if (lzh_putlen) {
|
||||
outbuf[(*outlen)++]=(lzh_putbuf >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
short int lzh_decode_char(uchar *inbuf, long *incnt, long inlen)
|
||||
{
|
||||
unsigned short c;
|
||||
|
||||
c = lzh_son[LZH_R];
|
||||
|
||||
/*
|
||||
* start searching tree from the root to leaves.
|
||||
* choose node #(lzh_son[]) if input bit == 0
|
||||
* else choose #(lzh_son[]+1) (input bit == 1)
|
||||
*/
|
||||
while (c < LZH_T) {
|
||||
c += lzh_getbit(inbuf,incnt,inlen);
|
||||
c = lzh_son[c];
|
||||
}
|
||||
c -= LZH_T;
|
||||
lzh_update(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
short int lzh_decode_position(uchar *inbuf, long *incnt, long inlen)
|
||||
{
|
||||
unsigned short i, j, c;
|
||||
|
||||
/* decode upper 6 bits from given table */
|
||||
i = lzh_getbyte(inbuf,incnt,inlen);
|
||||
c = (unsigned)lzh_d_code[i] << 6;
|
||||
j = lzh_d_len[i];
|
||||
|
||||
/* input lower 6 bits directly */
|
||||
j -= 2;
|
||||
while (j--) {
|
||||
i = (i << 1) + lzh_getbit(inbuf,incnt,inlen);
|
||||
}
|
||||
return c | i & 0x3f;
|
||||
}
|
||||
|
||||
/* Compression */
|
||||
|
||||
/* Encoding/Compressing */
|
||||
/* Returns length of outbuf */
|
||||
long LZHCALL lzh_encode(uchar *inbuf, long inlen, uchar *outbuf)
|
||||
{
|
||||
short int i, c, len, r, s, last_match_length;
|
||||
long incnt,outlen; /* textsize=0; */
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
|
||||
if((lzh_text_buf=(uchar *)MALLOC(LZH_N + LZH_F - 1))==NULL)
|
||||
return(-1);
|
||||
if((lzh_freq=(unsigned short*)MALLOC((LZH_T + 1)*sizeof(unsigned short)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
return(-1); }
|
||||
if((lzh_prnt=(short *)MALLOC((LZH_T + LZH_N_CHAR)*sizeof(short)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_freq);
|
||||
return(-1); }
|
||||
if((lzh_son=(short *)MALLOC((LZH_T + 1) * sizeof(short)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
return(-1); }
|
||||
if((lzh_lson=(short *)MALLOC((LZH_N + 1)*sizeof(short)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
return(-1); }
|
||||
if((lzh_rson=(short *)MALLOC((LZH_N + 257)*sizeof(short)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
FREE(lzh_lson);
|
||||
return(-1); }
|
||||
if((lzh_dad=(short *)MALLOC((LZH_N + 1)*sizeof(short)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
FREE(lzh_lson);
|
||||
FREE(lzh_rson);
|
||||
return(-1); }
|
||||
#endif
|
||||
|
||||
incnt=0;
|
||||
memcpy(outbuf,&inlen,sizeof(inlen));
|
||||
outlen=sizeof(inlen);
|
||||
if(!inlen) {
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
FREE(lzh_lson);
|
||||
FREE(lzh_rson);
|
||||
FREE(lzh_dad);
|
||||
#endif
|
||||
return(outlen); }
|
||||
lzh_start_huff();
|
||||
lzh_init_tree();
|
||||
s = 0;
|
||||
r = LZH_N - LZH_F;
|
||||
for (i = s; i < r; i++)
|
||||
lzh_text_buf[i] = ' ';
|
||||
for (len = 0; len < LZH_F && incnt<inlen; len++)
|
||||
lzh_text_buf[r + len] = inbuf[incnt++];
|
||||
/* textsize = len; */
|
||||
for (i = 1; i <= LZH_F; i++)
|
||||
lzh_insert_node((short)(r - i));
|
||||
lzh_insert_node(r);
|
||||
do {
|
||||
if (lzh_match_length > len)
|
||||
lzh_match_length = len;
|
||||
if (lzh_match_length <= LZH_THRESHOLD) {
|
||||
lzh_match_length = 1;
|
||||
lzh_encode_char(lzh_text_buf[r],outbuf,&outlen);
|
||||
} else {
|
||||
lzh_encode_char((unsigned short)(255 - LZH_THRESHOLD + lzh_match_length)
|
||||
,outbuf,&outlen);
|
||||
lzh_encode_position(lzh_match_position
|
||||
,outbuf,&outlen);
|
||||
}
|
||||
last_match_length = lzh_match_length;
|
||||
for (i = 0; i < last_match_length && incnt<inlen; i++) {
|
||||
lzh_delete_node(s);
|
||||
c=inbuf[incnt++];
|
||||
lzh_text_buf[s] = (uchar)c;
|
||||
if (s < LZH_F - 1)
|
||||
lzh_text_buf[s + LZH_N] = (uchar)c;
|
||||
s = (s + 1) & (LZH_N - 1);
|
||||
r = (r + 1) & (LZH_N - 1);
|
||||
lzh_insert_node(r);
|
||||
}
|
||||
/***
|
||||
if ((textsize += i) > printcount) {
|
||||
printf("%12ld\r", textsize);
|
||||
printcount += 1024;
|
||||
}
|
||||
***/
|
||||
while (i++ < last_match_length) {
|
||||
lzh_delete_node(s);
|
||||
s = (s + 1) & (LZH_N - 1);
|
||||
r = (r + 1) & (LZH_N - 1);
|
||||
if (--len) lzh_insert_node(r);
|
||||
}
|
||||
} while (len > 0);
|
||||
lzh_encode_end(outbuf,&outlen);
|
||||
/*
|
||||
printf("input: %ld (%ld) bytes\n", inlen,textsize);
|
||||
printf("output: %ld bytes\n", outlen);
|
||||
printf("output/input: %.3f\n", (double)outlen / inlen);
|
||||
*/
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
FREE(lzh_lson);
|
||||
FREE(lzh_rson);
|
||||
FREE(lzh_dad);
|
||||
#endif
|
||||
|
||||
return(outlen);
|
||||
}
|
||||
|
||||
/* Decoding/Uncompressing */
|
||||
/* Returns length of outbuf */
|
||||
long LZHCALL lzh_decode(uchar *inbuf, long inlen, uchar *outbuf)
|
||||
{
|
||||
short int i, j, k, r, c;
|
||||
unsigned long int count;
|
||||
long incnt,textsize;
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
|
||||
if((lzh_text_buf=(uchar *)MALLOC((LZH_N + LZH_F - 1)*2))==NULL)
|
||||
return(-1);
|
||||
if((lzh_freq=(unsigned short *)MALLOC((LZH_T + 1)*sizeof(unsigned short)))
|
||||
==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
return(-1); }
|
||||
if((lzh_prnt=(short *)MALLOC((LZH_T + LZH_N_CHAR)*sizeof(short)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_freq);
|
||||
return(-1); }
|
||||
if((lzh_son=(short *)MALLOC((LZH_T + 1) * sizeof(short)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
return(-1); }
|
||||
|
||||
#endif
|
||||
|
||||
incnt=0;
|
||||
memcpy(&textsize,inbuf,sizeof(textsize));
|
||||
incnt+=sizeof(textsize);
|
||||
if (textsize == 0) {
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
#endif
|
||||
return(textsize); }
|
||||
lzh_start_huff();
|
||||
for (i = 0; i < LZH_N - LZH_F; i++)
|
||||
*(lzh_text_buf+i) = ' ';
|
||||
r = LZH_N - LZH_F;
|
||||
for (count = 0; count < (unsigned long)textsize; ) {
|
||||
c = lzh_decode_char(inbuf,&incnt,inlen);
|
||||
if (c < 256) {
|
||||
outbuf[count]=(uchar)c;
|
||||
#if 0
|
||||
if(r>(LZH_N + LZH_F - 1) || r<0) {
|
||||
printf("Overflow! (%d)\n",r);
|
||||
getch();
|
||||
exit(-1); }
|
||||
#endif
|
||||
*(lzh_text_buf+r) = (uchar)c;
|
||||
r++;
|
||||
r &= (LZH_N - 1);
|
||||
count++;
|
||||
} else {
|
||||
i = (r - lzh_decode_position(inbuf,&incnt,inlen) - 1)
|
||||
& (LZH_N - 1);
|
||||
j = c - 255 + LZH_THRESHOLD;
|
||||
for (k = 0; k < j && count<(unsigned long)textsize; k++) {
|
||||
c = lzh_text_buf[(i + k) & (LZH_N - 1)];
|
||||
outbuf[count]=(uchar)c;
|
||||
#if 0
|
||||
if(r>(LZH_N + LZH_F - 1) || r<0) {
|
||||
printf("Overflow! (%d)\n",r);
|
||||
exit(-1); }
|
||||
#endif
|
||||
*(lzh_text_buf+r) = (uchar)c;
|
||||
r++;
|
||||
r &= (LZH_N - 1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/***
|
||||
printf("%12ld\n", count);
|
||||
***/
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
#endif
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
|
81
goldlib/smblib/lzh.h
Normal file
81
goldlib/smblib/lzh.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* lzh.h */
|
||||
|
||||
/* Synchronet LZH compression library */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/****************************************************************************
|
||||
* @format.tab-size 4 (Plain Text/Source Code File Header) *
|
||||
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
|
||||
* *
|
||||
* Rob Swindell's conversion of 1988 LZH (LHarc) encoding functions *
|
||||
* Based on Japanese version 29-NOV-1988 *
|
||||
* LZSS coded by Haruhiko Okumura *
|
||||
* Adaptive Huffman Coding coded by Haruyasu Yoshizaki *
|
||||
* *
|
||||
* Anonymous FTP access to the most recent released source is available at *
|
||||
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
|
||||
* *
|
||||
* Anonymous CVS access to the development source and modification history *
|
||||
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
|
||||
* (just hit return, no password is necessary) *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
|
||||
* *
|
||||
* For Synchronet coding style and modification guidelines, see *
|
||||
* http://www.synchro.net/source.html *
|
||||
* *
|
||||
* You are encouraged to submit any modifications (preferably in Unix diff *
|
||||
* format) via e-mail to mods@synchro.net *
|
||||
* *
|
||||
* Note: If this box doesn't appear square, then you need to fix your tabs. *
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef LZHEXPORT
|
||||
#undef LZHEXPORT
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef __FLAT__
|
||||
#define __FLAT__
|
||||
#endif
|
||||
#ifdef __BORLANDC__
|
||||
#define LZHCALL __stdcall
|
||||
#else
|
||||
#define LZHCALL
|
||||
#endif
|
||||
#ifdef LZHDLL /* LZH functions in DLL */
|
||||
#ifdef LZH_EXPORTS
|
||||
#define LZHEXPORT __declspec( dllexport )
|
||||
#else
|
||||
#define LZHEXPORT __declspec( dllimport )
|
||||
#endif
|
||||
#else /* self-contained executable */
|
||||
#define LZHEXPORT
|
||||
#endif
|
||||
#else /* !_WIN32 */
|
||||
#define LZHCALL
|
||||
#define LZHEXPORT
|
||||
#endif
|
||||
|
||||
#ifndef GOLDEDPLUS
|
||||
#ifndef uchar
|
||||
#define uchar unsigned char
|
||||
#endif
|
||||
#else
|
||||
#include <gdefs.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
LZHEXPORT long LZHCALL lzh_encode(uchar *inbuf, long inlen, uchar *outbuf);
|
||||
LZHEXPORT long LZHCALL lzh_decode(uchar *inbuf, long inlen, uchar *outbuf);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __WATCOMC__ /* Use MSC standard (prepended underscore) */
|
||||
#pragma aux lzh_encode "_*"
|
||||
#pragma aux lzh_decode "_*"
|
||||
#endif
|
548
goldlib/smblib/smbdefs.h
Normal file
548
goldlib/smblib/smbdefs.h
Normal file
@ -0,0 +1,548 @@
|
||||
/* smbdefs.h */
|
||||
|
||||
/* Synchronet message base constant and structure definitions */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/****************************************************************************
|
||||
* @format.tab-size 4 (Plain Text/Source Code File Header) *
|
||||
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
|
||||
* *
|
||||
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* See the GNU General Public License for more details: gpl.txt or *
|
||||
* http://www.fsf.org/copyleft/gpl.html *
|
||||
* *
|
||||
* Anonymous FTP access to the most recent released source is available at *
|
||||
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
|
||||
* *
|
||||
* Anonymous CVS access to the development source and modification history *
|
||||
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
|
||||
* (just hit return, no password is necessary) *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
|
||||
* *
|
||||
* For Synchronet coding style and modification guidelines, see *
|
||||
* http://www.synchro.net/source.html *
|
||||
* *
|
||||
* You are encouraged to submit any modifications (preferably in Unix diff *
|
||||
* format) via e-mail to mods@synchro.net *
|
||||
* *
|
||||
* Note: If this box doesn't appear square, then you need to fix your tabs. *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SMBDEFS_H
|
||||
#define _SMBDEFS_H
|
||||
|
||||
#ifdef GOLDEDPLUS
|
||||
#include <gdefs.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
/**********/
|
||||
/* Macros */
|
||||
/**********/
|
||||
|
||||
|
||||
#undef TAB
|
||||
#define TAB '\t' /* Horizontal tabulation ^I */
|
||||
#undef LF
|
||||
#define LF '\n' /* Line feed ^J */
|
||||
#undef CR
|
||||
#define CR '\r' /* Carriage return ^M */
|
||||
#undef SP
|
||||
#define SP ' ' /* Space */
|
||||
#undef FF
|
||||
#define FF 0x0c /* Form feed ^L */
|
||||
#undef ESC
|
||||
#define ESC 0x1b /* Escape ^[ */
|
||||
|
||||
#ifndef GOLDEDPLUS
|
||||
#ifndef uchar
|
||||
#define uchar unsigned char
|
||||
#endif
|
||||
#ifdef __GLIBC__
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
#ifndef ushort
|
||||
#define ushort unsigned short
|
||||
#define ulong unsigned long
|
||||
#define uint unsigned int
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* Memory allocation macros for various compilers and environments */
|
||||
/* MALLOC is used for allocations of 64k or less */
|
||||
/* FREE is used to free buffers allocated with MALLOC */
|
||||
/* LMALLOC is used for allocations of possibly larger than 64k */
|
||||
/* LFREE is used to free buffers allocated with LMALLOC */
|
||||
/* REALLOC is used to re-size a previously MALLOCed or LMALLOCed buffer */
|
||||
/****************************************************************************/
|
||||
#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
|
||||
# define HUGE16 huge
|
||||
# define FAR16 far
|
||||
# if defined(__TURBOC__)
|
||||
# define REALLOC(x,y) farrealloc(x,y)
|
||||
# define LMALLOC(x) farmalloc(x)
|
||||
# define MALLOC(x) farmalloc(x)
|
||||
# define LFREE(x) farfree(x)
|
||||
# define FREE(x) farfree(x)
|
||||
# elif defined(__WATCOMC__)
|
||||
# define REALLOC realloc
|
||||
# define LMALLOC(x) halloc(x,1) /* far heap, but slow */
|
||||
# define MALLOC malloc /* far heap, but 64k max */
|
||||
# define LFREE hfree
|
||||
# define FREE free
|
||||
# else /* Other 16-bit Compiler */
|
||||
# define REALLOC realloc
|
||||
# define LMALLOC malloc
|
||||
# define MALLOC malloc
|
||||
# define LFREE free
|
||||
# define FREE free
|
||||
# endif
|
||||
#else /* 32-bit Compiler or Small Memory Model */
|
||||
# define HUGE16
|
||||
# define FAR16
|
||||
# define REALLOC realloc
|
||||
# define LMALLOC malloc
|
||||
# define MALLOC malloc
|
||||
# define LFREE free
|
||||
# define FREE free
|
||||
#endif
|
||||
|
||||
|
||||
#define SDT_BLOCK_LEN 256 /* Size of data blocks */
|
||||
#define SHD_BLOCK_LEN 256 /* Size of header blocks */
|
||||
|
||||
#define SMB_SELFPACK 0 /* Self-packing storage allocation */
|
||||
#define SMB_FASTALLOC 1 /* Fast allocation */
|
||||
#define SMB_HYPERALLOC 2 /* No allocation */
|
||||
|
||||
#define SMB_EMAIL 1 /* User numbers stored in Indexes */
|
||||
|
||||
/* Time zone macros for when_t.zone */
|
||||
#define DAYLIGHT 0x8000 /* Daylight savings is active */
|
||||
#define US_ZONE 0x4000 /* U.S. time zone */
|
||||
#define WESTERN_ZONE 0x2000 /* Non-standard zone west of UT */
|
||||
#define EASTERN_ZONE 0x1000 /* Non-standard zone east of UT */
|
||||
|
||||
/* US Time Zones (standard) */
|
||||
#define AST 0x40F0 // Atlantic (-04:00)
|
||||
#define EST 0x412C // Eastern (-05:00)
|
||||
#define CST 0x4168 // Central (-06:00)
|
||||
#define MST 0x41A4 // Mountain (-07:00)
|
||||
#define PST 0x41E0 // Pacific (-08:00)
|
||||
#define YST 0x421C // Yukon (-09:00)
|
||||
#define HST 0x4258 // Hawaii/Alaska (-10:00)
|
||||
#define BST 0x4294 // Bering (-11:00)
|
||||
|
||||
/* US Time Zones (daylight) */
|
||||
#define ADT 0xC0F0 // Atlantic (-03:00)
|
||||
#define EDT 0xC12C // Eastern (-04:00)
|
||||
#define CDT 0xC168 // Central (-05:00)
|
||||
#define MDT 0xC1A4 // Mountain (-06:00)
|
||||
#define PDT 0xC1E0 // Pacific (-07:00)
|
||||
#define YDT 0xC21C // Yukon (-08:00)
|
||||
#define HDT 0xC258 // Hawaii/Alaska (-09:00)
|
||||
#define BDT 0xC294 // Bering (-10:00)
|
||||
|
||||
/* Non-standard Time Zones */
|
||||
#define MID 0x2294 // Midway (-11:00)
|
||||
#define VAN 0x21E0 // Vancouver (-08:00)
|
||||
#define EDM 0x21A4 // Edmonton (-07:00)
|
||||
#define WIN 0x2168 // Winnipeg (-06:00)
|
||||
#define BOG 0x212C // Bogota (-05:00)
|
||||
#define CAR 0x20F0 // Caracas (-04:00)
|
||||
#define RIO 0x20B4 // Rio de Janeiro (-03:00)
|
||||
#define FER 0x2078 // Fernando de Noronha (-02:00)
|
||||
#define AZO 0x203C // Azores (-01:00)
|
||||
#define LON 0x1000 // London (+00:00)
|
||||
#define BER 0x103C // Berlin (+01:00)
|
||||
#define ATH 0x1078 // Athens (+02:00)
|
||||
#define MOS 0x10B4 // Moscow (+03:00)
|
||||
#define DUB 0x10F0 // Dubai (+04:00)
|
||||
#define KAB 0x110E // Kabul (+04:30)
|
||||
#define KAR 0x112C // Karachi (+05:00)
|
||||
#define BOM 0x114A // Bombay (+05:30)
|
||||
#define KAT 0x1159 // Kathmandu (+05:45)
|
||||
#define DHA 0x1168 // Dhaka (+06:00)
|
||||
#define BAN 0x11A4 // Bangkok (+07:00)
|
||||
#define HON 0x11E0 // Hong Kong (+08:00)
|
||||
#define TOK 0x121C // Tokyo (+09:00)
|
||||
#define SYD 0x1258 // Sydney (+10:00)
|
||||
#define NOU 0x1294 // Noumea (+11:00)
|
||||
#define WEL 0x12D0 // Wellington (+12:00)
|
||||
|
||||
/* Valid hfield_t.types */
|
||||
#define SENDER 0x00
|
||||
#define SENDERAGENT 0x01
|
||||
#define SENDERNETTYPE 0x02
|
||||
#define SENDERNETADDR 0x03
|
||||
#define SENDEREXT 0x04
|
||||
#define SENDERPOS 0x05
|
||||
#define SENDERORG 0x06
|
||||
|
||||
#define AUTHOR 0x10
|
||||
#define AUTHORAGENT 0x11
|
||||
#define AUTHORNETTYPE 0x12
|
||||
#define AUTHORNETADDR 0x13
|
||||
#define AUTHOREXT 0x14
|
||||
#define AUTHORPOS 0x15
|
||||
#define AUTHORORG 0x16
|
||||
|
||||
#define REPLYTO 0x20
|
||||
#define REPLYTOAGENT 0x21
|
||||
#define REPLYTONETTYPE 0x22
|
||||
#define REPLYTONETADDR 0x23
|
||||
#define REPLYTOEXT 0x24
|
||||
#define REPLYTOPOS 0x25
|
||||
#define REPLYTOORG 0x26
|
||||
|
||||
#define RECIPIENT 0x30
|
||||
#define RECIPIENTAGENT 0x31
|
||||
#define RECIPIENTNETTYPE 0x32
|
||||
#define RECIPIENTNETADDR 0x33
|
||||
#define RECIPIENTEXT 0x34
|
||||
#define RECIPIENTPOS 0x35
|
||||
#define RECIPIENTORG 0x36
|
||||
|
||||
#define FORWARDTO 0x40
|
||||
#define FORWARDTOAGENT 0x41
|
||||
#define FORWARDTONETTYPE 0x42
|
||||
#define FORWARDTONETADDR 0x43
|
||||
#define FORWARDTOEXT 0x44
|
||||
#define FORWARDTOPOS 0x45
|
||||
#define FORWARDTOORG 0x46
|
||||
|
||||
#define FORWARDED 0x48
|
||||
|
||||
#define RECEIVEDBY 0x50
|
||||
#define RECEIVEDBYAGENT 0x51
|
||||
#define RECEIVEDBYNETTYPE 0x52
|
||||
#define RECEIVEDBYNETADDR 0x53
|
||||
#define RECEIVEDBYEXT 0x54
|
||||
#define RECEIVEDBYPOS 0x55
|
||||
#define RECEIVEDBYORG 0x56
|
||||
|
||||
#define RECEIVED 0x58
|
||||
|
||||
#define SUBJECT 0x60
|
||||
#define SUMMARY 0x61
|
||||
#define SMB_COMMENT 0x62
|
||||
#define CARBONCOPY 0x63
|
||||
#define SMB_GROUP 0x64
|
||||
#define EXPIRATION 0x65
|
||||
#define PRIORITY 0x66
|
||||
|
||||
#define FILEATTACH 0x70
|
||||
#define DESTFILE 0x71
|
||||
#define FILEATTACHLIST 0x72
|
||||
#define DESTFILELIST 0x73
|
||||
#define FILEREQUEST 0x74
|
||||
#define FILEPASSWORD 0x75
|
||||
#define FILEREQUESTLIST 0x76
|
||||
#define FILEPASSWORDLIST 0x77
|
||||
|
||||
#define IMAGEATTACH 0x80
|
||||
#define ANIMATTACH 0x81
|
||||
#define FONTATTACH 0x82
|
||||
#define SOUNDATTACH 0x83
|
||||
#define PRESENTATTACH 0x84
|
||||
#define VIDEOATTACH 0x85
|
||||
#define APPDATAATTACH 0x86
|
||||
|
||||
#define IMAGETRIGGER 0x90
|
||||
#define ANIMTRIGGER 0x91
|
||||
#define FONTTRIGGER 0x92
|
||||
#define SOUNDTRIGGER 0x93
|
||||
#define PRESENTTRIGGER 0x94
|
||||
#define VIDEOTRIGGER 0x95
|
||||
#define APPDATATRIGGER 0x96
|
||||
|
||||
#define FIDOCTRL 0xa0
|
||||
#define FIDOAREA 0xa1
|
||||
#define FIDOSEENBY 0xa2
|
||||
#define FIDOPATH 0xa3
|
||||
#define FIDOMSGID 0xa4
|
||||
#define FIDOREPLYID 0xa5
|
||||
#define FIDOPID 0xa6
|
||||
#define FIDOFLAGS 0xa7
|
||||
|
||||
#define RFC822HEADER 0xb0
|
||||
#define RFC822MSGID 0xb1
|
||||
#define RFC822REPLYID 0xb2
|
||||
|
||||
#define UNKNOWN 0xf1
|
||||
#define UNKNOWNASCII 0xf2
|
||||
#define UNUSED 0xff
|
||||
|
||||
/* Valid dfield_t.types */
|
||||
#define TEXT_BODY 0x00
|
||||
#define TEXT_SOUL 0x01
|
||||
#define TEXT_TAIL 0x02
|
||||
#define TEXT_WING 0x03
|
||||
#define IMAGEEMBED 0x20
|
||||
#define ANIMEMBED 0x21
|
||||
#define FONTEMBED 0x22
|
||||
#define SOUNDEMBED 0x23
|
||||
#define PRESENTEMBED 0x24
|
||||
#define VIDEOEMBED 0x25
|
||||
#define APPDATAEMBED 0x26
|
||||
#define UNUSED 0xff
|
||||
|
||||
|
||||
/* Message attributes */
|
||||
#define MSG_PRIVATE (1<<0)
|
||||
#define MSG_READ (1<<1)
|
||||
#define MSG_PERMANENT (1<<2)
|
||||
#define MSG_LOCKED (1<<3)
|
||||
#define MSG_DELETE (1<<4)
|
||||
#define MSG_ANONYMOUS (1<<5)
|
||||
#define MSG_KILLREAD (1<<6)
|
||||
#define MSG_MODERATED (1<<7)
|
||||
#define MSG_VALIDATED (1<<8)
|
||||
#define MSG_REPLIED (1<<9) // User replied to this message
|
||||
|
||||
/* Auxillary header attributes */
|
||||
#define MSG_FILEREQUEST (1<<0) // File request
|
||||
#define MSG_FILEATTACH (1<<1) // File(s) attached to Msg
|
||||
#define MSG_TRUNCFILE (1<<2) // Truncate file(s) when sent
|
||||
#define MSG_KILLFILE (1<<3) // Delete file(s) when sent
|
||||
#define MSG_RECEIPTREQ (1<<4) // Return receipt requested
|
||||
#define MSG_CONFIRMREQ (1<<5) // Confirmation receipt requested
|
||||
#define MSG_NODISP (1<<6) // Msg may not be displayed to user
|
||||
|
||||
/* Message network attributes */
|
||||
#define MSG_LOCAL (1<<0) // Msg created locally
|
||||
#define MSG_INTRANSIT (1<<1) // Msg is in-transit
|
||||
#define MSG_SENT (1<<2) // Sent to remote
|
||||
#define MSG_KILLSENT (1<<3) // Kill when sent
|
||||
#define MSG_ARCHIVESENT (1<<4) // Archive when sent
|
||||
#define MSG_HOLD (1<<5) // Hold for pick-up
|
||||
#define MSG_CRASH (1<<6) // Crash
|
||||
#define MSG_IMMEDIATE (1<<7) // Send Msg now, ignore restrictions
|
||||
#define MSG_DIRECT (1<<8) // Send directly to destination
|
||||
#define MSG_GATE (1<<9) // Send via gateway
|
||||
#define MSG_ORPHAN (1<<10) // Unknown destination
|
||||
#define MSG_FPU (1<<11) // Force pickup
|
||||
#define MSG_TYPELOCAL (1<<12) // Msg is for local use only
|
||||
#define MSG_TYPEECHO (1<<13) // Msg is for conference distribution
|
||||
#define 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
|
||||
};
|
||||
|
||||
|
||||
/************/
|
||||
/* Typedefs */
|
||||
/************/
|
||||
|
||||
#ifndef GOLDEDPLUS
|
||||
#ifdef __GNUC__
|
||||
#define _PACK __attribute__ ((packed))
|
||||
#else
|
||||
#define _PACK
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma pack(push) /* Disk image structures must be packed */
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
#else
|
||||
#define _PACK
|
||||
#if defined(GOLD_CANPACK)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct _PACK { // Time with time-zone
|
||||
|
||||
ulong time; // Local time (unix format)
|
||||
short zone; // Time zone
|
||||
|
||||
} when_t;
|
||||
|
||||
typedef struct _PACK { // Index record
|
||||
|
||||
ushort to; // 16-bit CRC of recipient name (lower case)
|
||||
ushort from; // 16-bit CRC of sender name (lower case)
|
||||
ushort subj; // 16-bit CRC of subject (lower case, w/o RE:)
|
||||
ushort attr; // attributes (read, permanent, etc.)
|
||||
ulong offset; // offset into header file
|
||||
ulong number; // number of message (1 based)
|
||||
ulong time; // time/date message was imported/posted
|
||||
|
||||
} idxrec_t;
|
||||
|
||||
typedef struct _PACK { // Message base header (fixed portion)
|
||||
|
||||
uchar id[4]; // text or binary unique hdr ID
|
||||
ushort version; // version number (initially 100h for 1.00)
|
||||
ushort length; // length including this struct
|
||||
|
||||
} smbhdr_t;
|
||||
|
||||
typedef struct _PACK { // Message base status header
|
||||
|
||||
ulong last_msg; // last message number
|
||||
ulong total_msgs; // total messages
|
||||
ulong header_offset; // byte offset to first header record
|
||||
ulong max_crcs; // Maximum number of CRCs to keep in history
|
||||
ulong max_msgs; // Maximum number of message to keep in sub
|
||||
ushort max_age; // Maximum age of message to keep in sub (in days)
|
||||
ushort attr; // Attributes for this message base (SMB_HYPER,etc)
|
||||
|
||||
} smbstatus_t;
|
||||
|
||||
typedef struct _PACK { // Message header
|
||||
|
||||
uchar id[4]; // SHD<^Z>
|
||||
ushort type; // Message type (normally 0)
|
||||
ushort version; // Version of type (initially 100h for 1.00)
|
||||
ushort length; // Total length of fixed record + all fields
|
||||
ushort attr; // Attributes (bit field) (duped in SID)
|
||||
ulong auxattr; // Auxillary attributes (bit field)
|
||||
ulong netattr; // Network attributes
|
||||
when_t when_written; // Time message was written (unix format)
|
||||
when_t when_imported; // Time message was imported
|
||||
ulong number; // Message number
|
||||
ulong thread_orig; // Original message number in thread
|
||||
ulong thread_next; // Next message in thread
|
||||
ulong thread_first; // First reply to this message
|
||||
ushort delivery_attempts; // Delivery attempt counter
|
||||
uchar reserved[14]; // Reserved for future use
|
||||
ulong offset; // Offset for buffer into data file (0 or mod 256)
|
||||
ushort total_dfields; // Total number of data fields
|
||||
|
||||
} msghdr_t;
|
||||
|
||||
typedef struct _PACK { // Data field
|
||||
|
||||
ushort type; // Type of data field
|
||||
ulong offset; // Offset into buffer
|
||||
ulong length; // Length of data field
|
||||
|
||||
} dfield_t;
|
||||
|
||||
typedef struct _PACK { // Header field
|
||||
|
||||
ushort type;
|
||||
ushort length; // Length of buffer
|
||||
|
||||
} hfield_t;
|
||||
|
||||
typedef struct _PACK { // FidoNet address (zone:net/node.point)
|
||||
|
||||
ushort zone;
|
||||
ushort net;
|
||||
ushort node;
|
||||
ushort point;
|
||||
|
||||
} fidoaddr_t;
|
||||
|
||||
typedef struct _PACK { // Network (type and address)
|
||||
|
||||
ushort type;
|
||||
void *addr;
|
||||
|
||||
} net_t;
|
||||
|
||||
#ifndef GOLDEDPLUS
|
||||
#ifdef _WIN32
|
||||
#pragma pack(pop) /* original packing */
|
||||
#endif
|
||||
#else
|
||||
#undef _PACK
|
||||
#if defined(GOLD_CANPACK)
|
||||
#pragma pack()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct { // Message
|
||||
|
||||
idxrec_t idx; // Index
|
||||
msghdr_t hdr; // Header record (fixed portion)
|
||||
char *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
|
||||
ushort 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
|
||||
ushort 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)
|
||||
ulong offset; // Offset (number of records) into index
|
||||
uchar forwarded; // Forwarded from agent to another
|
||||
when_t expiration; // Message will exipre on this day (if >0)
|
||||
|
||||
} smbmsg_t;
|
||||
|
||||
typedef struct { // Message base
|
||||
|
||||
char file[128]; // Path and base filename (no extension)
|
||||
FILE *sdt_fp; // File pointer for data (.sdt) file
|
||||
FILE *shd_fp; // File pointer for header (.shd) file
|
||||
FILE *sid_fp; // File pointer for index (.sid) file
|
||||
FILE *sda_fp; // File pointer for data allocation (.sda) file
|
||||
FILE *sha_fp; // File pointer for header allocation (.sha) file
|
||||
ulong retry_time; // Maximum number of seconds to retry opens/locks
|
||||
smbstatus_t status; // Status header record
|
||||
char shd_buf[SHD_BLOCK_LEN]; // File I/O buffer for header file
|
||||
char last_error[128]; // Last error message
|
||||
|
||||
} smb_t;
|
||||
|
||||
#endif /* Don't add anything after this #endif statement */
|
3
goldlib/smblib/smblib.all
Normal file
3
goldlib/smblib/smblib.all
Normal file
@ -0,0 +1,3 @@
|
||||
lzh cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
smblib cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
smbtxt cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
1555
goldlib/smblib/smblib.cpp
Normal file
1555
goldlib/smblib/smblib.cpp
Normal file
File diff suppressed because it is too large
Load Diff
218
goldlib/smblib/smblib.h
Normal file
218
goldlib/smblib/smblib.h
Normal file
@ -0,0 +1,218 @@
|
||||
/* smblib.h */
|
||||
|
||||
/* Synchronet message base (SMB) library function prototypes */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/****************************************************************************
|
||||
* @format.tab-size 4 (Plain Text/Source Code File Header) *
|
||||
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
|
||||
* *
|
||||
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* See the GNU General Public License for more details: gpl.txt or *
|
||||
* http://www.fsf.org/copyleft/gpl.html *
|
||||
* *
|
||||
* Anonymous FTP access to the most recent released source is available at *
|
||||
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
|
||||
* *
|
||||
* Anonymous CVS access to the development source and modification history *
|
||||
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
|
||||
* (just hit return, no password is necessary) *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
|
||||
* *
|
||||
* For Synchronet coding style and modification guidelines, see *
|
||||
* http://www.synchro.net/source.html *
|
||||
* *
|
||||
* You are encouraged to submit any modifications (preferably in Unix diff *
|
||||
* format) via e-mail to mods@synchro.net *
|
||||
* *
|
||||
* Note: If this box doesn't appear square, then you need to fix your tabs. *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SMBLIB_H
|
||||
#define _SMBLIB_H
|
||||
|
||||
#include <lzh.h>
|
||||
|
||||
#ifdef SMBEXPORT
|
||||
#undef SMBEXPORT
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef __FLAT__
|
||||
#define __FLAT__
|
||||
#endif
|
||||
#ifdef __BORLANDC__
|
||||
#define SMBCALL __stdcall
|
||||
#else
|
||||
#define SMBCALL
|
||||
#endif
|
||||
#ifdef SMBDLL /* SMBLIB contained in DLL */
|
||||
#ifdef SMB_EXPORTS
|
||||
#define SMBEXPORT __declspec( dllexport )
|
||||
#else
|
||||
#define SMBEXPORT __declspec( dllimport )
|
||||
#endif
|
||||
#else /* self-contained executable */
|
||||
#define SMBEXPORT
|
||||
#endif
|
||||
#elif defined __unix__
|
||||
#define SMBCALL
|
||||
#define SMBEXPORT
|
||||
#elif defined __FLAT__
|
||||
#define SMBCALL
|
||||
#define SMBEXPORT _export
|
||||
#else
|
||||
#define SMBCALL
|
||||
#define SMBEXPORT
|
||||
#endif
|
||||
|
||||
#include <smbdefs.h>
|
||||
|
||||
#define SMB_STACK_LEN 4 /* Max msg bases in smb_stack() */
|
||||
#define SMB_STACK_POP 0 /* Pop a msg base off of smb_stack() */
|
||||
#define SMB_STACK_PUSH 1 /* Push a msg base onto smb_stack() */
|
||||
#define SMB_STACK_XCHNG 2 /* Exchange msg base w/last pushed */
|
||||
|
||||
#define GETMSGTXT_TAILS 1 /* Get message tail(s) too */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SMBEXPORT int SMBCALL smb_ver(void);
|
||||
SMBEXPORT char * SMBCALL smb_lib_ver(void);
|
||||
SMBEXPORT int SMBCALL smb_open(smb_t* smb);
|
||||
SMBEXPORT void SMBCALL smb_close(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_open_da(smb_t* smb);
|
||||
SMBEXPORT void SMBCALL smb_close_da(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_open_ha(smb_t* smb);
|
||||
SMBEXPORT void SMBCALL smb_close_ha(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_create(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_stack(smb_t* smb, int op);
|
||||
SMBEXPORT int SMBCALL smb_trunchdr(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_locksmbhdr(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_getstatus(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_putstatus(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_unlocksmbhdr(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg);
|
||||
SMBEXPORT int SMBCALL smb_getlastidx(smb_t* smb, idxrec_t *idx);
|
||||
SMBEXPORT uint SMBCALL smb_getmsghdrlen(smbmsg_t* msg);
|
||||
SMBEXPORT ulong SMBCALL smb_getmsgdatlen(smbmsg_t* msg);
|
||||
SMBEXPORT int SMBCALL smb_lockmsghdr(smb_t* smb, smbmsg_t* msg);
|
||||
SMBEXPORT int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg);
|
||||
SMBEXPORT int SMBCALL smb_unlockmsghdr(smb_t* smb, smbmsg_t* msg);
|
||||
SMBEXPORT int SMBCALL smb_addcrc(smb_t* smb, ulong crc);
|
||||
SMBEXPORT int SMBCALL smb_hfield(smbmsg_t* msg, ushort type, ushort length, void* data);
|
||||
SMBEXPORT int SMBCALL smb_dfield(smbmsg_t* msg, ushort type, ulong length);
|
||||
SMBEXPORT int SMBCALL smb_addmsghdr(smb_t* smb, smbmsg_t* msg,int storage);
|
||||
SMBEXPORT int SMBCALL smb_putmsg(smb_t* smb, smbmsg_t* msg);
|
||||
SMBEXPORT int SMBCALL smb_putmsgidx(smb_t* smb, smbmsg_t* msg);
|
||||
SMBEXPORT int SMBCALL smb_putmsghdr(smb_t* smb, smbmsg_t* msg);
|
||||
SMBEXPORT void SMBCALL smb_freemsgmem(smbmsg_t* msg);
|
||||
SMBEXPORT ulong SMBCALL smb_hdrblocks(ulong length);
|
||||
SMBEXPORT ulong SMBCALL smb_datblocks(ulong length);
|
||||
SMBEXPORT long SMBCALL smb_allochdr(smb_t* smb, ulong length);
|
||||
SMBEXPORT long SMBCALL smb_fallochdr(smb_t* smb, ulong length);
|
||||
SMBEXPORT long SMBCALL smb_hallochdr(smb_t* smb);
|
||||
SMBEXPORT long SMBCALL smb_allocdat(smb_t* smb, ulong length, ushort headers);
|
||||
SMBEXPORT long SMBCALL smb_fallocdat(smb_t* smb, ulong length, ushort headers);
|
||||
SMBEXPORT long SMBCALL smb_hallocdat(smb_t* smb);
|
||||
SMBEXPORT int SMBCALL smb_incdat(smb_t* smb, ulong offset, ulong length, ushort headers);
|
||||
SMBEXPORT int SMBCALL smb_freemsg(smb_t* smb, smbmsg_t* msg);
|
||||
SMBEXPORT int SMBCALL smb_freemsgdat(smb_t* smb, ulong offset, ulong length, ushort headers);
|
||||
SMBEXPORT int SMBCALL smb_freemsghdr(smb_t* smb, ulong offset, ulong length);
|
||||
SMBEXPORT void SMBCALL smb_freemsgtxt(char HUGE16* buf);
|
||||
SMBEXPORT int SMBCALL smb_copymsgmem(smbmsg_t* destmsg, smbmsg_t* srcmsg);
|
||||
SMBEXPORT char HUGE16* SMBCALL smb_getmsgtxt(smb_t* smb, smbmsg_t* msg, ulong mode);
|
||||
|
||||
/* FILE pointer I/O functions */
|
||||
|
||||
SMBEXPORT int SMBCALL smb_feof(FILE* fp);
|
||||
SMBEXPORT int SMBCALL smb_ferror(FILE* fp);
|
||||
SMBEXPORT int SMBCALL smb_fflush(FILE* fp);
|
||||
SMBEXPORT int SMBCALL smb_fgetc(FILE* fp);
|
||||
SMBEXPORT int SMBCALL smb_fputc(int ch, FILE* fp);
|
||||
SMBEXPORT int SMBCALL smb_fseek(FILE* fp, long offset, int whence);
|
||||
SMBEXPORT long SMBCALL smb_ftell(FILE* fp);
|
||||
SMBEXPORT long SMBCALL smb_fread(void HUGE16* buf, long bytes, FILE* fp);
|
||||
SMBEXPORT long SMBCALL smb_fwrite(void HUGE16* buf, long bytes, FILE* fp);
|
||||
SMBEXPORT long SMBCALL smb_fgetlength(FILE* fp);
|
||||
SMBEXPORT int SMBCALL smb_fsetlength(FILE* fp, long length);
|
||||
SMBEXPORT void SMBCALL smb_rewind(FILE* fp);
|
||||
SMBEXPORT void SMBCALL smb_clearerr(FILE* fp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __WATCOMC__ /* Use MSC standard (prepended underscore) */
|
||||
#pragma aux smb_ver "_*"
|
||||
#pragma aux smb_lib_ver "_*"
|
||||
#pragma aux smb_open "_*"
|
||||
#pragma aux smb_close "_*"
|
||||
#pragma aux smb_open_da "_*"
|
||||
#pragma aux smb_close_da "_*"
|
||||
#pragma aux smb_open_ha "_*"
|
||||
#pragma aux smb_close_ha "_*"
|
||||
#pragma aux smb_create "_*"
|
||||
#pragma aux smb_stack "_*"
|
||||
#pragma aux smb_trunchdr "_*"
|
||||
#pragma aux smb_locksmbhdr "_*"
|
||||
#pragma aux smb_getstatus "_*"
|
||||
#pragma aux smb_putstatus "_*"
|
||||
#pragma aux smb_unlocksmbhdr "_*"
|
||||
#pragma aux smb_getmsgidx "_*"
|
||||
#pragma aux smb_getlastidx "_*"
|
||||
#pragma aux smb_getmsghdrlen "_*"
|
||||
#pragma aux smb_getmsgdatlen "_*"
|
||||
#pragma aux smb_lockmsghdr "_*"
|
||||
#pragma aux smb_getmsghdr "_*"
|
||||
#pragma aux smb_unlockmsghdr "_*"
|
||||
#pragma aux smb_addcrc "_*"
|
||||
#pragma aux smb_hfield "_*"
|
||||
#pragma aux smb_dfield "_*"
|
||||
#pragma aux smb_addmsghdr "_*"
|
||||
#pragma aux smb_putmsg "_*"
|
||||
#pragma aux smb_putmsgidx "_*"
|
||||
#pragma aux smb_putmsghdr "_*"
|
||||
#pragma aux smb_freemsgmem "_*"
|
||||
#pragma aux smb_hdrblocks "_*"
|
||||
#pragma aux smb_datblocks "_*"
|
||||
#pragma aux smb_allochdr "_*"
|
||||
#pragma aux smb_fallochdr "_*"
|
||||
#pragma aux smb_hallochdr "_*"
|
||||
#pragma aux smb_allocdat "_*"
|
||||
#pragma aux smb_fallocdat "_*"
|
||||
#pragma aux smb_hallocdat "_*"
|
||||
#pragma aux smb_incdat "_*"
|
||||
#pragma aux smb_freemsg "_*"
|
||||
#pragma aux smb_freemsgdat "_*"
|
||||
#pragma aux smb_freemsghdr "_*"
|
||||
#pragma aux smb_getmsgtxt "_*"
|
||||
#pragma aux smb_freemsgtxt "_*"
|
||||
#pragma aux smb_feof "_*"
|
||||
#pragma aux smb_ferror "_*"
|
||||
#pragma aux smb_fflush "_*"
|
||||
#pragma aux smb_fgetc "_*"
|
||||
#pragma aux smb_fputc "_*"
|
||||
#pragma aux smb_fseek "_*"
|
||||
#pragma aux smb_ftell "_*"
|
||||
#pragma aux smb_fread "_*"
|
||||
#pragma aux smb_fwrite "_*"
|
||||
#pragma aux smb_fgetlength "_*"
|
||||
#pragma aux smb_fsetlength "_*"
|
||||
#pragma aux smb_rewind "_*"
|
||||
#pragma aux smb_clearerr "_*"
|
||||
#pragma aux lzh_encode "_*"
|
||||
#pragma aux lzh_decode "_*"
|
||||
#endif /* Watcom */
|
||||
|
||||
|
||||
#endif /* Don't add anything after this #endif statement */
|
121
goldlib/smblib/smbtxt.cpp
Normal file
121
goldlib/smblib/smbtxt.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/* smbtxt.c */
|
||||
|
||||
/* Synchronet message base (SMB) message text library routines */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/****************************************************************************
|
||||
* @format.tab-size 4 (Plain Text/Source Code File Header) *
|
||||
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
|
||||
* *
|
||||
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* See the GNU Lesser General Public License for more details: lgpl.txt or *
|
||||
* http://www.fsf.org/copyleft/lesser.html *
|
||||
* *
|
||||
* Anonymous FTP access to the most recent released source is available at *
|
||||
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
|
||||
* *
|
||||
* Anonymous CVS access to the development source and modification history *
|
||||
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
|
||||
* (just hit return, no password is necessary) *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
|
||||
* *
|
||||
* For Synchronet coding style and modification guidelines, see *
|
||||
* http://www.synchro.net/source.html *
|
||||
* *
|
||||
* You are encouraged to submit any modifications (preferably in Unix diff *
|
||||
* format) via e-mail to mods@synchro.net *
|
||||
* *
|
||||
* Note: If this box doesn't appear square, then you need to fix your tabs. *
|
||||
****************************************************************************/
|
||||
|
||||
/* ANSI */
|
||||
#include <malloc.h>
|
||||
|
||||
/* SMB-specific */
|
||||
#include "smblib.h"
|
||||
|
||||
char HUGE16* SMBCALL smb_getmsgtxt(smb_t* smb, smbmsg_t* msg, ulong mode)
|
||||
{
|
||||
char HUGE16* buf=NULL,HUGE16* lzhbuf,HUGE16* p;
|
||||
ushort xlat;
|
||||
int i,lzh;
|
||||
long l=0,lzhlen,length;
|
||||
|
||||
for(i=0;i<msg->hdr.total_dfields;i++) {
|
||||
if(!(msg->dfield[i].type==TEXT_BODY
|
||||
|| (mode&GETMSGTXT_TAILS && msg->dfield[i].type==TEXT_TAIL))
|
||||
|| msg->dfield[i].length<=2L)
|
||||
continue;
|
||||
fseek(smb->sdt_fp,msg->hdr.offset+msg->dfield[i].offset
|
||||
,SEEK_SET);
|
||||
fread(&xlat,2,1,smb->sdt_fp);
|
||||
lzh=0;
|
||||
if(xlat==XLAT_LZH) {
|
||||
lzh=1;
|
||||
fread(&xlat,2,1,smb->sdt_fp);
|
||||
}
|
||||
if(xlat!=XLAT_NONE) /* no other translations currently supported */
|
||||
continue;
|
||||
|
||||
length=msg->dfield[i].length-2L;
|
||||
if(lzh) {
|
||||
length-=2;
|
||||
if(length<1)
|
||||
continue;
|
||||
if((lzhbuf=(char HUGE16 *)LMALLOC(length))==NULL) {
|
||||
sprintf(smb->last_error
|
||||
,"malloc failure of %ld bytes for LZH buffer"
|
||||
,length);
|
||||
return(buf);
|
||||
}
|
||||
smb_fread(lzhbuf,length,smb->sdt_fp);
|
||||
lzhlen=*(long*)lzhbuf;
|
||||
if((p=(char HUGE16 *)REALLOC(buf,l+lzhlen+3L))==NULL) {
|
||||
sprintf(smb->last_error
|
||||
,"realloc failure of %ld bytes for text buffer"
|
||||
,l+lzhlen+3L);
|
||||
FREE(lzhbuf);
|
||||
return(buf);
|
||||
}
|
||||
buf=p;
|
||||
lzh_decode((uchar*)lzhbuf,length,(uchar*)buf+l);
|
||||
FREE(lzhbuf);
|
||||
l+=lzhlen;
|
||||
}
|
||||
else {
|
||||
if((p=(char HUGE16 *)REALLOC(buf,l+length+3L))==NULL) {
|
||||
sprintf(smb->last_error
|
||||
,"realloc failure of %ld bytes for text buffer"
|
||||
,l+length+3L);
|
||||
return(buf);
|
||||
}
|
||||
buf=p;
|
||||
p=buf+l;
|
||||
l+=fread(p,1,length,smb->sdt_fp);
|
||||
}
|
||||
if(!l)
|
||||
continue;
|
||||
l--;
|
||||
while(l && buf[l]==0) l--;
|
||||
l++;
|
||||
*(buf+l)=CR;
|
||||
l++;
|
||||
*(buf+l)=LF;
|
||||
l++;
|
||||
*(buf+l)=0;
|
||||
}
|
||||
return(buf);
|
||||
}
|
||||
|
||||
void SMBCALL smb_freemsgtxt(char HUGE16* buf)
|
||||
{
|
||||
if(buf!=NULL)
|
||||
FREE(buf);
|
||||
}
|
Reference in New Issue
Block a user