示例#1
0
/* Prints up to 16 characters in hexdump style with optional colors
 * if `ascii' is non-zero, an additional ascii representation is printed
 */
void hexdump_line(int fd, const void *data, ssize_t len,
                  int offset, int ascii,
                  const char *description,
                  const unsigned char *indices,
                  const char *colors[])
{
	int i, cur = -1;
	char c;

	if ( description != NULL )
		fd_printf(fd, "           %s%s%s\n", desc_color, description, reset);

	for (i=0; i<16; i++)
	{
		if (i == 0)
		{
			if (offset)
				fd_printf(fd, "%08x  ", data);
			else
				fd_printf(fd, "          ");
		}
		else if (i % 8 == 0)
			fd_printf(fd, " ");

		if (i < len)
		{
			if ( indices && colors && (cur != indices[i]) )
				fd_printf(fd, "%s", colors[cur = indices[i]]);

			fd_printf(fd, " %02x", ((const unsigned char *)data)[i]);
		}
		else
			fd_printf(fd, "   ");
	}

	if (indices && colors)
		fd_printf(fd, "\033[m");

	if (ascii && len > 0)
	{
		cur = -1;
		fd_printf(fd, "   |");

		for (i=0; i<16; i++)
		{
			if (i == len)
				break;

			if ( indices && colors && (cur != indices[i]) )
				fd_printf(fd, "%s", colors[cur = indices[i]]);

			c = ((const unsigned char *)data)[i];
			fd_printf(fd, "%c", isprint(c)?c:'.');
		}

		if (indices && colors)
			fd_printf(fd, "\033[m");

		fd_printf(fd, "|");
	}

	fd_printf(fd, "\n");
}
示例#2
0
/* Read a character (until one is available) and store it in buffer */
static void vtty_read_and_store(vtty_t *vtty,int *fd_slot)
{
   int c;
   
   /* wait until we get a character input */
   c = vtty_read(vtty,fd_slot);
  
   /* if read error, do nothing */
   if (c < 0) return;

   /* If something was read, make sure the handler is informed */
   vtty->input_pending = TRUE;  

   if (!vtty->terminal_support) {
      vtty_store(vtty,c);
      return;
   }
  
   switch(vtty->input_state) {
      case VTTY_INPUT_TEXT :
         switch(c) {
            case 0x1b:
               vtty->input_state = VTTY_INPUT_VT1;
               return;

            /* Ctrl + ']' (0x1d, 29), or Alt-Gr + '*' (0xb3, 179) */
            case 0x1d:
            case 0xb3:
               if (ctrl_code_ok == 1) {
                 vtty->input_state = VTTY_INPUT_REMOTE;
               } else {
                 vtty_store(vtty,c);
               }
               return;
            case IAC :
               vtty->input_state = VTTY_INPUT_TELNET;
               return;
            case 0:  /* NULL - Must be ignored - generated by Linux telnet */
            case 10: /* LF (Line Feed) - Must be ignored on Windows platform */
               return;
            default:
               /* Store a standard character */
               vtty_store(vtty,c);
               return;
         }
         
      case VTTY_INPUT_VT1 :
         switch(c) {
            case 0x5b:
               vtty->input_state = VTTY_INPUT_VT2;
               return;
            default:
               vtty_store(vtty,0x1b);
               vtty_store(vtty,c);
         }
         vtty->input_state = VTTY_INPUT_TEXT;
         return;
  
      case VTTY_INPUT_VT2 :
         switch(c) {
            case 0x41:   /* Up Arrow */
               vtty_store(vtty,16);
               break;
            case 0x42:   /* Down Arrow */
               vtty_store(vtty,14);
               break;
            case 0x43:   /* Right Arrow */
               vtty_store(vtty,6);
               break;
            case 0x44:   /* Left Arrow */
               vtty_store(vtty,2);
               break;
            default:
               vtty_store(vtty,0x5b);
               vtty_store(vtty,0x1b);
               vtty_store(vtty,c);
               break;
         }
         vtty->input_state = VTTY_INPUT_TEXT;
         return;
  
      case VTTY_INPUT_REMOTE :
         remote_control(vtty, c);
         vtty->input_state = VTTY_INPUT_TEXT;
         return;
  
      case VTTY_INPUT_TELNET :
         vtty->telnet_cmd = c;
         switch(c) {
            case WILL:
            case WONT:
            case DO:
            case DONT:
               vtty->input_state = VTTY_INPUT_TELNET_IYOU;
               return;
            case SB :
               vtty->telnet_cmd = c;
               vtty->input_state = VTTY_INPUT_TELNET_SB1;
               return;
            case SE:
               break;
            case IAC :
               vtty_store(vtty, IAC);
               break;
         }
         vtty->input_state = VTTY_INPUT_TEXT;
         return;
  
      case VTTY_INPUT_TELNET_IYOU :
         vtty->telnet_opt = c;
         /* if telnet client can support ttype, ask it to send ttype string */
         if ((vtty->telnet_cmd == WILL) && 
             (vtty->telnet_opt == TELOPT_TTYPE)) 
         {
            vtty_put_char(vtty, IAC);
            vtty_put_char(vtty, SB);
            vtty_put_char(vtty, TELOPT_TTYPE);
            vtty_put_char(vtty, TELQUAL_SEND);
            vtty_put_char(vtty, IAC);
            vtty_put_char(vtty, SE);
         }
         vtty->input_state = VTTY_INPUT_TEXT;
         return;
  
      case VTTY_INPUT_TELNET_SB1 :
         vtty->telnet_opt = c;
         vtty->input_state = VTTY_INPUT_TELNET_SB2;
         return;
  
      case VTTY_INPUT_TELNET_SB2 :
         vtty->telnet_qual = c;
         if ((vtty->telnet_opt == TELOPT_TTYPE) && 
             (vtty->telnet_qual == TELQUAL_IS))
            vtty->input_state = VTTY_INPUT_TELNET_SB_TTYPE;
         else
            vtty->input_state = VTTY_INPUT_TELNET_NEXT;
         return;
  
      case VTTY_INPUT_TELNET_SB_TTYPE :
         /* parse ttype string: first char is sufficient */
         /* if client is xterm or vt, set the title bar */
         if ((c == 'x') || (c == 'X') || (c == 'v') || (c == 'V')) {
            fd_printf(*fd_slot,0,"\033]0;%s\07", vtty->vm->name);
         }
         vtty->input_state = VTTY_INPUT_TELNET_NEXT;
         return;
  
      case VTTY_INPUT_TELNET_NEXT :
         /* ignore all chars until next IAC */
         if (c == IAC)
            vtty->input_state = VTTY_INPUT_TELNET;
         return;
   }
}
示例#3
0
文件: picocom.c 项目: Rosonix/picocom
int
run_cmd(int fd, const char *cmd, const char *args_extra)
{
	pid_t pid;
	sigset_t sigm, sigm_old;

	/* block signals, let child establish its own handlers */
	sigemptyset(&sigm);
	sigaddset(&sigm, SIGTERM);
	sigprocmask(SIG_BLOCK, &sigm, &sigm_old);

	pid = fork();
	if ( pid < 0 ) {
		sigprocmask(SIG_SETMASK, &sigm_old, NULL);
		fd_printf(STO, "*** cannot fork: %s ***\r\n", strerror(errno));
		return -1;
	} else if ( pid ) {
		/* father: picocom */
		int status, r;

		/* reset the mask */
		sigprocmask(SIG_SETMASK, &sigm_old, NULL);
		/* wait for child to finish */
		do {
			r = waitpid(pid, &status, 0);
		} while ( r < 0 && errno == EINTR );
		/* reset terminal (back to raw mode) */
		term_apply(STI, 0);
		/* check and report child return status */
		if ( WIFEXITED(status) ) { 
			fd_printf(STO, "\r\n*** exit status: %d ***\r\n", 
					  WEXITSTATUS(status));
			return WEXITSTATUS(status);
		} else if ( WIFSIGNALED(status) ) {
			fd_printf(STO, "\r\n*** killed by signal: %d ***\r\n", 
					  WTERMSIG(status));
			return -1;
		} else {
			fd_printf(STO, "\r\n*** abnormal termination: 0x%x ***\r\n", r);
			return -1;
		}
	} else {
		/* child: external program */
		long fl;
		int argc;
		char *argv[RUNCMD_ARGS_MAX + 1];
		int r;
			
		/* unmanage terminal, and reset it to canonical mode */
		term_remove(STI);
		/* unmanage serial port fd, without reset */
		term_erase(fd);
		/* set serial port fd to blocking mode */
		fl = fcntl(fd, F_GETFL); 
		fl &= ~O_NONBLOCK;
		fcntl(fd, F_SETFL, fl);
		/* connect stdin and stdout to serial port */
		close(STI);
		close(STO);
		dup2(fd, STI);
		dup2(fd, STO);
		
		/* build command arguments vector */
		argc = 0;
		r = split_quoted(cmd, &argc, argv, RUNCMD_ARGS_MAX);
		if ( r < 0 ) {
			fd_printf(STDERR_FILENO, "Cannot parse command\n");
			exit(RUNCMD_EXEC_FAIL);
		}
		r = split_quoted(args_extra, &argc, argv, RUNCMD_ARGS_MAX);
		if ( r < 0 ) {
			fd_printf(STDERR_FILENO, "Cannot parse extra args\n");
			exit(RUNCMD_EXEC_FAIL);
		}
		if ( argc < 1 ) {
			fd_printf(STDERR_FILENO, "No command given\n");
			exit(RUNCMD_EXEC_FAIL);
		}	
		argv[argc] = NULL;
			
		/* run extenral command */
		fd_printf(STDERR_FILENO, "$ %s %s\n", cmd, args_extra);
		establish_child_signal_handlers();
		sigprocmask(SIG_SETMASK, &sigm_old, NULL);
		execvp(argv[0], argv);

		fd_printf(STDERR_FILENO, "exec: %s\n", strerror(errno));
		exit(RUNCMD_EXEC_FAIL);
	}
}
示例#4
0
文件: picocom.c 项目: Rosonix/picocom
/* Process command key. Returns non-zero if command results in picocom
   exit, zero otherwise. */
int
do_command (unsigned char c)
{
	static int dtr_up = 0;
	int newbaud, newflow, newparity, newbits, newstopbits;
	const char *xfr_cmd;
	char *fname;
	int r;

	switch (c) {
	case KEY_EXIT:
		return 1;
	case KEY_QUIT:
		term_set_hupcl(tty_fd, 0);
		term_flush(tty_fd);
		term_apply(tty_fd, 1);
		term_erase(tty_fd);
		return 1;
	case KEY_STATUS:
		show_status(dtr_up);
		break;
	case KEY_HELP:
	case KEY_KEYS:
		show_keys();
		break;
	case KEY_PULSE:
		fd_printf(STO, "\r\n*** pulse DTR ***\r\n");
		if ( term_pulse_dtr(tty_fd) < 0 )
			fd_printf(STO, "*** FAILED\r\n");
		break;
	case KEY_TOGGLE:
		if ( dtr_up )
			r = term_lower_dtr(tty_fd);
		else
			r = term_raise_dtr(tty_fd);
		if ( r >= 0 ) dtr_up = ! dtr_up;
		fd_printf(STO, "\r\n*** DTR: %s ***\r\n", 
				  dtr_up ? "up" : "down");
		break;
	case KEY_BAUD:
	case KEY_BAUD_UP:
	case KEY_BAUD_DN:
		if ( c== KEY_BAUD) {
			newbaud = read_baud();
			if ( newbaud < 0 ) {
				fd_printf(STO, "*** cannot read baudrate ***\r\n");
				break;
			}
			opts.baud = newbaud;
		} else if (c == KEY_BAUD_UP) {
			opts.baud = baud_up(opts.baud);
		} else {
			opts.baud = baud_down(opts.baud);
		}
		term_set_baudrate(tty_fd, opts.baud);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newbaud = term_get_baudrate(tty_fd, NULL);
		if ( opts.baud != newbaud ) {
			fd_printf(STO, "\r\n*** baud: %d (%d) ***\r\n", 
					  opts.baud, newbaud);
		} else {
			fd_printf(STO, "\r\n*** baud: %d ***\r\n", opts.baud);
		}
		set_tty_write_sz(newbaud);
		break;
	case KEY_FLOW:
		opts.flow = flow_next(opts.flow);
		term_set_flowcntrl(tty_fd, opts.flow);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newflow = term_get_flowcntrl(tty_fd);
		if ( opts.flow != newflow ) {
			fd_printf(STO, "\r\n*** flow: %s (%s) ***\r\n", 
					  flow_str[opts.flow], flow_str[newflow]);
		} else {
			fd_printf(STO, "\r\n*** flow: %s ***\r\n", 
					  flow_str[opts.flow]);
		}
		break;
	case KEY_PARITY:
		opts.parity = parity_next(opts.parity);
		term_set_parity(tty_fd, opts.parity);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newparity = term_get_parity(tty_fd);
		if (opts.parity != newparity ) {
			fd_printf(STO, "\r\n*** parity: %s (%s) ***\r\n",
					  parity_str[opts.parity], 
					  parity_str[newparity]);
		} else {
			fd_printf(STO, "\r\n*** parity: %s ***\r\n", 
					  parity_str[opts.parity]);
		}
		break;
	case KEY_BITS:
		opts.databits = bits_next(opts.databits);
		term_set_databits(tty_fd, opts.databits);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newbits = term_get_databits(tty_fd);
		if (opts.databits != newbits ) {
			fd_printf(STO, "\r\n*** databits: %d (%d) ***\r\n",
					  opts.databits, newbits);
		} else {
			fd_printf(STO, "\r\n*** databits: %d ***\r\n", 
					  opts.databits);
		}
		break;
	case KEY_STOP:
		opts.stopbits = stopbits_next(opts.stopbits);
		term_set_stopbits(tty_fd, opts.stopbits);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newstopbits = term_get_stopbits(tty_fd);
		if (opts.stopbits != newstopbits ) {
			fd_printf(STO, "\r\n*** stopbits: %d (%d) ***\r\n",
					  opts.stopbits, newstopbits);
		} else {
			fd_printf(STO, "\r\n*** stopbits: %d ***\r\n", 
					  opts.stopbits);
		}
		break;
	case KEY_LECHO:
		opts.lecho = ! opts.lecho;
		fd_printf(STO, "\r\n*** local echo: %s ***\r\n", 
				  opts.lecho ? "yes" : "no");
		break;
	case KEY_SEND:
	case KEY_RECEIVE:
		xfr_cmd = (c == KEY_SEND) ? opts.send_cmd : opts.receive_cmd;
		if ( xfr_cmd[0] == '\0' ) {
			fd_printf(STO, "\r\n*** command disabled ***\r\n");
			break;
		}
		fname = read_filename();
		if (fname == NULL) {
			fd_printf(STO, "*** cannot read filename ***\r\n");
			break;
		}
		run_cmd(tty_fd, xfr_cmd, fname);
		free(fname);
		break;
	case KEY_BREAK:
		term_break(tty_fd);
		fd_printf(STO, "\r\n*** break sent ***\r\n");
		break;
	default:
		break;
	}

	return 0;
}
示例#5
0
文件: picocom.c 项目: Rosonix/picocom
void
show_status (int dtr_up) 
{
	int baud, bits, stopbits, mctl;
	enum flowcntrl_e flow;
	enum parity_e parity;

	term_refresh(tty_fd);

	baud = term_get_baudrate(tty_fd, NULL);
	flow = term_get_flowcntrl(tty_fd);
	parity = term_get_parity(tty_fd);
	bits = term_get_databits(tty_fd);
	stopbits = term_get_stopbits(tty_fd);
	
	fd_printf(STO, "\r\n");
 
	if ( baud != opts.baud ) {
		fd_printf(STO, "*** baud: %d (%d)\r\n", opts.baud, baud);
	} else { 
		fd_printf(STO, "*** baud: %d\r\n", opts.baud);
	}
	if ( flow != opts.flow ) {
		fd_printf(STO, "*** flow: %s (%s)\r\n", 
				  flow_str[opts.flow], flow_str[flow]);
	} else {
		fd_printf(STO, "*** flow: %s\r\n", flow_str[opts.flow]);
	}
	if ( parity != opts.parity ) {
		fd_printf(STO, "*** parity: %s (%s)\r\n", 
				  parity_str[opts.parity], parity_str[parity]);
	} else {
		fd_printf(STO, "*** parity: %s\r\n", parity_str[opts.parity]);
	}
	if ( bits != opts.databits ) {
		fd_printf(STO, "*** databits: %d (%d)\r\n", opts.databits, bits);
	} else {
		fd_printf(STO, "*** databits: %d\r\n", opts.databits);
	}
	if ( stopbits != opts.stopbits ) {
		fd_printf(STO, "*** stopbits: %d (%d)\r\n", opts.stopbits, stopbits);
	} else {
		fd_printf(STO, "*** stopbits: %d\r\n", opts.stopbits);
	}

	mctl = term_get_mctl(tty_fd);
	if (mctl >= 0 && mctl != MCTL_UNAVAIL) {
		if ( ((mctl & MCTL_DTR) ? 1 : 0) == dtr_up )  
			fd_printf(STO, "*** dtr: %s\r\n", dtr_up ? "up" : "down");
		else
			fd_printf(STO, "*** dtr: %s (%s)\r\n", 
					  dtr_up ? "up" : "down",
					  (mctl & MCTL_DTR) ? "up" : "down");
		fd_printf(STO, "*** mctl: ");
		fd_printf(STO, "DTR:%c DSR:%c DCD:%c RTS:%c CTS:%c RI:%c\r\n",
				  (mctl & MCTL_DTR) ? '1' : '0',
				  (mctl & MCTL_DSR) ? '1' : '0',
				  (mctl & MCTL_DCD) ? '1' : '0',
				  (mctl & MCTL_RTS) ? '1' : '0',
				  (mctl & MCTL_CTS) ? '1' : '0',
				  (mctl & MCTL_RI) ? '1' : '0');
	} else {
		fd_printf(STO, "*** dtr: %s\r\n", dtr_up ? "up" : "down");
	}
}
示例#6
0
文件: picocom.c 项目: Rosonix/picocom
void
show_keys()
{
#ifndef NO_HELP
	fd_printf(STO, "\r\n");
	fd_printf(STO, "*** Picocom commands (all prefixed by [C-%c])\r\n",
			  KEYC(opts.escape));
	fd_printf(STO, "\r\n");
	fd_printf(STO, "*** [C-%c] : Exit picocom\r\n", 
			  KEYC(KEY_EXIT));
	fd_printf(STO, "*** [C-%c] : Exit without reseting serial port\r\n", 
			  KEYC(KEY_QUIT));
	fd_printf(STO, "*** [C-%c] : Set baudrate\r\n", 
			  KEYC(KEY_BAUD));
	fd_printf(STO, "*** [C-%c] : Increase baudrate (baud-up)\r\n", 
			  KEYC(KEY_BAUD_UP));
	fd_printf(STO, "*** [C-%c] : Decrease baudrate (baud-down)\r\n",
			  KEYC(KEY_BAUD_DN));;
	fd_printf(STO, "*** [C-%c] : Change number of databits\r\n",
			  KEYC(KEY_BITS));
	fd_printf(STO, "*** [C-%c] : Change number of stopbits\r\n",
			  KEYC(KEY_STOP));
	fd_printf(STO, "*** [C-%c] : Change flow-control mode\r\n",
			  KEYC(KEY_FLOW));
	fd_printf(STO, "*** [C-%c] : Change parity mode\r\n",
			  KEYC(KEY_PARITY));
	fd_printf(STO, "*** [C-%c] : Pulse DTR\r\n",
			  KEYC(KEY_PULSE));
	fd_printf(STO, "*** [C-%c] : Toggle DTR\r\n",
			  KEYC(KEY_TOGGLE));
	fd_printf(STO, "*** [C-%c] : Send break\r\n",
			  KEYC(KEY_BREAK));
	fd_printf(STO, "*** [C-%c] : Toggle local echo\r\n",
			  KEYC(KEY_LECHO));
	fd_printf(STO, "*** [C-%c] : Send file\r\n",
			  KEYC(KEY_SEND));
	fd_printf(STO, "*** [C-%c] : Receive file\r\n",
			  KEYC(KEY_RECEIVE));
	fd_printf(STO, "*** [C-%c] : Show port settings\r\n",
			  KEYC(KEY_STATUS));
	fd_printf(STO, "*** [C-%c] : Show this message\r\n",
			  KEYC(KEY_HELP));
	fd_printf(STO, "\r\n");
#else /* defined NO_HELP */
	fd_printf(STO, "*** Help is disabled.\r\n");
#endif /* of NO_HELP */
}
示例#7
0
文件: picocom.c 项目: Rosonix/picocom
void
loop(void)
{
	enum {
		ST_COMMAND,
		ST_TRANSPARENT
	} state;
	fd_set rdset, wrset;
	int r, n;
	unsigned char c;

	tty_q.len = 0;
	state = ST_TRANSPARENT;

	while ( ! sig_exit ) {
		FD_ZERO(&rdset);
		FD_ZERO(&wrset);
		FD_SET(STI, &rdset);
		FD_SET(tty_fd, &rdset);
		if ( tty_q.len ) FD_SET(tty_fd, &wrset);

		r = select(tty_fd + 1, &rdset, &wrset, NULL, NULL);
		if ( r < 0 )  {
			if ( errno == EINTR )
				continue;
			else
				fatal("select failed: %d : %s", errno, strerror(errno));
		}

		if ( FD_ISSET(STI, &rdset) ) {

			/* read from terminal */

			do {
				n = read(STI, &c, 1);
			} while (n < 0 && errno == EINTR);
			if (n == 0) {
				fatal("stdin closed");
			} else if (n < 0) {
				/* is this really necessary? better safe than sory! */
				if ( errno != EAGAIN && errno != EWOULDBLOCK ) 
					fatal("read from stdin failed: %s", strerror(errno));
				else
					goto skip_proc_STI;
			}

			switch (state) {
			case ST_COMMAND:
				if ( c == opts.escape ) {
					/* pass the escape character down */
					if (tty_q.len + M_MAXMAP <= TTY_Q_SZ) {
						n = do_map((char *)tty_q.buff + tty_q.len, 
								   opts.omap, c);
						tty_q.len += n;
						if ( opts.lecho ) 
							map_and_write(STO, opts.emap, c);
					} else {
						fd_printf(STO, "\x07");
					}
				} else {
					/* process command key */
					if ( do_command(c) )
						/* picocom exit */
						return;
				}
				state = ST_TRANSPARENT;
				break;
			case ST_TRANSPARENT:
				if ( c == opts.escape ) {
					state = ST_COMMAND;
				} else {
					if (tty_q.len + M_MAXMAP <= TTY_Q_SZ) {
						n = do_map((char *)tty_q.buff + tty_q.len, 
								   opts.omap, c);
						tty_q.len += n;
						if ( opts.lecho ) 
							map_and_write(STO, opts.emap, c);
					} else 
						fd_printf(STO, "\x07");
				}
				break;
			default:
				assert(0);
				break;
			}
		}
	skip_proc_STI:

		if ( FD_ISSET(tty_fd, &rdset) ) {

			char buff_rd[TTY_RD_SZ];
			char buff_map[TTY_RD_SZ * M_MAXMAP];

			/* read from port */

			do {
				n = read(tty_fd, &buff_rd, sizeof(buff_rd));
			} while (n < 0 && errno == EINTR);
			if (n == 0) {
				fatal("term closed");
			} else if ( n < 0 ) {
				if ( errno != EAGAIN && errno != EWOULDBLOCK )
					fatal("read from term failed: %s", strerror(errno));
			} else {
				int i;
				char *bmp = &buff_map[0];
				for (i = 0; i < n; i++) {
					bmp += do_map(bmp, opts.imap, buff_rd[i]);
				}
				n = bmp - buff_map;
				if ( writen_ni(STO, buff_map, n) < n )
					fatal("write to stdout failed: %s", strerror(errno));
			}
		}

		if ( FD_ISSET(tty_fd, &wrset) ) {

			/* write to port */

			int sz;
			sz = (tty_q.len < tty_write_sz) ? tty_q.len : tty_write_sz;
			do {
				n = write(tty_fd, tty_q.buff, sz);
			} while ( n < 0 && errno == EINTR );
			if ( n <= 0 )
				fatal("write to term failed: %s", strerror(errno));
			memmove(tty_q.buff, tty_q.buff + n, tty_q.len - n);
			tty_q.len -= n;
		}
	}
}
示例#8
0
/**
 * Updates current->cols with the current window size (width),
 * and     current->rows with the current window rows (height)
 */
