2 static char *RCSid
= "$Id$";
6 * The Regina Rexx Interpreter
7 * Copyright (C) 1992-1994 Anders Christensen <anders@pvv.unit.no>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 # include "configur.h"
33 # if defined(_MSC_VER)
35 /* Stupid MSC can't compile own headers without warning at least in VC 5.0 */
36 # pragma warning(disable: 4115 4201 4214)
40 # pragma warning(default: 4115 4201 4214)
47 # ifdef HAVE_SYS_SOCKET_H
48 # include <sys/socket.h>
50 # ifdef HAVE_NETINET_IN_H
51 # include <netinet/in.h>
53 # ifdef HAVE_SYS_SELECT_H
54 # include <sys/select.h>
59 # ifdef HAVE_ARPA_INET_H
60 # include <arpa/inet.h>
80 #define SUCCESS(a) ((a)&&(a)->value[0] == '0')
83 # define DEBUGDUMP(x) {x;}
85 # define DEBUGDUMP(x) {}
89 unsigned int bufflen
=0;
91 #if !defined(HAVE_STRERROR)
93 * Sigh! This must probably be done this way, although it's incredibly
94 * backwards. Some versions of gcc comes with a complete set of ANSI C
95 * include files, which contains the definition of strerror(). However,
96 * that function does not exist in the default libraries of SunOS.
97 * To circumvent that problem, strerror() is #define'd to get_sys_errlist()
98 * in config.h, and here follows the definition of that function.
99 * Originally, strerror() was #defined to sys_errlist[x], but that does
100 * not work if string.h contains a declaration of the (non-existing)
101 * function strerror().
103 * So, this is a mismatch between the include files and the library, and
104 * it should not create problems for Regina. However, the _user_ will not
105 * encounter any problems until he compiles Regina, so we'll have to
106 * clean up after a buggy installation of the C compiler!
108 const char *get_sys_errlist( int num
)
110 extern char *sys_errlist
[] ;
111 return sys_errlist
[num
] ;
115 int send_all( int sock
, char *action
)
118 * Send everything in stdin to the socket. Each LF encountered
120 * This code borrowed from rxstack.c in REXX/imc
129 while ( ( c
= getchar() ) != EOF
&& c
!= '\n' )
132 && (( buff
= realloc( buff
, bufflen
<<= 1 ) ) == NULL
) )
134 showerror( ERR_STORAGE_EXHAUSTED
, 0, ERR_STORAGE_EXHAUSTED_TMPL
);
135 exit( ERR_STORAGE_EXHAUSTED
);
137 buff
[len
++] = (char)c
;
139 if ( (c
== EOF
|| feof(stdin
) )
142 DEBUGDUMP(printf("--- Queue %s ---\n", action
[0] == RXSTACK_QUEUE_FIFO
? "FIFO" : "LIFO"););
143 rc
= send_command_to_rxstack( NULL
, sock
, action
, buff
, len
);
146 result
= read_result_from_rxstack( NULL
, sock
, RXSTACK_HEADER_SIZE
);
147 DROPSTRENG( result
);
153 char *get_unspecified_queue( void )
155 char *rxq
= getenv( "RXQUEUE" );
162 char *get_action( char *parm
)
166 if ( strcmp( parm
, "/fifo" ) == 0 )
167 action
= RXSTACK_QUEUE_FIFO_STR
;
168 else if ( strcmp( parm
, "/lifo" ) == 0 )
169 action
= RXSTACK_QUEUE_LIFO_STR
;
170 else if ( strcmp( parm
, "/clear" ) == 0 )
171 action
= RXSTACK_EMPTY_QUEUE_STR
;
172 else if ( strcmp( parm
, "/pull" ) == 0 )
173 action
= RXSTACK_PULL_STR
;
174 else if ( strcmp( parm
, "/queued" ) == 0 )
175 action
= RXSTACK_NUMBER_IN_QUEUE_STR
;
178 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INVALID_SWITCH
, ERR_RXSTACK_INVALID_SWITCH_TMPL
, "/fifo, /lifo, /clear, /queued, /pull" );
179 /* not setting action will exit */
184 void junk_return_from_rxstack( int sock
, streng
*header
)
189 length
= get_length_from_header( NULL
, header
);
192 result
= read_result_from_rxstack( NULL
, sock
, length
);
194 DROPSTRENG( result
);
209 int main( int argc
, char *argv
[])
211 int sock
,portno
,rc
=0,i
,num
;
213 streng
*queue
=NULL
,*server_name
=NULL
;
218 WORD wsver
= (WORD
)MAKEWORD(1,1);
223 if ( WSAStartup( wsver
, &wsaData
) != 0 )
225 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_NO_WINSOCK
, ERR_RXSTACK_NO_WINSOCK_TMPL
, WSAGetLastError() );
226 exit(ERR_RXSTACK_NO_WINSOCK
);
232 * Process the command line
239 action
= RXSTACK_QUEUE_FIFO_STR
;
240 in_queue
= get_unspecified_queue();
242 else if ( argc
== 2 )
249 if ( argv
[1][0] == '/' )
252 * Only parameter is a switch
254 in_queue
= get_unspecified_queue();
255 action
= get_action( argv
[1] );
260 * Only parameter is a queue name
263 action
= RXSTACK_QUEUE_FIFO_STR
;
266 else if ( argc
== 3 )
269 * "rxqueue queue /switch"
272 if ( argv
[2][0] == '/' )
275 * Parameter is a switch
277 action
= get_action( argv
[2] );
285 fprintf(stderr
, "Invalid number of parameters\n");
290 queue
= MAKESTRENG( strlen( in_queue
) );
293 showerror( ERR_STORAGE_EXHAUSTED
, 0, ERR_STORAGE_EXHAUSTED_TMPL
);
294 exit(ERR_STORAGE_EXHAUSTED
);
296 memcpy( PSTRENGVAL( queue
), in_queue
, PSTRENGLEN( queue
) );
298 * Parse the queue to determine server address
301 if ( parse_queue( NULL
, queue
, &server_name
, &server_address
, &portno
) == 0 )
303 if ( PSTRENGLEN( queue
) == 0 )
306 queue
= MAKESTRENG( strlen( in_queue
) );
309 showerror( ERR_STORAGE_EXHAUSTED
, 0, ERR_STORAGE_EXHAUSTED_TMPL
);
310 exit(ERR_STORAGE_EXHAUSTED
);
312 memcpy( PSTRENGVAL( queue
), "SESSION", PSTRENGLEN( queue
) );
314 DEBUGDUMP(printf( "queue: <%s> server: %s<%d> Port:%d\n", PSTRENGVAL( queue
), PSTRENGVAL( server_name
), server_address
,portno
););
315 sock
= connect_to_rxstack( NULL
, portno
, server_name
, server_address
);
319 exit(ERR_RXSTACK_CANT_CONNECT
);
322 * Now process the actual command
326 case RXSTACK_QUEUE_FIFO
:
327 case RXSTACK_QUEUE_LIFO
:
328 DEBUGDUMP(printf("--- Queue %s ", action
[0] == RXSTACK_QUEUE_FIFO
? "FIFO" : "LIFO"););
330 * Allocate the initial buffer
332 if (( buff
= (char *)malloc( bufflen
= 256 ) ) == NULL
)
334 showerror( ERR_STORAGE_EXHAUSTED
, 0, ERR_STORAGE_EXHAUSTED_TMPL
);
335 rc
= ERR_STORAGE_EXHAUSTED
;
339 * Set the current queue
341 DEBUGDUMP(printf("(Set Queue) ---\n"););
342 rc
= send_command_to_rxstack( NULL
, sock
, RXSTACK_SET_QUEUE_STR
, PSTRENGVAL( queue
) , PSTRENGLEN( queue
) );
345 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Setting default queue" );
346 rc
= ERR_RXSTACK_INTERNAL
;
349 result
= read_result_from_rxstack( NULL
, sock
, RXSTACK_HEADER_SIZE
);
350 if ( !SUCCESS( result
) )
352 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Setting default queue" );
353 DROPSTRENG( result
);
354 rc
= ERR_RXSTACK_INTERNAL
;
358 * Success. We need to throw away the returned queue name. We
361 junk_return_from_rxstack( sock
, result
);
362 send_all( sock
, action
);
363 DROPSTRENG( result
);
366 case RXSTACK_EMPTY_QUEUE
:
367 DEBUGDUMP(printf("--- Empty Queue ---\n"););
368 rc
= send_command_to_rxstack( NULL
, sock
, action
, PSTRENGVAL( queue
) , PSTRENGLEN( queue
) );
371 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Emptying queue" );
372 rc
= ERR_RXSTACK_INTERNAL
;
375 result
= read_result_from_rxstack( NULL
, sock
, RXSTACK_HEADER_SIZE
);
376 if ( !SUCCESS( result
) )
378 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Emptying queue" );
379 DROPSTRENG( result
);
380 rc
= ERR_RXSTACK_INTERNAL
;
383 DROPSTRENG( result
);
386 case RXSTACK_NUMBER_IN_QUEUE
:
388 * Set the current queue
390 DEBUGDUMP(printf("--- Set Queue ---\n"););
391 rc
= send_command_to_rxstack( NULL
, sock
, RXSTACK_SET_QUEUE_STR
, PSTRENGVAL( queue
), PSTRENGLEN( queue
) );
394 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Setting default queue" );
395 rc
= ERR_RXSTACK_INTERNAL
;
399 * Read the return response header
401 result
= read_result_from_rxstack( NULL
, sock
, RXSTACK_HEADER_SIZE
);
402 if ( !SUCCESS( result
) )
404 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Setting default queue" );
405 DROPSTRENG( result
);
406 rc
= ERR_RXSTACK_INTERNAL
;
410 * Success. We need to throw away the returned queue name. We
413 junk_return_from_rxstack( sock
, result
);
414 DROPSTRENG( result
);
415 DEBUGDUMP(printf("--- Number in Queue ---\n"););
416 num
= get_number_in_queue_from_rxstack( NULL
, sock
);
417 printf("%d\n", num
);
422 * Set the current queue
424 DEBUGDUMP(printf("--- Set Queue ---\n"););
425 rc
= send_command_to_rxstack( NULL
, sock
, RXSTACK_SET_QUEUE_STR
, PSTRENGVAL( queue
), PSTRENGLEN( queue
) );
428 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Setting default queue" );
429 rc
= ERR_RXSTACK_INTERNAL
;
432 result
= read_result_from_rxstack( NULL
, sock
, RXSTACK_HEADER_SIZE
);
433 if ( !SUCCESS( result
) )
435 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Setting default queue" );
436 DROPSTRENG( result
);
437 rc
= ERR_RXSTACK_INTERNAL
;
441 * Success. We need to throw away the returned queue name. We
444 junk_return_from_rxstack( sock
, result
);
445 DROPSTRENG( result
);
447 * Loop until the number of lines on the queue is zero
451 DEBUGDUMP(printf("--- Pull ---\n"););
452 rc
= get_line_from_rxstack( NULL
, sock
, &result
);
455 for ( i
= 0; i
< PSTRENGLEN( result
); i
++ )
457 putchar( result
->value
[i
] );
463 showerror( ERR_EXTERNAL_QUEUE
, ERR_RXSTACK_INTERNAL
, ERR_RXSTACK_INTERNAL_TMPL
, rc
, "Getting line from queue" );
464 rc
= ERR_RXSTACK_INTERNAL
;
475 DROPSTRENG( result
);
480 * Tell the server we want to disconnect
481 * Don't expect any return result.
483 DEBUGDUMP(printf("--- Exit ---\n"););
484 send_command_to_rxstack( NULL
, sock
, RXSTACK_EXIT_STR
, NULL
, 0 );
489 DEBUGDUMP(printf( "queue: <%s> server: %s<%d> Port:%d\n", PSTRENGVAL( queue
), PSTRENGVAL( server_name
), server_address
,portno
););
492 DROPSTRENG( server_name
);