[alt.sources] ecu - SCO XENIX V/{2,3}86 Extended CU part 15/47

wht@tridom.uucp (Warren Tucker) (10/09/89)

---- Cut Here and unpack ----
#!/bin/sh
# this is part 15 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file feval.c continued
#
CurArch=15
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file feval.c"
sed 's/^X//' << 'SHAR_EOF' >> feval.c
X	{
X		free_esd(tesd1);
X		return(eInvalidFunction);
X	}
X
X	erc = 0;
X	itmp=keyword_lookup(feval_str_tbl,s32);
X	switch(itmp)
X	{
X/* LEFT($S0,$I0)   return leftmost $I0 characters of $S0 */
X	case FSleft:
X		erc = strfunc_left(param,tesd1,result_esd);
X		break;
X
X/* RIGHT($S0,$I0)   return rightmost $I0 characters of $S0 */
X	case FSright:
X		erc = strfunc_right(param,tesd1,result_esd);
X		break;
X
X/* MID($S0,$I0,$I1)   return middle $I1 chars of $S0 starting at $I0 */
X	case FSmid:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gstr(param,tesd1))
X			break;
X		if(erc = skip_comma(param))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		int1 = (int)ltmp;
X		if(int1 < 0)
X		{
X			erc = eBadParameter;
X			break;
X		}
X		if(erc = skip_cmd_break(param))
X			break;
X		if(param->pb[param->index] == ')') /* if we find a ')' instead of ... */
X		{                                  /* 2nd int param, default to max */
X			++param->index;
X			int2 = 256;
X		}
X		else
X		{
X			if(erc = skip_comma(param))
X				break;
X			if(erc = gint(param,&ltmp))
X				break;
X			int2 = (int)ltmp;
X			if(int2 < 0)
X			{
X				erc = eBadParameter;
X				break;
X			}
X			if(erc = skip_paren(param,0))
X				break;
X		}
X
X		if(int1 >= tesd1->cb) /* if initial index past end of string */
X			break;
X		itmp = tesd1->cb - int1;
X		itmp = (int2 < itmp) ? int2 : itmp;
X		cptr = tesd1->pb + int1;
X		goto CPTR_ITMP_COMMON;
X
X/* ARGV($I0) */
X	case FSargv:
X		if(!proc_level)
X		{
X			pputs("not executing procedure\n");
X			erc = eFATAL_ALREADY;
X			break;
X		}
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		itmp = (long)pcb_stack[proc_level - 1]->argc; /* arg count */
X		if((int)ltmp > itmp - 1)
X		{
X			if(proctrace)
X			{
X				pprintf("WARNING: %%argc=%d, %%argv(%ld) null\n",
X					itmp,ltmp);
X			}
X			break;
X		}
X		cptr = (pcb_stack[proc_level - 1])->argv[(int)ltmp];
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSdir:
X		cptr = curr_dir;
X		itmp = strlen(curr_dir);
X		goto CPTR_ITMP_COMMON;
X
X	case FSetime:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		cptr = get_elapsed_time(ltmp);
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSerrstr:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		if((int)ltmp >= sys_nerr)
X		{
X			sprintf(s32,"error %d",(int)ltmp);
X			cptr = s32;
X		}
X		else
X			cptr = sys_errlist[(int)ltmp];
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSenvvar:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gstr(param,tesd1))
X			break;
X		if(erc = skip_comma(param))
X			break;
X		if(!(cptr = getenv(tesd1->pb)))
X			break;
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSlogname:
X		if(!(cptr = getlogin()))
X			break;
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSfmodestr:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		cptr = mode_map((int)ltmp,(char *)0);
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FStty:
X		cptr = get_ttyname();
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSrname:
X		if(!Lmodem_off_hook)
X			break;
X		cptr = Llogical;
X		itmp = strlen(Llogical);
X		goto CPTR_ITMP_COMMON;
X
X	case FSrdesc:
X		if(!Lmodem_off_hook)
X			break;
X		cptr = Ldescr;
X		itmp = strlen(Ldescr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSrtel:
X		if(!Lmodem_off_hook)
X			break;
X		cptr = Ltelno;
X		itmp = strlen(Ltelno);
X		goto CPTR_ITMP_COMMON;
X
X	case FSline:
X		if(Liofd < 0)
X			break;
X		cptr = Lline;
X		itmp = strlen(Lline);
X		goto CPTR_ITMP_COMMON;
X
X	case FSmonth:
X	    cptr = &month_name_list[(get_month() - 1) * 3];
X		itmp = 3;
X		goto CPTR_ITMP_COMMON;
X
X	case FSday:
X		cptr = &day_of_week_list[get_day() * 3];
X		itmp = 3;
X		goto CPTR_ITMP_COMMON;
X
XCPTR_ITMP_COMMON:
X		if( itmp > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		memcpy(&result_esd->pb[result_esd->cb],cptr,itmp);
X		result_esd->cb += itmp;
X		break;
X
X	case FSedate:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		if(19 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		epoch_secs_to_str(ltmp,3,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 19;
X		break;
X
X	case FStimes:
X		if(8 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(1,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 8;
X		break;
X
X	case FStime:
X		if(5 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(0,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 5;
X		break;
X
X	case FSdate:
X		if(10 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(5,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 10;
X		break;
X
X	case FScgets:
X		erc = ttygets_esd(result_esd,1,1);
X		break;
X
X	case FScgetc:
X		if(result_esd->cb == result_esd->maxcb)
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		result_esd->pb[result_esd->cb] = ttygetc(0);
X		result_esd->cb++;
X		break;
X
X	case FSchr:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(!ltmp)
X		{
X			pputs("cannot use %chr(0)\n");
X			return(eFATAL_ALREADY);
X		}
X		if(erc = skip_paren(param,0))
X			break;
X		if(result_esd->cb == result_esd->maxcb )
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		result_esd->pb[result_esd->cb] = (char)ltmp;
X		result_esd->cb++;
X		break;
X
X	case FSitos:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		s32[0] = 0;
X		if(!skip_comma(param))
X		{
X			if(erc = get_numeric_zstr(param,s32 + 1,sizeof(s32) - 4))
X				strcpy(s32 + 1,"1");
X			if(((itmp = atoi(s32 + 1)) < 0) ||
X				(itmp > (result_esd->maxcb - result_esd->cb)))
X			{
X				erc = eBufferTooSmall;
X				break;
X			}
X			s32[0] = '%';
X			if(ulindex(param->pb + param->index,"x") == 0)
X			{
X				param->index++;
X				strcat(s32,"lx");
X			}
X			else if(ulindex(param->pb + param->index,"o") == 0)
X			{
X				param->index++;
X				strcat(s32,"lo");
X			}
X			else if(ulindex(param->pb + param->index,"d") == 0)
X			{
X				param->index++;
X				strcat(s32,"ld");
X			}
X			else if(erc)
X				break;
X			else
X				strcat(s32,"ld");
X		}
X		if(erc = skip_paren(param,0))
X			break;
X		sprintf(tesd1->pb,s32[0] ? s32 : "%ld",ltmp);
X		tesd1->cb = strlen(tesd1->pb);
X		if(result_esd->maxcb - result_esd->cb < tesd1->cb)
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		strcpy(&result_esd->pb[result_esd->cb],tesd1->pb);
X		result_esd->cb += tesd1->cb;
X		break;
X
X	default:
X		erc = eInvalidFunction;
X		break;
X	}   /* end of keyword lookup erc switch statement */
X
X	null_terminate_esd(result_esd);
X	free_esd(tesd1);
X	return(erc);
X
X}   /* end of feval_str() */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of feval.c */
SHAR_EOF
echo "File feval.c is complete"
chmod 0644 feval.c || echo "restore of feval.c fails"
echo "x - extracting gint.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > gint.c &&
X/* CHK=0xE9C4 */
X/*+-------------------------------------------------------------------------
X    gint.c - ecu get integer parameter functions
X	Copyright 1989 Warren H. Tucker, III.  All rights reserved.
X
X  Defined functions:
X	gcol_range(param,col1,col2)
X	gint(param,int_returned)
X	gint_base(param,value)
X	gint_constant(param,value)
X	gintop(param,intop)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-03-1989-22:57-wht------------- ecu 2.00 ---------------- */
X/*:06-24-1989-16:53-wht-flush edits --- ecu 1.95 */
X
X#include "ecu.h"
X#include "ecuerror.h"
X#include "esd.h"
X#include "var.h"
X
X#define OP_ADD      1
X#define OP_SUB      2
X#define OP_MUL      3
X#define OP_DIV      4
X#define OP_XOR      5
X#define OP_MOD      6
X#define OP_OR       7
X#define OP_AND      8
X
X#define BASE_DEC	1
X#define BASE_OCT	2
X#define BASE_HEX  	3
X
X
X/*+-------------------------------------------------------------------------
X    gint_constant(param,int_returned) - evaluate integer constant
X--------------------------------------------------------------------------*/
Xint
Xgint_constant(param,value)
XESD *param;
Xlong *value;
X{
Xregister itmp;
Xint base = BASE_DEC;
Xint erc;
Xlong new_value;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X	null_terminate_esd(param);
X
X/* get integer from string */
X	base = BASE_DEC;
X	if((!strncmp(param->pb + param->index,"0x",2)) ||
X		(!strncmp(param->pb + param->index,"0X",2)))
X	{
X		base = BASE_HEX;
X		param->index += 2;
X	}
X	else if(*(param->pb + param->index) == '0')
X		base = BASE_OCT;
X
X	param->old_index = param->index;
X	switch(base)
X	{
X	case BASE_HEX:
X		sscanf(param->pb + param->index,"%lx",&new_value);
X		itmp = param->index + strspn(param->pb + param->index,
X			"0123456789ABCDEFabcdef");
X		erc = eInvalidHexNumber;
X		break;
X	case BASE_DEC:
X		sscanf(param->pb + param->index,"%ld",&new_value);
X		itmp = param->index + strspn(param->pb + param->index,"0123456789");
X		erc = eInvalidDecNumber;
X		break;
X	case BASE_OCT:
X		sscanf(param->pb + param->index,"%lo",&new_value);
X		itmp = param->index + strspn(param->pb + param->index,"01234567");
X		erc = eInvalidOctNumber;
X		break;
X	}
X
X	param->index = itmp;
X	if(isalnum(*(param->pb + itmp)))
X		param->old_index = itmp;
X
X	if(param->old_index != param->index)
X	{
X		*value = new_value;
X		return(0);
X	}
X	return(erc);
X
X}   /* end of gint_constant */
X
X/*+-------------------------------------------------------------------------
X    gint_base(param,value) - evaluate integer constant, variable or function
X--------------------------------------------------------------------------*/
Xint
Xgint_base(param,value)
XESD *param;
Xlong *value;
X{
Xregister erc;
Xlong *varptr;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X
X	switch(param->pb[param->index])		/* look at first character */
X	{
X	case '$':		/* '$i...' variable reference? */
X		if(param->index >= param->cb-2)
X			return(eSyntaxError);
X		param->old_index = ++param->index;
X		if(to_lower(param->pb[param->index++]) != 'i')
X			return(eIllegalVarType);
X		if(erc = get_ivptr(param,&varptr))
X			return(erc);
X		*value = *varptr;	
X		return(0);
X
X	case '%':		/* '%...' function reference? */
X		param->index++;
X		if(erc = feval_int(param,value))
X			return(erc);
X		return(0);
X
X	default:
X		break;
X	}   /* end of switch statement */
X
X/* we did not catch any special cases with the switch statement must
Xbe numeric integer */
X
X	return(gint_constant(param,value));
X
X}   /* end of gint_base() */
X
X/*+-------------------------------------------------------------------------
X    gintop(param,intop) - evaluate integer operator
X--------------------------------------------------------------------------*/
Xint
Xgintop(param,intop)
XESD *param;
Xint *intop;
X{
X	register erc;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X	switch(param->pb[param->index])
X	{
X	case '+':
X		param->index++;
X		*intop = OP_ADD;
X		break;
X
X	case '-':
X		param->index++;
X		*intop = OP_SUB;
X		break;
X
X	case '*':
X		param->index++;
X		*intop = OP_MUL;
X		break;
X
X	case '/':
X		param->index++;
X		*intop = OP_DIV;
X		break;
X
X	case '|':
X		param->index++;
X		*intop = OP_OR;
X		break;
X
X	case '@':
X		param->index++;
X		*intop = OP_MOD;
X		break;
X
X	case '^':
X		param->index++;
X		*intop = OP_XOR;
X		break;
X
X	case '&':
X		param->index++;
X		*intop = OP_AND;
X		break;
X
X	default:
X		return(eInvalidIntOp);
X		break;
X	}   /* end of switch statement */
X
X	return(0);
X
X}   /* end of gintop() */
X
X/*+-------------------------------------------------------------------------
X    gint(param,int_returned) - evaluate integer expression
X--------------------------------------------------------------------------*/
Xint
Xgint(param,int_returned)
XESD *param;
Xlong *int_returned;
X{
Xregister erc;
Xlong int1;
Xlong int_accum = 0;
Xint intop;
X
X	if(erc = gint_base(param,&int1))
X		return(erc);
X	int_accum = int1;
X
X	while((erc = gintop(param,&intop)) == 0)
X	{
X		if(erc = gint_base(param,&int1))
X			return(erc);
X		switch(intop)
X		{
X		case OP_ADD:
X			int_accum += int1;
X			break;
X		case OP_SUB:
X			int_accum -= int1;
X			break;
X		case OP_MUL:
X			int_accum *= int1;
X			break;
X		case OP_DIV:
X			int_accum /= int1;
X			break;
X		case OP_MOD:
X			int_accum %= int1;
X			break;
X		case OP_XOR:
X			(unsigned)int_accum ^= (unsigned)int1;
X			break;
X		case OP_AND:
X			(unsigned)int_accum &= (unsigned)int1;
X			break;
X		case OP_OR:
X			(unsigned)int_accum |= (unsigned)int1;
X			break;
X		default:
X			return(eInvalidIntOp);
X		}
X	}
X	param->index = param->old_index;
X
X	*int_returned = int_accum;
X	return(0);
X}   /* end of gint() */
X
X/*+-------------------------------------------------------------------------
X    col_range(param,col1,col2) - get a column range
X:$i0[-$i1]
Xargument may be integer constant, function or variable, but not expression
X--------------------------------------------------------------------------*/
Xint
Xgcol_range(param,col1,col2)
XESD *param;
Xulong *col1;
Xulong *col2;
X{
X	register erc;
X
X	if(skip_cmd_char(param,':') == 0)
X	{
X		if(erc = gint_base(param,col1))
X			return(erc);
X
X		if(skip_cmd_char(param,'-') == 0)     /* if hyphen found, range */
X		{
X			if(erc = gint_base(param,col2))
X				return(erc);
X		}
X		else
X			*col2 = *col1;		/* otherwise, first and last columns same */
X
X		if(*col1 > *col2)
X		{
X			pputs("Invalid column range: column 1 greater than column 2\n");
X			return(eFATAL_ALREADY);
X		}
X	}
X	else
X		erc = eBadParameter;
X
X	return(erc);
X}   /* end of gcol_range() */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of gint.c */
SHAR_EOF
chmod 0644 gint.c || echo "restore of gint.c fails"
echo "x - extracting gstr.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > gstr.c &&
X/* CHK=0xC476 */
X/*+-------------------------------------------------------------------------
X    gstr.c - ecu get string parameter functions
X	Copyright 1989 Warren H. Tucker, III.  All rights reserved.
X
X  Defined functions:
X	gstr(param,result)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-03-1989-22:57-wht------------- ecu 2.00 ---------------- */
X/*:06-26-1989-23:59-wht-fix bug where svar too long didn't report error */
X/*:06-24-1989-16:53-wht-flush edits --- ecu 1.95 */
X
X#include "ecu.h"
X#include "ecuerror.h"
X#include "esd.h"
X#include "var.h"
X
Xextern int proctrace;
X
X/*+-------------------------------------------------------------------------
X    gstr() - get a string constant, variable, function or expression
X
XExamples:
X
X set $s0='test ... '+%date+' '+%time+%chr(0x0D)+%chr(0x0A)
X hexdump $s0
X0000  74 65 73 74 20 2E 2E 2E 20 30 36 2D 30 39 2D 31 | test ... 06-09-1 |
X0010  39 38 39 20 31 37 3A 31 35 0D 0A                | 989 17:15..      |
X
X set $s0='12345678':1-6+'abc'
X set s0
X$S00 = '234567abc'
X
X--------------------------------------------------------------------------*/
Xint
Xgstr(param,result)
XESD *param;
XESD *result;
X{
Xregister char param_char;
Xregister char *pb;
XESD *tesd;
XESD *svptr;
Xint cb = 0;
Xint segment_index;
Xint next_is_literal = 0;	/* last char was not a backslash */
Xulong itmp1;
Xulong itmp2;
Xulong itmp3;
Xulong itmp4;
Xint erc;
Xint param_index_save;
Xint result_remaining;
Xint in_quoted_string = 0;   /* not currently in quoted string */
Xint end_of_parameter = 0;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X
X	segment_index = 0;			
X	result_remaining = result->maxcb;	/* number we can put into result */
X	param_index_save = param->index;
X
X	if((tesd = make_esd(result_remaining)) == (ESD *)0)
X		return(eNoMemory);
X	pb = tesd->pb;
X
XCONCATENATE:
X	while((param->index < param->cb) && !end_of_parameter)
X	{
X		param_char = param->pb[param->index];
X		if(in_quoted_string)
X		{
X			++param->index;
X			if(next_is_literal)
X			{
X				next_is_literal = 0;
X				switch(param_char)
X				{
X					case 'b' : param_char = 0x08; break;
X					case 'n' : param_char = 0x0A; break;
X					case 'r' : param_char = 0x0D; break;
X					case 't' : param_char = 0x09; break;
X					case '\'': param_char = '\''; break;
X				}
X				if(result_remaining-- == 0)
X				{
X					erc = eBufferTooSmall;
X					goto RETURN;
X				}
X				*(pb + cb++) = param_char;
X			}
X			else if(param_char == '\\')
X				next_is_literal = 1;
X			else if(param_char == '\'')
X				in_quoted_string = 0;
X			else
X			{
X				if(result_remaining-- == 0)
X				{
X					erc = eBufferTooSmall;
X					goto RETURN;
X				}
X				*(pb + cb++) = param_char;
X			}
X		}
X		else /* not in quoted string */
X		{
X			param->old_index = param->index;
X			switch(param_char)
X			{
X			case '\'':      /* apostrophe denotes literal text */
X				++param->index;
X				in_quoted_string = 1;
X				break;
X
X			case '%':
X				++param->index;
X				tesd->cb = cb;
X				if(erc = feval_str(param,tesd))
X					goto RETURN;
X				cb = tesd->cb;
X				result_remaining = (result->maxcb - cb);
X				break;
X
X			case '$':           /* '$Snn' variable reference? */
X				/* must be at least two more character */
X				if(param->index >= param->cb-2)
X				{
X					erc = eSyntaxError;
X					goto RETURN;
X				}
X				param->old_index = ++param->index;
X				if(to_lower(param->pb[param->index++]) != 's' )
X				{
X					erc = eIllegalVarType;
X					goto RETURN;
X				}
X				if(erc = get_svptr(param,&svptr))
X					goto RETURN;
X				if(svptr->cb > (result->maxcb - cb))
X				{
X					erc = eBufferTooSmall;
X					goto RETURN;
X				}
X				else if(svptr->cb)
X				{
X					memcpy(&pb[cb],svptr->pb,svptr->cb);
X					cb += svptr->cb;
X					result_remaining -= svptr->cb;
X				}
X				break;
X
X			case ':':
X/*
Xitmp1 holds col 1 (0-n) of substring operation
Xitmp2 holds col 2 (0-n) of operation adjusted to reflect end of string segment
Xitmp3 holds length of string segment
Xitmp4 holds length of substring segment output by substring operation
X*/
X				if(erc = gcol_range(param,&itmp1,&itmp2))
X					goto RETURN;
X				if((itmp3 = cb - segment_index)
X				    &&
X					(itmp4 = ((itmp2<itmp3)?itmp2:itmp3) - itmp1 + 1))
X				{
X					if(itmp1)
X						memcpy(&pb[segment_index],
X							&pb[segment_index+(int)itmp1],(int)itmp4);
X					cb -= ((int)itmp3 - (int)itmp4);
X				}
X				break;
X
X			case '+':
X				segment_index = cb;
X				++param->index;
X				goto CONCATENATE;
X
X			case ';':
X			case '#':
X				end_of_parameter = 1;
X				break;
X
X			default:
X				null_terminate_esd(result);
X				erc = 0;
X				if((param->index < param->cb) &&
X					isalnum(*(param->pb + param->index)))
X					erc = eSyntaxError;
X				else if(param_index_save == param->index)
X					erc = eBadParameter;
X				end_of_parameter = 1;
X				break;
X			}   /* end of switch (param_char) */
X		}       /* end of else not in quoted string */
X	}           /* end of while(index<cb) */
X
X
XRETURN:
X	if(cb)
X		strncpy(result->pb,pb,cb);
X	result->cb = cb;
X	null_terminate_esd(result);
X	free_esd(tesd);
X	return(erc);
X}   /* end of gqstr */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of qstr.c */
SHAR_EOF
chmod 0644 gstr.c || echo "restore of gstr.c fails"
echo "x - extracting hdbintf.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > hdbintf.c &&
X/* CHK=0x6D2E */
X#define LOG_UNGETTY
X#define LOG_HDBDIAL
X/*+-------------------------------------------------------------------------
X	hdbintf.c - HDB UUCP database and /etc/utmp interface routines
X	Copyright 1989 Warren H. Tucker, III. All Rights Reserved
X
X  Defined functions:
X	enddvent()
X	getdvbaud(baud)
X	getdvent()
X	getdvline(line)
X	hdb_dial()
X	ungetty_get_line()
X	ungetty_return_line()
X	utmp_status(line)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-03-1989-22:57-wht------------- ecu 2.00 ---------------- */
X/*:07-01-1989-13:40-wht-creation */
X
X#include "ecu.h"
X#include "esd.h"
X#include "var.h"
X#include "ecuhangup.h"
X#include "utmpstatus.h"
X#include "ecuungetty.h"
X#include "dvent.h"
X#include "dialer.h"
X#include <errno.h>
X#include <utmp.h>
X
Xextern int errno;
Xextern char kbdintr;		/* current input INTR */
Xextern int interrupt;
Xextern ulong current_colors;
Xextern char *sys_errlist[];
X
Xint there_is_hdb_on_this_machine = 0;
XFILE *fpdv = NULL;
Xchar *Devices_file = "/usr/lib/uucp/Devices";
Xchar *utmp_file = "/etc/utmp";
Xstruct utmp last_utmp;
Xchar *ungetty = "/usr/lib/ecu/ecuungetty";
Xchar ungetty_ttyname[64] = "";
X
X/*+-------------------------------------------------------------------------
X	ungetty_get_line()
X--------------------------------------------------------------------------*/
Xungetty_get_line()
X{
Xint itmp;
Xchar ungetty_log[80];
Xint ungetty_pid;
Xint (*original_sighdlr)();
Xint wait_status;
Xchar bamboozlement[20];
Xchar *bamboozle();
X
X	if(!there_is_hdb_on_this_machine)
X		return(LOPEN_ENABLED);
X
X	strcpy(bamboozlement,bamboozle(getpid()));
X	if((ungetty_pid = fork()) == 0)
X	{
X		execl(ungetty,"ungetty",Lline,bamboozlement,(char *)0);
X		perror("ungetty exec error");
X		ff(se,"\r\n");
X		exit(-1);
X	}
X	original_sighdlr = signal(SIGCLD,SIG_DFL);
X	while(((itmp = wait(&wait_status)) != ungetty_pid) &&
X			(itmp != -1))
X		;
X	signal(SIGCLD,original_sighdlr);
X	switch((wait_status >> 8) & 0xFF)
X	{
X		case UG_NOTENAB:	/* line acquired: not enabled */
X			ungetty_ttyname[0] = 0;
X			break;
X
X		case UG_ENAB:		/* line acquired: need ungetty -r when done */
X#if defined(LOG_UNGETTY)
X			sprintf(ungetty_log,"UNGETTY acquired %s",Lline);
X			ecu_log_event(ungetty_log);
X#endif
X			strcpy(ungetty_ttyname,Lline);
X			break;
X
X		case UG_FAIL:		/* line in use */
X			ungetty_ttyname[0] = 0;
X			return(LOPEN_ENABLED_IN_USE);
X
X		default:
X			sprintf(ungetty_log,"UNGETTY status 0x%04x (%d==%d?)",
X				wait_status,itmp,ungetty_pid);
X			ecu_log_event(ungetty_log);
X			ungetty_ttyname[0] = 0;
X			return(LOPEN_ENABLED);
X	}
X
X	return(0);
X
X}	/* end of ungetty_get_line */
X
X/*+-------------------------------------------------------------------------
X	ungetty_return_line()
X--------------------------------------------------------------------------*/
Xvoid
Xungetty_return_line()
X{
Xint ungetty_pid;
Xint itmp;
Xint (*original_sighdlr)();
Xint wait_status = 0xDEAD;
Xchar ungetty_log[80];
Xchar bamboozlement[20];
Xchar *bamboozle();
X
X	if(!there_is_hdb_on_this_machine)
X		return;
X	if(!ungetty_ttyname[0])
X		return;
X
X	strcpy(bamboozlement,bamboozle(getpid()));
X
X	/* call ungetty to see if we need to switch to dialin */
X	if((ungetty_pid = fork()) == 0)
X	{
X		execl(ungetty,"ungetty","-t",ungetty_ttyname,bamboozlement,(char *)0);
X		perror("ungetty -t exec error");
X		ff(se,"\r\n");
X		exit(-1);
X	}
X	original_sighdlr = signal(SIGCLD,SIG_DFL);
X	while(((itmp = wait(&wait_status)) != ungetty_pid) &&
X			(itmp != -1) )
X		;
X	signal(SIGCLD,original_sighdlr);
X	switch((wait_status >> 8) & 0xFF)
X	{
X		case UG_RESTART:
X			break;
X
X		default:
X			sprintf(ungetty_log,"UNGETTY -t %s status %04x (%d==%d?)",
X				ungetty_ttyname,wait_status,itmp,ungetty_pid);
X			ecu_log_event(ungetty_log);
X			ungetty_ttyname[0] = 0;
X			return;
X	}
X
X	strcpy(bamboozlement,bamboozle(getpid()));
X
X	if((ungetty_pid = fork()) == 0)
X	{
X		execl(ungetty,"ungetty","-r",ungetty_ttyname,bamboozlement,(char *)0);
X		perror("ungetty -r exec error");
X		ff(se,"\r\n");
X		exit(-1);
X	}
X
X	original_sighdlr = signal(SIGCLD,SIG_DFL);
X	while(((itmp = wait(&wait_status)) != ungetty_pid) &&
X			(itmp != -1))
X		;
X	if(wait_status)
X	{
X		sprintf(ungetty_log,"UNGETTY -r %s status 0x%04x (%d==%d?)",
X			ungetty_ttyname,wait_status,itmp,ungetty_pid);
X	}
X	else
X		sprintf(ungetty_log,"UNGETTY returned %s",ungetty_ttyname);
X	ecu_log_event(ungetty_log);
X
X	ungetty_ttyname[0] = 0;
X
X}	/* end of ungetty_return_line */
X
X/*+-------------------------------------------------------------------------
X	utmp_status(line)
X'line' is "/dev/ttyxx"-style
Xreturns US_ value and utmp struct last_utmp;
X--------------------------------------------------------------------------*/
Xint
Xutmp_status(line)
Xchar *line;
X{
Xregister ufd;
Xregister status = US_NOTFOUND;
X
X	if((ufd = open(utmp_file,O_RDONLY,755)) < 0)
X	{
X		curbotleft();
X		perror(utmp_file);
X		hangup(HANGUP_LINE_OPEN_ERROR);
X	}
X
X	while(read(ufd,(char *)&last_utmp,sizeof(last_utmp)) > 0)
X	{
X	    if((ulcmpb(last_utmp.ut_line,line + 5) < 0) &&
X			(!kill(last_utmp.ut_pid,0) || (errno != ESRCH)))
X		{
X			if(!strcmp(last_utmp.ut_user,"LOGIN"))
X				status = US_LOGIN;
X			else if(!strcmp(last_utmp.ut_user,"DIALOUT"))
X				status = US_DIALOUT;
X			else
X				status = US_LOGGEDIN;
X			break;
X		}
X	}
X	close(ufd);
X	return(status);
X
X}	/* end of utmp_status */
X
X/*+-------------------------------------------------------------------------
X	getdvent() - get first or next device entry (a la getpwent)
X--------------------------------------------------------------------------*/
Xstruct dvent *
Xgetdvent()
X{
Xint itmp;
Xchar *cptr;
X#define MAX_DV_TOKENS 9
Xchar *tokens[MAX_DV_TOKENS];
Xstatic struct dvent dve;
Xstatic char dvstr[128];
Xchar *strchr();
X
X	if(!there_is_hdb_on_this_machine)
X		return((struct dvent *)0);
X
X	if(fpdv == NULL)
X	{
X		if((fpdv = fopen(Devices_file,"r")) == NULL)
X			return((struct dvent *)0);
X	}
X
X	while(1)
X	{
X		if(fgets(dvstr,sizeof(dvstr),fpdv) == NULL)
X			return((struct dvent *)0);
X
X		if((dvstr[0] == '#') || (strlen(dvstr) == 1))
X			continue;
X
X		build_arg_array(dvstr,tokens,MAX_DV_TOKENS,&itmp);
X
X		if(itmp > 1)
X			break;
X	}
X
X	dve.type = tokens[0];
X	dve.line = tokens[1];
X	dve.dialer = tokens[2];
X	if(!strcmp(tokens[3],"Any"))
X	{
X		dve.low_baud = 1;
X		dve.high_baud = 100000L;
X	}
X	else
X	{
X		dve.low_baud = atoi(tokens[3]);
X		if(!(cptr = strchr(tokens[3],'-')))
X			dve.high_baud = dve.low_baud;
X		else
X			dve.high_baud = atoi(cptr + 1);
X	}
X	dve.dialprog = tokens[4];
X	return(&dve);
X
X}	/* end of getdvent */
X
X/*+-------------------------------------------------------------------------
X	getdvbaud(baud) - get device entry matching baud rate
X--------------------------------------------------------------------------*/
Xstruct dvent *
Xgetdvbaud(baud)
Xuint baud;
X{
Xstruct dvent *dve;
X
X	while(1)
X	{
X		if((dve = getdvent()) == (struct dvent *)0)
X			return(dve);
X		if((dve->low_baud <= baud) && (baud <= dve->high_baud))
X			return(dve);
X	}
X	/*NOTREACHED*/
X
X}	/* end of getdvbaud */
X
X/*+-------------------------------------------------------------------------
X	getdvline(line) - get device entry matching line
Xcalling argument 'line's is string AFTER "/dev/tty"
X--------------------------------------------------------------------------*/
Xstruct dvent *
Xgetdvline(line)
Xchar *line;
X{
Xstruct dvent *dve;
X
X	while(1)
X	{
X		if((dve = getdvent()) == (struct dvent *)0)
X			return(dve);
X		if(!strcmp(dve->line + 3,line))
X			return(dve);
X	}
X	/*NOTREACHED*/
X
X}	/* end of getdvline */
X
X/*+-------------------------------------------------------------------------
X	enddvent()
X--------------------------------------------------------------------------*/
Xvoid
Xenddvent()
X{
X	if(fpdv != NULL)
X	{
X		fclose(fpdv);
X		fpdv = NULL;
X	}
X}	/* end of enddvent */
X
X/*+-------------------------------------------------------------------------
X	hdb_dial_error(errcode)
X
Xalso sets iv[0] to dial command status
X--------------------------------------------------------------------------*/
Xchar *
Xhdb_dial_error_text(errcode)
Xint errcode;
X{
X
X	iv[0] = 1;
X	switch(errcode & 0x7F)
X	{
X		case RCE_INUSE:
X			return("!Line in use");
X		case RCE_SIG:
X			iv[0] = 2;
X			return("!Interrupted");
X		case RCE_ARGS:
X			return("!Invalid arguments");
X		case RCE_PHNO:
X			return("!Invalid phone number");
X		case RCE_SPEED:
X			return("!Bad baud rate");
X		case RCE_OPEN:
X			return("!Line open error");
X		case RCE_IOCTL:
X			return("!Ioctl error");
X		case RCE_TIMOUT:
X			iv[0] = 3;
X			return("!Modem Error");
X		case RCE_NOTONE:
X			return("NO DIAL TONE");
X		case RCE_BUSY:
X			return("BUSY");
X		case RCE_NOCARR:
X			return("NO CARRIER");
X		case RCE_ANSWER:
X			return("NO ANSWER");
X		default:
X			
X		case RCE_NULL:
X			return("unknown error\n");
X	}
X}	/* end of hdb_dial_error */
X
X/*+-------------------------------------------------------------------------
X	hdb_dial(presult) - dial with uucp dialer if we can
X
Xreturn 0 if connected
X       1 if dial failed
X       2 if interrupted
X       3 if modem error
X       4 if use ecu hayes dialer
SHAR_EOF
echo "End of part 15"
echo "File hdbintf.c is continued in part 16"
echo "16" > s2_seq_.tmp
exit 0
-- 
-------------------------------------------------------------------
Warren Tucker, Tridom Corporation       ...!gatech!emory!tridom!wht 
Ker-au'-lo-phon.  An 8-foot partial flue-stop, having metal pipes
surmounted by adjustable rings, and with a hole bored near the top
of each pipe, producing a soft and "reedy" tone.