home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2373 < prev    next >
Internet Message Format  |  1990-12-28  |  45KB

  1. From: pgd@bbt.se
  2. Newsgroups: alt.sources
  3. Subject: socket-emulation - socket emulation library for xenix (SYSV)
  4. Message-ID: <1990Dec19.195904.11476@bbt.se>
  5. Date: 19 Dec 90 19:59:04 GMT
  6.  
  7. Here is a hack I made, when I was tired of always missing those
  8. sockets. It is only tested on a few programs, and not deeply either.
  9. Prerequsites are UNIX SYSV, named pipes and file locks.
  10. Xenix and gcc helps. 
  11.  
  12. #!/bin/sh
  13. # This is socket-emulation, a shell archive (shar 3.32)
  14. # made 12/19/1990 19:56 UTC by pgd@compuram.bbt.se
  15. #
  16. # existing files WILL be overwritten
  17. #
  18. # This shar contains:
  19. # length  mode       name
  20. # ------ ---------- ------------------------------------------
  21. #   4223 -rw-rw---- README
  22. #   3259 -rw-rw---- accept.c
  23. #   1934 -rw-rw---- bind.c
  24. #   3270 -rw-rw---- connect.c
  25. #    909 -rw-rw---- hostbyaddr.c
  26. #    898 -rw-rw---- hostbyname.c
  27. #    643 -rw-rw---- getpeername.c
  28. #    621 -rw-rw---- getsockname.c
  29. #    995 -rw-rw---- getsockopt.c
  30. #    428 -rw-rw---- listen.c
  31. #    923 -rw-rw---- setsockopt.c
  32. #   3109 -rw-rw---- socket.c
  33. #   1427 -rw-rw---- soclose.c
  34. #    874 -rw-rw---- soread.c
  35. #    483 -rw-rw---- sowrite.c
  36. #   1211 -rw-rw---- soioctl.c
  37. #   2664 -rw-rw---- netdb.h
  38. #   4578 -rw--w---- socket.h
  39. #   2068 -rw--w---- socketvar.h
  40. #   1030 -rw-rw---- Makefile
  41. #
  42. if touch 2>&1 | fgrep 'amc' > /dev/null
  43.  then TOUCH=touch
  44.  else TOUCH=true
  45. fi
  46. # ============= README ==============
  47. echo "x - extracting README (Text)"
  48. sed 's/^X//' << 'SHAR_EOF' > README &&
  49. X          Socket Emulation Library for SYSV
  50. X          ---------------------------------
  51. X
  52. XThis library emulates the BSD sockets with SYSV named pipes. It is
  53. Xmeant as a drop-in for those who have no sockets, but still want to
  54. Xuse programs using sockets. In particular, it was developed to get
  55. XX-windows working on xenix without any networking (or streams).
  56. X
  57. XWARNING:
  58. X--------
  59. XThe whole package is a fast hack. Don't expect any miracles. I have no
  60. Xaccess to an UNIX system with real pipes, and don't even have manual
  61. Xpages for the functions, so the implementation is just an educated
  62. Xguess. The functions might return the wrong error codes on failures,
  63. Xetc. If you figure out something wrong, i am happy to hear about it.
  64. XCurrently it is only working on a XENIX/386 2.3.2 system with gcc.
  65. X
  66. X
  67. XINSTALLATION:
  68. X-------------
  69. XIf you have are running Xenix 2.3.2, and have gcc, you can just put
  70. Xeverything in a directory, and type make. Gcc will give some warnings,
  71. Xthat is allright, but the compilation should proceed nicely, and it
  72. Xwill stop with the libsocket.a library ready.
  73. XI put socket.h in /usr/include/sys, netdb.h in /usr/include, and
  74. XSlibsocket.a in /lib/386. If you like that, you can just do a "make
  75. Xinstall", as root. Otherwise you have to install manually.
  76. X
  77. XIf you don't have Xenix or gcc, it will probably not compile so
  78. Xeasily.  Be prepared to do some hacking to get it going. I would
  79. Xrecommend to start trying on something less than X-windows, unless you
  80. Xreally like extra trouble.
  81. X
  82. X
  83. XDESCRIPTION:
  84. X------------
  85. XEach socket is implemented as a pipe (fifo) in the /tmp directory. The
  86. Xnames are generated uniquely, and have no significance outside the
  87. Xsocket library. This pipe is the control channel. It is only read on,
  88. Xnever written on by the socket creator.
  89. X
  90. XWhen you bind a name to the socket, a link is created to that pipe,
  91. Xwith a name according to the bound name. The client program can later
  92. Xconnect to that socket, and the communication channel is created as
  93. Xtwo more pipes (with unique names) in the /tmp directory. Two pipes
  94. Xare needed since sockets are bi-directional, but pipes only
  95. Xuni-directional. The hand-shaking between the two processes go through
  96. Xthe respective control pipes, created by the socket() call.
  97. X
  98. XAll in all, each socket connection uses 4 pipes. One each as control
  99. Xchannels for the sockets (in the two processes), and one each for the
  100. Xdata transfer.
  101. X
  102. XThe file descriptor returned by the socket() call, is connected to the
  103. Xread channel, when the connection is established. But you should avoid
  104. Xusing any i/o calls on that file descriptor directly. The read(),
  105. Xwrite(), ioctl(), and close() procedures are defined as macros in the
  106. Xsocket.h file, and are redirected to the procedures soread(),
  107. Xsowrite(), soioctl() and soclose(). If the i/o is going to a socket
  108. Xfile descriptor, those procedures takes care of redirecting the
  109. Xfunction to the correct i/o channel, otherwise they just to the same
  110. Xthing as their normal counterparts.
  111. X
  112. XThis means that in every c-file where you do a read(), write(),
  113. Xioctl() or close() on a file, which is a socket, you have to include
  114. Xsocket.h. This is normally always the case anyway.
  115. X
  116. XOnly two address families are defined AF_UNIX and AF_INET. Inet
  117. Xsockets all go to the same machine.
  118. X
  119. XDIFFERENCES:
  120. X------------
  121. XThere is no <netinet/in.h> file. The definitions in that file is
  122. Xincluded in socket.h, so you can normally just comment out any
  123. Xreferences to it. The same for un.h
  124. XThere is a symbol SOCKET_EMULATION defined by socket.h, that can be
  125. Xused for conditional compilation in the c files.
  126. XThe error numbers are completely different from the BSD ones.
  127. X
  128. X
  129. XBUGS:
  130. X-----
  131. Xselect() should be trapped also. as it is now, select() on writes
  132. Xdoes not work.
  133. X
  134. X
  135. XCOPYRIGHTS:
  136. X----------- 
  137. XCopyright on a hack? Are you kidding?  Some parts were snatched from
  138. Xthe BSD tahoe distribution. Maybe their copyright should be somewhere.
  139. XI guess a warning is enough. But as all source is very heavily munged,
  140. Xi figured it is so different, so that there is hardly any similarity.
  141. XTry grepping on the comments. Maybe one, or two, are left from the bsd
  142. Xfiles. 
  143. X
  144. XMY ADDRESS:
  145. X-----------
  146. XI would be happy to hear some feedback about problems. My e-mail
  147. Xaddress is: pgd@compuram.bbt.se
  148. X
  149. X
  150. XP.Garbha
  151. SHAR_EOF
  152. $TOUCH -am 1219204390 README &&
  153. chmod 0660 README ||
  154. echo "restore of README failed"
  155. set `wc -c README`;Wc_c=$1
  156. if test "$Wc_c" != "4223"; then
  157.     echo original size 4223, current size $Wc_c
  158. fi
  159. # ============= accept.c ==============
  160. echo "x - extracting accept.c (Text)"
  161. sed 's/^X//' << 'SHAR_EOF' > accept.c &&
  162. X#include <stdio.h>
  163. X#include <string.h>
  164. X#include <sys/types.h>
  165. X#include <sys/param.h>
  166. X#include <sys/stat.h>
  167. X#include <sys/fcntl.h>
  168. X#include <memory.h>
  169. X#include <malloc.h>
  170. X#include <errno.h>
  171. X#include <prototypes.h>
  172. X#include "socket.h"
  173. X#include "socketvar.h"
  174. X
  175. Xstatic int doconnect(struct socket *so);
  176. Xstatic struct socket_packet msg;
  177. X
  178. Xint
  179. Xaccept(int s, struct sockaddr *name, int *anamelen)
  180. X{
  181. X    register struct socket *so;
  182. X    int cc, fd, e;
  183. X
  184. X    if ((so = GETSOCKET(s)) == NULL)
  185. X        return -1;
  186. X    if ((so->so_options & SO_ACCEPTCONN) == 0) {
  187. X        errno = EINVAL;
  188. X        return -1;
  189. X    }
  190. X    /*
  191. X     * Read a packet from the pipe
  192. X     */
  193. X    cc = read(so->so_fd, (char *)&msg, sizeof(msg));
  194. X    if (cc == 0 && so->so_state & SS_NBIO) {
  195. X        errno = EWOULDBLOCK;
  196. X        return -1;
  197. X    }
  198. X    if (cc == -1)
  199. X        return -1;
  200. X    if (msg.scm_magic != SOCKET_MAGIC) {
  201. X        /* Garbage block. Do nothing */
  202. X        errno = EIO;
  203. X        return -1;
  204. X    }
  205. X
  206. X    /*
  207. X     * Dispatch on packet type
  208. X     */
  209. X    switch (msg.scm_msg) {
  210. X    case MSG_CONNECT:
  211. X        if ((fd = doconnect(so)) != -1) {
  212. X            so = GETSOCKET(fd);
  213. X            *anamelen = SOCKADDRLEN(so->so_conn);
  214. X            memcpy((char *)name, (char *)so->so_conn, *anamelen);
  215. X            return fd;
  216. X        }
  217. X    case MSG_DISCONNECT:
  218. X        e = _sodisconnect2(so);
  219. X        errno = ECONNABORTED;
  220. X        return -1;
  221. X
  222. X    default:
  223. X        errno = EOPNOTSUPP;
  224. X        return -1;
  225. X    }
  226. X}
  227. X
  228. X    
  229. Xstatic int
  230. Xdoconnect(register struct socket *so)
  231. X{
  232. X    register struct socket *so2;
  233. X    int rfd, wfd, sofd, pfd;
  234. X    char twname[20], trname[20];
  235. X    int peersotype;
  236. X    int cc;
  237. X
  238. X    /*
  239. X     * Open up our side of the socket files.
  240. X     * Note that read and write sides are swapped.
  241. X     *
  242. X     */
  243. X    sprintf(twname, "/tmp/%s", msg.scm_wname);
  244. X    if ((rfd = open(twname, O_RDWR)) == -1)
  245. X        return -1;
  246. X    fcntl(rfd, F_SETFD, O_RDONLY);
  247. X    sprintf(trname, "/tmp/%s", msg.scm_rname);
  248. X    if ((wfd = open(trname, O_RDWR)) == -1) {
  249. X        close(rfd);
  250. X        return -1;
  251. X    }
  252. X    fcntl(wfd, F_SETFD, O_WRONLY);
  253. X    if ((pfd = open(msg.scm_addr.un.sun_path, O_RDWR)) == -1) {
  254. X        close(rfd); close(wfd);
  255. X        return -1;
  256. X    }
  257. X
  258. X    /*
  259. X     * Connection established. Pass back
  260. X     * our message.
  261. X     */
  262. X    msg.scm_magic = SOCKET_MAGIC;
  263. X    peersotype = msg.scm_type;
  264. X    msg.scm_type = so->so_type;
  265. X    msg.scm_msg = peersotype == so->so_type ? MSG_CONNECT_OK : MSG_FAIL;
  266. X    memcpy((char *)&msg.scm_addr, (char *)so->so_addr, SOCKADDRLEN(so->so_addr));
  267. X    cc = write(pfd, (char *)&msg, sizeof msg);
  268. X    if (cc == -1)
  269. X        goto bad;
  270. X    if (cc != sizeof msg) {
  271. X        errno = EIO;
  272. X        goto bad;
  273. X    }
  274. X    if (peersotype != so->so_type) {
  275. X        errno = EPROTOTYPE;
  276. X        goto bad;
  277. X    }
  278. X
  279. X    if ((sofd = socket(so->so_domain, so->so_type, so->so_protocol)) == -1)
  280. X        goto bad;
  281. X    /*
  282. X     * Juggle around the file descriptors so that the socket
  283. X     * fd refers to the read pipe.
  284. X     */
  285. X    so2 = GETSOCKET(sofd);
  286. X    sofd = dup(so->so_fd);
  287. X    if (sofd == -1) {
  288. X        soclose(sofd);
  289. X        goto bad;
  290. X    }
  291. X    rfd = dup2(rfd, so2->so_fd);
  292. X    if (rfd == -1) {
  293. X        close(sofd);
  294. X        soclose(sofd);
  295. X        goto bad;
  296. X    }
  297. X    so2->so_fd = sofd;
  298. X    so2->so_rfd = rfd;
  299. X    so2->so_wfd = wfd;
  300. X    so2->so_pfd = pfd;
  301. X    so2->so_addr = NULL;
  302. X    so2->so_conn = (struct sockaddr *)malloc(SOCKADDRLEN(so->so_addr));
  303. X    memcpy((char *)so2->so_conn, (char *)&msg.scm_addr, SOCKADDRLEN(so->so_addr));
  304. X    so2->so_rname = strdup(msg.scm_wname);
  305. X    so2->so_wname = strdup(msg.scm_rname);
  306. X    so2->so_state |= SS_ISCONNECTED;
  307. X    return rfd;
  308. X
  309. Xbad:
  310. X    close(rfd); close(wfd); close(pfd);
  311. X    unlink(trname); unlink (twname);
  312. X    return -1;
  313. X}
  314. X
  315. X
  316. SHAR_EOF
  317. $TOUCH -am 1215095190 accept.c &&
  318. chmod 0660 accept.c ||
  319. echo "restore of accept.c failed"
  320. set `wc -c accept.c`;Wc_c=$1
  321. if test "$Wc_c" != "3259"; then
  322.     echo original size 3259, current size $Wc_c
  323. fi
  324. # ============= bind.c ==============
  325. echo "x - extracting bind.c (Text)"
  326. sed 's/^X//' << 'SHAR_EOF' > bind.c &&
  327. X#include <stdio.h>
  328. X#include <string.h>
  329. X#include <sys/types.h>
  330. X#include <sys/stat.h>
  331. X#include <memory.h>
  332. X#include <sys/errno.h>
  333. X#include <prototypes.h>
  334. X#include <errno.h>
  335. X#include <sys/fcntl.h>
  336. X#include "socket.h"
  337. X#include "socketvar.h"
  338. X
  339. X/*
  340. X * Bind an address to an already defined socket.
  341. X * AF_UNIX sockets can be located anywhere in the file
  342. X * structure. The file according to the pathname is linked to
  343. X * the socket pipe created by socket().
  344. X * AF_INET sockets are simulated by a file in the /usr/spool/socket
  345. X * directory, unique according to the socket number
  346. X * AF_UNSPEC sockets use the original pipe created by socket().
  347. X */
  348. Xint
  349. Xbind(int sofd, struct sockaddr *name, int namelen)
  350. X{
  351. X    register struct socket *so;
  352. X    char *path;
  353. X    int fd, e;
  354. X
  355. X    if ((so = GETSOCKET(sofd)) == NULL)
  356. X        return -1;
  357. X    if (so->so_state & SS_ISCONNECTED) {
  358. X        errno = EADDRINUSE;
  359. X        return -1;
  360. X    }
  361. X    if (so->so_domain != name->sa_family) {
  362. X        errno = EPROTOTYPE;
  363. X        return -1;
  364. X    }
  365. X    if (so->so_addr != NULL) {
  366. X        errno = EADDRINUSE;
  367. X        return -1;
  368. X    }
  369. X    /*
  370. X     * Create a link to the socket according to the
  371. X     * address given.
  372. X     */
  373. X    if (name->sa_family != AF_UNSPEC) {
  374. X        path = _socketname(name);
  375. X        if (path == NULL) {
  376. X            errno = EOPNOTSUPP;
  377. X            return -1;
  378. X        }
  379. X        if (link(so->so_name, path) == -1) {
  380. X            if (errno != EEXIST)
  381. X                return -1;
  382. X            /*
  383. X             * Socket address exists. Check if it is bound
  384. X             * to an active socket, or just "left around"
  385. X             */
  386. X            fd = open(path, O_RDWR);
  387. X            if (fd == -1)
  388. X                return -1;
  389. X            e = _checksolock(fd, 0);
  390. X            if (e == -1) {
  391. X                close(fd);
  392. X                return -1;
  393. X            }
  394. X            if (e) {
  395. X                errno = EADDRINUSE;
  396. X                close(fd);
  397. X                return -1;
  398. X            }
  399. X            /*
  400. X             * The socked file is free. Delete it, and
  401. X             * try the bind it to the socket again.
  402. X             */
  403. X            close(fd);
  404. X            unlink(path);
  405. X            if (link(so->so_name, path) == -1)
  406. X                return -1;
  407. X        }
  408. X    }
  409. X    so->so_addr = (struct sockaddr *)malloc(namelen);
  410. X    memcpy((char *)so->so_addr, (char *)name, namelen);
  411. X    return 0;
  412. X}
  413. SHAR_EOF
  414. $TOUCH -am 1215055390 bind.c &&
  415. chmod 0660 bind.c ||
  416. echo "restore of bind.c failed"
  417. set `wc -c bind.c`;Wc_c=$1
  418. if test "$Wc_c" != "1934"; then
  419.     echo original size 1934, current size $Wc_c
  420. fi
  421. # ============= connect.c ==============
  422. echo "x - extracting connect.c (Text)"
  423. sed 's/^X//' << 'SHAR_EOF' > connect.c &&
  424. X#include <stdio.h>
  425. X#include <string.h>
  426. X#include <sys/types.h>
  427. X#include <sys/stat.h>
  428. X#include <memory.h>
  429. X#include <sys/fcntl.h>
  430. X#include <errno.h>
  431. X#include <prototypes.h>
  432. X#include "socket.h"
  433. X#include "socketvar.h"
  434. X
  435. Xstatic int seq = 1;
  436. X
  437. Xint
  438. Xconnect(int s, struct sockaddr *name, int namelen)
  439. X{
  440. X    register struct socket *so;
  441. X    int pid, cc;
  442. X    char rname[15], wname[15], trname[20], twname[20];
  443. X    int rfd, wfd;
  444. X    struct socket_packet msg;
  445. X    char *path;
  446. X    int pfd, sofd;
  447. X
  448. X    if ((so = GETSOCKET(s)) == NULL)
  449. X        return -1;
  450. X    if (so->so_options & SO_ACCEPTCONN) {
  451. X        errno = EOPNOTSUPP;
  452. X        return -1;
  453. X    }
  454. X    /*
  455. X     * Can connect only once, otherwise, try to disconnect first.
  456. X     * This allows user to disconnect by connecting to, e.g.,
  457. X     * a null address.
  458. X     */
  459. X    if (so->so_state & SS_ISCONNECTED) {
  460. X        if (_sodisconnect(so) < 0) {
  461. X            errno = EISCONN;
  462. X            return -1;
  463. X        }
  464. X    }
  465. X
  466. X    /*
  467. X     * Now find socket to connect to, 
  468. X     */
  469. X    path = _socketname(name);
  470. X    if (path == NULL) {
  471. X        errno = EOPNOTSUPP;
  472. X        return -1;
  473. X    }
  474. X    if ((pfd = open(path, O_RDWR)) == -1)
  475. X        return -1;
  476. X    fcntl(rfd, F_SETFD, O_WRONLY);
  477. X
  478. X    /*
  479. X     * Check if other side is listening
  480. X     */
  481. X    if (_checksolock(pfd, SO_ACCEPTCONN) == -1) {
  482. X        errno = ENOTCONN;
  483. X        close(pfd);
  484. X        return -1;
  485. X    }
  486. X
  487. X    /*
  488. X     * Other side is listening. Set up the socket
  489. X     * data channels.
  490. X     */
  491. X    pid = getpid();
  492. X    sprintf(rname, "SR.%d.%d", pid, ++seq);
  493. X    sprintf(trname, "/tmp/%s", rname);
  494. X    sprintf(wname, "SW.%d.%d", pid, seq);
  495. X    sprintf(twname, "/tmp/%s", wname);
  496. X    if (mknod(trname, S_IFIFO|0777, 0) == -1 ||
  497. X        mknod(twname, S_IFIFO|0777, 0) == -1)
  498. X        goto bad3;
  499. X    if ((rfd = open(trname, O_RDWR)) == -1)
  500. X        goto bad2;
  501. X    fcntl(rfd, F_SETFD, O_RDONLY);
  502. X    if ((wfd = open(twname, O_RDWR)) == -1)
  503. X        goto bad1;
  504. X    fcntl(wfd, F_SETFD, O_WRONLY);
  505. X    /*
  506. X     * Now send a message telling that we want to connect
  507. X     */
  508. X    msg.scm_magic = SOCKET_MAGIC;
  509. X    msg.scm_msg = MSG_CONNECT;
  510. X    msg.scm_type = so->so_type;
  511. X    strcpy(msg.scm_rname, rname);
  512. X    strcpy(msg.scm_wname, wname);
  513. X    strcpy((char *)&msg.scm_addr.un.sun_path, so->so_name);
  514. X    cc = write(pfd, (char *)&msg, sizeof(msg));
  515. X    if (cc == -1)
  516. X        goto bad;
  517. X    if (cc != sizeof(msg)) {
  518. X        errno = EPIPE; goto bad;
  519. X    }
  520. X
  521. X    /*
  522. X     * Message sent. Now we have to receive a message
  523. X     * on our socket pipe, to finalize the handshake.
  524. X     */
  525. X    cc = read(so->so_fd, (char *)&msg, sizeof(msg));
  526. X    if (cc == -1)
  527. X        goto bad;
  528. X    if (cc != sizeof(msg) || msg.scm_magic != SOCKET_MAGIC) {
  529. X        errno = EIO;
  530. X        goto bad;
  531. X    }
  532. X    if (msg.scm_msg != MSG_CONNECT_OK) {
  533. X        errno = ECONNREFUSED;
  534. X        goto bad;
  535. X    }
  536. X    if (so->so_type != msg.scm_type) {
  537. X        errno = EPROTOTYPE;
  538. X        goto bad;
  539. X    }
  540. X
  541. X    /*
  542. X     * Juggle around the file descriptors so that the socket
  543. X     * fd refers to the read pipe.
  544. X     */
  545. X    sofd = dup(so->so_fd);
  546. X    if (sofd == -1)
  547. X        goto bad;
  548. X    rfd = dup2(rfd, so->so_fd);
  549. X    if (rfd == -1) {
  550. X        close(sofd);
  551. X        goto bad;
  552. X    }
  553. X    so->so_conn = (struct sockaddr *)malloc(SOCKADDRLEN(&msg.scm_addr.sa));
  554. X    memcpy((char *)so->so_conn, (char *)&msg.scm_addr, SOCKADDRLEN(&msg.scm_addr.sa));
  555. X    so->so_state |= SS_ISCONNECTED;
  556. X    so->so_rname = strdup(rname);
  557. X    so->so_wname = strdup(wname);
  558. X    so->so_rfd = rfd;
  559. X    so->so_wfd = wfd;
  560. X    so->so_pfd = pfd;
  561. X    so->so_fd = sofd;
  562. X    return 0;
  563. X
  564. Xbad:    close(wfd); 
  565. Xbad1:    close(rfd);
  566. Xbad2:    unlink(trname); unlink(twname);
  567. Xbad3:    close(pfd);
  568. X    so->so_rfd = so->so_wfd = so->so_pfd = -1;
  569. X    return -1;
  570. X}
  571. X
  572. SHAR_EOF
  573. $TOUCH -am 1215093790 connect.c &&
  574. chmod 0660 connect.c ||
  575. echo "restore of connect.c failed"
  576. set `wc -c connect.c`;Wc_c=$1
  577. if test "$Wc_c" != "3270"; then
  578.     echo original size 3270, current size $Wc_c
  579. fi
  580. # ============= hostbyaddr.c ==============
  581. echo "x - extracting hostbyaddr.c (Text)"
  582. sed 's/^X//' << 'SHAR_EOF' > hostbyaddr.c &&
  583. X#include <stdio.h>
  584. X#include <sys/types.h>
  585. X#include <sys/utsname.h>
  586. X#include "netdb.h"
  587. X#include "socket.h"
  588. X
  589. Xstatic int hassysname;
  590. Xstatic struct utsname sysname;
  591. Xint h_errno;
  592. X
  593. Xstruct hostent *
  594. Xgethostbyaddr(struct sockaddr *host)
  595. X{
  596. X    static struct hostent hent;
  597. X    static struct sockaddr_in inaddr;
  598. X
  599. X    if (!hassysname) {
  600. X        if (uname(&sysname) == -1)
  601. X            return NULL;
  602. X        hassysname = 1;
  603. X    }
  604. X    /*
  605. X     * Here, the host name must match the current host
  606. X     * for the function to work.
  607. X     * As an alternative, we can map all host names
  608. X     * to the current host.
  609. X     */
  610. X#if 0
  611. X    if (strcmp(host, sysname.nodename) == 0) {
  612. X#endif
  613. X        hent.h_name = sysname.nodename;
  614. X        hent.h_aliases = NULL;
  615. X        hent.h_addrtype = AF_INET;
  616. X        hent.h_length = 1;
  617. X        hent.h_addr = &inaddr;
  618. X        inaddr.sin_family = AF_INET;
  619. X        inaddr.sin_port = 0;
  620. X        inaddr.sin_addr.s_addr = 0;
  621. X        return &hent;
  622. X#if 0
  623. X    } else {
  624. X        h_errno = HOST_NOT_FOUND;
  625. X        return NULL;
  626. X    }
  627. X#endif
  628. X}
  629. SHAR_EOF
  630. $TOUCH -am 1215115390 hostbyaddr.c &&
  631. chmod 0660 hostbyaddr.c ||
  632. echo "restore of hostbyaddr.c failed"
  633. set `wc -c hostbyaddr.c`;Wc_c=$1
  634. if test "$Wc_c" != "909"; then
  635.     echo original size 909, current size $Wc_c
  636. fi
  637. # ============= hostbyname.c ==============
  638. echo "x - extracting hostbyname.c (Text)"
  639. sed 's/^X//' << 'SHAR_EOF' > hostbyname.c &&
  640. X#include <stdio.h>
  641. X#include <sys/types.h>
  642. X#include <sys/utsname.h>
  643. X#include "netdb.h"
  644. X#include "socket.h"
  645. X
  646. Xstatic int hassysname;
  647. Xstatic struct utsname sysname;
  648. Xint h_errno;
  649. X
  650. Xstruct hostent *
  651. Xgethostbyname(char *host)
  652. X{
  653. X    static struct hostent hent;
  654. X    static struct sockaddr_in inaddr;
  655. X
  656. X    if (!hassysname) {
  657. X        if (uname(&sysname) == -1)
  658. X            return NULL;
  659. X        hassysname = 1;
  660. X    }
  661. X    /*
  662. X     * Here, the host name must match the current host
  663. X     * for the function to work.
  664. X     * As an alternative, we can map all host names
  665. X     * to the current host.
  666. X     */
  667. X#if 0
  668. X    if (strcmp(host, sysname.nodename) == 0) {
  669. X#endif
  670. X        hent.h_name = sysname.nodename;
  671. X        hent.h_aliases = NULL;
  672. X        hent.h_addrtype = AF_INET;
  673. X        hent.h_length = 1;
  674. X        hent.h_addr = &inaddr;
  675. X        inaddr.sin_family = AF_INET;
  676. X        inaddr.sin_port = 0;
  677. X        inaddr.sin_addr.s_addr = 0;
  678. X        return &hent;
  679. X#if 0
  680. X    } else {
  681. X        h_errno = HOST_NOT_FOUND;
  682. X        return NULL;
  683. X    }
  684. X#endif
  685. X}
  686. SHAR_EOF
  687. $TOUCH -am 1214084890 hostbyname.c &&
  688. chmod 0660 hostbyname.c ||
  689. echo "restore of hostbyname.c failed"
  690. set `wc -c hostbyname.c`;Wc_c=$1
  691. if test "$Wc_c" != "898"; then
  692.     echo original size 898, current size $Wc_c
  693. fi
  694. # ============= getpeername.c ==============
  695. echo "x - extracting getpeername.c (Text)"
  696. sed 's/^X//' << 'SHAR_EOF' > getpeername.c &&
  697. X#include <stdio.h>
  698. X#include <sys/types.h>
  699. X#include <errno.h>
  700. X#include <prototypes.h>
  701. X#include <string.h>
  702. X#include <memory.h>
  703. X#include "socket.h"
  704. X#include "socketvar.h"
  705. X
  706. X/*
  707. X * Get name of peer for connected socket.
  708. X */
  709. Xint
  710. Xgetpeername(int fdes, struct sockaddr *asa, int *alen)
  711. X{
  712. X    register struct socket *so;
  713. X    int len;
  714. X
  715. X    if ((so = GETSOCKET(fdes)) == NULL)
  716. X        return -1;
  717. X    if (so->so_conn) {
  718. X        len = so->so_conn->sa_family == AF_UNIX
  719. X            ? strlen(((struct sockaddr_un *)so->so_conn)->sun_path)
  720. X                + 1 + sizeof(short)
  721. X            : sizeof(struct sockaddr);
  722. X        *alen = len;
  723. X        memcpy((char *)asa, (char *)so->so_conn, len);
  724. X    } else
  725. X        *alen = 0;
  726. X    return 0;
  727. X}
  728. X
  729. SHAR_EOF
  730. $TOUCH -am 1213151490 getpeername.c &&
  731. chmod 0660 getpeername.c ||
  732. echo "restore of getpeername.c failed"
  733. set `wc -c getpeername.c`;Wc_c=$1
  734. if test "$Wc_c" != "643"; then
  735.     echo original size 643, current size $Wc_c
  736. fi
  737. # ============= getsockname.c ==============
  738. echo "x - extracting getsockname.c (Text)"
  739. sed 's/^X//' << 'SHAR_EOF' > getsockname.c &&
  740. X#include <stdio.h>
  741. X#include <sys/types.h>
  742. X#include <errno.h>
  743. X#include <prototypes.h>
  744. X#include <string.h>
  745. X#include <memory.h>
  746. X#include "socket.h"
  747. X#include "socketvar.h"
  748. X
  749. X/*
  750. X * Get socket name.
  751. X */
  752. Xint
  753. Xgetsockname(int fdes, struct sockaddr *asa, int *alen)
  754. X{
  755. X    register struct socket *so;
  756. X    int len;
  757. X
  758. X    if ((so = GETSOCKET(fdes)) == NULL)
  759. X        return -1;
  760. X    if (so->so_addr) {
  761. X        len = so->so_addr->sa_family == AF_UNIX
  762. X            ? strlen(((struct sockaddr_un *)so->so_addr)->sun_path)
  763. X                + 1 + sizeof(short)
  764. X            : sizeof(struct sockaddr);
  765. X        *alen = len;
  766. X        memcpy((char *)asa, (char *)so->so_addr, len);
  767. X    } else
  768. X        *alen = 0;
  769. X    return 0;
  770. X}
  771. X
  772. SHAR_EOF
  773. $TOUCH -am 1213151490 getsockname.c &&
  774. chmod 0660 getsockname.c ||
  775. echo "restore of getsockname.c failed"
  776. set `wc -c getsockname.c`;Wc_c=$1
  777. if test "$Wc_c" != "621"; then
  778.     echo original size 621, current size $Wc_c
  779. fi
  780. # ============= getsockopt.c ==============
  781. echo "x - extracting getsockopt.c (Text)"
  782. sed 's/^X//' << 'SHAR_EOF' > getsockopt.c &&
  783. X#include <stdio.h>
  784. X#include <sys/types.h>
  785. X#include <errno.h>
  786. X#include <prototypes.h>
  787. X#include <string.h>
  788. X#include <memory.h>
  789. X#include "socket.h"
  790. X#include "socketvar.h"
  791. X
  792. Xint
  793. Xgetsockopt(int s, int level, int name, int *val, int *avalsize)
  794. X{
  795. X    struct socket *so;
  796. X
  797. X    if ((so = GETSOCKET(s)) == NULL)
  798. X        return -1;
  799. X    if (level != SOL_SOCKET) {
  800. X        errno = ENOPROTOOPT;
  801. X        return -1;
  802. X    }
  803. X    switch (name) {
  804. X    case SO_LINGER:
  805. X    case SO_USELOOPBACK:
  806. X    case SO_DONTROUTE:
  807. X    case SO_DEBUG:
  808. X    case SO_KEEPALIVE:
  809. X    case SO_REUSEADDR:
  810. X    case SO_BROADCAST:
  811. X    case SO_OOBINLINE:
  812. X        *val = so->so_options & name;
  813. X        *avalsize = sizeof(so->so_options);
  814. X        break;
  815. X
  816. X    case SO_TYPE:
  817. X        *val = so->so_type;
  818. X        *avalsize = sizeof(so->so_type);
  819. X        break;
  820. X
  821. X    case SO_ERROR:
  822. X        *val = 0;
  823. X        *avalsize = sizeof(int);
  824. X        break;
  825. X
  826. X    case SO_SNDBUF:
  827. X    case SO_RCVBUF:
  828. X    case SO_SNDLOWAT:
  829. X    case SO_RCVLOWAT:
  830. X    case SO_SNDTIMEO:
  831. X    case SO_RCVTIMEO:
  832. X        *val = 0;
  833. X        *avalsize = sizeof(int);
  834. X        break;
  835. X
  836. X    default:
  837. X        errno = ENOPROTOOPT;
  838. X        return -1;
  839. X    }
  840. X    return 0;
  841. X}
  842. X
  843. SHAR_EOF
  844. $TOUCH -am 1213151890 getsockopt.c &&
  845. chmod 0660 getsockopt.c ||
  846. echo "restore of getsockopt.c failed"
  847. set `wc -c getsockopt.c`;Wc_c=$1
  848. if test "$Wc_c" != "995"; then
  849.     echo original size 995, current size $Wc_c
  850. fi
  851. # ============= listen.c ==============
  852. echo "x - extracting listen.c (Text)"
  853. sed 's/^X//' << 'SHAR_EOF' > listen.c &&
  854. X#include <stdio.h>
  855. X#include <string.h>
  856. X#include <sys/types.h>
  857. X#include <sys/stat.h>
  858. X#include <memory.h>
  859. X#include <prototypes.h>
  860. X#include <errno.h>
  861. X#include "socket.h"
  862. X#include "socketvar.h"
  863. X
  864. Xint
  865. Xlisten(int s, int backlog)
  866. X{
  867. X    register struct socket *so;
  868. X
  869. X    if ((so = GETSOCKET(s)) == NULL)
  870. X        return -1;
  871. X    if (_setsolock(s, SO_ACCEPTCONN) == -1) {
  872. X        errno = EALREADY;
  873. X        return -1;
  874. X    }
  875. X    so->so_options |= SO_ACCEPTCONN;
  876. X    return 0;
  877. X}
  878. X
  879. SHAR_EOF
  880. $TOUCH -am 1213151590 listen.c &&
  881. chmod 0660 listen.c ||
  882. echo "restore of listen.c failed"
  883. set `wc -c listen.c`;Wc_c=$1
  884. if test "$Wc_c" != "428"; then
  885.     echo original size 428, current size $Wc_c
  886. fi
  887. # ============= setsockopt.c ==============
  888. echo "x - extracting setsockopt.c (Text)"
  889. sed 's/^X//' << 'SHAR_EOF' > setsockopt.c &&
  890. X#include <stdio.h>
  891. X#include <sys/types.h>
  892. X#include <errno.h>
  893. X#include <prototypes.h>
  894. X#include <string.h>
  895. X#include <memory.h>
  896. X#include "socket.h"
  897. X#include "socketvar.h"
  898. X
  899. X/*
  900. X * Most socket options are no-ops
  901. X * but we set them anyway, so that a getsockopt can
  902. X * read them back.
  903. X */
  904. Xint
  905. Xsetsockopt(int s, int level, int name, char *val, int valsize)
  906. X{
  907. X    struct socket *so;
  908. X
  909. X    if ((so = GETSOCKET(s)) == NULL)
  910. X        return -1;
  911. X    if (level != SOL_SOCKET) {
  912. X        errno = ENOPROTOOPT;
  913. X        return -1;
  914. X    }
  915. X    switch (name) {
  916. X    case SO_LINGER:
  917. X    case SO_DEBUG:
  918. X    case SO_KEEPALIVE:
  919. X    case SO_DONTROUTE:
  920. X    case SO_USELOOPBACK:
  921. X    case SO_BROADCAST:
  922. X    case SO_REUSEADDR:
  923. X    case SO_OOBINLINE:
  924. X        if (*val)
  925. X            so->so_options |= name;
  926. X        else
  927. X            so->so_options &= ~name;
  928. X        break;
  929. X        
  930. X    case SO_SNDBUF:
  931. X    case SO_RCVBUF:
  932. X    case SO_SNDLOWAT:
  933. X    case SO_RCVLOWAT:
  934. X    case SO_SNDTIMEO:
  935. X    case SO_RCVTIMEO:
  936. X        break;
  937. X
  938. X    default:
  939. X        errno = ENOPROTOOPT;
  940. X        break;
  941. X    }
  942. X    return 0;
  943. X}
  944. X
  945. X
  946. SHAR_EOF
  947. $TOUCH -am 1213151590 setsockopt.c &&
  948. chmod 0660 setsockopt.c ||
  949. echo "restore of setsockopt.c failed"
  950. set `wc -c setsockopt.c`;Wc_c=$1
  951. if test "$Wc_c" != "923"; then
  952.     echo original size 923, current size $Wc_c
  953. fi
  954. # ============= socket.c ==============
  955. echo "x - extracting socket.c (Text)"
  956. sed 's/^X//' << 'SHAR_EOF' > socket.c &&
  957. X#include <stdio.h>
  958. X#include <string.h>
  959. X#include <sys/types.h>
  960. X#include <sys/stat.h>
  961. X#include <sys/param.h>
  962. X#include <sys/fcntl.h>
  963. X#include <memory.h>
  964. X#include <malloc.h>
  965. X#include <prototypes.h>
  966. X#include <errno.h>
  967. X#include "socket.h"
  968. X#include "socketvar.h"
  969. X
  970. Xstruct socket *_socktab[NOFILE];
  971. Xfd_set _socketmap;        /* File descriptor map */
  972. Xstatic int seq = 0;        /* Sequence number for file creation */
  973. X
  974. X/*
  975. X * Sockets are emulated by named pipes. A socket is characterized
  976. X * by a file in the "/usr/spool/socket" directory.
  977. X * The filename is randomly generated to always be unique.
  978. X * The actual connection consist of two other named pipe files
  979. X * in the "/tmp" directory. Since there is only one channel
  980. X * for the pipes, we need two pipes to simulate one socket.
  981. X */
  982. Xint
  983. Xsocket(int domain, int type, int protocol)
  984. X{
  985. X    register struct socket *so;
  986. X    int sofd;
  987. X    char soname[30];
  988. X
  989. X    if ((domain != AF_UNIX && domain != AF_INET)
  990. X        || type != SOCK_STREAM || protocol != 0) {
  991. X         errno = EPROTONOSUPPORT;
  992. X         return NULL;
  993. X    }
  994. X    if ((so = (struct socket *)malloc(sizeof(struct socket))) == NULL)
  995. X        return NULL;
  996. X    so->so_options = 0;
  997. X    so->so_state = 0;
  998. X    so->so_type = type;
  999. X    so->so_rfd = so->so_wfd = so->so_pfd = -1;
  1000. X    so->so_domain = domain;
  1001. X    so->so_protocol = protocol;
  1002. X    so->so_rname = so->so_wname = NULL;
  1003. X    so->so_conn = NULL;
  1004. X
  1005. X    /*
  1006. X     * create the main socket pipe
  1007. X     */
  1008. X    sprintf(soname, "/tmp/SO.%d.%d", getpid(), ++seq);
  1009. X    if (mknod(soname, S_IFIFO|0777, 0) == -1) {
  1010. X        free((char *)so);
  1011. X        return -1;
  1012. X    }
  1013. X    if ((sofd = open(soname, O_RDWR)) == -1) {
  1014. X        unlink(soname); free((char *)so); 
  1015. X        return -1;
  1016. X    }
  1017. X    fcntl(sofd, F_SETFD, O_RDONLY);
  1018. X    so->so_name = strdup(soname);
  1019. X    so->so_fd = sofd;
  1020. X    FD_SET(sofd, &_socketmap);
  1021. X    _socktab[sofd] = so;
  1022. X
  1023. X    /*
  1024. X     * Indicate socket is active
  1025. X     */
  1026. X    _setsolock(sofd, 0);
  1027. X    return sofd;
  1028. X}
  1029. X
  1030. X/*
  1031. X * To be able to have a few status bits for the pipe files
  1032. X * we use file locks, at a high address.
  1033. X * "_setsolock" can be used to set a flag, and "_checksolock" to
  1034. X * examine the state of the flag.
  1035. X */
  1036. Xint
  1037. X_setsolock(int fd, int type)
  1038. X{
  1039. X    struct flock lockblk;
  1040. X
  1041. X    lockblk.l_type = F_WRLCK;
  1042. X    lockblk.l_whence = 0;
  1043. X    lockblk.l_start = type + 10000000L;
  1044. X    lockblk.l_len = 1;
  1045. X    return fcntl(fd, F_SETLK, &lockblk);
  1046. X}
  1047. X
  1048. Xint
  1049. X_clearsolock(int fd, int type)
  1050. X{
  1051. X    struct flock lockblk;
  1052. X
  1053. X    lockblk.l_type = F_UNLCK;
  1054. X    lockblk.l_whence = 0;
  1055. X    lockblk.l_start = type + 10000000L;
  1056. X    lockblk.l_len = 1;
  1057. X    return fcntl(fd, F_SETLK, &lockblk);
  1058. X}
  1059. X
  1060. X/*
  1061. X * Check for a lock.
  1062. X * Returns:
  1063. X *    -1 if error
  1064. X *    0 if no lock
  1065. X *    1 if lock
  1066. X */
  1067. Xint
  1068. X_checksolock(int fd, long type)
  1069. X{
  1070. X    struct flock lockblk;
  1071. X
  1072. X    lockblk.l_type = F_WRLCK;
  1073. X    lockblk.l_whence = 0;
  1074. X    lockblk.l_start = type + 10000000L;
  1075. X    lockblk.l_len = 1;
  1076. X    if (fcntl(fd, F_GETLK, &lockblk) == -1)
  1077. X        return -1;
  1078. X    return lockblk.l_type != F_UNLCK;
  1079. X}
  1080. X
  1081. Xchar *
  1082. X_socketname(struct sockaddr *addr)
  1083. X{
  1084. X    static char path[108];
  1085. X
  1086. X    switch (addr->sa_family) {
  1087. X    case AF_UNIX:
  1088. X        strcpy(path, ((struct sockaddr_un *)addr)->sun_path);
  1089. X        break;
  1090. X
  1091. X    case AF_INET:
  1092. X        sprintf(path, "/usr/spool/socket/PORT.%d",
  1093. X            (unsigned)((struct sockaddr_in *)addr)->sin_port);
  1094. X        break;
  1095. X    default:
  1096. X        return NULL;
  1097. X    }
  1098. X    return path;
  1099. X}
  1100. SHAR_EOF
  1101. $TOUCH -am 1215094190 socket.c &&
  1102. chmod 0660 socket.c ||
  1103. echo "restore of socket.c failed"
  1104. set `wc -c socket.c`;Wc_c=$1
  1105. if test "$Wc_c" != "3109"; then
  1106.     echo original size 3109, current size $Wc_c
  1107. fi
  1108. # ============= soclose.c ==============
  1109. echo "x - extracting soclose.c (Text)"
  1110. sed 's/^X//' << 'SHAR_EOF' > soclose.c &&
  1111. X#include <stdio.h>
  1112. X#include <sys/types.h>
  1113. X#include <prototypes.h>
  1114. X#include <errno.h>
  1115. X#include <malloc.h>
  1116. X#include "socket.h"
  1117. X#include "socketvar.h"
  1118. X
  1119. Xint
  1120. Xsoclose(int fildes)
  1121. X{
  1122. X    register struct socket *so;
  1123. X
  1124. X    if ((so = GETSOCKET(fildes)) == NULL)
  1125. X        return -1;
  1126. X    if (so->so_state & SS_ISCONNECTED) {
  1127. X        if (_sodisconnect(so) == -1)
  1128. X            return -1;
  1129. X    }
  1130. X    close(so->so_fd);
  1131. X    unlink(so->so_name);
  1132. X    if (so->so_name)
  1133. X        free((char *)so->so_name);
  1134. X    if (so->so_addr)
  1135. X        free((char *)so->so_addr);
  1136. X    _socktab[fildes] = NULL;
  1137. X    free((char *)so);
  1138. X    return 0;
  1139. X}
  1140. X
  1141. X/*
  1142. X * Disconnect socket connection, and notify other side.
  1143. X */
  1144. Xint
  1145. X_sodisconnect(so)
  1146. X    register struct socket *so;
  1147. X{
  1148. X    struct socket_packet msg;
  1149. X    int cc;
  1150. X
  1151. X    if ((so->so_state & SS_ISCONNECTED) == 0) {
  1152. X        errno = ENOTCONN;
  1153. X        return -1;
  1154. X    }
  1155. X    msg.scm_magic = SOCKET_MAGIC;
  1156. X    msg.scm_msg = MSG_DISCONNECT;
  1157. X    msg.scm_type = so->so_type;
  1158. X    cc = write(so->so_pfd, (char *)&msg, sizeof(msg));
  1159. X    return _sodisconnect2(so);
  1160. X}
  1161. X
  1162. X/*
  1163. X * Come here if socket should be disconnected without 
  1164. X * notifying the other side.
  1165. X */
  1166. Xint
  1167. X_sodisconnect2(register struct socket *so)
  1168. X{
  1169. X    char fname[80];
  1170. X
  1171. X    if (so->so_state & SS_ISCONNECTED) {
  1172. X        close(so->so_rfd);
  1173. X        close(so->so_wfd);
  1174. X        close(so->so_pfd);
  1175. X        sprintf(fname, "/tmp/%s", so->so_rname);
  1176. X        unlink(fname);
  1177. X        sprintf(fname, "/tmp/%s", so->so_wname);
  1178. X        unlink(fname);
  1179. X        free((char *)so->so_conn);
  1180. X        so->so_conn = NULL;
  1181. X        so->so_state &= ~SS_ISCONNECTED;
  1182. X    }
  1183. X    return 0;
  1184. X}
  1185. X
  1186. SHAR_EOF
  1187. $TOUCH -am 1215095390 soclose.c &&
  1188. chmod 0660 soclose.c ||
  1189. echo "restore of soclose.c failed"
  1190. set `wc -c soclose.c`;Wc_c=$1
  1191. if test "$Wc_c" != "1427"; then
  1192.     echo original size 1427, current size $Wc_c
  1193. fi
  1194. # ============= soread.c ==============
  1195. echo "x - extracting soread.c (Text)"
  1196. sed 's/^X//' << 'SHAR_EOF' > soread.c &&
  1197. X#include <stdio.h>
  1198. X#include <sys/types.h>
  1199. X#include <fcntl.h>
  1200. X#include <errno.h>
  1201. X#include <prototypes.h>
  1202. X#include "socket.h"
  1203. X#include "socketvar.h"
  1204. X
  1205. Xint
  1206. Xsoread(int fildes, char *buf, int nbytes)
  1207. X{
  1208. X    register struct socket *so;
  1209. X    int cc;
  1210. X
  1211. X    if ((so = GETSOCKET(fildes)) == NULL)
  1212. X        return -1;
  1213. X    if ((so->so_state & SS_ISCONNECTED) == 0) {
  1214. X        errno = ENOTCONN;
  1215. X        return -1;
  1216. X    }
  1217. X    cc = read(so->so_rfd, buf, nbytes);
  1218. X    if (cc == 0 && (so->so_state & SS_NBIO) == 0) {
  1219. X        /*
  1220. X         * Use may have set FNDELAY with a fcntl.
  1221. X         * check it out here. The other solution would
  1222. X         * be to trap the fcntls, and check the arguments.
  1223. X         */
  1224. X        if (fcntl(so->so_rfd, F_GETFL, 0) & O_NDELAY)
  1225. X            so->so_state |= SS_NBIO;
  1226. X        else {
  1227. X            /*
  1228. X             * Why did we come here?
  1229. X             * Maybe connection is severed.
  1230. X             */
  1231. X        }
  1232. X    }
  1233. X    if (so->so_state & SS_NBIO && cc == 0) {
  1234. X        errno = EWOULDBLOCK;
  1235. X        return -1;
  1236. X    }
  1237. X    return cc;
  1238. X}
  1239. SHAR_EOF
  1240. $TOUCH -am 1219124090 soread.c &&
  1241. chmod 0660 soread.c ||
  1242. echo "restore of soread.c failed"
  1243. set `wc -c soread.c`;Wc_c=$1
  1244. if test "$Wc_c" != "874"; then
  1245.     echo original size 874, current size $Wc_c
  1246. fi
  1247. # ============= sowrite.c ==============
  1248. echo "x - extracting sowrite.c (Text)"
  1249. sed 's/^X//' << 'SHAR_EOF' > sowrite.c &&
  1250. X#include <stdio.h>
  1251. X#include <sys/types.h>
  1252. X#include <errno.h>
  1253. X#include <prototypes.h>
  1254. X#include "socket.h"
  1255. X#include "socketvar.h"
  1256. X
  1257. Xint
  1258. Xsowrite(int fildes, char *buf, int nbytes)
  1259. X{
  1260. X    register struct socket *so;
  1261. X    int cc;
  1262. X
  1263. X    if ((so = GETSOCKET(fildes)) == NULL)
  1264. X        return -1;
  1265. X    if ((so->so_state & SS_ISCONNECTED) == 0) {
  1266. X        errno = ENOTCONN;
  1267. X        return -1;
  1268. X    }
  1269. X    cc = write(so->so_wfd, buf, nbytes);
  1270. X    if (so->so_state & SS_NBIO && cc == 0) {
  1271. X        errno = EWOULDBLOCK;
  1272. X        return -1;
  1273. X    }
  1274. X    return cc;
  1275. X}
  1276. SHAR_EOF
  1277. $TOUCH -am 1213151790 sowrite.c &&
  1278. chmod 0660 sowrite.c ||
  1279. echo "restore of sowrite.c failed"
  1280. set `wc -c sowrite.c`;Wc_c=$1
  1281. if test "$Wc_c" != "483"; then
  1282.     echo original size 483, current size $Wc_c
  1283. fi
  1284. # ============= soioctl.c ==============
  1285. echo "x - extracting soioctl.c (Text)"
  1286. sed 's/^X//' << 'SHAR_EOF' > soioctl.c &&
  1287. X#include <stdio.h>
  1288. X#include <sys/types.h>
  1289. X#include <sys/stat.h>
  1290. X#include <sys/ioctl.h>
  1291. X#include <prototypes.h>
  1292. X#include <errno.h>
  1293. X#include <fcntl.h>
  1294. X#include "socket.h"
  1295. X#include "socketvar.h"
  1296. X
  1297. Xint
  1298. Xsoioctl(int fildes, int request, int *arg)
  1299. X{
  1300. X    register struct socket *so;
  1301. X    struct stat sbuf;
  1302. X
  1303. X    if ((so = GETSOCKET(fildes)) == NULL)
  1304. X        return -1;
  1305. X    switch (request) {
  1306. X    case FIOSNBIO:
  1307. X        if (*arg) {
  1308. X            if (so->so_fd != -1)
  1309. X                fcntl(so->so_fd, F_SETFL,
  1310. X                      fcntl(so->so_fd, F_GETFL, 0) | O_NDELAY);
  1311. X            if (so->so_rfd != -1)
  1312. X
  1313. X                fcntl(so->so_rfd, F_SETFL,
  1314. X                      fcntl(so->so_rfd, F_GETFL, 0) | O_NDELAY);
  1315. X            so->so_state |= SS_NBIO;
  1316. X        } else {
  1317. X            if (so->so_fd != -1)
  1318. X                fcntl(so->so_fd, F_SETFL,
  1319. X                      fcntl(so->so_fd, F_GETFL, 0) & ~O_NDELAY);
  1320. X            if (so->so_rfd != -1)
  1321. X                fcntl(so->so_rfd, F_SETFL,
  1322. X                      fcntl(so->so_rfd, F_GETFL, 0) & ~O_NDELAY);
  1323. X            so->so_state &= ~SS_NBIO;
  1324. X        }
  1325. X        break;
  1326. X        
  1327. X#ifdef FIOASYNC
  1328. X    case FIOASYNC:
  1329. X        if (*arg)
  1330. X            so->so_state |= SS_ASYNC;
  1331. X        else
  1332. X            so->so_state &= ~SS_ASYNC;
  1333. X        return (0);
  1334. X#endif
  1335. X
  1336. X    case FIONREAD:
  1337. X        if (fstat(so->so_rfd, &sbuf) == -1)
  1338. X            return -1;
  1339. X        *arg = sbuf.st_size;
  1340. X        return (0);
  1341. X
  1342. X    default:
  1343. X        errno = EOPNOTSUPP;
  1344. X        return -1;
  1345. X    }
  1346. X    return 0;
  1347. X}
  1348. X
  1349. X
  1350. SHAR_EOF
  1351. $TOUCH -am 1219123990 soioctl.c &&
  1352. chmod 0660 soioctl.c ||
  1353. echo "restore of soioctl.c failed"
  1354. set `wc -c soioctl.c`;Wc_c=$1
  1355. if test "$Wc_c" != "1211"; then
  1356.     echo original size 1211, current size $Wc_c
  1357. fi
  1358. # ============= netdb.h ==============
  1359. echo "x - extracting netdb.h (Text)"
  1360. sed 's/^X//' << 'SHAR_EOF' > netdb.h &&
  1361. X/*
  1362. X * Copyright (c) 1980, 1983, 1988 Regents of the University of California.
  1363. X * All rights reserved.
  1364. X *
  1365. X * Redistribution and use in source and binary forms are permitted
  1366. X * provided that the above copyright notice and this paragraph are
  1367. X * duplicated in all such forms and that any documentation,
  1368. X * advertising materials, and other materials related to such
  1369. X * distribution and use acknowledge that the software was developed
  1370. X * by the University of California, Berkeley.  The name of the
  1371. X * University may not be used to endorse or promote products derived
  1372. X * from this software without specific prior written permission.
  1373. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1374. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1375. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1376. X *
  1377. X *    @(#)netdb.h    5.10 (Berkeley) 6/27/88
  1378. X */
  1379. X
  1380. X/*
  1381. X * Structures returned by network
  1382. X * data base library.  All addresses
  1383. X * are supplied in host order, and
  1384. X * returned in network order (suitable
  1385. X * for use in system calls).
  1386. X */
  1387. Xstruct    hostent {
  1388. X    char    *h_name;    /* official name of host */
  1389. X    char    **h_aliases;    /* alias list */
  1390. X    int    h_addrtype;    /* host address type */
  1391. X    int    h_length;    /* length of address */
  1392. X    char    **h_addr_list;    /* list of addresses from name server */
  1393. X#define    h_addr    h_addr_list[0]    /* address, for backward compatiblity */
  1394. X};
  1395. X
  1396. X/*
  1397. X * Assumption here is that a network number
  1398. X * fits in 32 bits -- probably a poor one.
  1399. X */
  1400. Xstruct    netent {
  1401. X    char        *n_name;    /* official name of net */
  1402. X    char        **n_aliases;    /* alias list */
  1403. X    int        n_addrtype;    /* net address type */
  1404. X    unsigned long    n_net;        /* network # */
  1405. X};
  1406. X
  1407. Xstruct    servent {
  1408. X    char    *s_name;    /* official service name */
  1409. X    char    **s_aliases;    /* alias list */
  1410. X    int    s_port;        /* port # */
  1411. X    char    *s_proto;    /* protocol to use */
  1412. X};
  1413. X
  1414. Xstruct    protoent {
  1415. X    char    *p_name;    /* official protocol name */
  1416. X    char    **p_aliases;    /* alias list */
  1417. X    int    p_proto;    /* protocol # */
  1418. X};
  1419. X
  1420. Xstruct hostent    *gethostbyname(), *gethostbyaddr(), *gethostent();
  1421. Xstruct netent    *getnetbyname(), *getnetbyaddr(), *getnetent();
  1422. Xstruct servent    *getservbyname(), *getservbyport(), *getservent();
  1423. Xstruct protoent    *getprotobyname(), *getprotobynumber(), *getprotoent();
  1424. X
  1425. X/*
  1426. X * Error return codes from gethostbyname() and gethostbyaddr()
  1427. X * (left in extern int h_errno).
  1428. X */
  1429. X
  1430. X#define    HOST_NOT_FOUND    1 /* Authoritative Answer Host not found */
  1431. X#define    TRY_AGAIN    2 /* Non-Authoritive Host not found, or SERVERFAIL */
  1432. X#define    NO_RECOVERY    3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
  1433. X#define    NO_DATA        4 /* Valid name, no data record of requested type */
  1434. X#define    NO_ADDRESS    NO_DATA        /* no address, look for MX record */
  1435. SHAR_EOF
  1436. $TOUCH -am 1213172690 netdb.h &&
  1437. chmod 0660 netdb.h ||
  1438. echo "restore of netdb.h failed"
  1439. set `wc -c netdb.h`;Wc_c=$1
  1440. if test "$Wc_c" != "2664"; then
  1441.     echo original size 2664, current size $Wc_c
  1442. fi
  1443. # ============= socket.h ==============
  1444. echo "x - extracting socket.h (Text)"
  1445. sed 's/^X//' << 'SHAR_EOF' > socket.h &&
  1446. X/*
  1447. X * The only socket type supported is the stream socket
  1448. X */
  1449. X#define    SOCK_STREAM    1        /* stream socket */
  1450. X
  1451. X/*
  1452. X * Option flags per-socket. most are dummys
  1453. X */
  1454. X#define    SO_DEBUG    0x0001        /* turn on debugging info recording */
  1455. X#define    SO_ACCEPTCONN    0x0002        /* socket has had listen() */
  1456. X#define    SO_REUSEADDR    0x0004        /* allow local address reuse */
  1457. X#define    SO_KEEPALIVE    0x0008        /* keep connections alive */
  1458. X#define    SO_DONTROUTE    0x0010        /* just use interface addresses */
  1459. X#define    SO_BROADCAST    0x0020        /* permit sending of broadcast msgs */
  1460. X#define    SO_USELOOPBACK    0x0040        /* bypass hardware when possible */
  1461. X#define    SO_LINGER    0x0080        /* linger on close if data present */
  1462. X#define    SO_OOBINLINE    0x0100        /* leave received OOB data in line */
  1463. X
  1464. X/*
  1465. X * Additional options, not kept in so_options.
  1466. X */
  1467. X#define SO_SNDBUF    0x1001        /* send buffer size */
  1468. X#define SO_RCVBUF    0x1002        /* receive buffer size */
  1469. X#define SO_SNDLOWAT    0x1003        /* send low-water mark */
  1470. X#define SO_RCVLOWAT    0x1004        /* receive low-water mark */
  1471. X#define SO_SNDTIMEO    0x1005        /* send timeout */
  1472. X#define SO_RCVTIMEO    0x1006        /* receive timeout */
  1473. X#define    SO_ERROR    0x1007        /* get error status and clear */
  1474. X#define    SO_TYPE        0x1008        /* get socket type */
  1475. X
  1476. X/*
  1477. X * Level number for (get/set)sockopt() to apply to socket itself.
  1478. X */
  1479. X#define    SOL_SOCKET    0xffff        /* options for socket level */
  1480. X
  1481. X/*
  1482. X * Address families.
  1483. X */
  1484. X#define    AF_UNSPEC    0        /* unspecified */
  1485. X#define    AF_UNIX        1        /* local to host (pipes, portals) */
  1486. X#define    AF_INET        2        /* internetwork: UDP, TCP, etc. */
  1487. X
  1488. X#define    AF_MAX        3
  1489. X
  1490. X/*
  1491. X * Protocol families, same as address families for now.
  1492. X */
  1493. X#define    PF_UNSPEC    AF_UNSPEC
  1494. X#define    PF_UNIX        AF_UNIX
  1495. X#define    PF_INET        AF_INET
  1496. X
  1497. X/*
  1498. X * Structure used to keep socket address.
  1499. X */
  1500. Xstruct sockaddr {
  1501. X    ushort    sa_family;        /* address family */
  1502. X    char    sa_data[14];        /* up to 14 bytes of direct address */
  1503. X};
  1504. X
  1505. X/*
  1506. X *  These definitions are normally in in.h
  1507. X */
  1508. Xstruct in_addr {
  1509. X    ulong_t s_addr;
  1510. X};
  1511. X
  1512. Xstruct sockaddr_in {
  1513. X    short    sin_family;        /* AF_INET */
  1514. X    ushort    sin_port;        /* port number */
  1515. X    struct in_addr sin_addr;    /* internet address (always 0) */
  1516. X    char    sin_zero[8];        /* filler only */
  1517. X};
  1518. X
  1519. X#define    INADDR_ANY        (ulong_t)0x00000000
  1520. X#define    INADDR_BROADCAST    (ulong_t)0xffffffff    /* must be masked */
  1521. X#define    SOCKADDRLEN(A)    ((A)->sa_family == AF_UNIX ? sizeof(struct sockaddr_un) : (A)->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr))
  1522. X
  1523. X#define    ntohs(X)    (X)
  1524. X#define    htons(X)    (X)
  1525. X#define    htonl(X)    (X)
  1526. X
  1527. X/*
  1528. X * Since we have no networking, this routine always give the same result
  1529. X */
  1530. X#define    inet_addr(HOST)    (0)
  1531. X
  1532. X/*
  1533. X * This structure is normally in un.h
  1534. X */
  1535. Xstruct    sockaddr_un {
  1536. X    short    sun_family;        /* AF_UNIX */
  1537. X    char    sun_path[108];        /* path name */
  1538. X};
  1539. X
  1540. X#ifndef EADDRINUSE
  1541. X#define    EADDRINUSE    35    /* bind - socket is occupied or inuse */
  1542. X#define    EALREADY    36    /* connect - already connected */
  1543. X#define    ECONNABORTED    37    /* connection aborted */
  1544. X#define    ECONNREFUSED    38    /* connection refused */
  1545. X#define    ECONNRESET    39    /* ??? */
  1546. X#define    EDESTADDRREQ    40    /* destination address required */
  1547. X#define    EINPROGRESS    41    /* in progress */
  1548. X#define    EISCONN        42    /* is already connected */
  1549. X#define    ENOPROTOOPT    46    /* no protocol option */
  1550. X#define    ENOTCONN    47    /* not connected */
  1551. X#define    ENOTSOCK    48    /* not socket */
  1552. X#define    EOPNOTSUPP    49    /* operation not supported */
  1553. X#define    EPROTONOSUPPORT    50    /* protocol not supported */
  1554. X#define    EPROTOTYPE    51    /* connect - trying to connect to socket of different type */
  1555. X#define    EWOULDBLOCK    EAGAIN    /* would block */
  1556. X#endif
  1557. X
  1558. X/*
  1559. X * prototypes for the socket emulation package functions
  1560. X */
  1561. Xint accept(int s, struct sockaddr *name, int *anamelen);
  1562. Xint bind(int sofd, struct sockaddr *name, int namelen);
  1563. Xint connect(int s, struct sockaddr *name, int namelen);
  1564. Xint getpeername(int fdes, struct sockaddr *asa, int *alen);
  1565. Xint getsockname(int fdes, struct sockaddr *asa, int *alen);
  1566. Xint getsockopt(int s, int level, int name, int *val, int *avalsize);
  1567. Xstruct hostent *gethostbyname ( char *host );
  1568. Xint listen(int s, int backlog);
  1569. Xint setsockopt(int s, int level, int name, char *val, int valsize);
  1570. Xint socket(int domain, int type, int protocol);
  1571. Xint soclose(int fildes);
  1572. Xint soioctl(int fildes, int request, int *arg);
  1573. Xint soread(int fildes, char *buf, int nbytes);
  1574. Xint sowrite(int fildes, char *buf, int nbytes);
  1575. X
  1576. X    
  1577. X#ifndef SOCKET_LIBRARY_BUILD
  1578. X#define read    soread
  1579. X#define    write    sowrite
  1580. X#define    close    soclose
  1581. X#define    ioctl    soioctl
  1582. X#endif
  1583. X
  1584. X#ifndef FIOSNBIO
  1585. X#define    FIOSNBIO    ((('f') << 8) | 40)
  1586. X#endif
  1587. X
  1588. X#ifndef FIONREAD
  1589. X#define    FIONREAD ((('f') << 8) | 41)
  1590. X#endif
  1591. X
  1592. X#define    S_IFSOCK    S_IFIFO
  1593. X#define    SOCKET_EMULATION
  1594. SHAR_EOF
  1595. $TOUCH -am 1219114290 socket.h &&
  1596. chmod 0620 socket.h ||
  1597. echo "restore of socket.h failed"
  1598. set `wc -c socket.h`;Wc_c=$1
  1599. if test "$Wc_c" != "4578"; then
  1600.     echo original size 4578, current size $Wc_c
  1601. fi
  1602. # ============= socketvar.h ==============
  1603. echo "x - extracting socketvar.h (Text)"
  1604. sed 's/^X//' << 'SHAR_EOF' > socketvar.h &&
  1605. X/*
  1606. X * Socket structure used internally in the socket emulation package
  1607. X */
  1608. X
  1609. Xstruct socket {
  1610. X    short    so_options;        /* from socket call, see socket.h */
  1611. X    short    so_state;        /* internal state flags SS_*, below */
  1612. X    char    so_type;        /* socket type */
  1613. X    short    so_fd;            /* socket file descriptor */
  1614. X    char    *so_name;        /* Name of socket pipe */
  1615. X    struct sockaddr *so_addr;    /* Address of socket */
  1616. X    long    so_domain;
  1617. X    short    so_protocol;
  1618. X    /*
  1619. X     * the following variables set for a connected socket
  1620. X     */
  1621. X    short    so_rfd;            /* Read-side file descriptor */
  1622. X    short    so_wfd;            /* write-side file descriptor */
  1623. X    short    so_pfd;            /* Peer socket file descriptor */
  1624. X    char    *so_rname;        /* Read-side-pipe filename */
  1625. X    char    *so_wname;        /* Write-side-pipe filename */
  1626. X    struct sockaddr *so_conn;    /* Address of connected socket */
  1627. X};
  1628. X
  1629. X/*
  1630. X * Socket state bits.
  1631. X */
  1632. X#define    SS_ISCONNECTED        0x002    /* socket connected to a peer */
  1633. X#define    SS_NBIO            0x100    /* non-blocking ops */
  1634. X
  1635. X
  1636. X/*
  1637. X * Message send through the main socket channel
  1638. X */
  1639. Xstruct socket_packet {
  1640. X    unsigned short    scm_magic;    /* Magic number */
  1641. X    char    scm_msg;        /* Socket message */
  1642. X    char    scm_type;        /* socket type */
  1643. X    char    scm_rname[14];        /* name of "read" pipe */
  1644. X    char    scm_wname[14];        /* name of "write" pipe */
  1645. X    union {                /* Callers address */
  1646. X        struct sockaddr sa;
  1647. X        struct sockaddr_in in;
  1648. X        struct sockaddr_un un;
  1649. X    } scm_addr;
  1650. X};
  1651. X#define    SOCKET_MAGIC    0xc561
  1652. X/*
  1653. X * Socket message types
  1654. X */
  1655. X#define    MSG_CONNECT    1        /* Want to connect to socket */
  1656. X#define    MSG_CONNECT_OK    2        /* Connect ok message */
  1657. X#define    MSG_FAIL    3        /* General failure message */
  1658. X#define    MSG_DISCONNECT    4        /* Disconnection message */
  1659. X
  1660. X#define    GETSOCKET(sofd)    ((sofd)>=0 && (sofd)<=FD_SETSIZE ? _socktab[sofd] : NULL)
  1661. Xextern struct socket *_socktab[];
  1662. Xextern fd_set _socketmap;
  1663. X
  1664. X/*
  1665. X * Internal routines in the socket package
  1666. X */
  1667. Xint _setsolock ( int fd , int type );
  1668. Xint _clearsolock ( int fd , int type );
  1669. Xint _checksolock ( int fd , long type );
  1670. Xchar *_socketname ( struct sockaddr *addr );
  1671. Xint _sodisconnect ( struct socket *so );
  1672. Xint _sodisconnect2 ( register struct socket *so );
  1673. X
  1674. SHAR_EOF
  1675. $TOUCH -am 1219125090 socketvar.h &&
  1676. chmod 0620 socketvar.h ||
  1677. echo "restore of socketvar.h failed"
  1678. set `wc -c socketvar.h`;Wc_c=$1
  1679. if test "$Wc_c" != "2068"; then
  1680.     echo original size 2068, current size $Wc_c
  1681. fi
  1682. # ============= Makefile ==============
  1683. echo "x - extracting Makefile (Text)"
  1684. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  1685. XCC = gcc
  1686. XCFLAGS = -g -Wall -I. -DSOCKET_LIBRARY_BUILD
  1687. X
  1688. XSRCFILES = accept.c bind.c connect.c hostbyaddr.c hostbyname.c getpeername.c getsockname.c getsockopt.c \
  1689. X    listen.c setsockopt.c socket.c soclose.c soread.c sowrite.c soioctl.c
  1690. X
  1691. XOBJFILES = accept.o bind.o connect.o hostbyaddr.o hostbyname.o getpeername.o getsockname.o getsockopt.o \
  1692. X    listen.o setsockopt.o socket.o soclose.o soread.o sowrite.o soioctl.o
  1693. X
  1694. XHFILES = netdb.h socket.h socketvar.h
  1695. X
  1696. XLIBS = libsocket.a
  1697. X
  1698. Xtest : libsocket.a test.o
  1699. X    $(CC) $(CFLAGS) test.o -o test libsocket.a
  1700. X    cp test testx
  1701. X
  1702. Xlibsocket.a : $(OBJFILES)
  1703. X    rm -f libsocket.a
  1704. X    ar qc libsocket.a $(OBJFILES)
  1705. X    ranlib libsocket.a
  1706. X
  1707. Xinstall: libsocket.a socket.h socketvar.h
  1708. X    cp libsocket.a /lib/386/Slibsocket.a
  1709. X    chmod 644 /lib/386/Slibsocket.a
  1710. X    cp socket.h /usr/include/sys/socket.h
  1711. X    chmod 644 /usr/include/sys/socket.h
  1712. X    cp netdb.h /usr/include/netdb.h
  1713. X    chmod 644 /usr/include/netdb.h
  1714. X
  1715. Xshar:: $(SRCFILES) $(HFILES)
  1716. X    shar -n socket-emulation -a -s $(MYNAME) README $(SRCFILES) $(HFILES) Makefile >socket.shar
  1717. SHAR_EOF
  1718. $TOUCH -am 1219205590 Makefile &&
  1719. chmod 0660 Makefile ||
  1720. echo "restore of Makefile failed"
  1721. set `wc -c Makefile`;Wc_c=$1
  1722. if test "$Wc_c" != "1030"; then
  1723.     echo original size 1030, current size $Wc_c
  1724. fi
  1725. exit 0
  1726.