source: trunk/FACT++/dim/src/dis_Markus.c@ 14915

Last change on this file since 14915 was 10614, checked in by tbretz, 14 years ago
New release V19 r20
File size: 63.1 KB
Line 
1/*
2 * DIS (Delphi Information Server) Package implements a library of
3 * routines to be used by servers.
4 *
5 * Started on : 10-11-91
6 * Last modification : 28-07-94
7 * Written by : C. Gaspar
8 * Adjusted by : G.C. Ballintijn
9 *
10 */
11
12#ifdef VMS
13# include <lnmdef.h>
14# include <ssdef.h>
15# include <descrip.h>
16# include <cfortran.h>
17#endif
18/*
19#define DEBUG
20*/
21#include <time.h>
22#ifdef VAX
23#include <timeb.h>
24#else
25#include <sys/timeb.h>
26#endif
27
28#define DIMLIB
29#include <dim.h>
30#include <dis.h>
31
32#define ALL 0
33#define MORE 1
34#define NONE 2
35
36typedef struct dis_dns_ent {
37 struct dis_dns_ent *next;
38 struct dis_dns_ent *prev;
39 long dnsid;
40 char task_name[MAX_NAME];
41 TIMR_ENT *dns_timr_ent;
42 DIS_DNS_PACKET dis_dns_packet;
43 int dis_n_services;
44 int dns_dis_conn_id;
45 int dis_first_time;
46 int serving;
47 unsigned int dis_service_id;
48 unsigned int dis_client_id;
49 int updating_service_list;
50} DIS_DNS_CONN;
51
52typedef struct req_ent {
53 struct req_ent *next;
54 struct req_ent *prev;
55 int conn_id;
56 int service_id;
57 int req_id;
58 int type;
59 struct serv *service_ptr;
60 int timeout;
61 int format;
62 int first_time;
63 int delay_delete;
64 int to_delete;
65 TIMR_ENT *timr_ent;
66 struct reqp_ent *reqpp;
67} REQUEST;
68
69typedef struct serv {
70 struct serv *next;
71 struct serv *prev;
72 char name[MAX_NAME];
73 int id;
74 int type;
75 char def[MAX_NAME];
76 FORMAT_STR format_data[MAX_NAME/4];
77 int *address;
78 int size;
79 void (*user_routine)();
80 long tag;
81 int registered;
82 int quality;
83 int user_secs;
84 int user_millisecs;
85 int tid;
86 REQUEST *request_head;
87 DIS_DNS_CONN *dnsp;
88 int delay_delete;
89 int to_delete;
90} SERVICE;
91
92typedef struct reqp_ent {
93 struct reqp_ent *next;
94 struct reqp_ent *prev;
95 REQUEST *reqp;
96} REQUEST_PTR;
97
98typedef struct cli_ent {
99 struct cli_ent *next;
100 struct cli_ent *prev;
101 int conn_id;
102 REQUEST_PTR *requestp_head;
103 DIS_DNS_CONN *dnsp;
104} CLIENT;
105
106static CLIENT *Client_head = (CLIENT *)0;
107
108static DIS_DNS_CONN *DNS_head = (DIS_DNS_CONN *)0;
109
110/*
111static char Task_name[MAX_NAME];
112static TIMR_ENT *Dns_timr_ent = (TIMR_ENT *)0;
113static DIS_DNS_PACKET Dis_dns_packet = {0, 0, {0}};
114static int Dis_n_services = 0;
115*/
116static int Dis_first_time = 1;
117/*
118static int Dns_dis_conn_id = 0;
119*/
120static int Protocol;
121static int Port_number;
122static int Dis_conn_id = 0;
123static int Curr_conn_id = 0;
124static int Serving = 0;
125static void (*Client_exit_user_routine)() = 0;
126static void (*Exit_user_routine)() = 0;
127static void (*Error_user_routine)() = 0;
128static int Error_conn_id = 0;
129DIS_DNS_CONN *Default_DNS = 0;
130
131typedef struct exit_ent {
132 struct exit_ent *next;
133 int conn_id;
134 int exit_id;
135} EXIT_H;
136
137static EXIT_H *Exit_h_head = (EXIT_H *)0;
138
139/* Do not forget to increase when this file is modified */
140static int Version_number = DIM_VERSION_NUMBER;
141static int Dis_timer_q = 0;
142static int Threads_off = 0;
143/*
144static unsigned int Dis_service_id, Dis_client_id;
145static int Updating_service_list = 0;
146*/
147static int Last_client;
148
149#ifdef DEBUG
150static int Debug_on = 1;
151#else
152static int Debug_on = 0;
153#endif
154
155_DIM_PROTO( static void dis_insert_request, (int conn_id, DIC_PACKET *dic_packet,
156 int size, int status ) );
157_DIM_PROTO( int execute_service, (int req_id) );
158_DIM_PROTO( void execute_command, (SERVICE *servp, DIC_PACKET *packet) );
159_DIM_PROTO( void register_dns_services, (int flag) );
160_DIM_PROTO( void register_services, (DIS_DNS_CONN *dnsp, int flag, int dns_flag) );
161_DIM_PROTO( void std_cmnd_handler, (long *tag, int *cmnd_buff, int *size) );
162_DIM_PROTO( void client_info, (long *tag, int **bufp, int *size) );
163_DIM_PROTO( void service_info, (long *tag, int **bufp, int *size) );
164_DIM_PROTO( void add_exit_handler, (int *tag, int *bufp, int *size) );
165_DIM_PROTO( static void exit_handler, (int *tag, int *bufp, int *size) );
166_DIM_PROTO( static void error_handler, (int conn_id, int severity, int errcode, char *reason) );
167_DIM_PROTO( SERVICE *find_service, (char *name) );
168_DIM_PROTO( CLIENT *find_client, (int conn_id) );
169_DIM_PROTO( static int get_format_data, (FORMAT_STR *format_data, char *def) );
170_DIM_PROTO( static int release_conn, (int conn_id, int print_flag, int dns_flag) );
171_DIM_PROTO( SERVICE *dis_hash_service_exists, (char *name) );
172_DIM_PROTO( SERVICE *dis_hash_service_get_next, (int *start, SERVICE *prev, int flag) );
173_DIM_PROTO( static unsigned do_dis_add_service_dns, (char *name, char *type, void *address, int size,
174 void (*user_routine)(), long tag, long dnsid ) );
175_DIM_PROTO( static DIS_DNS_CONN *create_dns, (long dnsid) );
176
177void dis_set_debug_on()
178{
179 Debug_on = 1;
180}
181
182void dis_set_debug_off()
183{
184 Debug_on = 0;
185}
186
187void dis_no_threads()
188{
189 Threads_off = 1;
190}
191
192static DIS_STAMPED_PACKET *Dis_packet = 0;
193static int Dis_packet_size = 0;
194
195int dis_set_buffer_size(int size)
196{
197 if(Dis_packet_size)
198 free(Dis_packet);
199 Dis_packet = (DIS_STAMPED_PACKET *)malloc(DIS_STAMPED_HEADER + size);
200 if(Dis_packet)
201 {
202 Dis_packet_size = DIS_STAMPED_HEADER + size;
203 return(1);
204 }
205 else
206 return(0);
207}
208
209static int check_service_name(char *name)
210{
211 if(strlen(name) > (MAX_NAME - 1))
212 return(0);
213 return(1);
214}
215
216static void dis_init()
217{
218 int dis_hash_service_init();
219 void dis_dns_init();
220
221 dis_dns_init();
222 {
223 DISABLE_AST
224 dis_hash_service_init();
225 ENABLE_AST
226 }
227}
228
229static unsigned do_dis_add_service_dns( char *name, char *type, void *address, int size,
230 void (*user_routine)(), long tag, long dnsid )
231{
232 register SERVICE *new_serv;
233 register int service_id;
234 char str[512];
235 int dis_hash_service_insert();
236 DIS_DNS_CONN *dnsp;
237 extern DIS_DNS_CONN *dis_find_dns(long);
238
239 dis_init();
240 {
241 DISABLE_AST
242 if(!check_service_name(name))
243 {
244 strcpy(str,"Service name too long: ");
245 strcat(str,name);
246 error_handler(0, DIM_ERROR, DIMSVCTOOLG, str);
247 ENABLE_AST
248 return((unsigned) 0);
249 }
250 if( find_service(name) )
251 {
252 strcpy(str,"Duplicate Service: ");
253 strcat(str,name);
254 error_handler(0, DIM_ERROR, DIMSVCDUPLC, str);
255 ENABLE_AST
256 return((unsigned) 0);
257 }
258 new_serv = (SERVICE *)malloc( sizeof(SERVICE) );
259 strncpy( new_serv->name, name, MAX_NAME );
260 if(type != (char *)0)
261 {
262 if (strlen(type) >= MAX_NAME)
263 {
264 strcpy(str,"Format String Too Long: ");
265 strcat(str,name);
266 error_handler(0, DIM_ERROR, DIMSVCFORMT, str);
267 free(new_serv);
268 ENABLE_AST
269 return((unsigned) 0);
270 }
271 if (! get_format_data(new_serv->format_data, type))
272 {
273 strcpy(str,"Bad Format String: ");
274 strcat(str,name);
275 error_handler(0, DIM_ERROR, DIMSVCFORMT, str);
276 free(new_serv);
277 ENABLE_AST
278 return((unsigned) 0);
279 }
280 strcpy(new_serv->def,type);
281 }
282 else
283 {
284 new_serv->format_data[0].par_bytes = 0;
285 new_serv->def[0] = '\0';
286 }
287 new_serv->type = 0;
288 new_serv->address = (int *)address;
289 new_serv->size = size;
290 new_serv->user_routine = user_routine;
291 new_serv->tag = tag;
292 new_serv->registered = 0;
293 new_serv->quality = 0;
294 new_serv->user_secs = 0;
295 new_serv->tid = 0;
296 new_serv->delay_delete = 0;
297 new_serv->to_delete = 0;
298 dnsp = dis_find_dns(dnsid);
299 if(!dnsp)
300 dnsp = create_dns(dnsid);
301 new_serv->dnsp = dnsp;
302 service_id = id_get((void *)new_serv, SRC_DIS);
303 new_serv->id = service_id;
304 new_serv->request_head = (REQUEST *)malloc(sizeof(REQUEST));
305 dll_init( (DLL *) (new_serv->request_head) );
306 dis_hash_service_insert(new_serv);
307/*
308 Dis_n_services++;
309*/
310 dnsp->dis_n_services++;
311 ENABLE_AST
312 }
313 return((unsigned)service_id);
314}
315
316static unsigned do_dis_add_service( char *name, char *type, void *address, int size,
317 void (*user_routine)(), long tag )
318{
319 return do_dis_add_service_dns( name, type, address, size,
320 user_routine, tag, 0 );
321}
322
323#ifdef VxWorks
324void dis_destroy(int tid)
325{
326register SERVICE *servp, *prevp;
327int n_left = 0;
328
329 prevp = 0;
330 while( servp = dis_hash_service_get_next(prevp))
331 {
332 if(servp->tid == tid)
333 {
334 dis_remove_service(servp->id);
335 }
336 else
337 {
338 prevp = servp;
339 n_left++;
340 }
341 }
342 if(n_left == 5)
343 {
344 prevp = 0;
345 while( servp = dis_hash_service_get_next(prevp))
346 {
347 dis_remove_service(servp->id);
348 }
349 dna_close(Dis_conn_id);
350 dna_close(Dns_dis_conn_id);
351 Dns_dis_conn_id = 0;
352 Dis_first_time = 1;
353 dtq_rem_entry(Dis_timer_q, Dns_timr_ent);
354 Dns_timr_ent = NULL;
355 }
356}
357
358
359#endif
360
361unsigned dis_add_service( char *name, char *type, void *address, int size,
362 void (*user_routine)(), long tag)
363{
364 unsigned ret;
365#ifdef VxWorks
366 register SERVICE *servp;
367#endif
368/*
369 DISABLE_AST
370*/
371 ret = do_dis_add_service( name, type, address, size, user_routine, tag);
372#ifdef VxWorks
373 servp = (SERVICE *)id_get_ptr(ret, SRC_DIS);
374 servp->tid = taskIdSelf();
375#endif
376/*
377 ENABLE_AST
378*/
379 return(ret);
380}
381
382unsigned dis_add_service_dns( long dnsid, char *name, char *type, void *address, int size,
383 void (*user_routine)(), long tag)
384{
385 unsigned ret;
386#ifdef VxWorks
387 register SERVICE *servp;
388#endif
389/*
390 DISABLE_AST
391*/
392 ret = do_dis_add_service_dns( name, type, address, size, user_routine, tag, dnsid);
393#ifdef VxWorks
394 servp = (SERVICE *)id_get_ptr(ret, SRC_DIS);
395 servp->tid = taskIdSelf();
396#endif
397/*
398 ENABLE_AST
399*/
400 return(ret);
401}
402
403static unsigned do_dis_add_cmnd_dns( char *name, char *type, void (*user_routine)(), long tag, long dnsid )
404{
405 register SERVICE *new_serv;
406 register int service_id;
407 char str[512];
408 int dis_hash_service_insert();
409 DIS_DNS_CONN *dnsp;
410 extern DIS_DNS_CONN *dis_find_dns(long);
411
412 dis_init();
413 {
414 DISABLE_AST
415 if(!check_service_name(name))
416 {
417 strcpy(str,"Command name too long: ");
418 strcat(str,name);
419 error_handler(0, DIM_ERROR, DIMSVCTOOLG, str);
420 ENABLE_AST
421 return((unsigned) 0);
422 }
423 if( find_service(name) )
424 {
425 ENABLE_AST
426 return((unsigned) 0);
427 }
428 new_serv = (SERVICE *)malloc(sizeof(SERVICE));
429 strncpy(new_serv->name, name, MAX_NAME);
430 if(type != (char *)0)
431 {
432 if( !get_format_data(new_serv->format_data, type))
433 {
434 ENABLE_AST
435 return((unsigned) 0);
436 }
437 strcpy(new_serv->def,type);
438 }
439 else
440 {
441 new_serv->format_data[0].par_bytes = 0;
442 new_serv->def[0] = '\0';
443 }
444 new_serv->type = COMMAND;
445 new_serv->address = 0;
446 new_serv->size = 0;
447 if(user_routine)
448 new_serv->user_routine = user_routine;
449 else
450 new_serv->user_routine = std_cmnd_handler;
451 new_serv->tag = tag;
452 new_serv->tid = 0;
453 new_serv->registered = 0;
454 new_serv->quality = 0;
455 new_serv->user_secs = 0;
456 new_serv->delay_delete = 0;
457 new_serv->to_delete = 0;
458 service_id = id_get((void *)new_serv, SRC_DIS);
459 new_serv->id = service_id;
460 dnsp = dis_find_dns(dnsid);
461 if(!dnsp)
462 dnsp = create_dns(dnsid);
463 new_serv->dnsp = dnsp;
464 new_serv->request_head = (REQUEST *)malloc(sizeof(REQUEST));
465 dll_init( (DLL *) (new_serv->request_head) );
466 dis_hash_service_insert(new_serv);
467/*
468 Dis_n_services++;
469*/
470 dnsp->dis_n_services++;
471 ENABLE_AST
472 }
473 return((unsigned) service_id);
474}
475
476static unsigned do_dis_add_cmnd( char *name, char *type, void (*user_routine)(), long tag)
477{
478 return do_dis_add_cmnd_dns(name, type, user_routine, tag, 0);
479}
480
481unsigned dis_add_cmnd( char *name, char *type, void (*user_routine)(), long tag )
482{
483 unsigned ret;
484
485/*
486 DISABLE_AST
487*/
488 ret = do_dis_add_cmnd( name, type, user_routine, tag );
489/*
490 ENABLE_AST
491*/
492 return(ret);
493}
494
495unsigned dis_add_cmnd_dns( long dnsid, char *name, char *type, void (*user_routine)(), long tag )
496{
497 unsigned ret;
498
499 /*
500 DISABLE_AST
501 */
502 ret = do_dis_add_cmnd_dns( name, type, user_routine, tag, dnsid );
503 /*
504 ENABLE_AST
505 */
506 return(ret);
507}
508
509void dis_add_client_exit_handler( void (*user_routine)())
510{
511
512 DISABLE_AST
513 Client_exit_user_routine = user_routine;
514 ENABLE_AST
515}
516
517void dis_add_exit_handler( void (*user_routine)())
518{
519
520 DISABLE_AST
521 Exit_user_routine = user_routine;
522 ENABLE_AST
523}
524
525void dis_add_error_handler( void (*user_routine)())
526{
527
528 DISABLE_AST
529 Error_user_routine = user_routine;
530 ENABLE_AST
531}
532
533static int get_format_data(FORMAT_STR *format_data, char *def)
534{
535 register char code, last_code = 0;
536 int num;
537
538 code = *def;
539 while(*def)
540 {
541 if(code != last_code)
542 {
543 format_data->par_num = 0;
544 format_data->flags = 0;
545 switch(code)
546 {
547 case 'i':
548 case 'I':
549 case 'l':
550 case 'L':
551 format_data->par_bytes = SIZEOF_LONG;
552 format_data->flags |= SWAPL;
553 break;
554 case 'x':
555 case 'X':
556 format_data->par_bytes = SIZEOF_DOUBLE;
557 format_data->flags |= SWAPD;
558 break;
559 case 's':
560 case 'S':
561 format_data->par_bytes = SIZEOF_SHORT;
562 format_data->flags |= SWAPS;
563 break;
564 case 'f':
565 case 'F':
566 format_data->par_bytes = SIZEOF_FLOAT;
567 format_data->flags |= SWAPL;
568#ifdef vms
569 format_data->flags |= IT_IS_FLOAT;
570#endif
571 break;
572 case 'd':
573 case 'D':
574 format_data->par_bytes = SIZEOF_DOUBLE;
575 format_data->flags |= SWAPD;
576#ifdef vms
577 format_data->flags |= IT_IS_FLOAT;
578#endif
579 break;
580 case 'c':
581 case 'C':
582 format_data->par_bytes = SIZEOF_CHAR;
583 format_data->flags |= NOSWAP;
584 break;
585 }
586 }
587 def++;
588 if(*def != ':')
589 {
590 if(*def)
591 {
592/*
593 printf("Bad service definition parsing\n");
594 fflush(stdout);
595
596 error_handler("Bad service definition parsing",2);
597*/
598 return(0);
599 }
600 else
601 format_data->par_num = 0;
602 }
603 else
604 {
605 def++;
606 sscanf(def,"%d",&num);
607 format_data->par_num += num;
608 while((*def != ';') && (*def != '\0'))
609 def++;
610 if(*def)
611 def++;
612 }
613 last_code = code;
614 code = *def;
615 if(code != last_code)
616 format_data++;
617 }
618 format_data->par_bytes = 0;
619 return(1);
620}
621
622void recv_dns_dis_rout( int conn_id, DNS_DIS_PACKET *packet, int size, int status )
623{
624 char str[128];
625 int dns_timr_time;
626 extern int rand_tmout(int, int);
627 extern int open_dns(long, void (*)(), void (*)(), int, int, int);
628 extern DIS_DNS_CONN *find_dns_by_conn_id(int);
629 extern void do_register_services(DIS_DNS_CONN *);
630 extern void do_dis_stop_serving_dns(DIS_DNS_CONN *);
631 DIS_DNS_CONN *dnsp;
632
633 if(size){}
634 dnsp = find_dns_by_conn_id(conn_id);
635 if(!dnsp)
636 {
637 return;
638 }
639 switch(status)
640 {
641 case STA_DISC: /* connection broken */
642 if( dnsp->dns_timr_ent ) {
643 dtq_rem_entry( Dis_timer_q, dnsp->dns_timr_ent );
644 dnsp->dns_timr_ent = NULL;
645 }
646
647 if(dnsp->dns_dis_conn_id > 0)
648 dna_close(dnsp->dns_dis_conn_id);
649 if(dnsp->serving)
650 {
651 dnsp->dns_dis_conn_id = open_dns(dnsp->dnsid, recv_dns_dis_rout, error_handler,
652 DIS_DNS_TMOUT_MIN, DIS_DNS_TMOUT_MAX, SRC_DIS );
653 if(dnsp->dns_dis_conn_id == -2)
654 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
655 }
656 break;
657 case STA_CONN: /* connection received */
658 if(dnsp->serving)
659 {
660 dnsp->dns_dis_conn_id = conn_id;
661 register_services(dnsp, ALL, 0);
662 dns_timr_time = rand_tmout(WATCHDOG_TMOUT_MIN,
663 WATCHDOG_TMOUT_MAX);
664 dnsp->dns_timr_ent = dtq_add_entry( Dis_timer_q,
665 dns_timr_time,
666 do_register_services, dnsp );
667 }
668 else
669 {
670 dna_close(conn_id);
671 }
672 break;
673 default : /* normal packet */
674 if(vtohl(packet->size) != DNS_DIS_HEADER)
675 break;
676 switch( vtohl(packet->type) )
677 {
678 case DNS_DIS_REGISTER :
679 sprintf(str,
680 "%s: Watchdog Timeout, DNS requests registration",
681 dnsp->task_name);
682 error_handler(0, DIM_WARNING, DIMDNSTMOUT, str);
683 register_services(dnsp, ALL, 0);
684 break;
685 case DNS_DIS_KILL :
686 sprintf(str,
687 "%s: Some Services already known to DNS",
688 dnsp->task_name);
689 /*
690 exit(2);
691 */
692 error_handler(0, DIM_FATAL, DIMDNSDUPLC, str);
693 do_dis_stop_serving_dns(dnsp);
694 dis_stop_serving();
695/*
696 exit_tag = 0;
697 exit_code = 2;
698 exit_size = sizeof(int);
699 exit_handler(&exit_tag, &exit_code, &exit_size);
700*/
701 break;
702 case DNS_DIS_STOP :
703 sprintf(str,
704 "%s: DNS refuses connection",dnsp->task_name);
705/*
706 exit(2);
707*/
708 error_handler(0, DIM_FATAL, DIMDNSREFUS, str);
709 do_dis_stop_serving_dns(dnsp);
710 dis_stop_serving();
711/*
712 exit_tag = 0;
713 exit_code = 2;
714 exit_size = sizeof(int);
715 exit_handler(&exit_tag, &exit_code, &exit_size);
716*/
717 break;
718 case DNS_DIS_EXIT :
719 sprintf(str,
720 "%s: DNS requests Exit",dnsp->task_name);
721 error_handler(0, DIM_FATAL, DIMDNSEXIT, str);
722 break;
723 }
724 break;
725 }
726}
727
728
729/* register services within the name server
730 *
731 * Send services uses the DNA package. services is a linked list of services
732 * stored by add_service.
733 */
734
735int send_dns_update_packet(DIS_DNS_CONN *dnsp)
736{
737 DIS_DNS_PACKET *dis_dns_p = &(dnsp->dis_dns_packet);
738 int n_services;
739 SERVICE_REG *serv_regp;
740
741 n_services = 1;
742 dis_dns_p->n_services = htovl(n_services);
743 dis_dns_p->size = htovl(DIS_DNS_HEADER +
744 n_services * sizeof(SERVICE_REG));
745 serv_regp = dis_dns_p->services;
746 strcpy( serv_regp->service_name, "DUMMY_UPDATE_PACKET" );
747 if(dnsp->dns_dis_conn_id > 0)
748 {
749 if( !dna_write(dnsp->dns_dis_conn_id, &(dnsp->dis_dns_packet),
750 DIS_DNS_HEADER + n_services * sizeof(SERVICE_REG)))
751 {
752 release_conn(dnsp->dns_dis_conn_id, 0, 1);
753 }
754 }
755 return(1);
756}
757
758void do_register_services(DIS_DNS_CONN *dnsp)
759{
760 register_services(dnsp, NONE, 0);
761}
762
763void register_services(DIS_DNS_CONN *dnsp, int flag, int dns_flag)
764{
765 register DIS_DNS_PACKET *dis_dns_p = &(dnsp->dis_dns_packet);
766 register int n_services, tot_n_services;
767 register SERVICE *servp;
768 register SERVICE_REG *serv_regp;
769 int hash_index, new_entries;
770 extern int get_node_addr();
771 int dis_hash_service_registered();
772
773 if(!dis_dns_p->src_type)
774 {
775 get_node_name( dis_dns_p->node_name );
776/*
777 strcpy( dis_dns_p->task_name, Task_name );
778*/
779 strncpy( dis_dns_p->task_name, dnsp->task_name,
780 MAX_TASK_NAME-4 );
781 dis_dns_p->task_name[MAX_TASK_NAME-4-1] = '\0';
782 get_node_addr( dis_dns_p->node_addr );
783/*
784 dis_dns_p->port = htovl(Port_number);
785*/
786 dis_dns_p->pid = htovl(getpid());
787 dis_dns_p->protocol = htovl(Protocol);
788 dis_dns_p->src_type = htovl(SRC_DIS);
789 dis_dns_p->format = htovl(MY_FORMAT);
790 }
791
792 dis_dns_p->port = htovl(Port_number);
793 serv_regp = dis_dns_p->services;
794 n_services = 0;
795 tot_n_services = 0;
796 if( flag == NONE ) {
797 dis_dns_p->n_services = htovl(n_services);
798 dis_dns_p->size = htovl( DIS_DNS_HEADER +
799 (n_services*sizeof(SERVICE_REG)));
800 if(dnsp->dns_dis_conn_id > 0)
801 {
802 if(!dna_write(dnsp->dns_dis_conn_id, &(dnsp->dis_dns_packet),
803 DIS_DNS_HEADER + n_services*sizeof(SERVICE_REG)))
804 {
805 release_conn(dnsp->dns_dis_conn_id, 0, 1);
806 }
807 }
808 return;
809 }
810 if(flag == ALL)
811 {
812 servp = 0;
813 hash_index = -1;
814 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)))
815 {
816 if(servp->dnsp == dnsp)
817 servp->registered = 0;
818 }
819 }
820 servp = 0;
821 hash_index = -1;
822 new_entries = 0;
823 if(flag == MORE)
824 new_entries = 1;
825 while( (servp = dis_hash_service_get_next(&hash_index, servp, new_entries)))
826 {
827 if( flag == MORE )
828 {
829 if( servp->registered )
830 {
831 continue;
832 }
833 }
834
835 if(servp->dnsp != dnsp)
836 continue;
837
838 strcpy( serv_regp->service_name, servp->name );
839 strcpy( serv_regp->service_def, servp->def );
840 if(servp->type == COMMAND)
841 serv_regp->service_id = htovl( servp->id | 0x10000000);
842 else
843 serv_regp->service_id = htovl( servp->id );
844
845 serv_regp++;
846 n_services++;
847 dis_hash_service_registered(hash_index, servp);
848 if( n_services == MAX_SERVICE_UNIT )
849 {
850 dis_dns_p->n_services = htovl(n_services);
851 dis_dns_p->size = htovl(DIS_DNS_HEADER +
852 n_services * sizeof(SERVICE_REG));
853 if(dnsp->dns_dis_conn_id > 0)
854 {
855 if( !dna_write(dnsp->dns_dis_conn_id,
856 &(dnsp->dis_dns_packet),
857 DIS_DNS_HEADER + n_services *
858 sizeof(SERVICE_REG)) )
859 {
860 release_conn(dnsp->dns_dis_conn_id, 0, 1);
861 }
862 }
863 serv_regp = dis_dns_p->services;
864 tot_n_services += MAX_SERVICE_UNIT;
865 n_services = 0;
866 continue;
867 }
868 }
869 if( n_services )
870 {
871 dis_dns_p->n_services = htovl(n_services);
872 dis_dns_p->size = htovl(DIS_DNS_HEADER +
873 n_services * sizeof(SERVICE_REG));
874 if(dnsp->dns_dis_conn_id > 0)
875 {
876 if( !dna_write(dnsp->dns_dis_conn_id, &(dnsp->dis_dns_packet),
877 DIS_DNS_HEADER + n_services * sizeof(SERVICE_REG)))
878 {
879 release_conn(dnsp->dns_dis_conn_id, 0, 1);
880 }
881
882 }
883 tot_n_services += n_services;
884 }
885 if(!dns_flag)
886 {
887 if(tot_n_services >= MAX_REGISTRATION_UNIT)
888 {
889 send_dns_update_packet(dnsp);
890 }
891 }
892}
893
894void unregister_service(DIS_DNS_CONN *dnsp, SERVICE *servp)
895{
896 register DIS_DNS_PACKET *dis_dns_p = &(dnsp->dis_dns_packet);
897 register int n_services;
898 register SERVICE_REG *serv_regp;
899 extern int get_node_addr();
900
901 if(dnsp->dns_dis_conn_id > 0)
902 {
903 if(!dis_dns_p->src_type)
904 {
905 get_node_name( dis_dns_p->node_name );
906/*
907 strcpy( dis_dns_p->task_name, Task_name );
908*/
909 strncpy( dis_dns_p->task_name, dnsp->task_name,
910 MAX_TASK_NAME-4 );
911 dis_dns_p->task_name[MAX_TASK_NAME-4-1] = '\0';
912 get_node_addr( dis_dns_p->node_addr );
913 dis_dns_p->port = htovl(Port_number);
914 dis_dns_p->protocol = htovl(Protocol);
915 dis_dns_p->src_type = htovl(SRC_DIS);
916 dis_dns_p->format = htovl(MY_FORMAT);
917 }
918 serv_regp = dis_dns_p->services;
919 strcpy( serv_regp->service_name, servp->name );
920 strcpy( serv_regp->service_def, servp->def );
921 serv_regp->service_id = htovl( servp->id | 0x80000000);
922 serv_regp++;
923 n_services = 1;
924 servp->registered = 0;
925 dis_dns_p->n_services = htovl(n_services);
926 dis_dns_p->size = htovl(DIS_DNS_HEADER +
927 n_services * sizeof(SERVICE_REG));
928
929 if( !dna_write(dnsp->dns_dis_conn_id, &(dnsp->dis_dns_packet),
930 DIS_DNS_HEADER + n_services * sizeof(SERVICE_REG)) )
931 {
932 release_conn(dnsp->dns_dis_conn_id, 0, 1);
933 }
934 if(dnsp->dis_service_id)
935 dis_update_service(dnsp->dis_service_id);
936 }
937}
938
939void do_update_service_list(DIS_DNS_CONN *dnsp)
940{
941 dnsp->updating_service_list = 0;
942 dis_update_service(dnsp->dis_service_id);
943}
944
945/* start serving client requests
946 *
947 * Using the DNA package start accepting requests from clients.
948 * When a request arrives the routine "dis_insert_request" will be executed.
949 */
950
951int dis_start_serving(char *task)
952{
953 return dis_start_serving_dns(0, task);
954}
955
956static DIS_DNS_CONN *create_dns(long dnsid)
957{
958 DIS_DNS_CONN *dnsp;
959
960 dnsp = malloc(sizeof(DIS_DNS_CONN));
961 dnsp->dns_timr_ent = (TIMR_ENT *)0;
962 dnsp->dis_n_services = 0;
963 dnsp->dns_dis_conn_id = 0;
964 dnsp->dis_first_time = 1;
965 dnsp->serving = 0;
966 dnsp->dis_dns_packet.size = 0;
967 dnsp->dis_dns_packet.src_type = 0;
968 dnsp->dis_dns_packet.node_name[0] = 0;
969 dnsp->updating_service_list = 0;
970 dnsp->dnsid = dnsid;
971 dll_insert_queue( (DLL *) DNS_head, (DLL *) dnsp );
972 return dnsp;
973}
974
975void dis_dns_init()
976{
977 static int done = 0;
978 DIS_DNS_CONN *dnsp;
979 void dim_init_threads(void);
980
981 if(!done)
982 {
983 if(!Threads_off)
984 {
985 dim_init_threads();
986 }
987 {
988 DISABLE_AST
989 if(!DNS_head)
990 {
991 DNS_head = (DIS_DNS_CONN *)malloc(sizeof(DIS_DNS_CONN));
992 dll_init( (DLL *) DNS_head );
993 }
994 dnsp = create_dns(0);
995 Default_DNS = dnsp;
996 done = 1;
997 ENABLE_AST
998 }
999 }
1000}
1001
1002int dis_start_serving_dns(long dnsid, char *task/*, int *idlist*/)
1003{
1004 char str0[MAX_NAME], str1[MAX_NAME],str2[MAX_NAME],
1005 str3[MAX_NAME],str4[MAX_NAME];
1006 char task_name_aux[MAX_TASK_NAME];
1007 extern int open_dns();
1008 extern DIS_DNS_CONN *dis_find_dns(long);
1009 DIS_DNS_CONN *dnsp;
1010 int more_ids[10] = {0};
1011
1012 dis_init();
1013 {
1014 DISABLE_AST
1015 /*
1016#ifdef VxWorks
1017 taskDeleteHookAdd(remove_all_services);
1018 printf("Adding delete hook\n");
1019#endif
1020*/
1021
1022 if(!Client_head)
1023 {
1024 Client_head = (CLIENT *)malloc(sizeof(CLIENT));
1025 dll_init( (DLL *) Client_head );
1026 }
1027 if(dnsid == 0)
1028 {
1029 dnsp = Default_DNS;
1030 }
1031 else if(!(dnsp = dis_find_dns(dnsid)))
1032 {
1033 dnsp = create_dns(dnsid);
1034 }
1035 dnsp->serving = 1;
1036 Serving = 1;
1037 if(Dis_first_time)
1038 {
1039 strncpy( task_name_aux, task, MAX_TASK_NAME );
1040 task_name_aux[MAX_TASK_NAME-1] = '\0';
1041 Port_number = SEEK_PORT;
1042 if( !(Dis_conn_id = dna_open_server( task_name_aux, dis_insert_request,
1043 &Protocol, &Port_number, error_handler) ))
1044 {
1045 ENABLE_AST
1046 return(0);
1047 }
1048 Dis_first_time = 0;
1049 }
1050 if(dnsp->dis_first_time)
1051 {
1052 dnsp->dis_first_time = 0;
1053
1054 sprintf(str0, "%s/VERSION_NUMBER", task);
1055 sprintf(str1, "%s/CLIENT_LIST", task);
1056 sprintf(str2, "%s/SERVICE_LIST", task);
1057 sprintf(str3, "%s/SET_EXIT_HANDLER", task);
1058 sprintf(str4, "%s/EXIT", task);
1059
1060 more_ids[0] = do_dis_add_service_dns( str0, "L", &Version_number,
1061 sizeof(Version_number), 0, 0, dnsid );
1062
1063 more_ids[1] = do_dis_add_service_dns( str1, "C", 0, 0, client_info, (long)dnsp, dnsid );
1064 dnsp->dis_client_id = more_ids[1];
1065 more_ids[2] = do_dis_add_service_dns( str2, "C", 0, 0, service_info, (long)dnsp, dnsid );
1066 dnsp->dis_service_id = more_ids[2];
1067 more_ids[3] = do_dis_add_cmnd_dns( str3, "L:1", add_exit_handler, 0, dnsid );
1068 more_ids[4] = do_dis_add_cmnd_dns( str4, "L:1", exit_handler, 0, dnsid );
1069 more_ids[5] = 0;
1070 strcpy( dnsp->task_name, task );
1071 }
1072/*
1073 if(idlist)
1074 {
1075 for(i = 0; idlist[i]; i++)
1076 {
1077 servp = (SERVICE *)id_get_ptr(idlist[i], SRC_DIS);
1078 if(servp)
1079 {
1080 servp->dnsp = dnsp;
1081 n_services++;
1082 }
1083 }
1084 }
1085 if(dnsp != Default_DNS)
1086 {
1087 for(i = 0; more_ids[i]; i++)
1088 {
1089 servp = (SERVICE *)id_get_ptr(more_ids[i], SRC_DIS);
1090 if(servp)
1091 {
1092 servp->dnsp = dnsp;
1093 n_services++;
1094 }
1095 }
1096 dnsp->dis_n_services += n_services;
1097 Dis_n_services -= n_services;
1098 }
1099*/
1100 if(!Dis_timer_q)
1101 Dis_timer_q = dtq_create();
1102 if( !dnsp->dns_dis_conn_id )
1103 {
1104 if(!strcmp(task,"DIS_DNS"))
1105 {
1106 register_services(dnsp, ALL, 1);
1107 ENABLE_AST
1108 return(id_get(&(dnsp->dis_dns_packet), SRC_DIS));
1109 }
1110 else
1111 {
1112
1113 dnsp->dns_dis_conn_id = open_dns(dnsid, recv_dns_dis_rout, error_handler,
1114 DIS_DNS_TMOUT_MIN, DIS_DNS_TMOUT_MAX, SRC_DIS );
1115 if(dnsp->dns_dis_conn_id == -2)
1116 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
1117 }
1118 }
1119 else
1120 {
1121 register_services(dnsp, MORE, 0);
1122 if(dnsp->dis_service_id)
1123 {
1124/*
1125 dis_update_service(Dis_service_id);
1126*/
1127 if(!dnsp->updating_service_list)
1128 {
1129 dtq_start_timer(1, do_update_service_list, dnsp);
1130 dnsp->updating_service_list = 1;
1131 }
1132 }
1133 }
1134 ENABLE_AST
1135 }
1136 return(1);
1137}
1138
1139
1140/* asynchrounous reception of requests */
1141/*
1142 Called by DNA package.
1143 A request has arrived, queue it to process later - dis_ins_request
1144*/
1145static void dis_insert_request(int conn_id, DIC_PACKET *dic_packet, int size, int status)
1146{
1147 register SERVICE *servp;
1148 register REQUEST *newp, *reqp;
1149 CLIENT *clip;
1150 REQUEST_PTR *reqpp;
1151 int type, new_client = 0, found = 0;
1152 int find_release_request();
1153 DIS_DNS_CONN *dnsp;
1154
1155 if(size){}
1156 /* status = 1 => new connection, status = -1 => conn. lost */
1157 if(!Client_head)
1158 {
1159 Client_head = (CLIENT *)malloc(sizeof(CLIENT));
1160 dll_init( (DLL *) Client_head );
1161 }
1162 if(status != 0)
1163 {
1164 if(status == -1) /* release all requests from conn_id */
1165 {
1166 release_conn(conn_id, 0, 0);
1167 }
1168 }
1169 else
1170 {
1171 if(!(servp = find_service(dic_packet->service_name)))
1172 {
1173 release_conn(conn_id, 0, 0);
1174 return;
1175 }
1176 dic_packet->type = vtohl(dic_packet->type);
1177 type = dic_packet->type & 0xFFF;
1178 /*
1179 if(type == COMMAND)
1180 {
1181 Curr_conn_id = conn_id;
1182 execute_command(servp, dic_packet);
1183 Curr_conn_id = 0;
1184 return;
1185 }
1186 */
1187 if(type == DIM_DELETE)
1188 {
1189 find_release_request(conn_id, vtohl(dic_packet->service_id));
1190 return;
1191 }
1192 newp = (REQUEST *)/*my_*/malloc(sizeof(REQUEST));
1193 newp->service_ptr = servp;
1194 newp->service_id = vtohl(dic_packet->service_id);
1195 newp->type = dic_packet->type;
1196 newp->timeout = vtohl(dic_packet->timeout);
1197 newp->format = vtohl(dic_packet->format);
1198 newp->conn_id = conn_id;
1199 newp->first_time = 1;
1200 newp->delay_delete = 0;
1201 newp->to_delete = 0;
1202 newp->timr_ent = 0;
1203 newp->req_id = id_get((void *)newp, SRC_DIS);
1204 newp->reqpp = 0;
1205 if(type == ONCE_ONLY)
1206 {
1207 execute_service(newp->req_id);
1208 id_free(newp->req_id, SRC_DIS);
1209 free(newp);
1210 return;
1211 }
1212 if(type == COMMAND)
1213 {
1214 Curr_conn_id = conn_id;
1215 execute_command(servp, dic_packet);
1216 Curr_conn_id = 0;
1217 reqp = servp->request_head;
1218 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1219 (DLL *) reqp)) )
1220 {
1221 if(reqp->conn_id == conn_id)
1222 {
1223 id_free(newp->req_id, SRC_DIS);
1224 free(newp);
1225 found = 1;
1226 break;
1227 }
1228 }
1229 if(!found)
1230 dll_insert_queue( (DLL *) servp->request_head, (DLL *) newp );
1231 return;
1232 }
1233 dll_insert_queue( (DLL *) servp->request_head, (DLL *) newp );
1234 if(!(clip = find_client(conn_id)))
1235 {
1236 clip = (CLIENT *)malloc(sizeof(CLIENT));
1237 clip->conn_id = conn_id;
1238 clip->dnsp = servp->dnsp;
1239 clip->requestp_head = (REQUEST_PTR *)malloc(sizeof(REQUEST_PTR));
1240 dll_init( (DLL *) clip->requestp_head );
1241 dll_insert_queue( (DLL *) Client_head, (DLL *) clip );
1242 new_client = 1;
1243 }
1244 reqpp = (REQUEST_PTR *)malloc(sizeof(REQUEST_PTR));
1245 reqpp->reqp = newp;
1246 dll_insert_queue( (DLL *) clip->requestp_head, (DLL *) reqpp );
1247 newp->reqpp = reqpp;
1248 if((type != MONIT_ONLY) && (type != UPDATE))
1249 {
1250 execute_service(newp->req_id);
1251 }
1252 if((type != MONIT_ONLY) && (type != MONIT_FIRST))
1253 {
1254 if(newp->timeout != 0)
1255 {
1256 newp->timr_ent = dtq_add_entry( Dis_timer_q,
1257 newp->timeout,
1258 execute_service,
1259 newp->req_id );
1260 }
1261 }
1262 if(new_client)
1263 {
1264 Last_client = conn_id;
1265 dnsp = clip->dnsp;
1266 if(dnsp->dis_client_id)
1267 dis_update_service(dnsp->dis_client_id);
1268 }
1269 }
1270}
1271
1272/* A timeout for a timed or monitored service occured, serve it. */
1273
1274int execute_service( int req_id )
1275{
1276 int *buffp, size;
1277 register REQUEST *reqp;
1278 register SERVICE *servp;
1279 char str[80], def[MAX_NAME];
1280 register char *ptr;
1281 int last_conn_id;
1282 int *pkt_buffer, header_size, aux;
1283#ifdef WIN32
1284 struct timeb timebuf;
1285#else
1286 struct timeval tv;
1287 struct timezone *tz;
1288#endif
1289 FORMAT_STR format_data_cp[MAX_NAME/4];
1290
1291 reqp = (REQUEST *)id_get_ptr(req_id, SRC_DIS);
1292 if(!reqp)
1293 return(0);
1294 if(reqp->to_delete)
1295 return(0);
1296 reqp->delay_delete++;
1297 servp = reqp->service_ptr;
1298 last_conn_id = Curr_conn_id;
1299 Curr_conn_id = reqp->conn_id;
1300 ptr = servp->def;
1301 if(servp->type == COMMAND)
1302 {
1303 sprintf(str,"This is a COMMAND Service");
1304 buffp = (int *)str;
1305 size = 26;
1306 sprintf(def,"c:26");
1307 ptr = def;
1308 }
1309 else if( servp->user_routine != 0 )
1310 {
1311 (servp->user_routine)( &servp->tag, &buffp, &size,
1312 &reqp->first_time );
1313 reqp->first_time = 0;
1314
1315 }
1316 else
1317 {
1318 buffp = servp->address;
1319 size = servp->size;
1320 }
1321 Curr_conn_id = last_conn_id;
1322/* send even if no data but not if negative */
1323 if( size < 0)
1324 {
1325 reqp->delay_delete--;
1326 return(0);
1327 }
1328 if( DIS_STAMPED_HEADER + size > Dis_packet_size )
1329 {
1330 if( Dis_packet_size )
1331 free( Dis_packet );
1332 Dis_packet = (DIS_STAMPED_PACKET *)malloc(DIS_STAMPED_HEADER + size);
1333 if(!Dis_packet)
1334 {
1335 reqp->delay_delete--;
1336 return(0);
1337 }
1338 Dis_packet_size = DIS_STAMPED_HEADER + size;
1339 }
1340 Dis_packet->service_id = htovl(reqp->service_id);
1341 if((reqp->type & 0xFF000) == STAMPED)
1342 {
1343 pkt_buffer = ((DIS_STAMPED_PACKET *)Dis_packet)->buffer;
1344 header_size = DIS_STAMPED_HEADER;
1345 if(!servp->user_secs)
1346 {
1347#ifdef WIN32
1348 ftime(&timebuf);
1349 aux = timebuf.millitm;
1350 Dis_packet->time_stamp[0] = htovl(aux);
1351 Dis_packet->time_stamp[1] = htovl((int)timebuf.time);
1352#else
1353 tz = 0;
1354 gettimeofday(&tv, tz);
1355 aux = tv.tv_usec / 1000;
1356 Dis_packet->time_stamp[0] = htovl(aux);
1357 Dis_packet->time_stamp[1] = htovl(tv.tv_sec);
1358#endif
1359 }
1360 else
1361 {
1362 aux = /*0xc0de0000 |*/ servp->user_millisecs;
1363 Dis_packet->time_stamp[0] = htovl(aux);
1364 Dis_packet->time_stamp[1] = htovl(servp->user_secs);
1365 }
1366 Dis_packet->reserved[0] = htovl(0xc0dec0de);
1367 Dis_packet->quality = htovl(servp->quality);
1368 }
1369 else
1370 {
1371 pkt_buffer = ((DIS_PACKET *)Dis_packet)->buffer;
1372 header_size = DIS_HEADER;
1373 }
1374 memcpy(format_data_cp, servp->format_data, sizeof(format_data_cp));
1375 size = copy_swap_buffer_out(reqp->format, format_data_cp,
1376 pkt_buffer,
1377 buffp, size);
1378 Dis_packet->size = htovl(header_size + size);
1379 if( !dna_write_nowait(reqp->conn_id, Dis_packet, header_size + size) )
1380 {
1381 reqp->to_delete = 1;
1382 }
1383/*
1384 else
1385 {
1386 if((reqp->type & 0xFFF) == MONITORED)
1387 {
1388 if(reqp->timr_ent)
1389 dtq_clear_entry(reqp->timr_ent);
1390 }
1391 }
1392*/
1393 reqp->delay_delete--;
1394 return(1);
1395}
1396
1397void remove_service( int req_id )
1398{
1399 register REQUEST *reqp;
1400 register SERVICE *servp;
1401 static DIS_PACKET *dis_packet;
1402 static int packet_size = 0;
1403 int service_id;
1404
1405 reqp = (REQUEST *)id_get_ptr(req_id, SRC_DIS);
1406 servp = reqp->service_ptr;
1407 if( !packet_size ) {
1408 dis_packet = (DIS_PACKET *)malloc(DIS_HEADER);
1409 packet_size = DIS_HEADER;
1410 }
1411 service_id = (reqp->service_id | 0x80000000);
1412 dis_packet->service_id = htovl(service_id);
1413 dis_packet->size = htovl(DIS_HEADER);
1414 if( !dna_write(reqp->conn_id, dis_packet, DIS_HEADER) )
1415 {
1416 release_conn(reqp->conn_id, 0, 0);
1417 }
1418}
1419
1420void execute_command(SERVICE *servp, DIC_PACKET *packet)
1421{
1422 int size;
1423 int format;
1424 FORMAT_STR format_data_cp[MAX_NAME/4], *formatp;
1425 static int *buffer;
1426 static int buffer_size = 0;
1427 int add_size;
1428
1429 size = vtohl(packet->size) - DIC_HEADER;
1430 add_size = size + (size/2);
1431 if(!buffer_size)
1432 {
1433 buffer = (int *)malloc(add_size);
1434 buffer_size = add_size;
1435 }
1436 else
1437 {
1438 if( add_size > buffer_size )
1439 {
1440 free(buffer);
1441 buffer = (int *)malloc(add_size);
1442 buffer_size = add_size;
1443 }
1444 }
1445
1446 dis_set_timestamp(servp->id, 0, 0);
1447 if(servp->user_routine != 0)
1448 {
1449 format = vtohl(packet->format);
1450 memcpy(format_data_cp, servp->format_data, sizeof(format_data_cp));
1451 if((format & 0xF) == ((MY_FORMAT) & 0xF))
1452 {
1453 for(formatp = format_data_cp; formatp->par_bytes; formatp++)
1454 {
1455 if(formatp->flags & IT_IS_FLOAT)
1456 formatp->flags |= (format & 0xf0);
1457 formatp->flags &= 0xFFF0; /* NOSWAP */
1458 }
1459 }
1460 else
1461 {
1462 for(formatp = format_data_cp; formatp->par_bytes; formatp++)
1463 {
1464 if(formatp->flags & IT_IS_FLOAT)
1465 formatp->flags |= (format & 0xf0);
1466 }
1467 }
1468 size = copy_swap_buffer_in(format_data_cp,
1469 buffer,
1470 packet->buffer, size);
1471 (servp->user_routine)(&servp->tag, buffer, &size);
1472 }
1473}
1474
1475void dis_report_service(char *serv_name)
1476{
1477 register SERVICE *servp;
1478 register REQUEST *reqp;
1479 int to_delete = 0, more;
1480
1481
1482 DISABLE_AST
1483 servp = find_service(serv_name);
1484 reqp = servp->request_head;
1485 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1486 (DLL *) reqp)) )
1487 {
1488 if((reqp->type & 0xFFF) != TIMED_ONLY)
1489 {
1490 execute_service(reqp->req_id);
1491 if(reqp->to_delete)
1492 to_delete = 1;
1493 }
1494 }
1495 if(to_delete)
1496 {
1497 do
1498 {
1499 more = 0;
1500 reqp = servp->request_head;
1501 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1502 (DLL *) reqp)) )
1503 {
1504 if(reqp->to_delete)
1505 {
1506 more = 1;
1507 release_conn(reqp->conn_id, 1, 0);
1508 break;
1509 }
1510 }
1511 }while(more);
1512 }
1513 ENABLE_AST
1514}
1515
1516int dis_update_service(unsigned service_id)
1517{
1518int do_update_service();
1519
1520 return(do_update_service(service_id,0));
1521}
1522
1523int dis_selective_update_service(unsigned service_id, int *client_ids)
1524{
1525int do_update_service();
1526
1527 return(do_update_service(service_id, client_ids));
1528}
1529
1530int check_client(REQUEST *reqp, int *client_ids)
1531{
1532 if(!client_ids)
1533 return(1);
1534 while(*client_ids)
1535 {
1536 if(reqp->conn_id == *client_ids)
1537 {
1538 return(1);
1539 }
1540 client_ids++;
1541 }
1542 return(0);
1543}
1544
1545int do_update_service(unsigned service_id, int *client_ids)
1546{
1547 register REQUEST *reqp;
1548 register SERVICE *servp;
1549 REQUEST_PTR *reqpp;
1550 CLIENT *clip;
1551 register int found = 0;
1552 int to_delete = 0, more, conn_id;
1553 char str[128];
1554 int release_request();
1555
1556 DISABLE_AST
1557 if(!service_id)
1558 {
1559 sprintf(str, "Update Service - Invalid service id");
1560 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1561 ENABLE_AST
1562 return(found);
1563 }
1564 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1565 if(!servp)
1566 {
1567 ENABLE_AST
1568 return(found);
1569 }
1570 if(servp->id != (int)service_id)
1571 {
1572 ENABLE_AST
1573 return(found);
1574 }
1575 servp->delay_delete = 1;
1576 reqp = servp->request_head;
1577 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1578 (DLL *) reqp)) )
1579 {
1580if(Debug_on)
1581{
1582dim_print_date_time_millis();
1583printf("Updating %s (id = %ld, ptr = %08lX) for %s@%s (req_id = %d, req_ptr = %08lX)\n",
1584 servp->name, (long)service_id, (long)servp,
1585 Net_conns[reqp->conn_id].task, Net_conns[reqp->conn_id].node, reqp->req_id, (long)reqp);
1586}
1587 if(check_client(reqp, client_ids))
1588 reqp->delay_delete = 1;
1589 }
1590 ENABLE_AST
1591 {
1592 DISABLE_AST
1593 reqp = servp->request_head;
1594 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1595 (DLL *) reqp)) )
1596 {
1597 if(reqp->delay_delete && ((reqp->type & 0xFFF) != COMMAND))
1598 {
1599 if(check_client(reqp, client_ids))
1600 {
1601 if( (reqp->type & 0xFFF) != TIMED_ONLY )
1602 {
1603 /* DISABLE_AST
1604 */
1605 execute_service(reqp->req_id);
1606 found++;
1607 ENABLE_AST
1608 {
1609 DISABLE_AST
1610 }
1611 }
1612 }
1613 }
1614 }
1615 ENABLE_AST
1616 }
1617 {
1618 DISABLE_AST
1619 reqp = servp->request_head;
1620 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1621 (DLL *) reqp)) )
1622 {
1623 if(check_client(reqp, client_ids))
1624 {
1625 reqp->delay_delete = 0;
1626 if(reqp->to_delete)
1627 to_delete = 1;
1628 }
1629 }
1630 ENABLE_AST
1631 }
1632 if(to_delete)
1633 {
1634 DISABLE_AST
1635 do
1636 {
1637 more = 0;
1638 reqp = servp->request_head;
1639 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1640 (DLL *) reqp)) )
1641 {
1642 if(reqp->to_delete & 0x1)
1643 {
1644 more = 1;
1645 reqp->to_delete = 0;
1646 release_conn(reqp->conn_id, 1, 0);
1647 break;
1648 }
1649 else if(reqp->to_delete & 0x2)
1650 {
1651 more = 1;
1652 reqp->to_delete = 0;
1653 reqpp = reqp->reqpp;
1654 conn_id = reqp->conn_id;
1655 release_request(reqp, reqpp, 1);
1656 clip = find_client(conn_id);
1657 if(clip)
1658 {
1659 if( dll_empty((DLL *)clip->requestp_head) )
1660 {
1661 release_conn( conn_id, 0, 0);
1662 }
1663 }
1664 break;
1665 }
1666 }
1667 }while(more);
1668 ENABLE_AST
1669 }
1670 {
1671 DISABLE_AST
1672 servp->delay_delete = 0;
1673 if(servp->to_delete)
1674 {
1675 dis_remove_service(servp->id);
1676 }
1677 ENABLE_AST
1678 }
1679
1680 return(found);
1681}
1682
1683int dis_get_n_clients(unsigned service_id)
1684{
1685 register REQUEST *reqp;
1686 register SERVICE *servp;
1687 register int found = 0;
1688 char str[128];
1689
1690 DISABLE_AST
1691 if(!service_id)
1692 {
1693 sprintf(str, "Service Has Clients- Invalid service id");
1694 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1695 ENABLE_AST
1696 return(found);
1697 }
1698 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1699 if(!servp)
1700 {
1701 ENABLE_AST
1702 return(found);
1703 }
1704 if(servp->id != (int)service_id)
1705 {
1706 ENABLE_AST
1707 return(found);
1708 }
1709 reqp = servp->request_head;
1710 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1711 (DLL *) reqp)) )
1712 {
1713 found++;
1714 }
1715 ENABLE_AST
1716 return found;
1717}
1718
1719int dis_get_timeout(unsigned service_id, int client_id)
1720{
1721 register REQUEST *reqp;
1722 register SERVICE *servp;
1723 char str[128];
1724
1725 if(!service_id)
1726 {
1727 sprintf(str,"Get Timeout - Invalid service id");
1728 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1729 return(-1);
1730 }
1731 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1732 if(!servp)
1733 {
1734 return(-1);
1735 }
1736 reqp = servp->request_head;
1737 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1738 (DLL *) reqp)) )
1739 {
1740 if(reqp->conn_id == client_id)
1741 return(reqp->timeout);
1742 }
1743 return(-1);
1744}
1745
1746void dis_set_quality( unsigned serv_id, int quality )
1747{
1748 register SERVICE *servp;
1749 char str[128];
1750
1751 DISABLE_AST
1752 if(!serv_id)
1753 {
1754 sprintf(str,"Set Quality - Invalid service id");
1755 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1756 ENABLE_AST
1757 return;
1758 }
1759 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
1760 if(!servp)
1761 {
1762 ENABLE_AST
1763 return;
1764 }
1765 if(servp->id != (int)serv_id)
1766 {
1767 ENABLE_AST
1768 return;
1769 }
1770 servp->quality = quality;
1771 ENABLE_AST
1772}
1773
1774int dis_set_timestamp( unsigned serv_id, int secs, int millisecs )
1775{
1776 register SERVICE *servp;
1777 char str[128];
1778#ifdef WIN32
1779 struct timeb timebuf;
1780#else
1781 struct timeval tv;
1782 struct timezone *tz;
1783#endif
1784
1785 DISABLE_AST
1786 if(!serv_id)
1787 {
1788 sprintf(str,"Set Timestamp - Invalid service id");
1789 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1790 ENABLE_AST
1791 return(0);
1792 }
1793 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
1794 if(!servp)
1795 {
1796 ENABLE_AST
1797 return(0);
1798 }
1799 if(servp->id != (int)serv_id)
1800 {
1801 ENABLE_AST
1802 return(0);
1803 }
1804 if(secs == 0)
1805 {
1806#ifdef WIN32
1807 ftime(&timebuf);
1808 servp->user_secs = (int)timebuf.time;
1809 servp->user_millisecs = timebuf.millitm;
1810#else
1811 tz = 0;
1812 gettimeofday(&tv, tz);
1813 servp->user_secs = tv.tv_sec;
1814 servp->user_millisecs = tv.tv_usec / 1000;
1815#endif
1816 }
1817 else
1818 {
1819 servp->user_secs = secs;
1820/*
1821 servp->user_millisecs = (millisecs & 0xffff);
1822*/
1823 servp->user_millisecs = millisecs;
1824 }
1825 ENABLE_AST
1826 return(1);
1827}
1828
1829int dis_get_timestamp( unsigned serv_id, int *secs, int *millisecs )
1830{
1831 register SERVICE *servp;
1832 char str[128];
1833
1834 DISABLE_AST
1835 if(!serv_id)
1836 {
1837 sprintf(str,"Get Timestamp - Invalid service id");
1838 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1839 ENABLE_AST
1840 return(0);
1841 }
1842 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
1843 if(!servp)
1844 {
1845 ENABLE_AST
1846 return(0);
1847 }
1848 if(servp->id != (int)serv_id)
1849 {
1850 ENABLE_AST
1851 return(0);
1852 }
1853 if(servp->user_secs)
1854 {
1855 *secs = servp->user_secs;
1856 *millisecs = servp->user_millisecs;
1857 }
1858 else
1859 {
1860 *secs = 0;
1861 *millisecs = 0;
1862 }
1863 ENABLE_AST
1864 return(1);
1865}
1866
1867void dis_send_service(unsigned service_id, int *buffer, int size)
1868{
1869 register REQUEST *reqp, *prevp;
1870 register SERVICE *servp;
1871 static DIS_PACKET *dis_packet;
1872 static int packet_size = 0;
1873 int conn_id;
1874 char str[128];
1875
1876 DISABLE_AST
1877 if( !service_id ) {
1878 sprintf(str,"Send Service - Invalid service id");
1879 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1880 ENABLE_AST
1881 return;
1882 }
1883 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1884 if(!packet_size)
1885 {
1886 dis_packet = (DIS_PACKET *)malloc(DIS_HEADER+size);
1887 packet_size = DIS_HEADER + size;
1888 }
1889 else
1890 {
1891 if( DIS_HEADER+size > packet_size )
1892 {
1893 free(dis_packet);
1894 dis_packet = (DIS_PACKET *)malloc(DIS_HEADER+size);
1895 packet_size = DIS_HEADER+size;
1896 }
1897 }
1898 prevp = servp->request_head;
1899 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1900 (DLL *) prevp)) )
1901 {
1902 dis_packet->service_id = htovl(reqp->service_id);
1903 memcpy(dis_packet->buffer, buffer, size);
1904 dis_packet->size = htovl(DIS_HEADER + size);
1905
1906 conn_id = reqp->conn_id;
1907 if( !dna_write_nowait(conn_id, dis_packet, size + DIS_HEADER) )
1908 {
1909 release_conn(conn_id, 1, 0);
1910 }
1911 else
1912 prevp = reqp;
1913 }
1914 ENABLE_AST
1915}
1916
1917int dis_remove_service(unsigned service_id)
1918{
1919 register REQUEST *reqp, *auxp;
1920 register SERVICE *servp;
1921 REQUEST_PTR *reqpp;
1922 int found = 0;
1923 char str[128];
1924 int release_request();
1925 int dis_hash_service_remove();
1926 DIS_DNS_CONN *dnsp;
1927 int n_services;
1928 void do_dis_stop_serving_dns(DIS_DNS_CONN *);
1929
1930 DISABLE_AST
1931 if(!service_id)
1932 {
1933 sprintf(str,"Remove Service - Invalid service id");
1934 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1935 ENABLE_AST
1936 return(found);
1937 }
1938 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1939 if(!servp)
1940 {
1941 ENABLE_AST
1942 return(found);
1943 }
1944 if(servp->id != (int)service_id)
1945 {
1946 ENABLE_AST
1947 return(found);
1948 }
1949 if(servp->delay_delete)
1950 {
1951 servp->to_delete = 1;
1952 ENABLE_AST
1953 return(found);
1954 }
1955 /* remove from name server */
1956
1957 dnsp = servp->dnsp;
1958 unregister_service(dnsp, servp);
1959 /* Release client requests and remove from actual clients */
1960 reqp = servp->request_head;
1961 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1962 (DLL *) reqp)) )
1963 {
1964 remove_service(reqp->req_id);
1965 auxp = reqp->prev;
1966 reqpp = (REQUEST_PTR *) reqp->reqpp;
1967 release_request(reqp, reqpp, 1);
1968 found = 1;
1969 reqp = auxp;
1970 }
1971 if(servp->id == (int)dnsp->dis_service_id)
1972 dnsp->dis_service_id = 0;
1973 if(servp->id == (int)dnsp->dis_client_id)
1974 dnsp->dis_client_id = 0;
1975 dis_hash_service_remove(servp);
1976 id_free(servp->id, SRC_DIS);
1977 free(servp->request_head);
1978 free(servp);
1979/*
1980 if(dnsp != Default_DNS)
1981 {
1982 dnsp->dis_n_services--;
1983 n_services = dnsp->dis_n_services;
1984 }
1985 else
1986 {
1987 Dis_n_services--;
1988 n_services = Dis_n_services;
1989 }
1990*/
1991 dnsp->dis_n_services--;
1992 n_services = dnsp->dis_n_services;
1993
1994 ENABLE_AST
1995 if(dnsp->serving)
1996 {
1997 if(n_services == 5)
1998 {
1999/*
2000 dis_stop_serving();
2001*/
2002 do_dis_stop_serving_dns(dnsp);
2003 }
2004 }
2005 return(found);
2006}
2007
2008void do_dis_stop_serving_dns(DIS_DNS_CONN *dnsp)
2009{
2010register SERVICE *servp, *prevp;
2011void dim_stop_threads(void);
2012int dis_no_dns();
2013int hash_index, old_index;
2014
2015 dnsp->serving = 0;
2016 dis_init();
2017/*
2018 dis_hash_service_init();
2019 prevp = 0;
2020 if(Dis_conn_id)
2021 {
2022 dna_close(Dis_conn_id);
2023 Dis_conn_id = 0;
2024 }
2025*/
2026 {
2027 DISABLE_AST
2028 if(dnsp->dns_timr_ent)
2029 {
2030 dtq_rem_entry(Dis_timer_q, dnsp->dns_timr_ent);
2031 dnsp->dns_timr_ent = NULL;
2032 }
2033 if(dnsp->dns_dis_conn_id)
2034 {
2035 dna_close(dnsp->dns_dis_conn_id);
2036 dnsp->dns_dis_conn_id = 0;
2037 }
2038 ENABLE_AST
2039 }
2040 {
2041 DISABLE_AST
2042 prevp = 0;
2043 hash_index = -1;
2044 old_index = -1;
2045 while( (servp = dis_hash_service_get_next(&hash_index, prevp, 0)) )
2046 {
2047 if(servp->dnsp == dnsp)
2048 {
2049 dis_remove_service(servp->id);
2050 if(old_index != hash_index)
2051 prevp = 0;
2052 }
2053 else
2054 {
2055 prevp = servp;
2056 old_index = hash_index;
2057 }
2058 }
2059 ENABLE_AST
2060 }
2061 dnsp->dis_first_time = 1;
2062/*
2063 if(dnsp != Default_DNS)
2064 {
2065 dll_remove(dnsp);
2066 free(dnsp);
2067 }
2068*/
2069/*
2070 if(dll_empty(DNS_head))
2071*/
2072 if(dis_no_dns())
2073 dis_stop_serving();
2074}
2075
2076void dis_stop_serving_dns(long dnsid)
2077{
2078 DIS_DNS_CONN *dnsp, *dis_find_dns();
2079
2080 dnsp = dis_find_dns(dnsid);
2081 do_dis_stop_serving_dns(dnsp);
2082}
2083
2084void dis_stop_serving()
2085{
2086register SERVICE *servp, *prevp;
2087void dim_stop_threads(void);
2088int hash_index;
2089
2090 Serving = 0;
2091 dis_init();
2092 if(Dis_conn_id)
2093 {
2094 dna_close(Dis_conn_id);
2095 Dis_conn_id = 0;
2096 }
2097/*
2098 if(Dns_dis_conn_id)
2099 {
2100 dna_close(Dns_dis_conn_id);
2101 Dns_dis_conn_id = 0;
2102 }
2103*/
2104 {
2105 DISABLE_AST
2106 prevp = 0;
2107 hash_index = -1;
2108 while( (servp = dis_hash_service_get_next(&hash_index, prevp, 0)) )
2109 {
2110 dis_remove_service(servp->id);
2111 prevp = 0;
2112 }
2113 ENABLE_AST
2114 }
2115/*
2116 if(Dis_conn_id)
2117 dna_close(Dis_conn_id);
2118 if(Dns_dis_conn_id)
2119 dna_close(Dns_dis_conn_id);
2120 Dns_dis_conn_id = 0;
2121*/
2122 Dis_first_time = 1;
2123/*
2124 if(Dns_timr_ent)
2125 {
2126 dtq_rem_entry(Dis_timer_q, Dns_timr_ent);
2127 Dns_timr_ent = NULL;
2128 }
2129*/
2130 dtq_delete(Dis_timer_q);
2131 Dis_timer_q = 0;
2132 dim_stop_threads();
2133}
2134
2135/* find service by name */
2136SERVICE *find_service(char *name)
2137{
2138 return(dis_hash_service_exists(name));
2139}
2140
2141CLIENT *find_client(int conn_id)
2142{
2143 register CLIENT *clip;
2144
2145 clip = (CLIENT *)
2146 dll_search( (DLL *) Client_head, &conn_id, sizeof(conn_id));
2147 return(clip);
2148}
2149
2150void release_all_requests(int conn_id, CLIENT *clip)
2151{
2152 register REQUEST_PTR *reqpp, *auxp;
2153 register REQUEST *reqp;
2154 int found = 0;
2155 int release_request();
2156 DIS_DNS_CONN *dnsp;
2157
2158 DISABLE_AST;
2159 if(clip)
2160 {
2161 reqpp = clip->requestp_head;
2162 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2163 (DLL *) reqpp)) )
2164 {
2165 auxp = reqpp->prev;
2166 reqp = (REQUEST *) reqpp->reqp;
2167 release_request(reqp, reqpp, 0);
2168 found = 1;
2169 reqpp = auxp;
2170 }
2171 dnsp = clip->dnsp;
2172 dll_remove(clip);
2173 free(clip->requestp_head);
2174 free(clip);
2175 }
2176 if(found)
2177 {
2178 Last_client = -conn_id;
2179 if(dnsp->dis_client_id)
2180 dis_update_service(dnsp->dis_client_id);
2181 }
2182 dna_close(conn_id);
2183 ENABLE_AST;
2184}
2185
2186CLIENT *check_delay_delete(int conn_id)
2187{
2188 register REQUEST_PTR *reqpp;
2189 register CLIENT *clip;
2190 register REQUEST *reqp;
2191 int found = 0;
2192
2193 DISABLE_AST;
2194 clip = find_client(conn_id);
2195 if(clip)
2196 {
2197 reqpp = clip->requestp_head;
2198 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2199 (DLL *) reqpp)) )
2200 {
2201 reqp = (REQUEST *) reqpp->reqp;
2202 if(reqp->delay_delete)
2203 {
2204 reqp->to_delete = 1;
2205 found = 1;
2206 }
2207 }
2208 }
2209 ENABLE_AST;
2210 if(found)
2211 {
2212 return((CLIENT *)-1);
2213 }
2214 return(clip);
2215}
2216
2217char *dis_get_error_services()
2218{
2219 return(dis_get_client_services(Error_conn_id));
2220}
2221
2222char *dis_get_client_services(int conn_id)
2223{
2224 register REQUEST_PTR *reqpp;
2225 register CLIENT *clip;
2226 register REQUEST *reqp;
2227 register SERVICE *servp;
2228
2229 int n_services = 0;
2230 int max_size;
2231 static int curr_allocated_size = 0;
2232 static char *service_info_buffer;
2233 char *buff_ptr;
2234
2235
2236 if(!conn_id)
2237 return((char *)0);
2238 {
2239 DISABLE_AST;
2240 clip = find_client(conn_id);
2241 if(clip)
2242 {
2243 reqpp = clip->requestp_head;
2244 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2245 (DLL *) reqpp)))
2246 {
2247 n_services++;
2248 }
2249 if(!n_services)
2250 {
2251 ENABLE_AST
2252 return((char *)0);
2253 }
2254 max_size = n_services * MAX_NAME;
2255 if(!curr_allocated_size)
2256 {
2257 service_info_buffer = (char *)malloc(max_size);
2258 curr_allocated_size = max_size;
2259 }
2260 else if (max_size > curr_allocated_size)
2261 {
2262 free(service_info_buffer);
2263 service_info_buffer = (char *)malloc(max_size);
2264 curr_allocated_size = max_size;
2265 }
2266 service_info_buffer[0] = '\0';
2267 buff_ptr = service_info_buffer;
2268 reqpp = clip->requestp_head;
2269 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2270 (DLL *) reqpp)) )
2271 {
2272 reqp = (REQUEST *) reqpp->reqp;
2273 servp = reqp->service_ptr;
2274 strcat(buff_ptr, servp->name);
2275 strcat(buff_ptr, "\n");
2276 buff_ptr += strlen(buff_ptr);
2277 }
2278 }
2279 else
2280 {
2281 ENABLE_AST
2282 return((char *)0);
2283 }
2284 ENABLE_AST;
2285 }
2286/*
2287 dim_print_date_time();
2288 dna_get_node_task(conn_id, node, task);
2289 printf("Client %s@%s uses services: \n", task, node);
2290 printf("%s\n",service_info_buffer);
2291*/
2292 return(service_info_buffer);
2293}
2294
2295int find_release_request(int conn_id, int service_id)
2296{
2297 register REQUEST_PTR *reqpp, *auxp;
2298 register CLIENT *clip;
2299 register REQUEST *reqp;
2300 int release_request();
2301
2302 DISABLE_AST
2303 clip = find_client(conn_id);
2304 if(clip)
2305 {
2306 reqpp = clip->requestp_head;
2307 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2308 (DLL *) reqpp)) )
2309 {
2310 reqp = (REQUEST *) reqpp->reqp;
2311 if(reqp->service_id == service_id)
2312 {
2313 if(reqp->delay_delete)
2314 {
2315 reqp->to_delete += 0x2;
2316 }
2317 else
2318 {
2319 auxp = reqpp->prev;
2320 release_request(reqp, reqpp, 0);
2321 reqpp = auxp;
2322 }
2323 }
2324 }
2325 if( dll_empty((DLL *)clip->requestp_head) )
2326 {
2327 release_conn( conn_id, 0, 0 );
2328 }
2329 }
2330 ENABLE_AST
2331 return(1);
2332}
2333
2334int release_request(REQUEST *reqp, REQUEST_PTR *reqpp, int remove)
2335{
2336 int conn_id;
2337 CLIENT *clip;
2338
2339 DISABLE_AST
2340 conn_id = reqp->conn_id;
2341 if(reqpp)
2342 dll_remove((DLL *)reqpp);
2343 dll_remove((DLL *)reqp);
2344 if(reqp->timr_ent)
2345 dtq_rem_entry(Dis_timer_q, reqp->timr_ent);
2346 id_free(reqp->req_id, SRC_DIS);
2347 free(reqp);
2348 free(reqpp);
2349/* Would do it too early, the client will disconnect anyway
2350*/
2351 if((remove) && (!Serving))
2352 {
2353 clip = find_client(conn_id);
2354 if(clip)
2355 {
2356 if( dll_empty((DLL *)clip->requestp_head) )
2357 {
2358 release_conn( conn_id, 0, 0);
2359 }
2360 }
2361 }
2362
2363 ENABLE_AST
2364 return(1);
2365}
2366
2367static int release_conn(int conn_id, int print_flg, int dns_flag)
2368{
2369 static int releasing = 0;
2370 CLIENT *clip;
2371 int do_exit_handler();
2372
2373 DISABLE_AST
2374 if(print_flg){}
2375 if(dns_flag)
2376 {
2377 recv_dns_dis_rout( conn_id, 0, 0, STA_DISC );
2378 ENABLE_AST
2379 return(0);
2380 }
2381#ifdef VMS
2382 if(print_flg)
2383 {
2384 dim_print_date_time();
2385 dna_get_node_task(conn_id, node, task);
2386 printf(" Couldn't write to client %s@%s, releasing connection %d\n",
2387 task, node, conn_id);
2388 fflush(stdout);
2389 }
2390#endif
2391 clip = check_delay_delete(conn_id);
2392 if(clip != (CLIENT *)-1)
2393 {
2394 if( Client_exit_user_routine != 0 )
2395 {
2396 releasing++;
2397 Curr_conn_id = conn_id;
2398 do_exit_handler(conn_id);
2399 releasing--;
2400 }
2401 if(!releasing)
2402 {
2403 release_all_requests(conn_id, clip);
2404 }
2405 }
2406 ENABLE_AST
2407 return(1);
2408}
2409
2410typedef struct cmnds{
2411 struct cmnds *next;
2412 long tag;
2413 int size;
2414 int buffer[1];
2415} DIS_CMND;
2416
2417static DIS_CMND *Cmnds_head = (DIS_CMND *)0;
2418
2419void std_cmnd_handler(long *tag, int *cmnd_buff, int *size)
2420{
2421 register DIS_CMND *new_cmnd;
2422/* queue the command */
2423
2424 if(!Cmnds_head)
2425 {
2426 Cmnds_head = (DIS_CMND *)malloc(sizeof(DIS_CMND));
2427 sll_init((SLL *) Cmnds_head);
2428 }
2429 new_cmnd = (DIS_CMND *)malloc((*size)+12);
2430 new_cmnd->next = 0;
2431 new_cmnd->tag = *tag;
2432 new_cmnd->size = *size;
2433 memcpy(new_cmnd->buffer, cmnd_buff, *size);
2434 sll_insert_queue((SLL *) Cmnds_head, (SLL *) new_cmnd);
2435}
2436
2437int dis_get_next_cmnd(long *tag, int *buffer, int *size)
2438{
2439 register DIS_CMND *cmndp;
2440 register int ret_val = -1;
2441
2442 DISABLE_AST
2443 if(!Cmnds_head)
2444 {
2445 Cmnds_head = (DIS_CMND *)malloc(sizeof(DIS_CMND));
2446 sll_init((SLL *) Cmnds_head);
2447 }
2448 if(*size == 0)
2449 {
2450 if( (cmndp = (DIS_CMND *) sll_get_head((SLL *) Cmnds_head)))
2451 {
2452 if(cmndp->size > 0)
2453 {
2454 *size = cmndp->size;
2455 *tag = cmndp->tag;
2456 ENABLE_AST
2457 return(-1);
2458 }
2459 }
2460 }
2461 if( (cmndp = (DIS_CMND *) sll_remove_head((SLL *) Cmnds_head)) )
2462 {
2463 if (*size >= cmndp->size)
2464 {
2465 *size = cmndp->size;
2466 ret_val = 1;
2467 }
2468 memcpy(buffer, cmndp->buffer, *size);
2469 *tag = cmndp->tag;
2470 free(cmndp);
2471 ENABLE_AST
2472 return(ret_val);
2473 }
2474 ENABLE_AST
2475 return(0);
2476}
2477
2478int dis_get_conn_id()
2479{
2480 return(Curr_conn_id);
2481}
2482
2483int dis_get_client(char *name)
2484{
2485 int ret = 0;
2486 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2487
2488 DISABLE_AST
2489
2490 if(Curr_conn_id)
2491 {
2492 dna_get_node_task(Curr_conn_id, node, task);
2493 strcpy(name,task);
2494 strcat(name,"@");
2495 strcat(name,node);
2496 ret = Curr_conn_id;
2497 }
2498 ENABLE_AST
2499 return(ret);
2500}
2501
2502#ifdef VMS
2503dis_convert_str(c_str, for_str)
2504char *c_str;
2505struct dsc$descriptor_s *for_str;
2506{
2507 int i;
2508
2509 strcpy(for_str->dsc$a_pointer, c_str);
2510 for(i = strlen(c_str); i< for_str->dsc$w_length; i++)
2511 for_str->dsc$a_pointer[i] = ' ';
2512}
2513#endif
2514
2515void client_info(long *tag, int **bufp, int *size, int *first_time)
2516{
2517 register CLIENT *clip;
2518 int curr_conns[MAX_CONNS];
2519 int i, index, max_size;
2520 static int curr_allocated_size = 0;
2521 static char *dns_info_buffer;
2522 register char *dns_client_info;
2523 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2524 DIS_DNS_CONN *dnsp = (DIS_DNS_CONN *)*tag;
2525
2526 max_size = sizeof(DNS_CLIENT_INFO);
2527 if(!curr_allocated_size)
2528 {
2529 dns_info_buffer = malloc(max_size);
2530 curr_allocated_size = max_size;
2531 }
2532 dns_client_info = dns_info_buffer;
2533 dns_client_info[0] = '\0';
2534 index = 0;
2535 if(*first_time)
2536 {
2537 clip = Client_head;
2538 while( (clip = (CLIENT *)dll_get_next( (DLL *) Client_head,
2539 (DLL*) clip)) )
2540 {
2541 if(clip->dnsp != dnsp)
2542 continue;
2543 curr_conns[index++] = clip->conn_id;
2544 }
2545 max_size = (index+1)*sizeof(DNS_CLIENT_INFO);
2546 if (max_size > curr_allocated_size)
2547 {
2548 free(dns_info_buffer);
2549 dns_info_buffer = malloc(max_size);
2550 curr_allocated_size = max_size;
2551 }
2552 dns_client_info = dns_info_buffer;
2553 dns_client_info[0] = '\0';
2554 }
2555 else
2556 {
2557 if(Last_client > 0)
2558 {
2559 strcat(dns_client_info,"+");
2560 curr_conns[index++] = Last_client;
2561 }
2562 else
2563 {
2564 strcat(dns_client_info,"-");
2565 curr_conns[index++] = -Last_client;
2566 }
2567 }
2568
2569 for(i=0; i<index;i++)
2570 {
2571 dna_get_node_task(curr_conns[i], node, task);
2572 strcat(dns_client_info,task);
2573 strcat(dns_client_info,"@");
2574 strcat(dns_client_info,node);
2575 strcat(dns_client_info,"|");
2576 }
2577 if(index)
2578 dns_client_info[strlen(dns_client_info)-1] = '\0';
2579 *bufp = (int *)dns_info_buffer;
2580 *size = strlen(dns_info_buffer)+1;
2581}
2582
2583void append_service(char *service_info_buffer, SERVICE *servp)
2584{
2585 char name[MAX_NAME], *ptr;
2586
2587 if(strstr(servp->name,"/RpcIn"))
2588 {
2589 strcpy(name,servp->name);
2590 ptr = (char *)strstr(name,"/RpcIn");
2591 *ptr = 0;
2592 strcat(service_info_buffer, name);
2593 strcat(service_info_buffer, "|");
2594 if(servp->def[0])
2595 {
2596 strcat(service_info_buffer, servp->def);
2597 }
2598 strcat(name,"/RpcOut");
2599 if( (servp = find_service(name)) )
2600 {
2601 strcat(service_info_buffer, ",");
2602 if(servp->def[0])
2603 {
2604 strcat(service_info_buffer, servp->def);
2605 }
2606 }
2607 strcat(service_info_buffer, "|RPC");
2608 strcat(service_info_buffer, "\n");
2609 }
2610 else if(strstr(servp->name,"/RpcOut"))
2611 {
2612/*
2613 if(servp->def[0])
2614 {
2615 strcat(service_info_buffer, servp->def);
2616 }
2617 strcat(service_info_buffer, "|RPC");
2618 strcat(service_info_buffer, "\n");
2619
2620*/
2621 }
2622 else
2623 {
2624 strcat(service_info_buffer, servp->name);
2625 strcat(service_info_buffer, "|");
2626 if(servp->def[0])
2627 {
2628 strcat(service_info_buffer, servp->def);
2629 }
2630 strcat(service_info_buffer, "|");
2631 if(servp->type == COMMAND)
2632 {
2633 strcat(service_info_buffer, "CMD");
2634 }
2635 strcat(service_info_buffer, "\n");
2636 }
2637}
2638
2639void service_info(long *tag, int **bufp, int *size, int *first_time)
2640{
2641 register SERVICE *servp;
2642 int max_size, done = 0;
2643 static int curr_allocated_size = 0;
2644 static char *service_info_buffer;
2645 char *buff_ptr;
2646 DIS_DNS_CONN *dnsp = (DIS_DNS_CONN *)*tag;
2647 int hash_index;
2648
2649 DISABLE_AST
2650 max_size = (dnsp->dis_n_services+10) * (MAX_NAME*2 + 4);
2651 if(!curr_allocated_size)
2652 {
2653 service_info_buffer = (char *)malloc(max_size);
2654 curr_allocated_size = max_size;
2655 }
2656 else if (max_size > curr_allocated_size)
2657 {
2658 free(service_info_buffer);
2659 service_info_buffer = (char *)malloc(max_size);
2660 curr_allocated_size = max_size;
2661 }
2662 service_info_buffer[0] = '\0';
2663 buff_ptr = service_info_buffer;
2664 servp = 0;
2665 hash_index = -1;
2666 if(*first_time)
2667 {
2668 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
2669 {
2670 if(servp->dnsp != dnsp)
2671 continue;
2672 if(servp->registered)
2673 {
2674 servp->registered = 2;
2675 append_service(buff_ptr, servp);
2676 buff_ptr += strlen(buff_ptr);
2677 }
2678 }
2679 }
2680 else
2681 {
2682 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
2683 {
2684 if(servp->dnsp != dnsp)
2685 continue;
2686 if(servp->registered == 1)
2687 {
2688 if(!done)
2689 {
2690 strcat(buff_ptr, "+");
2691 buff_ptr += strlen(buff_ptr);
2692 done = 1;
2693 }
2694 append_service(buff_ptr, servp);
2695 buff_ptr += strlen(buff_ptr);
2696 servp->registered = 2;
2697 }
2698 else if(servp->registered == 0)
2699 {
2700 strcat(buff_ptr, "-");
2701 buff_ptr += strlen(buff_ptr);
2702 append_service(buff_ptr, servp);
2703 buff_ptr += strlen(buff_ptr);
2704 }
2705 }
2706 }
2707 *bufp = (int *)service_info_buffer;
2708 *size = buff_ptr - service_info_buffer+1;
2709 ENABLE_AST
2710}
2711
2712void add_exit_handler(int *tag, int *bufp, int *size)
2713{
2714 EXIT_H *newp;
2715
2716 if(size){}
2717 if(tag){}
2718 if(*bufp)
2719 {
2720 if(!Exit_h_head)
2721 {
2722 Exit_h_head = (EXIT_H *)malloc(sizeof(EXIT_H));
2723 sll_init( (SLL *) Exit_h_head );
2724 }
2725 newp = (EXIT_H *)malloc(sizeof(EXIT_H));
2726 newp->conn_id = Curr_conn_id;
2727 newp->exit_id = *bufp;
2728 sll_insert_queue( (SLL *) Exit_h_head, (SLL *) newp );
2729 }
2730 else
2731 {
2732 if(!Exit_h_head)
2733 return;
2734 if((newp = (EXIT_H *)sll_search((SLL *) Exit_h_head,
2735 (char *)&Curr_conn_id, 4)) )
2736 {
2737 sll_remove( (SLL *) Exit_h_head, (SLL *) newp );
2738 }
2739 }
2740}
2741
2742void dis_set_client_exit_handler(int conn_id, int tag)
2743{
2744 EXIT_H *newp;
2745
2746 DISABLE_AST
2747 if(tag)
2748 {
2749 if(!Exit_h_head)
2750 {
2751 Exit_h_head = (EXIT_H *)malloc(sizeof(EXIT_H));
2752 sll_init( (SLL *) Exit_h_head );
2753 }
2754 if( (newp = (EXIT_H *)sll_search((SLL *) Exit_h_head,
2755 (char *)&conn_id, 4)) )
2756 {
2757 newp->conn_id = conn_id;
2758 newp->exit_id = tag;
2759 }
2760 else
2761 {
2762 newp = (EXIT_H *)malloc(sizeof(EXIT_H));
2763 newp->conn_id = conn_id;
2764 newp->exit_id = tag;
2765 sll_insert_queue( (SLL *) Exit_h_head, (SLL *) newp );
2766 }
2767 }
2768 else
2769 {
2770 if(!Exit_h_head)
2771 {
2772 ENABLE_AST
2773 return;
2774 }
2775 if( (newp = (EXIT_H *)sll_search((SLL *) Exit_h_head,
2776 (char *)&conn_id, 4)) )
2777 {
2778 sll_remove( (SLL *) Exit_h_head, (SLL *) newp );
2779 }
2780 }
2781 ENABLE_AST
2782}
2783
2784int do_exit_handler(int conn_id)
2785{
2786 register EXIT_H *exitp;
2787
2788 DISABLE_AST;
2789 if(!Exit_h_head)
2790 {
2791 ENABLE_AST;
2792 return(0);
2793 }
2794 while( (exitp = (EXIT_H *) sll_search_next_remove((SLL *) Exit_h_head,
2795 0, (char *) &conn_id, 4)) )
2796 {
2797 (Client_exit_user_routine)( &exitp->exit_id );
2798 free(exitp);
2799 }
2800 ENABLE_AST
2801 return(1);
2802}
2803
2804static void exit_handler(int *tag, int *bufp, int *size)
2805{
2806
2807 if(size){}
2808 if(tag){}
2809 if(Exit_user_routine)
2810 (Exit_user_routine)( bufp );
2811 else
2812 {
2813/*
2814 printf("%s PID %d Exiting!\n", Task_name, getpid());
2815*/
2816 exit(*bufp);
2817 }
2818}
2819
2820static void error_handler(int conn_id, int severity, int errcode, char *reason)
2821{
2822 int exit_tag, exit_code, exit_size;
2823 int last_conn_id;
2824
2825 if(Error_user_routine)
2826 {
2827 Error_conn_id = conn_id;
2828 last_conn_id = Curr_conn_id;
2829 Curr_conn_id = conn_id;
2830 (Error_user_routine)( severity, errcode, reason);
2831 Error_conn_id = 0;
2832 Curr_conn_id = last_conn_id;
2833 }
2834 else
2835 {
2836 dim_print_msg(reason, severity);
2837 }
2838 if(severity == DIM_FATAL)
2839 {
2840 exit_tag = 0;
2841 exit_code = errcode;
2842 exit_size = sizeof(int);
2843 exit_handler(&exit_tag, &exit_code, &exit_size);
2844 }
2845}
2846/*
2847#define MAX_HASH_ENTRIES 2000
2848*/
2849#define MAX_HASH_ENTRIES 5000
2850
2851static SERVICE *Service_hash_table[MAX_HASH_ENTRIES];
2852static int Service_new_entries[MAX_HASH_ENTRIES];
2853
2854int dis_hash_service_init()
2855{
2856 int i;
2857 static int done = 0;
2858
2859 if(!done)
2860 {
2861 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
2862 {
2863 Service_hash_table[i] = (SERVICE *) malloc(8);
2864 dll_init((DLL *) Service_hash_table[i]);
2865 Service_new_entries[i] = 0;
2866 }
2867 done = 1;
2868 }
2869 return(1);
2870}
2871
2872int dis_hash_service_insert(SERVICE *servp)
2873{
2874 int index;
2875 index = HashFunction(servp->name, MAX_HASH_ENTRIES);
2876 Service_new_entries[index]++;
2877 dll_insert_queue((DLL *) Service_hash_table[index],
2878 (DLL *) servp);
2879 return(1);
2880}
2881
2882int dis_hash_service_registered(int index, SERVICE *servp)
2883{
2884 servp->registered = 1;
2885 Service_new_entries[index]--;
2886 if(Service_new_entries[index] < 0)
2887 Service_new_entries[index] = 0;
2888 return 1;
2889}
2890
2891int dis_hash_service_remove(SERVICE *servp)
2892{
2893 dll_remove( (DLL *) servp );
2894 return(1);
2895}
2896
2897
2898SERVICE *dis_hash_service_exists(char *name)
2899{
2900 int index;
2901 SERVICE *servp;
2902
2903 index = HashFunction(name, MAX_HASH_ENTRIES);
2904 if( (servp = (SERVICE *) dll_search(
2905 (DLL *) Service_hash_table[index],
2906 name, strlen(name)+1)) )
2907 {
2908 return(servp);
2909 }
2910 return((SERVICE *)0);
2911}
2912
2913SERVICE *dis_hash_service_get_next(int *curr_index, SERVICE *prevp, int new_entries)
2914{
2915 int index;
2916 SERVICE *servp = 0;
2917/*
2918 if(!prevp)
2919 {
2920 index = -1;
2921 }
2922*/
2923 index = *curr_index;
2924 if(index == -1)
2925 {
2926 index++;
2927 prevp = Service_hash_table[index];
2928 }
2929 if(!prevp)
2930 {
2931 prevp = Service_hash_table[index];
2932 }
2933 do
2934 {
2935 if((!new_entries) || (Service_new_entries[index] > 0))
2936 {
2937 servp = (SERVICE *) dll_get_next(
2938 (DLL *) Service_hash_table[index],
2939 (DLL *) prevp);
2940 if(servp)
2941 break;
2942 }
2943 index++;
2944 if(index == MAX_HASH_ENTRIES)
2945 {
2946 *curr_index = -1;
2947 return((SERVICE *) 0);
2948 }
2949 prevp = Service_hash_table[index];
2950 } while(!servp);
2951 *curr_index = index;
2952 return(servp);
2953}
2954
2955DIS_DNS_CONN *dis_find_dns(long dnsid)
2956{
2957 DIS_DNS_CONN *dnsp;
2958
2959 dnsp = (DIS_DNS_CONN *)
2960 dll_search( (DLL *) DNS_head, &dnsid, sizeof(dnsid));
2961/*
2962 if(!dnsp)
2963 {
2964 dnsp = create_dns(dnsid);
2965 }
2966*/
2967 return dnsp;
2968}
2969
2970int dis_no_dns()
2971{
2972 DIS_DNS_CONN *dnsp;
2973
2974 dnsp = (DIS_DNS_CONN *) DNS_head;
2975 while ( (dnsp = (DIS_DNS_CONN *) dll_get_next( (DLL *) DNS_head, (DLL *) dnsp)))
2976 {
2977/*
2978 if(dnsp != Default_DNS)
2979 return 0;
2980*/
2981 if(dnsp->serving)
2982 return 0;
2983 }
2984 return 1;
2985}
2986
2987DIS_DNS_CONN *find_dns_by_conn_id(int conn_id)
2988{
2989 DIS_DNS_CONN *dnsp;
2990 extern long dns_get_dnsid();
2991 long dnsid;
2992
2993 dnsid = dns_get_dnsid(conn_id, SRC_DIS);
2994 dnsp = dis_find_dns(dnsid);
2995 if(!dnsp)
2996 dnsp = Default_DNS;
2997 return (DIS_DNS_CONN *)dnsp;
2998}
2999
3000void dis_print_hash_table()
3001{
3002 SERVICE *servp;
3003 int i;
3004 int n_entries, max_entry_index = 0;
3005 int max_entries = 0;
3006
3007 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
3008 {
3009 n_entries = 0;
3010 servp = Service_hash_table[i];
3011 while( (servp = (SERVICE *) dll_get_next(
3012 (DLL *) Service_hash_table[i],
3013 (DLL *) servp)) )
3014 {
3015 n_entries++;
3016 if(n_entries == 1)
3017 printf(" Name = %s\n",servp->name);
3018 }
3019 if(n_entries != 0)
3020 printf("HASH[%d] - %d entries\n", i, n_entries);
3021 if(n_entries > max_entries)
3022 {
3023 max_entries = n_entries;
3024 max_entry_index = i;
3025 }
3026 }
3027 printf("Maximum : HASH[%d] - %d entries\n", max_entry_index, max_entries);
3028 fflush(stdout);
3029}
3030
3031void dis_hash_print()
3032{
3033 SERVICE *servp;
3034 int hash_index;
3035
3036 servp = 0;
3037 hash_index = -1;
3038 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
3039 {
3040 printf("Name = %s\n",servp->name);
3041 }
3042}
3043
3044#ifdef VMS
3045/* CFORTRAN WRAPPERS */
3046FCALLSCFUN1(INT, dis_start_serving, DIS_START_SERVING, dis_start_serving,
3047 STRING)
3048FCALLSCFUN3(INT, dis_get_next_cmnd, DIS_GET_NEXT_CMND, dis_get_next_cmnd,
3049 PINT, PVOID, PINT)
3050FCALLSCFUN1(INT, dis_get_client, DIS_GET_CLIENT, dis_get_client,
3051 PSTRING)
3052FCALLSCFUN6(INT, dis_add_service, DIS_ADD_SERVICE, dis_add_service,
3053 STRING, PVOID, PVOID, INT, PVOID, INT)
3054FCALLSCSUB4( dis_add_cmnd, DIS_ADD_CMND, dis_add_cmnd,
3055 STRING, PVOID, PVOID, INT)
3056FCALLSCSUB1( dis_add_client_exit_handler, DIS_ADD_CLIENT_EXIT_HANDLER,
3057 dis_add_client_exit_handler,
3058 PVOID)
3059FCALLSCSUB2( dis_set_client_exit_handler, DIS_SET_CLIENT_EXIT_HANDLER,
3060 dis_set_client_exit_handler,
3061 INT, INT)
3062FCALLSCSUB1( dis_add_exit_handler, DIS_ADD_EXIT_HANDLER,
3063 dis_add_exit_handler,
3064 PVOID)
3065FCALLSCSUB1( dis_report_service, DIS_REPORT_SERVICE, dis_report_service,
3066 STRING)
3067FCALLSCSUB2( dis_convert_str, DIS_CONVERT_STR, dis_convert_str,
3068 PVOID, PVOID)
3069FCALLSCFUN1(INT, dis_update_service, DIS_UPDATE_SERVICE, dis_update_service,
3070 INT)
3071FCALLSCFUN1(INT, dis_remove_service, DIS_REMOVE_SERVICE, dis_remove_service,
3072 INT)
3073FCALLSCSUB3( dis_send_service, DIS_SEND_SERVICE, dis_send_service,
3074 INT, PVOID, INT)
3075FCALLSCSUB2( dis_set_quality, DIS_SET_QUALITY, dis_set_quality,
3076 INT, INT)
3077FCALLSCSUB3(INT, dis_set_timestamp, DIS_SET_TIMESTAMP, dis_set_timestamp,
3078 INT, INT, INT)
3079FCALLSCFUN2(INT, dis_selective_update_service, DIS_SELECTIVE_UPDATE_SERVICE,
3080 dis_selective_update_service,
3081 INT, PINT)
3082FCALLSCSUB3(INT, dis_get_timestamp, DIS_GET_TIMESTAMP, dis_get_timestamp,
3083 INT, PINT, PINT)
3084#endif
Note: See TracBrowser for help on using the repository browser.