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