home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-13 | 57.2 KB | 1,908 lines |
- Newsgroups: comp.sources.misc
- Path: sparky!kent
- From: cristy@eplrx7.es.duPont.com (John Cristy)
- Subject: v34i031: imagemagick - X11 image processing and display v2.2, Part03/26
- Message-ID: <1992Dec13.202349.7975@sparky.imd.sterling.com>
- Followup-To: comp.sources.d
- X-Md4-Signature: dcedf45d348e8c1204f2200228373068
- Sender: kent@sparky.imd.sterling.com (Kent Landfield)
- Organization: Sterling Software
- References: <csm-v34i028=imagemagick.141926@sparky.IMD.Sterling.COM>
- Date: Sun, 13 Dec 1992 20:23:49 GMT
- Approved: kent@sparky.imd.sterling.com
- Lines: 1893
-
- Submitted-by: cristy@eplrx7.es.duPont.com (John Cristy)
- Posting-number: Volume 34, Issue 31
- Archive-name: imagemagick/part03
- Environment: UNIX, VMS, X11, SGI, DEC, Cray, Sun, Vax
-
- #!/bin/sh
- # this is Part.03 (part 3 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file ImageMagick/xtp/regular.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 3; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping ImageMagick/xtp/regular.c'
- else
- echo 'x - continuing file ImageMagick/xtp/regular.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/xtp/regular.c' &&
- % & Company not be used in advertising or publicity pertaining to %
- % distribution of the software without specific, written prior %
- % permission. E. I. Dupont de Nemours & Company makes no representations %
- % about the suitability of this software for any purpose. It is provided %
- % "as is" without express or implied warranty. %
- % %
- % E. I. Dupont de Nemours & Company disclaims all warranties with regard %
- % to this software, including all implied warranties of merchantability %
- % and fitness, in no event shall E. I. Dupont de Nemours & Company be %
- % liable for any special, indirect or consequential damages or any %
- % damages whatsoever resulting from loss of use, data or profits, whether %
- % in an action of contract, negligence or other tortious action, arising %
- % out of or in connection with the use or performance of this software. %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % CompileRegularExpression returns NULL for a failure, where failures are
- % syntax errors, exceeding implementation limits, or applying `+' or `*'
- % to a possibly-null operand.
- %
- % This is essentially the same routine written and copywrited by Henry
- % Spencer, University of Toronto. I made minor programming changes but
- % major variable name changes to improve readability.
- %
- % A regular expression is zero or more branches, separated by `|'. It
- % matches anything that matches one of the branches.
- %
- % A branch is zero or more pieces, concatenated. It matches a match for
- % the first, followed by a match for the second, etc.
- %
- % A piece is an atom possibly followed by `*', `+', or `?'. An atom
- % followed by `*' matches a sequence of 0 or more matches of the atom. An
- % atom followed by `+' matches a sequence of 1 or more matches of the
- % atom. An atom followed by `?' matches a match of the atom, or the null
- % pattern.
- %
- % An atom is a regular expression in parentheses (matching a match for
- % the regular expression), a range (see below), `.' (matching any single
- % character), `^' (matching the null pattern at the beginning of the input
- % pattern), `$' (matching the null pattern at the end of the input pattern),
- % a `\' followed by a single character (matching that character), or a
- % single character with no other significance (matching that character).
- %
- % A range is a sequence of characters enclosed in `[]'. It normally
- % matches any single character from the sequence. If the sequence begins
- % with `^', it matches any single character not from the rest of the
- % sequence. If two characters in the sequence are separated by `-', this
- % is shorthand for the full list of ASCII characters between them (e.g.
- % `[0-9]' matches any decimal digit). To include a literal `]' in the
- % sequence, make it the first character (following a possible `^'). To
- % include a literal `-', make it the first or last character.
- %
- % If a regular expression could match two different parts of the input
- % pattern, it will match the one which begins earliest. If both begin in
- % the same place but match different lengths, or match the same length
- % in different ways, life gets messier, as follows.
- %
- % In general, the possibilities in a list of branches are considered in
- % left-to-right order, the possibilities for `*', `+', and `?' are
- % considered longest-first, nested constructs are considered from the
- % outermost in, and concatenated constructs are considered
- % leftmost-first. The match that will be chosen is the one that uses the
- % earliest possibility in the first choice that has to be made. If there
- % is more than one choice, the next will be made in the same manner
- % (earliest possibility) subject to the decision on the first choice.
- % And so forth.
- %
- % For example, `(ab|a)b*c' could match `abc' in one of two ways. The
- % first choice is between `ab' and `a'; since `ab' is earlier, and does
- % lead to a successful overall match, it is chosen. Since the `b' is
- % already spoken for, the `b*' must match its last possibility-the empty
- % pattern-since it must respect the earlier choice.
- %
- % In the particular case where no `|'s are present and there is only one
- % `*', `+', or `?', the net effect is that the longest possible match
- % will be chosen. So `ab*', presented with `xabbbby', will match `abbbb'.
- % Note that if `ab*' is tried against `xabyabbbz', it will match `ab'
- % just after `x', due to the begins-earliest rule. (In effect, the deci-
- % sion on where to start the match is the first choice to be made, hence
- % subsequent choices must respect it even if this leads them to
- % less-preferred alternatives.)
- %
- %
- */
- X
- #include "xtp.h"
- #include "regular.h"
- X
- /*
- X Variable declarations.
- */
- char
- X *code,
- X **subpattern_end,
- X *p,
- X start_code,
- X *start_pattern,
- X **subpattern;
- X
- static char
- X *token;
- X
- static int
- X number_parenthesis;
- X
- static long
- X code_size;
- X
- /*
- X Forward declarations.
- */
- static char
- X *NextToken _Declare((register char *)),
- X *Node _Declare((int)),
- X *Piece _Declare((int *)),
- X *Regular _Declare((int,int *));
- X
- static int
- X Repeat _Declare((char *));
- X
- static void
- X EmitCode _Declare((int)),
- X Tail _Declare((char *,char *));
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % A t o m %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static char *Atom(flagp)
- int
- X *flagp;
- {
- X int
- X flags;
- X
- X register char
- X *status;
- X
- X *flagp=WorstCase;
- X switch(*token++)
- X {
- X case '^':
- X {
- X status=Node(MatchBeginningOfLine);
- X break;
- X }
- X case '$':
- X {
- X status=Node(MatchEndOfProgramOfLine);
- X break;
- X }
- X case '.':
- X {
- X status=Node(MatchAnyCharacter);
- X *flagp|=NonNull | Simple;
- X break;
- X }
- X case '[':
- X {
- X register int
- X class,
- X class_end;
- X
- X if (*token != '^')
- X status=Node(MatchAnyCharacterOf);
- X else
- X {
- X /*
- X Complement of range.
- X */
- X status=Node(MatchAnyCharacterBut);
- X token++;
- X }
- X if ((*token == ']') || (*token == '-'))
- X EmitCode(*token++);
- X while ((*token != '\0') && (*token != ']'))
- X {
- X if (*token != '-')
- X EmitCode(*token++);
- X else
- X {
- X token++;
- X if ((*token == ']') || (*token == '\0'))
- X EmitCode('-');
- X else
- X {
- X class=((int)*(unsigned char *)(token-2))+1;
- X class_end=((int)*(unsigned char *)(token));
- X if (class > class_end+1)
- X Fail("invalid [] range");
- X for(; class <= class_end; class++)
- X EmitCode((char) class);
- X token++;
- X }
- X }
- X }
- X EmitCode('\0');
- X if (*token != ']')
- X Fail("unmatched []");
- X token++;
- X *flagp|=NonNull | Simple;
- X break;
- X }
- X case '(':
- X {
- X status=Regular(1,&flags);
- X if (status == NULL)
- X return(NULL);
- X *flagp|=flags & (NonNull | SpecialStart);
- X break;
- X }
- X case '\0':
- X case '|':
- X case ')':
- X {
- X Fail("internal urp");
- X break;
- X }
- X case '?':
- X case '+':
- X case '*':
- X {
- X Fail("?+* follows nothing");
- X break;
- X }
- X case '\\':
- X {
- X if (*token == '\0')
- X Fail("trailing \\");
- X status=Node(MatchExactly);
- X EmitCode(*token++);
- X EmitCode('\0');
- X *flagp|=NonNull | Simple;
- X break;
- X }
- X default:
- X {
- X register char
- X ender;
- X
- X register int
- X length;
- X
- X token--;
- X length=strcspn(token,Meta);
- X if (length <= 0)
- X Fail("internal disaster");
- X ender=(*(token+length));
- X if (length > 1 && MultipleMatches(ender))
- X length--;
- X *flagp|=NonNull;
- X if (length == 1)
- X *flagp|=Simple;
- X status=Node(MatchExactly);
- X while (length > 0)
- X {
- X EmitCode(*token++);
- X length--;
- X }
- X EmitCode('\0');
- X break;
- X }
- X }
- X return(status);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % B r a n c h %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function Branch Implements the | operator.
- %
- %
- */
- static char *Branch(flagp)
- int
- X *flagp;
- {
- X int
- X flags;
- X
- X register char
- X *chain,
- X *latest,
- X *status;
- X
- X *flagp=WorstCase;
- X status=Node(MatchThisOrNext);
- X chain=NULL;
- X while ((*token != '\0') && (*token != '|') && (*token != ')'))
- X {
- X latest=Piece(&flags);
- X if (latest == NULL)
- X return(NULL);
- X *flagp|=flags & NonNull;
- X if (chain == NULL)
- X *flagp|=flags & SpecialStart;
- X else
- X Tail(chain,latest);
- X chain=latest;
- X }
- X if (chain == NULL)
- X (void) Node(MatchEmptyString);
- X return(status);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % E m i t C o d e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static void EmitCode(opcode)
- int
- X opcode;
- {
- X if (code != &start_code)
- X *code++=(char) opcode;
- X else
- X code_size++;
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % I n s e r t %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function Insert inserts an operator in front of an already-emitted operand.
- %
- */
- static void Insert(opcode,operand)
- char
- X opcode,
- X *operand;
- {
- X register char
- X *p,
- X *place,
- X *q;
- X
- X if (code == &start_code)
- X {
- X code_size+=3;
- X return;
- X }
- X p=code;
- X code+=3;
- X q=code;
- X while (p > operand)
- X *--q=(*--p);
- X place=operand;
- X *place++=opcode;
- X *place++='\0';
- X *place++='\0';
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % M a t c h %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static int Match(regular_expression)
- char
- X *regular_expression;
- {
- X char
- X *next_token;
- X
- X register char
- X *scan;
- X
- X scan=regular_expression;
- X while (scan != NULL)
- X {
- X next_token=NextToken(scan);
- X switch(OpCode(scan))
- X {
- X case MatchBeginningOfLine:
- X {
- X if (p != start_pattern)
- X return(0);
- X break;
- X }
- X case MatchEndOfProgramOfLine:
- X {
- X if (*p != '\0')
- X return(0);
- X break;
- X }
- X case MatchAnyCharacter:
- X {
- X if (*p == '\0')
- X return(0);
- X p++;
- X break;
- X }
- X case MatchExactly:
- X {
- X register char
- X *operand;
- X
- X register int
- X length;
- X
- X operand=Operand(scan);
- X /*
- X Inline the first character for speed.
- X */
- X if (*operand != *p)
- X return(0);
- X length=strlen(operand);
- X if ((length > 1) && (strncmp(operand,p,length) != 0))
- X return(0);
- X p+=length;
- X break;
- X }
- X case MatchAnyCharacterOf:
- X {
- X if ((*p == '\0' || strchr(Operand(scan),*p) == NULL))
- X return(0);
- X p++;
- X break;
- X }
- X case MatchAnyCharacterBut:
- X {
- X if ((*p == '\0') || (strchr(Operand(scan),*p) != NULL))
- X return(0);
- X p++;
- X break;
- X }
- X case MatchEmptyString:
- X break;
- X case Back:
- X break;
- X case Open+1:
- X case Open+2:
- X case Open+3:
- X case Open+4:
- X case Open+5:
- X case Open+6:
- X case Open+7:
- X case Open+8:
- X case Open+9:
- X {
- X register char
- X *save;
- X
- X register int
- X no;
- X
- X no=OpCode(scan)-Open;
- X save=p;
- X if (!Match(next_token))
- X return(0);
- X else
- X {
- X /*
- X Don't set subpattern if some later invocation of the same
- X parentheses already has.
- X */
- X if (subpattern[no] == NULL)
- X subpattern[no]=save;
- X return(1);
- X }
- X break;
- X }
- X case Close+1:
- X case Close+2:
- X case Close+3:
- X case Close+4:
- X case Close+5:
- X case Close+6:
- X case Close+7:
- X case Close+8:
- X case Close+9:
- X {
- X register char
- X *save;
- X
- X register int
- X no;
- X
- X no=OpCode(scan)-Close;
- X save=p;
- X if (!Match(next_token))
- X return(0);
- X else
- X {
- X /*
- X Don't set subpattern_end if some later invocation of the same
- X parentheses already has.
- X */
- X if (subpattern_end[no] == NULL)
- X subpattern_end[no]=save;
- X return(1);
- X }
- X break;
- X }
- X case MatchThisOrNext:
- X {
- X register char
- X *save;
- X
- X if (OpCode(next_token) != MatchThisOrNext)
- X next_token=Operand(scan);
- X else
- X {
- X do
- X {
- X save=p;
- X if (Match(Operand(scan)))
- X return(1);
- X p=save;
- X scan=NextToken(scan);
- X } while ((scan != NULL) && (OpCode(scan) == MatchThisOrNext));
- X return(0);
- X }
- X break;
- X }
- X case MatchZeroOrMore:
- X case MatchOneOrMore:
- X {
- X register char
- X next_tokench,
- X *save;
- X
- X register int
- X min,
- X no;
- X
- X /*
- X Lookahead to avoid useless match attempts when we know what
- X character comes next_token.
- X */
- X next_tokench='\0';
- X if (OpCode(next_token) == MatchExactly)
- X next_tokench=(*Operand(next_token));
- X min=(OpCode(scan) == MatchZeroOrMore) ? 0 : 1;
- X save=p;
- X no=Repeat(Operand(scan));
- X while (no >= min)
- X {
- X /*
- X If it could work, try it.
- X */
- X if ((next_tokench == '\0') || (*p == next_tokench))
- X if (Match(next_token))
- X return(1);
- X /*
- X Couldn't or didn't -- back up.
- X */
- X no--;
- X p=save+no;
- X }
- X return(0);
- X break;
- X }
- X case EndOfProgram:
- X return(1);
- X break;
- X default:
- X (void) fprintf(stderr,"Regular(3): %s","memory corruption");
- X return(0);
- X break;
- X }
- X scan=next_token;
- X }
- X (void) fprintf(stderr,"Regular(3): %s","corrupted pointers");
- X return(0);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % N e x t T o k e n %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static char *NextToken(p)
- register char
- X *p;
- {
- X register int
- X offset;
- X
- X if (p == &start_code)
- X return(NULL);
- X offset=Next(p);
- X if (offset == 0)
- X return(NULL);
- X if (OpCode(p) == Back)
- X return(p-offset);
- X else
- X return(p+offset);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % N o d e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static char *Node(opcode)
- int
- X opcode;
- {
- X register char
- X *ptr,
- X *status;
- X
- X status=code;
- X if (status == &start_code)
- X {
- X code_size+=3;
- X return(status);
- X }
- X ptr=status;
- X *ptr++=(char) opcode;
- X *ptr++='\0';
- X *ptr++='\0';
- X code=ptr;
- X return(status);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % O p T a i l %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static void OpTail(p,value)
- char
- X *p;
- X
- char
- X *value;
- {
- X /*
- X "Operandless" and "op != MatchThisOrNext" are synonymous in practice.
- X */
- X if ((p == NULL) || (p == &start_code) || (OpCode(p) != MatchThisOrNext))
- X return;
- X Tail(Operand(p),value);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % P i e c e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static char *Piece(flagp)
- int
- X *flagp;
- {
- X int
- X flags;
- X
- X register char
- X *next_token,
- X op,
- X *status;
- X
- X status=Atom(&flags);
- X if (status == NULL)
- X return(NULL);
- X op=(*token);
- X if (!MultipleMatches(op))
- X {
- X *flagp=flags;
- X return(status);
- X }
- X if (!(flags & NonNull) && op != '?')
- X Fail("*+ operand could be empty");
- X *flagp=(op != '+') ? (WorstCase | SpecialStart) : (WorstCase | NonNull);
- X if (op == '*' && (flags & Simple))
- X Insert(MatchZeroOrMore,status);
- X else
- X if (op == '*')
- X {
- X /*
- X Emit x* as (x&|), where & means "self".
- X */
- X Insert(MatchThisOrNext,status);
- X OpTail(status,Node(Back));
- X OpTail(status,status);
- X Tail(status,Node(MatchThisOrNext));
- X Tail(status,Node(MatchEmptyString));
- X }
- X else
- X if ((op == '+') && (flags & Simple))
- X Insert(MatchOneOrMore,status);
- X else
- X if (op == '+')
- X {
- X /*
- X Emit x+ as x (&|), where & means "self".
- X */
- X next_token=Node(MatchThisOrNext);
- X Tail(status,next_token);
- X Tail(Node(Back),status);
- X Tail(next_token,Node(MatchThisOrNext));
- X Tail(status,Node(MatchEmptyString));
- X }
- X else
- X if (op == '?')
- X {
- X /*
- X Emit x? as (x|)
- X */
- X Insert(MatchThisOrNext,status);
- X Tail(status,Node(MatchThisOrNext));
- X next_token=Node(MatchEmptyString);
- X Tail(status,next_token);
- X OpTail(status,next_token);
- X }
- X token++;
- X if (MultipleMatches(*token))
- X Fail("nested *?+");
- X return(status);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % R e g u l a r %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static char *Regular(parenthesized,flagp)
- int
- X parenthesized;
- X
- int
- X *flagp;
- {
- X int
- X flags;
- X
- X register char
- X *br,
- X *ender,
- X *status;
- X
- X register int
- X count;
- X
- X count=0;
- X *flagp=NonNull;
- X if (!parenthesized)
- X status=NULL;
- X else
- X {
- X /*
- X Make an Open node.
- X */
- X if (number_parenthesis >= NumberSubExpressions)
- X Fail("too many ()");
- X count=number_parenthesis;
- X number_parenthesis++;
- X status=Node(Open+count);
- X }
- X /*
- X Pick up the branches, linking them together.
- X */
- X br=Branch(&flags);
- X if (br == NULL)
- X return(NULL);
- X if (status != NULL)
- X Tail(status,br);
- X else
- X status=br;
- X if (!(flags & NonNull))
- X *flagp&=(~NonNull);
- X *flagp|=flags & SpecialStart;
- X while (*token == '|')
- X {
- X token++;
- X br=Branch(&flags);
- X if (br == NULL)
- X return(NULL);
- X Tail(status,br);
- X if (!(flags & NonNull))
- X *flagp &= ~NonNull;
- X *flagp|=flags & SpecialStart;
- X }
- X /*
- X Make a closing node and hook it on the end.
- X */
- X ender=Node((parenthesized) ? Close+count : EndOfProgram);
- X Tail(status,ender);
- X /*
- X Hook the tails of the branches to the closing node.
- X */
- X for(br=status; br != NULL; br=NextToken(br))
- X OpTail(br,ender);
- X /*
- X Check for proper termination.
- X */
- X if (parenthesized && (*token++ != ')'))
- X Fail("unmatched()")
- X else
- X if (!parenthesized && (*token != '\0'))
- X {
- X if (*token == ')')
- X Fail("unmatched()")
- X else
- X Fail("junk on end")
- X }
- X return(status);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % R e p e a t %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static int Repeat(p)
- char
- X *p;
- {
- X register char
- X *operand,
- X *scan;
- X
- X register int
- X count=0;
- X
- X scan=p;
- X operand=Operand(p);
- X switch(OpCode(p))
- X {
- X case MatchAnyCharacter:
- X {
- X count=strlen(scan);
- X scan+=count;
- X break;
- X }
- X case MatchExactly:
- X {
- X while (*operand == *scan)
- X {
- X count++;
- X scan++;
- X }
- X break;
- X }
- X case MatchAnyCharacterOf:
- X {
- X while ((*scan != '\0') && (strchr(operand,*scan) != NULL))
- X {
- X count++;
- X scan++;
- X }
- X break;
- X }
- X case MatchAnyCharacterBut:
- X {
- X while ((*scan != '\0') && (strchr(operand,*scan) == NULL))
- X {
- X count++;
- X scan++;
- X }
- X break;
- X }
- X default:
- X {
- X (void) fprintf(stderr,"Regular(3): %s","internal foulup");
- X count=0;
- X break;
- X }
- X }
- X p=scan;
- X return(count);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % T a i l %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static void Tail(p,val)
- char
- X *p;
- X
- char
- X *val;
- {
- X register char
- X *scan,
- X *temp;
- X
- X register int
- X offset;
- X
- X if (p == &start_code)
- X return;
- X /*
- X Find last node.
- X */
- X scan=p;
- X for(;;)
- X {
- X temp=NextToken(scan);
- X if (temp == NULL)
- X break;
- X scan=temp;
- X }
- X if (OpCode(scan) == Back)
- X offset=scan-val;
- X else
- X offset=val-scan;
- X *(scan+1)=(offset >> 8) & 0377;
- X *(scan+2)=offset & 0377;
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % T r y %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- static int Try(regular_expression,pattern)
- RegularExpression
- X *regular_expression;
- X
- char
- X *pattern;
- {
- X register char
- X **ep,
- X **sp;
- X
- X register int
- X i;
- X
- X p=pattern;
- X subpattern=regular_expression->subpattern;
- X subpattern_end=regular_expression->subpattern_end;
- X sp=regular_expression->subpattern;
- X ep=regular_expression->subpattern_end;
- X for(i=NumberSubExpressions; i > 0; i--)
- X {
- X *sp++=NULL;
- X *ep++=NULL;
- X }
- X if (!Match(regular_expression->program+1))
- X return(0);
- X else
- X {
- X regular_expression->subpattern[0]=pattern;
- X regular_expression->subpattern_end[0]=p;
- X return(1);
- X }
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % C o m p i l e R e g u l a r E x p r e s s i o n %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function CompileRegularExpression compiles a regular expression into a
- % structure of type RegularExpression and returns a pointer to it. The space
- % is allocated using function malloc and may be released by function free.
- %
- %
- */
- RegularExpression *CompileRegularExpression(regular_expression)
- char
- X *regular_expression;
- {
- X int
- X flags;
- X
- X register char
- X *longest,
- X *scan;
- X
- X register RegularExpression
- X *r;
- X
- X register int
- X length;
- X
- X if (regular_expression == NULL)
- X Fail("NULL argument");
- X /*
- X First pass: determine size.
- X */
- X token=regular_expression;
- X number_parenthesis=1;
- X code_size=0L;
- X code=(&start_code);
- X EmitCode(Magick);
- X if (Regular(0,&flags) == NULL)
- X return(NULL);
- X /*
- X Allocate space.
- X */
- X r=(RegularExpression *) malloc((code_size+sizeof(RegularExpression)));
- X if (r == (RegularExpression *) NULL)
- X Fail("out of space");
- X /*
- X Second pass: emit code.
- X */
- X token=regular_expression;
- X number_parenthesis=1;
- X code=r->program;
- X EmitCode(Magick);
- X if (Regular(0,&flags) == NULL)
- X return(NULL);
- X /*
- X Dig out information for optimizations.
- X */
- X r->start_character='\0';
- X r->anchor=0;
- X r->priority_pattern=NULL;
- X r->pattern_length=0;
- X scan=r->program+1;
- X if (OpCode(NextToken(scan)) == EndOfProgram)
- X {
- X scan=Operand(scan);
- X if (OpCode(scan) == MatchExactly)
- X r->start_character=(*Operand(scan));
- X else
- X if (OpCode(scan) == MatchBeginningOfLine)
- X r->anchor++;
- X /*
- X If there's something expensive in the regular expression, find the
- X longest literal pattern that must appear and make it the
- X priority_pattern.
- X */
- X if (flags & SpecialStart)
- X {
- X longest=NULL;
- X length=0;
- X for(; scan != NULL; scan=NextToken(scan))
- X if ((OpCode(scan) == MatchExactly) &&
- X (strlen(Operand(scan)) >= length))
- X {
- X longest=Operand(scan);
- X length=strlen(Operand(scan));
- X }
- X r->priority_pattern=longest;
- X r->pattern_length=length;
- X }
- X }
- X return(r);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % E x e c u t e R e g u l a r E x p r e s s i o n %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function ExecuteRegularExpression matches a NULL-terminated pattern against
- % the compiled regular expression in regular-expression. It returns 1 for
- % success and 0 for failure.
- %
- %
- */
- int ExecuteRegularExpression(regular_expression,pattern)
- register RegularExpression
- X *regular_expression;
- X
- register char
- X *pattern;
- {
- X register char
- X *s;
- X
- X if ((regular_expression == (RegularExpression *) NULL) ||
- X (pattern == (char *) NULL))
- X {
- X (void) fprintf(stderr,"Regular(3): %s","NULL parameter\n");
- X return(0);
- X }
- X /*
- X Check validity of program.
- X */
- X if (((int)*(unsigned char *)(regular_expression->program)) != Magick)
- X {
- X (void) fprintf(stderr,"Regular(3): %s","corrupted program");
- X return(0);
- X }
- X /*
- X If there is a "must appear" pattern, look for it.
- X */
- X if (regular_expression->priority_pattern != NULL)
- X {
- X s=pattern;
- X while ((s=strchr(s,regular_expression->priority_pattern[0])) != NULL)
- X {
- X if (strncmp(s,regular_expression->priority_pattern,
- X regular_expression->pattern_length) == 0)
- X break;
- X s++;
- X }
- X if (s == NULL)
- X return(0);
- X }
- X /*
- X Mark beginning of line for ^.
- X */
- X start_pattern=pattern;
- X /*
- X Simplest case: anchored match need be tried only once.
- X */
- X if (regular_expression->anchor)
- X return(Try(regular_expression,pattern));
- X /*
- X Messy cases: unanchored match.
- X */
- X s=pattern;
- X if (regular_expression->start_character != '\0')
- X while ((s=strchr(s,regular_expression->start_character)) != NULL)
- X {
- X if (Try(regular_expression,s))
- X return(1);
- X s++;
- X }
- X else
- X do
- X {
- X if (Try(regular_expression,s))
- X return(1);
- X } while (*s++ != '\0');
- X return(0);
- }
- SHAR_EOF
- echo 'File ImageMagick/xtp/regular.c is complete' &&
- chmod 0644 ImageMagick/xtp/regular.c ||
- echo 'restore of ImageMagick/xtp/regular.c failed'
- Wc_c="`wc -c < 'ImageMagick/xtp/regular.c'`"
- test 36656 -eq "$Wc_c" ||
- echo 'ImageMagick/xtp/regular.c: original size 36656, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ImageMagick/xtp/regular.h ==============
- if test -f 'ImageMagick/xtp/regular.h' -a X"$1" != X"-c"; then
- echo 'x - skipping ImageMagick/xtp/regular.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ImageMagick/xtp/regular.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/xtp/regular.h' &&
- /*
- X Definitions etc. for RegularExpression(3) routines.
- */
- #define EndOfProgram 0
- #define MatchBeginningOfLine 1
- #define MatchEndOfProgramOfLine 2
- #define MatchAnyCharacter 3
- #define MatchAnyCharacterOf 4
- #define MatchAnyCharacterBut 5
- #define MatchThisOrNext 6
- #define Back 7
- #define MatchExactly 8
- #define MatchEmptyString 9
- #define MatchZeroOrMore 10
- #define MatchOneOrMore 11
- #define Open 20
- #define Close 30
- X
- #define WorstCase 0
- #define NonNull 1
- #define Simple 2
- #define SpecialStart 4
- X
- #define Fail(m) \
- { \
- X (void) fprintf(stderr,"RegularExpression: %s\n",m); \
- X return(NULL); \
- }
- #define Magick 0234
- #define Meta "^$.[()|?+*\\"
- #define MultipleMatches(c) (((c) == '*') || ((c) == '+') || ((c) == '?'))
- #define Next(p) (((*((p)+1) & 0377) << 8 )+(*((p)+2) & 0377))
- #define NumberSubExpressions 10
- #define OpCode(p) (*(p))
- #define Operand(p) ((p)+3)
- X
- typedef struct _RegularExpression
- {
- X char
- X *subpattern[NumberSubExpressions],
- X *subpattern_end[NumberSubExpressions],
- X start_character,
- X anchor,
- X *priority_pattern;
- X
- X int
- X pattern_length;
- X
- X char
- X program[1];
- } RegularExpression;
- X
- extern RegularExpression
- X *CompileRegularExpression _Declare((char *));
- X
- extern int
- X ExecuteRegularExpression _Declare((RegularExpression *,char *));
- SHAR_EOF
- chmod 0644 ImageMagick/xtp/regular.h ||
- echo 'restore of ImageMagick/xtp/regular.h failed'
- Wc_c="`wc -c < 'ImageMagick/xtp/regular.h'`"
- test 1299 -eq "$Wc_c" ||
- echo 'ImageMagick/xtp/regular.h: original size 1299, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ImageMagick/xtp/xtp.c ==============
- if test -f 'ImageMagick/xtp/xtp.c' -a X"$1" != X"-c"; then
- echo 'x - skipping ImageMagick/xtp/xtp.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ImageMagick/xtp/xtp.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/xtp/xtp.c' &&
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % X X TTTTT PPPP %
- % X X T P P %
- % X T PPPP %
- % X X T P %
- % X X T P %
- % %
- % %
- % File transfer program. %
- % %
- % %
- % %
- % Software Design %
- % John Cristy %
- % October 1992 %
- % %
- % %
- % Copyright 1992 E. I. Dupont de Nemours & Company %
- % %
- % Permission to use, copy, modify, distribute, and sell this software and %
- % its documentation for any purpose is hereby granted without fee, %
- % provided that the above copyright notice appear in all copies and that %
- % both that copyright notice and this permission notice appear in %
- % supporting documentation, and that the name of E. I. Dupont de Nemours %
- % & Company not be used in advertising or publicity pertaining to %
- % distribution of the software without specific, written prior %
- % permission. E. I. Dupont de Nemours & Company makes no representations %
- % about the suitability of this software for any purpose. It is provided %
- % "as is" without express or implied warranty. %
- % %
- % E. I. Dupont de Nemours & Company disclaims all warranties with regard %
- % to this software, including all implied warranties of merchantability %
- % and fitness, in no event shall E. I. Dupont de Nemours & Company be %
- % liable for any special, indirect or consequential damages or any %
- % damages whatsoever resulting from loss of use, data or profits, whether %
- % in an action of contract, negligence or other tortious action, arising %
- % out of or in connection with the use or performance of this software. %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Xtp is a utility for retrieving, listing, or printing files from a
- % remote network site. Xtp performs most of the same functions as the
- % FTP program, but does not require any interactive commands. You simply
- % specify the file transfer task on the command line and xtp performs the
- % transfer automatically.
- %
- % This program was adapted from a similiar program written by Steve Singles,
- % University of Delaware.
- %
- % Command syntax:
- %
- % Usage: xtp [-options ...] <host/ip address> [ <home directory> ]
- %
- % Where options include:
- % -binary retrieve files as binary
- % -exclude expression exclude files that match the expression
- % -directory expression list file names that match the expression
- % -ident password specifies password
- % -port number port number of FTP server
- % -print expression print files that match the expression
- % -prune do not recursively search for files
- % -retrieve expression retrieve files that match the expression
- % -send expression send files that match the expression
- % -timeout seconds specifies maximum seconds of XTP session
- % -user name identify yourself to the remote FTP server
- %
- %
- */
- X
- /*
- X Include declarations.
- */
- #define _POSIX_SOURCE 1
- #include "xtp.h"
- #include "regular.h"
- #include <unistd.h>
- #include <sys/types.h>
- #include <signal.h>
- #include <termios.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/wait.h>
- /*
- X Variable declarations.
- */
- static char
- X *application_name,
- X slave_tty[16];
- X
- static int
- X master,
- X status;
- X
- static RegularExpression
- X *directory_expression,
- X *exclude_expression,
- X *print_expression,
- X *retrieve_expression;
- X
- /*
- X External declarations.
- */
- extern char
- X *GetHostInfo _Declare((char *));
- X
- /*
- X Forward declarations.
- */
- static char
- X *Wait _Declare((void));
- X
- static void
- X DirectoryRequest _Declare((char *, char *)),
- X PrintRequest _Declare((char *,unsigned int)),
- X RetrieveRequest _Declare((char *,unsigned int));
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % D i r e c t o r y R e q u e s t %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function DirectoryRequest lists a file name and its attributes.
- %
- % The format of the DirectoryRequest routine is:
- %
- % DirectoryRequest(fileinfo,filename)
- %
- % A description of each parameter follows:
- %
- % o filename: Specifies a pointer to a character array that contains
- % information about the file.
- %
- % o filename: Specifies a pointer to a character array that contains
- % the name of the file.
- %
- */
- static void DirectoryRequest(fileinfo,filename)
- char
- X *fileinfo,
- X *filename;
- {
- X status=0;
- X if (*fileinfo == '\0')
- X (void) fprintf(stdout,"%s\n",filename);
- X else
- X (void) fprintf(stdout,"%s %s\n",fileinfo,filename);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % E r r o r %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function Error displays an error message and then terminates the program.
- %
- % The format of the Error routine is:
- %
- % Error(message,qualifier)
- %
- % A description of each parameter follows:
- %
- % o message: Specifies the message to display before terminating the
- % program.
- %
- % o qualifier: Specifies any qualifier to the message.
- %
- %
- */
- void Error(message,qualifier)
- char
- X *message,
- X *qualifier;
- {
- X (void) fprintf(stderr,"%s: %s",application_name,message);
- X if (qualifier != (char *) NULL)
- X (void) fprintf(stderr," (%s)",qualifier);
- X (void) fprintf(stderr,".\n");
- X exit(1);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % E x e c u t e F t p %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function ExecuteFtp executes the FTP program as a child process.
- %
- % The format of the ExecuteFtp routine is:
- %
- % ExecuteFtp(host_name,port)
- %
- % A description of each parameter follows:
- %
- % o host_name: Specifies a pointer to a character array that contains the
- % name of the host to establish a connection to a FTP server.
- %
- % o port: Specifies a port number. If the port number is NULL, xtp
- % attempts to contact a FTP server at the default port.
- %
- %
- %
- */
- static void ExecuteFtp(host_name,port)
- char
- X *host_name,
- X *port;
- {
- X int
- X slave;
- X
- X struct sigaction
- X action;
- X
- X struct termios
- X attributes;
- X
- X /*
- X Get slave tty line.
- X */
- X action.sa_handler=SIG_IGN;
- X (void) sigemptyset(&action.sa_mask);
- X action.sa_flags=0;
- X (void) sigaction(SIGTSTP,&action,(struct sigaction *) NULL);
- X if (isatty(STDIN_FILENO))
- X (void) setsid();
- X slave=open(slave_tty,O_RDWR | O_NOCTTY);
- X if (slave < 0)
- X Error("unable to open slave pseudo-terminal",slave_tty);
- X /*
- X Condition slave tty line.
- X */
- X (void) tcgetattr(slave,&attributes);
- X attributes.c_cflag|=HUPCL;
- X attributes.c_lflag&=(~(ICANON | ECHO));
- X attributes.c_oflag&=(~OPOST);
- X (void) tcflush(slave,TCIFLUSH);
- X (void) tcsetattr(slave,TCSANOW,&attributes);
- X /*
- X Execute FTP program as a child process.
- X */
- X (void) close(master);
- X (void) dup2(slave,STDIN_FILENO);
- X (void) dup2(slave,STDOUT_FILENO);
- X (void) dup2(slave,STDERR_FILENO);
- X (void) close(slave);
- X (void) execlp("ftp","ftp","-n","-i","-g","-v",host_name,port,(char *) 0);
- X perror("ftp");
- X (void) kill(0,SIGTERM);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % G e t P a s s w o r d %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function GetPassword prompts the user for a password. The password is
- % not echoed on the terminal.
- %
- % The format of the GetPassword routine is:
- %
- % password=GetPassword(prompt)
- %
- % A description of each parameter follows:
- %
- % o password: Specifies a pointer to a character array that contains
- % accepted from the user.
- %
- % o prompt: Specifies a pointer to a character array that contains
- % a message to display to the user.
- %
- %
- */
- static char *GetPassword(prompt)
- char
- X *prompt;
- {
- X static char
- X password[2048];
- X
- X struct termios
- X attributes;
- X
- X (void) fprintf(stdout,"%s",prompt);
- X (void) fflush(stdout);
- X (void) tcgetattr(STDIN_FILENO,&attributes);
- X attributes.c_lflag&=(~ECHO);
- X (void) tcsetattr(STDIN_FILENO,TCSANOW,&attributes);
- X gets(password);
- X attributes.c_lflag|=ECHO;
- X (void) tcsetattr(STDIN_FILENO,TCSANOW,&attributes);
- X (void) fprintf(stdout,"\n");
- X return(password);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % G e t P s e u d o T e r m i n a l %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function GetPseudoTerminal returns a master/slave pair of pseudo-terminals.
- %
- % The format of the GetPseudoTerminal routine is:
- %
- % GetPseudoTerminal()
- %
- %
- */
- static void GetPseudoTerminal()
- {
- X char
- X master_tty[16];
- X
- X register char
- X *bank,
- X *cp;
- X
- X struct stat
- X info;
- X
- X for (bank="pqrs"; *bank; bank++)
- X {
- X (void) sprintf(master_tty,"/dev/pty%c0",*bank);
- X if (stat(master_tty,&info) < 0)
- X break;
- X for (cp="0123456789abcdef"; *cp; cp++)
- X {
- X (void) sprintf((char *) master_tty,"/dev/pty%c%c",*bank,*cp);
- X master=open(master_tty,O_RDWR);
- X if (master >= 0)
- X {
- X /*
- X Verify slave side is usable.
- X */
- X (void) sprintf(slave_tty,"/dev/tty%c%c",*bank,*cp);
- X if (access(slave_tty,R_OK | W_OK) == 0)
- X {
- X struct termios
- X attributes;
- X
- X /*
- X Condition master tty line.
- X */
- X (void) tcgetattr(master,&attributes);
- X attributes.c_lflag&=(~(ICANON | ECHO));
- X (void) tcsetattr(master,TCSANOW,&attributes);
- X return;
- X }
- X (void) close(master);
- X }
- X }
- X }
- X Error("All network ports in use",(char *) NULL);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % M a k e D i r e c t o r y %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function MakeDirectory checks each component of a directory path and if it
- % does not exist, creates it.
- %
- % The format of the MakeDirectory routine is:
- %
- % MakeDirectory(directory)
- %
- % A description of each parameter follows:
- %
- % o directory: Specifies a pointer to a character array that contains
- % the name of the directory to create.
- %
- %
- */
- static int MakeDirectory(directory)
- char
- X *directory;
- {
- X register char
- X *p;
- X
- X struct stat
- X info;
- X
- X /*
- X Determine first component of the directory.
- X */
- X p=strrchr(directory,'/');
- X if ((p == (char *) NULL) || (p == directory))
- X return(False);
- X *p='\0';
- X if (lstat(directory,&info) < 0)
- X {
- X /*
- X Path component does not exist; create it.
- X */
- X if (MakeDirectory(directory) == 0)
- X if (mkdir(directory,(mode_t) 0777) >= 0)
- X {
- X *p='/';
- X return(False);
- X }
- X }
- X else
- X if (S_ISDIR(info.st_mode))
- X {
- X /*
- X Path component already exists.
- X */
- X *p='/';
- X return(False);
- X }
- X /*
- X Path component is a file not a directory.
- X */
- X *p='/';
- X return(True);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % P r i n t R e q u e s t %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function PrintRequest prints a file on the remote FTP server.
- %
- % The format of the PrintRequest routine is:
- %
- % PrintRequest(filename,verbose)
- %
- % A description of each parameter follows:
- %
- % o filename: Specifies a pointer to a character array that contains
- % the name of the file to print.
- %
- % o verbose: An unsigned integer. A value other than zero dhows all
- % responses from the remote server.
- %
- %
- */
- static void PrintRequest(filename,verbose)
- char
- X *filename;
- X
- unsigned int
- X verbose;
- {
- X char
- X command[2048],
- X *response;
- X
- X /*
- X get remote-file [ - | < |zcat > ].
- X */
- X (void) sprintf(command,"get %s",filename);
- X if (strcmp(filename+strlen(filename)-2,".Z"))
- X (void) strcat(command," -\r");
- X else
- X (void) strcat(command," |zcat\r");
- X (void) write(master,command,strlen(command));
- X (void) fprintf(stdout,"%s:\n",filename);
- X while (response=Wait())
- X if (status == 0)
- X (void) fprintf(stdout,"%s\n",response);
- X else
- X if ((status == 5) || verbose)
- X (void) fprintf(stderr,"%s\n",response);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % P r o c e s s R e q u e s t %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function ProcessRequest first records any file in the current directory
- % of the remote FTP server or any of its subdirectories. Next each filename
- % is either accepted or rejected based on a user specified regular
- % expresssion. If any files match the regular expression, its filename is
- % listed, it is printed, or it is retrieved as specified on the command line.
- %
- % The format of the ProcessRequest routine is:
- %
- % ProcessRequest(prune,verbose)
- SHAR_EOF
- true || echo 'restore of ImageMagick/xtp/xtp.c failed'
- fi
- echo 'End of part 3'
- echo 'File ImageMagick/xtp/xtp.c is continued in part 4'
- echo 4 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
-