1 saw 1.4 #ifdef __osf__
2 #define BIT64
3 #endif
|
4 saw 1.1 /*-----------------------------------------------------------------------------
5 * Copyright (c) 1994 Southeastern Universities Research Association,
6 * Continuous Electron Beam Accelerator Facility
7 *
8 * This software was developed under a United States Government license
9 * described in the NOTICE file included as part of this distribution.
10 *
11 * Stephen A. Wood, 12000 Jefferson Ave., Newport News, VA 23606
12 * Email: saw@cebaf.gov Tel: (804) 249-7367 Fax: (804) 249-5800
13 *-----------------------------------------------------------------------------
14 *
15 * Description:
16 * Routines used by a client to retrieve CTP variables
17 *
18 * Author: Stephen Wood, CEBAF Hall C
19 *
20 * Revision History:
21 * $Log: thClient.c,v $
|
22 saw 1.4 * Revision 1.6 1999/08/25 13:16:06 saw
23 * *** empty log message ***
|
24 saw 1.3 *
|
25 saw 1.4 * Revision 1.5 1999/03/01 19:53:05 saw
26 * Add OSF stuff
|
27 saw 1.2 *
|
28 saw 1.1 * Revision 1.4 1995/08/03 13:50:52 saw
29 * Add SGI compatibility
30 *
31 * Revision 1.3 1994/11/07 14:09:42 saw
32 * Bug fixes in thGetList_test and callback server code.
33 *
34 * Revision 1.2 1994/10/17 17:07:28 saw
35 * Add thGetList_test and the callback service davar_readmultiple_test_cb_1
36 *
37 * Revision 1.1 1994/09/27 19:19:09 saw
38 * Initial revision
39 *
40 */
41 #include <stdio.h>
42 #include <string.h>
43 #include <rpc/rpc.h>
44 #include "daVar.h"
45 #include "daVarRpc.h"
46 #include "cfortran.h"
47
|
48 saw 1.4 int thCreateList(); /* Move to some include file */
49 int thAddToList(int handle, char *pattern);
50 int thRemoveFromList(int handle, char *pattern);
51 #ifdef BIT64
52 int thGetList(int handle, int client);
53 int thGetList_test(int handle, int client, char *test_condition,
|
54 saw 1.1 int max_time_wait, int max_event_wait);
|
55 saw 1.4 int thImportVars(char *pattern, int client);
|
56 saw 1.1 #else
|
57 saw 1.4 int thGetList(int handle, CLIENT *clnt);
58 int thGetList_test(int handle, CLIENT *clnt, char *test_condition,
59 int max_time_wait, int max_event_wait);
60 int thImportVars(char *pattern, CLIENT *clnt);
61 #endif
62 int thPrintList(int handle);
63 #ifdef BIT64
64 int myClntCreate(char *host, int prog, int vers, char *proto);
|
65 saw 1.1 #endif
|
66 saw 1.2
|
67 saw 1.4 FCALLSCFUN0(INT,thCreateList,THCRLIST,thcrlist);
68 FCALLSCFUN2(INT,thAddToList,THADDLIST,thaddlist,INT,STRING);
69 FCALLSCFUN2(INT,thRemoveFromList,THREMLIST,thremlist,INT,STRING);
70 FCALLSCFUN2(INT,thGetList,THGETLIST,thgetlist,INT,INT);
71 FCALLSCFUN5(INT,thGetList_test,THCGETLIST,thcgetlist,INT,INT,STRING,INT,INT);
72 FCALLSCFUN1(INT,thPrintList,THPRTLIST,thprtlist,INT);
73 /* Don't really understand the following. What about ultrix?
74 This is probably because of the _ in clnt_create */
75 #ifndef __osf__
76 FCALLSCFUN4(INT,clnt_create,CLNT_CREATE,clnt_create,STRING,INT,INT,STRING);
77 #else
78 #ifdef BIT64
79 FCALLSCFUN4(INT,myClntCreate,CLNT_CREATE,clnt_create,STRING,INT,INT,STRING);
|
80 saw 1.1 #else
|
81 saw 1.4 FCALLSCFUN4(INT,clnt_create,CLNT_CREATE_,clnt_create_,STRING,INT,INT,STRING);
82 #endif
|
83 saw 1.1 #endif
84
85 struct thNameNode {
86 char *name;
87 struct thNameNode *next;
88 };
89 typedef struct thNameNode thNameNode;
90
91 struct thNameList {
92 thNameNode *namehead;
93 int nnames; /* Number of names in list */
94 int rpc_made;
95 NAMELIST rpc; /* List in form for RPC argument */
96 };
97 typedef struct thNameList thNameList;
98
99 TESTNAMELIST *pending_arg=0;
100 int pending_flag=0;
101 int callback_result;
102
|
103 saw 1.4 #ifdef BIT64
104 #define MAXHANDLES 10
105 static thNameList *handle_list[MAXHANDLES]={0,0,0,0,0,0,0,0,0,0};
106 static CLIENT *clnt_list[MAXHANDLES]={0,0,0,0,0,0,0,0,0,0};
107 #endif
108
109 #ifdef BIT64
110 /* Keep client pointers in an array so that we can return a 32 bit "handle"
111 instead of 64 bit. We probably won't need more than one, but we have an
112 array to hold 10 client pointers just for the heck of it.
113 */
114 int myClntCreate(char *host, int prog, int vers, char *proto)
115 {
116 CLIENT *clnt;
117 int client;
118
119 clnt = clnt_create(host, prog, vers, proto);
120 for(client=0;client<MAXHANDLES;client++){
121 if(clnt_list[client]==0) {
122 clnt_list[client] = clnt;
123 return(client+1);
124 saw 1.4 }
125 }
126 return(0);
127 }
128 #endif
129 int thCreateList(){
|
130 saw 1.1 /* Create a handle for a list of variables */
131 thNameList *list;
|
132 saw 1.4 #ifdef BIT64
133 int ihandle;
134 #endif
|
135 saw 1.1
136 list = (thNameList *) malloc(sizeof(thNameList));;
137 list->namehead = 0;
138 list->nnames = 0;
139 list->rpc_made = 0;
140 list->rpc.NAMELIST_len = 0;
141 list->rpc.NAMELIST_val = 0;
|
142 saw 1.4 #ifdef BIT64
143 for(ihandle=0;ihandle<MAXHANDLES;ihandle++){
144 if(handle_list[ihandle]==0) {
145 handle_list[ihandle] = list;
146 printf("cr: handle_list[%d]=%x\n",ihandle,handle_list[ihandle]);
147 return(ihandle+1);
148 }
149 }
150 free(list);
151 return(0);
152 #else
153 return((int) list);
154 #endif
|
155 saw 1.1 }
|
156 saw 1.4 int thAddToList(int handle, char *pattern)
|
157 saw 1.1 /* Add registered variables to a list of variables to get from a server
158 Return the number of variables added
159 Should we check for duplicates? Not now. No harm in duplicates.
160 thRemoveFromList will remove all duplicates though. */
161 {
162 thNameList *list;
163 thNameNode *next,*this;
164 char **vlist; /* List of characters matching pattern */
165 int count; /* Number of variables being added */
166 int i;
167
|
168 saw 1.4 #ifdef BIT64
169 list = (thNameList *) handle_list[handle-1];
170 #else
|
171 saw 1.1 list = (thNameList *) handle;
|
172 saw 1.4 #endif
|
173 saw 1.1 daVarList(pattern,&vlist,&count);
174 for(i=0;i<count;i++) {
175 next = list->namehead; /* The current list */
176 this = list->namehead = (thNameNode *) malloc(sizeof(thNameNode)); /* New name */
177 this->name = (char *) malloc(strlen(vlist[i])+1);
178 strcpy(this->name,vlist[i]);
179 this->next = next; /* Attach rest of list */
180 }
181 list->nnames += count; /* Perhaps I should just count when needed ? */
182 list->rpc_made = 0; /* RPC format list now out of date. */
183 return(list->nnames);
184 }
|
185 saw 1.4 int thRemoveFromList(int handle, char *pattern)
|
186 saw 1.1 {
187 thNameList *list;
188 thNameNode *this,**thisp;
189 char **vlist; /* List of characters matching pattern */
190 int count; /* Number of variables being removed */
191 int nremove;
192 int i;
193
|
194 saw 1.4 #ifdef BIT64
195 list = (thNameList *) handle_list[handle-1];
196 #else
|
197 saw 1.1 list = (thNameList *) handle;
|
198 saw 1.4 #endif
|
199 saw 1.1 daVarList(pattern,&vlist,&count);
200 nremove = 0;
201 for(i=0;i<count;i++) {
202 this = list->namehead; /* Start of list */
203 thisp = &list->namehead; /* Pointer to next field of previous name */
204 while(this) {
205 if(strcasecmp(this->name,vlist[i])==0) { /* Remove matching string */
206 *thisp = this->next;
207 free(this->name);
208 free(this);
209 this = *thisp;
210 nremove++;
211 } else {
212 thisp = &(this->next);
213 this = this->next;
214 }
215 }
216 }
217 list->nnames -= nremove; /* Perhaps I should just count when needed ? */
218 return(list->nnames);
219 }
|
220 saw 1.4 int thPrintList(int handle)
|
221 saw 1.1 /* For debugging */
222 {
223 thNameList *list;
224 thNameNode *next,*this;
225 int count;
226
|
227 saw 1.4 #ifdef BIT64
228 list = (thNameList *) handle_list[handle-1];
229 #else
|
230 saw 1.1 list = (thNameList *) handle;
|
231 saw 1.4 #endif
|
232 saw 1.1 this = list->namehead;
233 printf("Variables attached to handle %d\n",handle);
234 count++;
235 while(this) {
236 printf("%s\n",this->name);
237 count++;
238 this = this->next;
239 }
240 return(count);
241 }
|
242 saw 1.4 #ifdef BIT64
243 int thGetList(int handle, int client)
244 #else
245 int thGetList(int handle, CLIENT *clnt)
246 #endif
|
247 saw 1.1 /* Returns 0 for total success, -1 for total failure, a positive number
248 for the number of variables that didn't work */
249 {
250 thNameList *list;
251 thNameNode *next,*this;
252 int i;
253 RVALLIST *vals;
254 int nerrors;
|
255 saw 1.4 #ifdef BIT64
256 CLIENT *clnt;
257
258 clnt = clnt_list[client-1];
259 #endif
|
260 saw 1.1
|
261 saw 1.4 /*
262 printf("sizeof(handle)=%d\n",sizeof(handle));
263 printf("thGetLIst: handle=%d\n",handle);
264 printf("thGhandle_list[0]=%x\n",handle_list[0]);
265 printf("handle_list[%d-1]=%x\n",handle,handle_list[handle-1]);
266 */
267 #ifdef BIT64
268 list = (thNameList *) handle_list[handle-1];
269 #else
|
270 saw 1.1 list = (thNameList *) handle;
|
271 saw 1.4 #endif
|
272 saw 1.1 /* printf("list->nnames=%d\n",list->nnames);*/
273 if(!list->rpc_made) {
274 if(list->rpc.NAMELIST_len == 0) {
275 list->rpc.NAMELIST_len = list->nnames;
276 list->rpc.NAMELIST_val = (char **) malloc(list->rpc.NAMELIST_len
277 *sizeof(char *));
278 } else if (list->rpc.NAMELIST_len != list->nnames) {
279 list->rpc.NAMELIST_len = list->nnames;
280 list->rpc.NAMELIST_val = (char **)
281 realloc(list->rpc.NAMELIST_val,list->rpc.NAMELIST_len*sizeof(char *));
282 }
283 this = list->namehead;
284 for(i=0;(i<list->nnames && this);i++){
285 list->rpc.NAMELIST_val[i] = this->name;
286 this = this->next;
287 }
288 }
289 nerrors = 0;
290 if(vals = davar_readmultiple_1(&(list->rpc),clnt)) {
291 this = list->namehead;
292 /* printf("list->rpc.NAMELIST_len=%d\n",list->rpc.NAMELIST_len);*/
293 saw 1.1 for(i=0;(i<list->rpc.NAMELIST_len && this);i++){
294 /* printf("%s\n",this->name);*/
295 if(vals->RVALLIST_val[i].valtype != DAVARERROR_RPC){
296 if(daVarWriteVar(this->name,&(vals->RVALLIST_val[i])) != S_SUCCESS)
297 nerrors++;
298 } else {
299 nerrors++;
300 }
301 this = this->next;
302 }
303 } else {
304 nerrors = -1;
305 }
306 return(nerrors);
307 }
308 #if 0
|
309 saw 1.4 #ifdef BIT64
310 int thPutList(int handle, int client)
311 #else
312 int thPutList(int handle, CLIENT *clnt)
313 #endif
|
314 saw 1.1 /* Returns 0 for total success, -1 for total failure, a positive number
315 for the number of variables that didn't work */
316 {
317 thNameList *list;
318 thNameNode *next,*this;
319 int i;
320 WVALLIST vals;
321 int nerrors;
|
322 saw 1.4 #ifdef BIT64
323 CLIENT *clnt;
324
325 clnt = clnt_list[client-1];
326 #endif
|
327 saw 1.1
328 /* Create the write structure */
|
329 saw 1.4 #ifdef BIT64
330 list = (thNameList *) handle_list[handle-1];
331 #else
|
332 saw 1.1 list = (thNameList *) handle;
|
333 saw 1.4 #endif
|
334 saw 1.1 /* printf("list->nnames=%d\n",list->nnames);*/
335 if(!list->rpc_made) {
336 if(list->rpc.NAMELIST_len == 0) {
337 list->rpc.NAMELIST_len = list->nnames;
338 list->rpc.NAMELIST_val = (char **) malloc(list->rpc.NAMELIST_len
339 *sizeof(char *));
340 } else if (list->rpc.NAMELIST_len != list->nnames) {
341 list->rpc.NAMELIST_len = list->nnames;
342 list->rpc.NAMELIST_val = (char **)
343 realloc(list->rpc.NAMELIST_val,list->rpc.NAMELIST_len*sizeof(char *));
344 }
345 this = list->namehead;
346 for(i=0;(i<list->nnames && this);i++){
347 list->rpc.NAMELIST_val[i] = this->name;
348 this = this->next;
349 }
350 }
351 nerrors = 0;
352 if(vals = davar_readmultiple_1(&(list->rpc),clnt)) {
353 this = list->namehead;
354 /* printf("list->rpc.NAMELIST_len=%d\n",list->rpc.NAMELIST_len);*/
355 saw 1.1 for(i=0;(i<list->rpc.NAMELIST_len && this);i++){
356 /* printf("%s\n",this->name);*/
357 if(vals->RVALLIST_val[i].valtype != DAVARERROR_RPC){
358 if(daVarWriteVar(this->name,&(vals->RVALLIST_val[i])) != S_SUCCESS)
359 nerrors++;
360 } else {
361 nerrors++;
362 }
363 this = this->next;
364 }
365 } else {
366 nerrors = -1;
367 }
368 return(nerrors);
369 }
370 #endif
371 #if 0
372 int tsize=0;
373 struct timeval timeout;
|
374 saw 1.4 int servone(int wait)
|
375 saw 1.1 /* Need to move something that does this into CTP proper */
376 {
377 fd_set readfdset;
378 extern int errno;
379
380 timeout.tv_sec = wait;
381 timeout.tv_usec = 1;
382
383 #ifdef hpux
384 if(!tsize) tsize = NFDBITS;
385 #else
386 if(!tsize) tsize = getdtablesize(); /* how many descriptors can we have */
387 #endif
388
389 readfdset = svc_fdset;
390 switch(select(tsize, &readfdset, (fd_set *) NULL, (fd_set *) NULL,
391 &timeout)) {
392 case -1:
393 if (errno == EBADF) break;
394 perror("select failed");
395 break;
396 saw 1.1 case 0:
397 /* perform other functions here if select() timed-out */
398 break;
399 default:
400 svc_getreqset(&readfdset);
401 }
402 }
403 #endif
|
404 saw 1.4 #ifdef BIT64
405 int thGetList_test(int handle, int client, char *test_condition,
406 int max_time_wait, int max_event_wait)
407 #else
408 int thGetList_test(int handle, CLIENT *clnt, char *test_condition,
|
409 saw 1.1 int max_time_wait, int max_event_wait)
|
410 saw 1.4 #endif
|
411 saw 1.1 /* Returns 0 for total success, -1 for total failure, a positive number
412 for the number of variables that didn't work */
413 {
414 thNameList *list;
415 thNameNode *next,*this;
416 int i;
417 int *status;
418 TESTNAMELIST *arg;
|
419 saw 1.4 int servret;
420 #ifdef BIT64
421 CLIENT *clnt;
422
423 clnt = clnt_list[client-1];
424 #endif
|
425 saw 1.1
426 /* Can return some kind of error if pending_arg is not zero */
|
427 saw 1.4 #ifdef BIT64
428 list = (thNameList *) handle_list[handle-1];
429 #else
|
430 saw 1.1 list = (thNameList *) handle;
|
431 saw 1.4 #endif
|
432 saw 1.1 /* printf("list->nnames=%d\n",list->nnames);*/
433 if(!list->rpc_made) {
434 if(list->rpc.NAMELIST_len == 0) {
435 list->rpc.NAMELIST_len = list->nnames;
436 list->rpc.NAMELIST_val = (char **) malloc(list->rpc.NAMELIST_len
437 *sizeof(char *));
438 } else if (list->rpc.NAMELIST_len != list->nnames) {
439 list->rpc.NAMELIST_len = list->nnames;
440 list->rpc.NAMELIST_val = (char **)
441 realloc(list->rpc.NAMELIST_val,list->rpc.NAMELIST_len*sizeof(char *));
442 }
443 this = list->namehead;
444 for(i=0;(i<list->nnames && this);i++){
445 list->rpc.NAMELIST_val[i] = this->name;
446 this = this->next;
447 }
448 }
449 arg = (TESTNAMELIST *) malloc(sizeof(TESTNAMELIST));
450 arg->test_condition = (char *) malloc(strlen(test_condition)+1);
451 strcpy(arg->test_condition,test_condition);
452 arg->max_time_wait = max_time_wait;
453 saw 1.1 arg->max_event_wait = max_event_wait;
454 arg->prog = DAVARSVR;
455 arg->vers = DAVARVERS+1;
456 arg->NAMELISTP = &list->rpc;
457 pending_arg = arg;
458 pending_flag = 1;
459
460 if(!(status = davar_readmultiple_test_1(arg,clnt)))
461 return(-1);
462
463 /* Now wait for the incoming network call */
464
465 servret = 1;
466 while(pending_flag && servret > 0) /* Wait for timeout, completion or failur*/
467 servret = daVarServOnce(arg->max_time_wait+10); /* Will wait double?? */
468 if(servret == 0) callback_result = -2; /* Timeout */
469 else if(servret == -1) callback_result = -3;
470
471 free(arg->test_condition);
472 free(arg);
473 pending_arg = 0;
474 saw 1.1
475 return(callback_result);
|
476 saw 1.4 }
477 #ifdef BIT64
478 int thImportVars(char *pattern, int client)
479 #else
480 int thImportVars(char *pattern, CLIENT *clnt)
481 #endif
482 /* Returns 0 for total success, -1 for total failure, a positive number
483 for the number of variables that didn't work */
484 {
485 WVALLIST *vals;
486 int count;
487
488 thNameList *list;
489 thNameNode *next,*this;
490 int i;
491 int nerrors;
492 #ifdef BIT64
493 CLIENT *clnt;
494
495 clnt = clnt_list[client-1];
496 #endif
497 saw 1.4
498 /* need to initialize the hash tables */
499
500 if(!(vals = davar_readpatternmatch_1(&pattern,clnt))) {
501 return(-1); /* Failed */
502 }
503
504 count = vals->WVALLIST_len;
505 /*printf("daVarImportVars got %d variables matching %s\n",count,pattern);*/
506 nerrors = 0;
507 for(i=0;i<count;i++) {
508 char *name;
509 int valtype;
510 daVarStruct var;
511
512 name = vals->WVALLIST_val[i].name;
513 /*printf("%d: %s\n",i,name);*/
514 /* Don't do anything if it already exists */
515 if(daVarWriteVar(name,vals->WVALLIST_val[i].val) == S_SUCCESS) continue;
516 var.type = vals->WVALLIST_val[i].val->valtype;
517 if(var.type == DAVARERROR_RPC){
518 saw 1.4 printf("Error getting %s\n",name);
519 nerrors++;
520 continue;
521 }
522 var.name = name;
523 /*printf("Vartype = %d\n",var.type);*/
524 switch(var.type)
525 {
526 case DAVARINT_RPC:
527 var.size = vals->WVALLIST_val[i].val->any_u.i.i_len;
528 /*printf("size=%d\n",var.size);*/
529 var.varptr = (void *) malloc(var.size*sizeof(DAINT));
530 break;
531 case DAVARFLOAT_RPC:
532 var.size = vals->WVALLIST_val[i].val->any_u.r.r_len;
533 /*printf("size=%d\n",var.size);*/
534 var.varptr = (void *) malloc(var.size*sizeof(DAFLOAT));
535 break;
536 case DAVARDOUBLE_RPC:
537 var.size = vals->WVALLIST_val[i].val->any_u.d.d_len;
538 /*printf("size=%d\n",var.size);*/
539 saw 1.4 var.varptr = (void *) malloc(var.size*sizeof(DADOUBLE));
540 break;
541 case DAVARSTRING_RPC:
542 var.size = strlen(vals->WVALLIST_val[i].val->any_u.s) + 1;
543 /*printf("size=%d\n",var.size);*/
544 var.varptr = malloc(var.size);
545 break;
546 }
547 var.opaque = 0;
548 var.rhook = var.whook = 0;
549 var.flag = DAVAR_REPOINTOK | DAVAR_DYNAMIC_PAR;
550 var.flag = DAVAR_REPOINTOK | DAVAR_DYNAMIC_PAR;
551 var.title = 0;
552 daVarRegister((int) 0, &var);
553 /* free(var.name);*/
554 if(daVarWriteVar(name,vals->WVALLIST_val[i].val) != S_SUCCESS) {
555 printf("daVarWriteVar of %s should have worked\n",name);
556 nerrors++;
557 }
558 }
559 return(nerrors);
|
560 saw 1.1 }
561 int *davar_readmultiple_test_cb_1(RVALLIST *vals, CLIENT *clnt)
562 {
563 static int result;
564
565 TESTNAMELIST *argp;
566 thNameNode *next,*this;
567 int i;
568
569 if(pending_arg) argp = pending_arg;
570 else {
571 pending_flag = 0;
572 return(&result); /* What error code ?? */
573 }
574
575 callback_result = 0;
576 if(argp->NAMELISTP->NAMELIST_len == vals->RVALLIST_len) {
577 for(i=0;(i<argp->NAMELISTP->NAMELIST_len);i++){
578 /* printf("%s\n",this->name);*/
579 if(vals->RVALLIST_val[i].valtype != DAVARERROR_RPC){
580 if(daVarWriteVar(argp->NAMELISTP->NAMELIST_val[i]
581 saw 1.1 ,&(vals->RVALLIST_val[i])) != S_SUCCESS)
582 callback_result++;
583 } else {
584 callback_result++;
585 }
586 }
587 } else if (vals->RVALLIST_len>0) {
588 printf("Lengths: %d %d",argp->NAMELISTP->NAMELIST_len,vals->RVALLIST_len);
589 callback_result = -1;
590 } else {
591 callback_result = -2; /* Server send timeout signal */
592 }
593 pending_flag = 0;
594 return(&result);
595 }
|