/*======================================================================*/
long ConfirmFile( char *filename, char *prompt )
{
 /*** See if the file exists and if not, prompt the user for some input.   ***/

    while (! CheckExist( filename )) {
	printf(" The files %s does not exist\n"
	       " enter q to quit\n", filename);
	ReadFilename( prompt, filename );
	if ( filename[0] == 'q' )
	    return(ERR_MISC);
    }
    return( 0 );
}
Beispiel #2
0
int btContent::InitialFromMI(const char *metainfo_fname,const char *saveas)
{
#define ERR_RETURN()	{if(b) delete []b; return -1;}
  unsigned char *ptr = m_shake_buffer;
  char *b;
  const char *s;
  size_t flen, q, r;

  b = _file2mem(metainfo_fname,&flen);
  if ( !b ) return -1;

  // announce
  if( !meta_str("announce",&s,&r) ) ERR_RETURN();
  if( r > MAXPATHLEN ) ERR_RETURN();
  m_announce = new char [r + 1];
  memcpy(m_announce, s, r);
  m_announce[r] = '\0';
  
  // infohash
  if( !(r = meta_pos("info")) ) ERR_RETURN();
  if( !(q = decode_dict(b + r, flen - r, (char *) 0)) ) ERR_RETURN();
  Sha1(b + r, q, m_shake_buffer + 28);

  if( meta_int("creation date",&r)) m_create_date = (time_t) r;
 
  // hash table
  if( !meta_str("info|pieces",&s,&m_hashtable_length) ||
      m_hashtable_length % 20 != 0) ERR_RETURN();

  m_hash_table = new unsigned char[m_hashtable_length];

#ifndef WINDOWS
  if( !m_hash_table ) ERR_RETURN();
#endif
  memcpy(m_hash_table, s, m_hashtable_length);

  if(!meta_int("info|piece length",&m_piece_length)) ERR_RETURN();
  m_npieces = m_hashtable_length / 20;

  if( m_piece_length > cfg_max_slice_size * cfg_req_queue_length ){
    fprintf(stderr,"error, piece length too long[%u]. please recomplie CTorrent with a larger cfg_max_slice_size in <btconfig.h>.\n", m_piece_length);
    ERR_RETURN();
  }

  if( m_piece_length < cfg_req_slice_size )
    cfg_req_slice_size = m_piece_length;
  else{
    for( ;(m_piece_length / cfg_req_slice_size) >= cfg_req_queue_length; ){
      cfg_req_slice_size *= 2;
      if( cfg_req_slice_size > cfg_max_slice_size ) ERR_RETURN();
    }
  }
  
  if( m_btfiles.BuildFromMI(b, flen, saveas) < 0) ERR_RETURN();

  delete []b;
  PrintOut();
  
  if( arg_flg_exam_only ) return 0;

  if( ( r = m_btfiles.CreateFiles() ) < 0) ERR_RETURN();

  global_piece_buffer = new char[m_piece_length];
#ifndef WINDOWS
  if( !global_piece_buffer ) ERR_RETURN();
#endif

  pBF = new BitField(m_npieces);
#ifndef WINDOWS
  if( !pBF ) ERR_RETURN();
#endif

  m_left_bytes = m_btfiles.GetTotalLength() / m_piece_length;
  if( m_btfiles.GetTotalLength() % m_piece_length ) m_left_bytes++;
  if( m_left_bytes != m_npieces ) ERR_RETURN();
  
  m_left_bytes = m_btfiles.GetTotalLength();

  if( arg_bitfield_file ){

    if( !arg_flg_check_only ){
      if( pBF->SetReferFile(arg_bitfield_file) >= 0){
	size_t idx;
	r = 0;
	for( idx = 0; idx < m_npieces; idx++ )
	  if( pBF->IsSet(idx) ) m_left_bytes -= GetPieceLength(idx);
      }
      else{
	fprintf(stderr,"warn, couldn't set bit field refer file %s.\n",arg_bitfield_file);
      }
    }
    
    if( r ) CheckExist();
    
  }else if( arg_flg_force_seed_mode ){
    pBF->SetAll();
    m_left_bytes = 0;
  }else if( r ){
    CheckExist();
  }
  
  printf("Already/Total: %u/%u\n",pBF->Count(),m_npieces);
  
  if( arg_flg_check_only ){
    if( arg_bitfield_file ) pBF->WriteToFile(arg_bitfield_file);
    exit(1);
  }
  
  CacheConfigure();

  *ptr = (unsigned char) 19; ptr++; // protocol string length
  memcpy(ptr,"BitTorrent protocol",19); ptr += 19; //  protocol string
  memset(ptr,0,8);		// reserved set zero.

  {				// peer id
    int i;
    ptr = m_shake_buffer + 48;
    for( i = 0; i < 20; i++,ptr++) *ptr = (unsigned char)(rand() & 0xFF);
  }

  return 0;
}