rxsock.h
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2021 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* https://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /***************************************************************************/
39 /* REXX sockets function support rxsock.h */
40 /* sockets utility function package */
41 /***************************************************************************/
42 
43 #include "oorexxapi.h"
44 
45 /*------------------------------------------------------------------
46  * typedef for struct
47  *------------------------------------------------------------------*/
48 typedef struct sockaddr_in sockaddr_in;
49 typedef struct in_addr in_addr;
50 
51 #if defined(WIN32)
52 typedef int socklen_t;
53 #endif
54 
55 class StemManager;
56 
57 
58 /*------------------------------------------------------------------
59  * strip blanks from a line
60  *------------------------------------------------------------------*/
61 void stripBlanks(char *string);
62 
63 /*------------------------------------------------------------------
64  * convert a stem variable to an array of ints
65  *------------------------------------------------------------------*/
66 void stemToIntArray(RexxCallContext *context, RexxObjectPtr stem, int &count, int *&arr);
67 
68 /*------------------------------------------------------------------
69  * convert an array of ints to a stem variable
70  *------------------------------------------------------------------*/
71 void intArrayToStem(RexxCallContext *context, RexxObjectPtr stem, int count, int *arr);
72 
73 /*------------------------------------------------------------------
74  * convert a stemmed variable to a sockaddr
75  *------------------------------------------------------------------*/
77 
78 /*------------------------------------------------------------------
79  * convert a sockaddr to a stemmed variable
80  *------------------------------------------------------------------*/
82 
83 /*------------------------------------------------------------------
84  * convert a hostent to a stemmed variable
85  *------------------------------------------------------------------*/
86 void hostEntToStem(RexxCallContext *context, struct hostent *pHostEnt, StemManager &stem);
87 
88 /*------------------------------------------------------------------
89  * convert a string sock option to an integer
90  *------------------------------------------------------------------*/
91 int stringToSockOpt(const char *pszOptName);
92 
93 /*------------------------------------------------------------------
94  * set errno
95  *------------------------------------------------------------------*/
96 void setErrno(RexxCallContext *context, bool noError);
97 
98 /*------------------------------------------------------------------
99  * portable caseless compare function.
100  *------------------------------------------------------------------*/
101 int caselessCompare(const char *op1, const char *op2);
102 
103 
105 {
106 public:
107  StemManager(RexxCallContext *c) : context(c), stem(NULL), prefix(NULL) { }
109  {
110  if (prefix != NULL)
111  {
112  free(prefix);
113  }
114  }
115 
116  /**
117  * Resolve the stem object that was passed as an argument.
118  *
119  * @param source The source argument object.
120  *
121  * @return true if the stem could be resolved, false for any errors
122  * resolving the stem object.
123  */
125  {
126  // handle the case where no stem was provided at all
127  if (source == NULL) {
128  return false;
129  }
130  // this is the simplest solution
131  if (context->IsStem(source))
132  {
133  stem = (RexxStemObject)source;
134  }
135  else
136  {
137  const char *stemName = context->ObjectToStringValue(source);
138  const char *dotPos = strchr(stemName, '.');
139  // if no dot or the dot is the last character, this is a standard
140  // stem value
141  if (dotPos == NULL || dotPos == (stemName + strlen(stemName) - 1))
142  {
143  stem = context->ResolveStemVariable(source);
144  }
145  else
146  {
147  prefix = strdup(dotPos + 1);
148  if (prefix == NULL)
149  {
150  context->InvalidRoutine();
151  return false;
152  }
153 
154  // uppercase the rest of the prefix value
155  char *scanner = prefix;
156  while (*scanner != '\0')
157  {
158  *scanner = toupper(*scanner);
159  scanner++;
160  }
161  RexxStringObject stemPortion = context->String(stemName, (dotPos - stemName) + 1);
162  stem = context->ResolveStemVariable(stemPortion);
163  }
164  if (stem == NULL)
165  {
166  // context->InvalidRoutine();
167  // don't call context->InvalidRoutine() because we
168  // want to allow an empty string as a parm
169  return false;
170  }
171  }
172  return true;
173  }
174 
175  /**
176  * Set a value in the argument stem.
177  *
178  * @param name The name to set.
179  * @param value
180  */
181  void setValue(const char *name, RexxObjectPtr value)
182  {
183  if (prefix == NULL)
184  {
185  context->SetStemElement(stem, name, value);
186  }
187  else
188  {
189  char fullName[256];
190  snprintf(fullName, sizeof fullName, "%s%s", prefix, name);
191  context->SetStemElement(stem, fullName, value);
192  }
193  }
194 
195  /**
196  * Set a value in the argument stem.
197  *
198  * @param index The index to set.
199  * @param value
200  */
201  void setValue(size_t index, RexxObjectPtr value)
202  {
203  if (prefix == NULL)
204  {
205  context->SetStemArrayElement(stem, index, value);
206  }
207  else
208  {
209  char fullName[256];
210  snprintf(fullName, sizeof fullName, "%s.%d", prefix, (int)index);
211  context->SetStemElement(stem, fullName, value);
212  }
213  }
214 
215  /**
216  * Retrieve a value from an argument stem.
217  *
218  * @param name The argument stem name.
219  *
220  * @return The retrieved object, if any.
221  */
222  RexxObjectPtr getValue(const char *name)
223  {
224  if (prefix == NULL)
225  {
226  return context->GetStemElement(stem, name);
227  }
228  else
229  {
230  char fullName[256];
231  snprintf(fullName, sizeof fullName, "%s%s", prefix, name);
232  return context->GetStemElement(stem, fullName);
233  }
234  }
235 
236  RexxObjectPtr getValue(size_t index)
237  {
238  if (prefix == NULL)
239  {
240  return context->GetStemArrayElement(stem, index);
241  }
242  else
243  {
244  char fullName[256];
245  snprintf(fullName, sizeof fullName, "%s.%d", prefix, (int)index);
246  return context->GetStemElement(stem, fullName);
247  }
248  }
249 
250 
251 protected:
252  RexxCallContext *context; // the context pointer
253  RexxStemObject stem; // the target stem
254  char *prefix; // extra prefix to use on the stem
255 };
~StemManager()
Definition: rxsock.h:108
RexxCallContext * context
Definition: rxsock.h:252
char * prefix
Definition: rxsock.h:254
StemManager(RexxCallContext *c)
Definition: rxsock.h:107
RexxObjectPtr getValue(const char *name)
Definition: rxsock.h:222
bool resolveStem(RexxObjectPtr source)
Definition: rxsock.h:124
RexxStemObject stem
Definition: rxsock.h:253
void setValue(size_t index, RexxObjectPtr value)
Definition: rxsock.h:201
void setValue(const char *name, RexxObjectPtr value)
Definition: rxsock.h:181
RexxObjectPtr getValue(size_t index)
Definition: rxsock.h:236
struct _RexxStringObject * RexxStringObject
Definition: rexx.h:128
struct _RexxObjectPtr * RexxObjectPtr
Definition: rexx.h:127
struct _RexxStemObject * RexxStemObject
Definition: rexx.h:139
void setErrno(RexxCallContext *context, bool noError)
Definition: rxsock.cpp:453
void intArrayToStem(RexxCallContext *context, RexxObjectPtr stem, int count, int *arr)
Definition: rxsock.cpp:232
void stemToIntArray(RexxCallContext *context, RexxObjectPtr stem, int &count, int *&arr)
Definition: rxsock.cpp:173
struct sockaddr_in sockaddr_in
Definition: rxsock.h:48
int stringToSockOpt(const char *pszOptName)
Definition: rxsock.cpp:422
void stemToSockAddr(RexxCallContext *context, StemManager &stem, sockaddr_in *pSockAddr)
Definition: rxsock.cpp:261
void hostEntToStem(RexxCallContext *context, struct hostent *pHostEnt, StemManager &stem)
Definition: rxsock.cpp:364
void sockAddrToStem(RexxCallContext *context, sockaddr_in *pSockAddr, StemManager &stem)
Definition: rxsock.cpp:343
int caselessCompare(const char *op1, const char *op2)
Definition: rxsock.cpp:108
void stripBlanks(char *string)
Definition: rxsock.cpp:124
struct in_addr in_addr
Definition: rxsock.h:49