⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 通讯程序源码
💻 C
字号:
/* * 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 intquit(){	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. */intcan_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 intci_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 voidprint_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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -