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

📄 tprx.c

📁 一个使用IPX协议在两台机器间传送文件的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
         /* printf("dir: restore: %s\n", cwd); */
         if ( c_set_path(cwd) != 0 )
         {
            printf("can not change to path '%s'\n", cwd);
            return;
         }
      }
      else
      {

         /* in the next few lines, the current dir will be stored */
         /* and restored... this is probably useless, because */
         /* the directory is already created by the lines above */
         /* But: It does not slow down the transfer process */

         _splitpath( tprx->f_name, drive, dirs, fname, ext );
         /* strcpy(npath, drive); */
         strcpy(npath, "");
         strcat(npath, dirs);
         strcat(fname, ext);

         /* create the path, if it does not exist directory */
         cwd = c_getcwd();
         if ( cwd == NULL )
         {
            printf("can not get current working directory\n");
            return;
         }
         /* printf("file: cwd: %s\n", cwd); */
         if ( c_create_path(npath) != 0 )
         {
            printf("can not create path '%s'\n", npath);
            return;
         }

         /* printf("destpath: %s\n", npath); */
         if ( c_set_path(cwd) != 0 )
         {
            printf("can not change to path '%s'\n", cwd);
            return;
         }

         /* create the file */
         tprx->f_handle = c_open(tprx->f_name, O_CREAT|O_RDWR|O_BINARY, S_IWRITE);
         if ( tprx->f_handle < 0 )
         {
            printf("can not create '%s'\n", tprx->f_name);
         }
      }
   }
   else
   {
      printf("test mode: file/dir '%s' is not written to disk.\n", tprx->f_name);
   }
   tprx->f_start = clock();
}

void tprx_Error(tprx_type tprx, char *s, int is_fatal)
{
   fprintf(stderr, "\n");
   fprintf(stderr, TPRX_ID_STR "%s\n", s);
   if ( tprx->is_break_enable != 0 )
      tprx->is_ended = 1;
   if ( is_fatal != 0 )
      tprx->is_ended = 1;
   tprx_SetState(tprx, tprx_state_none);

   if ( tprx->is_adr_known != 0 )
   {
      clock_t c1 = clock() + CLOCKS_PER_SEC;
      long cnt = 4L;
      while ( clock() < c1 && cnt > 0L )
      {
         clock_t c2;
         ipx_dispatch();
         if ( tprx->tx_ecb->inuse == 0 )
         {
            tp_set_blk_id(tprx->tx_data, TP_ID_ERROR);
            tp_set_blk_ver(tprx->tx_data, TP_VERSION);
            strcpy(tp_get_blk_data_adr(tprx->tx_data), s);

            ipx_fill_send_ecb(
               tprx->tx_ecb,
               ipx_get_header(&(tprx->adr), tprx->socket, tprx->socket),
               tprx->tx_data,
               tprx->b_len+TP_BLK_INFO_SIZE);

            ipx_send_ecb(tprx->tx_ecb);
            cnt--;
         }
         c2 = clock() + CLOCKS_PER_SEC/8;
         while ( clock() < c2  )
            ;
      }
   }
}

size_t tprx_GetWriteSize(tprx_type tprx)
{
   size_t elen;

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

   return elen;
}

int tprx_Write(tprx_type tprx)
{
   size_t len, i;
   len = tprx_GetWriteSize(tprx);

   if ( (tprx->flags & TP_FLAG_IS_DISABLE_CRC) == 0 )
   {
      if ( (tprx->flags & TP_FLAG_IS_CRC32) == 0 )
      {
         for( i = 0; i < len; i += 1024 )
         {
            ipx_dispatch();
            tprx->f_crc = (unsigned long)crc16((unsigned short)tprx->f_crc,
               (unsigned char *)tprx->b_pool_ptr+(size_t)i,
               (len > i+1024) ? 1024 : len-i);
         }
      }
      else
      {
         for( i = 0; i < len; i += 1024 )
         {
            ipx_dispatch();
            tprx->f_crc = crc32(tprx->f_crc,
               (unsigned char *)tprx->b_pool_ptr+(size_t)i,
               (len > i+1024) ? 1024 : len-i);
         }
      }
      if ( tprx->f_crc != tprx->f_remote_crc )
      {
         tprx_Error(tprx, "crc error", 0);
         return 0;
      }
      /*
      tprx->f_crc = crc32(tprx->f_crc,
         (unsigned char *)tprx->b_pool_ptr, len);
      */
   }
   if ( (tprx->flags & TP_FLAG_IS_TEST_MODE) == 0 )
   {
      if ( tprx->f_is_write_data != 0 && tprx->f_handle >= 0 )
      {
         if ( len > 0 )
         {
            if ( c_write(tprx->f_handle, tprx->b_pool_ptr, (long)(unsigned long)len) != (long)(unsigned long)len )
            {
               tprx_Error(tprx, "write error", 0);
               return 0;
            }
         }
      }
   }
   tprx->f_pos += (long)len;
   tprx->f_is_write_data = 0;
   return 1;
}

