/****************************************************************************** (c) 2002-2008 Christine Caulfield christine.caulfield@googlemail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dn_endian.h" #include "dnlogin.h" /* The global state */ int termfd = -1; int exit_char = 035; /* Default to ^] */ int finished = 0; /* terminate mainloop */ int debug = 0; int char_timeout = 0; int timeout_valid = 0; static int mainloop(void) { while (!finished) { char inbuf[1024]; struct timeval tv; int res; int sockfd = found_getsockfd(); fd_set in_set; tv.tv_usec = 0; tv.tv_sec = char_timeout; FD_ZERO(&in_set); FD_SET(termfd, &in_set); FD_SET(sockfd, &in_set); if ( (res=select(FD_SETSIZE, &in_set, NULL, NULL, timeout_valid?&tv:NULL)) < 0) { break; } if (res == 0 && timeout_valid && tv.tv_sec == 0 && tv.tv_usec == 0) { tty_timeout(); } timeout_valid = 0; /* Read from keyboard */ if (FD_ISSET(termfd, &in_set)) { int len; if ( (len=read(termfd, inbuf, sizeof(inbuf))) <= 0) { perror("read tty"); break; } tty_process_terminal(inbuf, len); } if (FD_ISSET(sockfd, &in_set)) if (found_read() == -1) break; } write(termfd, "\n", 1); return 0; } static void set_exit_char(char *string) { int newchar = 0; if (string[0] == '^') { newchar = toupper(string[1]) - '@'; } else newchar = strtol(string, NULL, 0); // Just a number // Make sure it's resaonable if (newchar > 0 && newchar < 256) exit_char = newchar; } static void usage(char *prog, FILE * f) { fprintf(f, "\nUsage: %s [OPTIONS] node\n\n", prog); fprintf(f, "\nOptions:\n"); fprintf(f, " -? -h display this help message\n"); fprintf(f, " -V show version number\n"); fprintf(f, " -e set exit char\n"); fprintf(f, " -T connect timeout (default 60 seconds)\n"); fprintf(f, " -d debug information\n"); fprintf(f, "\n"); } int main(int argc, char *argv[]) { int opt; int connect_timeout = 60; // Deal with command-line arguments. opterr = 0; optind = 0; while ((opt = getopt(argc, argv, "?Vhd:te:T:")) != EOF) { switch (opt) { case 'h': usage(argv[0], stdout); exit(0); case '?': usage(argv[0], stderr); exit(0); case 'V': printf("\ndnlogin from dnprogs version %s\n\n", VERSION); exit(1); break; case 'e': set_exit_char(optarg); break; case 'T': connect_timeout = atoi(optarg); break; case 'd': debug = atoi(optarg); break; } } if (optind >= argc) { usage(argv[0], stderr); exit(2); } send_input = cterm_send_input; send_oob = cterm_send_oob; rahead_change = cterm_rahead_change; if (found_setup_link(argv[optind], DNOBJECT_CTERM, cterm_process_network, connect_timeout) == 0) { if (tty_setup("/dev/fd/0", 1) == -1) if (tty_setup("/proc/self/fd/0", 1)) { perror("cannot connect to stdin\n"); } mainloop(); tty_setup(NULL, 0); } else { return 2; } return 0; }