]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/xtrans/Xtransdnet.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / lib / xtrans / Xtransdnet.c
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 $ */
3 /*
4
5 Copyright (c) 1993, 1994  X Consortium
6
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:
14
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17
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.
25
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.
30
31 */
32
33 /* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA
34  *
35  * All Rights Reserved
36  *
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.
46  *
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.
54  */
55
56 #ifndef WIN32
57 #include <netdnet/dn.h>
58 #include <netdnet/dnetdb.h>
59 #include <sys/ioctl.h>
60 #endif /* !WIN32 */
61
62 #include <stdio.h>
63
64 #ifdef WIN32
65 #define _WILLWINSOCK_
66 #define BOOL wBOOL
67 #undef Status
68 #define Status wStatus
69 #include <prgpre.h> /* PATHWORKS header normally in %MSTOOLS%\h\pathwork */
70 #undef Status
71 #define Status int
72 #undef BOOL
73 #include <X11/Xw32defs.h>
74 #undef close
75 #define close closesocket
76 #endif /* WIN32 */
77
78
79 #if defined(X11_t)
80 #define DNETOBJ "X$X"
81 #endif
82 #if defined(XIM_t)
83 #define DNETOBJ "IMSERVER$"
84 #endif
85 #if defined(FS_t) || defined(FONT_t)
86 #define DNETOBJ "X$FONT"
87 #endif
88 #if defined(ICE_t)
89 #define DNETOBJ ""
90 #endif
91 #if defined(TEST_t)
92 #define DNETOBJ "X$TEST"
93 #endif
94
95
96 /*
97  * This is the DNET implementation of the X Transport service layer
98  */
99
100 /*
101  * This function gets the local address of the socket and stores it in the
102  * XtransConnInfo structure for the connection.
103  */
104
105 static int
106 TRANS(DNETGetAddr) (ciptr)
107
108 XtransConnInfo ciptr;
109
110 {
111     struct sockaddr_dn  sockname;
112     int                 namelen = sizeof(sockname);
113
114     PRMSG (3,"DNETGetAddr(%x)\n", ciptr, 0, 0);
115
116     if (getsockname (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
117     {
118         PRMSG (1,"DNETGetAddr: getsockname() failed: %d\n",
119               EGET(), 0, 0);
120         return -1;
121     }
122
123
124     /*
125      * Everything looks good: fill in the XtransConnInfo structure.
126      */
127
128     if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
129     {
130         PRMSG (1, "DNETGetAddr: Can't allocate space for the addr\n",
131                0, 0, 0);
132         return -1;
133     }
134
135     ciptr->family = sockname.sdn_family;
136     ciptr->addrlen = namelen;
137     memcpy (ciptr->addr, &sockname, ciptr->addrlen);
138
139     return 0;
140 }
141
142
143 /*
144  * This function gets the remote address of the socket and stores it in the
145  * XtransConnInfo structure for the connection.
146  */
147
148 static int
149 TRANS(DNETGetPeerAddr) (ciptr)
150
151 XtransConnInfo ciptr;
152
153 {
154     struct sockaddr_dn  sockname;
155     int                 namelen = sizeof(sockname);
156
157     PRMSG (3,"DNETGetPeerAddr(%x)\n", ciptr, 0, 0);
158
159     if (getpeername (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
160     {
161         PRMSG (1,"DNETGetPeerAddr: getpeername() failed: %d\n",
162               EGET(), 0, 0);
163         return -1;
164     }
165
166     /*
167      * Everything looks good: fill in the XtransConnInfo structure.
168      */
169
170     if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
171     {
172         PRMSG (1,
173               "DNETGetPeerAddr: Can't allocate space for the addr\n",
174               0, 0, 0);
175         return -1;
176     }
177
178     ciptr->peeraddrlen = namelen;
179     memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
180
181     return 0;
182 }
183
184
185 #ifdef TRANS_CLIENT
186
187 static XtransConnInfo
188 TRANS(DNETOpenCOTSClient) (thistrans, protocol, host, port)
189
190 Xtransport      *thistrans;
191 char            *protocol;
192 char            *host;
193 char            *port;
194
195 {
196     XtransConnInfo      ciptr;
197
198     PRMSG (2,"DNETOpenCOTSClient(%s,%s,%s)\n", protocol, host, port);
199
200     if ((ciptr = (XtransConnInfo) xcalloc (
201         1, sizeof(struct _XtransConnInfo))) == NULL)
202     {
203         PRMSG (1, "DNETOpenCOTSClient: malloc failed\n", 0, 0, 0);
204         return NULL;
205     }
206
207     ciptr->index = 0;           /* only one form of DECnet */
208
209     /* nothing else to do here */
210
211     return ciptr;
212 }
213
214 #endif /* TRANS_CLIENT */
215
216
217 #ifdef TRANS_SERVER
218
219 static XtransConnInfo
220 TRANS(DNETOpenCOTSServer) (thistrans, protocol, host, port)
221
222 Xtransport      *thistrans;
223 char            *protocol;
224 char            *host;
225 char            *port;
226
227 {
228     XtransConnInfo      ciptr;
229
230     PRMSG (2,"DNETOpenCOTSServer(%s,%s,%s)\n", protocol, host, port);
231
232     if ((ciptr = (XtransConnInfo) xcalloc (
233         1, sizeof(struct _XtransConnInfo))) == NULL)
234     {
235         PRMSG (1, "DNETOpenCOTSServer: malloc failed\n", 0, 0, 0);
236         return NULL;
237     }
238
239     if ((ciptr->fd = socket (AF_DECnet, SOCK_STREAM, 0)) < 0)
240     {
241         xfree ((char *) ciptr);
242         return NULL;
243     }
244
245     ciptr->index = 0;           /* only one form of DECnet */
246
247     return (ciptr);
248 }
249
250 #endif /* TRANS_SERVER */
251
252
253 #ifdef TRANS_CLIENT
254
255 static XtransConnInfo
256 TRANS(DNETOpenCLTSClient) (thistrans, protocol, host, port)
257
258 Xtransport      *thistrans;
259 char            *protocol;
260 char            *host;
261 char            *port;
262
263 {
264     XtransConnInfo      ciptr;
265
266     PRMSG (2,"DNETOpenCLTSClient(%s,%s,%s)\n", protocol, host, port);
267
268     if ((ciptr = (XtransConnInfo) xcalloc (
269         1, sizeof (struct _XtransConnInfo))) == NULL)
270     {
271         PRMSG (1, "DNETOpenCLTSClient: malloc failed\n", 0, 0, 0);
272         return NULL;
273     }
274
275     ciptr->index = 0;           /* only one form of DECnet */
276
277     /* nothing else to do here */
278
279     return ciptr;
280 }
281
282 #endif /* TRANS_CLIENT */
283
284
285 #ifdef TRANS_SERVER
286
287 static XtransConnInfo
288 TRANS(DNETOpenCLTSServer) (thistrans, protocol, host, port)
289
290 Xtransport      *thistrans;
291 char            *protocol;
292 char            *host;
293 char            *port;
294
295 {
296     /* NEED TO IMPLEMENT */
297
298     PRMSG (2,"DNETOpenCLTSServer(%s,%s,%s)\n", protocol, host, port);
299     return NULL;
300 }
301
302 #endif /* TRANS_SERVER */
303
304
305 #ifdef TRANS_REOPEN
306
307 static XtransConnInfo
308 TRANS(DNETReopenCOTSServer) (thistrans, fd, port)
309
310 Xtransport      *thistrans;
311 int             fd;
312 char            *port;
313
314 {
315     XtransConnInfo      ciptr;
316
317     PRMSG (2,"DNETReopenCOTSServer(%d,%s)\n", fd, port, 0);
318
319     if ((ciptr = (XtransConnInfo) xcalloc (
320         1, sizeof(struct _XtransConnInfo))) == NULL)
321     {
322         PRMSG (1, "DNETReopenCOTSServer: malloc failed\n", 0, 0, 0);
323         return NULL;
324     }
325
326     ciptr->fd = fd;
327     ciptr->index = 0;           /* only one form of DECnet */
328
329     return (ciptr);
330 }
331
332 static XtransConnInfo
333 TRANS(DNETReopenCLTSServer) (thistrans, fd, port)
334
335 Xtransport      *thistrans;
336 int             fd;
337 char            *port;
338
339 {
340     XtransConnInfo      ciptr;
341
342     PRMSG (2,"DNETReopenCLTSServer(%d,%s)\n", fd, port, 0);
343
344     if ((ciptr = (XtransConnInfo) xcalloc (
345         1, sizeof(struct _XtransConnInfo))) == NULL)
346     {
347         PRMSG (1, "DNETReopenCLTSServer: malloc failed\n", 0, 0, 0);
348         return NULL;
349     }
350
351     ciptr->fd = fd;
352     ciptr->index = 0;           /* only one form of DECnet */
353
354     return (ciptr);
355 }
356
357 #endif /* TRANS_REOPEN */
358
359
360 static int
361 TRANS(DNETSetOption) (ciptr, option, arg)
362
363 XtransConnInfo  ciptr;
364 int             option;
365 int             arg;
366
367 {
368     PRMSG (2,"DNETSetOption(%d,%d,%d)\n", ciptr->fd, option, arg);
369
370     return -1;
371 }
372
373
374 #ifdef TRANS_SERVER
375
376 static int
377 TRANS(DNETCreateListener) (ciptr, port)
378
379 XtransConnInfo  ciptr;
380 char            *port;
381
382 {
383     struct sockaddr_dn  dnsock;
384     int                 fd = ciptr->fd;
385
386     PRMSG (3, "DNETCreateListener(%x,%d)\n", ciptr, fd, 0);
387
388     bzero ((char *) &dnsock, sizeof (dnsock));
389     dnsock.sdn_family = AF_DECnet;
390
391     if (port && *port )
392         sprintf (dnsock.sdn_objname, "%s%s", DNETOBJ, port);
393     else
394 #ifdef X11_t
395         return -1;
396 #else
397         sprintf (dnsock.sdn_objname, "%s%d", DNETOBJ, getpid ());
398 #endif
399
400     dnsock.sdn_objnamel = strlen (dnsock.sdn_objname);
401
402     if (bind (fd, (struct sockaddr *) &dnsock, sizeof (dnsock)))
403     {
404         close (fd);
405         return -1;
406     }
407
408     if (listen (fd, 5))
409     {
410         close (fd);
411         return (-1);
412     }
413
414
415     /* Set a flag to indicate that this connection is a listener */
416
417     ciptr->flags = 1;
418
419     return 0;
420 }
421
422
423 static XtransConnInfo
424 TRANS(DNETAccept) (ciptr, status)
425
426 XtransConnInfo  ciptr;
427 int             *status;
428
429 {
430     XtransConnInfo      newciptr;
431     struct sockaddr_dn  sockname;
432     int                 namelen = sizeof(sockname);
433
434     PRMSG (2, "DNETAccept(%x,%d)\n", ciptr, ciptr->fd, 0);
435
436     if ((newciptr = (XtransConnInfo) xcalloc(
437         1, sizeof (struct _XtransConnInfo))) == NULL)
438     {
439         PRMSG (1, "DNETAccept: malloc failed\n", 0, 0, 0);
440         *status = TRANS_ACCEPT_BAD_MALLOC;
441         return NULL;
442     }
443
444     if((newciptr->fd = accept (ciptr->fd,
445         (struct sockaddr *) &sockname, &namelen)) < 0)
446     {
447         PRMSG (1, "DNETAccept: accept() failed\n", 0, 0, 0);
448
449         xfree (newciptr);
450         *status = TRANS_ACCEPT_FAILED;
451         return NULL;
452     }
453
454     /*
455      * Get this address again because the transport may give a more 
456      * specific address now that a connection is established.
457      */
458
459     if (TRANS(DNETGetAddr) (newciptr) < 0)
460     {
461         PRMSG(1,
462         "DNETAccept: ...DNETGetAddr() failed:\n", 0, 0, 0);
463         close (newciptr->fd);
464         xfree (newciptr);
465         *status = TRANS_ACCEPT_MISC_ERROR;
466         return NULL;
467     }
468
469     if (TRANS(DNETGetPeerAddr) (newciptr) < 0)
470     {
471         PRMSG(1,
472         "DNETAccept: ...DNETGetPeerAddr() failed:\n", 0, 0, 0);
473
474         close (newciptr->fd);
475         if (newciptr->addr) xfree (newciptr->addr);
476         xfree (newciptr);
477         *status = TRANS_ACCEPT_MISC_ERROR;
478         return NULL;
479     }
480
481     *status = 0;
482
483     return newciptr;
484 }
485
486 #endif /* TRANS_SERVER */
487
488
489 #ifdef TRANS_CLIENT
490
491 #define OBJBUFSIZE 64
492
493 static int
494 TRANS(DNETConnect) (ciptr, host, port)
495
496 XtransConnInfo  ciptr;
497 char            *host;
498 char            *port;
499
500 {
501     char objname[OBJBUFSIZE];
502
503     extern int dnet_conn();
504     
505     PRMSG (2,"DNETConnect(%d,%s,%s)\n", ciptr->fd, host, port);
506
507 #ifdef X11_t
508     /*
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.
512      *
513      * The port that is passed here is really a string containing the idisplay
514      * from ConnectDisplay().
515      */
516
517     if (is_numeric (port))
518     {
519         short tmpport = (short) atoi (port);
520
521         sprintf (objname, "X$X%d", tmpport);
522     }
523     else
524 #endif
525         strncpy(objname, port, OBJBUFSIZE);
526
527
528     /*
529      * Do the connect
530      */
531
532     if (!host) host = "0";
533
534     if ((ciptr->fd = dnet_conn (host, objname, SOCK_STREAM, 0, 0, 0, 0)) < 0)
535     {
536         return TRANS_CONNECT_FAILED;
537     }
538
539
540     /*
541      * Sync up the address fields of ciptr.
542      */
543
544     if (TRANS(DNETGetAddr) (ciptr) < 0)
545     {
546         PRMSG (1,
547               "DNETConnect: ...DNETGetAddr() failed:\n", 0, 0, 0);
548         return TRANS_CONNECT_FAILED;
549     }
550
551     if (TRANS(DNETGetPeerAddr) (ciptr) < 0)
552     {
553         PRMSG (1,
554               "DNETConnect: ...DNETGetPeerAddr() failed:\n",
555               0, 0, 0);
556         return TRANS_CONNECT_FAILED;
557     }
558
559     return 0;
560 }
561
562 #endif /* TRANS_CLIENT */
563
564
565 static int
566 TRANS(DNETBytesReadable) (ciptr, pend)
567
568 XtransConnInfo  ciptr;
569 BytesReadable_t *pend;
570
571 {
572     PRMSG (2,"DNETBytesReadable(%x,%d,%x)\n", ciptr, ciptr->fd, pend);
573
574 #ifdef WIN32
575     return ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
576 #else
577     return ioctl(ciptr->fd, FIONREAD, (char *)pend);
578 #endif /* WIN32 */
579 }
580
581
582 static int
583 TRANS(DNETRead) (ciptr, buf, size)
584
585 XtransConnInfo  ciptr;
586 char            *buf;
587 int             size;
588
589 {
590     PRMSG (2,"DNETRead(%d,%x,%d)\n", ciptr->fd, buf, size);
591
592 #ifdef WIN32
593     return recv ((SOCKET)ciptr->fd, buf, size, 0);
594 #else
595     return read (ciptr->fd, buf, size);
596 #endif /* WIN32 */
597 }
598
599
600 static int
601 TRANS(DNETWrite) (ciptr, buf, size)
602
603 XtransConnInfo  ciptr;
604 char            *buf;
605 int             size;
606
607 {
608     PRMSG (2,"DNETWrite(%d,%x,%d)\n", ciptr->fd, buf, size);
609
610 #ifdef WIN32
611     return send ((SOCKET)ciptr->fd, buf, size, 0);
612 #else
613     return write (ciptr->fd, buf, size);
614 #endif /* WIN32 */
615 }
616
617
618 static int
619 TRANS(DNETReadv) (ciptr, buf, size)
620
621 XtransConnInfo  ciptr;
622 struct iovec    *buf;
623 int             size;
624
625 {
626     PRMSG (2,"DNETReadv(%d,%x,%d)\n", ciptr->fd, buf, size);
627
628     return READV (ciptr, buf, size);
629 }
630
631
632 static int
633 TRANS(DNETWritev) (ciptr, buf, size)
634
635 XtransConnInfo  ciptr;
636 struct iovec    *buf;
637 int             size;
638
639 {
640     PRMSG (2,"DNETWritev(%d,%x,%d)\n", ciptr->fd, buf, size);
641
642     return WRITEV (ciptr, buf, size);
643 }
644
645
646 static int
647 TRANS(DNETDisconnect) (ciptr)
648
649 XtransConnInfo  ciptr;
650
651 {
652     PRMSG (2,"DNETDisconnect(%x,%d)\n", ciptr, ciptr->fd, 0);
653
654     return shutdown (ciptr->fd, 2); /* disallow further sends and receives */
655 }
656
657
658 static int
659 TRANS(DNETClose) (ciptr)
660
661 XtransConnInfo  ciptr;
662
663 {
664     PRMSG (2,"DNETClose(%x,%d)\n", ciptr, ciptr->fd, 0);
665
666     return close (ciptr->fd);
667 }
668
669
670 Xtransport      TRANS(DNETFuncs) = {
671     /* DNET Interface */
672     "dnet",
673     0,
674 #ifdef TRANS_CLIENT
675     TRANS(DNETOpenCOTSClient),
676 #endif /* TRANS_CLIENT */
677 #ifdef TRANS_SERVER
678     TRANS(DNETOpenCOTSServer),
679 #endif /* TRANS_SERVER */
680 #ifdef TRANS_CLIENT
681     TRANS(DNETOpenCLTSClient),
682 #endif /* TRANS_CLIENT */
683 #ifdef TRANS_SERVER
684     TRANS(DNETOpenCLTSServer),
685 #endif /* TRANS_SERVER */
686 #ifdef TRANS_REOPEN
687     TRANS(DNETReopenCOTSServer),
688     TRANS(DNETReopenCLTSServer),
689 #endif /* TRANS_REOPEN */
690     TRANS(DNETSetOption),
691 #ifdef TRANS_SERVER
692     TRANS(DNETCreateListener),
693     NULL,                                       /* ResetListener */
694     TRANS(DNETAccept),
695 #endif /* TRANS_SERVER */
696 #ifdef TRANS_CLIENT
697     TRANS(DNETConnect),
698 #endif /* TRANS_CLIENT */
699     TRANS(DNETBytesReadable),
700     TRANS(DNETRead),
701     TRANS(DNETWrite),
702     TRANS(DNETReadv),
703     TRANS(DNETWritev),
704     TRANS(DNETDisconnect),
705     TRANS(DNETClose),
706     TRANS(DNETClose),
707 };