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

📄 tptx.c

📁 一个使用IPX协议在两台机器间传送文件的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
         c2 = clock() + CLOCKS_PER_SEC;

         while ( tptx->tx_ecb[0]->inuse != 0 && clock() < c2 )
            ipx_dispatch();

         tp_set_blk_id(tptx->tx_data[0], TP_ID_ERROR);
         tp_set_blk_ver(tptx->tx_data[0], TP_VERSION);
         strcpy(tp_get_blk_data_adr(tptx->tx_data[0]), s);

         ipx_fill_send_ecb(
            tptx->tx_ecb[0],
            ipx_get_header(&(tptx->adr), tptx->socket, tptx->socket),
            tptx->tx_data[0],
            tptx->b_len+TP_BLK_INFO_SIZE);

         ipx_send_ecb(tptx->tx_ecb[0]);
         if ( cnt >= 0L )
            cnt--;

         c2 = clock() + CLOCKS_PER_SEC/8;
         while ( clock() < c2 )
            ;
      }
   }
}

void tptx_TerminateReceiver(tptx_type tptx)
{
   tptx_SetState(tptx, tptx_state_none);

   {
      clock_t c1;
      long cnt = 5L;
      c1 = clock() + CLOCKS_PER_SEC*2;
      while ( clock() < c1 && cnt > 0L )
      {
         clock_t c2;

         ipx_dispatch();
         c2 = clock() + CLOCKS_PER_SEC;

         while ( tptx->tx_ecb[0]->inuse != 0 && clock() < c2 )
            ipx_dispatch();

         tp_set_blk_id(tptx->tx_data[0], TP_ID_TERMINATE);
         tp_set_blk_ver(tptx->tx_data[0], TP_VERSION);

         ipx_fill_send_ecb(
            tptx->tx_ecb[0],
            ipx_get_header(NULL, tptx->socket, tptx->socket),
            tptx->tx_data[0],
            tptx->b_len+TP_BLK_INFO_SIZE);

         ipx_send_ecb(tptx->tx_ecb[0]);
         if ( cnt >= 0L )
            cnt--;

         c2 = clock() + CLOCKS_PER_SEC/8;
         while ( clock() < c2 )
            ;
      }
   }
}



int tptx_ListenECB(tptx_type tptx)
{
   if ( tptx->rx_ecb->inuse != 0 )
   {
      return 1;
   }
   if ( ipx_fill_receive_ecb(
      tptx->rx_ecb,
      tptx->socket,
      tptx->rx_data,
      tptx->b_len+TP_BLK_INFO_SIZE) == NULL )
   {
      tptx_Error(tptx, "cannot fill receive ecb");
      return 0;
   }
   if ( ipx_listen_ecb(tptx->rx_ecb) == 0 )
   {
      tptx_Error(tptx, "cannot listen to ecb");
      return 0;
   }
   return 1;
}

int tptx_ListenAndSearch(tptx_type tptx, short id1, short id2)
{
   if ( tptx->rx_ecb->inuse == 0 )
   {
      /* printf("inuse: %d   \r", tptx->rx_ecb->inuse); */
      if ( tptx->rx_ecb->cc == 0 )
      {
         if (tp_ecb_get_id(tptx->rx_ecb) == TP_ID_ERROR )
         {
            static char s[80];
            sprintf(s, "remote error: '%s'", tp_ecb_get_data_adr(tptx->rx_ecb));
            tptx_Error(tptx, s);
            return 0;
         }
         if (tp_ecb_get_id(tptx->rx_ecb) != id1 &&
             tp_ecb_get_id(tptx->rx_ecb) != id2 )
         {
            if ( tptx_ListenECB(tptx) == 0 )
               return 0;
         }
         else
         {
            return 1;
         }
      }
      else
      {
         printf(TPTX_ID_STR "receive warning: %s\n", 
            ipx_get_ecb_cc_string(tptx->rx_ecb));
         if ( tptx_ListenECB(tptx) == 0 )
            return 0;
      }
   }
   return 0;
}

void tptx_WaitSend(tptx_type tptx,
   int no,
   void (*next_state)(tptx_type tptx),
   void (*repeated_state)(tptx_type tptx),
   clock_t delay)
{
   if ( tptx->tx_ecb[no]->inuse == 0 )
   {
      if ( tptx->tx_ecb[no]->cc != 0 )
      {
         tptx_Error(tptx, ipx_get_ecb_cc_string(tptx->tx_ecb[0]));
      }
      else
      {
         tptx->clock_dest = clock()+delay;
         tptx_SetRepeatedState(tptx, repeated_state);
         tptx_SetState(tptx, next_state);
      }
   }
}

int tptx_CheckTime(tptx_type tptx)
{
   if ( tptx->clock_dest < clock() )
   {
      tptx_SetState(tptx, tptx_GetRepeatedState(tptx));
      return 0;
   }
   return 1;
}

int tptx_Dispatch(tptx_type tptx)
{
   ipx_dispatch();
   if ( tptx->is_ended != 0 )
      return tptx->is_ended;
   tptx->state_fn(tptx);
   if ( tptx->state_fn != tptx_state_user_check )
   {
      if ( kbhit() != 0 )
      {
         if ( getch() == 27 )
         {
            tptx_Error(tptx, "user break");
         }
      }
   }
   return tptx->is_ended;
}

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

void tptx_state_none(tptx_type tptx)
{
   tptx_ListenECB(tptx);
}

void tptx_state_gen_request(tptx_type tptx)
{
   tp_request request;

   tp_debug_out("tptx_state_gen_request");

   request = (tp_request)tp_get_blk_data_adr(tptx->tx_data[0]);

   request->adr = *ipx_get_local_net_number();
   request->file_size = tptx->f_len;
   /* request->flags = 0; */
   request->flags = tptx->flags;
   if ( tptx->f_name == NULL )
      request->flags |= TP_FLAG_IS_DIR;
   request->attr = tptx->f_attr;
   request->time = tptx->f_time;
   request->date = tptx->f_date;
   request->short_name_offset = (unsigned)(strlen(tptx->f_logname)+1);

   if ( sizeof(tp_request_struct)+(size_t)request->short_name_offset+1 > tptx->b_len )
   {
      tptx_Error(tptx, "path too long");
      return;
   }

   strcpy(
      tp_get_blk_data_adr(tptx->tx_data[0])+sizeof(tp_request_struct),
      tptx->f_logname);
   strcpy(
      tp_get_blk_data_adr(tptx->tx_data[0])+sizeof(tp_request_struct)
      +(size_t)request->short_name_offset,
      tptx->f_logsname);
   /*
   printf("lfn:%s normal:%s", tptx->f_logname, tptx->f_logsname);
   */

   tp_set_blk_id(tptx->tx_data[0], TP_ID_REQUEST);

   tptx_SendECB(tptx, 0);

   tptx_SetState(tptx, tptx_state_chk_request);
}

void tptx_state_chk_request(tptx_type tptx)
{
   tp_debug_out("tptx_state_chk_request");

   tptx_WaitSend(tptx, 0,
      tptx_state_wait_ack_request,
      tptx_state_gen_request,
      tptx->large_delay);
}

void tptx_state_wait_ack_request(tptx_type tptx)
{
   /* tp_debug_out("tptx_state_wait_ack_request"); */

   if ( tptx_CheckTime(tptx) == 0 )
      return;
   if ( tptx_ListenAndSearch(tptx, TP_ID_ACK_REQUEST, TP_ID_NONE) != 0 )
   {
      tp_ack_request ack_request;
      ack_request = (tp_ack_request)tp_ecb_get_data_adr(tptx->rx_ecb);
      tptx->adr = ack_request->adr;
      tptx->is_adr_known = 1;
      tptx_ListenECB(tptx);
      if ( (ack_request->flags & TP_FLAG_IS_LFN) == 0 )
         tptx->flags &= ~TP_FLAG_IS_LFN;
         
      if ( ack_request->exist != 0 &&
          (tptx->flags & TP_FLAG_IS_NO_USER_CHECK) == 0 )
      {
         printf("remote file '%s' exists, overwrite (y,n,a)? ",
            tptx->f_logname);
         fflush(stdout);
         tptx_SetState(tptx, tptx_state_user_check);
      }
      else
      {
         tptx_DoPAux(tptx, TP_MSG_PSTART);
         tptx_SetState(tptx, tptx_state_gen_file_start);
      }
   }
}

void tptx_state_user_check(tptx_type tptx)
{
   if ( kbhit() != 0 )
   {
      int c = getch();
      switch(c)
      {
         case 'n':
         case 'N':
            printf("%c\n", c);
            tptx->f_is_skip = 1;
            tptx_SetState(tptx, tptx_state_gen_file_end);
            return;
         case 'a':
         case 'A':
            printf("%c\n", c);
            tptx_SetFlag(tptx, TP_FLAG_IS_NO_USER_CHECK);
            tptx_DoPAux(tptx, TP_MSG_PSTART);
            tptx_SetState(tptx, tptx_state_gen_file_start);
            return;
         case 'y':
         case 'Y':
         case 'j':
         case 'J':
            printf("%c\n", c);
            tptx_DoPAux(tptx, TP_MSG_PSTART);
            tptx_SetState(tptx, tptx_state_gen_file_start);
            return;
         case 27:
            tptx_Error(tptx, "user escape");
            return;
      }
   }
   if ( tptx_ListenAndSearch(tptx, TP_ID_FILE_START, TP_ID_NONE) != 0 )
   {
      tp_file_start file_start;
      file_start = (tp_file_start)tp_get_blk_data_adr(tptx->rx_data);
      tptx->f_is_skip = file_start->is_skip_file;
      tptx->flags = file_start->flags;
      tptx_ListenECB(tptx);
      if ( tptx->f_is_skip != 0 )
      {
         printf("n\n");
         tptx_SetState(tptx, tptx_state_gen_file_end);
      }
      else
      {
         printf("y/a\n");
         tptx_DoPAux(tptx, TP_MSG_PSTART);
         tptx_SetState(tptx, tptx_state_gen_file_start);
      }
   }

}

void tptx_state_gen_file_start(tptx_type tptx)
{
   tp_file_start file_start;

   tp_debug_out("tptx_state_gen_file_start");

   file_start = (tp_file_start)tp_get_blk_data_adr(tptx->tx_data[0]);
   file_start->is_skip_file = 0;
   file_start->flags = tptx->flags;

   tp_set_blk_id(tptx->tx_data[0], TP_ID_FILE_START);
   tptx_SendECB(tptx, 0);

   tptx_SetState(tptx, tptx_state_chk_file_start);
}

void tptx_state_chk_file_start(tptx_type tptx)
{
   tp_debug_out("tptx_state_chk_file_start");

   tptx_WaitSend(tptx, 0,
      tptx_state_wait_ack_file_start,
      tptx_state_gen_file_start,
      tptx->small_delay);
}

void tptx_state_wait_ack_file_start(tptx_type tptx)
{
   /* tp_debug_out("tptx_state_wait_ack_file_start"); */

   if ( tptx_CheckTime(tptx) == 0 )
      return;
   if ( tptx_ListenAndSearch(tptx, TP_ID_ACK_FILE_START, TP_ID_NONE) != 0 )
   {
      tptx->f_start = clock();
      tptx_ListenECB(tptx);
      tptx_SetState(tptx, tptx_state_gen_block_start);
   }
}

void tptx_state_gen_block_start(tptx_type tptx)
{
   tp_block_start block_start;

   tp_debug_out("tptx_state_gen_block_start");
   /* printf("filepos: %ld\n", tptx->f_pos); */
   tptx_DoPAux(tptx, TP_MSG_PDATA);


   block_start = (tp_block_start)tp_get_blk_data_adr(tptx->tx_data[0]);
   block_start->cnt =
      (tptx_GetExpectedReadSize(tptx)+tptx->b_len-1)/tptx->b_len;

   tp_set_blk_id(tptx->tx_data[0], TP_ID_BLOCK_START);
   tptx_SendECB(tptx, 0);

   tptx_SetState(tptx, tptx_state_chk_block_start);
}

void tptx_state_chk_block_start(tptx_type tptx)
{
   tp_debug_out("tptx_state_chk_block_start");

   tptx_WaitSend(tptx, 0,
      tptx_state_wait_ack_block_start,
      tptx_state_gen_block_start,
      tptx->small_delay);
}

void tptx_state_wait_ack_block_start(tptx_type tptx)
{
   tp_debug_out("tptx_state_wait_ack_block_start");

   if ( tptx_CheckTime(tptx) == 0 )
      return;
   if ( tptx_ListenAndSearch(tptx, TP_ID_ACK_BLOCK_START, TP_ID_NONE) != 0 )
   {
      tptx_ListenECB(tptx);
      tptx_CopyRead(tptx);
      tptx_InitPool(tptx,
         (tptx_GetExpectedReadSize(tptx)+tptx->b_len-1)/tptx->b_len,
         NULL);
      tptx_SetState(tptx, tptx_state_gen_data);
   }
}

void tptx_state_gen_data(tptx_type tptx)
{
   /* tp_debug_out("tptx_state_gen_data"); */

   if ( tptx->b_list_cnt < tptx->b_curr_cnt )
   {
      tp_data data;

      /*
      printf("(%d,%d/%d)", (int)tptx->b_list_ptr[tptx->b_list_cnt],
         tptx->b_list_cnt, tptx->b_curr_cnt);
      */

      data = (tp_data)tp_get_blk_data_adr(tptx->tx_data[tptx->b_list_cnt]);
      data->no = tptx->b_list_ptr[tptx->b_list_cnt];
      if ( tptx->b_pool_size-(size_t)(((size_t)data->no)*tptx->b_len) <
               tptx->b_len )
         data->len = tptx->b_pool_size-(size_t)(((size_t)data->no)*tptx->b_len);
      else
         data->len = tptx->b_len;
      tptx_CopyMemoryFromPool(tptx,
         data->no,
         tp_get_blk_data_adr(tptx->tx_data[tptx->b_list_cnt])+sizeof(tp_data_struct),
         data->len);

      tp_set_blk_id(tptx->tx_data[tptx->b_list_cnt], TP_ID_DATA);
      tptx_SendECB(tptx, tptx->b_list_cnt);
      tptx->b_list_cnt++;
   }
   else
   {
      tptx_SetState(tptx, tptx_state_chk_data);
      tptx_Read(tptx);
   }
}