void tprx_CloseFile(tprx_type tprx)
{
   if ( (tprx->flags & TP_FLAG_IS_TEST_MODE) == 0 )
   {
      if ( tprx->f_handle >= 0 )
      {
         int handle;
         c_close(tprx->f_handle);
         tprx->f_handle = -1;
         _dos_setfileattr( tprx->f_name, (tprx->f_attr) );
         _dos_open( tprx->f_name, _O_RDONLY, &handle );
         _dos_setftime( handle, tprx->f_date, tprx->f_time );
         _dos_close( handle );
      }
   }
}

int tprx_ListenECB(tprx_type tprx, int i)
{
   if ( tprx->rx_ecb[i]->inuse != 0 )
   {
      return 1;
   }
   if ( ipx_fill_receive_ecb(
      tprx->rx_ecb[i],
      tprx->socket,
      tprx->rx_data[i],
      tprx->b_len+TP_BLK_INFO_SIZE) == NULL )
   {
      tprx_Error(tprx, "cannot fill receive ecb", 1);
      return 0;
   }
   if ( ipx_listen_ecb(tprx->rx_ecb[i]) == 0 )
   {
      tprx_Error(tprx, "cannot listen to ecb", 1);
      return 0;
   }
   return 1;
}

int tprx_ListenAll(tprx_type tprx)
{
   int i;
   for( i = 0; i < tprx->rx_cnt; i++ )
   {
      if ( tprx_ListenECB(tprx, i) == 0 )
         return 0;
   }
   return 1;
}

int tprx_ListenExcept(tprx_type tprx, int id1, int id2)
{
   int i;
   for( i = 0; i < tprx->rx_cnt; i++ )
   {
      if ( tprx->rx_ecb[i]->inuse == 0 )
      {
         if ( tprx->rx_ecb[i]->cc == 0 )
         {
            if ( tp_ecb_get_id(tprx->rx_ecb[i]) == TP_ID_ERROR )
            {
               static char s[80];
               sprintf(s, "remote error: '%s'", tp_ecb_get_data_adr(tprx->rx_ecb[i]));
               tprx_Error(tprx, s, 0);
               tprx_ListenECB(tprx, i);
               return 0;
            }
            if ( tp_ecb_get_id(tprx->rx_ecb[i]) == TP_ID_TERMINATE )
            {
               static char s[80];
               sprintf(s, "received kill signal");
               tprx_Error(tprx, s, 1);
               tprx_ListenECB(tprx, i);
               return 0;
            }
            if (tp_ecb_get_id(tprx->rx_ecb[i]) != id1 &&
                tp_ecb_get_id(tprx->rx_ecb[i]) != id2)
            {
               if ( tprx_ListenECB(tprx, i) == 0 )
                  return 0;
            }
         }
         else
         {
            printf( TPRX_ID_STR "receiver warning: %s\n", 
               ipx_get_ecb_cc_string(tprx->rx_ecb[i]));
            if ( tprx_ListenECB(tprx, i) == 0 )
               return 0;
         }
      }
   }
   return 1;
}


