1 /* 2 * The Regina Rexx Interpreter 3 * Copyright (C) 2000 Mark Hessling <M.Hessling@qut.edu.au> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public 16 * License along with this library; if not, write to the Free 17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 #include "rexxbif.h" /* C functions that mimic REXX BIFs */ 20 21 #define FIFO_LINE(buf,line) { \ 22 /* This macro adds a line to a buffer in FIFO manner. \ 23 * The line's higher/lower elements will be overwritten both. \ 24 */ \ 25 (line)->lower = NULL ; \ 26 (line)->higher = (buf)->bottom ; \ 27 (buf)->bottom = line ; \ 28 if ( (line)->higher != NULL ) \ 29 (line)->higher->lower = (line) ; \ 30 else \ 31 { \ 32 (buf)->top = (line) ; /* buffer was empty previously */ \ 33 assert( (buf)->elements == 0 ) ; \ 34 } \ 35 (buf)->elements++ ; \ 36 } 37 38 #define LIFO_LINE(buf,line) { \ 39 /* This macro adds a line to a buffer in LIFO manner. \ 40 * The line's higher/lower elements will be overwritten both. \ 41 */ \ 42 (line)->higher = NULL ; \ 43 (line)->lower = (buf)->top ; \ 44 (buf)->top = line ; \ 45 if ( (line)->lower != NULL ) \ 46 (line)->lower->higher = (line) ; \ 47 else \ 48 { \ 49 (buf)->bottom = (line) ; /* buffer was empty previously */ \ 50 assert( (buf)->elements == 0 ) ; \ 51 } \ 52 (buf)->elements++ ; \ 53 } 54 55 #define POP_LINE(buf,line) { \ 56 /* This macro removes a line from a buffer. The argument "line" \ 57 * will be overwritten. The higher/older elements of that value \ 58 * won't be overwritten. \ 59 */ \ 60 if ( ( (line) = (buf)->top ) != NULL ) \ 61 { \ 62 (buf)->elements-- ; \ 63 if ( ( (buf)->top = (line)->lower ) == NULL ) \ 64 { \ 65 (buf)->bottom = NULL ; \ 66 assert( (buf)->elements == 0 ) ; \ 67 (buf)->elements = 0 ; /* if assert is defined out */ \ 68 } \ 69 else \ 70 { \ 71 (buf)->top->higher = NULL ; \ 72 } \ 73 } \ 74 } 75 76 #define GLUE_BUFFER1(buf1,buf2) { \ 77 /* This macro glues buf2 at the top of buf1 and writes the result \ 78 * to buf1. buf2's top/bottom/elements fields are reset. \ 79 */ \ 80 if ( (buf2)->bottom != NULL ) \ 81 { \ 82 if ( (buf1)->top == NULL ) \ 83 { \ 84 assert( ( (buf1)->bottom == NULL ) && ( (buf1)->elements == 0 ) ) ;\ 85 (buf1)->top = (buf2)->top ; \ 86 (buf1)->bottom = (buf2)->bottom ; \ 87 (buf1)->elements = (buf2)->elements ; \ 88 } \ 89 else \ 90 { \ 91 (buf1)->top->higher = (buf2)->bottom ; \ 92 (buf2)->bottom->lower = (buf1)->top ; \ 93 (buf1)->top = (buf2)->top ; \ 94 (buf1)->elements += (buf2)->elements ; \ 95 } \ 96 } \ 97 else \ 98 { \ 99 assert( ( (buf2)->top == NULL ) && ( (buf2)->elements == 0 ) ) ; \ 100 } \ 101 (buf2)->top = NULL ; \ 102 (buf2)->bottom = NULL ; \ 103 (buf2)->elements = 0 ; \ 104 } 105 106 #define GLUE_BUFFER2(buf1,buf2) { \ 107 /* This macro glues buf2 at the top of buf1 and writes the result \ 108 * to buf2. buf1's top/bottom/elements fields are reset. \ 109 */ \ 110 if ( (buf1)->bottom != NULL ) \ 111 { \ 112 if ( (buf2)->top == NULL ) \ 113 { \ 114 assert( ( (buf2)->bottom == NULL ) && ( (buf2)->elements == 0 ) ) ;\ 115 (buf2)->top = (buf1)->top ; \ 116 (buf2)->bottom = (buf1)->bottom ; \ 117 (buf2)->elements = (buf1)->elements ; \ 118 } \ 119 else \ 120 { \ 121 (buf1)->top->higher = (buf2)->bottom ; \ 122 (buf2)->bottom->lower = (buf1)->top ; \ 123 (buf2)->bottom = (buf1)->bottom ; \ 124 (buf2)->elements += (buf2)->elements ; \ 125 } \ 126 } \ 127 else \ 128 { \ 129 assert( ( (buf1)->top == NULL ) && ( (buf1)->elements == 0 ) ) ; \ 130 } \ 131 (buf1)->top = NULL ; \ 132 (buf1)->bottom = NULL ; \ 133 (buf1)->elements = 0 ; \ 134 } 135 136 void showerror( int err, int suberr, char *tmpl, ...); 137 int init_external_queue( const tsd_t *TSD ); 138 void term_external_queue( void ); 139 int default_port_number( void ) ; 140 int default_external_address( void ) ; 141 streng *default_external_name( const tsd_t *TSD ) ; 142 int connect_to_rxstack( tsd_t *TSD, Queue *q ) ; 143 int disconnect_from_rxstack( const tsd_t *TSD, Queue *q ) ; 144 int parse_queue( tsd_t *TSD, streng *queue, Queue *q ) ; 145 int send_command_to_rxstack( const tsd_t *TSD, int sock, const char *action, const char *str, int len ); 146 streng *read_result_from_rxstack( const tsd_t *TSD, int sock, int result_size ); 147 int delete_queue_from_rxstack( const tsd_t *TSD, int sock, const streng *queue_name ); 148 int set_queue_in_rxstack( const tsd_t *TSD, int sock, const streng *queue_name ); 149 int get_number_in_queue_from_rxstack( const tsd_t *TSD, int sock, int *errcode ); 150 int get_queues_from_rxstack( const tsd_t *TSD, int sock, int *errcode, streng **results ); 151 int clear_queue_on_rxstack( const tsd_t *TSD, int sock ) ; 152 int get_queue_from_rxstack( const tsd_t *TSD, const Queue *q, streng **result ); 153 int create_queue_on_rxstack( const tsd_t *TSD, const Queue *q, const streng *queue, streng **result ); 154 int timeout_queue_on_rxstack( const tsd_t *TSD, int sock, long timeout ); 155 int get_line_from_rxstack( const tsd_t *TSD, int sock, streng **result, int nowait ); 156 int queue_line_lifo_to_rxstack( const tsd_t *TSD, int sock, const streng *line ); 157 int queue_line_fifo_to_rxstack( const tsd_t *TSD, int sock, const streng *line ); 158 int get_length_from_header( const tsd_t *TSD, const streng *header ); 159 160 #define RXSTACK_EXIT 'X' 161 #define RXSTACK_EXIT_STR "X" 162 #define RXSTACK_KILL 'Z' 163 #define RXSTACK_KILL_STR "Z" 164 #define RXSTACK_QUEUE_FIFO 'F' 165 #define RXSTACK_QUEUE_FIFO_STR "F" 166 #define RXSTACK_QUEUE_LIFO 'L' 167 #define RXSTACK_QUEUE_LIFO_STR "L" 168 #define RXSTACK_CREATE_QUEUE 'C' 169 #define RXSTACK_CREATE_QUEUE_STR "C" 170 #define RXSTACK_DELETE_QUEUE 'D' 171 #define RXSTACK_DELETE_QUEUE_STR "D" 172 #define RXSTACK_EMPTY_QUEUE 'E' 173 #define RXSTACK_EMPTY_QUEUE_STR "E" 174 #define RXSTACK_PULL 'P' 175 #define RXSTACK_PULL_STR "P" 176 #define RXSTACK_FETCH 'p' 177 #define RXSTACK_FETCH_STR "p" 178 #define RXSTACK_SET_QUEUE 'S' 179 #define RXSTACK_SET_QUEUE_STR "S" 180 #define RXSTACK_GET_QUEUE 'G' 181 #define RXSTACK_GET_QUEUE_STR "G" 182 #define RXSTACK_NUMBER_IN_QUEUE 'N' 183 #define RXSTACK_NUMBER_IN_QUEUE_STR "N" 184 #define RXSTACK_SHOW_QUEUES 'Q' 185 #define RXSTACK_SHOW_QUEUES_STR "Q" 186 #define RXSTACK_TIMEOUT_QUEUE 'T' 187 #define RXSTACK_TIMEOUT_QUEUE_STR "T" 188 #define RXSTACK_UNKNOWN '?' 189 #define RXSTACK_UNKNOWN_STR "?" 190 #define RXSTACK_HEADER_SIZE 7 191 #define RXSTACK_PEEK_HEADER_SIZE 2 192 #define RXSTACK_TIMEOUT_SIZE 6 193 194 #ifndef RXSOCKET 195 # define RXSOCKET 5757 196 #endif 197 198 #define ERR_RXSTACK_CANT_CONNECT 101 199 #define ERR_RXSTACK_CANT_CONNECT_TMPL "Error connecting to %s on port %d: \"%s\"" 200 #define ERR_RXSTACK_NO_IP 102 201 #define ERR_RXSTACK_NO_IP_TMPL "Unable to obtain IP address for %s" 202 #define ERR_RXSTACK_INVALID_SERVER 103 203 #define ERR_RXSTACK_INVALID_SERVER_TMPL "Invalid format for server in specified queue name: \"%s\"" 204 #define ERR_RXSTACK_INVALID_QUEUE 104 205 #define ERR_RXSTACK_INVALID_QUEUE_TMPL "Invalid format for queue name: \"%s\"" 206 #define ERR_RXSTACK_NO_WINSOCK 105 207 #define ERR_RXSTACK_NO_WINSOCK_TMPL "Unable to start Windows Socket interface: %s" 208 #define ERR_RXSTACK_TOO_MANY_QUEUES 106 209 #define ERR_RXSTACK_TOO_MANY_QUEUES_TMPL "Maximum number of external queues exceeded: %d" 210 #define ERR_RXSTACK_READING_SOCKET 107 211 #define ERR_RXSTACK_READING_SOCKET_TMPL "Error occured reading socket: %s" 212 #define ERR_RXSTACK_INVALID_SWITCH 108 213 #define ERR_RXSTACK_INVALID_SWITCH_TMPL "Invalid switch passed. Must be one of \"%s\"" 214 #define ERR_RXSTACK_ACTION_SESSION 112 215 #define ERR_RXSTACK_ACTION_SESSION_TMPL "Unable to %s SESSION queue" 216 217 #define ERR_RXSTACK_INTERNAL 99 218 #define ERR_RXSTACK_INTERNAL_TMPL "Internal error with external queue interface: %d \"%s\"" 219 #define ERR_RXSTACK_GENERAL 100 220 #define ERR_RXSTACK_GENERAL_TMPL "General system error with external queue interface. %s. %s" 221 222 #define ERR_STORAGE_EXHAUSTED_TMPL "System resources exhausted" 223 224 /* 225 * Return codes from interacting with rxstack 226 */ 227 #define RXSTACK_OK 0 228 #define RXSTACK_EMPTY 1 229 #define RXSTACK_ERROR 2 230 #define RXSTACK_WAITING 3 231 #define RXSTACK_TIMEOUT 4 232