home *** CD-ROM | disk | FTP | other *** search
- /*
- * Pcomm is a public domain telecommunication program for Unix that
- * is designed to operate similarly to the MSDOS program, ProComm.
- * ProComm (TM) is copyrighted by Datastorm Technologies, Inc.
- *
- * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- * Directorate of Engineering & Housing
- * Environmental Management Office
- * Fort Hood, TX 76544-5057
- *
- * Release v1.0 12 Mar 88
- * Release v1.1 21 Aug 88
- * Release v1.2 4 Feb 89
- * Release v2.0 18 Jul 92
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <signal.h>
- #include <curses.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #define MAIN
- #include "config.h"
- #include "dial_dir.h"
- #include "extrnl.h"
- #include "misc.h"
- #include "modem.h"
- #include "param.h"
- #include "status.h"
-
- #ifndef OLDCURSES
- #include <term.h>
- #else /* OLDCURSES */
- #ifdef UNIXPC
- #include <sgtty.h>
- #endif /* UNIXPC */
- char tcbuf[1024];
- struct sgttyb t_mode, c_mode;
- #ifndef cbreak
- #define cbreak crmode
- #endif
- #endif /* OLDCURSES */
-
- struct DIAL_DIR *dir;
- struct EXTRNL *extrnl;
- struct MODEM *modem;
- struct PARAM *param;
- struct STATUS *status;
-
- int fd = -1; /* file descriptor for port */
- int xmc; /* magic cookie terminal */
- int msg_status; /* read/write permissions on TTY */
- char *null_ptr = ""; /* generic char pointer to a null */
-
- static int quit(), ci_match();
- static void print_usage();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- extern char *optarg;
- int c, i, data_bits;
- unsigned baud;
- char *mytty, *ttyname(), *term, *getenv(), *sys_name, parity;
- char *extra_dir, buf[80], message[80], *str_dup(), *number;
- char *aux;
- struct DIAL_DIR *read_dir();
- struct EXTRNL *read_extrnl();
- struct MODEM *read_modem();
- struct PARAM *read_param();
- struct STATUS *init();
- struct stat stbuf;
- void exit(), error_win(), vcs_table(), terminal(), free_ptr();
- void info();
- #ifdef OLDCURSES
- char *tgetstr(), *t, tb[1024];
- t = tcbuf;
- #endif /* OLDCURSES */
-
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTERM, (SIG_TYPE(*) ()) quit);
- signal(SIGHUP, (SIG_TYPE(*) ()) quit);
-
- extra_dir = NULL;
- sys_name = NULL;
- aux = NULL;
- parity = '\0';
- baud = 0;
- data_bits = 0;
- number = NULL;
- /* the command line */
- while ((c = getopt(argc, argv, "d:f:a:eonw:b:p:")) != EOF) {
- switch (c) {
- case 'd': /* the extra directory to search */
- extra_dir = str_dup(optarg);
- break;
- case 'f': /* the short cut into the dialing dir */
- sys_name = str_dup(optarg);
- break;
- case 'a': /* auxiliary (script, TTY, or modem) */
- aux = str_dup(optarg);
- break;
- case 'e':
- if (parity != '\0')
- print_usage("Parity values are mutually exclusive");
- parity = 'E';
- break;
- case 'o':
- if (parity != '\0')
- print_usage("Parity values are mutually exclusive");
- parity = 'O';
- break;
- case 'n':
- if (parity != '\0')
- print_usage("Parity values are mutually exclusive");
- parity = 'N';
- break;
- case 'w':
- data_bits = atoi(optarg);
- if (data_bits != 7 && data_bits != 8)
- print_usage("Unsupported number of word length (data bits)");
- break;
- case 'b':
- baud = (unsigned int) atoi(optarg);
- switch (baud) {
- case 300:
- case 1200:
- case 2400:
- case 4800:
- case 9600:
- case 19200:
- case 38400:
- break;
- default:
- print_usage("Unsupported baud rate");
- break;
- }
- break;
- case 'p':
- number = str_dup(optarg);
- break;
- case '?': /* default */
- print_usage("");
- break;
- }
- }
- /* get terminal type */
- term = getenv("TERM");
- if (term == NULL || *term == '\0') {
- fprintf(stderr, "Windows not supported (TERM not defined)\n");
- exit(1);
- }
- /* see if terminfo entry exists */
- #ifdef OLDCURSES
- i = tgetent(tb, term);
- #else /* OLDCURSES */
- setupterm(term, 1, &i);
- #endif /* OLDCURSES */
-
- if (i != 1) {
- fprintf(stderr, "Windows not supported (no terminfo data for \"%s\")\n", term);
- exit(1);
- }
- /* minimum screen size */
- #ifdef OLDCURSES
- if (tgetnum("co") < 80 || tgetnum("li") < 24) {
- #else /* OLDCURSES */
- if (columns < 80 || lines < 24) {
- #endif /* OLDCURSES */
- fprintf(stderr, "Windows not supported (minimum 80x24 screen required)\n");
- exit(1);
- }
- /* must have cursor movement */
- #ifdef OLDCURSES
- if (tgetstr("cm", &t) == NULL) {
- #else /* OLDCURSES */
- if (cursor_address == NULL) {
- #endif /* OLDCURSES */
- fprintf(stderr, "Windows not supported (terminal too dumb)\n");
- exit(1);
- }
- /* load magic cookie variable */
- #ifdef OLDCURSES
- xmc = tgetnum("sg");
- #else /* OLDCURSES */
- xmc = magic_cookie_glitch;
- #endif /* OLDCURSES */
- /* ok... now let's go! */
- #ifdef OLDCURSES
- ioctl(0, TIOCGETP, &t_mode);
- #endif /* OLDCURSES */
-
- initscr();
- nonl();
- cbreak();
- noecho();
-
- #ifdef OLDCURSES
- ioctl(0, TIOCGETP, &c_mode);
- #endif /* OLDCURSES */
-
- dir = (struct DIAL_DIR *) NULL;
- extrnl = (struct EXTRNL *) NULL;
- param = (struct PARAM *) NULL;
- modem = (struct MODEM *) NULL;
- /* display herald if no arguments */
- if (argc == 1) {
- info(AUTO_CLEAR);
- erase();
- refresh();
- }
- /* get "msgs" status */
- if (mytty = ttyname(0)) {
- stat(mytty, &stbuf);
- msg_status = stbuf.st_mode & 0777;
- chmod(mytty, 0600);
- }
-
- mvaddstr(12, 31, "Initializing...");
- refresh();
- /* create the VCS table */
- vcs_table();
- /* create the status structure */
- status = init(extra_dir);
- /* read the support files */
- param = read_param();
- dir = read_dir();
- extrnl = read_extrnl();
- modem = read_modem();
-
- /* warning about screen size */
- if (LINES > MAX_ROW || COLS > MAX_COL-1)
- error_win(0, "Your screen size exceeds an internal Pcomm limit",
- "The edges of the screen may contain garbage");
-
- /* short-cut to dialing window? */
- if (sys_name != NULL) {
- for (i=1; i<dir->d_entries+1; i++) {
- if (ci_match(dir->name[i], sys_name)) {
- dir->q_num[0] = i;
- dir->d_cur = i;
- if (!dial_win(25))
- aux = dir->aux[dir->d_cur];
- break;
- }
- }
- /* if match not found */
- if (dir->q_num[0] == -1) {
- sprintf(buf, "Can't match \"%s\" in dialing directory", sys_name);
- sprintf(message, "file \"%s\"", dir->d_path);
- error_win(0, buf, message);
- }
- free_ptr(sys_name);
- }
- /* phone number on the command line */
- else if (number != NULL) {
- dir->name[0] = str_dup(number);
- dir->number[0] = str_dup(number);
- if (baud)
- dir->baud[0] = baud;
- if (parity)
- dir->parity[0] = parity;
- if (data_bits)
- dir->data_bits[0] = data_bits;
- dir->q_num[0] = 0;
- dir->d_cur = 0;
-
- dial_win(25);
- free_ptr(number);
- }
- /* start terminal dialogue */
- terminal(aux);
- exit(0);
- }
-
- /*
- * Something dreadful happened... Clean up the mess we made with the
- * TTY driver and release the phone line.
- */
-
- static int
- quit()
- {
- void cleanup();
-
- cleanup(1);
- /* never returns... */
- return(0);
- }
-
- /*
- * Check write permission with the real UID and GID. Returns a 0 on
- * permission denied, 1 on OK, and 2 on OK-but the file already exists.
- */
-
- int
- can_write(file)
- char *file;
- {
- char *p, path[256], *strcpy(), *strrchr();
-
- strcpy(path, file);
- /* dissect the path component */
- if (p = strrchr(path, '/'))
- *p = '\0';
- else
- strcpy(path, ".");
- /* if it already exists */
- if (!access(file, 0)) {
- if (!access(file, 2))
- return(OK_BUT_EXISTS);
- return(DENIED);
- }
- /* if path is writable */
- if (!access(path, 2))
- return(WRITE_OK);
- return(DENIED);
- }
-
- /*
- * Check the read and write permissions before opening a file. This
- * is a horrible kludge to work around the fact that a lot of systems
- * that claim to be SVID compatible don't treat setuid(2) and setgid(2)
- * properly. For example, on a Masscomp, you can't flip-flop back and
- * forth between the real and effective UID/GID.
- */
-
- FILE *
- uid_fopen(file, mode)
- char *file, *mode;
- {
- FILE *fp;
-
- #ifdef SETUID_BROKE
- switch (*mode) {
- case 'a':
- case 'w':
- switch(can_write(file)) {
- case DENIED:
- fp = (FILE *) NULL;
- break;
- case OK_BUT_EXISTS:
- fp = fopen(file, mode);
- break;
- case WRITE_OK:
- fp = fopen(file, mode);
- chown(file, getuid(), getgid());
- break;
- }
- break;
- case 'r':
- if (access(file, 4))
- fp = (FILE *) NULL;
- else
- fp = fopen(file, mode);
- break;
- }
- #else /* SETUID_BROKE */
- int euid, egid;
-
- euid = geteuid();
- egid = getegid();
- /* abdicate the throne */
- setuid(getuid());
- setgid(getgid());
-
- fp = fopen(file, mode);
- /* put things back */
- setuid(euid);
- setgid(egid);
- #endif /* SETUID_BROKE */
- return(fp);
- }
-
- /*
- * See if s2 in contained in s1 (case insensitive). Returns a 1 on yes,
- * and a 0 on no.
- */
-
- static int
- ci_match(s1, s2)
- char *s1, *s2;
- {
- int i;
- char str1[128], str2[128], *strstr();
-
- /* copy the strings to lower case */
- i = 0;
- while(*s1) {
- if (isupper(*s1))
- str1[i++] = tolower(*s1);
- else
- str1[i++] = *s1;
-
- if (i >= 127)
- break;
- s1++;
- }
- str1[i] = '\0';
-
- i = 0;
- while(*s2) {
- if (isupper(*s2))
- str2[i++] = tolower(*s2);
- else
- str2[i++] = *s2;
-
- if (i >= 127)
- break;
- s2++;
- }
- str2[i] = '\0';
- /* do they match? */
- if (strstr(str1, str2))
- return(1);
- return(0);
- }
-
- static void
- print_usage(err_message)
- char *err_message;
- {
- void exit();
-
- if (*err_message != '\0')
- fprintf(stderr, "Error: %s\n", err_message);
- fprintf(stderr, "\nUsage: pcomm [-d directory] [-f system name] [-a auxiliary file]\n");
- fprintf(stderr, " [-e|o|n] [-w word length] [-b baud] [-p phone number]\n\n");
- fprintf(stderr, "Command line options:\n");
- fprintf(stderr, "\t-d use this directory to find Pcomm support files\n");
- fprintf(stderr, "\t-f dial the entry that matches this system name\n");
- fprintf(stderr, "\t-a auxiliary file (script, TTY, or modem)\n\n");
- fprintf(stderr, "The following are used for manual dialing:\n");
- fprintf(stderr, "\t-e use even parity\n");
- fprintf(stderr, "\t-o use odd parity\n");
- fprintf(stderr, "\t-n use no parity\n");
- fprintf(stderr, "\t-w word length (number of data bits 7 or 8)\n");
- fprintf(stderr, "\t-b baud rate (300, 1200, 2400, 4800, 9600, 19200, 38400)\n");
- fprintf(stderr, "\t-p phone number to dial\n");
- exit(1);
- }
-