[comp.sources.unix] v20i069: Pcomm telecommunication package, Part03/08

rsalz@uunet.uu.net (Rich Salz) (10/26/89)

Submitted-by: Emmet P. Gray <uiucuxc!fthood!egray>
Posting-number: Volume 20, Issue 69
Archive-name: pcomm1.2/part03

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	admin.c
#	chg_dir.c
#	config.h
#	curses.c
#	d_delete.c
#	d_lib.c
#	d_manual.c
#	d_menu.c
#	d_print.c
#	d_prompt.c
#	d_revise.c
#	data_log.c
#	di_delay.c
#
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'admin.c'" '(2941 characters)'
if test -f 'admin.c'
then
	echo shar: "will not over-write existing file 'admin.c'"
else
sed 's/^X//' << \SHAR_EOF > 'admin.c'
X/*
X * Perform administrative functions.  Check to see if the user has
X * permission to make long distance calls, and record all phone calls
X * made by Pcomm.
X */
X
X#include <stdio.h>
X#include <grp.h>
X#include "config.h"
X#include "dial_dir.h"
X#include "param.h"
X
X/*
X * Make a log of all calls made by Pcomm.  The argument is the index
X * into the queue.
X */
X
X/* ARGSUSED */
Xvoid
Xlog_calls(i)
Xint i;
X{
X#ifdef LOG_CALLS
X	FILE *fp;
X	char *number, *build_num(), *date, *ctime(), *getlogin(), buf[80];
X	long now, time();
X	void error_win();
X					/* build the complete phone number */
X	number = build_num(i);
X					/* build date and time */
X	time(&now);
X	date = ctime(&now);
X	date[10] = '\0';
X	date[16] = '\0';
X
X	if (!(fp = fopen(LOGFILE, "a+"))) {
X					/* fatal! (to prevent hanky panky) */
X		sprintf(buf, "Can't open log file \"%s\"", LOGFILE);
X		error_win(1, buf, "Contact your system administrator");
X	}
X
X	fprintf(fp, "pcomm: %s called %s at %s on %s\n", getlogin(), number, &date[11], date);
X	fclose(fp);
X#endif /* LOG_CALLS */
X	return;
X}
X
X/*
X * Check to see if long distance (toll) call is authorized.  The argument
X * is the index into the queue.
X */
X
X/* ARGSUSED */
Xint
Xlimit_ld(i)
Xint i;
X{
X#ifdef LIMIT_LD
X	char *number, *build_num(), *name, *getlogin();
X	struct group *getgrnam(), *grpbuf;
X
X					/* if no group, don't bother */
X	grpbuf = getgrnam(GROUP_NAME);
X	if (grpbuf == NULL || *grpbuf->gr_mem == '\0')
X		return(0);
X					/* are you in the group? */
X	name = getlogin();
X	for (; *grpbuf->gr_mem!='\0'; grpbuf->gr_mem++) {
X		if (!strcmp(*grpbuf->gr_mem, name))
X			return(0);
X	}
X					/* numbers only... */
X	number = build_num(i);
X
X	/*
X	 * VERY SITE SPECIFIC!!!  We use a "9" to get an outside line,
X	 * so any 9 followed by a 1 is a toll call (except for 1-800
X	 * numbers).
X	 */
X	if (!strncmp(number, "91", 2) && strncmp(number, "91800", 5)) {
X		error_win(0, "You are not authorized to place long distance (toll) calls", "");
X		return(1);
X	}
X
X	if (*number == '\0') {
X		error_win(0, "You are not authorized direct access to the line", "Use the automatic dialing feature");
X		return(1);
X	}
X#endif /* LIMIT_LD */
X	return(0);
X}
X
X#if defined(LOG_CALLS) || defined(LIMIT_LD)
X/*
X * Put together the complete phone number but strip out the extraneous
X * characters.
X */
X
Xstatic char *
Xbuild_num(i)
Xint i;
X{
X	int j;
X	char *t, temp[80], *strcpy(), *strcat();
X	static char ans[80];
X
X	temp[0] = '\0';
X					/* add LD codes? */
X	switch (dir->q_ld[i]) {
X		case 0:
X			break;
X		case '+':
X			strcpy(temp, param->ld_plus);
X			break;
X		case '-':
X			strcpy(temp, param->ld_minus);
X			break;
X		case '@':
X			strcpy(temp, param->ld_at);
X			break;
X		case '#':
X			strcpy(temp, param->ld_pound);
X			break;
X	}
X					/* add the number */
X	strcat(temp, dir->number[dir->q_num[i]]);
X
X					/* copy only digits */
X	j = 0;
X	t = temp;
X	while (*t) {
X		if (*t >= '0' && *t <= '9')
X			ans[j++] = *t;
X		t++;
X	}
X	ans[j] = '\0';
X
X	return(ans);
X}
X#endif /* LOG_CALLS || LIMIT_LD */
SHAR_EOF
if test 2941 -ne "`wc -c < 'admin.c'`"
then
	echo shar: "error transmitting 'admin.c'" '(should have been 2941 characters)'
fi
fi
echo shar: "extracting 'chg_dir.c'" '(1514 characters)'
if test -f 'chg_dir.c'
then
	echo shar: "will not over-write existing file 'chg_dir.c'"
else
sed 's/^X//' << \SHAR_EOF > 'chg_dir.c'
X/*
X * Open a window to prompt for a new directory.  Checks to see you have
X * search permission.
X */
X
X#include <curses.h>
X#include "config.h"
X#include "misc.h"
X
Xvoid
Xchg_dir()
X{
X	extern int fd;
X	WINDOW *ch_win, *newwin();
X	char *ans, *dir, *expand(), *cwd, *getcwd(), cwdbuf[200];
X	char *get_str();
X
X	cwd = getcwd(cwdbuf, 200);
X
X	ch_win = newwin(6, 70, 5, 5);
X
X	mvwprintw(ch_win, 2, 4, "Current directory: %s", cwd);
X	mvwaddstr(ch_win, 3, 4, "New directory: ");
X	box(ch_win, VERT, HORZ);
X
X	mvwattrstr(ch_win, 0, 3, A_BOLD, " Change directory ");
X	wmove(ch_win, 3, 19);
X	wrefresh(ch_win);
X					/* get the answer */
X	while ((ans = get_str(ch_win, 80, "", " \t\n")) != NULL) {
X					/* a CR means no change */
X		if (*ans == '\0')
X			break;
X					/* expand the input */
X		dir = expand(ans);
X					/* if you have search permission */
X		if (!access(dir, 1)) {
X			if (!chdir(dir))
X				break;
X		}
X		beep();
X		mvwattrstr(ch_win, 4, 15, A_BOLD, "No such directory or no access permission");
X		wrefresh(ch_win);
X		wait_key(ch_win, 3);
X					/* clean up the mess */
X		clear_line(ch_win, 3, 19, TRUE);
X		clear_line(ch_win, 4, 14, TRUE);
X		wmove(ch_win, 3, 19);
X		wrefresh(ch_win);
X	}
X	if (fd == -1) {
X		werase(ch_win);
X		wrefresh(ch_win);
X	}
X	delwin(ch_win);
X	return;
X}
X
X#ifdef BSD
X/*
X * Get the current working directory, AT&T style.  Well... not really, it
X * doesn't handle a NULL pointer for the buffer.
X */
X
X/* ARGSUSED */
Xchar *
Xgetcwd(buf, len)
Xchar *buf;
Xint len;
X{
X	char *getwd();
X
X	return(getwd(buf));
X}
X#endif /* BSD */
SHAR_EOF
if test 1514 -ne "`wc -c < 'chg_dir.c'`"
then
	echo shar: "error transmitting 'chg_dir.c'" '(should have been 1514 characters)'
fi
fi
echo shar: "extracting 'config.h'" '(2286 characters)'
if test -f 'config.h'
then
	echo shar: "will not over-write existing file 'config.h'"
else
sed 's/^X//' << \SHAR_EOF > 'config.h'
X/*
X * Various tunable parameters.  This should appear before any other local
X * header file.
X */
X
X/* Are you using a Berkeley flavor of Unix? */
X#undef	BSD
X
X/* Use the dialing routines specific to the AT&T Unix PC 7300/3b1 */
X#undef	UNIXPC
X
X/* Older versions of curses(3) use termcap in lieu of terminfo */
X#undef	OLDCURSES
X
X/* Use shared memory in lieu of a file for the virtual screen */
X#define	SHAREDMEM
X
X/* Should a missing video attribute be promoted to standout? */
X#define NOPROMOTE
X
X/* Use extra precautions if Pcomm is set-user-id or set-group-id */
X#undef	SETUGID
X
X/* Should Pcomm make a log of all phone calls? */
X#undef	LOG_CALLS
X
X/* The name of the log file (if used).  */
X#define	LOGFILE		"/usr/adm/phone.calls"
X
X/* Should long distance (toll) calls be limited to a specific group? */
X#undef	LIMIT_LD
X
X/* The name of the privileged group for limiting long distance calls */
X#define	GROUP_NAME	"uucp"
X
X/* The path to the line printer program */
X#define	LPR		"lp"
X
X/* The path to the "pretty" printer program (if none, use "pr | lp") */
X#define	LPRINT		"pr | lp"
X
X/* The path to the default directory containing the Pcomm support files */
X#define	DEFAULT_DIR	"/usr/local/lib/pcomm"
X
X/* The path to the directory where UUCP locks are found */
X#define	LOCK_DIR	"/usr/spool/uucp"
X
X/* Do the lock files use ASCII encoded PID's? */
X#undef	ASCII_PID
X
X/* Fold the last character of the lock to lower case? */
X#undef	XENIX_LOCKS
X
X/* Should Pcomm optimize redialing by keeping the TTY port open */
X#define	KEEP_PORT
X
X/* Does the status line scroll up on "magic cookie" terminals? */
X#undef	XMC_BROKE
X
X/* Does the alarm() system call work correctly with the wgetch() function? */
X#undef	WGETCH_BROKE
X
X/* The size of the serial port character buffer */
X#define CLIST_SIZ	64
X
X/* The size of the input buffer (should be about the same as CLIST_SIZ) */
X#define INPUT_BUF	64
X
X/* The size of the output buffer (should be about one half INPUT_BUF) */
X#define OUTPUT_BUF	32
X
X/* Does memmove() exist or is memcpy() well behaved when overlapping? */
X#define MEMMOVE	memcpy
X
X/* Does your Unix allow flip-flop between real and effective user IDs? */
X#undef SETUID_BROKE
X
Xtypedef void SIG_TYPE;
X/* typedef int SIG_TYPE; */
X
X#ifdef BSD
X#define strchr index
X#define strrchr rindex
X#endif /* BSD */
SHAR_EOF
if test 2286 -ne "`wc -c < 'config.h'`"
then
	echo shar: "error transmitting 'config.h'" '(should have been 2286 characters)'
fi
fi
echo shar: "extracting 'curses.c'" '(9053 characters)'
if test -f 'curses.c'
then
	echo shar: "will not over-write existing file 'curses.c'"
