This is main.c in view mode; [Download] [Up]
/* * Pcomm is a public domain telecommunication program for Unix that * is designed to operate similar 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.0 4 Feb 89 * Patch #1 18 Feb 89 * Patch #2 11 Mar 89 * Patch #3 11 May 89 * Patch #4 23 Jun 89 * Patch #5 30 Oct 89 * Patch #6 8 Nov 89 * Patch #7 13 Jan 90 * Patch #8 20 Jan 90 * Patch #9 1 Sep 90 * Patch #10 30 Dec 90 */ #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 */ #ifdef SHAREDMEM int shm_id; #endif /* SHAREDMEM */ 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 null pointer */ main(argc, argv) int argc; char *argv[]; { extern char *optarg; int c, i, code; static int quit(), match_ci(); char *mytty, *ttyname(), *term, *getenv(), *sys_name, *str_dup(); char *extra_dir, buf[80], message[80]; 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(), free_ptr(); #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); sys_name = NULL; extra_dir = NULL; /* the command line */ while ((c = getopt(argc, argv, "d:f:")) != 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 '?': /* default */ fprintf(stderr, "Usage: pcomm [-d directory] [-f system name]\n"); exit(1); 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 XENIX_3 raw(); #endif /* XENIX_3 */ #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; /* show the herald, return status */ status = init(sys_name); /* get "msgs" status */ if (mytty = ttyname(0)) { stat(mytty, &stbuf); msg_status = stbuf.st_mode & 0777; chmod(mytty, 0600); } mvaddstr(12, 31, "Initializing..."); refresh(); /* read the support files */ param = read_param(extra_dir); dir = read_dir(extra_dir); extrnl = read_extrnl(extra_dir); modem = read_modem(extra_dir); /* 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? */ code = 0; if (sys_name != NULL) { for (i=1; i<dir->d_entries+1; i++) { if (match_ci(dir->name[i], sys_name)) { dir->q_num[0] = i; dir->d_cur = i; break; } } /* if match is found */ if (dir->q_num[0] != -1) code = dial_win(); else { 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); } /* start terminal dialogue */ terminal(extra_dir, code); 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 * my_fopen(file, mode) char *file, *mode; { FILE *fp; #ifdef SETUGID #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); #else /* SETUGID */ return(fopen(file, mode)); #endif /* SETUGID */ } /* * See if s2 in contained in s1 (case insensitive). Returns a 1 on yes, * and a 0 on no. */ static int match_ci(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); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.