1 /* $XConsortium: Xtransdnet.c,v 1.16 95/02/10 17:54:09 mor Exp $ */
2 /* $XFree86: xc/lib/xtrans/Xtransdnet.c,v 3.2 1996/05/10 06:55:47 dawes Exp $ */
5 Copyright (c) 1993, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
26 Except as contained in this notice, the name of the X Consortium shall
27 not be used in advertising or otherwise to promote the sale, use or
28 other dealings in this Software without prior written authorization
29 from the X Consortium.
33 /* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA
37 * Permission to use, copy, modify, and distribute this software and its
38 * documentation for any purpose and without fee is hereby granted, provided
39 * that the above copyright notice appear in all copies and that both that
40 * copyright notice and this permission notice appear in supporting
41 * documentation, and that the name NCR not be used in advertising
42 * or publicity pertaining to distribution of the software without specific,
43 * written prior permission. NCR and makes no representations about the
44 * suitability of this software for any purpose. It is provided "as is"
45 * without express or implied warranty.
47 * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
48 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
49 * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
50 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
51 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
52 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
53 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
57 #include <netdnet/dn.h>
58 #include <netdnet/dnetdb.h>
59 #include <sys/ioctl.h>
68 #define Status wStatus
69 #include <prgpre.h> /* PATHWORKS header normally in %MSTOOLS%\h\pathwork */
73 #include <X11/Xw32defs.h>
75 #define close closesocket
83 #define DNETOBJ "IMSERVER$"
85 #if defined(FS_t) || defined(FONT_t)
86 #define DNETOBJ "X$FONT"
92 #define DNETOBJ "X$TEST"
97 * This is the DNET implementation of the X Transport service layer
101 * This function gets the local address of the socket and stores it in the
102 * XtransConnInfo structure for the connection.
106 TRANS(DNETGetAddr) (ciptr)
108 XtransConnInfo ciptr;
111 struct sockaddr_dn sockname;
112 int namelen = sizeof(sockname);
114 PRMSG (3,"DNETGetAddr(%x)\n", ciptr, 0, 0);
116 if (getsockname (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
118 PRMSG (1,"DNETGetAddr: getsockname() failed: %d\n",
125 * Everything looks good: fill in the XtransConnInfo structure.
128 if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
130 PRMSG (1, "DNETGetAddr: Can't allocate space for the addr\n",
135 ciptr->family = sockname.sdn_family;
136 ciptr->addrlen = namelen;
137 memcpy (ciptr->addr, &sockname, ciptr->addrlen);
144 * This function gets the remote address of the socket and stores it in the
145 * XtransConnInfo structure for the connection.
149 TRANS(DNETGetPeerAddr) (ciptr)
151 XtransConnInfo ciptr;
154 struct sockaddr_dn sockname;
155 int namelen = sizeof(sockname);
157 PRMSG (3,"DNETGetPeerAddr(%x)\n", ciptr, 0, 0);
159 if (getpeername (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
161 PRMSG (1,"DNETGetPeerAddr: getpeername() failed: %d\n",
167 * Everything looks good: fill in the XtransConnInfo structure.
170 if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
173 "DNETGetPeerAddr: Can't allocate space for the addr\n",
178 ciptr->peeraddrlen = namelen;
179 memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
187 static XtransConnInfo
188 TRANS(DNETOpenCOTSClient) (thistrans, protocol, host, port)
190 Xtransport *thistrans;
196 XtransConnInfo ciptr;
198 PRMSG (2,"DNETOpenCOTSClient(%s,%s,%s)\n", protocol, host, port);
200 if ((ciptr = (XtransConnInfo) xcalloc (
201 1, sizeof(struct _XtransConnInfo))) == NULL)
203 PRMSG (1, "DNETOpenCOTSClient: malloc failed\n", 0, 0, 0);
207 ciptr->index = 0; /* only one form of DECnet */
209 /* nothing else to do here */
214 #endif /* TRANS_CLIENT */
219 static XtransConnInfo
220 TRANS(DNETOpenCOTSServer) (thistrans, protocol, host, port)
222 Xtransport *thistrans;
228 XtransConnInfo ciptr;
230 PRMSG (2,"DNETOpenCOTSServer(%s,%s,%s)\n", protocol, host, port);
232 if ((ciptr = (XtransConnInfo) xcalloc (
233 1, sizeof(struct _XtransConnInfo))) == NULL)
235 PRMSG (1, "DNETOpenCOTSServer: malloc failed\n", 0, 0, 0);
239 if ((ciptr->fd = socket (AF_DECnet, SOCK_STREAM, 0)) < 0)
241 xfree ((char *) ciptr);
245 ciptr->index = 0; /* only one form of DECnet */
250 #endif /* TRANS_SERVER */
255 static XtransConnInfo
256 TRANS(DNETOpenCLTSClient) (thistrans, protocol, host, port)
258 Xtransport *thistrans;
264 XtransConnInfo ciptr;
266 PRMSG (2,"DNETOpenCLTSClient(%s,%s,%s)\n", protocol, host, port);
268 if ((ciptr = (XtransConnInfo) xcalloc (
269 1, sizeof (struct _XtransConnInfo))) == NULL)
271 PRMSG (1, "DNETOpenCLTSClient: malloc failed\n", 0, 0, 0);
275 ciptr->index = 0; /* only one form of DECnet */
277 /* nothing else to do here */
282 #endif /* TRANS_CLIENT */
287 static XtransConnInfo
288 TRANS(DNETOpenCLTSServer) (thistrans, protocol, host, port)
290 Xtransport *thistrans;
296 /* NEED TO IMPLEMENT */
298 PRMSG (2,"DNETOpenCLTSServer(%s,%s,%s)\n", protocol, host, port);
302 #endif /* TRANS_SERVER */
307 static XtransConnInfo
308 TRANS(DNETReopenCOTSServer) (thistrans, fd, port)
310 Xtransport *thistrans;
315 XtransConnInfo ciptr;
317 PRMSG (2,"DNETReopenCOTSServer(%d,%s)\n", fd, port, 0);
319 if ((ciptr = (XtransConnInfo) xcalloc (
320 1, sizeof(struct _XtransConnInfo))) == NULL)
322 PRMSG (1, "DNETReopenCOTSServer: malloc failed\n", 0, 0, 0);
327 ciptr->index = 0; /* only one form of DECnet */
332 static XtransConnInfo
333 TRANS(DNETReopenCLTSServer) (thistrans, fd, port)
335 Xtransport *thistrans;
340 XtransConnInfo ciptr;
342 PRMSG (2,"DNETReopenCLTSServer(%d,%s)\n", fd, port, 0);
344 if ((ciptr = (XtransConnInfo) xcalloc (
345 1, sizeof(struct _XtransConnInfo))) == NULL)
347 PRMSG (1, "DNETReopenCLTSServer: malloc failed\n", 0, 0, 0);
352 ciptr->index = 0; /* only one form of DECnet */
357 #endif /* TRANS_REOPEN */
361 TRANS(DNETSetOption) (ciptr, option, arg)
363 XtransConnInfo ciptr;
368 PRMSG (2,"DNETSetOption(%d,%d,%d)\n", ciptr->fd, option, arg);
377 TRANS(DNETCreateListener) (ciptr, port)
379 XtransConnInfo ciptr;
383 struct sockaddr_dn dnsock;
386 PRMSG (3, "DNETCreateListener(%x,%d)\n", ciptr, fd, 0);
388 bzero ((char *) &dnsock, sizeof (dnsock));
389 dnsock.sdn_family = AF_DECnet;
392 sprintf (dnsock.sdn_objname, "%s%s", DNETOBJ, port);
397 sprintf (dnsock.sdn_objname, "%s%d", DNETOBJ, getpid ());
400 dnsock.sdn_objnamel = strlen (dnsock.sdn_objname);
402 if (bind (fd, (struct sockaddr *) &dnsock, sizeof (dnsock)))
415 /* Set a flag to indicate that this connection is a listener */
423 static XtransConnInfo
424 TRANS(DNETAccept) (ciptr, status)
426 XtransConnInfo ciptr;
430 XtransConnInfo newciptr;
431 struct sockaddr_dn sockname;
432 int namelen = sizeof(sockname);
434 PRMSG (2, "DNETAccept(%x,%d)\n", ciptr, ciptr->fd, 0);
436 if ((newciptr = (XtransConnInfo) xcalloc(
437 1, sizeof (struct _XtransConnInfo))) == NULL)
439 PRMSG (1, "DNETAccept: malloc failed\n", 0, 0, 0);
440 *status = TRANS_ACCEPT_BAD_MALLOC;
444 if((newciptr->fd = accept (ciptr->fd,
445 (struct sockaddr *) &sockname, &namelen)) < 0)
447 PRMSG (1, "DNETAccept: accept() failed\n", 0, 0, 0);
450 *status = TRANS_ACCEPT_FAILED;
455 * Get this address again because the transport may give a more
456 * specific address now that a connection is established.
459 if (TRANS(DNETGetAddr) (newciptr) < 0)
462 "DNETAccept: ...DNETGetAddr() failed:\n", 0, 0, 0);
463 close (newciptr->fd);
465 *status = TRANS_ACCEPT_MISC_ERROR;
469 if (TRANS(DNETGetPeerAddr) (newciptr) < 0)
472 "DNETAccept: ...DNETGetPeerAddr() failed:\n", 0, 0, 0);
474 close (newciptr->fd);
475 if (newciptr->addr) xfree (newciptr->addr);
477 *status = TRANS_ACCEPT_MISC_ERROR;
486 #endif /* TRANS_SERVER */
491 #define OBJBUFSIZE 64
494 TRANS(DNETConnect) (ciptr, host, port)
496 XtransConnInfo ciptr;
501 char objname[OBJBUFSIZE];
503 extern int dnet_conn();
505 PRMSG (2,"DNETConnect(%d,%s,%s)\n", ciptr->fd, host, port);
509 * X has a well known port, that is transport dependent. It is easier
510 * to handle it here, than try and come up with a transport independent
511 * representation that can be passed in and resolved the usual way.
513 * The port that is passed here is really a string containing the idisplay
514 * from ConnectDisplay().
517 if (is_numeric (port))
519 short tmpport = (short) atoi (port);
521 sprintf (objname, "X$X%d", tmpport);
525 strncpy(objname, port, OBJBUFSIZE);
532 if (!host) host = "0";
534 if ((ciptr->fd = dnet_conn (host, objname, SOCK_STREAM, 0, 0, 0, 0)) < 0)
536 return TRANS_CONNECT_FAILED;
541 * Sync up the address fields of ciptr.
544 if (TRANS(DNETGetAddr) (ciptr) < 0)
547 "DNETConnect: ...DNETGetAddr() failed:\n", 0, 0, 0);
548 return TRANS_CONNECT_FAILED;
551 if (TRANS(DNETGetPeerAddr) (ciptr) < 0)
554 "DNETConnect: ...DNETGetPeerAddr() failed:\n",
556 return TRANS_CONNECT_FAILED;
562 #endif /* TRANS_CLIENT */
566 TRANS(DNETBytesReadable) (ciptr, pend)
568 XtransConnInfo ciptr;
569 BytesReadable_t *pend;
572 PRMSG (2,"DNETBytesReadable(%x,%d,%x)\n", ciptr, ciptr->fd, pend);
575 return ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
577 return ioctl(ciptr->fd, FIONREAD, (char *)pend);
583 TRANS(DNETRead) (ciptr, buf, size)
585 XtransConnInfo ciptr;
590 PRMSG (2,"DNETRead(%d,%x,%d)\n", ciptr->fd, buf, size);
593 return recv ((SOCKET)ciptr->fd, buf, size, 0);
595 return read (ciptr->fd, buf, size);
601 TRANS(DNETWrite) (ciptr, buf, size)
603 XtransConnInfo ciptr;
608 PRMSG (2,"DNETWrite(%d,%x,%d)\n", ciptr->fd, buf, size);
611 return send ((SOCKET)ciptr->fd, buf, size, 0);
613 return write (ciptr->fd, buf, size);
619 TRANS(DNETReadv) (ciptr, buf, size)
621 XtransConnInfo ciptr;
626 PRMSG (2,"DNETReadv(%d,%x,%d)\n", ciptr->fd, buf, size);
628 return READV (ciptr, buf, size);
633 TRANS(DNETWritev) (ciptr, buf, size)
635 XtransConnInfo ciptr;
640 PRMSG (2,"DNETWritev(%d,%x,%d)\n", ciptr->fd, buf, size);
642 return WRITEV (ciptr, buf, size);
647 TRANS(DNETDisconnect) (ciptr)
649 XtransConnInfo ciptr;
652 PRMSG (2,"DNETDisconnect(%x,%d)\n", ciptr, ciptr->fd, 0);
654 return shutdown (ciptr->fd, 2); /* disallow further sends and receives */
659 TRANS(DNETClose) (ciptr)
661 XtransConnInfo ciptr;
664 PRMSG (2,"DNETClose(%x,%d)\n", ciptr, ciptr->fd, 0);
666 return close (ciptr->fd);
670 Xtransport TRANS(DNETFuncs) = {
675 TRANS(DNETOpenCOTSClient),
676 #endif /* TRANS_CLIENT */
678 TRANS(DNETOpenCOTSServer),
679 #endif /* TRANS_SERVER */
681 TRANS(DNETOpenCLTSClient),
682 #endif /* TRANS_CLIENT */
684 TRANS(DNETOpenCLTSServer),
685 #endif /* TRANS_SERVER */
687 TRANS(DNETReopenCOTSServer),
688 TRANS(DNETReopenCLTSServer),
689 #endif /* TRANS_REOPEN */
690 TRANS(DNETSetOption),
692 TRANS(DNETCreateListener),
693 NULL, /* ResetListener */
695 #endif /* TRANS_SERVER */
698 #endif /* TRANS_CLIENT */
699 TRANS(DNETBytesReadable),
704 TRANS(DNETDisconnect),