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

📄 tptx.c

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

   TPTX.C

   (c) 1996 by Oliver Kraus

*/

#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <assert.h>
#include <dos.h>
#include <fcntl.h>
#include "tptx.h"
#include "crc16.h"
#include "crc32.h"
#include "cio.h"

/* #include "debugmem.h" */

#define TPTX_ID_STR "transmitter: "

char *tptx_es_ipx_not_found     = TPTX_ID_STR "ipx not found";
char *tptx_es_socket_table_full = TPTX_ID_STR "socket table full";
char *tptx_es_socket_open       = TPTX_ID_STR "socket already open";
char *tptx_es_out_of_memory     = TPTX_ID_STR "out of memory";

/* - - - - - state prototypes  - - - - - - - - - - - - - - - - - - - - - - */

void tptx_state_none(tptx_type tptx);
void tptx_state_gen_request(tptx_type tptx);
void tptx_state_chk_request(tptx_type tptx);
void tptx_state_wait_ack_request(tptx_type tptx);
void tptx_state_user_check(tptx_type tptx);
void tptx_state_gen_file_start(tptx_type tptx);
void tptx_state_chk_file_start(tptx_type tptx);
void tptx_state_wait_ack_file_start(tptx_type tptx);
void tptx_state_gen_block_start(tptx_type tptx);
void tptx_state_chk_block_start(tptx_type tptx);
void tptx_state_wait_ack_block_start(tptx_type tptx);
void tptx_state_gen_data(tptx_type tptx);
void tptx_state_chk_data(tptx_type tptx);
void tptx_state_gen_block_end(tptx_type tptx);
void tptx_state_chk_block_end(tptx_type tptx);
void tptx_state_wait_ack_block_end(tptx_type tptx);
void tptx_state_gen_file_end(tptx_type tptx);
void tptx_state_chk_file_end(tptx_type tptx);
void tptx_state_wait_ack_file_end(tptx_type tptx);

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

/*
   allocate pool memory
*/
int tptx_OpenPool(tptx_type tptx, 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 */

   tptx->b_len = b_len;
   tptx->b_cnt = b_cnt;
   tptx->tx_cnt = b_cnt+TPTX_TX_ADD;
   tptx->b_pool_size = b_cnt*b_len;

   /* data buffers for ipx listen process */

   tptx->tx_data = (char **)malloc(tptx->tx_cnt*sizeof(char *));
   if ( tptx->tx_data != NULL )
   {
      for( i = 0; i < tptx->tx_cnt; i++ )
         tptx->tx_data[i] = (char *)malloc(tptx->b_len+TP_BLK_INFO_SIZE);
      for( i = 0; i < tptx->tx_cnt; i++ )
         if ( tptx->tx_data[i] == NULL )
            break;
      if ( i >= tptx->tx_cnt )
      {

   /* allocate ipx ecb data buffers */

         tptx->tx_ecb = (ipx_ecb_struct **)malloc(tptx->tx_cnt*sizeof(ipx_ecb_struct *));
         if ( tptx->tx_ecb != NULL )
         {
            for( i = 0; i < tptx->tx_cnt; i++ )
               tptx->tx_ecb[i] = (ipx_ecb_struct *)malloc(sizeof(ipx_ecb_struct));
            for( i = 0; i < tptx->tx_cnt; i++ )
               if ( tptx->tx_ecb[i] == NULL )
                  break;
            if ( i >= tptx->tx_cnt )
            {

   /* clear ecb buffers */

               for( i = 0; i < tptx->tx_cnt; i++ )
               {
                  tptx->tx_ecb[i]->inuse = 0;
                  tp_set_blk_id(tptx->tx_data[i], TP_ID_NONE);
               }

   /* allocate block send list */

               tptx->b_list_ptr = (short *)malloc(tptx->b_cnt*sizeof(short));
               if ( tptx->b_list_ptr != NULL )
               {

   /* allocate memory pool */

                  tptx->b_pool_ptr = (char *)malloc(tptx->b_pool_size);
                  if ( tptx->b_pool_ptr != NULL )
                  {
                     tptx->b_pool_dptr = (char *)malloc(tptx->b_pool_size);
                     if ( tptx->b_pool_dptr != NULL )
                     {

                        return 1;
                     }
                     free(tptx->b_pool_dptr);
                     tptx->b_pool_dptr = NULL;
                  }

   /* deallocate everything, if something went wrong */

                  free(tptx->b_list_ptr);
                  tptx->b_list_ptr = NULL;
               }
            }
            for( i = 0; i < tptx->tx_cnt; i++ )
               if ( tptx->tx_ecb[i] != NULL )
                  free(tptx->tx_ecb[i]);
            free(tptx->tx_ecb);
            tptx->tx_ecb = NULL;
         }
      }
      for( i = 0; i < tptx->tx_cnt; i++ )
         if ( tptx->tx_data[i] != NULL )
            free(tptx->tx_data[i]);
      free(tptx->tx_data);
      tptx->tx_data = NULL;
   }
   return 0;
}

