int vdehist_term_to_mgmt(struct vdehiststat *st) { unsigned char buf[BUFSIZE]; int n,i,rv=0; n=vdehist_termread(st->termfd,buf,BUFSIZE); //printf("termto mgmt N%d %x %x %x %x\n",n,buf[0],buf[1],buf[2],buf[3]); if (n==0) return 1; else if (n<0) return n; else { for (i=0;i<n && strlen(st->linebuf)<BUFSIZE;i++) { if (buf[i] == 0xff && buf[i+1] == 0xff) i++; if(buf[i]==0) buf[i]='\n'; /*telnet encode \n as a 0 when in raw mode*/ if (buf[i] == 0xff && buf[i+1] != 0xff) { i+=telnet_options(st,buf+i); } else if(buf[i] == 0x1b) { /* ESCAPE! */ if (buf[i+1]=='[' && st->status == HIST_COMMAND) { st->edited=1; switch (buf[i+2]) { case 'A': //fprintf(stderr,"UP\n"); erase_line(st,0); put_history(st); get_history(1,st); redraw_line(st,0); st->bufindex=strlen(st->linebuf); break; case 'B': //fprintf(stderr,"DOWN\n"); erase_line(st,0); put_history(st); get_history(-1,st); redraw_line(st,0); break; case 'C': //fprintf(stderr,"RIGHT\n"); if (st->linebuf[st->bufindex] != '\0') { vdehist_termwrite(st->termfd,"\033[C",3); (st->bufindex)++; } break; case 'D': //fprintf(stderr,"LEFT\n"); if (st->bufindex > 0) { vdehist_termwrite(st->termfd,"\033[D",3); (st->bufindex)--; } break; } i+=3; } else i+=2;/* ignored */ } else if(buf[i] < 0x20 && !(buf[i] == '\n' || buf[i] == '\r')) { /*ctrl*/ if (buf[i] == 4) /*ctrl D is a shortcut for UNIX people! */ { rv=1; break; } switch (buf[i]) { case 3: /*ctrl C cleans the current buffer */ erase_line(st,0); st->bufindex=0; st->linebuf[(st->bufindex)]=0; break; case 12: /* ctrl L redraw */ erase_line(st,1); redraw_line(st,1); break; case 1: /* ctrl A begin of line */ erase_line(st,0); st->bufindex=0; redraw_line(st,0); break; case 5: /* ctrl E endofline */ erase_line(st,0); st->bufindex=strlen(st->linebuf); redraw_line(st,0); case '\t': /* tab */ if (st->lastchar== '\t') { erase_line(st,1); showexpand(st->linebuf,st->bufindex,st->termfd); redraw_line(st,1); } else { erase_line(st,0); st->bufindex=tabexpand(st->linebuf,st->bufindex,BUFSIZE); redraw_line(st,0); } break; } } else if(buf[i] == 0x7f) { if(st->bufindex > 0) { char *x; (st->bufindex)--; x=st->linebuf+st->bufindex; memmove(x,x+1,strlen(x)); if (st->echo && !(st->status & HIST_PASSWDFLAG)) { if (st->edited) vdehist_termwrite(st->termfd,"\010\033[P",4); else vdehist_termwrite(st->termfd,"\010 \010",3); } } } else { if (st->echo && !(st->status & HIST_PASSWDFLAG)) { if (st->edited && buf[i] >= ' ') vdehist_termwrite(st->termfd,"\033[@",3); vdehist_termwrite(st->termfd,&(buf[i]),1); } if (buf[i] != '\r') { if (buf[i]=='\n') { if (st->status == HIST_COMMAND) { st->histindex=0; put_history(st); if (strlen(st->linebuf) > 0) shift_history(st); } st->bufindex=strlen(st->linebuf); if ((rv=hist_sendcmd(st)) != 0) break; st->bufindex=st->edited=st->histindex=0; st->linebuf[(st->bufindex)]=0; } else { char *x; x=st->linebuf+st->bufindex; memmove(x+1,x,strlen(x)+1); st->linebuf[(st->bufindex)++]=buf[i]; } } } st->lastchar=buf[i]; } } return rv; }
int main ( void ) { char* line; time_t* led_flash_timer; time_t* reboot_timer; socket_t* socket = socket0_g; int reboot_stage = 0; /* Turn off all LEDs as a starting point */ led_clear(); /* this must be first, because all the other init functions call malloc */ init_malloc(); /* Initialize current time and some timers */ init_current_time(); led_flash_timer = init_timer(); set_timer(led_flash_timer, 500); reboot_timer = init_timer(); /* receive packet buffer */ rx_packet_g = malloc(sizeof(packet_t)); /* socket init */ socket0_g = init_socket(0); socket1_g = init_socket(1); /* open ethernet port and wait for connection requests keep trying forever */ while (!open_link()); /* infinite loop. Everything is timer, interrupt and queue driven from here on down */ while (1) { /* Flash a heartbeat LED */ if (timer_expired(led_flash_timer)) { led_flip(0); set_timer(led_flash_timer, 500); } /* Check for newly downloaded tftp file. Add to all tx buffers */ /* Has a file been uploaded via tftp ? */ if (udp_file_g != NULL) { /* Notify telnet clients that file has been received */ if (udp_file_g->ready) { udp_file_g->ready = 0; telnet_broadcast("Received file %s, %d bytes, linux %d\r\n", udp_file_g->filename, udp_file_g->total_bytes, udp_file_g->linux_boot); if (process_file(socket0_g) == 0) /* Disconnect in 1 second */ set_timer(reboot_timer, 1000); else telnet_broadcast("Not an elf file\r\n"); } } /* reboot timer expired */ if (timer_expired(reboot_timer)) { /* First stage of reboot sequence is to nicely disconnect */ if (reboot_stage == 0) { set_timer(reboot_timer, 1000); reboot_stage = 1; socket0_g->tcp_disconnect = 1; socket1_g->tcp_disconnect = 1; } else { /* Second stage of reboot sequence is to turn off ethmac and then jump to restart vector */ close_link(); reboot(); } } /* Poll both sockets in turn for activity */ if (socket == socket0_g) socket = socket1_g; else socket = socket0_g; /* Check if any tcp packets need to be re-transmitted */ tcp_retransmit(socket); /* Handle exit command */ if (socket->tcp_disconnect && socket->tcp_connection_state == TCP_OPEN) { tcp_disconnect(socket); } /* Reset connection */ if (socket->tcp_reset) { socket->tcp_connection_state = TCP_CLOSED; socket->telnet_connection_state = TELNET_CLOSED; socket->telnet_options_sent = 0; tcp_reply(socket, NULL, 0); socket->tcp_reset = 0; } /* Send telnet options */ if (socket->tcp_connection_state == TCP_OPEN && !socket->telnet_options_sent){ telnet_options(socket); socket->telnet_options_sent = 1; } /* telnet connection open Communicate with client */ else if (socket->telnet_connection_state == TELNET_OPEN) { /* Send telnet greeting */ if (!socket->telnet_sent_opening_message){ put_line (socket->telnet_txbuf, "Amber Processor Boot Loader\r\n> "); socket->telnet_sent_opening_message = 1; } /* Parse telnet rx buffer */ if (get_line(socket->telnet_rxbuf, &line)) parse_command (socket, line); /* Transmit text from telnet tx buffer */ telnet_tx(socket, socket->telnet_txbuf); } } }