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