int tptx_IsOk(tptx_type tptx)
{
   assert(tptx != NULL);
   assert(tptx->tx_cnt == tptx->b_cnt+TPTX_TX_ADD);
   assert(tptx->b_cnt*2 < (int)tptx->b_len);
   return 1;
}

tptx_type tptx_Open(unsigned short socket, int is_lfn)
{
   tptx_type tptx;

   if ( ipx_init() == 0 )
   {
      fprintf(stderr, tptx_es_ipx_not_found);
      return NULL;
   }

   switch(ipx_open_socket(socket))
   {
      case 0x0fe:
         fprintf(stderr, tptx_es_socket_table_full);
         return NULL;
      case 0x0ff:
         fprintf(stderr, tptx_es_socket_open);
         return NULL;
   }

   tptx = (tptx_type)malloc(sizeof(tptx_struct));
   if ( tptx != NULL )
   {
      tptx->flags = 0;
      if ( c_is_long_filename(0) != 0 && is_lfn != 0 )
         tptx->flags |= TP_FLAG_IS_LFN;

      tptx->socket   = socket;
      tptx->is_adr_known = 0;

      tptx->f_name = NULL;
      tptx->f_logname = NULL;
      tptx->f_logsname = NULL;
      tptx->fp = NULL;
      /* tptx->f_handle = -1; */

      tptx->small_delay = CLOCKS_PER_SEC/2;
      tptx->large_delay = CLOCKS_PER_SEC*2;

      /*
      tptx->small_delay = 1;
      tptx->large_delay = 2;
      */

      tptx_SetState(tptx, tptx_state_none);

      tptx->is_aux = 0;
      tptx->f_time_sum = (clock_t)0;
      tptx->f_len_sum = 0L;

      if ( tptx_OpenPool(tptx, TPTX_B_LEN, TPTX_B_CNT) != 0 )
      {
         tptx->rx_data = (char *)malloc(tptx->b_len+TP_BLK_INFO_SIZE);
         if ( tptx->rx_data != NULL )
         {
            tptx->rx_ecb = (ipx_ecb_struct *)malloc(sizeof(ipx_ecb_struct));
            if ( tptx->rx_ecb != NULL )
            {
               tptx->rx_ecb->inuse = 0;
               tptx->rx_ecb->cc = 0;
               tp_set_blk_id(tptx->rx_data, TP_ID_NONE);
               tptx_ListenECB(tptx);
               return tptx;
            }
            free(tptx->rx_data);
         }
         tptx_ClosePool(tptx);
      }
      free(tptx);
   }
   ipx_close_socket(socket);
   return NULL;
}

void tptx_ClosePool(tptx_type tptx)
{
   int i;

   assert(tptx != NULL);

   free(tptx->b_pool_ptr);
   tptx->b_pool_ptr = NULL;

   free(tptx->b_pool_dptr);
   tptx->b_pool_dptr = NULL;

   free(tptx->b_list_ptr);
   tptx->b_list_ptr = NULL;

   for( i = 0; i < tptx->tx_cnt; i++ )
      if ( tptx->tx_ecb[i] != NULL )
      {
         ipx_cancel_ecb(tptx->tx_ecb[i]);
         free(tptx->tx_ecb[i]);
      }
   free(tptx->tx_ecb);
   tptx->tx_ecb = NULL;

   for( i = 0; i < tptx->tx_cnt; i++ )
      if ( tptx->tx_data[i] != NULL )
         free(tptx->tx_data[i]);
   free(tptx->tx_data);
   tptx->tx_data = NULL;

}

void tptx_CloseFile(tptx_type tptx)
{
   /* if ( tptx->f_handle >= 0 ) */
   if ( tptx->fp != NULL )
   {
      fclose(tptx->fp);
      tptx->fp = NULL;
      /* tptx->f_handle = -1; */
      tptx->f_time_sum += clock()-tptx->f_start;
      tptx->f_len_sum += tptx->f_len;
   }

   if ( tptx->f_name != NULL )
   {
      free(tptx->f_name);
      tptx->f_name = NULL;
   }

   tptx->is_ended = 1;
}

