pike.git / lib / modules / Protocols.pmod / Bittorrent.pmod / Torrent.pike

version» Context lines:

pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:50:   //! t->start_update_tracker();   //!   //! // Finally, start the download:   //! t->start_download();   //!   //! return -1;   //! }   //! @endcode      #pike __REAL_VERSION__ + #require constant(Crypto.SHA1)    - #if constant(Crypto.SHA1) -  +    import .Bencoding;      Protocols.HTTP.Session http=Protocols.HTTP.Session();      mapping(string:int|array|string|mapping) metainfo;   mapping(string:int|array|string|mapping) info; // info part of metainfo      array(int(0..1)) file_got=0;   multiset(int) file_want;   int total_bytes;
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:127: Inside #if constant(Crypto.SHA1)
  //! Called if there is a protocol error.   function(string,mixed...:void|mixed) warning=lambda() {};         Protocols.DNS.async_client dns_async=Protocols.DNS.async_client();         //! Loads the metainfo from a file.   void load_metainfo(string filename)   { -  string s=Stdio.read_file(filename); -  if (!s) -  error("Failed to read metainfo file %O: %s\n", -  filename,strerror(errno())); -  catch { -  s = utf8_to_string(s); -  }; +  Stdio.Buffer buf=Stdio.Buffer(); +  buf->input_from(Stdio.File(filename));    mixed err=catch { -  decode_metainfo(s); +  decode_metainfo(buf);    };    if (!err) return;       err[0]=sprintf("Failed to read metainfo file %O:\n",filename)+err[0];    throw(err);   }    - void decode_metainfo(string s) + void decode_metainfo(Stdio.Buffer buf)   {    mixed err=catch { -  metainfo=decode(s); +  metainfo=decode(buf);    if (!mappingp(metainfo))    error("Metainfo file does not contain a dictionary (%t)\n",metainfo);    info=metainfo->info;    if (!mappingp(info))    error("Metainfo->info file does not "    "contain a dictionary (%t)\n",metainfo->info);      // if (((info->length+info["piece length"]-1)/info["piece length"])*20   // != strlen(info["pieces"]))   // error("Metainfo->info->pieces has the wrong length; "
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:200: Inside #if constant(Crypto.SHA1)
   {    if (path)    filename=combine_path(base,@path);    else    filename=base;       if (!file_stat(filename) && create_ok)    {    Stdio.mkdirhier(combine_path(filename,".."));    if (!fd->open(filename,datamode+"c",0666)) -  error("failed to create target file %O: %s\n", +  error("failed to create target file %O: %s.\n",    filename,strerror(fd->errno()));    created=1;    }    else    {    if (!fd->open(filename,datamode)) -  error("failed to open target file %O: %s\n", +  error("failed to open target file %O: %s.\n",    filename,strerror(fd->errno()));    created=0;    }    }       // Use Crypto module interface for Stdio.File objects to    // hash our files.    string phash(int(0..) off, int(0..) bytes) {    if (off>offset+length)    return "";
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:237: Inside #if constant(Crypto.SHA1)
      if (bytes<0) return "";          fd->seek(off-offset);    return Crypto.SHA1.hash(fd, bytes);    }       void pwrite(int off,string data)    { - // werror("%O: pwrite(%O,%d bytes) =%O..%O of %O\n", - // this,off,strlen(data), - // off-offset,off-offset+strlen(data),length); +     if (off>offset+length) return; // noop    int end=off+strlen(data);    if (end<=offset) return; // noop       if (off<offset)    data=data[offset-off..],off=offset;    if (end>offset+length)    data=data[0..offset+length-off-1];       fd->seek(off-offset);    if (fd->write(data)<strlen(data)) -  error("failed to write %d bytes to %O: %s\n", +  error("failed to write %d bytes to %O: %s.\n",    strlen(data),filename,strerror(fd->errno()));    }       string pread(int off,int bytes)    {    if (off>offset+length) return ""; // noop    int end=off+bytes;    - // werror("%O: pread(%O,%d bytes) =%O..%O of %O\n", - // this,off,bytes, - // off-offset,off-offset+bytes,length); -  +     if (off<offset)    bytes-=(offset-off),off=offset;    if (end>offset+length)    bytes=offset+length-off;       if (bytes<0) return "";       fd->seek(off-offset);    string s=fd->read(bytes);    if (!s) s="";
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:290: Inside #if constant(Crypto.SHA1)
   void pclear(int off,string data)    {    if (created) pwrite(off,data);    }       void allocate_peak()    {    if (fd->stat()->size>=length) return; // done    fd->seek(length-1);    if (fd->write("\0")<1) -  error("failed to write last byte to %O: %s\n", +  error("failed to write last byte to %O: %s.\n",    filename,strerror(fd->errno()));    }       string _sprintf(int t)    {    if (t=='O') return sprintf("Torrent.Target(%O, %d bytes at +%d)",    filename,length,offset);    }   }   
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:347: Inside #if constant(Crypto.SHA1)
   error("error in info (name=%O)\n",info->name);    else    base_filename=info->name;       if (info->files)    {    targets=({});    int offset=0;    foreach (info->files;;mapping m)    { - // werror("%O\n",m); +     targets+=({Target(base_filename,m->length,    offset,m->path)});    offset+=m->length;    }    total_bytes=offset;    }    else    {    targets=({Target(base_filename,info->length,0)});    total_bytes=info->length;
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:503:    "port":(string)my_port,    "numwant":(string)max(max_peers-sizeof(peers_ordered),100),    "compact":"1",    "no_peer_id":"1",    ]);    if (my_ip) req->ip=my_ip;    if (event) req->event=event;       object r;    + #if constant(Gz.File)    http->default_headers["Accept-Encoding"]="gzip"; -  + #endif       r=http->async_get_url(    metainfo->announce,    req,    0, // headers ok    lambda() // data ok    {    if (!r->status_desc())    {    warning("tracker request failed, tracker hanged up\n");
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:529:    warning("tracker request failed, code %d %O: %O\n",    r->status(),r->status_desc()[..50],    r->data()[..77]);    return;    }       string data=r->data();       if ( (< "gzip", "x-gzip" >)[ r->headers()["content-encoding"] ])    { - // werror("gruk %O\n",data); +    #if constant(Gz.File) -  data=Gz.File(Stdio.FakeFile(data))->read(); +  data=Gz.uncompress(data);   #else /* !constant(Gz.File) */    warning("tracker request failed: encoding %O not supported.\n",    r->headers()["content-encoding"]);    return;   #endif /* constant(Gz.File) */ - // werror("%O\n",data); +     }       mapping m;    mixed err=catch {    m=decode(data); - // werror("tracker says: %O\n",m); - // werror("%O\n",r->headers()); +     };    if (err)    {    error("tracker request failed, says "    "(raw, doesn't speak bencoded): %O (%s)\n",    r->data()[..77],    r->headers()["content-encoding"]||"unknown type");    }    else    {
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:625:    if ((int)m->interval &&    tracker_update_interval<((int)m->interval)/2)    tracker_update_interval<((int)m->interval)/2;    }    else if ((int)m->interval)    tracker_update_interval=(int)m->interval;    },    lambda() // failed    {    if (errno()==0) -  warning("tracker request timeout\n",strerror(errno())); +  warning("tracker request timeout\n");    else -  warning("tracker request failed, %s\n",strerror(errno())); +  warning("tracker request failed, %s\n", strerror(errno()));    });   }      int last_increase=0;   int min_time_between_increase=30;   void increase_number_of_peers(void|int n)   {    if (time(1)-last_increase<min_time_between_increase)    {    remove_call_out(increase_number_of_peers);
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:850:    multiset from_peers=available_peers;       array choices=({});    int minp=0;       if (sizeof(completed_peers_avail) &&    (completed_peers_used<min_completed_peers ||    sizeof(file_want) == sizeof(file_got))) // first seed    from_peers&=completed_peers_avail;    - // werror("%O\n",from_peers); -  +     if (!sizeof(from_peers))    {    werror("NO SOURCE!!\n");    return 0; // no source    }    - // if (sizeof(lost_in_space)) - // werror("lost_in_space=%O\n",lost_in_space); -  +     for (int i=!sizeof(lost_in_space); i<2 && !sizeof(choices); i++)    {    array u=v;    if (!i) u&=indices(lost_in_space); // restrain    foreach (u;;int n)    {    multiset(.Peer) p=file_peers[n];       if (!minp) minp=sizeof(p);    else if (minp<sizeof(p) && sizeof(choices)) break;
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:886:    }       if (sizeof(choices))    {    int i=random(sizeof(choices));    array v=(array)choices[i][1];    int n=choices[i][0];       .Peer peer=v[random(sizeof(v))];    - // werror("download piece %O from %O\n",n,peer); -  +     if (lost_in_space[n])    {    lost_in_space[n]->reactivate(peer);    m_delete(lost_in_space,n);    }    else    PieceDownload(peer,n);       return 1;    }
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:994:    downloads[piece]=this;       int size=info["piece length"];    if (piece+1==sizeof(file_got) &&    total_bytes%info["piece length"])    size=total_bytes%info["piece length"];    for (int i=0; i<size; i+=download_chunk_size)    {    int z=min(size-i,download_chunk_size);    expect_chunks[i]=z; -  - // werror("expect p=%d o=%d %d bytes\n",piece,i,z); +     }       queue_chunks();    }       void reactivate(.Peer _peer)    {   #ifdef TORRENT_PIECEDOWNLOAD_DEBUG    werror("reactivate lost download: %O %O %O\n",    peer,piece,indices(chunks));
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:1093:    }       if (from!=peer)    {    more_peers-=({from});    download_more();    }       if (piece==n && expect_chunks[i]==strlen(data))    { - // werror("got piece %d off %d bytes %d\n",n,i,strlen(data)); -  +     chunks[i]=data;    m_delete(queued_chunks,i);       if (sizeof(expect_chunks-chunks))    {    queue_chunks(); // request more    }    else    {    string res="";
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:1203:   #endif    disjoin();    download_more();       if (handovers[piece]==this ||    downloads[piece]==this)    {    error("destruction of download still in structs:\n"    "download: %O\ndownloads: %O\nhandovers: %O\n",    this,downloads,handovers); -  - // werror("%s\n",master()->describe_backtrace(backtrace())); +     }       more_peers->cancel_requests(0);       destruct(this);    }       string _sprintf(int t)    {    if (t=='O')
pike.git/lib/modules/Protocols.pmod/Bittorrent.pmod/Torrent.pike:1335:    if (p->peer_interested)    p->unchoke();       if (find_call_out(got_piece_drop_interest)==-1)    call_out(got_piece_drop_interest,10);   }      void got_piece_drop_interest()   {   // drop interest for now uninteresting peers -  +     foreach (peers_ordered;;.Peer p)    if (p->were_interested)    {    multiset mz=(multiset)string2arr(p->bitfield);    if (!sizeof(mz&file_want))    p->show_uninterest();    }   }      // ----------------------------------------------------------------    - void destroy() + protected void _destruct()   {    // some clean-up    if (targets) map(targets,destruct);    map(peers_ordered,destruct);    map(peers_unused,destruct);       remove_call_out(update_tracker_loop);    remove_call_out(increase_number_of_peers);    if( listen_port )    destruct( listen_port);    if( http )    destruct( http );   }      // ---------------------------------------------------------------- -  - #else /* !constant(Crypto.SHA1) */ -  - constant this_program_does_not_exist=1; -  - #endif /* constant(Crypto.SHA1) */ +