home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / metamail / tahoe / tty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-18  |  4.4 KB  |  225 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifdef notdef
  14. static char sccsid[] = "@(#)tty.c    5.5 (Berkeley) 2/18/88";
  15. #endif /* notdef */
  16.  
  17. /*
  18.  * Mail -- a mail program
  19.  *
  20.  * Generally useful tty stuff.
  21.  */
  22.  
  23. #include "rcv.h"
  24.  
  25. static    int    c_erase;        /* Current erase char */
  26. static    int    c_kill;            /* Current kill char */
  27. static    int    hadcont;        /* Saw continue signal */
  28. static    jmp_buf    rewrite;        /* Place to go when continued */
  29. #ifndef TIOCSTI
  30. static    int    ttyset;            /* We must now do erase/kill */
  31. #endif
  32.  
  33. /*
  34.  * Read all relevant header fields.
  35.  */
  36.  
  37. grabh(hp, gflags)
  38.     struct header *hp;
  39. {
  40.     struct sgttyb ttybuf;
  41. #ifndef TIOCSTI
  42.     int (*saveint)(), (*savequit)();
  43. #endif
  44.     int (*savecont)();
  45.     int errs;
  46.  
  47.     savecont = signal(SIGCONT, SIG_DFL);
  48.     errs = 0;
  49. #ifndef TIOCSTI
  50.     ttyset = 0;
  51. #endif
  52.     if (gtty(fileno(stdin), &ttybuf) < 0) {
  53.         perror("gtty");
  54.         return(-1);
  55.     }
  56.     c_erase = ttybuf.sg_erase;
  57.     c_kill = ttybuf.sg_kill;
  58. #ifndef TIOCSTI
  59.     ttybuf.sg_erase = 0;
  60.     ttybuf.sg_kill = 0;
  61.     if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL)
  62.         signal(SIGINT, SIG_DFL);
  63.     if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
  64.         signal(SIGQUIT, SIG_DFL);
  65. #endif
  66.     if (gflags & GTO) {
  67. #ifndef TIOCSTI
  68.         if (!ttyset && hp->h_to != NOSTR)
  69.             ttyset++, stty(fileno(stdin), &ttybuf);
  70. #endif
  71.         hp->h_to = readtty("To: ", hp->h_to);
  72.         if (hp->h_to != NOSTR)
  73.             hp->h_seq++;
  74.     }
  75.     if (gflags & GSUBJECT) {
  76. #ifndef TIOCSTI
  77.         if (!ttyset && hp->h_subject != NOSTR)
  78.             ttyset++, stty(fileno(stdin), &ttybuf);
  79. #endif
  80.         hp->h_subject = readtty("Subject: ", hp->h_subject);
  81.         if (hp->h_subject != NOSTR)
  82.             hp->h_seq++;
  83.     }
  84.     if (gflags & GCC) {
  85. #ifndef TIOCSTI
  86.         if (!ttyset && hp->h_cc != NOSTR)
  87.             ttyset++, stty(fileno(stdin), &ttybuf);
  88. #endif
  89.         hp->h_cc = readtty("Cc: ", hp->h_cc);
  90.         if (hp->h_cc != NOSTR)
  91.             hp->h_seq++;
  92.     }
  93.     if (gflags & GBCC) {
  94. #ifndef TIOCSTI
  95.         if (!ttyset && hp->h_bcc != NOSTR)
  96.             ttyset++, stty(fileno(stdin), &ttybuf);
  97. #endif
  98.         hp->h_bcc = readtty("Bcc: ", hp->h_bcc);
  99.         if (hp->h_bcc != NOSTR)
  100.             hp->h_seq++;
  101.     }
  102.     signal(SIGCONT, savecont);
  103. #ifndef TIOCSTI
  104.     ttybuf.sg_erase = c_erase;
  105.     ttybuf.sg_kill = c_kill;
  106.     if (ttyset)
  107.         stty(fileno(stdin), &ttybuf);
  108.     signal(SIGINT, saveint);
  109.     signal(SIGQUIT, savequit);
  110. #endif
  111.     return(errs);
  112. }
  113.  
  114. /*
  115.  * Read up a header from standard input.
  116.  * The source string has the preliminary contents to
  117.  * be read.
  118.  *
  119.  */
  120.  
  121. char *
  122. readtty(pr, src)
  123.     char pr[], src[];
  124. {
  125.     char ch, canonb[BUFSIZ];
  126.     int c;
  127.     register char *cp, *cp2;
  128.     int ttycont();
  129.  
  130.     fputs(pr, stdout);
  131.     fflush(stdout);
  132.     if (src != NOSTR && strlen(src) > BUFSIZ - 2) {
  133.         printf("too long to edit\n");
  134.         return(src);
  135.     }
  136. #ifndef TIOCSTI
  137.     if (src != NOSTR)
  138.         cp = copy(src, canonb);
  139.     else
  140.         cp = copy("", canonb);
  141.     fputs(canonb, stdout);
  142.     fflush(stdout);
  143. #else
  144.     cp = src == NOSTR ? "" : src;
  145.     while (c = *cp++) {
  146.         if (c == c_erase || c == c_kill) {
  147.             ch = '\\';
  148.             ioctl(0, TIOCSTI, &ch);
  149.         }
  150.         ch = c;
  151.         ioctl(0, TIOCSTI, &ch);
  152.     }
  153.     cp = canonb;
  154.     *cp = 0;
  155. #endif
  156.     cp2 = cp;
  157.     while (cp2 < canonb + BUFSIZ)
  158.         *cp2++ = 0;
  159.     cp2 = cp;
  160.     if (setjmp(rewrite))
  161.         goto redo;
  162.     signal(SIGCONT, ttycont);
  163.     clearerr(stdin);
  164.     while (cp2 < canonb + BUFSIZ) {
  165.         c = getc(stdin);
  166.         if (c == EOF || c == '\n')
  167.             break;
  168.         *cp2++ = c;
  169.     }
  170.     *cp2 = 0;
  171.     signal(SIGCONT, SIG_DFL);
  172.     if (c == EOF && ferror(stdin) && hadcont) {
  173. redo:
  174.         hadcont = 0;
  175.         cp = strlen(canonb) > 0 ? canonb : NOSTR;
  176.         clearerr(stdin);
  177.         return(readtty(pr, cp));
  178.     }
  179. #ifndef TIOCSTI
  180.     if (cp == NOSTR || *cp == '\0')
  181.         return(src);
  182.     cp2 = cp;
  183.     if (!ttyset)
  184.         return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
  185.     while (*cp != '\0') {
  186.         c = *cp++;
  187.         if (c == c_erase) {
  188.             if (cp2 == canonb)
  189.                 continue;
  190.             if (cp2[-1] == '\\') {
  191.                 cp2[-1] = c;
  192.                 continue;
  193.             }
  194.             cp2--;
  195.             continue;
  196.         }
  197.         if (c == c_kill) {
  198.             if (cp2 == canonb)
  199.                 continue;
  200.             if (cp2[-1] == '\\') {
  201.                 cp2[-1] = c;
  202.                 continue;
  203.             }
  204.             cp2 = canonb;
  205.             continue;
  206.         }
  207.         *cp2++ = c;
  208.     }
  209.     *cp2 = '\0';
  210. #endif
  211.     if (equal("", canonb))
  212.         return(NOSTR);
  213.     return(savestr(canonb));
  214. }
  215.  
  216. /*
  217.  * Receipt continuation.
  218.  */
  219. /*ARGSUSED*/
  220. ttycont(s)
  221. {
  222.     hadcont++;
  223.     longjmp(rewrite, 1);
  224. }
  225.