コード例 #1
0
ファイル: segmenter.c プロジェクト: pagxir/ubitcore
int
seg_readbuf( btFileSet *fs, int piece, int start, char *buf, int len) {
    btFile *f;
    _int64 addr = ((_int64)piece * fs->blocksize)+start;
    int ifile;

    if (!bs_isSet(&fs->completed, piece)) {
        printf("Attempted to read uncompleted block %d from disk.\n", piece);
        return -1;
    }
    for (ifile=0; ifile < fs->nfiles; ifile++) {
	f=fs->file[ifile];
	if ( f->start+f->len >= addr &&
		f->start < addr + len) 
	{
	    /* this file (partly) includes this piece */
	    int fd = cacheopen( f->path, O_RDONLY, 0);
	    off_t fpos = addr - f->start;	

	    _int64 rlen;
	    _int64 beg = 0;
	    ssize_t res;

#if 0
	    fprintf( stderr, "cacheopen( %s, O_RDONLY)\n", f->path);
#endif
	    if (fd == -1)  {
#if 0
		bts_perror(errno, "readbuf.cacheopen");
#endif
		return -1;
	    }
	    if (fpos < 0) {
		beg = -fpos;
		fpos = 0;
	    }
	    rlen = min(f->len - fpos, len - beg);

	    if (lseek( fd, fpos, SEEK_SET) != fpos) {
		SYSDIE("lseek failed");
		return -1;
	    }


	    DIE_UNLESS( rlen <= fs->blocksize);
	    res = read(fd, buf+beg, rlen);
	    if (res != rlen) {
	        if (res == 0) {
		    /* EOF */
		    return -1;
		}
		fprintf(stderr, "On file '%s'\n", f->path);
		fprintf(stderr, "read( ..., buf[%lld], %lld) = %d\n", beg, rlen, res);
		bts_perror(errno, "readbuf.read");
		return -1;
	    }
	}
    }
    return 0;
}
コード例 #2
0
ファイル: segmenter.c プロジェクト: ermakus/stm
int seg_readbuf( btFileSet *fs, kBitSet *writeCache, int piece, int start, char *buf, int len) {
    btFile *f;
    _int64 addr = ((_int64)piece * fs->blocksize)+start;
    int ifile;

    if (!bs_isSet(writeCache, piece) && !bs_isSet(&fs->completed, piece)) 
    {
        //printf("Attempted to read uncompleted block %d from disk.\n", piece);
        return -1;
    }
    for (ifile=0; ifile < fs->nfiles; ifile++) {
	f=fs->file[ifile];
	if ( f->start+f->len >= addr &&
		f->start < addr + len) 
	{
	    /* this file (partly) includes this piece */
	    int fd = cacheopen( f->path, O_RDONLY, 0);
	    off_t fpos = addr - f->start;	

	    _int64 rlen;
	    _int64 beg = 0;
	    ssize_t res;

	    if (fd == -1)  {
		bts_perror(errno, "readbuf.cacheopen");
		return -1;
	    }
	    if (fpos < 0) {
		beg = -fpos;
		fpos = 0;
	    }
	    rlen = min(f->len - fpos, len - beg);

	    if (lseek( fd, fpos, SEEK_SET) != fpos) {
		bts_perror(errno, "readbuf.read");
		return -1;
	    }


	    bt_assert( rlen <= fs->blocksize);
	    res = read(fd, buf+beg, rlen);
	    if (res != rlen) {
	        if (res == 0) {
		    /* EOF */
		    return -1;
		}
		bts_perror(errno, "readbuf.read");
		return -1;
	    }
	}
    }
    return 0;
}
コード例 #3
0
ファイル: Torrent.cpp プロジェクト: ermakus/stm
void CTorrent::run()
{

  m_bRunning = true;
  m_bStopping = false;

  try 
  {

   if( !check() ) { 
      m_nState = STATE_STOPPED;
      m_bStopping = m_bRunning = false;
      notify("Checking canceled");
      return;
    }

    btContext* ctx = &m_Context;
    int dl = 0;

    m_pListener->notify("Starting server..");
    ctx_startserver(ctx);

    m_pListener->notify("Registering...");
    ctx_register(ctx, dl);
      
    m_nState = STATE_RUNNING;
    m_pListener->notify("Download started");

  int ttv;
  int tv_slow = 1; /*ms*/
  int tv_fast = 0; /*ms*/
  btPeer *peer;
  int cs;
  struct sockaddr csin;
  int err;

  time_t choke_timer;
  time_t report_timer;
  time_t now;

  int i;

  time( &now );
  choke_timer = report_timer = now;

  while( !m_bStopping )
  {
	int readerr;
	int writeerr;
	int execerr;
	int pollerr;
	socklen_t sa_len;

        /*
	 * Select a socket or time out
	 */
	if (ctx->xsock) {
	    ttv = tv_fast;
	} else {
	    ttv = tv_slow;
	}

        err = poll( ctx->status, ctx->nstatus, ttv);

	if (err < 0) { 
		bts_perror(errno, "poll");
		m_nState = STATE_ERROR;
                break;
	}

	time(&now);

	for (cs=0; cs < SOCKID_MAX; cs++) {
	    /* loop through executable sockets */
            if (ctx->x_set[ cs]) {
		btPeer *p = ctx->sockpeer[cs];
		execerr = clientRun( cs, EXECUTE);
		if (execerr == 0) {
		    if ( ctx->x_set[ cs]) {
			ctx->x_set[ cs] = 0;
			ctx->xsock--;
		    }
		}
		
		if ( kStream_oqlen( &p->ios)) {
		    /* data is waiting on the output buffer */
                    ctx_setevents( ctx, cs, POLLOUT);
		}

		if (execerr < 0) {
		    clientError("execute", cs);
		} 
	    } 
	} 


        for (i=0; i<ctx->nstatus; i++) {
	    /* for each poll event */
	    cs = ctx->status[i].fd;

	    readerr=0;
	    writeerr=0;
	    execerr=0;
	    pollerr=0;

	    if (CTX_STATUS_REVENTS( ctx, i) & POLLIN) 
            {
		bt_assert( ctx->status[i].events & POLLIN);
		/* readable */
	        if (cs == ctx->ss) {
		    /* service socket */
		    sa_len = sizeof(csin);
		    cs = accept( ctx->ss, &csin, &sa_len);
		    if (cs < 0) {
			bts_perror( errno, "accept");
		    } else {
                        peer_answer( ctx, cs);
		    } 
		} else if (cs == ctx->udpsock) {
		    int err = udp_ready( ctx);
		    if (err) {
			printf("Error %d processing UDP packet.\n", err);
		    }
		} else {
		    btPeer *p = ctx->sockpeer[ cs];
		    readerr = clientRun( cs, READABLE);
		    if (readerr == 1) {
			/* more to read */
			if (!ctx->x_set[cs]) {
			    ctx->x_set[cs] = 1;
			    ctx->xsock++;
			}
		    }
		    if ( kStream_oqlen( &p->ios)) {
		        /* data is waiting on the output buffer */
			ctx_setevents( ctx, cs, POLLOUT);
		    }
		}
	    } /* if */

	    if (CTX_STATUS_REVENTS( ctx, i) & POLLOUT) {
		writeerr = clientWrite( cs );
		if (writeerr == 0) {
		    /* output drained */
		    ctx_clrevents( ctx, cs, POLLOUT);
		    if (!ctx->x_set[ cs]) {
			/* output buffer is empty, check for more work */
			ctx->x_set[ cs] = 1;
			ctx->xsock++;
		    }
		}
	    } /* if */

	    if (CTX_STATUS_REVENTS( ctx, i) & (POLLERR | POLLHUP | POLLNVAL)) 
	    {
	        int events = CTX_STATUS_REVENTS( ctx, i);
		if (events & POLLHUP) {
		    ctx->sockpeer[cs]->ios.error = BTERR_POLLHUP;
		} else if (events & POLLERR) {
		    ctx->sockpeer[cs]->ios.error = BTERR_POLLERR;
		} else if (events & POLLNVAL) {
		    ctx->sockpeer[cs]->ios.error = BTERR_POLLNVAL;
		}
		pollerr = -1;
	    }

	    if (readerr < 0 || writeerr < 0 || execerr < 0 || pollerr < 0) 
            {
	        const char *act = NULL;
		if (readerr<0) act = "read";
		if (writeerr<0) act = "write";
		if (execerr<0) act = "execute";
		if (pollerr<0) act = "poll";
		clientError( act, cs);
	    } 

	    peer = ctx->sockpeer[cs];

	    if (  peer && !peer->remote.choked && peer->local.interested && !peer->local.snubbed && now - peer->lastreceived > 120) 
	    {
		peer->local.snubbed = 1;
	    }
	    
	    if (peer && peer->pex_supported > 0 && peer->pex_timer > 0 && now - peer->pex_timer >= 60)
	    {
		sendPeerExchange(ctx->downloads[peer->download], peer);
	    }
	    
	} 

        if (ctx->downloads[dl]->reregister_interval != 0 &&  now - ctx->downloads[dl]->reregister_timer > ctx->downloads[dl]->reregister_interval) 
        {
                notify("Updating...");
		ctx->downloads[dl]->reregister_timer = now;
		ctx_reregister( ctx, dl);
        }

	if (now - report_timer > 0) 
        {
	    int complt = bs_countBits( &ctx->downloads[dl]->fileset.completed);
       	    if ((complt == ctx->downloads[dl]->fileset.npieces) && !ctx->downloads[dl]->complete) 
            {
		notify("Completing...");
                ctx_complete (ctx, dl);
                m_nState = STATE_COMPLETE;
                break;
            }
            report_timer=now;
	    updateStatus();
	}

	if (now - choke_timer > 30) {
	    /* recalculate favorite peers */
	    choke_timer=now;
	    peer_favorites( ctx, &ctx->downloads[dl]->peerset);
	}
    }

   } 
   catch(const char* ex) 
   {
       m_pListener->error( ex );
       m_nState = STATE_ERROR;
   }

   notify("Disconnecting...");

   int dl = 0;

   ctx_writefastresume(m_Context.downloads[dl], (char*) m_szDownloadDir );
   ctx_shutdown( &m_Context, dl );
   cacheclose();

   m_bRunning = false;

   if( m_bStopping ) {
      notify("Download stopped");
      m_bStopping = false;
      m_nState = STATE_STOPPED;
   } 
   else
   if( m_nState == STATE_COMPLETE ) {
      notify("Download complete");
   }
   else
   if( m_nState == STATE_ERROR ) {
      notify("Download failed");
   }
   else
       m_nState = STATE_STOPPED;

}