/*
   search for a received block with identifier id
   return index to rx_ecb array or -1, if id not found
*/
int tprx_SearchId(tprx_type tprx, short id)
{
   int i;
   assert(tprx != NULL);
   for( i = 0; i < tprx->rx_cnt; i++ )
   {
      if ( tprx->rx_ecb[i]->inuse == 0 )
      {
         if ( tprx->rx_ecb[i]->cc != 0 )
         {
            tprx_Error(tprx, ipx_get_ecb_cc_string(tprx->rx_ecb[i]), 0);
            tprx_ListenECB(tprx, i);
         }
         else if (tp_ecb_get_id(tprx->rx_ecb[i]) == id)
         {
            if ( tp_ecb_get_ver(tprx->rx_ecb[i]) != TP_VERSION )
            {
               tprx_Error(tprx, "wrong version", 0);
               tprx_ListenECB(tprx, i);
            }
            else
            {
               return i;
            }
         }
      }
   }
   return -1;
}

/*
   search for any received block
   return index to rx_ecb array or -1, if found
*/
int tprx_SearchAny(tprx_type tprx)
{
   int i;
   assert(tprx != NULL);
   for( i = 0; i < tprx->rx_cnt; i++ )
   {
      if ( tprx->rx_ecb[i]->inuse == 0 )
      {
         if ( tprx->rx_ecb[i]->cc != 0 )
         {
            tprx_Error(tprx, ipx_get_ecb_cc_string(tprx->rx_ecb[i]), 0);
            tprx_ListenECB(tprx, i);
         }
         else
         {
            if ( tp_ecb_get_ver(tprx->rx_ecb[i]) != TP_VERSION )
            {
               tprx_Error(tprx, "wrong version", 0);
               tprx_ListenECB(tprx, i);
            }
            else
            {
               return i;
            }
         }
      }
   }
   return -1;
}



int tprx_ListenAndSearch(tprx_type tprx, int id)
{
   tprx_ListenExcept(tprx, id, TP_ID_NONE);
   return tprx_SearchId(tprx, id);
}

void tprx_SendECB(tprx_type tprx)
{
   tp_set_blk_ver(tprx->tx_data, TP_VERSION);

   ipx_fill_send_ecb(
      tprx->tx_ecb,
      ipx_get_header(&(tprx->adr), tprx->socket, tprx->socket),
      tprx->tx_data,
      tprx->b_len+TP_BLK_INFO_SIZE);

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

void tprx_WaitSend(tprx_type tprx,
   void (*next_state)(tprx_type tprx),
   void (*repeated_state)(tprx_type tprx),
   clock_t delay)
{
   if ( tprx->tx_ecb->inuse == 0 )
   {
      if ( tprx->tx_ecb->cc != 0 )
      {
         tprx_Error(tprx, ipx_get_ecb_cc_string(tprx->tx_ecb), 1);
      }
      else
      {
         tprx->clock_dest = clock()+delay;
         tprx_SetRepeatedState(tprx, repeated_state);
         tprx_SetState(tprx, next_state);
      }
   }
}

int tprx_CheckTime(tprx_type tprx)
{
   if ( tprx->clock_dest < clock() )
   {
      tprx_SetState(tprx, tprx_GetRepeatedState(tprx));
      return 0;
   }
   return 1;
}

int tprx_Dispatch(tprx_type tprx)
{
   ipx_dispatch();
   if( tprx->is_ended != 0 )
      return 1;
   tprx->state_fn(tprx);
   if ( tprx->state_fn != tprx_state_user_check )
   {
      if ( kbhit() != 0 )
      {
         if ( getch() == 27 )
         {
            tprx_Error(tprx, "user break", 1);
         }
      }
   }
   return tprx->is_ended;
}


/* - - - - - state functions - - - - - - - - - - - - - - - - - - - - - - - */

void tprx_state_none(tprx_type tprx)
{
   int pos;

   pos = tprx_ListenAndSearch(tprx, TP_ID_REQUEST);
   if ( pos >= 0 )
   {
      tp_request request;
      request = (tp_request)tp_ecb_get_data_adr(tprx->rx_ecb[pos]);
      tprx->adr = request->adr;
      tprx->is_adr_known = 1;
      tprx->f_len = request->file_size;

      if ( (tprx->flags & TP_FLAG_IS_LFN) == 0 )
         request->flags &= ~TP_FLAG_IS_LFN;

      tprx->flags = (tprx->flags&TP_FLAG_IS_LFN)|request->flags;
      tprx->f_attr = request->attr;
      tprx->f_time = request->time;
      tprx->f_date = request->date;

⌨️ 快捷键说明

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