📄 tprx.c
字号:
/*
TPRX.C
(c) 1996 by Oliver Kraus
*/
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <fcntl.h>
#include <assert.h>
#include <sys\stat.h>
#include <sys\types.h>
#include <fcntl.h>
#include "cio.h"
#include "tprx.h"
#include "crc16.h"
#include "crc32.h"
/* #include "debugmem.h" */
#define TPRX_ID_STR "receiver: "
char *tprx_es_ipx_not_found = TPRX_ID_STR "ipx not found";
char *tprx_es_socket_table_full = TPRX_ID_STR "socket table full";
char *tprx_es_socket_open = TPRX_ID_STR "socket already open";
char *tprx_es_out_of_memory = TPRX_ID_STR "out of memory";
/* - - - - - state prototypes - - - - - - - - - - - - - - - - - - - - - - */
void tprx_state_none(tprx_type tprx);
void tprx_state_gen_ack_request(tprx_type tprx);
void tprx_state_chk_ack_request(tprx_type tprx);
void tprx_state_user_check(tprx_type tprx);
void tprx_state_gen_file_start(tprx_type tprx);
void tprx_state_chk_file_start(tprx_type tprx);
void tprx_state_wait_file_start(tprx_type tprx);
void tprx_state_gen_ack_file_start(tprx_type tprx);
void tprx_state_chk_ack_file_start(tprx_type tprx);
void tprx_state_wait_block_start(tprx_type tprx);
void tprx_state_gen_ack_block_start(tprx_type tprx);
void tprx_state_chk_ack_block_start(tprx_type tprx);
void tprx_state_wait_data(tprx_type tprx);
void tprx_state_gen_missed_blocks(tprx_type tprx);
void tprx_state_chk_missed_blocks(tprx_type tprx);
void tprx_state_gen_ack_block_end(tprx_type tprx);
void tprx_state_chk_ack_block_end(tprx_type tprx);
void tprx_state_gen_ack_file_end(tprx_type tprx);
void tprx_state_chk_ack_file_end(tprx_type tprx);
void tprx_state_none2(tprx_type tprx);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
allocate pool memory
*/
int tprx_OpenPool(tprx_type tprx, size_t b_len, int b_cnt)
{
int i;
/* check against 16 bit system */
if ( (long)b_len*(long)b_cnt > 65500 )
return 1;
/* assign parameter */
tprx->b_len = b_len;
tprx->b_cnt = b_cnt;
tprx->rx_cnt = b_cnt+TPRX_RX_ADD;
tprx->b_pool_size = b_cnt*b_len;
/* data buffers for ipx listen process */
tprx->rx_data = (char **)malloc(tprx->rx_cnt*sizeof(char *));
if ( tprx->rx_data != NULL )
{
for( i = 0; i < tprx->rx_cnt; i++ )
tprx->rx_data[i] = (char *)malloc(tprx->b_len+TP_BLK_INFO_SIZE);
for( i = 0; i < tprx->rx_cnt; i++ )
if ( tprx->rx_data[i] == NULL )
break;
if ( i >= tprx->rx_cnt )
{
/* allocate ipx ecb data buffers */
tprx->rx_ecb = (ipx_ecb_struct **)malloc(tprx->rx_cnt*sizeof(ipx_ecb_struct *));
if ( tprx->rx_ecb != NULL )
{
for( i = 0; i < tprx->rx_cnt; i++ )
tprx->rx_ecb[i] = (ipx_ecb_struct *)malloc(sizeof(ipx_ecb_struct));
for( i = 0; i < tprx->rx_cnt; i++ )
if ( tprx->rx_ecb[i] == NULL )
break;
if ( i >= tprx->rx_cnt )
{
/* clear ecb buffers */
for( i = 0; i < tprx->rx_cnt; i++ )
{
tprx->rx_ecb[i]->inuse = 0;
tprx->rx_ecb[i]->cc = 0;
tp_set_blk_id(tprx->rx_data[i], TP_ID_NONE);
}
/* allocate "block available" array */
tprx->b_is_present = (char *)malloc(tprx->b_cnt*sizeof(char));
if ( tprx->b_is_present != NULL )
{
/* allocate memory pool */
tprx->b_pool_ptr = (char *)malloc(tprx->b_pool_size);
if ( tprx->b_pool_ptr != NULL )
{
/* allocate missed blocks list */
tprx->b_missed_list =
(short *)malloc(tprx->b_cnt*sizeof(short));
if ( tprx->b_missed_list != NULL )
{
return 1;
}
/* deallocate everything, if something went wrong */
free(tprx->b_pool_ptr);
tprx->b_pool_ptr = NULL;
}
free(tprx->b_is_present);
tprx->b_is_present = NULL;
}
}
for( i = 0; i < tprx->rx_cnt; i++ )
if ( tprx->rx_ecb[i] != NULL )
free(tprx->rx_ecb[i]);
free(tprx->rx_ecb);
tprx->rx_ecb = NULL;
}
}
for( i = 0; i < tprx->rx_cnt; i++ )
if ( tprx->rx_data[i] != NULL )
free(tprx->rx_data[i]);
free(tprx->rx_data);
tprx->rx_data = NULL;
}
return 0;
}
int tprx_IsOk(tprx_type tprx)
{
assert(tprx != NULL);
assert(tprx->rx_cnt == tprx->b_cnt+TPRX_RX_ADD);
assert(tprx->b_cnt*2 < (int)tprx->b_len);
return 1;
}
tprx_type tprx_Open(unsigned short socket)
{
tprx_type tprx;
if ( ipx_init() == 0 )
{
fprintf(stderr, tprx_es_ipx_not_found);
return NULL;
}
switch(ipx_open_socket(socket))
{
case 0x0fe:
fprintf(stderr, tprx_es_socket_table_full);
return NULL;
case 0x0ff:
fprintf(stderr, tprx_es_socket_open);
return NULL;
}
tprx = (tprx_type)malloc(sizeof(tprx_struct));
if ( tprx != NULL )
{
tprx->flags = 0;
tprx->is_break_enable = 1;
if ( c_is_long_filename(0) != 0 )
tprx->flags |= TP_FLAG_IS_LFN;
tprx->is_ended = 0;
tprx->is_adr_known = 0;
tprx->socket = socket;
tprx->f_name = NULL;
tprx->f_handle = -1;
tprx->f_len = 0L;
tprx->f_pos = 0L;
tprx->f_start = (clock_t)0;
tprx->small_delay = CLOCKS_PER_SEC/4;
tprx->large_delay = CLOCKS_PER_SEC;
/* tprx->small_delay = 1; */
/* tprx->large_delay = 2; */
tprx->is_aux = 0;
tprx_SetState(tprx, tprx_state_none);
if ( tprx_OpenPool(tprx, TPRX_B_LEN, TPRX_B_CNT) != 0 )
{
tprx->tx_data = (char *)malloc(tprx->b_len+TP_BLK_INFO_SIZE);
if ( tprx->tx_data != NULL )
{
tprx->tx_ecb = (ipx_ecb_struct *)malloc(sizeof(ipx_ecb_struct));
if ( tprx->tx_ecb != NULL )
{
tprx->tx_ecb->inuse = 0;
tprx->tx_ecb->cc = 0;
tp_set_blk_id(tprx->tx_data, TP_ID_NONE);
tprx_ListenAll(tprx);
return tprx;
}
free(tprx->tx_data);
}
tprx_ClosePool(tprx);
}
free(tprx);
}
ipx_close_socket(socket);
return NULL;
}
void tprx_ClosePool(tprx_type tprx)
{
int i;
assert(tprx != NULL);
free(tprx->b_missed_list);
tprx->b_missed_list = NULL;
free(tprx->b_pool_ptr);
tprx->b_pool_ptr = NULL;
free(tprx->b_is_present);
tprx->b_is_present = NULL;
for( i = 0; i < tprx->rx_cnt; i++ )
if ( tprx->rx_ecb[i] != NULL )
{
ipx_cancel_ecb(tprx->rx_ecb[i]);
free(tprx->rx_ecb[i]);
}
free(tprx->rx_ecb);
tprx->rx_ecb = NULL;
for( i = 0; i < tprx->rx_cnt; i++ )
if ( tprx->rx_data[i] != NULL )
free(tprx->rx_data[i]);
free(tprx->rx_data);
tprx->rx_data = NULL;
}
void tprx_Close(tprx_type tprx)
{
assert(tprx != NULL);
if ( tprx->f_name != NULL )
free(tprx->f_name);
ipx_cancel_ecb(tprx->tx_ecb);
free(tprx->tx_ecb);
free(tprx->tx_data);
tprx_ClosePool(tprx);
if ( tprx->f_handle >= 0 )
c_close(tprx->f_handle);
ipx_close_socket(tprx->socket);
free(tprx);
}
void tprx_SetAux(tprx_type tprx, int (*aux)( int msg, void *data ))
{
if ( tprx_IsOk(tprx) == 0 )
return;
tprx->aux = aux;
tprx->is_aux = 1;
}
void tprx_DoAux(tprx_type tprx, int msg, void *data)
{
if ( tprx_IsOk(tprx) == 0 )
return;
if ( tprx->is_aux != 0 )
tprx->aux(msg, data);
}
void tprx_DoPAux(tprx_type tprx, int msg)
{
tprx->pdata.total = tprx->f_len;
tprx->pdata.curr = tprx->f_pos;
tprx->pdata.crc = tprx->f_crc;
tprx->pdata.path = tprx->f_name;
tprx->pdata.file_start = tprx->f_start;
tprx->pdata.missed = tprx->b_missed_sum;
tprx_DoAux(tprx, msg, (void *)&(tprx->pdata));
}
void tprx_InitPool(tprx_type tprx, int b_curr_cnt)
{
int i;
tprx->b_curr_cnt = b_curr_cnt;
tprx->b_in_cnt = 0;
tprx->b_is_any_present = 0;
for( i = 0; i < tprx->b_cnt; i++ )
tprx->b_is_present[i] = 0;
}
void tprx_CopyMemoryToPool(tprx_type tprx, int no, void *adr, size_t len)
{
assert(no < tprx->b_curr_cnt);
if ( tprx->b_is_present[no] == 0 )
{
memcpy(tprx->b_pool_ptr+no*tprx->b_len, adr, len);
tprx->b_in_cnt++;
tprx->b_is_present[no] = 1;
tprx->b_is_any_present = 1;
}
}
void tprx_MakeMissedList(tprx_type tprx)
{
int i;
int missed = 0;
for( i = 0; i < tprx->b_curr_cnt; i++ )
{
if ( tprx->b_is_present[i] == 0 )
{
tprx->b_missed_list[missed++] = (short)i;
}
}
tprx->b_missed_cnt = missed;
tprx->b_missed_sum += (long)missed;
assert(missed == tprx->b_curr_cnt-tprx->b_in_cnt);
}
void tprx_SetFileName(tprx_type tprx, char *path)
{
if ( tprx->f_handle >= 0 )
c_close(tprx->f_handle);
tprx->f_handle = -1;
tprx->f_exist = 0;
if ( tprx->f_name != NULL )
free(tprx->f_name);
tprx->f_name = (char *)malloc(strlen(path)+1);
if ( tprx->f_name == NULL )
return;
strcpy(tprx->f_name, path);
if ( (tprx->flags & TP_FLAG_IS_LFN) == 0 )
strupr(tprx->f_name);
if ( (tprx->flags & TP_FLAG_IS_DIR) == 0 )
{
int fhandle;
tprx->f_exist = 0;
fhandle = c_open(tprx->f_name, O_BINARY, S_IWRITE);
if ( fhandle >= 0 )
{
tprx->f_exist = 1;
c_close(fhandle);
}
}
}
void tprx_OpenFile(tprx_type tprx)
{
static char drive[_MAX_DRIVE];
static char dirs[_MAX_DIR];
static char fname[_MAX_FNAME+_MAX_EXT];
static char ext[_MAX_EXT];
static char npath[_MAX_PATH];
tprx->f_is_write_data = 0;
tprx->f_pos = 0UL;
tprx->f_crc = 0L;
tprx->f_start = 0L;
tprx->b_missed_sum = 0;
if ( (tprx->flags & TP_FLAG_IS_TEST_MODE) == 0 )
{
char *cwd;
tprx->f_handle = -1;
if ( (tprx->flags & TP_FLAG_IS_DIR) != 0 )
{
/* store current path */
cwd = c_getcwd();
/* printf("dir: cwd: %s\n", cwd); */
if ( cwd == NULL )
{
printf("can not get current working directory\n");
return;
}
/* create directory */
/* printf("dir: path: %s\n", tprx->f_name); */
if ( c_create_path(tprx->f_name) != 0 )
{
printf("can not create directory '%s'\n", tprx->f_name);
return;
}
/* restore directory */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -