⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tprx.c

📁 一个使用IPX协议在两台机器间传送文件的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*

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