static int getWindowSize(struct current *current)
{
    struct winsize ws;

    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0) {
        current->cols = ws.ws_col;
        current->rows = ws.ws_row;
        return 0;
    }

    /* Failed to query the window size. Perhaps we are on a serial terminal.
     * Try to query the width by sending the cursor as far to the right
     * and reading back the cursor position.
     * Note that this is only done once per call to linenoise rather than
     * every time the line is refreshed for efficiency reasons.
     *
     * In more detail, we:
     * (a) request current cursor position,
     * (b) move cursor far right, far down
     * (c) request cursor position again,
     * (d) at last move back to the old position.
     * This gives us the width without messing with the externally
     * visible cursor position.
     *
     * Console codes:
     * A up
     * B down
     * C right
     * D left
     *
     * For portability we are NOT using the control sequences
     *    ESC [ s
     *    ESC [ u
     * to save and restore the cursor position, as many terminal
     * emulators do not honor them.
     */

    if (current->cols == 0) {
        int herec;
        int herel;

        current->cols = 80;
	current->rows = 25;

        /* (a) */
        if (queryCursor (current->fd, &herec, &herel)) {
            /* (b) */
            fd_printf(current->fd, "\x1b[999C\x1b[999B");

            /* (c). Note: If (a) succeeded, then (c) should as well.
             * For paranoia we still check and have a fallback action
             * for (d) in case of failure..
             */
            if (!queryCursor (current->fd, &current->cols, &current->rows)) {
                /* (d') Unable to get accurate position data, reset
                 * the cursor to the far left. While this may not
                 * restore the exact original position it should not
                 * be too bad. We will have lost the vertical position
		 * however.
                 */
                fd_printf(current->fd, "\r");
            } else {
                /* (d) Reset the cursor back to the original location. */
                if (current->cols > herec) {
                    fd_printf(current->fd, "\x1b[%dD", current->cols - herec);
                }
                if (current->rows > herel) {
                    fd_printf(current->fd, "\x1b[%dA", current->rows - herel);
                }
            }
        } /* 1st query failed, doing nothing => default 80 */
    }

    return 0;
}
示例#9
0
static void eraseEol(struct current *current)
{
    fd_printf(current->fd, "\x1b[0K");
}
示例#10
0
static void setCursorPos(struct current *current, int x)
{
    fd_printf(current->fd, "\r\x1b[%dC", x);
}
示例#11
0
static void outputControlChar(struct current *current, char ch)
{
    fd_printf(current->fd, "\x1b[7m^%c\x1b[0m", ch);
}
示例#12
0
static void cursorToLeft(struct current *current)
{
    fd_printf(current->fd, "\r");
}
示例#13
0
static void clearScreen(struct current *current)
{
    fd_printf(current->fd, "\x1b[H\x1b[2J");
}
示例#14
0
NOEXPORT void imap_server(CLI *c) {
    char *line, *id, *tail, *capa;

    s_poll_init(c->fds);
    s_poll_add(c->fds, c->local_rfd.fd, 1, 0);
    switch(s_poll_wait(c->fds, 0, 200)) {
    case 0: /* fd not ready to read */
        s_log(LOG_DEBUG, "RFC 2595 detected");
        break;
    case 1: /* fd ready to read */
        s_log(LOG_DEBUG, "RFC 2595 not detected");
        return; /* return if RFC 2595 is not used */
    default: /* -1 */
        sockerror("RFC2595 (s_poll_wait)");
        longjmp(c->err, 1);
    }

    /* process server welcome and send it to client */
    line=fd_getline(c, c->remote_fd.fd);
    if(!is_prefix(line, "* OK")) {
        s_log(LOG_ERR, "Unknown server welcome");
        str_free(line);
        longjmp(c->err, 1);
    }
    capa=strstr(line, "CAPABILITY");
    if(!capa)
        capa=strstr(line, "capability");
    if(capa)
        *capa='K'; /* disable CAPABILITY within greeting */
    fd_printf(c, c->local_wfd.fd, "%s (stunnel)", line);

    id=str_dup("");
    while(1) { /* process client commands */
        str_free(line);
        line=fd_getline(c, c->local_rfd.fd);
        /* split line into id and tail */
        str_free(id);
        id=str_dup(line);
        tail=strchr(id, ' ');
        if(!tail)
            break;
        *tail++='\0';

        if(is_prefix(tail, "STARTTLS")) {
            fd_printf(c, c->local_wfd.fd,
                "%s OK Begin TLS negotiation now", id);
            str_free(line);
            str_free(id);
            return; /* success */
        } else if(is_prefix(tail, "CAPABILITY")) {
            fd_putline(c, c->remote_fd.fd, line); /* send it to server */
            str_free(line);
            line=fd_getline(c, c->remote_fd.fd); /* get the capabilites */
            if(*line=='*') {
                /*
                 * append STARTTLS
                 * should also add LOGINDISABLED, but can't because
                 * of Mozilla bug #324138/#312009
                 * LOGIN would fail as "unexpected command", anyway
                 */
                fd_printf(c, c->local_wfd.fd, "%s STARTTLS", line);
                str_free(line);
                line=fd_getline(c, c->remote_fd.fd); /* next line */
            }
            fd_putline(c, c->local_wfd.fd, line); /* forward to the client */
            tail=strchr(line, ' ');
            if(!tail || !is_prefix(tail+1, "OK")) { /* not OK? */
                fd_putline(c, c->local_wfd.fd,
                    "* BYE unexpected server response");
                s_log(LOG_ERR, "Unexpected server response: %s", line);
                break;
            }
        } else if(is_prefix(tail, "LOGOUT")) {
            fd_putline(c, c->local_wfd.fd, "* BYE server terminating");
            fd_printf(c, c->local_wfd.fd, "%s OK LOGOUT completed", id);
            break;
        } else {
            fd_putline(c, c->local_wfd.fd, "* BYE stunnel: unexpected command");
            fd_printf(c, c->local_wfd.fd, "%s BAD %s unexpected", id, tail);
            s_log(LOG_ERR, "Unexpected client command %s", tail);
            break;
        }
    }
    /* clean server shutdown */
    str_free(id);
    fd_putline(c, c->remote_fd.fd, "stunnel LOGOUT");
    str_free(line);
    line=fd_getline(c, c->remote_fd.fd);
    if(*line=='*') {
        str_free(line);
        line=fd_getline(c, c->remote_fd.fd);
    }
    str_free(line);
    longjmp(c->err, 2); /* don't reset */
}
示例#15
0
文件: picocom.c 项目: Rosonix/picocom
int
main(int argc, char *argv[])
{
	int r;

	parse_args(argc, argv);

	establish_signal_handlers();

	r = term_lib_init();
	if ( r < 0 )
		fatal("term_init failed: %s", term_strerror(term_errno, errno));

#ifdef UUCP_LOCK_DIR
	if ( ! opts.nolock ) uucp_lockname(UUCP_LOCK_DIR, opts.port);
	if ( uucp_lock() < 0 )
		fatal("cannot lock %s: %s", opts.port, strerror(errno));
#endif

	tty_fd = open(opts.port, O_RDWR | O_NONBLOCK | O_NOCTTY);
	if (tty_fd < 0)
		fatal("cannot open %s: %s", opts.port, strerror(errno));

#ifdef USE_FLOCK
	if ( ! opts.nolock ) {
		r = flock(tty_fd, LOCK_EX | LOCK_NB);
		if ( r < 0 )
			fatal("cannot lock %s: %s", opts.port, strerror(errno));
	}
#endif

	if ( opts.noinit ) {
		r = term_add(tty_fd);
	} else {
		r = term_set(tty_fd,
					 1,              /* raw mode. */
					 opts.baud,      /* baud rate. */
					 opts.parity,    /* parity. */
					 opts.databits,  /* data bits. */
					 opts.stopbits,  /* stop bits. */
					 opts.flow,      /* flow control. */
					 1,              /* local or modem */
					 !opts.noreset); /* hup-on-close. */
	}
	if ( r < 0 )
		fatal("failed to add device %s: %s", 
			  opts.port, term_strerror(term_errno, errno));
	r = term_apply(tty_fd, 0);
	if ( r < 0 )
		fatal("failed to config device %s: %s", 
			  opts.port, term_strerror(term_errno, errno));

	set_tty_write_sz(term_get_baudrate(tty_fd, NULL));
	
	r = term_add(STI);
	if ( r < 0 )
		fatal("failed to add I/O device: %s", 
			  term_strerror(term_errno, errno));
	term_set_raw(STI);
	r = term_apply(STI, 0);
	if ( r < 0 )
		fatal("failed to set I/O device to raw mode: %s",
			  term_strerror(term_errno, errno));

#ifdef LINENOISE
	init_history();
#endif

#ifndef NO_HELP
	fd_printf(STO, "Type [C-%c] [C-%c] to see available commands\r\n\r\n",
			  KEYC(opts.escape), KEYC(KEY_HELP));
#endif
	fd_printf(STO, "Terminal ready\r\n");
	loop();

#ifdef LINENOISE
	cleanup_history();
#endif

	fd_printf(STO, "\r\n");
	if ( opts.noreset ) {
		fd_printf(STO, "Skipping tty reset...\r\n");
		term_erase(tty_fd);
	}

	if ( sig_exit )
		fd_printf(STO, "Picocom was killed\r\n");
	else
		fd_printf(STO, "Thanks for using picocom\r\n");
	/* wait a bit for output to drain */
	sleep(1);

#ifdef UUCP_LOCK_DIR
	uucp_unlock();
#endif

	return EXIT_SUCCESS;
}
示例#16
0
NOEXPORT void ntlm(CLI *c) {
    char *line, buf[BUFSIZ], *ntlm1_txt, *ntlm2_txt, *ntlm3_txt, *tmpstr;
    long content_length=0; /* no HTTP content */

    /* send Proxy-Authorization (phase 1) */
    fd_printf(c, c->remote_fd.fd, "Proxy-Connection: keep-alive");
    ntlm1_txt=ntlm1();
    if(!ntlm1_txt) {
        s_log(LOG_ERR, "Proxy-Authenticate: Failed to build NTLM request");
        longjmp(c->err, 1);
    }
    fd_printf(c, c->remote_fd.fd, "Proxy-Authorization: NTLM %s", ntlm1_txt);
    str_free(ntlm1_txt);
    fd_putline(c, c->remote_fd.fd, ""); /* empty line */
    line=fd_getline(c, c->remote_fd.fd);

    /* receive Proxy-Authenticate (phase 2) */
    if(!is_prefix(line, "HTTP/1.0 407") && !is_prefix(line, "HTTP/1.1 407")) {
        s_log(LOG_ERR, "Proxy-Authenticate: NTLM authorization request rejected");
        do { /* read all headers */
            str_free(line);
            line=fd_getline(c, c->remote_fd.fd);
        } while(*line);
        str_free(line);
        longjmp(c->err, 1);
    }
    ntlm2_txt=NULL;
    do { /* read all headers */
        str_free(line);
        line=fd_getline(c, c->remote_fd.fd);
        if(is_prefix(line, "Proxy-Authenticate: NTLM "))
            ntlm2_txt=str_dup(line+25);
        else if(is_prefix(line, "Content-Length: ")) {
            content_length=strtol(line+16, &tmpstr, 10);
            if(tmpstr==line+16 || *tmpstr || content_length<0) {
                s_log(LOG_ERR, "Proxy-Authenticate: Invalid Content-Length");
                str_free(line);
                longjmp(c->err, 1);
            }
        }
    } while(*line);
    if(!ntlm2_txt) { /* no Proxy-Authenticate: NTLM header */
        s_log(LOG_ERR, "Proxy-Authenticate: NTLM header not found");
        str_free(line);
        longjmp(c->err, 1);
    }

    /* read and ignore HTTP content (if any) */
    while(content_length>0) {
        s_read(c, c->remote_fd.fd, buf, s_min(content_length, BUFSIZ));
        content_length-=s_min(content_length, BUFSIZ);
    }

    /* send Proxy-Authorization (phase 3) */
    fd_printf(c, c->remote_fd.fd, "CONNECT %s HTTP/1.1", c->opt->protocol_host);
    fd_printf(c, c->remote_fd.fd, "Host: %s", c->opt->protocol_host);
    ntlm3_txt=ntlm3(c->opt->protocol_username, c->opt->protocol_password, ntlm2_txt);
    str_free(ntlm2_txt);
    if(!ntlm3_txt) {
        s_log(LOG_ERR, "Proxy-Authenticate: Failed to build NTLM response");
        longjmp(c->err, 1);
    }
    fd_printf(c, c->remote_fd.fd, "Proxy-Authorization: NTLM %s", ntlm3_txt);
    str_free(ntlm3_txt);
}
示例#17
0
文件: support.c 项目: rdadolf/msms
int write_section_header(int fd) {
  assert(fd>1 && "Invalid file descriptor");
  fd_printf(fd, "%%%%\n"); // Just prints %%
  return 0;
}