void tptx_state_chk_data(tptx_type tptx)
{
   int i, c;

   /* tp_debug_out("tptx_state_chk_data"); */

   c = 0;
   for( i = 0; i < tptx->b_curr_cnt; i++ )
   {
      if ( tptx->tx_ecb[i]->inuse == 0 )
      {
         if ( tptx->tx_ecb[i]->cc != 0 )
         {
            tptx_Error(tptx, ipx_get_ecb_cc_string(tptx->tx_ecb[0]));
         }
         else
         {
            c++;
         }
      }
   }
   if ( c == tptx->b_curr_cnt )
   {
      tptx_SetState(tptx, tptx_state_gen_block_end);
   }
}

void tptx_state_gen_block_end(tptx_type tptx)
{
   tp_block_end block_end;

   tp_debug_out("tptx_state_gen_block_end");

   block_end = (tp_block_end)tp_get_blk_data_adr(tptx->tx_data[0]);
   block_end->crc = tptx->f_crc;

   tp_set_blk_id(tptx->tx_data[0], TP_ID_BLOCK_END);
   tptx_SendECB(tptx, 0);

   tptx_SetState(tptx, tptx_state_chk_block_end);
}

void tptx_state_chk_block_end(tptx_type tptx)
{
   tp_debug_out("tptx_state_chk_block_end");

   tptx_WaitSend(tptx, 0,
      tptx_state_wait_ack_block_end,
      tptx_state_gen_block_end,
      tptx->small_delay);
}

void tptx_state_wait_ack_block_end(tptx_type tptx)
{
   /* tp_debug_out("tptx_state_wait_ack_block_end"); */

   if ( tptx_CheckTime(tptx) == 0 )
      return;
   if ( tptx_ListenAndSearch(tptx, TP_ID_ACK_BLOCK_END, TP_ID_MISSED_BLOCKS) != 0 )
   {
      if ( tp_ecb_get_id(tptx->rx_ecb) == TP_ID_MISSED_BLOCKS )
      {
         tp_missed_blocks missed_blocks;
         missed_blocks = (tp_missed_blocks)tp_ecb_get_data_adr(tptx->rx_ecb);
         /* printf("missed: %d\n", (int)missed_blocks->cnt); */
         tptx_InitPool(tptx,
            missed_blocks->cnt,
            (short *)(tp_ecb_get_data_adr(tptx->rx_ecb)+
               sizeof(tp_missed_blocks_struct)));
         tptx_SetState(tptx, tptx_state_gen_data);
         tptx_ListenECB(tptx);
         return;
      }
      else if ( tp_ecb_get_id(tptx->rx_ecb) == TP_ID_ACK_BLOCK_END )
      {
         if ( tptx->f_pos >= tptx->f_len )
         {
            tptx_SetState(tptx, tptx_state_gen_file_end);
         }
         else
         {
            tptx_SetState(tptx, tptx_state_gen_block_start);
         }
         tptx_ListenECB(tptx);
      }
   }
}

void tptx_state_gen_file_end(tptx_type tptx)
{
   tp_debug_out("tptx_state_gen_file_end");

   tp_set_blk_id(tptx->tx_data[0], TP_ID_FILE_END);
   tptx_SendECB(tptx, 0);
   tptx_SetState(tptx, tptx_state_chk_file_end);
}

void tptx_state_chk_file_end(tptx_type tptx)
{
   tp_debug_out("tptx_state_chk_file_end");

   tptx_WaitSend(tptx, 0,
      tptx_state_wait_ack_file_end,
      tptx_state_gen_file_end,
      tptx->large_delay);
}

void tptx_state_wait_ack_file_end(tptx_type tptx)
{
   tp_debug_out("tptx_state_wait_ack_file_end");

   if ( tptx_CheckTime(tptx) == 0 )
      return;
   if ( tptx_ListenAndSearch(tptx, TP_ID_ACK_FILE_END, TP_ID_NONE) != 0 )
   {
      if ( tptx->f_is_skip == 0 )
      {
         tptx_DoPAux(tptx, TP_MSG_PDATA);
         tptx_DoPAux(tptx, TP_MSG_PEND);
      }
      tptx_CloseFile(tptx);
      tptx_ListenECB(tptx);
      tptx_SetState(tptx, tptx_state_none);
   }
}

⌨️ 快捷键说明

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