Various SMB fixes
This commit is contained in:
parent
41796b160f
commit
cff3b440eb
@ -12,6 +12,15 @@ ______________________________________________________________________
|
||||
Notes for GoldED+ 1.1.5, /snapshot/
|
||||
______________________________________________________________________
|
||||
|
||||
- Fixed various types of SMB corruption, especially on changing
|
||||
message or updating attrbutes.
|
||||
|
||||
- Fixed crash on hex-dumping empty SMB message.
|
||||
|
||||
- Fixed problem with non-emporting mail from SMB area.
|
||||
|
||||
! Updated SMBLib to the recent version.
|
||||
|
||||
+ Added patch by Vladimir V. Korablin for @notforward template token.
|
||||
The line containing this token is left only when message IS NOT
|
||||
a forward. This is "@forward"'s counterpart.
|
||||
|
@ -547,7 +547,10 @@ void GMsgList::Run() {
|
||||
return;
|
||||
}
|
||||
|
||||
index = AA->Msgn.ToReln(reader_msg->msgno)-1;
|
||||
if(AA->Msgn.ToReln(reader_msg->msgno) != 0)
|
||||
index = AA->Msgn.ToReln(reader_msg->msgno)-1;
|
||||
else
|
||||
index = 0;
|
||||
minimum_index = 0;
|
||||
msgmark2 = AA->Msgn.ToReln(AA->bookmark);
|
||||
|
||||
@ -977,7 +980,8 @@ void GThreadlist::BuildThreadIndex(dword msgn) {
|
||||
|
||||
bool GThreadlist::NextThread(bool next) {
|
||||
|
||||
for(uint m = AA->Msgn.ToReln(reader_msg->msgno)-1;
|
||||
uint m = AA->Msgn.ToReln(reader_msg->msgno);
|
||||
for(m = m ? m-1 : 0;
|
||||
next ? m < AA->Msgn.Count() : m;
|
||||
next ? m++ : m--) {
|
||||
|
||||
|
@ -31,9 +31,6 @@ gcrcm32 cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
gcrcs16 cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
gcrcs32 cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
|
||||
## Compression
|
||||
glzh cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
|
||||
## Debugging.
|
||||
gdbgerr cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
gdbgexit cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
|
@ -1,651 +0,0 @@
|
||||
// This may look like C code, but it is really -*- C++ -*-
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// The Goldware Library
|
||||
// Copyright (C) 2000 Alex. S. Aganichev
|
||||
// ------------------------------------------------------------------
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this program; if not, write to the Free
|
||||
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
// MA 02111-1307, USA
|
||||
// ------------------------------------------------------------------
|
||||
// $Id$
|
||||
// ------------------------------------------------------------------
|
||||
// Digital Dynamics 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
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
#include <cstring>
|
||||
#include <gctype.h>
|
||||
#include <gmemdbg.h>
|
||||
#include <glzh.h>
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
static char lzh_text_buf[LZH_N + LZH_F - 1];
|
||||
static short int lzh_match_position, lzh_match_length, lzh_lson[LZH_N + 1], lzh_rson[LZH_N + 257], lzh_dad[LZH_N + 1];
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Initializing tree
|
||||
|
||||
static void glzh_init_tree(void) {
|
||||
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
|
||||
|
||||
static void glzh_insert_node(short int r) {
|
||||
short int i, p, cmp;
|
||||
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) < 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
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Deleting node from the tree
|
||||
|
||||
static void glzh_delete_node(short int p) {
|
||||
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
|
||||
|
||||
// character code (= 0..LZH_N_CHAR-1)
|
||||
#define LZH_N_CHAR (256 - LZH_THRESHOLD + LZH_F)
|
||||
// Size of table
|
||||
#define LZH_T (LZH_N_CHAR * 2 - 1)
|
||||
// root position
|
||||
#define LZH_R (LZH_T - 1)
|
||||
// update when cumulative frequency reaches to this value
|
||||
#define MAX_FREQ 0x8000
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Tables for encoding/decoding upper 6 bits of sliding dictionary pointer
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// encoder table
|
||||
|
||||
static char 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
|
||||
};
|
||||
|
||||
static char 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
|
||||
|
||||
static char 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,
|
||||
};
|
||||
|
||||
static char 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,
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static unsigned short lzh_freq[LZH_T + 1]; // cumulative freq table
|
||||
static short int lzh_prnt[LZH_T + LZH_N_CHAR];
|
||||
static short int lzh_son[LZH_T + 1];
|
||||
|
||||
static unsigned short lzh_getbuf = 0;
|
||||
static char lzh_getlen = 0;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// get one bit
|
||||
|
||||
static int glzh_getbit(char *inbuf, long *incnt, long inlen) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// get a byte
|
||||
|
||||
static short int glzh_getbyte(char *inbuf, long *incnt, long inlen) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static unsigned lzh_putbuf = 0;
|
||||
static char lzh_putlen = 0;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// output c bits
|
||||
|
||||
static void glzh_putcode(short int l, unsigned short c, char *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
|
||||
|
||||
static void glzh_start_huff() {
|
||||
short int i, j;
|
||||
|
||||
lzh_getbuf = 0;
|
||||
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
|
||||
|
||||
static void glzh_reconst() {
|
||||
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;
|
||||
|
||||
memmove(lzh_freq+k+1, lzh_freq+k, l);
|
||||
lzh_freq[k] = f;
|
||||
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
|
||||
|
||||
static void glzh_update(short int c)
|
||||
{
|
||||
short int i, j, k, l;
|
||||
|
||||
if (lzh_freq[LZH_R] == MAX_FREQ)
|
||||
glzh_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
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static unsigned short lzh_code, lzh_len;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static void glzh_encode_char(unsigned short c, char *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);
|
||||
glzh_putcode(j, i, outbuf, outlen);
|
||||
lzh_code = i;
|
||||
lzh_len = j;
|
||||
glzh_update(c);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static void glzh_encode_position(unsigned short c, char *outbuf, long *outlen) {
|
||||
unsigned short i;
|
||||
|
||||
// output upper 6 bits with encoding
|
||||
i = c >> 6;
|
||||
glzh_putcode(lzh_p_len[i], (unsigned)lzh_p_code[i] << 8, outbuf, outlen);
|
||||
|
||||
// output lower 6 bits directly
|
||||
glzh_putcode(6, (c & 0x3f) << 10, outbuf, outlen);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static void glzh_encode_end(char *outbuf, long *outlen) {
|
||||
|
||||
if(lzh_putlen)
|
||||
outbuf[(*outlen)++]=(lzh_putbuf >> 8);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static short int glzh_decode_char(char *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 += glzh_getbit(inbuf,incnt,inlen);
|
||||
c = lzh_son[c];
|
||||
}
|
||||
c -= LZH_T;
|
||||
glzh_update(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static short int glzh_decode_position(char *inbuf, long *incnt, long inlen) {
|
||||
unsigned short i, j, c;
|
||||
|
||||
// decode upper 6 bits from given table
|
||||
i = glzh_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) + glzh_getbit(inbuf,incnt,inlen);
|
||||
return c | i & 0x3f;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Encoding/Compressing: returns length of outbuf
|
||||
|
||||
long glzh_encode(char *inbuf, long inlen, char *outbuf) {
|
||||
short int i, c, len, r, s, last_match_length;
|
||||
long incnt,outlen; // textsize=0;
|
||||
|
||||
incnt=0;
|
||||
memcpy(outbuf,&inlen,sizeof(inlen));
|
||||
outlen=sizeof(inlen);
|
||||
if(not inlen) {
|
||||
return(outlen);
|
||||
}
|
||||
glzh_start_huff();
|
||||
glzh_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 and incnt<inlen; len++)
|
||||
lzh_text_buf[r + len] = inbuf[incnt++];
|
||||
for(i = 1; i <= LZH_F; i++)
|
||||
glzh_insert_node(r - i);
|
||||
glzh_insert_node(r);
|
||||
do {
|
||||
if(lzh_match_length > len)
|
||||
lzh_match_length = len;
|
||||
if(lzh_match_length <= LZH_THRESHOLD) {
|
||||
lzh_match_length = 1;
|
||||
glzh_encode_char(lzh_text_buf[r],outbuf,&outlen);
|
||||
} else {
|
||||
glzh_encode_char(255 - LZH_THRESHOLD + lzh_match_length, outbuf, &outlen);
|
||||
glzh_encode_position(lzh_match_position, outbuf, &outlen);
|
||||
}
|
||||
last_match_length = lzh_match_length;
|
||||
for(i = 0; i<last_match_length and incnt<inlen; i++) {
|
||||
glzh_delete_node(s);
|
||||
c=inbuf[incnt++];
|
||||
lzh_text_buf[s] = c;
|
||||
if(s < LZH_F - 1)
|
||||
lzh_text_buf[s + LZH_N] = c;
|
||||
s = (s + 1) & (LZH_N - 1);
|
||||
r = (r + 1) & (LZH_N - 1);
|
||||
glzh_insert_node(r);
|
||||
}
|
||||
while(i++ < last_match_length) {
|
||||
glzh_delete_node(s);
|
||||
s = (s + 1) & (LZH_N - 1);
|
||||
r = (r + 1) & (LZH_N - 1);
|
||||
if(--len)
|
||||
glzh_insert_node(r);
|
||||
}
|
||||
} while(len > 0);
|
||||
glzh_encode_end(outbuf, &outlen);
|
||||
|
||||
return(outlen);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Decoding/Uncompressing: returns length of outbuf
|
||||
|
||||
long glzh_decode(char *inbuf, long inlen, char *outbuf) {
|
||||
short int i, j, k, r, c;
|
||||
unsigned long int count;
|
||||
long incnt,textsize;
|
||||
|
||||
incnt=0;
|
||||
memcpy(&textsize, inbuf, sizeof(textsize));
|
||||
incnt+=sizeof(textsize);
|
||||
if(textsize == 0) {
|
||||
return(textsize);
|
||||
}
|
||||
glzh_start_huff();
|
||||
for(i = 0; i < LZH_N - LZH_F; i++)
|
||||
*(lzh_text_buf+i) = ' ';
|
||||
r = LZH_N - LZH_F;
|
||||
for(count = 0; count < textsize; ) {
|
||||
c = glzh_decode_char(inbuf,&incnt,inlen);
|
||||
if(c < 256) {
|
||||
outbuf[count]=c;
|
||||
*(lzh_text_buf+r) = c;
|
||||
r++;
|
||||
r &= (LZH_N - 1);
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
i = (r - glzh_decode_position(inbuf,&incnt,inlen) - 1) & (LZH_N - 1);
|
||||
j = c - 255 + LZH_THRESHOLD;
|
||||
for (k = 0; k < j && count<textsize; k++) {
|
||||
c = lzh_text_buf[(i + k) & (LZH_N - 1)];
|
||||
outbuf[count]=c;
|
||||
*(lzh_text_buf+r) = c;
|
||||
r++;
|
||||
r &= (LZH_N - 1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
@ -1,41 +0,0 @@
|
||||
// This may look like C code, but it is really -*- C++ -*-
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// The Goldware Library
|
||||
// Copyright (C) 2000 Alexander S. Aganichev
|
||||
// ------------------------------------------------------------------
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this program; if not, write to the Free
|
||||
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
// MA 02111-1307, USA
|
||||
// ------------------------------------------------------------------
|
||||
// $Id$
|
||||
// ------------------------------------------------------------------
|
||||
// Input form and field editing.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
#ifndef __glzh_h
|
||||
#define __glzh_h
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
long glzh_encode(char *inbuf, long inlen, char *outbuf);
|
||||
long glzh_decode(char *inbuf, long inlen, char *outbuf);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------
|
@ -3,7 +3,6 @@
|
||||
TOP=../..
|
||||
TARGET=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)
|
||||
|
@ -505,7 +505,7 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
|
||||
char *fbuf, *sbody, *stail;
|
||||
char buf[256];
|
||||
smbmsg_t smsg;
|
||||
fidoaddr_t destaddr, origaddr;
|
||||
fidoaddr_t destaddr;
|
||||
|
||||
GFTRK("SMBSaveHdr");
|
||||
|
||||
@ -571,8 +571,12 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
|
||||
if((mode & GMSG_UPDATE) and not (mode & GMSG_TXT)) {
|
||||
if(mode & GMSG_NEW)
|
||||
smb_addmsghdr(data, &smsg, data->status.attr & SMB_HYPERALLOC);
|
||||
else
|
||||
smb_putmsghdr(data, &smsg);
|
||||
else {
|
||||
smsg.idx.time = smsg.hdr.when_imported.time;
|
||||
smsg.idx.attr = smsg.hdr.attr;
|
||||
smsg.offset = Msgn->ToReln(msg->msgno) - 1;
|
||||
smb_putmsg(data, &smsg);
|
||||
}
|
||||
smb_freemsgmem(&smsg);
|
||||
GFTRK(NULL);
|
||||
return;
|
||||
@ -600,13 +604,6 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
|
||||
}
|
||||
|
||||
ushort net = NET_FIDO;
|
||||
origaddr.zone = msg->orig.zone;
|
||||
origaddr.net = msg->orig.net;
|
||||
origaddr.node = msg->orig.node;
|
||||
origaddr.point = msg->orig.point;
|
||||
smb_hfield(&smsg, SENDERNETTYPE, sizeof(ushort), &net);
|
||||
smb_hfield(&smsg, SENDERNETADDR, sizeof(fidoaddr_t), &origaddr);
|
||||
|
||||
destaddr.zone = msg->dest.zone;
|
||||
destaddr.net = msg->dest.net;
|
||||
destaddr.node = msg->dest.node;
|
||||
@ -631,12 +628,14 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
|
||||
|
||||
// calculate maximum possible size of sbody/stail
|
||||
for(l = 0, fbuf = msg->txt; *fbuf != NUL; l++, fbuf++)
|
||||
if(l == CR)
|
||||
if(*fbuf == CR)
|
||||
++l;
|
||||
|
||||
l += 2; // reserve 2 bytes for the encoding type
|
||||
|
||||
fbuf = msg->txt;
|
||||
sbody = (char *)throw_malloc(SDT_BLOCK_LEN*smb_datblocks(l));
|
||||
stail = (char *)throw_malloc(SDT_BLOCK_LEN*smb_datblocks(l));
|
||||
sbody = (char *)throw_malloc(SDT_BLOCK_LEN*smb_datblocks(l))+2;
|
||||
stail = (char *)throw_malloc(SDT_BLOCK_LEN*smb_datblocks(l))+2;
|
||||
|
||||
for(l = bodylen = taillen = done = 0, cr = true; (ch = fbuf[l]) != NUL; l++) {
|
||||
if(ch == CTRL_A and cr) {
|
||||
@ -753,29 +752,57 @@ void SMBArea::save_hdr(int mode, gmsg* msg)
|
||||
|
||||
if(smsg.hdr.offset != (ulong)-1L) {
|
||||
fseek(data->sdt_fp, smsg.hdr.offset, SEEK_SET);
|
||||
ushort xlat = XLAT_NONE;
|
||||
fwrite(&xlat, 2, 1, data->sdt_fp);
|
||||
*(ushort *)(sbody-2) = XLAT_NONE;
|
||||
l = ftell(data->sdt_fp);
|
||||
fwrite(sbody, SDT_BLOCK_LEN, smb_datblocks(bodylen), data->sdt_fp);
|
||||
fwrite(sbody-2, 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);
|
||||
*(ushort *)(stail-2) = XLAT_NONE;
|
||||
fwrite(stail-2, 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);
|
||||
|
||||
int storage = data->status.attr & SMB_HYPERALLOC;
|
||||
|
||||
if(mode & GMSG_NEW) {
|
||||
smb_addmsghdr(data, &smsg, data->status.attr & SMB_HYPERALLOC);
|
||||
smb_addmsghdr(data, &smsg, storage);
|
||||
Msgn->Append(smsg.hdr.number);
|
||||
}
|
||||
else
|
||||
smb_putmsghdr(data, &smsg);
|
||||
else {
|
||||
// Changing message... It is always bad idea since it is usually
|
||||
// undescribed and not supported by the API
|
||||
long l;
|
||||
|
||||
if(data->locked or (smb_locksmbhdr(data) == 0)) {
|
||||
if(smb_getstatus(data) == 0) {
|
||||
if((storage == SMB_HYPERALLOC) or (smb_open_ha(data) == 0)) {
|
||||
smsg.hdr.length = smb_getmsghdrlen(&smsg);
|
||||
if(storage == SMB_HYPERALLOC)
|
||||
l = smb_hallochdr(data);
|
||||
else if(storage == SMB_FASTALLOC)
|
||||
l = smb_fallochdr(data, smsg.hdr.length);
|
||||
else
|
||||
l = smb_allochdr(data, smsg.hdr.length);
|
||||
if(storage != SMB_HYPERALLOC)
|
||||
smb_close_ha(data);
|
||||
if(l!=-1L) {
|
||||
smsg.idx.offset = data->status.header_offset+l;
|
||||
smsg.idx.time = smsg.hdr.when_imported.time;
|
||||
smsg.idx.attr = smsg.hdr.attr;
|
||||
smsg.offset = Msgn->ToReln(msg->msgno) - 1;
|
||||
smb_putmsg(data, &smsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
smb_unlocksmbhdr(data);
|
||||
}
|
||||
}
|
||||
throw_xfree(sbody);
|
||||
throw_xfree(stail);
|
||||
throw_xfree(sbody-2);
|
||||
throw_xfree(stail-2);
|
||||
smb_freemsgmem(&smsg);
|
||||
|
||||
GFTRK(NULL);
|
||||
@ -813,7 +840,10 @@ void SMBArea::del_msg(gmsg* msg)
|
||||
}
|
||||
if(smb_getmsghdr(data, &smsg) == 0) {
|
||||
smsg.hdr.attr |= MSG_DELETE;
|
||||
int rv = smb_putmsghdr(data, &smsg);
|
||||
smsg.idx.time = smsg.hdr.when_imported.time;
|
||||
smsg.idx.attr = smsg.hdr.attr;
|
||||
smsg.offset = reln - 1L;
|
||||
int rv = smb_putmsg(data, &smsg);
|
||||
smb_unlockmsghdr(data, &smsg);
|
||||
if(rv == 0)
|
||||
msg->attr.del1();
|
||||
@ -874,7 +904,7 @@ static char *binstr(char *buf, ushort length)
|
||||
for(i = 0; i < length; i++)
|
||||
if(buf[i] and not isprint(buf[i]))
|
||||
break;
|
||||
if(i == length) /* not binary */
|
||||
if(i == length) /* not binary */
|
||||
return buf;
|
||||
|
||||
if(length > 42)
|
||||
@ -1045,11 +1075,14 @@ common:
|
||||
msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen);
|
||||
lzh_decode(inbuf, smsg.dfield[i].length - l, (uchar *)(msg->txt+txt_len-1));
|
||||
throw_xfree(inbuf);
|
||||
} else {
|
||||
}
|
||||
else if(l < smsg.dfield[i].length) {
|
||||
outlen = smsg.dfield[i].length - l;
|
||||
msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen);
|
||||
fread(msg->txt+txt_len-1, smsg.dfield[i].length - l, 1, data->sdt_fp);
|
||||
}
|
||||
else
|
||||
outlen = 0;
|
||||
txt_len+=outlen;
|
||||
msg->txt[txt_len-1] = NUL;
|
||||
break;
|
||||
|
@ -3,6 +3,7 @@
|
||||
TOP=../..
|
||||
TARGET=smblib
|
||||
INCS=-I$(TOP)/goldlib/smblib -I$(TOP)/goldlib/gall
|
||||
CFLAGS=-x c++
|
||||
|
||||
include $(TOP)/GNUmakef.inc
|
||||
include $(TOP)/GNUmakef.lib
|
||||
|
@ -1,9 +0,0 @@
|
||||
/* crc32.h */
|
||||
|
||||
/* wrapper for gall library */
|
||||
|
||||
#include <gcrcall.h>
|
||||
|
||||
#define ucrc32(ch,crc) updCrc32(ch,crc)
|
||||
|
||||
|
8
goldlib/smblib/filewrap.h
Normal file
8
goldlib/smblib/filewrap.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __filewrap_h
|
||||
#define __filewrap_h
|
||||
|
||||
#include <gfilutil.h>
|
||||
|
||||
#define sopen(fn,access,share) (sopen)((fn),(access),(share),S_IREAD|S_IWRITE)
|
||||
|
||||
#endif // __filewrap_h
|
8
goldlib/smblib/genwrap.h
Normal file
8
goldlib/smblib/genwrap.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __genwrap_h
|
||||
#define __genwrap_h
|
||||
|
||||
#include <gtimall.h>
|
||||
|
||||
#define SLEEP(a) usleep(a)
|
||||
|
||||
#endif // __genwrap_h
|
@ -35,7 +35,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* FreeBSD's malloc.h is deprecated, it drops a warning and */
|
||||
/* #includes <stdlib.h>, which is already here. */
|
||||
#ifndef __FreeBSD__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "lzh.h"
|
||||
|
||||
/****************************************************************************/
|
||||
@ -582,7 +588,7 @@ short int lzh_decode_position(uchar *inbuf, long *incnt, long inlen)
|
||||
while (j--) {
|
||||
i = (i << 1) + lzh_getbit(inbuf,incnt,inlen);
|
||||
}
|
||||
return c | i & 0x3f;
|
||||
return c | (i & 0x3f);
|
||||
}
|
||||
|
||||
/* Compression */
|
@ -53,23 +53,19 @@
|
||||
#else /* self-contained executable */
|
||||
#define LZHEXPORT
|
||||
#endif
|
||||
#elif defined(__unix__) || defined(__GNUC__)
|
||||
#ifndef __FLAT__
|
||||
#define __FLAT__
|
||||
#endif
|
||||
#define LZHCALL
|
||||
#define LZHEXPORT
|
||||
#else /* !_WIN32 */
|
||||
#define LZHCALL
|
||||
#define LZHEXPORT
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifndef __FLAT__
|
||||
#define __FLAT__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GOLDEDPLUS
|
||||
#ifndef uchar
|
||||
#define uchar unsigned char
|
||||
#endif
|
||||
#else
|
||||
#include <gdefs.h>
|
||||
typedef unsigned char uchar;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -38,43 +38,28 @@
|
||||
#ifndef _SMBDEFS_H
|
||||
#define _SMBDEFS_H
|
||||
|
||||
#ifdef GOLDEDPLUS
|
||||
#include <gdefs.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
/**********/
|
||||
/* Macros */
|
||||
/**********/
|
||||
|
||||
#define SMB_HEADER_ID "SMB\x1a" /* <S> <M> <B> <^Z> */
|
||||
#define SHD_HEADER_ID "SHD\x1a" /* <S> <H> <D> <^Z> */
|
||||
#define LEN_HEADER_ID 4
|
||||
|
||||
#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
|
||||
typedef unsigned char uchar;
|
||||
#endif
|
||||
#ifdef __GLIBC__
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
#ifndef ushort
|
||||
#define ushort unsigned short
|
||||
#define ulong unsigned long
|
||||
#define uint unsigned int
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* Memory allocation macros for various compilers and environments */
|
||||
@ -126,6 +111,8 @@
|
||||
|
||||
#define SMB_EMAIL 1 /* User numbers stored in Indexes */
|
||||
|
||||
#define SMB_ERR_NOT_OPEN -100 /* Message base not open */
|
||||
|
||||
/* Time zone macros for when_t.zone */
|
||||
#define DAYLIGHT 0x8000 /* Daylight savings is active */
|
||||
#define US_ZONE 0x4000 /* U.S. time zone */
|
||||
@ -277,6 +264,12 @@
|
||||
#define RFC822HEADER 0xb0
|
||||
#define RFC822MSGID 0xb1
|
||||
#define RFC822REPLYID 0xb2
|
||||
#define RFC822TO 0xb3
|
||||
#define RFC822FROM 0xb4
|
||||
#define RFC822REPLYTO 0xb5
|
||||
|
||||
#define USENETPATH 0xc0
|
||||
#define USENETNEWSGROUPS 0xc1
|
||||
|
||||
#define UNKNOWN 0xf1
|
||||
#define UNKNOWNASCII 0xf2
|
||||
@ -337,14 +330,15 @@
|
||||
|
||||
|
||||
enum {
|
||||
NET_NONE
|
||||
,NET_UNKNOWN
|
||||
,NET_FIDO
|
||||
,NET_POSTLINK
|
||||
,NET_QWK
|
||||
,NET_INTERNET
|
||||
,NET_WWIV
|
||||
,NET_MHS
|
||||
NET_NONE /* Local message */
|
||||
,NET_UNKNOWN /* Unknown network type */
|
||||
,NET_FIDO /* FidoNet address, faddr_t format (4D) */
|
||||
,NET_POSTLINK /* Imported with UTI driver */
|
||||
,NET_QWK /* QWK networked messsage */
|
||||
,NET_INTERNET /* Internet e-mail, netnews, etc. */
|
||||
,NET_WWIV /* unused */
|
||||
,NET_MHS /* unused */
|
||||
,NET_FIDO_ASCII /* FidoNet address, ASCIIZ format (e.g. 5D) */
|
||||
|
||||
/* Add new ones here */
|
||||
|
||||
@ -382,23 +376,20 @@ enum {
|
||||
/* Typedefs */
|
||||
/************/
|
||||
|
||||
#ifndef GOLDEDPLUS
|
||||
#ifdef __GNUC__
|
||||
#define _PACK __attribute__ ((packed))
|
||||
#else
|
||||
#define _PACK
|
||||
#if defined(_WIN32) || defined(__BORLANDC__)
|
||||
#define PRAGMA_PACK
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(PRAGMA_PACK)
|
||||
#define _PACK
|
||||
#else
|
||||
#define _PACK __attribute__ ((packed))
|
||||
#endif
|
||||
|
||||
#if defined(PRAGMA_PACK)
|
||||
#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
|
||||
|
||||
@ -421,7 +412,7 @@ typedef struct _PACK { // Index record
|
||||
|
||||
typedef struct _PACK { // Message base header (fixed portion)
|
||||
|
||||
uchar id[4]; // text or binary unique hdr ID
|
||||
uchar id[LEN_HEADER_ID]; // SMB<^Z>
|
||||
ushort version; // version number (initially 100h for 1.00)
|
||||
ushort length; // length including this struct
|
||||
|
||||
@ -441,7 +432,7 @@ typedef struct _PACK { // Message base status header
|
||||
|
||||
typedef struct _PACK { // Message header
|
||||
|
||||
uchar id[4]; // SHD<^Z>
|
||||
uchar id[LEN_HEADER_ID]; // 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
|
||||
@ -492,16 +483,9 @@ typedef struct _PACK { // Network (type and address)
|
||||
|
||||
} net_t;
|
||||
|
||||
#ifndef GOLDEDPLUS
|
||||
#ifdef _WIN32
|
||||
#if defined(PRAGMA_PACK)
|
||||
#pragma pack(pop) /* original packing */
|
||||
#endif
|
||||
#else
|
||||
#undef _PACK
|
||||
#if defined(GOLD_CANPACK)
|
||||
#pragma pack()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct { // Message
|
||||
|
||||
@ -513,6 +497,15 @@ typedef struct { // Message
|
||||
*from_ext, // From extension
|
||||
*replyto, // Reply-to name
|
||||
*replyto_ext, // Reply-to extension */
|
||||
*id, // RFC822 Message-ID
|
||||
*reply_id, // RFC822 Reply-ID
|
||||
*path, // USENET Path
|
||||
*newsgroups, // USENET Newsgroups
|
||||
*ftn_pid, // FTN PID
|
||||
*ftn_area, // FTN AREA
|
||||
*ftn_flags, // FTN FLAGS
|
||||
*ftn_msgid, // FTN MSGID
|
||||
*ftn_reply, // FTN REPLY
|
||||
*subj; // Subject
|
||||
ushort to_agent, // Type of agent message is to
|
||||
from_agent, // Type of agent message is from
|
||||
@ -525,7 +518,7 @@ typedef struct { // Message
|
||||
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
|
||||
int forwarded; // Forwarded from agent to another
|
||||
when_t expiration; // Message will exipre on this day (if >0)
|
||||
|
||||
} smbmsg_t;
|
||||
@ -539,10 +532,17 @@ typedef struct { // Message base
|
||||
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
|
||||
ulong retry_delay; // Time-slice yield (milliseconds) while retrying
|
||||
smbstatus_t status; // Status header record
|
||||
int locked; // SMB header is locked
|
||||
char shd_buf[SHD_BLOCK_LEN]; // File I/O buffer for header file
|
||||
char last_error[128]; // Last error message
|
||||
|
||||
/* Private member variables (not initialized by or used by smblib) */
|
||||
uint subnum; // Sub-board number
|
||||
long msgs; // Number of messages loaded (for user)
|
||||
long curmsg; // Current message number (for user)
|
||||
|
||||
} smb_t;
|
||||
|
||||
#endif /* Don't add anything after this #endif statement */
|
||||
|
@ -1,3 +1,2 @@
|
||||
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
|
||||
lzh c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
smblib c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg
|
||||
|
@ -48,7 +48,11 @@
|
||||
#endif
|
||||
|
||||
/* ANSI C Library headers */
|
||||
#include <malloc.h>
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -60,16 +64,11 @@
|
||||
|
||||
/* SMB-specific headers */
|
||||
#include "smblib.h"
|
||||
#ifndef GOLDEDPLUS
|
||||
#include "smbwrap.h"
|
||||
#else
|
||||
#include <gfilutil.h>
|
||||
|
||||
#define sopen(fn,access,share) (sopen)((fn),(access),(share),S_IREAD|S_IWRITE)
|
||||
#endif
|
||||
#include "genwrap.h"
|
||||
#include "filewrap.h"
|
||||
|
||||
/* Use smb_ver() and smb_lib_ver() to obtain these values */
|
||||
#define SMBLIB_VERSION "2.13" /* SMB library version */
|
||||
#define SMBLIB_VERSION "2.16" /* SMB library version */
|
||||
#define SMB_VERSION 0x0121 /* SMB format version */
|
||||
/* High byte major, low byte minor */
|
||||
|
||||
@ -93,18 +92,26 @@ int SMBCALL smb_open(smb_t* smb)
|
||||
char str[128];
|
||||
smbhdr_t hdr;
|
||||
|
||||
/* Set default values, if uninitialized */
|
||||
if(!smb->retry_time)
|
||||
smb->retry_time=10;
|
||||
smb->retry_time=10; /* seconds */
|
||||
if(!smb->retry_delay
|
||||
|| smb->retry_delay>(smb->retry_time*100)) /* at least ten retries */
|
||||
smb->retry_delay=250; /* milliseconds */
|
||||
smb->shd_fp=smb->sdt_fp=smb->sid_fp=NULL;
|
||||
smb->last_error[0]=0;
|
||||
sprintf(str,"%s.shd",smb->file);
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO))==-1
|
||||
|| (smb->shd_fp=fdopen(file,"r+b"))==NULL) {
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO))==-1) {
|
||||
sprintf(smb->last_error,"%d opening %s",errno,str);
|
||||
if(file!=-1)
|
||||
close(file);
|
||||
return(2);
|
||||
}
|
||||
|
||||
if((smb->shd_fp=fdopen(file,"r+b"))==NULL) {
|
||||
sprintf(smb->last_error,"%d fdopening %s (%d)",errno,str,file);
|
||||
close(file);
|
||||
return(4);
|
||||
}
|
||||
|
||||
if(filelength(file)>=sizeof(smbhdr_t)) {
|
||||
setvbuf(smb->shd_fp,smb->shd_buf,_IONBF,SHD_BLOCK_LEN);
|
||||
if(smb_locksmbhdr(smb)!=0) {
|
||||
@ -118,8 +125,8 @@ int SMBCALL smb_open(smb_t* smb)
|
||||
smb_close(smb);
|
||||
return(-10);
|
||||
}
|
||||
if(memcmp(hdr.id,"SMB\x1a",4)) {
|
||||
sprintf(smb->last_error,"corrupt header id: %.4s",hdr.id);
|
||||
if(memcmp(hdr.id,SMB_HEADER_ID,LEN_HEADER_ID)) {
|
||||
sprintf(smb->last_error,"corrupt SMB header ID: %.*s",LEN_HEADER_ID,hdr.id);
|
||||
smb_close(smb);
|
||||
return(-2);
|
||||
}
|
||||
@ -141,25 +148,35 @@ int SMBCALL smb_open(smb_t* smb)
|
||||
setvbuf(smb->shd_fp,smb->shd_buf,_IOFBF,SHD_BLOCK_LEN);
|
||||
|
||||
sprintf(str,"%s.sdt",smb->file);
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO))==-1
|
||||
|| (smb->sdt_fp=fdopen(file,"r+b"))==NULL) {
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO))==-1) {
|
||||
sprintf(smb->last_error,"%d opening %s",errno,str);
|
||||
if(file!=-1)
|
||||
close(file);
|
||||
smb_close(smb);
|
||||
return(1);
|
||||
}
|
||||
|
||||
if((smb->sdt_fp=fdopen(file,"r+b"))==NULL) {
|
||||
sprintf(smb->last_error,"%d fdopening %s (%d)",errno,str,file);
|
||||
close(file);
|
||||
smb_close(smb);
|
||||
return(5);
|
||||
}
|
||||
|
||||
setvbuf(smb->sdt_fp,NULL,_IOFBF,2*1024);
|
||||
|
||||
sprintf(str,"%s.sid",smb->file);
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO))==-1
|
||||
|| (smb->sid_fp=fdopen(file,"r+b"))==NULL) {
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO))==-1) {
|
||||
sprintf(smb->last_error,"%d opening %s",errno,str);
|
||||
if(file!=-1)
|
||||
close(file);
|
||||
smb_close(smb);
|
||||
return(3);
|
||||
}
|
||||
|
||||
if((smb->sid_fp=fdopen(file,"r+b"))==NULL) {
|
||||
sprintf(smb->last_error,"%d fdopening %s (%d)",errno,str,file);
|
||||
close(file);
|
||||
smb_close(smb);
|
||||
return(6);
|
||||
}
|
||||
|
||||
setvbuf(smb->sid_fp,NULL,_IOFBF,2*1024);
|
||||
|
||||
return(0);
|
||||
@ -190,26 +207,28 @@ int SMBCALL smb_open_da(smb_t* smb)
|
||||
{
|
||||
int file;
|
||||
char str[128];
|
||||
ulong start=0;
|
||||
time_t start=0;
|
||||
|
||||
sprintf(str,"%s.sda",smb->file);
|
||||
while(1) {
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW))!=-1)
|
||||
break;
|
||||
if(errno!=EACCES) {
|
||||
if(errno!=EACCES && errno!=EAGAIN) {
|
||||
sprintf(smb->last_error,"%d opening %s",errno,str);
|
||||
return(-1);
|
||||
}
|
||||
if(!start)
|
||||
start=time(NULL);
|
||||
else
|
||||
if(time(NULL)-start>=smb->retry_time) {
|
||||
sprintf(smb->last_error,"timeout opening %s",str);
|
||||
if(time(NULL)-start>=(time_t)smb->retry_time) {
|
||||
sprintf(smb->last_error,"timeout opening %s (retry_time=%ld)"
|
||||
,str,smb->retry_time);
|
||||
return(-2);
|
||||
}
|
||||
SLEEP(smb->retry_delay);
|
||||
}
|
||||
if((smb->sda_fp=fdopen(file,"r+b"))==NULL) {
|
||||
sprintf(smb->last_error,"%d fdopening %s",errno,str);
|
||||
sprintf(smb->last_error,"%d fdopening %s (%d)",errno,str,file);
|
||||
close(file);
|
||||
return(-3);
|
||||
}
|
||||
@ -233,26 +252,28 @@ int SMBCALL smb_open_ha(smb_t* smb)
|
||||
{
|
||||
int file;
|
||||
char str[128];
|
||||
ulong start=0;
|
||||
time_t start=0;
|
||||
|
||||
sprintf(str,"%s.sha",smb->file);
|
||||
while(1) {
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW))!=-1)
|
||||
break;
|
||||
if(errno!=EACCES) {
|
||||
if(errno!=EACCES && errno!=EAGAIN) {
|
||||
sprintf(smb->last_error,"%d opening %s",errno,str);
|
||||
return(-1);
|
||||
}
|
||||
if(!start)
|
||||
start=time(NULL);
|
||||
else
|
||||
if(time(NULL)-start>=smb->retry_time) {
|
||||
sprintf(smb->last_error,"timeout opening %s",str);
|
||||
if(time(NULL)-start>=(time_t)smb->retry_time) {
|
||||
sprintf(smb->last_error,"timeout opening %s (retry_time=%ld)"
|
||||
,str,smb->retry_time);
|
||||
return(-2);
|
||||
}
|
||||
SLEEP(smb->retry_delay);
|
||||
}
|
||||
if((smb->sha_fp=fdopen(file,"r+b"))==NULL) {
|
||||
sprintf(smb->last_error,"%d opening %s",errno,str);
|
||||
sprintf(smb->last_error,"%d fdopening %s (%d)",errno,str,file);
|
||||
close(file);
|
||||
return(-3);
|
||||
}
|
||||
@ -285,76 +306,35 @@ void SMBCALL smb_close_ha(smb_t* smb)
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_stack(smb_t* smb, int op)
|
||||
{
|
||||
static char stack_file[SMB_STACK_LEN][128];
|
||||
static FILE* stack_sdt[SMB_STACK_LEN],
|
||||
*stack_shd[SMB_STACK_LEN],
|
||||
*stack_sid[SMB_STACK_LEN],
|
||||
*stack_sda[SMB_STACK_LEN],
|
||||
*stack_sha[SMB_STACK_LEN];
|
||||
static int stack_idx = 0;
|
||||
char tmp_file[128];
|
||||
FILE *tmp;
|
||||
static smb_t stack[SMB_STACK_LEN];
|
||||
static int stack_idx;
|
||||
smb_t tmp_smb;
|
||||
|
||||
switch(op) {
|
||||
case SMB_STACK_PUSH:
|
||||
if(stack_idx>=SMB_STACK_LEN) {
|
||||
sprintf(smb->last_error,"SMB stack overflow");
|
||||
return(1);
|
||||
}
|
||||
if(smb->shd_fp==NULL || smb->sdt_fp==NULL || smb->sid_fp==NULL)
|
||||
return(0); /* Msg base not open */
|
||||
memcpy(stack_file[stack_idx],smb->file,128);
|
||||
stack_sdt[stack_idx]=smb->sdt_fp;
|
||||
stack_shd[stack_idx]=smb->shd_fp;
|
||||
stack_sid[stack_idx]=smb->sid_fp;
|
||||
stack_sda[stack_idx]=smb->sda_fp;
|
||||
stack_sha[stack_idx]=smb->sha_fp;
|
||||
stack_idx++;
|
||||
return(0);
|
||||
case SMB_STACK_POP:
|
||||
if(!stack_idx) /* Nothing on the stack, so do nothing */
|
||||
return(0);
|
||||
stack_idx--;
|
||||
memcpy(smb->file,stack_file[stack_idx],128);
|
||||
smb->sdt_fp=stack_sdt[stack_idx];
|
||||
smb->shd_fp=stack_shd[stack_idx];
|
||||
smb->sid_fp=stack_sid[stack_idx];
|
||||
smb->sda_fp=stack_sda[stack_idx];
|
||||
smb->sha_fp=stack_sha[stack_idx];
|
||||
if(op==SMB_STACK_PUSH) {
|
||||
if(stack_idx>=SMB_STACK_LEN) {
|
||||
sprintf(smb->last_error,"SMB stack overflow");
|
||||
return(1);
|
||||
}
|
||||
if(smb->shd_fp==NULL || smb->sdt_fp==NULL || smb->sid_fp==NULL)
|
||||
return(0); /* Msg base not open */
|
||||
memcpy(&stack[stack_idx],smb,sizeof(smb_t));
|
||||
stack_idx++;
|
||||
return(0);
|
||||
}
|
||||
/* pop or xchng */
|
||||
if(!stack_idx) /* Nothing on the stack, so do nothing */
|
||||
return(0);
|
||||
if(op==SMB_STACK_XCHNG) {
|
||||
if(smb->shd_fp==NULL)
|
||||
return(0);
|
||||
case SMB_STACK_XCHNG:
|
||||
if(!stack_idx) /* Nothing on the stack, so do nothing */
|
||||
return(0);
|
||||
if(!smb->shd_fp)
|
||||
return(0);
|
||||
stack_idx--;
|
||||
memcpy(&tmp_smb,smb,sizeof(smb_t));
|
||||
}
|
||||
|
||||
memcpy(tmp_file,stack_file[stack_idx],128);
|
||||
memcpy(stack_file[stack_idx],smb->file,128);
|
||||
memcpy(smb->file,tmp_file,128);
|
||||
|
||||
tmp=stack_sdt[stack_idx];
|
||||
stack_sdt[stack_idx]=smb->sdt_fp;
|
||||
smb->sdt_fp=tmp;
|
||||
|
||||
tmp=stack_shd[stack_idx];
|
||||
stack_shd[stack_idx]=smb->shd_fp;
|
||||
smb->shd_fp=tmp;
|
||||
|
||||
tmp=stack_sid[stack_idx];
|
||||
stack_sid[stack_idx]=smb->sid_fp;
|
||||
smb->sid_fp=tmp;
|
||||
|
||||
tmp=stack_sda[stack_idx];
|
||||
stack_sda[stack_idx]=smb->sda_fp;
|
||||
smb->sda_fp=tmp;
|
||||
|
||||
tmp=stack_sha[stack_idx];
|
||||
stack_sha[stack_idx]=smb->sha_fp;
|
||||
smb->sha_fp=tmp;
|
||||
|
||||
stack_idx++;
|
||||
return(0);
|
||||
stack_idx--;
|
||||
memcpy(smb,&stack[stack_idx],sizeof(smb_t));
|
||||
if(op==SMB_STACK_XCHNG) {
|
||||
memcpy(&stack[stack_idx],&tmp_smb,sizeof(smb_t));
|
||||
stack_idx++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@ -366,23 +346,29 @@ int SMBCALL smb_stack(smb_t* smb, int op)
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_trunchdr(smb_t* smb)
|
||||
{
|
||||
ulong start=0;
|
||||
time_t start=0;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
rewind(smb->shd_fp);
|
||||
while(1) {
|
||||
if(!chsize(fileno(smb->shd_fp),0L))
|
||||
break;
|
||||
if(errno!=EACCES) {
|
||||
if(errno!=EACCES && errno!=EAGAIN) {
|
||||
sprintf(smb->last_error,"%d changing header file size",errno);
|
||||
return(-1);
|
||||
}
|
||||
if(!start)
|
||||
start=time(NULL);
|
||||
else
|
||||
if(time(NULL)-start>=smb->retry_time) { /* Time-out */
|
||||
sprintf(smb->last_error,"timeout changing header file size");
|
||||
if(time(NULL)-start>=(time_t)smb->retry_time) { /* Time-out */
|
||||
sprintf(smb->last_error,"timeout changing header file size (retry_time=%ld)"
|
||||
,smb->retry_time);
|
||||
return(-2);
|
||||
}
|
||||
SLEEP(smb->retry_delay);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@ -396,18 +382,26 @@ int SMBCALL smb_trunchdr(smb_t* smb)
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_locksmbhdr(smb_t* smb)
|
||||
{
|
||||
ulong start=0;
|
||||
time_t start=0;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
while(1) {
|
||||
if(!lock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t)))
|
||||
if(lock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t))==0) {
|
||||
smb->locked=1; /* TRUE */
|
||||
return(0);
|
||||
}
|
||||
if(!start)
|
||||
start=time(NULL);
|
||||
else
|
||||
if(time(NULL)-start>=smb->retry_time)
|
||||
if(time(NULL)-start>=(time_t)smb->retry_time)
|
||||
break;
|
||||
/* In case we've already locked it */
|
||||
unlock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t));
|
||||
if(unlock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t))==0)
|
||||
smb->locked=0; /* FALSE */
|
||||
SLEEP(smb->retry_delay);
|
||||
}
|
||||
sprintf(smb->last_error,"timeout locking header");
|
||||
return(-1);
|
||||
@ -420,6 +414,10 @@ int SMBCALL smb_getstatus(smb_t* smb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
setvbuf(smb->shd_fp,smb->shd_buf,_IONBF,SHD_BLOCK_LEN);
|
||||
clearerr(smb->shd_fp);
|
||||
fseek(smb->shd_fp,sizeof(smbhdr_t),SEEK_SET);
|
||||
@ -438,6 +436,10 @@ int SMBCALL smb_putstatus(smb_t* smb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
clearerr(smb->shd_fp);
|
||||
fseek(smb->shd_fp,sizeof(smbhdr_t),SEEK_SET);
|
||||
i=fwrite(&(smb->status),1,sizeof(smbstatus_t),smb->shd_fp);
|
||||
@ -453,7 +455,16 @@ int SMBCALL smb_putstatus(smb_t* smb)
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_unlocksmbhdr(smb_t* smb)
|
||||
{
|
||||
return(unlock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t)));
|
||||
int result;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
result = unlock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t));
|
||||
if(result==0)
|
||||
smb->locked=0; /* FALSE */
|
||||
return(result);
|
||||
}
|
||||
|
||||
/********************************/
|
||||
@ -465,18 +476,23 @@ int SMBCALL smb_unlocksmbhdr(smb_t* smb)
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_lockmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
{
|
||||
ulong start=0;
|
||||
time_t start=0;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
while(1) {
|
||||
if(!lock(fileno(smb->shd_fp),msg->idx.offset,sizeof(msghdr_t)))
|
||||
return(0);
|
||||
if(!start)
|
||||
start=time(NULL);
|
||||
else
|
||||
if(time(NULL)-start>=smb->retry_time)
|
||||
if(time(NULL)-start>=(time_t)smb->retry_time)
|
||||
break;
|
||||
/* In case we've already locked it */
|
||||
unlock(fileno(smb->shd_fp),msg->idx.offset,sizeof(msghdr_t));
|
||||
SLEEP(smb->retry_delay);
|
||||
}
|
||||
sprintf(smb->last_error,"timeout locking header");
|
||||
return(-1);
|
||||
@ -495,6 +511,10 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg)
|
||||
idxrec_t idx;
|
||||
ulong l,length,total,bot,top;
|
||||
|
||||
if(smb->sid_fp==NULL) {
|
||||
sprintf(smb->last_error,"index not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
clearerr(smb->sid_fp);
|
||||
if(!msg->hdr.number) {
|
||||
fseek(smb->sid_fp,msg->offset*sizeof(idxrec_t),SEEK_SET);
|
||||
@ -546,6 +566,24 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg)
|
||||
return(0);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Reads the first index record in the open message base */
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_getfirstidx(smb_t* smb, idxrec_t *idx)
|
||||
{
|
||||
if(smb->sid_fp==NULL) {
|
||||
sprintf(smb->last_error,"index not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
clearerr(smb->sid_fp);
|
||||
fseek(smb->sid_fp,0,SEEK_SET);
|
||||
if(!fread(idx,sizeof(idxrec_t),1,smb->sid_fp)) {
|
||||
sprintf(smb->last_error,"reading index");
|
||||
return(-2);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Reads the last index record in the open message base */
|
||||
/****************************************************************************/
|
||||
@ -553,6 +591,10 @@ int SMBCALL smb_getlastidx(smb_t* smb, idxrec_t *idx)
|
||||
{
|
||||
long length;
|
||||
|
||||
if(smb->sid_fp==NULL) {
|
||||
sprintf(smb->last_error,"index not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
clearerr(smb->sid_fp);
|
||||
length=filelength(fileno(smb->sid_fp));
|
||||
if(length<sizeof(idxrec_t)) {
|
||||
@ -615,6 +657,10 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
ulong l,offset;
|
||||
idxrec_t idx;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
rewind(smb->shd_fp);
|
||||
fseek(smb->shd_fp,msg->idx.offset,SEEK_SET);
|
||||
idx=msg->idx;
|
||||
@ -626,8 +672,8 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
sprintf(smb->last_error,"reading msg header");
|
||||
return(-1);
|
||||
}
|
||||
if(memcmp(msg->hdr.id,"SHD\x1a",4)) {
|
||||
sprintf(smb->last_error,"corrupt header id: %.4s",msg->hdr.id);
|
||||
if(memcmp(msg->hdr.id,SHD_HEADER_ID,LEN_HEADER_ID)) {
|
||||
sprintf(smb->last_error,"corrupt message header ID: %.*s",LEN_HEADER_ID,msg->hdr.id);
|
||||
return(-2);
|
||||
}
|
||||
if(msg->hdr.version<0x110) {
|
||||
@ -721,7 +767,7 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
break;
|
||||
case SENDERNETADDR:
|
||||
if(!msg->forwarded)
|
||||
msg->from_net.addr=msg->hfield_dat[i];
|
||||
msg->from_net.addr=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case REPLYTO:
|
||||
msg->replyto=(char *)msg->hfield_dat[i];
|
||||
@ -736,7 +782,7 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
msg->replyto_net.type=*(ushort *)msg->hfield_dat[i];
|
||||
break;
|
||||
case REPLYTONETADDR:
|
||||
msg->replyto_net.addr=msg->hfield_dat[i];
|
||||
msg->replyto_net.addr=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case RECIPIENT:
|
||||
msg->to=(char *)msg->hfield_dat[i];
|
||||
@ -751,11 +797,39 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
msg->to_net.type=*(ushort *)msg->hfield_dat[i];
|
||||
break;
|
||||
case RECIPIENTNETADDR:
|
||||
msg->to_net.addr=msg->hfield_dat[i];
|
||||
msg->to_net.addr=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case SUBJECT:
|
||||
msg->subj=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
break;
|
||||
case RFC822MSGID:
|
||||
msg->id=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case RFC822REPLYID:
|
||||
msg->reply_id=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case USENETPATH:
|
||||
msg->path=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case USENETNEWSGROUPS:
|
||||
msg->newsgroups=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case FIDOMSGID:
|
||||
msg->ftn_msgid=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case FIDOREPLYID:
|
||||
msg->ftn_reply=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case FIDOAREA:
|
||||
msg->ftn_area=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case FIDOPID:
|
||||
msg->ftn_pid=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
case FIDOFLAGS:
|
||||
msg->ftn_flags=(char *)msg->hfield_dat[i];
|
||||
break;
|
||||
|
||||
}
|
||||
l+=msg->hfield[i].length;
|
||||
}
|
||||
@ -832,6 +906,10 @@ int SMBCALL smb_copymsgmem(smbmsg_t* msg, smbmsg_t* srcmsg)
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_unlockmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
{
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
return(unlock(fileno(smb->shd_fp),msg->idx.offset,sizeof(msghdr_t)));
|
||||
}
|
||||
|
||||
@ -839,11 +917,11 @@ int SMBCALL smb_unlockmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
/****************************************************************************/
|
||||
/* Adds a header field to the 'msg' structure (in memory only) */
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_hfield(smbmsg_t* msg, ushort type, ushort length, void* data)
|
||||
int SMBCALL smb_hfield(smbmsg_t* msg, ushort type, size_t length, void* data)
|
||||
{
|
||||
hfield_t *vp;
|
||||
void **vpp;
|
||||
int i;
|
||||
hfield_t* vp;
|
||||
void* *vpp;
|
||||
int i;
|
||||
|
||||
i=msg->total_hfields;
|
||||
if((vp=(hfield_t *)REALLOC(msg->hfield,sizeof(hfield_t)*(i+1)))==NULL)
|
||||
@ -867,6 +945,23 @@ int SMBCALL smb_hfield(smbmsg_t* msg, ushort type, ushort length, void* data)
|
||||
return(0);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Searches for a specific header field (by type) and returns it */
|
||||
/****************************************************************************/
|
||||
void* SMBCALL smb_get_hfield(smbmsg_t* msg, ushort type, hfield_t* hfield)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<msg->total_hfields;i++)
|
||||
if(msg->hfield[i].type == type) {
|
||||
if(hfield != NULL)
|
||||
hfield = &msg->hfield[i];
|
||||
return(msg->hfield_dat[i]);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Adds a data field to the 'msg' structure (in memory only) */
|
||||
/* Automatically figures out the offset into the data buffer from existing */
|
||||
@ -874,7 +969,7 @@ int SMBCALL smb_hfield(smbmsg_t* msg, ushort type, ushort length, void* data)
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_dfield(smbmsg_t* msg, ushort type, ulong length)
|
||||
{
|
||||
dfield_t *vp;
|
||||
dfield_t* vp;
|
||||
int i,j;
|
||||
|
||||
i=msg->hdr.total_dfields;
|
||||
@ -900,7 +995,7 @@ int SMBCALL smb_addcrc(smb_t* smb, ulong crc)
|
||||
int file;
|
||||
long length;
|
||||
ulong l,*buf;
|
||||
ulong start=0;
|
||||
time_t start=0;
|
||||
|
||||
if(!smb->status.max_crcs)
|
||||
return(0);
|
||||
@ -909,17 +1004,19 @@ int SMBCALL smb_addcrc(smb_t* smb, ulong crc)
|
||||
while(1) {
|
||||
if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW))!=-1)
|
||||
break;
|
||||
if(errno!=EACCES) {
|
||||
if(errno!=EACCES && errno!=EAGAIN) {
|
||||
sprintf(smb->last_error,"%d opening %s", errno, str);
|
||||
return(-1);
|
||||
}
|
||||
if(!start)
|
||||
start=time(NULL);
|
||||
else
|
||||
if(time(NULL)-start>=smb->retry_time) {
|
||||
sprintf(smb->last_error,"timeout opening %s", str);
|
||||
if(time(NULL)-start>=(time_t)smb->retry_time) {
|
||||
sprintf(smb->last_error,"timeout opening %s (retry_time=%ld)"
|
||||
,str,smb->retry_time);
|
||||
return(-2);
|
||||
}
|
||||
SLEEP(smb->retry_delay);
|
||||
}
|
||||
|
||||
length=filelength(file);
|
||||
@ -943,6 +1040,8 @@ int SMBCALL smb_addcrc(smb_t* smb, ulong crc)
|
||||
if(l<smb->status.max_crcs) { /* Dupe CRC found */
|
||||
close(file);
|
||||
FREE(buf);
|
||||
sprintf(smb->last_error
|
||||
,"duplicate message detected");
|
||||
return(1);
|
||||
}
|
||||
chsize(file,0L); /* truncate it */
|
||||
@ -958,12 +1057,14 @@ int SMBCALL smb_addcrc(smb_t* smb, ulong crc)
|
||||
if(l<(ulong)(length/4L)) { /* Dupe CRC found */
|
||||
close(file);
|
||||
FREE(buf);
|
||||
sprintf(smb->last_error
|
||||
,"duplicate message detected");
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
lseek(file,0L,SEEK_END);
|
||||
write(file,&crc,4); /* Write to the end */
|
||||
write(file,&crc,sizeof(crc)); /* Write to the end */
|
||||
FREE(buf);
|
||||
close(file);
|
||||
return(0);
|
||||
@ -974,19 +1075,24 @@ int SMBCALL smb_addcrc(smb_t* smb, ulong crc)
|
||||
/* If storage is SMB_SELFPACK, self-packing conservative allocation is used */
|
||||
/* If storage is SMB_FASTALLOC, fast allocation is used */
|
||||
/* If storage is SMB_HYPERALLOC, no allocation tables are used (fastest) */
|
||||
/* This function will UN-lock the SMB header */
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
|
||||
{
|
||||
int i;
|
||||
long l;
|
||||
|
||||
if(smb_locksmbhdr(smb))
|
||||
if(!smb->locked && smb_locksmbhdr(smb))
|
||||
return(1);
|
||||
if(smb_getstatus(smb))
|
||||
if(smb_getstatus(smb)) {
|
||||
smb_unlocksmbhdr(smb);
|
||||
return(2);
|
||||
}
|
||||
|
||||
if(storage!=SMB_HYPERALLOC && (i=smb_open_ha(smb))!=0)
|
||||
if(storage!=SMB_HYPERALLOC && (i=smb_open_ha(smb))!=0) {
|
||||
smb_unlocksmbhdr(smb);
|
||||
return(i);
|
||||
}
|
||||
|
||||
msg->hdr.length=smb_getmsghdrlen(msg);
|
||||
if(storage==SMB_HYPERALLOC)
|
||||
@ -995,24 +1101,24 @@ int SMBCALL smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
|
||||
l=smb_fallochdr(smb,msg->hdr.length);
|
||||
else
|
||||
l=smb_allochdr(smb,msg->hdr.length);
|
||||
if(storage!=SMB_HYPERALLOC)
|
||||
smb_close_ha(smb);
|
||||
if(l==-1L) {
|
||||
smb_unlocksmbhdr(smb);
|
||||
smb_close_ha(smb);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
smb->status.last_msg++;
|
||||
msg->idx.number=msg->hdr.number=smb->status.last_msg;
|
||||
msg->idx.number=msg->hdr.number=smb->status.last_msg+1;
|
||||
msg->idx.offset=smb->status.header_offset+l;
|
||||
msg->idx.time=msg->hdr.when_imported.time;
|
||||
msg->idx.attr=msg->hdr.attr;
|
||||
msg->offset=smb->status.total_msgs;
|
||||
smb->status.total_msgs++;
|
||||
smb_putstatus(smb);
|
||||
|
||||
if(storage!=SMB_HYPERALLOC)
|
||||
smb_close_ha(smb);
|
||||
i=smb_putmsg(smb,msg);
|
||||
if(i==0) { /* success */
|
||||
smb->status.last_msg++;
|
||||
smb->status.total_msgs++;
|
||||
smb_putstatus(smb);
|
||||
}
|
||||
smb_unlocksmbhdr(smb);
|
||||
return(i);
|
||||
}
|
||||
@ -1032,13 +1138,16 @@ int SMBCALL smb_putmsg(smb_t* smb, smbmsg_t* msg)
|
||||
|
||||
/****************************************************************************/
|
||||
/* Writes index information for 'msg' */
|
||||
/* msg->idx */
|
||||
/* and msg->offset must be set prior to calling to this function */
|
||||
/* msg->idx */
|
||||
/* and msg->offset must be set prior to calling to this function */
|
||||
/* Returns 0 if everything ok */
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_putmsgidx(smb_t* smb, smbmsg_t* msg)
|
||||
{
|
||||
|
||||
if(smb->sid_fp==NULL) {
|
||||
sprintf(smb->last_error,"index not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
clearerr(smb->sid_fp);
|
||||
fseek(smb->sid_fp,msg->offset*sizeof(idxrec_t),SEEK_SET);
|
||||
if(!fwrite(&msg->idx,sizeof(idxrec_t),1,smb->sid_fp)) {
|
||||
@ -1051,9 +1160,9 @@ int SMBCALL smb_putmsgidx(smb_t* smb, smbmsg_t* msg)
|
||||
|
||||
/****************************************************************************/
|
||||
/* Writes header information for 'msg' */
|
||||
/* msg->hdr.length */
|
||||
/* msg->idx.offset */
|
||||
/* and msg->offset must be set prior to calling to this function */
|
||||
/* msg->hdr.length */
|
||||
/* msg->idx.offset */
|
||||
/* and msg->offset must be set prior to calling to this function */
|
||||
/* Returns 0 if everything ok */
|
||||
/****************************************************************************/
|
||||
int SMBCALL smb_putmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
@ -1061,12 +1170,26 @@ int SMBCALL smb_putmsghdr(smb_t* smb, smbmsg_t* msg)
|
||||
ushort i;
|
||||
ulong l;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
if(msg->idx.offset<sizeof(smbhdr_t)+sizeof(smbstatus_t)
|
||||
|| msg->idx.offset<smb->status.header_offset) {
|
||||
sprintf(smb->last_error,"invalid header offset: %ld",msg->idx.offset);
|
||||
return(-7);
|
||||
}
|
||||
clearerr(smb->shd_fp);
|
||||
if(fseek(smb->shd_fp,msg->idx.offset,SEEK_SET)) {
|
||||
sprintf(smb->last_error,"seeking to %ld in index",msg->idx.offset);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/**********************************/
|
||||
/* Set the message header ID here */
|
||||
/**********************************/
|
||||
memcpy(&msg->hdr.id,SHD_HEADER_ID,LEN_HEADER_ID);
|
||||
|
||||
/************************************************/
|
||||
/* Write the fixed portion of the header record */
|
||||
/************************************************/
|
||||
@ -1120,11 +1243,15 @@ int SMBCALL smb_create(smb_t* smb)
|
||||
char str[128];
|
||||
smbhdr_t hdr;
|
||||
|
||||
if(smb->shd_fp==NULL || smb->sdt_fp==NULL || smb->sid_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
if(filelength(fileno(smb->shd_fp))>=sizeof(smbhdr_t)+sizeof(smbstatus_t)
|
||||
&& smb_locksmbhdr(smb)) /* header exists, so lock it */
|
||||
return(1);
|
||||
memset(&hdr,0,sizeof(smbhdr_t));
|
||||
memcpy(hdr.id,"SMB\x1a",4); /* <S> <M> <B> <^Z> */
|
||||
memcpy(hdr.id,SMB_HEADER_ID,LEN_HEADER_ID);
|
||||
hdr.version=SMB_VERSION;
|
||||
hdr.length=sizeof(smbhdr_t)+sizeof(smbstatus_t);
|
||||
smb->status.last_msg=smb->status.total_msgs=0;
|
||||
@ -1191,6 +1318,10 @@ long SMBCALL smb_allocdat(smb_t* smb, ulong length, ushort headers)
|
||||
ushort i,j;
|
||||
ulong l,blocks,offset=0L;
|
||||
|
||||
if(smb->sda_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
blocks=smb_datblocks(length);
|
||||
j=0; /* j is consecutive unused block counter */
|
||||
fflush(smb->sda_fp);
|
||||
@ -1225,6 +1356,10 @@ long SMBCALL smb_fallocdat(smb_t* smb, ulong length, ushort headers)
|
||||
{
|
||||
ulong l,blocks,offset;
|
||||
|
||||
if(smb->sda_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
fflush(smb->sda_fp);
|
||||
clearerr(smb->sda_fp);
|
||||
blocks=smb_datblocks(length);
|
||||
@ -1249,9 +1384,13 @@ int SMBCALL smb_freemsgdat(smb_t* smb, ulong offset, ulong length
|
||||
, ushort headers)
|
||||
{
|
||||
int da_opened=0;
|
||||
int retval=0;
|
||||
ushort i;
|
||||
ulong l,blocks;
|
||||
|
||||
if(smb->status.attr&SMB_HYPERALLOC) /* do nothing */
|
||||
return(0);
|
||||
|
||||
blocks=smb_datblocks(length);
|
||||
|
||||
if(smb->sda_fp==NULL) {
|
||||
@ -1266,29 +1405,33 @@ int SMBCALL smb_freemsgdat(smb_t* smb, ulong offset, ulong length
|
||||
sprintf(smb->last_error
|
||||
,"seeking to %ld of allocation file"
|
||||
,((offset/SDT_BLOCK_LEN)+l)*2L);
|
||||
return(1);
|
||||
retval=1;
|
||||
break;
|
||||
}
|
||||
if(!fread(&i,2,1,smb->sda_fp)) {
|
||||
sprintf(smb->last_error,"reading allocation bytes");
|
||||
return(2);
|
||||
retval=2;
|
||||
break;
|
||||
}
|
||||
if(headers>i)
|
||||
if(!headers || headers>i)
|
||||
i=0; /* don't want to go negative */
|
||||
else
|
||||
i-=headers;
|
||||
if(fseek(smb->sda_fp,-2L,SEEK_CUR)) {
|
||||
sprintf(smb->last_error,"seeking backwards 2 bytes in allocation file");
|
||||
return(3);
|
||||
retval=3;
|
||||
break;
|
||||
}
|
||||
if(!fwrite(&i,2,1,smb->sda_fp)) {
|
||||
sprintf(smb->last_error,"writing allocation bytes");
|
||||
return(4);
|
||||
retval=4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fflush(smb->sda_fp);
|
||||
if(da_opened)
|
||||
smb_close_da(smb);
|
||||
return(0);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@ -1300,6 +1443,10 @@ int SMBCALL smb_incdat(smb_t* smb, ulong offset, ulong length, ushort headers)
|
||||
ushort i;
|
||||
ulong l,blocks;
|
||||
|
||||
if(smb->sda_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
clearerr(smb->sda_fp);
|
||||
blocks=smb_datblocks(length);
|
||||
for(l=0;l<blocks;l++) {
|
||||
@ -1328,6 +1475,10 @@ int SMBCALL smb_freemsghdr(smb_t* smb, ulong offset, ulong length)
|
||||
uchar c=0;
|
||||
ulong l,blocks;
|
||||
|
||||
if(smb->sha_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
clearerr(smb->sha_fp);
|
||||
blocks=smb_hdrblocks(length);
|
||||
fseek(smb->sha_fp,offset/SHD_BLOCK_LEN,SEEK_SET);
|
||||
@ -1375,6 +1526,10 @@ long SMBCALL smb_allochdr(smb_t* smb, ulong length)
|
||||
ushort i;
|
||||
ulong l,blocks,offset=0;
|
||||
|
||||
if(smb->sha_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
blocks=smb_hdrblocks(length);
|
||||
i=0; /* i is consecutive unused block counter */
|
||||
fflush(smb->sha_fp);
|
||||
@ -1411,6 +1566,10 @@ long SMBCALL smb_fallochdr(smb_t* smb, ulong length)
|
||||
uchar c=1;
|
||||
ulong l,blocks,offset;
|
||||
|
||||
if(smb->sha_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
blocks=smb_hdrblocks(length);
|
||||
fflush(smb->sha_fp);
|
||||
clearerr(smb->sha_fp);
|
||||
@ -1434,6 +1593,10 @@ long SMBCALL smb_hallochdr(smb_t* smb)
|
||||
{
|
||||
ulong l;
|
||||
|
||||
if(smb->shd_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
fflush(smb->shd_fp);
|
||||
fseek(smb->shd_fp,0L,SEEK_END);
|
||||
l=ftell(smb->shd_fp);
|
||||
@ -1454,6 +1617,10 @@ long SMBCALL smb_hallocdat(smb_t* smb)
|
||||
{
|
||||
long l;
|
||||
|
||||
if(smb->sdt_fp==NULL) {
|
||||
sprintf(smb->last_error,"msgbase not open");
|
||||
return(SMB_ERR_NOT_OPEN);
|
||||
}
|
||||
fflush(smb->sdt_fp);
|
||||
fseek(smb->sdt_fp,0L,SEEK_END);
|
||||
l=ftell(smb->sdt_fp);
|
@ -10,12 +10,12 @@
|
||||
* *
|
||||
* 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 *
|
||||
* 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 General Public License for more details: gpl.txt or *
|
||||
* http://www.fsf.org/copyleft/gpl.html *
|
||||
* 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 *
|
||||
@ -38,7 +38,7 @@
|
||||
#ifndef _SMBLIB_H
|
||||
#define _SMBLIB_H
|
||||
|
||||
#include <lzh.h>
|
||||
#include "lzh.h"
|
||||
|
||||
#ifdef SMBEXPORT
|
||||
#undef SMBEXPORT
|
||||
@ -53,41 +53,44 @@
|
||||
#else
|
||||
#define SMBCALL
|
||||
#endif
|
||||
#ifdef SMBDLL /* SMBLIB contained in DLL */
|
||||
#ifdef SMB_EXPORTS
|
||||
#define SMBEXPORT __declspec( dllexport )
|
||||
#else
|
||||
#if defined(SMB_IMPORTS) || defined(SMB_EXPORTS)
|
||||
#if defined(SMB_IMPORTS)
|
||||
#define SMBEXPORT __declspec( dllimport )
|
||||
#else
|
||||
#define SMBEXPORT __declspec( dllexport )
|
||||
#endif
|
||||
#else /* self-contained executable */
|
||||
#define SMBEXPORT
|
||||
#endif
|
||||
#elif defined __unix__ || defined __GNUC__
|
||||
#elif defined(__unix__) || defined(__GNUC__)
|
||||
#ifndef __FLAT__
|
||||
#define __FLAT__
|
||||
#endif
|
||||
#define SMBCALL
|
||||
#define SMBEXPORT
|
||||
#elif defined __FLAT__
|
||||
#define SMBCALL
|
||||
#define SMBEXPORT _export
|
||||
#else
|
||||
#define SMBCALL
|
||||
#define SMBEXPORT
|
||||
#endif
|
||||
|
||||
#include <smbdefs.h>
|
||||
#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_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 SMB_STACK_XCHNG 2 /* Exchange msg base w/last pushed */
|
||||
|
||||
#define GETMSGTXT_TAILS 1 /* Get message tail(s) too */
|
||||
#define GETMSGTXT_TAILS (1<<0) /* Get message tail(s) */
|
||||
#define GETMSGTXT_NO_BODY (1<<1) /* Do not retrieve message body */
|
||||
|
||||
#define SMB_IS_OPEN(smb) ((smb)->shd_fp!=NULL)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SMBEXPORT int SMBCALL smb_ver(void);
|
||||
SMBEXPORT char * SMBCALL smb_lib_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);
|
||||
@ -102,6 +105,7 @@ 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_getfirstidx(smb_t* smb, idxrec_t *idx);
|
||||
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);
|
||||
@ -109,8 +113,9 @@ 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_hfield(smbmsg_t* msg, ushort type, size_t length, void* data);
|
||||
SMBEXPORT int SMBCALL smb_dfield(smbmsg_t* msg, ushort type, ulong length);
|
||||
SMBEXPORT void* SMBCALL smb_get_hfield(smbmsg_t* msg, ushort type, hfield_t* hfield);
|
||||
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);
|
||||
@ -169,6 +174,7 @@ SMBEXPORT void SMBCALL smb_clearerr(FILE* fp);
|
||||
#pragma aux smb_putstatus "_*"
|
||||
#pragma aux smb_unlocksmbhdr "_*"
|
||||
#pragma aux smb_getmsgidx "_*"
|
||||
#pragma aux smb_getfirstidx "_*"
|
||||
#pragma aux smb_getlastidx "_*"
|
||||
#pragma aux smb_getmsghdrlen "_*"
|
||||
#pragma aux smb_getmsgdatlen "_*"
|
||||
|
@ -1,121 +0,0 @@
|
||||
/* 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