else
sed 's/^X//' << \SHAR_EOF > 'curses.c'
X/*
X * Miscellaneous curses(3) routines.
X */
X
X#define STR_WIDTH	256
X#define NUM_WIDTH	16
X
X#include <stdio.h>
X#include <curses.h>
X#include <signal.h>
X#include "config.h"
X#include "misc.h"
X
X#ifdef BSD
X#include <setjmp.h>
Xjmp_buf wk_buf;
X#endif /* BSD */
X
X#ifndef OLDCURSES
X#include <term.h>
X#else /* OLDCURSES */
X#ifdef UNIXPC
X#include <sgtty.h>
X#endif /* UNIXPC */
X#endif /* OLDCURSES */
X
X/*
X * Get a string from a window.  Similar to wgetstr(), except we limit
X * the length, return a NULL (not pointer to NULL) on <ESC> key, beep
X * at any character in "disallow" string, and beep at any character not
X * in "allow". (It doesn't make sense to use both "allow" and "disallow"
X * at the same time).  Returns a pointer to a static area.
X */
X
Xchar *
Xget_str(win, num, allow, disallow)
XWINDOW *win;
Xint num;
Xchar *allow, *disallow;
X{
X	int count, x, y;
X	char ans, *strchr();
X	static char buf[STR_WIDTH];
X
X	count = 0;
X	while ((ans = wgetch(win)) != '\r') {
X					/* do our own backspace */
X		if (ans == BS || ans == DEL) {
X			if (!count) {
X				beep();
X				continue;
X			}
X			count--;
X			buf[count] = '\0';
X			getyx(win, y, x);
X			x--;
X			wmove(win, y, x);
X			waddch(win, (chtype) ' ');
X			wmove(win, y, x);
X			wrefresh(win);
X			continue;
X		}
X					/* an <ESC> anywhere in the string */
X		if (ans == ESC)
X			return(NULL);
X
X					/* illegal character? */
X		if (*disallow != '\0' && strchr(disallow, ans)) {
X			beep();
X			continue;
X		}
X		if (*allow != '\0' && !strchr(allow, ans)) {
X			beep();
X			continue;
X		}
X					/* exceeded the max? */
X		if (count >= num || count >= STR_WIDTH) {
X			beep();
X			continue;
X		}
X
X		buf[count] = ans;
X		waddch(win, (chtype) ans);
X		wrefresh(win);
X		count++;
X	}
X	buf[count] = '\0';
X	return(buf);
X}
X
X/*
X * Get a number from a window.  We limit the length and return a -1
X * on <ESC> key.
X */
X
Xint
Xget_num(win, num)
XWINDOW *win;
Xint num;
X{
X	int count, x, y, number;
X	char ans, buf[NUM_WIDTH];
X
X	count = 0;
X	while ((ans = wgetch(win)) != '\r') {
X					/* do our own backspace */
X		if (ans == BS || ans == DEL) {
X			if (!count) {
X				beep();
X				continue;
X			}
X			count--;
X			buf[count] = '\0';
X			getyx(win, y, x);
X			x--;
X			wmove(win, y, x);
X			waddch(win, (chtype) ' ');
X			wmove(win, y, x);
X			wrefresh(win);
X			continue;
X		}
X					/* an <ESC> anywhere in the string */
X		if (ans == ESC)
X			return(-1);
X					/* only digits are allowed */
X		if (ans < '0' || ans > '9') {
X			beep();
X			continue;
X		}
X					/* exceeded the max? */
X		if (count >= num || count >= NUM_WIDTH) {
X			beep();
X			continue;
X		}
X
X		buf[count] = ans;
X		waddch(win, (chtype) ans);
X		wrefresh(win);
X		count++;
X	}
X	buf[count] = '\0';
X	number = atoi(buf);
X	return(number);
X}
X
X/*
X * Change video attributes while printing a string.  The use of the
X * pre-processor definition NOPROMOTE (located in config.h) means that
X * strings will be printed without any special video attribute if the
X * requested capability doesn't exist.
X */
X
Xwattrstr(win, attr, str)
XWINDOW *win;
Xchtype attr;
Xchar *str;
X{
X	int do_it;
X					/* if nothing, do nothing */
X	if (str == NULL || *str == '\0')
X		return(0);
X
X#ifdef OLDCURSES
X	if (attr)
X		wstandout(win);
X	waddstr(win, str);
X	if (attr)
X		wstandend(win);
X#else /* OLDCURSES */
X
X#ifdef NOPROMOTE
X					/* does the capability exist? */
X	do_it = 0;
X	if ((attr & A_STANDOUT) && enter_standout_mode)
X		do_it++;
X	if ((attr & A_UNDERLINE) && enter_underline_mode)
X		do_it++;
X	if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
X		do_it++;
X	if ((attr & A_BLINK) && enter_blink_mode)
X		do_it++;
X	if ((attr & A_BOLD) && enter_bold_mode)
X		do_it++;
X	if ((attr & A_DIM) && enter_dim_mode)
X		do_it++;
X#else /* NOPROMOTE */
X	do_it = 1;
X#endif /* NOPROMOTE */
X
X	if (do_it)
X		wattron(win, attr);
X					/* print the string */
X	waddstr(win, str);
X	if (do_it)
X		wattroff(win, attr);
X#endif /* OLDCURSES */
X	return(0);
X}
X
X/*
X * Change video attributes while printing a character.
X */
X
Xwattrch(win, attr, c)
XWINDOW *win;
Xchtype attr;
Xchar c;
X{
X	int do_it;
X
X	if (c == '\0')
X		return(0);
X#ifdef OLDCURSES
X	if (attr)
X		wstandout(win);
X	waddch(win, (chtype) c);
X	if (attr)
X		wstandend(win);
X#else /* OLDCURSES */
X
X#ifdef NOPROMOTE
X					/* does the capability exist? */
X	do_it = 0;
X	if ((attr & A_STANDOUT) && enter_standout_mode)
X		do_it++;
X	if ((attr & A_UNDERLINE) && enter_underline_mode)
X		do_it++;
X	if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
X		do_it++;
X	if ((attr & A_BLINK) && enter_blink_mode)
X		do_it++;
X	if ((attr & A_BOLD) && enter_bold_mode)
X		do_it++;
X	if ((attr & A_DIM) && enter_dim_mode)
X		do_it++;
X#else /* NOPROMOTE */
X	do_it = 1;
X#endif /* NOPROMOTE */
X
X	if (do_it)
X		wattron(win, attr);
X					/* print the character */
X	waddch(win, (chtype) c);
X	if (do_it)
X		wattroff(win, attr);
X#endif /* OLDCURSES */
X	return(0);
X}
X
X
X/*
X * Change video attributes while printing a number.
X */
X
Xwattrnum(win, attr, num)
XWINDOW *win;
Xchtype attr;
Xint num;
X{
X	int do_it;
X	char buf[40];
X
X	sprintf(buf, "%d", num);
X
X#ifdef OLDCURSES
X	if (attr)
X		wstandout(win);
X	waddstr(win, buf);
X	if (attr)
X		wstandend(win);
X#else /* OLDCURSES */
X
X#ifdef NOPROMOTE
X					/* does the capability exist? */
X	do_it = 0;
X	if ((attr & A_STANDOUT) && enter_standout_mode)
X		do_it++;
X	if ((attr & A_UNDERLINE) && enter_underline_mode)
X		do_it++;
X	if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
X		do_it++;
X	if ((attr & A_BLINK) && enter_blink_mode)
X		do_it++;
X	if ((attr & A_BOLD) && enter_bold_mode)
X		do_it++;
X	if ((attr & A_DIM) && enter_dim_mode)
X		do_it++;
X#else /* NOPROMOTE */
X	do_it = 1;
X#endif /* NOPROMOTE */
X
X	if (do_it)
X		wattron(win, attr);
X					/* print the character */
X	waddstr(win, buf);
X	if (do_it)
X		wattroff(win, attr);
X#endif /* OLDCURSES */
X	return(0);
X}
X
X/*
X * Prompt for a Yes or No answer.  Echo the single key input as words.
X * Handle the funny cursor movement problems with magic cookie terminals.
X * Returns a 1 on yes.
X */
X
Xint
Xyes_prompt(win, y, x, attr, str)
XWINDOW *win;
Xint y, x;
Xchtype attr;
Xchar *str;
X{
X	int ret_code;
X	char new_str[80], *strcpy(), *strcat();
X					/* sanity checking */
X	if (strlen(str) > 71)
X		*(str+71) = '\0';
X					/* build and display the prompt */
X	strcpy(new_str, str);
X	strcat(new_str, "? (y/n):");
X	mvwattrstr(win, y, x, attr, new_str);
X	wmove(win, y, strlen(new_str)+x+2);
X	wrefresh(win);
X
X	ret_code = -1;
X	while (ret_code == -1) {
X		switch (wgetch(win)) {
X			case 'y':
X			case 'Y':
X				waddstr(win, "Yes");
X				ret_code = 1;
X				break;
X			case 'n':
X			case 'N':
X			case ESC:
X				waddstr(win, "No");
X				ret_code = 0;
X				break;
X			default:
X				beep();
X
X		}
X	}
X	wrefresh(win);
X	return(ret_code);
X}
X
X/*
X * Handy routine for clear-to-end-of-line.  Fixes up the box if requested.
X */
X
Xint
Xclear_line(win, y, x, re_box)
XWINDOW *win;
Xint y, x, re_box;
X{
X	if (wmove(win, y, x) == ERR)
X		return(ERR);
X
X	wclrtoeol(win);
X
X	if (re_box) {
X		mvwaddch(win, y, win->_maxx-1, (chtype) ACS_VLINE);
X		wmove(win, y, x);
X	}
X	return(0);
X}
X
X/*
X * Routine to make a horizontal line.  Does NOT do a wrefresh().
X */
X
Xint
Xhorizontal(win, x, y, len)
XWINDOW *win;
Xint x, y, len;
X{
X	wmove(win, x, y);
X
X	while (len--)
X		waddch(win, ACS_HLINE);
X
X	return(0);
X}
X
X/*
X * Wait for a key or time out.  Returns a -1 on timeout.  This is similar
X * to the half-delay mode in the newer versions of curses(3).
X */
X
Xstatic int wk_flag;
X
X/* ARGSUSED */
Xint
Xwait_key(win, sec)
XWINDOW *win;
Xunsigned int sec;
X{
X	int key, wk_force();
X	unsigned int alarm();
X	char c;
X
X	signal(SIGALRM, wk_force);
X	wk_flag = 0;
X
X	alarm(sec);
X
X#ifdef BSD
X	if (setjmp(wk_buf))
X		return(-1);
X#endif /* BSD */
X
X#ifdef WGETCH_BROKE
X	read(0, &c, 1);
X	key = c & 0x7f;
X#else /* WGETCH_BROKE */
X	key = wgetch(win);
X#endif /* WGETCH_BROKE */
X
X	if (wk_flag)
X		return(-1);
X	alarm(0);
X	return(key);
X}
X
X/* ARGSUSED */
Xstatic int
Xwk_force(dummy)
Xint dummy;
X{
X#ifdef BSD
X	longjmp(wk_buf, 1);
X#else /* BSD */
X	signal(SIGALRM, wk_force);
X	wk_flag = 1;
X#endif /* BSD */
X}
X
X/*
X * Here are some routines that are probably missing from the older
X * flavors of curses(3).
X */
X
X#ifdef OLDCURSES
X/*
X * Make the terminal bell go off
X */
X
Xint
Xbeep()
X{
X	fputc(BEL, stderr);
X	return(0);
X}
X
X/*
X * Fix the stdin so that a read is satisfied immediately.  When read()
X * is called it returns the character in the queue, or an error if no
X * key was pressed.  The window argument is not used!
X */
X
X/* ARGSUSED */
Xint
Xnodelay(win, on)
XWINDOW *win;
Xint on;
X{
X	if (on)
X		tty_noblock(0, TRUE);
X	else
X		tty_noblock(0, FALSE);
X	return(0);
X}
X
X/*
X * Take the terminal out of the "curses mode".  The t_mode structure was 
X * captured before we initialized the curses mode.
X */
X
Xint
Xresetterm()
X{
X	extern char _putchar();
X	extern struct sgttyb t_mode;
X
X	ioctl(0, TIOCSETP, &t_mode);
X	tputs(TE, 1, _putchar);
X	tputs(VE, 1, _putchar);
X	return(0);
X}
X
X/*
X * Put the terminal back into the "curses mode".  The c_mode structure was
X * captured after we initialized the curses mode.
X */
X
Xint
Xfixterm()
X{
X	extern char _putchar();
X	extern struct sgttyb c_mode;
X
X	ioctl(0, TIOCSETP, &c_mode);
X	tputs(TI, 1, _putchar);
X	tputs(VS, 1, _putchar);
X	return(0);
X}
X#endif /* OLDCURSES */
SHAR_EOF
if test 9053 -ne "`wc -c < 'curses.c'`"
then
	echo shar: "error transmitting 'curses.c'" '(should have been 9053 characters)'
