ftp.nice.ch/pub/next/unix/communication/pcomm.NIHS.bs.tar.gz#/pcomm/Source/main.c

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.