1b077aed3SPierre Pronchery /*
2b077aed3SPierre Pronchery * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
3b077aed3SPierre Pronchery * Copyright 2016 VMS Software, Inc. All Rights Reserved.
4b077aed3SPierre Pronchery *
5b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
6b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy
7b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at
8b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html
9b077aed3SPierre Pronchery */
10b077aed3SPierre Pronchery
11b077aed3SPierre Pronchery #ifdef __VMS
12b077aed3SPierre Pronchery # define OPENSSL_SYS_VMS
13b077aed3SPierre Pronchery # pragma message disable DOLLARID
14b077aed3SPierre Pronchery
15b077aed3SPierre Pronchery
16b077aed3SPierre Pronchery # include <openssl/opensslconf.h>
17b077aed3SPierre Pronchery
18b077aed3SPierre Pronchery # if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
19b077aed3SPierre Pronchery /*
20b077aed3SPierre Pronchery * On VMS, you need to define this to get the declaration of fileno(). The
21b077aed3SPierre Pronchery * value 2 is to make sure no function defined in POSIX-2 is left undefined.
22b077aed3SPierre Pronchery */
23b077aed3SPierre Pronchery # define _POSIX_C_SOURCE 2
24b077aed3SPierre Pronchery # endif
25b077aed3SPierre Pronchery
26b077aed3SPierre Pronchery # include <stdio.h>
27b077aed3SPierre Pronchery
28b077aed3SPierre Pronchery # undef _POSIX_C_SOURCE
29b077aed3SPierre Pronchery
30b077aed3SPierre Pronchery # include <sys/types.h>
31b077aed3SPierre Pronchery # include <sys/socket.h>
32b077aed3SPierre Pronchery # include <netinet/in.h>
33b077aed3SPierre Pronchery # include <inet.h>
34b077aed3SPierre Pronchery # include <unistd.h>
35b077aed3SPierre Pronchery # include <string.h>
36b077aed3SPierre Pronchery # include <errno.h>
37b077aed3SPierre Pronchery # include <starlet.h>
38b077aed3SPierre Pronchery # include <iodef.h>
39b077aed3SPierre Pronchery # ifdef __alpha
40b077aed3SPierre Pronchery # include <iosbdef.h>
41b077aed3SPierre Pronchery # else
42b077aed3SPierre Pronchery typedef struct _iosb { /* Copied from IOSBDEF.H for Alpha */
43b077aed3SPierre Pronchery # pragma __nomember_alignment
44b077aed3SPierre Pronchery __union {
45b077aed3SPierre Pronchery __struct {
46b077aed3SPierre Pronchery unsigned short int iosb$w_status; /* Final I/O status */
47b077aed3SPierre Pronchery __union {
48b077aed3SPierre Pronchery __struct { /* 16-bit byte count variant */
49b077aed3SPierre Pronchery unsigned short int iosb$w_bcnt; /* 16-bit byte count */
50b077aed3SPierre Pronchery __union {
51b077aed3SPierre Pronchery unsigned int iosb$l_dev_depend; /* 32-bit device dependent info */
52b077aed3SPierre Pronchery unsigned int iosb$l_pid; /* 32-bit pid */
53b077aed3SPierre Pronchery } iosb$r_l;
54b077aed3SPierre Pronchery } iosb$r_bcnt_16;
55b077aed3SPierre Pronchery __struct { /* 32-bit byte count variant */
56b077aed3SPierre Pronchery unsigned int iosb$l_bcnt; /* 32-bit byte count (unaligned) */
57b077aed3SPierre Pronchery unsigned short int iosb$w_dev_depend_high; /* 16-bit device dependent info */
58b077aed3SPierre Pronchery } iosb$r_bcnt_32;
59b077aed3SPierre Pronchery } iosb$r_devdepend;
60b077aed3SPierre Pronchery } iosb$r_io_64;
61b077aed3SPierre Pronchery __struct {
62b077aed3SPierre Pronchery __union {
63b077aed3SPierre Pronchery unsigned int iosb$l_getxxi_status; /* Final GETxxI status */
64b077aed3SPierre Pronchery unsigned int iosb$l_reg_status; /* Final $Registry status */
65b077aed3SPierre Pronchery } iosb$r_l_status;
66b077aed3SPierre Pronchery unsigned int iosb$l_reserved; /* Reserved field */
67b077aed3SPierre Pronchery } iosb$r_get_64;
68b077aed3SPierre Pronchery } iosb$r_io_get;
69b077aed3SPierre Pronchery } IOSB;
70b077aed3SPierre Pronchery
71b077aed3SPierre Pronchery # if !defined(__VAXC)
72b077aed3SPierre Pronchery # define iosb$w_status iosb$r_io_get.iosb$r_io_64.iosb$w_status
73b077aed3SPierre Pronchery # define iosb$w_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$w_bcnt
74b077aed3SPierre Pronchery # define iosb$r_l iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$r_l
75b077aed3SPierre Pronchery # define iosb$l_dev_depend iosb$r_l.iosb$l_dev_depend
76b077aed3SPierre Pronchery # define iosb$l_pid iosb$r_l.iosb$l_pid
77b077aed3SPierre Pronchery # define iosb$l_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$l_bcnt
78b077aed3SPierre Pronchery # define iosb$w_dev_depend_high iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$w_dev_depend_high
79b077aed3SPierre Pronchery # define iosb$l_getxxi_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_getxxi_status
80b077aed3SPierre Pronchery # define iosb$l_reg_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_reg_status
81b077aed3SPierre Pronchery # endif /* #if !defined(__VAXC) */
82b077aed3SPierre Pronchery
83b077aed3SPierre Pronchery # endif /* End of IOSBDEF */
84b077aed3SPierre Pronchery
85b077aed3SPierre Pronchery # include <efndef.h>
86b077aed3SPierre Pronchery # include <stdlib.h>
87b077aed3SPierre Pronchery # include <ssdef.h>
88b077aed3SPierre Pronchery # include <time.h>
89b077aed3SPierre Pronchery # include <stdarg.h>
90b077aed3SPierre Pronchery # include <descrip.h>
91b077aed3SPierre Pronchery
92b077aed3SPierre Pronchery # include "vms_term_sock.h"
93b077aed3SPierre Pronchery
94b077aed3SPierre Pronchery # ifdef __alpha
95b077aed3SPierre Pronchery static struct _iosb TerminalDeviceIosb;
96b077aed3SPierre Pronchery # else
97b077aed3SPierre Pronchery IOSB TerminalDeviceIosb;
98b077aed3SPierre Pronchery # endif
99b077aed3SPierre Pronchery
100b077aed3SPierre Pronchery static char TerminalDeviceBuff[255 + 2];
101b077aed3SPierre Pronchery static int TerminalSocketPair[2] = {0, 0};
102b077aed3SPierre Pronchery static unsigned short TerminalDeviceChan = 0;
103b077aed3SPierre Pronchery
104b077aed3SPierre Pronchery static int CreateSocketPair (int, int, int, int *);
105b077aed3SPierre Pronchery static void SocketPairTimeoutAst (int);
106b077aed3SPierre Pronchery static int TerminalDeviceAst (int);
107b077aed3SPierre Pronchery static void LogMessage (char *, ...);
108b077aed3SPierre Pronchery
109b077aed3SPierre Pronchery /*
110b077aed3SPierre Pronchery ** Socket Pair Timeout Value (must be 0-59 seconds)
111b077aed3SPierre Pronchery */
112b077aed3SPierre Pronchery # define SOCKET_PAIR_TIMEOUT_VALUE 20
113b077aed3SPierre Pronchery
114b077aed3SPierre Pronchery /*
115b077aed3SPierre Pronchery ** Socket Pair Timeout Block which is passed to timeout AST
116b077aed3SPierre Pronchery */
117b077aed3SPierre Pronchery typedef struct _SocketPairTimeoutBlock {
118b077aed3SPierre Pronchery unsigned short SockChan1;
119b077aed3SPierre Pronchery unsigned short SockChan2;
120b077aed3SPierre Pronchery } SPTB;
121b077aed3SPierre Pronchery
122b077aed3SPierre Pronchery # ifdef TERM_SOCK_TEST
123b077aed3SPierre Pronchery
124b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
125b077aed3SPierre Pronchery /* */
126b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
main(int argc,char * argv[],char * envp[])127b077aed3SPierre Pronchery int main (int argc, char *argv[], char *envp[])
128b077aed3SPierre Pronchery {
129b077aed3SPierre Pronchery char TermBuff[80];
130b077aed3SPierre Pronchery int TermSock,
131b077aed3SPierre Pronchery status,
132b077aed3SPierre Pronchery len;
133b077aed3SPierre Pronchery
134b077aed3SPierre Pronchery LogMessage ("Enter 'q' or 'Q' to quit ...");
135b077aed3SPierre Pronchery while (OPENSSL_strcasecmp (TermBuff, "Q")) {
136b077aed3SPierre Pronchery /*
137b077aed3SPierre Pronchery ** Create the terminal socket
138b077aed3SPierre Pronchery */
139b077aed3SPierre Pronchery status = TerminalSocket (TERM_SOCK_CREATE, &TermSock);
140b077aed3SPierre Pronchery if (status != TERM_SOCK_SUCCESS)
141b077aed3SPierre Pronchery exit (1);
142b077aed3SPierre Pronchery
143b077aed3SPierre Pronchery /*
144b077aed3SPierre Pronchery ** Process the terminal input
145b077aed3SPierre Pronchery */
146b077aed3SPierre Pronchery LogMessage ("Waiting on terminal I/O ...\n");
147b077aed3SPierre Pronchery len = recv (TermSock, TermBuff, sizeof(TermBuff), 0) ;
148b077aed3SPierre Pronchery TermBuff[len] = '\0';
149b077aed3SPierre Pronchery LogMessage ("Received terminal I/O [%s]", TermBuff);
150b077aed3SPierre Pronchery
151b077aed3SPierre Pronchery /*
152b077aed3SPierre Pronchery ** Delete the terminal socket
153b077aed3SPierre Pronchery */
154b077aed3SPierre Pronchery status = TerminalSocket (TERM_SOCK_DELETE, &TermSock);
155b077aed3SPierre Pronchery if (status != TERM_SOCK_SUCCESS)
156b077aed3SPierre Pronchery exit (1);
157b077aed3SPierre Pronchery }
158b077aed3SPierre Pronchery
159b077aed3SPierre Pronchery return 1;
160b077aed3SPierre Pronchery
161b077aed3SPierre Pronchery }
162b077aed3SPierre Pronchery # endif
163b077aed3SPierre Pronchery
164b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
165b077aed3SPierre Pronchery /* */
166b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
TerminalSocket(int FunctionCode,int * ReturnSocket)167b077aed3SPierre Pronchery int TerminalSocket (int FunctionCode, int *ReturnSocket)
168b077aed3SPierre Pronchery {
169b077aed3SPierre Pronchery int status;
170b077aed3SPierre Pronchery $DESCRIPTOR (TerminalDeviceDesc, "SYS$COMMAND");
171b077aed3SPierre Pronchery
172b077aed3SPierre Pronchery /*
173b077aed3SPierre Pronchery ** Process the requested function code
174b077aed3SPierre Pronchery */
175b077aed3SPierre Pronchery switch (FunctionCode) {
176b077aed3SPierre Pronchery case TERM_SOCK_CREATE:
177b077aed3SPierre Pronchery /*
178b077aed3SPierre Pronchery ** Create a socket pair
179b077aed3SPierre Pronchery */
180b077aed3SPierre Pronchery status = CreateSocketPair (AF_INET, SOCK_STREAM, 0, TerminalSocketPair);
181b077aed3SPierre Pronchery if (status == -1) {
182b077aed3SPierre Pronchery LogMessage ("TerminalSocket: CreateSocketPair () - %08X", status);
183b077aed3SPierre Pronchery if (TerminalSocketPair[0])
184b077aed3SPierre Pronchery close (TerminalSocketPair[0]);
185b077aed3SPierre Pronchery if (TerminalSocketPair[1])
186b077aed3SPierre Pronchery close (TerminalSocketPair[1]);
187b077aed3SPierre Pronchery return TERM_SOCK_FAILURE;
188b077aed3SPierre Pronchery }
189b077aed3SPierre Pronchery
190b077aed3SPierre Pronchery /*
191b077aed3SPierre Pronchery ** Assign a channel to the terminal device
192b077aed3SPierre Pronchery */
193b077aed3SPierre Pronchery status = sys$assign (&TerminalDeviceDesc,
194b077aed3SPierre Pronchery &TerminalDeviceChan,
195b077aed3SPierre Pronchery 0, 0, 0);
196b077aed3SPierre Pronchery if (! (status & 1)) {
197b077aed3SPierre Pronchery LogMessage ("TerminalSocket: SYS$ASSIGN () - %08X", status);
198b077aed3SPierre Pronchery close (TerminalSocketPair[0]);
199b077aed3SPierre Pronchery close (TerminalSocketPair[1]);
200b077aed3SPierre Pronchery return TERM_SOCK_FAILURE;
201b077aed3SPierre Pronchery }
202b077aed3SPierre Pronchery
203b077aed3SPierre Pronchery /*
204b077aed3SPierre Pronchery ** Queue an async IO to the terminal device
205b077aed3SPierre Pronchery */
206b077aed3SPierre Pronchery status = sys$qio (EFN$C_ENF,
207b077aed3SPierre Pronchery TerminalDeviceChan,
208b077aed3SPierre Pronchery IO$_READVBLK,
209b077aed3SPierre Pronchery &TerminalDeviceIosb,
210b077aed3SPierre Pronchery TerminalDeviceAst,
211b077aed3SPierre Pronchery 0,
212b077aed3SPierre Pronchery TerminalDeviceBuff,
213b077aed3SPierre Pronchery sizeof(TerminalDeviceBuff) - 2,
214b077aed3SPierre Pronchery 0, 0, 0, 0);
215b077aed3SPierre Pronchery if (! (status & 1)) {
216b077aed3SPierre Pronchery LogMessage ("TerminalSocket: SYS$QIO () - %08X", status);
217b077aed3SPierre Pronchery close (TerminalSocketPair[0]);
218b077aed3SPierre Pronchery close (TerminalSocketPair[1]);
219b077aed3SPierre Pronchery return TERM_SOCK_FAILURE;
220b077aed3SPierre Pronchery }
221b077aed3SPierre Pronchery
222b077aed3SPierre Pronchery /*
223b077aed3SPierre Pronchery ** Return the input side of the socket pair
224b077aed3SPierre Pronchery */
225b077aed3SPierre Pronchery *ReturnSocket = TerminalSocketPair[1];
226b077aed3SPierre Pronchery break;
227b077aed3SPierre Pronchery
228b077aed3SPierre Pronchery case TERM_SOCK_DELETE:
229b077aed3SPierre Pronchery /*
230b077aed3SPierre Pronchery ** Cancel any pending IO on the terminal channel
231b077aed3SPierre Pronchery */
232b077aed3SPierre Pronchery status = sys$cancel (TerminalDeviceChan);
233b077aed3SPierre Pronchery if (! (status & 1)) {
234b077aed3SPierre Pronchery LogMessage ("TerminalSocket: SYS$CANCEL () - %08X", status);
235b077aed3SPierre Pronchery close (TerminalSocketPair[0]);
236b077aed3SPierre Pronchery close (TerminalSocketPair[1]);
237b077aed3SPierre Pronchery return TERM_SOCK_FAILURE;
238b077aed3SPierre Pronchery }
239b077aed3SPierre Pronchery
240b077aed3SPierre Pronchery /*
241b077aed3SPierre Pronchery ** Deassign the terminal channel
242b077aed3SPierre Pronchery */
243b077aed3SPierre Pronchery status = sys$dassgn (TerminalDeviceChan);
244b077aed3SPierre Pronchery if (! (status & 1)) {
245b077aed3SPierre Pronchery LogMessage ("TerminalSocket: SYS$DASSGN () - %08X", status);
246b077aed3SPierre Pronchery close (TerminalSocketPair[0]);
247b077aed3SPierre Pronchery close (TerminalSocketPair[1]);
248b077aed3SPierre Pronchery return TERM_SOCK_FAILURE;
249b077aed3SPierre Pronchery }
250b077aed3SPierre Pronchery
251b077aed3SPierre Pronchery /*
252b077aed3SPierre Pronchery ** Close the terminal socket pair
253b077aed3SPierre Pronchery */
254b077aed3SPierre Pronchery close (TerminalSocketPair[0]);
255b077aed3SPierre Pronchery close (TerminalSocketPair[1]);
256b077aed3SPierre Pronchery
257b077aed3SPierre Pronchery /*
258b077aed3SPierre Pronchery ** Return the initialized socket
259b077aed3SPierre Pronchery */
260b077aed3SPierre Pronchery *ReturnSocket = 0;
261b077aed3SPierre Pronchery break;
262b077aed3SPierre Pronchery
263b077aed3SPierre Pronchery default:
264b077aed3SPierre Pronchery /*
265b077aed3SPierre Pronchery ** Invalid function code
266b077aed3SPierre Pronchery */
267b077aed3SPierre Pronchery LogMessage ("TerminalSocket: Invalid Function Code - %d", FunctionCode);
268b077aed3SPierre Pronchery return TERM_SOCK_FAILURE;
269b077aed3SPierre Pronchery break;
270b077aed3SPierre Pronchery }
271b077aed3SPierre Pronchery
272b077aed3SPierre Pronchery /*
273b077aed3SPierre Pronchery ** Return success
274b077aed3SPierre Pronchery */
275b077aed3SPierre Pronchery return TERM_SOCK_SUCCESS;
276b077aed3SPierre Pronchery
277b077aed3SPierre Pronchery }
278b077aed3SPierre Pronchery
279b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
280b077aed3SPierre Pronchery /* */
281b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
CreateSocketPair(int SocketFamily,int SocketType,int SocketProtocol,int * SocketPair)282b077aed3SPierre Pronchery static int CreateSocketPair (int SocketFamily,
283b077aed3SPierre Pronchery int SocketType,
284b077aed3SPierre Pronchery int SocketProtocol,
285b077aed3SPierre Pronchery int *SocketPair)
286b077aed3SPierre Pronchery {
287b077aed3SPierre Pronchery struct dsc$descriptor AscTimeDesc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
288b077aed3SPierre Pronchery static const char* LocalHostAddr = {"127.0.0.1"};
289b077aed3SPierre Pronchery unsigned short TcpAcceptChan = 0,
290b077aed3SPierre Pronchery TcpDeviceChan = 0;
291b077aed3SPierre Pronchery unsigned long BinTimeBuff[2];
292b077aed3SPierre Pronchery struct sockaddr_in sin;
293b077aed3SPierre Pronchery char AscTimeBuff[32];
294b077aed3SPierre Pronchery short LocalHostPort;
295b077aed3SPierre Pronchery int status;
296b077aed3SPierre Pronchery unsigned int slen;
297b077aed3SPierre Pronchery
298b077aed3SPierre Pronchery # ifdef __alpha
299b077aed3SPierre Pronchery struct _iosb iosb;
300b077aed3SPierre Pronchery # else
301b077aed3SPierre Pronchery IOSB iosb;
302b077aed3SPierre Pronchery # endif
303b077aed3SPierre Pronchery
304b077aed3SPierre Pronchery int SockDesc1 = 0,
305b077aed3SPierre Pronchery SockDesc2 = 0;
306b077aed3SPierre Pronchery SPTB sptb;
307b077aed3SPierre Pronchery $DESCRIPTOR (TcpDeviceDesc, "TCPIP$DEVICE");
308b077aed3SPierre Pronchery
309b077aed3SPierre Pronchery /*
310b077aed3SPierre Pronchery ** Create a socket
311b077aed3SPierre Pronchery */
312b077aed3SPierre Pronchery SockDesc1 = socket (SocketFamily, SocketType, 0);
313b077aed3SPierre Pronchery if (SockDesc1 < 0) {
314b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: socket () - %d", errno);
315b077aed3SPierre Pronchery return -1;
316b077aed3SPierre Pronchery }
317b077aed3SPierre Pronchery
318b077aed3SPierre Pronchery /*
319b077aed3SPierre Pronchery ** Initialize the socket information
320b077aed3SPierre Pronchery */
321b077aed3SPierre Pronchery slen = sizeof(sin);
322b077aed3SPierre Pronchery memset ((char *) &sin, 0, slen);
323b077aed3SPierre Pronchery sin.sin_family = SocketFamily;
324b077aed3SPierre Pronchery sin.sin_addr.s_addr = inet_addr (LocalHostAddr);
325b077aed3SPierre Pronchery sin.sin_port = 0;
326b077aed3SPierre Pronchery
327b077aed3SPierre Pronchery /*
328b077aed3SPierre Pronchery ** Bind the socket to the local IP
329b077aed3SPierre Pronchery */
330b077aed3SPierre Pronchery status = bind (SockDesc1, (struct sockaddr *) &sin, slen);
331b077aed3SPierre Pronchery if (status < 0) {
332b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: bind () - %d", errno);
333b077aed3SPierre Pronchery close (SockDesc1);
334b077aed3SPierre Pronchery return -1;
335b077aed3SPierre Pronchery }
336b077aed3SPierre Pronchery
337b077aed3SPierre Pronchery /*
338b077aed3SPierre Pronchery ** Get the socket name so we can save the port number
339b077aed3SPierre Pronchery */
340b077aed3SPierre Pronchery status = getsockname (SockDesc1, (struct sockaddr *) &sin, &slen);
341b077aed3SPierre Pronchery if (status < 0) {
342b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: getsockname () - %d", errno);
343b077aed3SPierre Pronchery close (SockDesc1);
344b077aed3SPierre Pronchery return -1;
345b077aed3SPierre Pronchery } else
346b077aed3SPierre Pronchery LocalHostPort = sin.sin_port;
347b077aed3SPierre Pronchery
348b077aed3SPierre Pronchery /*
349b077aed3SPierre Pronchery ** Setup a listen for the socket
350b077aed3SPierre Pronchery */
351b077aed3SPierre Pronchery listen (SockDesc1, 5);
352b077aed3SPierre Pronchery
353b077aed3SPierre Pronchery /*
354b077aed3SPierre Pronchery ** Get the binary (64-bit) time of the specified timeout value
355b077aed3SPierre Pronchery */
356*0d0c8621SEnji Cooper BIO_snprintf(AscTimeBuff, sizeof(AscTimeBuff), "0 0:0:%02d.00", SOCKET_PAIR_TIMEOUT_VALUE);
357b077aed3SPierre Pronchery AscTimeDesc.dsc$w_length = strlen (AscTimeBuff);
358b077aed3SPierre Pronchery AscTimeDesc.dsc$a_pointer = AscTimeBuff;
359b077aed3SPierre Pronchery status = sys$bintim (&AscTimeDesc, BinTimeBuff);
360b077aed3SPierre Pronchery if (! (status & 1)) {
361b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: SYS$BINTIM () - %08X", status);
362b077aed3SPierre Pronchery close (SockDesc1);
363b077aed3SPierre Pronchery return -1;
364b077aed3SPierre Pronchery }
365b077aed3SPierre Pronchery
366b077aed3SPierre Pronchery /*
367b077aed3SPierre Pronchery ** Assign another channel to the TCP/IP device for the accept.
368b077aed3SPierre Pronchery ** This is the channel that ends up being connected to.
369b077aed3SPierre Pronchery */
370b077aed3SPierre Pronchery status = sys$assign (&TcpDeviceDesc, &TcpDeviceChan, 0, 0, 0);
371b077aed3SPierre Pronchery if (! (status & 1)) {
372b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: SYS$ASSIGN () - %08X", status);
373b077aed3SPierre Pronchery close (SockDesc1);
374b077aed3SPierre Pronchery return -1;
375b077aed3SPierre Pronchery }
376b077aed3SPierre Pronchery
377b077aed3SPierre Pronchery /*
378b077aed3SPierre Pronchery ** Get the channel of the first socket for the accept
379b077aed3SPierre Pronchery */
380b077aed3SPierre Pronchery TcpAcceptChan = decc$get_sdc (SockDesc1);
381b077aed3SPierre Pronchery
382b077aed3SPierre Pronchery /*
383b077aed3SPierre Pronchery ** Perform the accept using $QIO so we can do this asynchronously
384b077aed3SPierre Pronchery */
385b077aed3SPierre Pronchery status = sys$qio (EFN$C_ENF,
386b077aed3SPierre Pronchery TcpAcceptChan,
387b077aed3SPierre Pronchery IO$_ACCESS | IO$M_ACCEPT,
388b077aed3SPierre Pronchery &iosb,
389b077aed3SPierre Pronchery 0, 0, 0, 0, 0,
390b077aed3SPierre Pronchery &TcpDeviceChan,
391b077aed3SPierre Pronchery 0, 0);
392b077aed3SPierre Pronchery if (! (status & 1)) {
393b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: SYS$QIO () - %08X", status);
394b077aed3SPierre Pronchery close (SockDesc1);
395b077aed3SPierre Pronchery sys$dassgn (TcpDeviceChan);
396b077aed3SPierre Pronchery return -1;
397b077aed3SPierre Pronchery }
398b077aed3SPierre Pronchery
399b077aed3SPierre Pronchery /*
400b077aed3SPierre Pronchery ** Create the second socket to do the connect
401b077aed3SPierre Pronchery */
402b077aed3SPierre Pronchery SockDesc2 = socket (SocketFamily, SocketType, 0);
403b077aed3SPierre Pronchery if (SockDesc2 < 0) {
404b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: socket () - %d", errno);
405b077aed3SPierre Pronchery sys$cancel (TcpAcceptChan);
406b077aed3SPierre Pronchery close (SockDesc1);
407b077aed3SPierre Pronchery sys$dassgn (TcpDeviceChan);
408b077aed3SPierre Pronchery return (-1) ;
409b077aed3SPierre Pronchery }
410b077aed3SPierre Pronchery
411b077aed3SPierre Pronchery /*
412b077aed3SPierre Pronchery ** Setup the Socket Pair Timeout Block
413b077aed3SPierre Pronchery */
414b077aed3SPierre Pronchery sptb.SockChan1 = TcpAcceptChan;
415b077aed3SPierre Pronchery sptb.SockChan2 = decc$get_sdc (SockDesc2);
416b077aed3SPierre Pronchery
417b077aed3SPierre Pronchery /*
418b077aed3SPierre Pronchery ** Before we block on the connect, set a timer that can cancel I/O on our
419b077aed3SPierre Pronchery ** two sockets if it never connects.
420b077aed3SPierre Pronchery */
421b077aed3SPierre Pronchery status = sys$setimr (EFN$C_ENF,
422b077aed3SPierre Pronchery BinTimeBuff,
423b077aed3SPierre Pronchery SocketPairTimeoutAst,
424b077aed3SPierre Pronchery &sptb,
425b077aed3SPierre Pronchery 0);
426b077aed3SPierre Pronchery if (! (status & 1)) {
427b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: SYS$SETIMR () - %08X", status);
428b077aed3SPierre Pronchery sys$cancel (TcpAcceptChan);
429b077aed3SPierre Pronchery close (SockDesc1);
430b077aed3SPierre Pronchery close (SockDesc2);
431b077aed3SPierre Pronchery sys$dassgn (TcpDeviceChan);
432b077aed3SPierre Pronchery return -1;
433b077aed3SPierre Pronchery }
434b077aed3SPierre Pronchery
435b077aed3SPierre Pronchery /*
436b077aed3SPierre Pronchery ** Now issue the connect
437b077aed3SPierre Pronchery */
438b077aed3SPierre Pronchery memset ((char *) &sin, 0, sizeof(sin)) ;
439b077aed3SPierre Pronchery sin.sin_family = SocketFamily;
440b077aed3SPierre Pronchery sin.sin_addr.s_addr = inet_addr (LocalHostAddr) ;
441b077aed3SPierre Pronchery sin.sin_port = LocalHostPort ;
442b077aed3SPierre Pronchery
443b077aed3SPierre Pronchery status = connect (SockDesc2, (struct sockaddr *) &sin, sizeof(sin));
444b077aed3SPierre Pronchery if (status < 0 ) {
445b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: connect () - %d", errno);
446b077aed3SPierre Pronchery sys$cantim (&sptb, 0);
447b077aed3SPierre Pronchery sys$cancel (TcpAcceptChan);
448b077aed3SPierre Pronchery close (SockDesc1);
449b077aed3SPierre Pronchery close (SockDesc2);
450b077aed3SPierre Pronchery sys$dassgn (TcpDeviceChan);
451b077aed3SPierre Pronchery return -1;
452b077aed3SPierre Pronchery }
453b077aed3SPierre Pronchery
454b077aed3SPierre Pronchery /*
455b077aed3SPierre Pronchery ** Wait for the asynch $QIO to finish. Note that if the I/O was aborted
456b077aed3SPierre Pronchery ** (SS$_ABORT), then we probably canceled it from the AST routine - so log
457b077aed3SPierre Pronchery ** a timeout.
458b077aed3SPierre Pronchery */
459b077aed3SPierre Pronchery status = sys$synch (EFN$C_ENF, &iosb);
460b077aed3SPierre Pronchery if (! (iosb.iosb$w_status & 1)) {
461b077aed3SPierre Pronchery if (iosb.iosb$w_status == SS$_ABORT)
462b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: SYS$QIO(iosb) timeout");
463b077aed3SPierre Pronchery else {
464b077aed3SPierre Pronchery LogMessage ("CreateSocketPair: SYS$QIO(iosb) - %d",
465b077aed3SPierre Pronchery iosb.iosb$w_status);
466b077aed3SPierre Pronchery sys$cantim (&sptb, 0);
467b077aed3SPierre Pronchery }
468b077aed3SPierre Pronchery close (SockDesc1);
469b077aed3SPierre Pronchery close (SockDesc2);
470b077aed3SPierre Pronchery sys$dassgn (TcpDeviceChan);
471b077aed3SPierre Pronchery return -1;
472b077aed3SPierre Pronchery }
473b077aed3SPierre Pronchery
474b077aed3SPierre Pronchery /*
475b077aed3SPierre Pronchery ** Here we're successfully connected, so cancel the timer, convert the
476b077aed3SPierre Pronchery ** I/O channel to a socket fd, close the listener socket and return the
477b077aed3SPierre Pronchery ** connected pair.
478b077aed3SPierre Pronchery */
479b077aed3SPierre Pronchery sys$cantim (&sptb, 0);
480b077aed3SPierre Pronchery
481b077aed3SPierre Pronchery close (SockDesc1) ;
482b077aed3SPierre Pronchery SocketPair[0] = SockDesc2 ;
483b077aed3SPierre Pronchery SocketPair[1] = socket_fd (TcpDeviceChan);
484b077aed3SPierre Pronchery
485b077aed3SPierre Pronchery return (0) ;
486b077aed3SPierre Pronchery
487b077aed3SPierre Pronchery }
488b077aed3SPierre Pronchery
489b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
490b077aed3SPierre Pronchery /* */
491b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
SocketPairTimeoutAst(int astparm)492b077aed3SPierre Pronchery static void SocketPairTimeoutAst (int astparm)
493b077aed3SPierre Pronchery {
494b077aed3SPierre Pronchery SPTB *sptb = (SPTB *) astparm;
495b077aed3SPierre Pronchery
496b077aed3SPierre Pronchery sys$cancel (sptb->SockChan2); /* Cancel the connect() */
497b077aed3SPierre Pronchery sys$cancel (sptb->SockChan1); /* Cancel the accept() */
498b077aed3SPierre Pronchery
499b077aed3SPierre Pronchery return;
500b077aed3SPierre Pronchery
501b077aed3SPierre Pronchery }
502b077aed3SPierre Pronchery
503b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
504b077aed3SPierre Pronchery /* */
505b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
TerminalDeviceAst(int astparm)506b077aed3SPierre Pronchery static int TerminalDeviceAst (int astparm)
507b077aed3SPierre Pronchery {
508b077aed3SPierre Pronchery int status;
509b077aed3SPierre Pronchery
510b077aed3SPierre Pronchery /*
511b077aed3SPierre Pronchery ** Terminate the terminal buffer
512b077aed3SPierre Pronchery */
513b077aed3SPierre Pronchery TerminalDeviceBuff[TerminalDeviceIosb.iosb$w_bcnt] = '\0';
514b077aed3SPierre Pronchery strcat (TerminalDeviceBuff, "\n");
515b077aed3SPierre Pronchery
516b077aed3SPierre Pronchery /*
517b077aed3SPierre Pronchery ** Send the data read from the terminal device through the socket pair
518b077aed3SPierre Pronchery */
519b077aed3SPierre Pronchery send (TerminalSocketPair[0], TerminalDeviceBuff,
520b077aed3SPierre Pronchery TerminalDeviceIosb.iosb$w_bcnt + 1, 0);
521b077aed3SPierre Pronchery
522b077aed3SPierre Pronchery /*
523b077aed3SPierre Pronchery ** Queue another async IO to the terminal device
524b077aed3SPierre Pronchery */
525b077aed3SPierre Pronchery status = sys$qio (EFN$C_ENF,
526b077aed3SPierre Pronchery TerminalDeviceChan,
527b077aed3SPierre Pronchery IO$_READVBLK,
528b077aed3SPierre Pronchery &TerminalDeviceIosb,
529b077aed3SPierre Pronchery TerminalDeviceAst,
530b077aed3SPierre Pronchery 0,
531b077aed3SPierre Pronchery TerminalDeviceBuff,
532b077aed3SPierre Pronchery sizeof(TerminalDeviceBuff) - 1,
533b077aed3SPierre Pronchery 0, 0, 0, 0);
534b077aed3SPierre Pronchery
535b077aed3SPierre Pronchery /*
536b077aed3SPierre Pronchery ** Return status
537b077aed3SPierre Pronchery */
538b077aed3SPierre Pronchery return status;
539b077aed3SPierre Pronchery
540b077aed3SPierre Pronchery }
541b077aed3SPierre Pronchery
542b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
543b077aed3SPierre Pronchery /* */
544b077aed3SPierre Pronchery /*----------------------------------------------------------------------------*/
LogMessage(char * msg,...)545b077aed3SPierre Pronchery static void LogMessage (char *msg, ...)
546b077aed3SPierre Pronchery {
547b077aed3SPierre Pronchery char *Month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
548b077aed3SPierre Pronchery "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
549b077aed3SPierre Pronchery static unsigned int pid = 0;
550b077aed3SPierre Pronchery va_list args;
551b077aed3SPierre Pronchery time_t CurTime;
552b077aed3SPierre Pronchery struct tm *LocTime;
553b077aed3SPierre Pronchery char MsgBuff[256];
554b077aed3SPierre Pronchery
555b077aed3SPierre Pronchery /*
556b077aed3SPierre Pronchery ** Get the process pid
557b077aed3SPierre Pronchery */
558b077aed3SPierre Pronchery if (pid == 0)
559b077aed3SPierre Pronchery pid = getpid ();
560b077aed3SPierre Pronchery
561b077aed3SPierre Pronchery /*
562b077aed3SPierre Pronchery ** Convert the current time into local time
563b077aed3SPierre Pronchery */
564b077aed3SPierre Pronchery CurTime = time (NULL);
565b077aed3SPierre Pronchery LocTime = localtime (&CurTime);
566b077aed3SPierre Pronchery
567b077aed3SPierre Pronchery /*
568b077aed3SPierre Pronchery ** Format the message buffer
569b077aed3SPierre Pronchery */
570*0d0c8621SEnji Cooper BIO_snprintf(MsgBuff, sizeof(MsgBuff), "%02d-%s-%04d %02d:%02d:%02d [%08X] %s\n",
571b077aed3SPierre Pronchery LocTime->tm_mday, Month[LocTime->tm_mon],
572b077aed3SPierre Pronchery (LocTime->tm_year + 1900), LocTime->tm_hour, LocTime->tm_min,
573b077aed3SPierre Pronchery LocTime->tm_sec, pid, msg);
574b077aed3SPierre Pronchery
575b077aed3SPierre Pronchery /*
576b077aed3SPierre Pronchery ** Get any variable arguments and add them to the print of the message
577b077aed3SPierre Pronchery ** buffer
578b077aed3SPierre Pronchery */
579b077aed3SPierre Pronchery va_start (args, msg);
580b077aed3SPierre Pronchery vfprintf (stderr, MsgBuff, args);
581b077aed3SPierre Pronchery va_end (args);
582b077aed3SPierre Pronchery
583b077aed3SPierre Pronchery /*
584b077aed3SPierre Pronchery ** Flush standard error output
585b077aed3SPierre Pronchery */
586b077aed3SPierre Pronchery fsync (fileno (stderr));
587b077aed3SPierre Pronchery
588b077aed3SPierre Pronchery return;
589b077aed3SPierre Pronchery
590b077aed3SPierre Pronchery }
591b077aed3SPierre Pronchery #endif
592