Newsgroups: comp.sources.unix From: robert.corbett@eng.Sun.COM (Roger Corbett) Subject: v26i291: byacc-1.9 - Berkeley YACC, Part03/03 Sender: unix-sources-moderator@gw.home.vix.com Approved: vixie@gw.home.vix.com Submitted-By: robert.corbett@eng.Sun.COM (Roger Corbett) Posting-Number: Volume 26, Issue 291 Archive-Name: byacc-1.9/part03 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'reader.c' <<'END_OF_FILE' X#include "defs.h" X X/* The line size must be a positive integer. One hundred was chosen */ X/* because few lines in Yacc input grammars exceed 100 characters. */ X/* Note that if a line exceeds LINESIZE characters, the line buffer */ X/* will be expanded to accomodate it. */ X X#define LINESIZE 100 X Xchar *cache; Xint cinc, cache_size; X Xint ntags, tagmax; Xchar **tag_table; X Xchar saw_eof, unionized; Xchar *cptr, *line; Xint linesize; X Xbucket *goal; Xint prec; Xint gensym; Xchar last_was_action; X Xint maxitems; Xbucket **pitem; X Xint maxrules; Xbucket **plhs; X Xint name_pool_size; Xchar *name_pool; X Xchar line_format[] = "#line %d \"%s\"\n"; X X Xcachec(c) Xint c; X{ X assert(cinc >= 0); X if (cinc >= cache_size) X { X cache_size += 256; X cache = REALLOC(cache, cache_size); X if (cache == 0) no_space(); X } X cache[cinc] = c; X ++cinc; X} X X Xget_line() X{ X register FILE *f = input_file; X register int c; X register int i; X X if (saw_eof || (c = getc(f)) == EOF) X { X if (line) { FREE(line); line = 0; } X cptr = 0; X saw_eof = 1; X return; X } X X if (line == 0 || linesize != (LINESIZE + 1)) X { X if (line) FREE(line); X linesize = LINESIZE + 1; X line = MALLOC(linesize); X if (line == 0) no_space(); X } X X i = 0; X ++lineno; X for (;;) X { X line[i] = c; X if (c == '\n') { cptr = line; return; } X if (++i >= linesize) X { X linesize += LINESIZE; X line = REALLOC(line, linesize); X if (line == 0) no_space(); X } X c = getc(f); X if (c == EOF) X { X line[i] = '\n'; X saw_eof = 1; X cptr = line; X return; X } X } X} X X Xchar * Xdup_line() X{ X register char *p, *s, *t; X X if (line == 0) return (0); X s = line; X while (*s != '\n') ++s; X p = MALLOC(s - line + 1); X if (p == 0) no_space(); X X s = line; X t = p; X while ((*t++ = *s++) != '\n') continue; X return (p); X} X X Xskip_comment() X{ X register char *s; X X int st_lineno = lineno; X char *st_line = dup_line(); X char *st_cptr = st_line + (cptr - line); X X s = cptr + 2; X for (;;) X { X if (*s == '*' && s[1] == '/') X { X cptr = s + 2; X FREE(st_line); X return; X } X if (*s == '\n') X { X get_line(); X if (line == 0) X unterminated_comment(st_lineno, st_line, st_cptr); X s = cptr; X } X else X ++s; X } X} X X Xint Xnextc() X{ X register char *s; X X if (line == 0) X { X get_line(); X if (line == 0) X return (EOF); X } X X s = cptr; X for (;;) X { X switch (*s) X { X case '\n': X get_line(); X if (line == 0) return (EOF); X s = cptr; X break; X X case ' ': X case '\t': X case '\f': X case '\r': X case '\v': X case ',': X case ';': X ++s; X break; X X case '\\': X cptr = s; X return ('%'); X X case '/': X if (s[1] == '*') X { X cptr = s; X skip_comment(); X s = cptr; X break; X } X else if (s[1] == '/') X { X get_line(); X if (line == 0) return (EOF); X s = cptr; X break; X } X /* fall through */ X X default: X cptr = s; X return (*s); X } X } X} X X Xint Xkeyword() X{ X register int c; X char *t_cptr = cptr; X X c = *++cptr; X if (isalpha(c)) X { X cinc = 0; X for (;;) X { X if (isalpha(c)) X { X if (isupper(c)) c = tolower(c); X cachec(c); X } X else if (isdigit(c) || c == '_' || c == '.' || c == '$') X cachec(c); X else X break; X c = *++cptr; X } X cachec(NUL); X X if (strcmp(cache, "token") == 0 || strcmp(cache, "term") == 0) X return (TOKEN); X if (strcmp(cache, "type") == 0) X return (TYPE); X if (strcmp(cache, "left") == 0) X return (LEFT); X if (strcmp(cache, "right") == 0) X return (RIGHT); X if (strcmp(cache, "nonassoc") == 0 || strcmp(cache, "binary") == 0) X return (NONASSOC); X if (strcmp(cache, "start") == 0) X return (START); X if (strcmp(cache, "union") == 0) X return (UNION); X if (strcmp(cache, "ident") == 0) X return (IDENT); X } X else X { X ++cptr; X if (c == '{') X return (TEXT); X if (c == '%' || c == '\\') X return (MARK); X if (c == '<') X return (LEFT); X if (c == '>') X return (RIGHT); X if (c == '0') X return (TOKEN); X if (c == '2') X return (NONASSOC); X } X syntax_error(lineno, line, t_cptr); X /*NOTREACHED*/ X} X X Xcopy_ident() X{ X register int c; X register FILE *f = output_file; X X c = nextc(); X if (c == EOF) unexpected_EOF(); X if (c != '"') syntax_error(lineno, line, cptr); X ++outline; X fprintf(f, "#ident \""); X for (;;) X { X c = *++cptr; X if (c == '\n') X { X fprintf(f, "\"\n"); X return; X } X putc(c, f); X if (c == '"') X { X putc('\n', f); X ++cptr; X return; X } X } X} X X Xcopy_text() X{ X register int c; X int quote; X register FILE *f = text_file; X int need_newline = 0; X int t_lineno = lineno; X char *t_line = dup_line(); X char *t_cptr = t_line + (cptr - line - 2); X X if (*cptr == '\n') X { X get_line(); X if (line == 0) X unterminated_text(t_lineno, t_line, t_cptr); X } X if (!lflag) fprintf(f, line_format, lineno, input_file_name); X Xloop: X c = *cptr++; X switch (c) X { X case '\n': X next_line: X putc('\n', f); X need_newline = 0; X get_line(); X if (line) goto loop; X unterminated_text(t_lineno, t_line, t_cptr); X X case '\'': X case '"': X { X int s_lineno = lineno; X char *s_line = dup_line(); X char *s_cptr = s_line + (cptr - line - 1); X X quote = c; X putc(c, f); X for (;;) X { X c = *cptr++; X putc(c, f); X if (c == quote) X { X need_newline = 1; X FREE(s_line); X goto loop; X } X if (c == '\n') X unterminated_string(s_lineno, s_line, s_cptr); X if (c == '\\') X { X c = *cptr++; X putc(c, f); X if (c == '\n') X { X get_line(); X if (line == 0) X unterminated_string(s_lineno, s_line, s_cptr); X } X } X } X } X X case '/': X putc(c, f); X need_newline = 1; X c = *cptr; X if (c == '/') X { X putc('*', f); X while ((c = *++cptr) != '\n') X { X if (c == '*' && cptr[1] == '/') X fprintf(f, "* "); X else X putc(c, f); X } X fprintf(f, "*/"); X goto next_line; X } X if (c == '*') X { X int c_lineno = lineno; X char *c_line = dup_line(); X char *c_cptr = c_line + (cptr - line - 1); X X putc('*', f); X ++cptr; X for (;;) X { X c = *cptr++; X putc(c, f); X if (c == '*' && *cptr == '/') X { X putc('/', f); X ++cptr; X FREE(c_line); X goto loop; X } X if (c == '\n') X { X get_line(); X if (line == 0) X unterminated_comment(c_lineno, c_line, c_cptr); X } X } X } X need_newline = 1; X goto loop; X X case '%': X case '\\': X if (*cptr == '}') X { X if (need_newline) putc('\n', f); X ++cptr; X FREE(t_line); X return; X } X /* fall through */ X X default: X putc(c, f); X need_newline = 1; X goto loop; X } X} X X Xcopy_union() X{ X register int c; X int quote; X int depth; X int u_lineno = lineno; X char *u_line = dup_line(); X char *u_cptr = u_line + (cptr - line - 6); X X if (unionized) over_unionized(cptr - 6); X unionized = 1; X X if (!lflag) X fprintf(text_file, line_format, lineno, input_file_name); X X fprintf(text_file, "typedef union"); X if (dflag) fprintf(union_file, "typedef union"); X X depth = 0; Xloop: X c = *cptr++; X putc(c, text_file); X if (dflag) putc(c, union_file); X switch (c) X { X case '\n': X next_line: X get_line(); X if (line == 0) unterminated_union(u_lineno, u_line, u_cptr); X goto loop; X X case '{': X ++depth; X goto loop; X X case '}': X if (--depth == 0) X { X fprintf(text_file, " YYSTYPE;\n"); X FREE(u_line); X return; X } X goto loop; X X case '\'': X case '"': X { X int s_lineno = lineno; X char *s_line = dup_line(); X char *s_cptr = s_line + (cptr - line - 1); X X quote = c; X for (;;) X { X c = *cptr++; X putc(c, text_file); X if (dflag) putc(c, union_file); X if (c == quote) X { X FREE(s_line); X goto loop; X } X if (c == '\n') X unterminated_string(s_lineno, s_line, s_cptr); X if (c == '\\') X { X c = *cptr++; X putc(c, text_file); X if (dflag) putc(c, union_file); X if (c == '\n') X { X get_line(); X if (line == 0) X unterminated_string(s_lineno, s_line, s_cptr); X } X } X } X } X X case '/': X c = *cptr; X if (c == '/') X { X putc('*', text_file); X if (dflag) putc('*', union_file); X while ((c = *++cptr) != '\n') X { X if (c == '*' && cptr[1] == '/') X { X fprintf(text_file, "* "); X if (dflag) fprintf(union_file, "* "); X } X else X { X putc(c, text_file); X if (dflag) putc(c, union_file); X } X } X fprintf(text_file, "*/\n"); X if (dflag) fprintf(union_file, "*/\n"); X goto next_line; X } X if (c == '*') X { X int c_lineno = lineno; X char *c_line = dup_line(); X char *c_cptr = c_line + (cptr - line - 1); X X putc('*', text_file); X if (dflag) putc('*', union_file); X ++cptr; X for (;;) X { X c = *cptr++; X putc(c, text_file); X if (dflag) putc(c, union_file); X if (c == '*' && *cptr == '/') X { X putc('/', text_file); X if (dflag) putc('/', union_file); X ++cptr; X FREE(c_line); X goto loop; X } X if (c == '\n') X { X get_line(); X if (line == 0) X unterminated_comment(c_lineno, c_line, c_cptr); X } X } X } X goto loop; X X default: X goto loop; X } X} X X Xint Xhexval(c) Xint c; X{ X if (c >= '0' && c <= '9') X return (c - '0'); X if (c >= 'A' && c <= 'F') X return (c - 'A' + 10); X if (c >= 'a' && c <= 'f') X return (c - 'a' + 10); X return (-1); X} X X Xbucket * Xget_literal() X{ X register int c, quote; X register int i; X register int n; X register char *s; X register bucket *bp; X int s_lineno = lineno; X char *s_line = dup_line(); X char *s_cptr = s_line + (cptr - line); X X quote = *cptr++; X cinc = 0; X for (;;) X { X c = *cptr++; X if (c == quote) break; X if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr); X if (c == '\\') X { X char *c_cptr = cptr - 1; X X c = *cptr++; X switch (c) X { X case '\n': X get_line(); X if (line == 0) unterminated_string(s_lineno, s_line, s_cptr); X continue; X X case '0': case '1': case '2': case '3': X case '4': case '5': case '6': case '7': X n = c - '0'; X c = *cptr; X if (IS_OCTAL(c)) X { X n = (n << 3) + (c - '0'); X c = *++cptr; X if (IS_OCTAL(c)) X { X n = (n << 3) + (c - '0'); X ++cptr; X } X } X if (n > MAXCHAR) illegal_character(c_cptr); X c = n; X break; X X case 'x': X c = *cptr++; X n = hexval(c); X if (n < 0 || n >= 16) X illegal_character(c_cptr); X for (;;) X { X c = *cptr; X i = hexval(c); X if (i < 0 || i >= 16) break; X ++cptr; X n = (n << 4) + i; X if (n > MAXCHAR) illegal_character(c_cptr); X } X c = n; X break; X X case 'a': c = 7; break; X case 'b': c = '\b'; break; X case 'f': c = '\f'; break; X case 'n': c = '\n'; break; X case 'r': c = '\r'; break; X case 't': c = '\t'; break; X case 'v': c = '\v'; break; X } X } X cachec(c); X } X FREE(s_line); X X n = cinc; X s = MALLOC(n); X if (s == 0) no_space(); X X for (i = 0; i < n; ++i) X s[i] = cache[i]; X X cinc = 0; X if (n == 1) X cachec('\''); X else X cachec('"'); X X for (i = 0; i < n; ++i) X { X c = ((unsigned char *)s)[i]; X if (c == '\\' || c == cache[0]) X { X cachec('\\'); X cachec(c); X } X else if (isprint(c)) X cachec(c); X else X { X cachec('\\'); X switch (c) X { X case 7: cachec('a'); break; X case '\b': cachec('b'); break; X case '\f': cachec('f'); break; X case '\n': cachec('n'); break; X case '\r': cachec('r'); break; X case '\t': cachec('t'); break; X case '\v': cachec('v'); break; X default: X cachec(((c >> 6) & 7) + '0'); X cachec(((c >> 3) & 7) + '0'); X cachec((c & 7) + '0'); X break; X } X } X } X X if (n == 1) X cachec('\''); X else X cachec('"'); X X cachec(NUL); X bp = lookup(cache); X bp->class = TERM; X if (n == 1 && bp->value == UNDEFINED) X bp->value = *(unsigned char *)s; X FREE(s); X X return (bp); X} X X Xint Xis_reserved(name) Xchar *name; X{ X char *s; X X if (strcmp(name, ".") == 0 || X strcmp(name, "$accept") == 0 || X strcmp(name, "$end") == 0) X return (1); X X if (name[0] == '$' && name[1] == '$' && isdigit(name[2])) X { X s = name + 3; X while (isdigit(*s)) ++s; X if (*s == NUL) return (1); X } X X return (0); X} X X Xbucket * Xget_name() X{ X register int c; X X cinc = 0; X for (c = *cptr; IS_IDENT(c); c = *++cptr) X cachec(c); X cachec(NUL); X X if (is_reserved(cache)) used_reserved(cache); X X return (lookup(cache)); X} X X Xint Xget_number() X{ X register int c; X register int n; X X n = 0; X for (c = *cptr; isdigit(c); c = *++cptr) X n = 10*n + (c - '0'); X X return (n); X} X X Xchar * Xget_tag() X{ X register int c; X register int i; X register char *s; X int t_lineno = lineno; X char *t_line = dup_line(); X char *t_cptr = t_line + (cptr - line); X X ++cptr; X c = nextc(); X if (c == EOF) unexpected_EOF(); X if (!isalpha(c) && c != '_' && c != '$') X illegal_tag(t_lineno, t_line, t_cptr); X X cinc = 0; X do { cachec(c); c = *++cptr; } while (IS_IDENT(c)); X cachec(NUL); X X c = nextc(); X if (c == EOF) unexpected_EOF(); X if (c != '>') X illegal_tag(t_lineno, t_line, t_cptr); X ++cptr; X X for (i = 0; i < ntags; ++i) X { X if (strcmp(cache, tag_table[i]) == 0) X return (tag_table[i]); X } X X if (ntags >= tagmax) X { X tagmax += 16; X tag_table = (char **) X (tag_table ? REALLOC(tag_table, tagmax*sizeof(char *)) X : MALLOC(tagmax*sizeof(char *))); X if (tag_table == 0) no_space(); X } X X s = MALLOC(cinc); X if (s == 0) no_space(); X strcpy(s, cache); X tag_table[ntags] = s; X ++ntags; X FREE(t_line); X return (s); X} X X Xdeclare_tokens(assoc) Xint assoc; X{ X register int c; X register bucket *bp; X int value; X char *tag = 0; X X if (assoc != TOKEN) ++prec; X X c = nextc(); X if (c == EOF) unexpected_EOF(); X if (c == '<') X { X tag = get_tag(); X c = nextc(); X if (c == EOF) unexpected_EOF(); X } X X for (;;) X { X if (isalpha(c) || c == '_' || c == '.' || c == '$') X bp = get_name(); X else if (c == '\'' || c == '"') X bp = get_literal(); X else X return; X X if (bp == goal) tokenized_start(bp->name); X bp->class = TERM; X X if (tag) X { X if (bp->tag && tag != bp->tag) X retyped_warning(bp->name); X bp->tag = tag; X } X X if (assoc != TOKEN) X { X if (bp->prec && prec != bp->prec) X reprec_warning(bp->name); X bp->assoc = assoc; X bp->prec = prec; X } X X c = nextc(); X if (c == EOF) unexpected_EOF(); X value = UNDEFINED; X if (isdigit(c)) X { X value = get_number(); X if (bp->value != UNDEFINED && value != bp->value) X revalued_warning(bp->name); X bp->value = value; X c = nextc(); X if (c == EOF) unexpected_EOF(); X } X } X} X X Xdeclare_types() X{ X register int c; X register bucket *bp; X char *tag; X X c = nextc(); X if (c == EOF) unexpected_EOF(); X if (c != '<') syntax_error(lineno, line, cptr); X tag = get_tag(); X X for (;;) X { X c = nextc(); X if (isalpha(c) || c == '_' || c == '.' || c == '$') X bp = get_name(); X else if (c == '\'' || c == '"') X bp = get_literal(); X else X return; X X if (bp->tag && tag != bp->tag) X retyped_warning(bp->name); X bp->tag = tag; X } X} X X Xdeclare_start() X{ X register int c; X register bucket *bp; X X c = nextc(); X if (c == EOF) unexpected_EOF(); X if (!isalpha(c) && c != '_' && c != '.' && c != '$') X syntax_error(lineno, line, cptr); X bp = get_name(); X if (bp->class == TERM) X terminal_start(bp->name); X if (goal && goal != bp) X restarted_warning(); X goal = bp; X} X X Xread_declarations() X{ X register int c, k; X X cache_size = 256; X cache = MALLOC(cache_size); X if (cache == 0) no_space(); X X for (;;) X { X c = nextc(); X if (c == EOF) unexpected_EOF(); X if (c != '%') syntax_error(lineno, line, cptr); X switch (k = keyword()) X { X case MARK: X return; X X case IDENT: X copy_ident(); X break; X X case TEXT: X copy_text(); X break; X X case UNION: X copy_union(); X break; X X case TOKEN: X case LEFT: X case RIGHT: X case NONASSOC: X declare_tokens(k); X break; X X case TYPE: X declare_types(); X break; X X case START: X declare_start(); X break; X } X } X} X X Xinitialize_grammar() X{ X nitems = 4; X maxitems = 300; X pitem = (bucket **) MALLOC(maxitems*sizeof(bucket *)); X if (pitem == 0) no_space(); X pitem[0] = 0; X pitem[1] = 0; X pitem[2] = 0; X pitem[3] = 0; X X nrules = 3; X maxrules = 100; X plhs = (bucket **) MALLOC(maxrules*sizeof(bucket *)); X if (plhs == 0) no_space(); X plhs[0] = 0; X plhs[1] = 0; X plhs[2] = 0; X rprec = (short *) MALLOC(maxrules*sizeof(short)); X if (rprec == 0) no_space(); X rprec[0] = 0; X rprec[1] = 0; X rprec[2] = 0; X rassoc = (char *) MALLOC(maxrules*sizeof(char)); X if (rassoc == 0) no_space(); X rassoc[0] = TOKEN; X rassoc[1] = TOKEN; X rassoc[2] = TOKEN; X} X X Xexpand_items() X{ X maxitems += 300; X pitem = (bucket **) REALLOC(pitem, maxitems*sizeof(bucket *)); X if (pitem == 0) no_space(); X} X X Xexpand_rules() X{ X maxrules += 100; X plhs = (bucket **) REALLOC(plhs, maxrules*sizeof(bucket *)); X if (plhs == 0) no_space(); X rprec = (short *) REALLOC(rprec, maxrules*sizeof(short)); X if (rprec == 0) no_space(); X rassoc = (char *) REALLOC(rassoc, maxrules*sizeof(char)); X if (rassoc == 0) no_space(); X} X X Xadvance_to_start() X{ X register int c; X register bucket *bp; X char *s_cptr; X int s_lineno; X X for (;;) X { X c = nextc(); X if (c != '%') break; X s_cptr = cptr; X switch (keyword()) X { X case MARK: X no_grammar(); X X case TEXT: X copy_text(); X break; X X case START: X declare_start(); X break; X X default: X syntax_error(lineno, line, s_cptr); X } X } X X c = nextc(); X if (!isalpha(c) && c != '_' && c != '.' && c != '_') X syntax_error(lineno, line, cptr); X bp = get_name(); X if (goal == 0) X { X if (bp->class == TERM) X terminal_start(bp->name); X goal = bp; X } X X s_lineno = lineno; X c = nextc(); X if (c == EOF) unexpected_EOF(); X if (c != ':') syntax_error(lineno, line, cptr); X start_rule(bp, s_lineno); X ++cptr; X} X X Xstart_rule(bp, s_lineno) Xregister bucket *bp; Xint s_lineno; X{ X if (bp->class == TERM) X terminal_lhs(s_lineno); X bp->class = NONTERM; X if (nrules >= maxrules) X expand_rules(); X plhs[nrules] = bp; X rprec[nrules] = UNDEFINED; X rassoc[nrules] = TOKEN; X} X X Xend_rule() X{ X register int i; X X if (!last_was_action && plhs[nrules]->tag) X { X for (i = nitems - 1; pitem[i]; --i) continue; X if (pitem[i+1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag) X default_action_warning(); X } X X last_was_action = 0; X if (nitems >= maxitems) expand_items(); X pitem[nitems] = 0; X ++nitems; X ++nrules; X} X X Xinsert_empty_rule() X{ X register bucket *bp, **bpp; X X assert(cache); X sprintf(cache, "$$%d", ++gensym); X bp = make_bucket(cache); X last_symbol->next = bp; X last_symbol = bp; X bp->tag = plhs[nrules]->tag; X bp->class = NONTERM; X X if ((nitems += 2) > maxitems) X expand_items(); X bpp = pitem + nitems - 1; X *bpp-- = bp; X while (bpp[0] = bpp[-1]) --bpp; X X if (++nrules >= maxrules) X expand_rules(); X plhs[nrules] = plhs[nrules-1]; X plhs[nrules-1] = bp; X rprec[nrules] = rprec[nrules-1]; X rprec[nrules-1] = 0; X rassoc[nrules] = rassoc[nrules-1]; X rassoc[nrules-1] = TOKEN; X} X X Xadd_symbol() X{ X register int c; X register bucket *bp; X int s_lineno = lineno; X X c = *cptr; X if (c == '\'' || c == '"') X bp = get_literal(); X else X bp = get_name(); X X c = nextc(); X if (c == ':') X { X end_rule(); X start_rule(bp, s_lineno); X ++cptr; X return; X } X X if (last_was_action) X insert_empty_rule(); X last_was_action = 0; X X if (++nitems > maxitems) X expand_items(); X pitem[nitems-1] = bp; X} X X Xcopy_action() X{ X register int c; X register int i, n; X int depth; X int quote; X char *tag; X register FILE *f = action_file; X int a_lineno = lineno; X char *a_line = dup_line(); X char *a_cptr = a_line + (cptr - line); X X if (last_was_action) X insert_empty_rule(); X last_was_action = 1; X X fprintf(f, "case %d:\n", nrules - 2); X if (!lflag) X fprintf(f, line_format, lineno, input_file_name); X if (*cptr == '=') ++cptr; X X n = 0; X for (i = nitems - 1; pitem[i]; --i) ++n; X X depth = 0; Xloop: X c = *cptr; X if (c == '$') X { X if (cptr[1] == '<') X { X int d_lineno = lineno; X char *d_line = dup_line(); X char *d_cptr = d_line + (cptr - line); X X ++cptr; X tag = get_tag(); X c = *cptr; X if (c == '$') X { X fprintf(f, "yyval.%s", tag); X ++cptr; X FREE(d_line); X goto loop; X } X else if (isdigit(c)) X { X i = get_number(); X if (i > n) dollar_warning(d_lineno, i); X fprintf(f, "yyvsp[%d].%s", i - n, tag); X FREE(d_line); X goto loop; X } X else if (c == '-' && isdigit(cptr[1])) X { X ++cptr; X i = -get_number() - n; X fprintf(f, "yyvsp[%d].%s", i, tag); X FREE(d_line); X goto loop; X } X else X dollar_error(d_lineno, d_line, d_cptr); X } X else if (cptr[1] == '$') X { X if (ntags) X { X tag = plhs[nrules]->tag; X if (tag == 0) untyped_lhs(); X fprintf(f, "yyval.%s", tag); X } X else X fprintf(f, "yyval"); X cptr += 2; X goto loop; X } X else if (isdigit(cptr[1])) X { X ++cptr; X i = get_number(); X if (ntags) X { X if (i <= 0 || i > n) X unknown_rhs(i); X tag = pitem[nitems + i - n - 1]->tag; X if (tag == 0) untyped_rhs(i, pitem[nitems + i - n - 1]->name); X fprintf(f, "yyvsp[%d].%s", i - n, tag); X } X else X { X if (i > n) X dollar_warning(lineno, i); X fprintf(f, "yyvsp[%d]", i - n); X } X goto loop; X } X else if (cptr[1] == '-') X { X cptr += 2; X i = get_number(); X if (ntags) X unknown_rhs(-i); X fprintf(f, "yyvsp[%d]", -i - n); X goto loop; X } X } X if (isalpha(c) || c == '_' || c == '$') X { X do X { X putc(c, f); X c = *++cptr; X } while (isalnum(c) || c == '_' || c == '$'); X goto loop; X } X putc(c, f); X ++cptr; X switch (c) X { X case '\n': X next_line: X get_line(); X if (line) goto loop; X unterminated_action(a_lineno, a_line, a_cptr); X X case ';': X if (depth > 0) goto loop; X fprintf(f, "\nbreak;\n"); X return; X X case '{': X ++depth; X goto loop; X X case '}': X if (--depth > 0) goto loop; X fprintf(f, "\nbreak;\n"); X return; X X case '\'': X case '"': X { X int s_lineno = lineno; X char *s_line = dup_line(); X char *s_cptr = s_line + (cptr - line - 1); X X quote = c; X for (;;) X { X c = *cptr++; X putc(c, f); X if (c == quote) X { X FREE(s_line); X goto loop; X } X if (c == '\n') X unterminated_string(s_lineno, s_line, s_cptr); X if (c == '\\') X { X c = *cptr++; X putc(c, f); X if (c == '\n') X { X get_line(); X if (line == 0) X unterminated_string(s_lineno, s_line, s_cptr); X } X } X } X } X X case '/': X c = *cptr; X if (c == '/') X { X putc('*', f); X while ((c = *++cptr) != '\n') X { X if (c == '*' && cptr[1] == '/') X fprintf(f, "* "); X else X putc(c, f); X } X fprintf(f, "*/\n"); X goto next_line; X } X if (c == '*') X { X int c_lineno = lineno; X char *c_line = dup_line(); X char *c_cptr = c_line + (cptr - line - 1); X X putc('*', f); X ++cptr; X for (;;) X { X c = *cptr++; X putc(c, f); X if (c == '*' && *cptr == '/') X { X putc('/', f); X ++cptr; X FREE(c_line); X goto loop; X } X if (c == '\n') X { X get_line(); X if (line == 0) X unterminated_comment(c_lineno, c_line, c_cptr); X } X } X } X goto loop; X X default: X goto loop; X } X} X X Xint Xmark_symbol() X{ X register int c; X register bucket *bp; X X c = cptr[1]; X if (c == '%' || c == '\\') X { X cptr += 2; X return (1); X } X X if (c == '=') X cptr += 2; X else if ((c == 'p' || c == 'P') && X ((c = cptr[2]) == 'r' || c == 'R') && X ((c = cptr[3]) == 'e' || c == 'E') && X ((c = cptr[4]) == 'c' || c == 'C') && X ((c = cptr[5], !IS_IDENT(c)))) X cptr += 5; X else X syntax_error(lineno, line, cptr); X X c = nextc(); X if (isalpha(c) || c == '_' || c == '.' || c == '$') X bp = get_name(); X else if (c == '\'' || c == '"') X bp = get_literal(); X else X { X syntax_error(lineno, line, cptr); X /*NOTREACHED*/ X } X X if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules]) X prec_redeclared(); X X rprec[nrules] = bp->prec; X rassoc[nrules] = bp->assoc; X return (0); X} X X Xread_grammar() X{ X register int c; X X initialize_grammar(); X advance_to_start(); X X for (;;) X { X c = nextc(); X if (c == EOF) break; X if (isalpha(c) || c == '_' || c == '.' || c == '$' || c == '\'' || X c == '"') X add_symbol(); X else if (c == '{' || c == '=') X copy_action(); X else if (c == '|') X { X end_rule(); X start_rule(plhs[nrules-1], 0); X ++cptr; X } X else if (c == '%') X { X if (mark_symbol()) break; X } X else X syntax_error(lineno, line, cptr); X } X end_rule(); X} X X Xfree_tags() X{ X register int i; X X if (tag_table == 0) return; X X for (i = 0; i < ntags; ++i) X { X assert(tag_table[i]); X FREE(tag_table[i]); X } X FREE(tag_table); X} X X Xpack_names() X{ X register bucket *bp; X register char *p, *s, *t; X X name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */ X for (bp = first_symbol; bp; bp = bp->next) X name_pool_size += strlen(bp->name) + 1; X name_pool = MALLOC(name_pool_size); X if (name_pool == 0) no_space(); X X strcpy(name_pool, "$accept"); X strcpy(name_pool+8, "$end"); X t = name_pool + 13; X for (bp = first_symbol; bp; bp = bp->next) X { X p = t; X s = bp->name; X while (*t++ = *s++) continue; X FREE(bp->name); X bp->name = p; X } X} X X Xcheck_symbols() X{ X register bucket *bp; X X if (goal->class == UNKNOWN) X undefined_goal(goal->name); X X for (bp = first_symbol; bp; bp = bp->next) X { X if (bp->class == UNKNOWN) X { X undefined_symbol_warning(bp->name); X bp->class = TERM; X } X } X} X X Xpack_symbols() X{ X register bucket *bp; X register bucket **v; X register int i, j, k, n; X X nsyms = 2; X ntokens = 1; X for (bp = first_symbol; bp; bp = bp->next) X { X ++nsyms; X if (bp->class == TERM) ++ntokens; X } X start_symbol = ntokens; X nvars = nsyms - ntokens; X X symbol_name = (char **) MALLOC(nsyms*sizeof(char *)); X if (symbol_name == 0) no_space(); X symbol_value = (short *) MALLOC(nsyms*sizeof(short)); X if (symbol_value == 0) no_space(); X symbol_prec = (short *) MALLOC(nsyms*sizeof(short)); X if (symbol_prec == 0) no_space(); X symbol_assoc = MALLOC(nsyms); X if (symbol_assoc == 0) no_space(); X X v = (bucket **) MALLOC(nsyms*sizeof(bucket *)); X if (v == 0) no_space(); X X v[0] = 0; X v[start_symbol] = 0; X X i = 1; X j = start_symbol + 1; X for (bp = first_symbol; bp; bp = bp->next) X { X if (bp->class == TERM) X v[i++] = bp; X else X v[j++] = bp; X } X assert(i == ntokens && j == nsyms); X X for (i = 1; i < ntokens; ++i) X v[i]->index = i; X X goal->index = start_symbol + 1; X k = start_symbol + 2; X while (++i < nsyms) X if (v[i] != goal) X { X v[i]->index = k; X ++k; X } X X goal->value = 0; X k = 1; X for (i = start_symbol + 1; i < nsyms; ++i) X { X if (v[i] != goal) X { X v[i]->value = k; X ++k; X } X } X X k = 0; X for (i = 1; i < ntokens; ++i) X { X n = v[i]->value; X if (n > 256) X { X for (j = k++; j > 0 && symbol_value[j-1] > n; --j) X symbol_value[j] = symbol_value[j-1]; X symbol_value[j] = n; X } X } X X if (v[1]->value == UNDEFINED) X v[1]->value = 256; X X j = 0; X n = 257; X for (i = 2; i < ntokens; ++i) X { X if (v[i]->value == UNDEFINED) X { X while (j < k && n == symbol_value[j]) X { X while (++j < k && n == symbol_value[j]) continue; X ++n; X } X v[i]->value = n; X ++n; X } X } X X symbol_name[0] = name_pool + 8; X symbol_value[0] = 0; X symbol_prec[0] = 0; X symbol_assoc[0] = TOKEN; X for (i = 1; i < ntokens; ++i) X { X symbol_name[i] = v[i]->name; X symbol_value[i] = v[i]->value; X symbol_prec[i] = v[i]->prec; X symbol_assoc[i] = v[i]->assoc; X } X symbol_name[start_symbol] = name_pool; X symbol_value[start_symbol] = -1; X symbol_prec[start_symbol] = 0; X symbol_assoc[start_symbol] = TOKEN; X for (++i; i < nsyms; ++i) X { X k = v[i]->index; X symbol_name[k] = v[i]->name; X symbol_value[k] = v[i]->value; X symbol_prec[k] = v[i]->prec; X symbol_assoc[k] = v[i]->assoc; X } X X FREE(v); X} X X Xpack_grammar() X{ X register int i, j; X int assoc, prec; X X ritem = (short *) MALLOC(nitems*sizeof(short)); X if (ritem == 0) no_space(); X rlhs = (short *) MALLOC(nrules*sizeof(short)); X if (rlhs == 0) no_space(); X rrhs = (short *) MALLOC((nrules+1)*sizeof(short)); X if (rrhs == 0) no_space(); X rprec = (short *) REALLOC(rprec, nrules*sizeof(short)); X if (rprec == 0) no_space(); X rassoc = REALLOC(rassoc, nrules); X if (rassoc == 0) no_space(); X X ritem[0] = -1; X ritem[1] = goal->index; X ritem[2] = 0; X ritem[3] = -2; X rlhs[0] = 0; X rlhs[1] = 0; X rlhs[2] = start_symbol; X rrhs[0] = 0; X rrhs[1] = 0; X rrhs[2] = 1; X X j = 4; X for (i = 3; i < nrules; ++i) X { X rlhs[i] = plhs[i]->index; X rrhs[i] = j; X assoc = TOKEN; X prec = 0; X while (pitem[j]) X { X ritem[j] = pitem[j]->index; X if (pitem[j]->class == TERM) X { X prec = pitem[j]->prec; X assoc = pitem[j]->assoc; X } X ++j; X } X ritem[j] = -i; X ++j; X if (rprec[i] == UNDEFINED) X { X rprec[i] = prec; X rassoc[i] = assoc; X } X } X rrhs[i] = j; X X FREE(plhs); X FREE(pitem); X} X X Xprint_grammar() X{ X register int i, j, k; X int spacing; X register FILE *f = verbose_file; X X if (!vflag) return; X X k = 1; X for (i = 2; i < nrules; ++i) X { X if (rlhs[i] != rlhs[i-1]) X { X if (i != 2) fprintf(f, "\n"); X fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]); X spacing = strlen(symbol_name[rlhs[i]]) + 1; X } X else X { X fprintf(f, "%4d ", i - 2); X j = spacing; X while (--j >= 0) putc(' ', f); X putc('|', f); X } X X while (ritem[k] >= 0) X { X fprintf(f, " %s", symbol_name[ritem[k]]); X ++k; X } X ++k; X putc('\n', f); X } X} X X Xreader() X{ X write_section(banner); X create_symbol_table(); X read_declarations(); X read_grammar(); X free_symbol_table(); X free_tags(); X pack_names(); X check_symbols(); X pack_symbols(); X pack_grammar(); X free_symbols(); X print_grammar(); X} END_OF_FILE if test 30469 -ne `wc -c <'reader.c'`; then echo shar: \"'reader.c'\" unpacked with wrong size! fi # end of 'reader.c' fi if test -f 'test/ftp.tab.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'test/ftp.tab.c'\" else echo shar: Extracting \"'test/ftp.tab.c'\" \(40069 characters\) sed "s/^X//" >'test/ftp.tab.c' <<'END_OF_FILE' X#ifndef lint Xstatic char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; X#endif X#define YYBYACC 1 X#define YYMAJOR 1 X#define YYMINOR 9 X#define yyclearin (yychar=(-1)) X#define yyerrok (yyerrflag=0) X#define YYRECOVERING (yyerrflag!=0) X#define YYPREFIX "yy" X#line 26 "ftp.y" X X#ifndef lint Xstatic char sccsid[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89"; X#endif /* not lint */ X X#include X#include X X#include X X#include X X#include X#include X#include X#include X#include X#include X#include X#include X Xextern struct sockaddr_in data_dest; Xextern int logged_in; Xextern struct passwd *pw; Xextern int guest; Xextern int logging; Xextern int type; Xextern int form; Xextern int debug; Xextern int timeout; Xextern int maxtimeout; Xextern int pdata; Xextern char hostname[], remotehost[]; Xextern char proctitle[]; Xextern char *globerr; Xextern int usedefault; Xextern int transflag; Xextern char tmpline[]; Xchar **glob(); X Xstatic int cmd_type; Xstatic int cmd_form; Xstatic int cmd_bytesz; Xchar cbuf[512]; Xchar *fromname; X Xchar *index(); X#line 60 "ftp.tab.c" X#define A 257 X#define B 258 X#define C 259 X#define E 260 X#define F 261 X#define I 262 X#define L 263 X#define N 264 X#define P 265 X#define R 266 X#define S 267 X#define T 268 X#define SP 269 X#define CRLF 270 X#define COMMA 271 X#define STRING 272 X#define NUMBER 273 X#define USER 274 X#define PASS 275 X#define ACCT 276 X#define REIN 277 X#define QUIT 278 X#define PORT 279 X#define PASV 280 X#define TYPE 281 X#define STRU 282 X#define MODE 283 X#define RETR 284 X#define STOR 285 X#define APPE 286 X#define MLFL 287 X#define MAIL 288 X#define MSND 289 X#define MSOM 290 X#define MSAM 291 X#define MRSQ 292 X#define MRCP 293 X#define ALLO 294 X#define REST 295 X#define RNFR 296 X#define RNTO 297 X#define ABOR 298 X#define DELE 299 X#define CWD 300 X#define LIST 301 X#define NLST 302 X#define SITE 303 X#define STAT 304 X#define HELP 305 X#define NOOP 306 X#define MKD 307 X#define RMD 308 X#define PWD 309 X#define CDUP 310 X#define STOU 311 X#define SMNT 312 X#define SYST 313 X#define SIZE 314 X#define MDTM 315 X#define UMASK 316 X#define IDLE 317 X#define CHMOD 318 X#define LEXERR 319 X#define YYERRCODE 256 Xshort yylhs[] = { -1, X 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, X 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, X 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, X 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, X 1, 1, 1, 1, 1, 1, 2, 3, 4, 4, X 12, 5, 13, 13, 13, 6, 6, 6, 6, 6, X 6, 6, 6, 7, 7, 7, 8, 8, 8, 10, X 14, 11, 9, X}; Xshort yylen[] = { 2, X 0, 2, 2, 4, 4, 4, 2, 4, 4, 4, X 4, 8, 5, 5, 5, 3, 5, 3, 5, 5, X 2, 5, 4, 2, 3, 5, 2, 4, 2, 5, X 5, 3, 3, 4, 6, 5, 7, 9, 4, 6, X 5, 2, 5, 5, 2, 2, 5, 1, 0, 1, X 1, 11, 1, 1, 1, 1, 3, 1, 3, 1, X 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, X 1, 1, 0, X}; Xshort yydefred[] = { 1, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 73, 73, 73, 0, 73, 0, 0, 73, 73, 73, X 73, 0, 0, 0, 0, 73, 73, 73, 73, 73, X 0, 73, 73, 2, 3, 46, 0, 0, 45, 0, X 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 24, 0, 0, 0, 0, 0, 21, 0, 0, 27, X 29, 0, 0, 0, 0, 0, 42, 0, 0, 48, X 0, 50, 0, 0, 0, 0, 0, 60, 0, 0, X 64, 66, 65, 0, 68, 69, 67, 0, 0, 0, X 0, 0, 0, 71, 0, 70, 0, 0, 25, 0, X 18, 0, 16, 0, 73, 0, 73, 0, 0, 0, X 0, 32, 33, 0, 0, 0, 4, 5, 0, 6, X 0, 0, 0, 51, 63, 8, 9, 10, 0, 0, X 0, 0, 11, 0, 23, 0, 0, 0, 0, 0, X 34, 0, 0, 39, 0, 0, 28, 0, 0, 0, X 0, 0, 0, 55, 53, 54, 57, 59, 62, 13, X 14, 15, 0, 47, 22, 26, 19, 17, 0, 0, X 36, 0, 0, 20, 30, 31, 41, 43, 44, 0, X 0, 35, 72, 0, 40, 0, 0, 0, 37, 0, X 0, 12, 0, 0, 38, 0, 0, 0, 52, X}; Xshort yydgoto[] = { 1, X 34, 35, 71, 73, 75, 80, 84, 88, 45, 95, X 184, 125, 157, 96, X}; Xshort yysindex[] = { 0, X -224, -247, -239, -236, -232, -222, -204, -200, -181, -177, X 0, 0, 0, -166, 0, -161, -199, 0, 0, 0, X 0, -160, -159, -264, -158, 0, 0, 0, 0, 0, X -157, 0, 0, 0, 0, 0, -167, -162, 0, -156, X 0, -250, -198, -165, -155, -154, -153, -151, -150, -152, X 0, -145, -252, -229, -217, -302, 0, -144, -146, 0, X 0, -142, -141, -140, -139, -137, 0, -136, -135, 0, X -134, 0, -133, -132, -130, -131, -128, 0, -249, -127, X 0, 0, 0, -126, 0, 0, 0, -125, -152, -152, X -152, -205, -152, 0, -124, 0, -152, -152, 0, -152, X 0, -143, 0, -173, 0, -171, 0, -152, -123, -152, X -152, 0, 0, -152, -152, -152, 0, 0, -138, 0, X -164, -164, -122, 0, 0, 0, 0, 0, -121, -120, X -118, -148, 0, -117, 0, -116, -115, -114, -113, -112, X 0, -163, -111, 0, -110, -109, 0, -107, -106, -105, X -104, -103, -129, 0, 0, 0, 0, 0, 0, 0, X 0, 0, -101, 0, 0, 0, 0, 0, -100, -102, X 0, -98, -102, 0, 0, 0, 0, 0, 0, -99, X -97, 0, 0, -95, 0, -96, -94, -92, 0, -152, X -93, 0, -91, -90, 0, -88, -87, -86, 0, X}; Xshort yyrindex[] = { 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, -83, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, -82, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, -81, -80, 0, -158, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, X}; Xshort yygindex[] = { 0, X 0, 0, 0, 0, 0, 0, 0, 0, 16, -89, X -25, 35, 47, 0, X}; X#define YYTABLESIZE 190 Xshort yytable[] = { 129, X 130, 131, 104, 134, 59, 60, 76, 136, 137, 77, X 138, 78, 79, 105, 106, 107, 98, 99, 146, 123, X 148, 149, 36, 124, 150, 151, 152, 46, 47, 37, X 49, 2, 38, 52, 53, 54, 55, 39, 58, 100, X 101, 62, 63, 64, 65, 66, 40, 68, 69, 3, X 4, 102, 103, 5, 6, 7, 8, 9, 10, 11, X 12, 13, 81, 132, 133, 41, 82, 83, 42, 14, X 51, 15, 16, 17, 18, 19, 20, 21, 22, 23, X 24, 25, 26, 27, 28, 29, 30, 43, 31, 32, X 33, 44, 85, 86, 154, 140, 141, 143, 144, 155, X 193, 87, 48, 156, 70, 170, 171, 50, 56, 72, X 57, 61, 67, 89, 90, 91, 74, 163, 93, 94, X 142, 92, 145, 97, 108, 109, 110, 111, 139, 112, X 113, 114, 115, 116, 153, 117, 118, 121, 119, 120, X 122, 180, 126, 127, 128, 135, 147, 186, 160, 161, X 124, 162, 164, 165, 166, 167, 168, 159, 173, 169, X 174, 172, 175, 176, 177, 178, 179, 181, 158, 182, X 183, 185, 190, 187, 189, 188, 191, 192, 195, 194, X 196, 0, 0, 198, 197, 73, 199, 49, 56, 58, X}; Xshort yycheck[] = { 89, X 90, 91, 305, 93, 269, 270, 257, 97, 98, 260, X 100, 262, 263, 316, 317, 318, 269, 270, 108, 269, X 110, 111, 270, 273, 114, 115, 116, 12, 13, 269, X 15, 256, 269, 18, 19, 20, 21, 270, 23, 269, X 270, 26, 27, 28, 29, 30, 269, 32, 33, 274, X 275, 269, 270, 278, 279, 280, 281, 282, 283, 284, X 285, 286, 261, 269, 270, 270, 265, 266, 269, 294, X 270, 296, 297, 298, 299, 300, 301, 302, 303, 304, X 305, 306, 307, 308, 309, 310, 311, 269, 313, 314, X 315, 269, 258, 259, 259, 269, 270, 269, 270, 264, X 190, 267, 269, 268, 272, 269, 270, 269, 269, 272, X 270, 270, 270, 269, 269, 269, 273, 266, 269, 272, X 105, 273, 107, 269, 269, 272, 269, 269, 272, 270, X 270, 269, 269, 269, 273, 270, 270, 269, 271, 270, X 269, 271, 270, 270, 270, 270, 270, 173, 270, 270, X 273, 270, 270, 270, 270, 270, 270, 123, 269, 272, X 270, 273, 270, 270, 270, 270, 270, 269, 122, 270, X 273, 270, 269, 273, 270, 273, 271, 270, 270, 273, X 271, -1, -1, 271, 273, 269, 273, 270, 270, 270, X}; X#define YYFINAL 1 X#ifndef YYDEBUG X#define YYDEBUG 0 X#endif X#define YYMAXTOKEN 319 X#if YYDEBUG Xchar *yyname[] = { X"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"A","B","C","E","F","I","L","N", X"P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT", X"REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL", X"MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR", X"DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP", X"STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR", X}; Xchar *yyrule[] = { X"$accept : cmd_list", X"cmd_list :", X"cmd_list : cmd_list cmd", X"cmd_list : cmd_list rcmd", X"cmd : USER SP username CRLF", X"cmd : PASS SP password CRLF", X"cmd : PORT SP host_port CRLF", X"cmd : PASV CRLF", X"cmd : TYPE SP type_code CRLF", X"cmd : STRU SP struct_code CRLF", X"cmd : MODE SP mode_code CRLF", X"cmd : ALLO SP NUMBER CRLF", X"cmd : ALLO SP NUMBER SP R SP NUMBER CRLF", X"cmd : RETR check_login SP pathname CRLF", X"cmd : STOR check_login SP pathname CRLF", X"cmd : APPE check_login SP pathname CRLF", X"cmd : NLST check_login CRLF", X"cmd : NLST check_login SP STRING CRLF", X"cmd : LIST check_login CRLF", X"cmd : LIST check_login SP pathname CRLF", X"cmd : STAT check_login SP pathname CRLF", X"cmd : STAT CRLF", X"cmd : DELE check_login SP pathname CRLF", X"cmd : RNTO SP pathname CRLF", X"cmd : ABOR CRLF", X"cmd : CWD check_login CRLF", X"cmd : CWD check_login SP pathname CRLF", X"cmd : HELP CRLF", X"cmd : HELP SP STRING CRLF", X"cmd : NOOP CRLF", X"cmd : MKD check_login SP pathname CRLF", X"cmd : RMD check_login SP pathname CRLF", X"cmd : PWD check_login CRLF", X"cmd : CDUP check_login CRLF", X"cmd : SITE SP HELP CRLF", X"cmd : SITE SP HELP SP STRING CRLF", X"cmd : SITE SP UMASK check_login CRLF", X"cmd : SITE SP UMASK check_login SP octal_number CRLF", X"cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF", X"cmd : SITE SP IDLE CRLF", X"cmd : SITE SP IDLE SP NUMBER CRLF", X"cmd : STOU check_login SP pathname CRLF", X"cmd : SYST CRLF", X"cmd : SIZE check_login SP pathname CRLF", X"cmd : MDTM check_login SP pathname CRLF", X"cmd : QUIT CRLF", X"cmd : error CRLF", X"rcmd : RNFR check_login SP pathname CRLF", X"username : STRING", X"password :", X"password : STRING", X"byte_size : NUMBER", X"host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER", X"form_code : N", X"form_code : T", X"form_code : C", X"type_code : A", X"type_code : A SP form_code", X"type_code : E", X"type_code : E SP form_code", X"type_code : I", X"type_code : L", X"type_code : L SP byte_size", X"type_code : L byte_size", X"struct_code : F", X"struct_code : R", X"struct_code : P", X"mode_code : S", X"mode_code : B", X"mode_code : C", X"pathname : pathstring", X"pathstring : STRING", X"octal_number : NUMBER", X"check_login :", X}; X#endif X#ifndef YYSTYPE Xtypedef int YYSTYPE; X#endif X#ifdef YYSTACKSIZE X#undef YYMAXDEPTH X#define YYMAXDEPTH YYSTACKSIZE X#else X#ifdef YYMAXDEPTH X#define YYSTACKSIZE YYMAXDEPTH X#else X#define YYSTACKSIZE 500 X#define YYMAXDEPTH 500 X#endif X#endif Xint yydebug; Xint yynerrs; Xint yyerrflag; Xint yychar; Xshort *yyssp; XYYSTYPE *yyvsp; XYYSTYPE yyval; XYYSTYPE yylval; Xshort yyss[YYSTACKSIZE]; XYYSTYPE yyvs[YYSTACKSIZE]; X#define yystacksize YYSTACKSIZE X#line 658 "ftp.y" X Xextern jmp_buf errcatch; X X#define CMD 0 /* beginning of command */ X#define ARGS 1 /* expect miscellaneous arguments */ X#define STR1 2 /* expect SP followed by STRING */ X#define STR2 3 /* expect STRING */ X#define OSTR 4 /* optional SP then STRING */ X#define ZSTR1 5 /* SP then optional STRING */ X#define ZSTR2 6 /* optional STRING after SP */ X#define SITECMD 7 /* SITE command */ X#define NSTR 8 /* Number followed by a string */ X Xstruct tab { X char *name; X short token; X short state; X short implemented; /* 1 if command is implemented */ X char *help; X}; X Xstruct tab cmdtab[] = { /* In order defined in RFC 765 */ X { "USER", USER, STR1, 1, " username" }, X { "PASS", PASS, ZSTR1, 1, " password" }, X { "ACCT", ACCT, STR1, 0, "(specify account)" }, X { "SMNT", SMNT, ARGS, 0, "(structure mount)" }, X { "REIN", REIN, ARGS, 0, "(reinitialize server state)" }, X { "QUIT", QUIT, ARGS, 1, "(terminate service)", }, X { "PORT", PORT, ARGS, 1, " b0, b1, b2, b3, b4" }, X { "PASV", PASV, ARGS, 1, "(set server in passive mode)" }, X { "TYPE", TYPE, ARGS, 1, " [ A | E | I | L ]" }, X { "STRU", STRU, ARGS, 1, "(specify file structure)" }, X { "MODE", MODE, ARGS, 1, "(specify transfer mode)" }, X { "RETR", RETR, STR1, 1, " file-name" }, X { "STOR", STOR, STR1, 1, " file-name" }, X { "APPE", APPE, STR1, 1, " file-name" }, X { "MLFL", MLFL, OSTR, 0, "(mail file)" }, X { "MAIL", MAIL, OSTR, 0, "(mail to user)" }, X { "MSND", MSND, OSTR, 0, "(mail send to terminal)" }, X { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" }, X { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" }, X { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" }, X { "MRCP", MRCP, STR1, 0, "(mail recipient)" }, X { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" }, X { "REST", REST, ARGS, 0, "(restart command)" }, X { "RNFR", RNFR, STR1, 1, " file-name" }, X { "RNTO", RNTO, STR1, 1, " file-name" }, X { "ABOR", ABOR, ARGS, 1, "(abort operation)" }, X { "DELE", DELE, STR1, 1, " file-name" }, X { "CWD", CWD, OSTR, 1, "[ directory-name ]" }, X { "XCWD", CWD, OSTR, 1, "[ directory-name ]" }, X { "LIST", LIST, OSTR, 1, "[ path-name ]" }, X { "NLST", NLST, OSTR, 1, "[ path-name ]" }, X { "SITE", SITE, SITECMD, 1, "site-cmd [ arguments ]" }, X { "SYST", SYST, ARGS, 1, "(get type of operating system)" }, X { "STAT", STAT, OSTR, 1, "[ path-name ]" }, X { "HELP", HELP, OSTR, 1, "[ ]" }, X { "NOOP", NOOP, ARGS, 1, "" }, X { "MKD", MKD, STR1, 1, " path-name" }, X { "XMKD", MKD, STR1, 1, " path-name" }, X { "RMD", RMD, STR1, 1, " path-name" }, X { "XRMD", RMD, STR1, 1, " path-name" }, X { "PWD", PWD, ARGS, 1, "(return current directory)" }, X { "XPWD", PWD, ARGS, 1, "(return current directory)" }, X { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" }, X { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" }, X { "STOU", STOU, STR1, 1, " file-name" }, X { "SIZE", SIZE, OSTR, 1, " path-name" }, X { "MDTM", MDTM, OSTR, 1, " path-name" }, X { NULL, 0, 0, 0, 0 } X}; X Xstruct tab sitetab[] = { X { "UMASK", UMASK, ARGS, 1, "[ umask ]" }, X { "IDLE", IDLE, ARGS, 1, "[ maximum-idle-time ]" }, X { "CHMOD", CHMOD, NSTR, 1, " mode file-name" }, X { "HELP", HELP, OSTR, 1, "[ ]" }, X { NULL, 0, 0, 0, 0 } X}; X Xstruct tab * Xlookup(p, cmd) X register struct tab *p; X char *cmd; X{ X X for (; p->name != NULL; p++) X if (strcmp(cmd, p->name) == 0) X return (p); X return (0); X} X X#include X X/* X * getline - a hacked up version of fgets to ignore TELNET escape codes. X */ Xchar * Xgetline(s, n, iop) X char *s; X register FILE *iop; X{ X register c; X register char *cs; X X cs = s; X/* tmpline may contain saved command from urgent mode interruption */ X for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) { X *cs++ = tmpline[c]; X if (tmpline[c] == '\n') { X *cs++ = '\0'; X if (debug) X syslog(LOG_DEBUG, "command: %s", s); X tmpline[0] = '\0'; X return(s); X } X if (c == 0) X tmpline[0] = '\0'; X } X while ((c = getc(iop)) != EOF) { X c &= 0377; X if (c == IAC) { X if ((c = getc(iop)) != EOF) { X c &= 0377; X switch (c) { X case WILL: X case WONT: X c = getc(iop); X printf("%c%c%c", IAC, DONT, 0377&c); X (void) fflush(stdout); X continue; X case DO: X case DONT: X c = getc(iop); X printf("%c%c%c", IAC, WONT, 0377&c); X (void) fflush(stdout); X continue; X case IAC: X break; X default: X continue; /* ignore command */ X } X } X } X *cs++ = c; X if (--n <= 0 || c == '\n') X break; X } X if (c == EOF && cs == s) X return (NULL); X *cs++ = '\0'; X if (debug) X syslog(LOG_DEBUG, "command: %s", s); X return (s); X} X Xstatic int Xtoolong() X{ X time_t now; X extern char *ctime(); X extern time_t time(); X X reply(421, X "Timeout (%d seconds): closing control connection.", timeout); X (void) time(&now); X if (logging) { X syslog(LOG_INFO, X "User %s timed out after %d seconds at %s", X (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now)); X } X dologout(1); X} X Xyylex() X{ X static int cpos, state; X register char *cp, *cp2; X register struct tab *p; X int n; X char c, *strpbrk(); X char *copy(); X X for (;;) { X switch (state) { X X case CMD: X (void) signal(SIGALRM, toolong); X (void) alarm((unsigned) timeout); X if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) { X reply(221, "You could at least say goodbye."); X dologout(0); X } X (void) alarm(0); X#ifdef SETPROCTITLE X if (strncasecmp(cbuf, "PASS", 4) != NULL) X setproctitle("%s: %s", proctitle, cbuf); X#endif /* SETPROCTITLE */ X if ((cp = index(cbuf, '\r'))) { X *cp++ = '\n'; X *cp = '\0'; X } X if ((cp = strpbrk(cbuf, " \n"))) X cpos = cp - cbuf; X if (cpos == 0) X cpos = 4; X c = cbuf[cpos]; X cbuf[cpos] = '\0'; X upper(cbuf); X p = lookup(cmdtab, cbuf); X cbuf[cpos] = c; X if (p != 0) { X if (p->implemented == 0) { X nack(p->name); X longjmp(errcatch,0); X /* NOTREACHED */ X } X state = p->state; X *(char **)&yylval = p->name; X return (p->token); X } X break; X X case SITECMD: X if (cbuf[cpos] == ' ') { X cpos++; X return (SP); X } X cp = &cbuf[cpos]; X if ((cp2 = strpbrk(cp, " \n"))) X cpos = cp2 - cbuf; X c = cbuf[cpos]; X cbuf[cpos] = '\0'; X upper(cp); X p = lookup(sitetab, cp); X cbuf[cpos] = c; X if (p != 0) { X if (p->implemented == 0) { X state = CMD; X nack(p->name); X longjmp(errcatch,0); X /* NOTREACHED */ X } X state = p->state; X *(char **)&yylval = p->name; X return (p->token); X } X state = CMD; X break; X X case OSTR: X if (cbuf[cpos] == '\n') { X state = CMD; X return (CRLF); X } X /* FALLTHROUGH */ X X case STR1: X case ZSTR1: X dostr1: X if (cbuf[cpos] == ' ') { X cpos++; X state = state == OSTR ? STR2 : ++state; X return (SP); X } X break; X X case ZSTR2: X if (cbuf[cpos] == '\n') { X state = CMD; X return (CRLF); X } X /* FALLTHROUGH */ X X case STR2: X cp = &cbuf[cpos]; X n = strlen(cp); X cpos += n - 1; X /* X * Make sure the string is nonempty and \n terminated. X */ X if (n > 1 && cbuf[cpos] == '\n') { X cbuf[cpos] = '\0'; X *(char **)&yylval = copy(cp); X cbuf[cpos] = '\n'; X state = ARGS; X return (STRING); X } X break; X X case NSTR: X if (cbuf[cpos] == ' ') { X cpos++; X return (SP); X } X if (isdigit(cbuf[cpos])) { X cp = &cbuf[cpos]; X while (isdigit(cbuf[++cpos])) X ; X c = cbuf[cpos]; X cbuf[cpos] = '\0'; X yylval = atoi(cp); X cbuf[cpos] = c; X state = STR1; X return (NUMBER); X } X state = STR1; X goto dostr1; X X case ARGS: X if (isdigit(cbuf[cpos])) { X cp = &cbuf[cpos]; X while (isdigit(cbuf[++cpos])) X ; X c = cbuf[cpos]; X cbuf[cpos] = '\0'; X yylval = atoi(cp); X cbuf[cpos] = c; X return (NUMBER); X } X switch (cbuf[cpos++]) { X X case '\n': X state = CMD; X return (CRLF); X X case ' ': X return (SP); X X case ',': X return (COMMA); X X case 'A': X case 'a': X return (A); X X case 'B': X case 'b': X return (B); X X case 'C': X case 'c': X return (C); X X case 'E': X case 'e': X return (E); X X case 'F': X case 'f': X return (F); X X case 'I': X case 'i': X return (I); X X case 'L': X case 'l': X return (L); X X case 'N': X case 'n': X return (N); X X case 'P': X case 'p': X return (P); X X case 'R': X case 'r': X return (R); X X case 'S': X case 's': X return (S); X X case 'T': X case 't': X return (T); X X } X break; X X default: X fatal("Unknown state in scanner."); X } X yyerror((char *) 0); X state = CMD; X longjmp(errcatch,0); X } X} X Xupper(s) X register char *s; X{ X while (*s != '\0') { X if (islower(*s)) X *s = toupper(*s); X s++; X } X} X Xchar * Xcopy(s) X char *s; X{ X char *p; X extern char *malloc(), *strcpy(); X X p = malloc((unsigned) strlen(s) + 1); X if (p == NULL) X fatal("Ran out of memory."); X (void) strcpy(p, s); X return (p); X} X Xhelp(ctab, s) X struct tab *ctab; X char *s; X{ X register struct tab *c; X register int width, NCMDS; X char *type; X X if (ctab == sitetab) X type = "SITE "; X else X type = ""; X width = 0, NCMDS = 0; X for (c = ctab; c->name != NULL; c++) { X int len = strlen(c->name); X X if (len > width) X width = len; X NCMDS++; X } X width = (width + 8) &~ 7; X if (s == 0) { X register int i, j, w; X int columns, lines; X X lreply(214, "The following %scommands are recognized %s.", X type, "(* =>'s unimplemented)"); X columns = 76 / width; X if (columns == 0) X columns = 1; X lines = (NCMDS + columns - 1) / columns; X for (i = 0; i < lines; i++) { X printf(" "); X for (j = 0; j < columns; j++) { X c = ctab + j * lines + i; X printf("%s%c", c->name, X c->implemented ? ' ' : '*'); X if (c + lines >= &ctab[NCMDS]) X break; X w = strlen(c->name) + 1; X while (w < width) { X putchar(' '); X w++; X } X } X printf("\r\n"); X } X (void) fflush(stdout); X reply(214, "Direct comments to ftp-bugs@%s.", hostname); X return; X } X upper(s); X c = lookup(ctab, s); X if (c == (struct tab *)0) { X reply(502, "Unknown command %s.", s); X return; X } X if (c->implemented) X reply(214, "Syntax: %s%s %s", type, c->name, c->help); X else X reply(214, "%s%-*s\t%s; unimplemented.", type, width, X c->name, c->help); X} X Xsizecmd(filename) Xchar *filename; X{ X switch (type) { X case TYPE_L: X case TYPE_I: { X struct stat stbuf; X if (stat(filename, &stbuf) < 0 || X (stbuf.st_mode&S_IFMT) != S_IFREG) X reply(550, "%s: not a plain file.", filename); X else X reply(213, "%lu", stbuf.st_size); X break;} X case TYPE_A: { X FILE *fin; X register int c, count; X struct stat stbuf; X fin = fopen(filename, "r"); X if (fin == NULL) { X perror_reply(550, filename); X return; X } X if (fstat(fileno(fin), &stbuf) < 0 || X (stbuf.st_mode&S_IFMT) != S_IFREG) { X reply(550, "%s: not a plain file.", filename); X (void) fclose(fin); X return; X } X X count = 0; X while((c=getc(fin)) != EOF) { X if (c == '\n') /* will get expanded to \r\n */ X count++; X count++; X } X (void) fclose(fin); X X reply(213, "%ld", count); X break;} X default: X reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]); X } X} X#line 908 "ftp.tab.c" X#define YYABORT goto yyabort X#define YYREJECT goto yyabort X#define YYACCEPT goto yyaccept X#define YYERROR goto yyerrlab Xint Xyyparse() X{ X register int yym, yyn, yystate; X#if YYDEBUG X register char *yys; X extern char *getenv(); X X if (yys = getenv("YYDEBUG")) X { X yyn = *yys; X if (yyn >= '0' && yyn <= '9') X yydebug = yyn - '0'; X } X#endif X X yynerrs = 0; X yyerrflag = 0; X yychar = (-1); X X yyssp = yyss; X yyvsp = yyvs; X *yyssp = yystate = 0; X Xyyloop: X if (yyn = yydefred[yystate]) goto yyreduce; X if (yychar < 0) X { X if ((yychar = yylex()) < 0) yychar = 0; X#if YYDEBUG X if (yydebug) X { X yys = 0; X if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; X if (!yys) yys = "illegal-symbol"; X printf("%sdebug: state %d, reading %d (%s)\n", X YYPREFIX, yystate, yychar, yys); X } X#endif X } X if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && X yyn <= YYTABLESIZE && yycheck[yyn] == yychar) X { X#if YYDEBUG X if (yydebug) X printf("%sdebug: state %d, shifting to state %d\n", X YYPREFIX, yystate, yytable[yyn]); X#endif X if (yyssp >= yyss + yystacksize - 1) X { X goto yyoverflow; X } X *++yyssp = yystate = yytable[yyn]; X *++yyvsp = yylval; X yychar = (-1); X if (yyerrflag > 0) --yyerrflag; X goto yyloop; X } X if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && X yyn <= YYTABLESIZE && yycheck[yyn] == yychar) X { X yyn = yytable[yyn]; X goto yyreduce; X } X if (yyerrflag) goto yyinrecovery; X#ifdef lint X goto yynewerror; X#endif Xyynewerror: X yyerror("syntax error"); X#ifdef lint X goto yyerrlab; X#endif Xyyerrlab: X ++yynerrs; Xyyinrecovery: X if (yyerrflag < 3) X { X yyerrflag = 3; X for (;;) X { X if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && X yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) X { X#if YYDEBUG X if (yydebug) X printf("%sdebug: state %d, error recovery shifting\ X to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); X#endif X if (yyssp >= yyss + yystacksize - 1) X { X goto yyoverflow; X } X *++yyssp = yystate = yytable[yyn]; X *++yyvsp = yylval; X goto yyloop; X } X else X { X#if YYDEBUG X if (yydebug) X printf("%sdebug: error recovery discarding state %d\n", X YYPREFIX, *yyssp); X#endif X if (yyssp <= yyss) goto yyabort; X --yyssp; X --yyvsp; X } X } X } X else X { X if (yychar == 0) goto yyabort; X#if YYDEBUG X if (yydebug) X { X yys = 0; X if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; X if (!yys) yys = "illegal-symbol"; X printf("%sdebug: state %d, error recovery discards token %d (%s)\n", X YYPREFIX, yystate, yychar, yys); X } X#endif X yychar = (-1); X goto yyloop; X } Xyyreduce: X#if YYDEBUG X if (yydebug) X printf("%sdebug: state %d, reducing by rule %d (%s)\n", X YYPREFIX, yystate, yyn, yyrule[yyn]); X#endif X yym = yylen[yyn]; X yyval = yyvsp[1-yym]; X switch (yyn) X { Xcase 2: X#line 99 "ftp.y" X { X fromname = (char *) 0; X } Xbreak; Xcase 4: X#line 106 "ftp.y" X { X user((char *) yyvsp[-1]); X free((char *) yyvsp[-1]); X } Xbreak; Xcase 5: X#line 111 "ftp.y" X { X pass((char *) yyvsp[-1]); X free((char *) yyvsp[-1]); X } Xbreak; Xcase 6: X#line 116 "ftp.y" X { X usedefault = 0; X if (pdata >= 0) { X (void) close(pdata); X pdata = -1; X } X reply(200, "PORT command successful."); X } Xbreak; Xcase 7: X#line 125 "ftp.y" X { X passive(); X } Xbreak; Xcase 8: X#line 129 "ftp.y" X { X switch (cmd_type) { X X case TYPE_A: X if (cmd_form == FORM_N) { X reply(200, "Type set to A."); X type = cmd_type; X form = cmd_form; X } else X reply(504, "Form must be N."); X break; X X case TYPE_E: X reply(504, "Type E not implemented."); X break; X X case TYPE_I: X reply(200, "Type set to I."); X type = cmd_type; X break; X X case TYPE_L: X#if NBBY == 8 X if (cmd_bytesz == 8) { X reply(200, X "Type set to L (byte size 8)."); X type = cmd_type; X } else X reply(504, "Byte size must be 8."); X#else /* NBBY == 8 */ X UNIMPLEMENTED for NBBY != 8 X#endif /* NBBY == 8 */ X } X } Xbreak; Xcase 9: X#line 164 "ftp.y" X { X switch (yyvsp[-1]) { X X case STRU_F: X reply(200, "STRU F ok."); X break; X X default: X reply(504, "Unimplemented STRU type."); X } X } Xbreak; Xcase 10: X#line 176 "ftp.y" X { X switch (yyvsp[-1]) { X X case MODE_S: X reply(200, "MODE S ok."); X break; X X default: X reply(502, "Unimplemented MODE type."); X } X } Xbreak; Xcase 11: X#line 188 "ftp.y" X { X reply(202, "ALLO command ignored."); X } Xbreak; Xcase 12: X#line 192 "ftp.y" X { X reply(202, "ALLO command ignored."); X } Xbreak; Xcase 13: X#line 196 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X retrieve((char *) 0, (char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 14: X#line 203 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X store((char *) yyvsp[-1], "w", 0); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 15: X#line 210 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X store((char *) yyvsp[-1], "a", 0); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 16: X#line 217 "ftp.y" X { X if (yyvsp[-1]) X send_file_list("."); X } Xbreak; Xcase 17: X#line 222 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X send_file_list((char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 18: X#line 229 "ftp.y" X { X if (yyvsp[-1]) X retrieve("/bin/ls -lgA", ""); X } Xbreak; Xcase 19: X#line 234 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X retrieve("/bin/ls -lgA %s", (char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 20: X#line 241 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X statfilecmd((char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 21: X#line 248 "ftp.y" X { X statcmd(); X } Xbreak; Xcase 22: X#line 252 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X delete((char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 23: X#line 259 "ftp.y" X { X if (fromname) { X renamecmd(fromname, (char *) yyvsp[-1]); X free(fromname); X fromname = (char *) 0; X } else { X reply(503, "Bad sequence of commands."); X } X free((char *) yyvsp[-1]); X } Xbreak; Xcase 24: X#line 270 "ftp.y" X { X reply(225, "ABOR command successful."); X } Xbreak; Xcase 25: X#line 274 "ftp.y" X { X if (yyvsp[-1]) X cwd(pw->pw_dir); X } Xbreak; Xcase 26: X#line 279 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X cwd((char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 27: X#line 286 "ftp.y" X { X help(cmdtab, (char *) 0); X } Xbreak; Xcase 28: X#line 290 "ftp.y" X { X register char *cp = (char *)yyvsp[-1]; X X if (strncasecmp(cp, "SITE", 4) == 0) { X cp = (char *)yyvsp[-1] + 4; X if (*cp == ' ') X cp++; X if (*cp) X help(sitetab, cp); X else X help(sitetab, (char *) 0); X } else X help(cmdtab, (char *) yyvsp[-1]); X } Xbreak; Xcase 29: X#line 305 "ftp.y" X { X reply(200, "NOOP command successful."); X } Xbreak; Xcase 30: X#line 309 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X makedir((char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 31: X#line 316 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X removedir((char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 32: X#line 323 "ftp.y" X { X if (yyvsp[-1]) X pwd(); X } Xbreak; Xcase 33: X#line 328 "ftp.y" X { X if (yyvsp[-1]) X cwd(".."); X } Xbreak; Xcase 34: X#line 333 "ftp.y" X { X help(sitetab, (char *) 0); X } Xbreak; Xcase 35: X#line 337 "ftp.y" X { X help(sitetab, (char *) yyvsp[-1]); X } Xbreak; Xcase 36: X#line 341 "ftp.y" X { X int oldmask; X X if (yyvsp[-1]) { X oldmask = umask(0); X (void) umask(oldmask); X reply(200, "Current UMASK is %03o", oldmask); X } X } Xbreak; Xcase 37: X#line 351 "ftp.y" X { X int oldmask; X X if (yyvsp[-3]) { X if ((yyvsp[-1] == -1) || (yyvsp[-1] > 0777)) { X reply(501, "Bad UMASK value"); X } else { X oldmask = umask(yyvsp[-1]); X reply(200, X "UMASK set to %03o (was %03o)", X yyvsp[-1], oldmask); X } X } X } Xbreak; Xcase 38: X#line 366 "ftp.y" X { X if (yyvsp[-5] && (yyvsp[-1] != NULL)) { X if (yyvsp[-3] > 0777) X reply(501, X "CHMOD: Mode value must be between 0 and 0777"); X else if (chmod((char *) yyvsp[-1], yyvsp[-3]) < 0) X perror_reply(550, (char *) yyvsp[-1]); X else X reply(200, "CHMOD command successful."); X } X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 39: X#line 380 "ftp.y" X { X reply(200, X "Current IDLE time limit is %d seconds; max %d", X timeout, maxtimeout); X } Xbreak; Xcase 40: X#line 386 "ftp.y" X { X if (yyvsp[-1] < 30 || yyvsp[-1] > maxtimeout) { X reply(501, X "Maximum IDLE time must be between 30 and %d seconds", X maxtimeout); X } else { X timeout = yyvsp[-1]; X (void) alarm((unsigned) timeout); X reply(200, X "Maximum IDLE time set to %d seconds", X timeout); X } X } Xbreak; Xcase 41: X#line 400 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X store((char *) yyvsp[-1], "w", 1); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 42: X#line 407 "ftp.y" X { X#ifdef unix X#ifdef BSD X reply(215, "UNIX Type: L%d Version: BSD-%d", X NBBY, BSD); X#else /* BSD */ X reply(215, "UNIX Type: L%d", NBBY); X#endif /* BSD */ X#else /* unix */ X reply(215, "UNKNOWN Type: L%d", NBBY); X#endif /* unix */ X } Xbreak; Xcase 43: X#line 428 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) X sizecmd((char *) yyvsp[-1]); X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 44: X#line 445 "ftp.y" X { X if (yyvsp[-3] && yyvsp[-1] != NULL) { X struct stat stbuf; X if (stat((char *) yyvsp[-1], &stbuf) < 0) X perror_reply(550, "%s", (char *) yyvsp[-1]); X else if ((stbuf.st_mode&S_IFMT) != S_IFREG) { X reply(550, "%s: not a plain file.", X (char *) yyvsp[-1]); X } else { X register struct tm *t; X struct tm *gmtime(); X t = gmtime(&stbuf.st_mtime); X reply(213, X "19%02d%02d%02d%02d%02d%02d", X t->tm_year, t->tm_mon+1, t->tm_mday, X t->tm_hour, t->tm_min, t->tm_sec); X } X } X if (yyvsp[-1] != NULL) X free((char *) yyvsp[-1]); X } Xbreak; Xcase 45: X#line 467 "ftp.y" X { X reply(221, "Goodbye."); X dologout(0); X } Xbreak; Xcase 46: X#line 472 "ftp.y" X { X yyerrok; X } Xbreak; Xcase 47: X#line 477 "ftp.y" X { X char *renamefrom(); X X if (yyvsp[-3] && yyvsp[-1]) { X fromname = renamefrom((char *) yyvsp[-1]); X if (fromname == (char *) 0 && yyvsp[-1]) { X free((char *) yyvsp[-1]); X } X } X } Xbreak; Xcase 49: X#line 493 "ftp.y" X { X *(char **)&(yyval) = ""; X } Xbreak; Xcase 52: X#line 504 "ftp.y" X { X register char *a, *p; X X a = (char *)&data_dest.sin_addr; X a[0] = yyvsp[-10]; a[1] = yyvsp[-8]; a[2] = yyvsp[-6]; a[3] = yyvsp[-4]; X p = (char *)&data_dest.sin_port; X p[0] = yyvsp[-2]; p[1] = yyvsp[0]; X data_dest.sin_family = AF_INET; X } Xbreak; Xcase 53: X#line 516 "ftp.y" X { X yyval = FORM_N; X } Xbreak; Xcase 54: X#line 520 "ftp.y" X { X yyval = FORM_T; X } Xbreak; Xcase 55: X#line 524 "ftp.y" X { X yyval = FORM_C; X } Xbreak; Xcase 56: X#line 530 "ftp.y" X { X cmd_type = TYPE_A; X cmd_form = FORM_N; X } Xbreak; Xcase 57: X#line 535 "ftp.y" X { X cmd_type = TYPE_A; X cmd_form = yyvsp[0]; X } Xbreak; Xcase 58: X#line 540 "ftp.y" X { X cmd_type = TYPE_E; X cmd_form = FORM_N; X } Xbreak; Xcase 59: X#line 545 "ftp.y" X { X cmd_type = TYPE_E; X cmd_form = yyvsp[0]; X } Xbreak; Xcase 60: X#line 550 "ftp.y" X { X cmd_type = TYPE_I; X } Xbreak; Xcase 61: X#line 554 "ftp.y" X { X cmd_type = TYPE_L; X cmd_bytesz = NBBY; X } Xbreak; Xcase 62: X#line 559 "ftp.y" X { X cmd_type = TYPE_L; X cmd_bytesz = yyvsp[0]; X } Xbreak; Xcase 63: X#line 565 "ftp.y" X { X cmd_type = TYPE_L; X cmd_bytesz = yyvsp[0]; X } Xbreak; Xcase 64: X#line 572 "ftp.y" X { X yyval = STRU_F; X } Xbreak; Xcase 65: X#line 576 "ftp.y" X { X yyval = STRU_R; X } Xbreak; Xcase 66: X#line 580 "ftp.y" X { X yyval = STRU_P; X } Xbreak; Xcase 67: X#line 586 "ftp.y" X { X yyval = MODE_S; X } Xbreak; Xcase 68: X#line 590 "ftp.y" X { X yyval = MODE_B; X } Xbreak; Xcase 69: X#line 594 "ftp.y" X { X yyval = MODE_C; X } Xbreak; Xcase 70: X#line 600 "ftp.y" X { X /* X * Problem: this production is used for all pathname X * processing, but only gives a 550 error reply. X * This is a valid reply in some cases but not in others. X */ X if (logged_in && yyvsp[0] && strncmp((char *) yyvsp[0], "~", 1) == 0) { X *(char **)&(yyval) = *glob((char *) yyvsp[0]); X if (globerr != NULL) { X reply(550, globerr); X yyval = NULL; X } X free((char *) yyvsp[0]); X } else X yyval = yyvsp[0]; X } Xbreak; Xcase 72: X#line 622 "ftp.y" X { X register int ret, dec, multby, digit; X X /* X * Convert a number that was read as decimal number X * to what it would be if it had been read as octal. X */ X dec = yyvsp[0]; X multby = 1; X ret = 0; X while (dec) { X digit = dec%10; X if (digit > 7) { X ret = -1; X break; X } X ret += digit * multby; X multby *= 8; X dec /= 10; X } X yyval = ret; X } Xbreak; Xcase 73: X#line 647 "ftp.y" X { X if (logged_in) X yyval = 1; X else { X reply(530, "Please login with USER and PASS."); X yyval = 0; X } X } Xbreak; X#line 1688 "ftp.tab.c" X } X yyssp -= yym; X yystate = *yyssp; X yyvsp -= yym; X yym = yylhs[yyn]; X if (yystate == 0 && yym == 0) X { X#if YYDEBUG X if (yydebug) X printf("%sdebug: after reduction, shifting from state 0 to\ X state %d\n", YYPREFIX, YYFINAL); X#endif X yystate = YYFINAL; X *++yyssp = YYFINAL; X *++yyvsp = yyval; X if (yychar < 0) X { X if ((yychar = yylex()) < 0) yychar = 0; X#if YYDEBUG X if (yydebug) X { X yys = 0; X if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; X if (!yys) yys = "illegal-symbol"; X printf("%sdebug: state %d, reading %d (%s)\n", X YYPREFIX, YYFINAL, yychar, yys); X } X#endif X } X if (yychar == 0) goto yyaccept; X goto yyloop; X } X if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && X yyn <= YYTABLESIZE && yycheck[yyn] == yystate) X yystate = yytable[yyn]; X else X yystate = yydgoto[yym]; X#if YYDEBUG X if (yydebug) X printf("%sdebug: after reduction, shifting from state %d \ Xto state %d\n", YYPREFIX, *yyssp, yystate); X#endif X if (yyssp >= yyss + yystacksize - 1) X { X goto yyoverflow; X } X *++yyssp = yystate; X *++yyvsp = yyval; X goto yyloop; Xyyoverflow: X yyerror("yacc stack overflow"); Xyyabort: X return (1); Xyyaccept: X return (0); X} END_OF_FILE if test 40069 -ne `wc -c <'test/ftp.tab.c'`; then echo shar: \"'test/ftp.tab.c'\" unpacked with wrong size! fi # end of 'test/ftp.tab.c' fi echo shar: End of archive 3 \(of 3\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0