home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / UWPC201.ZIP / UWSERVER.TAR / utility / uwterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-25  |  15.5 KB  |  690 lines

  1. /*
  2.  *    uwterm
  3.  *
  4.  * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  5.  * copy this program is given provided that the copy is not sold and that
  6.  * this copyright notice is included.
  7.  */
  8. #include <sys/types.h>
  9. #include <sys/file.h>
  10. #include <sys/ioctl.h>
  11. #include <sys/socket.h>
  12. #include <sys/time.h>
  13. #include <sys/resource.h>
  14. #include <sys/wait.h>
  15. #include <netinet/in.h>
  16. #include <signal.h>
  17. #include <strings.h>
  18. #include <ctype.h>
  19. #include <errno.h>
  20. #include <stdio.h>
  21.  
  22. #include "openpty.h"
  23. #include "uwlib.h"
  24.  
  25. #ifndef UWTERM
  26. #define    UWTERM    "uwterm"
  27. #endif
  28.  
  29. #define    CTL(c)        ((c)&037)
  30.  
  31. #ifndef FD_SET
  32. /* 4.2 retrofit: better definitions for these are in 4.3BSD's <sys/types.h> */
  33. #define    FD_SET(n,p)    ((p)->fds_bits[0] |= (1 << (n)))
  34. #define    FD_CLR(n,p)    ((p)->fds_bits[0] &= ~(1 << (n)))
  35. #define    FD_ISSET(n,p)    ((p)->fds_bits[0] & (1 << (n)))
  36. #define    FD_ZERO(p)    ((p)->fds_bits[0] = 0)
  37. #define    FD_SETSIZE    (NBBY*sizeof(long))
  38. #endif
  39.  
  40. extern int optind;
  41. extern char *optarg;
  42. extern char *getenv();
  43. extern char *malloc();
  44. extern deadkid();
  45. extern int errno;
  46.  
  47. #ifndef htons
  48. /* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
  49. extern unsigned short htons(), ntohs();
  50. extern unsigned long htonl(), ntohl();
  51. #endif
  52.  
  53. char *argv0;
  54.  
  55. main(argc, argv)
  56. int argc;
  57. char **argv;
  58. {
  59.     register char *cp;
  60.     register int c;
  61.     int wflag;
  62.     uwtype_t wtype;
  63.     char *term, *title, *server, *login;
  64.     struct sockaddr_in sa, *sin;
  65.     char hostname[32];
  66.  
  67.     /*
  68.      * If called with no arguments, create a new window using the
  69.      * current shell according to the SHELL environment variable
  70.      * (or "/bin/sh" if that doesn't exist).
  71.      *
  72.      * Options which are recognized directly are:
  73.      *
  74.      *    -ninet    connect to server at address "inet"
  75.      *    -wtype    create window with emulation "type"
  76.      *    -ttitle    label window with "title"
  77.      *    -llogin    use login name "login" on remote machine
  78.      *
  79.      * If no explicit title is specified, the command name is used.
  80.      */
  81.     argv0 = argv[0];
  82.     sin = (struct sockaddr_in *)0;
  83.     server = (char *)0;
  84.     login = (char *)0;
  85.     title = (char *)0;
  86.     wflag = 0;
  87.     term = (char *)0;
  88.     while ((c = getopt(argc, argv, "l:n:t:w:")) != EOF) {
  89.         switch (c) {
  90.         case 'l':
  91.             if (optarg[0] == '\0') {
  92.                 fprintf(stderr,
  93.                     "%s: \"-l\" requires user name\n", argv0);
  94.             } else
  95.                 login = optarg;
  96.             break;
  97.         case 'n':
  98.             server = optarg;
  99.             sa.sin_family = AF_INET;
  100.             sa.sin_addr.s_addr = 0;
  101.             sa.sin_port = 0;
  102.             bzero(sa.sin_zero, sizeof sa.sin_zero);
  103.             for (cp=optarg; isxdigit(c = *cp); cp++) {
  104.                 /* Pyramid compiler botch */
  105.                 /* sa.sin_addr.s_addr *= 16; */
  106.                 sa.sin_addr.s_addr <<= 4;
  107.                 if (isdigit(c))
  108.                     sa.sin_addr.s_addr += c - '0';
  109.                 else if (islower(c))
  110.                     sa.sin_addr.s_addr += c-'a' + 10;
  111.                 else
  112.                     sa.sin_addr.s_addr += c-'A' + 10;
  113.             }
  114.             if (c == '.')
  115.                 for (cp++; isdigit(c = *cp); cp++)
  116.                     sa.sin_port = sa.sin_port*10 + c-'0';
  117.             if (sa.sin_addr.s_addr == 0 || sa.sin_port == 0) {
  118.                 fprintf(stderr,
  119.                     "%s: bad Internet address: %s\n",
  120.                     argv0, optarg);
  121.                 return(1);
  122.             }
  123.             sa.sin_addr.s_addr = htonl(sa.sin_addr.s_addr);
  124.             sa.sin_port = htons(sa.sin_port);
  125.             sin = &sa;
  126.             break;
  127.         case 'w':
  128.             wflag++;
  129.             term = optarg;
  130.             wtype = uw_ttype(optarg);
  131.             break;
  132.         case 't':
  133.             title = optarg;
  134.             break;
  135.         }
  136.     }
  137.  
  138.     gethostname(hostname, sizeof hostname);
  139.     if (title == (char *)0) {
  140.         /*
  141.          * If there was no "-t" argument, then "title" will still
  142.          * be NULL.  In this case we use the host name.
  143.          */
  144.         if (optind == argc)
  145.             title = hostname;
  146.         else
  147.             title = argv[optind];
  148.     }
  149.     
  150.     if (!term) {
  151.         /*
  152.          * If there was no "-w" argument, fetch the window
  153.          * type from the environment.  If that fails, use
  154.          * a default.
  155.          */
  156.         if ((term=getenv("TERM")) != (char *)0)
  157.             wtype = uw_ttype(term);
  158.         else
  159.             wtype = UWT_ADM31;
  160.     }
  161.  
  162.     if (optind == argc-1) {
  163.         /*
  164.          * The remaining argument is the host name.  Fork an "rsh"
  165.          * to execute this on the remote machine.
  166.          */
  167.         return(doremote(argv[optind], server, title, term, login));
  168.     } else if (optind == argc) {
  169.         /*
  170.          * There are no other arguments.  Set up the connection
  171.          * to this machine.
  172.          */
  173.         return(dolocal(sin, title, wtype, term));
  174.     } else {
  175.         fprintf(stderr,
  176.             "Usage: \"%s [-ttitle] [-wtype] [-naddr] [-llogin] host\"\n",
  177.             argv0);
  178.         return(1);
  179.     }
  180. }
  181.  
  182. doremote(host, server, title, term, login)
  183. char *host;
  184. char *server;
  185. char *title;
  186. char *term;
  187. char *login;
  188. {
  189.     register int fd, i, pid;
  190.     register char *cp;
  191.     char *av[16];
  192.  
  193.     /*
  194.      * Invoke a remote "uwterm" via "rsh".
  195.      */
  196.     i = 0;
  197.     av[i++] = "rsh";
  198.     av[i++] = host;
  199.     av[i++] = "-n";
  200.     if (login != NULL) {
  201.         av[i++] = "-l";
  202.         av[i++] = login;
  203.     }
  204.     av[i++] = UWTERM;
  205.     if (server == (char *)0) {
  206.         if ((server = getenv("UW_INET")) == (char *)0) {
  207.             fprintf(stderr,"%s: Can't find window server\n",argv0);
  208.             return(1);
  209.         }
  210.     }
  211.     if ((cp = malloc(3+strlen(server))) == (char *)0) {
  212.         fprintf(stderr, "%s: out of memory\n", argv0);
  213.         return(1);
  214.     }
  215.     (void)strcat(strcpy(cp, "-n"), server);
  216.     av[i++] = cp;
  217.  
  218.     if (title != (char *)0) {
  219.         if ((cp = malloc(3+strlen(title))) == (char *)0) {
  220.             fprintf(stderr, "%s: out of memory\n", argv0);
  221.             return(1);
  222.         }
  223.         (void)strcat(strcpy(cp, "-t"), title);
  224.         av[i++] = cp;
  225.     }
  226.  
  227.     if (term != (char *)0) {
  228.         if ((cp = malloc(3+strlen(term))) == (char *)0) {
  229.             fprintf(stderr, "%s: out of memory\n", argv0);
  230.             return(1);
  231.         }
  232.         (void)strcat(strcpy(cp, "-w"), term);
  233.         av[i++] = cp;
  234.     }
  235.  
  236.     av[i] = (char *)0;
  237.  
  238.     for (fd=getdtablesize()-1; fd > 2; fd--)
  239.         (void)fcntl(fd, F_SETFD, 1);
  240.     (void)execvp(av[0], av);
  241.     (void)execv("/usr/ucb/rsh", av);    /* last-ditch try */
  242.     perror(av[0]);
  243.     return(1);
  244. }
  245.  
  246.             
  247. dolocal(sin, title, wtype, term)
  248. struct sockaddr_in *sin;
  249. char *title;
  250. uwtype_t wtype;
  251. char *term;
  252. {
  253.     register UWIN uwin;
  254.     register int fd;
  255.     register int s;
  256.     struct ptydesc pt;
  257.  
  258.     /*
  259.      * Create and initialize a pseudo-terminal.
  260.      */
  261.     if (openpty(&pt) < 0) {
  262.         fprintf(stderr, "No pseudo-terminals are available\n");
  263.         return(1);
  264.     }
  265.     ttyinit(pt.pt_tfd);
  266.  
  267.  
  268.     /*
  269.      * Make fd's 0 and 1 be "/dev/null".  We'd like to force a known
  270.      * definition for fd 2 at this point, but we may need it for
  271.      * uw_perror() if uw_new() fails.
  272.      */
  273.     if ((fd = open("/dev/null", O_RDWR)) >= 0) {    /* should be zero */
  274.         if (fd != 0 && pt.pt_tfd != 0 && pt.pt_pfd != 0)
  275.             dup2(fd, 0);
  276.         if (fd != 1 && pt.pt_tfd != 1 && pt.pt_pfd != 1)
  277.             dup2(fd, 1);
  278.         if (fd > 2)
  279.             (void)close(fd);
  280.     }
  281.  
  282.     /*
  283.      * Create and title the window.  Make it visible.
  284.      */
  285.     if ((uwin = uw_new(wtype, sin)) == (UWIN)0) {
  286.         uw_perror(argv0, uwerrno, errno);
  287.         return(1);
  288.     }
  289.     (void)uw_stitle(uwin, title);
  290.     (void)uw_svis(uwin, 1);
  291.  
  292.     /*
  293.      * We no longer have use for fd 2, so make it "/dev/null" (the
  294.      * same as fd 0.
  295.      */
  296.     (void)dup2(0, 2);
  297.  
  298.     /*
  299.      * Adjust the environment to contain the correct values of TERM,
  300.      * UW_ID, and UW_INET.  These will be inherited by the child
  301.      * we will create next.
  302.      */
  303.     adjenv(term, sin, UW_ID(uwin));
  304.  
  305.     /*
  306.      * Create a process to execute the command connected to the pty.
  307.      */
  308.     runcmd(pt.pt_tfd, pt.pt_tname);
  309.  
  310.     /*
  311.      * Ignore signals that might cause us trouble.  We do NOT ignore
  312.      * SIGTSTP so that the user can move us from the foreground into
  313.      * the background if desired.
  314.      */
  315.     signal(SIGINT, SIG_IGN);
  316.     signal(SIGQUIT, SIG_IGN);
  317.     signal(SIGCHLD, deadkid);
  318.  
  319. #if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
  320.     /*
  321.      * Install an option handling routine to catch window size
  322.      * changes from the Mac and make the appropriate changes to
  323.      * the pseudo-terminal.
  324.      */
  325.     setresize(uwin, pt.pt_pfd);
  326. #endif
  327.  
  328.     /*
  329.      * Close the slave side of the pty.  Copy data between the pty
  330.      * and the window.  The return value from copy() is the exit
  331.      * status.
  332.      */
  333.     (void)close(pt.pt_tfd);
  334.     s = copy(pt.pt_pfd, UW_DATAFD(uwin));
  335.     uw_kill(uwin);
  336.     return(s);
  337. }
  338.  
  339. ttyinit(ptyfd)
  340. register int ptyfd;
  341. {
  342.     register int ttyfd;
  343.     struct sgttyb sg;
  344.     struct tchars tc;
  345.     struct ltchars ltc;
  346.     int ldisc;
  347.     int lmode;
  348.  
  349.     /*
  350.      * Initialize the modes of the terminal whose file descriptor
  351.      * is "ptyfd" to the same modes as the current terminal.  If there
  352.      * isn't a "current terminal" handy, then use hardcoded defaults.
  353.      */
  354.     for (ttyfd=0; ttyfd < 3 && ioctl(ttyfd, TIOCGETD, &ldisc) < 0; ttyfd++)
  355.         ;
  356.     if (ttyfd < 3) {
  357.         (void)ioctl(ttyfd, TIOCGETP, &sg);
  358.         (void)ioctl(ttyfd, TIOCGETC, &tc);
  359.         (void)ioctl(ttyfd, TIOCGLTC, <c);
  360.         (void)ioctl(ttyfd, TIOCLGET, &lmode);
  361.     } else {
  362.         ldisc = NTTYDISC;
  363.  
  364.         sg.sg_ispeed = sg.sg_ospeed = 13; /* doesn't really matter */
  365.         sg.sg_erase = 0177;    /* ugh */
  366.         sg.sg_kill = CTL('u');    /* ugh */
  367.         sg.sg_flags = ECHO|CRMOD|ANYP;
  368.  
  369.         tc.t_intrc = CTL('c');    /* yuck, should be 0177 */
  370.         tc.t_quitc = CTL('\\');
  371.         tc.t_startc = CTL('q');
  372.         tc.t_stopc = CTL('s');
  373.         tc.t_eofc = CTL('d');
  374.         tc.t_brkc = -1;
  375.  
  376.         ltc.t_suspc = CTL('z');
  377.         ltc.t_dsuspc = CTL('y');
  378.         ltc.t_rprntc = CTL('r');
  379.         ltc.t_flushc = CTL('o');
  380.         ltc.t_werasc = CTL('w');
  381.         ltc.t_lnextc = CTL('v');
  382.  
  383.         lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
  384.     }
  385.     (void)ioctl(ptyfd, TIOCSETD, &ldisc);
  386.     (void)ioctl(ptyfd, TIOCSETP, &sg);
  387.     (void)ioctl(ptyfd, TIOCSETC, &tc);
  388.     (void)ioctl(ptyfd, TIOCSLTC, <c);
  389.     (void)ioctl(ptyfd, TIOCLSET, &lmode);
  390. }
  391.  
  392. adjenv(term, sin, wid)
  393. char *term;
  394. struct sockaddr_in *sin;
  395. uwid_t wid;
  396. {
  397.     char *env[4];
  398.     static char ttype[sizeof "TERM=" + 16];
  399.     static char inet[sizeof INET_ENV + 16];
  400.     static char idstr[sizeof "UW_ID=" + 20];
  401.  
  402.     /*
  403.      * Redefine the environment variable UW_ID.  Redefine UW_INET
  404.      * if "sin" is non-NULL.  Redefine TERM.
  405.      */
  406.     (void)sprintf(ttype, "TERM=%.15s", term);
  407.     env[0] = ttype;
  408.     
  409.     (void)sprintf(idstr, "UW_ID=%ld", wid);
  410.     env[1] = idstr;
  411.  
  412.     if (sin != NULL) {
  413.         (void)sprintf(inet, "%s=%08lx.%d", INET_ENV,
  414.             ntohl(sin->sin_addr.s_addr), ntohs(sin->sin_port));
  415.         env[2] = inet;
  416.         env[3] = (char *)0;
  417.     }  else
  418.         env[2] = (char *)0;
  419.     env_set(env);
  420. }
  421.  
  422. runcmd(fd, tname)
  423. int fd;
  424. char *tname;
  425. {
  426.     register int pid;
  427.     register char *shell;
  428.  
  429.     /*
  430.      * Figure out the name of the user's shell.  If unknown,
  431.      * use a default.
  432.      */
  433.     if ((shell = getenv("SHELL")) == (char *)0)
  434.         shell = "/bin/sh";
  435.  
  436.     /*
  437.      * Fork a new process and attach "fd" to fd's 0, 1, and 2 of
  438.      * that new process.  Disassociate the current controlling
  439.      * terminal and attach the new one (whose name is "tname").
  440.      */
  441.     while ((pid = fork()) < 0)
  442.         sleep(5);
  443.     if (pid == 0) {
  444.         if (fd != 0)
  445.             dup2(fd, 0);
  446.         if (fd != 1)
  447.             dup2(fd, 1);
  448.         if (fd != 2)
  449.             dup2(fd, 2);
  450.         if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
  451.             (void)ioctl(fd, TIOCNOTTY, (char *)0);
  452.             (void)close(fd);
  453.         } else
  454.             setpgrp(0, 0);
  455.         (void)open(tname, O_RDWR);
  456.         for (fd=getdtablesize()-1; fd > 2; fd--)
  457.             (void)fcntl(fd, F_SETFD, 1);
  458.         execlp(shell, "-", (char *)0);
  459.         execl(shell, "-", (char *)0);
  460.         _exit(1);
  461.     }
  462. }
  463.  
  464. copy(fd1, fd2)
  465. int fd1, fd2;
  466. {
  467.     struct fdinfo {
  468.         int    fi_fd;        /* associated file descriptor */
  469.         int    fi_size;    /* amount of data in buffer */
  470.         char    *fi_ptr;    /* pointer to data in fi_buf */
  471.         char    fi_buf[1024];
  472.     };
  473.     register struct fdinfo *fi, *fo;
  474.     register int n, nfds, len;
  475.     struct fdinfo fdinfo[2];
  476.     struct fd_set rdmask[2], wtmask[2], exmask[2];
  477.     struct timeval tv;
  478.  
  479.     /*
  480.      * Copy data between file descriptors fd1 and fd2.  Return when an
  481.      * EOF is read or an I/O error (other than an interrupted system
  482.      * call or non-blocking I/O message) is encountered.
  483.      */
  484.     FD_ZERO(&rdmask[1]);
  485.     FD_ZERO(&wtmask[1]);
  486.     FD_ZERO(&exmask[1]);
  487.  
  488.     fdinfo[0].fi_fd = fd1;
  489.     fdinfo[0].fi_size = 0;
  490.     fdinfo[1].fi_fd = fd2;
  491.     fdinfo[1].fi_size = 0;
  492.  
  493.     FD_SET(fd1, &rdmask[1]);
  494.     FD_SET(fd2, &rdmask[1]);
  495.  
  496.     (void)fcntl(fd1, F_SETFL, FNDELAY);
  497.     (void)fcntl(fd2, F_SETFL, FNDELAY);
  498.  
  499.     nfds = ((fd1 > fd2) ? fd1 : fd2) + 1;
  500.  
  501.     while (1) {
  502.         rdmask[0] = rdmask[1];
  503.         wtmask[0] = wtmask[1];
  504.         exmask[0] = exmask[1];
  505.         errno = 0;
  506.         if (fdinfo[0].fi_size != 0 || fdinfo[1].fi_size != 0) {
  507.             /*
  508.              * Select does not work correctly for writes on
  509.              * some machines, so we must fake it.  If a write
  510.              * is pending, we time out after 1/50 second and
  511.              * pretend that select told us that writes could
  512.              * now be performed.  The code below will do the
  513.              * correct thing if the write would still block.
  514.              */
  515.             tv.tv_sec = 0;
  516.             tv.tv_usec = 1000000 / 50;
  517.             n = select(nfds, rdmask, wtmask, exmask, &tv);
  518.             wtmask[0] = wtmask[1];
  519.         } else
  520.             n = select(nfds, rdmask, wtmask, exmask, (struct timeval *)0);
  521.         if (n < 0 && errno == EINTR) {
  522.             continue;
  523.         } else if (n <= 0) {
  524.             perror("select");
  525.             return(1);
  526.         }
  527.         for (fi=fdinfo; fi < fdinfo+2; fi++) {
  528.             fo = fdinfo + !(fi - fdinfo);
  529.             if (FD_ISSET(fi->fi_fd, rdmask)) {
  530.                 /* data available for reading */
  531.                 len = read(fi->fi_fd, fi->fi_buf,
  532.                     sizeof fi->fi_buf);
  533.                 if (len > 0) {
  534.                     fi->fi_size = len;
  535.                     fi->fi_ptr = fi->fi_buf;
  536.                     FD_CLR(fi->fi_fd, &rdmask[1]);
  537.                     FD_SET(fo->fi_fd, &wtmask[1]);
  538.                     FD_SET(fo->fi_fd, &wtmask[0]);
  539.                 } else if (len == 0) {
  540.                     /* EOF, exit */
  541.                     return(0);
  542.                 } else if (errno != EWOULDBLOCK &&
  543.                     errno != EINTR) {
  544.                     /* error, exit */
  545.                     return(1);
  546.                 }
  547.             }
  548.             if (FD_ISSET(fo->fi_fd, wtmask)) {
  549.                 /* data ready for writing */
  550.                 errno = 0;
  551.                 len = write(fo->fi_fd, fi->fi_ptr, fi->fi_size);
  552.                 if (len > 0) {
  553.                     fi->fi_ptr += len;
  554.                     fi->fi_size -= len;
  555.                     if (fi->fi_size == 0) {
  556.                         FD_SET(fi->fi_fd, &rdmask[1]);
  557.                         FD_CLR(fo->fi_fd, &wtmask[1]);
  558.                     }
  559.                 } else if (errno != EWOULDBLOCK &&
  560.                     errno != EINTR) {
  561.                     /* error, exit */
  562.                     return(1);
  563.                 }
  564.             }
  565.         }
  566.     }
  567. }
  568.  
  569. deadkid()
  570. {
  571.     register int pid;
  572.  
  573.     /*
  574.      * Collect dead children.  Don't bother with their exit status
  575.      * or resource usage.
  576.      */
  577.     while ((pid = wait3((union wait *)0, WNOHANG, (struct rusage *)0)) > 0)
  578.         ;
  579. }
  580.  
  581. #if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
  582. static int ptyfd;
  583.  
  584. #ifdef TIOCSWINSZ
  585. static struct winsize winsz;
  586.  
  587. void
  588. doresize(uwin, optnum, optcmd, uwoptval)
  589. UWIN uwin;
  590. uwopt_t optnum;
  591. uwoptcmd_t optcmd;
  592. union uwoptval *uwoptval;
  593. {
  594.     uwtype_t wtype;
  595.  
  596.     /*
  597.      * 4.3BSD-style window resizing
  598.      */
  599.     if (uw_gtype(uwin, &wtype) < 0)
  600.         wtype = UWT_ADM31;    /* probably wrong to do this here */
  601.     if (optcmd == UWOC_SET) {
  602.         switch (optnum) {
  603.         case UWOP_WSIZE:
  604.             winsz.ws_ypixel = uwoptval->uwov_point.v;
  605.             winsz.ws_xpixel = uwoptval->uwov_point.h;
  606.             break;
  607.         case UWOP_TSIZE:
  608.             if (wtype <= UWT_ANSI) {
  609.                 winsz.ws_row = uwoptval->uwov_point.v;
  610.                 winsz.ws_col = uwoptval->uwov_point.h;
  611.             }
  612.             break;
  613.         }
  614.         if (wtype <= UWT_ANSI &&
  615.             (optnum == UWOP_WSIZE || optnum == UWOP_TSIZE))
  616.             (void)ioctl(ptyfd, TIOCSWINSZ, &winsz);
  617.     }
  618. }
  619.  
  620. setresize(uwin, fd)
  621. UWIN uwin;
  622. int fd;
  623. {
  624.     struct uwpoint pt;
  625.     uwtype_t wtype;
  626.  
  627.     /*
  628.      * Set up the option-handling routine "doresize".
  629.      */
  630.     ptyfd = fd;
  631.     uw_optfn(uwin, UWOP_TSIZE, doresize);
  632.     uw_optfn(uwin, UWOP_WSIZE, doresize);
  633.     winsz.ws_row = 24;    /* default to standard terminal size */
  634.     winsz.ws_col = 80;
  635.     if (uw_gwsize(uwin, &pt) == 0) {
  636.         winsz.ws_ypixel = pt.uwp_v;
  637.         winsz.ws_xpixel = pt.uwp_h;
  638.     } else {
  639.         /* make up something plausible */
  640.         winsz.ws_ypixel = 8 * winsz.ws_row;
  641.         winsz.ws_xpixel = 8 * winsz.ws_col;
  642.     }
  643.  
  644.     if (uw_gtype(uwin, &wtype) == 0 && wtype <= UWT_ANSI)
  645.         (void)uw_optcmd(uwin, UWOP_TSIZE, UWOC_DO, (union uwoptval *)0);
  646. }
  647.  
  648. #else
  649. #ifdef TIOCSSIZE
  650. void
  651. doresize(uwin, optnum, optcmd, uwoptval)
  652. UWIN uwin;
  653. uwopt_t optnum;
  654. uwoptcmd_t optcmd;
  655. union uwoptval *uwoptval;
  656. {
  657.     struct ttysize ts;
  658.     uwtype_t wtype;
  659.  
  660.     /*
  661.      * Sun-style window resizing
  662.      */
  663.     if (uw_gtype(uwin, &wtype) < 0)
  664.         wtype = UWT_ADM31;    /* probably wrong to do this here */
  665.     if (wtype <= UWT_ANSI && optnum == UWOP_TSIZE && optcmd == UWOC_SET) {
  666.         ts.ts_lines = uwoptval->uwov_point.v;
  667.         ts.ts_cols = uwoptval->uwov_point.h;
  668.         (void)ioctl(ptyfd, TIOCSSIZE, &ts);
  669.     }
  670. }
  671.  
  672. setresize(uwin, fd)
  673. UWIN uwin;
  674. int fd;
  675. {
  676.     uwtype_t wtype;
  677.  
  678.     /*
  679.      * Set up the option-handling routine "doresize".
  680.      */
  681.     ptyfd = fd;
  682.     uw_optfn(uwin, UWOP_TSIZE, doresize);
  683.  
  684.     if (uw_gtype(uwin, &wtype) == 0 && wtype <= UWT_ANSI)
  685.         (void)uw_optcmd(uwin, UWOP_TSIZE, UWOC_DO, (union uwoptval *)0);
  686. }
  687. #endif
  688. #endif
  689. #endif
  690.