v16i008: Modem communications package, Part03/08

Rich Salz rsalz at uunet.uu.net
Wed Sep 14 02:41:45 AEST 1988


Submitted-by: Emmet P Gray <fthood!egray>
Posting-number: Volume 16, Issue 8
Archive-name: pcomm2/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
#	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'" '(2880 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] = NULL;
X	date[16] = NULL;
X
X	if (!(fp = fopen(LOGFILE, "a+"))) {
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 || !*grpbuf->gr_mem)
X		return(0);
X					/* are you in the group? */
X	name = getlogin();
X	for (; *grpbuf->gr_mem!=NULL; 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 == NULL) {
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[40], *strcpy(), *strcat();
X	static char ans[40];
X
X	temp[0] = NULL;
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] = NULL;
X
X	return(ans);
X}
X#endif /* LOG_CALLS || LIMIT_LD */
SHAR_EOF
if test 2880 -ne "`wc -c < 'admin.c'`"
then
	echo shar: "error transmitting 'admin.c'" '(should have been 2880 characters)'
fi
fi
echo shar: "extracting 'chg_dir.c'" '(1305 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	void free_ptr();
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, 60, "", " 	")) != NULL) {
X					/* a CR means no change */
X		if (*ans == NULL)
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				free_ptr(dir);
X				break;
X			}
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, 1);
X		clear_line(ch_win, 4, 14, 1);
X		wmove(ch_win, 3, 19);
X		wrefresh(ch_win);
X		free_ptr(dir);
X	}
X	if (fd == -1) {
X		werase(ch_win);
X		wrefresh(ch_win);
X	}
X	delwin(ch_win);
X	return;
X}
SHAR_EOF
if test 1305 -ne "`wc -c < 'chg_dir.c'`"
then
	echo shar: "error transmitting 'chg_dir.c'" '(should have been 1305 characters)'
fi
fi
echo shar: "extracting 'curses.c'" '(8404 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#include <stdio.h>
X#include <curses.h>
X#include <signal.h>
X#include "config.h"
X#ifdef OLDCURSES
X#include <fcntl.h>
X#else /* OLDCURSES */
X#include <term.h>
X#endif /* OLDCURSES */
X#include "misc.h"
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)
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[80];
X
X	count = 0;
X	while ((ans = wgetch(win)) != '\r') {
X					/* do our own backspace */
X		if (ans == BS) {
X			if (!count) {
X				beep();
X				continue;
X			}
X			count--;
X			buf[count] = NULL;
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 != NULL && strchr(disallow, ans)) {
X			beep();
X			continue;
X		}
X		if (*allow != NULL && !strchr(allow, ans)) {
X			beep();
X			continue;
X		}
X					/* exceeded the max? */
X		if (count == num) {
X			beep();
X			continue;
X		}
X
X		buf[count] = ans;
X		waddch(win, (chtype) ans);
X		wrefresh(win);
X		count++;
X	}
X	buf[count] = NULL;
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[80];
X
X	count = 0;
X	while ((ans = wgetch(win)) != '\r') {
X					/* do our own backspace */
X		if (ans == BS) {
X			if (!count) {
X				beep();
X				continue;
X			}
X			count--;
X			buf[count] = NULL;
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) {
X			beep();
X			continue;
X		}
X
X		buf[count] = ans;
X		waddch(win, (chtype) ans);
X		wrefresh(win);
X		count++;
X	}
X	buf[count] = NULL;
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 == NULL)
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#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 == NULL)
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#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[20];
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#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 save, ret_code;
X	char new_str[80], *strcpy(), *strcat();
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		save = wgetch(win);
X		switch (save) {
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
Xint
Xwait_key(win, sec)
XWINDOW *win;
Xunsigned int sec;
X{
X	int key, wk_force();
X	unsigned int alarm();
X#ifdef WGETCH_BROKE
X	char c;
X#endif /* WGETCH_BROKE */
X
X	signal(SIGALRM, wk_force);
X	wk_flag = 0;
X
X	alarm(sec);
X#ifdef WGETCH_BROKE
X	read(0, &c, 1);
X	key = c;
X#else /* WGETCH_BROKE */
X	key = wgetch(win);
X#endif /* WGETCH_BROKE */
X	if (wk_flag)
X		return(-1);
X	alarm(0);
X	return(key);
X}
X/*ARGSUSED*/
Xstatic int
Xwk_force(dummy)
Xint dummy;
X{
X	wk_flag = 1;
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
Xint
Xnodelay(win, flag)
XWINDOW *win;
Xint flag;
X{
X	if (flag)
X		fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | O_NDELAY);
X	else
X		fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~O_NDELAY);
X	return(0);
X}
X
X/*
X * Take the terminal out of the "curses mode"
X */
X
Xint
Xresetterm()
X{
X	resetty();
X	return(0);
X}
X
X/*
X * Put the terminal back into the "curses mode"
X */
X
Xint
Xmyputchar(c)
Xchar c;
X{
X	return(putchar(c));
X}
Xint
Xfixterm()
X{
X	int myputchar();
X	extern char *TI, *VS;
X
X	tputs(TI, 1, myputchar);
X	tputs(VS, 1, myputchar);
X	nonl();
X	crmode();
X	noecho();
X	return(0);
X}
X#endif /* OLDCURSES */
SHAR_EOF
if test 8404 -ne "`wc -c < 'curses.c'`"
then
	echo shar: "error transmitting 'curses.c'" '(should have been 8404 characters)'
fi
fi
echo shar: "extracting 'd_delete.c'" '(2009 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 return code of 1 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->index[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->index[i] = null_ptr;
X		}
X		delwin(d_win);
X		return(1);
X	}
X	delwin(d_win);
X	return(0);
X}
SHAR_EOF
if test 2009 -ne "`wc -c < 'd_delete.c'`"
then
	echo shar: "error transmitting 'd_delete.c'" '(should have been 2009 characters)'
fi
fi
echo shar: "extracting 'd_lib.c'" '(6787 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, j, oops;
X	char *strdup(), buf[80], *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	i = 0;
X	oops = 0;
X	while (fgets(buf, 80, fp) != NULL) {
X		i++;
X		if (i > 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", i);
X			oops++;
X			break;
X		}
X		/*
X		 * Parse the rest of the line.  This is similar to using
X		 * the "real" strtok() function, but my version returns
X		 * a null pointer if the parameter is missing.  Note the
X		 * array of field separators.
X		 */
X		for (j=0; j<8; j++) {
X			if (!(str = str_tok((char *) NULL, sep[j]))) {
X				sprintf(message, "is missing a parameter at line %d", i);
X				oops++;
X				break;
X			}
X			switch (j) {
X				case 0:
X					d.name[i] = strdup(str);
X					break;
X				case 1:
X					d.number[i] = strdup(str);
X					break;
X				case 2:
X					d.baud[i] = atoi(str);
X					break;
X				case 3:
X					d.parity[i] = *str;
X					break;
X				case 4:
X					d.dbits[i] = atoi(str);
X					break;
X				case 5:
X					d.sbits[i] = atoi(str);
X					break;
X				case 6:
X					d.duplex[i] = *str;
X					break;
X				case 7:
X					d.index[i] = strdup(str);
X					break;
X			}
X		}
X		if (oops)
X			break;
X					/* sanity checking */
X		sprintf(token, "DIR_%d", i);
X		if (strcmp(temp_token, token)) {
X			sprintf(message, "is corrupted at line %d", i);
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 = i;
X					/* if empty database */
X	if (!i) {
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	i++;
X	for (; 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.index[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.index[0] = null_ptr;
X					/* create an empty queue */
X	for (i=0; i<NUM_QUEUE; i++) {
X		d.q_ld[i] = NULL;
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 return code of 1 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[80], *strdup();
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, 80, fp_in) != NULL)
X		temp[++i] = strdup(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->index[entry]);
X
X	if (entry <= dir->d_entries)
X		free_ptr(temp[entry]);
X	temp[entry] = strdup(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] = strdup(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 return code
X * of 1 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[80], *strdup();
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, 80, fp_in) != NULL)
X		temp[++i] = strdup(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		free_ptr(temp[i]);
X		temp[i] = strdup(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 6787 -ne "`wc -c < 'd_lib.c'`"
then
	echo shar: "error transmitting 'd_lib.c'" '(should have been 6787 characters)'
fi
fi
echo shar: "extracting 'd_manual.c'" '(1920 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 return code of
X * 1 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 "misc.h"
X#include "dial_dir.h"
X
Xint
Xmanual()
X{
X	extern int xmc;
X	extern char *null_ptr;
X	WINDOW *m_win, *newwin();
X	char *number, *strdup(), *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, "", "")) == 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 = NULL;
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	free_ptr(dir->name[0]);
X	free_ptr(dir->number[0]);
X	dir->name[0] = strdup(number);
X					/* if space, change to null */
X	if (!strcmp(number, " "))
X		dir->number[0] = null_ptr;
X	else
X		dir->number[0] = strdup(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 1920 -ne "`wc -c < 'd_manual.c'`"
then
	echo shar: "error transmitting 'd_manual.c'" '(should have been 1920 characters)'
fi
fi
echo shar: "extracting 'd_menu.c'" '(6921 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
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, current, 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  Index/TTY    ");
X					/* show the first 10 entries */
X	dir_scroll(dm_win, 1);
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#ifndef OLDCURSES
X	keypad(dm_win, TRUE);
X#endif /* OLDCURSES */
X					/* prompt for options */
X	current = 1;
X	count = 0;
X	ld_code = NULL;
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 BS:	/* do our own backspace */
X				if (!count) {
X					beep();
X					break;
X				}
X				count--;
X				if (!count)
X					ld_code = NULL;
X				buf[count] = NULL;
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] = NULL;
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, 0);
X			clear_line(dm_win, 3, 0, 0);
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  Index/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	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->index[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 pointer means not active */
X	if (*param->ld_plus != NULL)
X		waddstr(win, "+ ");
X	if (*param->ld_minus != NULL)
X		waddstr(win, "- ");
X	if (*param->ld_at != NULL)
X		waddstr(win, "@ ");
X	if (*param->ld_pound != NULL)
X		waddstr(win, "# ");
X	return;
X}
SHAR_EOF
if test 6921 -ne "`wc -c < 'd_menu.c'`"
then
	echo shar: "error transmitting 'd_menu.c'" '(should have been 6921 characters)'
fi
fi
echo shar: "extracting 'd_print.c'" '(3496 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#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();
X	WINDOW *p_win, *newwin();
X	char *file, *e_get_str(), buf[80];
X	int is_printer, i, can;
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 ((file = e_get_str(p_win, 40)) == NULL) {
X					/* erase because it overlaps dm_win */
X		werase(p_win);
X		wrefresh(p_win);
X		delwin(p_win);
X		return;
X	}
X	is_printer = 0;
X					/* the default (printer) */
X	if (*file == NULL) {
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 we
X		 * have write permission too).  Currently only allows
X		 * you to bail out or overwrite the file.
X		 */
X		if (!(can = can_write(file))) {
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		}
X		if (can == 2) {
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		}
X		fp = fopen(file, "w");
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->index[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[80];
X
X	done_it = 0;
X	count = 0;
X	while ((ans = wgetch(win)) != '\r') {
X					/* do our own backspace */
X		if (ans == BS) {
X			if (!count) {
X				beep();
X				continue;
X			}
X			count--;
X			buf[count] = NULL;
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) {
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] = NULL;
X	return(buf);
X}
SHAR_EOF
if test 3496 -ne "`wc -c < 'd_print.c'`"
then
	echo shar: "error transmitting 'd_print.c'" '(should have been 3496 characters)'
fi
fi
echo shar: "extracting 'd_prompt.c'" '(6003 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 return code of 1 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], index[40];
X	char parity, duplex, *strdup(), *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(index, dir->index[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->index[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, "", ";")) == NULL)
X		return(0);
X	if (*ans != NULL) {
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, 1);
X	waddstr(win, "Number: ");
X	wrefresh(win);
X
X	if ((ans = get_str(win, 18, "", ";")) == NULL)
X		return(0);
X	if (*ans != NULL) {
X		strcpy(number, ans);
X		mvwaddstr(win, 2, 26, "                  ");
X		wrefresh(win);
X		/*
X		 * Should be right justified, but we don't wanna to 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, 1);
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 a return to accept the currently showing
X	 * value.  The first value 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 command line index */
X	clear_line(win, 4, 4, 1);
X	waddstr(win, "Command line index (or TTY): ");
X	wrefresh(win);
X
X	if ((ans = get_str(win, 14, "", ";")) == NULL)
X		return(0);
X	if (*ans != NULL) {
X		strcpy(index, ans);
X		mvwaddstr(win, 2, 62, "              ");
X		wrefresh(win);
X		mvwattrstr(win, 2, 62, A_BOLD, index);
X	}
X					/* store 'em for real */
X	free_ptr(dir->name[i]);
X	free_ptr(dir->number[i]);
X	free_ptr(dir->index[i]);
X
X	if (!strcmp(name, " "))
X		dir->name[i] = null_ptr;
X	else
X		dir->name[i] = strdup(name);
X	if (!strcmp(number, " "))
X		dir->number[i] = null_ptr;
X	else
X		dir->number[i] = strdup(number);
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	if (!strcmp(index, " "))
X		dir->index[i] = null_ptr;
X	else
X		dir->index[i] = strdup(index);
X
X	return(1);
X}
SHAR_EOF
if test 6003 -ne "`wc -c < 'd_prompt.c'`"
then
	echo shar: "error transmitting 'd_prompt.c'" '(should have been 6003 characters)'
fi
fi
echo shar: "extracting 'd_revise.c'" '(4006 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 return code of 1 means
X * 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(), *strdup();
X	void free_ptr();
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] = NULL;
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) {
X			if (!count) {
X				beep();
X				continue;
X			}
X			count--;
X			buf[count] = NULL;
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					free_ptr(param->ld_plus);
X					param->ld_plus = strdup(ld);
X					param_flag++;
X				}
X				break;
X			case '-':
X				if ((ld = ld_prompt(r_win, param->ld_minus, ans)) != NULL) {
X					free_ptr(param->ld_minus);
X					param->ld_minus = strdup(ld);
X					param_flag++;
X				}
X				break;
X			case '@':
X				if ((ld = ld_prompt(r_win, param->ld_at, ans)) != NULL) {
X					free_ptr(param->ld_at);
X					param->ld_at = strdup(ld);
X					param_flag++;
X				}
X				break;
X			case '#':
X				if ((ld = ld_prompt(r_win, param->ld_pound, ans)) != NULL) {
X					free_ptr(param->ld_pound);
X					param->ld_pound = strdup(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, 1);
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 a null pointer.  Returns the new value or NULL on escape.
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, "", "")) == NULL)
X		return(NULL);
X					/* if space, change to NULL pointer */
X	if (!strcmp(ans, " "))
X		ans = null_ptr;
X					/* display new value */
X	clear_line(win, 2, 4, 1);
X	wattrstr(win, A_BOLD, ans);
X
X	return(ans);
X}
SHAR_EOF
if test 4006 -ne "`wc -c < 'd_revise.c'`"
then
	echo shar: "error transmitting 'd_revise.c'" '(should have been 4006 characters)'
fi
fi
echo shar: "extracting 'data_log.c'" '(1801 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 return code of 1 means we
X * 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	extern char *null_ptr;
X	int ret_code;
X	WINDOW *dl_win, *newwin();
X	char *ans, *path, *expand(), *get_str(), *strdup(), *strcpy();
X	void input_off(), free_ptr();
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	path = null_ptr;
X	while ((ans = get_str(dl_win, 60, "", " 	")) != NULL) {
X					/* give 'em the default */
X		if (*ans == NULL)
X			path = strdup(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, 1);
X		clear_line(dl_win, 4, 24, 1);
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	free_ptr(path);
X	return(ret_code);
X}
SHAR_EOF
if test 1801 -ne "`wc -c < 'data_log.c'`"
then
	echo shar: "error transmitting 'data_log.c'" '(should have been 1801 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, 20, "%-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

-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.



More information about the Comp.sources.unix mailing list