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; }
static int clientPrint(int clientSocket, char* s) { int len = strlen(s); return clientWrite(clientSocket, s, len); }
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; }
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; }