int tptx_OpenFile(tptx_type tptx, char *name)
{
   tptx_CloseFile(tptx);

   tptx->f_len = 0L;
   tptx->f_pos = 0L;
   tptx->f_crc = 0UL;
   tptx->f_d_crc = 0UL;
   tptx->f_is_skip = 0;
   tptx->f_start = clock();
   tptx->b_is_dptr_ok = 0;
   tptx->f_date = 0;
   tptx->f_time = 0;
   tptx->fp = NULL;

   tptx->f_name = NULL;
   if ( name != NULL )
   {
      tptx->f_name = (char *)malloc(strlen(name)+1);
      if ( tptx->f_name == NULL )
         return 0;
      strcpy(tptx->f_name, name);

      /* tptx->f_handle = c_open(name, O_RDONLY|O_BINARY, 0); */
      tptx->fp = fopen(name, "rb");
      if ( tptx->fp == NULL )
         return 0;

      fseek(tptx->fp, 0L, SEEK_END);
      tptx->f_len = ftell( tptx->fp );
      fseek(tptx->fp, 0L, SEEK_SET);
      /* tptx->f_len = filelength(fileno(tptx->fp)); */
      _dos_getfileattr( name, &(tptx->f_attr) );
      {
         int handle;
         _dos_open( name, _O_RDONLY, &handle );
         _dos_getftime( handle, &(tptx->f_date), &(tptx->f_time) );
         _dos_close( handle );
      }
   }

   tptx_SetState(tptx, tptx_state_gen_request);
   tptx_ListenECB(tptx);

   return 1;
}


void tptx_Close(tptx_type tptx)
{
   assert(tptx != NULL);

   if ( tptx->f_logname != NULL )
      free(tptx->f_logname);
   if ( tptx->f_logsname != NULL )
      free(tptx->f_logsname);

   tptx_CloseFile(tptx);

   ipx_cancel_ecb(tptx->rx_ecb);
   free(tptx->rx_ecb);
   free(tptx->rx_data);

   tptx_ClosePool(tptx);

   ipx_close_socket(tptx->socket);
   free(tptx);
}

void tptx_SetAux(tptx_type tptx, int (*aux)( int msg, void *data ))
{
   if ( tptx_IsOk(tptx) == 0 )
      return;
   tptx->aux = aux;
   tptx->is_aux = 1;
}

void tptx_DoAux(tptx_type tptx, int msg, void *data)
{
   if ( tptx_IsOk(tptx) == 0 )
      return;
   if ( tptx->is_aux != 0 )
      tptx->aux(msg, data);
}

void tptx_DoPAux(tptx_type tptx, int msg)
{
   tptx->pdata.total       = tptx->f_len;
   tptx->pdata.curr        = tptx->f_pos;
   tptx->pdata.crc         = tptx->f_crc;
   tptx->pdata.path        = tptx->f_name;
   tptx->pdata.file_start  = tptx->f_start;
   tptx->pdata.missed      = 0;

   if ( tptx->pdata.path == NULL )
   {
      tptx->pdata.path     = tptx->f_logsname;
   }
   tptx_DoAux(tptx, msg, (void *)&(tptx->pdata));
}

int tptx_Send(tptx_type tptx, char *phy_name, char *log_name, char *log_sname)
{
   if ( tptx->f_logname != NULL )
   {
      free(tptx->f_logname);
      tptx->f_logname = NULL;
   }
   if ( tptx->f_logsname != NULL )
   {
      free(tptx->f_logsname);
      tptx->f_logsname = NULL;
   }

   tptx->f_logname = (char *)malloc(strlen(log_name)+1);
   if ( tptx->f_logname == NULL )
      return 0;
   strcpy(tptx->f_logname, log_name);

   if ( log_sname == NULL )
      log_sname = log_name;

   tptx->f_logsname = (char *)malloc(strlen(log_sname)+1);
   if ( tptx->f_logsname == NULL )
      return 0;
   strcpy(tptx->f_logsname, log_sname);

   if ( tptx_OpenFile(tptx, phy_name) == 0 )
      return 0;

   tptx->is_ended = 0;

   return 1;
}

size_t tptx_GetExpectedReadSize(tptx_type tptx)
{
   size_t elen;

   if ( tptx->f_len-tptx->f_pos >= (long)tptx->b_pool_size )
      elen = tptx->b_pool_size;
   else
      elen = (size_t)(tptx->f_len-tptx->f_pos);

   return elen;
}

