home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / byacc19 / part03 < prev    next >
Encoding:
Text File  |  1993-07-04  |  74.3 KB  |  3,573 lines

  1. Newsgroups: comp.sources.unix
  2. From: robert.corbett@eng.Sun.COM (Roger Corbett)
  3. Subject: v26i291: byacc-1.9 - Berkeley YACC, Part03/03
  4. Sender: unix-sources-moderator@gw.home.vix.com
  5. Approved: vixie@gw.home.vix.com
  6.  
  7. Submitted-By: robert.corbett@eng.Sun.COM (Roger Corbett)
  8. Posting-Number: Volume 26, Issue 291
  9. Archive-Name: byacc-1.9/part03
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 3 (of 3)."
  18. # Contents:  reader.c test/ftp.tab.c
  19. # Wrapped by vixie@gw.home.vix.com on Mon Jul  5 19:23:05 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'reader.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'reader.c'\"
  23. else
  24. echo shar: Extracting \"'reader.c'\" \(30469 characters\)
  25. sed "s/^X//" >'reader.c' <<'END_OF_FILE'
  26. X#include "defs.h"
  27. X
  28. X/*  The line size must be a positive integer.  One hundred was chosen    */
  29. X/*  because few lines in Yacc input grammars exceed 100 characters.    */
  30. X/*  Note that if a line exceeds LINESIZE characters, the line buffer    */
  31. X/*  will be expanded to accomodate it.                    */
  32. X
  33. X#define LINESIZE 100
  34. X
  35. Xchar *cache;
  36. Xint cinc, cache_size;
  37. X
  38. Xint ntags, tagmax;
  39. Xchar **tag_table;
  40. X
  41. Xchar saw_eof, unionized;
  42. Xchar *cptr, *line;
  43. Xint linesize;
  44. X
  45. Xbucket *goal;
  46. Xint prec;
  47. Xint gensym;
  48. Xchar last_was_action;
  49. X
  50. Xint maxitems;
  51. Xbucket **pitem;
  52. X
  53. Xint maxrules;
  54. Xbucket **plhs;
  55. X
  56. Xint name_pool_size;
  57. Xchar *name_pool;
  58. X
  59. Xchar line_format[] = "#line %d \"%s\"\n";
  60. X
  61. X
  62. Xcachec(c)
  63. Xint c;
  64. X{
  65. X    assert(cinc >= 0);
  66. X    if (cinc >= cache_size)
  67. X    {
  68. X    cache_size += 256;
  69. X    cache = REALLOC(cache, cache_size);
  70. X    if (cache == 0) no_space();
  71. X    }
  72. X    cache[cinc] = c;
  73. X    ++cinc;
  74. X}
  75. X
  76. X
  77. Xget_line()
  78. X{
  79. X    register FILE *f = input_file;
  80. X    register int c;
  81. X    register int i;
  82. X
  83. X    if (saw_eof || (c = getc(f)) == EOF)
  84. X    {
  85. X    if (line) { FREE(line); line = 0; }
  86. X    cptr = 0;
  87. X    saw_eof = 1;
  88. X    return;
  89. X    }
  90. X
  91. X    if (line == 0 || linesize != (LINESIZE + 1))
  92. X    {
  93. X    if (line) FREE(line);
  94. X    linesize = LINESIZE + 1;
  95. X    line = MALLOC(linesize);
  96. X    if (line == 0) no_space();
  97. X    }
  98. X
  99. X    i = 0;
  100. X    ++lineno;
  101. X    for (;;)
  102. X    {
  103. X    line[i]  =  c;
  104. X    if (c == '\n') { cptr = line; return; }
  105. X    if (++i >= linesize)
  106. X    {
  107. X        linesize += LINESIZE;
  108. X        line = REALLOC(line, linesize);
  109. X        if (line ==  0) no_space();
  110. X    }
  111. X    c = getc(f);
  112. X    if (c ==  EOF)
  113. X    {
  114. X        line[i] = '\n';
  115. X        saw_eof = 1;
  116. X        cptr = line;
  117. X        return;
  118. X    }
  119. X    }
  120. X}
  121. X
  122. X
  123. Xchar *
  124. Xdup_line()
  125. X{
  126. X    register char *p, *s, *t;
  127. X
  128. X    if (line == 0) return (0);
  129. X    s = line;
  130. X    while (*s != '\n') ++s;
  131. X    p = MALLOC(s - line + 1);
  132. X    if (p == 0) no_space();
  133. X
  134. X    s = line;
  135. X    t = p;
  136. X    while ((*t++ = *s++) != '\n') continue;
  137. X    return (p);
  138. X}
  139. X
  140. X
  141. Xskip_comment()
  142. X{
  143. X    register char *s;
  144. X
  145. X    int st_lineno = lineno;
  146. X    char *st_line = dup_line();
  147. X    char *st_cptr = st_line + (cptr - line);
  148. X
  149. X    s = cptr + 2;
  150. X    for (;;)
  151. X    {
  152. X    if (*s == '*' && s[1] == '/')
  153. X    {
  154. X        cptr = s + 2;
  155. X        FREE(st_line);
  156. X        return;
  157. X    }
  158. X    if (*s == '\n')
  159. X    {
  160. X        get_line();
  161. X        if (line == 0)
  162. X        unterminated_comment(st_lineno, st_line, st_cptr);
  163. X        s = cptr;
  164. X    }
  165. X    else
  166. X        ++s;
  167. X    }
  168. X}
  169. X
  170. X
  171. Xint
  172. Xnextc()
  173. X{
  174. X    register char *s;
  175. X
  176. X    if (line == 0)
  177. X    {
  178. X    get_line();
  179. X    if (line == 0)
  180. X        return (EOF);
  181. X    }
  182. X
  183. X    s = cptr;
  184. X    for (;;)
  185. X    {
  186. X    switch (*s)
  187. X    {
  188. X    case '\n':
  189. X        get_line();
  190. X        if (line == 0) return (EOF);
  191. X        s = cptr;
  192. X        break;
  193. X
  194. X    case ' ':
  195. X    case '\t':
  196. X    case '\f':
  197. X    case '\r':
  198. X    case '\v':
  199. X    case ',':
  200. X    case ';':
  201. X        ++s;
  202. X        break;
  203. X
  204. X    case '\\':
  205. X        cptr = s;
  206. X        return ('%');
  207. X
  208. X    case '/':
  209. X        if (s[1] == '*')
  210. X        {
  211. X        cptr = s;
  212. X        skip_comment();
  213. X        s = cptr;
  214. X        break;
  215. X        }
  216. X        else if (s[1] == '/')
  217. X        {
  218. X        get_line();
  219. X        if (line == 0) return (EOF);
  220. X        s = cptr;
  221. X        break;
  222. X        }
  223. X        /* fall through */
  224. X
  225. X    default:
  226. X        cptr = s;
  227. X        return (*s);
  228. X    }
  229. X    }
  230. X}
  231. X
  232. X
  233. Xint
  234. Xkeyword()
  235. X{
  236. X    register int c;
  237. X    char *t_cptr = cptr;
  238. X
  239. X    c = *++cptr;
  240. X    if (isalpha(c))
  241. X    {
  242. X    cinc = 0;
  243. X    for (;;)
  244. X    {
  245. X        if (isalpha(c))
  246. X        {
  247. X        if (isupper(c)) c = tolower(c);
  248. X        cachec(c);
  249. X        }
  250. X        else if (isdigit(c) || c == '_' || c == '.' || c == '$')
  251. X        cachec(c);
  252. X        else
  253. X        break;
  254. X        c = *++cptr;
  255. X    }
  256. X    cachec(NUL);
  257. X
  258. X    if (strcmp(cache, "token") == 0 || strcmp(cache, "term") == 0)
  259. X        return (TOKEN);
  260. X    if (strcmp(cache, "type") == 0)
  261. X        return (TYPE);
  262. X    if (strcmp(cache, "left") == 0)
  263. X        return (LEFT);
  264. X    if (strcmp(cache, "right") == 0)
  265. X        return (RIGHT);
  266. X    if (strcmp(cache, "nonassoc") == 0 || strcmp(cache, "binary") == 0)
  267. X        return (NONASSOC);
  268. X    if (strcmp(cache, "start") == 0)
  269. X        return (START);
  270. X    if (strcmp(cache, "union") == 0)
  271. X        return (UNION);
  272. X    if (strcmp(cache, "ident") == 0)
  273. X        return (IDENT);
  274. X    }
  275. X    else
  276. X    {
  277. X    ++cptr;
  278. X    if (c == '{')
  279. X        return (TEXT);
  280. X    if (c == '%' || c == '\\')
  281. X        return (MARK);
  282. X    if (c == '<')
  283. X        return (LEFT);
  284. X    if (c == '>')
  285. X        return (RIGHT);
  286. X    if (c == '0')
  287. X        return (TOKEN);
  288. X    if (c == '2')
  289. X        return (NONASSOC);
  290. X    }
  291. X    syntax_error(lineno, line, t_cptr);
  292. X    /*NOTREACHED*/
  293. X}
  294. X
  295. X
  296. Xcopy_ident()
  297. X{
  298. X    register int c;
  299. X    register FILE *f = output_file;
  300. X
  301. X    c = nextc();
  302. X    if (c == EOF) unexpected_EOF();
  303. X    if (c != '"') syntax_error(lineno, line, cptr);
  304. X    ++outline;
  305. X    fprintf(f, "#ident \"");
  306. X    for (;;)
  307. X    {
  308. X    c = *++cptr;
  309. X    if (c == '\n')
  310. X    {
  311. X        fprintf(f, "\"\n");
  312. X        return;
  313. X    }
  314. X    putc(c, f);
  315. X    if (c == '"')
  316. X    {
  317. X        putc('\n', f);
  318. X        ++cptr;
  319. X        return;
  320. X    }
  321. X    }
  322. X}
  323. X
  324. X
  325. Xcopy_text()
  326. X{
  327. X    register int c;
  328. X    int quote;
  329. X    register FILE *f = text_file;
  330. X    int need_newline = 0;
  331. X    int t_lineno = lineno;
  332. X    char *t_line = dup_line();
  333. X    char *t_cptr = t_line + (cptr - line - 2);
  334. X
  335. X    if (*cptr == '\n')
  336. X    {
  337. X    get_line();
  338. X    if (line == 0)
  339. X        unterminated_text(t_lineno, t_line, t_cptr);
  340. X    }
  341. X    if (!lflag) fprintf(f, line_format, lineno, input_file_name);
  342. X
  343. Xloop:
  344. X    c = *cptr++;
  345. X    switch (c)
  346. X    {
  347. X    case '\n':
  348. X    next_line:
  349. X    putc('\n', f);
  350. X    need_newline = 0;
  351. X    get_line();
  352. X    if (line) goto loop;
  353. X    unterminated_text(t_lineno, t_line, t_cptr);
  354. X
  355. X    case '\'':
  356. X    case '"':
  357. X    {
  358. X        int s_lineno = lineno;
  359. X        char *s_line = dup_line();
  360. X        char *s_cptr = s_line + (cptr - line - 1);
  361. X
  362. X        quote = c;
  363. X        putc(c, f);
  364. X        for (;;)
  365. X        {
  366. X        c = *cptr++;
  367. X        putc(c, f);
  368. X        if (c == quote)
  369. X        {
  370. X            need_newline = 1;
  371. X            FREE(s_line);
  372. X            goto loop;
  373. X        }
  374. X        if (c == '\n')
  375. X            unterminated_string(s_lineno, s_line, s_cptr);
  376. X        if (c == '\\')
  377. X        {
  378. X            c = *cptr++;
  379. X            putc(c, f);
  380. X            if (c == '\n')
  381. X            {
  382. X            get_line();
  383. X            if (line == 0)
  384. X                unterminated_string(s_lineno, s_line, s_cptr);
  385. X            }
  386. X        }
  387. X        }
  388. X    }
  389. X
  390. X    case '/':
  391. X    putc(c, f);
  392. X    need_newline = 1;
  393. X    c = *cptr;
  394. X    if (c == '/')
  395. X    {
  396. X        putc('*', f);
  397. X        while ((c = *++cptr) != '\n')
  398. X        {
  399. X        if (c == '*' && cptr[1] == '/')
  400. X            fprintf(f, "* ");
  401. X        else
  402. X            putc(c, f);
  403. X        }
  404. X        fprintf(f, "*/");
  405. X        goto next_line;
  406. X    }
  407. X    if (c == '*')
  408. X    {
  409. X        int c_lineno = lineno;
  410. X        char *c_line = dup_line();
  411. X        char *c_cptr = c_line + (cptr - line - 1);
  412. X
  413. X        putc('*', f);
  414. X        ++cptr;
  415. X        for (;;)
  416. X        {
  417. X        c = *cptr++;
  418. X        putc(c, f);
  419. X        if (c == '*' && *cptr == '/')
  420. X        {
  421. X            putc('/', f);
  422. X            ++cptr;
  423. X            FREE(c_line);
  424. X            goto loop;
  425. X        }
  426. X        if (c == '\n')
  427. X        {
  428. X            get_line();
  429. X            if (line == 0)
  430. X            unterminated_comment(c_lineno, c_line, c_cptr);
  431. X        }
  432. X        }
  433. X    }
  434. X    need_newline = 1;
  435. X    goto loop;
  436. X
  437. X    case '%':
  438. X    case '\\':
  439. X    if (*cptr == '}')
  440. X    {
  441. X        if (need_newline) putc('\n', f);
  442. X        ++cptr;
  443. X        FREE(t_line);
  444. X        return;
  445. X    }
  446. X    /* fall through */
  447. X
  448. X    default:
  449. X    putc(c, f);
  450. X    need_newline = 1;
  451. X    goto loop;
  452. X    }
  453. X}
  454. X
  455. X
  456. Xcopy_union()
  457. X{
  458. X    register int c;
  459. X    int quote;
  460. X    int depth;
  461. X    int u_lineno = lineno;
  462. X    char *u_line = dup_line();
  463. X    char *u_cptr = u_line + (cptr - line - 6);
  464. X
  465. X    if (unionized) over_unionized(cptr - 6);
  466. X    unionized = 1;
  467. X
  468. X    if (!lflag)
  469. X    fprintf(text_file, line_format, lineno, input_file_name);
  470. X
  471. X    fprintf(text_file, "typedef union");
  472. X    if (dflag) fprintf(union_file, "typedef union");
  473. X
  474. X    depth = 0;
  475. Xloop:
  476. X    c = *cptr++;
  477. X    putc(c, text_file);
  478. X    if (dflag) putc(c, union_file);
  479. X    switch (c)
  480. X    {
  481. X    case '\n':
  482. X    next_line:
  483. X    get_line();
  484. X    if (line == 0) unterminated_union(u_lineno, u_line, u_cptr);
  485. X    goto loop;
  486. X
  487. X    case '{':
  488. X    ++depth;
  489. X    goto loop;
  490. X
  491. X    case '}':
  492. X    if (--depth == 0)
  493. X    {
  494. X        fprintf(text_file, " YYSTYPE;\n");
  495. X        FREE(u_line);
  496. X        return;
  497. X    }
  498. X    goto loop;
  499. X
  500. X    case '\'':
  501. X    case '"':
  502. X    {
  503. X        int s_lineno = lineno;
  504. X        char *s_line = dup_line();
  505. X        char *s_cptr = s_line + (cptr - line - 1);
  506. X
  507. X        quote = c;
  508. X        for (;;)
  509. X        {
  510. X        c = *cptr++;
  511. X        putc(c, text_file);
  512. X        if (dflag) putc(c, union_file);
  513. X        if (c == quote)
  514. X        {
  515. X            FREE(s_line);
  516. X            goto loop;
  517. X        }
  518. X        if (c == '\n')
  519. X            unterminated_string(s_lineno, s_line, s_cptr);
  520. X        if (c == '\\')
  521. X        {
  522. X            c = *cptr++;
  523. X            putc(c, text_file);
  524. X            if (dflag) putc(c, union_file);
  525. X            if (c == '\n')
  526. X            {
  527. X            get_line();
  528. X            if (line == 0)
  529. X                unterminated_string(s_lineno, s_line, s_cptr);
  530. X            }
  531. X        }
  532. X        }
  533. X    }
  534. X
  535. X    case '/':
  536. X    c = *cptr;
  537. X    if (c == '/')
  538. X    {
  539. X        putc('*', text_file);
  540. X        if (dflag) putc('*', union_file);
  541. X        while ((c = *++cptr) != '\n')
  542. X        {
  543. X        if (c == '*' && cptr[1] == '/')
  544. X        {
  545. X            fprintf(text_file, "* ");
  546. X            if (dflag) fprintf(union_file, "* ");
  547. X        }
  548. X        else
  549. X        {
  550. X            putc(c, text_file);
  551. X            if (dflag) putc(c, union_file);
  552. X        }
  553. X        }
  554. X        fprintf(text_file, "*/\n");
  555. X        if (dflag) fprintf(union_file, "*/\n");
  556. X        goto next_line;
  557. X    }
  558. X    if (c == '*')
  559. X    {
  560. X        int c_lineno = lineno;
  561. X        char *c_line = dup_line();
  562. X        char *c_cptr = c_line + (cptr - line - 1);
  563. X
  564. X        putc('*', text_file);
  565. X        if (dflag) putc('*', union_file);
  566. X        ++cptr;
  567. X        for (;;)
  568. X        {
  569. X        c = *cptr++;
  570. X        putc(c, text_file);
  571. X        if (dflag) putc(c, union_file);
  572. X        if (c == '*' && *cptr == '/')
  573. X        {
  574. X            putc('/', text_file);
  575. X            if (dflag) putc('/', union_file);
  576. X            ++cptr;
  577. X            FREE(c_line);
  578. X            goto loop;
  579. X        }
  580. X        if (c == '\n')
  581. X        {
  582. X            get_line();
  583. X            if (line == 0)
  584. X            unterminated_comment(c_lineno, c_line, c_cptr);
  585. X        }
  586. X        }
  587. X    }
  588. X    goto loop;
  589. X
  590. X    default:
  591. X    goto loop;
  592. X    }
  593. X}
  594. X
  595. X
  596. Xint
  597. Xhexval(c)
  598. Xint c;
  599. X{
  600. X    if (c >= '0' && c <= '9')
  601. X    return (c - '0');
  602. X    if (c >= 'A' && c <= 'F')
  603. X    return (c - 'A' + 10);
  604. X    if (c >= 'a' && c <= 'f')
  605. X    return (c - 'a' + 10);
  606. X    return (-1);
  607. X}
  608. X
  609. X
  610. Xbucket *
  611. Xget_literal()
  612. X{
  613. X    register int c, quote;
  614. X    register int i;
  615. X    register int n;
  616. X    register char *s;
  617. X    register bucket *bp;
  618. X    int s_lineno = lineno;
  619. X    char *s_line = dup_line();
  620. X    char *s_cptr = s_line + (cptr - line);
  621. X
  622. X    quote = *cptr++;
  623. X    cinc = 0;
  624. X    for (;;)
  625. X    {
  626. X    c = *cptr++;
  627. X    if (c == quote) break;
  628. X    if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr);
  629. X    if (c == '\\')
  630. X    {
  631. X        char *c_cptr = cptr - 1;
  632. X
  633. X        c = *cptr++;
  634. X        switch (c)
  635. X        {
  636. X        case '\n':
  637. X        get_line();
  638. X        if (line == 0) unterminated_string(s_lineno, s_line, s_cptr);
  639. X        continue;
  640. X
  641. X        case '0': case '1': case '2': case '3':
  642. X        case '4': case '5': case '6': case '7':
  643. X        n = c - '0';
  644. X        c = *cptr;
  645. X        if (IS_OCTAL(c))
  646. X        {
  647. X            n = (n << 3) + (c - '0');
  648. X            c = *++cptr;
  649. X            if (IS_OCTAL(c))
  650. X            {
  651. X            n = (n << 3) + (c - '0');
  652. X            ++cptr;
  653. X            }
  654. X        }
  655. X        if (n > MAXCHAR) illegal_character(c_cptr);
  656. X        c = n;
  657. X            break;
  658. X
  659. X        case 'x':
  660. X        c = *cptr++;
  661. X        n = hexval(c);
  662. X        if (n < 0 || n >= 16)
  663. X            illegal_character(c_cptr);
  664. X        for (;;)
  665. X        {
  666. X            c = *cptr;
  667. X            i = hexval(c);
  668. X            if (i < 0 || i >= 16) break;
  669. X            ++cptr;
  670. X            n = (n << 4) + i;
  671. X            if (n > MAXCHAR) illegal_character(c_cptr);
  672. X        }
  673. X        c = n;
  674. X        break;
  675. X
  676. X        case 'a': c = 7; break;
  677. X        case 'b': c = '\b'; break;
  678. X        case 'f': c = '\f'; break;
  679. X        case 'n': c = '\n'; break;
  680. X        case 'r': c = '\r'; break;
  681. X        case 't': c = '\t'; break;
  682. X        case 'v': c = '\v'; break;
  683. X        }
  684. X    }
  685. X    cachec(c);
  686. X    }
  687. X    FREE(s_line);
  688. X
  689. X    n = cinc;
  690. X    s = MALLOC(n);
  691. X    if (s == 0) no_space();
  692. X    
  693. X    for (i = 0; i < n; ++i)
  694. X    s[i] = cache[i];
  695. X
  696. X    cinc = 0;
  697. X    if (n == 1)
  698. X    cachec('\'');
  699. X    else
  700. X    cachec('"');
  701. X
  702. X    for (i = 0; i < n; ++i)
  703. X    {
  704. X    c = ((unsigned char *)s)[i];
  705. X    if (c == '\\' || c == cache[0])
  706. X    {
  707. X        cachec('\\');
  708. X        cachec(c);
  709. X    }
  710. X    else if (isprint(c))
  711. X        cachec(c);
  712. X    else
  713. X    {
  714. X        cachec('\\');
  715. X        switch (c)
  716. X        {
  717. X        case 7: cachec('a'); break;
  718. X        case '\b': cachec('b'); break;
  719. X        case '\f': cachec('f'); break;
  720. X        case '\n': cachec('n'); break;
  721. X        case '\r': cachec('r'); break;
  722. X        case '\t': cachec('t'); break;
  723. X        case '\v': cachec('v'); break;
  724. X        default:
  725. X        cachec(((c >> 6) & 7) + '0');
  726. X        cachec(((c >> 3) & 7) + '0');
  727. X        cachec((c & 7) + '0');
  728. X        break;
  729. X        }
  730. X    }
  731. X    }
  732. X
  733. X    if (n == 1)
  734. X    cachec('\'');
  735. X    else
  736. X    cachec('"');
  737. X
  738. X    cachec(NUL);
  739. X    bp = lookup(cache);
  740. X    bp->class = TERM;
  741. X    if (n == 1 && bp->value == UNDEFINED)
  742. X    bp->value = *(unsigned char *)s;
  743. X    FREE(s);
  744. X
  745. X    return (bp);
  746. X}
  747. X
  748. X
  749. Xint
  750. Xis_reserved(name)
  751. Xchar *name;
  752. X{
  753. X    char *s;
  754. X
  755. X    if (strcmp(name, ".") == 0 ||
  756. X        strcmp(name, "$accept") == 0 ||
  757. X        strcmp(name, "$end") == 0)
  758. X    return (1);
  759. X
  760. X    if (name[0] == '$' && name[1] == '$' && isdigit(name[2]))
  761. X    {
  762. X    s = name + 3;
  763. X    while (isdigit(*s)) ++s;
  764. X    if (*s == NUL) return (1);
  765. X    }
  766. X
  767. X    return (0);
  768. X}
  769. X
  770. X
  771. Xbucket *
  772. Xget_name()
  773. X{
  774. X    register int c;
  775. X
  776. X    cinc = 0;
  777. X    for (c = *cptr; IS_IDENT(c); c = *++cptr)
  778. X    cachec(c);
  779. X    cachec(NUL);
  780. X
  781. X    if (is_reserved(cache)) used_reserved(cache);
  782. X
  783. X    return (lookup(cache));
  784. X}
  785. X
  786. X
  787. Xint
  788. Xget_number()
  789. X{
  790. X    register int c;
  791. X    register int n;
  792. X
  793. X    n = 0;
  794. X    for (c = *cptr; isdigit(c); c = *++cptr)
  795. X    n = 10*n + (c - '0');
  796. X
  797. X    return (n);
  798. X}
  799. X
  800. X
  801. Xchar *
  802. Xget_tag()
  803. X{
  804. X    register int c;
  805. X    register int i;
  806. X    register char *s;
  807. X    int t_lineno = lineno;
  808. X    char *t_line = dup_line();
  809. X    char *t_cptr = t_line + (cptr - line);
  810. X
  811. X    ++cptr;
  812. X    c = nextc();
  813. X    if (c == EOF) unexpected_EOF();
  814. X    if (!isalpha(c) && c != '_' && c != '$')
  815. X    illegal_tag(t_lineno, t_line, t_cptr);
  816. X
  817. X    cinc = 0;
  818. X    do { cachec(c); c = *++cptr; } while (IS_IDENT(c));
  819. X    cachec(NUL);
  820. X
  821. X    c = nextc();
  822. X    if (c == EOF) unexpected_EOF();
  823. X    if (c != '>')
  824. X    illegal_tag(t_lineno, t_line, t_cptr);
  825. X    ++cptr;
  826. X
  827. X    for (i = 0; i < ntags; ++i)
  828. X    {
  829. X    if (strcmp(cache, tag_table[i]) == 0)
  830. X        return (tag_table[i]);
  831. X    }
  832. X
  833. X    if (ntags >= tagmax)
  834. X    {
  835. X    tagmax += 16;
  836. X    tag_table = (char **)
  837. X            (tag_table ? REALLOC(tag_table, tagmax*sizeof(char *))
  838. X                   : MALLOC(tagmax*sizeof(char *)));
  839. X    if (tag_table == 0) no_space();
  840. X    }
  841. X
  842. X    s = MALLOC(cinc);
  843. X    if  (s == 0) no_space();
  844. X    strcpy(s, cache);
  845. X    tag_table[ntags] = s;
  846. X    ++ntags;
  847. X    FREE(t_line);
  848. X    return (s);
  849. X}
  850. X
  851. X
  852. Xdeclare_tokens(assoc)
  853. Xint assoc;
  854. X{
  855. X    register int c;
  856. X    register bucket *bp;
  857. X    int value;
  858. X    char *tag = 0;
  859. X
  860. X    if (assoc != TOKEN) ++prec;
  861. X
  862. X    c = nextc();
  863. X    if (c == EOF) unexpected_EOF();
  864. X    if (c == '<')
  865. X    {
  866. X    tag = get_tag();
  867. X    c = nextc();
  868. X    if (c == EOF) unexpected_EOF();
  869. X    }
  870. X
  871. X    for (;;)
  872. X    {
  873. X    if (isalpha(c) || c == '_' || c == '.' || c == '$')
  874. X        bp = get_name();
  875. X    else if (c == '\'' || c == '"')
  876. X        bp = get_literal();
  877. X    else
  878. X        return;
  879. X
  880. X    if (bp == goal) tokenized_start(bp->name);
  881. X    bp->class = TERM;
  882. X
  883. X    if (tag)
  884. X    {
  885. X        if (bp->tag && tag != bp->tag)
  886. X        retyped_warning(bp->name);
  887. X        bp->tag = tag;
  888. X    }
  889. X
  890. X    if (assoc != TOKEN)
  891. X    {
  892. X        if (bp->prec && prec != bp->prec)
  893. X        reprec_warning(bp->name);
  894. X        bp->assoc = assoc;
  895. X        bp->prec = prec;
  896. X    }
  897. X
  898. X    c = nextc();
  899. X    if (c == EOF) unexpected_EOF();
  900. X    value = UNDEFINED;
  901. X    if (isdigit(c))
  902. X    {
  903. X        value = get_number();
  904. X        if (bp->value != UNDEFINED && value != bp->value)
  905. X        revalued_warning(bp->name);
  906. X        bp->value = value;
  907. X        c = nextc();
  908. X        if (c == EOF) unexpected_EOF();
  909. X    }
  910. X    }
  911. X}
  912. X
  913. X
  914. Xdeclare_types()
  915. X{
  916. X    register int c;
  917. X    register bucket *bp;
  918. X    char *tag;
  919. X
  920. X    c = nextc();
  921. X    if (c == EOF) unexpected_EOF();
  922. X    if (c != '<') syntax_error(lineno, line, cptr);
  923. X    tag = get_tag();
  924. X
  925. X    for (;;)
  926. X    {
  927. X    c = nextc();
  928. X    if (isalpha(c) || c == '_' || c == '.' || c == '$')
  929. X        bp = get_name();
  930. X    else if (c == '\'' || c == '"')
  931. X        bp = get_literal();
  932. X    else
  933. X        return;
  934. X
  935. X    if (bp->tag && tag != bp->tag)
  936. X        retyped_warning(bp->name);
  937. X    bp->tag = tag;
  938. X    }
  939. X}
  940. X
  941. X
  942. Xdeclare_start()
  943. X{
  944. X    register int c;
  945. X    register bucket *bp;
  946. X
  947. X    c = nextc();
  948. X    if (c == EOF) unexpected_EOF();
  949. X    if (!isalpha(c) && c != '_' && c != '.' && c != '$')
  950. X    syntax_error(lineno, line, cptr);
  951. X    bp = get_name();
  952. X    if (bp->class == TERM)
  953. X    terminal_start(bp->name);
  954. X    if (goal && goal != bp)
  955. X    restarted_warning();
  956. X    goal = bp;
  957. X}
  958. X
  959. X
  960. Xread_declarations()
  961. X{
  962. X    register int c, k;
  963. X
  964. X    cache_size = 256;
  965. X    cache = MALLOC(cache_size);
  966. X    if (cache == 0) no_space();
  967. X
  968. X    for (;;)
  969. X    {
  970. X    c = nextc();
  971. X    if (c == EOF) unexpected_EOF();
  972. X    if (c != '%') syntax_error(lineno, line, cptr);
  973. X    switch (k = keyword())
  974. X    {
  975. X    case MARK:
  976. X        return;
  977. X
  978. X    case IDENT:
  979. X        copy_ident();
  980. X        break;
  981. X
  982. X    case TEXT:
  983. X        copy_text();
  984. X        break;
  985. X
  986. X    case UNION:
  987. X        copy_union();
  988. X        break;
  989. X
  990. X    case TOKEN:
  991. X    case LEFT:
  992. X    case RIGHT:
  993. X    case NONASSOC:
  994. X        declare_tokens(k);
  995. X        break;
  996. X
  997. X    case TYPE:
  998. X        declare_types();
  999. X        break;
  1000. X
  1001. X    case START:
  1002. X        declare_start();
  1003. X        break;
  1004. X    }
  1005. X    }
  1006. X}
  1007. X
  1008. X
  1009. Xinitialize_grammar()
  1010. X{
  1011. X    nitems = 4;
  1012. X    maxitems = 300;
  1013. X    pitem = (bucket **) MALLOC(maxitems*sizeof(bucket *));
  1014. X    if (pitem == 0) no_space();
  1015. X    pitem[0] = 0;
  1016. X    pitem[1] = 0;
  1017. X    pitem[2] = 0;
  1018. X    pitem[3] = 0;
  1019. X
  1020. X    nrules = 3;
  1021. X    maxrules = 100;
  1022. X    plhs = (bucket **) MALLOC(maxrules*sizeof(bucket *));
  1023. X    if (plhs == 0) no_space();
  1024. X    plhs[0] = 0;
  1025. X    plhs[1] = 0;
  1026. X    plhs[2] = 0;
  1027. X    rprec = (short *) MALLOC(maxrules*sizeof(short));
  1028. X    if (rprec == 0) no_space();
  1029. X    rprec[0] = 0;
  1030. X    rprec[1] = 0;
  1031. X    rprec[2] = 0;
  1032. X    rassoc = (char *) MALLOC(maxrules*sizeof(char));
  1033. X    if (rassoc == 0) no_space();
  1034. X    rassoc[0] = TOKEN;
  1035. X    rassoc[1] = TOKEN;
  1036. X    rassoc[2] = TOKEN;
  1037. X}
  1038. X
  1039. X
  1040. Xexpand_items()
  1041. X{
  1042. X    maxitems += 300;
  1043. X    pitem = (bucket **) REALLOC(pitem, maxitems*sizeof(bucket *));
  1044. X    if (pitem == 0) no_space();
  1045. X}
  1046. X
  1047. X
  1048. Xexpand_rules()
  1049. X{
  1050. X    maxrules += 100;
  1051. X    plhs = (bucket **) REALLOC(plhs, maxrules*sizeof(bucket *));
  1052. X    if (plhs == 0) no_space();
  1053. X    rprec = (short *) REALLOC(rprec, maxrules*sizeof(short));
  1054. X    if (rprec == 0) no_space();
  1055. X    rassoc = (char *) REALLOC(rassoc, maxrules*sizeof(char));
  1056. X    if (rassoc == 0) no_space();
  1057. X}
  1058. X
  1059. X
  1060. Xadvance_to_start()
  1061. X{
  1062. X    register int c;
  1063. X    register bucket *bp;
  1064. X    char *s_cptr;
  1065. X    int s_lineno;
  1066. X
  1067. X    for (;;)
  1068. X    {
  1069. X    c = nextc();
  1070. X    if (c != '%') break;
  1071. X    s_cptr = cptr;
  1072. X    switch (keyword())
  1073. X    {
  1074. X    case MARK:
  1075. X        no_grammar();
  1076. X
  1077. X    case TEXT:
  1078. X        copy_text();
  1079. X        break;
  1080. X
  1081. X    case START:
  1082. X        declare_start();
  1083. X        break;
  1084. X
  1085. X    default:
  1086. X        syntax_error(lineno, line, s_cptr);
  1087. X    }
  1088. X    }
  1089. X
  1090. X    c = nextc();
  1091. X    if (!isalpha(c) && c != '_' && c != '.' && c != '_')
  1092. X    syntax_error(lineno, line, cptr);
  1093. X    bp = get_name();
  1094. X    if (goal == 0)
  1095. X    {
  1096. X    if (bp->class == TERM)
  1097. X        terminal_start(bp->name);
  1098. X    goal = bp;
  1099. X    }
  1100. X
  1101. X    s_lineno = lineno;
  1102. X    c = nextc();
  1103. X    if (c == EOF) unexpected_EOF();
  1104. X    if (c != ':') syntax_error(lineno, line, cptr);
  1105. X    start_rule(bp, s_lineno);
  1106. X    ++cptr;
  1107. X}
  1108. X
  1109. X
  1110. Xstart_rule(bp, s_lineno)
  1111. Xregister bucket *bp;
  1112. Xint s_lineno;
  1113. X{
  1114. X    if (bp->class == TERM)
  1115. X    terminal_lhs(s_lineno);
  1116. X    bp->class = NONTERM;
  1117. X    if (nrules >= maxrules)
  1118. X    expand_rules();
  1119. X    plhs[nrules] = bp;
  1120. X    rprec[nrules] = UNDEFINED;
  1121. X    rassoc[nrules] = TOKEN;
  1122. X}
  1123. X
  1124. X
  1125. Xend_rule()
  1126. X{
  1127. X    register int i;
  1128. X
  1129. X    if (!last_was_action && plhs[nrules]->tag)
  1130. X    {
  1131. X    for (i = nitems - 1; pitem[i]; --i) continue;
  1132. X    if (pitem[i+1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag)
  1133. X        default_action_warning();
  1134. X    }
  1135. X
  1136. X    last_was_action = 0;
  1137. X    if (nitems >= maxitems) expand_items();
  1138. X    pitem[nitems] = 0;
  1139. X    ++nitems;
  1140. X    ++nrules;
  1141. X}
  1142. X
  1143. X
  1144. Xinsert_empty_rule()
  1145. X{
  1146. X    register bucket *bp, **bpp;
  1147. X
  1148. X    assert(cache);
  1149. X    sprintf(cache, "$$%d", ++gensym);
  1150. X    bp = make_bucket(cache);
  1151. X    last_symbol->next = bp;
  1152. X    last_symbol = bp;
  1153. X    bp->tag = plhs[nrules]->tag;
  1154. X    bp->class = NONTERM;
  1155. X
  1156. X    if ((nitems += 2) > maxitems)
  1157. X    expand_items();
  1158. X    bpp = pitem + nitems - 1;
  1159. X    *bpp-- = bp;
  1160. X    while (bpp[0] = bpp[-1]) --bpp;
  1161. X
  1162. X    if (++nrules >= maxrules)
  1163. X    expand_rules();
  1164. X    plhs[nrules] = plhs[nrules-1];
  1165. X    plhs[nrules-1] = bp;
  1166. X    rprec[nrules] = rprec[nrules-1];
  1167. X    rprec[nrules-1] = 0;
  1168. X    rassoc[nrules] = rassoc[nrules-1];
  1169. X    rassoc[nrules-1] = TOKEN;
  1170. X}
  1171. X
  1172. X
  1173. Xadd_symbol()
  1174. X{
  1175. X    register int c;
  1176. X    register bucket *bp;
  1177. X    int s_lineno = lineno;
  1178. X
  1179. X    c = *cptr;
  1180. X    if (c == '\'' || c == '"')
  1181. X    bp = get_literal();
  1182. X    else
  1183. X    bp = get_name();
  1184. X
  1185. X    c = nextc();
  1186. X    if (c == ':')
  1187. X    {
  1188. X    end_rule();
  1189. X    start_rule(bp, s_lineno);
  1190. X    ++cptr;
  1191. X    return;
  1192. X    }
  1193. X
  1194. X    if (last_was_action)
  1195. X    insert_empty_rule();
  1196. X    last_was_action = 0;
  1197. X
  1198. X    if (++nitems > maxitems)
  1199. X    expand_items();
  1200. X    pitem[nitems-1] = bp;
  1201. X}
  1202. X
  1203. X
  1204. Xcopy_action()
  1205. X{
  1206. X    register int c;
  1207. X    register int i, n;
  1208. X    int depth;
  1209. X    int quote;
  1210. X    char *tag;
  1211. X    register FILE *f = action_file;
  1212. X    int a_lineno = lineno;
  1213. X    char *a_line = dup_line();
  1214. X    char *a_cptr = a_line + (cptr - line);
  1215. X
  1216. X    if (last_was_action)
  1217. X    insert_empty_rule();
  1218. X    last_was_action = 1;
  1219. X
  1220. X    fprintf(f, "case %d:\n", nrules - 2);
  1221. X    if (!lflag)
  1222. X    fprintf(f, line_format, lineno, input_file_name);
  1223. X    if (*cptr == '=') ++cptr;
  1224. X
  1225. X    n = 0;
  1226. X    for (i = nitems - 1; pitem[i]; --i) ++n;
  1227. X
  1228. X    depth = 0;
  1229. Xloop:
  1230. X    c = *cptr;
  1231. X    if (c == '$')
  1232. X    {
  1233. X    if (cptr[1] == '<')
  1234. X    {
  1235. X        int d_lineno = lineno;
  1236. X        char *d_line = dup_line();
  1237. X        char *d_cptr = d_line + (cptr - line);
  1238. X
  1239. X        ++cptr;
  1240. X        tag = get_tag();
  1241. X        c = *cptr;
  1242. X        if (c == '$')
  1243. X        {
  1244. X        fprintf(f, "yyval.%s", tag);
  1245. X        ++cptr;
  1246. X        FREE(d_line);
  1247. X        goto loop;
  1248. X        }
  1249. X        else if (isdigit(c))
  1250. X        {
  1251. X        i = get_number();
  1252. X        if (i > n) dollar_warning(d_lineno, i);
  1253. X        fprintf(f, "yyvsp[%d].%s", i - n, tag);
  1254. X        FREE(d_line);
  1255. X        goto loop;
  1256. X        }
  1257. X        else if (c == '-' && isdigit(cptr[1]))
  1258. X        {
  1259. X        ++cptr;
  1260. X        i = -get_number() - n;
  1261. X        fprintf(f, "yyvsp[%d].%s", i, tag);
  1262. X        FREE(d_line);
  1263. X        goto loop;
  1264. X        }
  1265. X        else
  1266. X        dollar_error(d_lineno, d_line, d_cptr);
  1267. X    }
  1268. X    else if (cptr[1] == '$')
  1269. X    {
  1270. X        if (ntags)
  1271. X        {
  1272. X        tag = plhs[nrules]->tag;
  1273. X        if (tag == 0) untyped_lhs();
  1274. X        fprintf(f, "yyval.%s", tag);
  1275. X        }
  1276. X        else
  1277. X        fprintf(f, "yyval");
  1278. X        cptr += 2;
  1279. X        goto loop;
  1280. X    }
  1281. X    else if (isdigit(cptr[1]))
  1282. X    {
  1283. X        ++cptr;
  1284. X        i = get_number();
  1285. X        if (ntags)
  1286. X        {
  1287. X        if (i <= 0 || i > n)
  1288. X            unknown_rhs(i);
  1289. X        tag = pitem[nitems + i - n - 1]->tag;
  1290. X        if (tag == 0) untyped_rhs(i, pitem[nitems + i - n - 1]->name);
  1291. X        fprintf(f, "yyvsp[%d].%s", i - n, tag);
  1292. X        }
  1293. X        else
  1294. X        {
  1295. X        if (i > n)
  1296. X            dollar_warning(lineno, i);
  1297. X        fprintf(f, "yyvsp[%d]", i - n);
  1298. X        }
  1299. X        goto loop;
  1300. X    }
  1301. X    else if (cptr[1] == '-')
  1302. X    {
  1303. X        cptr += 2;
  1304. X        i = get_number();
  1305. X        if (ntags)
  1306. X        unknown_rhs(-i);
  1307. X        fprintf(f, "yyvsp[%d]", -i - n);
  1308. X        goto loop;
  1309. X    }
  1310. X    }
  1311. X    if (isalpha(c) || c == '_' || c == '$')
  1312. X    {
  1313. X    do
  1314. X    {
  1315. X        putc(c, f);
  1316. X        c = *++cptr;
  1317. X    } while (isalnum(c) || c == '_' || c == '$');
  1318. X    goto loop;
  1319. X    }
  1320. X    putc(c, f);
  1321. X    ++cptr;
  1322. X    switch (c)
  1323. X    {
  1324. X    case '\n':
  1325. X    next_line:
  1326. X    get_line();
  1327. X    if (line) goto loop;
  1328. X    unterminated_action(a_lineno, a_line, a_cptr);
  1329. X
  1330. X    case ';':
  1331. X    if (depth > 0) goto loop;
  1332. X    fprintf(f, "\nbreak;\n");
  1333. X    return;
  1334. X
  1335. X    case '{':
  1336. X    ++depth;
  1337. X    goto loop;
  1338. X
  1339. X    case '}':
  1340. X    if (--depth > 0) goto loop;
  1341. X    fprintf(f, "\nbreak;\n");
  1342. X    return;
  1343. X
  1344. X    case '\'':
  1345. X    case '"':
  1346. X    {
  1347. X        int s_lineno = lineno;
  1348. X        char *s_line = dup_line();
  1349. X        char *s_cptr = s_line + (cptr - line - 1);
  1350. X
  1351. X        quote = c;
  1352. X        for (;;)
  1353. X        {
  1354. X        c = *cptr++;
  1355. X        putc(c, f);
  1356. X        if (c == quote)
  1357. X        {
  1358. X            FREE(s_line);
  1359. X            goto loop;
  1360. X        }
  1361. X        if (c == '\n')
  1362. X            unterminated_string(s_lineno, s_line, s_cptr);
  1363. X        if (c == '\\')
  1364. X        {
  1365. X            c = *cptr++;
  1366. X            putc(c, f);
  1367. X            if (c == '\n')
  1368. X            {
  1369. X            get_line();
  1370. X            if (line == 0)
  1371. X                unterminated_string(s_lineno, s_line, s_cptr);
  1372. X            }
  1373. X        }
  1374. X        }
  1375. X    }
  1376. X
  1377. X    case '/':
  1378. X    c = *cptr;
  1379. X    if (c == '/')
  1380. X    {
  1381. X        putc('*', f);
  1382. X        while ((c = *++cptr) != '\n')
  1383. X        {
  1384. X        if (c == '*' && cptr[1] == '/')
  1385. X            fprintf(f, "* ");
  1386. X        else
  1387. X            putc(c, f);
  1388. X        }
  1389. X        fprintf(f, "*/\n");
  1390. X        goto next_line;
  1391. X    }
  1392. X    if (c == '*')
  1393. X    {
  1394. X        int c_lineno = lineno;
  1395. X        char *c_line = dup_line();
  1396. X        char *c_cptr = c_line + (cptr - line - 1);
  1397. X
  1398. X        putc('*', f);
  1399. X        ++cptr;
  1400. X        for (;;)
  1401. X        {
  1402. X        c = *cptr++;
  1403. X        putc(c, f);
  1404. X        if (c == '*' && *cptr == '/')
  1405. X        {
  1406. X            putc('/', f);
  1407. X            ++cptr;
  1408. X            FREE(c_line);
  1409. X            goto loop;
  1410. X        }
  1411. X        if (c == '\n')
  1412. X        {
  1413. X            get_line();
  1414. X            if (line == 0)
  1415. X            unterminated_comment(c_lineno, c_line, c_cptr);
  1416. X        }
  1417. X        }
  1418. X    }
  1419. X    goto loop;
  1420. X
  1421. X    default:
  1422. X    goto loop;
  1423. X    }
  1424. X}
  1425. X
  1426. X
  1427. Xint
  1428. Xmark_symbol()
  1429. X{
  1430. X    register int c;
  1431. X    register bucket *bp;
  1432. X
  1433. X    c = cptr[1];
  1434. X    if (c == '%' || c == '\\')
  1435. X    {
  1436. X    cptr += 2;
  1437. X    return (1);
  1438. X    }
  1439. X
  1440. X    if (c == '=')
  1441. X    cptr += 2;
  1442. X    else if ((c == 'p' || c == 'P') &&
  1443. X         ((c = cptr[2]) == 'r' || c == 'R') &&
  1444. X         ((c = cptr[3]) == 'e' || c == 'E') &&
  1445. X         ((c = cptr[4]) == 'c' || c == 'C') &&
  1446. X         ((c = cptr[5], !IS_IDENT(c))))
  1447. X    cptr += 5;
  1448. X    else
  1449. X    syntax_error(lineno, line, cptr);
  1450. X
  1451. X    c = nextc();
  1452. X    if (isalpha(c) || c == '_' || c == '.' || c == '$')
  1453. X    bp = get_name();
  1454. X    else if (c == '\'' || c == '"')
  1455. X    bp = get_literal();
  1456. X    else
  1457. X    {
  1458. X    syntax_error(lineno, line, cptr);
  1459. X    /*NOTREACHED*/
  1460. X    }
  1461. X
  1462. X    if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
  1463. X    prec_redeclared();
  1464. X
  1465. X    rprec[nrules] = bp->prec;
  1466. X    rassoc[nrules] = bp->assoc;
  1467. X    return (0);
  1468. X}
  1469. X
  1470. X
  1471. Xread_grammar()
  1472. X{
  1473. X    register int c;
  1474. X
  1475. X    initialize_grammar();
  1476. X    advance_to_start();
  1477. X
  1478. X    for (;;)
  1479. X    {
  1480. X    c = nextc();
  1481. X    if (c == EOF) break;
  1482. X    if (isalpha(c) || c == '_' || c == '.' || c == '$' || c == '\'' ||
  1483. X        c == '"')
  1484. X        add_symbol();
  1485. X    else if (c == '{' || c == '=')
  1486. X        copy_action();
  1487. X    else if (c == '|')
  1488. X    {
  1489. X        end_rule();
  1490. X        start_rule(plhs[nrules-1], 0);
  1491. X        ++cptr;
  1492. X    }
  1493. X    else if (c == '%')
  1494. X    {
  1495. X        if (mark_symbol()) break;
  1496. X    }
  1497. X    else
  1498. X        syntax_error(lineno, line, cptr);
  1499. X    }
  1500. X    end_rule();
  1501. X}
  1502. X
  1503. X
  1504. Xfree_tags()
  1505. X{
  1506. X    register int i;
  1507. X
  1508. X    if (tag_table == 0) return;
  1509. X
  1510. X    for (i = 0; i < ntags; ++i)
  1511. X    {
  1512. X    assert(tag_table[i]);
  1513. X    FREE(tag_table[i]);
  1514. X    }
  1515. X    FREE(tag_table);
  1516. X}
  1517. X
  1518. X
  1519. Xpack_names()
  1520. X{
  1521. X    register bucket *bp;
  1522. X    register char *p, *s, *t;
  1523. X
  1524. X    name_pool_size = 13;  /* 13 == sizeof("$end") + sizeof("$accept") */
  1525. X    for (bp = first_symbol; bp; bp = bp->next)
  1526. X    name_pool_size += strlen(bp->name) + 1;
  1527. X    name_pool = MALLOC(name_pool_size);
  1528. X    if (name_pool == 0) no_space();
  1529. X
  1530. X    strcpy(name_pool, "$accept");
  1531. X    strcpy(name_pool+8, "$end");
  1532. X    t = name_pool + 13;
  1533. X    for (bp = first_symbol; bp; bp = bp->next)
  1534. X    {
  1535. X    p = t;
  1536. X    s = bp->name;
  1537. X    while (*t++ = *s++) continue;
  1538. X    FREE(bp->name);
  1539. X    bp->name = p;
  1540. X    }
  1541. X}
  1542. X
  1543. X
  1544. Xcheck_symbols()
  1545. X{
  1546. X    register bucket *bp;
  1547. X
  1548. X    if (goal->class == UNKNOWN)
  1549. X    undefined_goal(goal->name);
  1550. X
  1551. X    for (bp = first_symbol; bp; bp = bp->next)
  1552. X    {
  1553. X    if (bp->class == UNKNOWN)
  1554. X    {
  1555. X        undefined_symbol_warning(bp->name);
  1556. X        bp->class = TERM;
  1557. X    }
  1558. X    }
  1559. X}
  1560. X
  1561. X
  1562. Xpack_symbols()
  1563. X{
  1564. X    register bucket *bp;
  1565. X    register bucket **v;
  1566. X    register int i, j, k, n;
  1567. X
  1568. X    nsyms = 2;
  1569. X    ntokens = 1;
  1570. X    for (bp = first_symbol; bp; bp = bp->next)
  1571. X    {
  1572. X    ++nsyms;
  1573. X    if (bp->class == TERM) ++ntokens;
  1574. X    }
  1575. X    start_symbol = ntokens;
  1576. X    nvars = nsyms - ntokens;
  1577. X
  1578. X    symbol_name = (char **) MALLOC(nsyms*sizeof(char *));
  1579. X    if (symbol_name == 0) no_space();
  1580. X    symbol_value = (short *) MALLOC(nsyms*sizeof(short));
  1581. X    if (symbol_value == 0) no_space();
  1582. X    symbol_prec = (short *) MALLOC(nsyms*sizeof(short));
  1583. X    if (symbol_prec == 0) no_space();
  1584. X    symbol_assoc = MALLOC(nsyms);
  1585. X    if (symbol_assoc == 0) no_space();
  1586. X
  1587. X    v = (bucket **) MALLOC(nsyms*sizeof(bucket *));
  1588. X    if (v == 0) no_space();
  1589. X
  1590. X    v[0] = 0;
  1591. X    v[start_symbol] = 0;
  1592. X
  1593. X    i = 1;
  1594. X    j = start_symbol + 1;
  1595. X    for (bp = first_symbol; bp; bp = bp->next)
  1596. X    {
  1597. X    if (bp->class == TERM)
  1598. X        v[i++] = bp;
  1599. X    else
  1600. X        v[j++] = bp;
  1601. X    }
  1602. X    assert(i == ntokens && j == nsyms);
  1603. X
  1604. X    for (i = 1; i < ntokens; ++i)
  1605. X    v[i]->index = i;
  1606. X
  1607. X    goal->index = start_symbol + 1;
  1608. X    k = start_symbol + 2;
  1609. X    while (++i < nsyms)
  1610. X    if (v[i] != goal)
  1611. X    {
  1612. X        v[i]->index = k;
  1613. X        ++k;
  1614. X    }
  1615. X
  1616. X    goal->value = 0;
  1617. X    k = 1;
  1618. X    for (i = start_symbol + 1; i < nsyms; ++i)
  1619. X    {
  1620. X    if (v[i] != goal)
  1621. X    {
  1622. X        v[i]->value = k;
  1623. X        ++k;
  1624. X    }
  1625. X    }
  1626. X
  1627. X    k = 0;
  1628. X    for (i = 1; i < ntokens; ++i)
  1629. X    {
  1630. X    n = v[i]->value;
  1631. X    if (n > 256)
  1632. X    {
  1633. X        for (j = k++; j > 0 && symbol_value[j-1] > n; --j)
  1634. X        symbol_value[j] = symbol_value[j-1];
  1635. X        symbol_value[j] = n;
  1636. X    }
  1637. X    }
  1638. X
  1639. X    if (v[1]->value == UNDEFINED)
  1640. X    v[1]->value = 256;
  1641. X
  1642. X    j = 0;
  1643. X    n = 257;
  1644. X    for (i = 2; i < ntokens; ++i)
  1645. X    {
  1646. X    if (v[i]->value == UNDEFINED)
  1647. X    {
  1648. X        while (j < k && n == symbol_value[j])
  1649. X        {
  1650. X        while (++j < k && n == symbol_value[j]) continue;
  1651. X        ++n;
  1652. X        }
  1653. X        v[i]->value = n;
  1654. X        ++n;
  1655. X    }
  1656. X    }
  1657. X
  1658. X    symbol_name[0] = name_pool + 8;
  1659. X    symbol_value[0] = 0;
  1660. X    symbol_prec[0] = 0;
  1661. X    symbol_assoc[0] = TOKEN;
  1662. X    for (i = 1; i < ntokens; ++i)
  1663. X    {
  1664. X    symbol_name[i] = v[i]->name;
  1665. X    symbol_value[i] = v[i]->value;
  1666. X    symbol_prec[i] = v[i]->prec;
  1667. X    symbol_assoc[i] = v[i]->assoc;
  1668. X    }
  1669. X    symbol_name[start_symbol] = name_pool;
  1670. X    symbol_value[start_symbol] = -1;
  1671. X    symbol_prec[start_symbol] = 0;
  1672. X    symbol_assoc[start_symbol] = TOKEN;
  1673. X    for (++i; i < nsyms; ++i)
  1674. X    {
  1675. X    k = v[i]->index;
  1676. X    symbol_name[k] = v[i]->name;
  1677. X    symbol_value[k] = v[i]->value;
  1678. X    symbol_prec[k] = v[i]->prec;
  1679. X    symbol_assoc[k] = v[i]->assoc;
  1680. X    }
  1681. X
  1682. X    FREE(v);
  1683. X}
  1684. X
  1685. X
  1686. Xpack_grammar()
  1687. X{
  1688. X    register int i, j;
  1689. X    int assoc, prec;
  1690. X
  1691. X    ritem = (short *) MALLOC(nitems*sizeof(short));
  1692. X    if (ritem == 0) no_space();
  1693. X    rlhs = (short *) MALLOC(nrules*sizeof(short));
  1694. X    if (rlhs == 0) no_space();
  1695. X    rrhs = (short *) MALLOC((nrules+1)*sizeof(short));
  1696. X    if (rrhs == 0) no_space();
  1697. X    rprec = (short *) REALLOC(rprec, nrules*sizeof(short));
  1698. X    if (rprec == 0) no_space();
  1699. X    rassoc = REALLOC(rassoc, nrules);
  1700. X    if (rassoc == 0) no_space();
  1701. X
  1702. X    ritem[0] = -1;
  1703. X    ritem[1] = goal->index;
  1704. X    ritem[2] = 0;
  1705. X    ritem[3] = -2;
  1706. X    rlhs[0] = 0;
  1707. X    rlhs[1] = 0;
  1708. X    rlhs[2] = start_symbol;
  1709. X    rrhs[0] = 0;
  1710. X    rrhs[1] = 0;
  1711. X    rrhs[2] = 1;
  1712. X
  1713. X    j = 4;
  1714. X    for (i = 3; i < nrules; ++i)
  1715. X    {
  1716. X    rlhs[i] = plhs[i]->index;
  1717. X    rrhs[i] = j;
  1718. X    assoc = TOKEN;
  1719. X    prec = 0;
  1720. X    while (pitem[j])
  1721. X    {
  1722. X        ritem[j] = pitem[j]->index;
  1723. X        if (pitem[j]->class == TERM)
  1724. X        {
  1725. X        prec = pitem[j]->prec;
  1726. X        assoc = pitem[j]->assoc;
  1727. X        }
  1728. X        ++j;
  1729. X    }
  1730. X    ritem[j] = -i;
  1731. X    ++j;
  1732. X    if (rprec[i] == UNDEFINED)
  1733. X    {
  1734. X        rprec[i] = prec;
  1735. X        rassoc[i] = assoc;
  1736. X    }
  1737. X    }
  1738. X    rrhs[i] = j;
  1739. X
  1740. X    FREE(plhs);
  1741. X    FREE(pitem);
  1742. X}
  1743. X
  1744. X
  1745. Xprint_grammar()
  1746. X{
  1747. X    register int i, j, k;
  1748. X    int spacing;
  1749. X    register FILE *f = verbose_file;
  1750. X
  1751. X    if (!vflag) return;
  1752. X
  1753. X    k = 1;
  1754. X    for (i = 2; i < nrules; ++i)
  1755. X    {
  1756. X    if (rlhs[i] != rlhs[i-1])
  1757. X    {
  1758. X        if (i != 2) fprintf(f, "\n");
  1759. X        fprintf(f, "%4d  %s :", i - 2, symbol_name[rlhs[i]]);
  1760. X        spacing = strlen(symbol_name[rlhs[i]]) + 1;
  1761. X    }
  1762. X    else
  1763. X    {
  1764. X        fprintf(f, "%4d  ", i - 2);
  1765. X        j = spacing;
  1766. X        while (--j >= 0) putc(' ', f);
  1767. X        putc('|', f);
  1768. X    }
  1769. X
  1770. X    while (ritem[k] >= 0)
  1771. X    {
  1772. X        fprintf(f, " %s", symbol_name[ritem[k]]);
  1773. X        ++k;
  1774. X    }
  1775. X    ++k;
  1776. X    putc('\n', f);
  1777. X    }
  1778. X}
  1779. X
  1780. X
  1781. Xreader()
  1782. X{
  1783. X    write_section(banner);
  1784. X    create_symbol_table();
  1785. X    read_declarations();
  1786. X    read_grammar();
  1787. X    free_symbol_table();
  1788. X    free_tags();
  1789. X    pack_names();
  1790. X    check_symbols();
  1791. X    pack_symbols();
  1792. X    pack_grammar();
  1793. X    free_symbols();
  1794. X    print_grammar();
  1795. X}
  1796. END_OF_FILE
  1797. if test 30469 -ne `wc -c <'reader.c'`; then
  1798.     echo shar: \"'reader.c'\" unpacked with wrong size!
  1799. fi
  1800. # end of 'reader.c'
  1801. fi
  1802. if test -f 'test/ftp.tab.c' -a "${1}" != "-c" ; then 
  1803.   echo shar: Will not clobber existing file \"'test/ftp.tab.c'\"
  1804. else
  1805. echo shar: Extracting \"'test/ftp.tab.c'\" \(40069 characters\)
  1806. sed "s/^X//" >'test/ftp.tab.c' <<'END_OF_FILE'
  1807. X#ifndef lint
  1808. Xstatic char yysccsid[] = "@(#)yaccpar    1.9 (Berkeley) 02/21/93";
  1809. X#endif
  1810. X#define YYBYACC 1
  1811. X#define YYMAJOR 1
  1812. X#define YYMINOR 9
  1813. X#define yyclearin (yychar=(-1))
  1814. X#define yyerrok (yyerrflag=0)
  1815. X#define YYRECOVERING (yyerrflag!=0)
  1816. X#define YYPREFIX "yy"
  1817. X#line 26 "ftp.y"
  1818. X
  1819. X#ifndef lint
  1820. Xstatic char sccsid[] = "@(#)ftpcmd.y    5.20.1.1 (Berkeley) 3/2/89";
  1821. X#endif /* not lint */
  1822. X
  1823. X#include <sys/param.h>
  1824. X#include <sys/socket.h>
  1825. X
  1826. X#include <netinet/in.h>
  1827. X
  1828. X#include <arpa/ftp.h>
  1829. X
  1830. X#include <stdio.h>
  1831. X#include <signal.h>
  1832. X#include <ctype.h>
  1833. X#include <pwd.h>
  1834. X#include <setjmp.h>
  1835. X#include <syslog.h>
  1836. X#include <sys/stat.h>
  1837. X#include <time.h>
  1838. X
  1839. Xextern    struct sockaddr_in data_dest;
  1840. Xextern    int logged_in;
  1841. Xextern    struct passwd *pw;
  1842. Xextern    int guest;
  1843. Xextern    int logging;
  1844. Xextern    int type;
  1845. Xextern    int form;
  1846. Xextern    int debug;
  1847. Xextern    int timeout;
  1848. Xextern    int maxtimeout;
  1849. Xextern  int pdata;
  1850. Xextern    char hostname[], remotehost[];
  1851. Xextern    char proctitle[];
  1852. Xextern    char *globerr;
  1853. Xextern    int usedefault;
  1854. Xextern  int transflag;
  1855. Xextern  char tmpline[];
  1856. Xchar    **glob();
  1857. X
  1858. Xstatic    int cmd_type;
  1859. Xstatic    int cmd_form;
  1860. Xstatic    int cmd_bytesz;
  1861. Xchar    cbuf[512];
  1862. Xchar    *fromname;
  1863. X
  1864. Xchar    *index();
  1865. X#line 60 "ftp.tab.c"
  1866. X#define A 257
  1867. X#define B 258
  1868. X#define C 259
  1869. X#define E 260
  1870. X#define F 261
  1871. X#define I 262
  1872. X#define L 263
  1873. X#define N 264
  1874. X#define P 265
  1875. X#define R 266
  1876. X#define S 267
  1877. X#define T 268
  1878. X#define SP 269
  1879. X#define CRLF 270
  1880. X#define COMMA 271
  1881. X#define STRING 272
  1882. X#define NUMBER 273
  1883. X#define USER 274
  1884. X#define PASS 275
  1885. X#define ACCT 276
  1886. X#define REIN 277
  1887. X#define QUIT 278
  1888. X#define PORT 279
  1889. X#define PASV 280
  1890. X#define TYPE 281
  1891. X#define STRU 282
  1892. X#define MODE 283
  1893. X#define RETR 284
  1894. X#define STOR 285
  1895. X#define APPE 286
  1896. X#define MLFL 287
  1897. X#define MAIL 288
  1898. X#define MSND 289
  1899. X#define MSOM 290
  1900. X#define MSAM 291
  1901. X#define MRSQ 292
  1902. X#define MRCP 293
  1903. X#define ALLO 294
  1904. X#define REST 295
  1905. X#define RNFR 296
  1906. X#define RNTO 297
  1907. X#define ABOR 298
  1908. X#define DELE 299
  1909. X#define CWD 300
  1910. X#define LIST 301
  1911. X#define NLST 302
  1912. X#define SITE 303
  1913. X#define STAT 304
  1914. X#define HELP 305
  1915. X#define NOOP 306
  1916. X#define MKD 307
  1917. X#define RMD 308
  1918. X#define PWD 309
  1919. X#define CDUP 310
  1920. X#define STOU 311
  1921. X#define SMNT 312
  1922. X#define SYST 313
  1923. X#define SIZE 314
  1924. X#define MDTM 315
  1925. X#define UMASK 316
  1926. X#define IDLE 317
  1927. X#define CHMOD 318
  1928. X#define LEXERR 319
  1929. X#define YYERRCODE 256
  1930. Xshort yylhs[] = {                                        -1,
  1931. X    0,    0,    0,    1,    1,    1,    1,    1,    1,    1,
  1932. X    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  1933. X    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  1934. X    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  1935. X    1,    1,    1,    1,    1,    1,    2,    3,    4,    4,
  1936. X   12,    5,   13,   13,   13,    6,    6,    6,    6,    6,
  1937. X    6,    6,    6,    7,    7,    7,    8,    8,    8,   10,
  1938. X   14,   11,    9,
  1939. X};
  1940. Xshort yylen[] = {                                         2,
  1941. X    0,    2,    2,    4,    4,    4,    2,    4,    4,    4,
  1942. X    4,    8,    5,    5,    5,    3,    5,    3,    5,    5,
  1943. X    2,    5,    4,    2,    3,    5,    2,    4,    2,    5,
  1944. X    5,    3,    3,    4,    6,    5,    7,    9,    4,    6,
  1945. X    5,    2,    5,    5,    2,    2,    5,    1,    0,    1,
  1946. X    1,   11,    1,    1,    1,    1,    3,    1,    3,    1,
  1947. X    1,    3,    2,    1,    1,    1,    1,    1,    1,    1,
  1948. X    1,    1,    0,
  1949. X};
  1950. Xshort yydefred[] = {                                      1,
  1951. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  1952. X   73,   73,   73,    0,   73,    0,    0,   73,   73,   73,
  1953. X   73,    0,    0,    0,    0,   73,   73,   73,   73,   73,
  1954. X    0,   73,   73,    2,    3,   46,    0,    0,   45,    0,
  1955. X    7,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  1956. X   24,    0,    0,    0,    0,    0,   21,    0,    0,   27,
  1957. X   29,    0,    0,    0,    0,    0,   42,    0,    0,   48,
  1958. X    0,   50,    0,    0,    0,    0,    0,   60,    0,    0,
  1959. X   64,   66,   65,    0,   68,   69,   67,    0,    0,    0,
  1960. X    0,    0,    0,   71,    0,   70,    0,    0,   25,    0,
  1961. X   18,    0,   16,    0,   73,    0,   73,    0,    0,    0,
  1962. X    0,   32,   33,    0,    0,    0,    4,    5,    0,    6,
  1963. X    0,    0,    0,   51,   63,    8,    9,   10,    0,    0,
  1964. X    0,    0,   11,    0,   23,    0,    0,    0,    0,    0,
  1965. X   34,    0,    0,   39,    0,    0,   28,    0,    0,    0,
  1966. X    0,    0,    0,   55,   53,   54,   57,   59,   62,   13,
  1967. X   14,   15,    0,   47,   22,   26,   19,   17,    0,    0,
  1968. X   36,    0,    0,   20,   30,   31,   41,   43,   44,    0,
  1969. X    0,   35,   72,    0,   40,    0,    0,    0,   37,    0,
  1970. X    0,   12,    0,    0,   38,    0,    0,    0,   52,
  1971. X};
  1972. Xshort yydgoto[] = {                                       1,
  1973. X   34,   35,   71,   73,   75,   80,   84,   88,   45,   95,
  1974. X  184,  125,  157,   96,
  1975. X};
  1976. Xshort yysindex[] = {                                      0,
  1977. X -224, -247, -239, -236, -232, -222, -204, -200, -181, -177,
  1978. X    0,    0,    0, -166,    0, -161, -199,    0,    0,    0,
  1979. X    0, -160, -159, -264, -158,    0,    0,    0,    0,    0,
  1980. X -157,    0,    0,    0,    0,    0, -167, -162,    0, -156,
  1981. X    0, -250, -198, -165, -155, -154, -153, -151, -150, -152,
  1982. X    0, -145, -252, -229, -217, -302,    0, -144, -146,    0,
  1983. X    0, -142, -141, -140, -139, -137,    0, -136, -135,    0,
  1984. X -134,    0, -133, -132, -130, -131, -128,    0, -249, -127,
  1985. X    0,    0,    0, -126,    0,    0,    0, -125, -152, -152,
  1986. X -152, -205, -152,    0, -124,    0, -152, -152,    0, -152,
  1987. X    0, -143,    0, -173,    0, -171,    0, -152, -123, -152,
  1988. X -152,    0,    0, -152, -152, -152,    0,    0, -138,    0,
  1989. X -164, -164, -122,    0,    0,    0,    0,    0, -121, -120,
  1990. X -118, -148,    0, -117,    0, -116, -115, -114, -113, -112,
  1991. X    0, -163, -111,    0, -110, -109,    0, -107, -106, -105,
  1992. X -104, -103, -129,    0,    0,    0,    0,    0,    0,    0,
  1993. X    0,    0, -101,    0,    0,    0,    0,    0, -100, -102,
  1994. X    0,  -98, -102,    0,    0,    0,    0,    0,    0,  -99,
  1995. X  -97,    0,    0,  -95,    0,  -96,  -94,  -92,    0, -152,
  1996. X  -93,    0,  -91,  -90,    0,  -88,  -87,  -86,    0,
  1997. X};
  1998. Xshort yyrindex[] = {                                      0,
  1999. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2000. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2001. X    0,    0,  -83,    0,    0,    0,    0,    0,    0,    0,
  2002. X    0,    0,    0,    0,    0,    0,    0,  -82,    0,    0,
  2003. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2004. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2005. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2006. X    0,    0,    0,    0,    0,  -81,  -80,    0, -158,    0,
  2007. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2008. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2009. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2010. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2011. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2012. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2013. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2014. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2015. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2016. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2017. X    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2018. X    0,    0,    0,    0,    0,    0,    0,    0,    0,
  2019. X};
  2020. Xshort yygindex[] = {                                      0,
  2021. X    0,    0,    0,    0,    0,    0,    0,    0,   16,  -89,
  2022. X  -25,   35,   47,    0,
  2023. X};
  2024. X#define YYTABLESIZE 190
  2025. Xshort yytable[] = {                                     129,
  2026. X  130,  131,  104,  134,   59,   60,   76,  136,  137,   77,
  2027. X  138,   78,   79,  105,  106,  107,   98,   99,  146,  123,
  2028. X  148,  149,   36,  124,  150,  151,  152,   46,   47,   37,
  2029. X   49,    2,   38,   52,   53,   54,   55,   39,   58,  100,
  2030. X  101,   62,   63,   64,   65,   66,   40,   68,   69,    3,
  2031. X    4,  102,  103,    5,    6,    7,    8,    9,   10,   11,
  2032. X   12,   13,   81,  132,  133,   41,   82,   83,   42,   14,
  2033. X   51,   15,   16,   17,   18,   19,   20,   21,   22,   23,
  2034. X   24,   25,   26,   27,   28,   29,   30,   43,   31,   32,
  2035. X   33,   44,   85,   86,  154,  140,  141,  143,  144,  155,
  2036. X  193,   87,   48,  156,   70,  170,  171,   50,   56,   72,
  2037. X   57,   61,   67,   89,   90,   91,   74,  163,   93,   94,
  2038. X  142,   92,  145,   97,  108,  109,  110,  111,  139,  112,
  2039. X  113,  114,  115,  116,  153,  117,  118,  121,  119,  120,
  2040. X  122,  180,  126,  127,  128,  135,  147,  186,  160,  161,
  2041. X  124,  162,  164,  165,  166,  167,  168,  159,  173,  169,
  2042. X  174,  172,  175,  176,  177,  178,  179,  181,  158,  182,
  2043. X  183,  185,  190,  187,  189,  188,  191,  192,  195,  194,
  2044. X  196,    0,    0,  198,  197,   73,  199,   49,   56,   58,
  2045. X};
  2046. Xshort yycheck[] = {                                      89,
  2047. X   90,   91,  305,   93,  269,  270,  257,   97,   98,  260,
  2048. X  100,  262,  263,  316,  317,  318,  269,  270,  108,  269,
  2049. X  110,  111,  270,  273,  114,  115,  116,   12,   13,  269,
  2050. X   15,  256,  269,   18,   19,   20,   21,  270,   23,  269,
  2051. X  270,   26,   27,   28,   29,   30,  269,   32,   33,  274,
  2052. X  275,  269,  270,  278,  279,  280,  281,  282,  283,  284,
  2053. X  285,  286,  261,  269,  270,  270,  265,  266,  269,  294,
  2054. X  270,  296,  297,  298,  299,  300,  301,  302,  303,  304,
  2055. X  305,  306,  307,  308,  309,  310,  311,  269,  313,  314,
  2056. X  315,  269,  258,  259,  259,  269,  270,  269,  270,  264,
  2057. X  190,  267,  269,  268,  272,  269,  270,  269,  269,  272,
  2058. X  270,  270,  270,  269,  269,  269,  273,  266,  269,  272,
  2059. X  105,  273,  107,  269,  269,  272,  269,  269,  272,  270,
  2060. X  270,  269,  269,  269,  273,  270,  270,  269,  271,  270,
  2061. X  269,  271,  270,  270,  270,  270,  270,  173,  270,  270,
  2062. X  273,  270,  270,  270,  270,  270,  270,  123,  269,  272,
  2063. X  270,  273,  270,  270,  270,  270,  270,  269,  122,  270,
  2064. X  273,  270,  269,  273,  270,  273,  271,  270,  270,  273,
  2065. X  271,   -1,   -1,  271,  273,  269,  273,  270,  270,  270,
  2066. X};
  2067. X#define YYFINAL 1
  2068. X#ifndef YYDEBUG
  2069. X#define YYDEBUG 0
  2070. X#endif
  2071. X#define YYMAXTOKEN 319
  2072. X#if YYDEBUG
  2073. Xchar *yyname[] = {
  2074. 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,
  2075. 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,
  2076. 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,
  2077. 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,
  2078. 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,
  2079. 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,
  2080. 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",
  2081. X"P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT",
  2082. X"REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL",
  2083. X"MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR",
  2084. X"DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP",
  2085. X"STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR",
  2086. X};
  2087. Xchar *yyrule[] = {
  2088. X"$accept : cmd_list",
  2089. X"cmd_list :",
  2090. X"cmd_list : cmd_list cmd",
  2091. X"cmd_list : cmd_list rcmd",
  2092. X"cmd : USER SP username CRLF",
  2093. X"cmd : PASS SP password CRLF",
  2094. X"cmd : PORT SP host_port CRLF",
  2095. X"cmd : PASV CRLF",
  2096. X"cmd : TYPE SP type_code CRLF",
  2097. X"cmd : STRU SP struct_code CRLF",
  2098. X"cmd : MODE SP mode_code CRLF",
  2099. X"cmd : ALLO SP NUMBER CRLF",
  2100. X"cmd : ALLO SP NUMBER SP R SP NUMBER CRLF",
  2101. X"cmd : RETR check_login SP pathname CRLF",
  2102. X"cmd : STOR check_login SP pathname CRLF",
  2103. X"cmd : APPE check_login SP pathname CRLF",
  2104. X"cmd : NLST check_login CRLF",
  2105. X"cmd : NLST check_login SP STRING CRLF",
  2106. X"cmd : LIST check_login CRLF",
  2107. X"cmd : LIST check_login SP pathname CRLF",
  2108. X"cmd : STAT check_login SP pathname CRLF",
  2109. X"cmd : STAT CRLF",
  2110. X"cmd : DELE check_login SP pathname CRLF",
  2111. X"cmd : RNTO SP pathname CRLF",
  2112. X"cmd : ABOR CRLF",
  2113. X"cmd : CWD check_login CRLF",
  2114. X"cmd : CWD check_login SP pathname CRLF",
  2115. X"cmd : HELP CRLF",
  2116. X"cmd : HELP SP STRING CRLF",
  2117. X"cmd : NOOP CRLF",
  2118. X"cmd : MKD check_login SP pathname CRLF",
  2119. X"cmd : RMD check_login SP pathname CRLF",
  2120. X"cmd : PWD check_login CRLF",
  2121. X"cmd : CDUP check_login CRLF",
  2122. X"cmd : SITE SP HELP CRLF",
  2123. X"cmd : SITE SP HELP SP STRING CRLF",
  2124. X"cmd : SITE SP UMASK check_login CRLF",
  2125. X"cmd : SITE SP UMASK check_login SP octal_number CRLF",
  2126. X"cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
  2127. X"cmd : SITE SP IDLE CRLF",
  2128. X"cmd : SITE SP IDLE SP NUMBER CRLF",
  2129. X"cmd : STOU check_login SP pathname CRLF",
  2130. X"cmd : SYST CRLF",
  2131. X"cmd : SIZE check_login SP pathname CRLF",
  2132. X"cmd : MDTM check_login SP pathname CRLF",
  2133. X"cmd : QUIT CRLF",
  2134. X"cmd : error CRLF",
  2135. X"rcmd : RNFR check_login SP pathname CRLF",
  2136. X"username : STRING",
  2137. X"password :",
  2138. X"password : STRING",
  2139. X"byte_size : NUMBER",
  2140. X"host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
  2141. X"form_code : N",
  2142. X"form_code : T",
  2143. X"form_code : C",
  2144. X"type_code : A",
  2145. X"type_code : A SP form_code",
  2146. X"type_code : E",
  2147. X"type_code : E SP form_code",
  2148. X"type_code : I",
  2149. X"type_code : L",
  2150. X"type_code : L SP byte_size",
  2151. X"type_code : L byte_size",
  2152. X"struct_code : F",
  2153. X"struct_code : R",
  2154. X"struct_code : P",
  2155. X"mode_code : S",
  2156. X"mode_code : B",
  2157. X"mode_code : C",
  2158. X"pathname : pathstring",
  2159. X"pathstring : STRING",
  2160. X"octal_number : NUMBER",
  2161. X"check_login :",
  2162. X};
  2163. X#endif
  2164. X#ifndef YYSTYPE
  2165. Xtypedef int YYSTYPE;
  2166. X#endif
  2167. X#ifdef YYSTACKSIZE
  2168. X#undef YYMAXDEPTH
  2169. X#define YYMAXDEPTH YYSTACKSIZE
  2170. X#else
  2171. X#ifdef YYMAXDEPTH
  2172. X#define YYSTACKSIZE YYMAXDEPTH
  2173. X#else
  2174. X#define YYSTACKSIZE 500
  2175. X#define YYMAXDEPTH 500
  2176. X#endif
  2177. X#endif
  2178. Xint yydebug;
  2179. Xint yynerrs;
  2180. Xint yyerrflag;
  2181. Xint yychar;
  2182. Xshort *yyssp;
  2183. XYYSTYPE *yyvsp;
  2184. XYYSTYPE yyval;
  2185. XYYSTYPE yylval;
  2186. Xshort yyss[YYSTACKSIZE];
  2187. XYYSTYPE yyvs[YYSTACKSIZE];
  2188. X#define yystacksize YYSTACKSIZE
  2189. X#line 658 "ftp.y"
  2190. X
  2191. Xextern jmp_buf errcatch;
  2192. X
  2193. X#define    CMD    0    /* beginning of command */
  2194. X#define    ARGS    1    /* expect miscellaneous arguments */
  2195. X#define    STR1    2    /* expect SP followed by STRING */
  2196. X#define    STR2    3    /* expect STRING */
  2197. X#define    OSTR    4    /* optional SP then STRING */
  2198. X#define    ZSTR1    5    /* SP then optional STRING */
  2199. X#define    ZSTR2    6    /* optional STRING after SP */
  2200. X#define    SITECMD    7    /* SITE command */
  2201. X#define    NSTR    8    /* Number followed by a string */
  2202. X
  2203. Xstruct tab {
  2204. X    char    *name;
  2205. X    short    token;
  2206. X    short    state;
  2207. X    short    implemented;    /* 1 if command is implemented */
  2208. X    char    *help;
  2209. X};
  2210. X
  2211. Xstruct tab cmdtab[] = {        /* In order defined in RFC 765 */
  2212. X    { "USER", USER, STR1, 1,    "<sp> username" },
  2213. X    { "PASS", PASS, ZSTR1, 1,    "<sp> password" },
  2214. X    { "ACCT", ACCT, STR1, 0,    "(specify account)" },
  2215. X    { "SMNT", SMNT, ARGS, 0,    "(structure mount)" },
  2216. X    { "REIN", REIN, ARGS, 0,    "(reinitialize server state)" },
  2217. X    { "QUIT", QUIT, ARGS, 1,    "(terminate service)", },
  2218. X    { "PORT", PORT, ARGS, 1,    "<sp> b0, b1, b2, b3, b4" },
  2219. X    { "PASV", PASV, ARGS, 1,    "(set server in passive mode)" },
  2220. X    { "TYPE", TYPE, ARGS, 1,    "<sp> [ A | E | I | L ]" },
  2221. X    { "STRU", STRU, ARGS, 1,    "(specify file structure)" },
  2222. X    { "MODE", MODE, ARGS, 1,    "(specify transfer mode)" },
  2223. X    { "RETR", RETR, STR1, 1,    "<sp> file-name" },
  2224. X    { "STOR", STOR, STR1, 1,    "<sp> file-name" },
  2225. X    { "APPE", APPE, STR1, 1,    "<sp> file-name" },
  2226. X    { "MLFL", MLFL, OSTR, 0,    "(mail file)" },
  2227. X    { "MAIL", MAIL, OSTR, 0,    "(mail to user)" },
  2228. X    { "MSND", MSND, OSTR, 0,    "(mail send to terminal)" },
  2229. X    { "MSOM", MSOM, OSTR, 0,    "(mail send to terminal or mailbox)" },
  2230. X    { "MSAM", MSAM, OSTR, 0,    "(mail send to terminal and mailbox)" },
  2231. X    { "MRSQ", MRSQ, OSTR, 0,    "(mail recipient scheme question)" },
  2232. X    { "MRCP", MRCP, STR1, 0,    "(mail recipient)" },
  2233. X    { "ALLO", ALLO, ARGS, 1,    "allocate storage (vacuously)" },
  2234. X    { "REST", REST, ARGS, 0,    "(restart command)" },
  2235. X    { "RNFR", RNFR, STR1, 1,    "<sp> file-name" },
  2236. X    { "RNTO", RNTO, STR1, 1,    "<sp> file-name" },
  2237. X    { "ABOR", ABOR, ARGS, 1,    "(abort operation)" },
  2238. X    { "DELE", DELE, STR1, 1,    "<sp> file-name" },
  2239. X    { "CWD",  CWD,  OSTR, 1,    "[ <sp> directory-name ]" },
  2240. X    { "XCWD", CWD,    OSTR, 1,    "[ <sp> directory-name ]" },
  2241. X    { "LIST", LIST, OSTR, 1,    "[ <sp> path-name ]" },
  2242. X    { "NLST", NLST, OSTR, 1,    "[ <sp> path-name ]" },
  2243. X    { "SITE", SITE, SITECMD, 1,    "site-cmd [ <sp> arguments ]" },
  2244. X    { "SYST", SYST, ARGS, 1,    "(get type of operating system)" },
  2245. X    { "STAT", STAT, OSTR, 1,    "[ <sp> path-name ]" },
  2246. X    { "HELP", HELP, OSTR, 1,    "[ <sp> <string> ]" },
  2247. X    { "NOOP", NOOP, ARGS, 1,    "" },
  2248. X    { "MKD",  MKD,  STR1, 1,    "<sp> path-name" },
  2249. X    { "XMKD", MKD,  STR1, 1,    "<sp> path-name" },
  2250. X    { "RMD",  RMD,  STR1, 1,    "<sp> path-name" },
  2251. X    { "XRMD", RMD,  STR1, 1,    "<sp> path-name" },
  2252. X    { "PWD",  PWD,  ARGS, 1,    "(return current directory)" },
  2253. X    { "XPWD", PWD,  ARGS, 1,    "(return current directory)" },
  2254. X    { "CDUP", CDUP, ARGS, 1,    "(change to parent directory)" },
  2255. X    { "XCUP", CDUP, ARGS, 1,    "(change to parent directory)" },
  2256. X    { "STOU", STOU, STR1, 1,    "<sp> file-name" },
  2257. X    { "SIZE", SIZE, OSTR, 1,    "<sp> path-name" },
  2258. X    { "MDTM", MDTM, OSTR, 1,    "<sp> path-name" },
  2259. X    { NULL,   0,    0,    0,    0 }
  2260. X};
  2261. X
  2262. Xstruct tab sitetab[] = {
  2263. X    { "UMASK", UMASK, ARGS, 1,    "[ <sp> umask ]" },
  2264. X    { "IDLE", IDLE, ARGS, 1,    "[ <sp> maximum-idle-time ]" },
  2265. X    { "CHMOD", CHMOD, NSTR, 1,    "<sp> mode <sp> file-name" },
  2266. X    { "HELP", HELP, OSTR, 1,    "[ <sp> <string> ]" },
  2267. X    { NULL,   0,    0,    0,    0 }
  2268. X};
  2269. X
  2270. Xstruct tab *
  2271. Xlookup(p, cmd)
  2272. X    register struct tab *p;
  2273. X    char *cmd;
  2274. X{
  2275. X
  2276. X    for (; p->name != NULL; p++)
  2277. X        if (strcmp(cmd, p->name) == 0)
  2278. X            return (p);
  2279. X    return (0);
  2280. X}
  2281. X
  2282. X#include <arpa/telnet.h>
  2283. X
  2284. X/*
  2285. X * getline - a hacked up version of fgets to ignore TELNET escape codes.
  2286. X */
  2287. Xchar *
  2288. Xgetline(s, n, iop)
  2289. X    char *s;
  2290. X    register FILE *iop;
  2291. X{
  2292. X    register c;
  2293. X    register char *cs;
  2294. X
  2295. X    cs = s;
  2296. X/* tmpline may contain saved command from urgent mode interruption */
  2297. X    for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
  2298. X        *cs++ = tmpline[c];
  2299. X        if (tmpline[c] == '\n') {
  2300. X            *cs++ = '\0';
  2301. X            if (debug)
  2302. X                syslog(LOG_DEBUG, "command: %s", s);
  2303. X            tmpline[0] = '\0';
  2304. X            return(s);
  2305. X        }
  2306. X        if (c == 0)
  2307. X            tmpline[0] = '\0';
  2308. X    }
  2309. X    while ((c = getc(iop)) != EOF) {
  2310. X        c &= 0377;
  2311. X        if (c == IAC) {
  2312. X            if ((c = getc(iop)) != EOF) {
  2313. X            c &= 0377;
  2314. X            switch (c) {
  2315. X            case WILL:
  2316. X            case WONT:
  2317. X                c = getc(iop);
  2318. X                printf("%c%c%c", IAC, DONT, 0377&c);
  2319. X                (void) fflush(stdout);
  2320. X                continue;
  2321. X            case DO:
  2322. X            case DONT:
  2323. X                c = getc(iop);
  2324. X                printf("%c%c%c", IAC, WONT, 0377&c);
  2325. X                (void) fflush(stdout);
  2326. X                continue;
  2327. X            case IAC:
  2328. X                break;
  2329. X            default:
  2330. X                continue;    /* ignore command */
  2331. X            }
  2332. X            }
  2333. X        }
  2334. X        *cs++ = c;
  2335. X        if (--n <= 0 || c == '\n')
  2336. X            break;
  2337. X    }
  2338. X    if (c == EOF && cs == s)
  2339. X        return (NULL);
  2340. X    *cs++ = '\0';
  2341. X    if (debug)
  2342. X        syslog(LOG_DEBUG, "command: %s", s);
  2343. X    return (s);
  2344. X}
  2345. X
  2346. Xstatic int
  2347. Xtoolong()
  2348. X{
  2349. X    time_t now;
  2350. X    extern char *ctime();
  2351. X    extern time_t time();
  2352. X
  2353. X    reply(421,
  2354. X      "Timeout (%d seconds): closing control connection.", timeout);
  2355. X    (void) time(&now);
  2356. X    if (logging) {
  2357. X        syslog(LOG_INFO,
  2358. X            "User %s timed out after %d seconds at %s",
  2359. X            (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
  2360. X    }
  2361. X    dologout(1);
  2362. X}
  2363. X
  2364. Xyylex()
  2365. X{
  2366. X    static int cpos, state;
  2367. X    register char *cp, *cp2;
  2368. X    register struct tab *p;
  2369. X    int n;
  2370. X    char c, *strpbrk();
  2371. X    char *copy();
  2372. X
  2373. X    for (;;) {
  2374. X        switch (state) {
  2375. X
  2376. X        case CMD:
  2377. X            (void) signal(SIGALRM, toolong);
  2378. X            (void) alarm((unsigned) timeout);
  2379. X            if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
  2380. X                reply(221, "You could at least say goodbye.");
  2381. X                dologout(0);
  2382. X            }
  2383. X            (void) alarm(0);
  2384. X#ifdef SETPROCTITLE
  2385. X            if (strncasecmp(cbuf, "PASS", 4) != NULL)
  2386. X                setproctitle("%s: %s", proctitle, cbuf);
  2387. X#endif /* SETPROCTITLE */
  2388. X            if ((cp = index(cbuf, '\r'))) {
  2389. X                *cp++ = '\n';
  2390. X                *cp = '\0';
  2391. X            }
  2392. X            if ((cp = strpbrk(cbuf, " \n")))
  2393. X                cpos = cp - cbuf;
  2394. X            if (cpos == 0)
  2395. X                cpos = 4;
  2396. X            c = cbuf[cpos];
  2397. X            cbuf[cpos] = '\0';
  2398. X            upper(cbuf);
  2399. X            p = lookup(cmdtab, cbuf);
  2400. X            cbuf[cpos] = c;
  2401. X            if (p != 0) {
  2402. X                if (p->implemented == 0) {
  2403. X                    nack(p->name);
  2404. X                    longjmp(errcatch,0);
  2405. X                    /* NOTREACHED */
  2406. X                }
  2407. X                state = p->state;
  2408. X                *(char **)&yylval = p->name;
  2409. X                return (p->token);
  2410. X            }
  2411. X            break;
  2412. X
  2413. X        case SITECMD:
  2414. X            if (cbuf[cpos] == ' ') {
  2415. X                cpos++;
  2416. X                return (SP);
  2417. X            }
  2418. X            cp = &cbuf[cpos];
  2419. X            if ((cp2 = strpbrk(cp, " \n")))
  2420. X                cpos = cp2 - cbuf;
  2421. X            c = cbuf[cpos];
  2422. X            cbuf[cpos] = '\0';
  2423. X            upper(cp);
  2424. X            p = lookup(sitetab, cp);
  2425. X            cbuf[cpos] = c;
  2426. X            if (p != 0) {
  2427. X                if (p->implemented == 0) {
  2428. X                    state = CMD;
  2429. X                    nack(p->name);
  2430. X                    longjmp(errcatch,0);
  2431. X                    /* NOTREACHED */
  2432. X                }
  2433. X                state = p->state;
  2434. X                *(char **)&yylval = p->name;
  2435. X                return (p->token);
  2436. X            }
  2437. X            state = CMD;
  2438. X            break;
  2439. X
  2440. X        case OSTR:
  2441. X            if (cbuf[cpos] == '\n') {
  2442. X                state = CMD;
  2443. X                return (CRLF);
  2444. X            }
  2445. X            /* FALLTHROUGH */
  2446. X
  2447. X        case STR1:
  2448. X        case ZSTR1:
  2449. X        dostr1:
  2450. X            if (cbuf[cpos] == ' ') {
  2451. X                cpos++;
  2452. X                state = state == OSTR ? STR2 : ++state;
  2453. X                return (SP);
  2454. X            }
  2455. X            break;
  2456. X
  2457. X        case ZSTR2:
  2458. X            if (cbuf[cpos] == '\n') {
  2459. X                state = CMD;
  2460. X                return (CRLF);
  2461. X            }
  2462. X            /* FALLTHROUGH */
  2463. X
  2464. X        case STR2:
  2465. X            cp = &cbuf[cpos];
  2466. X            n = strlen(cp);
  2467. X            cpos += n - 1;
  2468. X            /*
  2469. X             * Make sure the string is nonempty and \n terminated.
  2470. X             */
  2471. X            if (n > 1 && cbuf[cpos] == '\n') {
  2472. X                cbuf[cpos] = '\0';
  2473. X                *(char **)&yylval = copy(cp);
  2474. X                cbuf[cpos] = '\n';
  2475. X                state = ARGS;
  2476. X                return (STRING);
  2477. X            }
  2478. X            break;
  2479. X
  2480. X        case NSTR:
  2481. X            if (cbuf[cpos] == ' ') {
  2482. X                cpos++;
  2483. X                return (SP);
  2484. X            }
  2485. X            if (isdigit(cbuf[cpos])) {
  2486. X                cp = &cbuf[cpos];
  2487. X                while (isdigit(cbuf[++cpos]))
  2488. X                    ;
  2489. X                c = cbuf[cpos];
  2490. X                cbuf[cpos] = '\0';
  2491. X                yylval = atoi(cp);
  2492. X                cbuf[cpos] = c;
  2493. X                state = STR1;
  2494. X                return (NUMBER);
  2495. X            }
  2496. X            state = STR1;
  2497. X            goto dostr1;
  2498. X
  2499. X        case ARGS:
  2500. X            if (isdigit(cbuf[cpos])) {
  2501. X                cp = &cbuf[cpos];
  2502. X                while (isdigit(cbuf[++cpos]))
  2503. X                    ;
  2504. X                c = cbuf[cpos];
  2505. X                cbuf[cpos] = '\0';
  2506. X                yylval = atoi(cp);
  2507. X                cbuf[cpos] = c;
  2508. X                return (NUMBER);
  2509. X            }
  2510. X            switch (cbuf[cpos++]) {
  2511. X
  2512. X            case '\n':
  2513. X                state = CMD;
  2514. X                return (CRLF);
  2515. X
  2516. X            case ' ':
  2517. X                return (SP);
  2518. X
  2519. X            case ',':
  2520. X                return (COMMA);
  2521. X
  2522. X            case 'A':
  2523. X            case 'a':
  2524. X                return (A);
  2525. X
  2526. X            case 'B':
  2527. X            case 'b':
  2528. X                return (B);
  2529. X
  2530. X            case 'C':
  2531. X            case 'c':
  2532. X                return (C);
  2533. X
  2534. X            case 'E':
  2535. X            case 'e':
  2536. X                return (E);
  2537. X
  2538. X            case 'F':
  2539. X            case 'f':
  2540. X                return (F);
  2541. X
  2542. X            case 'I':
  2543. X            case 'i':
  2544. X                return (I);
  2545. X
  2546. X            case 'L':
  2547. X            case 'l':
  2548. X                return (L);
  2549. X
  2550. X            case 'N':
  2551. X            case 'n':
  2552. X                return (N);
  2553. X
  2554. X            case 'P':
  2555. X            case 'p':
  2556. X                return (P);
  2557. X
  2558. X            case 'R':
  2559. X            case 'r':
  2560. X                return (R);
  2561. X
  2562. X            case 'S':
  2563. X            case 's':
  2564. X                return (S);
  2565. X
  2566. X            case 'T':
  2567. X            case 't':
  2568. X                return (T);
  2569. X
  2570. X            }
  2571. X            break;
  2572. X
  2573. X        default:
  2574. X            fatal("Unknown state in scanner.");
  2575. X        }
  2576. X        yyerror((char *) 0);
  2577. X        state = CMD;
  2578. X        longjmp(errcatch,0);
  2579. X    }
  2580. X}
  2581. X
  2582. Xupper(s)
  2583. X    register char *s;
  2584. X{
  2585. X    while (*s != '\0') {
  2586. X        if (islower(*s))
  2587. X            *s = toupper(*s);
  2588. X        s++;
  2589. X    }
  2590. X}
  2591. X
  2592. Xchar *
  2593. Xcopy(s)
  2594. X    char *s;
  2595. X{
  2596. X    char *p;
  2597. X    extern char *malloc(), *strcpy();
  2598. X
  2599. X    p = malloc((unsigned) strlen(s) + 1);
  2600. X    if (p == NULL)
  2601. X        fatal("Ran out of memory.");
  2602. X    (void) strcpy(p, s);
  2603. X    return (p);
  2604. X}
  2605. X
  2606. Xhelp(ctab, s)
  2607. X    struct tab *ctab;
  2608. X    char *s;
  2609. X{
  2610. X    register struct tab *c;
  2611. X    register int width, NCMDS;
  2612. X    char *type;
  2613. X
  2614. X    if (ctab == sitetab)
  2615. X        type = "SITE ";
  2616. X    else
  2617. X        type = "";
  2618. X    width = 0, NCMDS = 0;
  2619. X    for (c = ctab; c->name != NULL; c++) {
  2620. X        int len = strlen(c->name);
  2621. X
  2622. X        if (len > width)
  2623. X            width = len;
  2624. X        NCMDS++;
  2625. X    }
  2626. X    width = (width + 8) &~ 7;
  2627. X    if (s == 0) {
  2628. X        register int i, j, w;
  2629. X        int columns, lines;
  2630. X
  2631. X        lreply(214, "The following %scommands are recognized %s.",
  2632. X            type, "(* =>'s unimplemented)");
  2633. X        columns = 76 / width;
  2634. X        if (columns == 0)
  2635. X            columns = 1;
  2636. X        lines = (NCMDS + columns - 1) / columns;
  2637. X        for (i = 0; i < lines; i++) {
  2638. X            printf("   ");
  2639. X            for (j = 0; j < columns; j++) {
  2640. X                c = ctab + j * lines + i;
  2641. X                printf("%s%c", c->name,
  2642. X                    c->implemented ? ' ' : '*');
  2643. X                if (c + lines >= &ctab[NCMDS])
  2644. X                    break;
  2645. X                w = strlen(c->name) + 1;
  2646. X                while (w < width) {
  2647. X                    putchar(' ');
  2648. X                    w++;
  2649. X                }
  2650. X            }
  2651. X            printf("\r\n");
  2652. X        }
  2653. X        (void) fflush(stdout);
  2654. X        reply(214, "Direct comments to ftp-bugs@%s.", hostname);
  2655. X        return;
  2656. X    }
  2657. X    upper(s);
  2658. X    c = lookup(ctab, s);
  2659. X    if (c == (struct tab *)0) {
  2660. X        reply(502, "Unknown command %s.", s);
  2661. X        return;
  2662. X    }
  2663. X    if (c->implemented)
  2664. X        reply(214, "Syntax: %s%s %s", type, c->name, c->help);
  2665. X    else
  2666. X        reply(214, "%s%-*s\t%s; unimplemented.", type, width,
  2667. X            c->name, c->help);
  2668. X}
  2669. X
  2670. Xsizecmd(filename)
  2671. Xchar *filename;
  2672. X{
  2673. X    switch (type) {
  2674. X    case TYPE_L:
  2675. X    case TYPE_I: {
  2676. X        struct stat stbuf;
  2677. X        if (stat(filename, &stbuf) < 0 ||
  2678. X            (stbuf.st_mode&S_IFMT) != S_IFREG)
  2679. X            reply(550, "%s: not a plain file.", filename);
  2680. X        else
  2681. X            reply(213, "%lu", stbuf.st_size);
  2682. X        break;}
  2683. X    case TYPE_A: {
  2684. X        FILE *fin;
  2685. X        register int c, count;
  2686. X        struct stat stbuf;
  2687. X        fin = fopen(filename, "r");
  2688. X        if (fin == NULL) {
  2689. X            perror_reply(550, filename);
  2690. X            return;
  2691. X        }
  2692. X        if (fstat(fileno(fin), &stbuf) < 0 ||
  2693. X            (stbuf.st_mode&S_IFMT) != S_IFREG) {
  2694. X            reply(550, "%s: not a plain file.", filename);
  2695. X            (void) fclose(fin);
  2696. X            return;
  2697. X        }
  2698. X
  2699. X        count = 0;
  2700. X        while((c=getc(fin)) != EOF) {
  2701. X            if (c == '\n')    /* will get expanded to \r\n */
  2702. X                count++;
  2703. X            count++;
  2704. X        }
  2705. X        (void) fclose(fin);
  2706. X
  2707. X        reply(213, "%ld", count);
  2708. X        break;}
  2709. X    default:
  2710. X        reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
  2711. X    }
  2712. X}
  2713. X#line 908 "ftp.tab.c"
  2714. X#define YYABORT goto yyabort
  2715. X#define YYREJECT goto yyabort
  2716. X#define YYACCEPT goto yyaccept
  2717. X#define YYERROR goto yyerrlab
  2718. Xint
  2719. Xyyparse()
  2720. X{
  2721. X    register int yym, yyn, yystate;
  2722. X#if YYDEBUG
  2723. X    register char *yys;
  2724. X    extern char *getenv();
  2725. X
  2726. X    if (yys = getenv("YYDEBUG"))
  2727. X    {
  2728. X        yyn = *yys;
  2729. X        if (yyn >= '0' && yyn <= '9')
  2730. X            yydebug = yyn - '0';
  2731. X    }
  2732. X#endif
  2733. X
  2734. X    yynerrs = 0;
  2735. X    yyerrflag = 0;
  2736. X    yychar = (-1);
  2737. X
  2738. X    yyssp = yyss;
  2739. X    yyvsp = yyvs;
  2740. X    *yyssp = yystate = 0;
  2741. X
  2742. Xyyloop:
  2743. X    if (yyn = yydefred[yystate]) goto yyreduce;
  2744. X    if (yychar < 0)
  2745. X    {
  2746. X        if ((yychar = yylex()) < 0) yychar = 0;
  2747. X#if YYDEBUG
  2748. X        if (yydebug)
  2749. X        {
  2750. X            yys = 0;
  2751. X            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  2752. X            if (!yys) yys = "illegal-symbol";
  2753. X            printf("%sdebug: state %d, reading %d (%s)\n",
  2754. X                    YYPREFIX, yystate, yychar, yys);
  2755. X        }
  2756. X#endif
  2757. X    }
  2758. X    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
  2759. X            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
  2760. X    {
  2761. X#if YYDEBUG
  2762. X        if (yydebug)
  2763. X            printf("%sdebug: state %d, shifting to state %d\n",
  2764. X                    YYPREFIX, yystate, yytable[yyn]);
  2765. X#endif
  2766. X        if (yyssp >= yyss + yystacksize - 1)
  2767. X        {
  2768. X            goto yyoverflow;
  2769. X        }
  2770. X        *++yyssp = yystate = yytable[yyn];
  2771. X        *++yyvsp = yylval;
  2772. X        yychar = (-1);
  2773. X        if (yyerrflag > 0)  --yyerrflag;
  2774. X        goto yyloop;
  2775. X    }
  2776. X    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
  2777. X            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
  2778. X    {
  2779. X        yyn = yytable[yyn];
  2780. X        goto yyreduce;
  2781. X    }
  2782. X    if (yyerrflag) goto yyinrecovery;
  2783. X#ifdef lint
  2784. X    goto yynewerror;
  2785. X#endif
  2786. Xyynewerror:
  2787. X    yyerror("syntax error");
  2788. X#ifdef lint
  2789. X    goto yyerrlab;
  2790. X#endif
  2791. Xyyerrlab:
  2792. X    ++yynerrs;
  2793. Xyyinrecovery:
  2794. X    if (yyerrflag < 3)
  2795. X    {
  2796. X        yyerrflag = 3;
  2797. X        for (;;)
  2798. X        {
  2799. X            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
  2800. X                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
  2801. X            {
  2802. X#if YYDEBUG
  2803. X                if (yydebug)
  2804. X                    printf("%sdebug: state %d, error recovery shifting\
  2805. X to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
  2806. X#endif
  2807. X                if (yyssp >= yyss + yystacksize - 1)
  2808. X                {
  2809. X                    goto yyoverflow;
  2810. X                }
  2811. X                *++yyssp = yystate = yytable[yyn];
  2812. X                *++yyvsp = yylval;
  2813. X                goto yyloop;
  2814. X            }
  2815. X            else
  2816. X            {
  2817. X#if YYDEBUG
  2818. X                if (yydebug)
  2819. X                    printf("%sdebug: error recovery discarding state %d\n",
  2820. X                            YYPREFIX, *yyssp);
  2821. X#endif
  2822. X                if (yyssp <= yyss) goto yyabort;
  2823. X                --yyssp;
  2824. X                --yyvsp;
  2825. X            }
  2826. X        }
  2827. X    }
  2828. X    else
  2829. X    {
  2830. X        if (yychar == 0) goto yyabort;
  2831. X#if YYDEBUG
  2832. X        if (yydebug)
  2833. X        {
  2834. X            yys = 0;
  2835. X            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  2836. X            if (!yys) yys = "illegal-symbol";
  2837. X            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
  2838. X                    YYPREFIX, yystate, yychar, yys);
  2839. X        }
  2840. X#endif
  2841. X        yychar = (-1);
  2842. X        goto yyloop;
  2843. X    }
  2844. Xyyreduce:
  2845. X#if YYDEBUG
  2846. X    if (yydebug)
  2847. X        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
  2848. X                YYPREFIX, yystate, yyn, yyrule[yyn]);
  2849. X#endif
  2850. X    yym = yylen[yyn];
  2851. X    yyval = yyvsp[1-yym];
  2852. X    switch (yyn)
  2853. X    {
  2854. Xcase 2:
  2855. X#line 99 "ftp.y"
  2856. X {
  2857. X            fromname = (char *) 0;
  2858. X        }
  2859. Xbreak;
  2860. Xcase 4:
  2861. X#line 106 "ftp.y"
  2862. X {
  2863. X            user((char *) yyvsp[-1]);
  2864. X            free((char *) yyvsp[-1]);
  2865. X        }
  2866. Xbreak;
  2867. Xcase 5:
  2868. X#line 111 "ftp.y"
  2869. X {
  2870. X            pass((char *) yyvsp[-1]);
  2871. X            free((char *) yyvsp[-1]);
  2872. X        }
  2873. Xbreak;
  2874. Xcase 6:
  2875. X#line 116 "ftp.y"
  2876. X {
  2877. X            usedefault = 0;
  2878. X            if (pdata >= 0) {
  2879. X                (void) close(pdata);
  2880. X                pdata = -1;
  2881. X            }
  2882. X            reply(200, "PORT command successful.");
  2883. X        }
  2884. Xbreak;
  2885. Xcase 7:
  2886. X#line 125 "ftp.y"
  2887. X {
  2888. X            passive();
  2889. X        }
  2890. Xbreak;
  2891. Xcase 8:
  2892. X#line 129 "ftp.y"
  2893. X {
  2894. X            switch (cmd_type) {
  2895. X
  2896. X            case TYPE_A:
  2897. X                if (cmd_form == FORM_N) {
  2898. X                    reply(200, "Type set to A.");
  2899. X                    type = cmd_type;
  2900. X                    form = cmd_form;
  2901. X                } else
  2902. X                    reply(504, "Form must be N.");
  2903. X                break;
  2904. X
  2905. X            case TYPE_E:
  2906. X                reply(504, "Type E not implemented.");
  2907. X                break;
  2908. X
  2909. X            case TYPE_I:
  2910. X                reply(200, "Type set to I.");
  2911. X                type = cmd_type;
  2912. X                break;
  2913. X
  2914. X            case TYPE_L:
  2915. X#if NBBY == 8
  2916. X                if (cmd_bytesz == 8) {
  2917. X                    reply(200,
  2918. X                        "Type set to L (byte size 8).");
  2919. X                    type = cmd_type;
  2920. X                } else
  2921. X                    reply(504, "Byte size must be 8.");
  2922. X#else /* NBBY == 8 */
  2923. X                UNIMPLEMENTED for NBBY != 8
  2924. X#endif /* NBBY == 8 */
  2925. X            }
  2926. X        }
  2927. Xbreak;
  2928. Xcase 9:
  2929. X#line 164 "ftp.y"
  2930. X {
  2931. X            switch (yyvsp[-1]) {
  2932. X
  2933. X            case STRU_F:
  2934. X                reply(200, "STRU F ok.");
  2935. X                break;
  2936. X
  2937. X            default:
  2938. X                reply(504, "Unimplemented STRU type.");
  2939. X            }
  2940. X        }
  2941. Xbreak;
  2942. Xcase 10:
  2943. X#line 176 "ftp.y"
  2944. X {
  2945. X            switch (yyvsp[-1]) {
  2946. X
  2947. X            case MODE_S:
  2948. X                reply(200, "MODE S ok.");
  2949. X                break;
  2950. X
  2951. X            default:
  2952. X                reply(502, "Unimplemented MODE type.");
  2953. X            }
  2954. X        }
  2955. Xbreak;
  2956. Xcase 11:
  2957. X#line 188 "ftp.y"
  2958. X {
  2959. X            reply(202, "ALLO command ignored.");
  2960. X        }
  2961. Xbreak;
  2962. Xcase 12:
  2963. X#line 192 "ftp.y"
  2964. X {
  2965. X            reply(202, "ALLO command ignored.");
  2966. X        }
  2967. Xbreak;
  2968. Xcase 13:
  2969. X#line 196 "ftp.y"
  2970. X {
  2971. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  2972. X                retrieve((char *) 0, (char *) yyvsp[-1]);
  2973. X            if (yyvsp[-1] != NULL)
  2974. X                free((char *) yyvsp[-1]);
  2975. X        }
  2976. Xbreak;
  2977. Xcase 14:
  2978. X#line 203 "ftp.y"
  2979. X {
  2980. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  2981. X                store((char *) yyvsp[-1], "w", 0);
  2982. X            if (yyvsp[-1] != NULL)
  2983. X                free((char *) yyvsp[-1]);
  2984. X        }
  2985. Xbreak;
  2986. Xcase 15:
  2987. X#line 210 "ftp.y"
  2988. X {
  2989. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  2990. X                store((char *) yyvsp[-1], "a", 0);
  2991. X            if (yyvsp[-1] != NULL)
  2992. X                free((char *) yyvsp[-1]);
  2993. X        }
  2994. Xbreak;
  2995. Xcase 16:
  2996. X#line 217 "ftp.y"
  2997. X {
  2998. X            if (yyvsp[-1])
  2999. X                send_file_list(".");
  3000. X        }
  3001. Xbreak;
  3002. Xcase 17:
  3003. X#line 222 "ftp.y"
  3004. X {
  3005. X            if (yyvsp[-3] && yyvsp[-1] != NULL) 
  3006. X                send_file_list((char *) yyvsp[-1]);
  3007. X            if (yyvsp[-1] != NULL)
  3008. X                free((char *) yyvsp[-1]);
  3009. X        }
  3010. Xbreak;
  3011. Xcase 18:
  3012. X#line 229 "ftp.y"
  3013. X {
  3014. X            if (yyvsp[-1])
  3015. X                retrieve("/bin/ls -lgA", "");
  3016. X        }
  3017. Xbreak;
  3018. Xcase 19:
  3019. X#line 234 "ftp.y"
  3020. X {
  3021. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  3022. X                retrieve("/bin/ls -lgA %s", (char *) yyvsp[-1]);
  3023. X            if (yyvsp[-1] != NULL)
  3024. X                free((char *) yyvsp[-1]);
  3025. X        }
  3026. Xbreak;
  3027. Xcase 20:
  3028. X#line 241 "ftp.y"
  3029. X {
  3030. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  3031. X                statfilecmd((char *) yyvsp[-1]);
  3032. X            if (yyvsp[-1] != NULL)
  3033. X                free((char *) yyvsp[-1]);
  3034. X        }
  3035. Xbreak;
  3036. Xcase 21:
  3037. X#line 248 "ftp.y"
  3038. X {
  3039. X            statcmd();
  3040. X        }
  3041. Xbreak;
  3042. Xcase 22:
  3043. X#line 252 "ftp.y"
  3044. X {
  3045. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  3046. X                delete((char *) yyvsp[-1]);
  3047. X            if (yyvsp[-1] != NULL)
  3048. X                free((char *) yyvsp[-1]);
  3049. X        }
  3050. Xbreak;
  3051. Xcase 23:
  3052. X#line 259 "ftp.y"
  3053. X {
  3054. X            if (fromname) {
  3055. X                renamecmd(fromname, (char *) yyvsp[-1]);
  3056. X                free(fromname);
  3057. X                fromname = (char *) 0;
  3058. X            } else {
  3059. X                reply(503, "Bad sequence of commands.");
  3060. X            }
  3061. X            free((char *) yyvsp[-1]);
  3062. X        }
  3063. Xbreak;
  3064. Xcase 24:
  3065. X#line 270 "ftp.y"
  3066. X {
  3067. X            reply(225, "ABOR command successful.");
  3068. X        }
  3069. Xbreak;
  3070. Xcase 25:
  3071. X#line 274 "ftp.y"
  3072. X {
  3073. X            if (yyvsp[-1])
  3074. X                cwd(pw->pw_dir);
  3075. X        }
  3076. Xbreak;
  3077. Xcase 26:
  3078. X#line 279 "ftp.y"
  3079. X {
  3080. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  3081. X                cwd((char *) yyvsp[-1]);
  3082. X            if (yyvsp[-1] != NULL)
  3083. X                free((char *) yyvsp[-1]);
  3084. X        }
  3085. Xbreak;
  3086. Xcase 27:
  3087. X#line 286 "ftp.y"
  3088. X {
  3089. X            help(cmdtab, (char *) 0);
  3090. X        }
  3091. Xbreak;
  3092. Xcase 28:
  3093. X#line 290 "ftp.y"
  3094. X {
  3095. X            register char *cp = (char *)yyvsp[-1];
  3096. X
  3097. X            if (strncasecmp(cp, "SITE", 4) == 0) {
  3098. X                cp = (char *)yyvsp[-1] + 4;
  3099. X                if (*cp == ' ')
  3100. X                    cp++;
  3101. X                if (*cp)
  3102. X                    help(sitetab, cp);
  3103. X                else
  3104. X                    help(sitetab, (char *) 0);
  3105. X            } else
  3106. X                help(cmdtab, (char *) yyvsp[-1]);
  3107. X        }
  3108. Xbreak;
  3109. Xcase 29:
  3110. X#line 305 "ftp.y"
  3111. X {
  3112. X            reply(200, "NOOP command successful.");
  3113. X        }
  3114. Xbreak;
  3115. Xcase 30:
  3116. X#line 309 "ftp.y"
  3117. X {
  3118. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  3119. X                makedir((char *) yyvsp[-1]);
  3120. X            if (yyvsp[-1] != NULL)
  3121. X                free((char *) yyvsp[-1]);
  3122. X        }
  3123. Xbreak;
  3124. Xcase 31:
  3125. X#line 316 "ftp.y"
  3126. X {
  3127. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  3128. X                removedir((char *) yyvsp[-1]);
  3129. X            if (yyvsp[-1] != NULL)
  3130. X                free((char *) yyvsp[-1]);
  3131. X        }
  3132. Xbreak;
  3133. Xcase 32:
  3134. X#line 323 "ftp.y"
  3135. X {
  3136. X            if (yyvsp[-1])
  3137. X                pwd();
  3138. X        }
  3139. Xbreak;
  3140. Xcase 33:
  3141. X#line 328 "ftp.y"
  3142. X {
  3143. X            if (yyvsp[-1])
  3144. X                cwd("..");
  3145. X        }
  3146. Xbreak;
  3147. Xcase 34:
  3148. X#line 333 "ftp.y"
  3149. X {
  3150. X            help(sitetab, (char *) 0);
  3151. X        }
  3152. Xbreak;
  3153. Xcase 35:
  3154. X#line 337 "ftp.y"
  3155. X {
  3156. X            help(sitetab, (char *) yyvsp[-1]);
  3157. X        }
  3158. Xbreak;
  3159. Xcase 36:
  3160. X#line 341 "ftp.y"
  3161. X {
  3162. X            int oldmask;
  3163. X
  3164. X            if (yyvsp[-1]) {
  3165. X                oldmask = umask(0);
  3166. X                (void) umask(oldmask);
  3167. X                reply(200, "Current UMASK is %03o", oldmask);
  3168. X            }
  3169. X        }
  3170. Xbreak;
  3171. Xcase 37:
  3172. X#line 351 "ftp.y"
  3173. X {
  3174. X            int oldmask;
  3175. X
  3176. X            if (yyvsp[-3]) {
  3177. X                if ((yyvsp[-1] == -1) || (yyvsp[-1] > 0777)) {
  3178. X                    reply(501, "Bad UMASK value");
  3179. X                } else {
  3180. X                    oldmask = umask(yyvsp[-1]);
  3181. X                    reply(200,
  3182. X                        "UMASK set to %03o (was %03o)",
  3183. X                        yyvsp[-1], oldmask);
  3184. X                }
  3185. X            }
  3186. X        }
  3187. Xbreak;
  3188. Xcase 38:
  3189. X#line 366 "ftp.y"
  3190. X {
  3191. X            if (yyvsp[-5] && (yyvsp[-1] != NULL)) {
  3192. X                if (yyvsp[-3] > 0777)
  3193. X                    reply(501,
  3194. X                "CHMOD: Mode value must be between 0 and 0777");
  3195. X                else if (chmod((char *) yyvsp[-1], yyvsp[-3]) < 0)
  3196. X                    perror_reply(550, (char *) yyvsp[-1]);
  3197. X                else
  3198. X                    reply(200, "CHMOD command successful.");
  3199. X            }
  3200. X            if (yyvsp[-1] != NULL)
  3201. X                free((char *) yyvsp[-1]);
  3202. X        }
  3203. Xbreak;
  3204. Xcase 39:
  3205. X#line 380 "ftp.y"
  3206. X {
  3207. X            reply(200,
  3208. X                "Current IDLE time limit is %d seconds; max %d",
  3209. X                timeout, maxtimeout);
  3210. X        }
  3211. Xbreak;
  3212. Xcase 40:
  3213. X#line 386 "ftp.y"
  3214. X {
  3215. X            if (yyvsp[-1] < 30 || yyvsp[-1] > maxtimeout) {
  3216. X                reply(501,
  3217. X            "Maximum IDLE time must be between 30 and %d seconds",
  3218. X                    maxtimeout);
  3219. X            } else {
  3220. X                timeout = yyvsp[-1];
  3221. X                (void) alarm((unsigned) timeout);
  3222. X                reply(200,
  3223. X                    "Maximum IDLE time set to %d seconds",
  3224. X                    timeout);
  3225. X            }
  3226. X        }
  3227. Xbreak;
  3228. Xcase 41:
  3229. X#line 400 "ftp.y"
  3230. X {
  3231. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  3232. X                store((char *) yyvsp[-1], "w", 1);
  3233. X            if (yyvsp[-1] != NULL)
  3234. X                free((char *) yyvsp[-1]);
  3235. X        }
  3236. Xbreak;
  3237. Xcase 42:
  3238. X#line 407 "ftp.y"
  3239. X {
  3240. X#ifdef unix
  3241. X#ifdef BSD
  3242. X            reply(215, "UNIX Type: L%d Version: BSD-%d",
  3243. X                NBBY, BSD);
  3244. X#else /* BSD */
  3245. X            reply(215, "UNIX Type: L%d", NBBY);
  3246. X#endif /* BSD */
  3247. X#else /* unix */
  3248. X            reply(215, "UNKNOWN Type: L%d", NBBY);
  3249. X#endif /* unix */
  3250. X        }
  3251. Xbreak;
  3252. Xcase 43:
  3253. X#line 428 "ftp.y"
  3254. X {
  3255. X            if (yyvsp[-3] && yyvsp[-1] != NULL)
  3256. X                sizecmd((char *) yyvsp[-1]);
  3257. X            if (yyvsp[-1] != NULL)
  3258. X                free((char *) yyvsp[-1]);
  3259. X        }
  3260. Xbreak;
  3261. Xcase 44:
  3262. X#line 445 "ftp.y"
  3263. X {
  3264. X            if (yyvsp[-3] && yyvsp[-1] != NULL) {
  3265. X                struct stat stbuf;
  3266. X                if (stat((char *) yyvsp[-1], &stbuf) < 0)
  3267. X                    perror_reply(550, "%s", (char *) yyvsp[-1]);
  3268. X                else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
  3269. X                    reply(550, "%s: not a plain file.",
  3270. X                        (char *) yyvsp[-1]);
  3271. X                } else {
  3272. X                    register struct tm *t;
  3273. X                    struct tm *gmtime();
  3274. X                    t = gmtime(&stbuf.st_mtime);
  3275. X                    reply(213,
  3276. X                        "19%02d%02d%02d%02d%02d%02d",
  3277. X                        t->tm_year, t->tm_mon+1, t->tm_mday,
  3278. X                        t->tm_hour, t->tm_min, t->tm_sec);
  3279. X                }
  3280. X            }
  3281. X            if (yyvsp[-1] != NULL)
  3282. X                free((char *) yyvsp[-1]);
  3283. X        }
  3284. Xbreak;
  3285. Xcase 45:
  3286. X#line 467 "ftp.y"
  3287. X {
  3288. X            reply(221, "Goodbye.");
  3289. X            dologout(0);
  3290. X        }
  3291. Xbreak;
  3292. Xcase 46:
  3293. X#line 472 "ftp.y"
  3294. X {
  3295. X            yyerrok;
  3296. X        }
  3297. Xbreak;
  3298. Xcase 47:
  3299. X#line 477 "ftp.y"
  3300. X {
  3301. X            char *renamefrom();
  3302. X
  3303. X            if (yyvsp[-3] && yyvsp[-1]) {
  3304. X                fromname = renamefrom((char *) yyvsp[-1]);
  3305. X                if (fromname == (char *) 0 && yyvsp[-1]) {
  3306. X                    free((char *) yyvsp[-1]);
  3307. X                }
  3308. X            }
  3309. X        }
  3310. Xbreak;
  3311. Xcase 49:
  3312. X#line 493 "ftp.y"
  3313. X {
  3314. X            *(char **)&(yyval) = "";
  3315. X        }
  3316. Xbreak;
  3317. Xcase 52:
  3318. X#line 504 "ftp.y"
  3319. X {
  3320. X            register char *a, *p;
  3321. X
  3322. X            a = (char *)&data_dest.sin_addr;
  3323. X            a[0] = yyvsp[-10]; a[1] = yyvsp[-8]; a[2] = yyvsp[-6]; a[3] = yyvsp[-4];
  3324. X            p = (char *)&data_dest.sin_port;
  3325. X            p[0] = yyvsp[-2]; p[1] = yyvsp[0];
  3326. X            data_dest.sin_family = AF_INET;
  3327. X        }
  3328. Xbreak;
  3329. Xcase 53:
  3330. X#line 516 "ftp.y"
  3331. X {
  3332. X        yyval = FORM_N;
  3333. X    }
  3334. Xbreak;
  3335. Xcase 54:
  3336. X#line 520 "ftp.y"
  3337. X {
  3338. X        yyval = FORM_T;
  3339. X    }
  3340. Xbreak;
  3341. Xcase 55:
  3342. X#line 524 "ftp.y"
  3343. X {
  3344. X        yyval = FORM_C;
  3345. X    }
  3346. Xbreak;
  3347. Xcase 56:
  3348. X#line 530 "ftp.y"
  3349. X {
  3350. X        cmd_type = TYPE_A;
  3351. X        cmd_form = FORM_N;
  3352. X    }
  3353. Xbreak;
  3354. Xcase 57:
  3355. X#line 535 "ftp.y"
  3356. X {
  3357. X        cmd_type = TYPE_A;
  3358. X        cmd_form = yyvsp[0];
  3359. X    }
  3360. Xbreak;
  3361. Xcase 58:
  3362. X#line 540 "ftp.y"
  3363. X {
  3364. X        cmd_type = TYPE_E;
  3365. X        cmd_form = FORM_N;
  3366. X    }
  3367. Xbreak;
  3368. Xcase 59:
  3369. X#line 545 "ftp.y"
  3370. X {
  3371. X        cmd_type = TYPE_E;
  3372. X        cmd_form = yyvsp[0];
  3373. X    }
  3374. Xbreak;
  3375. Xcase 60:
  3376. X#line 550 "ftp.y"
  3377. X {
  3378. X        cmd_type = TYPE_I;
  3379. X    }
  3380. Xbreak;
  3381. Xcase 61:
  3382. X#line 554 "ftp.y"
  3383. X {
  3384. X        cmd_type = TYPE_L;
  3385. X        cmd_bytesz = NBBY;
  3386. X    }
  3387. Xbreak;
  3388. Xcase 62:
  3389. X#line 559 "ftp.y"
  3390. X {
  3391. X        cmd_type = TYPE_L;
  3392. X        cmd_bytesz = yyvsp[0];
  3393. X    }
  3394. Xbreak;
  3395. Xcase 63:
  3396. X#line 565 "ftp.y"
  3397. X {
  3398. X        cmd_type = TYPE_L;
  3399. X        cmd_bytesz = yyvsp[0];
  3400. X    }
  3401. Xbreak;
  3402. Xcase 64:
  3403. X#line 572 "ftp.y"
  3404. X {
  3405. X        yyval = STRU_F;
  3406. X    }
  3407. Xbreak;
  3408. Xcase 65:
  3409. X#line 576 "ftp.y"
  3410. X {
  3411. X        yyval = STRU_R;
  3412. X    }
  3413. Xbreak;
  3414. Xcase 66:
  3415. X#line 580 "ftp.y"
  3416. X {
  3417. X        yyval = STRU_P;
  3418. X    }
  3419. Xbreak;
  3420. Xcase 67:
  3421. X#line 586 "ftp.y"
  3422. X {
  3423. X        yyval = MODE_S;
  3424. X    }
  3425. Xbreak;
  3426. Xcase 68:
  3427. X#line 590 "ftp.y"
  3428. X {
  3429. X        yyval = MODE_B;
  3430. X    }
  3431. Xbreak;
  3432. Xcase 69:
  3433. X#line 594 "ftp.y"
  3434. X {
  3435. X        yyval = MODE_C;
  3436. X    }
  3437. Xbreak;
  3438. Xcase 70:
  3439. X#line 600 "ftp.y"
  3440. X {
  3441. X        /*
  3442. X         * Problem: this production is used for all pathname
  3443. X         * processing, but only gives a 550 error reply.
  3444. X         * This is a valid reply in some cases but not in others.
  3445. X         */
  3446. X        if (logged_in && yyvsp[0] && strncmp((char *) yyvsp[0], "~", 1) == 0) {
  3447. X            *(char **)&(yyval) = *glob((char *) yyvsp[0]);
  3448. X            if (globerr != NULL) {
  3449. X                reply(550, globerr);
  3450. X                yyval = NULL;
  3451. X            }
  3452. X            free((char *) yyvsp[0]);
  3453. X        } else
  3454. X            yyval = yyvsp[0];
  3455. X    }
  3456. Xbreak;
  3457. Xcase 72:
  3458. X#line 622 "ftp.y"
  3459. X {
  3460. X        register int ret, dec, multby, digit;
  3461. X
  3462. X        /*
  3463. X         * Convert a number that was read as decimal number
  3464. X         * to what it would be if it had been read as octal.
  3465. X         */
  3466. X        dec = yyvsp[0];
  3467. X        multby = 1;
  3468. X        ret = 0;
  3469. X        while (dec) {
  3470. X            digit = dec%10;
  3471. X            if (digit > 7) {
  3472. X                ret = -1;
  3473. X                break;
  3474. X            }
  3475. X            ret += digit * multby;
  3476. X            multby *= 8;
  3477. X            dec /= 10;
  3478. X        }
  3479. X        yyval = ret;
  3480. X    }
  3481. Xbreak;
  3482. Xcase 73:
  3483. X#line 647 "ftp.y"
  3484. X {
  3485. X        if (logged_in)
  3486. X            yyval = 1;
  3487. X        else {
  3488. X            reply(530, "Please login with USER and PASS.");
  3489. X            yyval = 0;
  3490. X        }
  3491. X    }
  3492. Xbreak;
  3493. X#line 1688 "ftp.tab.c"
  3494. X    }
  3495. X    yyssp -= yym;
  3496. X    yystate = *yyssp;
  3497. X    yyvsp -= yym;
  3498. X    yym = yylhs[yyn];
  3499. X    if (yystate == 0 && yym == 0)
  3500. X    {
  3501. X#if YYDEBUG
  3502. X        if (yydebug)
  3503. X            printf("%sdebug: after reduction, shifting from state 0 to\
  3504. X state %d\n", YYPREFIX, YYFINAL);
  3505. X#endif
  3506. X        yystate = YYFINAL;
  3507. X        *++yyssp = YYFINAL;
  3508. X        *++yyvsp = yyval;
  3509. X        if (yychar < 0)
  3510. X        {
  3511. X            if ((yychar = yylex()) < 0) yychar = 0;
  3512. X#if YYDEBUG
  3513. X            if (yydebug)
  3514. X            {
  3515. X                yys = 0;
  3516. X                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  3517. X                if (!yys) yys = "illegal-symbol";
  3518. X                printf("%sdebug: state %d, reading %d (%s)\n",
  3519. X                        YYPREFIX, YYFINAL, yychar, yys);
  3520. X            }
  3521. X#endif
  3522. X        }
  3523. X        if (yychar == 0) goto yyaccept;
  3524. X        goto yyloop;
  3525. X    }
  3526. X    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
  3527. X            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
  3528. X        yystate = yytable[yyn];
  3529. X    else
  3530. X        yystate = yydgoto[yym];
  3531. X#if YYDEBUG
  3532. X    if (yydebug)
  3533. X        printf("%sdebug: after reduction, shifting from state %d \
  3534. Xto state %d\n", YYPREFIX, *yyssp, yystate);
  3535. X#endif
  3536. X    if (yyssp >= yyss + yystacksize - 1)
  3537. X    {
  3538. X        goto yyoverflow;
  3539. X    }
  3540. X    *++yyssp = yystate;
  3541. X    *++yyvsp = yyval;
  3542. X    goto yyloop;
  3543. Xyyoverflow:
  3544. X    yyerror("yacc stack overflow");
  3545. Xyyabort:
  3546. X    return (1);
  3547. Xyyaccept:
  3548. X    return (0);
  3549. X}
  3550. END_OF_FILE
  3551. if test 40069 -ne `wc -c <'test/ftp.tab.c'`; then
  3552.     echo shar: \"'test/ftp.tab.c'\" unpacked with wrong size!
  3553. fi
  3554. # end of 'test/ftp.tab.c'
  3555. fi
  3556. echo shar: End of archive 3 \(of 3\).
  3557. cp /dev/null ark3isdone
  3558. MISSING=""
  3559. for I in 1 2 3 ; do
  3560.     if test ! -f ark${I}isdone ; then
  3561.     MISSING="${MISSING} ${I}"
  3562.     fi
  3563. done
  3564. if test "${MISSING}" = "" ; then
  3565.     echo You have unpacked all 3 archives.
  3566.     rm -f ark[1-9]isdone
  3567. else
  3568.     echo You still need to unpack the following archives:
  3569.     echo "        " ${MISSING}
  3570. fi
  3571. ##  End of shell archive.
  3572. exit 0
  3573.