int printlog_cgi(HttpState* state) { auto int bytes_written; switch(state->substate) { case PRTLOG_INIT: state->p=&prtlog_header[0]; state->substate=PRTLOG_HEADER; read_log_reset(); // intentionally no break case PRTLOG_HEADER: if(*state->p) { bytes_written=sock_fastwrite(&state->s,state->p,strlen(state->p)); if(bytes_written>0) state->p+=bytes_written; } else { state->p=NULL; state->offset=0; state->substate=PRTLOG_PRTITEM; } break; case PRTLOG_PRTITEM: if(state->p==NULL || *state->p=='\0' || *state->p=='\xff') { read_log(state->buffer, 128); if(strlen(state->buffer)) { //still reading out log contents state->p=state->buffer; state->offset = 0; } else { state->offset=0; state->p=&prtlog_footer[0]; state->substate=PRTLOG_FOOTER; } state->offset++; } else { bytes_written=sock_fastwrite(&state->s,state->p,strlen(state->p)); if(bytes_written>0) { state->p+=bytes_written; } } break; case PRTLOG_FOOTER: if(*state->p) { bytes_written=sock_fastwrite(&state->s,state->p,strlen(state->p)); if(bytes_written>0) state->p+=bytes_written; } else return 1; // done break; } return 0; }
/* * Send a tftp request packet */ static void send_req (char request, const char *fname) { char *cp, *mode; int len; int fnamlen = strlen (fname); /* The output buffer is setup with the request code, the file name, * and the name of the data format. */ memset (outbuf, 0, sizeof(*outbuf)); outbuf->th_opcode = intel16 (request); len = SEGSIZE - sizeof(outbuf->th_opcode) - strlen(tftp_xfer_mode) - 1; cp = (char*) &outbuf->th_stuff[0]; for ( ; *fname && len > 0 && fnamlen > 0; len--, fnamlen--) *cp++ = *fname++; *cp++ = '\0'; for (mode = tftp_xfer_mode; *mode; ) *cp++ = *mode++; *cp++ = '\0'; /* Finally send the request */ len = (int) (cp - (char*)outbuf); sock_fastwrite (sock, (BYTE*)outbuf, len); }
/* * Sample submit.cgi function */ int submit(HttpState* state) { int i; if(state->length) { /* buffer to write out */ if(state->offset < state->length) { state->offset += sock_fastwrite(&state->s, state->buffer + (int)state->offset, (int)state->length - (int)state->offset); } else { state->offset = 0; state->length = 0; } } else { switch(state->substate) { case 0: _f_strcpy(state->buffer, "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n"); break; case 1: /* init the FORMSpec data */ FORMSpec[0].value[0] = '\0'; FORMSpec[1].value[0] = '\0'; state->p = state->buffer; parse_post(state); state->substate++; return 0; case 2: http_setcookie(state->buffer, FORMSpec[0].value); break; case 3: _f_strcpy(state->buffer, "\r\n\r\n<html><head><title>Results</title></head><body>\r\n"); break; case 4: sprintf(state->buffer, "<p>Username: %s<p>\r\n<p>Email: %s<p>\r\n", FORMSpec[0].value, FORMSpec[1].value); break; case 5: _f_strcpy(state->buffer, "<p>Go <a href=\"/\">home</a></body></html>\r\n"); break; default: state->substate = 0; return 1; } state->length = strlen(state->buffer); state->offset = 0; state->substate++; } return 0; }
/* * Send a tftp acknowledge packet */ static void send_ack (WORD block) { struct tftphdr ack; ack.th_opcode = intel16 (ACK); ack.th_block = intel16 (block); sock_fastwrite (sock, (BYTE*)&ack, TFTP_HEADSIZE); }
int send_iac( char cmd, char opt) { byte io_data[3]; io_data[0] = IAC; io_data[1] = cmd; io_data[2] = opt; sock_fastwrite( s, io_data, 3 ); return( !tcp_tick( s )); }
void cook_cmd(void) { auto int len; len = 3; while(len > 0) { len -= sock_fastwrite(state->s, state->cmdbuf + 3 - len, len); } }
/********************************************************************************* This function sends data out the xml socket. ********************************************************************************/ int My_Snd_Pkt(My_Socket_Type *my_sock) { /* send the packet */ my_sock->txbytes = sock_fastwrite(&my_sock->sock, my_sock->buff,my_sock->txbytes+1); switch(my_sock->txbytes) { case -1: return 4; // there was an error go to state 4 (NO_WAIT_CLOSE) default: memset(my_sock->buff,0x00,BUFF_SIZE); my_sock->txbytes = 0; (my_sock->statetime) = MS_TIMER+TCP_TIMEOUT; // reset time to be in the RECEIVE state return 2; //now go to state 2 (RECEIVE) } }
int send_packet(void) { /* send the packet */ memset(buff,'S',BUFF_SIZE); // fill buffer with S's buff[BUFF_SIZE-1] = '\n'; // null terminate the buffer bytes = sock_fastwrite(&sock,buff,BUFF_SIZE); switch(bytes) { case -1: return 3; // there was an error stay is SEND state and retry default: statetime = MS_TIMER+TIME_OUT; // reset time to be in the RECEIVE state return 2; //now go to state 2 (RECEIVE) } }
int do_transmission(void) { unsigned int send_chars; int status; if( tran_in == tran_out ) return(0); if( tran_in > tran_out ) send_chars = tran_in - tran_out; else send_chars = TRANSMIT_BUF_SIZE - tran_out; if( send_chars > TRANSMIT_MAX ) send_chars = TRANSMIT_MAX; sock_flushnext( s ); send_chars = sock_fastwrite( s, &transmit_buffer[ tran_out], send_chars ); /* this only changes it by the number of bytes we have emptied out */ tran_out = (tran_out + send_chars) % TRANSMIT_BUF_SIZE; return(0); }
int tn_sttyp(void) { /* Send telnet terminal type. */ char *ttn; int ttl; /* Name & length of terminal type. */ ttn = termtype; /* we already got this from environment */ if ((*ttn == 0) || ((ttl = strlen(ttn)) >= TSBUFSIZ)) { ttn = "UNKNOWN"; ttl = 7; } ttn = strcpy(&sb[1],ttn); /* Copy to subnegotiation buffer */ ttn = strchr( strupr(ttn), 0 ); *sb = 0; /* 'is'... */ *ttn++ = IAC; *ttn = SE; if (send_iac(SB,TELOPT_TTYPE)) /* Send: Terminal Type */ return(-1); sock_fastwrite( s, sb, ttl+3 ); return(0); }
SSPEC_RESOURCETABLE_END // This code is a catch-all that writes out any data to the HTTP server // socket that has not yet been written. int write_http_buffer(HttpState *state) { if (state->length == 0) { return 0; } if (state->offset < state->length) { state->offset += sock_fastwrite(&state->s, state->buffer + (int)state->offset, (int)state->length - (int)state->offset); } if (state->offset == state->length) { state->offset = 0; state->length = 0; } // Indicate whether there's still data to write return (int) (state->length - state->offset); }
int Read(HttpState* state) { int i; char line[10]; if (state->length) { /* buffer to write out */ if (state->offset < state->length) { state->offset += sock_fastwrite(&state->s, state->buffer + (int)state->offset, (int)state->length - (int)state->offset); } else { state->offset = 0; state->length = 0; } } else { switch (state->substate) { case 0: strcpy(state->buffer, "HTTP/1.0 200 OK\r\n\r\n"); state->length = strlen(state->buffer); state->offset = 0; state->substate++; break; case 1: strcpy(state->buffer, "<html><head><title>Read Email</title></head><body>\r\n"); state->length = strlen(state->buffer); state->substate++; break; case 2: emailCurr = emailList.head; emailNum = 1; strcpy(state->buffer, "<H1>Read Email</H1>\r\n"); state->length = strlen(state->buffer); state->substate++; break; case 3: bodyPosition = 0; if (emailCurr != -1) { strcpy(state->buffer, "<B>Email #"); itoa(emailNum, line); strcat(state->buffer, line); strcat(state->buffer, "</B><P><PRE>"); state->length = strlen(state->buffer); state->substate++; } else if (emailNum == 1) { strcpy(state->buffer, "No email"); state->length = strlen(state->buffer); state->substate = 9; } else { state->substate = 9; } break; case 4: xmem2root(&email, emailBuffer + sizeof(Email)*emailCurr, sizeof(Email)); strcpy(state->buffer, "FROM: "); strcat(state->buffer, email.from); strcat(state->buffer, "\r\n"); state->length = strlen(state->buffer); emailNum++; emailCurr = emailIndex[emailCurr].next; state->substate++; break; case 5: strcpy(state->buffer, "SUBJECT: "); strcat(state->buffer, email.subject); strcat(state->buffer, "\r\n"); state->length = strlen(state->buffer); state->substate++; break; case 6: strcpy(state->buffer, "BODY\r\n"); state->length = strlen(state->buffer); state->substate++; break; case 7: strncpy(state->buffer, email.body + bodyPosition, HTTP_MAXBUFFER); if (state->buffer[HTTP_MAXBUFFER - 1] != '\0') { state->buffer[HTTP_MAXBUFFER - 1] = '\0'; if (strlen(state->buffer) == (HTTP_MAXBUFFER - 1)) { // More data to get bodyPosition += HTTP_MAXBUFFER - 1; } else { state->substate++; } } else { state->substate++; } state->length = strlen(state->buffer); break; case 8: strcpy(state->buffer, "\r\n</PRE>\r\n"); state->length = strlen(state->buffer); state->substate = 3; break; case 9: strcpy(state->buffer, "<p><a href=\"/\">Back to main page</a></body></html>\r\n"); state->length = strlen(state->buffer); state->substate++; break; default: state->substate = 0; return 1; } } return 0; }
/* * Accept the new email and display it to the LCD. */ int Submit(HttpState* state) { if (state->length) { /* buffer to write out */ if (state->offset < state->length) { state->offset += sock_fastwrite(&state->s, state->buffer + (int)state->offset, (int)state->length - (int)state->offset); } else { state->offset = 0; state->length = 0; } } else { switch (state->substate) { case 0: /* init the FORMSpec data */ FORMSpec[0].value[0] = '\0'; FORMSpec[1].value[0] = '\0'; FORMSpec[2].value[0] = '\0'; state->p = state->buffer; state->substate++; break; case 1: /* parse the POST information */ if (ParsePost(state) != -1) { // Add the email to the email list if (AddEmail(emailTemp.from, emailTemp.subject, emailTemp.body) != -1) { state->substate++; } else { // Failed to add the email state->substate = 10; } } else { // Failed to parse the new email state->substate = 10; } break; case 2: state->substate = 0; cgi_redirectto(state,REDIRECTTO); break; // This case only occurs when there has been an error case 10: strcpy(state->buffer, "HTTP/1.0 200 OK\r\n\r\n"); state->length = strlen(state->buffer); state->offset = 0; state->substate++; break; case 11: strcpy(state->buffer, "<HTML><HEAD><TITLE>Email Failed!</TITLE></HEAD><BODY><H1>Email failed!</H1>\r\n"); state->length = strlen(state->buffer); state->substate++; break; case 12: strcpy(state->buffer, "<P><A HREF=\"/\">Back to main page</A></BODY></HTML>\r\n"); state->length = strlen(state->buffer); state->substate++; break; default: state->substate = 0; return 1; } } return 0; }
/* * TCP transmitter */ static int tcp_transmit (Socket *socket, const void *buf, int len, int flags) { sock_type *sk = (sock_type*)socket->tcp_sock; tcp_tick (sk); tcp_Retransmitter (1); if (sk->tcp.state < tcp_StateESTAB || sk->tcp.state >= tcp_StateLASTACK) { socket->so_state |= SS_CANTSENDMORE; SOCK_DEBUGF ((socket, ", ENOTCONN (%s)", /* !! or EPIPE */ (sk->tcp.locflags & LF_GOT_FIN) ? "got FIN" : "can't send")); SOCK_ERR (ENOTCONN); return (-1); } if (socket->so_state & SS_NBIO) { int in_len = len; if (check_non_block_tx(socket,&len) < 0) { SOCK_DEBUGF ((socket, ", EWOULDBLOCK")); SOCK_ERR (EWOULDBLOCK); return (-1); } if (in_len != len) SOCK_DEBUGF ((socket, " [%d]", len)); /* trace "len=x [y]" */ } SOCK_DEBUGF ((socket, ", %s (%d) / TCP", inet_ntoa(socket->remote_addr->sin_addr), ntohs(socket->remote_addr->sin_port))); #if 0 /* Must wait for room in send buffer */ if ((flags & MSG_WAITALL) || len > sock_tbleft(sk)) len = sock_write (sk, (BYTE*)buf, len); else len = sock_fastwrite (sk, (BYTE*)buf, len); #else /* This is more efficient. The above sock_fastwrite() would * effectively turn off Nagle's algorithm. */ ARGSUSED (flags); len = sock_write (sk, (BYTE*)buf, len); #endif if (len <= 0) /* error in tcp_write() */ { if (sk->tcp.state != tcp_StateESTAB) { SOCK_DEBUGF ((socket, ", ENOTCONN")); SOCK_ERR (ENOTCONN); /* maybe EPIPE? */ } else { SOCK_DEBUGF ((socket, ", ENETDOWN")); SOCK_ERR (ENETDOWN); } return (-1); } return (len); }
int ViewLog(HttpState *state) { if (state->length) { /* buffer to write out */ if (state->offset < state->length) { state->offset += sock_fastwrite(&state->s, state->buffer + (int)state->offset, (int)state->length - (int)state->offset); } else { state->offset = 0; state->length = 0; } } else { switch (state->substate) { case 0: logPosition = 0; strcpy(state->buffer, "HTTP/1.0 200 OK\r\n\r\n"); state->length = strlen(state->buffer); state->offset = 0; state->substate++; break; case 1: strcpy(state->buffer, "<html><head><title>Display Log</title></head><body>\r\n"); state->length = strlen(state->buffer); state->substate++; break; case 2: strcpy(state->buffer, "<H1>Display Log</H1>\r\n<PRE>\r\n"); state->length = strlen(state->buffer); state->substate++; break; case 3: xmem2root(state->buffer, logBuffer + logPosition, HTTP_MAXBUFFER); if (state->buffer[HTTP_MAXBUFFER - 1] != '\0') { state->buffer[HTTP_MAXBUFFER - 1] = '\0'; if (strlen(state->buffer) == (HTTP_MAXBUFFER - 1)) { // More data to get logPosition += HTTP_MAXBUFFER - 1; } else { state->substate++; } } else { state->substate++; } state->length = strlen(state->buffer); break; case 4: strcpy(state->buffer, "\r\n</PRE>\r\n"); state->length = strlen(state->buffer); state->substate++; break; case 5: strcpy(state->buffer, "<p><a href=\"/\">Back to main page</a></body></html>\r\n"); state->length = strlen(state->buffer); state->substate++; break; default: state->substate = 0; return 1; } } return 0; }
void vs_handler(VsState* state) { auto tcp_Socket* socket; auto int ch, bytes_written; auto int bytes_to_write; if(vs_info.mode==VS_MODEOFF) return; socket=&state->socket; /* * was the connection reset? */ if(state->state!=VS_INIT && tcp_tick(socket)==0) { #ifdef VERBOSE printf("Connection closed\n"); #endif state->state=VS_INIT; state->open_timeout=vs_info.open_timeout; } switch(state->state) { case VS_INIT: /* * passive open on the socket port */ if(state->open_timeout && vs_info.mode == VS_MODEACTIVE) { costate { waitfor(DelayMs(state->open_timeout)); state->open_timeout=0; } if(state->open_timeout) break; } serYopen(vs_info.baud); if(vs_info.mode == VS_MODEPASSIVE) { if (tcp_listen(socket,vs_info.port,0,0,NULL,0) != 0) { state->state=VS_LISTEN; #ifdef VERBOSE printf("\nListening on socket\n"); #endif } else { printf("\nError listening on socket!\n"); } } else if(vs_info.mode == VS_MODEACTIVE) { if (tcp_open(socket,0,vs_info.dest_ip,vs_info.dest_port,NULL) != 0) { state->state=VS_OPENING; #ifdef VERBOSE printf("\nOpening socket\n"); #endif } else { printf("\nError opening socket!\n"); } } break; case VS_LISTEN: case VS_OPENING: /* * wait for a connection */ if(sock_established(socket) || sock_bytesready(socket) >= 0) { state->state=VS_OPEN; sock_mode(socket,vs_info.binary); #ifdef VERBOSE printf("New Connection\n"); #endif } break; case VS_OPEN: if(vs_info.timeout!=0 && state->offset && (long) ((state->last_character+vs_info.timeout) - MS_TIMER) < 0) { bytes_written=sock_fastwrite(socket,state->buffer,state->offset); if (bytes_written < 0) { state->state = VS_WAITCLOSE; sock_close(socket); #ifdef VERBOSE printf("Connection closed\n"); #endif break; } /* * Hmmm... We weren't able to write all the bytes out. * Since we don't want to loose any characters, we will * shift everything over and hopefully write it soon. * */ if(bytes_written!=state->offset) { memcpy(state->buffer,state->buffer+bytes_written,state->offset-bytes_written); state->offset = bytes_written; break; } else state->offset = 0; } /* * process any characters. */ bytes_to_write=sock_bytesready(socket); if(bytes_to_write>serYwrFree()) bytes_to_write=serYwrFree(); if(bytes_to_write>(int)sizeof(state->buffer)) bytes_to_write=sizeof(state->buffer); if(bytes_to_write>0) { sock_read(socket,state->buffer,bytes_to_write); serYwrite(state->buffer,bytes_to_write); } /* * If we aren't worried about interpacket delay * just send the characters if there is room in * the buffer. * */ if(vs_info.timeout==0) { bytes_to_write=serYrdUsed(); if(bytes_to_write>sock_tbleft(socket)) bytes_to_write=sock_tbleft(socket); if(bytes_to_write>(int)sizeof(state->buffer)) bytes_to_write=sizeof(state->buffer); if(bytes_to_write>0) { serYread(state->buffer,bytes_to_write,0); sock_write(socket,state->buffer,bytes_to_write); } } else { while(state->offset<VS_MAXOFFSET && (ch=serYgetc())!=-1) { #ifdef USE_STDIO printf("%c",ch); #endif state->buffer[state->offset++]=ch; state->last_character=MS_TIMER; } } /* * We should immediately flush characters if the buffer * is full. * */ if(state->offset==VS_MAXOFFSET) { bytes_written=sock_fastwrite(socket,state->buffer,state->offset); if (bytes_written < 0) { state->state = VS_WAITCLOSE; sock_close(socket); #ifdef VERBOSE printf("Connection closed\n"); #endif break; } /* * Hmmm... We weren't able to write all the bytes out. * Since we don't want to loose any characters, we will * shift everything over and hopefully write it soon. * */ if(bytes_written!=state->offset) { memcpy(state->buffer,state->buffer+bytes_written,state->offset-bytes_written); state->offset = bytes_written; } else state->offset = 0; } break; case VS_WAITCLOSE: break; default: /* * how did we get here? programming error? */ state->state=VS_INIT; break; }
int main() { auto int if_status; printf("Multiple Interface Echo Test\n"); usage(); printf("\nPress any key to proceed.\n"); while (!kbhit()); getchar(); printf("Initializing TCP/IP stack...\n"); for (i = 0; i < IF_MAX; i++) ifconfig(i, IFG_IPADDR, oldip+i, #ifdef USE_IF_CALLBACK IFS_IF_CALLBACK, updowncb, #endif IFS_END); sock_init(); // Wait for the interface to come up while (IF_COMING_UP == (if_status = ifpending(IF_DEFAULT)) || IF_COMING_DOWN == if_status) { tcp_tick(NULL); } printf("...done.\n"); memset(state, 0, sizeof(state)); socknum = -1; seq = 1; ping_ip = 0; act_ip = 0; asock = s + (NUM_SOCKS - 1); astate = state + (NUM_SOCKS - 1); *astate = STATE_DONT_USE; if(!udp_extopen(&usock, IF_ANY, ECHO_PORT, -1L, 0, echo_handler, 0, 0)) { printf("udp_extopen failed!\n"); exit(0); } for (;;) { socknum++; if (socknum == NUM_SOCKS) socknum = 0; tcp_tick(NULL); if (state[socknum] > STATE_CLOSED && !sock_alive(s+socknum)) { if (socknum == NUM_LISTEN_SOCKS) { printf("Active socket closed\n"); state[socknum] = STATE_DONT_USE; } else { printf("Socket %d closed\n", socknum); state[socknum] = STATE_CLOSED; } sock_perror(s+socknum, NULL); } for (i = 0; i < IF_MAX; i++) { ifconfig(i, IFG_IPADDR, &ip, IFS_END); if (oldip[i] != ip) { printf("IPaddr on i/f %d changed from %08lx to %08lx\n", i, oldip[i], ip); oldip[i] = ip; ifconfig(i, IFS_ICMP_CONFIG_RESET, IFS_END); } } if (kbhit()) { kb = getchar(); if (kb == '?') usage(); else if (kb == 'i') ip_print_ifs(); else if (kb == 'r') router_printall(); else if (kb == 'c') arpcache_printall(); else if (kb == 'p') { printf("Press an interface number [TCP/IP now blocked]\n"); while (!kbhit()); kb = getchar(); if (isdigit(kb)) { ifconfig(kb - '0', IFG_ROUTER_DEFAULT, &ping_ip, IFS_END); if (ping_ip) { printf("Pinging router %08lX...\n", ping_ip); _send_ping(ping_ip, seq++, 1, IPTOS_DEFAULT, &ping_id); } else printf("No router for interface %d\n", kb - '0'); } else printf("No interface selected.\n"); } else if (kb == 'a') { if (act_ip && *astate != STATE_DONT_USE) { printf("Closing active connection to %s...\n", inet_ntoa(buf, act_ip)); sock_close(asock); while (tcp_tick(asock)); } *astate = STATE_DONT_USE; printf("Enter a host name or IP address [TCP/IP now blocked]\n"); gets(buf); printf("Resolving...\n"); act_ip = resolve(buf); if (act_ip) { printf("Enter a port number to connect to (0-65535)\n"); gets(buf); aport = (word)atol(buf); printf("Opening to %s:%u...\n", inet_ntoa(buf, act_ip), aport); *astate = STATE_ACTOPEN; } else printf("Could not resolve %s to IP address.\n", buf); } else if (isdigit(kb)) { // Toggle interface status kb -= '0'; if (!(1u<<kb & IF_SET)) { printf("Not a valid interface\n"); continue; } if (ifstatus(kb)) { printf("Bringing interface %d down...\n", kb); ifconfig(kb, IFS_DOWN, IFS_END); } else { printf("Bringing interface %d up...\n", kb); ifconfig(kb, IFS_UP, IFS_END); } } } if (ping_ip) { if (_chk_ping(ping_ip , &ping_id) != 0xffffffffL) { printf("Got ping response from %08lX\n", ping_ip); ping_ip = 0; } } switch (state[socknum]) { case STATE_CLOSED: if (!tcp_extlisten(s + socknum, IF_ANY, ECHO_PORT, 0, 0, t_handler, 0, 0, 0)) { printf("Listen failed - socket %d\n", socknum); state[socknum] = STATE_DONT_USE; break; } printf("Listening on socket %d...\n", socknum); state[socknum] = STATE_LISTEN; break; case STATE_ACTOPEN: if (!tcp_extopen(s + socknum, IF_ANY, 0, act_ip, aport, t_handler, 0, 0)) { printf("Active open failed\n"); state[socknum] = STATE_DONT_USE; break; } state[socknum] = STATE_LISTEN; break; case STATE_LISTEN: if (sock_established(s + socknum)) { printf("Connection %d estab.\n", socknum); state[socknum] = STATE_ESTAB; } break; case STATE_ESTAB: if ((rb = sock_fastread(s + socknum, buf, sizeof(buf))) > 0) { sock_fastwrite(s + socknum, buf, rb); if (!strncmp(buf, "quit", 4)) { printf("Peer on socket %d requests close\n", socknum); sock_close(s + socknum); state[socknum] = STATE_CLOSING; } } else if (rb < 0) { printf("Connection %d closed by peer.\n", socknum); sock_close(s + socknum); state[socknum] = STATE_CLOSING; } break; default: break; } } }
int printlog_cgi(HttpState *state) { auto int bytes_written; switch (state->substate) { case PRTLOG_INIT: // Temporarily cast const away since the p member in HttpState is a // general purpose pointer state->p = (char *) &prtlog_header[0]; state->substate = PRTLOG_HEADER; read_log_reset(); // intentionally no break case PRTLOG_HEADER: if (*state->p) { bytes_written = sock_fastwrite(&state->s, state->p, strlen(state->p)); if (bytes_written > 0) { state->p += bytes_written; } } else { state->p = NULL; state->offset = 0; state->substate = PRTLOG_PRTITEM; } break; case PRTLOG_PRTITEM: if (state->p == NULL || *state->p == '\0' || *state->p == '\xff') { read_log(state->buffer, 128); if (strlen(state->buffer)) { //still reading out log contents state->p = state->buffer; state->offset = 0; } else { state->offset = 0; // Temporarily cast const away since the p member in HttpState is // a general purpose pointer state->p = (char *) &prtlog_footer[0]; state->substate = PRTLOG_FOOTER; } ++state->offset; } else { bytes_written = sock_fastwrite(&state->s, state->p, strlen(state->p)); if (bytes_written > 0) { state->p += bytes_written; } } break; case PRTLOG_FOOTER: if (*state->p) { bytes_written = sock_fastwrite(&state->s, state->p, strlen(state->p)); if (bytes_written > 0) { state->p += bytes_written; } } else { return 1; // done } break; } return 0; }
void main(void) { // index is used to loop through the interfaces int index; // Initialize the TCP/IP stack sock_init(); // Initialize the state machine structure for (index = 0; index <= VIRTUAL_ETH; index++) { socks[index].state = LSTN_STATE; socks[index].iface = 0; memset(socks[index].buff, 0, sizeof(socks[index].buff)); socks[index].bytes = 0; } // Perform network configuration on the main (physical) Ethernet ineterface printf("Bringing up Main Interface %2d:\n", socks[0].iface); ifconfig(IF_ETH0, IFS_IPADDR, aton(LOCAL_IP), IFS_NETMASK, aton(LOCAL_NETMASK), IFS_ROUTER_SET,aton(LOCAL_GATEWAY), IFS_UP, IFS_END); // Wait for the interface to come up while (ifpending(IF_ETH0) == IF_COMING_UP) { tcp_tick(NULL); } printf("Main Interface %2d: is up!!\n", socks[0].iface); // Configure each of the virtual Ethernet interfaces for (index = 1; index <= VIRTUAL_ETH; index++) { // virtual_eth() creates a new virtual Ethernet interface and returns // the new interface number socks[index].iface = virtual_eth(IF_ETH0, aton(LOCAL_IP) + index, aton(LOCAL_NETMASK), NULL); if (socks[index].iface != -1) { printf("Created Virtual Interface %2d:\n", socks[index].iface); } else { exit(0); } // Wait for the virtual Ethernet interface to come up while (ifpending(socks[index].iface) == IF_COMING_UP) { tcp_tick(NULL); } printf("Virtual Interface %2d: is up!!\n", socks[index].iface); } // Print out information on the interfaces ip_print_ifs(); // Begin the main program loop while (1) { // Iterate over the Ethernet interfaces for (index = 0; index <= VIRTUAL_ETH; index++) { switch (socks[index].state) { // Listen on the socket case LSTN_STATE: // Note that the iface number is passed to tcp_extlisten() if (tcp_extlisten(&socks[index].s, socks[index].iface, LOCAL_PORT, 0, 0, NULL, 0, 0, 0)) { socks[index].state = ESTB_STATE; socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer printf("Interface %2d: listening on port: %5d\n", socks[index].iface, LOCAL_PORT); } else { // tcp_extlisten() failed--let the user know printf("Interface %2d: tcp_extlisten failed\n", socks[index].iface); socks[index].state = CLSE_STATE; socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer } break; // Check if a connection has been established case ESTB_STATE: if (sock_established(&socks[index].s) || sock_bytesready(&socks[index].s) >= 0) { socks[index].state = RECV_STATE; socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer printf("Interface %2d: socket established.\n", socks[index].iface); } break; // Check if data has been received. If so, read it out. case RECV_STATE: // Read any incoming data socks[index].bytes = sock_fastread(&socks[index].s, socks[index].buff, sizeof(socks[index].buff)); if (socks[index].bytes == -1) { // sock_fastread() returned an error--means that the socket is // likely closed printf("Interface %2d: sock_fastread failed\n", socks[index].iface); socks[index].state = CLSE_STATE; socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer } // Check if we received any data if (socks[index].bytes > 0) { printf("Interface %2d: revd: %2d bytes\n", socks[index].iface, socks[index].bytes); socks[index].state = SEND_STATE; // send the data back socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer } break; // Echo back any received data case SEND_STATE: socks[index].bytes = sock_fastwrite(&socks[index].s, socks[index].buff, socks[index].bytes); if (socks[index].bytes == -1) { // sock_fastwrite() returned an error--means that the socket // is likely closed printf("Interface %2d: sock_fastwrite failed\n", socks[index].iface); socks[index].state = CLSE_STATE; socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer } // Check how much data was written. Note that in this program, // if not all the data was written, the remaining data will be // dropped. A more realistic program would try sending the rest // of the data later, or using sock_awrite() until the data can // be sent. if (socks[index].bytes > 0) { printf("Interface %2d: sent: %2d bytes\n", socks[index].iface, socks[index].bytes); socks[index].state = RECV_STATE; socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer } break; // Close the socket case CLSE_STATE: sock_close(&socks[index].s); socks[index].state = CLWT_STATE; socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer break; // Wait for the socket to completely close case CLWT_STATE: if (!sock_alive(&socks[index].s)) { printf("Interface %2d: socket closed.\n", socks[index].iface); socks[index].state = LSTN_STATE; socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer } break; // Abort the socket--used only if a socket has timed out in one of // the closing states case ABRT_STATE: sock_abort(&socks[index].s); // abort the socket socks[index].state = LSTN_STATE; // try to listen again socks[index].timer = SEC_TIMER + TIME2WAIT; // reset the timer break; } // Drive the TCP/IP stack tcp_tick(NULL); // Check the timeout on this socket, and close or abort the socket // if necessary timed_out(index); } } }
int ftpsession(struct Url *url,struct HTTPrecord *cache,char *uploadfile) { longword host; char str[256]; char buffer[BUFLEN+2]; tcp_Socket datasocket; word dataport=0; int rv=0,len; char *ptr,*datahostptr,datahost[80]; char isdir=0,retry=0;//,ascii=0; long total=0; //!!glennmcc: Nov 11, 2007 -- for 'dblp code' below int dblp=0; //!!glennmcc: end //!!glennmcc: Nov 13, 2007 -- for EZNOS2 fix below int eznos2=0; //!!glennmcc: end int log; if(!tcpip)return 0; free_socket(); if((!url->file[0] || url->file[strlen(url->file)-1]=='/') && !uploadfile) isdir=1; sprintf(str,msg_askdns,url->host); outs(str); GlobalLogoStyle=0; //SDL set resolve animation host=resolve_fn( url->host, (sockfunct_t) TcpIdleFunc ); //SDL // host=resolve( url->host ); if(!host) { DNSerr(url->host); return 0; } // if(!uploadfile) //!glennmcc: Oct 20, 2012 - commented-out to make upload log more verbose log=a_open("FTP.LOG",O_BINARY|O_WRONLY|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE); GlobalLogoStyle=2; //SDL set connect animation if (!tcp_open( socket, locport(), host, url->port, NULL )) { sprintf(str,msg_errcon,url->host); outs(str); return 0; } sprintf(str,msg_con,url->host,url->port); outs(str); write(log,str,strlen(str)); write(log,"\r\n",2); sock_wait_established(socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status); //SDL GlobalLogoStyle=1; //SDL set data animation sock_mode( socket, TCP_MODE_ASCII ); outs(MSG_LOGIN); do { sock_wait_input( socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL sock_gets( socket, (unsigned char *)buffer, sizeof( buffer )); outs(buffer); write(log,buffer,strlen(buffer)); write(log,"\r\n",2); // printf("FTP daemon said>"); // puts(buffer); if ( *buffer != '2' && buffer[0]!=' ') goto quit; } while(buffer[3]=='-' || buffer[0]==' '); //continued message! if(!url->user[0]) ptr="anonymous"; else ptr=url->user; sprintf( str, "USER %s", ptr); write(log,str,strlen(str)); write(log,"\r\n",2); sock_puts(socket,(unsigned char *)str); sock_wait_input( socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL sock_gets( socket, (unsigned char *)buffer, sizeof( buffer )); outs(buffer); write(log,buffer,strlen(buffer)); write(log,"\r\n",2); // printf("FTP daemon said>"); // puts(buffer); //!!glennmcc: May 11, 2005 //removed due to the fact that not all sites use '3' //see additional info below with respect to anonymous password // if ( *buffer != '3' ) goto quit; //!!glennmcc: end //open cache filename: //!glennmcc: Oct 20, 2012 - commented-out to make upload log more verbose // if(uploadfile) // strcpy(cache->locname,"FTP.LOG"); // else //!glennmcc end: Oct 20, 2012 { //!!glennmcc: Oct 22, 2008 -- strchr() was preventing the use of 'CachePath .\cache\' // ptr=strchr(cache->locname,'.'); ptr=strrchr(cache->locname,'.'); //!!glennmcc: end if(ptr) { strcpy(&ptr[1],"FTP"); strcpy(cache->rawname,cache->locname); } } cache->handle=a_open(cache->locname,O_BINARY|O_WRONLY|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE); if(cache->handle<0) goto quit; strcpy(cache->mime,"text/plain"); if(url->password[0]) ptr=url->password; else { if(url->user[0] && !strcmp(url->host,AUTHENTICATION->host) && !strcmp(AUTHENTICATION->realm,"$ftp")) ptr=AUTHENTICATION->password; else { ptr=configvariable(&ARACHNEcfg,"FakeFTPeMail",NULL); if(!ptr || !strchr(ptr,'@')) { ptr=configvariable(&ARACHNEcfg,"eMail",NULL); if(!ptr) ptr="@"; } } } //!!glennmcc: May 11, 2005 //some sites do not require a password after 'anonymous' //therefer, this entire block is now within this 'if()' so that //the password (email address), will only be sent if asked for //!!glennmcc: Nov 13, 2007 -- EZNOS2 says "Enter PASS command" if (strstr(buffer,"sword") || strstr(buffer,"Enter PASS command")) //if (strstr(buffer,"sword"))//original line { sprintf( str, "PASS %s", ptr); sock_puts(socket,(unsigned char *)str); write(log,str,strlen(str)); write(log,"\r\n",2); }//!!glennmcc: inserted Mar 02, 2008 //Some servers need the following 'do/while' section, //therefore, only the section above for sending the password needs to be //'blocked' when no password was requested. do { sock_wait_input( socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL sock_gets( socket, (unsigned char *)buffer, sizeof( buffer )); outs(buffer); write(log,buffer,strlen(buffer)); write(log,"\r\n",2); // printf("FTP daemon said>"); // puts(buffer); if (strstr(buffer,"Enter PASS command")) eznos2=1; if (*buffer != '2' && buffer[0]!=' ' && !eznos2) { write(cache->handle,buffer,strlen(buffer)); rv=1; goto quit; } else if ((buffer[3]=='-' || buffer[0]==' ') && (isdir || uploadfile)) { strcat(buffer,"\r\n"); rv=1; write(cache->handle,buffer,strlen(buffer)); } } while(buffer[3]=='-' || buffer[0]==' ' || buffer[0]=='3'); //continued message! //}//!!glennmcc: end May 11, 2005 -- removed on Mar 02, 2008 //ask server where we have to connect: sock_puts(socket,(unsigned char *)"PASV"); sock_wait_input( socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL sock_gets( socket, (unsigned char *)buffer, sizeof( buffer )); outs(buffer); write(log,buffer,strlen(buffer)); write(log,"\r\n",2); // printf("FTP daemon said>"); // puts(buffer); //2xx Entering passive mode (a,b,c,d,x,y) if ( *buffer != '2' ) goto quit; datahostptr=strchr(buffer,'('); //!!glennmcc: Nov 13, 2007 -- EZNOS2 doesn't enclose the info in () //therefore, if '(' is not found... look for the last 'space'. if(!datahostptr) {datahostptr=strrchr(buffer,' '); eznos2=1;} //if that still fails... 'quit' //!!glennmcc: end if(!datahostptr) goto quit;//original line ptr=++datahostptr; { int carka=0; char *portptr=NULL; while(*ptr) { if(*ptr==',') { carka++; if(carka<4) *ptr='.'; else if(carka==4) { *ptr='\0'; portptr=ptr+1; } else if (carka==5) { *ptr='\0'; dataport=256*(word)atoi(portptr); // ,x,y -> 256*x+y portptr=ptr+1; //!!glennmcc: Nov 13, 2007 -- part of above fix for EZNO2 info not in () if(eznos2) dataport+=atoi(portptr); // ,x,y -> 256*x+y //!!glennmcc: end } } else if(*ptr==')' && portptr) { //!!glennmcc: Nov 11, 2007 -- some servers have double ')' // at the end of the port address info... // this 'dblp code' will prevent that from adding the final set twice //eg: (99,167,219,186,234,255)) instead of.... (99,167,219,186,234,255) //without this fix ... 255 gets added a 2nd time and //we end-up-with... port 60414 instead of the correct port of 60159 *ptr='\0'; if(!dblp)//!!glennmcc: Nov 11, 2007 dataport+=atoi(portptr); // ,x,y -> 256*x+y dblp=1;//!!glennmcc: Nov 11, 2007 } ptr++; } } if(!dataport) goto quit; //!!glennmcc: Aug 31, 2009 //EZNOS2 sends the IP of the machine on a router as datahost //therefore we need to go back to the original host if(eznos2) { makestr(datahost,url->host,79); outs(datahost); Piip(); } else //!!glennmcc:end makestr(datahost,datahostptr,79);//original line retry: if(isdir) { if(url->file[0]) { //!!glennmcc: Oct 15, 2007 -- fix problems with CWD on FTP servers //which interpret the leading '/' as an attempted CD to 'root' if(url->file[0]=='/') sprintf( str, "CWD %s", url->file+1); else //!!glennmcc: end Oct 15, 2007 sprintf( str, "CWD %s", url->file); sock_puts(socket,(unsigned char *)str); do { sock_wait_input( socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL sock_gets( socket, (unsigned char *)buffer, sizeof( buffer )); outs(buffer); //!!glennmcc: Apr 08, 2005 -- commented-out this block // to fix the problem of 'broken dir listing' when the // 'FTP welcome message' contains linefeeds // such as at ftp://ftp.cdrom.com/.2/simtelnet/ /* if ( *buffer != '2' && buffer[0]!=' ') { write(cache->handle,buffer,strlen(buffer)); rv=1; goto quit; } else if (buffer[3]=='-' || buffer[0]==' ') */ //!!glennmcc: end { strcat(buffer,"\r\n"); rv=1; write(cache->handle,buffer,strlen(buffer)); } } //!!glennmcc: Apr 08, 2005 -- added a test for !=' ' which is also // needed for the same fix at ftp://ftp.cdrom.com/.2/simtelnet/ while(buffer[3]=='-' || buffer[3]!=' ' || buffer[0]==' '); //continued message! // while(buffer[3]=='-' || buffer[0]==' '); //continued message! //!!glennmcc: end } strcpy(cache->mime,"ftp/list"); sprintf( str, "LIST"); } else { char *fnameptr; char mimestr[80]="ftp/binary"; fnameptr=strrchr(url->file,'/'); if(!fnameptr) { fnameptr=strrchr(url->file,'\\'); if(!fnameptr) fnameptr=url->file; else fnameptr++; } else fnameptr++; sprintf( str, "TYPE I"); if(fnameptr) { char ext[5]; strcpy(mimestr,"file/"); strncat(mimestr,fnameptr,70); mimestr[79]='\0'; get_extension(mimestr,ext); if(!strncmpi(ext,"TXT",3) || !strncmpi(ext,"HTM",3)) { //!!glennmcc: begin June 09, 2002 //optionally upload TXT and HTM in binary mode ptr=configvariable(&ARACHNEcfg,"UseBinaryFTP",NULL); if(!ptr || toupper(*ptr)=='N') //!!glennmcc: end sprintf( str, "TYPE A"); // ascii=1; } } strcpy(cache->mime,mimestr); sock_puts(socket,(unsigned char *)str); write(log,str,strlen(str)); write(log,"\r\n",2); sock_wait_input( socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL sock_gets( socket, (unsigned char *)buffer, sizeof( buffer )); outs(buffer); write(log,buffer,strlen(buffer)); write(log,"\r\n",2); // printf("FTP daemon said>"); // puts(buffer); if ( *buffer != '2' || uploadfile) { strcat(buffer,"\n"); write(cache->handle,buffer,strlen(buffer)); } if ( *buffer != '2' ) { rv=1; goto quit; } if(!uploadfile) //!!glennmcc: Oct 17, 2007 -- fix problems with FTP servers //which interpret the leading '/' as an attempted CD to 'root' if(url->file[0]=='/') sprintf( str, "RETR %s", url->file+1); else sprintf( str, "RETR %s", url->file); //original single line above this comment //!!glennmcc: end else sprintf( str, "STOR %s", url->file); } sock_puts(socket,(unsigned char *)str); write(log,str,strlen(str)); write(log,"\r\n",2); //!!glennmcc: Oct 19, 2008 -- back to original fix //!!glennmcc: Nov 15, 2007 -- always 'close' the connection when done //with both dir listings and file downloads //Apr 10, 2007 fix did it only for dir listings if(isdir || strstr(str,"RETR")) //if(isdir) sock_puts(socket,(unsigned char *)"QUIT");//!!glennmcc: Apr 10, 2007 //!!glennmcc: end if(!retry) { //get file using datahost & dataport GlobalLogoStyle=0; //SDL set resolve animation host=resolve_fn( datahost, (sockfunct_t) TcpIdleFunc ); //SDL // host=resolve( datahost ); if(!host) goto quit; GlobalLogoStyle=2; //SDL set connect animation if (!tcp_open( &datasocket, locport(), host, dataport, NULL )) { sprintf(str,msg_errcon,datahost); outs(str); goto quit; } sprintf(str,msg_con,datahost,dataport); outs(str); write(log,str,strlen(str)); write(log,"\r\n",2); //wait for datasocket to open: sock_wait_established(&datasocket, sock_delay, (sockfunct_t) TcpIdleFunc, &status); //SDL //!!glennmcc: Sep 27, 2008 -- increase D/L speed on cable & DSL //many thanks to 'mik' for pointing me in the right direction. :) { #ifdef DEBUG char sp[80]; sprintf(sp,"Available stack = %u bytes",_SP); outs(sp); Piip(); Piip(); #endif if(_SP>(1024*SETBUFSIZE)) { char setbuf[1024*SETBUFSIZE]; sock_setbuf(&datasocket, (unsigned char *)setbuf, 1024*SETBUFSIZE); } } //!!glennmcc: end GlobalLogoStyle=1; //SDL set data animation } //wait for "110 openning connection" (or "550 ....error....") sock_wait_input( socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL sock_gets( socket, (unsigned char *)buffer, sizeof( buffer )); outs(buffer); write(log,buffer,strlen(buffer)); write(log,"\r\n",2); // printf("FTP daemon said>"); // puts(buffer); if ( *buffer != '1' || uploadfile) { strcat(buffer,"\n"); write(cache->handle,buffer,strlen(buffer)); } if ( *buffer != '1' ) { if(!strncmp(buffer,"550",3) && !retry) { retry=1; isdir=1-isdir; if(isdir) strcat(url->file,"/"); else { int i=strlen(url->file); if(i>0 && url->file[i-1]=='/') url->file[i-1]='\0'; } goto retry; } strcpy(cache->mime,"text/plain"); rv=1; goto dataquit; } if(!uploadfile) //-------------------------------------- download --------------- { while ( 1 ) { xChLogoTICK(1); if(GUITICK()) if(GLOBAL.gotolocation || GLOBAL.abort) goto dataquit; if (sock_dataready( &datasocket )) { len = sock_fastread( &datasocket, (unsigned char*)buffer, BUFLEN ); write(cache->handle,buffer,len); total+=len; sprintf(str,MSG_BYTESR,MSG_DOWNLD,total); outs(str); } else sock_tick( &datasocket, &status ); //shift TCP/IP } } else //-------------------------------------- upload ------------------ { int f,lenread,done; long length; char pom[256]; /* if(ascii) f=a_sopen(uploadfile,O_RDONLY|O_TEXT, SH_DENYNO, S_IREAD); else*/ f=a_sopen(uploadfile,O_RDONLY|O_BINARY, SH_DENYNO, S_IREAD); if(f<0) goto dataquit; lenread=done=0; length=0l; { long filel=a_filelength(f); while(1) { sprintf(pom,MSG_UPLOAD,length,filel); outs(pom); //!!glennmcc:Oct 23, 2008 -- 'reversed the logic' // to keep from overflowing at 21megs if(filel>100) percentbar((int)(length/(filel/100))); // percentbar((int)(100*length/filel)); lenread=a_read(f,buffer,BUFLEN); length+=lenread; if(lenread<=0) done=1; //wait until we can write to socket: while(sock_tbleft(&datasocket)<lenread) //SDL // while( datasocket.datalen > 1024) { sock_tick(&datasocket,&status); xChLogoTICK(1); // animation of logo if(GUITICK()) goto dataquit; } if(done) { sock_close( &datasocket ); a_close(f); goto dataclose; } sock_fastwrite(&datasocket,(unsigned char *)buffer,lenread); sock_tick(&datasocket,&status); }//loop } } dataquit: //!!glennmcc: Nov 15, 2007 -- removed sock_abort because it was // sometimes preventing the connection from being closed, // therefore preventing access to several files within a short time // due to too many connections open from the same IP // sock_abort( &datasocket );//original line //!!glennmcc: end dataclose: outs(MSG_CLOSE); sock_puts(socket,(unsigned char *)"QUIT");//!!glennmcc: Dec 04, 2006 sock_wait_closed( &datasocket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL if(uploadfile) { sock_wait_input( socket, sock_delay, (sockfunct_t) TcpIdleFunc, &status ); //SDL sock_gets( socket, (unsigned char *)buffer, sizeof( buffer )); outs(buffer); } quit: sock_puts(socket,(unsigned char *)"QUIT"); sock_close( socket ); closing[socknum]=1; sock_keepalive[socknum][0]='\0'; // sock_wait_closed( socket, sock_delay, NULL, &status ); //we will better wait because we are about to deallocate datasocket sock_err: switch (status) { case 1 : /* foreign host closed */ write(log,MSG_CLOSE,strlen(MSG_CLOSE)); write(log,"\r\n",2); close(log); break; case -1: /* timeout */ sprintf(str,MSG_TCPERR, sockerr(socket)); outs(str); write(log,str,strlen(str)); write(log,"\r\n",2); close(log); break; } if(total) { cache->knowsize=1; cache->size=total; rv=1; } if(cache->handle>=0) { a_close(cache->handle); rv=1; } return rv; }
void main() { int state; long timeout; int bytes_read; static char buffer[64]; static tcp_Socket socket; // Initialize I/O to use PowerCoreFLEX prototyping board brdInit(); serXopen(BAUD_RATE); // set up serial port serMode(0); sock_init(); // initialize DCRTCP tcp_reserveport(PORT); // set up PORT for SYN Queueing // which will hold a pending connection // until we are ready to process it. state=CONNECTION_INIT; while(1) { if(state==CONNECTION_OPEN) { if(debounce_key()) { sock_close(&socket); state=CONNECTION_CLOSED; } } /* * Make sure that the connection hasn't closed on us. * */ if(tcp_tick(&socket)==0 && state!=CONNECTION_INIT) { sock_close(&socket); state=CONNECTION_CLOSED; } switch(state) { case CONNECTION_INIT: tcp_listen(&socket,PORT,0,0,NULL,0); state=CONNECTION_LISTEN; break; case CONNECTION_LISTEN: if(sock_established(&socket)) { state=CONNECTION_OPEN; timeout=SEC_TIMER+TIMEOUT; serXrdFlush(); serXwrFlush(); led(RESET_LED); } break; case CONNECTION_OPEN: /* * close the socket on a timeout * */ if((long) (SEC_TIMER-timeout) >= 0) { sock_close(&socket); state=CONNECTION_CLOSED; break; } /* * read as many bytes from the socket as we have * room in the serial buffer. Also strip out the * telnet commands. */ bytes_read = 0; if(sock_bytesready(&socket) != -1) { bytes_read=sock_fastread(&socket, buffer, min(sizeof(buffer), serXwrFree())); bytes_read=strip_telnet_cmds(buffer, bytes_read); } /* * close the socket on an error * */ if(bytes_read<0) { sock_close(&socket); state=CONNECTION_CLOSED; break; } /* * copy any bytes that we read * */ if(bytes_read > 0) { timeout=SEC_TIMER+TIMEOUT; serXwrite(buffer, bytes_read); } /* * read as many bytes from the serial port as we * have room in the socket buffer. * */ bytes_read=serXread(buffer,min(sizeof(buffer),sock_tbleft(&socket)),100); if(bytes_read>0) { timeout=SEC_TIMER+TIMEOUT; if(sock_fastwrite(&socket,buffer,bytes_read)<0) { sock_close(&socket); state=CONNECTION_CLOSED; } } led(TOGGLE_LED); break; case CONNECTION_CLOSED: serXrdFlush(); serXwrFlush(); sprintf(buffer, "\n\rConnection closed\n\r"); serXwrite(buffer, strlen(buffer)); led(RESET_LED); state=CONNECTION_INIT; break; } } }