home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / unix / uw_shar.sit / uw-42-part5.shar < prev    next >
Text File  |  1989-09-14  |  62KB  |  2,451 lines

  1. #Date: Wed, 2 Mar 88 10:01:20 PST
  2. #From: rothberg@polya.stanford.edu (Edward Rothberg)
  3. #Subject: UW 4.2 part 5 of 8
  4. : This is a shar archive.  Extract with sh, not csh.
  5. if test ! -d lib; then
  6.     echo mkdir lib
  7.     mkdir lib
  8. fi
  9. if test ! -d server; then
  10.     echo mkdir server
  11.     mkdir server
  12. fi
  13. echo x - server/uw_utmp.c
  14. sed -e 's/^X//' > server/uw_utmp.c << '!EOF!server/uw_utmp.c!'
  15. X/*
  16. X *    uw_utmp - /etc/utmp handling
  17. X *
  18. X * Copyright 1985,1986 by John D. Bruner.  All rights reserved.  Permission to
  19. X * copy this program is given provided that the copy is not sold and that
  20. X * this copyright notice is included.
  21. X */
  22. X
  23. X#ifdef UTMP
  24. X
  25. X#include <sys/types.h>
  26. X#include <sys/file.h>
  27. X#include <sys/time.h>
  28. X#include <pwd.h>
  29. X#include <utmp.h>
  30. X#include <strings.h>
  31. X#include <ctype.h>
  32. X#include <stdio.h>
  33. X
  34. X#include "uw_param.h"
  35. X
  36. Xstruct utinfo {
  37. X    struct utinfo    *ui_next;
  38. X    struct utinfo    *ui_chain;
  39. X    char        *ui_line;
  40. X    int        ui_slot;
  41. X    int        ui_inuse;
  42. X};
  43. X
  44. Xstatic struct utinfo *hash[31];
  45. Xstatic struct utinfo *head;
  46. X
  47. Xstatic char *myname;
  48. Xstatic fildes_t utmpfd;
  49. X
  50. Xextern time_t time();
  51. X
  52. Xutmp_init(fd)
  53. Xfildes_t fd;
  54. X{
  55. X    register char *cp, *cq;
  56. X    register struct utinfo *ui;
  57. X    register int hashidx, slot;
  58. X    struct passwd *pw;
  59. X    FILE *fp;
  60. X    char line[256];
  61. X
  62. X    if ((utmpfd = fd) >= 0 && (fp = fopen("/etc/ttys", "r")) == NULL) {
  63. X        (void)close(utmpfd);
  64. X        utmpfd = -1;
  65. X    }
  66. X    if (utmpfd >= 0) {
  67. X        slot = 0;
  68. X        while (fgets(line, sizeof line, fp) != NULL) {
  69. X#ifdef V7TTYS
  70. X            if (!line[0] || !line[1]) {    /* malformed line */
  71. X                slot++;
  72. X                continue;
  73. X            }
  74. X            cp = line+2;    /* skip flag and speed index */
  75. X#else
  76. X            for (cp=line; *cp && isspace(*cp); cp++)
  77. X                ;
  78. X            if (*cp == '#')
  79. X                continue;
  80. X#endif
  81. X            slot++;
  82. X            if ((ui=(struct utinfo *)malloc(sizeof *ui)) != NULL) {
  83. X                for (cq=cp; *cq && !isspace(*cq); cq++)
  84. X                    ;
  85. X                if ((ui->ui_line=malloc(cq-cp+1)) != NULL) {
  86. X                    (void)strncpy(ui->ui_line, cp, cq-cp);
  87. X                    ui->ui_line[cq-cp] = '\0';
  88. X                } else {
  89. X                    free((char *)ui);
  90. X                    ui = (struct utinfo *)0;
  91. X                }
  92. X            }
  93. X            if (ui != NULL) {
  94. X                ui->ui_slot = slot;
  95. X                ui->ui_inuse = 0;
  96. X                ui->ui_chain = head;
  97. X                head = ui;
  98. X                hashidx = utmp_hash(ui->ui_line);
  99. X                ui->ui_next = hash[hashidx];
  100. X                hash[hashidx] = ui;
  101. X            }
  102. X        }
  103. X        (void)fclose(fp);
  104. X    }
  105. X    if ((pw = getpwuid(getuid())) != NULL &&
  106. X        (myname=malloc(1+strlen(pw->pw_name))) != NULL)
  107. X        (void)strcpy(myname, pw->pw_name);
  108. X}
  109. X
  110. Xstatic
  111. Xstruct utinfo *
  112. Xutmp_find(tty)
  113. Xchar *tty;
  114. X{
  115. X    register char *cp;
  116. X    register struct utinfo *ui;
  117. X
  118. X    if ((cp = rindex(tty, '/')) != NULL)
  119. X        cp++;
  120. X    else
  121. X        cp = tty;
  122. X    ui = hash[utmp_hash(cp)];
  123. X    while (ui != NULL && strcmp(ui->ui_line, cp) != 0)
  124. X        ui = ui->ui_next;
  125. X    return(ui);
  126. X}
  127. X
  128. Xutmp_add(tty)
  129. Xchar *tty;
  130. X{
  131. X    register struct utinfo *ui;
  132. X    struct utmp ut;
  133. X
  134. X    if ((ui = utmp_find(tty)) != NULL) {
  135. X        (void)strncpy(ut.ut_line, ui->ui_line, sizeof ut.ut_line);
  136. X        (void)strncpy(ut.ut_name, myname, sizeof ut.ut_name);
  137. X        (void)strncpy(ut.ut_host, "", sizeof ut.ut_host);
  138. X        ut.ut_time = (long)time((time_t)0);
  139. X        ui->ui_inuse = 1;
  140. X        utmp_write(ui->ui_slot, &ut);
  141. X    }
  142. X}
  143. X
  144. X
  145. Xutmp_rm(tty)
  146. Xchar *tty;
  147. X{
  148. X    register struct utinfo *ui;
  149. X    struct utmp ut;
  150. X
  151. X    if ((ui = utmp_find(tty)) != NULL) {
  152. X        (void)strncpy(ut.ut_line, ui->ui_line, sizeof ut.ut_line);
  153. X        (void)strncpy(ut.ut_name, "", sizeof ut.ut_name);
  154. X        (void)strncpy(ut.ut_host, "", sizeof ut.ut_host);
  155. X        ut.ut_time = (long)time((time_t)0);
  156. X        ui->ui_inuse = 0;
  157. X        utmp_write(ui->ui_slot, &ut);
  158. X    }
  159. X}
  160. X
  161. Xutmp_exit()
  162. X{
  163. X    register struct utinfo *ui;
  164. X    struct utmp ut;
  165. X
  166. X    for (ui=head; ui; ui=ui->ui_chain) {
  167. X        if (ui->ui_inuse) {
  168. X            (void)strncpy(ut.ut_line,ui->ui_line,sizeof ut.ut_line);
  169. X            (void)strncpy(ut.ut_name, "", sizeof ut.ut_name);
  170. X            (void)strncpy(ut.ut_host, "", sizeof ut.ut_host);
  171. X            ut.ut_time = (long)time((time_t)0);
  172. X            ui->ui_inuse = 0;
  173. X            utmp_write(ui->ui_slot, &ut);
  174. X        }
  175. X    }
  176. X}
  177. X
  178. Xutmp_write(slot, ut)
  179. Xregister int slot;
  180. Xstruct utmp *ut;
  181. X{
  182. X    extern off_t lseek();
  183. X
  184. X    if (utmpfd >= 0 &&
  185. X        lseek(utmpfd, slot*sizeof(*ut), L_SET) == (off_t)(slot*sizeof(*ut)))
  186. X        (void)write(utmpfd, (char *)ut, sizeof *ut);
  187. X}
  188. X
  189. Xstatic
  190. Xutmp_hash(s)
  191. Xregister char *s;
  192. X{
  193. X    register short h;
  194. X
  195. X    for (h=0; *s; s++)
  196. X        h = (h << ((*s)&7)) | (h >> (sizeof h - ((*s)&7))) + *s;
  197. X    return(h % sizeof hash / sizeof hash[0]);
  198. X}
  199. X#else
  200. Xutmp_add(tty)
  201. Xchar *tty;
  202. X{
  203. X}
  204. X
  205. Xutmp_rm(tty)
  206. Xchar *tty;
  207. X{
  208. X}
  209. X
  210. Xutmp_exit()
  211. X{
  212. X}
  213. X#endif
  214. !EOF!server/uw_utmp.c!
  215. echo x - server/uw_win.c
  216. sed -e 's/^X//' > server/uw_win.c << '!EOF!server/uw_win.c!'
  217. X/*
  218. X *    uw_win - window handling for UW
  219. X *
  220. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  221. X * copy this program is given provided that the copy is not sold and that
  222. X * this copyright notice is included.
  223. X */
  224. X
  225. X#include <sys/types.h>
  226. X#include <sys/file.h>
  227. X#include <sys/ioctl.h>
  228. X#include <signal.h>
  229. X#include <strings.h>
  230. X#include <stdio.h>
  231. X
  232. X#include "openpty.h"
  233. X#include "uw_param.h"
  234. X#include "uw_opt.h"
  235. X#include "uw_win.h"
  236. X#include "uw_fd.h"
  237. X
  238. X/*
  239. X * "defwtype" specifies the default window type.  This type is used when
  240. X * more specific information is not available.
  241. X */
  242. Xwtype_t defwtype = WT_ADM31;
  243. X
  244. X/*
  245. X * "window" is declared in "uw_win.h"  Here we define it.
  246. X */
  247. Xstruct window window[NWINDOW];        /* window data structures */
  248. X
  249. X/*
  250. X * "emulation" describes window emulation-specific data.  "generic_emul"
  251. X * describes emulations which do not require special server attention
  252. X * (e.g. file transfer, all of whose real work is done by a separate process).
  253. X */
  254. Xextern struct emulation adm31_emul, vt52_emul, ansi_emul, tek_emul;
  255. Xstatic struct emulation generic_emul;
  256. Xstatic struct emulation *emulation[WT_MAXTYPE+1] = {
  257. X    &adm31_emul,
  258. X    &vt52_emul,
  259. X    &ansi_emul,
  260. X    &tek_emul,
  261. X    &generic_emul,
  262. X    &generic_emul,
  263. X    &generic_emul,
  264. X};
  265. X
  266. Xextern char *win_getopt();
  267. Xextern void win_setopt();
  268. X
  269. Xstatic woptarg_t woa_vis[] = { WOA_UDATA(1), WOA_END };
  270. Xstatic woptarg_t woa_type[] = { WOA_UDATA(6), WOA_END };
  271. Xstatic woptarg_t woa_pos[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
  272. Xstatic woptarg_t woa_title[] = { WOA_STRING(255), WOA_END };
  273. Xstatic woptarg_t woa_size[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
  274. X
  275. Xstatic struct woptdefn genwinopt = {
  276. X    (1<<WOG_VIS), 0, 0, 0,
  277. X    (1<<WOG_VIS)|(1<<WOG_TYPE)|(1<<WOG_POS)|(1<<WOG_TITLE)|(1<<WOG_SIZE),
  278. X    {
  279. X/* WOG_END */    { NULL, NULL, NULL },
  280. X/* WOG_VIS */    { woa_vis, win_getopt, win_setopt },
  281. X/* WOG_TYPE */    { woa_type, win_getopt, win_setopt },
  282. X/* WOG_POS */    { woa_pos, win_getopt, win_setopt },
  283. X/* WOG_TITLE */    { woa_title, win_getopt, win_setopt },
  284. X/* WOG_SIZE */    { woa_size, win_getopt, win_setopt },
  285. X/* WOG_6 */    { NULL, NULL, NULL },
  286. X/* WOG_7 */    { NULL, NULL, NULL }
  287. X    }
  288. X};
  289. X
  290. X/*
  291. X * This is a violation of the level structure, but it is expedient.
  292. X */
  293. Xextern void ipc_optmsg();
  294. X
  295. Xwin_init()
  296. X{
  297. X    register struct window *w;
  298. X
  299. X    /*
  300. X     * Initialize.  Mark all windows unallocated.
  301. X     */
  302. X    for (w=window; w < window+NWINDOW; w++)
  303. X        w->w_alloc = 0;
  304. X}
  305. X
  306. Xlong
  307. Xwin_mkid()
  308. X{
  309. X    static unsigned short i = 0;
  310. X    static long pid = -1;
  311. X
  312. X    if (pid == -1)
  313. X        pid = getpid();
  314. X    return((pid << (NBBY*(sizeof(long)/sizeof(short)))) | i++);
  315. X}
  316. X
  317. Xstruct window *
  318. Xwin_search(wid, maxwin)
  319. Xlong wid;
  320. Xnwin_t maxwin;
  321. X{
  322. X    register struct window *w;
  323. X
  324. X    for (w=window; w < window+maxwin; w++)
  325. X        if (w->w_alloc && w->w_id == wid)
  326. X            return(w);
  327. X    return((struct window *)0);
  328. X}
  329. X
  330. Xstruct window *
  331. Xwin_neww(wclass, wtype, wnum, maxwin, wid, datafd, ctlfd, options)
  332. Xwclass_t wclass;
  333. Xwtype_t wtype;
  334. Xnwin_t wnum;
  335. Xnwin_t maxwin;
  336. Xlong wid;
  337. Xfildes_t datafd;
  338. Xfildes_t ctlfd;
  339. Xstruct woptdefn *options;
  340. X{
  341. X    fildes_t fd;
  342. X    int pid;
  343. X    struct window *w;
  344. X    char *tty, *shell;
  345. X    auto struct ptydesc pt;
  346. X    extern char *getenv();
  347. X
  348. X    /*
  349. X     * Create a new window.  "wclass" specifies the window wclass.
  350. X     * If "wnum" is negative, choose a window number; otherwise,
  351. X     * "wnum" is the window number.  "datafd" and "ctlfd" are the
  352. X     * data and control file descriptors to be associated with
  353. X     * this window.  If "datafd" is negative and "wclass" is
  354. X     * WC_INTERNAL, allocate a pseudo-terminal.
  355. X     *
  356. X     * If "options" is non-NULL it specifies the address of an
  357. X     * option definition structure; otherwise, a new one is constructed
  358. X     * from the generic and emulation-specific prototype structures.
  359. X     *
  360. X     * If "wid" is nonzero it is a proposed window ID.  It must be
  361. X     * unique (not in use).  If "wid" is zero, a new ID is assigned.
  362. X     *
  363. X     * The window type "wtype" will always be a terminal emulation
  364. X     * if the wclass is WC_INTERNAL.
  365. X     *
  366. X     * Internal-class windows are visible by default, while external
  367. X     * ones are initially invisible.
  368. X     *
  369. X     * Return the address of the window structure or NULL if
  370. X     * none could be created.
  371. X     */
  372. X    tty = (char *)0;
  373. X    if (wtype > WT_MAXTYPE)
  374. X        return((struct window *)0);
  375. X    if (wid == 0) {
  376. X        while (win_search(wid=win_mkid(), maxwin) != NULL)
  377. X            ;
  378. X    } else if (win_search(wid, maxwin) != NULL)
  379. X        return((struct window *)0);
  380. X    if (datafd < 0 && wclass == WC_INTERNAL) {
  381. X        if (!openpty(&pt)) {
  382. X            datafd = pt.pt_pfd;
  383. X            tty = pt.pt_tname;
  384. X            while ((pid = fork()) < 0)
  385. X                sleep(5);
  386. X            if (!pid) {
  387. X                win_envinit(wtype, wid);
  388. X                (void)signal(SIGHUP, SIG_DFL);
  389. X                (void)signal(SIGINT, SIG_DFL);
  390. X                (void)signal(SIGQUIT, SIG_DFL);
  391. X                (void)signal(SIGTERM, SIG_DFL);
  392. X                (void)signal(SIGTSTP, SIG_IGN);
  393. X                (void)signal(SIGCHLD, SIG_DFL);
  394. X                (void)ioctl(open("/dev/tty",O_RDWR),
  395. X                    (int)TIOCNOTTY, (char *)0);
  396. X                (void)close(open(pt.pt_tname, O_RDONLY));
  397. X                (void)setuid(getuid());
  398. X                if (!(shell = getenv("SHELL")))
  399. X                    shell = "/bin/sh";
  400. X                if (pt.pt_tfd != 0)
  401. X                    (void)dup2(pt.pt_tfd, 0);
  402. X                if (pt.pt_tfd != 1);
  403. X                    (void)dup2(pt.pt_tfd, 1);
  404. X                if (pt.pt_tfd != 2)
  405. X                    (void)dup2(pt.pt_tfd, 2);
  406. X                for (fd=3; fd < nfds; fd++)
  407. X                    (void)close(fd);
  408. X                tty_mode(0);    /* HACK! */
  409. X                execl(shell, shell, (char *)0);
  410. X                _exit(1);
  411. X            } else {
  412. X                utmp_add(tty);
  413. X                (void)close(pt.pt_tfd);
  414. X            }
  415. X        }
  416. X    }
  417. X
  418. X    if (datafd >= 0) {
  419. X        if (wnum > 0) {
  420. X            w = WIN_PTR(wnum);
  421. X            if (w->w_alloc)
  422. X                w = (struct window *)0;
  423. X        } else {
  424. X            for (w=window; w < window+maxwin && w->w_alloc; w++)
  425. X                ;
  426. X            if (w >= window+maxwin)
  427. X                w = (struct window *)0;
  428. X        }
  429. X    } else
  430. X        w = (struct window *)0;
  431. X
  432. X    if (w) {
  433. X        w->w_alloc = 1;
  434. X        w->w_id = wid;
  435. X        w->w_class = wclass;
  436. X        w->w_type = wtype;
  437. X        w->w_visible = (w->w_class == WC_INTERNAL);
  438. X        w->w_position.h = w->w_position.v = 0;
  439. X        w->w_size.h = w->w_size.v = 0;
  440. X        w->w_title[0] = '\0';
  441. X        if (emulation[wtype]->we_start &&
  442. X            !(*emulation[wtype]->we_start)(w)) {
  443. X            if (options)
  444. X                w->w_optdefn = *options;
  445. X            else
  446. X                opt_new(&w->w_optdefn, &genwinopt,
  447. X                    (struct woptdefn *)0);
  448. X        } else {
  449. X            if (options)
  450. X                w->w_optdefn = *options;
  451. X            else
  452. X                opt_new(&w->w_optdefn, &genwinopt,
  453. X                    &emulation[wtype]->we_optdefn);
  454. X        }
  455. X        w->w_datafd = datafd;
  456. X        (void)fcntl(datafd, F_SETFL, FNDELAY);
  457. X        FD_SET(datafd, &selmask[0].sm_rd);
  458. X        fdmap[datafd].f_type = FDT_DATA;
  459. X        fdmap[datafd].f_win = w;
  460. X        if (w->w_class == WC_INTERNAL) {
  461. X            if (tty)
  462. X                (void)strncpy(w->w_tty, tty, sizeof w->w_tty);
  463. X        } else {
  464. X            w->w_ctlfd = ctlfd;
  465. X            if (ctlfd >= 0) {
  466. X                (void)fcntl(ctlfd, F_SETFL, FNDELAY);
  467. X                FD_SET(ctlfd, &selmask[0].sm_rd);
  468. X                fdmap[ctlfd].f_type = FDT_CTL;
  469. X                fdmap[ctlfd].f_win = w;
  470. X                if (emulation[wtype]->we_setext)
  471. X                    (*emulation[wtype]->we_setext)(&w->w_optdefn);
  472. X                opt_setext(&w->w_optdefn, ipc_optmsg);
  473. X            }
  474. X        }
  475. X    }
  476. X            
  477. X    return(w);
  478. X}
  479. X
  480. Xwin_killw(w)
  481. Xregister struct window *w;
  482. X{
  483. X    /*
  484. X     * Kill the window "w".  This is pretty simple; we just close
  485. X     * the data and control file descriptors and mark the structure
  486. X     * inactive.
  487. X     */
  488. X    if (w && w->w_alloc) {
  489. X        if (w->w_datafd >= 0) {
  490. X            if (w->w_class == WC_INTERNAL)
  491. X                utmp_rm(w->w_tty);
  492. X            FD_CLR(w->w_datafd, &selmask[0].sm_rd);
  493. X            FD_CLR(w->w_datafd, &selmask[0].sm_wt);
  494. X            FD_CLR(w->w_datafd, &selmask[0].sm_ex);
  495. X            fdmap[w->w_datafd].f_type = FDT_NONE;
  496. X            (void)close(w->w_datafd);
  497. X        }
  498. X        if (w->w_class == WC_EXTERNAL && w->w_ctlfd >= 0) {
  499. X            FD_CLR(w->w_ctlfd, &selmask[0].sm_rd);
  500. X            FD_CLR(w->w_ctlfd, &selmask[0].sm_wt);
  501. X            FD_CLR(w->w_ctlfd, &selmask[0].sm_ex);
  502. X            fdmap[w->w_ctlfd].f_type = FDT_NONE;
  503. X            (void)close(w->w_ctlfd);
  504. X        }
  505. X        w->w_alloc = 0;
  506. X    }
  507. X}
  508. X
  509. Xwin_renew(w, report)
  510. Xstruct window *w;
  511. Xint report;
  512. X{
  513. X    /*
  514. X     * Reinitialize (re-NEW) the window "w".  Report the state of the
  515. X     * window to the Mac if "report" is nonzero.
  516. X     */
  517. X    opt_renew(&w->w_optdefn, report);
  518. X}
  519. X
  520. Xwin_newtype(w, wtype)
  521. Xregister struct window *w;
  522. Xregister wtype_t wtype;
  523. X{
  524. X    /*
  525. X     * Change the window emulation type to "wtype".
  526. X     */
  527. X    if (wtype <= WT_MAXTYPE && wtype != w->w_type) {
  528. X        if (emulation[w->w_type]->we_stop)
  529. X            (*emulation[w->w_type]->we_stop)(w);
  530. X        w->w_type = wtype;
  531. X        if (emulation[wtype]->we_start &&
  532. X            !(*emulation[wtype]->we_start)(w)) {
  533. X            opt_newtype(&w->w_optdefn, &genwinopt,
  534. X                (struct woptdefn *)0);
  535. X        } else {
  536. X            opt_newtype(&w->w_optdefn, &genwinopt,
  537. X                &emulation[wtype]->we_optdefn);
  538. X        }
  539. X        if (w->w_class == WC_EXTERNAL && w->w_ctlfd >= 0) {
  540. X            if (emulation[wtype]->we_setext)
  541. X                (*emulation[wtype]->we_setext)(&w->w_optdefn);
  542. X            opt_setext(&w->w_optdefn, ipc_optmsg);
  543. X        }
  544. X    }
  545. X}
  546. X
  547. Xwin_envinit(wtype, wid)
  548. Xregister wtype_t wtype;
  549. Xlong wid;
  550. X{
  551. X    register char *widstr;
  552. X    auto char *env[2];
  553. X
  554. X    /*
  555. X     * Set up the environment according to the new window type and
  556. X     * window ID.
  557. X     *
  558. X     * A 64-bit integer will fit in 20 digits.  If a "long" is wider
  559. X     * than this, then this code will have to be adjusted.
  560. X     */
  561. X    if (wtype <= WT_TEK4010)
  562. X        tty_envinit(wtype);
  563. X    if ((widstr = malloc(sizeof "UW_ID=" + 20)) != NULL) {
  564. X        sprintf(widstr, "UW_ID=%ld", wid);
  565. X        env[0] = widstr;
  566. X        env[1] = (char *)0;
  567. X        env_set(env);
  568. X    }
  569. X}
  570. X
  571. Xstatic
  572. Xchar *
  573. Xwin_getopt(win, num)
  574. Xcaddr_t win;
  575. Xwoption_t num;
  576. X{
  577. X    register struct window *w;
  578. X    static union optvalue ov;
  579. X
  580. X    /*
  581. X     * Get the value of window option "num".  It is arguably wrong to
  582. X     * always return the address of "ov" (even if the window isn't
  583. X     * allocated or an unknown option type was requested); however,
  584. X     * we're already in trouble and there is no good way to recover
  585. X     * at this point.
  586. X     */
  587. X    if ((w = (struct window *)win) != NULL && w->w_alloc) {
  588. X        switch (num) {
  589. X        case WOG_VIS:
  590. X            ov.ov_udata1 = w->w_visible;
  591. X            break;
  592. X        case WOG_TYPE:
  593. X            ov.ov_udata6 = w->w_type;
  594. X            break;
  595. X        case WOG_POS:
  596. X            ov.ov_point.h = w->w_position.h;
  597. X            ov.ov_point.v = w->w_position.v;
  598. X            break;
  599. X        case WOG_TITLE:
  600. X            (void)strncpy(ov.ov_string, w->w_title,
  601. X                sizeof ov.ov_string);
  602. X            ov.ov_string[sizeof ov.ov_string-1] = '\0';
  603. X            break;
  604. X        case WOG_SIZE:
  605. X            ov.ov_point.h = w->w_size.h;
  606. X            ov.ov_point.v = w->w_size.v;
  607. X            break;
  608. X        }
  609. X    }
  610. X    return((char *)&ov);
  611. X}
  612. X
  613. Xstatic
  614. Xvoid
  615. Xwin_setopt(win, num, value)
  616. Xcaddr_t win;
  617. Xwoption_t num;
  618. Xchar *value;
  619. X{
  620. X    register struct window *w;
  621. X    register union optvalue *ov;
  622. X
  623. X    /*
  624. X     * Set window option "num" to "value"
  625. X     */
  626. X    if ((w = (struct window *)win) != NULL && w->w_alloc &&
  627. X        (ov = (union optvalue *)value) != NULL) {
  628. X        switch (num) {
  629. X        case WOG_VIS:
  630. X            w->w_visible = ov->ov_udata1;
  631. X            break;
  632. X        case WOG_TYPE:
  633. X            win_newtype(w, (wtype_t)ov->ov_udata6);
  634. X            break;
  635. X        case WOG_POS:
  636. X            w->w_position.h = ov->ov_point.h;
  637. X            w->w_position.v = ov->ov_point.v;
  638. X            break;
  639. X        case WOG_TITLE:
  640. X            (void)strncpy(w->w_title, ov->ov_string,
  641. X                sizeof w->w_title);
  642. X            w->w_title[sizeof w->w_title-1] = '\0';
  643. X            break;
  644. X        case WOG_SIZE:
  645. X            w->w_size.h = ov->ov_point.h;
  646. X            w->w_size.v = ov->ov_point.v;
  647. X            break;
  648. X        }
  649. X    }
  650. X}
  651. !EOF!server/uw_win.c!
  652. echo x - lib/Makefile_4.2
  653. sed -e 's/^X//' > lib/Makefile_4.2 << '!EOF!lib/Makefile_4.2!'
  654. X#! /bin/make -f
  655. X#
  656. X#    uw library makefile (4.2BSD)
  657. X#
  658. X# INCDIR names the directory in which header files are located.
  659. X# SERVERDIR names the directory containing the server source.
  660. X# SERVER_OBJS names the object files derived from sources in SERVERDIR.
  661. X# OBJECTS names all of the object files required for the library.
  662. X#
  663. XINCDIR    =    ../h
  664. X
  665. XSERVERDIR =    ../server
  666. X
  667. XSERVER_OBJS =    $(SERVERDIR)/openpty.o $(SERVERDIR)/uw_env.o
  668. X
  669. XOBJECTS    =    uw_cmd.o uw_close.o uw_detach.o uw_fork.o uw_kill.o \
  670. X        uw_netadj.o uw_new.o uw_optcmd.o uw_optfn.o uw_options.o \
  671. X        uw_perror.o uw_ttype.o \
  672. X        uw_rsetopt.o uw_shell.o \
  673. X        uw_gvis.o uw_gtype.o uw_gtitle.o uw_gwsize.o uw_gpos.o \
  674. X        $(SERVER_OBJS)
  675. X
  676. XSOURCES    =    `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
  677. X
  678. XDEFINES    =    `cat ../DEFINES`
  679. X
  680. XCFLAGS    =    -O -I$(INCDIR) $(DEFINES)
  681. X
  682. XTARGET    =    libuw.a
  683. X
  684. X$(TARGET):    $(OBJECTS)
  685. X    ar cr $(TARGET) `lorder $(OBJECTS) | tsort`
  686. X    ranlib $(TARGET)
  687. X    -if [ ! -f uwlib.a ];then ln -s libuw.a uwlib.a;fi
  688. X
  689. X$(SERVER_OBJS):
  690. X    cd $(SERVERDIR); make `basename $@`
  691. X
  692. Xlint:
  693. X    lint -uhbx -I$(INCDIR) $(DEFINES) $(SOURCES)
  694. X
  695. Xtags:
  696. X    ctags $(SOURCES)
  697. X
  698. Xdepend: 
  699. X    grep '^#include' $(SOURCES) | \
  700. X    sed -e '/</d' \
  701. X        -e 's/:[^"]*"\([^"]*\)".*/: ..\/h\/\1/' \
  702. X        -e 's,^../[a-zA-Z0-9]*/\([^\.]*\)\.[cs],\1.o \1.L,' | \
  703. X    awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
  704. X        else { if (length(rec $$3) > 78) { print rec; rec = $$0; } \
  705. X               else rec = rec " " $$3 } } \
  706. X          END { print rec } ' > makedep
  707. X    echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
  708. X    echo '$$r makedep' >>eddep
  709. X    echo 'w' >>eddep
  710. X    cp Makefile Makefile.bak
  711. X    ex - Makefile < eddep
  712. X    rm eddep makedep
  713. X
  714. Xclean:
  715. X    -rm *.o
  716. X
  717. X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
  718. X
  719. !EOF!lib/Makefile_4.2!
  720. echo x - lib/Makefile_4.3
  721. sed -e 's/^X//' > lib/Makefile_4.3 << '!EOF!lib/Makefile_4.3!'
  722. X#! /bin/make -f
  723. X#
  724. X#    uw library makefile (4.3BSD)
  725. X#
  726. X# INCDIR names the directory in which header files are located.
  727. X# SERVERDIR names the directory containing the server source.
  728. X# SERVER_OBJS names the object files derived from sources in SERVERDIR.
  729. X# OBJECTS names all of the object files required for the library.
  730. X#
  731. X
  732. XINCDIR    =    ../h
  733. X
  734. XSERVERDIR =    ../server
  735. X
  736. XSERVER_OBJS =    $(SERVERDIR)/openpty.o $(SERVERDIR)/uw_env.o
  737. X
  738. XOBJECTS    =    uw_cmd.o uw_close.o uw_detach.o uw_fork.o uw_kill.o \
  739. X        uw_netadj.o uw_new.o uw_optcmd.o uw_optfn.o uw_options.o \
  740. X        uw_perror.o uw_ttype.o \
  741. X        uw_rsetopt.o uw_shell.o \
  742. X        uw_gvis.o uw_gtype.o uw_gtitle.o uw_gwsize.o uw_gpos.o \
  743. X        $(SERVER_OBJS)
  744. X
  745. XSOURCES    =    `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
  746. X
  747. XDEFINES    =    `cat ../DEFINES`
  748. X
  749. XCFLAGS    =    -O -I$(INCDIR) $(DEFINES)
  750. X
  751. XTARGET    =    libuw.a
  752. X
  753. X$(TARGET):    $(OBJECTS)
  754. X    ar cr $(TARGET) `lorder $(OBJECTS) | tsort`
  755. X    ranlib $(TARGET)
  756. X    -if [ ! -f uwlib.a ];then ln -s libuw.a uwlib.a;fi
  757. X
  758. X$(SERVER_OBJS):
  759. X    cd $(SERVERDIR); make `basename $@`
  760. X
  761. Xlint:
  762. X    lint -uhbx -I$(INCDIR) $(DEFINES) $(SOURCES)
  763. X
  764. Xtags:
  765. X    ctags $(SOURCES)
  766. X
  767. Xdepend: 
  768. X    $(CC) -M -I$(INCDIR) $(DEFINES) $(SOURCES) | \
  769. X    sed -e ':loop' \
  770. X        -e 's/\.\.\/[^ /]*\/\.\./../' \
  771. X        -e 't loop' | \
  772. X    awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
  773. X        else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
  774. X               else rec = rec " " $$2 } } \
  775. X          END { print rec } ' >> makedep
  776. X    echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
  777. X    echo '$$r makedep' >>eddep
  778. X    echo 'w' >>eddep
  779. X    cp Makefile Makefile.bak
  780. X    ex - Makefile < eddep
  781. X    rm eddep makedep
  782. X
  783. Xclean:
  784. X    -rm *.o
  785. X
  786. X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
  787. X
  788. !EOF!lib/Makefile_4.3!
  789. echo x - lib/uw_close.c
  790. sed -e 's/^X//' > lib/uw_close.c << '!EOF!lib/uw_close.c!'
  791. X/*
  792. X *    uw library - uw_close
  793. X *
  794. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  795. X * copy this program is given provided that the copy is not sold and that
  796. X * this copyright notice is included.
  797. X */
  798. X#include "uwlib.h"
  799. X
  800. Xuw_close(uwin)
  801. XUWIN uwin;
  802. X{
  803. X    /*
  804. X     * Close all connections to an existing window, but do not kill it.
  805. X     */
  806. X    if (uwin != (UWIN)0) {
  807. X        if (uwin->uwi_ctlfd >= 0)
  808. X            (void)uw_detach(uwin);
  809. X        if (uwin->uwi_datafd >= 0)
  810. X            (void)close(uwin->uwi_datafd);
  811. X        free((char *)uwin);
  812. X        return(0);
  813. X    } else {
  814. X        uwerrno = UWE_INVAL;
  815. X        return(-1);
  816. X    }
  817. X}
  818. !EOF!lib/uw_close.c!
  819. echo x - lib/uw_cmd.c
  820. sed -e 's/^X//' > lib/uw_cmd.c << '!EOF!lib/uw_cmd.c!'
  821. X/*
  822. X *    uw library - uw_cmd
  823. X *
  824. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  825. X * copy this program is given provided that the copy is not sold and that
  826. X * this copyright notice is included.
  827. X */
  828. X
  829. X#include "uwlib.h"
  830. X
  831. Xuwid_t
  832. Xuw_cmd(wtype, file, argv)
  833. Xuwtype_t wtype;
  834. Xchar *file;
  835. Xchar **argv;
  836. X{
  837. X    register uwid_t uwid;
  838. X
  839. X    /*
  840. X     * Create a new window (using uw_fork()) and run the specified
  841. X     * command in it.  Returns the window ID of the new window
  842. X     * (or -1 if the window creation failed).  There is no way to
  843. X     * determine if the executed command failed (e.g. if the
  844. X     * executable file did not exist).
  845. X     */
  846. X    if ((uwid = uw_fork(wtype, (int *)0)) == 0) {
  847. X        (void)execvp(file, argv);
  848. X        uwerrno = UWE_ERRNO;
  849. X        perror(file);
  850. X        _exit(1);
  851. X        /*NOTREACHED*/
  852. X    } else
  853. X        return(uwid);
  854. X}
  855. !EOF!lib/uw_cmd.c!
  856. echo x - lib/uw_detach.c
  857. sed -e 's/^X//' > lib/uw_detach.c << '!EOF!lib/uw_detach.c!'
  858. X/*
  859. X *    uw library - uw_detach
  860. X *
  861. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  862. X * copy this program is given provided that the copy is not sold and that
  863. X * this copyright notice is included.
  864. X */
  865. X#include "uwlib.h"
  866. X
  867. Xuw_detach(uwin)
  868. XUWIN uwin;
  869. X{
  870. X    /*
  871. X     * Detach the control file descriptor for a window, while still
  872. X     * retaining access to the data file descriptor.
  873. X     */
  874. X    if (uwin != (UWIN)0) {
  875. X        if (uwin->uwi_ctlfd >= 0) {
  876. X            uw_optdone(uwin->uwi_ctlfd);
  877. X            (void)close(uwin->uwi_ctlfd);
  878. X            uwin->uwi_ctlfd = -1;
  879. X            return(0);
  880. X        } else {
  881. X            uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
  882. X            return(-1);
  883. X        }
  884. X    } else {
  885. X        uwerrno = UWE_INVAL;
  886. X        return(-1);
  887. X    }
  888. X}
  889. !EOF!lib/uw_detach.c!
  890. echo x - lib/uw_fork.c
  891. sed -e 's/^X//' > lib/uw_fork.c << '!EOF!lib/uw_fork.c!'
  892. X/*
  893. X *    uw library - uw_fork
  894. X *
  895. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  896. X * copy this program is given provided that the copy is not sold and that
  897. X * this copyright notice is included.
  898. X */
  899. X#include <sys/types.h>
  900. X#include <sys/socket.h>
  901. X#include <sys/un.h>
  902. X#include <sys/ioctl.h>
  903. X#include <sys/uio.h>
  904. X#include <sys/file.h>
  905. X#include <strings.h>
  906. X#include <signal.h>
  907. X#include "openpty.h"
  908. X
  909. X#include "uwlib.h"
  910. X
  911. Xextern char *malloc();
  912. Xextern char *getenv();
  913. X
  914. Xuwid_t
  915. Xuw_fork(wtype, pidp)
  916. Xuwtype_t wtype;
  917. Xint *pidp;
  918. X{
  919. X    register int pid;
  920. X    register int sd;
  921. X    register struct uwipc *uwip;
  922. X    register uwid_t wid;
  923. X    auto int fd;
  924. X    char *portal;
  925. X    int lmode, ldisc;
  926. X    struct sgttyb sg;
  927. X    struct tchars tc;
  928. X    struct ltchars ltc;
  929. X    struct iovec iov;
  930. X    struct msghdr msg;
  931. X    struct sockaddr_un sa;
  932. X    struct ptydesc pt;
  933. X    char idstr[20];
  934. X    char *env[2];
  935. X    extern char *ltoa();
  936. X
  937. X    /*
  938. X     * Create a new window attached to a pseudo-terminal.  This routine
  939. X     * returns twice -- once in the parent and once in the (new) child.
  940. X     * The parent receives the window ID of the child (or -1 if the
  941. X     * window creation failed).  Zero is returned to the child.
  942. X     * If "pidp" is a non-NULL pointer, the process ID from the fork()
  943. X     * is stored there.
  944. X     */
  945. X
  946. X    /*
  947. X     * Get the terminal configuration for this tty.  For now we
  948. X     * assume that "/dev/tty" is defined.  Eventually we'll have to
  949. X     * provide defaults in case it is not.
  950. X     */
  951. X    if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
  952. X        (void)ioctl(fd, (int)TIOCGETP, (char *)&sg);
  953. X        (void)ioctl(fd, (int)TIOCGETC, (char *)&tc);
  954. X        (void)ioctl(fd, (int)TIOCGLTC, (char *)<c);
  955. X        (void)ioctl(fd, (int)TIOCLGET, (char *)&lmode);
  956. X        (void)ioctl(fd, (int)TIOCGETD, (char *)&ldisc);
  957. X        (void)close(fd);
  958. X    } else {
  959. X        /* ... */
  960. X    }
  961. X
  962. X    /*
  963. X     * Create a UNIX-domain socket.
  964. X     */
  965. X    if (!(portal=getenv("UW_UIPC"))) {
  966. X        uwerrno = UWE_NXSERV;
  967. X        return(-1);
  968. X    }
  969. X
  970. X    if ((sd=socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
  971. X        uwerrno = UWE_ERRNO;
  972. X        return(-1);
  973. X    }
  974. X    sa.sun_family = AF_UNIX;
  975. X    (void)strncpy(sa.sun_path, portal, sizeof sa.sun_path-1);
  976. X    sa.sun_path[sizeof sa.sun_path-1] = '\0';
  977. X
  978. X
  979. X    /*
  980. X     * Obtain a pseudo-tty and construct the datagram we will send later.
  981. X     */
  982. X    if (openpty(&pt) < 0) {
  983. X        uwerrno = UWE_ERRNO;
  984. X        return(-1);
  985. X    }
  986. X    uwip = (struct uwipc *)malloc(sizeof(struct uwipc)+strlen(pt.pt_pname));
  987. X    env[0] = malloc(sizeof "UW_ID=" + sizeof idstr);
  988. X    if (uwip == (struct uwipc *)0 || env[0] == (char *)0) {
  989. X        uwerrno = UWE_NOMEM;
  990. X        return(-1);
  991. X    }
  992. X    uwip->uwip_cmd = UWC_NEWT;
  993. X    uwip->uwip_len = (char *)&uwip->uwip_newt - (char *)uwip +
  994. X        sizeof(struct uwnewt) + strlen(pt.pt_pname);
  995. X    uwip->uwip_newt.uwnt_type = wtype;
  996. X    (void)strcpy(uwip->uwip_newt.uwnt_pty, pt.pt_pname);
  997. X
  998. X
  999. X    /* 
  1000. X     * Fork a child process using this pseudo-tty.  Initialize the
  1001. X     * terminal modes on the pseudo-tty to match those of the parent
  1002. X     * tty.  We really want a fork() here, not a vfork().
  1003. X     */
  1004. X    while ((pid=fork()) < 0)
  1005. X        sleep(5);
  1006. X    if (pidp != (int *)0)
  1007. X        *pidp = pid;
  1008. X    if (pid) {
  1009. X        wid = (long)pid << 16;
  1010. X        uwip->uwip_newt.uwnt_id = wid;
  1011. X    } else {
  1012. X        (void)setgid(getgid());
  1013. X        (void)setuid(getuid());
  1014. X        wid = (long)getpid() << 16;
  1015. X        (void)strcat(strcpy(env[0], "UW_ID="),
  1016. X             ltoa(wid, idstr, sizeof idstr));
  1017. X        env[1] = (char *)0;
  1018. X        env_set(env);
  1019. X        (void)signal(SIGTSTP, SIG_IGN);
  1020. X        (void)ioctl(open("/dev/tty", 2), (int)TIOCNOTTY, (char *)0);
  1021. X        (void)close(open(pt.pt_tname, 0)); /*set new ctrl tty */
  1022. X        (void)dup2(pt.pt_tfd, 0);
  1023. X        (void)dup2(0, 1);
  1024. X        (void)dup2(0, 2);
  1025. X        fd = getdtablesize();
  1026. X        while (--fd > 2)
  1027. X            (void)close(fd);
  1028. X        (void)ioctl(fd, (int)TIOCSETD, (char *)&ldisc);
  1029. X        (void)ioctl(0, (int)TIOCSETN, (char *)&sg);
  1030. X        (void)ioctl(0, (int)TIOCSETC, (char *)&tc);
  1031. X        (void)ioctl(0, (int)TIOCSLTC, (char *)<c);
  1032. X        (void)ioctl(0, (int)TIOCLSET, (char *)&lmode);
  1033. X        uwerrno = UWE_NONE;
  1034. X        return(0);
  1035. X    }
  1036. X
  1037. X
  1038. X    /*
  1039. X     * Pass the file descriptor to the window server.
  1040. X     */
  1041. X    iov.iov_base = (char *)uwip;
  1042. X    iov.iov_len = uwip->uwip_len;
  1043. X    msg.msg_name = (caddr_t)&sa;
  1044. X    msg.msg_namelen = sizeof sa.sun_family + strlen(sa.sun_path);
  1045. X    msg.msg_iov = &iov;
  1046. X    msg.msg_iovlen = 1;
  1047. X    msg.msg_accrights = (caddr_t)&pt.pt_pfd;
  1048. X    msg.msg_accrightslen = sizeof pt.pt_pfd;
  1049. X    if (sendmsg(sd, &msg, 0) < 0) {
  1050. X        free((char *)uwip);
  1051. X        uwerrno = UWE_ERRNO;
  1052. X        return(-1);
  1053. X    }
  1054. X    free((char *)uwip);
  1055. X    uwerrno = UWE_NONE;
  1056. X    return(wid);
  1057. X}
  1058. X
  1059. Xstatic
  1060. Xchar *
  1061. Xltoa(l, buf, buflen)
  1062. Xlong l;
  1063. Xchar *buf;
  1064. Xint buflen;
  1065. X{
  1066. X    register char *cp;
  1067. X    register unsigned long ul;
  1068. X    static char digits[] = "0123456789";
  1069. X
  1070. X    /*
  1071. X     * This routine replaces a call to sprintf() so that the library
  1072. X     * is independent of stdio.
  1073. X     */
  1074. X    cp = buf+buflen;
  1075. X    *--cp = '\0';
  1076. X    ul = l;
  1077. X    if (cp > buf) {
  1078. X        do {
  1079. X            *--cp = digits[ul%10];
  1080. X            ul /= 10;
  1081. X        } while (cp > buf && ul != 0);
  1082. X    }
  1083. X    return(cp);
  1084. X}
  1085. !EOF!lib/uw_fork.c!
  1086. echo x - lib/uw_gpos.c
  1087. sed -e 's/^X//' > lib/uw_gpos.c << '!EOF!lib/uw_gpos.c!'
  1088. X/*
  1089. X *    uw library - uw_gpos, uw_spos
  1090. X *
  1091. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1092. X * copy this program is given provided that the copy is not sold and that
  1093. X * this copyright notice is included.
  1094. X */
  1095. X#include "uwlib.h"
  1096. X
  1097. Xuw_gpos(uwin, pp)
  1098. Xregister UWIN uwin;
  1099. Xregister struct uwpoint *pp;
  1100. X{
  1101. X    /*
  1102. X     * Get the position of window "uwin" and store it in the point
  1103. X     * whose address is "pp".
  1104. X     */
  1105. X    if (uwin != (UWIN)0) {
  1106. X        if (pp != (struct uwpoint *)0) {
  1107. X            *pp = uwin->uwi_pos;
  1108. X            if (uwin->uwi_ctlfd > 0) {
  1109. X                return(0);
  1110. X            } else {
  1111. X                uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
  1112. X                return(-1);
  1113. X            }
  1114. X        } else {
  1115. X            uwerrno = uwin->uwi_uwerr = UWE_INVAL;
  1116. X            return(-1);
  1117. X        }
  1118. X    } else {
  1119. X        uwerrno = UWE_INVAL;
  1120. X        return(-1);
  1121. X    }
  1122. X}
  1123. X
  1124. Xuw_spos(uwin, pp)
  1125. Xregister UWIN uwin;
  1126. Xstruct uwpoint *pp;
  1127. X{
  1128. X    union uwoptval optval;
  1129. X
  1130. X    /*
  1131. X     * Set the position of window "uwin" to "pp".
  1132. X     */
  1133. X    if (uwin != (UWIN)0) {
  1134. X        if (pp != (struct uwpoint *)0) {
  1135. X            uwin->uwi_pos = *pp;
  1136. X            optval.uwov_point.v = pp->uwp_v;
  1137. X            optval.uwov_point.h = pp->uwp_h;
  1138. X            return(uw_optcmd(uwin, UWOP_POS, UWOC_SET, &optval));
  1139. X        } else {
  1140. X            uwerrno = uwin->uwi_uwerr = UWE_INVAL;
  1141. X            return(-1);
  1142. X        }
  1143. X    } else {
  1144. X        uwerrno = UWE_INVAL;
  1145. X        return(-1);
  1146. X    }
  1147. X}
  1148. !EOF!lib/uw_gpos.c!
  1149. echo x - lib/uw_gtitle.c
  1150. sed -e 's/^X//' > lib/uw_gtitle.c << '!EOF!lib/uw_gtitle.c!'
  1151. X/*
  1152. X *    uw library - uw_gtitle, uw_stitle
  1153. X *
  1154. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1155. X * copy this program is given provided that the copy is not sold and that
  1156. X * this copyright notice is included.
  1157. X */
  1158. X#include <strings.h>
  1159. X#include "uwlib.h"
  1160. X
  1161. Xuw_gtitle(uwin, ttl)
  1162. Xregister UWIN uwin;
  1163. Xuwtitle_t ttl;
  1164. X{
  1165. X    /*
  1166. X     * Get the title of window "uwin" and put it in "ttl".
  1167. X     */
  1168. X    if (uwin != (UWIN)0) {
  1169. X        (void)strncpy(ttl, uwin->uwi_title, sizeof(uwtitle_t));
  1170. X        if (uwin->uwi_ctlfd > 0) {
  1171. X            return(0);
  1172. X        } else {
  1173. X            uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
  1174. X            return(-1);
  1175. X        }
  1176. X    } else {
  1177. X        uwerrno = UWE_INVAL;
  1178. X        return(-1);
  1179. X    }
  1180. X}
  1181. X
  1182. Xuw_stitle(uwin, ttl)
  1183. Xregister UWIN uwin;
  1184. Xuwtitle_t ttl;
  1185. X{
  1186. X    union uwoptval optval;
  1187. X
  1188. X    /*
  1189. X     * Set the title of window "uwin" to "ttl".
  1190. X     */
  1191. X    if (uwin != (UWIN)0) {
  1192. X        (void)strncpy(uwin->uwi_title, ttl, sizeof uwin->uwi_title);
  1193. X        uwin->uwi_title[sizeof uwin->uwi_title - 1] = '\0';
  1194. X        (void)strncpy(optval.uwov_string,ttl,sizeof optval.uwov_string);
  1195. X        optval.uwov_string[sizeof optval.uwov_string - 1] = '\0';
  1196. X        return(uw_optcmd(uwin, UWOP_TITLE, UWOC_SET, &optval));
  1197. X    } else {
  1198. X        uwerrno = UWE_INVAL;
  1199. X        return(-1);
  1200. X    }
  1201. X}
  1202. !EOF!lib/uw_gtitle.c!
  1203. echo x - lib/uw_gtype.c
  1204. sed -e 's/^X//' > lib/uw_gtype.c << '!EOF!lib/uw_gtype.c!'
  1205. X/*
  1206. X *    uw library - uw_gtype, uw_stype
  1207. X *
  1208. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1209. X * copy this program is given provided that the copy is not sold and that
  1210. X * this copyright notice is included.
  1211. X */
  1212. X#include "uwlib.h"
  1213. X
  1214. Xuw_gtype(uwin, tp)
  1215. Xregister UWIN uwin;
  1216. Xregister uwtype_t *tp;
  1217. X{
  1218. X    /*
  1219. X     * Get the type of the window "uwin".  The window type is stored
  1220. X     * in the variable whose address is passed in "tp".
  1221. X     */
  1222. X    if (uwin != (UWIN)0) {
  1223. X        if (tp != (uwtype_t *)0) {
  1224. X            *tp = uwin->uwi_type;
  1225. X            if (uwin->uwi_ctlfd > 0) {
  1226. X                return(0);
  1227. X            } else {
  1228. X                uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
  1229. X                return(-1);
  1230. X            }
  1231. X        } else {
  1232. X            uwerrno = uwin->uwi_uwerr = UWE_INVAL;
  1233. X            return(-1);
  1234. X        }
  1235. X    } else {
  1236. X        uwerrno = UWE_INVAL;
  1237. X        return(-1);
  1238. X    }
  1239. X}
  1240. X
  1241. Xuw_stype(uwin, t)
  1242. Xregister UWIN uwin;
  1243. Xint t;
  1244. X{
  1245. X    union uwoptval optval;
  1246. X
  1247. X    /*
  1248. X     * Set the type of window "uwin" to "t".
  1249. X     */
  1250. X
  1251. X    if (uwin != (UWIN)0) {
  1252. X        if (t < UW_NWTYPES) {
  1253. X            uwin->uwi_type = t;
  1254. X            optval.uwov_6bit = uwin->uwi_type;
  1255. X            return(uw_optcmd(uwin, UWOP_TYPE, UWOC_SET, &optval));
  1256. X        } else {
  1257. X            uwerrno = uwin->uwi_uwerr = UWE_INVAL;
  1258. X            return(-1);
  1259. X        }
  1260. X    } else {
  1261. X        uwerrno = UWE_INVAL;
  1262. X        return(-1);
  1263. X    }
  1264. X}
  1265. !EOF!lib/uw_gtype.c!
  1266. echo x - lib/uw_gvis.c
  1267. sed -e 's/^X//' > lib/uw_gvis.c << '!EOF!lib/uw_gvis.c!'
  1268. X/*
  1269. X *    uw library - uw_gvis, uw_svis
  1270. X *
  1271. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1272. X * copy this program is given provided that the copy is not sold and that
  1273. X * this copyright notice is included.
  1274. X */
  1275. X#include "uwlib.h"
  1276. X
  1277. Xuw_gvis(uwin, vp)
  1278. Xregister UWIN uwin;
  1279. Xregister int *vp;
  1280. X{
  1281. X    /*
  1282. X     * Get the visibility status of the window "uwin".  "vp" is a
  1283. X     * pointer to the integer where the status is returned.
  1284. X     */
  1285. X    if (uwin != (UWIN)0) {
  1286. X        if (vp != (int *)0) {
  1287. X            *vp = uwin->uwi_vis;
  1288. X            if (uwin->uwi_ctlfd > 0) {
  1289. X                return(0);
  1290. X            } else {
  1291. X                uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
  1292. X                return(-1);
  1293. X            }
  1294. X        } else {
  1295. X            uwerrno = uwin->uwi_uwerr = UWE_INVAL;
  1296. X            return(-1);
  1297. X        }
  1298. X    } else {
  1299. X        uwerrno = UWE_INVAL;
  1300. X        return(-1);
  1301. X    }
  1302. X}
  1303. X
  1304. Xuw_svis(uwin, v)
  1305. Xregister UWIN uwin;
  1306. Xint v;
  1307. X{
  1308. X    union uwoptval optval;
  1309. X
  1310. X    /*
  1311. X     * Make window "uwin" visible (v != 0) or invisible (v == 0).
  1312. X     */
  1313. X    if (uwin != (UWIN)0) {
  1314. X        uwin->uwi_vis = (v != 0);
  1315. X        optval.uwov_1bit = uwin->uwi_vis;
  1316. X        return(uw_optcmd(uwin, UWOP_VIS, UWOC_SET, &optval));
  1317. X    } else {
  1318. X        uwerrno = UWE_INVAL;
  1319. X        return(-1);
  1320. X    }
  1321. X}
  1322. !EOF!lib/uw_gvis.c!
  1323. echo x - lib/uw_gwsize.c
  1324. sed -e 's/^X//' > lib/uw_gwsize.c << '!EOF!lib/uw_gwsize.c!'
  1325. X/*
  1326. X *    uw library - uw_gwsize, uw_swsize
  1327. X *
  1328. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1329. X * copy this program is given provided that the copy is not sold and that
  1330. X * this copyright notice is included.
  1331. X */
  1332. X#include "uwlib.h"
  1333. X
  1334. Xuw_gwsize(uwin, pp)
  1335. Xregister UWIN uwin;
  1336. Xregister struct uwpoint *pp;
  1337. X{
  1338. X    /*
  1339. X     * Get the (pixel) size of window "uwin" and store it in the
  1340. X     * point whose address is "pp".
  1341. X     */
  1342. X    if (uwin != (UWIN)0) {
  1343. X        if (pp != (struct uwpoint *)0) {
  1344. X            *pp = uwin->uwi_wsize;
  1345. X            if (uwin->uwi_ctlfd > 0) {
  1346. X                return(0);
  1347. X            } else {
  1348. X                uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
  1349. X                return(-1);
  1350. X            }
  1351. X        } else {
  1352. X            uwerrno = uwin->uwi_uwerr = UWE_INVAL;
  1353. X            return(-1);
  1354. X        }
  1355. X    } else {
  1356. X        uwerrno = UWE_INVAL;
  1357. X        return(-1);
  1358. X    }
  1359. X}
  1360. X
  1361. Xuw_swsize(uwin, pp)
  1362. Xregister UWIN uwin;
  1363. Xstruct uwpoint *pp;
  1364. X{
  1365. X    union uwoptval optval;
  1366. X
  1367. X    /*
  1368. X     * Set the (pixel) size of window "uwin" to "pp".
  1369. X     */
  1370. X    if (uwin != (UWIN)0) {
  1371. X        if (pp != (struct uwpoint *)0) {
  1372. X            uwin->uwi_wsize = *pp;
  1373. X            optval.uwov_point.v = pp->uwp_v;
  1374. X            optval.uwov_point.h = pp->uwp_h;
  1375. X            return(uw_optcmd(uwin, UWOP_WSIZE, UWOC_SET, &optval));
  1376. X        } else {
  1377. X            uwerrno = uwin->uwi_uwerr = UWE_INVAL;
  1378. X            return(-1);
  1379. X        }
  1380. X    } else {
  1381. X        uwerrno = UWE_INVAL;
  1382. X        return(-1);
  1383. X    }
  1384. X}
  1385. !EOF!lib/uw_gwsize.c!
  1386. echo x - lib/uw_kill.c
  1387. sed -e 's/^X//' > lib/uw_kill.c << '!EOF!lib/uw_kill.c!'
  1388. X/*
  1389. X *    uw library - uw_kill
  1390. X *
  1391. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1392. X * copy this program is given provided that the copy is not sold and that
  1393. X * this copyright notice is included.
  1394. X */
  1395. X#include <sys/types.h>
  1396. X#include <netinet/in.h>
  1397. X
  1398. X#include "uwlib.h"
  1399. X
  1400. X#ifndef htons
  1401. X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
  1402. Xextern unsigned short htons(), ntohs();
  1403. Xextern unsigned long htonl(), ntohl();
  1404. X#endif
  1405. X
  1406. Xuw_kill(uwin)
  1407. XUWIN uwin;
  1408. X{
  1409. X    register int len;
  1410. X    struct uwipc uwip;
  1411. X    extern int errno;
  1412. X
  1413. X    /*
  1414. X     * Kill the window "uwin".  After putting out the contract,
  1415. X     * destroy the evidence by closing all existing connections
  1416. X     * to the window.
  1417. X     */
  1418. X    if (uwin != (UWIN)0) {
  1419. X        if (uwin->uwi_ctlfd >= 0) {
  1420. X            len = sizeof uwip.uwip_killw +
  1421. X                (char *)&uwip.uwip_killw - (char *)&uwip;
  1422. X            uwip.uwip_len = htons(len);
  1423. X            uwip.uwip_cmd = htons(UWC_KILLW);
  1424. X            uwip.uwip_killw.uwkw_id = htonl(uwin->uwi_id);
  1425. X            if (write(uwin->uwi_ctlfd, (char *)&uwip, len) < 0) {
  1426. X                uwin->uwi_errno = errno;
  1427. X                uwerrno = uwin->uwi_uwerr = UWE_ERRNO;
  1428. X            } else
  1429. X                uwerrno = uwin->uwi_uwerr = UWE_NONE;
  1430. X            (void)uw_detach(uwin);
  1431. X        } else
  1432. X            uwerrno = uwin->uwi_uwerr = UWE_NOCTL;
  1433. X        if (uwin->uwi_uwerr == UWE_NONE)
  1434. X            return(0);
  1435. X        else
  1436. X            return(-1);
  1437. X    } else {
  1438. X        uwerrno = UWE_INVAL;
  1439. X        return(-1);
  1440. X    }
  1441. X}
  1442. !EOF!lib/uw_kill.c!
  1443. echo x - lib/uw_netadj.c
  1444. sed -e 's/^X//' > lib/uw_netadj.c << '!EOF!lib/uw_netadj.c!'
  1445. X/*
  1446. X *    uw library - uw_netadj
  1447. X *
  1448. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1449. X * copy this program is given provided that the copy is not sold and that
  1450. X * this copyright notice is included.
  1451. X */
  1452. X#include <sys/types.h>
  1453. X#include <sys/socket.h>
  1454. X#include <sys/un.h>
  1455. X#include <sys/ioctl.h>
  1456. X#include <sys/wait.h>
  1457. X#include <sys/time.h>
  1458. X#include <sys/resource.h>
  1459. X#include <sys/uio.h>
  1460. X#include <sys/file.h>
  1461. X#include <netinet/in.h>
  1462. X#include <strings.h>
  1463. X#include <signal.h>
  1464. X#include "openpty.h"
  1465. X
  1466. X#include "uw_opt.h"    /* I had hoped to avoid including this */
  1467. X#include "uwlib.h"
  1468. X
  1469. Xstatic woptarg_t woa_vis[] = { WOA_UDATA(1), WOA_END };
  1470. Xstatic woptarg_t woa_type[] = { WOA_UDATA(6), WOA_END };
  1471. Xstatic woptarg_t woa_pos[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
  1472. Xstatic woptarg_t woa_title[] = { WOA_STRING(255), WOA_END };
  1473. Xstatic woptarg_t woa_size[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
  1474. Xstatic woptarg_t woa_tsize[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
  1475. Xstatic woptarg_t woa_fontsz[] = { WOA_UDATA(6), WOA_END };
  1476. Xstatic woptarg_t woa_clipb[] = { WOA_UDATA(1), WOA_END };
  1477. Xstatic woptarg_t woa_bell[] = { WOA_UDATA(2), WOA_END };
  1478. Xstatic woptarg_t woa_curs[] = { WOA_UDATA(1), WOA_END };
  1479. Xstatic woptarg_t woa_chgsz[] = { WOA_UDATA(1), WOA_END };
  1480. X
  1481. Xstatic woptarg_t *optargs[][WONUM_MAX+1] = {
  1482. X    /* window type 0 == adm31 */
  1483. X    {
  1484. X        0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
  1485. X        woa_tsize, woa_fontsz, woa_clipb, woa_bell, woa_curs, woa_chgsz
  1486. X    },
  1487. X    /* window type 1 == vt52 */
  1488. X    {
  1489. X        0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
  1490. X        woa_tsize, woa_fontsz, woa_clipb, woa_bell, woa_curs, woa_chgsz
  1491. X    },
  1492. X    /* window type 2 == ansi */
  1493. X    {
  1494. X        0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
  1495. X        woa_tsize, woa_fontsz, woa_clipb, woa_bell, woa_curs, woa_chgsz
  1496. X    },
  1497. X    /* window type 3 = tek4010 */
  1498. X    {
  1499. X        0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
  1500. X    },
  1501. X    /* window type 4 = file transfer */
  1502. X    {
  1503. X        0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
  1504. X    },
  1505. X    /* window type 5 = printer */
  1506. X    {
  1507. X        0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
  1508. X    },
  1509. X    /* window type 6 = plot */
  1510. X    {
  1511. X        0, woa_vis, woa_type, woa_pos, woa_title, woa_size, 0, 0,
  1512. X    },
  1513. X};
  1514. X
  1515. X#ifdef htons
  1516. Xuw_hton(wtype, optnum, data)
  1517. Xuwtype_t wtype;
  1518. Xuwopt_t optnum;
  1519. Xchar *data;
  1520. X{
  1521. X}
  1522. X
  1523. Xuw_ntoh(wtype, optnum, data)
  1524. Xuwtype_t wtype;
  1525. Xuwopt_t optnum;
  1526. Xchar *data;
  1527. X{
  1528. X}
  1529. X
  1530. X#else
  1531. X/* These should have been defined in <netinet/in.h> but weren't (in 4.2BSD) */
  1532. Xextern unsigned short htons(), ntohs();
  1533. Xextern unsigned long htonl(), ntohl();
  1534. X
  1535. Xuw_hton(wtype, optnum, data)
  1536. Xuwtype_t wtype;
  1537. Xuwopt_t optnum;
  1538. Xchar *data;
  1539. X{
  1540. X    static struct netadj na = {
  1541. X        (short (*)())htons, (long (*)())htonl, htons, htonl
  1542. X    };
  1543. X    if (data != (char *)0 && wtype < sizeof optargs / sizeof optargs[0] &&
  1544. X        optnum <= WONUM_MAX && optargs[wtype][optnum] != (woptarg_t *)0) {
  1545. X        netadj(optargs[wtype][optnum], data, &na);
  1546. X    }
  1547. X}
  1548. X
  1549. Xuw_ntoh(wtype, optnum, data)
  1550. Xuwtype_t wtype;
  1551. Xuwopt_t optnum;
  1552. Xchar *data;
  1553. X{
  1554. X    static struct netadj na = {
  1555. X        (short (*)())ntohs, (long (*)())ntohl, ntohs, ntohl
  1556. X    };
  1557. X    if (data != (char *)0 && wtype < sizeof optargs / sizeof optargs[0] &&
  1558. X        optnum <= WONUM_MAX && optargs[wtype][optnum] != (woptarg_t *)0) {
  1559. X        netadj(optargs[wtype][optnum], data, &na);
  1560. X    }
  1561. X}
  1562. X
  1563. Xstatic
  1564. Xnetadj(woa, data, na)
  1565. Xregister woptarg_t *woa;
  1566. Xchar *data;
  1567. Xregister struct netadj *na;
  1568. X{
  1569. X    register char *cp;
  1570. X    register int cnt;
  1571. X    union {
  1572. X        struct {
  1573. X            char    c1;
  1574. X            short    s;
  1575. X        }    cs;
  1576. X        struct {
  1577. X            char    c2;
  1578. X            long    l;
  1579. X        }    cl;
  1580. X    } u;
  1581. X
  1582. X    /*
  1583. X     * Convert an option between host byte order and network byte order.
  1584. X     */
  1585. X    if (data && na) {
  1586. X        for (cp=data; *woa != WOA_END; woa++) {
  1587. X            cnt = *woa & ~WOA_CMDMASK;
  1588. X            switch (*woa & WOA_CMDMASK) {
  1589. X            case WOA_CHARS(0):
  1590. X            case WOA_STRING(0):
  1591. X                cp += cnt;
  1592. X                break;
  1593. X            case WOA_UDATA(0):
  1594. X                if (cnt <= NBBY) {
  1595. X                    cp++;
  1596. X                } else if (cnt <= sizeof(short)*NBBY) {
  1597. X                    while ((int)cp & ((char *)&u.cs.s-&u.cs.c1-1))
  1598. X                        cp++;
  1599. X                    *(u_short *)cp =
  1600. X                        (*na->na_ushort)(*(u_short *)cp);
  1601. X                    cp += sizeof(short);
  1602. X                } else {
  1603. X                    while ((int)cp & ((char *)&u.cl.l-&u.cl.c2-1))
  1604. X                        cp++;
  1605. X                    *(u_short *)cp =
  1606. X                        (*na->na_ushort)(*(u_short *)cp);
  1607. X                    cp += sizeof(long);
  1608. X                }
  1609. X            }
  1610. X        }
  1611. X    }
  1612. X}
  1613. X#endif
  1614. !EOF!lib/uw_netadj.c!
  1615. echo x - lib/uw_new.c
  1616. sed -e 's/^X//' > lib/uw_new.c << '!EOF!lib/uw_new.c!'
  1617. X/*
  1618. X *    uw library - uw_new
  1619. X *
  1620. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1621. X * copy this program is given provided that the copy is not sold and that
  1622. X * this copyright notice is included.
  1623. X */
  1624. X#include <sys/types.h>
  1625. X#include <sys/socket.h>
  1626. X#include <netinet/in.h>
  1627. X#include <sys/uio.h>
  1628. X#include <strings.h>
  1629. X#include <signal.h>
  1630. X#include <netdb.h>
  1631. X#include <ctype.h>
  1632. X#include "openpty.h"
  1633. X
  1634. X#include "uwlib.h"
  1635. X
  1636. Xextern char *malloc();
  1637. Xextern char *getenv();
  1638. X
  1639. X#ifndef htons
  1640. X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
  1641. Xextern unsigned short htons(), ntohs();
  1642. Xextern unsigned long htonl(), ntohl();
  1643. X#endif
  1644. X
  1645. XUWIN
  1646. Xuw_new(uwtype, sin)
  1647. Xuwtype_t uwtype;
  1648. Xstruct sockaddr_in *sin;
  1649. X{
  1650. X    register UWIN uwin;
  1651. X    register char *cp, c;
  1652. X    register int len;
  1653. X    register int ctlfd;
  1654. X    int rdsz;
  1655. X    auto int namelen;
  1656. X    auto struct sockaddr_in sa, datasin, ctlsin;
  1657. X    auto struct uwipc uwip;
  1658. X    extern int errno;
  1659. X
  1660. X    /*
  1661. X     * If our caller didn't supply an address for us to contact,
  1662. X     * look in the environment to find it.
  1663. X     */
  1664. X    if (sin == (struct sockaddr_in *)0) {
  1665. X        if ((cp = getenv(INET_ENV)) == (char *)0) {
  1666. X            uwerrno = UWE_NXSERV;
  1667. X            return((UWIN)0);
  1668. X        }
  1669. X        sin = &sa;
  1670. X        sa.sin_family = AF_INET;
  1671. X        sa.sin_addr.s_addr = 0;
  1672. X        sa.sin_port = 0;
  1673. X        bzero(sa.sin_zero, sizeof sa.sin_zero);
  1674. X        for ( ; isxdigit(c = *cp); cp++) {
  1675. X            /* Pyramid compiler blows this, must use left shift */
  1676. X            /* sa.sin_addr.s_addr *= 16; */
  1677. X            sa.sin_addr.s_addr <<= 4;
  1678. X            if (isdigit(c))
  1679. X                sa.sin_addr.s_addr += c-'0';
  1680. X            else if (islower(c))
  1681. X                sa.sin_addr.s_addr += c-'a' + 10;
  1682. X            else
  1683. X                sa.sin_addr.s_addr += c-'A' + 10;
  1684. X        }
  1685. X        if (c == '.') {
  1686. X            for (cp++; isdigit(c = *cp); cp++)
  1687. X                sa.sin_port = sa.sin_port*10 + c-'0';
  1688. X        }
  1689. X        if (sa.sin_addr.s_addr == 0 || sa.sin_port == 0 ||
  1690. X            c != '\0') {
  1691. X            /* bad address */
  1692. X            uwerrno = UWE_INVAL;
  1693. X            return((UWIN)0);
  1694. X        }
  1695. X        sa.sin_addr.s_addr = htonl(sa.sin_addr.s_addr);
  1696. X        sa.sin_port = htons(sa.sin_port);
  1697. X    }
  1698. X
  1699. X    /*
  1700. X     * Allocate space for a new window structure.
  1701. X     */
  1702. X    if ((uwin = (UWIN)malloc(sizeof(*uwin))) == (UWIN)0) {
  1703. X        uwerrno = UWE_NOMEM;
  1704. X        return((UWIN)0);
  1705. X    }
  1706. X    uwin->uwi_type = uwtype;
  1707. X    for (len=0; len < UW_NUMOPTS; len++) /* "len" is a convenient "int" */
  1708. X        uwin->uwi_options[len].uwi_optfn = (uwfnptr_t)0;
  1709. X    
  1710. X    /*
  1711. X     * Create sockets for the data and control file descriptors.
  1712. X     */
  1713. X    if ((uwin->uwi_datafd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
  1714. X        (uwin->uwi_ctlfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  1715. X        if (uwin->uwi_datafd >= 0)
  1716. X            (void)close(uwin->uwi_datafd);
  1717. X        return((UWIN)0);
  1718. X    }
  1719. X
  1720. X    /*
  1721. X     * Bind these sockets to a local address.  We figure out the
  1722. X     * local machine's host number and use it if possible; otherwise,
  1723. X     * we fall back to 127.0.0.1 (loopback device).  After binding,
  1724. X     * we determine the port number for the control socket, since we
  1725. X     * must send that to the server.  Connect to the server.
  1726. X     */
  1727. X    datasin.sin_family = AF_INET;
  1728. X    datasin.sin_port = 0;
  1729. X    bzero(datasin.sin_zero, sizeof datasin.sin_zero);
  1730. X    getmyaddr(&datasin.sin_addr);
  1731. X    ctlsin.sin_family = AF_INET;
  1732. X    ctlsin.sin_port = 0;
  1733. X    bzero(ctlsin.sin_zero, sizeof ctlsin.sin_zero);
  1734. X    getmyaddr(&ctlsin.sin_addr);
  1735. X    if (bind(uwin->uwi_datafd, (struct sockaddr *)&datasin, sizeof datasin) < 0 ||
  1736. X        bind(uwin->uwi_ctlfd, (struct sockaddr *)&ctlsin, sizeof ctlsin) < 0 ||
  1737. X        listen(uwin->uwi_ctlfd, 1) < 0) {
  1738. X        uwerrno = UWE_ERRNO;
  1739. X        goto error;
  1740. X    }
  1741. X    namelen = sizeof ctlsin;
  1742. X    (void)getsockname(uwin->uwi_ctlfd, (char *)&ctlsin, &namelen);
  1743. X
  1744. X    if (connect(uwin->uwi_datafd, sin, sizeof(struct sockaddr_in)) < 0) {
  1745. X        uwerrno = UWE_ERRNO;
  1746. X        goto error;
  1747. X    }
  1748. X
  1749. X    /*
  1750. X     * Now we have enough information to build the new-window command
  1751. X     * and send it to the server.  The initial command is sent to the
  1752. X     * data port.  Next, we wait for a connection from the server to
  1753. X     * our data socket.  Finally, we expect the server to send us a
  1754. X     * new window status message on the data fd.
  1755. X     */
  1756. X    len = sizeof uwip.uwip_neww + (char *)&uwip.uwip_neww - (char *)&uwip;
  1757. X    uwip.uwip_len = htons(len);
  1758. X    uwip.uwip_cmd = htons(UWC_NEWW);
  1759. X    uwip.uwip_neww.uwnw_id = 0;    /* let server choose this */
  1760. X    uwip.uwip_neww.uwnw_type = htons(uwtype);
  1761. X    uwip.uwip_neww.uwnw_ctlport = ctlsin.sin_port;/* byte order correct */
  1762. X    if (write(uwin->uwi_datafd, (char *)&uwip, len) < 0) {
  1763. X        uwerrno = UWE_ERRNO;
  1764. X        goto error;
  1765. X    }
  1766. X    
  1767. X    namelen = sizeof ctlsin;
  1768. X    if ((ctlfd = accept(uwin->uwi_ctlfd, (struct sockaddr_in *)&ctlsin, &namelen)) < 0) {
  1769. X        uwerrno = UWE_ERRNO;
  1770. X        goto error;
  1771. X    }
  1772. X    (void)close(uwin->uwi_ctlfd);
  1773. X    uwin->uwi_ctlfd = ctlfd;
  1774. X    uw_optinit(ctlfd, uwin);
  1775. X
  1776. X    cp = (char *)&uwip.uwip_len;
  1777. X    rdsz = sizeof uwip.uwip_len;
  1778. X    while (rdsz > 0 && (len=read(uwin->uwi_datafd, cp, rdsz)) > 0) {
  1779. X        cp += len;
  1780. X        rdsz -= len;
  1781. X    }
  1782. X    if (len > 0) {
  1783. X        rdsz = htons(uwip.uwip_len) - sizeof uwip.uwip_len;
  1784. X        while (rdsz > 0 && (len=read(uwin->uwi_datafd, cp, rdsz)) > 0) {
  1785. X            cp += len;
  1786. X            rdsz -= len;
  1787. X        }
  1788. X    }
  1789. X    if (len <= 0) {
  1790. X        uwerrno = UWE_ERRNO;
  1791. X        goto error;
  1792. X    }
  1793. X    uwerrno = uwin->uwi_uwerr = ntohs(uwip.uwip_status.uwst_err);
  1794. X    errno = uwin->uwi_errno = ntohs(uwip.uwip_status.uwst_errno);
  1795. X    if (uwin->uwi_uwerr != UWE_NONE)
  1796. X        goto error;
  1797. X    uwin->uwi_id = ntohl(uwip.uwip_status.uwst_id);
  1798. X    return(uwin);
  1799. X
  1800. Xerror:
  1801. X    (void)close(uwin->uwi_datafd);
  1802. X    (void)close(uwin->uwi_ctlfd);
  1803. X    free((char *)uwin);
  1804. X    return((UWIN)0);
  1805. X}
  1806. X
  1807. Xstatic
  1808. Xgetmyaddr(addr)
  1809. Xstruct in_addr *addr;
  1810. X{
  1811. X    register struct hostent *h;
  1812. X    char hostname[32];
  1813. X    static int once = 1;
  1814. X    static struct in_addr myaddr;
  1815. X
  1816. X    if (once) {
  1817. X        if (gethostname(hostname, sizeof hostname) < 0) {
  1818. X            (void)strncpy(hostname, "localhost", sizeof hostname-1);
  1819. X            hostname[sizeof hostname-1] = '\0';
  1820. X        }
  1821. X        if ((h = gethostbyname(hostname)) != (struct hostent *)0)
  1822. X            myaddr = *(struct in_addr *)h->h_addr;
  1823. X        else
  1824. X            myaddr.s_addr = htonl(0x7f000001L);
  1825. X        once = 0;
  1826. X    }
  1827. X    *addr = myaddr;
  1828. X}
  1829. !EOF!lib/uw_new.c!
  1830. echo x - lib/uw_optcmd.c
  1831. sed -e 's/^X//' > lib/uw_optcmd.c << '!EOF!lib/uw_optcmd.c!'
  1832. X/*
  1833. X *    uw library - uw_optcmd
  1834. X *
  1835. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1836. X * copy this program is given provided that the copy is not sold and that
  1837. X * this copyright notice is included.
  1838. X */
  1839. X#include <sys/types.h>
  1840. X#include <netinet/in.h>
  1841. X
  1842. X#include "uwlib.h"
  1843. X
  1844. X#ifndef htons
  1845. X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
  1846. Xextern unsigned short htons(), ntohs();
  1847. Xextern unsigned long htonl(), ntohl();
  1848. X#endif
  1849. X
  1850. Xuw_optcmd(uwin, optnum, optcmd, optval)
  1851. XUWIN uwin;
  1852. Xuwopt_t optnum;
  1853. Xuwoptcmd_t optcmd;
  1854. Xunion uwoptval *optval;
  1855. X{
  1856. X    register int len;
  1857. X    struct uwipc uwip;
  1858. X    extern int errno;
  1859. X
  1860. X    /*
  1861. X     * Send an option command string to the server (and eventually
  1862. X     * to the Macintosh).
  1863. X     */
  1864. X    if (uwin != (UWIN)0) {
  1865. X        if (uwin->uwi_ctlfd >= 0) {
  1866. X            if (optnum < UW_NUMOPTS) {
  1867. X                len = sizeof uwip;
  1868. X                uwip.uwip_len = htons(len);
  1869. X                uwip.uwip_cmd = htons(UWC_OPTION);
  1870. X                uwip.uwip_option.uwop_id = htonl(uwin->uwi_id);
  1871. X                uwip.uwip_option.uwop_opt = htons(optnum);
  1872. X                uwip.uwip_option.uwop_cmd = htons(optcmd);
  1873. X                switch (optcmd) {
  1874. X                case UWOC_SET:
  1875. X                    if (optval == (union uwoptval *)0) {
  1876. X                        uwin->uwi_uwerr = UWE_INVAL;
  1877. X                        break;
  1878. X                    } 
  1879. X                    uwip.uwip_option.uwop_val = *optval;
  1880. X                    uw_hton(uwin->uwi_type, optnum,
  1881. X                        (char *)&uwip.uwip_option.uwop_val);
  1882. X                    /* no break */
  1883. X                case UWOC_ASK:
  1884. X                case UWOC_DO:
  1885. X                case UWOC_DONT:
  1886. X                case UWOC_WILL:
  1887. X                case UWOC_WONT:
  1888. X                    if (write(uwin->uwi_ctlfd, (char *)&uwip,
  1889. X                        len) < 0) {
  1890. X                        uwin->uwi_uwerr = UWE_ERRNO;
  1891. X                        uwin->uwi_errno = errno;
  1892. X                    } else
  1893. X                        uwin->uwi_uwerr = UWE_NONE;
  1894. X                    break;
  1895. X                default:
  1896. X                    uwin->uwi_uwerr = UWE_INVAL;
  1897. X                    break;
  1898. X                }
  1899. X            } else
  1900. X                uwin->uwi_uwerr = UWE_INVAL;
  1901. X        }
  1902. X        uwerrno = uwin->uwi_uwerr;
  1903. X        if (uwin->uwi_uwerr == UWE_NONE)
  1904. X            return(0);
  1905. X        else
  1906. X            return(-1);
  1907. X    } else {
  1908. X        uwerrno = UWE_INVAL;
  1909. X        return(-1);
  1910. X    }
  1911. X}
  1912. !EOF!lib/uw_optcmd.c!
  1913. echo x - lib/uw_optfn.c
  1914. sed -e 's/^X//' > lib/uw_optfn.c << '!EOF!lib/uw_optfn.c!'
  1915. X/*
  1916. X *    uw library - uw_optfn
  1917. X *
  1918. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1919. X * copy this program is given provided that the copy is not sold and that
  1920. X * this copyright notice is included.
  1921. X */
  1922. X#include "uwlib.h"
  1923. X
  1924. Xuwfnptr_t
  1925. Xuw_optfn(uwin, optnum, optfn)
  1926. XUWIN uwin;
  1927. Xuwopt_t optnum;
  1928. Xuwfnptr_t optfn;
  1929. X{
  1930. X    uwfnptr_t oldfn;
  1931. X
  1932. X    /*
  1933. X     * Establish an option-processing function (defined by the host).
  1934. X     * The specified function will be called whenever an option message
  1935. X     * is received from the server.  The previous function is returned.
  1936. X     */
  1937. X    oldfn = (uwfnptr_t)0;
  1938. X    if (uwin != (UWIN)0) {
  1939. X        if (optnum < UW_NUMOPTS) {
  1940. X            oldfn = uwin->uwi_options[optnum].uwi_optfn;
  1941. X            uwin->uwi_options[optnum].uwi_optfn = optfn;
  1942. X            uwin->uwi_uwerr = UWE_NONE;
  1943. X        } else
  1944. X            uwin->uwi_uwerr = UWE_INVAL;
  1945. X    }
  1946. X    uwerrno = uwin->uwi_uwerr;
  1947. X    return(oldfn);
  1948. X}
  1949. !EOF!lib/uw_optfn.c!
  1950. echo x - lib/uw_options.c
  1951. sed -e 's/^X//' > lib/uw_options.c << '!EOF!lib/uw_options.c!'
  1952. X/*
  1953. X *    uw library - uw_options
  1954. X *
  1955. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1956. X * copy this program is given provided that the copy is not sold and that
  1957. X * this copyright notice is included.
  1958. X */
  1959. X#include <sys/types.h>
  1960. X#include <sys/file.h>
  1961. X#include <sys/time.h>
  1962. X#include <netinet/in.h>
  1963. X#include <strings.h>
  1964. X#include <signal.h>
  1965. X#include <errno.h>
  1966. X
  1967. X#include "uwlib.h"
  1968. X
  1969. X#ifndef FD_SET
  1970. X#define    FD_SET(n,p)    ((p)->fds_bits[0] |= (1 << (n)))
  1971. X#define    FD_CLR(n,p)    ((p)->fds_bits[0] &= ~(1 << (n)))
  1972. X#define    FD_ISSET(n,p)    ((p)->fds_bits[0] & (1 << (n)))
  1973. X#define    FD_ZERO(p)    ((p)->fds_bits[0] = 0)
  1974. X#define    FD_SETSIZE    (NBBY*sizeof(long))
  1975. X#endif
  1976. X
  1977. X#ifndef sigmask
  1978. X#define sigmask(m)    (1 << ((m)-1))
  1979. X#endif
  1980. X
  1981. X#ifndef htons
  1982. X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
  1983. Xextern unsigned short htons(), ntohs();
  1984. Xextern unsigned long htonl(), ntohl();
  1985. X#endif
  1986. X
  1987. Xstatic UWIN *fdmap;
  1988. Xstatic int (*oldsigio)();
  1989. Xstatic struct fd_set fdmask;
  1990. Xstatic int nfds;
  1991. X
  1992. Xextern char *malloc();
  1993. X
  1994. Xuw_optinit(fd, uwin)
  1995. Xint fd;
  1996. XUWIN uwin;
  1997. X{
  1998. X    register int i, flags;
  1999. X    static int first = 1;
  2000. X    extern uw_optinput();
  2001. X
  2002. X    /*
  2003. X     * The first time through, allocate the file descriptor map and
  2004. X     * bitmask, and cause SIGIO traps to be handled by uw_optinput.
  2005. X     */
  2006. X    if (first) {
  2007. X        first = 0;
  2008. X        nfds = getdtablesize();
  2009. X        fdmap = (UWIN *)malloc((unsigned)(sizeof(UWIN)*nfds));
  2010. X        if (fdmap != (UWIN *)0)
  2011. X            for (i = 0; i < nfds; i++)
  2012. X                fdmap[i] = (UWIN)0;
  2013. X        oldsigio = signal(SIGIO, uw_optinput);
  2014. X        FD_ZERO(&fdmask);
  2015. X    }
  2016. X
  2017. X    /*
  2018. X     * Add the new control fd to the map and mask.  Set the owner
  2019. X     * to this process
  2020. X     */
  2021. X    if (fd >= 0 && fd < nfds && uwin != (UWIN)0 && fdmap != (UWIN *)0) {
  2022. X        fdmap[fd] = uwin;
  2023. X        FD_SET(fd, &fdmask);
  2024. X#ifdef SETOWN_BUG
  2025. X        (void)fcntl(fd, F_SETOWN, -getpid());
  2026. X#else
  2027. X        (void)fcntl(fd, F_SETOWN, getpid());
  2028. X#endif
  2029. X        if ((flags = fcntl(fd, F_GETFL, 0)) >= 0)
  2030. X            (void)fcntl(fd, F_SETFL, flags|FASYNC|FNDELAY);
  2031. X        uwin->uwi_ipclen = 0;
  2032. X    }
  2033. X}
  2034. X
  2035. Xuw_optdone(fd)
  2036. X{
  2037. X    register int flags;
  2038. X
  2039. X    /*
  2040. X     * Turn off asynchronous I/O notification and remove the
  2041. X     * map and mask information for "fd".  We do not close the
  2042. X     * file descriptor, however -- the caller is expected to
  2043. X     * take care of that.
  2044. X     */
  2045. X    if (fd >= 0 && fd < nfds && fdmap != (UWIN *)0) {
  2046. X        if ((flags = fcntl(fd, F_GETFL, 0)) >= 0)
  2047. X            (void)fcntl(fd, F_SETFL, flags&~FASYNC);
  2048. X        else
  2049. X            (void)fcntl(fd, F_SETFL, 0);
  2050. X        (void)fcntl(fd, F_SETFL, 0);
  2051. X        fdmap[fd] = (UWIN)0;
  2052. X        FD_CLR(fd, &fdmask);
  2053. X    }
  2054. X}
  2055. X
  2056. Xstatic
  2057. Xuw_optinput(sig, code, scp)
  2058. Xint sig, code;
  2059. Xstruct sigcontext *scp;
  2060. X{
  2061. X    register int k, n, fd;
  2062. X    register UWIN uwin;
  2063. X    register struct uwoption *uwop;
  2064. X    register union uwoptval *uwov;
  2065. X    uwopt_t optnum;
  2066. X    uwoptcmd_t optcmd;
  2067. X    uwfnptr_t userfn;
  2068. X    int oldmask;
  2069. X    struct timeval timeo;
  2070. X    struct fd_set ready;
  2071. X    extern int errno;
  2072. X
  2073. X    /*
  2074. X     * This routine is called when input is waiting on a control
  2075. X     * file descriptor.
  2076. X     */
  2077. X    oldmask = sigblock(sigmask(SIGALRM));
  2078. X    do {
  2079. X        ready = fdmask;
  2080. X        timeo.tv_sec = 0;
  2081. X        timeo.tv_usec = 0;
  2082. X        n = select(nfds, &ready, (struct fd_set *)0,
  2083. X               (struct fd_set *)0, &timeo);
  2084. X        if (n < 0 && errno == EBADF) {
  2085. X            /*
  2086. X             * One of the file descriptors that we asked for
  2087. X             * is no longer valid.  This isn't supposed to
  2088. X             * happen; however, we try to handle it by testing
  2089. X             * each bit individually and eliminating the bad
  2090. X             * ones.
  2091. X             */
  2092. X            for (fd=0; fd < nfds; fd++) {
  2093. X                if (FD_ISSET(fd, &fdmask)) {
  2094. X                    do {
  2095. X                        ready = fdmask;
  2096. X                        timeo.tv_sec = 0;
  2097. X                        timeo.tv_usec = 0;
  2098. X                        k = select(nfds, &ready,
  2099. X                            (struct fd_set *)0,
  2100. X                            (struct fd_set *)0, &timeo);
  2101. X                        if (k < 0 && errno == EBADF) {
  2102. X                            fdmap[fd] = (UWIN)0;
  2103. X                            FD_CLR(fd, &fdmask);
  2104. X                        }
  2105. X                    } while (n < 0 && errno == EINTR);
  2106. X                }
  2107. X            }
  2108. X        }
  2109. X    } while (n < 0 && errno == EINTR);
  2110. X
  2111. X    for (fd=0; n > 0 && fd < nfds; fd++) {
  2112. X        if (FD_ISSET(fd, &ready)) {
  2113. X            n--;
  2114. X            uwin = fdmap[fd];
  2115. X            while ((k = getmesg(fd, uwin)) > 0) {
  2116. X                uwin->uwi_ipclen = 0;    /* for next time */
  2117. X                if (uwin->uwi_ipcbuf.uwip_cmd == UWC_OPTION) {
  2118. X                    uwop = &uwin->uwi_ipcbuf.uwip_option;
  2119. X                    uwov = &uwop->uwop_val;
  2120. X                    optnum = ntohs(uwop->uwop_opt);
  2121. X                    optcmd = ntohs(uwop->uwop_cmd);
  2122. X                    if (optcmd == UWOC_SET)
  2123. X                        uw_ntoh(uwin->uwi_type, optnum,
  2124. X                            (char *)uwov);
  2125. X                    if (optcmd == UWOC_SET) switch(optnum) {
  2126. X                    case UWOP_VIS:
  2127. X                        uwin->uwi_vis = !!uwov->uwov_6bit;
  2128. X                        break;
  2129. X                    case UWOP_TYPE:
  2130. X                        if (uwov->uwov_6bit<UW_NWTYPES)
  2131. X                            uwin->uwi_type=uwov->uwov_6bit;
  2132. X                        break;
  2133. X                    case UWOP_POS:
  2134. X                        uwin->uwi_pos.uwp_v = uwov->uwov_point.v;
  2135. X                        uwin->uwi_pos.uwp_h = uwov->uwov_point.h;
  2136. X                        break;
  2137. X                    case UWOP_TITLE:
  2138. X                        (void)strncpy(uwin->uwi_title,
  2139. X                            uwov->uwov_string,
  2140. X                            sizeof uwin->uwi_title);
  2141. X                        break;
  2142. X                    case UWOP_WSIZE:
  2143. X                        uwin->uwi_wsize.uwp_v = uwov->uwov_point.v;
  2144. X                        uwin->uwi_wsize.uwp_h = uwov->uwov_point.h;
  2145. X                        break;
  2146. X                    }
  2147. X                    if (optnum == UWOP_TYPE &&
  2148. X                        optcmd == UWOC_SET &&
  2149. X                        uwov->uwov_6bit < UW_NWTYPES)
  2150. X                        uwin->uwi_type=uwov->uwov_6bit;
  2151. X                    userfn = uwin->uwi_options[optnum].uwi_optfn;
  2152. X                    if (userfn != (uwfnptr_t)0)
  2153. X                        (*userfn)(uwin, optnum,
  2154. X                              optcmd, uwov);
  2155. X                }
  2156. X            }
  2157. X            if (k < 0)
  2158. X                (void)uw_detach(uwin);    /* I/O error or EOF */
  2159. X        }
  2160. X    }
  2161. X    (void)sigsetmask(oldmask);
  2162. X
  2163. X    /*
  2164. X     * Finally, if "oldsigio" is not SIG_DFL, call it.
  2165. X     */
  2166. X    if (oldsigio != SIG_DFL)
  2167. X        (*oldsigio)(sig, code, scp);
  2168. X}
  2169. X
  2170. Xstatic
  2171. Xgetmesg(fd, uwin)
  2172. Xregister int fd;
  2173. Xregister UWIN uwin;
  2174. X{
  2175. X    register int len;
  2176. X    register char *cp;
  2177. X
  2178. X    /*
  2179. X     * Read some more bytes from control socket "fd" into the input
  2180. X     * buffer.  Return 1 if the message is now complete, -1 if an
  2181. X     * EOF was reached, or 0 otherwise.  Before returning 1, the byte
  2182. X     * order of the common parameters (command, length) is changed
  2183. X     * from network to host order.
  2184. X     */
  2185. X    cp = (char *)&uwin->uwi_ipcbuf + uwin->uwi_ipclen;
  2186. X    if (uwin->uwi_ipclen < sizeof(uwin->uwi_ipcbuf.uwip_len)) {
  2187. X        len = read(fd, cp, sizeof uwin->uwi_ipcbuf.uwip_len - uwin->uwi_ipclen);
  2188. X        if (len == 0 || (len < 0 && errno != EWOULDBLOCK))
  2189. X            return(-1);
  2190. X        if (len < 0)
  2191. X            return(0);
  2192. X        if ((uwin->uwi_ipclen +=len) < sizeof uwin->uwi_ipcbuf.uwip_len)
  2193. X            return(0);
  2194. X        uwin->uwi_ipcbuf.uwip_len = ntohs(uwin->uwi_ipcbuf.uwip_len);
  2195. X        if (uwin->uwi_ipcbuf.uwip_len==sizeof uwin->uwi_ipcbuf.uwip_len)
  2196. X            return(1);
  2197. X        cp += len;
  2198. X    }
  2199. X    if (uwin->uwi_ipcbuf.uwip_len > sizeof(struct uwipc))
  2200. X        uwin->uwi_ipcbuf.uwip_len = sizeof(struct uwipc);
  2201. X    len = read(fd, cp, uwin->uwi_ipcbuf.uwip_len - uwin->uwi_ipclen);
  2202. X    if (len == 0 || (len < 0 && errno != EWOULDBLOCK))
  2203. X        return(-1);
  2204. X    if ((uwin->uwi_ipclen += len) == uwin->uwi_ipcbuf.uwip_len) {
  2205. X        uwin->uwi_ipcbuf.uwip_cmd = ntohs(uwin->uwi_ipcbuf.uwip_cmd);
  2206. X        return(1);
  2207. X    } else
  2208. X        return(0);
  2209. X}
  2210. !EOF!lib/uw_options.c!
  2211. echo x - lib/uw_perror.c
  2212. sed -e 's/^X//' > lib/uw_perror.c << '!EOF!lib/uw_perror.c!'
  2213. X/*
  2214. X *    uw library - uw_perror
  2215. X *
  2216. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  2217. X * copy this program is given provided that the copy is not sold and that
  2218. X * this copyright notice is included.
  2219. X */
  2220. X#include "uwlib.h"
  2221. X
  2222. Xchar *uwerrlist[] = {
  2223. X    "no error",
  2224. X    "system call error",
  2225. X    "nonexistent window type",
  2226. X    "window ID duplicated (in use)",
  2227. X    "operation not implemented",
  2228. X    "non-existent server",
  2229. X    "unable to allocate required memory",
  2230. X    "invalid argument to function",
  2231. X    "no control file descriptor for window",
  2232. X};
  2233. Xunsigned uwnerr = sizeof uwerrlist / sizeof uwerrlist[0];
  2234. X
  2235. Xint uwerrno;
  2236. X
  2237. X/*ARGSUSED*/
  2238. Xvoid
  2239. Xuw_perror(mesg, uwerr, errno)
  2240. Xchar *mesg;
  2241. Xuwerr_t uwerr;
  2242. Xint errno;
  2243. X{
  2244. X    register char *errmsg;
  2245. X
  2246. X    /*
  2247. X     * Print a UW error message.  We call write() directly to avoid
  2248. X     * making the UW library dependent upon stdio.
  2249. X     */
  2250. X    if (uwerr == UWE_ERRNO) {
  2251. X        perror(mesg);
  2252. X    } else {
  2253. X        if (mesg != (char *)0) {
  2254. X            (void)write(2, mesg, strlen(mesg));
  2255. X            (void)write(2, ": ", 2);
  2256. X        }
  2257. X        if (uwerr >= uwnerr)
  2258. X            errmsg = "unknown UW error";
  2259. X        else
  2260. X            errmsg = uwerrlist[uwerr];
  2261. X        (void)write(2, errmsg, strlen(errmsg));
  2262. X        (void)write(2, "\n", 1);
  2263. X    }
  2264. X}
  2265. !EOF!lib/uw_perror.c!
  2266. echo x - lib/uw_rsetopt.c
  2267. sed -e 's/^X//' > lib/uw_rsetopt.c << '!EOF!lib/uw_rsetopt.c!'
  2268. X/*
  2269. X *    uw library - uw_rsetopt
  2270. X *
  2271. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  2272. X * copy this program is given provided that the copy is not sold and that
  2273. X * this copyright notice is included.
  2274. X */
  2275. X#include <sys/types.h>
  2276. X#include <sys/socket.h>
  2277. X#include <sys/un.h>
  2278. X#include <sys/ioctl.h>
  2279. X#include <sys/uio.h>
  2280. X#include <sys/file.h>
  2281. X#include <strings.h>
  2282. X#include <signal.h>
  2283. X#include "openpty.h"
  2284. X
  2285. X#include "uwlib.h"
  2286. X
  2287. Xextern char *malloc();
  2288. Xextern char *getenv();
  2289. X
  2290. Xuw_rsetopt(uwid, optnum, optval)
  2291. Xuwid_t uwid;
  2292. Xuwopt_t optnum;
  2293. Xunion uwoptval *optval;
  2294. X{
  2295. X    register int sd;
  2296. X    register struct uwipc *uwip;
  2297. X    char *portal;
  2298. X    struct iovec iov;
  2299. X    struct msghdr msg;
  2300. X    struct sockaddr_un sa;
  2301. X
  2302. X    /*
  2303. X     * Set a window option on a remote window (that is, one for which
  2304. X     * we do not have a control fd).
  2305. X     */
  2306. X
  2307. X    /*
  2308. X     * Create a UNIX-domain socket.
  2309. X     */
  2310. X    if (!(portal=getenv("UW_UIPC"))) {
  2311. X        uwerrno = UWE_NXSERV;
  2312. X        return(-1);
  2313. X    }
  2314. X
  2315. X    if ((sd=socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
  2316. X        uwerrno = UWE_ERRNO;
  2317. X        return(-1);
  2318. X    }
  2319. X    sa.sun_family = AF_UNIX;
  2320. X    (void)strncpy(sa.sun_path, portal, sizeof sa.sun_path-1);
  2321. X    sa.sun_path[sizeof sa.sun_path-1] = '\0';
  2322. X
  2323. X
  2324. X    /*
  2325. X     * Construct the datagram we will send later.
  2326. X     */
  2327. X    uwip = (struct uwipc *)malloc(sizeof(struct uwipc));
  2328. X    if (uwip == (struct uwipc *)0) {
  2329. X        uwerrno = UWE_NOMEM;
  2330. X        return(-1);
  2331. X    }
  2332. X    uwip->uwip_cmd = UWC_OPTION;
  2333. X    uwip->uwip_len = sizeof(struct uwipc);
  2334. X    uwip->uwip_option.uwop_id = uwid;
  2335. X    uwip->uwip_option.uwop_cmd = UWOC_SET;
  2336. X    uwip->uwip_option.uwop_opt = optnum;
  2337. X    uwip->uwip_option.uwop_val = *optval;
  2338. X
  2339. X    /*
  2340. X     * Pass the file descriptor to the window server.
  2341. X     */
  2342. X    iov.iov_base = (char *)uwip;
  2343. X    iov.iov_len = uwip->uwip_len;
  2344. X    msg.msg_name = (caddr_t)&sa;
  2345. X    msg.msg_namelen = sizeof sa.sun_family + strlen(sa.sun_path);
  2346. X    msg.msg_iov = &iov;
  2347. X    msg.msg_iovlen = 1;
  2348. X    msg.msg_accrights = (caddr_t)0;
  2349. X    msg.msg_accrightslen = 0;
  2350. X    if (sendmsg(sd, &msg, 0) < 0) {
  2351. X        free((char *)uwip);
  2352. X        uwerrno = UWE_ERRNO;
  2353. X        return(-1);
  2354. X    }
  2355. X    free((char *)uwip);
  2356. X    uwerrno = UWE_NONE;
  2357. X    return(0);
  2358. X}
  2359. !EOF!lib/uw_rsetopt.c!
  2360. echo x - lib/uw_shell.c
  2361. sed -e 's/^X//' > lib/uw_shell.c << '!EOF!lib/uw_shell.c!'
  2362. X/*
  2363. X *    uw library - uw_shell
  2364. X *
  2365. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  2366. X * copy this program is given provided that the copy is not sold and that
  2367. X * this copyright notice is included.
  2368. X */
  2369. X#include "uwlib.h"
  2370. X
  2371. Xchar *uwshellname = "/bin/sh";    /* can be patched by caller if desired */
  2372. X
  2373. Xuwid_t
  2374. Xuw_shell(wtype, cmd)
  2375. Xuwtype_t wtype;
  2376. Xchar *cmd;
  2377. X{
  2378. X    register uwid_t uwid;
  2379. X
  2380. X    /*
  2381. X     * Create a new window (using uw_fork()) and execute the specified
  2382. X     * shell command in it.  Returns the window ID of the new window
  2383. X     * (or -1 if the window creation failed)  There is no way to
  2384. X     * determine if the executed command failed.
  2385. X     */
  2386. X    if ((uwid = uw_fork(wtype, (int *)0)) == 0) {
  2387. X        (void)execl(uwshellname, uwshellname, "-c", cmd, (char *)0);
  2388. X        _exit(1);    /* we'd better not reach this point */
  2389. X        /*NOTREACHED*/
  2390. X    } else
  2391. X        return(uwid);
  2392. X}
  2393. !EOF!lib/uw_shell.c!
  2394. echo x - lib/uw_ttype.c
  2395. sed -e 's/^X//' > lib/uw_ttype.c << '!EOF!lib/uw_ttype.c!'
  2396. X/*
  2397. X *    uw library - uw_ttype
  2398. X *
  2399. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  2400. X * copy this program is given provided that the copy is not sold and that
  2401. X * this copyright notice is included.
  2402. X */
  2403. X#include <strings.h>
  2404. X#include "uwlib.h"
  2405. X
  2406. Xstruct table {
  2407. X    char        *tname;
  2408. X    uwtype_t    wtype;
  2409. X};
  2410. X
  2411. X/* The following table must be sorted */
  2412. Xstatic struct table table[] = {
  2413. X    { "aaa-24", UWT_ANSI },
  2414. X    { "adm3", UWT_ADM31 },
  2415. X    { "adm31", UWT_ADM31 },
  2416. X    { "adm3a", UWT_ADM31 },
  2417. X    { "ansi", UWT_ANSI },
  2418. X    { "tek", UWT_TEK4010 },
  2419. X    { "tek4010", UWT_TEK4010 },
  2420. X    { "tek4012", UWT_TEK4010 },
  2421. X    { "vt52", UWT_VT52 },
  2422. X};
  2423. X
  2424. Xuwtype_t
  2425. Xuw_ttype(name)
  2426. Xchar *name;
  2427. X{
  2428. X    register struct table *t, *lo, *hi;
  2429. X    register int cmp;
  2430. X
  2431. X    /*
  2432. X     * Map a terminal name string to a UW window emulation type.
  2433. X     */
  2434. X    lo = table;
  2435. X    hi = table + sizeof table / sizeof table[0] - 1;
  2436. X    while (lo <= hi) {
  2437. X        t = lo + (hi-lo) / 2;
  2438. X        cmp = strcmp(name, t->tname);
  2439. X        if (cmp == 0)
  2440. X            return(t->wtype);
  2441. X        if (cmp < 0)
  2442. X            hi = t-1;
  2443. X        else
  2444. X            lo = t+1;
  2445. X    }
  2446. X    return(UWT_ADM31);    /* default if no match */
  2447. X}
  2448. !EOF!lib/uw_ttype.c!
  2449. exit 0
  2450. : end of shell archive
  2451.