fi
fi
echo shar: "extracting 'd_delete.c'" '(2015 characters)'
if test -f 'd_delete.c'
then
	echo shar: "will not over-write existing file 'd_delete.c'"
else
sed 's/^X//' << \SHAR_EOF > 'd_delete.c'
X/*
X * The delete option of the dialing directory.  Prompts for saving
X * changes to disk.  A non-zero return code means that entries were deleted.
X */
X
X#include <stdio.h>
X#include <curses.h>
X#include "config.h"
X#include "dial_dir.h"
X#include "misc.h"
X#include "param.h"
X
Xint
Xdelete()
X{
X	extern char *null_ptr;
X	WINDOW *d_win, *newwin();
X	int i, first, last;
X	void free_ptr();
X
X	d_win = newwin(6, 32, 10, 15);
X
X	mvwaddstr(d_win, 2, 2, "Delete entry:     thru:");
X	box(d_win, VERT, HORZ);
X	wmove(d_win, 2, 16);
X	wrefresh(d_win);
X					/* get the first of the range */
X	while ((first = get_num(d_win, 3)) != -1) {
X		if (first > 0 && first <= NUM_DIR)
X			break;
X		mvwaddstr(d_win, 2, 16, "   ");
X		wmove(d_win, 2, 16);
X		beep();
X		wrefresh(d_win);
X	}
X	if (first == -1) {
X		delwin(d_win);
X		return(0);
X	}
X					/* get the last of the range */
X	wmove(d_win, 2, 26);
X	wrefresh(d_win);
X	while ((last = get_num(d_win, 3)) != -1) {
X		if ((first <= last && last <= NUM_DIR) || last == 0)
X			break;
X		mvwaddstr(d_win, 2, 26, "   ");
X		wmove(d_win, 2, 26);
X		beep();
X		wrefresh(d_win);
X	}
X	if (last == -1) {
X		delwin(d_win);
X		return(0);
X	}
X					/* if "last" omitted, echo "first" */
X	if (!last) {
X		last = first;
X		mvwprintw(d_win, 2, 26, "%d", first);
X		wrefresh(d_win);
X	}
X					/* save to disk? */
X	if (yes_prompt(d_win, 3, 2, A_BOLD, "Are you sure")) {
X					/* delete from the physical file */
X		if (del_dir(first, last)) {
X			touchwin(d_win);
X			wrefresh(d_win);
X		}
X		/*
X		 * We don't really care if del_dir() fails because we still
X		 * change the version in memory.
X		 */
X		for (i=first; i<=last; i++) {
X			free_ptr(dir->name[i]);
X			free_ptr(dir->number[i]);
X			free_ptr(dir->script[i]);
X			dir->name[i] = null_ptr;
X			dir->number[i] = null_ptr;
X			dir->baud[i] = param->d_baud;
X			dir->parity[i] = param->d_parity;
X			dir->dbits[i] = param->d_dbits;
X			dir->sbits[i] = param->d_sbits;
X			dir->duplex[i] = *param->d_duplex;
X			dir->script[i] = null_ptr;
X		}
X		delwin(d_win);
X		return(1);
X	}
X	delwin(d_win);
X	return(0);
X}
SHAR_EOF
if test 2015 -ne "`wc -c < 'd_delete.c'`"
then
	echo shar: "error transmitting 'd_delete.c'" '(should have been 2015 characters)'
fi
fi
echo shar: "extracting 'd_lib.c'" '(6921 characters)'
if test -f 'd_lib.c'
then
	echo shar: "will not over-write existing file 'd_lib.c'"
else
sed 's/^X//' << \SHAR_EOF > 'd_lib.c'
X/*
X * Routines to manipulate the dialing directory file pcomm.dial_dir
X */
X
X#include <stdio.h>
X#include "dial_dir.h"
X#include "param.h"
X
X/*
X * Read the dialing directory.  Returns a pointer to a static area
X * containing the DIAL_DIR structure.  All of the entries are created
X * regardless of the number of physical entries in the file.  Element
X * number zero is reserved for the "manual" entry.  All errors are fatal.
X */
X
Xstruct DIAL_DIR *
Xread_dir(extra)
Xchar *extra;
X{
X	extern char *null_ptr;
X	FILE *fp, *my_fopen();
X	int i, line, oops;
X	char *str_dup(), buf[200], *temp_token, *str, *str_tok(), token[20];
X	char message[80], *sep, *findfile();
X	static struct DIAL_DIR d;
X	void error_win();
X
X	if ((d.d_path = findfile(extra, "pcomm.dial_dir")) == NULL)
X		error_win(1, "Support file \"pcomm.dial_dir\" is missing", "or no read permission");
X
X	if (!(fp = my_fopen(d.d_path, "r"))) {
X		sprintf(buf, "\"%s\" for read", d.d_path);
X		error_win(1, "Can't open dialing directory file", buf);
X	}
X
X	sep = ";;---;;\n";
X	line = 0;
X	oops = 0;
X	while (fgets(buf, 200, fp) != NULL) {
X		line++;
X		if (line > NUM_DIR)
X			break;
X					/* get the token */
X		if (!(temp_token = str_tok(buf, '='))) {
X			sprintf(message, "is missing a token at line %d", line);
X			oops++;
X			break;
X		}
X		/*
X		 * Parse the rest of the line.  This is similar to using
X		 * the "real" strtok() function, but this version returns
X		 * a pointer to NULL if the token is missing.  Note the use
X		 * of the array of field separators.
X		 */
X		for (i=0; i<8; i++) {
X			if (!(str = str_tok((char *) NULL, sep[i]))) {
X				sprintf(message, "is missing a parameter at line %d", line);
X				oops++;
X				break;
X			}
X			switch (i) {
X				case 0:
X					d.name[line] = str_dup(str);
X					break;
X				case 1:
X					d.number[line] = str_dup(str);
X					break;
X				case 2:
X					d.baud[line] = atoi(str);
X					break;
X				case 3:
X					d.parity[line] = *str;
X					break;
X				case 4:
X					d.dbits[line] = atoi(str);
X					break;
X				case 5:
X					d.sbits[line] = atoi(str);
X					break;
X				case 6:
X					d.duplex[line] = *str;
X					break;
X				case 7:
X					d.script[line] = str_dup(str);
X					break;
X			}
X		}
X		if (oops)
X			break;
X					/* sanity checking */
X		sprintf(token, "DIR_%d", line);
X		if (strcmp(temp_token, token)) {
X			sprintf(message, "is corrupted at line %d", line);
X			oops++;
X			break;
X		}
X	}
X	fclose(fp);
X
X	if (oops) {
X		sprintf(buf, "Dialing directory file \"%s\"", d.d_path);
X		error_win(1, buf, message);
X	}
X	d.d_entries = line;
X					/* if empty database */
X	if (!line) {
X		sprintf(buf, "Dialing directory file \"%s\"", d.d_path);
X		error_win(0, buf, "has no data");
X	}
X					/* fill in the rest with defaults */
X	for (i=line+1; i<=NUM_DIR; i++) {
X		d.name[i] = null_ptr;
X		d.number[i] = null_ptr;
X		d.baud[i] = param->d_baud;
X		d.parity[i] = param->d_parity;
X		d.dbits[i] = param->d_dbits;
X		d.sbits[i] = param->d_sbits;
X		d.duplex[i] = *param->d_duplex;
X		d.script[i] = null_ptr;
X	}
X					/* create an empty "manual" entry */
X	d.name[0] = null_ptr;
X	d.number[0] = null_ptr;
X	d.baud[0] = param->d_baud;
X	d.parity[0] = param->d_parity;
X	d.dbits[0] = param->d_dbits;
X	d.sbits[0] = param->d_sbits;
X	d.duplex[0] = *param->d_duplex;
X	d.script[0] = null_ptr;
X					/* create an empty queue */
X	for (i=0; i<NUM_QUEUE; i++) {
X		d.q_ld[i] = '\0';
X		d.q_num[i] = -1;
X	}
X					/* the start up d_cur is 0 */
X	d.d_cur = 0;
X	return(&d);
X}
X
X/*
X * Update a dialing directory entry.  Update only the one entry asked for,
X * not the entire image in memory.  If the new entry is beyond the end of
X * the physical file, then fill in the holes, and update "dir->d_entries".
X * A non-zero return code means a non-fatal error.
X */
X
Xint
Xup_dir(entry)
Xint entry;
X{
X	FILE *fp_in, *fp_out, *my_fopen();
X	int i;
X	char *temp[NUM_DIR+1], buf[200], *str_dup(), *str_rep();
X	void error_win(), free_ptr();
X
X					/* open for read */
X	if (!(fp_in = my_fopen(dir->d_path, "r"))) {
X		sprintf(buf, "\"%s\" for read", dir->d_path);
X		error_win(1, "Can't open dialing directory file", buf);
X	}
X					/* read in a temporary version */
X	i = 0;
X	while (fgets(buf, 200, fp_in) != NULL)
X		temp[++i] = str_dup(buf);
X
X	fclose(fp_in);
X					/* alter only 1 entry */
X	sprintf(buf, "DIR_%d=%s;%s;%d-%c-%d-%d;%c;%s\n", entry,
X	 dir->name[entry], dir->number[entry], dir->baud[entry],
X	 dir->parity[entry], dir->dbits[entry], dir->sbits[entry],
X	 dir->duplex[entry], dir->script[entry]);
X
X	if (entry <= dir->d_entries)
X		free_ptr(temp[entry]);
X	temp[entry] = str_dup(buf);
X					/* fill in holes if beyond end */
X	if (entry > dir->d_entries+1) {
X		for (i=dir->d_entries+1; i<entry; i++) {
X			sprintf(buf, "DIR_%d=;;%d-%c-%d-%d;%c;\n", i,
X			 param->d_baud, param->d_parity, param->d_dbits,
X			 param->d_sbits, *param->d_duplex);
X			temp[i] = str_rep(temp[i], buf);
X		}
X	}
X					/* update "dir->d_entries" */
X	if (entry > dir->d_entries)
X		dir->d_entries = entry;
X
X					/* open for write */
X	if (!(fp_out = my_fopen(dir->d_path, "w"))) {
X		for (i=1; i<=dir->d_entries; i++)
X			free_ptr(temp[i]);
X		sprintf(buf, "\"%s\"", dir->d_path);
X		error_win(0, "No write permission on dialing directory file", buf);
X		return(1);
X	}
X					/* put it back */
X	for (i=1; i<=dir->d_entries; i++) {
X		fputs(temp[i], fp_out);
X		free_ptr(temp[i]);
X	}
X
X	fclose(fp_out);
X	return(0);
X}
X
X/*
X * Delete a range of dialing directory entries.  Actually, just copies
X * default (empty) entries in place of deleted entries.  However, it will
X * shrink the file if deletions occur at the physical EOF.  A non-zero
X * return code means a non-fatal error.
X */
X
Xint
Xdel_dir(first, last)
Xint first, last;
X{
X	FILE *fp_in, *fp_out, *my_fopen();
X	int i;
X	char *temp[NUM_DIR+1], buf[200], *str_dup(), *str_rep();
X	void error_win(), free_ptr();
X					/* sanity checking */
X	if (first > dir->d_entries)
X		return(0);
X	if (last > dir->d_entries)
X		last = dir->d_entries;
X
X					/* open for read */
X	if (!(fp_in = my_fopen(dir->d_path, "r"))) {
X		sprintf(buf, "\"%s\" for read", dir->d_path);
X		error_win(1, "Can't open dialing directory file", buf);
X	}
X					/* read in a temporary version */
X	i = 0;
X	while (fgets(buf, 200, fp_in) != NULL)
X		temp[++i] = str_dup(buf);
X
X	fclose(fp_in);
X					/* delete the range of values */
X	for (i=first; i<=last; i++) {
X		sprintf(buf, "DIR_%d=;;%d-%c-%d-%d;%c;\n", i, param->d_baud,
X		 param->d_parity, param->d_dbits, param->d_sbits,
X		 *param->d_duplex);
X		temp[i] = str_rep(temp[i], buf);
X	}
X					/* shrink the file? */
X	if (last >= dir->d_entries) {
X		for (i=first; i<=last; i++)
X			free_ptr(temp[i]);
X		dir->d_entries = first-1;
X	}
X					/* open for write */
X	if (!(fp_out = my_fopen(dir->d_path, "w"))) {
X		for (i=1; i<=dir->d_entries; i++)
X			free_ptr(temp[i]);
X		sprintf(buf, "\"%s\"", dir->d_path);
X		error_win(0, "No write permission on dialing directory file", buf);
X		return(1);
X	}
X					/* put it all back */
X	for (i=1; i<=dir->d_entries; i++) {
X		fputs(temp[i], fp_out);
X		free_ptr(temp[i]);
X	}
X
X	fclose(fp_out);
X	return(0);
X}
SHAR_EOF
if test 6921 -ne "`wc -c < 'd_lib.c'`"
then
	echo shar: "error transmitting 'd_lib.c'" '(should have been 6921 characters)'
fi
fi
echo shar: "extracting 'd_manual.c'" '(1944 characters)'
if test -f 'd_manual.c'
then
	echo shar: "will not over-write existing file 'd_manual.c'"
else
sed 's/^X//' << \SHAR_EOF > 'd_manual.c'
X/*
X * The manual dial option of the dialing directory.  A non-zero return code
X * means we're ready to dial.  Dialing directory entry 0 is reserved
X * for the manual dial option.  No sanity checking is done on the input.
X */
X
X#include <stdio.h>
X#include <curses.h>
X#include "config.h"
X#include "dial_dir.h"
X#include "misc.h"
X
Xint
Xmanual()
X{
X	extern int xmc;
X	extern char *null_ptr;
X	WINDOW *m_win, *newwin();
X	char *number, *str_rep(), *get_str(), ld_code, *strchr();
X	void fix_xmc(), free_ptr();
X
X	m_win = newwin(5, 50, 0, 20);
X
X	box(m_win, VERT, HORZ);
X	mvwaddstr(m_win, 2, 3, "Phone Number: ");
X	wrefresh(m_win);
X					/* get a phone number */
X	if ((number = get_str(m_win, 30, "", "\n")) == NULL) {
X		werase(m_win);
X		wrefresh(m_win);
X		delwin(m_win);
X		if (xmc > 0)
X			fix_xmc();
X		return(0);
X	}
X					/* is first char an LD code? */
X	ld_code = '\0';
X	if (strchr("+-@#", *number)) {
X		ld_code = *number;
X		number++;
X	}
X					/* put it in the queue */
X	dir->q_ld[0] = ld_code;
X	dir->q_num[0] = 0;
X					/* end of queue marker */
X	dir->q_num[1] = -1;
X	dir->d_cur = 0;
X					/* build the entry zero */
X	dir->name[0] = str_rep(dir->name[0], number);
X					/* if space, change to null_ptr */
X	if (!strcmp(number, " ")) {
X		free_ptr(dir->number[0]);
X		dir->number[0] = null_ptr;
X	}
X	else
X		dir->number[0] = str_rep(dir->number[0], number);
X					/* it overlaps dm_win, so erase it */
X	werase(m_win);
X	wrefresh(m_win);
X	delwin(m_win);
X	if (xmc > 0)
X		fix_xmc();
X	return(1);
X}
X
X/*
X * Clear the end of the physical screen where the magic cookie got shifted
X * Geez, I hate magic cookie terminals...  Wyse, are you listening?
X */
X
Xstatic void
Xfix_xmc()
X{
X	WINDOW *cl_win, *newwin();
X
X	/*
X	 * Since the cookie got shifted off the window, we have to
X	 * create a new window to cover where the cookie ended up.
X	 */
X	cl_win = newwin(1, 2, 4, 78);
X					/* have to touch, otherwise nothing! */
X	touchwin(cl_win);
X	wrefresh(cl_win);
X	delwin(cl_win);
X
X	return;
X}
SHAR_EOF
if test 1944 -ne "`wc -c < 'd_manual.c'`"
then
	echo shar: "error transmitting 'd_manual.c'" '(should have been 1944 characters)'
fi
fi
echo shar: "extracting 'd_menu.c'" '(6993 characters)'
if test -f 'd_menu.c'
then
	echo shar: "will not over-write existing file 'd_menu.c'"
else
sed 's/^X//' << \SHAR_EOF > 'd_menu.c'
X/*
X * Routines for the dialing directory menu.
X */
X
X#include <stdio.h>
X#include <curses.h>
X#include "config.h"
X#include "dial_dir.h"
X#include "misc.h"
X#include "param.h"
X
Xstatic int current = 1;
X/*
X * Display the dialing directory and prompt for options.  A non-zero return
X * code means we're ready to dial.
X */
X
Xint
Xdial_menu()
X{
X	extern int xmc;
X	WINDOW *dm_win, *newwin();
X	char buf[5], ld_code;
X	int ans, start, needs_repair, count, x, y, i, ret_code;
X	void dir_scroll(), active_ld(), disp_ld(), print_dir(), st_line();
X
X	touchwin(stdscr);
X	refresh();
X	st_line("");
X
X	dm_win = newwin(22, 78, 1, 1);
X	mvwattrstr(dm_win, 1, 20, A_BOLD, "D I A L I N G       D I R E C T O R Y");
X	horizontal(dm_win, 2, 0, 78);
X	mvwattrstr(dm_win, 3, 0, A_STANDOUT, "           Name                   Number        Baud P D S Dpx  Script/TTY    ");
X					/* show 10 entries */
X	dir_scroll(dm_win, current);
X
X	mvwaddstr(dm_win, 15, 4, "==>");
X	mvwattrch(dm_win, 15, 14, A_BOLD, 'R');
X	waddstr(dm_win, " Revise");
X	mvwattrch(dm_win, 15, 34, A_BOLD, 'M');
X	waddstr(dm_win, " Manual Dialing");
X	mvwaddstr(dm_win, 15, 55, "Entry to Dial");
X
X	mvwattrch(dm_win, 16, 14, A_BOLD, 'P');
X	waddstr(dm_win, " LD Codes");
X	mvwattrch(dm_win, 16, 34, A_BOLD, 'D');
X	waddstr(dm_win, " Delete Entry");
X	mvwattrstr(dm_win, 16, 55, A_BOLD, "<CR>");
X	waddstr(dm_win, " Scroll Down");
X
X	mvwattrstr(dm_win, 17, 14, A_BOLD, "<up>/<down>");
X	waddstr(dm_win, " Page");
X	mvwattrch(dm_win, 17, 34, A_BOLD, 'L');
X	waddstr(dm_win, " Print Entries");
X	mvwattrstr(dm_win, 17, 55, A_BOLD, "<ESC>");
X	waddstr(dm_win, " Exit");
X
X	mvwaddstr(dm_win, 19, 4, "LD Codes Active:");
X					/* show which LD codes are active */
X	active_ld(dm_win);
X
X	box(dm_win, VERT, HORZ);
X	y = 15;
X	x = 8;
X	wmove(dm_win, 15, 8);
X	wrefresh(dm_win);
X
X#ifndef OLDCURSES
X	keypad(dm_win, TRUE);
X#endif /* OLDCURSES */
X					/* prompt for options */
X	count = 0;
X	ld_code = '\0';
X	ret_code = 0;
X	do {
X		needs_repair = 0;
X		ans = wgetch(dm_win);
X					/* get an entry number */
X		if (ans >= '0' && ans <= '9') {
X			if (count > 2) {
X				beep();
X				continue;
X			}
X			buf[count] = ans;
X			waddch(dm_win, (chtype) ans);
X			wrefresh(dm_win);
X			count++;
X			continue;
X		}
X		switch (ans) {
X			case DEL:
X			case BS:	/* do our own backspace */
X				if (!count) {
X					beep();
X					break;
X				}
X				count--;
X				if (!count)
X					ld_code = '\0';
X				buf[count] = '\0';
X				getyx(dm_win, y, x);
X				x--;
X				wmove(dm_win, y, x);
X				waddch(dm_win, (chtype) ' ');
X				wmove(dm_win, y, x);
X				wrefresh(dm_win);
X				break;
X#ifndef OLDCURSES
X			case KEY_UP:
X#endif /* OLDCURSES */
X			case 'u':
X			case 'U':	/* up arrow key */
X				if (current == 1) {
X					beep();
X					break;
X				}
X				start = current - 10;
X				if (start < 1)
X					start = 1;
X				current = start;
X				dir_scroll(dm_win, start);
X				break;
X#ifndef OLDCURSES
X			case KEY_DOWN:
X			case '\n':
X#endif /* OLDCURSES */
X			case 'n':
X			case 'N':	/* down arrow key */
X				if (current == NUM_DIR-9) {
X					beep();
X					break;
X				}
X				start = current + 10;
X				if (start > NUM_DIR-9)
X					start = NUM_DIR-9;
X				current = start;
X				dir_scroll(dm_win, start);
X				break;
X			case '\r':	/* <CR> key */
X				if (!count) {
X					if (current == NUM_DIR-9) {
X						beep();
X						break;
X					}
X					current++;
X					if (current > NUM_DIR-9)
X						current = NUM_DIR-9;
X					dir_scroll(dm_win, current);
X				}
X				/*
X				 * The <CR> is used for the scroll-down-one-line
X				 * function, and to terminate numeric input.
X				 */
X				else {
X					buf[count] = '\0';
X					i = atoi(buf);
X					if (!i || i > NUM_DIR) {
X						beep();
X						mvwaddstr(dm_win, 15, 8, "   ");
X						x = 8;
X						count = 0;
X						break;
X					}
X					dir->q_ld[0] = ld_code;
X					dir->q_num[0] = i;
X					dir->d_cur = i;
X
X					/* end of queue marker */
X					dir->q_num[1] = -1;
X
X					ret_code++;
X					break;
X				}
X				break;
X			case 'r':
X			case 'R':	/* revise */
X				if (revise()) {
X					active_ld(dm_win);
X					dir_scroll(dm_win, current);
X				}
X				touchwin(dm_win);
X				break;
X			case 'p':	/* display LD codes */
X			case 'P':
X				disp_ld();
X				touchwin(dm_win);
X				needs_repair++;
X				break;
X			case 'd':
X			case 'D':	/* delete a range of entries */
X				if (delete())
X					dir_scroll(dm_win, current);
X				touchwin(dm_win);
X				break;
X			case 'm':
X			case 'M':	/* manual dial */
X				if (manual()) {
X					ret_code++;
X					break;
X				}
X				touchwin(dm_win);
X				needs_repair++;
X				break;
X			case 'l':
X			case 'L':	/* print the entries */
X				print_dir();
X				touchwin(dm_win);
X				needs_repair++;
X				break;
X			case '+':	/* LD codes */
X			case '-':
X			case '@':
X			case '#':
X				waddch(dm_win, (chtype) ans);
X				wrefresh(dm_win);
X				ld_code = ans;
X				continue;
X			case ESC:	/* <ESC> key (exit) */
X				break;
X			default:
X				beep();
X		}
X		if (ret_code)
X			break;
X					/* magic cookie terminal? */
X		if (xmc > 0 && needs_repair) {
X			clear_line(dm_win, 1, 0, FALSE);
X			clear_line(dm_win, 3, 0, FALSE);
X			wrefresh(dm_win);
X			mvwattrstr(dm_win, 1, 20, A_BOLD, "D I A L I N G       D I R E C T O R Y");
X			mvwattrstr(dm_win, 3, 0, A_STANDOUT, "           Name                   Number        Baud P D S Dpx  Script/TTY    ");
X			box(dm_win, VERT, HORZ);
X		}
X		wmove(dm_win, y, x);
X		wrefresh(dm_win);
X	} while (ans != ESC);
X
X	werase(dm_win);
X	wrefresh(dm_win);
X	delwin(dm_win);
X	if (ret_code) {
X		touchwin(stdscr);
X		refresh();
X	}
X	return(ret_code);
X}
X
X/*
X * Scroll the dialing directory.  Actually, we're not doing a real scroll
X * function on the screen, we're just repainting 10 lines.
X */
X
Xstatic void
Xdir_scroll(win, start)
XWINDOW *win;
Xint start;
X{
X	int i;
X
X	wmove(win, 4, 0);
X	for (i=start; i<start+10; i++)
X		wprintw(win,
X		 "%4d- %-20.20s %18.18s  %5d-%c-%d-%d  %c  %-14.14s\n", i,
X		 dir->name[i], dir->number[i], dir->baud[i], dir->parity[i],
X		 dir->dbits[i], dir->sbits[i], dir->duplex[i], dir->script[i]);
X	box(win, VERT, HORZ);
X	return;
X}
X
X/*
X * Display the Long Distance codes.  Press any key to continue.
X */
X
Xstatic void
Xdisp_ld()
X{
X	WINDOW *ld_win, *newwin();
X
X	ld_win = newwin(12, 30, 0, 0);
X	mvwaddstr(ld_win, 1, 5, "Long Distance Codes\n");
X	horizontal(ld_win, 2, 0, 30);
X	mvwprintw(ld_win, 3, 2, "+ %-20.20s", param->ld_plus);
X	mvwprintw(ld_win, 5, 2, "- %-20.20s", param->ld_minus);
X	mvwprintw(ld_win, 7, 2, "@ %-20.20s", param->ld_at);
X	mvwprintw(ld_win, 9, 2, "# %-20.20s", param->ld_pound);
X	box(ld_win, VERT, HORZ);
X
X	mvwaddstr(ld_win, 11, 8, " Press any key ");
X	wmove(ld_win, 11, 29);
X	wrefresh(ld_win);
X	wgetch(ld_win);
X					/* it overlaps, so erase it */
X	werase(ld_win);
X	wrefresh(ld_win);
X	delwin(ld_win);
X	return;
X}
X
X/*
X * Display which of the Long Distance codes are active.
X */
X
Xstatic void
Xactive_ld(win)
XWINDOW *win;
X{
X	mvwaddstr(win, 19, 21, "        ");
X	wmove(win, 19, 21);
X					/* a NULL means it's not active */
X	if (*param->ld_plus != '\0')
X		waddstr(win, "+ ");
X	if (*param->ld_minus != '\0')
X		waddstr(win, "- ");
X	if (*param->ld_at != '\0')
X		waddstr(win, "@ ");
X	if (*param->ld_pound != '\0')
X		waddstr(win, "# ");
X	return;
X}
SHAR_EOF
if test 6993 -ne "`wc -c < 'd_menu.c'`"
then
	echo shar: "error transmitting 'd_menu.c'" '(should have been 6993 characters)'
fi
fi
echo shar: "extracting 'd_print.c'" '(3958 characters)'
if test -f 'd_print.c'
then
	echo shar: "will not over-write existing file 'd_print.c'"
else
sed 's/^X//' << \SHAR_EOF > 'd_print.c'
X/*
X * The print option of the dialing directory.  A carriage return will
X * send the dialing directory to the print spool program, otherwise the
X * selected file will be used.
X */
X
X#define MAX_STRING	80
X
X#include <stdio.h>
X#include <curses.h>
X#include "config.h"
X#include "dial_dir.h"
X#include "misc.h"
X
Xvoid
Xprint_dir()
X{
X	FILE *fp, *popen(), *my_fopen();
X	WINDOW *p_win, *newwin();
X	char *ans, *file, *e_get_str(), buf[100], *expand();
X	int is_printer, i;
X	void error_win();
X	unsigned int sleep();
X
X	p_win = newwin(5, 54, 0, 26);
X
X	mvwaddstr(p_win, 2, 3, "Print to: (printer)");
X	box(p_win, VERT, HORZ);
X	wmove(p_win, 2, 13);
X	wrefresh(p_win);
X
X	/*
X	 * This is a special version of get_str() that looks at the
X	 * first character to see if it should erase the default answer
X	 * already on the screen.
X	 */
X	if ((ans = e_get_str(p_win, 80)) == NULL) {
X					/* erase because it overlaps dm_win */
X		werase(p_win);
X		wrefresh(p_win);
X		delwin(p_win);
X		return;
X	}
X	file = expand(ans);
X	is_printer = 0;
X					/* the default (printer) */
X	if (*file == '\0') {
X		if (!(fp = popen(LPRINT, "w"))) {
X			sprintf(buf, "\"%s\"", LPRINT);
X			error_win(0, "Can't open printer program", buf);
X			werase(p_win);
X			wrefresh(p_win);
X			delwin(p_win);
X			return;
X		}
X		is_printer++;
X	}
X					/* the requested file */
X	else {
X		/*
X		 * Check to see if the file already exists (and if you
X		 * have write permission too).  Currently only allows
X		 * you to bail out or overwrite the file (no append).
X		 */
X		switch(can_write(file)) {
X			case DENIED:
X				sprintf(buf, "\"%s\"", file);
X				error_win(0, "No write permission on file", buf);
X				werase(p_win);
X				wrefresh(p_win);
X				delwin(p_win);
X				return;
X			case OK_BUT_EXISTS:
X				werase(p_win);
X				mvwprintw(p_win, 2, 3, "File \"%s\" already exists!", file);
X				beep();
X				box(p_win, VERT, HORZ);
X				if (!yes_prompt(p_win, 3, 3, A_BOLD, "Overwrite")) {
X					werase(p_win);
X					wrefresh(p_win);
X					delwin(p_win);
X					return;
X				}
X				/* fall thru */
X			case WRITE_OK:
X				if (!(fp = my_fopen(file, "w"))) {
X					sprintf(buf, "\"%s\"", file);
X					error_win(0, "Can't open file", buf);
X					werase(p_win);
X					wrefresh(p_win);
X					delwin(p_win);
X					return;
X				}
X				break;
X		}
X	}
X
X	werase(p_win);
X	mvwaddstr(p_win, 2, 13, "Printing Pcomm directory");
X	box(p_win, VERT, HORZ);
X	wrefresh(p_win);
X
X	/*
X	 * Only prints up to the end of the physical file, not the entire
X	 * structure.  I gave some thought about not printing empty entries,
X	 * but...
X	 */
X	for (i=1; i<=dir->d_entries; i++)
X		fprintf(fp, "%4d- %-20.20s %18.18s  %5d-%c-%d-%d  %c  %-14.14s\n",
X		 i, dir->name[i], dir->number[i], dir->baud[i], dir->parity[i],
X		 dir->dbits[i], dir->sbits[i], dir->duplex[i], dir->script[i]);
X
X	if (is_printer)
X		pclose(fp);
X	else {
X					/* a dramatic delay... */
X		sleep(1);
X		fclose(fp);
X	}
X
X	werase(p_win);
X	wrefresh(p_win);
X	delwin(p_win);
X	return;
X}
X
X/*
X * Get a string from a window but erase the line first.
X */
X
Xstatic char *
Xe_get_str(win, num)
XWINDOW *win;
Xint num;
X{
X	int count, x, y, done_it;
X	char ans;
X	static char buf[MAX_STRING];
X
X	done_it = 0;
X	count = 0;
X	while ((ans = wgetch(win)) != '\r') {
X					/* do our own backspace */
X		if (ans == BS || ans == DEL) {
X			if (!count) {
X				beep();
X				continue;
X			}
X			count--;
X			buf[count] = '\0';
X			getyx(win, y, x);
X			x--;
X			wmove(win, y, x);
X			waddch(win, (chtype) ' ');
X			wmove(win, y, x);
X			wrefresh(win);
X			continue;
X		}
X					/* exceeded the max? */
X		if (count >= num || count >= MAX_STRING) {
X			beep();
X			continue;
X		}
X					/* illegal character? */
X		if (ans == '\n') {
X			beep();
X			continue;
X		}
X					/* an <ESC> anywhere in the string */
X		if (ans == ESC)
X			return(NULL);
X					/* erase the default answer */
X		if (!done_it) {
X			waddstr(win, "         ");
X			wmove(win, 2, 13);
X			wrefresh(win);
X			done_it++;
X		}
X
X		buf[count] = ans;
X		waddch(win, (chtype) ans);
X		wrefresh(win);
X		count++;
X	}
X	buf[count] = '\0';
X	return(buf);
X}
SHAR_EOF
if test 3958 -ne "`wc -c < 'd_print.c'`"
then
	echo shar: "error transmitting 'd_print.c'" '(should have been 3958 characters)'
fi
fi
echo shar: "extracting 'd_prompt.c'" '(6130 characters)'
if test -f 'd_prompt.c'
then
	echo shar: "will not over-write existing file 'd_prompt.c'"
else
sed 's/^X//' << \SHAR_EOF > 'd_prompt.c'
X/*
X * Prompt for directory entry changes.  Copies the original values in
X * case you change your mind half way thru.  A non-zero return code means
X * the entry was changed.
X */
X
X#include <stdio.h>
X#include <curses.h>
X#include "config.h"
X#include "dial_dir.h"
X#include "misc.h"
X
Xint
Xprompt_lib(win, i)
XWINDOW *win;
Xint i;
X{
X	extern int xmc;
X	extern char *null_ptr;
X	int n, baud, dbits, sbits, spot;
X	static int valid_baud[6] = {300, 1200, 2400, 4800, 9600, 19200};
X	static char *valid_parity[3] = {"Even", "Odd", "None"};
X	char *ans, *get_str(), c, temp, name[40], number[40], script[40];
X	char parity, duplex, *str_rep(), *strcpy(), buf[40];
X	void free_ptr();
X					/* make copies */
X	strcpy(name, dir->name[i]);
X	strcpy(number, dir->number[i]);
X	baud = dir->baud[i];
X	parity = dir->parity[i];
X	dbits = dir->dbits[i];
X	sbits = dir->sbits[i];
X	duplex = dir->duplex[i];
X	strcpy(script, dir->script[i]);
X					/* display original values */
X	werase(win);
X	mvwprintw(win, 2, 5, "%-20.20s %18.18s  %5d-%c-%d-%d  %c  %-14.14s\n",
X	 dir->name[i], dir->number[i], dir->baud[i], dir->parity[i],
X	 dir->dbits[i], dir->sbits[i], dir->duplex[i], dir->script[i]);
X	box(win, VERT, HORZ);
X
X					/* prompt for name */
X	mvwaddstr(win, 4, 4, "Name: ");
X	wrefresh(win);
X
X	if ((ans = get_str(win, 20, "", ";\n")) == NULL)
X		return(0);
X	if (*ans != '\0') {
X		strcpy(name, ans);
X		mvwaddstr(win, 2, 5, "                    ");
X		wrefresh(win);
X		mvwattrstr(win, 2, 5, A_BOLD, name);
X	}
X					/* prompt for number */
X	clear_line(win, 4, 4, TRUE);
X	waddstr(win, "Number: ");
X	wrefresh(win);
X
X	if ((ans = get_str(win, 18, "", ";\n")) == NULL)
X		return(0);
X	if (*ans != '\0') {
X		strcpy(number, ans);
X		mvwaddstr(win, 2, 26, "                  ");
X		wrefresh(win);
X		/*
X		 * Should be right justified, but we don't wanna have
X		 * the attribute turned on for blanks.
X		 */
X		spot = 26 + 18 - strlen(number);
X		mvwattrstr(win, 2, spot, A_BOLD, number);
X	}
X					/* template for next few */
X	clear_line(win, 4, 4, TRUE);
X	mvwaddstr(win, 4, 31, "(Any key to change, <CR> to accept)");
X
X	/*
X	 * These next few prompts display a series of choices and allow
X	 * the user to hit <CR> to accept the currently showing value
X	 * or any other key to see the next choice.  The first value
X	 * displayed is always the current value.
X	 */
X					/* choose from baud menu */
X	for (n=0; n<6; n++) {
X		if (valid_baud[n] == baud)
X			break;
X	}
X	mvwprintw(win, 4, 4, "Baud: %-5d", valid_baud[n]);
X	wmove(win, 4, 10);
X	wrefresh(win);
X
X	while ((c = wgetch(win)) != '\r') {
X		if (c == ESC)
X			return(0);
X		n = (n == 5) ? 0 : n+1;
X		mvwprintw(win, 4, 4, "Baud: %-5d", valid_baud[n]);
X		wmove(win, 4, 10);
X		wrefresh(win);
X	}
X	if (baud != valid_baud[n]) {
X		baud = valid_baud[n];
X		sprintf(buf, "%5d", baud);
X		if (xmc > 0) {
X			sprintf(buf, "%5d-%c-%d-%d", baud, parity, dbits, sbits);
X			mvwaddstr(win, 2, 46, "           ");
X			wrefresh(win);
X		}
X		mvwattrstr(win, 2, 46, A_BOLD, buf);
X	}
X					/* choose from parity menu */
X	for (n=0; n<3; n++) {
X		if (*valid_parity[n] == parity)
X			break;
X	}
X	mvwprintw(win, 4, 4, "Parity: %-5.5s", valid_parity[n]);
X	wmove(win, 4, 12);
X	wrefresh(win);
X
X	while ((c = wgetch(win)) != '\r') {
X		if (c == ESC)
X			return(0);
X		n = (n == 2) ? 0 : n+1;
X		mvwprintw(win, 4, 4, "Parity: %-5.5s", valid_parity[n]);
X		wmove(win, 4, 12);
X		wrefresh(win);
X	}
X	if (parity != *valid_parity[n]) {
X		parity = *valid_parity[n];
X		if (xmc > 0) {
X			sprintf(buf, "%5d-%c-%d-%d", baud, parity, dbits, sbits);
X			mvwaddstr(win, 2, 46, "           ");
X			wrefresh(win);
X			mvwattrstr(win, 2, 46, A_BOLD, buf);
X		}
X		else
X			mvwattrch(win, 2, 52, A_BOLD, parity);
X	}
X					/* choose from data bits menu */
X	n = dbits;
X	mvwprintw(win, 4, 4, "Data Bits: %d    ", n);
X	wmove(win, 4, 15);
X	wrefresh(win);
X
X	while ((c = wgetch(win)) != '\r') {
X		if (c == ESC)
X			return(0);
X		n = (n == 8) ? 7 : 8;
X		mvwprintw(win, 4, 4, "Data Bits: %d    ", n);
X		wmove(win, 4, 15);
X		wrefresh(win);
X	}
X	if (dbits != n) {
X		dbits = n;
X		if (xmc > 0) {
X			sprintf(buf, "%5d-%c-%d-%d", baud, parity, dbits, sbits);
X			mvwaddstr(win, 2, 46, "           ");
X			wrefresh(win);
X			mvwattrstr(win, 2, 46, A_BOLD, buf);
X		}
X		else
X			mvwattrnum(win, 2, 54, A_BOLD, dbits);
X	}
X					/* choose from stop bits menu */
X	n = sbits;
X	mvwprintw(win, 4, 4, "Stop Bits: %d    ", n);
X	wmove(win, 4, 15);
X	wrefresh(win);
X
X	while ((c = wgetch(win)) != '\r') {
X		if (c == ESC)
X			return(0);
X		n = (n == 2) ? 1 : 2;
X		mvwprintw(win, 4, 4, "Stop Bits: %d    ", n);
X		wmove(win, 4, 15);
X		wrefresh(win);
X	}
X	if (sbits != n) {
X		sbits = n;
X		if (xmc > 0) {
X			sprintf(buf, "%5d-%c-%d-%d", baud, parity, dbits, sbits);
X			mvwaddstr(win, 2, 46, "           ");
X			wrefresh(win);
X			mvwattrstr(win, 2, 46, A_BOLD, buf);
X		}
X		else
X			mvwattrnum(win, 2, 56, A_BOLD, sbits);
X	}
X					/* choose from duplex menu */
X	temp = duplex;
X	mvwprintw(win, 4, 4, "Duplex: %c    ", temp);
X	wmove(win, 4, 12);
X	wrefresh(win);
X
X	while ((c = wgetch(win)) != '\r') {
X		if (c == ESC)
X			return(0);
X		temp = (temp == 'F') ? 'H' : 'F';
X		mvwprintw(win, 4, 4, "Duplex: %c    ", temp);
X		wmove(win, 4, 12);
X		wrefresh(win);
X	}
X	if (duplex != temp) {
X		duplex = temp;
X		mvwattrch(win, 2, 59, A_BOLD, duplex);
X	}
X					/* prompt for script or TTY */
X	clear_line(win, 4, 4, TRUE);
X	waddstr(win, "Script name (or TTY): ");
X	wrefresh(win);
X
X	if ((ans = get_str(win, 14, "", ";\n")) == NULL)
X		return(0);
X
X	if (*ans != '\0') {
X		strcpy(script, ans);
X		mvwaddstr(win, 2, 62, "              ");
X		wrefresh(win);
X		mvwattrstr(win, 2, 62, A_BOLD, script);
X	}
X					/* store 'em for real */
X
X	if (!strcmp(name, " ")) {
X		free_ptr(dir->name[i]);
X		dir->name[i] = null_ptr;
X	}
X	else
X		dir->name[i] = str_rep(dir->name[i], name);
X
X	if (!strcmp(number, " ")) {
X		free_ptr(dir->number[i]);
X		dir->number[i] = null_ptr;
X	}
X	else
X		dir->number[i] = str_rep(dir->number[i], number);
X
X	dir->baud[i] = baud;
X	dir->parity[i] = parity;
X	dir->dbits[i] = dbits;
X	dir->sbits[i] = sbits;
X	dir->duplex[i] = duplex;
X
X	if (!strcmp(script, " ")) {
X		free_ptr(dir->script[i]);
X		dir->script[i] = null_ptr;
X	}
X	else
X		dir->script[i] = str_rep(dir->script[i], script);
X
X	return(1);
X}
SHAR_EOF
if test 6130 -ne "`wc -c < 'd_prompt.c'`"
then
	echo shar: "error transmitting 'd_prompt.c'" '(should have been 6130 characters)'
fi
fi
echo shar: "extracting 'd_revise.c'" '(4009 characters)'
if test -f 'd_revise.c'
then
	echo shar: "will not over-write existing file 'd_revise.c'"
else
sed 's/^X//' << \SHAR_EOF > 'd_revise.c'
X/*
X * The revise option of the dialing directory.  A non-zero return code
X * means that something was updated.  Prompts for saving changes to disk.
X */
X
X#include <stdio.h>
X#include <curses.h>
X#include "config.h"
X#include "dial_dir.h"
X#include "misc.h"
X#include "param.h"
X
Xint
Xrevise()
X{
X	WINDOW *r_win, *newwin();
X	int count, dir_flag, param_flag, num, x, y, save;
X	char ans, buf[40], *ld, *ld_prompt(), *str_rep();
X
X	r_win = newwin(7, 77, 7, 2);
X
X	mvwaddstr(r_win, 3, 6, "Entry to revise?");
X	mvwaddstr(r_win, 3, 35, "(Entry Number, +, -, @, #)");
X	box(r_win, VERT, HORZ);
X	wmove(r_win, 3, 23);
X	wrefresh(r_win);
X
X	dir_flag = 0;
X	param_flag = 0;
X	count = 0;
X
X	/*
X	 * Can't use my home-grown get_str() and get_num() functions
X	 * here, because we are prompting for an entry number or a
X	 * long distance code.  This routine echoes numbers only.
X	 */
X	while ((ans = wgetch(r_win)) != ESC) {
X		if (ans >= '0' && ans <= '9') {
X			if (count == 3) {
X				beep();
X				continue;
X			}
X			buf[count] = ans;
X			waddch(r_win, (chtype) ans);
X			wrefresh(r_win);
X			count++;
X			continue;
X		}
X					/* terminating CR */
X		if (ans == '\r') {
X			if (!count) {
X				beep();
X				continue;
X			}
X			buf[count] = '\0';
X			num = atoi(buf);
X					/* valid range of numbers? */
X			if (num == 0 || num > NUM_DIR) {
X				beep();
X				mvwaddstr(r_win, 3, 23, "   ");
X				wmove(r_win, 3, 23);
X				wrefresh(r_win);
X				count = 0;
X				continue;
X			}
X					/* prompt for that entry */
X			if (prompt_lib(r_win, num)) {
X				dir_flag++;
X				break;
X			}
X			delwin(r_win);
X			return(0);
X		}
X					/* do our own backspace */
X		if (ans == BS || ans == DEL) {
X			if (!count) {
X				beep();
X				continue;
X			}
X			count--;
X			buf[count] = '\0';
X			getyx(r_win, y, x);
X			x--;
X			wmove(r_win, y, x);
X			waddch(r_win, (chtype) ' ');
X			wmove(r_win, y, x);
X			wrefresh(r_win);
X			continue;
X		}
X					/* non-number after number is error */
X		if (count) {
X			beep();
X			continue;
X		}
X					/* prompt for LD codes */
X		switch (ans) {
X			case '+':
X				if ((ld = ld_prompt(r_win, param->ld_plus, ans)) != NULL) {
X					param->ld_plus = str_rep(param->ld_plus, ld);
X					param_flag++;
X				}
X				break;
X			case '-':
X				if ((ld = ld_prompt(r_win, param->ld_minus, ans)) != NULL) {
X					param->ld_minus = str_rep(param->ld_minus, ld);
X					param_flag++;
X				}
X				break;
X			case '@':
X				if ((ld = ld_prompt(r_win, param->ld_at, ans)) != NULL) {
X					param->ld_at = str_rep(param->ld_at, ld);
X					param_flag++;
X				}
X				break;
X			case '#':
X				if ((ld = ld_prompt(r_win, param->ld_pound, ans)) != NULL) {
X					param->ld_pound = str_rep(param->ld_pound, ld);
X					param_flag++;
X				}
X				break;
X			default:
X				beep();
X				continue;
X		}
X		break;
X	}
X					/* if nothing changed */
X	if (!param_flag && !dir_flag) {
X		delwin(r_win);
X		return(0);
X	}
X					/* save to disk? */
X	clear_line(r_win, 4, 4, TRUE);
X	if (dir_flag) {
X		sprintf(buf, "Save entry %d to disk", num);
X		save = yes_prompt(r_win, 4, 4, A_BOLD, buf);
X	}
X	else
X		save = yes_prompt(r_win, 4, 4, A_BOLD, "Save to disk");
X
X					/* update the files */
X	if (save && dir_flag) {
X		if (up_dir(num)) {
X			touchwin(r_win);
X			wrefresh(r_win);
X		}
X	}
X	if (save && param_flag) {
X		if (up_param()) {
X			touchwin(r_win);
X			wrefresh(r_win);
X		}
X	}
X	delwin(r_win);
X	return(1);
X}
X
X/*
X * Prompt for long distance code changes.  If new string is a space,
X * change it to null_ptr.  Returns NULL on escape.  Since it uses
X * get_str(), the return value is a pointer to a static area.
X */
X
Xstatic char *
Xld_prompt(win, current_ld, name)
XWINDOW *win;
Xchar *current_ld, name;
X{
X	extern char *null_ptr;
X	char *ans, *get_str();
X
X	werase(win);
X	mvwprintw(win, 2, 4, "%-20.20s", current_ld);
X	mvwprintw(win, 4, 4, "New LD code for %c: ", name);
X	box(win, VERT, HORZ);
X	wrefresh(win);
X
X	if ((ans = get_str(win, 20, "", "\n")) == NULL)
X		return(NULL);
X					/* if space, change to null_ptr */
X	if (!strcmp(ans, " "))
X		ans = null_ptr;
X					/* display new value */
X	clear_line(win, 2, 4, TRUE);
X	wattrstr(win, A_BOLD, ans);
X
X	return(ans);
X}
SHAR_EOF
if test 4009 -ne "`wc -c < 'd_revise.c'`"
then
	echo shar: "error transmitting 'd_revise.c'" '(should have been 4009 characters)'
fi
fi
echo shar: "extracting 'data_log.c'" '(1726 characters)'
if test -f 'data_log.c'
then
	echo shar: "will not over-write existing file 'data_log.c'"
else
sed 's/^X//' << \SHAR_EOF > 'data_log.c'
X/*
X * Open a window to prompt for a path name to be used for the data logging
X * feature.  Also turns on the data logging.  A non-zero return code means
X * we need to restart the input routine.
X */
X
X#include <stdio.h>
X#include <curses.h>
X#include "config.h"
X#include "misc.h"
X#include "param.h"
X#include "status.h"
X
Xint
Xdata_logging()
X{
X	extern int fd;
X	int ret_code;
X	WINDOW *dl_win, *newwin();
X	char *ans, *path, *expand(), *get_str(), *strcpy();
X	void input_off();
X
X	dl_win = newwin(6, 70, 5, 5);
X
X	mvwprintw(dl_win, 2, 4, "Default log file: %s", param->logfile);
X	mvwaddstr(dl_win, 3, 4, "New log file: ");
X	box(dl_win, VERT, HORZ);
X
X	mvwattrstr(dl_win, 0, 3, A_BOLD, " Start Data Logging ");
X	wmove(dl_win, 3, 18);
X	wrefresh(dl_win);
X					/* get the path */
X	ret_code = 0;
X	while ((ans = get_str(dl_win, PATH, "", " \t\n")) != NULL) {
X					/* give 'em the default */
X		if (*ans == '\0')
X			path = param->logfile;
X		else
X			path = expand(ans);
X
X					/* test write permission */
X		if (can_write(path)) {
X			ret_code++;
X			break;
X		}
X
X		beep();
X		mvwattrstr(dl_win, 4, 24, A_BOLD, "No write permission");
X		wrefresh(dl_win);
X		wait_key(dl_win, 3);
X					/* clean up the mess */
X		clear_line(dl_win, 3, 18, TRUE);
X		clear_line(dl_win, 4, 24, TRUE);
X		wmove(dl_win, 3, 18);
X		wrefresh(dl_win);
X	}
X	if (ret_code) {
X		strcpy(status->log_path, path);
X		status->log = 1;
X		/*
X		 * Without shared memory, killing and restarting the input
X		 * routine is the only way to change the name of the file
X		 * that the input routines uses.
X		 */
X#ifdef SHAREDMEM
X		ret_code = 0;
X#else /* SHAREDMEM */
X		input_off();
X#endif /* SHAREDMEM */
X	}
X	if (fd == -1) {
X		werase(dl_win);
X		wrefresh(dl_win);
X	}
X	delwin(dl_win);
X
X	return(ret_code);
X}
SHAR_EOF
if test 1726 -ne "`wc -c < 'data_log.c'`"
then
	echo shar: "error transmitting 'data_log.c'" '(should have been 1726 characters)'
fi
fi
echo shar: "extracting 'di_delay.c'" '(1978 characters)'
if test -f 'di_delay.c'
then
	echo shar: "will not over-write existing file 'di_delay.c'"
else
sed 's/^X//' << \SHAR_EOF > 'di_delay.c'
X/*
X * Prompt for new delay times during a dialing session.  Also, prompts
X * if changes should be saved to disk.  Dialing is suspended during
X * this routine.
X */
X
X#include <stdio.h>
X#include <curses.h>
X#include "config.h"
X#include "misc.h"
X#include "param.h"
X
Xvoid
Xdelay_times()
X{
X	WINDOW *dt_win, *newwin();
X	int cdelay, rdelay;
X
X	dt_win = newwin(9, 45, 7, 15);
X
X	mvwprintw(dt_win, 2, 4, "Current connect delay time: %d", param->c_delay);
X	mvwprintw(dt_win, 3, 4, "Current redial delay time: %d", param->r_delay);
X	mvwaddstr(dt_win, 5, 4, "New connect delay: ");
X	mvwaddstr(dt_win, 6, 4, "New redial delay: ");
X	box(dt_win, VERT, HORZ);
X
X	mvwattrstr(dt_win, 0, 3, A_BOLD, " Change delay times ");
X	wmove(dt_win, 5, 23);
X	wrefresh(dt_win);
X					/* get the cdelay number */
X	if ((cdelay = get_num(dt_win, 3)) == -1) {
X		delwin(dt_win);
X		return;
X	}
X					/* give 'em the current settings */
X	if (!cdelay) {
X		cdelay = param->c_delay;
X		wprintw(dt_win, "%-3d", cdelay);
X	}
X	else {
X					/* some reasonable limit */
X		if (cdelay > MAX_CDELAY || cdelay < MIN_CDELAY) {
X			beep();
X			if (cdelay > MAX_CDELAY)
X				cdelay = MAX_CDELAY;
X			else
X				cdelay = MIN_CDELAY;
X			mvwprintw(dt_win, 5, 23, "%-3d", cdelay);
X		}
X	}
X					/* get the rdelay number */
X	wmove(dt_win, 6, 20);
X	wrefresh(dt_win);
X	if ((rdelay = get_num(dt_win, 3)) == -1) {
X		delwin(dt_win);
X		return;
X	}
X					/* give 'em the current settings */
X	if (!rdelay) {
X		rdelay = param->r_delay;
X		wprintw(dt_win, "%-3d", rdelay);
X	}
X	else {
X					/* some reasonable limit */
X		if (rdelay > MAX_PAUSE || rdelay < MIN_PAUSE) {
X			beep();
X			if (rdelay > MAX_PAUSE)
X				rdelay = MAX_PAUSE;
X			else
X				rdelay = MIN_PAUSE;
X			mvwprintw(dt_win, 6, 22, "%-3d", rdelay);
X		}
X	}
X					/* set 'em */
X	param->c_delay = cdelay;
X	param->r_delay = rdelay;
X					/* save 'em to disk? */
X	if (yes_prompt(dt_win, 7, 12, A_BOLD, "Save to disk")) {
X		if (up_param()) {
X			touchwin(dt_win);
X			wrefresh(dt_win);
X		}
X	}
X
X	delwin(dt_win);
X	return;
X}
SHAR_EOF
if test 1978 -ne "`wc -c < 'di_delay.c'`"
then
	echo shar: "error transmitting 'di_delay.c'" '(should have been 1978 characters)'
fi
fi
exit 0
#	End of shell archive


From uiucuxc!fthood!egray@uunet.UU.NET Fri May 12 01:10:20 1989
Received: from uunet.UU.NET by pineapple.bbn.com
	id <AA10345@pineapple.bbn.com>; Fri, 12 May 89 01:10:06 -0400
Received: from uiucuxc.UUCP by uunet.UU.NET (5.61/1.14) with UUCP 
	id AA04432; Fri, 12 May 89 01:10:41 -0400
From: uiucuxc!fthood!egray@uunet.UU.NET
Received: from fthood.UUCP by uxc.cso.uiuc.edu with UUCP
	(5.61+/IDA-1.2.8) id AA00426; Thu, 11 May 89 23:40:56 -0500
Date: Thu, 11 May 89 23:40:56 -0500
Message-Id: <8905120440.AA00426@uxc.cso.uiuc.edu>
To: uiucuxc!pineapple.bbn.com!rsalz@uunet.UU.NET
Subject: Patch #3 to Pcomm v1.2
Status: R

Hello again...

Some background...  I sent you the source to Pcomm v1.2 back in Feb.
I've also sent you patch #1 and then patch #2.   This is patch #3...

I figure I'll keep sending you the patches up to the point when Pcomm
v1.2 appears in comp.sources.unix, then I'll start sending them to
comp.sources.bugs.

Emmet P. Gray				US Army, HQ III Corps & Fort Hood
...!uunet!uiucuxc!fthood!egray		Attn: AFZF-DE-ENV
fthood!egray@uxc.cso.uiuc.edu		Directorate of Engineering & Housing
					Environmental Management Office
					Fort Hood, TX 76544-5057

----------- cut here ------------ cut here ----------- cut here ----------
Subject: Patch #3 to Pcomm v1.2

This is patch #3 to the Pcomm v1.2 distribution package.  This patch
will fix few problems with Pcomm on Microsoft XENIX 3.0/3.5 and changes
the method of getting rid of zombie processes.

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
------------------------------------------------------------------------------
Prereq: "1.2.2"
*** old/info.c	Tue Mar  7 11:18:10 1989
--- info.c	Thu May 11 11:54:25 1989
***************
*** 4,9
   */
  
! #define VERSION	"1.2.2"
! #define DATE	"11 Mar 89"
  
  #include <stdio.h>

--- 4,9 -----
   */
  
! #define VERSION	"1.2.3"
! #define DATE	"11 May 89"
  
  #include <stdio.h>
*** old/Makefile	Fri Feb  3 07:39:32 1989
--- Makefile	Thu May 11 11:53:47 1989
***************
*** 8,11
  #TERMLIB = -ltinfo -lx
  
  CFLAGS = -O
  LDFLAGS = -s

--- 8,15 -----
  #TERMLIB = -ltinfo -lx
  
+ #for 80286 versions of Microsoft Xenix 3.0/3.5
+ #CFLAGS = -O -Mme2 -Dresetterm=xresetterm -DXENIX_3
+ #LDFLAGS = -s -Mm -F 5120
+ 
  CFLAGS = -O
  LDFLAGS = -s
***************
*** 63,71
  	cp matches $(BIN)
  	cp modem_break $(BIN)
! #	rm pcomm
! #	rm pcomm_input
! #	rm waitfor
! #	rm matches
! #	rm modem_break
  
  lint:

--- 67,77 -----
  	cp matches $(BIN)
  	cp modem_break $(BIN)
! 
! clean:
! 	rm pcomm
! 	rm pcomm_input
! 	rm waitfor
! 	rm matches
! 	rm modem_break
  
  lint:
*** old/d_menu.c	Fri Jan 27 09:38:36 1989
--- d_menu.c	Thu May 11 10:35:34 1989
***************
*** 50,53
  	waddstr(dm_win, " Scroll Down");
  
  	mvwattrstr(dm_win, 17, 14, A_BOLD, "<up>/<down>");
  	waddstr(dm_win, " Page");

--- 50,56 -----
  	waddstr(dm_win, " Scroll Down");
  
+ #ifdef OLDCURSES
+ 	mvwattrstr(dm_win, 17, 14, A_BOLD, "U/N");
+ #else /* OLDCURSES */
  	mvwattrstr(dm_win, 17, 14, A_BOLD, "<up>/<down>");
  #endif /* OLDCURSES */
***************
*** 51,54
  
  	mvwattrstr(dm_win, 17, 14, A_BOLD, "<up>/<down>");
  	waddstr(dm_win, " Page");
  	mvwattrch(dm_win, 17, 34, A_BOLD, 'L');

--- 54,58 -----
  #else /* OLDCURSES */
  	mvwattrstr(dm_win, 17, 14, A_BOLD, "<up>/<down>");
+ #endif /* OLDCURSES */
  	waddstr(dm_win, " Page");
  	mvwattrch(dm_win, 17, 34, A_BOLD, 'L');
*** old/di_delay.c	Fri Jan 13 07:47:22 1989
--- di_delay.c	Wed Apr 26 08:35:19 1989
***************
*** 50,54
  	}
  					/* get the rdelay number */
! 	wmove(dt_win, 6, 20);
  	wrefresh(dt_win);
  	if ((rdelay = get_num(dt_win, 3)) == -1) {

--- 50,54 -----
  	}
  					/* get the rdelay number */
! 	wmove(dt_win, 6, 22);
  	wrefresh(dt_win);
  	if ((rdelay = get_num(dt_win, 3)) == -1) {
*** old/di_win.c	Mon Jan 16 17:17:30 1989
--- di_win.c	Sat Apr 22 22:43:28 1989
***************
*** 198,202
  			else
  				write(fd, &cr, 1);
! 			sleep(1);
  		}
  					/* if we get here, no key was pressed */

--- 198,202 -----
  			else
  				write(fd, &cr, 1);
! 			sleep(2);
  		}
  					/* if we get here, no key was pressed */
***************
*** 257,260
  					dir->q_num[j] = dir->q_num[j+1];
  				dir->q_num[NUM_QUEUE-1] = -1;
  				break;
  			case 'e':

--- 257,263 -----
  					dir->q_num[j] = dir->q_num[j+1];
  				dir->q_num[NUM_QUEUE-1] = -1;
+ 
+ 				if (dir->q_num[i] == -1)
+ 					i = 0;
  				break;
  			case 'e':
*** old/getopt.c	Tue Oct 18 11:47:04 1988
--- getopt.c	Wed Apr 26 08:26:40 1989
***************
*** 4,7
  
  #include <stdio.h>
  
  int optind = 1;

--- 4,8 -----
  
  #include <stdio.h>
+ #include "config.h"
  
  int optind = 1;
*** old/help.c	Mon Jan 16 17:18:02 1989
--- help.c	Thu May 11 10:36:59 1989
***************
*** 23,26
  	horizontal(h_win, 2, 0, 80);
  	mvwattrstr(h_win, 4, 0, A_BOLD, "       Major Functions          Utility Functions         File Functions\n\n");
  	mvwprintw(h_win,  6,  2, "Dialing Directory.%4.4s-D  Program Info ....%4.4s-I  Send Files ....%4.4s-<up>", hot, hot, hot);
  	mvwprintw(h_win,  7,  2, "Auto Redial ......%4.4s-R  Setup Screen ....%4.4s-S  Receive Files .%4.4s-<down>", hot, hot, hot);

--- 23,30 -----
  	horizontal(h_win, 2, 0, 80);
  	mvwattrstr(h_win, 4, 0, A_BOLD, "       Major Functions          Utility Functions         File Functions\n\n");
+ #ifdef OLDCURSES
+ 	mvwprintw(h_win,  6,  2, "Dialing Directory.%4.4s-D  Program Info ....%4.4s-I  Send Files ....%4.4s-U", hot, hot, hot);
+ 	mvwprintw(h_win,  7,  2, "Auto Redial ......%4.4s-R  Setup Screen ....%4.4s-S  Receive Files .%4.4s-N", hot, hot, hot);
+ #else /* OLDCURSES */
  	mvwprintw(h_win,  6,  2, "Dialing Directory.%4.4s-D  Program Info ....%4.4s-I  Send Files ....%4.4s-<up>", hot, hot, hot);
  	mvwprintw(h_win,  7,  2, "Auto Redial ......%4.4s-R  Setup Screen ....%4.4s-S  Receive Files .%4.4s-<down>", hot, hot, hot);
***************
*** 25,28
  	mvwprintw(h_win,  6,  2, "Dialing Directory.%4.4s-D  Program Info ....%4.4s-I  Send Files ....%4.4s-<up>", hot, hot, hot);
  	mvwprintw(h_win,  7,  2, "Auto Redial ......%4.4s-R  Setup Screen ....%4.4s-S  Receive Files .%4.4s-<down>", hot, hot, hot);
  	mvwprintw(h_win,  8,  2, "Keyboard Macros ..%4.4s-M  Change Directory.%4.4s-B  Pass Thru Mode.%4.4s-T", hot, hot, hot);
  	mvwprintw(h_win,  9,  2, "Line Settings ....%4.4s-P  Clear Screen ....%4.4s-C  Directory .....%4.4s-F", hot, hot, hot);

--- 29,33 -----
  	mvwprintw(h_win,  6,  2, "Dialing Directory.%4.4s-D  Program Info ....%4.4s-I  Send Files ....%4.4s-<up>", hot, hot, hot);
  	mvwprintw(h_win,  7,  2, "Auto Redial ......%4.4s-R  Setup Screen ....%4.4s-S  Receive Files .%4.4s-<down>", hot, hot, hot);
+ #endif /* OLDCURSES */
  	mvwprintw(h_win,  8,  2, "Keyboard Macros ..%4.4s-M  Change Directory.%4.4s-B  Pass Thru Mode.%4.4s-T", hot, hot, hot);
  	mvwprintw(h_win,  9,  2, "Line Settings ....%4.4s-P  Clear Screen ....%4.4s-C  Directory .....%4.4s-F", hot, hot, hot);
*** old/main.c	Tue Mar  7 11:18:10 1989
--- main.c	Thu May 11 11:54:47 1989
***************
*** 15,18
   *	Patch #1	18 Feb 89
   *	Patch #2	11 Mar 89
   */
  

--- 15,19 -----
   *	Patch #1	18 Feb 89
   *	Patch #2	11 Mar 89
+  *	Patch #3	11 May 89
   */
  
***************
*** 150,153
  	cbreak();
  	noecho();
  
  #ifdef OLDCURSES

--- 151,157 -----
  	cbreak();
  	noecho();
+ #ifdef XENIX_3
+ 	raw();
+ #endif /* XENIX_3 */
  
  #ifdef OLDCURSES
*** old/modem_break.c	Thu Jan 12 14:32:16 1989
--- modem_break.c	Wed May 10 12:18:47 1989
***************
*** 5,8
  
  #include <stdio.h>
  #ifdef BSD
  #include <sgtty.h>

--- 5,12 -----
  
  #include <stdio.h>
+ #ifdef XENIX_3
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+ #endif /* XENIX_3 */
  #ifdef BSD
  #include <sgtty.h>
*** old/script.c	Mon Feb 20 15:32:06 1989
--- script.c	Sun Apr  2 12:21:17 1989
***************
*** 138,143
  			break;
  	}
- 					/* wait for the zombie process */
- 	wait(&sig_status);
  
  	signal(SIGINT, istat);

--- 138,141 -----
  			break;
  	}
  
  	signal(SIGINT, istat);
*** old/terminal.c	Mon Feb 20 15:32:08 1989
--- terminal.c	Tue May  2 09:29:35 1989
***************
*** 394,397
  input_off()
  {
  	if (pid != -1) {
  		kill(pid, SIGTERM);

--- 394,399 -----
  input_off()
  {
+ 	SIG_TYPE (*cstat)();
+ 
  	if (pid != -1) {
  		/*
***************
*** 395,398
  {
  	if (pid != -1) {
  		kill(pid, SIGTERM);
  		pid = -1;

--- 397,404 -----
  
  	if (pid != -1) {
+ 		/*
+ 		 * This serves to periodically clean up the process table
+ 		 */
+ 		cstat = signal(SIGCLD, SIG_IGN);
  		kill(pid, SIGTERM);
  		pid = -1;
***************
*** 397,400
  		kill(pid, SIGTERM);
  		pid = -1;
  	}
  	return;

--- 403,407 -----
  		kill(pid, SIGTERM);
  		pid = -1;
+ 		signal(SIGCLD, cstat);
  	}
  	return;
*** old/tty_att.c	Thu Dec 29 13:24:52 1988
--- tty_att.c	Wed May 10 12:18:47 1989
***************
*** 4,7
  
  #include <stdio.h>
  #include <termio.h>
  #include <fcntl.h>

--- 4,11 -----
  
  #include <stdio.h>
+ #ifdef XENIX_3
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+ #endif /* XENIX_3 */
  #include <termio.h>
  #include <fcntl.h>
*** old/vcs.c	Fri Jan 27 10:06:04 1989
--- vcs.c	Wed May 10 12:18:48 1989
***************
*** 10,13
  #include <curses.h>
  #include <term.h>
  #endif /* OLDCURSES */
  

--- 10,15 -----
  #include <curses.h>
  #include <term.h>
+ #else /* OLDCURSES */
+ char tcbuf[1024];
  #endif /* OLDCURSES */
  
***************
*** 188,192
  
  #ifdef OLDCURSES
! 	char tcbuf[1024], tb[1024], *t, *cursor_home, *clr_eol, *clr_eos;
  	char *clear_screen, *cursor_up, *cursor_down, *cursor_right;
  	char *cursor_left, *cursor_address, *getenv(), *tgetstr(), *tgoto();

--- 190,194 -----
  
  #ifdef OLDCURSES
! 	char tb[1024], *t, *cursor_home, *clr_eol, *clr_eos;
  	char *clear_screen, *cursor_up, *cursor_down, *cursor_right;
  	char *cursor_left, *cursor_address, *getenv(), *tgetstr(), *tgoto();
*** old/x_extrnl.c	Fri Feb  3 10:08:06 1989
--- x_extrnl.c	Sun Apr  2 12:21:19 1989
***************
*** 118,123
  			break;
  	}
- 					/* wait for the zombie process */
- 	wait(&sig_status);
  
  	signal(SIGINT, istat);

--- 118,121 -----
  			break;
  	}
  
  	signal(SIGINT, istat);


-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.