Pcomm v1.2 (3 of 8)
egray at fthood.UUCP
egray at fthood.UUCP
Sat Feb 4 03:36:00 AEST 1989
This is part 3 (of 8) to the Pcomm v1.2 distribution package.
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
-------------------------------------------------------------------------------
#! /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
# This archive created: Fri Feb 3 07:35:21 1989
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
More information about the Unix-pc.sources
mailing list