예제 #1
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;

}
예제 #2
0
파일: daemon.c 프로젝트: hanappe/p2pfoodlab
static int clientPrint(int clientSocket, char* s)
{
    int len = strlen(s);
    return clientWrite(clientSocket, s, len);
}
예제 #3
0
파일: daemon.c 프로젝트: hanappe/p2pfoodlab
int main(int argc, char **argv)
{
    int err;

    parseArguments(argc, argv);

    if (nodaemon == 0) {
        err = daemonise();
        if (err != 0) exit(1);

        err = writePidFile(pidFile);
        if (err != 0) exit(1);
    }

    err = signalisation();
    if (err != 0) exit(1);

    serverSocket = openServerSocket(port);
    if (serverSocket == -1) exit(1);

    request_t req;
    response_t resp;
    output_t output;

    memset(&output, 0, sizeof(output_t));

    while (serverSocket != -1) {

        memset(&req, 0, sizeof(request_t));
        memset(&resp, 0, sizeof(response_t));

        int client = serverSocketAccept(serverSocket);
        if (client == -1)
            continue;


        int r = parseRequest(client, &req, &resp);
        if (r != 0) {
            clientPrintf(client, "HTTP/1.1 %03d\r\n", resp.status);
            closeClient(client);
            continue;
        }

        if (1) {
            printf("path: %s\n", req.path);
            for (int i =0; i < req.num_args; i++)
                printf("arg[%d]: %s = %s\n", i, req.names[i], req.values[i]);
        }

        const char* cmdline = findCommand(req.path);

        if (cmdline == NULL) {
            log_warn("Daemon: Invalid path: '%s'\n", req.path);
            clientPrint(client, "HTTP/1.1 404\r\n");
            closeClient(client);
            continue;
        }

        if (execute(&output, cmdline) != 0) {
            clientPrint(client, "HTTP/1.1 500\r\n"); // Internal server error
            closeClient(client);
            continue;
        }

        if ((output.count > 8) && (strncmp(output.buf, "HTTP/1.1", 8) == 0)) {
            clientWrite(client, output.buf, output.count);
        } else {
            clientPrintf(client, "HTTP/1.1 200\r\nContent-Length: %d\r\n\r\n",
                         output.count);
            clientWrite(client, output.buf, output.count);
        }

        closeClient(client);

        output_clear(&output);
        if (req.path) free(req.path);
    }

    removePidFile(pidFile);

    return 0;
}
예제 #4
0
int main(int argc, char **argv)
{
        int err;

        server_init();

        parse_arguments(argc, argv);

        log_set_file(logFile);

        if (nodaemon == 0) {
                err = daemonise();
                if (err != 0) exit(1);

                err = writePidFile(pidFile);
                if (err != 0) exit(1);

                err = drop_privileges();
                if (err != 0) exit(1);
        }

        err = signalisation();
        if (err != 0) exit(1);

        serverSocket = openServerSocket(NULL, port);
        if (serverSocket == -1) exit(1);

        log_info("Server ready for connections");

        request_t req;
        response_t resp;

        memset(&req, 0, sizeof(request_t));
        memset(&resp, 0, sizeof(response_t));
                        
        while (serverSocket != -1) {

                int client = serverSocketAccept(serverSocket);
                if (client == -1) {
                        continue;
                }

                int r = parseRequest(client, &req, &resp);
                if (r != 0) {
                        clientPrintf(client, "HTTP/1.1 %03d\r\n", resp.status);
                        closeClient(client);
                        continue;
                }

                log_info("Request: %s", req.path);

                if (1) {
                        list_t* l = req.args;
                        while (l) {
                                pair_t* p = (pair_t*) l->data;
                                log_debug("args[]: %s = %s", p->name, p->value);
                                l = l->next;
                        }
                        l = req.headers;
                        while (l) {
                                pair_t* p = (pair_t*) l->data;
                                log_debug("headers[]: '%s': '%s'", p->name, p->value);
                                l = l->next;
                        }
                }

                server_handle_request(&req, &resp);

                // Debug printf
                
                if (resp.status != 0) {
                        clientPrintf(client, 
                                     "HTTP/1.1 %03d\r\n"
                                     "Content-Length: %d\r\n"
                                     "Content-Type: %s\r\n"
                                     "\r\n", 
                                     resp.status, resp.length, resp.content_type);

                        clientWrite(client, resp.body, resp.length);
                        
                } else {
                        log_err("main.c, request status == 0, request not handle!");
                }

                closeClient(client);
                
                request_clear(&req);
                response_clear(&resp);
        }

        removePidFile(pidFile); 

        return 0;
}