int tptx_Read(tptx_type tptx)
{
   size_t len, i;
   len = 0;

   if ( tptx_IsOk(tptx) == 0 )
      return 0;

   if ( tptx->b_is_dptr_ok != 0 )
      return 1;

   if ( tptx->fp != NULL )
   {
      assert(tptx->f_pos == ftell(tptx->fp));

      len = fread(tptx->b_pool_dptr, 1, tptx->b_pool_size, tptx->fp);
      if (len != tptx_GetExpectedReadSize(tptx))
      {
         static char s[80];
         sprintf(s, "read error at position %ld", tptx->f_pos);
         tptx_Error(tptx, s);
         return 0;
      }
      if ( (tptx->flags & TP_FLAG_IS_DISABLE_CRC) == 0 )
      {
         if ( (tptx->flags & TP_FLAG_IS_CRC32) == 0 )
         {
            for( i = 0; i < len; i += 1024 )
            {
               ipx_dispatch();
               tptx->f_d_crc = (unsigned long)crc16((unsigned short)tptx->f_d_crc,
                  (unsigned char *)tptx->b_pool_dptr+(size_t)i,
                  (len > i+1024) ? 1024 : len-i);
            }
         }
         else
         {
            for( i = 0; i < len; i += 1024 )
            {
               ipx_dispatch();
               tptx->f_d_crc = crc32(tptx->f_d_crc,
                  (unsigned char *)tptx->b_pool_dptr+(size_t)i,
                  (len > i+1024) ? 1024 : len-i);
            }
         }

         /*
         tptx->f_d_crc = crc32(tptx->f_d_crc,
            (unsigned char *)tptx->b_pool_dptr, len);
         */
      }
   }
   tptx->f_read_len = (long)len;
   tptx->b_is_dptr_ok = 1;
   return 1;
}


int tptx_CopyRead(tptx_type tptx)
{
   if ( tptx->b_is_dptr_ok == 0 )
   {
      if ( tptx_Read(tptx) == 0 )
         return 0;
   }
   memcpy(tptx->b_pool_ptr, tptx->b_pool_dptr, tptx->f_read_len);
   tptx->f_crc = tptx->f_d_crc;
   tptx->f_pos += tptx->f_read_len;
   tptx->b_is_dptr_ok = 0;
   return 1;
}

void tptx_InitPool(tptx_type tptx, int b_curr_cnt, short *list)
{
   int i;
   tptx->b_curr_cnt = b_curr_cnt;
   tptx->b_list_cnt = 0;
   if ( list == NULL )
   {
      for( i = 0; i < b_curr_cnt; i++ )
         tptx->b_list_ptr[i] = (short)i;
   }
   else
   {
      for( i = 0; i < b_curr_cnt; i++ )
         tptx->b_list_ptr[i] = list[i];
   }
}

void tptx_CopyMemoryFromPool(tptx_type tptx, int no, void *adr, size_t len)
{
   assert(no < tptx->b_cnt);
   memcpy(adr, tptx->b_pool_ptr+no*tptx->b_len, len);
}

void tptx_SendECB(tptx_type tptx, int no)
{
   tp_set_blk_ver(tptx->tx_data[no], TP_VERSION);

   if ( tptx->is_adr_known == 0 )
   {
      ipx_fill_send_ecb(
         tptx->tx_ecb[no],
         ipx_get_header(NULL, tptx->socket, tptx->socket),
         tptx->tx_data[no],
         tptx->b_len+TP_BLK_INFO_SIZE);
   }
   else
   {
       ipx_fill_send_ecb(
         tptx->tx_ecb[no],
         ipx_get_header(&(tptx->adr), tptx->socket, tptx->socket),
         tptx->tx_data[no],
         tptx->b_len+TP_BLK_INFO_SIZE);
   }

   if ( ipx_send_ecb(tptx->tx_ecb[no]) == 0 )
   {
      static char s[80];
      sprintf(s, "cannot send msg %d", tp_get_blk_id(tptx->tx_data[no]) );
      tptx_Error(tptx, s);
   }
}

void tptx_Error(tptx_type tptx, char *s)
{
   fprintf(stderr, "\n");
   fprintf(stderr, TPTX_ID_STR "%s\n", s);
   tptx->is_ended = 2;
   tptx_SetState(tptx, tptx_state_none);

   if ( tptx->is_adr_known != 0 )
   {
      clock_t c1 = clock() + CLOCKS_PER_SEC;
      long cnt = 4L;
      while ( clock() < c1 && cnt > 0L )
      {
         clock_t c2;

         ipx_dispatch();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -