1/* exp_clib.c - top-level functions in the expect C library, libexpect.a
2
3Written by: Don Libes, libes@cme.nist.gov, NIST, 12/3/90
4
5Design and implementation of this program was paid for by U.S. tax
6dollars.  Therefore it is public domain.  However, the author and NIST
7would appreciate credit if this program or parts of it are used.
8*/
9
10#include "expect_cf.h"
11#include <stdio.h>
12#include <setjmp.h>
13#ifdef HAVE_INTTYPES_H
14#  include <inttypes.h>
15#endif
16#include <sys/types.h>
17#include <sys/ioctl.h>
18
19#ifdef TIME_WITH_SYS_TIME
20# include <sys/time.h>
21# include <time.h>
22#else
23# if HAVE_SYS_TIME_H
24#  include <sys/time.h>
25# else
26#  include <time.h>
27# endif
28#endif
29
30#ifdef CRAY
31# ifndef TCSETCTTY
32#  if defined(HAVE_TERMIOS)
33#   include <termios.h>
34#  else
35#   include <termio.h>
36#  endif
37# endif
38#endif
39
40#ifdef HAVE_SYS_FCNTL_H
41#  include <sys/fcntl.h>
42#else
43#  include <fcntl.h>
44#endif
45
46#ifdef HAVE_STRREDIR_H
47#include <sys/strredir.h>
48# ifdef SRIOCSREDIR
49#  undef TIOCCONS
50# endif
51#endif
52
53#include <signal.h>
54/*#include <memory.h> - deprecated - ANSI C moves them into string.h */
55#include "string.h"
56
57#include <errno.h>
58
59#ifdef NO_STDLIB_H
60
61/*
62 * Tcl's compat/stdlib.h
63 */
64
65/*
66 * stdlib.h --
67 *
68 *	Declares facilities exported by the "stdlib" portion of
69 *	the C library.  This file isn't complete in the ANSI-C
70 *	sense;  it only declares things that are needed by Tcl.
71 *	This file is needed even on many systems with their own
72 *	stdlib.h (e.g. SunOS) because not all stdlib.h files
73 *	declare all the procedures needed here (such as strtod).
74 *
75 * Copyright (c) 1991 The Regents of the University of California.
76 * Copyright (c) 1994 Sun Microsystems, Inc.
77 *
78 * See the file "license.terms" for information on usage and redistribution
79 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
80 *
81 * RCS: @(#) $Id: exp_clib.c,v 5.39 2010/08/31 22:20:27 andreas_kupries Exp $
82 */
83
84#ifndef _STDLIB
85#define _STDLIB
86
87extern void		abort _ANSI_ARGS_((void));
88extern double		atof _ANSI_ARGS_((CONST char *string));
89extern int		atoi _ANSI_ARGS_((CONST char *string));
90extern long		atol _ANSI_ARGS_((CONST char *string));
91extern char *		calloc _ANSI_ARGS_((unsigned int numElements,
92			    unsigned int size));
93extern void		exit _ANSI_ARGS_((int status));
94extern int		free _ANSI_ARGS_((char *blockPtr));
95extern char *		getenv _ANSI_ARGS_((CONST char *name));
96extern char *		malloc _ANSI_ARGS_((unsigned int numBytes));
97extern void		qsort _ANSI_ARGS_((VOID *base, int n, int size,
98			    int (*compar)(CONST VOID *element1, CONST VOID
99			    *element2)));
100extern char *		realloc _ANSI_ARGS_((char *ptr, unsigned int numBytes));
101extern double		strtod _ANSI_ARGS_((CONST char *string, char **endPtr));
102extern long		strtol _ANSI_ARGS_((CONST char *string, char **endPtr,
103			    int base));
104extern unsigned long	strtoul _ANSI_ARGS_((CONST char *string,
105			    char **endPtr, int base));
106
107#endif /* _STDLIB */
108
109/*
110 * end of Tcl's compat/stdlib.h
111 */
112
113#else
114#include <stdlib.h>		/* for malloc */
115#endif
116
117#include <tcl.h>
118#include "expect.h"
119#define TclRegError exp_TclRegError
120
121/*
122 * regexp code - from tcl8.0.4/generic/regexp.c
123 */
124
125/*
126 * TclRegComp and TclRegExec -- TclRegSub is elsewhere
127 *
128 *	Copyright (c) 1986 by University of Toronto.
129 *	Written by Henry Spencer.  Not derived from licensed software.
130 *
131 *	Permission is granted to anyone to use this software for any
132 *	purpose on any computer system, and to redistribute it freely,
133 *	subject to the following restrictions:
134 *
135 *	1. The author is not responsible for the consequences of use of
136 *		this software, no matter how awful, even if they arise
137 *		from defects in it.
138 *
139 *	2. The origin of this software must not be misrepresented, either
140 *		by explicit claim or by omission.
141 *
142 *	3. Altered versions must be plainly marked as such, and must not
143 *		be misrepresented as being the original software.
144 *
145 * Beware that some of this code is subtly aware of the way operator
146 * precedence is structured in regular expressions.  Serious changes in
147 * regular-expression syntax might require a total rethink.
148 *
149 * *** NOTE: this code has been altered slightly for use in Tcl: ***
150 * *** 1. Use ckalloc and ckfree instead of  malloc and free.	 ***
151 * *** 2. Add extra argument to regexp to specify the real	 ***
152 * ***    start of the string separately from the start of the	 ***
153 * ***    current search. This is needed to search for multiple	 ***
154 * ***    matches within a string.				 ***
155 * *** 3. Names have been changed, e.g. from regcomp to		 ***
156 * ***    TclRegComp, to avoid clashes with other 		 ***
157 * ***    regexp implementations used by applications. 		 ***
158 * *** 4. Added errMsg declaration and TclRegError procedure	 ***
159 * *** 5. Various lint-like things, such as casting arguments	 ***
160 * ***	  in procedure calls.					 ***
161 *
162 * *** NOTE: This code has been altered for use in MT-Sturdy Tcl ***
163 * *** 1. All use of static variables has been changed to access ***
164 * ***    fields of a structure.                                 ***
165 * *** 2. This in addition to changes to TclRegError makes the   ***
166 * ***    code multi-thread safe.                                ***
167 *
168 * RCS: @(#) $Id: exp_clib.c,v 5.39 2010/08/31 22:20:27 andreas_kupries Exp $
169 */
170
171#if 0
172#include "tclInt.h"
173#include "tclPort.h"
174#endif
175
176/*
177 * The variable below is set to NULL before invoking regexp functions
178 * and checked after those functions.  If an error occurred then TclRegError
179 * will set the variable to point to a (static) error message.  This
180 * mechanism unfortunately does not support multi-threading, but the
181 * procedures TclRegError and TclGetRegError can be modified to use
182 * thread-specific storage for the variable and thereby make the code
183 * thread-safe.
184 */
185
186static char *errMsg = NULL;
187
188/*
189 * The "internal use only" fields in regexp.h are present to pass info from
190 * compile to execute that permits the execute phase to run lots faster on
191 * simple cases.  They are:
192 *
193 * regstart	char that must begin a match; '\0' if none obvious
194 * reganch	is the match anchored (at beginning-of-line only)?
195 * regmust	string (pointer into program) that match must include, or NULL
196 * regmlen	length of regmust string
197 *
198 * Regstart and reganch permit very fast decisions on suitable starting points
199 * for a match, cutting down the work a lot.  Regmust permits fast rejection
200 * of lines that cannot possibly match.  The regmust tests are costly enough
201 * that TclRegComp() supplies a regmust only if the r.e. contains something
202 * potentially expensive (at present, the only such thing detected is * or +
203 * at the start of the r.e., which can involve a lot of backup).  Regmlen is
204 * supplied because the test in TclRegExec() needs it and TclRegComp() is
205 * computing it anyway.
206 */
207
208/*
209 * Structure for regexp "program".  This is essentially a linear encoding
210 * of a nondeterministic finite-state machine (aka syntax charts or
211 * "railroad normal form" in parsing technology).  Each node is an opcode
212 * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
213 * all nodes except BRANCH implement concatenation; a "next" pointer with
214 * a BRANCH on both ends of it is connecting two alternatives.  (Here we
215 * have one of the subtle syntax dependencies:  an individual BRANCH (as
216 * opposed to a collection of them) is never concatenated with anything
217 * because of operator precedence.)  The operand of some types of node is
218 * a literal string; for others, it is a node leading into a sub-FSM.  In
219 * particular, the operand of a BRANCH node is the first node of the branch.
220 * (NB this is *not* a tree structure:  the tail of the branch connects
221 * to the thing following the set of BRANCHes.)  The opcodes are:
222 */
223
224/* definition	number	opnd?	meaning */
225#define	END	0	/* no	End of program. */
226#define	BOL	1	/* no	Match "" at beginning of line. */
227#define	EOL	2	/* no	Match "" at end of line. */
228#define	ANY	3	/* no	Match any one character. */
229#define	ANYOF	4	/* str	Match any character in this string. */
230#define	ANYBUT	5	/* str	Match any character not in this string. */
231#define	BRANCH	6	/* node	Match this alternative, or the next... */
232#define	BACK	7	/* no	Match "", "next" ptr points backward. */
233#define	EXACTLY	8	/* str	Match this string. */
234#define	NOTHING	9	/* no	Match empty string. */
235#define	STAR	10	/* node	Match this (simple) thing 0 or more times. */
236#define	PLUS	11	/* node	Match this (simple) thing 1 or more times. */
237#define	OPEN	20	/* no	Mark this point in input as start of #n. */
238			/*	OPEN+1 is number 1, etc. */
239#define	CLOSE	(OPEN+NSUBEXP)	/* no	Analogous to OPEN. */
240
241/*
242 * Opcode notes:
243 *
244 * BRANCH	The set of branches constituting a single choice are hooked
245 *		together with their "next" pointers, since precedence prevents
246 *		anything being concatenated to any individual branch.  The
247 *		"next" pointer of the last BRANCH in a choice points to the
248 *		thing following the whole choice.  This is also where the
249 *		final "next" pointer of each individual branch points; each
250 *		branch starts with the operand node of a BRANCH node.
251 *
252 * BACK		Normal "next" pointers all implicitly point forward; BACK
253 *		exists to make loop structures possible.
254 *
255 * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
256 *		BRANCH structures using BACK.  Simple cases (one character
257 *		per match) are implemented with STAR and PLUS for speed
258 *		and to minimize recursive plunges.
259 *
260 * OPEN,CLOSE	...are numbered at compile time.
261 */
262
263/*
264 * A node is one char of opcode followed by two chars of "next" pointer.
265 * "Next" pointers are stored as two 8-bit pieces, high order first.  The
266 * value is a positive offset from the opcode of the node containing it.
267 * An operand, if any, simply follows the node.  (Note that much of the
268 * code generation knows about this implicit relationship.)
269 *
270 * Using two bytes for the "next" pointer is vast overkill for most things,
271 * but allows patterns to get big without disasters.
272 */
273#define	OP(p)	(*(p))
274#define	NEXT(p)	(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
275#define	OPERAND(p)	((p) + 3)
276
277/*
278 * See regmagic.h for one further detail of program structure.
279 */
280
281
282/*
283 * Utility definitions.
284 */
285#ifndef CHARBITS
286#define	UCHARAT(p)	((int)*(unsigned char *)(p))
287#else
288#define	UCHARAT(p)	((int)*(p)&CHARBITS)
289#endif
290
291#define	FAIL(m)	{ TclRegError(m); return(NULL); }
292#define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
293#define	META	"^$.[()|?+*\\"
294
295/*
296 * Flags to be passed up and down.
297 */
298#define	HASWIDTH	01	/* Known never to match null string. */
299#define	SIMPLE		02	/* Simple enough to be STAR/PLUS operand. */
300#define	SPSTART		04	/* Starts with * or +. */
301#define	WORST		0	/* Worst case. */
302
303/*
304 * Global work variables for TclRegComp().
305 */
306struct regcomp_state  {
307    char *regparse;		/* Input-scan pointer. */
308    int regnpar;		/* () count. */
309    char *regcode;		/* Code-emit pointer; &regdummy = don't. */
310    long regsize;		/* Code size. */
311};
312
313static char regdummy;
314
315/*
316 * The first byte of the regexp internal "program" is actually this magic
317 * number; the start node begins in the second byte.
318 */
319#define	MAGIC	0234
320
321
322/*
323 * Forward declarations for TclRegComp()'s friends.
324 */
325
326static char *		reg _ANSI_ARGS_((int paren, int *flagp,
327			    struct regcomp_state *rcstate));
328static char *		regatom _ANSI_ARGS_((int *flagp,
329			    struct regcomp_state *rcstate));
330static char *		regbranch _ANSI_ARGS_((int *flagp,
331			    struct regcomp_state *rcstate));
332static void		regc _ANSI_ARGS_((int b,
333			    struct regcomp_state *rcstate));
334static void		reginsert _ANSI_ARGS_((int op, char *opnd,
335			    struct regcomp_state *rcstate));
336static char *		regnext _ANSI_ARGS_((char *p));
337static char *		regnode _ANSI_ARGS_((int op,
338			    struct regcomp_state *rcstate));
339static void 		regoptail _ANSI_ARGS_((char *p, char *val));
340static char *		regpiece _ANSI_ARGS_((int *flagp,
341			    struct regcomp_state *rcstate));
342static void 		regtail _ANSI_ARGS_((char *p, char *val));
343
344#ifdef STRCSPN
345static int strcspn _ANSI_ARGS_((char *s1, char *s2));
346#endif
347
348/*
349 - TclRegComp - compile a regular expression into internal code
350 *
351 * We can't allocate space until we know how big the compiled form will be,
352 * but we can't compile it (and thus know how big it is) until we've got a
353 * place to put the code.  So we cheat:  we compile it twice, once with code
354 * generation turned off and size counting turned on, and once "for real".
355 * This also means that we don't allocate space until we are sure that the
356 * thing really will compile successfully, and we never have to move the
357 * code and thus invalidate pointers into it.  (Note that it has to be in
358 * one piece because free() must be able to free it all.)
359 *
360 * Beware that the optimization-preparation code in here knows about some
361 * of the structure of the compiled regexp.
362 */
363regexp *
364TclRegComp(exp)
365char *exp;
366{
367	register regexp *r;
368	register char *scan;
369	register char *longest;
370	register int len;
371	int flags;
372	struct regcomp_state state;
373	struct regcomp_state *rcstate= &state;
374
375	if (exp == NULL)
376		FAIL("NULL argument");
377
378	/* First pass: determine size, legality. */
379	rcstate->regparse = exp;
380	rcstate->regnpar = 1;
381	rcstate->regsize = 0L;
382	rcstate->regcode = &regdummy;
383	regc(MAGIC, rcstate);
384	if (reg(0, &flags, rcstate) == NULL)
385		return(NULL);
386
387	/* Small enough for pointer-storage convention? */
388	if (rcstate->regsize >= 32767L)		/* Probably could be 65535L. */
389		FAIL("regexp too big");
390
391	/* Allocate space. */
392	r = (regexp *)ckalloc(sizeof(regexp) + (unsigned)rcstate->regsize);
393	if (r == NULL)
394		FAIL("out of space");
395
396	/* Second pass: emit code. */
397	rcstate->regparse = exp;
398	rcstate->regnpar = 1;
399	rcstate->regcode = r->program;
400	regc(MAGIC, rcstate);
401	if (reg(0, &flags, rcstate) == NULL) {
402	  ckfree ((char*) r);
403	  return(NULL);
404	}
405
406	/* Dig out information for optimizations. */
407	r->regstart = '\0';	/* Worst-case defaults. */
408	r->reganch = 0;
409	r->regmust = NULL;
410	r->regmlen = 0;
411	scan = r->program+1;			/* First BRANCH. */
412	if (OP(regnext(scan)) == END) {		/* Only one top-level choice. */
413		scan = OPERAND(scan);
414
415		/* Starting-point info. */
416		if (OP(scan) == EXACTLY)
417			r->regstart = *OPERAND(scan);
418		else if (OP(scan) == BOL)
419			r->reganch++;
420
421		/*
422		 * If there's something expensive in the r.e., find the
423		 * longest literal string that must appear and make it the
424		 * regmust.  Resolve ties in favor of later strings, since
425		 * the regstart check works with the beginning of the r.e.
426		 * and avoiding duplication strengthens checking.  Not a
427		 * strong reason, but sufficient in the absence of others.
428		 */
429		if (flags&SPSTART) {
430			longest = NULL;
431			len = 0;
432			for (; scan != NULL; scan = regnext(scan))
433				if (OP(scan) == EXACTLY && ((int) strlen(OPERAND(scan))) >= len) {
434					longest = OPERAND(scan);
435					len = strlen(OPERAND(scan));
436				}
437			r->regmust = longest;
438			r->regmlen = len;
439		}
440	}
441
442	return(r);
443}
444
445/*
446 - reg - regular expression, i.e. main body or parenthesized thing
447 *
448 * Caller must absorb opening parenthesis.
449 *
450 * Combining parenthesis handling with the base level of regular expression
451 * is a trifle forced, but the need to tie the tails of the branches to what
452 * follows makes it hard to avoid.
453 */
454static char *
455reg(paren, flagp, rcstate)
456int paren;			/* Parenthesized? */
457int *flagp;
458struct regcomp_state *rcstate;
459{
460	register char *ret;
461	register char *br;
462	register char *ender;
463	register int parno = 0;
464	int flags;
465
466	*flagp = HASWIDTH;	/* Tentatively. */
467
468	/* Make an OPEN node, if parenthesized. */
469	if (paren) {
470		if (rcstate->regnpar >= NSUBEXP)
471			FAIL("too many ()");
472		parno = rcstate->regnpar;
473		rcstate->regnpar++;
474		ret = regnode(OPEN+parno,rcstate);
475	} else
476		ret = NULL;
477
478	/* Pick up the branches, linking them together. */
479	br = regbranch(&flags,rcstate);
480	if (br == NULL)
481		return(NULL);
482	if (ret != NULL)
483		regtail(ret, br);	/* OPEN -> first. */
484	else
485		ret = br;
486	if (!(flags&HASWIDTH))
487		*flagp &= ~HASWIDTH;
488	*flagp |= flags&SPSTART;
489	while (*rcstate->regparse == '|') {
490		rcstate->regparse++;
491		br = regbranch(&flags,rcstate);
492		if (br == NULL)
493			return(NULL);
494		regtail(ret, br);	/* BRANCH -> BRANCH. */
495		if (!(flags&HASWIDTH))
496			*flagp &= ~HASWIDTH;
497		*flagp |= flags&SPSTART;
498	}
499
500	/* Make a closing node, and hook it on the end. */
501	ender = regnode((paren) ? CLOSE+parno : END,rcstate);
502	regtail(ret, ender);
503
504	/* Hook the tails of the branches to the closing node. */
505	for (br = ret; br != NULL; br = regnext(br))
506		regoptail(br, ender);
507
508	/* Check for proper termination. */
509	if (paren && *rcstate->regparse++ != ')') {
510		FAIL("unmatched ()");
511	} else if (!paren && *rcstate->regparse != '\0') {
512		if (*rcstate->regparse == ')') {
513			FAIL("unmatched ()");
514		} else
515			FAIL("junk on end");	/* "Can't happen". */
516		/* NOTREACHED */
517	}
518
519	return(ret);
520}
521
522/*
523 - regbranch - one alternative of an | operator
524 *
525 * Implements the concatenation operator.
526 */
527static char *
528regbranch(flagp, rcstate)
529int *flagp;
530struct regcomp_state *rcstate;
531{
532	register char *ret;
533	register char *chain;
534	register char *latest;
535	int flags;
536
537	*flagp = WORST;		/* Tentatively. */
538
539	ret = regnode(BRANCH,rcstate);
540	chain = NULL;
541	while (*rcstate->regparse != '\0' && *rcstate->regparse != '|' &&
542				*rcstate->regparse != ')') {
543		latest = regpiece(&flags, rcstate);
544		if (latest == NULL)
545			return(NULL);
546		*flagp |= flags&HASWIDTH;
547		if (chain == NULL)	/* First piece. */
548			*flagp |= flags&SPSTART;
549		else
550			regtail(chain, latest);
551		chain = latest;
552	}
553	if (chain == NULL)	/* Loop ran zero times. */
554		(void) regnode(NOTHING,rcstate);
555
556	return(ret);
557}
558
559/*
560 - regpiece - something followed by possible [*+?]
561 *
562 * Note that the branching code sequences used for ? and the general cases
563 * of * and + are somewhat optimized:  they use the same NOTHING node as
564 * both the endmarker for their branch list and the body of the last branch.
565 * It might seem that this node could be dispensed with entirely, but the
566 * endmarker role is not redundant.
567 */
568static char *
569regpiece(flagp, rcstate)
570int *flagp;
571struct regcomp_state *rcstate;
572{
573	register char *ret;
574	register char op;
575	register char *next;
576	int flags;
577
578	ret = regatom(&flags,rcstate);
579	if (ret == NULL)
580		return(NULL);
581
582	op = *rcstate->regparse;
583	if (!ISMULT(op)) {
584		*flagp = flags;
585		return(ret);
586	}
587
588	if (!(flags&HASWIDTH) && op != '?')
589		FAIL("*+ operand could be empty");
590	*flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
591
592	if (op == '*' && (flags&SIMPLE))
593		reginsert(STAR, ret, rcstate);
594	else if (op == '*') {
595		/* Emit x* as (x&|), where & means "self". */
596		reginsert(BRANCH, ret, rcstate);			/* Either x */
597		regoptail(ret, regnode(BACK,rcstate));		/* and loop */
598		regoptail(ret, ret);			/* back */
599		regtail(ret, regnode(BRANCH,rcstate));		/* or */
600		regtail(ret, regnode(NOTHING,rcstate));		/* null. */
601	} else if (op == '+' && (flags&SIMPLE))
602		reginsert(PLUS, ret, rcstate);
603	else if (op == '+') {
604		/* Emit x+ as x(&|), where & means "self". */
605		next = regnode(BRANCH,rcstate);			/* Either */
606		regtail(ret, next);
607		regtail(regnode(BACK,rcstate), ret);		/* loop back */
608		regtail(next, regnode(BRANCH,rcstate));		/* or */
609		regtail(ret, regnode(NOTHING,rcstate));		/* null. */
610	} else if (op == '?') {
611		/* Emit x? as (x|) */
612		reginsert(BRANCH, ret, rcstate);			/* Either x */
613		regtail(ret, regnode(BRANCH,rcstate));		/* or */
614		next = regnode(NOTHING,rcstate);		/* null. */
615		regtail(ret, next);
616		regoptail(ret, next);
617	}
618	rcstate->regparse++;
619	if (ISMULT(*rcstate->regparse))
620		FAIL("nested *?+");
621
622	return(ret);
623}
624
625/*
626 - regatom - the lowest level
627 *
628 * Optimization:  gobbles an entire sequence of ordinary characters so that
629 * it can turn them into a single node, which is smaller to store and
630 * faster to run.  Backslashed characters are exceptions, each becoming a
631 * separate node; the code is simpler that way and it's not worth fixing.
632 */
633static char *
634regatom(flagp, rcstate)
635int *flagp;
636struct regcomp_state *rcstate;
637{
638	register char *ret;
639	int flags;
640
641	*flagp = WORST;		/* Tentatively. */
642
643	switch (*rcstate->regparse++) {
644	case '^':
645		ret = regnode(BOL,rcstate);
646		break;
647	case '$':
648		ret = regnode(EOL,rcstate);
649		break;
650	case '.':
651		ret = regnode(ANY,rcstate);
652		*flagp |= HASWIDTH|SIMPLE;
653		break;
654	case '[': {
655			register int clss;
656			register int classend;
657
658			if (*rcstate->regparse == '^') {	/* Complement of range. */
659				ret = regnode(ANYBUT,rcstate);
660				rcstate->regparse++;
661			} else
662				ret = regnode(ANYOF,rcstate);
663			if (*rcstate->regparse == ']' || *rcstate->regparse == '-')
664				regc(*rcstate->regparse++,rcstate);
665			while (*rcstate->regparse != '\0' && *rcstate->regparse != ']') {
666				if (*rcstate->regparse == '-') {
667					rcstate->regparse++;
668					if (*rcstate->regparse == ']' || *rcstate->regparse == '\0')
669						regc('-',rcstate);
670					else {
671						clss = UCHARAT(rcstate->regparse-2)+1;
672						classend = UCHARAT(rcstate->regparse);
673						if (clss > classend+1)
674							FAIL("invalid [] range");
675						for (; clss <= classend; clss++)
676							regc((char)clss,rcstate);
677						rcstate->regparse++;
678					}
679				} else
680					regc(*rcstate->regparse++,rcstate);
681			}
682			regc('\0',rcstate);
683			if (*rcstate->regparse != ']')
684				FAIL("unmatched []");
685			rcstate->regparse++;
686			*flagp |= HASWIDTH|SIMPLE;
687		}
688		break;
689	case '(':
690		ret = reg(1, &flags, rcstate);
691		if (ret == NULL)
692			return(NULL);
693		*flagp |= flags&(HASWIDTH|SPSTART);
694		break;
695	case '\0':
696	case '|':
697	case ')':
698		FAIL("internal urp");	/* Supposed to be caught earlier. */
699		/* NOTREACHED */
700	case '?':
701	case '+':
702	case '*':
703		FAIL("?+* follows nothing");
704		/* NOTREACHED */
705	case '\\':
706		if (*rcstate->regparse == '\0')
707			FAIL("trailing \\");
708		ret = regnode(EXACTLY,rcstate);
709		regc(*rcstate->regparse++,rcstate);
710		regc('\0',rcstate);
711		*flagp |= HASWIDTH|SIMPLE;
712		break;
713	default: {
714			register int len;
715			register char ender;
716
717			rcstate->regparse--;
718			len = strcspn(rcstate->regparse, META);
719			if (len <= 0)
720				FAIL("internal disaster");
721			ender = *(rcstate->regparse+len);
722			if (len > 1 && ISMULT(ender))
723				len--;		/* Back off clear of ?+* operand. */
724			*flagp |= HASWIDTH;
725			if (len == 1)
726				*flagp |= SIMPLE;
727			ret = regnode(EXACTLY,rcstate);
728			while (len > 0) {
729				regc(*rcstate->regparse++,rcstate);
730				len--;
731			}
732			regc('\0',rcstate);
733		}
734		break;
735	}
736
737	return(ret);
738}
739
740/*
741 - regnode - emit a node
742 */
743static char *			/* Location. */
744regnode(op, rcstate)
745int op;
746struct regcomp_state *rcstate;
747{
748	register char *ret;
749	register char *ptr;
750
751	ret = rcstate->regcode;
752	if (ret == &regdummy) {
753		rcstate->regsize += 3;
754		return(ret);
755	}
756
757	ptr = ret;
758	*ptr++ = (char)op;
759	*ptr++ = '\0';		/* Null "next" pointer. */
760	*ptr++ = '\0';
761	rcstate->regcode = ptr;
762
763	return(ret);
764}
765
766/*
767 - regc - emit (if appropriate) a byte of code
768 */
769static void
770regc(b, rcstate)
771int b;
772struct regcomp_state *rcstate;
773{
774	if (rcstate->regcode != &regdummy)
775		*rcstate->regcode++ = (char)b;
776	else
777		rcstate->regsize++;
778}
779
780/*
781 - reginsert - insert an operator in front of already-emitted operand
782 *
783 * Means relocating the operand.
784 */
785static void
786reginsert(op, opnd, rcstate)
787int op;
788char *opnd;
789struct regcomp_state *rcstate;
790{
791	register char *src;
792	register char *dst;
793	register char *place;
794
795	if (rcstate->regcode == &regdummy) {
796		rcstate->regsize += 3;
797		return;
798	}
799
800	src = rcstate->regcode;
801	rcstate->regcode += 3;
802	dst = rcstate->regcode;
803	while (src > opnd)
804		*--dst = *--src;
805
806	place = opnd;		/* Op node, where operand used to be. */
807	*place++ = (char)op;
808	*place++ = '\0';
809	*place = '\0';
810}
811
812/*
813 - regtail - set the next-pointer at the end of a node chain
814 */
815static void
816regtail(p, val)
817char *p;
818char *val;
819{
820	register char *scan;
821	register char *temp;
822	register int offset;
823
824	if (p == &regdummy)
825		return;
826
827	/* Find last node. */
828	scan = p;
829	for (;;) {
830		temp = regnext(scan);
831		if (temp == NULL)
832			break;
833		scan = temp;
834	}
835
836	if (OP(scan) == BACK)
837		offset = scan - val;
838	else
839		offset = val - scan;
840	*(scan+1) = (char)((offset>>8)&0377);
841	*(scan+2) = (char)(offset&0377);
842}
843
844/*
845 - regoptail - regtail on operand of first argument; nop if operandless
846 */
847static void
848regoptail(p, val)
849char *p;
850char *val;
851{
852	/* "Operandless" and "op != BRANCH" are synonymous in practice. */
853	if (p == NULL || p == &regdummy || OP(p) != BRANCH)
854		return;
855	regtail(OPERAND(p), val);
856}
857
858/*
859 * TclRegExec and friends
860 */
861
862/*
863 * Global work variables for TclRegExec().
864 */
865struct regexec_state  {
866    char *reginput;		/* String-input pointer. */
867    char *regbol;		/* Beginning of input, for ^ check. */
868    char **regstartp;	/* Pointer to startp array. */
869    char **regendp;		/* Ditto for endp. */
870};
871
872/*
873 * Forwards.
874 */
875static int 		regtry _ANSI_ARGS_((regexp *prog, char *string,
876			    struct regexec_state *restate));
877static int 		regmatch _ANSI_ARGS_((char *prog,
878			    struct regexec_state *restate));
879static int 		regrepeat _ANSI_ARGS_((char *p,
880			    struct regexec_state *restate));
881
882#ifdef DEBUG
883int regnarrate = 0;
884void regdump _ANSI_ARGS_((regexp *r));
885static char *regprop _ANSI_ARGS_((char *op));
886#endif
887
888/*
889 - TclRegExec - match a regexp against a string
890 */
891int
892TclRegExec(prog, string, start)
893register regexp *prog;
894register char *string;
895char *start;
896{
897	register char *s;
898	struct regexec_state state;
899	struct regexec_state *restate= &state;
900
901	/* Be paranoid... */
902	if (prog == NULL || string == NULL) {
903		TclRegError("NULL parameter");
904		return(0);
905	}
906
907	/* Check validity of program. */
908	if (UCHARAT(prog->program) != MAGIC) {
909		TclRegError("corrupted program");
910		return(0);
911	}
912
913	/* If there is a "must appear" string, look for it. */
914	if (prog->regmust != NULL) {
915		s = string;
916		while ((s = strchr(s, prog->regmust[0])) != NULL) {
917			if (strncmp(s, prog->regmust, (size_t) prog->regmlen)
918			    == 0)
919				break;	/* Found it. */
920			s++;
921		}
922		if (s == NULL)	/* Not present. */
923			return(0);
924	}
925
926	/* Mark beginning of line for ^ . */
927	restate->regbol = start;
928
929	/* Simplest case:  anchored match need be tried only once. */
930	if (prog->reganch)
931		return(regtry(prog, string, restate));
932
933	/* Messy cases:  unanchored match. */
934	s = string;
935	if (prog->regstart != '\0')
936		/* We know what char it must start with. */
937		while ((s = strchr(s, prog->regstart)) != NULL) {
938			if (regtry(prog, s, restate))
939				return(1);
940			s++;
941		}
942	else
943		/* We don't -- general case. */
944		do {
945			if (regtry(prog, s, restate))
946				return(1);
947		} while (*s++ != '\0');
948
949	/* Failure. */
950	return(0);
951}
952
953/*
954 - regtry - try match at specific point
955 */
956static int			/* 0 failure, 1 success */
957regtry(prog, string, restate)
958regexp *prog;
959char *string;
960struct regexec_state *restate;
961{
962	register int i;
963	register char **sp;
964	register char **ep;
965
966	restate->reginput = string;
967	restate->regstartp = prog->startp;
968	restate->regendp = prog->endp;
969
970	sp = prog->startp;
971	ep = prog->endp;
972	for (i = NSUBEXP; i > 0; i--) {
973		*sp++ = NULL;
974		*ep++ = NULL;
975	}
976	if (regmatch(prog->program + 1,restate)) {
977		prog->startp[0] = string;
978		prog->endp[0] = restate->reginput;
979		return(1);
980	} else
981		return(0);
982}
983
984/*
985 - regmatch - main matching routine
986 *
987 * Conceptually the strategy is simple:  check to see whether the current
988 * node matches, call self recursively to see whether the rest matches,
989 * and then act accordingly.  In practice we make some effort to avoid
990 * recursion, in particular by going through "ordinary" nodes (that don't
991 * need to know whether the rest of the match failed) by a loop instead of
992 * by recursion.
993 */
994static int			/* 0 failure, 1 success */
995regmatch(prog, restate)
996char *prog;
997struct regexec_state *restate;
998{
999    register char *scan;	/* Current node. */
1000    char *next;		/* Next node. */
1001
1002    scan = prog;
1003#ifdef DEBUG
1004    if (scan != NULL && regnarrate)
1005	fprintf(stderr, "%s(\n", regprop(scan));
1006#endif
1007    while (scan != NULL) {
1008#ifdef DEBUG
1009	if (regnarrate)
1010	    fprintf(stderr, "%s...\n", regprop(scan));
1011#endif
1012	next = regnext(scan);
1013
1014	switch (OP(scan)) {
1015	    case BOL:
1016		if (restate->reginput != restate->regbol) {
1017		    return 0;
1018		}
1019		break;
1020	    case EOL:
1021		if (*restate->reginput != '\0') {
1022		    return 0;
1023		}
1024		break;
1025	    case ANY:
1026		if (*restate->reginput == '\0') {
1027		    return 0;
1028		}
1029		restate->reginput++;
1030		break;
1031	    case EXACTLY: {
1032		register int len;
1033		register char *opnd;
1034
1035		opnd = OPERAND(scan);
1036		/* Inline the first character, for speed. */
1037		if (*opnd != *restate->reginput) {
1038		    return 0 ;
1039		}
1040		len = strlen(opnd);
1041		if (len > 1 && strncmp(opnd, restate->reginput, (size_t) len)
1042			!= 0) {
1043		    return 0;
1044		}
1045		restate->reginput += len;
1046		break;
1047	    }
1048	    case ANYOF:
1049		if (*restate->reginput == '\0'
1050			|| strchr(OPERAND(scan), *restate->reginput) == NULL) {
1051		    return 0;
1052		}
1053		restate->reginput++;
1054		break;
1055	    case ANYBUT:
1056		if (*restate->reginput == '\0'
1057			|| strchr(OPERAND(scan), *restate->reginput) != NULL) {
1058		    return 0;
1059		}
1060		restate->reginput++;
1061		break;
1062	    case NOTHING:
1063		break;
1064	    case BACK:
1065		break;
1066	    case OPEN+1:
1067	    case OPEN+2:
1068	    case OPEN+3:
1069	    case OPEN+4:
1070	    case OPEN+5:
1071	    case OPEN+6:
1072	    case OPEN+7:
1073	    case OPEN+8:
1074	    case OPEN+9: {
1075		register int no;
1076		register char *save;
1077
1078	doOpen:
1079		no = OP(scan) - OPEN;
1080		save = restate->reginput;
1081
1082		if (regmatch(next,restate)) {
1083		    /*
1084		     * Don't set startp if some later invocation of the
1085		     * same parentheses already has.
1086		     */
1087		    if (restate->regstartp[no] == NULL) {
1088			restate->regstartp[no] = save;
1089		    }
1090		    return 1;
1091		} else {
1092		    return 0;
1093		}
1094	    }
1095	    case CLOSE+1:
1096	    case CLOSE+2:
1097	    case CLOSE+3:
1098	    case CLOSE+4:
1099	    case CLOSE+5:
1100	    case CLOSE+6:
1101	    case CLOSE+7:
1102	    case CLOSE+8:
1103	    case CLOSE+9: {
1104		register int no;
1105		register char *save;
1106
1107	doClose:
1108		no = OP(scan) - CLOSE;
1109		save = restate->reginput;
1110
1111		if (regmatch(next,restate)) {
1112				/*
1113				 * Don't set endp if some later
1114				 * invocation of the same parentheses
1115				 * already has.
1116				 */
1117		    if (restate->regendp[no] == NULL)
1118			restate->regendp[no] = save;
1119		    return 1;
1120		} else {
1121		    return 0;
1122		}
1123	    }
1124	    case BRANCH: {
1125		register char *save;
1126
1127		if (OP(next) != BRANCH) { /* No choice. */
1128		    next = OPERAND(scan); /* Avoid recursion. */
1129		} else {
1130		    do {
1131			save = restate->reginput;
1132			if (regmatch(OPERAND(scan),restate))
1133			    return(1);
1134			restate->reginput = save;
1135			scan = regnext(scan);
1136		    } while (scan != NULL && OP(scan) == BRANCH);
1137		    return 0;
1138		}
1139		break;
1140	    }
1141	    case STAR:
1142	    case PLUS: {
1143		register char nextch;
1144		register int no;
1145		register char *save;
1146		register int min;
1147
1148		/*
1149		 * Lookahead to avoid useless match attempts
1150		 * when we know what character comes next.
1151		 */
1152		nextch = '\0';
1153		if (OP(next) == EXACTLY)
1154		    nextch = *OPERAND(next);
1155		min = (OP(scan) == STAR) ? 0 : 1;
1156		save = restate->reginput;
1157		no = regrepeat(OPERAND(scan),restate);
1158		while (no >= min) {
1159		    /* If it could work, try it. */
1160		    if (nextch == '\0' || *restate->reginput == nextch)
1161			if (regmatch(next,restate))
1162			    return(1);
1163		    /* Couldn't or didn't -- back up. */
1164		    no--;
1165		    restate->reginput = save + no;
1166		}
1167		return(0);
1168	    }
1169	    case END:
1170		return(1);	/* Success! */
1171	    default:
1172		if (OP(scan) > OPEN && OP(scan) < OPEN+NSUBEXP) {
1173		    goto doOpen;
1174		} else if (OP(scan) > CLOSE && OP(scan) < CLOSE+NSUBEXP) {
1175		    goto doClose;
1176		}
1177		TclRegError("memory corruption");
1178		return 0;
1179	}
1180
1181	scan = next;
1182    }
1183
1184    /*
1185     * We get here only if there's trouble -- normally "case END" is
1186     * the terminating point.
1187     */
1188    TclRegError("corrupted pointers");
1189    return(0);
1190}
1191
1192/*
1193 - regrepeat - repeatedly match something simple, report how many
1194 */
1195static int
1196regrepeat(p, restate)
1197char *p;
1198struct regexec_state *restate;
1199{
1200	register int count = 0;
1201	register char *scan;
1202	register char *opnd;
1203
1204	scan = restate->reginput;
1205	opnd = OPERAND(p);
1206	switch (OP(p)) {
1207	case ANY:
1208		count = strlen(scan);
1209		scan += count;
1210		break;
1211	case EXACTLY:
1212		while (*opnd == *scan) {
1213			count++;
1214			scan++;
1215		}
1216		break;
1217	case ANYOF:
1218		while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
1219			count++;
1220			scan++;
1221		}
1222		break;
1223	case ANYBUT:
1224		while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
1225			count++;
1226			scan++;
1227		}
1228		break;
1229	default:		/* Oh dear.  Called inappropriately. */
1230		TclRegError("internal foulup");
1231		count = 0;	/* Best compromise. */
1232		break;
1233	}
1234	restate->reginput = scan;
1235
1236	return(count);
1237}
1238
1239/*
1240 - regnext - dig the "next" pointer out of a node
1241 */
1242static char *
1243regnext(p)
1244register char *p;
1245{
1246	register int offset;
1247
1248	if (p == &regdummy)
1249		return(NULL);
1250
1251	offset = NEXT(p);
1252	if (offset == 0)
1253		return(NULL);
1254
1255	if (OP(p) == BACK)
1256		return(p-offset);
1257	else
1258		return(p+offset);
1259}
1260
1261#ifdef DEBUG
1262
1263static char *regprop();
1264
1265/*
1266 - regdump - dump a regexp onto stdout in vaguely comprehensible form
1267 */
1268void
1269regdump(r)
1270regexp *r;
1271{
1272	register char *s;
1273	register char op = EXACTLY;	/* Arbitrary non-END op. */
1274	register char *next;
1275
1276
1277	s = r->program + 1;
1278	while (op != END) {	/* While that wasn't END last time... */
1279		op = OP(s);
1280		printf("%2d%s", s-r->program, regprop(s));	/* Where, what. */
1281		next = regnext(s);
1282		if (next == NULL)		/* Next ptr. */
1283			printf("(0)");
1284		else
1285			printf("(%d)", (s-r->program)+(next-s));
1286		s += 3;
1287		if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
1288			/* Literal string, where present. */
1289			while (*s != '\0') {
1290				putchar(*s);
1291				s++;
1292			}
1293			s++;
1294		}
1295		putchar('\n');
1296	}
1297
1298	/* Header fields of interest. */
1299	if (r->regstart != '\0')
1300		printf("start `%c' ", r->regstart);
1301	if (r->reganch)
1302		printf("anchored ");
1303	if (r->regmust != NULL)
1304		printf("must have \"%s\"", r->regmust);
1305	printf("\n");
1306}
1307
1308/*
1309 - regprop - printable representation of opcode
1310 */
1311static char *
1312regprop(op)
1313char *op;
1314{
1315	register char *p;
1316	static char buf[50];
1317
1318	(void) strcpy(buf, ":");
1319
1320	switch (OP(op)) {
1321	case BOL:
1322		p = "BOL";
1323		break;
1324	case EOL:
1325		p = "EOL";
1326		break;
1327	case ANY:
1328		p = "ANY";
1329		break;
1330	case ANYOF:
1331		p = "ANYOF";
1332		break;
1333	case ANYBUT:
1334		p = "ANYBUT";
1335		break;
1336	case BRANCH:
1337		p = "BRANCH";
1338		break;
1339	case EXACTLY:
1340		p = "EXACTLY";
1341		break;
1342	case NOTHING:
1343		p = "NOTHING";
1344		break;
1345	case BACK:
1346		p = "BACK";
1347		break;
1348	case END:
1349		p = "END";
1350		break;
1351	case OPEN+1:
1352	case OPEN+2:
1353	case OPEN+3:
1354	case OPEN+4:
1355	case OPEN+5:
1356	case OPEN+6:
1357	case OPEN+7:
1358	case OPEN+8:
1359	case OPEN+9:
1360		sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
1361		p = NULL;
1362		break;
1363	case CLOSE+1:
1364	case CLOSE+2:
1365	case CLOSE+3:
1366	case CLOSE+4:
1367	case CLOSE+5:
1368	case CLOSE+6:
1369	case CLOSE+7:
1370	case CLOSE+8:
1371	case CLOSE+9:
1372		sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
1373		p = NULL;
1374		break;
1375	case STAR:
1376		p = "STAR";
1377		break;
1378	case PLUS:
1379		p = "PLUS";
1380		break;
1381	default:
1382		if (OP(op) > OPEN && OP(op) < OPEN+NSUBEXP) {
1383		    sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
1384		    p = NULL;
1385		    break;
1386		} else if (OP(op) > CLOSE && OP(op) < CLOSE+NSUBEXP) {
1387		    sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
1388		    p = NULL;
1389		} else {
1390		    TclRegError("corrupted opcode");
1391		}
1392		break;
1393	}
1394	if (p != NULL)
1395		(void) strcat(buf, p);
1396	return(buf);
1397}
1398#endif
1399
1400/*
1401 * The following is provided for those people who do not have strcspn() in
1402 * their C libraries.  They should get off their butts and do something
1403 * about it; at least one public-domain implementation of those (highly
1404 * useful) string routines has been published on Usenet.
1405 */
1406#ifdef STRCSPN
1407/*
1408 * strcspn - find length of initial segment of s1 consisting entirely
1409 * of characters not from s2
1410 */
1411
1412static int
1413strcspn(s1, s2)
1414char *s1;
1415char *s2;
1416{
1417	register char *scan1;
1418	register char *scan2;
1419	register int count;
1420
1421	count = 0;
1422	for (scan1 = s1; *scan1 != '\0'; scan1++) {
1423		for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
1424			if (*scan1 == *scan2++)
1425				return(count);
1426		count++;
1427	}
1428	return(count);
1429}
1430#endif
1431
1432/*
1433 *----------------------------------------------------------------------
1434 *
1435 * TclRegError --
1436 *
1437 *	This procedure is invoked by the regexp code when an error
1438 *	occurs.  It saves the error message so it can be seen by the
1439 *	code that called Spencer's code.
1440 *
1441 * Results:
1442 *	None.
1443 *
1444 * Side effects:
1445 *	The value of "string" is saved in "errMsg".
1446 *
1447 *----------------------------------------------------------------------
1448 */
1449
1450void
1451exp_TclRegError(string)
1452    char *string;			/* Error message. */
1453{
1454    errMsg = string;
1455}
1456
1457char *
1458TclGetRegError()
1459{
1460    return errMsg;
1461}
1462
1463/*
1464 * end of regexp definitions and code
1465 */
1466
1467/*
1468 * stolen from exp_log.c - this function is called from the Expect library
1469 * but the one that the library supplies calls Tcl functions.  So we supply
1470 * our own.
1471 */
1472
1473static
1474void
1475expDiagLogU(str)
1476     char *str;
1477{
1478  if (exp_is_debugging) {
1479    fprintf(stderr,str);
1480    if (exp_logfile) fprintf(exp_logfile,str);
1481  }
1482}
1483
1484/*
1485 * expect-specific definitions and code
1486 */
1487
1488#include "expect.h"
1489#include "exp_int.h"
1490
1491/* exp_glob.c - expect functions for doing glob
1492 *
1493 * Based on Tcl's glob functions but modified to support anchors and to
1494 * return information about the possibility of future matches
1495 *
1496 * Modifications by: Don Libes, NIST, 2/6/90
1497 */
1498
1499/* The following functions implement expect's glob-style string
1500 * matching Exp_StringMatch allow's implements the unanchored front
1501 * (or conversely the '^') feature.  Exp_StringMatch2 does the rest of
1502 * the work.
1503 */
1504
1505/* Exp_StringMatch2 --
1506 *
1507 * Like Tcl_StringMatch except that
1508 * 1) returns number of characters matched, -1 if failed.
1509 *	(Can return 0 on patterns like "" or "$")
1510 * 2) does not require pattern to match to end of string
1511 * 3) much of code is stolen from Tcl_StringMatch
1512 * 4) front-anchor is assumed (Tcl_StringMatch retries for non-front-anchor)
1513 */
1514static
1515int
1516Exp_StringMatch2(string,pattern)
1517    register char *string;	/* String. */
1518    register char *pattern;	/* Pattern, which may contain
1519				 * special characters. */
1520{
1521    char c2;
1522    int match = 0;	/* # of chars matched */
1523
1524    while (1) {
1525	/* If at end of pattern, success! */
1526	if (*pattern == 0) {
1527		return match;
1528	}
1529
1530	/* If last pattern character is '$', verify that entire
1531	 * string has been matched.
1532	 */
1533	if ((*pattern == '$') && (pattern[1] == 0)) {
1534		if (*string == 0) return(match);
1535		else return(-1);
1536	}
1537
1538	/* Check for a "*" as the next pattern character.  It matches
1539	 * any substring.  We handle this by calling ourselves
1540	 * recursively for each postfix of string, until either we
1541	 * match or we reach the end of the string.
1542	 */
1543
1544	if (*pattern == '*') {
1545	    int head_len;
1546	    char *tail;
1547	    pattern += 1;
1548	    if (*pattern == 0) {
1549		return(strlen(string)+match); /* DEL */
1550	    }
1551	    /* find longest match - switched to this on 12/31/93 */
1552	    head_len = strlen(string);	/* length before tail */
1553	    tail = string + head_len;
1554	    while (head_len >= 0) {
1555		int rc;
1556
1557		if (-1 != (rc = Exp_StringMatch2(tail, pattern))) {
1558		    return rc + match + head_len;	/* DEL */
1559		}
1560		tail--;
1561		head_len--;
1562	    }
1563	    return -1;					/* DEL */
1564	}
1565
1566	/*
1567	 * after this point, all patterns must match at least one
1568	 * character, so check this
1569	 */
1570
1571	if (*string == 0) return -1;
1572
1573	/* Check for a "?" as the next pattern character.  It matches
1574	 * any single character.
1575	 */
1576
1577	if (*pattern == '?') {
1578	    goto thisCharOK;
1579	}
1580
1581	/* Check for a "[" as the next pattern character.  It is followed
1582	 * by a list of characters that are acceptable, or by a range
1583	 * (two characters separated by "-").
1584	 */
1585
1586	if (*pattern == '[') {
1587	    pattern += 1;
1588	    while (1) {
1589		if ((*pattern == ']') || (*pattern == 0)) {
1590		    return -1;			/* was 0; DEL */
1591		}
1592		if (*pattern == *string) {
1593		    break;
1594		}
1595		if (pattern[1] == '-') {
1596		    c2 = pattern[2];
1597		    if (c2 == 0) {
1598			return -1;		/* DEL */
1599		    }
1600		    if ((*pattern <= *string) && (c2 >= *string)) {
1601			break;
1602		    }
1603		    if ((*pattern >= *string) && (c2 <= *string)) {
1604			break;
1605		    }
1606		    pattern += 2;
1607		}
1608		pattern += 1;
1609	    }
1610
1611	    while (*pattern != ']') {
1612		if (*pattern == 0) {
1613		    pattern--;
1614		    break;
1615	        }
1616		pattern += 1;
1617	    }
1618	    goto thisCharOK;
1619	}
1620
1621	/* If the next pattern character is backslash, strip it off
1622	 * so we do exact matching on the character that follows.
1623	 */
1624
1625	if (*pattern == '\\') {
1626	    pattern += 1;
1627	    if (*pattern == 0) {
1628		return -1;
1629	    }
1630	}
1631
1632	/* There's no special character.  Just make sure that the next
1633	 * characters of each string match.
1634	 */
1635
1636	if (*pattern != *string) {
1637	    return -1;
1638	}
1639
1640	thisCharOK: pattern += 1;
1641	string += 1;
1642	match++;
1643    }
1644}
1645
1646
1647static
1648int	/* returns # of chars that matched */
1649Exp_StringMatch(string, pattern,offset)
1650char *string;
1651char *pattern;
1652int *offset;	/* offset from beginning of string where pattern matches */
1653{
1654	char *s;
1655	int sm;	/* count of chars matched or -1 */
1656	int caret = FALSE;
1657	int star = FALSE;
1658
1659	*offset = 0;
1660
1661	if (pattern[0] == '^') {
1662		caret = TRUE;
1663		pattern++;
1664	} else if (pattern[0] == '*') {
1665		star = TRUE;
1666	}
1667
1668	/*
1669	 * test if pattern matches in initial position.
1670	 * This handles front-anchor and 1st iteration of non-front-anchor.
1671	 * Note that 1st iteration must be tried even if string is empty.
1672	 */
1673
1674	sm = Exp_StringMatch2(string,pattern);
1675	if (sm >= 0) return(sm);
1676
1677	if (caret) return -1;
1678	if (star) return -1;
1679
1680	if (*string == '\0') return -1;
1681
1682	for (s = string+1;*s;s++) {
1683 		sm = Exp_StringMatch2(s,pattern);
1684		if (sm != -1) {
1685			*offset = s-string;
1686			return(sm);
1687		}
1688	}
1689	return -1;
1690}
1691
1692
1693#define EXP_MATCH_MAX	2000
1694/* public */
1695char *exp_buffer = 0;
1696char *exp_buffer_end = 0;
1697char *exp_match = 0;
1698char *exp_match_end = 0;
1699int exp_match_max = EXP_MATCH_MAX;	/* bytes */
1700int exp_full_buffer = FALSE;		/* don't return on full buffer */
1701int exp_remove_nulls = TRUE;
1702int exp_timeout = 10;			/* seconds */
1703int exp_pty_timeout = 5;		/* seconds - see CRAY below */
1704int exp_autoallocpty = TRUE;		/* if TRUE, we do allocation */
1705int exp_pty[2];				/* master is [0], slave is [1] */
1706int exp_pid;
1707char *exp_stty_init = 0;		/* initial stty args */
1708int exp_ttycopy = TRUE;			/* copy tty parms from /dev/tty */
1709int exp_ttyinit = TRUE;			/* set tty parms to sane state */
1710int exp_console = FALSE;		/* redirect console */
1711void (*exp_child_exec_prelude)() = 0;
1712void (*exp_close_in_child)() = 0;
1713
1714#ifdef HAVE_SIGLONGJMP
1715sigjmp_buf exp_readenv;		/* for interruptable read() */
1716#else
1717jmp_buf exp_readenv;		/* for interruptable read() */
1718#endif /* HAVE_SIGLONGJMP */
1719
1720int exp_reading = FALSE;	/* whether we can longjmp or not */
1721
1722int exp_is_debugging = FALSE;
1723FILE *exp_debugfile = 0;
1724
1725FILE *exp_logfile = 0;
1726int exp_logfile_all = FALSE;	/* if TRUE, write log of all interactions */
1727int exp_loguser = TRUE;		/* if TRUE, user sees interactions on stdout */
1728
1729
1730char *exp_printify();
1731int exp_getptymaster();
1732int exp_getptyslave();
1733
1734#define sysreturn(x)	return(errno = x, -1)
1735
1736void exp_init_pty();
1737
1738/*
1739   The following functions are linked from the Tcl library.  They
1740   don't cause anything else in the library to be dragged in, so it
1741   shouldn't cause any problems (e.g., bloat).
1742
1743   The functions are relatively small but painful enough that I don't care
1744   to recode them.  You may, if you absolutely want to get rid of any
1745   vestiges of Tcl.
1746*/
1747
1748static unsigned int bufsiz = 2*EXP_MATCH_MAX;
1749
1750static struct f {
1751	int valid;
1752
1753	char *buffer;		/* buffer of matchable chars */
1754	char *buffer_end;	/* one beyond end of matchable chars */
1755	char *match_end;	/* one beyond end of matched string */
1756	int msize;		/* size of allocate space */
1757				/* actual size is one larger for null */
1758} *fs = 0;
1759
1760static int fd_alloc_max = -1;	/* max fd allocated */
1761
1762/* translate fd or fp to fd */
1763static struct f *
1764fdfp2f(fd,fp)
1765int fd;
1766FILE *fp;
1767{
1768	if (fd == -1) return(fs + fileno(fp));
1769	else return(fs + fd);
1770}
1771
1772static struct f *
1773fd_new(fd)
1774int fd;
1775{
1776	int i, low;
1777	struct f *fp;
1778	struct f *newfs;	/* temporary, so we don't lose old fs */
1779
1780	if (fd > fd_alloc_max) {
1781		if (!fs) {	/* no fd's yet allocated */
1782			newfs = (struct f *)malloc(sizeof(struct f)*(fd+1));
1783			low = 0;
1784		} else {		/* enlarge fd table */
1785			newfs = (struct f *)realloc((char *)fs,sizeof(struct f)*(fd+1));
1786			low = fd_alloc_max+1;
1787		}
1788		fs = newfs;
1789		fd_alloc_max = fd;
1790		for (i = low; i <= fd_alloc_max; i++) { /* init new entries */
1791			fs[i].valid = FALSE;
1792		}
1793	}
1794
1795	fp = fs+fd;
1796
1797	if (!fp->valid) {
1798		/* initialize */
1799		fp->buffer = malloc((unsigned)(bufsiz+1));
1800		if (!fp->buffer) return 0;
1801		fp->msize = bufsiz;
1802		fp->valid = TRUE;
1803	}
1804	fp->buffer_end = fp->buffer;
1805	fp->match_end = fp->buffer;
1806	return fp;
1807
1808}
1809
1810static
1811void
1812exp_setpgrp()
1813{
1814#ifdef MIPS_BSD
1815    /* required on BSD side of MIPS OS <jmsellen@watdragon.waterloo.edu> */
1816#   include <sysv/sys.s>
1817    syscall(SYS_setpgrp);
1818#endif
1819
1820#ifdef SETPGRP_VOID
1821    (void) setpgrp();
1822#else
1823    (void) setpgrp(0,0);
1824#endif
1825}
1826
1827/* returns fd of master side of pty */
1828int
1829exp_spawnv(file,argv)
1830char *file;
1831char *argv[];	/* some compiler complains about **argv? */
1832{
1833	int cc;
1834	int errorfd;	/* place to stash fileno(stderr) in child */
1835			/* while we're setting up new stderr */
1836	int ttyfd;
1837	int sync_fds[2];
1838	int sync2_fds[2];
1839	int status_pipe[2];
1840	int child_errno;
1841	char sync_byte;
1842#ifdef PTYTRAP_DIES
1843	int slave_write_ioctls = 1;
1844		/* by default, slave will be write-ioctled this many times */
1845#endif
1846
1847	static int first_time = TRUE;
1848
1849	if (first_time) {
1850		first_time = FALSE;
1851		exp_init_pty();
1852		exp_init_tty();
1853		expDiagLogPtrSet(expDiagLogU);
1854
1855		/*
1856		 * TIP 27; It is unclear why this code produces a
1857		 * warning. The equivalent code in exp_main_sub.c
1858		 * (line 512) does not generate a warning !
1859		 */
1860
1861		expErrnoMsgSet(Tcl_ErrnoMsg);
1862	}
1863
1864	if (!file || !argv) sysreturn(EINVAL);
1865	if (!argv[0] || strcmp(file,argv[0])) {
1866		exp_debuglog("expect: warning: file (%s) != argv[0] (%s)\n",
1867			file,
1868			argv[0]?argv[0]:"");
1869	}
1870
1871#ifdef PTYTRAP_DIES
1872/* any extraneous ioctl's that occur in slave must be accounted for
1873when trapping, see below in child half of fork */
1874#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300)
1875	slave_write_ioctls++;
1876#endif
1877#endif /*PTYTRAP_DIES*/
1878
1879	if (exp_autoallocpty) {
1880		if (0 > (exp_pty[0] = exp_getptymaster())) sysreturn(ENODEV);
1881	}
1882	fcntl(exp_pty[0],F_SETFD,1);	/* close on exec */
1883#ifdef PTYTRAP_DIES
1884	exp_slave_control(exp_pty[0],1);*/
1885#endif
1886
1887	if (!fd_new(exp_pty[0])) {
1888		errno = ENOMEM;
1889		return -1;
1890	}
1891
1892	if (-1 == (pipe(sync_fds))) {
1893		return -1;
1894	}
1895	if (-1 == (pipe(sync2_fds))) {
1896		close(sync_fds[0]);
1897		close(sync_fds[1]);
1898		return -1;
1899	}
1900
1901	if (-1 == pipe(status_pipe)) {
1902		close(sync_fds[0]);
1903		close(sync_fds[1]);
1904		close(sync2_fds[0]);
1905		close(sync2_fds[1]);
1906		return -1;
1907	}
1908
1909	if ((exp_pid = fork()) == -1) return(-1);
1910	if (exp_pid) {
1911		/* parent */
1912		close(sync_fds[1]);
1913		close(sync2_fds[0]);
1914		close(status_pipe[1]);
1915
1916		if (!exp_autoallocpty) close(exp_pty[1]);
1917
1918#ifdef PTYTRAP_DIES
1919#ifdef HAVE_PTYTRAP
1920		if (exp_autoallocpty) {
1921			/* trap initial ioctls in a feeble attempt to not */
1922			/* block the initially.  If the process itself */
1923			/* ioctls /dev/tty, such blocks will be trapped */
1924			/* later during normal event processing */
1925
1926			while (slave_write_ioctls) {
1927				int cc;
1928
1929				cc = exp_wait_for_slave_open(exp_pty[0]);
1930#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300)
1931				if (cc == TIOCSCTTY) slave_write_ioctls = 0;
1932#endif
1933				if (cc & IOC_IN) slave_write_ioctls--;
1934				else if (cc == -1) {
1935					printf("failed to trap slave pty");
1936					return -1;
1937				}
1938			}
1939		}
1940#endif
1941#endif /*PTYTRAP_DIES*/
1942
1943		/*
1944		 * wait for slave to initialize pty before allowing
1945		 * user to send to it
1946		 */
1947
1948		exp_debuglog("parent: waiting for sync byte\r\n");
1949		cc = read(sync_fds[0],&sync_byte,1);
1950		if (cc == -1) {
1951		  exp_errorlog("parent sync byte read: %s\r\n",Tcl_ErrnoMsg(errno));
1952		  return -1;
1953		}
1954
1955		/* turn on detection of eof */
1956		exp_slave_control(exp_pty[0],1);
1957
1958		/*
1959		 * tell slave to go on now now that we have initialized pty
1960		 */
1961
1962		exp_debuglog("parent: telling child to go ahead\r\n");
1963		cc = write(sync2_fds[1]," ",1);
1964		if (cc == -1) {
1965		  exp_errorlog("parent sync byte write: %s\r\n",Tcl_ErrnoMsg(errno));
1966		  return -1;
1967		}
1968
1969		exp_debuglog("parent: now unsynchronized from child\r\n");
1970
1971		close(sync_fds[0]);
1972		close(sync2_fds[1]);
1973
1974		/* see if child's exec worked */
1975
1976	retry:
1977		switch (read(status_pipe[0],&child_errno,sizeof child_errno)) {
1978		case -1:
1979			if (errno == EINTR) goto retry;
1980			/* well it's not really the child's errno */
1981			/* but it can be treated that way */
1982			child_errno = errno;
1983			break;
1984		case 0:
1985			/* child's exec succeeded */
1986			child_errno = 0;
1987			break;
1988		default:
1989			/* child's exec failed; err contains exec's errno  */
1990			waitpid(exp_pid, NULL, 0);
1991			errno = child_errno;
1992			exp_pty[0] = -1;
1993		}
1994		close(status_pipe[0]);
1995		return(exp_pty[0]);
1996	}
1997
1998	/*
1999	 * child process - do not return from here!  all errors must exit()
2000	 */
2001
2002	close(sync_fds[0]);
2003	close(sync2_fds[1]);
2004	close(status_pipe[0]);
2005	fcntl(status_pipe[1],F_SETFD,1);	/* close on exec */
2006
2007#ifdef CRAY
2008	(void) close(exp_pty[0]);
2009#endif
2010
2011/* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */
2012/* is called.  setpgrp works though.  */
2013#if defined(POSIX) && !defined(ultrix)
2014#define DO_SETSID
2015#endif
2016#ifdef __convex__
2017#define DO_SETSID
2018#endif
2019
2020#ifdef DO_SETSID
2021	setsid();
2022#else
2023#ifdef SYSV3
2024#ifndef CRAY
2025	exp_setpgrp();
2026#endif /* CRAY */
2027#else /* !SYSV3 */
2028	exp_setpgrp();
2029
2030#ifdef TIOCNOTTY
2031	ttyfd = open("/dev/tty", O_RDWR);
2032	if (ttyfd >= 0) {
2033		(void) ioctl(ttyfd, TIOCNOTTY, (char *)0);
2034		(void) close(ttyfd);
2035	}
2036#endif /* TIOCNOTTY */
2037
2038#endif /* SYSV3 */
2039#endif /* DO_SETSID */
2040
2041	/* save error fd while we're setting up new one */
2042	errorfd = fcntl(2,F_DUPFD,3);
2043	/* and here is the macro to restore it */
2044#define restore_error_fd {close(2);fcntl(errorfd,F_DUPFD,2);}
2045
2046	if (exp_autoallocpty) {
2047
2048	    close(0);
2049	    close(1);
2050	    close(2);
2051
2052	    /* since we closed fd 0, open of pty slave must return fd 0 */
2053
2054	    if (0 > (exp_pty[1] = exp_getptyslave(exp_ttycopy,exp_ttyinit,
2055						exp_stty_init))) {
2056		restore_error_fd
2057		fprintf(stderr,"open(slave pty): %s\n",Tcl_ErrnoMsg(errno));
2058		exit(-1);
2059	    }
2060	    /* sanity check */
2061	    if (exp_pty[1] != 0) {
2062		restore_error_fd
2063		fprintf(stderr,"exp_getptyslave: slave = %d but expected 0\n",
2064								exp_pty[1]);
2065		exit(-1);
2066	    }
2067	} else {
2068		if (exp_pty[1] != 0) {
2069			close(0);	fcntl(exp_pty[1],F_DUPFD,0);
2070		}
2071		close(1);		fcntl(0,F_DUPFD,1);
2072		close(2);		fcntl(0,F_DUPFD,1);
2073		close(exp_pty[1]);
2074	}
2075
2076
2077
2078/* The test for hpux may have to be more specific.  In particular, the */
2079/* code should be skipped on the hp9000s300 and hp9000s720 (but there */
2080/* is no documented define for the 720!) */
2081
2082#if defined(TIOCSCTTY) && !defined(sun) && !defined(hpux)
2083	/* 4.3+BSD way to acquire controlling terminal */
2084	/* according to Stevens - Adv. Prog..., p 642 */
2085#ifdef __QNX__ /* posix in general */
2086	if (tcsetct(0, getpid()) == -1) {
2087	  restore_error_fd
2088	  expErrorLog("failed to get controlling terminal using TIOCSCTTY");
2089	  exit(-1);
2090	}
2091#else
2092	(void) ioctl(0,TIOCSCTTY,(char *)0);
2093	/* ignore return value - on some systems, it is defined but it
2094	 * fails and it doesn't seem to cause any problems.  Or maybe
2095	 * it works but returns a bogus code.  Noone seems to be able
2096	 * to explain this to me.  The systems are an assortment of
2097	 * different linux systems (and FreeBSD 2.5), RedHat 5.2 and
2098	 * Debian 2.0
2099	 */
2100#endif
2101#endif
2102
2103#ifdef CRAY
2104 	(void) setsid();
2105 	(void) ioctl(0,TCSETCTTY,0);
2106 	(void) close(0);
2107 	if (open("/dev/tty", O_RDWR) < 0) {
2108		restore_error_fd
2109 		fprintf(stderr,"open(/dev/tty): %s\r\n",Tcl_ErrnoMsg(errno));
2110 		exit(-1);
2111 	}
2112 	(void) close(1);
2113 	(void) close(2);
2114 	(void) dup(0);
2115 	(void) dup(0);
2116	setptyutmp();	/* create a utmp entry */
2117
2118	/* _CRAY2 code from Hal Peterson <hrp@cray.com>, Cray Research, Inc. */
2119#ifdef _CRAY2
2120	/*
2121	 * Interpose a process between expect and the spawned child to
2122	 * keep the slave side of the pty open to allow time for expect
2123	 * to read the last output.  This is a workaround for an apparent
2124	 * bug in the Unicos pty driver on Cray-2's under Unicos 6.0 (at
2125	 * least).
2126	 */
2127	if ((pid = fork()) == -1) {
2128		restore_error_fd
2129		fprintf(stderr,"second fork: %s\r\n",Tcl_ErrnoMsg(errno));
2130		exit(-1);
2131	}
2132
2133	if (pid) {
2134 		/* Intermediate process. */
2135		int status;
2136		int timeout;
2137		char *t;
2138
2139		/* How long should we wait? */
2140		timeout = exp_pty_timeout;
2141
2142		/* Let the spawned process run to completion. */
2143 		while (wait(&status) < 0 && errno == EINTR)
2144			/* empty body */;
2145
2146		/* Wait for the pty to clear. */
2147		sleep(timeout);
2148
2149		/* Duplicate the spawned process's status. */
2150		if (WIFSIGNALED(status))
2151			kill(getpid(), WTERMSIG(status));
2152
2153		/* The kill may not have worked, but this will. */
2154 		exit(WEXITSTATUS(status));
2155	}
2156#endif /* _CRAY2 */
2157#endif /* CRAY */
2158
2159	if (exp_console) {
2160#ifdef SRIOCSREDIR
2161		int fd;
2162
2163		if ((fd = open("/dev/console", O_RDONLY)) == -1) {
2164			restore_error_fd
2165			fprintf(stderr, "spawn %s: cannot open console, check permissions of /dev/console\n",argv[0]);
2166			exit(-1);
2167		}
2168		if (ioctl(fd, SRIOCSREDIR, 0) == -1) {
2169			restore_error_fd
2170			fprintf(stderr, "spawn %s: cannot redirect console, check permissions of /dev/console\n",argv[0]);
2171		}
2172		close(fd);
2173#endif
2174
2175#ifdef TIOCCONS
2176		int on = 1;
2177		if (ioctl(0,TIOCCONS,(char *)&on) == -1) {
2178			restore_error_fd
2179			fprintf(stderr, "spawn %s: cannot open console, check permissions of /dev/console\n",argv[0]);
2180			exit(-1);
2181		}
2182#endif /* TIOCCONS */
2183	}
2184
2185	/* tell parent that we are done setting up pty */
2186	/* The actual char sent back is irrelevant. */
2187
2188	/* exp_debuglog("child: telling parent that pty is initialized\r\n");*/
2189	cc = write(sync_fds[1]," ",1);
2190	if (cc == -1) {
2191		restore_error_fd
2192		fprintf(stderr,"child: sync byte write: %s\r\n",Tcl_ErrnoMsg(errno));
2193		exit(-1);
2194	}
2195	close(sync_fds[1]);
2196
2197	/* wait for master to let us go on */
2198	cc = read(sync2_fds[0],&sync_byte,1);
2199	if (cc == -1) {
2200		restore_error_fd
2201		exp_errorlog("child: sync byte read: %s\r\n",Tcl_ErrnoMsg(errno));
2202		exit(-1);
2203	}
2204	close(sync2_fds[0]);
2205
2206	/* exp_debuglog("child: now unsynchronized from parent\r\n"); */
2207
2208	/* (possibly multiple) masters are closed automatically due to */
2209	/* earlier fcntl(,,CLOSE_ON_EXEC); */
2210
2211	/* just in case, allow user to explicitly close other files */
2212	if (exp_close_in_child) (*exp_close_in_child)();
2213
2214	/* allow user to do anything else to child */
2215	if (exp_child_exec_prelude) (*exp_child_exec_prelude)();
2216
2217        (void) execvp(file,argv);
2218
2219	/* Unfortunately, by now we've closed fd's to stderr, logfile
2220	 * and debugfile.  The only reasonable thing to do is to send
2221	 * *back the error as part of the program output.  This will
2222	 * be *picked up in an expect or interact command.
2223	 */
2224
2225	write(status_pipe[1], &errno, sizeof errno);
2226	exit(-1);
2227	/*NOTREACHED*/
2228}
2229
2230/* returns fd of master side of pty */
2231/*VARARGS*/
2232int
2233exp_spawnl TCL_VARARGS_DEF(char *,arg1)
2234/*exp_spawnl(va_alist)*/
2235/*va_dcl*/
2236{
2237	va_list args; /* problematic line here */
2238	int i;
2239	char *arg, **argv;
2240
2241	arg = TCL_VARARGS_START(char *,arg1,args);
2242	/*va_start(args);*/
2243	for (i=1;;i++) {
2244		arg = va_arg(args,char *);
2245		if (!arg) break;
2246	}
2247	va_end(args);
2248	if (i == 0) sysreturn(EINVAL);
2249	if (!(argv = (char **)malloc((i+1)*sizeof(char *)))) sysreturn(ENOMEM);
2250	argv[0] = TCL_VARARGS_START(char *,arg1,args);
2251	/*va_start(args);*/
2252	for (i=1;;i++) {
2253		argv[i] = va_arg(args,char *);
2254		if (!argv[i]) break;
2255	}
2256	i = exp_spawnv(argv[0],argv+1);
2257	free((char *)argv);
2258	return(i);
2259}
2260
2261/* allow user-provided fd to be passed to expect funcs */
2262int
2263exp_spawnfd(fd)
2264int fd;
2265{
2266	if (!fd_new(fd)) {
2267		errno = ENOMEM;
2268		return -1;
2269	}
2270	return fd;
2271}
2272
2273/* remove nulls from s.  Initially, the number of chars in s is c, */
2274/* not strlen(s).  This count does not include the trailing null. */
2275/* returns number of nulls removed. */
2276static int
2277rm_nulls(s,c)
2278char *s;
2279int c;
2280{
2281	char *s2 = s;	/* points to place in original string to put */
2282			/* next non-null character */
2283	int count = 0;
2284	int i;
2285
2286	for (i=0;i<c;i++,s++) {
2287		if (0 == *s) {
2288			count++;
2289			continue;
2290		}
2291		if (count) *s2 = *s;
2292		s2++;
2293	}
2294	return(count);
2295}
2296
2297static int i_read_errno;/* place to save errno, if i_read() == -1, so it
2298			   doesn't get overwritten before we get to read it */
2299
2300/*ARGSUSED*/
2301static void
2302sigalarm_handler(n)
2303int n;			/* signal number, unused by us */
2304{
2305#ifdef REARM_SIG
2306	signal(SIGALRM,sigalarm_handler);
2307#endif
2308
2309#ifdef HAVE_SIGLONGJMP
2310	siglongjmp(exp_readenv,1);
2311#else
2312	longjmp(exp_readenv,1);
2313#endif /* HAVE_SIGLONGJMP */
2314}
2315
2316/* interruptable read */
2317static int
2318i_read(fd,fp,buffer,length,timeout)
2319int fd;
2320FILE *fp;
2321char *buffer;
2322int length;
2323int timeout;
2324{
2325	int cc = -2;
2326
2327	/* since setjmp insists on returning 1 upon longjmp(,0), */
2328	/* longjmp(,2 (EXP_RESTART)) instead. */
2329
2330	/* no need to set alarm if -1 (infinite) or 0 (poll with */
2331	/* guaranteed data) */
2332
2333	if (timeout > 0) alarm(timeout);
2334
2335	/* restart read if setjmp returns 0 (first time) or 2 (EXP_RESTART). */
2336	/* abort if setjmp returns 1 (EXP_ABORT). */
2337#ifdef HAVE_SIGLONGJMP
2338        if (EXP_ABORT != sigsetjmp(exp_readenv,1)) {
2339#else
2340	if (EXP_ABORT != setjmp(exp_readenv)) {
2341#endif /* HAVE_SIGLONGJMP */
2342		exp_reading = TRUE;
2343		if (fd == -1) {
2344			int c;
2345			c = getc(fp);
2346			if (c == EOF) {
2347/*fprintf(stderr,"<<EOF>>",c);fflush(stderr);*/
2348				if (feof(fp)) cc = 0;
2349				else cc = -1;
2350			} else {
2351/*fprintf(stderr,"<<%c>>",c);fflush(stderr);*/
2352				buffer[0] = c;
2353				cc = 1;
2354			}
2355		} else {
2356#ifndef HAVE_PTYTRAP
2357			cc = read(fd,buffer,length);
2358#else
2359#  include <sys/ptyio.h>
2360
2361			fd_set rdrs;
2362			fd_set excep;
2363
2364		restart:
2365			FD_ZERO(&rdrs);
2366			FD_ZERO(&excep);
2367			FD_SET(fd,&rdrs);
2368			FD_SET(fd,&excep);
2369			if (-1 == (cc = select(fd+1,
2370					 (SELECT_MASK_TYPE *)&rdrs,
2371					 (SELECT_MASK_TYPE *)0,
2372					 (SELECT_MASK_TYPE *)&excep,
2373					 (struct timeval *)0))) {
2374				/* window refreshes trigger EINTR, ignore */
2375				if (errno == EINTR) goto restart;
2376			}
2377			if (FD_ISSET(fd,&rdrs)) {
2378				cc = read(fd,buffer,length);
2379			} else if (FD_ISSET(fd,&excep)) {
2380				struct request_info ioctl_info;
2381				ioctl(fd,TIOCREQCHECK,&ioctl_info);
2382				if (ioctl_info.request == TIOCCLOSE) {
2383					cc = 0; /* indicate eof */
2384				} else {
2385					ioctl(fd, TIOCREQSET, &ioctl_info);
2386					/* presumably, we trapped an open here */
2387					goto restart;
2388				}
2389			}
2390#endif /* HAVE_PTYTRAP */
2391		}
2392#if 0
2393		/* can't get fread to return early! */
2394		else {
2395			if (!(cc = fread(buffer,1,length,fp))) {
2396				if (ferror(fp)) cc = -1;
2397			}
2398		}
2399#endif
2400		i_read_errno = errno;	/* errno can be overwritten by the */
2401					/* time we return */
2402	}
2403	exp_reading = FALSE;
2404
2405	if (timeout > 0) alarm(0);
2406	return(cc);
2407}
2408
2409/* I tried really hard to make the following two functions share the code */
2410/* that makes the ecase array, but I kept running into a brick wall when */
2411/* passing var args into the funcs and then again into a make_cases func */
2412/* I would very much appreciate it if someone showed me how to do it right */
2413
2414/* takes triplets of args, with a final "exp_last" arg */
2415/* triplets are type, pattern, and then int to return */
2416/* returns negative value if error (or EOF/timeout) occurs */
2417/* some negative values can also have an associated errno */
2418
2419/* the key internal variables that this function depends on are:
2420	exp_buffer
2421	exp_buffer_end
2422	exp_match_end
2423*/
2424static int
2425expectv(fd,fp,ecases)
2426int fd;
2427FILE *fp;
2428struct exp_case *ecases;
2429{
2430	int cc = 0;		/* number of chars returned in a single read */
2431	int buf_length;		/* numbers of chars in exp_buffer */
2432	int old_length;		/* old buf_length */
2433	int first_time = TRUE;	/* force old buffer to be tested before */
2434				/* additional reads */
2435	int polled = 0;		/* true if poll has caused read() to occur */
2436
2437	struct exp_case *ec;	/* points to current ecase */
2438
2439	time_t current_time;	/* current time (when we last looked)*/
2440	time_t end_time;	/* future time at which to give up */
2441	int remtime;		/* remaining time in timeout */
2442
2443	struct f *f;
2444	int return_val;
2445	int sys_error = 0;
2446#define return_normally(x)	{return_val = x; goto cleanup;}
2447#define return_errno(x)	{sys_error = x; goto cleanup;}
2448
2449	f = fdfp2f(fd,fp);
2450	if (!f) return_errno(ENOMEM);
2451
2452	exp_buffer = f->buffer;
2453	exp_buffer_end = f->buffer_end;
2454	exp_match_end = f->match_end;
2455
2456	buf_length = exp_buffer_end - exp_match_end;
2457	if (buf_length) {
2458		/*
2459		 * take end of previous match to end of buffer
2460		 * and copy to beginning of buffer
2461		 */
2462		memmove(exp_buffer,exp_match_end,buf_length);
2463	}
2464	exp_buffer_end = exp_buffer + buf_length;
2465	*exp_buffer_end = '\0';
2466
2467	if (!ecases) return_errno(EINVAL);
2468
2469	/* compile if necessary */
2470	for (ec=ecases;ec->type != exp_end;ec++) {
2471		if ((ec->type == exp_regexp) && !ec->re) {
2472			TclRegError((char *)0);
2473			if (!(ec->re = TclRegComp(ec->pattern))) {
2474				fprintf(stderr,"regular expression %s is bad: %s",ec->pattern,TclGetRegError());
2475				return_errno(EINVAL);
2476			  }
2477		  }
2478	}
2479
2480	/* get the latest buffer size.  Double the user input for two */
2481	/* reasons.  1) Need twice the space in case the match */
2482	/* straddles two bufferfuls, 2) easier to hack the division by */
2483	/* two when shifting the buffers later on */
2484
2485	bufsiz = 2*exp_match_max;
2486	if (f->msize != bufsiz) {
2487		/* if truncated, forget about some data */
2488		if (buf_length > bufsiz) {
2489			/* copy end of buffer down */
2490
2491			/* copy one less than what buffer can hold to avoid */
2492			/* triggering buffer-full handling code below */
2493			/* which will immediately dump the first half */
2494			/* of the buffer */
2495			memmove(exp_buffer,exp_buffer+(buf_length - bufsiz)+1,
2496				bufsiz-1);
2497			buf_length = bufsiz-1;
2498		}
2499		exp_buffer = realloc(exp_buffer,bufsiz+1);
2500		if (!exp_buffer) return_errno(ENOMEM);
2501		exp_buffer[buf_length] = '\0';
2502		exp_buffer_end = exp_buffer + buf_length;
2503		f->msize = bufsiz;
2504	}
2505
2506	/* some systems (i.e., Solaris) require fp be flushed when switching */
2507	/* directions - do this again afterwards */
2508	if (fd == -1) fflush(fp);
2509
2510	if (exp_timeout != -1) signal(SIGALRM,sigalarm_handler);
2511
2512	/* remtime and current_time updated at bottom of loop */
2513	remtime = exp_timeout;
2514
2515	time(&current_time);
2516	end_time = current_time + remtime;
2517
2518	for (;;) {
2519		/* when buffer fills, copy second half over first and */
2520		/* continue, so we can do matches over multiple buffers */
2521		if (buf_length == bufsiz) {
2522			int first_half, second_half;
2523
2524			if (exp_full_buffer) {
2525				exp_debuglog("expect: full buffer\r\n");
2526				exp_match = exp_buffer;
2527				exp_match_end = exp_buffer + buf_length;
2528				exp_buffer_end = exp_match_end;
2529				return_normally(EXP_FULLBUFFER);
2530			}
2531			first_half = bufsiz/2;
2532			second_half = bufsiz - first_half;
2533
2534			memcpy(exp_buffer,exp_buffer+first_half,second_half);
2535			buf_length = second_half;
2536			exp_buffer_end = exp_buffer + second_half;
2537		}
2538
2539		/*
2540		 * always check first if pattern is already in buffer
2541		 */
2542		if (first_time) {
2543			first_time = FALSE;
2544			goto after_read;
2545		}
2546
2547		/*
2548		 * check for timeout
2549 		 * we should timeout if either
2550 		 *   1) exp_timeout > remtime <= 0 (normal)
2551 		 *   2) exp_timeout == 0 and we have polled at least once
2552		 *
2553		 */
2554		if (((exp_timeout > remtime) && (remtime <= 0)) ||
2555 		    ((exp_timeout == 0) && polled)) {
2556			exp_debuglog("expect: timeout\r\n");
2557			exp_match_end = exp_buffer;
2558			return_normally(EXP_TIMEOUT);
2559		}
2560
2561 		/* remember that we have actually checked at least once */
2562 		polled = 1;
2563
2564		cc = i_read(fd,fp,
2565				exp_buffer_end,
2566				bufsiz - buf_length,
2567				remtime);
2568
2569		if (cc == 0) {
2570			exp_debuglog("expect: eof\r\n");
2571			return_normally(EXP_EOF);	/* normal EOF */
2572		} else if (cc == -1) {			/* abnormal EOF */
2573			/* ptys produce EIO upon EOF - sigh */
2574			if (i_read_errno == EIO) {
2575				/* convert to EOF indication */
2576				exp_debuglog("expect: eof\r\n");
2577				return_normally(EXP_EOF);
2578			}
2579			exp_debuglog("expect: error (errno = %d)\r\n",i_read_errno);
2580			return_errno(i_read_errno);
2581		} else if (cc == -2) {
2582			exp_debuglog("expect: timeout\r\n");
2583			exp_match_end = exp_buffer;
2584			return_normally(EXP_TIMEOUT);
2585		}
2586
2587		old_length = buf_length;
2588		buf_length += cc;
2589		exp_buffer_end += buf_length;
2590
2591		if (exp_logfile_all || (exp_loguser && exp_logfile)) {
2592			fwrite(exp_buffer + old_length,1,cc,exp_logfile);
2593		}
2594		if (exp_loguser) fwrite(exp_buffer + old_length,1,cc,stdout);
2595		if (exp_debugfile) fwrite(exp_buffer + old_length,1,cc,exp_debugfile);
2596
2597		/* if we wrote to any logs, flush them */
2598		if (exp_debugfile) fflush(exp_debugfile);
2599		if (exp_loguser) {
2600			fflush(stdout);
2601			if (exp_logfile) fflush(exp_logfile);
2602		}
2603
2604		/* remove nulls from input, so we can use C-style strings */
2605		/* doing it here lets them be sent to the screen, just */
2606		/*  in case they are involved in formatting operations */
2607		if (exp_remove_nulls) {
2608			buf_length -= rm_nulls(exp_buffer + old_length, cc);
2609		}
2610		/* cc should be decremented as well, but since it will not */
2611		/* be used before being set again, there is no need */
2612		exp_buffer_end = exp_buffer + buf_length;
2613		*exp_buffer_end = '\0';
2614                exp_match_end = exp_buffer;
2615
2616	after_read:
2617		exp_debuglog("expect: does {%s} match ",exp_printify(exp_buffer));
2618		/* pattern supplied */
2619		for (ec=ecases;ec->type != exp_end;ec++) {
2620			int matched = -1;
2621
2622			exp_debuglog("{%s}? ",exp_printify(ec->pattern));
2623			if (ec->type == exp_glob) {
2624				int offset;
2625				matched = Exp_StringMatch(exp_buffer,ec->pattern,&offset);
2626				if (matched >= 0) {
2627					exp_match = exp_buffer + offset;
2628					exp_match_end = exp_match + matched;
2629				}
2630			} else if (ec->type == exp_exact) {
2631				char *p = strstr(exp_buffer,ec->pattern);
2632				if (p) {
2633					matched = 1;
2634					exp_match = p;
2635					exp_match_end = p + strlen(ec->pattern);
2636				}
2637			} else if (ec->type == exp_null) {
2638				char *p;
2639
2640				for (p=exp_buffer;p<exp_buffer_end;p++) {
2641					if (*p == 0) {
2642						matched = 1;
2643						exp_match = p;
2644						exp_match_end = p+1;
2645					}
2646				}
2647			} else {
2648				TclRegError((char *)0);
2649				if (TclRegExec(ec->re,exp_buffer,exp_buffer)) {
2650					matched = 1;
2651					exp_match = ec->re->startp[0];
2652					exp_match_end = ec->re->endp[0];
2653				} else if (TclGetRegError()) {
2654			    		fprintf(stderr,"r.e. match (pattern %s) failed: %s",ec->pattern,TclGetRegError());
2655				}
2656			}
2657
2658			if (matched != -1) {
2659				exp_debuglog("yes\nexp_buffer is {%s}\n",
2660						exp_printify(exp_buffer));
2661				return_normally(ec->value);
2662			} else exp_debuglog("no\n");
2663		}
2664
2665		/*
2666		 * Update current time and remaining time.
2667		 * Don't bother if we are waiting forever or polling.
2668		 */
2669		if (exp_timeout > 0) {
2670			time(&current_time);
2671			remtime = end_time - current_time;
2672		}
2673	}
2674 cleanup:
2675	f->buffer     = exp_buffer;
2676	f->buffer_end = exp_buffer_end;
2677	f->match_end  = exp_match_end;
2678
2679	/* some systems (i.e., Solaris) require fp be flushed when switching */
2680	/* directions - do this before as well */
2681	if (fd == -1) fflush(fp);
2682
2683	if (sys_error) {
2684		errno = sys_error;
2685		return -1;
2686	}
2687	return return_val;
2688}
2689
2690int
2691exp_fexpectv(fp,ecases)
2692FILE *fp;
2693struct exp_case *ecases;
2694{
2695	return(expectv(-1,fp,ecases));
2696}
2697
2698int
2699exp_expectv(fd,ecases)
2700int fd;
2701struct exp_case *ecases;
2702{
2703	return(expectv(fd,(FILE *)0,ecases));
2704}
2705
2706/*VARARGS*/
2707int
2708exp_expectl TCL_VARARGS_DEF(int,arg1)
2709/*exp_expectl(va_alist)*/
2710/*va_dcl*/
2711{
2712	va_list args;
2713	int fd;
2714	struct exp_case *ec, *ecases;
2715	int i;
2716	enum exp_type type;
2717
2718	fd = TCL_VARARGS_START(int,arg1,args);
2719	/* va_start(args);*/
2720	/* fd = va_arg(args,int);*/
2721	/* first just count the arg sets */
2722	for (i=0;;i++) {
2723		type = va_arg(args,enum exp_type);
2724		if (type == exp_end) break;
2725
2726		/* Ultrix 4.2 compiler refuses enumerations comparison!? */
2727		if ((int)type < 0 || (int)type >= (int)exp_bogus) {
2728			fprintf(stderr,"bad type (set %d) in exp_expectl\n",i);
2729			sysreturn(EINVAL);
2730		}
2731
2732		va_arg(args,char *);		/* COMPUTED BUT NOT USED */
2733		if (type == exp_compiled) {
2734			va_arg(args,regexp *);	/* COMPUTED BUT NOT USED */
2735		}
2736		va_arg(args,int);		/* COMPUTED BUT NOT USED*/
2737	}
2738	va_end(args);
2739
2740	if (!(ecases = (struct exp_case *)
2741				malloc((1+i)*sizeof(struct exp_case))))
2742		sysreturn(ENOMEM);
2743
2744	/* now set up the actual cases */
2745	fd = TCL_VARARGS_START(int,arg1,args);
2746	/*va_start(args);*/
2747	/*va_arg(args,int);*/		/*COMPUTED BUT NOT USED*/
2748	for (ec=ecases;;ec++) {
2749		ec->type = va_arg(args,enum exp_type);
2750		if (ec->type == exp_end) break;
2751		ec->pattern = va_arg(args,char *);
2752		if (ec->type == exp_compiled) {
2753			ec->re = va_arg(args,regexp *);
2754		} else {
2755			ec->re = 0;
2756		}
2757		ec->value = va_arg(args,int);
2758	}
2759	va_end(args);
2760	i = expectv(fd,(FILE *)0,ecases);
2761
2762	for (ec=ecases;ec->type != exp_end;ec++) {
2763		/* free only if regexp and we compiled it for user */
2764		if (ec->type == exp_regexp) {
2765			free((char *)ec->re);
2766		}
2767	}
2768	free((char *)ecases);
2769	return(i);
2770}
2771
2772int
2773exp_fexpectl TCL_VARARGS_DEF(FILE *,arg1)
2774/*exp_fexpectl(va_alist)*/
2775/*va_dcl*/
2776{
2777	va_list args;
2778	FILE *fp;
2779	struct exp_case *ec, *ecases;
2780	int i;
2781	enum exp_type type;
2782
2783	fp = TCL_VARARGS_START(FILE *,arg1,args);
2784	/*va_start(args);*/
2785	/*fp = va_arg(args,FILE *);*/
2786	/* first just count the arg-pairs */
2787	for (i=0;;i++) {
2788		type = va_arg(args,enum exp_type);
2789		if (type == exp_end) break;
2790
2791		/* Ultrix 4.2 compiler refuses enumerations comparison!? */
2792		if ((int)type < 0 || (int)type >= (int)exp_bogus) {
2793			fprintf(stderr,"bad type (set %d) in exp_expectl\n",i);
2794			sysreturn(EINVAL);
2795		}
2796
2797		va_arg(args,char *);		/* COMPUTED BUT NOT USED */
2798		if (type == exp_compiled) {
2799			va_arg(args,regexp *);	/* COMPUTED BUT NOT USED */
2800		}
2801		va_arg(args,int);		/* COMPUTED BUT NOT USED*/
2802	}
2803	va_end(args);
2804
2805	if (!(ecases = (struct exp_case *)
2806					malloc((1+i)*sizeof(struct exp_case))))
2807		sysreturn(ENOMEM);
2808
2809#if 0
2810	va_start(args);
2811	va_arg(args,FILE *);		/*COMPUTED, BUT NOT USED*/
2812#endif
2813	(void) TCL_VARARGS_START(FILE *,arg1,args);
2814
2815	for (ec=ecases;;ec++) {
2816		ec->type = va_arg(args,enum exp_type);
2817		if (ec->type == exp_end) break;
2818		ec->pattern = va_arg(args,char *);
2819		if (ec->type == exp_compiled) {
2820			ec->re = va_arg(args,regexp *);
2821		} else {
2822			ec->re = 0;
2823		}
2824		ec->value = va_arg(args,int);
2825	}
2826	va_end(args);
2827	i = expectv(-1,fp,ecases);
2828
2829	for (ec=ecases;ec->type != exp_end;ec++) {
2830		/* free only if regexp and we compiled it for user */
2831		if (ec->type == exp_regexp) {
2832			free((char *)ec->re);
2833		}
2834	}
2835	free((char *)ecases);
2836	return(i);
2837}
2838
2839/* like popen(3) but works in both directions */
2840FILE *
2841exp_popen(program)
2842char *program;
2843{
2844	FILE *fp;
2845	int ec;
2846
2847	if (0 > (ec = exp_spawnl("sh","sh","-c",program,(char *)0))) return(0);
2848	if (!(fp = fdopen(ec,"r+"))) return(0);
2849	setbuf(fp,(char *)0);
2850	return(fp);
2851}
2852
2853int
2854exp_disconnect()
2855{
2856	int ttyfd;
2857
2858#ifndef EALREADY
2859#define EALREADY 37
2860#endif
2861
2862	/* presumably, no stderr, so don't bother with error message */
2863	if (exp_disconnected) sysreturn(EALREADY);
2864	exp_disconnected = TRUE;
2865
2866	freopen("/dev/null","r",stdin);
2867	freopen("/dev/null","w",stdout);
2868	freopen("/dev/null","w",stderr);
2869
2870#ifdef POSIX
2871	setsid();
2872#else
2873#ifdef SYSV3
2874	/* put process in our own pgrp, and lose controlling terminal */
2875	exp_setpgrp();
2876	signal(SIGHUP,SIG_IGN);
2877	if (fork()) exit(0);	/* first child exits (as per Stevens, */
2878	/* UNIX Network Programming, p. 79-80) */
2879	/* second child process continues as daemon */
2880#else /* !SYSV3 */
2881	exp_setpgrp();
2882/* Pyramid lacks this defn */
2883#ifdef TIOCNOTTY
2884	ttyfd = open("/dev/tty", O_RDWR);
2885	if (ttyfd >= 0) {
2886		/* zap controlling terminal if we had one */
2887		(void) ioctl(ttyfd, TIOCNOTTY, (char *)0);
2888		(void) close(ttyfd);
2889	}
2890#endif /* TIOCNOTTY */
2891#endif /* SYSV3 */
2892#endif /* POSIX */
2893	return(0);
2894}
2895
2896/* send to log if open and debugging enabled */
2897/* send to stderr if debugging enabled */
2898/* use this function for recording unusual things in the log */
2899/*VARARGS*/
2900void
2901exp_debuglog TCL_VARARGS_DEF(char *,arg1)
2902{
2903    char *fmt;
2904    va_list args;
2905
2906    fmt = TCL_VARARGS_START(char *,arg1,args);
2907    if (exp_debugfile) vfprintf(exp_debugfile,fmt,args);
2908    if (exp_is_debugging) {
2909	vfprintf(stderr,fmt,args);
2910	if (exp_logfile) vfprintf(exp_logfile,fmt,args);
2911    }
2912
2913    va_end(args);
2914}
2915
2916
2917/* send to log if open */
2918/* send to stderr */
2919/* use this function for error conditions */
2920/*VARARGS*/
2921void
2922exp_errorlog TCL_VARARGS_DEF(char *,arg1)
2923{
2924    char *fmt;
2925    va_list args;
2926
2927    fmt = TCL_VARARGS_START(char *,arg1,args);
2928    vfprintf(stderr,fmt,args);
2929    if (exp_debugfile) vfprintf(exp_debugfile,fmt,args);
2930    if (exp_logfile) vfprintf(exp_logfile,fmt,args);
2931    va_end(args);
2932}
2933
2934#include <ctype.h>
2935
2936char *
2937exp_printify(s)
2938char *s;
2939{
2940	static int destlen = 0;
2941	static char *dest = 0;
2942	char *d;		/* ptr into dest */
2943	unsigned int need;
2944
2945	if (s == 0) return("<null>");
2946
2947	/* worst case is every character takes 4 to printify */
2948	need = strlen(s)*4 + 1;
2949	if (need > destlen) {
2950		if (dest) ckfree(dest);
2951		dest = ckalloc(need);
2952		destlen = need;
2953	}
2954
2955	for (d = dest;*s;s++) {
2956		if (*s == '\r') {
2957			strcpy(d,"\\r");		d += 2;
2958		} else if (*s == '\n') {
2959			strcpy(d,"\\n");		d += 2;
2960		} else if (*s == '\t') {
2961			strcpy(d,"\\t");		d += 2;
2962		} else if (isascii(*s) && isprint(*s)) {
2963			*d = *s;			d += 1;
2964		} else {
2965			sprintf(d,"\\x%02x",*s & 0xff);	d += 4;
2966		}
2967	}
2968	*d = '\0';
2969	return(dest);
2970}
2971