25 saw 1.1 * Revision 1.4 1995/08/03 13:50:52 saw
26 * Add SGI compatibility
27 *
28 * Revision 1.3 1994/11/07 14:09:42 saw
29 * Bug fixes in thGetList_test and callback server code.
30 *
31 * Revision 1.2 1994/10/17 17:07:28 saw
32 * Add thGetList_test and the callback service davar_readmultiple_test_cb_1
33 *
34 * Revision 1.1 1994/09/27 19:19:09 saw
35 * Initial revision
36 *
37 */
38 #include <stdio.h>
39 #include <string.h>
40 #include <rpc/rpc.h>
41 #include "daVar.h"
42 #include "daVarRpc.h"
43 #include "cfortran.h"
44
45 long thCreateList(); /* Move to some include file */
46 saw 1.1 long thAddToList(long handle, char *pattern);
47 long thRemoveFromList(long handle, char *pattern);
48 long thGetList(long handle, CLIENT *clnt);
49 long thGetList_test(long handle, CLIENT *clnt, char *test_condition,
50 int max_time_wait, int max_event_wait);
51 long thPrintList(long handle);
52
53 FCALLSCFUN0(LONG,thCreateList,THCRLIST,thcrlist);
54 FCALLSCFUN2(LONG,thAddToList,THADDLIST,thaddlist,LONG,STRING);
55 FCALLSCFUN2(LONG,thRemoveFromList,THREMLIST,thremlist,LONG,STRING);
56 #ifdef __osf__
57 FCALLSCFUN2(LONG,thGetList,THGETLIST,thgetlist,LONG,PVOID);
58 FCALLSCFUN5(LONG,thGetList_test,THCGETLIST,thcgetlist,LONG,PVOID,STRING,INT,INT);
59 #else
60 FCALLSCFUN2(LONG,thGetList,THGETLIST,thgetlist,LONG,LONG);
61 FCALLSCFUN5(LONG,thGetList_test,THCGETLIST,thcgetlist,LONG,LONG,STRING,INT,INT);
62 #endif
63 FCALLSCFUN1(LONG,thPrintList,THPRTLIST,thprtlist,LONG);
64 /* Don't really understand the following. What about ultrix */
|
74 saw 1.1 #if !defined(__ultrix__) && !defined(linux)
75 FCALLSCFUN4(LONG,clnt_create,CLNT_CREATE,clnt_create,STRING,LONG,LONG,STRING);
76 #else
77 FCALLSCFUN4(LONG,clnt_create,CLNT_CREATE_,clnt_create_,STRING,LONG,LONG,STRING);
78 #endif
79
80 struct thNameNode {
81 char *name;
82 struct thNameNode *next;
83 };
84 typedef struct thNameNode thNameNode;
85
86 struct thNameList {
87 thNameNode *namehead;
88 int nnames; /* Number of names in list */
89 int rpc_made;
90 NAMELIST rpc; /* List in form for RPC argument */
91 };
92 typedef struct thNameList thNameList;
93
94 TESTNAMELIST *pending_arg=0;
95 saw 1.1 int pending_flag=0;
96 int callback_result;
97
98 long thCreateList(){
99 /* Create a handle for a list of variables */
100 thNameList *list;
101
102 list = (thNameList *) malloc(sizeof(thNameList));;
103 list->namehead = 0;
104 list->nnames = 0;
105 list->rpc_made = 0;
106 list->rpc.NAMELIST_len = 0;
107 list->rpc.NAMELIST_val = 0;
108 return((long) list);
109 }
110 long thAddToList(long handle, char *pattern)
111 /* Add registered variables to a list of variables to get from a server
112 Return the number of variables added
113 Should we check for duplicates? Not now. No harm in duplicates.
114 thRemoveFromList will remove all duplicates though. */
115 {
116 saw 1.1 thNameList *list;
117 thNameNode *next,*this;
118 char **vlist; /* List of characters matching pattern */
119 int count; /* Number of variables being added */
120 int i;
121
122 list = (thNameList *) handle;
123 daVarList(pattern,&vlist,&count);
124 for(i=0;i<count;i++) {
125 next = list->namehead; /* The current list */
126 this = list->namehead = (thNameNode *) malloc(sizeof(thNameNode)); /* New name */
127 this->name = (char *) malloc(strlen(vlist[i])+1);
128 strcpy(this->name,vlist[i]);
129 this->next = next; /* Attach rest of list */
130 }
131 list->nnames += count; /* Perhaps I should just count when needed ? */
132 list->rpc_made = 0; /* RPC format list now out of date. */
133 return(list->nnames);
134 }
135 long thRemoveFromList(long handle, char *pattern)
136 {
137 saw 1.1 thNameList *list;
138 thNameNode *this,**thisp;
139 char **vlist; /* List of characters matching pattern */
140 int count; /* Number of variables being removed */
141 int nremove;
142 int i;
143
144 list = (thNameList *) handle;
145 daVarList(pattern,&vlist,&count);
146 nremove = 0;
147 for(i=0;i<count;i++) {
148 this = list->namehead; /* Start of list */
149 thisp = &list->namehead; /* Pointer to next field of previous name */
150 while(this) {
151 if(strcasecmp(this->name,vlist[i])==0) { /* Remove matching string */
152 *thisp = this->next;
153 free(this->name);
154 free(this);
155 this = *thisp;
156 nremove++;
157 } else {
158 saw 1.1 thisp = &(this->next);
159 this = this->next;
160 }
161 }
162 }
163 list->nnames -= nremove; /* Perhaps I should just count when needed ? */
164 return(list->nnames);
165 }
166 long thPrintList(long handle)
167 /* For debugging */
168 {
169 thNameList *list;
170 thNameNode *next,*this;
171 int count;
172
173 list = (thNameList *) handle;
174 this = list->namehead;
175 printf("Variables attached to handle %d\n",handle);
176 count++;
177 while(this) {
178 printf("%s\n",this->name);
179 saw 1.1 count++;
180 this = this->next;
181 }
182 return(count);
183 }
184 long thGetList(long handle, CLIENT *clnt)
185 /* Returns 0 for total success, -1 for total failure, a positive number
186 for the number of variables that didn't work */
187 {
188 thNameList *list;
189 thNameNode *next,*this;
190 int i;
191 RVALLIST *vals;
192 int nerrors;
193
194 list = (thNameList *) handle;
195 /* printf("list->nnames=%d\n",list->nnames);*/
196 if(!list->rpc_made) {
197 if(list->rpc.NAMELIST_len == 0) {
198 list->rpc.NAMELIST_len = list->nnames;
199 list->rpc.NAMELIST_val = (char **) malloc(list->rpc.NAMELIST_len
200 saw 1.1 *sizeof(char *));
201 } else if (list->rpc.NAMELIST_len != list->nnames) {
202 list->rpc.NAMELIST_len = list->nnames;
203 list->rpc.NAMELIST_val = (char **)
204 realloc(list->rpc.NAMELIST_val,list->rpc.NAMELIST_len*sizeof(char *));
205 }
206 this = list->namehead;
207 for(i=0;(i<list->nnames && this);i++){
208 list->rpc.NAMELIST_val[i] = this->name;
209 this = this->next;
210 }
211 }
212 nerrors = 0;
213 if(vals = davar_readmultiple_1(&(list->rpc),clnt)) {
214 this = list->namehead;
215 /* printf("list->rpc.NAMELIST_len=%d\n",list->rpc.NAMELIST_len);*/
216 for(i=0;(i<list->rpc.NAMELIST_len && this);i++){
217 /* printf("%s\n",this->name);*/
218 if(vals->RVALLIST_val[i].valtype != DAVARERROR_RPC){
219 if(daVarWriteVar(this->name,&(vals->RVALLIST_val[i])) != S_SUCCESS)
220 nerrors++;
221 saw 1.1 } else {
222 nerrors++;
223 }
224 this = this->next;
225 }
226 } else {
227 nerrors = -1;
228 }
229 return(nerrors);
230 }
231 #if 0
232 long thPutList(long handle, CLIENT *clnt)
233 /* Returns 0 for total success, -1 for total failure, a positive number
234 for the number of variables that didn't work */
235 {
236 thNameList *list;
237 thNameNode *next,*this;
238 int i;
239 WVALLIST vals;
240 int nerrors;
241
242 saw 1.1 /* Create the write structure */
243 list = (thNameList *) handle;
244 /* printf("list->nnames=%d\n",list->nnames);*/
245 if(!list->rpc_made) {
246 if(list->rpc.NAMELIST_len == 0) {
247 list->rpc.NAMELIST_len = list->nnames;
248 list->rpc.NAMELIST_val = (char **) malloc(list->rpc.NAMELIST_len
249 *sizeof(char *));
250 } else if (list->rpc.NAMELIST_len != list->nnames) {
251 list->rpc.NAMELIST_len = list->nnames;
252 list->rpc.NAMELIST_val = (char **)
253 realloc(list->rpc.NAMELIST_val,list->rpc.NAMELIST_len*sizeof(char *));
254 }
255 this = list->namehead;
256 for(i=0;(i<list->nnames && this);i++){
257 list->rpc.NAMELIST_val[i] = this->name;
258 this = this->next;
259 }
260 }
261 nerrors = 0;
262 if(vals = davar_readmultiple_1(&(list->rpc),clnt)) {
263 saw 1.1 this = list->namehead;
264 /* printf("list->rpc.NAMELIST_len=%d\n",list->rpc.NAMELIST_len);*/
265 for(i=0;(i<list->rpc.NAMELIST_len && this);i++){
266 /* printf("%s\n",this->name);*/
267 if(vals->RVALLIST_val[i].valtype != DAVARERROR_RPC){
268 if(daVarWriteVar(this->name,&(vals->RVALLIST_val[i])) != S_SUCCESS)
269 nerrors++;
270 } else {
271 nerrors++;
272 }
273 this = this->next;
274 }
275 } else {
276 nerrors = -1;
277 }
278 return(nerrors);
279 }
280 #endif
281 #if 0
282 int tsize=0;
283 struct timeval timeout;
284 saw 1.1 long servone(int wait)
285 /* Need to move something that does this into CTP proper */
286 {
287 fd_set readfdset;
288 extern int errno;
289
290 timeout.tv_sec = wait;
291 timeout.tv_usec = 1;
292
293 #ifdef hpux
294 if(!tsize) tsize = NFDBITS;
295 #else
296 if(!tsize) tsize = getdtablesize(); /* how many descriptors can we have */
297 #endif
298
299 readfdset = svc_fdset;
300 switch(select(tsize, &readfdset, (fd_set *) NULL, (fd_set *) NULL,
301 &timeout)) {
302 case -1:
303 if (errno == EBADF) break;
304 perror("select failed");
305 saw 1.1 break;
306 case 0:
307 /* perform other functions here if select() timed-out */
308 break;
309 default:
310 svc_getreqset(&readfdset);
311 }
312 }
313 #endif
314 long thGetList_test(long handle, CLIENT *clnt, char *test_condition,
315 int max_time_wait, int max_event_wait)
316 /* Returns 0 for total success, -1 for total failure, a positive number
317 for the number of variables that didn't work */
318 {
319 thNameList *list;
320 thNameNode *next,*this;
321 int i;
322 RVALLIST *vals;
323 int *status;
324 TESTNAMELIST *arg;
325 long servret;
326 saw 1.1
327 /* Can return some kind of error if pending_arg is not zero */
328 list = (thNameList *) handle;
329 /* printf("list->nnames=%d\n",list->nnames);*/
330 if(!list->rpc_made) {
331 if(list->rpc.NAMELIST_len == 0) {
332 list->rpc.NAMELIST_len = list->nnames;
333 list->rpc.NAMELIST_val = (char **) malloc(list->rpc.NAMELIST_len
334 *sizeof(char *));
335 } else if (list->rpc.NAMELIST_len != list->nnames) {
336 list->rpc.NAMELIST_len = list->nnames;
337 list->rpc.NAMELIST_val = (char **)
338 realloc(list->rpc.NAMELIST_val,list->rpc.NAMELIST_len*sizeof(char *));
339 }
340 this = list->namehead;
341 for(i=0;(i<list->nnames && this);i++){
342 list->rpc.NAMELIST_val[i] = this->name;
343 this = this->next;
344 }
345 }
346 arg = (TESTNAMELIST *) malloc(sizeof(TESTNAMELIST));
347 saw 1.1 arg->test_condition = (char *) malloc(strlen(test_condition)+1);
348 strcpy(arg->test_condition,test_condition);
349 arg->max_time_wait = max_time_wait;
350 arg->max_event_wait = max_event_wait;
351 arg->prog = DAVARSVR;
352 arg->vers = DAVARVERS+1;
353 arg->NAMELISTP = &list->rpc;
354 pending_arg = arg;
355 pending_flag = 1;
356
357 if(!(status = davar_readmultiple_test_1(arg,clnt)))
358 return(-1);
359
360 /* Now wait for the incoming network call */
361
362 servret = 1;
363 while(pending_flag && servret > 0) /* Wait for timeout, completion or failur*/
364 servret = daVarServOnce(arg->max_time_wait+10); /* Will wait double?? */
365 if(servret == 0) callback_result = -2; /* Timeout */
366 else if(servret == -1) callback_result = -3;
367
368 saw 1.1 free(arg->test_condition);
369 free(arg);
370 pending_arg = 0;
371
372 return(callback_result);
373 }
374 int *davar_readmultiple_test_cb_1(RVALLIST *vals, CLIENT *clnt)
375 {
376 static int result;
377
378 TESTNAMELIST *argp;
379 thNameNode *next,*this;
380 int i;
381
382 if(pending_arg) argp = pending_arg;
383 else {
384 pending_flag = 0;
385 return(&result); /* What error code ?? */
386 }
387
388 callback_result = 0;
389 saw 1.1 if(argp->NAMELISTP->NAMELIST_len == vals->RVALLIST_len) {
390 for(i=0;(i<argp->NAMELISTP->NAMELIST_len);i++){
391 /* printf("%s\n",this->name);*/
392 if(vals->RVALLIST_val[i].valtype != DAVARERROR_RPC){
393 if(daVarWriteVar(argp->NAMELISTP->NAMELIST_val[i]
394 ,&(vals->RVALLIST_val[i])) != S_SUCCESS)
395 callback_result++;
396 } else {
397 callback_result++;
398 }
399 }
400 } else if (vals->RVALLIST_len>0) {
401 printf("Lengths: %d %d",argp->NAMELISTP->NAMELIST_len,vals->RVALLIST_len);
402 callback_result = -1;
403 } else {
404 callback_result = -2; /* Server send timeout signal */
405 }
406 pending_flag = 0;
407 return(&result);
408 }
|