Various SMB fixes

This commit is contained in:
Alexander S. Aganichev 2002-08-30 06:01:33 +00:00
parent 41796b160f
commit cff3b440eb
18 changed files with 504 additions and 1093 deletions

View File

@ -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.

View File

@ -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--) {

View File

@ -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

View File

@ -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);
}
// ------------------------------------------------------------------

View File

@ -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
// ------------------------------------------------------------------

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -1,9 +0,0 @@
/* crc32.h */
/* wrapper for gall library */
#include <gcrcall.h>
#define ucrc32(ch,crc) updCrc32(ch,crc)

View 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
View File

@ -0,0 +1,8 @@
#ifndef __genwrap_h
#define __genwrap_h
#include <gtimall.h>
#define SLEEP(a) usleep(a)
#endif // __genwrap_h

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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 "_*"

View File

@ -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);
}