示例#1
0
文件: input.c 项目: pollyzoid/psh
parsed_line* input_process(input_state* input) {
	parsed_line* line;

	/* set term into unbuffered mode */
	reset_term(input, false);

	/* terminal i/o */
	if (!read_input(input, input->history_current->buffer)) {
		return NULL;
	}
	/* back to buffered */
	reset_term(input, true);
	putc('\n', stdout);

	if (strlen(input->history_current->buffer) == 0) {
		print_prompt();
		return NULL;
	}

	/* parse line */
	line = parse_input(input->history_current);

	history_add(input);
	input->cursor = 0;

	return line;
}
示例#2
0
static void
vi_cmd(const char *command)
{
	char tmpfn[256];
	FILE *fp;
	int i;
	char *sqlch;
	FILE *tmpfp;
	char *line;
	char foobuf[40];
	int tmpfd;
	mode_t old_mask;

	strcpy(tmpfn, "/tmp/fisqlXXXXXX");
	old_mask = umask(077);
	tmpfd = mkstemp(tmpfn);
	umask(old_mask);
	if (tmpfd < 0 || (fp = fdopen(tmpfd, "w")) == NULL) {
		perror("fisql");
		reset_term();
		dbexit();
		exit(2);
	}
	if (ibuflines) {
		for (i = 0; i < ibuflines; i++) {
			fputs(ibuf[i], fp);
			fputc('\n', fp);
			free(ibuf[i]);
		}
	} else {
		for (i = 0; ((sqlch = dbgetchar(dbproc, i)) != NULL); i++) {
			fputc(*sqlch, fp);
		}
	}
	fclose(fp);

	edit(command, tmpfn);

	ibuflines = 0;
	fp = fopen(tmpfn, "r");
	if (!fp) {
		perror("fisql");
		reset_term();
		dbexit();
		exit(2);
	}
	tmpfp = rl_instream;
	rl_instream = fp;
	strcpy(foobuf, "1>> ");
	while ((line = readline(foobuf)) != NULL) {
		append_line(line);
		sprintf(foobuf, "%d>> ", ibuflines + 1);
	}
	rl_instream = tmpfp;
	fclose(fp);
	fputc('\r', stdout);
	fflush(stdout);
	unlink(tmpfn);
}
示例#3
0
文件: main.c 项目: Arigowin/ft_select
int		main(int ac, char **av)
{
	t_all			all;
	int				ret;

	all.elem = NULL;
	all.win.nb_elem = 0;
	all.show = 1;
	if (ac > 1 && av[1] != NULL)
	{
		ft_signal();
		if (init_term(&all))
			return (-1);
		if ((ret = init_lst(&(all.elem), av, &all)) == TRUE)
		{
			memoire(&all, 0);
			ret = ft_select(&all);
		}
		if (reset_term(&all) == -1)
			return (-1);
		if (ret == -2)
			print_select(&all);
		if (all.win.nb_elem > 0)
			freelst(&all);
	}
	return (0);
}
示例#4
0
int getch(void) {
	int ch;
	noecho();
	ch = getchar();
	reset_term();
	return ch;
}
示例#5
0
static void restart_init_handler(int sig_no)
{
  struct action_list_seed *x;
  pid_t pid;
  int fd;

  for (x = action_list_pointer; x; x = x->next) {
    if (!(x->action & RESTART)) continue;

    set_default();

    if (x->terminal_name[0]) {
      close(0);
      fd = open(x->terminal_name, (O_RDWR|O_NONBLOCK),0600);

      if (fd != 0) {
        error_msg("Unable to open %s,%s\n", x->terminal_name, strerror(errno));
        sleep(1);
        pid = vfork();

        if (pid == 0) {
          reboot(RB_HALT_SYSTEM);
          _exit(EXIT_SUCCESS);
        }

        while(1) sleep(1);
      } else {
        dup2(0, 1);
        dup2(0, 2);
        reset_term(0);
        run_command(x->command);
      }
    }
  }
}
示例#6
0
文件: error.c 项目: y0ja/21sh
void	exit_normal(t_all *all, int exit_ret)
{
	if (exit_ret != 42)
		free_all(all);
	reset_term(all);
	exit(exit_ret);
}
示例#7
0
int
edit(const char *editor, const char *arg)
{
	int pid;

      retry_fork:
	pid = fork();
	switch (pid) {
	case -1:
		if (errno == EAGAIN) {
			sleep(5);
			goto retry_fork;
		}
		perror("fisql");
		reset_term();
		dbexit();
		exit(EXIT_FAILURE);
		break;
	case 0:
		execlp(editor, editor, arg, (char *) 0);
		fprintf(stderr, "Unable to invoke the '%s' editor.\n", editor);
		exit(EXIT_FAILURE);
		break;
	default:
		waitpid(pid, (int *) 0, 0);
		break;
	}
	return 0;
}
示例#8
0
文件: signal.c 项目: gygy19/ft_select
void			ctrlc(int sigint)
{
	if (sigint == SIGINT)
	{
		reset_term(TERM);
		exit(0);
	}
}
示例#9
0
文件: input.c 项目: pollyzoid/psh
void input_restore(void) {
	fputs("\n", stdout);
	print_prompt();
	if (strlen(psh->input->history_current->buffer) != 0) {
		reset_term(psh->input, false);
		fputs(psh->input->history_current->buffer, stdout);
	}
	fflush(stdout);
}
示例#10
0
char			*prompt_dispatcher(t_glob *glob, t_prompt *prompt)
{
  char			*str;

  if (isatty(0) && init_termcaps(glob))
    {
      str = termcap_prompt(glob, prompt);
      str = epur_str(str, 1, 0);
      reset_term();
      return (str);
    }
  else
    {
      reset_term();
      str = basic_prompt(glob, prompt);
      str = epur_str(str, 1, 0);
      return (str);
    }
}
示例#11
0
文件: signal.c 项目: 42rdavid/42sh
void			ft_sigtstp(void)
{
	char		cp[2];

	cp[0] = g_data->term.c_cc[VSUSP];
	cp[1] = 0;
	signal(SIGTSTP, SIG_DFL);
	ioctl(0, TIOCSTI, cp);
	reset_term(&g_data->term);
}
示例#12
0
void init_main(void)
{
  struct sigaction sig_act;

  if (getpid() != 1) error_exit("Already running"); 
  printf("Started init\n"); 
  initialize_console();
  reset_term(0);

  if (chdir("/")) perror_exit("Can't cd to /");
  setsid();

  putenv("HOME=/");
  putenv("PATH=/sbin:/usr/sbin:/bin:/usr/bin");
  putenv("SHELL=/bin/sh");
  putenv("USER=root");

  inittab_parsing();  
  signal(SIGUSR1, halt_poweroff_reboot_handler);//halt
  signal(SIGUSR2, halt_poweroff_reboot_handler);//poweroff
  signal(SIGTERM, halt_poweroff_reboot_handler);//reboot
  signal(SIGQUIT, restart_init_handler);//restart init
  memset(&sig_act, 0, sizeof(sig_act));
  sigfillset(&sig_act.sa_mask);
  sigdelset(&sig_act.sa_mask, SIGCONT);
  sig_act.sa_handler = pause_handler;
  sigaction(SIGTSTP, &sig_act, NULL);
  memset(&sig_act, 0, sizeof(sig_act));
  sig_act.sa_handler = catch_signal;
  sigaction(SIGINT, &sig_act, NULL);
  sigaction(SIGHUP, &sig_act, NULL);  
  run_action_from_list(SYSINIT);
  check_if_pending_signals();
  run_action_from_list(WAIT);
  check_if_pending_signals();
  run_action_from_list(ONCE);
  while (1) {
    int suspected_WNOHANG = check_if_pending_signals();

    run_action_from_list(RESPAWN | ASKFIRST);
    suspected_WNOHANG = suspected_WNOHANG|check_if_pending_signals();
    sleep(1);//let cpu breath
    suspected_WNOHANG = suspected_WNOHANG|check_if_pending_signals();
    if (suspected_WNOHANG) suspected_WNOHANG=WNOHANG;

    while(1) {
      pid_t pid = waitpid(-1, NULL, suspected_WNOHANG);

      if (pid <= 0) break;
      mark_as_terminated_process(pid);
      suspected_WNOHANG = WNOHANG;
    }
  }
}
示例#13
0
文件: error.c 项目: y0ja/21sh
void	ft_error(t_all *all, int er)
{
	if (er == SYSCALL_FAIL)
		ft_putstr("A syscall failed...\n");
	if (er == NOTERMENV)
		printf("Specify terminal with setenv TERM.\n");
	else if (er == TERMINFODB)
		printf("Terminfo database could not be found.\n");
	else if (er == TERMNOTDEF)
		printf("Specified term is not defined.\n");
	else if (er == GETATTR)
		printf("tcgetattr() | tcsetattr() | tgetX() failed.\n");
	free_all(all);
	reset_term(all);
	exit(-1);
}
示例#14
0
文件: input.c 项目: pollyzoid/psh
input_state* input_init(void) {
	input_state *input;

	input = malloc(sizeof(input_state));
	input->history_current =
		input->history_first = NULL;
	input->cursor = 0;

	history_load(input);
	history_add(input);

	set_attr(input);
	reset_term(input, false);

	return input;
}
示例#15
0
//runs all same type of actions
static pid_t final_run(struct action_list_seed *x)
{
  pid_t pid;
  int fd;
  sigset_t signal_set;

  sigfillset(&signal_set);
  sigprocmask(SIG_BLOCK, &signal_set, NULL);
  if (x->action & ASKFIRST) pid = fork();
  else pid = vfork();

  if (pid > 0) {
    //parent process or error
    //unblock the signals
    sigfillset(&signal_set);
    sigprocmask(SIG_UNBLOCK, &signal_set, NULL);

    return pid;      
  } else if (pid < 0) {
    perror_msg("fork fail");
    sleep(1);
    return 0;
  }

  //new born child process
  sigset_t signal_set_c;
  sigfillset(&signal_set_c);
  sigprocmask(SIG_UNBLOCK, &signal_set_c, NULL);
  setsid(); //new session

  if (x->terminal_name[0]) {
    close(0);
    fd = open(x->terminal_name, (O_RDWR|O_NONBLOCK),0600);
    if (fd != 0) {
      error_msg("Unable to open %s,%s\n", x->terminal_name, strerror(errno));
      _exit(EXIT_FAILURE);
    } else {
      dup2(0, 1);
      dup2(0, 2);
    }
  }
  reset_term(0);
  run_command(x->command);
  _exit(-1);
}
示例#16
0
int					exit_pgm(int exit_code)
{
	t_node				*tree;
	t_line				*stline;
	t_duo				*env;

	tree = savior_tree(NULL, FALSE);
	savior_history(NULL, FALSE);
	stline = savior_stline(NULL, FALSE);
	env = savior_env(NULL, FALSE);
	del_tree(&tree);
	savior_tree(NULL, TRUE);
	save_history();
	duo_del(&env);
	savior_env(NULL, TRUE);
	reset_term();
	del_stline(&stline);
	savior_stline(NULL, TRUE);
	exit(exit_code);
	return (0);
}
示例#17
0
int		exec_ls(t_data *st, char *path, char *word)
{
	pid_t	father;
	char	*oldir;
	char	**args;

	ft_putstr("\n");
	tputs(tgetstr("cr", NULL), 0, ft_outc);
	oldir = ft_strjoin(getcwd(NULL, 1024), "/");
	chdir(path);
	args = get_tbl_ls(ft_strsplit(get_full_arg_ls(word), ' '));
	reset_term(st);
	father = fork();
	if (father > 0)
		wait(0);
	if (father == 0)
		execve("/bin/ls", args, st->envtab);
	chdir(oldir);
	init_term(st);
	return (1);
}
示例#18
0
文件: exit.c 项目: Zethir/42sh
static int	deal_with_int(t_shell *sh, t_job *job, t_parse *parse)
{
	int		i;
	int		j;

	i = 0;
	j = 1;
	while (parse->argv[j][i])
	{
		if (parse->argv[j][i] < '0' || parse->argv[j][i] > '9')
		{
			ft_putendl_fd("exit: Badly formed number.", 2);
			return (1);
		}
		i++;
	}
	i = ft_atoi(parse->argv[1]);
	free_job(job);
	free_parse(&parse);
	reset_term(sh);
	exit(i);
}
示例#19
0
文件: exit.c 项目: Zethir/42sh
int			do_exit(t_shell *sh, t_job *job, t_parse *parse)
{
	int		i;

	i = 1;
	if (!parse->argv[i])
	{
		free_job(job);
		free_parse(&parse);
		reset_term(sh);
		exit(0);
	}
	while (parse->argv[i])
		i++;
	if (i > 2)
	{
		ft_putendl_fd("exit: Expression Syntax.", 2);
		return (1);
	}
	else if (deal_with_int(sh, job, parse) == 1)
		return (1);
	return (0);
}
示例#20
0
文件: main.c 项目: rle-mino/21sh
int		main(int ac, char **av, char **env)
{
	struct termios		reset;
	t_le				le;
	t_env				*data_env;

	if (ac && av)
		;
	if (tcgetattr(0, &reset) == -1)
		message_handling();
	g_name_prog = NULL;
	signal(SIGWINCH, update_size);
	data_env = create_env(env);
	data_env->reset = reset;
	fill_env(&data_env, env);
	if (init_term(data_env) == 0)
		message_handling();
	init_env(&le, data_env);
	data_env->le = le;
	loop_prompt(data_env);
	free_env(&data_env);
	reset_term(reset);
	return (0);
}
示例#21
0
static void sig_handler(int signo UNUSED_PARAM)
{
	reset_term();
	_exit(EXIT_FAILURE);
}
示例#22
0
文件: tput.c 项目: andreiw/polaris
int
main(int argc, char **argv)
{
	int i, std_argc;
	char *term = getenv("TERM");
	char *cap, std_input = FALSE;
	int setuperr;

	(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	progname = argv[0];

	while ((i = getopt(argc, argv, "ST:")) != EOF) {
		switch (i) {
		case 'T':
			fildes = -1;
			(void) putenv("LINES=");
			(void) putenv("COLUMNS=");
			term = optarg;
			break;

		case 'S':
			std_input = TRUE;
			break;

		case '?':			/* FALLTHROUGH		*/
		usage:				/* FALLTHROUGH		*/
		default:
			(void) fprintf(stderr, gettext(
			"usage:\t%s [-T [term]] capname [parm argument...]\n"),
				progname);
			(void) fprintf(stderr, gettext("OR:\t%s -S <<\n"),
					progname);
			exit(2);
		}
	}

	if (!term || !*term) {
		(void) fprintf(stderr,
			gettext("%s: No value for $TERM and no -T specified\n"),
			progname);
		exit(2);
	}

	(void) setupterm(term, fildes, &setuperr);

	switch (setuperr) {
	case -2:
		(void) fprintf(stderr,
		gettext("%s: unreadable terminal descriptor \"%s\"\n"),
			progname, term);
		exit(3);
		break;

	case -1:
		(void) fprintf(stderr,
			gettext("%s: no terminfo database\n"), progname);
		exit(3);
		break;

	case 0:
	    (void) fprintf(stderr,
			gettext("%s: unknown terminal \"%s\"\n"),
				progname, term);
	    exit(3);
	}

	reset_shell_mode();

	/* command line arguments */
	if (!std_input) {
		if (argc == optind)
			goto usage;

		cap = argv[optind++];

		if (strcmp(cap, "init") == 0)
			initterm();
		else if (strcmp(cap, "reset") == 0)
			reset_term();
		else if (strcmp(cap, "longname") == 0)
			(void) printf("%s\n", longname());
		else
			exit(outputcap(cap, argc, argv));
		return (0);
	} else {			/* standard input argumets	*/
		char buff[128];
		char **v;

		/* allocate storage for the 'faked' argv[] array	*/
		v = (char **)malloc(10 * sizeof (char *));
		for (i = 0; i < 10; i++)
			v[i] = (char *)malloc(32 * sizeof (char));

		while (gets(buff) != NULL) {
			/* read standard input line; skip over empty lines */
			if ((std_argc =
			    sscanf(buff, "%s %s %s %s %s %s %s %s %s %s",
			    v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7],
			    v[8], v[9])) < 1) {
				continue;
			}

			cap = v[0];
			optind = 1;

			if (strcmp(cap, "init") == 0) {
				initterm();
			} else if (strcmp(cap, "reset") == 0) {
				reset_term();
			} else if (strcmp(cap, "longname") == 0) {
				(void) printf("%s\n", longname());
			} else {
				(void) outputcap(cap, std_argc, v);
			}
			(void) fflush(stdout);
		}

		return (0);
	}
}
示例#23
0
static void
read_sql_lines(void)
{
	char *cp;
	char *firstword;
	char firstword_separator;
	char *line = NULL;
	char foobuf[40];
	bool in_comment = false;

	reset_ibuf();
	while (1) {
		if (no_prompt) {
			foobuf[0] = '\0';
		} else {
			sprintf(foobuf, "%d>> ", ibuflines + 1);
		}
		free(line);
		line = readline(foobuf);
		if (line == NULL) {
			reset_term();
			dbexit();
			exit(default_exit);
		}
		for (cp = line; *cp && isspace((unsigned char) *cp); cp++)
			continue;
		if (*cp) {
			add_history(line);
		}
		if (in_comment) {
			goto append_line;
		}
		if (!(strncasecmp(line, "!!", 2))) {
			system_cmd(line + 2);
			continue;
		}
		/* XXX: isql off-by-one line count error for :r not duplicated */
		if (!(strncasecmp(line, ":r", 2))) {
			readfile_cmd(line);
			continue;
		}
		firstword = line;
		firstword_separator = '\0';
		for (cp = firstword; *cp; cp++) {
			if (isspace((unsigned char) *cp)) {
				firstword_separator = *cp;
				*cp = '\0';
				break;
			}
		}
		if ((!(strcasecmp(firstword, "exit")))
		    || (!(strcasecmp(firstword, "quit")))) {
			reset_term();
			dbexit();
			exit(default_exit);
		}
		if (!(strcasecmp(firstword, "reset"))) {
			reset_ibuf();
			continue;
		}
		if (!(strcasecmp(firstword, cmdend))) {
			if (ibuflines == 0) {
				continue;
			}
			break;
		}
		if ((!(strcasecmp(firstword, "vi")))
		    || (!(strcasecmp(firstword, editor)))) {
			vi_cmd(firstword);
			continue;
		}
		firstword[strlen(firstword)] = firstword_separator;

append_line:
		in_comment = update_comment(in_comment, line);
		append_line(line);
		line = NULL;
	}
}
示例#24
0
文件: signal.c 项目: 42rdavid/42sh
void			ft_sigexit(void)
{
	reset_term(&g_data->term);
	free(g_data);
	exit(0);
}
示例#25
0
int main(int argc, char **argv) {
        static const char default_list[] = "";

	const char *list;
	char *waitmessage = NULL;
	char *waitprint, *waitsprint;
	int waitseconds=0;
	int alarmlen=0;
	int ignore_control=0;
	struct termios tp;
	int r;
	struct pollfd ufds; /* only one, no need for an array... */
        poptContext context;
	struct poptOption options[] = {
            { "wait", 'c', POPT_ARG_INT, &waitseconds, 0, "Number of seconds to wait for keypress", NULL },
            { "message", 'm', POPT_ARG_STRING, &waitmessage, 0, "Message to print out while waiting for string\nNOTE: The message may have a \"%d\" in it, to hold the number of seconds left to wait.", NULL },
            { "ignore-control-chars", 'i', POPT_ARG_NONE, &ignore_control, 0, "Ignore Control-C and Control-D", NULL },
            POPT_AUTOHELP
            POPT_TABLEEND
        };

	context = poptGetContext("getkey", argc, (const char **)argv, options,
                                POPT_CONTEXT_POSIXMEHARDER);
        poptSetOtherOptionHelp(context, "[keys]");

        r = poptGetNextOpt(context);
        if (r < -1) {
            fprintf(stderr, "%s: %s\n", 
                   poptBadOption(context, POPT_BADOPTION_NOALIAS),
                   poptStrerror(r));

            return -1;
        }
        list = poptGetArg(context);
	if (list != NULL) {
	    char *p;

	    p = strdup(list);
	    list = p;
	    while (*p != 0) {
		*p = toupper(*p);
		p++;
	    }
	} else
	    list = default_list;
	if (waitseconds) {
	    if (waitseconds < 0) {
		fprintf(stderr, "--wait: Invalid time %d seconds\n",
			waitseconds);
		return -1;
	    }
	    alarmlen = waitseconds;
	}

	tcgetattr(0,&tp);
	orig_tp = tp;
	signal(SIGTERM,reset_term);
	if (alarmlen != 0) {
	    signal(SIGALRM,reset_term);
	    alarm(alarmlen);
	}

	tp.c_iflag=0;
	tp.c_oflag &= ~OPOST;
	tp.c_lflag &= ~(ISIG | ICANON);
	tcsetattr(0,TCSANOW,&tp);

	ufds.events = POLLIN;
	ufds.fd = 0;

	if (waitmessage) {
	    waitprint = alloca (strlen(waitmessage)+15); /* long enough */
	    waitprint[0] = '\r';
	    waitsprint = waitprint + 1;
	}

	while (1) {
	    if (waitmessage) {
		sprintf (waitsprint, waitmessage, waitseconds);
		write (1, waitprint, strlen(waitprint));
	    }
	    r = poll(&ufds, 1, alarmlen ? 1000 : -1);
	    if (r == 0) {
		/* we have waited a whole second with no keystroke... */
		waitseconds--;
	    }
	    if (r > 0) {
		char ch;

		read(0, &ch, sizeof(ch));
		ch = toupper(ch);
		/* Die if we get a control-c or control-d */
                if (ignore_control == 0 && (ch == 3 || ch == 4))
		    reset_term(1);
		/* Don't let a null character be interpreted as a match
		   by strchr */
		if (ch != 0
		    && (strcmp(list, "") == 0 || strchr(list, ch) != NULL))
		    reset_term(0);
	    }
	}
}
示例#26
0
static int send_udp(struct mt_packet *packet, int retransmit) {
	int sent_bytes;

	/* Clear keepalive counter */
	keepalive_counter = 0;

	if (!use_raw_socket) {
		/* Init SendTo struct */
		struct sockaddr_in socket_address;
		socket_address.sin_family = AF_INET;
		socket_address.sin_port = htons(MT_MACTELNET_PORT);
		socket_address.sin_addr.s_addr = htonl(INADDR_BROADCAST);

		sent_bytes = sendto(send_socket, packet->data, packet->size, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
	} else {
		sent_bytes = net_send_udp(sockfd, active_interface, srcmac, dstmac, &sourceip,  sourceport, &destip, MT_MACTELNET_PORT, packet->data, packet->size);
	}

	/* 
	 * Retransmit packet if no data is received within
	 * retransmit_intervals milliseconds.
	 */
	if (retransmit) {
		int i;

		for (i = 0; i < MAX_RETRANSMIT_INTERVALS; ++i) {
			fd_set read_fds;
			int reads;
			struct timeval timeout;
			int interval = retransmit_intervals[i] * 1000;

			/* Init select */
			FD_ZERO(&read_fds);
			FD_SET(insockfd, &read_fds);
			timeout.tv_sec = 0;
			timeout.tv_usec = interval;

			/* Wait for data or timeout */
			reads = select(insockfd + 1, &read_fds, NULL, NULL, &timeout);
			if (reads && FD_ISSET(insockfd, &read_fds)) {
				unsigned char buff[1500];
				int result;

				bzero(buff, 1500);
				result = recvfrom(insockfd, buff, 1500, 0, 0, 0);

				/* Handle incoming packets, waiting for an ack */
				if (result > 0 && handle_packet(buff, result) == MT_PTYPE_ACK) {
					return sent_bytes;
				}
			}

			/* Retransmit */
			send_udp(packet, 0);
		}

		if (is_a_tty && terminal_mode) {
			reset_term();
		}

		fprintf(stderr, "\nConnection timed out\n");
		exit(1);
	}
	return sent_bytes;
}
示例#27
0
/*
 * TODO: Rewrite main() when all sub-functionality is tested
 */
int main (int argc, char **argv) {
	int result;
	struct mt_packet data;
	struct sockaddr_in si_me;
	unsigned char buff[1500];
	unsigned char print_help = 0, have_username = 0, have_password = 0;
	int c;
	int optval = 1;

	while (1) {
		c = getopt(argc, argv, "nqt:u:p:vh?");

		if (c == -1) {
			break;
		}

		switch (c) {

			case 'n':
				use_raw_socket = 1;
				break;

			case 'u':
				/* Save username */
				strncpy(username, optarg, sizeof(username) - 1);
				username[sizeof(username) - 1] = '\0';
				have_username = 1;
				break;

			case 'p':
				/* Save password */
				strncpy(password, optarg, sizeof(password) - 1);
				password[sizeof(password) - 1] = '\0';
				have_password = 1;
				break;

			case 't':
				connect_timeout = atoi(optarg);
				break;

			case 'v':
				print_version();
				exit(0);
				break;

			case 'q':
				quiet_mode = 1;
				break;

			case 'h':
			case '?':
				print_help = 1;
				break;

		}
	}
	if (argc - optind < 1 || print_help) {
		print_version();
		fprintf(stderr, "Usage: %s <MAC|identity> [-h] [-n] [-t <timeout>] [-u <username>] [-p <password>]\n", argv[0]);

		if (print_help) {
			fprintf(stderr, "\nParameters:\n");
			fprintf(stderr, "  MAC       MAC-Address of the RouterOS/mactelnetd device. Use mndp to discover it.\n");
			fprintf(stderr, "  identity  The identity/name of your destination device. Uses MNDP protocol to find it.\n");
			fprintf(stderr, "  -n        Do not use broadcast packets. Less insecure but requires root privileges.\n");
			fprintf(stderr, "  -t        Amount of seconds to wait for a response on each interface.\n");
			fprintf(stderr, "  -u        Specify username on command line.\n");
			fprintf(stderr, "  -p        Specify password on command line.\n");
			fprintf(stderr, "  -q        Quiet mode.\n");
			fprintf(stderr, "  -h        This help.\n");
			fprintf(stderr, "\n");
		}
		return 1;
	}

	is_a_tty = isatty(fileno(stdout)) && isatty(fileno(stdin));
	if (!is_a_tty) {
		quiet_mode = 1;
	}

	/* Seed randomizer */
	srand(time(NULL));

	if (use_raw_socket) {
		if (geteuid() != 0) {
			fprintf(stderr, "You need to have root privileges to use the -n parameter.\n");
			return 1;
		}

		sockfd = net_init_raw_socket();
	}

	/* Receive regular udp packets with this socket */
	insockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (insockfd < 0) {
		perror("insockfd");
		return 1;
	}

	if (!use_raw_socket) {
		if (setsockopt(insockfd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval))==-1) {
			perror("SO_BROADCAST");
			return 1;
		}
	}

	/* Need to use, to be able to autodetect which interface to use */
	setsockopt(insockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval));

	/* Get mac-address from string, or check for hostname via mndp */
	if (!query_mndp_or_mac(argv[optind], dstmac, !quiet_mode)) {
		/* No valid mac address found, abort */
		return 1;
	}

	if (!have_username) {
		if (!quiet_mode) {
			printf("Login: "******"%254s", username);
	}

	if (!have_password) {
		char *tmp;
		tmp = getpass(quiet_mode ? "" : "Password: "******"255.255.255.255", &destip);
	memcpy(&sourceip, &(si_me.sin_addr), IPV4_ALEN);

	/* Sessioon key */
	sessionkey = rand() % 65535;

	/* stop output buffering */
	setvbuf(stdout, (char*)NULL, _IONBF, 0);

	if (!quiet_mode) {
		printf("Connecting to %s...", ether_ntoa((struct ether_addr *)dstmac));
	}

	/* Initialize receiving socket on the device chosen */
	memset((char *) &si_me, 0, sizeof(si_me));
	si_me.sin_family = AF_INET;
	si_me.sin_port = htons(sourceport);

	/* Bind to udp port */
	if (bind(insockfd, (struct sockaddr *)&si_me, sizeof(si_me)) == -1) {
		fprintf(stderr, "Error binding to %s:%d, %s\n", inet_ntoa(si_me.sin_addr), sourceport, strerror(errno));
		return 1;
	}

	if (!find_interface() || (result = recvfrom(insockfd, buff, 1400, 0, 0, 0)) < 1) {
		fprintf(stderr, "Connection failed.\n");
		return 1;
	}
	if (!quiet_mode) {
		printf("done\n");
	}

	/* Handle first received packet */
	handle_packet(buff, result);

	init_packet(&data, MT_PTYPE_DATA, srcmac, dstmac, sessionkey, 0);
	outcounter +=  add_control_packet(&data, MT_CPTYPE_BEGINAUTH, NULL, 0);

	/* TODO: handle result of send_udp */
	result = send_udp(&data, 1);

	while (running) {
		fd_set read_fds;
		int reads;
		static int terminal_gone = 0;
		struct timeval timeout;

		/* Init select */
		FD_ZERO(&read_fds);
		if (!terminal_gone) {
			FD_SET(0, &read_fds);
		}
		FD_SET(insockfd, &read_fds);

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;

		/* Wait for data or timeout */
		reads = select(insockfd+1, &read_fds, NULL, NULL, &timeout);
		if (reads > 0) {
			/* Handle data from server */
			if (FD_ISSET(insockfd, &read_fds)) {
				bzero(buff, 1500);
				result = recvfrom(insockfd, buff, 1500, 0, 0, 0);
				handle_packet(buff, result);
			}
			/* Handle data from keyboard/local terminal */
			if (FD_ISSET(0, &read_fds) && terminal_mode) {
				unsigned char keydata[512];
				int datalen;

				datalen = read(STDIN_FILENO, &keydata, 512);

				if (datalen > 0) {
					/* Data received, transmit to server */
					init_packet(&data, MT_PTYPE_DATA, srcmac, dstmac, sessionkey, outcounter);
					add_control_packet(&data, MT_CPTYPE_PLAINDATA, &keydata, datalen);
					outcounter += datalen;
					send_udp(&data, 1);
				} else {
					terminal_gone = 1;
				}
			}
		/* Handle select() timeout */
		} else {
			/* handle keepalive counter, transmit keepalive packet every 10 seconds
			   of inactivity  */
			if (keepalive_counter++ == 10) {
				struct mt_packet odata;
				init_packet(&odata, MT_PTYPE_ACK, srcmac, dstmac, sessionkey, outcounter);
				send_udp(&odata, 0);
			}
		}
	}

	if (is_a_tty && terminal_mode) {
		/* Reset terminal back to old settings */
		reset_term();
	}

	close(sockfd);
	close(insockfd);

	return 0;
}
示例#28
0
int
main(int argc, char *argv[])
{
	int echo = 0;

#ifdef notyet
	int print_statistics = 0;
#endif
	int fipsflagger = 0;
	int perfstats = 0;
	int no_prompt = 0;
	int use_encryption = 0;
	int chained_transactions = 0;
	const char *cmdend = "go";
	int headers = 0;
	char *columnwidth = NULL;
	const char *colseparator = " ";
	const char *lineseparator = "\n";
	int timeout = 0;
	char *username = NULL;
	char *password = NULL;
	char *server = NULL;
	DBCHAR *char_set = NULL;
	const char *editor;
	char *hostname = NULL;
	char *sqlch;
	char *interfaces_filename = NULL;
	char *input_filename = NULL;
	char *output_filename = NULL;
	int logintime = -1;
	char *language = NULL;
	int size = 0;
	char *sybenv;
	DBPROCESS *dbproc;
	LOGINREC *login;
	char **ibuf = NULL;
	int ibuflines = 0;
	int printedlines;
	int i;
	char *line;
	int dbrc;
	char foobuf[512];
	char *firstword;
	char *cp;
	int c;
	int errflg = 0;
	char *prbuf;
	int prbuflen;
	FILE *fp;
	FILE *tmpfp;
	FILE *tmpfp2;
	char *tfn;
	char tmpfn[256];
	int num_cols;
	int selcol;
	int col;
	int collen;
	DBINT colid;
	const char *opname;
	char adbuf[512];
	DBINT convlen;
	int printedcompute = 0;
	char adash;
	const char *database_name = NULL;
	int default_exit = EXIT_SUCCESS;

	setlocale(LC_ALL, "");

#ifdef __VMS
	/* Convert VMS-style arguments to Unix-style */
	parse_vms_args(&argc, &argv);
#endif

	editor = getenv("EDITOR");
	if (!editor) {
		editor = getenv("VISUAL");
	}
	if (!editor) {
		editor = "vi";
	}

	opterr = 0;
	optarg = NULL;
	while (!errflg && (c = getopt(argc, argv, "eFgpnvXYa:c:D:E:h:H:i:I:J:l:m:o:P:s:S:t:U:w:y:z:A:"))
	       != -1) {
		switch (c) {
		case 'e':
			echo = 1;
			break;
		case 'F':
			fipsflagger = 1;
			break;
		case 'g':
			errflg++;
			break;
		case 'p':
			errflg++;
			perfstats = 1;
			break;
		case 'n':
			no_prompt = 1;
			break;
		case 'v':
			puts("fisql, a free isql replacement by Nicholas S. Castellano");
			exit(EXIT_SUCCESS);
			break;
		case 'X':
			/* XXX: We get a different error message than isql gives; neither seems
			 * to work
			 */
			use_encryption = 1;
			break;
		case 'Y':
			chained_transactions = 1;
			break;
		case 'c':
			cmdend = optarg;
			break;
		case 'E':
			editor = optarg;
			break;
		case 'h':
			headers = atoi(optarg);
			break;
		case 'H':
			hostname = optarg;
			break;
		case 'i':
			input_filename = optarg;
			break;
		case 'I':
			interfaces_filename = optarg;
			break;
		case 'J':
			errflg++;
			break;
		case 'l':
			logintime = atoi(optarg);
			break;
		case 'm':
			global_errorlevel = atoi(optarg);
			break;
		case 'o':
			output_filename = optarg;
			break;
		case 'P':
			password = optarg;
			break;
		case 's':
			colseparator = optarg;
			break;
		case 'S':
			server = optarg;
			break;
		case 't':
			timeout = atoi(optarg);
			break;
		case 'U':
			username = optarg;
			break;
		case 'w':
			columnwidth = optarg;
			break;
		case 'y':
			/* XXX: this doesn't seem to be what isql does with -y...it doesn't
			 * seem to do anything actually
			 */
			sybenv = (char *) xmalloc((strlen(optarg) + 8) * sizeof(char));
			strcpy(sybenv, "SYBASE=");
			strcat(sybenv, optarg);
			putenv(sybenv);
			break;
		case 'z':
			language = optarg;
			break;
		case 'A':
			size = atoi(optarg);
			break;
		case 'D':
			database_name = optarg;
			break;
		default:
			errflg++;
			break;
		}
	}

	if (errflg) {
		fprintf(stderr, "usage: fisql [-e] [-F] [-g] [-p] [-n] [-v] [-X] [-Y]\n");
		fprintf(stderr, "\t[-c cmdend] [-D database_name] [-E editor]\n");
		fprintf(stderr, "\t[-h headers] [-H hostname] [-i inputfile]\n");
		fprintf(stderr, "\t[-I interfaces_file] [-J client character set]\n");
		fprintf(stderr, "\t[-l login_timeout] [-m errorlevel]\n");
		fprintf(stderr, "\t[-o outputfile]\n");
		fprintf(stderr, "\t[-P password] [-s colseparator] [-S server]\n");
		fprintf(stderr, "\t[-t timeout] [-U username] [-w columnwidth]\n");
		fprintf(stderr, "\t[-y sybase_dir] [-z language]\n");
		exit(EXIT_FAILURE);
	}
	if (!(isatty(fileno(stdin)))) {
		no_prompt = 1;
		rl_outstream = fopen("/dev/null", "rw");
	}
	rl_readline_name = "fisql";
	rl_bind_key('\t', rl_insert);
	if (password == NULL) {
		password = (char *) xmalloc(READPASSPHRASE_MAXLEN);
		readpassphrase("Password: "******"r", stdin) == NULL) {
			/* XXX: sybase isql generates this error while parsing the options,
			 * but doesn't redirect the input until after the Password: prompt
			 */
			/* lack of newline for bug-compatibility with isql */
			fprintf(stderr, "Unable to open input file '%s'.", optarg);
			exit(EXIT_FAILURE);
		}
	}
	if (output_filename) {
		if (freopen(output_filename, "w", stdout) == NULL) {
			/* XXX: sybase isql generates this error while parsing the options,
			 * but doesn't redirect the output until after the Password: prompt
			 */
			/* lack of newline for bug-compatibility with isql */
			fprintf(stderr, "Unable to open output file '%s'.", output_filename);
			exit(EXIT_FAILURE);
		}
	}
	if (isatty(fileno(stdin))) {
		rl_outstream = stdout;
	}
	dbinit();
#if 0
#ifdef DBVERSION_100
	dbsetversion(DBVERSION_100);
#endif
#endif
	if ((login = dblogin()) == NULL) {
		reset_term();
		exit(EXIT_FAILURE);
	}
	dbmsghandle(msg_handler);
	dberrhandle(err_handler);
	DBSETLAPP(login, "fisql");
	if (username) {
		DBSETLUSER(login, username);
	}
	DBSETLPWD(login, password);
	memset(password, 0, strlen(password));

	if (char_set) {
		DBSETLCHARSET(login, char_set);
	}
	if (use_encryption) {
		DBSETLENCRYPT(login, TRUE);
	}
	if (hostname) {
		DBSETLHOST(login, hostname);
	}
	if (language) {
		DBSETLNATLANG(login, language);
	}
	if (size) {
		DBSETLPACKET(login, (short) size);
	}
	if (interfaces_filename) {
		dbsetifile(interfaces_filename);
	}
	dbsettime(timeout);
	if (logintime >= 0) {
		dbsetlogintime(logintime);
	}
	if ((dbproc = dbopen(login, server)) == NULL) {
		fprintf(stderr, "fisql: dbopen() failed.\n");
		reset_term();
		exit(EXIT_FAILURE);
	}

	dbsetopt(dbproc, DBPRLINESEP, lineseparator, strlen(lineseparator));
	if (colseparator) {
		dbsetopt(dbproc, DBPRCOLSEP, colseparator, strlen(colseparator));
	}
	if (columnwidth) {
		dbsetopt(dbproc, DBPRLINELEN, columnwidth, 0);
	}
	if (chained_transactions) {
		dbsetopt(dbproc, DBCHAINXACTS, NULL, 0);
	}
	if (fipsflagger) {
		dbsetopt(dbproc, DBFIPSFLAG, NULL, 0);
	}
	if (perfstats) {
		dbsetopt(dbproc, DBSTAT, "time", 0);
	}
	if (database_name) {
		dbuse(dbproc, database_name);
	}

	while (1) {
		if (sigsetjmp(restart, 1)) {
			if (ibuf) {
				for (i = 0; i < ibuflines; i++) {
					free(ibuf[i]);
				}
				ibuflines = 0;
				free(ibuf);
				ibuf = NULL;
			}
			fputc('\n', stdout);
			rl_on_new_line();
			rl_reset_line_state();
		}
		dbcancel(dbproc);
		signal(SIGINT, inactive_interrupt_handler);
		ibuf = (char **) xmalloc(sizeof(char *));
		ibuflines = 0;
		while (1) {
			if (no_prompt) {
				foobuf[0] = '\0';
			} else {
				sprintf(foobuf, "%d>> ", ibuflines + 1);
			}
			line = readline(foobuf);
			if (line == NULL) {
				line = "exit";
			}
			for (cp = line; *cp && isspace((unsigned char) *cp); cp++)
				continue;
			if (*cp) {
				add_history(line);
			}
			if (!(strncasecmp(line, "!!", 2))) {
				int rv;
				cp = line + 2;
				switch (rv = system(cp)) {
				case 0:
					continue;
				case -1:
					fprintf(stderr,
					    "Failed to execute `%s'\n", cp);
					continue;
				default:
					fprintf(stderr, "Command `%s' exited "
					    "with code %d\n", cp, rv);
					continue;
				}
			}
			/* XXX: isql off-by-one line count error for :r not duplicated */
			if (!(strncasecmp(line, ":r", 2))) {
				for (cp = line + 2; *cp && (isspace((unsigned char) *cp)); cp++)
					continue;
				tfn = cp;
				for (; *cp && !(isspace((unsigned char) *cp)); cp++)
					continue;
				*cp = '\0';
				if ((fp = fopen(tfn, "r")) == NULL) {
					fprintf(stderr, "Operating system error: Failed to open %s.\n", tfn);
					continue;
				}
				tmpfp = rl_instream;
				tmpfp2 = rl_outstream;
				rl_instream = fp;
				rl_outstream = fopen("/dev/null", "w");
				while ((line = readline("")) != NULL) {
					ibuf[ibuflines++] = line;
					ibuf = (char **) xrealloc(ibuf, (ibuflines + 1) * sizeof(char *));
				}
				rl_instream = tmpfp;
				fclose(rl_outstream);
				rl_outstream = tmpfp2;
				fclose(fp);
				fputc('\r', stdout);
				fflush(stdout);
				continue;
			}
			firstword = (char *) xmalloc((strlen(line) + 1) * sizeof(char));
			strcpy(firstword, line);
			for (cp = firstword; *cp; cp++) {
				if (isspace((unsigned char) *cp)) {
					*cp = '\0';
					break;
				}
			}
			if ((!(strcasecmp(firstword, "exit")))
			    || (!(strcasecmp(firstword, "quit")))) {
				reset_term();
				dbexit();
				exit(default_exit);
			}
			if (!(strcasecmp(firstword, "reset"))) {
				for (i = 0; i < ibuflines; i++) {
					free(ibuf[i]);
				}
				ibuflines = 0;
				continue;
			}
			if (!(strcasecmp(firstword, cmdend))) {
				if (ibuflines == 0) {
					continue;
				}
				free(firstword);
				break;
			}
			if ((!(strcasecmp(firstword, "vi")))
			    || (!(strcasecmp(firstword, editor)))) {
				int tmpfd;

				strcpy(tmpfn, "/tmp/fisqlXXXXXX");
				tmpfd = mkstemp(tmpfn);
				if ((fp = fdopen(tmpfd, "w")) == NULL) {
					perror("fisql");
					reset_term();
					dbexit();
					exit(2);
				}
				if (ibuflines) {
					for (i = 0; i < ibuflines; i++) {
						fputs(ibuf[i], fp);
						fputc('\n', fp);
						free(ibuf[i]);
					}
				} else {
					for (i = 0; ((sqlch = dbgetchar(dbproc, i)) != NULL); i++) {
						fputc(*sqlch, fp);
					}
				}
				fclose(fp);
				if (!(strcmp(firstword, "vi"))) {
					edit("vi", tmpfn);
				} else {
					edit(editor, tmpfn);
				}
				ibuflines = 0;
				fp = fopen(tmpfn, "r");
				tmpfp = rl_instream;
				rl_instream = fp;
				strcpy(foobuf, "1>> ");
				while ((line = readline(foobuf)) != NULL) {
					ibuf[ibuflines++] = line;
					sprintf(foobuf, "%d>> ", ibuflines + 1);
					ibuf = (char **) xrealloc(ibuf, (ibuflines + 1) * sizeof(char *));
				}
				rl_instream = tmpfp;
				fclose(fp);
				fputc('\r', stdout);
				fflush(stdout);
				unlink(tmpfn);
				continue;
			}
			free(firstword);
			ibuf[ibuflines++] = line;
			ibuf = (char **) xrealloc(ibuf, (ibuflines + 1) * sizeof(char *));
		}
		dbfreebuf(dbproc);
		for (i = 0; i < ibuflines; i++) {
			if (echo) {
				puts(ibuf[i]);
			}
			dbcmd(dbproc, ibuf[i]);
			dbcmd(dbproc, "\n");
			free(ibuf[i]);
		}
		free(ibuf);
		ibuf = NULL;
		signal(SIGINT, active_interrupt_handler);
		dbsetinterrupt(dbproc, (void *) active_interrupt_pending, (void *) active_interrupt_servhandler);
		if (dbsqlexec(dbproc) == SUCCEED) {
			maybe_handle_active_interrupt();
			while ((dbrc = dbresults(dbproc)) != NO_MORE_RESULTS) {
				printedlines = 0;
#define USE_DBPRROW 0
#if USE_DBPRROW
				dbprhead(dbproc);
				dbprrow(dbproc);
#else
				if ((dbrc == SUCCEED) && (DBROWS(dbproc) == SUCCEED)) {
					prbuflen = dbspr1rowlen(dbproc);
					prbuf = (char *) xmalloc(prbuflen * sizeof(char));
					dbsprhead(dbproc, prbuf, prbuflen);
					fputs(prbuf, stdout);
					fputc('\n', stdout);
					dbsprline(dbproc, prbuf, prbuflen, '-');
					fputs(prbuf, stdout);
					fputc('\n', stdout);
					maybe_handle_active_interrupt();
					while ((dbrc = dbnextrow(dbproc)) != NO_MORE_ROWS) {
						if (dbrc == FAIL) {
							break;
						}
						if (dbrc != REG_ROW) {
							num_cols = dbnumalts(dbproc, dbrc);
							for (selcol = col = 1; col <= num_cols; col++) {
								colid = dbaltcolid(dbproc, dbrc, col);
								while (selcol < colid) {
									collen = get_printable_column_size(dbproc, selcol);
									for (i = 0; i < collen; i++) {
										putchar(' ');
									}
									selcol++;
									printf("%s", colseparator);
								}
								opname = dbprtype(dbaltop(dbproc, dbrc, col));
								printf("%s", opname);
								collen = get_printable_column_size(dbproc, colid);
								collen -= strlen(opname);
								while (collen-- > 0) {
									putchar(' ');
								}
								selcol++;
								printf("%s", colseparator);
							}
							printf("%s", lineseparator);
							for (selcol = col = 1; col <= num_cols; col++) {
								colid = dbaltcolid(dbproc, dbrc, col);
								while (selcol < colid) {
									collen = get_printable_column_size(dbproc, selcol);
									for (i = 0; i < collen; i++) {
										putchar(' ');
									}
									selcol++;
									printf("%s", colseparator);
								}
								collen = get_printable_column_size(dbproc, colid);
								adash = '-';
								for (i = 0; i < collen; i++) {
									putchar(adash);
								}
								selcol++;
								printf("%s", colseparator);
							}
							printf("%s", lineseparator);
							for (selcol = col = 1; col <= num_cols; col++) {
								colid = dbaltcolid(dbproc, dbrc, col);
								while (selcol < colid) {
									collen = get_printable_column_size(dbproc, selcol);
									for (i = 0; i < collen; i++) {
										putchar(' ');
									}
									selcol++;
									printf("%s", colseparator);
								}
								convlen = dbconvert(dbproc,
										    dbalttype(dbproc, dbrc, col),
										    dbadata(dbproc, dbrc, col),
										    dbadlen(dbproc, dbrc, col),
										    SYBCHAR, (BYTE *) adbuf, sizeof(adbuf));
								printf("%.*s", (int) convlen, adbuf);
								collen = get_printable_column_size(dbproc, colid);
								collen -= convlen;
								while (collen-- > 0) {
									putchar(' ');
								}
								selcol++;
								printf("%s", colseparator);
							}
							printf("%s", lineseparator);
							printedcompute = 1;
							continue;
						}
						if (printedcompute || (headers && (printedlines >= headers)
								       && ((printedlines % headers) == 0))) {
							fputc('\n', stdout);
							dbsprhead(dbproc, prbuf, prbuflen);
							fputs(prbuf, stdout);
							fputc('\n', stdout);
							dbsprline(dbproc, prbuf, prbuflen, '-');
							fputs(prbuf, stdout);
							fputc('\n', stdout);
							printedcompute = 0;
						}
						printedlines++;
						dbspr1row(dbproc, prbuf, prbuflen);
						fputs(prbuf, stdout);
						fputc('\n', stdout);
						maybe_handle_active_interrupt();
					}
					fputc('\n', stdout);
					free(prbuf);
					maybe_handle_active_interrupt();
				}
#endif
				if (dbrc != FAIL) {
					if ((DBCOUNT(dbproc) >= 0) || dbhasretstat(dbproc)) {
						if (DBCOUNT(dbproc) >= 0) {
							fprintf(stdout, "(%d rows affected", (int) DBCOUNT(dbproc));
							if (dbhasretstat(dbproc)) {
								dbrc = dbretstatus(dbproc);
								fprintf(stdout, ", return status = %d", dbrc);
							}
							fprintf(stdout, ")\n");
						} else {
							if (dbhasretstat(dbproc)) {
								dbrc = dbretstatus(dbproc);
								fprintf(stdout, "(return status = %d)\n", dbrc);
							}
						}
					}
				}
			}
		} else {
			/* Something failed, so change the default
			 * exit status to reflect that.
			 */
			default_exit = EXIT_FAILURE;
		}
	}
	reset_term();
	dbexit();
	exit(EXIT_FAILURE);
	return (0);
}
示例#29
0
/*
 * TODO: Rewrite main() when all sub-functionality is tested
 */
int main (int argc, char **argv) {
	int result;
	struct mt_packet data;
	struct sockaddr_in si_me;
	struct autologin_profile *login_profile;
	unsigned char buff[1500];
	unsigned char print_help = 0, have_username = 0, have_password = 0;
	unsigned char drop_priv = 0;
	int c;
	int optval = 1;

	strncpy(autologin_path, AUTOLOGIN_PATH, 254);

	setlocale(LC_ALL, "");
	bindtextdomain("mactelnet","/usr/share/locale");
	textdomain("mactelnet");

	while (1) {
		c = getopt(argc, argv, "lnqt:u:p:U:vh?BAa:");

		if (c == -1) {
			break;
		}

		switch (c) {

			case 'n':
				use_raw_socket = 1;
				break;

			case 'u':
				/* Save username */
				strncpy(username, optarg, sizeof(username) - 1);
				username[sizeof(username) - 1] = '\0';
				have_username = 1;
				break;

			case 'p':
				/* Save password */
#if defined(__linux__) && defined(_POSIX_MEMLOCK_RANGE)
				mlock(password, sizeof(password));
#endif
				strncpy(password, optarg, sizeof(password) - 1);
				password[sizeof(password) - 1] = '\0';
				have_password = 1;
				break;

			case 'U':
				/* Save nonpriv_username */
				strncpy(nonpriv_username, optarg, sizeof(nonpriv_username) - 1);
				nonpriv_username[sizeof(nonpriv_username) - 1] = '\0';
				drop_priv = 1;
				break;

			case 't':
				connect_timeout = atoi(optarg);
				mndp_timeout = connect_timeout;
				break;

			case 'v':
				print_version();
				exit(0);
				break;

			case 'q':
				quiet_mode = 1;
				break;

			case 'l':
				run_mndp = 1;
				break;

			case 'B':
				batch_mode = 1;
				break;

			case 'A':
				no_autologin = 1;
				break;

			case 'a':
				strncpy(autologin_path, optarg, 254);
				break;

			case 'h':
			case '?':
				print_help = 1;
				break;

		}
	}
	if (run_mndp) {
		return mndp(mndp_timeout, batch_mode);
	}
	if (argc - optind < 1 || print_help) {
		print_version();
		fprintf(stderr, _("Usage: %s <MAC|identity> [-h] [-n] [-a <path>] [-A] [-t <timeout>] [-u <user>] [-p <password>] [-U <user>] | -l [-B] [-t <timeout>]\n"), argv[0]);

		if (print_help) {
			fprintf(stderr, _("\nParameters:\n"
			"  MAC            MAC-Address of the RouterOS/mactelnetd device. Use mndp to\n"
			"                 discover it.\n"
			"  identity       The identity/name of your destination device. Uses\n"
			"                 MNDP protocol to find it.\n"
			"  -l             List/Search for routers nearby (MNDP). You may use -t to set timeout.\n"
			"  -B             Batch mode. Use computer readable output (CSV), for use with -l.\n"
			"  -n             Do not use broadcast packets. Less insecure but requires\n"
			"                 root privileges.\n"
			"  -a <path>      Use specified path instead of the default: " AUTOLOGIN_PATH " for autologin config file.\n"
			"  -A             Disable autologin feature.\n"
			"  -t <timeout>   Amount of seconds to wait for a response on each interface.\n"
			"  -u <user>      Specify username on command line.\n"
			"  -p <password>  Specify password on command line.\n"
			"  -U <user>      Drop privileges to this user. Used in conjunction with -n\n"
			"                 for security.\n"
			"  -q             Quiet mode.\n"
			"  -h             This help.\n"
			"\n"));
		}
		return 1;
	}

	is_a_tty = isatty(fileno(stdout)) && isatty(fileno(stdin));
	if (!is_a_tty) {
		quiet_mode = 1;
	}

	if (!no_autologin) {
		autologin_readfile(autologin_path);
		login_profile = autologin_find_profile(argv[optind]);

		if (!quiet_mode && login_profile != NULL && (login_profile->hasUsername || login_profile->hasPassword)) {
			fprintf(stderr, _("Using autologin credentials from %s\n"), autologin_path);
		}
		if (!have_username) {
			if (login_profile != NULL && login_profile->hasUsername) {
				have_username = 1;
				strncpy(username, login_profile->username, sizeof(username) - 1);
				username[sizeof(username) - 1] = '\0';
			}
		}

		if (!have_password) {
			if (login_profile != NULL && login_profile->hasPassword) {
				have_password = 1;
				strncpy(password, login_profile->password, sizeof(password) - 1);
				password[sizeof(password) - 1] = '\0';
			}
		}
	}

	/* Seed randomizer */
	srand(time(NULL));

	if (use_raw_socket) {
		if (geteuid() != 0) {
			fprintf(stderr, _("You need to have root privileges to use the -n parameter.\n"));
			return 1;
		}

		sockfd = net_init_raw_socket();

		if (drop_priv) {
			drop_privileges(nonpriv_username);
		}
	} else if (drop_priv) {
		fprintf(stderr, _("The -U option must be used in conjunction with the -n parameter.\n"));
		return 1;
	}

	/* Receive regular udp packets with this socket */
	insockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (insockfd < 0) {
		perror("insockfd");
		return 1;
	}

	if (!use_raw_socket) {
		if (setsockopt(insockfd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval))==-1) {
			perror("SO_BROADCAST");
			return 1;
		}
	}

	/* Need to use, to be able to autodetect which interface to use */
	setsockopt(insockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval));

	/* Get mac-address from string, or check for hostname via mndp */
	if (!query_mndp_or_mac(argv[optind], dstmac, !quiet_mode)) {
		/* No valid mac address found, abort */
		return 1;
	}

	if (!have_username) {
		if (!quiet_mode) {
			printf(_("Login: "******"%254s", username);
	}

	if (!have_password) {
		char *tmp;
		tmp = getpass(quiet_mode ? "" : _("Password: "******"255.255.255.255", &destip);
	memcpy(&sourceip, &(si_me.sin_addr), IPV4_ALEN);

	/* Session key */
	sessionkey = rand() % 65535;

	/* stop output buffering */
	setvbuf(stdout, (char*)NULL, _IONBF, 0);

	if (!quiet_mode) {
		printf(_("Connecting to %s..."), ether_ntoa((struct ether_addr *)dstmac));
	}

	/* Initialize receiving socket on the device chosen */
	memset((char *) &si_me, 0, sizeof(si_me));
	si_me.sin_family = AF_INET;
	si_me.sin_port = htons(sourceport);

	/* Bind to udp port */
	if (bind(insockfd, (struct sockaddr *)&si_me, sizeof(si_me)) == -1) {
		fprintf(stderr, _("Error binding to %s:%d, %s\n"), inet_ntoa(si_me.sin_addr), sourceport, strerror(errno));
		return 1;
	}

	if (!find_interface() || (result = recvfrom(insockfd, buff, 1400, 0, 0, 0)) < 1) {
		fprintf(stderr, _("Connection failed.\n"));
		return 1;
	}
	if (!quiet_mode) {
		printf(_("done\n"));
	}

	/* Handle first received packet */
	handle_packet(buff, result);

	init_packet(&data, MT_PTYPE_DATA, srcmac, dstmac, sessionkey, 0);
	outcounter +=  add_control_packet(&data, MT_CPTYPE_BEGINAUTH, NULL, 0);

	/* TODO: handle result of send_udp */
	result = send_udp(&data, 1);

	while (running) {
		fd_set read_fds;
		int reads;
		static int terminal_gone = 0;
		struct timeval timeout;

		/* Init select */
		FD_ZERO(&read_fds);
		if (!terminal_gone) {
			FD_SET(0, &read_fds);
		}
		FD_SET(insockfd, &read_fds);

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;

		/* Wait for data or timeout */
		reads = select(insockfd+1, &read_fds, NULL, NULL, &timeout);
		if (reads > 0) {
			/* Handle data from server */
			if (FD_ISSET(insockfd, &read_fds)) {
				bzero(buff, 1500);
				result = recvfrom(insockfd, buff, 1500, 0, 0, 0);
				handle_packet(buff, result);
			}
			/* Handle data from keyboard/local terminal */
			if (FD_ISSET(0, &read_fds) && terminal_mode) {
				unsigned char keydata[512];
				int datalen;

				datalen = read(STDIN_FILENO, &keydata, 512);

				if (datalen > 0) {
					/* Data received, transmit to server */
					init_packet(&data, MT_PTYPE_DATA, srcmac, dstmac, sessionkey, outcounter);
					add_control_packet(&data, MT_CPTYPE_PLAINDATA, &keydata, datalen);
					outcounter += datalen;
					send_udp(&data, 1);
				} else {
					terminal_gone = 1;
				}
			}
		/* Handle select() timeout */
		} else {
			/* handle keepalive counter, transmit keepalive packet every 10 seconds
			   of inactivity  */
			if (keepalive_counter++ == 10) {
				struct mt_packet odata;
				init_packet(&odata, MT_PTYPE_ACK, srcmac, dstmac, sessionkey, outcounter);
				send_udp(&odata, 0);
			}
		}
	}

	if (is_a_tty && terminal_mode) {
		/* Reset terminal back to old settings */
		reset_term();
	}

	close(sockfd);
	close(insockfd);

	return 0;
}
示例#30
0
文件: input.c 项目: pollyzoid/psh
void input_destroy(input_state* input) {
	history_save(input->history_first);
	reset_term(input, true);
	history_destroy(input->history_first);
	free(input);
}