Converted .c to .cpp
This commit is contained in:
parent
0573c95f34
commit
7a646ca788
5066
goldlib/glibc/regex.cpp
Normal file
5066
goldlib/glibc/regex.cpp
Normal file
File diff suppressed because it is too large
Load Diff
813
goldlib/smblib/lzh.cpp
Normal file
813
goldlib/smblib/lzh.cpp
Normal file
@ -0,0 +1,813 @@
|
||||
/* lzh.c */
|
||||
|
||||
/* Synchronet LZH compression library */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/****************************************************************************
|
||||
* @format.tab-size 4 (Plain Text/Source Code File Header) *
|
||||
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
|
||||
* *
|
||||
* Rob Swindell's conversion of 1988 LZH (LHarc) encoding functions *
|
||||
* Based on Japanese version 29-NOV-1988 *
|
||||
* LZSS coded by Haruhiko Okumura *
|
||||
* Adaptive Huffman Coding coded by Haruyasu Yoshizaki *
|
||||
* *
|
||||
* Anonymous FTP access to the most recent released source is available at *
|
||||
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
|
||||
* *
|
||||
* Anonymous CVS access to the development source and modification history *
|
||||
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
|
||||
* (just hit return, no password is necessary) *
|
||||
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
|
||||
* *
|
||||
* For Synchronet coding style and modification guidelines, see *
|
||||
* http://www.synchro.net/source.html *
|
||||
* *
|
||||
* You are encouraged to submit any modifications (preferably in Unix diff *
|
||||
* format) via e-mail to mods@synchro.net *
|
||||
* *
|
||||
* Note: If this box doesn't appear square, then you need to fix your tabs. *
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FreeBSD's malloc.h is deprecated, it drops a warning and */
|
||||
/* #includes <stdlib.h>, which is already here. */
|
||||
#if !defined(__FreeBSD__) && !defined(__APPLE__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "lzh.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* Memory allocation macros for various compilers and environments */
|
||||
/* MALLOC is used for allocations of 64k or less */
|
||||
/* FREE is used to free buffers allocated with MALLOC */
|
||||
/* LMALLOC is used for allocations of possibly larger than 64k */
|
||||
/* LFREE is used to free buffers allocated with LMALLOC */
|
||||
/* REALLOC is used to re-size a previously MALLOCed or LMALLOCed buffer */
|
||||
/****************************************************************************/
|
||||
#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
|
||||
#if defined(__TURBOC__)
|
||||
#define REALLOC(x,y) farrealloc(x,y)
|
||||
#define LMALLOC(x) farmalloc(x)
|
||||
#define MALLOC(x) farmalloc(x)
|
||||
#define LFREE(x) farfree(x)
|
||||
#define FREE(x) farfree(x)
|
||||
#elif defined(__WATCOMC__)
|
||||
#define REALLOC realloc
|
||||
#define LMALLOC(x) halloc(x,1) /* far heap, but slow */
|
||||
#define MALLOC malloc /* far heap, but 64k max */
|
||||
#define LFREE hfree
|
||||
#define FREE free
|
||||
#else /* Other 16-bit Compiler */
|
||||
#define REALLOC realloc
|
||||
#define LMALLOC malloc
|
||||
#define MALLOC malloc
|
||||
#define LFREE free
|
||||
#define FREE free
|
||||
#endif
|
||||
#else /* 32-bit Compiler or Small Memory Model */
|
||||
#define REALLOC realloc
|
||||
#define LMALLOC malloc
|
||||
#define MALLOC malloc
|
||||
#define LFREE free
|
||||
#define FREE free
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* LZSS Parameters */
|
||||
|
||||
#define LZH_N 4096 /* Size of string buffer */
|
||||
#define LZH_F 60 /* Size of look-ahead buffer */
|
||||
#define LZH_THRESHOLD 2
|
||||
#define LZH_NIL LZH_N /* End of tree's node */
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
|
||||
uint8_t *lzh_text_buf;
|
||||
int16_t lzh_match_position, lzh_match_length,
|
||||
*lzh_lson, *lzh_rson, *lzh_dad;
|
||||
|
||||
#else
|
||||
|
||||
uint8_t lzh_text_buf[LZH_N + LZH_F - 1];
|
||||
int16_t lzh_match_position, lzh_match_length,
|
||||
lzh_lson[LZH_N + 1], lzh_rson[LZH_N + 257], lzh_dad[LZH_N + 1];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void lzh_init_tree(void) /* Initializing tree */
|
||||
{
|
||||
int16_t i;
|
||||
|
||||
for (i = LZH_N + 1; i <= LZH_N + 256; i++)
|
||||
lzh_rson[i] = LZH_NIL; /* root */
|
||||
for (i = 0; i < LZH_N; i++)
|
||||
lzh_dad[i] = LZH_NIL; /* node */
|
||||
}
|
||||
|
||||
/******************************/
|
||||
/* Inserting node to the tree */
|
||||
/* Only used during encoding */
|
||||
/******************************/
|
||||
void lzh_insert_node(int16_t r)
|
||||
{
|
||||
int16_t i, p, cmp;
|
||||
uint8_t *key;
|
||||
uint32_t 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)
|
||||
< (uint32_t)lzh_match_position) {
|
||||
lzh_match_position = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lzh_dad[r] = lzh_dad[p];
|
||||
lzh_lson[r] = lzh_lson[p];
|
||||
lzh_rson[r] = lzh_rson[p];
|
||||
lzh_dad[lzh_lson[p]] = r;
|
||||
lzh_dad[lzh_rson[p]] = r;
|
||||
if (lzh_rson[lzh_dad[p]] == p)
|
||||
lzh_rson[lzh_dad[p]] = r;
|
||||
else
|
||||
lzh_lson[lzh_dad[p]] = r;
|
||||
lzh_dad[p] = LZH_NIL; /* remove p */
|
||||
}
|
||||
|
||||
void lzh_delete_node(int16_t p) /* Deleting node from the tree */
|
||||
{
|
||||
int16_t q;
|
||||
|
||||
if (lzh_dad[p] == LZH_NIL)
|
||||
return; /* unregistered */
|
||||
if (lzh_rson[p] == LZH_NIL)
|
||||
q = lzh_lson[p];
|
||||
else
|
||||
if (lzh_lson[p] == LZH_NIL)
|
||||
q = lzh_rson[p];
|
||||
else {
|
||||
q = lzh_lson[p];
|
||||
if (lzh_rson[q] != LZH_NIL) {
|
||||
do {
|
||||
q = lzh_rson[q];
|
||||
} while (lzh_rson[q] != LZH_NIL);
|
||||
lzh_rson[lzh_dad[q]] = lzh_lson[q];
|
||||
lzh_dad[lzh_lson[q]] = lzh_dad[q];
|
||||
lzh_lson[q] = lzh_lson[p];
|
||||
lzh_dad[lzh_lson[p]] = q;
|
||||
}
|
||||
lzh_rson[q] = lzh_rson[p];
|
||||
lzh_dad[lzh_rson[p]] = q;
|
||||
}
|
||||
lzh_dad[q] = lzh_dad[p];
|
||||
if (lzh_rson[lzh_dad[p]] == p)
|
||||
lzh_rson[lzh_dad[p]] = q;
|
||||
else
|
||||
lzh_lson[lzh_dad[p]] = q;
|
||||
lzh_dad[p] = LZH_NIL;
|
||||
}
|
||||
|
||||
/* Huffman coding parameters */
|
||||
|
||||
#define LZH_N_CHAR (256 - LZH_THRESHOLD + LZH_F)
|
||||
/* character code (= 0..LZH_N_CHAR-1) */
|
||||
#define LZH_T (LZH_N_CHAR * 2 - 1) /* Size of table */
|
||||
#define LZH_R (LZH_T - 1) /* root position */
|
||||
#define MAX_FREQ 0x8000
|
||||
/* update when cumulative frequency */
|
||||
/* reaches to this value */
|
||||
|
||||
/*
|
||||
* Tables for encoding/decoding upper 6 bits of
|
||||
* sliding dictionary pointer
|
||||
*/
|
||||
/* encoder table */
|
||||
uint8_t 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
|
||||
};
|
||||
|
||||
uint8_t 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 */
|
||||
uint8_t 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,
|
||||
};
|
||||
|
||||
uint8_t lzh_d_len[256] = {
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
};
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
|
||||
uint16_t *lzh_freq = NULL; /* cumulative freq table */
|
||||
|
||||
/*
|
||||
* pointing parent nodes.
|
||||
* area [LZH_T..(LZH_T + LZH_N_CHAR - 1)] are pointers for leaves
|
||||
*/
|
||||
int16_t *lzh_prnt = NULL;
|
||||
|
||||
/* pointing children nodes (son[], son[] + 1)*/
|
||||
int16_t *lzh_son = NULL;
|
||||
|
||||
#else /* STATIC */
|
||||
|
||||
uint16_t lzh_freq[LZH_T + 1]; /* cumulative freq table */
|
||||
int16_t lzh_prnt[LZH_T + LZH_N_CHAR];
|
||||
int16_t lzh_son[LZH_T + 1]; /* bug fixed by Digital Dynamics */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
uint16_t lzh_getbuf = 0; /* Was just "unsigned" fixed 04/12/95 */
|
||||
uint8_t lzh_getlen = 0;
|
||||
|
||||
int lzh_getbit(uint8_t *inbuf, int32_t *incnt, int32_t inlen) /* get one bit */
|
||||
{
|
||||
int16_t 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);
|
||||
}
|
||||
|
||||
int16_t lzh_getbyte(uint8_t *inbuf, int32_t *incnt, int32_t inlen) /* get a byte */
|
||||
{
|
||||
uint16_t 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;
|
||||
}
|
||||
|
||||
uint32_t lzh_putbuf = 0;
|
||||
uint8_t lzh_putlen = 0;
|
||||
|
||||
/* output c bits */
|
||||
void lzh_putcode(int16_t l, uint16_t c, uint8_t *outbuf, int32_t *outlen)
|
||||
{
|
||||
lzh_putbuf |= c >> lzh_putlen;
|
||||
if ((lzh_putlen += l) >= 8) {
|
||||
outbuf[(*outlen)++]=(lzh_putbuf >> 8);
|
||||
if ((lzh_putlen -= 8) >= 8) {
|
||||
outbuf[(*outlen)++]=lzh_putbuf;
|
||||
lzh_putlen -= 8;
|
||||
lzh_putbuf = c << (l - lzh_putlen);
|
||||
} else {
|
||||
lzh_putbuf <<= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* initialize freq tree */
|
||||
|
||||
void lzh_start_huff(void)
|
||||
{
|
||||
int16_t i, j;
|
||||
|
||||
lzh_getbuf = 0; /* Added by Digital Dynamics for repeating operations */
|
||||
lzh_getlen = 0;
|
||||
lzh_putbuf = 0;
|
||||
lzh_putlen = 0;
|
||||
|
||||
for (i = 0; i < LZH_N_CHAR; i++) {
|
||||
lzh_freq[i] = 1;
|
||||
lzh_son[i] = i + LZH_T;
|
||||
lzh_prnt[i + LZH_T] = i;
|
||||
}
|
||||
i = 0; j = LZH_N_CHAR;
|
||||
while (j <= LZH_R) {
|
||||
lzh_freq[j] = lzh_freq[i] + lzh_freq[i + 1];
|
||||
lzh_son[j] = i;
|
||||
lzh_prnt[i] = lzh_prnt[i + 1] = j;
|
||||
i += 2; j++;
|
||||
}
|
||||
lzh_freq[LZH_T] = 0xffff;
|
||||
lzh_prnt[LZH_R] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* reconstruct freq tree */
|
||||
|
||||
void lzh_reconst(void)
|
||||
{
|
||||
int16_t i, j, k;
|
||||
uint16_t f, l;
|
||||
|
||||
/* halven cumulative freq for leaf nodes */
|
||||
j = 0;
|
||||
for (i = 0; i < LZH_T; i++) {
|
||||
if (lzh_son[i] >= LZH_T) {
|
||||
lzh_freq[j] = (lzh_freq[i] + 1) / 2;
|
||||
lzh_son[j] = lzh_son[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
/* make a tree : first, connect children nodes */
|
||||
for (i = 0, j = LZH_N_CHAR; j < LZH_T; i += 2, j++) {
|
||||
k = i + 1;
|
||||
f = lzh_freq[j] = lzh_freq[i] + lzh_freq[k];
|
||||
for (k = j - 1; f < lzh_freq[k]; k--);
|
||||
k++;
|
||||
l = (j - k) * 2;
|
||||
|
||||
/* movmem() is Turbo-C dependent
|
||||
rewritten to memmove() by Kenji */
|
||||
|
||||
/* movmem(&lzh_freq[k], &lzh_freq[k + 1], l); */
|
||||
(void)memmove(lzh_freq+k+1,lzh_freq+k, l);
|
||||
lzh_freq[k] = f;
|
||||
/* movmem(&lzh_son[k], &lzh_son[k + 1], l); */
|
||||
(void)memmove(lzh_son+k+1,lzh_son+k, l);
|
||||
lzh_son[k] = i;
|
||||
}
|
||||
/* connect parent nodes */
|
||||
for (i = 0; i < LZH_T; i++) {
|
||||
if ((k = lzh_son[i]) >= LZH_T) {
|
||||
lzh_prnt[k] = i;
|
||||
} else {
|
||||
lzh_prnt[k] = lzh_prnt[k + 1] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update freq tree */
|
||||
|
||||
void lzh_update(int16_t c)
|
||||
{
|
||||
int16_t i, j, k, l;
|
||||
|
||||
if (lzh_freq[LZH_R] == MAX_FREQ) {
|
||||
lzh_reconst();
|
||||
}
|
||||
c = lzh_prnt[c + LZH_T];
|
||||
do {
|
||||
k = ++lzh_freq[c];
|
||||
|
||||
/* swap nodes to keep the tree freq-ordered */
|
||||
if (k > lzh_freq[l = c + 1]) {
|
||||
while (k > lzh_freq[++l]);
|
||||
l--;
|
||||
lzh_freq[c] = lzh_freq[l];
|
||||
lzh_freq[l] = k;
|
||||
|
||||
i = lzh_son[c];
|
||||
lzh_prnt[i] = l;
|
||||
if (i < LZH_T) lzh_prnt[i + 1] = l;
|
||||
|
||||
j = lzh_son[l];
|
||||
lzh_son[l] = i;
|
||||
|
||||
lzh_prnt[j] = c;
|
||||
if (j < LZH_T) lzh_prnt[j + 1] = c;
|
||||
lzh_son[c] = j;
|
||||
|
||||
c = l;
|
||||
}
|
||||
} while ((c = lzh_prnt[c]) != 0); /* do it until reaching the root */
|
||||
}
|
||||
|
||||
uint16_t lzh_code, lzh_len;
|
||||
|
||||
void lzh_encode_char(uint16_t c, uint8_t *outbuf, int32_t *outlen)
|
||||
{
|
||||
uint16_t i;
|
||||
int16_t j, k;
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
k = lzh_prnt[c + LZH_T];
|
||||
|
||||
/* search connections from leaf node to the root */
|
||||
do {
|
||||
i >>= 1;
|
||||
|
||||
/*
|
||||
if node's address is odd, output 1
|
||||
else output 0
|
||||
*/
|
||||
if (k & 1) i += 0x8000;
|
||||
|
||||
j++;
|
||||
} while ((k = lzh_prnt[k]) != LZH_R);
|
||||
lzh_putcode(j, i, outbuf, outlen);
|
||||
lzh_code = i;
|
||||
lzh_len = j;
|
||||
lzh_update(c);
|
||||
}
|
||||
|
||||
void lzh_encode_position(uint16_t c, uint8_t *outbuf, int32_t *outlen)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
/* output upper 6 bits with encoding */
|
||||
i = c >> 6;
|
||||
lzh_putcode(lzh_p_len[i], (uint16_t)(lzh_p_code[i] << 8), outbuf, outlen);
|
||||
|
||||
/* output lower 6 bits directly */
|
||||
lzh_putcode(6, (uint16_t)((c & 0x3f) << 10), outbuf, outlen);
|
||||
}
|
||||
|
||||
void lzh_encode_end(uint8_t *outbuf, int32_t *outlen)
|
||||
{
|
||||
if (lzh_putlen) {
|
||||
outbuf[(*outlen)++]=(lzh_putbuf >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
int16_t lzh_decode_char(uint8_t *inbuf, int32_t *incnt, int32_t inlen)
|
||||
{
|
||||
uint16_t c;
|
||||
|
||||
c = lzh_son[LZH_R];
|
||||
|
||||
/*
|
||||
* start searching tree from the root to leaves.
|
||||
* choose node #(lzh_son[]) if input bit == 0
|
||||
* else choose #(lzh_son[]+1) (input bit == 1)
|
||||
*/
|
||||
while (c < LZH_T) {
|
||||
c += lzh_getbit(inbuf,incnt,inlen);
|
||||
c = lzh_son[c];
|
||||
}
|
||||
c -= LZH_T;
|
||||
lzh_update(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
int16_t lzh_decode_position(uint8_t *inbuf, int32_t *incnt, int32_t inlen)
|
||||
{
|
||||
uint16_t i, j, c;
|
||||
|
||||
/* decode upper 6 bits from given table */
|
||||
i = lzh_getbyte(inbuf,incnt,inlen);
|
||||
c = (uint32_t)lzh_d_code[i] << 6;
|
||||
j = lzh_d_len[i];
|
||||
|
||||
/* input lower 6 bits directly */
|
||||
j -= 2;
|
||||
while (j--) {
|
||||
i = (i << 1) + lzh_getbit(inbuf,incnt,inlen);
|
||||
}
|
||||
return c | (i & 0x3f);
|
||||
}
|
||||
|
||||
/* Compression */
|
||||
|
||||
/* Encoding/Compressing */
|
||||
/* Returns length of outbuf */
|
||||
int32_t LZHCALL lzh_encode(uint8_t *inbuf, int32_t inlen, uint8_t *outbuf)
|
||||
{
|
||||
int16_t i, c, len, r, s, last_match_length;
|
||||
int32_t incnt, outlen; /* textsize=0; */
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
|
||||
if((lzh_text_buf=(uint8_t *)MALLOC(LZH_N + LZH_F - 1))==NULL)
|
||||
return(-1);
|
||||
if((lzh_freq=(uint16_t *)MALLOC((LZH_T + 1)*sizeof(uint16_t)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
return(-1); }
|
||||
if((lzh_prnt=(int16_t *)MALLOC((LZH_T + LZH_N_CHAR)*sizeof(int16_t)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_freq);
|
||||
return(-1); }
|
||||
if((lzh_son=(int16_t *)MALLOC((LZH_T + 1) * sizeof(int16_t)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
return(-1); }
|
||||
if((lzh_lson=(int16_t *)MALLOC((LZH_N + 1)*sizeof(int16_t)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
return(-1); }
|
||||
if((lzh_rson=(int16_t *)MALLOC((LZH_N + 257)*sizeof(int16_t)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
FREE(lzh_lson);
|
||||
return(-1); }
|
||||
if((lzh_dad=(int16_t *)MALLOC((LZH_N + 1)*sizeof(int16_t)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
FREE(lzh_lson);
|
||||
FREE(lzh_rson);
|
||||
return(-1); }
|
||||
#endif
|
||||
|
||||
incnt=0;
|
||||
memcpy(outbuf,&inlen,sizeof(inlen));
|
||||
outlen=sizeof(inlen);
|
||||
if(!inlen) {
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
FREE(lzh_lson);
|
||||
FREE(lzh_rson);
|
||||
FREE(lzh_dad);
|
||||
#endif
|
||||
return(outlen); }
|
||||
lzh_start_huff();
|
||||
lzh_init_tree();
|
||||
s = 0;
|
||||
r = LZH_N - LZH_F;
|
||||
for (i = s; i < r; i++)
|
||||
lzh_text_buf[i] = ' ';
|
||||
for (len = 0; len < LZH_F && incnt<inlen; len++)
|
||||
lzh_text_buf[r + len] = inbuf[incnt++];
|
||||
/* textsize = len; */
|
||||
for (i = 1; i <= LZH_F; i++)
|
||||
lzh_insert_node((int16_t)(r - i));
|
||||
lzh_insert_node(r);
|
||||
do {
|
||||
if (lzh_match_length > len)
|
||||
lzh_match_length = len;
|
||||
if (lzh_match_length <= LZH_THRESHOLD) {
|
||||
lzh_match_length = 1;
|
||||
lzh_encode_char(lzh_text_buf[r],outbuf,&outlen);
|
||||
} else {
|
||||
lzh_encode_char((uint16_t)(255 - LZH_THRESHOLD + lzh_match_length)
|
||||
,outbuf,&outlen);
|
||||
lzh_encode_position(lzh_match_position
|
||||
,outbuf,&outlen);
|
||||
}
|
||||
last_match_length = lzh_match_length;
|
||||
for (i = 0; i < last_match_length && incnt<inlen; i++) {
|
||||
lzh_delete_node(s);
|
||||
c=inbuf[incnt++];
|
||||
lzh_text_buf[s] = (uint8_t)c;
|
||||
if (s < LZH_F - 1)
|
||||
lzh_text_buf[s + LZH_N] = (uint8_t)c;
|
||||
s = (s + 1) & (LZH_N - 1);
|
||||
r = (r + 1) & (LZH_N - 1);
|
||||
lzh_insert_node(r);
|
||||
}
|
||||
/***
|
||||
if ((textsize += i) > printcount) {
|
||||
printf("%12ld\r", textsize);
|
||||
printcount += 1024;
|
||||
}
|
||||
***/
|
||||
while (i++ < last_match_length) {
|
||||
lzh_delete_node(s);
|
||||
s = (s + 1) & (LZH_N - 1);
|
||||
r = (r + 1) & (LZH_N - 1);
|
||||
if (--len) lzh_insert_node(r);
|
||||
}
|
||||
} while (len > 0);
|
||||
lzh_encode_end(outbuf,&outlen);
|
||||
/*
|
||||
printf("input: %ld (%ld) bytes\n", inlen,textsize);
|
||||
printf("output: %ld bytes\n", outlen);
|
||||
printf("output/input: %.3f\n", (double)outlen / inlen);
|
||||
*/
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
FREE(lzh_lson);
|
||||
FREE(lzh_rson);
|
||||
FREE(lzh_dad);
|
||||
#endif
|
||||
|
||||
return(outlen);
|
||||
}
|
||||
|
||||
/* Decoding/Uncompressing */
|
||||
/* Returns length of outbuf */
|
||||
int32_t LZHCALL lzh_decode(uint8_t *inbuf, int32_t inlen, uint8_t *outbuf)
|
||||
{
|
||||
int16_t i, j, k, r, c;
|
||||
uint32_t count;
|
||||
int32_t incnt, textsize;
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
|
||||
if((lzh_text_buf=(uint8_t *)MALLOC((LZH_N + LZH_F - 1)*2))==NULL)
|
||||
return(-1);
|
||||
if((lzh_freq=(uint16_t *)MALLOC((LZH_T + 1)*sizeof(uint16_t)))
|
||||
==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
return(-1); }
|
||||
if((lzh_prnt=(int16_t *)MALLOC((LZH_T + LZH_N_CHAR)*sizeof(int16_t)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_freq);
|
||||
return(-1); }
|
||||
if((lzh_son=(int16_t *)MALLOC((LZH_T + 1) * sizeof(int16_t)))==NULL) {
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
return(-1); }
|
||||
|
||||
#endif
|
||||
|
||||
incnt=0;
|
||||
memcpy(&textsize,inbuf,sizeof(textsize));
|
||||
incnt+=sizeof(textsize);
|
||||
if (textsize == 0) {
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
#endif
|
||||
return(textsize); }
|
||||
lzh_start_huff();
|
||||
for (i = 0; i < LZH_N - LZH_F; i++)
|
||||
*(lzh_text_buf+i) = ' ';
|
||||
r = LZH_N - LZH_F;
|
||||
for (count = 0; count < (uint32_t)textsize; ) {
|
||||
c = lzh_decode_char(inbuf,&incnt,inlen);
|
||||
if (c < 256) {
|
||||
outbuf[count]=(uint8_t)c;
|
||||
#if 0
|
||||
if(r>(LZH_N + LZH_F - 1) || r<0) {
|
||||
printf("Overflow! (%d)\n",r);
|
||||
getch();
|
||||
exit(-1); }
|
||||
#endif
|
||||
*(lzh_text_buf+r) = (uint8_t)c;
|
||||
r++;
|
||||
r &= (LZH_N - 1);
|
||||
count++;
|
||||
} else {
|
||||
i = (r - lzh_decode_position(inbuf,&incnt,inlen) - 1)
|
||||
& (LZH_N - 1);
|
||||
j = c - 255 + LZH_THRESHOLD;
|
||||
for (k = 0; k < j && count<(uint32_t)textsize; k++) {
|
||||
c = lzh_text_buf[(i + k) & (LZH_N - 1)];
|
||||
outbuf[count]=(uint8_t)c;
|
||||
#if 0
|
||||
if(r>(LZH_N + LZH_F - 1) || r<0) {
|
||||
printf("Overflow! (%d)\n",r);
|
||||
exit(-1); }
|
||||
#endif
|
||||
*(lzh_text_buf+r) = (uint8_t)c;
|
||||
r++;
|
||||
r &= (LZH_N - 1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/***
|
||||
printf("%12ld\n", count);
|
||||
***/
|
||||
|
||||
#ifdef LZH_DYNAMIC_BUF
|
||||
FREE(lzh_text_buf);
|
||||
FREE(lzh_prnt);
|
||||
FREE(lzh_freq);
|
||||
FREE(lzh_son);
|
||||
#endif
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
|
1729
goldlib/smblib/smblib.cpp
Normal file
1729
goldlib/smblib/smblib.cpp
Normal file
File diff suppressed because it is too large
Load Diff
514
goldlib/uulib/fptools.cpp
Normal file
514
goldlib/uulib/fptools.cpp
Normal file
@ -0,0 +1,514 @@
|
||||
/*
|
||||
* fptools.c, some helper functions for getcgi.c and uu(en|de)view
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License.
|
||||
* Use and be happy.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef SYSTEM_WINDLL
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifdef SYSTEM_OS2
|
||||
#include <os2.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file provides replacements for some handy functions that aren't
|
||||
* available on all systems, like most of the <string.h> functions. They
|
||||
* should behave exactly as their counterparts. There are also extensions
|
||||
* that aren't portable at all (like strirstr etc.).
|
||||
* The proper behaviour in a configure script is as follows:
|
||||
* AC_CHECK_FUNC(strrchr,AC_DEFINE(strrchr,_FP_strrchr))
|
||||
* This way, the (probably less efficient) replacements will only be used
|
||||
* where it is not provided by the default libraries. Be aware that this
|
||||
* does not work with replacements that just shadow wrong behaviour (like
|
||||
* _FP_free) or provide extended functionality (_FP_gets).
|
||||
* The above is not used in the uuenview/uudeview configuration script,
|
||||
* since both only use the replacement functions in non-performance-cri-
|
||||
* tical sections (except for _FP_tempnam and _FP_strerror, where some
|
||||
* functionality of the original would be lost).
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
#include <gdefs.h>
|
||||
#include <gctype.h>
|
||||
#include <fptools.h>
|
||||
|
||||
#if 0
|
||||
#ifdef SYSTEM_WINDLL
|
||||
BOOL _export WINAPI
|
||||
DllEntryPoint (HINSTANCE hInstance, DWORD seginfo,
|
||||
LPVOID lpCmdLine)
|
||||
{
|
||||
/* Don't do anything, so just return true */
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
char * fptools_id = "$Id$";
|
||||
|
||||
/*
|
||||
* some versions of free can't handle a NULL pointer properly
|
||||
* (ANSI says, free ignores a NULL pointer, but some machines
|
||||
* prefer to SIGSEGV on it)
|
||||
*/
|
||||
|
||||
void TOOLEXPORT
|
||||
_FP_free (void *ptr)
|
||||
{
|
||||
if (ptr) free (ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is non-standard, so I'm defining my own
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strdup (char *string)
|
||||
{
|
||||
char *result;
|
||||
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((result = (char *) malloc (strlen (string) + 1)) == NULL)
|
||||
return NULL;
|
||||
|
||||
strcpy (result, string);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* limited-length string copy. this function behaves differently from
|
||||
* the original in that the dest string is always terminated with a
|
||||
* NULL character.
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strncpy (char *dest, char *src, int length)
|
||||
{
|
||||
char *odest=dest;
|
||||
if (src == NULL || dest == NULL || length-- <= 0)
|
||||
return dest;
|
||||
|
||||
while (length-- && *src)
|
||||
*dest++ = *src++;
|
||||
|
||||
*dest++ = '\0';
|
||||
return odest;
|
||||
}
|
||||
|
||||
/*
|
||||
* duplicate a memory area
|
||||
*/
|
||||
|
||||
void * TOOLEXPORT
|
||||
_FP_memdup (void *ptr, int len)
|
||||
{
|
||||
void *result;
|
||||
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((result = malloc (len)) == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy (result, ptr, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* case-insensitive compare
|
||||
*/
|
||||
|
||||
int TOOLEXPORT
|
||||
_FP_stricmp (char *str1, char *str2)
|
||||
{
|
||||
if (str1==NULL || str2==NULL)
|
||||
return -1;
|
||||
|
||||
while (*str1) {
|
||||
if (g_tolower(*str1) != g_tolower(*str2))
|
||||
break;
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
return (g_tolower (*str1) - g_tolower (*str2));
|
||||
}
|
||||
|
||||
int TOOLEXPORT
|
||||
_FP_strnicmp (char *str1, char *str2, int count)
|
||||
{
|
||||
if (str1==NULL || str2==NULL)
|
||||
return -1;
|
||||
|
||||
while (*str1 && count) {
|
||||
if (g_tolower(*str1) != g_tolower(*str2))
|
||||
break;
|
||||
str1++;
|
||||
str2++;
|
||||
count--;
|
||||
}
|
||||
return count ? (g_tolower (*str1) - g_tolower (*str2)) : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* autoconf says this function might be a compatibility problem
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strstr (char *str1, char *str2)
|
||||
{
|
||||
char *ptr1, *ptr2;
|
||||
|
||||
if (str1==NULL)
|
||||
return NULL;
|
||||
if (str2==NULL)
|
||||
return str1;
|
||||
|
||||
while (*(ptr1=str1)) {
|
||||
for (ptr2=str2;
|
||||
*ptr1 && *ptr2 && *ptr1==*ptr2;
|
||||
ptr1++, ptr2++)
|
||||
/* empty loop */ ;
|
||||
|
||||
if (*ptr2 == '\0')
|
||||
return str1;
|
||||
str1++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strpbrk (char *str, char *accept)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
if (accept == NULL || *accept == '\0')
|
||||
return str;
|
||||
|
||||
for (; *str; str++)
|
||||
for (ptr=accept; *ptr; ptr++)
|
||||
if (*str == *ptr)
|
||||
return str;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* autoconf also complains about this one
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strtok (char *str1, char *str2)
|
||||
{
|
||||
static char *optr;
|
||||
char *ptr;
|
||||
|
||||
if (str2 == NULL)
|
||||
return NULL;
|
||||
|
||||
if (str1) {
|
||||
optr = str1;
|
||||
}
|
||||
else {
|
||||
if (*optr == '\0')
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (*optr && strchr (str2, *optr)) /* look for beginning of token */
|
||||
optr++;
|
||||
|
||||
if (*optr == '\0') /* no token found */
|
||||
return NULL;
|
||||
|
||||
ptr = optr;
|
||||
while (*optr && strchr (str2, *optr) == NULL) /* look for end of token */
|
||||
optr++;
|
||||
|
||||
if (*optr) {
|
||||
*optr++ = '\0';
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* case insensitive strstr.
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_stristr (char *str1, char *str2)
|
||||
{
|
||||
char *ptr1, *ptr2;
|
||||
|
||||
if (str1==NULL)
|
||||
return NULL;
|
||||
if (str2==NULL)
|
||||
return str1;
|
||||
|
||||
while (*(ptr1=str1)) {
|
||||
for (ptr2=str2;
|
||||
*ptr1 && *ptr2 && g_tolower(*ptr1)==g_tolower(*ptr2);
|
||||
ptr1++, ptr2++)
|
||||
/* empty loop */ ;
|
||||
|
||||
if (*ptr2 == '\0')
|
||||
return str1;
|
||||
str1++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nice fake of the real (non-standard) one
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strrstr (char *ptr, char *str)
|
||||
{
|
||||
char *found=NULL, *pstr, *iter=ptr;
|
||||
|
||||
if (ptr==NULL || str==NULL)
|
||||
return NULL;
|
||||
|
||||
if (*str == '\0')
|
||||
return ptr;
|
||||
|
||||
while ((pstr = _FP_strstr (iter, str)) != NULL) {
|
||||
found = pstr;
|
||||
iter = pstr + 1;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strirstr (char *ptr, char *str)
|
||||
{
|
||||
char *found=NULL, *iter=ptr, *pstr;
|
||||
|
||||
if (ptr==NULL || str==NULL)
|
||||
return NULL;
|
||||
if (*str == '\0')
|
||||
return ptr;
|
||||
|
||||
while ((pstr = _FP_stristr (iter, str)) != NULL) {
|
||||
found = pstr;
|
||||
iter = pstr + 1;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert whole string to case
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_stoupper (char *input)
|
||||
{
|
||||
char *iter = input;
|
||||
|
||||
if (input == NULL)
|
||||
return NULL;
|
||||
|
||||
while (*iter) {
|
||||
*iter = g_toupper (*iter);
|
||||
iter++;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_stolower (char *input)
|
||||
{
|
||||
char *iter = input;
|
||||
|
||||
if (input == NULL)
|
||||
return NULL;
|
||||
|
||||
while (*iter) {
|
||||
*iter = g_tolower (*iter);
|
||||
iter++;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/*
|
||||
* string matching with wildcards
|
||||
*/
|
||||
|
||||
int TOOLEXPORT
|
||||
_FP_strmatch (char *string, char *pattern)
|
||||
{
|
||||
char *p1 = string, *p2 = pattern;
|
||||
|
||||
if (pattern==NULL || string==NULL)
|
||||
return 0;
|
||||
|
||||
while (*p1 && *p2) {
|
||||
if (*p2 == '?') {
|
||||
p1++; p2++;
|
||||
}
|
||||
else if (*p2 == '*') {
|
||||
if (*++p2 == '\0')
|
||||
return 1;
|
||||
while (*p1 && *p1 != *p2)
|
||||
p1++;
|
||||
}
|
||||
else if (*p1 == *p2) {
|
||||
p1++; p2++;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (*p1 || *p2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strrchr (char *string, int tc)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
|
||||
ptr = string + strlen (string) - 1;
|
||||
|
||||
while (ptr != string && *ptr != tc)
|
||||
ptr--;
|
||||
|
||||
if (*ptr == tc)
|
||||
return ptr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* strip directory information from a filename. Works only on DOS and
|
||||
* Unix systems so far ...
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_cutdir (char *filename)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if (filename == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((ptr = _FP_strrchr (filename, '/')) != NULL)
|
||||
ptr++;
|
||||
else if ((ptr = _FP_strrchr (filename, '\\')) != NULL)
|
||||
ptr++;
|
||||
else
|
||||
ptr = filename;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* My own fgets function. It handles all kinds of line terminators
|
||||
* properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the
|
||||
* terminator is replaced by a single LF
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_fgets (char *buf, int n, FILE *stream)
|
||||
{
|
||||
char *obp = buf;
|
||||
int c;
|
||||
|
||||
if (feof (stream))
|
||||
return NULL;
|
||||
|
||||
while (--n) {
|
||||
if ((c = fgetc (stream)) == EOF) {
|
||||
if (ferror (stream))
|
||||
return NULL;
|
||||
else {
|
||||
if (obp == buf)
|
||||
return NULL;
|
||||
*buf = '\0';
|
||||
return obp;
|
||||
}
|
||||
}
|
||||
if (c == '\015') { /* CR */
|
||||
/*
|
||||
* Peek next character. If it's no LF, push it back.
|
||||
* ungetc(EOF, stream) is handled correctly according
|
||||
* to the manual page
|
||||
*/
|
||||
if ((c = fgetc (stream)) != '\012')
|
||||
if (!feof (stream))
|
||||
ungetc (c, stream);
|
||||
*buf++ = '\012';
|
||||
*buf = '\0';
|
||||
return obp;
|
||||
}
|
||||
else if (c == '\012') { /* LF */
|
||||
*buf++ = '\012';
|
||||
*buf = '\0';
|
||||
return obp;
|
||||
}
|
||||
/*
|
||||
* just another standard character
|
||||
*/
|
||||
*buf++ = c;
|
||||
}
|
||||
/*
|
||||
* n-1 characters already transferred
|
||||
*/
|
||||
*buf = '\0';
|
||||
|
||||
return obp;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* A replacement strerror function that just returns the error code
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_strerror (int errcode)
|
||||
{
|
||||
static char number[8];
|
||||
|
||||
sprintf (number, "%03d", errcode);
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
/*
|
||||
* tempnam is not ANSI, but tmpnam is. Ignore the prefix here.
|
||||
*/
|
||||
|
||||
char * TOOLEXPORT
|
||||
_FP_tempnam (char *dir, char *pfx)
|
||||
{
|
||||
return _FP_strdup (tmpnam (NULL));
|
||||
}
|
||||
#endif
|
1467
goldlib/uulib/uucheck.cpp
Normal file
1467
goldlib/uulib/uucheck.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1793
goldlib/uulib/uuencode.cpp
Normal file
1793
goldlib/uulib/uuencode.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1242
goldlib/uulib/uulib.cpp
Normal file
1242
goldlib/uulib/uulib.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1625
goldlib/uulib/uunconc.cpp
Normal file
1625
goldlib/uulib/uunconc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3170
goldlib/uulib/uuscan.cpp
Normal file
3170
goldlib/uulib/uuscan.cpp
Normal file
File diff suppressed because it is too large
Load Diff
168
goldlib/uulib/uustring.cpp
Normal file
168
goldlib/uulib/uustring.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* This file is part of uudeview, the simple and friendly multi-part multi-
|
||||
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
|
||||
* be contacted at fp@fpx.de
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Strings used in the library for easier translation etc.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef SYSTEM_WINDLL
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifdef SYSTEM_OS2
|
||||
#include <os2.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
#include <uudeview.h>
|
||||
#include <uuint.h>
|
||||
#include <uustring.h>
|
||||
|
||||
char * uustring_id = "$Id$";
|
||||
|
||||
typedef struct {
|
||||
int code;
|
||||
char * msg;
|
||||
} stringmap;
|
||||
|
||||
/*
|
||||
* Map of messages. This table is not exported, the messages must
|
||||
* be retrieved via the below uustring() function.
|
||||
*/
|
||||
|
||||
static stringmap messages[] = {
|
||||
/* I/O related errors/messages. Last parameter is strerror() */
|
||||
{ S_NOT_OPEN_SOURCE, "Could not open source file %s: %s" },
|
||||
{ S_NOT_OPEN_TARGET, "Could not open target file %s for writing: %s" },
|
||||
{ S_NOT_OPEN_FILE, "Could not open file %s: %s" },
|
||||
{ S_NOT_STAT_FILE, "Could not stat file %s: %s" },
|
||||
{ S_SOURCE_READ_ERR, "Read error on source file: %s" },
|
||||
{ S_READ_ERROR, "Error reading from %s: %s" },
|
||||
{ S_IO_ERR_TARGET, "I/O error on target file %s: %s" },
|
||||
{ S_WR_ERR_TARGET, "Write error on target file %s: %s" },
|
||||
{ S_WR_ERR_TEMP, "Write error on temp file: %s" },
|
||||
{ S_TMP_NOT_REMOVED, "Could not remove temp file %s: %s (ignored)" },
|
||||
|
||||
/* some other problems */
|
||||
{ S_OUT_OF_MEMORY, "Out of memory allocating %d bytes" },
|
||||
{ S_TARGET_EXISTS, "Target file %s exists and overwriting is not allowed" },
|
||||
{ S_NOT_RENAME, "Could not change name of %s to %s" },
|
||||
{ S_ERR_ENCODING, "Error while encoding %s: %s" },
|
||||
{ S_STAT_ONE_PART, "Could not stat input, encoding to one part only" },
|
||||
{ S_PARM_CHECK, "Parameter check failed in %s" },
|
||||
{ S_SHORT_BINHEX, "BinHex encoded file %s ended prematurely (%ld bytes left)" },
|
||||
{ S_DECODE_CANCEL, "Decode operation canceled" },
|
||||
{ S_ENCODE_CANCEL, "Encode operation canceled" },
|
||||
{ S_SCAN_CANCEL, "Scanning canceled" },
|
||||
{ S_SIZE_MISMATCH, "%s: Decoded size (%ld) does not match expected size (%ld)" },
|
||||
{ S_PSIZE_MISMATCH, "%s part %d: Decoded size (%ld) does not match expected size (%ld)" },
|
||||
{ S_CRC_MISMATCH, "CRC32 mismatch in %s. Decoded file probably corrupt." },
|
||||
{ S_PCRC_MISMATCH, "PCRC32 mismatch in %s part %d. Decoded file probably corrupt." },
|
||||
|
||||
/* informational messages */
|
||||
{ S_LOADED_PART, "Loaded from %s: '%s' (%s): %s part %d %s %s %s" },
|
||||
{ S_NO_DATA_FOUND, "No encoded data found in %s" },
|
||||
{ S_NO_BIN_FILE, "Oops, could not find decoded file?" },
|
||||
{ S_STRIPPED_SETUID, "Stripped setuid/setgid bits from target file %s mode %d" },
|
||||
{ S_DATA_SUSPICIOUS, "Data looks suspicious. Decoded file might be corrupt." },
|
||||
{ S_NO_TEMP_NAME, "Could not get name for temporary file" },
|
||||
{ S_BINHEX_SIZES, "BinHex file: data/resource fork sizes %ld/%ld" },
|
||||
{ S_BINHEX_BOTH, "BinHex file: both forks non-empty, decoding data fork" },
|
||||
{ S_SMERGE_MERGED, "Parts of '%s' merged with parts of '%s' (%d)" },
|
||||
|
||||
/* MIME-related messages */
|
||||
{ S_MIME_NO_BOUNDARY, "Multipart message without boundary ignored" },
|
||||
{ S_MIME_B_NOT_FOUND, "Boundary expected on Multipart message but found EOF" },
|
||||
{ S_MIME_MULTI_DEPTH, "Multipart message nested too deep" },
|
||||
{ S_MIME_PART_MULTI, "Handling partial multipart message as plain text" },
|
||||
|
||||
{ 0, "" }
|
||||
};
|
||||
|
||||
/*
|
||||
* description of the return values UURET_*
|
||||
*/
|
||||
|
||||
char *uuretcodes[] = {
|
||||
"OK",
|
||||
"File I/O Error",
|
||||
"Not Enough Memory",
|
||||
"Illegal Value",
|
||||
"No Data found",
|
||||
"Unexpected End of File",
|
||||
"Unsupported function",
|
||||
"File exists",
|
||||
"Continue -- no error", /* only to be seen internally */
|
||||
"Operation Canceled"
|
||||
};
|
||||
|
||||
/*
|
||||
* Names of encoding types
|
||||
*/
|
||||
|
||||
char *codenames[8] = {
|
||||
"", "UUdata", "Base64", "XXdata", "Binhex", "Text", "Text", "yEnc"
|
||||
};
|
||||
|
||||
/*
|
||||
* Message types
|
||||
*/
|
||||
|
||||
char *msgnames[6] = {
|
||||
"", "Note: ", "Warning: ", "ERROR: ", "FATAL ERROR: ", "PANIC: "
|
||||
};
|
||||
|
||||
/*
|
||||
* Retrieve one of the messages. We never return NULL
|
||||
* but instead escape to "oops".
|
||||
*/
|
||||
|
||||
char *
|
||||
uustring (int codeno)
|
||||
{
|
||||
static char * faileddef = "oops";
|
||||
stringmap *ptr = messages;
|
||||
|
||||
while (ptr->code) {
|
||||
if (ptr->code == codeno)
|
||||
return ptr->msg;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
UUMessage (uustring_id, __LINE__, UUMSG_ERROR,
|
||||
"Could not retrieve string no %d",
|
||||
codeno);
|
||||
|
||||
return faileddef;
|
||||
}
|
481
goldlib/uulib/uuutil.cpp
Normal file
481
goldlib/uulib/uuutil.cpp
Normal file
@ -0,0 +1,481 @@
|
||||
/*
|
||||
* This file is part of uudeview, the simple and friendly multi-part multi-
|
||||
* file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may
|
||||
* be contacted at fp@fpx.de
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* certain utilitarian functions that didn't fit anywhere else
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef SYSTEM_WINDLL
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifdef SYSTEM_OS2
|
||||
#include <os2.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <uudeview.h>
|
||||
#include <uuint.h>
|
||||
#include <fptools.h>
|
||||
#include <uustring.h>
|
||||
|
||||
char * uuutil_id = "$Id$";
|
||||
|
||||
/*
|
||||
* Parts with different known extensions will not be merged by SPMS.
|
||||
* if first character is '@', it is synonymous to the previous one.
|
||||
*/
|
||||
|
||||
static char *knownexts[] = {
|
||||
"mpg", "@mpeg", "avi", "mov",
|
||||
"gif", "jpg", "@jpeg", "tif",
|
||||
"voc", "wav", "@wave", "au",
|
||||
"zip", "arj", "tar",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* forward declarations of local functions
|
||||
*/
|
||||
|
||||
static int UUSMPKnownExt (char *filename);
|
||||
static uulist * UU_smparts_r (uulist *, int);
|
||||
|
||||
/*
|
||||
* mallocable areas
|
||||
*/
|
||||
|
||||
char *uuutil_bhwtmp;
|
||||
|
||||
/*
|
||||
* free some memory
|
||||
**/
|
||||
|
||||
void
|
||||
UUkillfread (fileread *data)
|
||||
{
|
||||
if (data != NULL) {
|
||||
_FP_free (data->subject);
|
||||
_FP_free (data->filename);
|
||||
_FP_free (data->origin);
|
||||
_FP_free (data->mimeid);
|
||||
_FP_free (data->mimetype);
|
||||
_FP_free (data->sfname);
|
||||
_FP_free (data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UUkillfile (uufile *data)
|
||||
{
|
||||
uufile *next;
|
||||
|
||||
while (data) {
|
||||
_FP_free (data->filename);
|
||||
_FP_free (data->subfname);
|
||||
_FP_free (data->mimeid);
|
||||
_FP_free (data->mimetype);
|
||||
UUkillfread (data->data);
|
||||
|
||||
next = data->NEXT;
|
||||
_FP_free (data);
|
||||
data = next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UUkilllist (uulist *data)
|
||||
{
|
||||
uulist *next;
|
||||
|
||||
while (data) {
|
||||
if (data->binfile != NULL)
|
||||
if (unlink (data->binfile))
|
||||
UUMessage (uuutil_id, __LINE__, UUMSG_WARNING,
|
||||
uustring (S_TMP_NOT_REMOVED),
|
||||
data->binfile, strerror (errno));
|
||||
|
||||
_FP_free (data->filename);
|
||||
_FP_free (data->subfname);
|
||||
_FP_free (data->mimeid);
|
||||
_FP_free (data->mimetype);
|
||||
_FP_free (data->binfile);
|
||||
UUkillfile (data->thisfile);
|
||||
_FP_free (data->haveparts);
|
||||
_FP_free (data->misparts);
|
||||
|
||||
next = data->NEXT;
|
||||
_FP_free (data);
|
||||
data = next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this kill function is an exception in that it doesn't kill data itself
|
||||
*/
|
||||
|
||||
void
|
||||
UUkillheaders (headers *data)
|
||||
{
|
||||
if (data != NULL) {
|
||||
_FP_free (data->from);
|
||||
_FP_free (data->subject);
|
||||
_FP_free (data->rcpt);
|
||||
_FP_free (data->date);
|
||||
_FP_free (data->mimevers);
|
||||
_FP_free (data->ctype);
|
||||
_FP_free (data->ctenc);
|
||||
_FP_free (data->fname);
|
||||
_FP_free (data->boundary);
|
||||
_FP_free (data->mimeid);
|
||||
memset (data, 0, sizeof (headers));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* checks for various well-known extensions. if two parts have different
|
||||
* known extensions, we won't merge them.
|
||||
*/
|
||||
|
||||
static int
|
||||
UUSMPKnownExt (char *filename)
|
||||
{
|
||||
char **eiter = knownexts, *ptr=_FP_strrchr(filename, '.');
|
||||
int count=0, where=0;
|
||||
|
||||
if (ptr == NULL)
|
||||
return -1;
|
||||
ptr++;
|
||||
|
||||
while (*eiter) {
|
||||
if (_FP_stricmp (ptr, (**eiter=='@')?*eiter+1:*eiter) == 0)
|
||||
return where;
|
||||
else
|
||||
eiter++;
|
||||
|
||||
if (*eiter == NULL)
|
||||
break;
|
||||
|
||||
if (**eiter=='@')
|
||||
count++;
|
||||
else
|
||||
where = ++count;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* de-compress a binhex RLE stream
|
||||
* the data read from in is uncompressed, and at most maxcount bytes
|
||||
* (or octets, as they say) are copied to out. Because an uncompression
|
||||
* might not be completed because of this maximum number of bytes. There-
|
||||
* for, the leftover character and repetition count is saved. If a marker
|
||||
* has been read but not the repetition count, *rpc is set to -256.
|
||||
*
|
||||
* the function returns the number of bytes eaten from in. If opc is not
|
||||
* NULL, the total number of characters stored in out is saved there
|
||||
*
|
||||
* with repetition counts, remember that we've already transferred *one*
|
||||
* occurence
|
||||
*/
|
||||
|
||||
int
|
||||
UUbhdecomp (char *in, char *out, char *last, int *rpc,
|
||||
size_t inc, size_t max, size_t *opc)
|
||||
{
|
||||
size_t count, used=0, dummy;
|
||||
char marker = '\220' /* '\x90' */;
|
||||
|
||||
if (opc == NULL)
|
||||
opc = &dummy;
|
||||
else
|
||||
*opc = 0;
|
||||
|
||||
if (*rpc == -256) {
|
||||
if (inc == 0)
|
||||
return 0;
|
||||
*rpc = (int) (unsigned char) *in++; used++;
|
||||
|
||||
if (*rpc == 0) {
|
||||
*last = *out++ = marker;
|
||||
max--; *opc+=1;
|
||||
}
|
||||
else
|
||||
*rpc-=1;
|
||||
}
|
||||
|
||||
if (*rpc) {
|
||||
count = (max > (size_t) *rpc) ? (size_t) *rpc : max;
|
||||
|
||||
memset (out, *last, count);
|
||||
|
||||
out += count;
|
||||
*opc += count;
|
||||
max -= count;
|
||||
*rpc -= count;
|
||||
}
|
||||
|
||||
while (used < inc && max) {
|
||||
if (*in == marker) {
|
||||
used++; in++;
|
||||
if (used == inc) {
|
||||
*rpc = -256;
|
||||
return used;
|
||||
}
|
||||
*rpc = (int) (unsigned char) *in++; used++;
|
||||
|
||||
if (*rpc == 0) {
|
||||
*last = *out++ = marker;
|
||||
max--; *opc+=1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
*rpc -= 1;
|
||||
|
||||
count = (max > (size_t) *rpc) ? (size_t) *rpc : max;
|
||||
memset (out, *last, count);
|
||||
|
||||
out += count;
|
||||
*opc += count;
|
||||
max -= count;
|
||||
*rpc -= count;
|
||||
}
|
||||
else {
|
||||
*last = *out++ = *in++;
|
||||
used++; *opc+=1; max--;
|
||||
}
|
||||
}
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
/*
|
||||
* write to binhex file
|
||||
*/
|
||||
|
||||
size_t
|
||||
UUbhwrite (char *ptr, size_t sel, size_t nel, FILE *file)
|
||||
{
|
||||
char *tmpstring=uuutil_bhwtmp;
|
||||
static int rpc = 0;
|
||||
static char lc;
|
||||
int count, tc=0;
|
||||
size_t opc;
|
||||
|
||||
if (ptr == NULL) { /* init */
|
||||
rpc = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (nel || (rpc != 0 && rpc != -256)) {
|
||||
count = UUbhdecomp (ptr, tmpstring, &lc, &rpc,
|
||||
nel, 256, &opc);
|
||||
if (fwrite (tmpstring, 1, opc, file) != opc)
|
||||
return 0;
|
||||
if (ferror (file))
|
||||
return 0;
|
||||
nel -= count;
|
||||
ptr += count;
|
||||
tc += count;
|
||||
}
|
||||
|
||||
return tc;
|
||||
}
|
||||
|
||||
static uulist *
|
||||
UU_smparts_r (uulist *addit, int pass)
|
||||
{
|
||||
uulist *iter = UUGlobalFileList;
|
||||
uufile *fiter, *dest, *temp;
|
||||
int count, flag, a, b;
|
||||
|
||||
while (iter) {
|
||||
if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
|
||||
iter = iter->NEXT;
|
||||
continue;
|
||||
}
|
||||
if (iter == addit) {
|
||||
iter = iter->NEXT;
|
||||
continue;
|
||||
}
|
||||
if ((iter->begin && addit->begin) || (iter->end && addit->end) ||
|
||||
(iter->uudet != addit->uudet)) {
|
||||
iter = iter->NEXT;
|
||||
continue;
|
||||
}
|
||||
if ((a = UUSMPKnownExt (addit->subfname)) != -1 &&
|
||||
(b = UUSMPKnownExt (iter->subfname)) != -1)
|
||||
if (a != b) {
|
||||
iter = iter->NEXT;
|
||||
continue;
|
||||
}
|
||||
|
||||
flag = count = 0;
|
||||
fiter = iter->thisfile;
|
||||
temp = addit->thisfile;
|
||||
dest = NULL;
|
||||
|
||||
while (temp) {
|
||||
if (!(temp->data->uudet)) {
|
||||
temp = temp->NEXT;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (fiter && fiter->partno < temp->partno) {
|
||||
dest = fiter;
|
||||
fiter = fiter->NEXT;
|
||||
}
|
||||
if (fiter && fiter->partno == temp->partno) {
|
||||
flag = 0;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
flag = 1;
|
||||
count += ((dest) ? temp->partno - dest->partno - 1 : 0) +
|
||||
((fiter) ? fiter->partno - temp->partno - 1 : 0);
|
||||
}
|
||||
|
||||
temp = temp->NEXT;
|
||||
}
|
||||
if (flag == 0 ||
|
||||
(pass == 0 && count > 0) ||
|
||||
(pass == 1 && count > 5)) {
|
||||
iter = iter->NEXT;
|
||||
continue;
|
||||
}
|
||||
|
||||
dest = iter->thisfile;
|
||||
fiter = addit->thisfile;
|
||||
|
||||
if (iter->filename == NULL && addit->filename != NULL)
|
||||
iter->filename = _FP_strdup (addit->filename);
|
||||
|
||||
if (addit->begin) iter->begin = 1;
|
||||
if (addit->end) iter->end = 1;
|
||||
|
||||
if (addit->mode != 0 && iter->mode == 0)
|
||||
iter->mode = addit->mode;
|
||||
|
||||
while (fiter) {
|
||||
flag = 0;
|
||||
|
||||
if (fiter->partno == iter->thisfile->partno ||
|
||||
(dest->NEXT != NULL && fiter->partno == dest->NEXT->partno)) {
|
||||
temp = fiter->NEXT;
|
||||
fiter->NEXT = NULL;
|
||||
|
||||
UUkillfile (fiter);
|
||||
|
||||
addit->thisfile= temp;
|
||||
fiter = temp;
|
||||
continue;
|
||||
}
|
||||
if (fiter->partno < iter->thisfile->partno) {
|
||||
temp = fiter->NEXT;
|
||||
fiter->NEXT = iter->thisfile;
|
||||
iter->thisfile = fiter;
|
||||
dest = fiter;
|
||||
addit->thisfile= temp;
|
||||
fiter = temp;
|
||||
}
|
||||
else if (dest->NEXT == NULL || fiter->partno < dest->NEXT->partno) {
|
||||
temp = fiter->NEXT;
|
||||
fiter->NEXT = dest->NEXT;
|
||||
dest->NEXT = fiter;
|
||||
addit->thisfile= temp;
|
||||
fiter = temp;
|
||||
}
|
||||
else {
|
||||
dest = dest->NEXT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
int UUEXPORT
|
||||
UUSmerge (int pass)
|
||||
{
|
||||
uulist *iter = UUGlobalFileList, *last=NULL, *res, *temp;
|
||||
int flag = 0;
|
||||
|
||||
while (iter) {
|
||||
if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
|
||||
last = iter;
|
||||
iter = iter->NEXT;
|
||||
continue;
|
||||
}
|
||||
if ((res = UU_smparts_r (iter, pass)) != NULL) {
|
||||
UUMessage (uuutil_id, __LINE__, UUMSG_MESSAGE,
|
||||
uustring (S_SMERGE_MERGED),
|
||||
(iter->subfname) ? iter->subfname : "",
|
||||
(res->subfname) ? res->subfname : "", pass);
|
||||
|
||||
temp = iter->NEXT;
|
||||
iter->NEXT = NULL;
|
||||
UUkilllist (iter);
|
||||
|
||||
flag++;
|
||||
|
||||
if (last == NULL) {
|
||||
UUGlobalFileList = temp;
|
||||
iter = temp;
|
||||
}
|
||||
else {
|
||||
last->NEXT = temp;
|
||||
iter = temp;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
last = iter;
|
||||
iter = iter->NEXT;
|
||||
}
|
||||
|
||||
/*
|
||||
* check again
|
||||
*/
|
||||
|
||||
UUCheckGlobalList ();
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
Reference in New Issue
Block a user