From cff3b440eb126f63beffc3217eb51eb473369174 Mon Sep 17 00:00:00 2001 From: "Alexander S. Aganichev" Date: Fri, 30 Aug 2002 06:01:33 +0000 Subject: [PATCH] Various SMB fixes --- docs/notework.txt | 9 + golded3/gemlst.cpp | 8 +- goldlib/gall/gall.all | 3 - goldlib/gall/glzh.cpp | 651 ------------------------ goldlib/gall/glzh.h | 41 -- goldlib/gmb3/Makefile | 1 - goldlib/gmb3/gmosmb1.cpp | 85 +++- goldlib/smblib/Makefile | 1 + goldlib/smblib/crc32.h | 9 - goldlib/smblib/filewrap.h | 8 + goldlib/smblib/genwrap.h | 8 + goldlib/smblib/{lzh.cpp => lzh.c} | 8 +- goldlib/smblib/lzh.h | 18 +- goldlib/smblib/smbdefs.h | 106 ++-- goldlib/smblib/smblib.all | 5 +- goldlib/smblib/{smblib.cpp => smblib.c} | 471 +++++++++++------ goldlib/smblib/smblib.h | 44 +- goldlib/smblib/smbtxt.cpp | 121 ----- 18 files changed, 504 insertions(+), 1093 deletions(-) delete mode 100644 goldlib/gall/glzh.cpp delete mode 100644 goldlib/gall/glzh.h delete mode 100644 goldlib/smblib/crc32.h create mode 100644 goldlib/smblib/filewrap.h create mode 100644 goldlib/smblib/genwrap.h rename goldlib/smblib/{lzh.cpp => lzh.c} (99%) rename goldlib/smblib/{smblib.cpp => smblib.c} (81%) delete mode 100644 goldlib/smblib/smbtxt.cpp diff --git a/docs/notework.txt b/docs/notework.txt index 49504e2..a3ea3a3 100644 --- a/docs/notework.txt +++ b/docs/notework.txt @@ -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. diff --git a/golded3/gemlst.cpp b/golded3/gemlst.cpp index a16632e..fab1276 100644 --- a/golded3/gemlst.cpp +++ b/golded3/gemlst.cpp @@ -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--) { diff --git a/goldlib/gall/gall.all b/goldlib/gall/gall.all index a9aec75..a81937b 100644 --- a/goldlib/gall/gall.all +++ b/goldlib/gall/gall.all @@ -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 diff --git a/goldlib/gall/glzh.cpp b/goldlib/gall/glzh.cpp deleted file mode 100644 index 28a03d5..0000000 --- a/goldlib/gall/glzh.cpp +++ /dev/null @@ -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 -#include -#include -#include - - -// ------------------------------------------------------------------ -// 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 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 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 && countstatus.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; diff --git a/goldlib/smblib/Makefile b/goldlib/smblib/Makefile index 0146dc1..54cd26a9 100644 --- a/goldlib/smblib/Makefile +++ b/goldlib/smblib/Makefile @@ -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 diff --git a/goldlib/smblib/crc32.h b/goldlib/smblib/crc32.h deleted file mode 100644 index 6e4ad7b..0000000 --- a/goldlib/smblib/crc32.h +++ /dev/null @@ -1,9 +0,0 @@ -/* crc32.h */ - -/* wrapper for gall library */ - -#include - -#define ucrc32(ch,crc) updCrc32(ch,crc) - - diff --git a/goldlib/smblib/filewrap.h b/goldlib/smblib/filewrap.h new file mode 100644 index 0000000..71b5c08 --- /dev/null +++ b/goldlib/smblib/filewrap.h @@ -0,0 +1,8 @@ +#ifndef __filewrap_h +#define __filewrap_h + +#include + +#define sopen(fn,access,share) (sopen)((fn),(access),(share),S_IREAD|S_IWRITE) + +#endif // __filewrap_h diff --git a/goldlib/smblib/genwrap.h b/goldlib/smblib/genwrap.h new file mode 100644 index 0000000..f4c358c --- /dev/null +++ b/goldlib/smblib/genwrap.h @@ -0,0 +1,8 @@ +#ifndef __genwrap_h +#define __genwrap_h + +#include + +#define SLEEP(a) usleep(a) + +#endif // __genwrap_h diff --git a/goldlib/smblib/lzh.cpp b/goldlib/smblib/lzh.c similarity index 99% rename from goldlib/smblib/lzh.cpp rename to goldlib/smblib/lzh.c index 707db9b..a7bb551 100644 --- a/goldlib/smblib/lzh.cpp +++ b/goldlib/smblib/lzh.c @@ -35,7 +35,13 @@ #include #include #include + +/* FreeBSD's malloc.h is deprecated, it drops a warning and */ +/* #includes , which is already here. */ +#ifndef __FreeBSD__ #include +#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 */ diff --git a/goldlib/smblib/lzh.h b/goldlib/smblib/lzh.h index b2ccc18..69ccada 100644 --- a/goldlib/smblib/lzh.h +++ b/goldlib/smblib/lzh.h @@ -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 + typedef unsigned char uchar; #endif #ifdef __cplusplus diff --git a/goldlib/smblib/smbdefs.h b/goldlib/smblib/smbdefs.h index 50a58b5..e6f4865 100644 --- a/goldlib/smblib/smbdefs.h +++ b/goldlib/smblib/smbdefs.h @@ -38,43 +38,28 @@ #ifndef _SMBDEFS_H #define _SMBDEFS_H -#ifdef GOLDEDPLUS -#include -#endif #include /**********/ /* Macros */ /**********/ +#define SMB_HEADER_ID "SMB\x1a" /* <^Z> */ +#define SHD_HEADER_ID "SHD\x1a" /* <^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 #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 */ diff --git a/goldlib/smblib/smblib.all b/goldlib/smblib/smblib.all index 79105fb..23c9dc0 100644 --- a/goldlib/smblib/smblib.all +++ b/goldlib/smblib/smblib.all @@ -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 diff --git a/goldlib/smblib/smblib.cpp b/goldlib/smblib/smblib.c similarity index 81% rename from goldlib/smblib/smblib.cpp rename to goldlib/smblib/smblib.c index 547a420..e0ff107 100644 --- a/goldlib/smblib/smblib.cpp +++ b/goldlib/smblib/smblib.c @@ -48,7 +48,11 @@ #endif /* ANSI C Library headers */ -#include + +#ifndef __FreeBSD__ + #include +#endif + #include #include #include @@ -60,16 +64,11 @@ /* SMB-specific headers */ #include "smblib.h" -#ifndef GOLDEDPLUS -#include "smbwrap.h" -#else -#include - -#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(lengthshd_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;itotal_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(lstatus.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.offsetidx.offsetstatus.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); /* <^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;lsha_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); diff --git a/goldlib/smblib/smblib.h b/goldlib/smblib/smblib.h index 3816610..df02a6e 100644 --- a/goldlib/smblib/smblib.h +++ b/goldlib/smblib/smblib.h @@ -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 +#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 +#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 "_*" diff --git a/goldlib/smblib/smbtxt.cpp b/goldlib/smblib/smbtxt.cpp deleted file mode 100644 index 5a033a2..0000000 --- a/goldlib/smblib/smbtxt.cpp +++ /dev/null @@ -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 - -/* 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;ihdr.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); -}