[comp.sources.misc] v16i029: ECU async comm package rev 3.0, Part05/35

wht@n4hgf.uucp (Warren Tucker) (01/06/91)

Submitted-by: wht@n4hgf.uucp (Warren Tucker)
Posting-number: Volume 16, Issue 29
Archive-name: ecu3/part05

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 05 of ecu3
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= ecuphone.c ==============
echo 'x - extracting ecuphone.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecuphone.c' &&
X/*+-------------------------------------------------------------------------
X	ecuphone.c -- visual phone dialer/directory editor
X	wht@n4hgf.Mt-Park.GA.US
X
X  .---[ title ]------------modified-.<-- dirw "top line"
X  |   stand out mode                |<-- dirw "header line"
X  |                                 |<-- scrw first line
X  |                                 |
X  |                                 |
X  |                                 |
X  |                                 |<-- scrw last line
X  +---------------------------------+<-- dirw bottom separator line
X  |                                 |<-- dirw extra cmd prompt line
X  |   stand out mode                |<-- dirw "cmd line"
X  `---------------------------------'<-- dirw bottom line
X
X  Defined functions:
X	check_curr_pde()
X	choose_line(baud)
X	copy_pde_to_lvar(tpde)
X	dirw_bot_msg(msg)
X	dirw_cmd_line_setup(prompt1,prompt2)
X	dirw_display()
X	dirw_display_config()
X	dirw_display_phonedir_name()
X	dirw_get_cmd(prompt)
X	lookup_logical_telno()
X	pde_add_or_edit(tpde,edit)
X	pde_add_or_edit_read(prompt,edit,x,buf,max,delim)
X	pde_cmd_add(tpde)
X	pde_cmd_change_dir()
X	pde_cmd_down()
X	pde_cmd_dump_list()
X	pde_cmd_find()
X	pde_cmd_mark(tpde)
X	pde_cmd_remove()
X	pde_cmd_remove_oops()
X	pde_cmd_save()
X	pde_cmd_set_wait()
X	pde_cmd_unmark(tpde)
X	pde_cmd_unmark_all()
X	pde_cmd_up()
X	pde_dial(tpde)
X	pde_dial_cycle()
X	pde_display(line,tpde,stand_out)
X	pde_display_logical(line,tpde,stand_out)
X	pde_list_add(tpde)
X	pde_list_erase()
X	pde_list_manager()
X	pde_list_read()
X	pde_list_remove(tpde)
X	pde_list_save_if_dirty()
X	pde_list_search(logical,exact_flag)
X	pde_list_set_dirty(flag)
X	scrw_fill(tpde,curr_pde_line)
X	scrw_fill_at(line_num,tpde,curr_pde_line)
X	want_pd_create(name)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include <curses.h>
X
X#define STDIO_H_INCLUDED
X#define OMIT_TERMIO_REFERENCES
X#include "ecu.h"
X#include "pc_scr.h"
X
X#include "ecupde.h"
X#include "ecukey.h"
X#include "ecuxkey.h"
X#include "ecuhangup.h"
X#include "utmpstatus.h"
X#include "dvent.h"
X#include "esd.h"
X#include "var.h"
X
Xextern char *find_procedure();
Xextern char *make_char_graphic();
X
Xvoid dirw_bot_msg();
Xvoid dirw_cmd_line_setup();
Xint pde_list_read();
X
X#if defined(BSD)
X#define strchr index
X#define strrchr rindex
X#endif
X
Xchar *strchr();
Xchar *strrchr();
X
X/* window definitions */
X#define DIRW_LINES		(LINES - 1)
X#define DIRW_COLS		(COLS)
X#define DIRW_COLS		(COLS)
X#define DIRW_TOP_LINES	2
X#define DIRW_BOT_LINES	4
X#define DIRW_CMD_LINE	(DIRW_LINES - 2)
X#define SCRW_LINES		(DIRW_LINES - DIRW_TOP_LINES - DIRW_BOT_LINES)
X#define SCRW_COLS		(DIRW_COLS)
X#define SCRW_TLY		(DIRW_TOP_LINES)
X#define SCRW_TLX		0
X
Xextern int errno;
X
Xextern int windows_active;
Xextern int interrupt;
Xextern int rcvr_pid;
Xextern char errmsg[];
Xextern char kbdintr;
Xextern int proc_level;
X
XWINDOW *dirw = (WINDOW *)0;
XWINDOW *scrw = (WINDOW *)0;
X
XPDE *pde_list_head = (PDE *)0;	/* pointer to first pde in linked list */
XPDE *curr_pde = (PDE *)0;		/* current pde */
XPDE *remove_pde = (PDE *)0;		/* if non-zero, pde just removed */
Xint remove_dirty_flag;			/* pde_list_dirty at remove time */
Xint pde_list_quan = 0;			/* count of items in list now */
Xint pde_list_dirty = 0;			/* pde_list modified but not saved */
Xint pde_marked_for_redial_count = 0;
Xint scrw_curr_pde_line;			/* scrw line curr_pde is on */
Xchar phonedir_name[256];		/* phone directory name */
Xint phonedir_name_x;			/* position for phonedir name on screen */
Xchar *phonedir_trigger = "#ECUPHONE\n";
X
X#ifdef WHT
X#define NAP_DECISEC_SINGLE_MIN         10
X#define NAP_DECISEC_MULTIPLE_MIN       10
X#else
X#define NAP_DECISEC_SINGLE_MIN         150
X#define NAP_DECISEC_MULTIPLE_MIN       50
X#endif
Xint nap_decisec_single   = 150;
Xint nap_decisec_multiple = 50;
X
X/*+-------------------------------------------------------------------------
X	pde_list_erase()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_list_erase()
X{
Xregister PDE *pde = pde_list_head;
Xregister PDE *next;
X
X	while(pde)
X	{
X		next = pde->next;
X		free((char *)pde);
X		pde = next;
X	}
X	pde_list_head = (PDE *)0;
X	pde_list_quan = 0;
X	curr_pde = (PDE *)0;
X	remove_pde = (PDE *)0;
X	pde_marked_for_redial_count = 0;
X
X}	/* end of pde_list_erase */
X
X/*+-------------------------------------------------------------------------
X	pde_list_set_dirty(flag)
X0: clean, 1 dirty, -1 do not modify;update screen only
X--------------------------------------------------------------------------*/
Xvoid
Xpde_list_set_dirty(flag)
Xint flag;
X{
Xregister itmp;
X	if(flag != pde_list_dirty)
X	{
X		if(flag != -1)
X			pde_list_dirty = flag;
X		wmove(dirw,0,DIRW_COLS - 14);
X		if(pde_list_dirty)
X			waddstr(dirw," modified ");
X		else
X		{
X			itmp = 10;
X			while(itmp--)
X				waddch(dirw,(unsigned)sHR);
X		}
X		wrefresh(dirw);
X	}
X}	/* end of pde_list_set_dirty */
X
X/*+-------------------------------------------------------------------------
X	pde_list_add(tpde) -- add to linked list
X--------------------------------------------------------------------------*/
Xvoid
Xpde_list_add(tpde)
XPDE *tpde;
X{
Xregister PDE *this = tpde;
Xregister PDE *prev;
Xregister PDE *next;
X
X/* if empty, init list with this one and quit */
X	if(pde_list_head == (PDE *)0)
X	{
X		pde_list_head = this;
X		this->prev = (PDE *)0;
X		this->next = (PDE *)0;
X		pde_list_quan++;
X		return;
X	}
X
X/* list not empty */
X	prev = (PDE *)0;		/* no previous yet */
X	next = pde_list_head;	/* init next to top of list */
X
X	while(strcmp(next->logical,this->logical) < 0)
X	{
X		prev = next;
X		next = prev->next;
X		if(next == (PDE *)0)
X			break;
X	}
X
X	if(prev)		/* if non-zero, we will not update the list head */
X	{
X		this->next = prev->next;
X		this->prev = prev;
X		prev->next = this;
X		if(next)
X			next->prev = this;
X	}
X	else	/* 'this' is to become the new list head (1st element) */
X	{
X		this->next = next;
X		this->prev = (PDE *)0;
X		if(next)
X			next->prev = this;
X		pde_list_head = this;
X	}
X	pde_list_quan++;
X
X}	/* end of pde_add */
X
X/*+-------------------------------------------------------------------------
X	pde_list_remove(tpde) -- remove from linked list
X--------------------------------------------------------------------------*/
Xvoid
Xpde_list_remove(tpde)
Xregister PDE *tpde;
X{
Xregister PDE *prev;
Xregister PDE *next;
X
X	prev = (PDE *)0;	/* there is no previous now */
X
X	if((next = pde_list_head) == (PDE *)0)	/* if empty list */
X		return;
X
X	while(next != tpde)
X	{
X		prev = next;
X		next = prev->next;
X		if(next == (PDE *)0)
X			return;
X	}
X
X/* take care of "current pde" */
X	if(tpde == curr_pde)
X	{
X		if(tpde->next)
X			curr_pde = tpde->next;
X		else if(tpde->prev)
X			curr_pde = tpde->prev;
X		else
X			curr_pde = (PDE *)0;
X	}
X
X/* marked? */
X	if(tpde->redial)
X	{
X		tpde->redial = 0;
X		pde_marked_for_redial_count--;
X	}
X
X/* unlink */
X
X	if(prev)		/* if non-zero, we will not update the list head */
X	{
X		prev->next = tpde->next;
X		if(tpde->next)
X			(tpde->next)->prev = prev;
X	}
X	else
X	{
X		pde_list_head = tpde->next;
X		if(tpde->next)
X			(tpde->next)->prev = (PDE *)0;
X	}
X
X	tpde->next = (PDE *)0;
X	tpde->prev = (PDE *)0;
X
X	pde_list_quan--;
X}	/* end of pde_list_remove */
X
X/*+-----------------------------------------------------------------------
X	PDE *pde_list_search(logical,exact_flag)
X------------------------------------------------------------------------*/
XPDE *
Xpde_list_search(logical,exact_flag)
Xchar *logical;
Xint exact_flag;
X{
Xregister PDE *tpde;
X
X	if(!pde_list_quan)
X	{
X		if(pde_list_read())
X			return((PDE *)0);
X	}
X
X	tpde = pde_list_head;
X	while(tpde)
X	{
X		/* only first few chars necessary for match with ulcmpb */
X		if(exact_flag)
X		{
X			if(strcmp(tpde->logical,logical) == 0)
X				return(tpde);
X		}
X		else
X		{
X			if(ulcmpb(tpde->logical,logical) < 0)
X				return(tpde);
X		}
X		tpde = tpde->next;
X	}
X	if(!tpde)
X		sprintf(errmsg,"'%s' not found",logical);
X	return(tpde);
X
X}	/* end of pde_list_search */
X
X/*+-------------------------------------------------------------------------
X	want_pd_create(name)
X--------------------------------------------------------------------------*/
Xint
Xwant_pd_create(name)
Xchar *name;
X{
Xuchar itmp = 255;
X
X#ifdef COMPILER_BUG_FIXED
X	dirw_bot_msg("type 'y' or 'n'");
X	while(itmp == 255)
X	{
X		ring_bell();
X		dirw_cmd_line_setup(name,"does not exist: create?");
X		itmp = ttygetc(0);
X		if(isupper(itmp))
X			itmp = tolower(itmp);
X		switch(itmp)
X		{
X			case 'y': itmp = 1; break;
X			case 'n': itmp = 0; break;
X			default: itmp = 255; break;		
X		}
X	}
X	dirw_bot_msg("");
X	return((int)itmp);
X
X#else
X
XKROCK:
X	dirw_bot_msg("type 'y' or 'n'");
X	ring_bell();
X	dirw_cmd_line_setup(name,"does not exist: create?");
X	itmp = ttygetc(0);
X	dirw_bot_msg("");
X	if(isupper(itmp))
X		itmp = tolower(itmp);
X	switch(itmp)
X	{
X		case 'y': return(1);
X		case 'n': return(0);
X	}
X	goto KROCK;
X#endif
X}	/* end of want_pd_create */
X
X/*+-------------------------------------------------------------------------
X	dirw_display_phonedir_name()
X--------------------------------------------------------------------------*/
Xvoid
Xdirw_display_phonedir_name()
X{
Xregister itmp,x;
Xchar s80[80];
X
X	if(!dirw || !phonedir_name[0])
X		return;
X
X	wmove(dirw,0,phonedir_name_x);
X	waddch(dirw,' ');
X	strncpy(s80,phonedir_name,itmp = DIRW_COLS - phonedir_name_x - 5);
X	s80[itmp] = 0;
X	waddstr(dirw,s80);
X	waddch(dirw,' ');
X	getyx(dirw,itmp,x);
X	while(x < DIRW_COLS - 1)
X		waddch(dirw,sHR),x++;
X
X}	/* end of dirw_display_phonedir_name */
X
X/*+-----------------------------------------------------------------------
X	pde_list_read()
Xsample .ecu/phone:
X#tri2:426-0624:2400:E:Tridom Pyramid        comment
Xarc:393-3083:2400:N:Atlanta Radio Club
X
Xreturn 0 if entire list read, else 1 if error (error msg in errmsg)
X------------------------------------------------------------------------*/
Xint
Xpde_list_read()
X{
Xregister token_number;
Xregister char *cptr;
Xregister char *token;
Xint itmp;
Xchar readpde_buf[128];
XFILE *fp_phone;
XPDE *tpde;
Xchar *str_token();
X
X	if(!phonedir_name[0])
X	{
X		get_home_dir(phonedir_name);
X		strcat(phonedir_name,"/.ecu/phone");
X	}
X
XTRY_OPEN:
X	if( (fp_phone = fopen(phonedir_name,"r")) == NULL)
X	{
X		if(errno == ENOENT)
X		{
X			if(!want_pd_create(phonedir_name))
X			{
X				strcpy(errmsg,"non-existent file not created");
X				return(1);
X			}
X			if((itmp = open(phonedir_name,
X				O_RDWR | O_CREAT | O_TRUNC,0600)) >= 0)
X			{
X				write(itmp,phonedir_trigger,strlen(phonedir_trigger));
X				close(itmp);
X				dirw_bot_msg("created new (empty) directory file");
X				ring_bell();
X				nap(1000L);
X				goto TRY_OPEN;
X			}
X			if(errno == ENOENT)
X			{
X				strcpy(errmsg,"directory does not exist");
X				ring_bell();
X				return(1);
X			}
X		}
X		strcpy(errmsg,sys_errlist[errno]);
X		return(1);
X	}
X
X/* we have an open directory file */
X	if(!fgets(readpde_buf,sizeof(readpde_buf),fp_phone) ||
X		strcmp(readpde_buf,phonedir_trigger))
X	{
X		fclose(fp_phone);
X		strcpy(errmsg,"not an ECU phone directory (or is pre-rev-3)");
X		ring_bell();
X		return(1);
X	}
X
X	dirw_display_phonedir_name();
X	pde_list_erase();		/* clear any previous directory */
X	while(fgets(readpde_buf,sizeof(readpde_buf),fp_phone) != NULL)
X	{
X		if(readpde_buf[0] == '#')		/* comment? */
X			continue;
X		if(itmp = strlen(readpde_buf))	/* itmp = len; if > 0 ... */
X		{
X			itmp--;
X			readpde_buf[itmp] = 0;		/* ... strip trailing NL */
X		}
X		cptr = readpde_buf;				/* first call to str_token, -> buff */
X		while((*cptr == 0x20) || (*cptr == TAB))
X			cptr++;						/* strip leading spaces */
X		if(*cptr == 0)					/* if line all blank, skip it */
X			continue;
X
X		if(!(tpde = (PDE *)malloc(sizeof(PDE ))))
X		{
X			fclose(fp_phone);
X			strcpy(errmsg,"Out of memory reading phone list");
X			return(1);
X		}
X
X		tpde->descr[0] = 0;
X		tpde->logical[0] = 0;
X		tpde->telno[0] = 0;
X		tpde->tty[0] = 0;
X		tpde->parity = 0;
X		tpde->baud = 2400;
X		tpde->redial = 0;
X		tpde->prev = (PDE *)0;
X		tpde->next = (PDE *)0;
X
X		token_number = 0;
X		while((token = str_token(cptr,":")) != NULL)
X		{
X			cptr = NULL;	/* further calls to str_token need NULL */
X			switch(token_number++)
X			{
X				case 0:		/* first field is logical name */
X					strncpy(tpde->logical,token,sizeof(tpde->logical));
X					tpde->logical[sizeof(tpde->logical) - 1] = 0;
X					break;
X				case 1:		/* second field is tpde->telno phone number */
X					strncpy(tpde->telno,token,sizeof(tpde->telno));
X					tpde->telno[sizeof(tpde->telno) - 1] = 0;
X					break;
X				case 2:		/* third field is line */
X					strncpy(tpde->tty,token,sizeof(tpde->tty));
X					tpde->tty[sizeof(tpde->tty) - 1] = 0;
X					break;
X				case 3:		/* fourth field is baud rate */
X					tpde->baud = atoi(token);
X					break;
X				case 4:		/* fifth field is parity */
X					switch(itmp = to_lower(token[0]))
X					{
X						case 'o':
X						case 'e':
X						case 'm':
X						case 's':
X							tpde->parity = itmp;
X							break;
X						default:
X						case 'n':
X							tpde->parity = 0;
X							break;
X					}
X					break;
X				default:
X					strncpy(tpde->descr,token,sizeof(tpde->descr));
X					tpde->descr[sizeof(tpde->descr) - 1] = 0;
X					break;
X			}	/* end of switch(token_number) */
X		}		/* end while not end of record */
X
X		pde_list_add(tpde);
X
X	}			/* while records left to ready */
X
X	fclose(fp_phone);
X	return(0);
X}	/* end of pde_list_read */
X
X/*+-------------------------------------------------------------------------
X	dirw_display_config()
X--------------------------------------------------------------------------*/
Xdirw_display_config()
X{
Xregister y,x;
X
X	wmove(dirw,DIRW_LINES - DIRW_BOT_LINES,0);
X	waddch(dirw,sLT);
X	getyx(dirw,y,x);
X	while(x++ < (DIRW_COLS - 1))
X		waddch(dirw,sHR);
X	waddch(dirw,sRT);
X	if(pde_marked_for_redial_count)
X	{
X		wmove(dirw,DIRW_LINES - DIRW_BOT_LINES,2);
X		wstandout(dirw);
X		wprintw(dirw," REDIAL CYCLE  wait: single=%d multiple=%d ",
X			nap_decisec_single / 10,nap_decisec_multiple / 10);
X
X		wmove(dirw,DIRW_LINES - DIRW_BOT_LINES,56);
X		wprintw(dirw," %2d marked entr%s ",
X			pde_marked_for_redial_count,
X			(pde_marked_for_redial_count == 1) ? "y" : "ies");
X		wstandend(dirw);
X	}
X}	/* end of dirw_display_config */
X
X/*+-----------------------------------------------------------------------
X	dirw_display()
X00000000001111111111222222222233333333334444444444555555555566666666667777777777
X01234567890123456789012345678901234567890123456789012345678901234567890123456789
X| entry name | telephone number | tty | baud P | description                   |
X| 0123456789 | 0123456789012345 | 01  | baud P | 01234567890123456789012345678 |
X------------------------------------------------------------------------*/
Xvoid
Xdirw_display()
X{
X	wmove(dirw,1,1);
X	wstandout(dirw);
X	wprintw(dirw,
X" entry name %c telephone number %c tty %c baud P %c description                   ",
X		sVR,sVR,sVR,sVR);
X	wstandend(dirw);
X	dirw_display_phonedir_name();
X	dirw_display_config();
X	wrefresh(dirw);
X}	/* end of dirw_display() */
X
X/*+-------------------------------------------------------------------------
X	dirw_bot_msg(msg)
X--------------------------------------------------------------------------*/
Xvoid
Xdirw_bot_msg(msg)
Xchar *msg;
X{
Xregister itmp;
Xregister itmp2;
Xstatic last_msglen = 0;
X#define DIRW_BOT_LINE_TLX 2
X#define DIRW_BOT_LINE_MAX_MSGLEN	(DIRW_COLS - DIRW_BOT_LINE_TLX - 8)
Xchar msg2[80];
X
X	if(!last_msglen && !strlen(msg))
X		return;
X
X	wmove(dirw,DIRW_LINES - 1,DIRW_BOT_LINE_TLX);
X
X	if((itmp = strlen(msg)) == 0)
X	{
X		itmp2 = last_msglen + 2;
X		for(itmp = 0; itmp < itmp2; itmp++)
X			waddch(dirw,(unsigned)sHR);
X		last_msglen = 0;
X	}
X	else
X	{
X		waddch(dirw,' ');
X		if(itmp > DIRW_BOT_LINE_MAX_MSGLEN)
X		{
X			strncpy(msg2,msg,DIRW_BOT_LINE_MAX_MSGLEN);
X			msg2[DIRW_BOT_LINE_MAX_MSGLEN + 1] = 0;
X			waddstr(dirw,msg2);
X			itmp = strlen(msg2);
X		}
X		else
X		{
X			waddstr(dirw,msg);
X			itmp = strlen(msg);
X		}
X		waddch(dirw,' ');
X		if((itmp2 = last_msglen - itmp) > 0)
X		{
X			while(itmp2--)
X				waddch(dirw,(unsigned)sHR);
X		}
X		last_msglen = itmp;		/* remember last message length */
X	}
X	wrefresh(dirw);
X}	/* end of dirw_bot_msg */
X
X/*+-------------------------------------------------------------------------
X	pde_display_logical(line,tpde,stand_out)
X--------------------------------------------------------------------------*/
Xvoid
Xpde_display_logical(line,tpde,stand_out)
Xint line;
XPDE *tpde;
Xint stand_out;
X{
X	wmove(scrw,line,0);
X	waddch(scrw,(unsigned)sVR);
X
X	if(tpde->redial)
X	{
X		wstandout(scrw);
X		waddch(scrw,'>');
X		wstandend(scrw);
X	}
X	else
X		waddch(scrw,' ');
X
X	if(stand_out)
X		wstandout(scrw);
X	wprintw(scrw,"%-10.10s",tpde->logical);
X	if(stand_out)
X		wstandend(scrw);
X
X}	/* end of pde_display_logical */
X
X/*+-----------------------------------------------------------------------
X	pde_display(win,line,tpde,stand_out)
X00000000001111111111222222222233333333334444444444555555555566666666667777777777
X01234567890123456789012345678901234567890123456789012345678901234567890123456789
X| entry name | telephone number | tty | baud P | description                   |
X| 0123456789 | 0123456789012345 | 01  | baud P | 01234567890123456789012345678 |
X--------------------------------------------------------------------------*/
Xpde_display(line,tpde,stand_out)
Xint line;
XPDE *tpde;
Xint stand_out;
X{
X
X	pde_display_logical(line,tpde,stand_out);
X	waddch(scrw,' ');
X	waddch(scrw,(unsigned)sVR);
X	waddch(scrw,' ');
X	wprintw(scrw,"%-16.16s %c ",tpde->telno,sVR);
X	if(tpde->tty[0])
X		wprintw(scrw,"%-2.2s  %c",tpde->tty,sVR);
X	else
X		wprintw(scrw,"Any %c",sVR);
X	wprintw(scrw,"%5u %c %c ",tpde->baud,
X		(tpde->parity) ? to_upper(tpde->parity) : 'N',sVR);
X	wprintw(scrw,"%-29.29s %c",tpde->descr,sVR);
X	return(0);
X
X}	/* end of pde_display */
X
X/*+-----------------------------------------------------------------------
X	scrw_fill(first_pde,curr_pde_line)
X------------------------------------------------------------------------*/
Xvoid
Xscrw_fill(tpde,curr_pde_line)
Xregister PDE *tpde;
Xint *curr_pde_line;
X{
Xregister line;
Xregister is_curr_pde;
X
X	*curr_pde_line = -1;
X	for(line = 0; line < SCRW_LINES; line++)
X	{
X		if(tpde)
X		{
X			if(is_curr_pde = (tpde == curr_pde))
X				*curr_pde_line = line;
X			pde_display(line,tpde,is_curr_pde);
X			tpde = tpde->next;
X		}
X		else
X		{
X			wmove(scrw,line,0);
X			waddch(scrw,(unsigned)sVR);
X			wclrtoeol(scrw);
X			wmove(scrw,line,SCRW_COLS - 1);
X			waddch(scrw,(unsigned)sVR);
X		}
X	}
X	wrefresh(scrw);
X
X}	/* end of scrw_fill */
X
X/*+-------------------------------------------------------------------------
X	scrw_fill_at(line_num,first_pde,curr_pde_line)
X--------------------------------------------------------------------------*/
Xvoid
Xscrw_fill_at(line_num,tpde,curr_pde_line)
Xint line_num;
Xregister PDE *tpde;
Xint *curr_pde_line;
X{
Xregister itmp;
X
X	if(!tpde)
X	{
X		scrw_fill(tpde,curr_pde_line);
X/*
X		wclear(scrw);
X		wrefresh(scrw);
X*/
X		return;
X	}
X	for(itmp = 0; itmp < line_num; itmp++)
X	{
X		if(!tpde->prev)
X			break;
X		tpde = tpde->prev;
X	}
X
X	scrw_fill(tpde,curr_pde_line);
X
X}	/* end of scrw_fill_at */
X
X/*+-------------------------------------------------------------------------
X	dirw_cmd_line_setup(prompt1,prompt2)
X--------------------------------------------------------------------------*/
Xvoid
Xdirw_cmd_line_setup(prompt1,prompt2)
Xchar *prompt1;
Xchar *prompt2;
X{
Xregister icol;
Xint y;
Xint x;
Xchar *cptr;
Xint standout_mode;
X
X	wmove(dirw,DIRW_CMD_LINE - 1,1);
X	wstandend(dirw);
X	standout_mode = 0;
X	waddch(dirw,' ');
X	cptr = prompt1;
X	while(*cptr)
X	{
X		if(*cptr == '~')
X		{
X			if(standout_mode)
X				wstandend(dirw);
X			else
X				wstandout(dirw);
X			standout_mode = !standout_mode;
X			cptr++;
X		}
X		else
X			waddch(dirw,*cptr++);
X	}
X	wstandend(dirw);
X	standout_mode = 0;
X
X	waddch(dirw,' ');
X	getyx(dirw,y,x);
X	for(icol = x; icol < DIRW_COLS - 1; icol++)
X		waddch(dirw,' ');
X
X	wmove(dirw,DIRW_CMD_LINE,1);
X	waddch(dirw,' ');
X	cptr = prompt2;
X	while(*cptr)
X	{
X		if(*cptr == '~')
X		{
X			if(standout_mode)
X				wstandend(dirw);
X			else
X				wstandout(dirw);
X			standout_mode = !standout_mode;
X			cptr++;
X		}
X		else
X			waddch(dirw,*cptr++);
X	}
X	wstandend(dirw);
X	waddch(dirw,' ');
X	getyx(dirw,y,x);
X	for(icol = x; icol < DIRW_COLS - 1; icol++)
X		waddch(dirw,' ');
X	wmove(dirw,y,x);
X	wrefresh(dirw);
X}	/* end of dirw_cmd_line_setup */
X
X/*+-------------------------------------------------------------------------
X	dirw_get_cmd()
X--------------------------------------------------------------------------*/
Xuchar
Xdirw_get_cmd(prompt)
Xchar *prompt;
X{
Xregister uchar cmd;
Xchar setupline1[128];	/* yetch ... avoid source line > 80 chars */
Xchar *setupline1_1 = "~d~own ~u~p ~e~dit ~a~dd ~r~emove ~s~ave ~f~ind ";
Xchar *setupline1_2 = "~c~hange dial dir ~ENTER~:dial ~ESC,q~uit";
X
X	strcpy(setupline1,setupline1_1);
X	strcat(setupline1,setupline1_2);
X
X	dirw_cmd_line_setup(
X		setupline1,
X		"redial: ~m~ark un~M~ark ~U~nmark all ~w~ait between dial");
X	cmd = ttygetc(1);
X	dirw_bot_msg("");
X	return(cmd);
X
X}	/* end of dirw_get_cmd */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_save()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_save()
X{
XFILE *fpold;
XFILE *fpnew;
XPDE *tpde;
Xchar phonedir_ntmp[256];		/* temp phone directory name */
Xchar iobuf[128];
Xint count = 0;
X
X	if(!pde_list_dirty)
X	{
X		dirw_bot_msg("directory has not been modified");
X		return;
X	}
X
X	strcpy(phonedir_ntmp,phonedir_name);
X	strcat(phonedir_ntmp,".t");
X
X	if((fpnew = fopen(phonedir_ntmp,"w")) == NULL)	/* open old file */
X	{
X		sprintf(iobuf,"cannot open %s",phonedir_ntmp);
X		dirw_bot_msg(iobuf);
X		return;
X	}
X
X/* write trigger */
X	fputs(phonedir_trigger,fpnew);
X
X/* retain commented entries */
X	if((fpold = fopen(phonedir_name,"r")) != NULL)	/* open old file */
X	{
X		while(fgets(iobuf,sizeof(iobuf),fpold) != NULL)
X		{
X			if((iobuf[0] == '#') && strcmp(iobuf,phonedir_trigger))
X				fputs(iobuf,fpnew);
X		}
X		fclose(fpold);
X	}
X
X/* write new entries */
X	tpde = pde_list_head;
X	while(tpde)
X	{
X		sprintf(iobuf,"%d",count+1);
X		dirw_bot_msg(iobuf);
X		sprintf(iobuf,"%s:%s:%s:%u:%c:%s\n",tpde->logical,tpde->telno,
X			tpde->tty,tpde->baud,
X			(tpde->parity) ? to_upper(tpde->parity) : 'N',
X			tpde->descr);
X		fputs(iobuf,fpnew);
X		tpde = tpde->next;
X		count++;
X	}
X
X	fclose(fpnew);
X	unlink(phonedir_name);
X	rename(phonedir_ntmp,phonedir_name);
X	sprintf(iobuf,"saved %d entries",count);
X	dirw_bot_msg(iobuf);
X	pde_list_set_dirty(0);
X
X}	/* end of pde_cmd_save */
X
X/*+-------------------------------------------------------------------------
X	pde_list_save_if_dirty()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_list_save_if_dirty()
X{
Xuint cmd = 0;
X
X	if(pde_list_dirty)
X	{
X		dirw_bot_msg("type 'y' or 'n'");
X		while(!cmd)
X		{
X			ring_bell();
X			dirw_cmd_line_setup("","current directory modified: save?");
X			cmd = ttygetc(0);
X			if(isupper(cmd))
X				cmd = tolower(cmd);
X			switch(cmd)
X			{
X				case 'y': pde_cmd_save(); break;
X				case 'n': break;
X				default:
X					cmd = 0;
X					break;		
X			}
X		}
X		dirw_bot_msg("");
X	}
X}	/* end of pde_list_save_if_dirty */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_up()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_up()
X{
Xregister PDE *tpde;
X
X	if((!curr_pde) || (curr_pde->prev == (PDE *)0))
X	{
X		ring_bell();
X		return;
X	}
X	if(scrw_curr_pde_line)
X	{
X		pde_display_logical(scrw_curr_pde_line,curr_pde,0);
X		scrw_curr_pde_line--;
X		curr_pde = curr_pde->prev;
X		pde_display_logical(scrw_curr_pde_line,curr_pde,1);
X	}
X	else
X	{
X		tpde = curr_pde;
X		curr_pde = curr_pde->prev;
X		scrw_fill_at(10,tpde,&scrw_curr_pde_line);
X	}
X
X}	/* end of pde_cmd_up */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_down()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_down()
X{
Xregister itmp;
Xregister PDE *tpde;
X
X	if((!curr_pde) || (curr_pde->next == (PDE *)0))
X	{
X		ring_bell();
X		return;
X	}
X	if(scrw_curr_pde_line < (SCRW_LINES - 1))
X	{
X		pde_display_logical(scrw_curr_pde_line,curr_pde,0);
X		scrw_curr_pde_line++;
X		curr_pde = curr_pde->next;
X		pde_display_logical(scrw_curr_pde_line,curr_pde,1);
X	}
X	else
X	{
X		tpde = curr_pde;
X		curr_pde = curr_pde->next;
X		scrw_fill_at(SCRW_LINES - 10,tpde,&scrw_curr_pde_line);
X	}
X
X}	/* end of pde_cmd_down */
X
X/*+-------------------------------------------------------------------------
X	check_curr_pde() -- return 1 if there is a current pde, else 0
X--------------------------------------------------------------------------*/
Xcheck_curr_pde()
X{
X	if(!curr_pde)
X	{
X		dirw_bot_msg("no directory entry selected");
X		return(0);
X	}
X	return(1);
X}	/* end of check_curr_pde */
X
X/*+-------------------------------------------------------------------------
X	pde_add_or_edit_read(prompt,edit,x,buf,max,delim)
Xmax must not wrap around to another line
X--------------------------------------------------------------------------*/
Xpde_add_or_edit_read(prompt,edit,x,buf,max,delim)
Xchar *prompt;
Xint edit;
Xint x;
Xchar *buf;
Xint max;
Xchar *delim;
X{
Xregister itmp;
Xchar s82[82];
X
X	while(1)
X	{
X		dirw_cmd_line_setup("",prompt);
X		wstandout(scrw);
X		if(edit)
X			strcpy(s82,buf);
X		itmp = wingets(scrw,scrw_curr_pde_line,x,s82,max,delim,edit);
X		wstandend(scrw);
X		
X		switch(*delim)
X		{
X			case ESC:
X				return;
X
X			case CR:
X			case NL:
X				if(edit && (itmp == 0))
X				{
X					*delim = TAB;
X					return;
X				}
X				strcpy(buf,s82);
X				return;
X
X			case CTL_B:
X				*buf = 0;
X				return;
X
X			case TAB:
X				if(!edit)
X					continue;
X				*buf = 0;
X				return;
X
X			default:
X				break;
X		}
X	}
X}	/* end of pde_add_or_edit_read */
X
X/*+-------------------------------------------------------------------------
X	pde_add_or_edit(tpde,edit)
Xif called with edit == 1, tpde MUST == curr_pde !!!
X00000000001111111111222222222233333333334444444444555555555566666666667777777777
X01234567890123456789012345678901234567890123456789012345678901234567890123456789
X| entry name | telephone number | tty | baud P | description                   |
X| 0123456789 | 0123456789012345 | 01  | baud P | 01234567890123456789012345678 |
X--------------------------------------------------------------------------*/
Xint
Xpde_add_or_edit(tpde,edit)
Xregister PDE *tpde;
Xint edit;
X{
Xregister itmp;
Xint input_state = 0;
Xint changed;
Xchar s50[50];
Xchar delim;
Xint done = 0;
Xint y,x;
XPDE *old_curr_pde;
Xuint baud;
X
X	if(!edit)
X	{
X		dirw_bot_msg("ESC: abort  ^U: erase input");
X		dirw_cmd_line_setup("","Enter new directory entry name: ");
X		getyx(dirw,y,x);
X		wstandout(dirw);
X		wingets(dirw,y,x,tpde->logical,10+1,&delim,0);
X		wstandend(dirw);
X		dirw_bot_msg("");
X		if((!strlen(tpde->logical)) || (tpde->logical[0] == ESC))
X		{
X			dirw_bot_msg("add aborted");
X			return(0);
X		}
X	
X		if(!isalpha(tpde->logical[0]))
X		{
X			dirw_bot_msg("first character must be alphabetic");
X			return(0);
X		}
X
X		if(pde_list_search(tpde->logical,1))
X		{
X			sprintf(s50,"'%s' is already in the directory",tpde->logical);
X			ring_bell();
X			dirw_bot_msg(s50);
X			return(0);
X		}
X
X		tpde->descr[0] = 0;
X		tpde->telno[0] = 0;
X		tpde->tty[0] = 0;
X		tpde->parity = '-';
X		tpde->baud = 0;				
X	
X		pde_list_add(tpde);
X		old_curr_pde = curr_pde;
X		curr_pde = tpde;
X		scrw_fill_at(SCRW_LINES / 2,tpde,&scrw_curr_pde_line);
X		tpde = curr_pde;
X	}	/* end of add code */
X
X	if(edit)
X		dirw_bot_msg("ESC: exit  ^U: erase input  ^B: back  TAB: forward");
X	else
X		dirw_bot_msg("ESC: abort  ^U: erase input  ^B: back up");
X
X/* add/edit common */
X	while(!done)
X	{
X		changed = 0;
X		switch(input_state)
X		{
X			case 0:
X				if(edit)
X					strcpy(s50,tpde->telno);
X				pde_add_or_edit_read("Enter telephone number",
X					edit,15,tpde->telno,16+1,&delim);
X				if(edit && strcmp(tpde->telno,s50))
X					changed = 1;
X				break;
X
X			case 1:
X				if(edit)
X					strcpy(s50,(tpde->tty[0]) ? tpde->tty : "Any");
X				pde_add_or_edit_read("Enter tty identifier (i.e., 1a)",
X					edit,34,s50,3+1,&delim);
X				if(edit && strcmp((tpde->tty[0]) ? tpde->tty : "Any",s50))
X					changed = 1;
X				if(!strcmpi(s50,"any"))
X					tpde->tty[0] = 0;
X				else
X				{
X					strncpy(tpde->tty,s50,2);
X					tpde->tty[2] = 0;
X				}
X				break;
X
X			case 2:
X				if(edit)
X					sprintf(s50,"%u",tpde->baud);
X				pde_add_or_edit_read(
X				"Enter baud rate (110,300,600,1200,2400,4800,9600,19200,38400)",
X					edit,39,s50,5+1,&delim);
X				if(valid_baud_rate(baud = atoi(s50)) < 0)
X				{
X					ring_bell();
X					continue;
X				}
X				if(edit && (tpde->baud != baud ))
X					changed = 1;
X				tpde->baud = baud;
X				break;
X
X			case 3:
X				if(edit)
X					sprintf(s50,"%c",(tpde->parity) ? tpde->parity : 'n');
X				pde_add_or_edit_read("Enter parity (n,o,e)",
X					edit,45,s50,1+1,&delim);
X				switch(s50[0] = to_lower(s50[0]))
X				{
X					case 'n':
X						s50[0] = 0;
X					case 'o':
X					case 'e':
X						if(edit && (tpde->parity != s50[0]))
X							changed = 1;
X						tpde->parity = s50[0];
X						break;
X					default:
X						ring_bell();
X						continue;
X				}
X				break;
X
X			case 4:
X				if(edit)
X					strcpy(s50,tpde->descr);
X				pde_add_or_edit_read("Enter description",
X					edit,49,tpde->descr,29+1,&delim);
X				if(edit && strcmp(tpde->descr,s50))
X					changed = 1;
X				break;
X		}
X
X		pde_display(scrw_curr_pde_line,tpde,1);	/* regardless of delimiter */
X
X		switch(delim) /* process delimiter */
X		{
X			case CTL_L:
X			case CTL_R:
X				tcap_clear_screen();
X				touchwin(stdscr);
X				wrefresh(stdscr);
X				touchwin(dirw);
X				wrefresh(dirw);
X				touchwin(scrw);
X				wrefresh(scrw);
X				break;
X
X			case CTL_B:
X				if(input_state)
X					input_state--;
X				break;
X
X			case TAB:
X				input_state++;
X				input_state %= 5;
X				break;
X
X			case ESC:
X				if(edit)
X				{
X					dirw_bot_msg("edit finished");
X					done = 1;
X				}
X				else
X				{
X					pde_list_remove(tpde);
X					curr_pde = old_curr_pde;
X					scrw_fill_at(scrw_curr_pde_line + 1,curr_pde,
X							&scrw_curr_pde_line);
X					dirw_bot_msg("add aborted");
X					return(0);
X				}
X				break;
X
X			case NL:
X				if(edit && changed)
X					pde_list_set_dirty(1);
X				/* fall thru */
X			default:
X				if(!edit && (input_state == 4))
X					done = 1;
X				else 
X				{
X					input_state++;
X					input_state %= 5;
X				}
X				break;
X		}
X	}
X	return(1);
X
X}	/* end of pde_add_or_edit */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_add(tpde)
Xif tpde != 0, it is an already valid pde that is to be added
Xelse if == 0, interactive add
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_add(tpde)
Xregister PDE *tpde;
X{
Xregister itmp;
X
X	if(tpde)
X	{
X		pde_list_add(tpde);
X	}
X	else
X	{
X		if(!(tpde = (PDE *)malloc(sizeof(PDE ))))
X		{
X			dirw_bot_msg("Out of memory -- cannot add new entry");
X			return;
X		}
X		if(!pde_add_or_edit(tpde,0))	/* routine will add to list ... */
X		{								/* ... if good return */
X			free((char *)tpde);
X			return;
X		}
X	}
X	pde_list_set_dirty(1);
X
X	curr_pde = tpde;
X	scrw_fill_at(SCRW_LINES / 2,curr_pde,&scrw_curr_pde_line);
X
X}	/* end of pde_cmd_add */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_mark(tpde) - mark for redial
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_mark(tpde)
Xregister PDE *tpde;
X{
X
X	if(!tpde)
X		return;
X	if(!tpde->redial)
X	{
X		tpde->redial = 1;
X		if(tpde == curr_pde)
X			pde_display_logical(scrw_curr_pde_line,curr_pde,1);
X		pde_marked_for_redial_count++;
X		dirw_display_config();
X	}
X
X}	/* end of pde_cmd_mark */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_unmark(tpde) - unmark for redial
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_unmark(tpde)
Xregister PDE *tpde;
X{
X
X	if(!tpde)
X		return;
X	if(tpde->redial)
X	{
X		tpde->redial = 0;
X		if(tpde == curr_pde)
X			pde_display_logical(scrw_curr_pde_line,curr_pde,1);
X		pde_marked_for_redial_count--;
X		dirw_display_config();
X	}
X
X}	/* end of pde_cmd_unmark */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_unmark_all() - unmark for redial all PDEs
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_unmark_all()
X{
Xregister PDE *tpde;
Xregister y;
X
X	tpde = pde_list_head;
X	while(tpde)
X	{
X		tpde->redial = 0;
X		tpde = tpde->next;
X	}
X
X	for(y = 0; y < SCRW_LINES; y++)
X	{
X		wmove(scrw,y,1);
X		waddch(scrw,' ');
X	}
X	pde_marked_for_redial_count = 0;
X	dirw_display_config();
X
X}	/* end of pde_cmd_unmark_all */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_remove_oops()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_remove_oops()
X{
X	if(!remove_pde)
X	{
X		dirw_bot_msg("no removed entry to restore");
X		return;
X	}
X	pde_cmd_add(remove_pde);
X	pde_list_set_dirty(remove_dirty_flag);
X	remove_pde = (PDE *)0;
X}	/* end of pde_cmd_remove_oops */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_remove()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_remove()
X{
Xregister itmp;
Xregister PDE *tpde;
Xchar s80[80];
X
X	if(!check_curr_pde())
X		return;
X
X	remove_pde = curr_pde;
X	remove_dirty_flag = pde_list_dirty;
X	pde_list_remove(curr_pde);
X	pde_list_set_dirty(1);
X
X	if(pde_list_quan)
X		scrw_fill_at(scrw_curr_pde_line + 1,curr_pde,&scrw_curr_pde_line);
X	else
X		scrw_fill((PDE *)0,&scrw_curr_pde_line);
X
X	ring_bell();
X	sprintf(s80,"if you did not mean to to remove '%s', press 'o' (oops) NOW!",
X			remove_pde->logical);
X	dirw_bot_msg(s80);
X
X}	/* end of pde_cmd_remove */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_find()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_cmd_find()
X{
Xregister itmp;
Xregister PDE *tpde;
Xchar findname[12];
Xchar delim;
Xint y,x;
X
X	dirw_bot_msg("ESC: abort  ^U: erase input");
X	dirw_cmd_line_setup("","Directory entry name to find: ");
X	getyx(dirw,y,x);
X	wstandout(dirw);
X	wingets(dirw,y,x,findname,10+1,&delim,0);
X	wstandend(dirw);
X	dirw_bot_msg("");
X	if((!strlen(findname)) || (delim == ESC))
X		return;
X
X	if(! (tpde = pde_list_search(findname,0)))
X	{
X		dirw_bot_msg(errmsg);
X		return;
X	}
X	curr_pde = tpde;
X	scrw_fill_at(SCRW_LINES / 2,tpde,&scrw_curr_pde_line);
X
X}	/* end of pde_cmd_find */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_change_dir()
X--------------------------------------------------------------------------*/
Xpde_cmd_change_dir()
X{
Xregister itmp;
Xregister PDE *tpde;
Xchar newdirname[256];
Xchar buf[256];
Xchar delim;
Xint y,x;
Xchar *expcmd;
Xextern char *sys_errlist[];
Xextern char errmsg[];
X
X	pde_list_save_if_dirty();
X	dirw_bot_msg("ESC: abort  ^U: erase input");
X	dirw_cmd_line_setup(" Enter new directory name:","");
X	getyx(dirw,y,x);
X	wstandout(dirw);
X	wingets(dirw,y,x,buf,70+1,&delim,0);
X	wstandend(dirw);
X	dirw_bot_msg("");
X	if((!strlen(buf)) || (delim == ESC))
X		return;
X
X	if((buf[0] == '~') || (buf[0] == '.') || (buf[0] == '/'))
X		strcpy(newdirname,buf);
X	else
X	{
X		get_curr_dir(newdirname,sizeof(newdirname));
X		strcat(newdirname,"/");
X		strcat(newdirname,buf);
X	}
X	if(find_shell_chars(newdirname))
X	{
X	char *expcmd;
X
X		if(expand_cmd_with_wildlist(newdirname,&expcmd))
X		{
X			dirw_bot_msg(expcmd);
X			ring_bell();
X			return;
X		}
X		strncpy(newdirname,expcmd,sizeof(newdirname) - 1);
X		newdirname[sizeof(newdirname) - 1] = 0;
X		free(expcmd);
X	}
X
X	if(access(newdirname,4))
X	{
X		if(errno == ENOENT)
X		{
X			if(!want_pd_create(newdirname))
X			{
X				dirw_bot_msg("non-existent file not created");
X				return;
X			}
X			if((itmp = open(newdirname,O_RDWR | O_CREAT | O_TRUNC,0600)) >= 0)
X			{
X				write(itmp,phonedir_trigger,strlen(phonedir_trigger));
X				close(itmp);
X				dirw_bot_msg("created new (empty) directory file");
X				ring_bell();
X				nap(1000L);
X				goto READ_LIST;
X			}
X			if(errno == ENOENT)
X			{
X				dirw_bot_msg("directory does not exist");
X				ring_bell();
X				return;
X			}
X		}
X		dirw_bot_msg(sys_errlist[errno]);
X		ring_bell();
X		return;
X	}
X
XREAD_LIST:
X	strcpy(phonedir_name,newdirname);
X	if(pde_list_read())
X	{
X		dirw_bot_msg(errmsg);
X		return;
X	}
X	curr_pde = pde_list_head;
X	scrw_fill(curr_pde,&scrw_curr_pde_line);
X	if(!pde_list_quan)
X	{
X		dirw_bot_msg("directory empty");
X		return;
X	}
X
X}	/* end of pde_cmd_change_dir */
X
X/*+-------------------------------------------------------------------------
X	pde_dial(tpde) - dial a pde (using procedure if configured)
Xreturns status ==  DCE_dial $i0 value ($s0 is also set, BTW)
Xassumes rcvr process dead (rcvr_pid == -1)
X--------------------------------------------------------------------------*/
Xint
Xpde_dial(tpde)
Xregister PDE *tpde;
X{
Xint status;
X
X#ifdef AUTO_DIAL_PROC
X	if(proc_level || !find_procedure(tpde->logical))
X		status = DCE_dial_pde(tpde);
X	else
X	{
X	char *pargv[2];
X		pargv[0] = tpde->logical;
X		pargv[1] = "!MENU";
X		if(do_proc(2,pargv))
X			status = 1;
X	}
X#else
X	status = DCE_dial_pde(tpde);
X#endif
X	interrupt = 0;
X	return(status);
X
X}	/* end of pde_dial */
X
X/*+-------------------------------------------------------------------------
X	pde_dial_cycle()
Xreturn 1 if connect occurs, 0 if cycle expires or interrupted
X--------------------------------------------------------------------------*/
Xint
Xpde_dial_cycle()
X{
Xregister PDE *tpde = pde_list_head;
Xuint ans;
Xint nap_decisec;
X
X	if(!tpde || !pde_list_quan)
X	{
X		ring_bell();
X		return(0);
X	}
X
X	if(!pde_marked_for_redial_count)
X	{
X		pde_dial(curr_pde);
X		return(!(int)iv[0]);
X	}
X
X	ff(se,"\r\nbeginning cycle through %d marked redial entries\r\n",
X		pde_marked_for_redial_count);
X	while(1)	/* forever until a connect or interrupt */
X	{
X		if(tpde->redial)
X		{
X			pde_dial(tpde);
X			switch((int)iv[0])
X			{
X				case 0:		/* CONNECTED */
X					tpde->redial = 0;
X					pde_marked_for_redial_count--;
X					bell_notify(XBELL_C);
X					return(1);
X				case 2:		/* INTERRUPTED */
X					ff(se,"\r\ndial interrupted: abort cycle (y,n)?  ");
X					interrupt = 0;
X					ans = 0;
X					while(ans == 0)
X					{
X						switch(ans = to_lower(ttygetc(1)))
X						{
X							case 'y':
X								ff(se,"YES\r\n");
X								goto ABORT_CYCLE;
X							case 'n':
X								ff(se,"NO\r\n");
X								break;
X							default: 
X								ring_bell();
X								ans = 0;
X						}
X					}
X					break;
X				case 1:		/* FAILED TO CONNECT */
X				case 3:		/* MODEM ERROR */
X				default:
X					if(pde_marked_for_redial_count == 1)
X						nap_decisec = nap_decisec_single;
X					else
X						nap_decisec = nap_decisec_multiple;
X					ff(se,
X					"waiting %d seconds ... 'c' to cycle, %s to abort\r\n",
X						nap_decisec/10,
X						(kbdintr == DEL) ?"DEL":make_char_graphic(kbdintr,0));
X					while(nap_decisec--)
X					{
X						nap(100L);
X						if(rdchk(0))
X						{
X							ans = to_lower(ttygetc(1));
X							ttyflush(0);
X							if(ans == 'c')
X								goto CONTINUE_CYCLE;
X							else if(ans == kbdintr)
X								goto ABORT_CYCLE;
X							else
X								ring_bell();
X						}
X						if(interrupt)
X							goto ABORT_CYCLE;
X					}
X					break;
X			}
X		}
XCONTINUE_CYCLE:
X		tpde = tpde->next;
X		if(!tpde)
X			tpde = pde_list_head;
X	}
X	/*NOTREACHED*/
X	return(0);	/* but just in case */
X
XABORT_CYCLE:
X	interrupt = 0;
X	ff(se,"redial cycle ABORTED\r\n");
X	return(0);
X
X}	/* end of pde_dial_cycle */
X
X/*+-------------------------------------------------------------------------
X	pde_cmd_set_wait()
X--------------------------------------------------------------------------*/
Xpde_cmd_set_wait()
X{
Xchar buf[64];
Xchar delim;
Xint y,x;
X
X	dirw_bot_msg("ESC: abort  ^U: erase input");
X	sprintf(buf,"(Must be greater than or equal to %d seconds)",
X		NAP_DECISEC_SINGLE_MIN / 10);
X	dirw_cmd_line_setup(buf,"Wait between dials when one entry marked:");
X	getyx(dirw,y,x);
X	sprintf(buf,"%d",nap_decisec_single / 10);
X	wstandout(dirw);
X	wingets(dirw,y,x,buf,3+1,&delim,1);
X	wstandend(dirw);
X	if((!strlen(buf)) || (delim == ESC))
X	{
X		dirw_bot_msg("");
X		return;
X	}
X	nap_decisec_single = 0;
X	sscanf(buf,"%d",&nap_decisec_single);
X	nap_decisec_single *= 10;
X	if(nap_decisec_single <  NAP_DECISEC_SINGLE_MIN)
X		nap_decisec_single = NAP_DECISEC_SINGLE_MIN;
X	dirw_display_config();
X
X	sprintf(buf,"(Must be greater than or equal to %d seconds)",
X		NAP_DECISEC_MULTIPLE_MIN / 10);
X	dirw_cmd_line_setup(buf,"Wait between dials when multiple entries marked:");
X	getyx(dirw,y,x);
X	sprintf(buf,"%d",nap_decisec_multiple / 10);
X	wstandout(dirw);
X	wingets(dirw,y,x,buf,3+1,&delim,1);
X	wstandend(dirw);
X	if((!strlen(buf)) || (delim == ESC))
X	{
X		dirw_bot_msg("");
X		return;
X	}
X	nap_decisec_multiple = 0;
X	sscanf(buf,"%d",&nap_decisec_multiple);
X	nap_decisec_multiple *= 10;
X	if(nap_decisec_multiple <  NAP_DECISEC_MULTIPLE_MIN)
X		nap_decisec_multiple = NAP_DECISEC_MULTIPLE_MIN;
X	dirw_display_config();
X
X	dirw_bot_msg("");
X
X}	/* end of pde_cmd_set_wait */
X
X/*+-------------------------------------------------------------------------
X	pde_list_manager()
X--------------------------------------------------------------------------*/
Xvoid
Xpde_list_manager()
X{
Xregister uchar cmd = 0;
Xint done;
Xchar s80[80];
XWINDOW *window_create();
Xint rcvr_was_active = (rcvr_pid > 0) || (rcvr_pid == -2);
X
X	kill_rcvr_process(SIGUSR1);
X	rcvr_pid = -1;
X
X	windows_start();
X	dirw = window_create("dialing directory",3,0,0,DIRW_LINES,DIRW_COLS);
X	phonedir_name_x = 26;	/* must be set before calling dirw_display */
X	dirw_display();
X
X	scrw = subwin(dirw,SCRW_LINES,SCRW_COLS,SCRW_TLY,SCRW_TLX);
X	scrollok(scrw,0);
X	if(!pde_list_quan)
X	{
X		if(pde_list_read())
X			dirw_bot_msg(errmsg);
X		else if(!pde_list_quan)
X			dirw_bot_msg("directory empty");
X	}
X
X	if(pde_list_quan)
X	{
X		if(curr_pde)
X			scrw_fill_at(scrw_curr_pde_line,curr_pde,&scrw_curr_pde_line);
X		else
X		{
X			curr_pde = pde_list_head;
X			scrw_fill(curr_pde,&scrw_curr_pde_line);
X		}
X	}
X
X	pde_list_set_dirty(-1);
X
X	done = 0;
X	while(!done)
X	{
X		cmd = dirw_get_cmd(
X	"d,j:down u,k:up e:edit a:add r:remove s:save f:find END:dial ESC,q:quit");
X		if((cmd != 'o') && (remove_pde))
X		{
X			free((char *)remove_pde);
X			remove_pde = (PDE *)0;
X		}
X
X		switch(cmd)
X		{
X			case XFcurdn:
X			case 'd':
X			case 'j': pde_cmd_down(); break;
X
X			case XFcurup:
X			case 'u':
X			case 'k': pde_cmd_up(); break;
X
X			case 's': pde_cmd_save(); break;
X
X			case 'm': pde_cmd_mark(curr_pde); break;
X			case 'M': pde_cmd_unmark(curr_pde); break;
X			case 'U': pde_cmd_unmark_all(); break;
X			case 'c': pde_cmd_change_dir(); break;
X
X			case 'w': pde_cmd_set_wait(); break;
X
X			case CR:
X			case NL:
X				cmd = CR;
X				if(!check_curr_pde())
X					break;
X				pde_list_save_if_dirty();
X				windows_end(dirw);
X				dirw = (WINDOW *)0;
X				scrw = (WINDOW *)0;
X				pde_dial_cycle();
X				done = 1;
X				if(rcvr_was_active)
X					start_rcvr_process(1);
X				break;
X
X			case ESC:
X			case CTL_C:
X				cmd = 'q';
X			case 'q':
X				done = 1;
X				continue;
X
X			case '/':
X			case 'f': pde_cmd_find(); break;
X
X			case 'r': pde_cmd_remove(); break;
X			case 'o': pde_cmd_remove_oops(); break;
X
X			case 'a': pde_cmd_add((PDE *)0); break;
X
X			case 'e': pde_add_or_edit(curr_pde,1); break;
X
X			case CTL_L:
X			case CTL_R:
X				touchwin(stdscr);
X				wrefresh(stdscr);
X				touchwin(dirw);
X				wrefresh(dirw);
X				touchwin(scrw);
X				wrefresh(scrw);
X				break;
X
X			default:
X				sprintf(s80,"invalid command: %s",
X					(cmd < 0x80) ? make_char_graphic(cmd,0) : "?");
X				ring_bell();
X				dirw_bot_msg(s80);
X				break;
X		}
X	}
X	interrupt = 0;
X	if(cmd == CR)
X		return;
X
X	pde_list_save_if_dirty();
X	windows_end(dirw);
X	dirw = (WINDOW *)0;
X	scrw = (WINDOW *)0;
X	redisplay_rcvr_screen();
X	if(rcvr_was_active)
X		start_rcvr_process(0);
X}	/* end of pde_list_manager */
X
X/*+-------------------------------------------------------------------------
X	choose_line(baud) - user is dialing a remote and will take 'Any' line
X--------------------------------------------------------------------------*/
Xvoid
Xchoose_line(baud)
Xuint baud;
X{
Xstruct dvent *dve;
Xchar s32[32];
X
X/* check out current line choice */
X	if(access(shm->Lline,6))
X		goto GET_LINE_THAT_MATCHES_BAUD;
X	dve = getdvline(shm->Lline + 8);
X	enddvent();
X	if(!dve)	/* if no match in Devices, let ecu fend for itself */
X		return;
X
X/* if shm->Lline is open and baud rate ok, no further */
X	if(shm->Liofd > 0)
X	{
X		if((dve->low_baud <= baud) && (baud <= dve->high_baud))
X			return;
X		lclose();	/* won't do ... gotta find a new one */
X		goto GET_LINE_THAT_MATCHES_BAUD;
X	}
X
X	if(!shm->Lline[0])
X		memset(shm->Lline,0,sizeof(shm->Lline));
X
X/* see if shm->Lline in use by someone else; if not and baud rate ok, no further */
X	switch(utmp_status(shm->Lline))
X	{
X		case US_NOTFOUND:	/* not in utmp, or getty dead */
X			if(line_locked(shm->Lline))
X				goto GET_LINE_THAT_MATCHES_BAUD;
X		case US_LOGIN:		/* enabled for login, idle */
X			if((dve->low_baud <= baud) && (baud <= dve->high_baud))
X				return;
X	}
X
X/* we've got to pick a new line */
XGET_LINE_THAT_MATCHES_BAUD:
X
X	strcpy(s32,"/dev/tty");
X	while(1)
X	{
X		if(!(dve = getdvbaud(baud)))
X		{
X			enddvent();		/* no match ... */
X			return;			/* ... so let current shm->Lline fail */
X		}
X/* by now, we know shm->Lline wont work */
X		if(!strcmp(dve->line,shm->Lline + 5))
X			continue;
X/* if not acu, dont use it */
X		if(ulindex(dve->type,"ACU") < 0)
X			continue;
X		strcpy(&s32[8],dve->line + 3);	/* yeech ... make "/dev/ttyxx" */
X		switch(utmp_status(s32))
X		{
X			case US_NOTFOUND:	/* not in utmp, or getty dead */
X				if(line_locked(s32))
X					continue;
X			case US_LOGIN:		/* enabled for login, idle */
X				strcpy(shm->Lline,s32);	/* @@@@@@@@@@@ MATCH @@@@@@@@@ */
X				shm->Lline[9] = to_lower(shm->Lline[9]);
X				enddvent();	
X				return;
X		}
X	}
X	/*NOTREACHED*/
X
X}	/* end of choose_line */
X
X/*+-------------------------------------------------------------------------
X	copy_pde_to_lvar(tpde)
X
Xif changing line, close old line and open new one
X--------------------------------------------------------------------------*/
Xvoid
Xcopy_pde_to_lvar(tpde)
Xregister PDE *tpde;
X{
Xint reopen = 0;
Xint lerr;
X
X	if(tpde->tty[0])
X	{
X		if(shm->Lline[0] && shm->Lline[8] && strcmp(tpde->tty,shm->Lline + 8))
X		{
X			reopen = 1;
X			shm->Lmodem_already_init = 0;
X			lclose();
X		}
X		strcpy(shm->Lline,"/dev/tty");
X		strcat(shm->Lline,tpde->tty);
X	}
X	else
X		choose_line(tpde->baud);
X
X	if(shm->Liofd < 0)
X		reopen = 1;
X	strcpy(shm->Llogical,tpde->logical);
X	strcpy(shm->Ldescr,tpde->descr);
X	strcpy(shm->Ltelno,tpde->telno);
X	if(!shm->Ldescr[0])
X		strcpy(shm->Ldescr,shm->Llogical);
X	shm->Lparity = tpde->parity;
X	if(shm->Lbaud != tpde->baud)
X		shm->Lmodem_already_init = 0;
X	shm->Lbaud =tpde->baud;	
X	if(reopen)
X	{
X		if(lerr = lopen())
X		{
X			tcap_curbotleft();
X			pprintf("%s: %s\n",shm->Lline,lopen_err_text(lerr));
X			hangup(HANGUP_LINE_OPEN_ERROR);
X		}
X	}
X	else
X	{
X		lset_baud_rate(1);
X		lset_parity(1);
X	}
X
X}	/* end of copy_pde_to_lvar */
X
X/*+-----------------------------------------------------------------------
X	lookup_logical_telno()
X
XA logical telephone number is either a symbolic identifer
Xor an lcb->telno telephone number.  A symbolic identifer is a string
Xwhose initial character is a letter.
XAn lcb->telno telephone number begins with a numeral.
X
XThis function converts a logical telephone number 
Xto a telephone number (suitable for dialing by a Hayes or
Xcompatible modem).  It is called by command line processing
Xwhen 'ecu logical-name' is specified or in response to
Xa %dial logical-name.  It is not used by the curses directory
Xmanager.
X
XIf the first character of 'shm->Llogical' is a digit, the entire
Xinput string is copied to 'shm->Ltelno'.  If 'shm->Llogical' has a 
Xnon-numeric first character, then the user's home directory is
Xsearched for the file .ecu/phone (~/.ecu/phone). The file is a series
Xof records terminated with a newline.  Each record has two or three
Xfields separated by colons.  The first field is the logical telephone
Xnumber and the second field is the telephone number.  The third
X(optional) field contains a string to further identify the telephone
Xnumber being called.
X
XCASE IS INSIGNIFICANT in logical entry names for this procedure
X
XThe function returns one of the following:
X
X  1		if no error occurs
X  0		if not numeric phone number and logical string not found in file.
X
X------------------------------------------------------------------------*/
Xlookup_logical_telno()
X{
Xregister PDE *tpde;
X
X	if(!pde_list_quan)
X	{
X		if(pde_list_read())
X			return(0);
X	}
X
X/* if literal phone number, return it immediately */
X
X	if(isdigit(shm->Llogical[0]))
X	{
X		strcpy(shm->Ltelno,shm->Llogical);
X		strcpy(shm->Ldescr,shm->Llogical);
X		return(1);
X	}
X
X/* if logical phone number */
X	if(tpde = pde_list_search(shm->Llogical,0))	/* inexact search */
X	{
X		copy_pde_to_lvar(tpde);
X		return(1);
X	}
X
X	shm->Llogical[0] = 0;
X	shm->Lrname[0] = 0;
X	shm->Ltelno[0] = 0;
X	shm->Ldescr[0] = 0;
X	return(0);
X
X}	/* end of lookup_logical_telno */
X
X/* end of ecuphone.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1224223290 'ecuphone.c' &&
chmod 0644 ecuphone.c ||
echo 'restore of ecuphone.c failed'
Wc_c="`wc -c < 'ecuphone.c'`"
test 48468 -eq "$Wc_c" ||
	echo 'ecuphone.c: original size 48468, current size' "$Wc_c"
true || echo 'restore of ecuphrase.c failed'
echo End of part 5, continue with part 6
exit 0
--------------------------------------------------------------------
Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
Hacker Extraordinaire  d' async PADs,  pods,  proteins and protocols

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.