source: trunk/FACT++/dim/src/dis_old.c@ 17853

Last change on this file since 17853 was 11071, checked in by tbretz, 14 years ago
Replaced v19r21 by a version extracted with 'unzip -a' to get proper unix text format.
File size: 63.2 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
793 dis_dns_p->port = htovl(Port_number);
794 serv_regp = dis_dns_p->services;
795 n_services = 0;
796 tot_n_services = 0;
797 if( flag == NONE ) {
798 dis_dns_p->n_services = htovl(n_services);
799 dis_dns_p->size = htovl( DIS_DNS_HEADER +
800 (n_services*sizeof(SERVICE_REG)));
801 if(dnsp->dns_dis_conn_id > 0)
802 {
803 if(!dna_write(dnsp->dns_dis_conn_id, &(dnsp->dis_dns_packet),
804 DIS_DNS_HEADER + n_services*sizeof(SERVICE_REG)))
805 {
806 release_conn(dnsp->dns_dis_conn_id, 0, 1);
807 }
808 }
809 return;
810 }
811 if(flag == ALL)
812 {
813 servp = 0;
814 hash_index = -1;
815 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)))
816 {
817 if(servp->dnsp == dnsp)
818 servp->registered = 0;
819 }
820 }
821 servp = 0;
822 hash_index = -1;
823 new_entries = 0;
824 if(flag == MORE)
825 new_entries = 1;
826 while( (servp = dis_hash_service_get_next(&hash_index, servp, new_entries)))
827 {
828 if( flag == MORE )
829 {
830 if( servp->registered )
831 {
832 continue;
833 }
834 }
835
836 if(servp->dnsp != dnsp)
837 continue;
838
839 strcpy( serv_regp->service_name, servp->name );
840 strcpy( serv_regp->service_def, servp->def );
841 if(servp->type == COMMAND)
842 serv_regp->service_id = htovl( servp->id | 0x10000000);
843 else
844 serv_regp->service_id = htovl( servp->id );
845
846 serv_regp++;
847 n_services++;
848 dis_hash_service_registered(hash_index, servp);
849 if( n_services == MAX_SERVICE_UNIT )
850 {
851 dis_dns_p->n_services = htovl(n_services);
852 dis_dns_p->size = htovl(DIS_DNS_HEADER +
853 n_services * sizeof(SERVICE_REG));
854 if(dnsp->dns_dis_conn_id > 0)
855 {
856 if( !dna_write(dnsp->dns_dis_conn_id,
857 &(dnsp->dis_dns_packet),
858 DIS_DNS_HEADER + n_services *
859 sizeof(SERVICE_REG)) )
860 {
861 release_conn(dnsp->dns_dis_conn_id, 0, 1);
862 }
863 }
864 serv_regp = dis_dns_p->services;
865 tot_n_services += MAX_SERVICE_UNIT;
866 n_services = 0;
867 continue;
868 }
869 }
870 if( n_services )
871 {
872 dis_dns_p->n_services = htovl(n_services);
873 dis_dns_p->size = htovl(DIS_DNS_HEADER +
874 n_services * sizeof(SERVICE_REG));
875 if(dnsp->dns_dis_conn_id > 0)
876 {
877 if( !dna_write(dnsp->dns_dis_conn_id, &(dnsp->dis_dns_packet),
878 DIS_DNS_HEADER + n_services * sizeof(SERVICE_REG)))
879 {
880 release_conn(dnsp->dns_dis_conn_id, 0, 1);
881 }
882
883 }
884 tot_n_services += n_services;
885 }
886 if(!dns_flag)
887 {
888 if(tot_n_services >= MAX_REGISTRATION_UNIT)
889 {
890 send_dns_update_packet(dnsp);
891 }
892 }
893}
894
895void unregister_service(DIS_DNS_CONN *dnsp, SERVICE *servp)
896{
897 register DIS_DNS_PACKET *dis_dns_p = &(dnsp->dis_dns_packet);
898 register int n_services;
899 register SERVICE_REG *serv_regp;
900 extern int get_node_addr();
901
902 if(dnsp->dns_dis_conn_id > 0)
903 {
904 if(!dis_dns_p->src_type)
905 {
906 get_node_name( dis_dns_p->node_name );
907/*
908 strcpy( dis_dns_p->task_name, Task_name );
909*/
910 strncpy( dis_dns_p->task_name, dnsp->task_name,
911 MAX_TASK_NAME-4 );
912 dis_dns_p->task_name[MAX_TASK_NAME-4-1] = '\0';
913 get_node_addr( dis_dns_p->node_addr );
914 dis_dns_p->port = htovl(Port_number);
915 dis_dns_p->protocol = htovl(Protocol);
916 dis_dns_p->src_type = htovl(SRC_DIS);
917 dis_dns_p->format = htovl(MY_FORMAT);
918 }
919 serv_regp = dis_dns_p->services;
920 strcpy( serv_regp->service_name, servp->name );
921 strcpy( serv_regp->service_def, servp->def );
922 serv_regp->service_id = htovl( servp->id | 0x80000000);
923 serv_regp++;
924 n_services = 1;
925 servp->registered = 0;
926 dis_dns_p->n_services = htovl(n_services);
927 dis_dns_p->size = htovl(DIS_DNS_HEADER +
928 n_services * sizeof(SERVICE_REG));
929
930 if( !dna_write(dnsp->dns_dis_conn_id, &(dnsp->dis_dns_packet),
931 DIS_DNS_HEADER + n_services * sizeof(SERVICE_REG)) )
932 {
933 release_conn(dnsp->dns_dis_conn_id, 0, 1);
934 }
935 if(dnsp->dis_service_id)
936 dis_update_service(dnsp->dis_service_id);
937 }
938}
939
940void do_update_service_list(DIS_DNS_CONN *dnsp)
941{
942 dnsp->updating_service_list = 0;
943 dis_update_service(dnsp->dis_service_id);
944}
945
946/* start serving client requests
947 *
948 * Using the DNA package start accepting requests from clients.
949 * When a request arrives the routine "dis_insert_request" will be executed.
950 */
951
952int dis_start_serving(char *task)
953{
954 return dis_start_serving_dns(0, task);
955}
956
957static DIS_DNS_CONN *create_dns(long dnsid)
958{
959 DIS_DNS_CONN *dnsp;
960
961 dnsp = malloc(sizeof(DIS_DNS_CONN));
962 dnsp->dns_timr_ent = (TIMR_ENT *)0;
963 dnsp->dis_n_services = 0;
964 dnsp->dns_dis_conn_id = 0;
965 dnsp->dis_first_time = 1;
966 dnsp->serving = 0;
967 dnsp->dis_dns_packet.size = 0;
968 dnsp->dis_dns_packet.src_type = 0;
969 dnsp->dis_dns_packet.node_name[0] = 0;
970 dnsp->updating_service_list = 0;
971 dnsp->dnsid = dnsid;
972 dll_insert_queue( (DLL *) DNS_head, (DLL *) dnsp );
973 return dnsp;
974}
975
976void dis_dns_init()
977{
978 static int done = 0;
979 DIS_DNS_CONN *dnsp;
980 void dim_init_threads(void);
981
982 if(!done)
983 {
984 if(!Threads_off)
985 {
986 dim_init_threads();
987 }
988 {
989 DISABLE_AST
990 if(!DNS_head)
991 {
992 DNS_head = (DIS_DNS_CONN *)malloc(sizeof(DIS_DNS_CONN));
993 dll_init( (DLL *) DNS_head );
994 }
995 dnsp = create_dns(0);
996 Default_DNS = dnsp;
997 done = 1;
998 ENABLE_AST
999 }
1000 }
1001}
1002
1003int dis_start_serving_dns(long dnsid, char *task/*, int *idlist*/)
1004{
1005 char str0[MAX_NAME], str1[MAX_NAME],str2[MAX_NAME],
1006 str3[MAX_NAME],str4[MAX_NAME];
1007 char task_name_aux[MAX_TASK_NAME];
1008 extern int open_dns();
1009 extern DIS_DNS_CONN *dis_find_dns(long);
1010 DIS_DNS_CONN *dnsp;
1011 int more_ids[10] = {0};
1012
1013 dis_init();
1014 {
1015 DISABLE_AST
1016 /*
1017#ifdef VxWorks
1018 taskDeleteHookAdd(remove_all_services);
1019 printf("Adding delete hook\n");
1020#endif
1021*/
1022
1023 if(!Client_head)
1024 {
1025 Client_head = (CLIENT *)malloc(sizeof(CLIENT));
1026 dll_init( (DLL *) Client_head );
1027 }
1028 if(dnsid == 0)
1029 {
1030 dnsp = Default_DNS;
1031 }
1032 else if(!(dnsp = dis_find_dns(dnsid)))
1033 {
1034 dnsp = create_dns(dnsid);
1035 }
1036 dnsp->serving = 1;
1037 Serving = 1;
1038 if(Dis_first_time)
1039 {
1040 strncpy( task_name_aux, task, MAX_TASK_NAME );
1041 task_name_aux[MAX_TASK_NAME-1] = '\0';
1042 Port_number = SEEK_PORT;
1043 if( !(Dis_conn_id = dna_open_server( task_name_aux, dis_insert_request,
1044 &Protocol, &Port_number, error_handler) ))
1045 {
1046 ENABLE_AST
1047 return(0);
1048 }
1049 Dis_first_time = 0;
1050 }
1051 if(dnsp->dis_first_time)
1052 {
1053 dnsp->dis_first_time = 0;
1054
1055 sprintf(str0, "%s/VERSION_NUMBER", task);
1056 sprintf(str1, "%s/CLIENT_LIST", task);
1057 sprintf(str2, "%s/SERVICE_LIST", task);
1058 sprintf(str3, "%s/SET_EXIT_HANDLER", task);
1059 sprintf(str4, "%s/EXIT", task);
1060
1061 more_ids[0] = do_dis_add_service_dns( str0, "L", &Version_number,
1062 sizeof(Version_number), 0, 0, dnsid );
1063
1064 more_ids[1] = do_dis_add_service_dns( str1, "C", 0, 0, client_info, (long)dnsp, dnsid );
1065 dnsp->dis_client_id = more_ids[1];
1066 more_ids[2] = do_dis_add_service_dns( str2, "C", 0, 0, service_info, (long)dnsp, dnsid );
1067 dnsp->dis_service_id = more_ids[2];
1068 more_ids[3] = do_dis_add_cmnd_dns( str3, "L:1", add_exit_handler, 0, dnsid );
1069 more_ids[4] = do_dis_add_cmnd_dns( str4, "L:1", exit_handler, 0, dnsid );
1070 more_ids[5] = 0;
1071 strcpy( dnsp->task_name, task );
1072 }
1073/*
1074 if(idlist)
1075 {
1076 for(i = 0; idlist[i]; i++)
1077 {
1078 servp = (SERVICE *)id_get_ptr(idlist[i], SRC_DIS);
1079 if(servp)
1080 {
1081 servp->dnsp = dnsp;
1082 n_services++;
1083 }
1084 }
1085 }
1086 if(dnsp != Default_DNS)
1087 {
1088 for(i = 0; more_ids[i]; i++)
1089 {
1090 servp = (SERVICE *)id_get_ptr(more_ids[i], SRC_DIS);
1091 if(servp)
1092 {
1093 servp->dnsp = dnsp;
1094 n_services++;
1095 }
1096 }
1097 dnsp->dis_n_services += n_services;
1098 Dis_n_services -= n_services;
1099 }
1100*/
1101 if(!Dis_timer_q)
1102 Dis_timer_q = dtq_create();
1103 if( !dnsp->dns_dis_conn_id )
1104 {
1105 if(!strcmp(task,"DIS_DNS"))
1106 {
1107 register_services(dnsp, ALL, 1);
1108 ENABLE_AST
1109 return(id_get(&(dnsp->dis_dns_packet), SRC_DIS));
1110 }
1111 else
1112 {
1113
1114 dnsp->dns_dis_conn_id = open_dns(dnsid, recv_dns_dis_rout, error_handler,
1115 DIS_DNS_TMOUT_MIN, DIS_DNS_TMOUT_MAX, SRC_DIS );
1116 if(dnsp->dns_dis_conn_id == -2)
1117 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
1118 }
1119 }
1120 else
1121 {
1122 register_services(dnsp, MORE, 0);
1123 if(dnsp->dis_service_id)
1124 {
1125/*
1126 dis_update_service(Dis_service_id);
1127*/
1128 if(!dnsp->updating_service_list)
1129 {
1130 dtq_start_timer(1, do_update_service_list, dnsp);
1131 dnsp->updating_service_list = 1;
1132 }
1133 }
1134 }
1135 ENABLE_AST
1136 }
1137 return(1);
1138}
1139
1140
1141/* asynchrounous reception of requests */
1142/*
1143 Called by DNA package.
1144 A request has arrived, queue it to process later - dis_ins_request
1145*/
1146static void dis_insert_request(int conn_id, DIC_PACKET *dic_packet, int size, int status)
1147{
1148 register SERVICE *servp;
1149 register REQUEST *newp, *reqp;
1150 CLIENT *clip;
1151 REQUEST_PTR *reqpp;
1152 int type, new_client = 0, found = 0;
1153 int find_release_request();
1154 DIS_DNS_CONN *dnsp;
1155
1156 if(size){}
1157 /* status = 1 => new connection, status = -1 => conn. lost */
1158 if(!Client_head)
1159 {
1160 Client_head = (CLIENT *)malloc(sizeof(CLIENT));
1161 dll_init( (DLL *) Client_head );
1162 }
1163 if(status != 0)
1164 {
1165 if(status == -1) /* release all requests from conn_id */
1166 {
1167 release_conn(conn_id, 0, 0);
1168 }
1169 }
1170 else
1171 {
1172 if(!(servp = find_service(dic_packet->service_name)))
1173 {
1174 release_conn(conn_id, 0, 0);
1175 return;
1176 }
1177 dic_packet->type = vtohl(dic_packet->type);
1178 type = dic_packet->type & 0xFFF;
1179 /*
1180 if(type == COMMAND)
1181 {
1182 Curr_conn_id = conn_id;
1183 execute_command(servp, dic_packet);
1184 Curr_conn_id = 0;
1185 return;
1186 }
1187 */
1188 if(type == DIM_DELETE)
1189 {
1190 find_release_request(conn_id, vtohl(dic_packet->service_id));
1191 return;
1192 }
1193 newp = (REQUEST *)/*my_*/malloc(sizeof(REQUEST));
1194 newp->service_ptr = servp;
1195 newp->service_id = vtohl(dic_packet->service_id);
1196 newp->type = dic_packet->type;
1197 newp->timeout = vtohl(dic_packet->timeout);
1198 newp->format = vtohl(dic_packet->format);
1199 newp->conn_id = conn_id;
1200 newp->first_time = 1;
1201 newp->delay_delete = 0;
1202 newp->to_delete = 0;
1203 newp->timr_ent = 0;
1204 newp->req_id = id_get((void *)newp, SRC_DIS);
1205 newp->reqpp = 0;
1206 if(type == ONCE_ONLY)
1207 {
1208 execute_service(newp->req_id);
1209 id_free(newp->req_id, SRC_DIS);
1210 free(newp);
1211 return;
1212 }
1213 if(type == COMMAND)
1214 {
1215 Curr_conn_id = conn_id;
1216 execute_command(servp, dic_packet);
1217 Curr_conn_id = 0;
1218 reqp = servp->request_head;
1219 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1220 (DLL *) reqp)) )
1221 {
1222 if(reqp->conn_id == conn_id)
1223 {
1224 id_free(newp->req_id, SRC_DIS);
1225 free(newp);
1226 found = 1;
1227 break;
1228 }
1229 }
1230 if(!found)
1231 dll_insert_queue( (DLL *) servp->request_head, (DLL *) newp );
1232 return;
1233 }
1234 dll_insert_queue( (DLL *) servp->request_head, (DLL *) newp );
1235 if(!(clip = find_client(conn_id)))
1236 {
1237 clip = (CLIENT *)malloc(sizeof(CLIENT));
1238 clip->conn_id = conn_id;
1239 clip->dnsp = servp->dnsp;
1240 clip->requestp_head = (REQUEST_PTR *)malloc(sizeof(REQUEST_PTR));
1241 dll_init( (DLL *) clip->requestp_head );
1242 dll_insert_queue( (DLL *) Client_head, (DLL *) clip );
1243 new_client = 1;
1244 }
1245 reqpp = (REQUEST_PTR *)malloc(sizeof(REQUEST_PTR));
1246 reqpp->reqp = newp;
1247 dll_insert_queue( (DLL *) clip->requestp_head, (DLL *) reqpp );
1248 newp->reqpp = reqpp;
1249 if((type != MONIT_ONLY) && (type != UPDATE))
1250 {
1251 execute_service(newp->req_id);
1252 }
1253 if((type != MONIT_ONLY) && (type != MONIT_FIRST))
1254 {
1255 if(newp->timeout != 0)
1256 {
1257 newp->timr_ent = dtq_add_entry( Dis_timer_q,
1258 newp->timeout,
1259 execute_service,
1260 newp->req_id );
1261 }
1262 }
1263 if(new_client)
1264 {
1265 Last_client = conn_id;
1266 dnsp = clip->dnsp;
1267 if(dnsp->dis_client_id)
1268 dis_update_service(dnsp->dis_client_id);
1269 }
1270 }
1271}
1272
1273/* A timeout for a timed or monitored service occured, serve it. */
1274
1275int execute_service( int req_id )
1276{
1277 int *buffp, size;
1278 register REQUEST *reqp;
1279 register SERVICE *servp;
1280 char str[80], def[MAX_NAME];
1281 register char *ptr;
1282 int last_conn_id;
1283 int *pkt_buffer, header_size, aux;
1284#ifdef WIN32
1285 struct timeb timebuf;
1286#else
1287 struct timeval tv;
1288 struct timezone *tz;
1289#endif
1290 FORMAT_STR format_data_cp[MAX_NAME/4];
1291
1292 reqp = (REQUEST *)id_get_ptr(req_id, SRC_DIS);
1293 if(!reqp)
1294 return(0);
1295 if(reqp->to_delete)
1296 return(0);
1297 reqp->delay_delete++;
1298 servp = reqp->service_ptr;
1299 last_conn_id = Curr_conn_id;
1300 Curr_conn_id = reqp->conn_id;
1301 ptr = servp->def;
1302 if(servp->type == COMMAND)
1303 {
1304 sprintf(str,"This is a COMMAND Service");
1305 buffp = (int *)str;
1306 size = 26;
1307 sprintf(def,"c:26");
1308 ptr = def;
1309 }
1310 else if( servp->user_routine != 0 )
1311 {
1312 (servp->user_routine)( &servp->tag, &buffp, &size,
1313 &reqp->first_time );
1314 reqp->first_time = 0;
1315
1316 }
1317 else
1318 {
1319 buffp = servp->address;
1320 size = servp->size;
1321 }
1322 Curr_conn_id = last_conn_id;
1323/* send even if no data but not if negative */
1324 if( size < 0)
1325 {
1326 reqp->delay_delete--;
1327 return(0);
1328 }
1329 if( DIS_STAMPED_HEADER + size > Dis_packet_size )
1330 {
1331 if( Dis_packet_size )
1332 free( Dis_packet );
1333 Dis_packet = (DIS_STAMPED_PACKET *)malloc(DIS_STAMPED_HEADER + size);
1334 if(!Dis_packet)
1335 {
1336 reqp->delay_delete--;
1337 return(0);
1338 }
1339 Dis_packet_size = DIS_STAMPED_HEADER + size;
1340 }
1341 Dis_packet->service_id = htovl(reqp->service_id);
1342 if((reqp->type & 0xFF000) == STAMPED)
1343 {
1344 pkt_buffer = ((DIS_STAMPED_PACKET *)Dis_packet)->buffer;
1345 header_size = DIS_STAMPED_HEADER;
1346 if(!servp->user_secs)
1347 {
1348#ifdef WIN32
1349 ftime(&timebuf);
1350 aux = timebuf.millitm;
1351 Dis_packet->time_stamp[0] = htovl(aux);
1352 Dis_packet->time_stamp[1] = htovl((int)timebuf.time);
1353#else
1354 tz = 0;
1355 gettimeofday(&tv, tz);
1356 aux = tv.tv_usec / 1000;
1357 Dis_packet->time_stamp[0] = htovl(aux);
1358 Dis_packet->time_stamp[1] = htovl(tv.tv_sec);
1359#endif
1360 }
1361 else
1362 {
1363 aux = /*0xc0de0000 |*/ servp->user_millisecs;
1364 Dis_packet->time_stamp[0] = htovl(aux);
1365 Dis_packet->time_stamp[1] = htovl(servp->user_secs);
1366 }
1367 Dis_packet->reserved[0] = htovl(0xc0dec0de);
1368 Dis_packet->quality = htovl(servp->quality);
1369 }
1370 else
1371 {
1372 pkt_buffer = ((DIS_PACKET *)Dis_packet)->buffer;
1373 header_size = DIS_HEADER;
1374 }
1375 memcpy(format_data_cp, servp->format_data, sizeof(format_data_cp));
1376 size = copy_swap_buffer_out(reqp->format, format_data_cp,
1377 pkt_buffer,
1378 buffp, size);
1379 Dis_packet->size = htovl(header_size + size);
1380 if( !dna_write_nowait(reqp->conn_id, Dis_packet, header_size + size) )
1381 {
1382 reqp->to_delete = 1;
1383 }
1384/*
1385 else
1386 {
1387 if((reqp->type & 0xFFF) == MONITORED)
1388 {
1389 if(reqp->timr_ent)
1390 dtq_clear_entry(reqp->timr_ent);
1391 }
1392 }
1393*/
1394 reqp->delay_delete--;
1395 return(1);
1396}
1397
1398void remove_service( int req_id )
1399{
1400 register REQUEST *reqp;
1401 register SERVICE *servp;
1402 static DIS_PACKET *dis_packet;
1403 static int packet_size = 0;
1404 int service_id;
1405
1406 reqp = (REQUEST *)id_get_ptr(req_id, SRC_DIS);
1407 servp = reqp->service_ptr;
1408 if( !packet_size ) {
1409 dis_packet = (DIS_PACKET *)malloc(DIS_HEADER);
1410 packet_size = DIS_HEADER;
1411 }
1412 service_id = (reqp->service_id | 0x80000000);
1413 dis_packet->service_id = htovl(service_id);
1414 dis_packet->size = htovl(DIS_HEADER);
1415 if( !dna_write(reqp->conn_id, dis_packet, DIS_HEADER) )
1416 {
1417 release_conn(reqp->conn_id, 0, 0);
1418 }
1419}
1420
1421void execute_command(SERVICE *servp, DIC_PACKET *packet)
1422{
1423 int size;
1424 int format;
1425 FORMAT_STR format_data_cp[MAX_NAME/4], *formatp;
1426 static int *buffer;
1427 static int buffer_size = 0;
1428 int add_size;
1429
1430 size = vtohl(packet->size) - DIC_HEADER;
1431 add_size = size + (size/2);
1432 if(!buffer_size)
1433 {
1434 buffer = (int *)malloc(add_size);
1435 buffer_size = add_size;
1436 }
1437 else
1438 {
1439 if( add_size > buffer_size )
1440 {
1441 free(buffer);
1442 buffer = (int *)malloc(add_size);
1443 buffer_size = add_size;
1444 }
1445 }
1446
1447 dis_set_timestamp(servp->id, 0, 0);
1448 if(servp->user_routine != 0)
1449 {
1450 format = vtohl(packet->format);
1451 memcpy(format_data_cp, servp->format_data, sizeof(format_data_cp));
1452 if((format & 0xF) == ((MY_FORMAT) & 0xF))
1453 {
1454 for(formatp = format_data_cp; formatp->par_bytes; formatp++)
1455 {
1456 if(formatp->flags & IT_IS_FLOAT)
1457 formatp->flags |= (format & 0xf0);
1458 formatp->flags &= 0xFFF0; /* NOSWAP */
1459 }
1460 }
1461 else
1462 {
1463 for(formatp = format_data_cp; formatp->par_bytes; formatp++)
1464 {
1465 if(formatp->flags & IT_IS_FLOAT)
1466 formatp->flags |= (format & 0xf0);
1467 }
1468 }
1469 size = copy_swap_buffer_in(format_data_cp,
1470 buffer,
1471 packet->buffer, size);
1472 (servp->user_routine)(&servp->tag, buffer, &size);
1473 }
1474}
1475
1476void dis_report_service(char *serv_name)
1477{
1478 register SERVICE *servp;
1479 register REQUEST *reqp;
1480 int to_delete = 0, more;
1481
1482
1483 DISABLE_AST
1484 servp = find_service(serv_name);
1485 reqp = servp->request_head;
1486 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1487 (DLL *) reqp)) )
1488 {
1489 if((reqp->type & 0xFFF) != TIMED_ONLY)
1490 {
1491 execute_service(reqp->req_id);
1492 if(reqp->to_delete)
1493 to_delete = 1;
1494 }
1495 }
1496 if(to_delete)
1497 {
1498 do
1499 {
1500 more = 0;
1501 reqp = servp->request_head;
1502 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1503 (DLL *) reqp)) )
1504 {
1505 if(reqp->to_delete)
1506 {
1507 more = 1;
1508 release_conn(reqp->conn_id, 1, 0);
1509 break;
1510 }
1511 }
1512 }while(more);
1513 }
1514 ENABLE_AST
1515}
1516
1517int dis_update_service(unsigned service_id)
1518{
1519int do_update_service();
1520
1521 return(do_update_service(service_id,0));
1522}
1523
1524int dis_selective_update_service(unsigned service_id, int *client_ids)
1525{
1526int do_update_service();
1527
1528 return(do_update_service(service_id, client_ids));
1529}
1530
1531int check_client(REQUEST *reqp, int *client_ids)
1532{
1533 if(!client_ids)
1534 return(1);
1535 while(*client_ids)
1536 {
1537 if(reqp->conn_id == *client_ids)
1538 {
1539 return(1);
1540 }
1541 client_ids++;
1542 }
1543 return(0);
1544}
1545
1546int do_update_service(unsigned service_id, int *client_ids)
1547{
1548 register REQUEST *reqp;
1549 register SERVICE *servp;
1550 REQUEST_PTR *reqpp;
1551 CLIENT *clip;
1552 register int found = 0;
1553 int to_delete = 0, more, conn_id;
1554 char str[128];
1555 int release_request();
1556
1557 DISABLE_AST
1558 if(!service_id)
1559 {
1560 sprintf(str, "Update Service - Invalid service id");
1561 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1562 ENABLE_AST
1563 return(found);
1564 }
1565 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1566 if(!servp)
1567 {
1568 ENABLE_AST
1569 return(found);
1570 }
1571 if(servp->id != (int)service_id)
1572 {
1573 ENABLE_AST
1574 return(found);
1575 }
1576 servp->delay_delete = 1;
1577 reqp = servp->request_head;
1578 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1579 (DLL *) reqp)) )
1580 {
1581if(Debug_on)
1582{
1583dim_print_date_time_millis();
1584printf("Updating %s (id = %d, ptr = %08lX) for %s@%s (req_id = %d, req_ptr = %08lX)\n",
1585 servp->name, (int)service_id, (unsigned long)servp,
1586 Net_conns[reqp->conn_id].task, Net_conns[reqp->conn_id].node, reqp->req_id, (unsigned long)reqp);
1587}
1588 if(check_client(reqp, client_ids))
1589 reqp->delay_delete = 1;
1590 }
1591 ENABLE_AST
1592 {
1593 DISABLE_AST
1594 reqp = servp->request_head;
1595 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1596 (DLL *) reqp)) )
1597 {
1598 if(reqp->delay_delete && ((reqp->type & 0xFFF) != COMMAND))
1599 {
1600 if(check_client(reqp, client_ids))
1601 {
1602 if( (reqp->type & 0xFFF) != TIMED_ONLY )
1603 {
1604/*
1605 DISABLE_AST
1606*/
1607 execute_service(reqp->req_id);
1608 found++;
1609 ENABLE_AST
1610 {
1611 DISABLE_AST
1612 }
1613 }
1614 }
1615 }
1616 }
1617 ENABLE_AST
1618 }
1619 {
1620 DISABLE_AST
1621 reqp = servp->request_head;
1622 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1623 (DLL *) reqp)) )
1624 {
1625 if(check_client(reqp, client_ids))
1626 {
1627 reqp->delay_delete = 0;
1628 if(reqp->to_delete)
1629 to_delete = 1;
1630 }
1631 }
1632 ENABLE_AST
1633 }
1634 if(to_delete)
1635 {
1636 DISABLE_AST
1637 do
1638 {
1639 more = 0;
1640 reqp = servp->request_head;
1641 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1642 (DLL *) reqp)) )
1643 {
1644 if(reqp->to_delete & 0x1)
1645 {
1646 more = 1;
1647 reqp->to_delete = 0;
1648 release_conn(reqp->conn_id, 1, 0);
1649 break;
1650 }
1651 else if(reqp->to_delete & 0x2)
1652 {
1653 more = 1;
1654 reqp->to_delete = 0;
1655 reqpp = reqp->reqpp;
1656 conn_id = reqp->conn_id;
1657 release_request(reqp, reqpp, 1);
1658 clip = find_client(conn_id);
1659 if(clip)
1660 {
1661 if( dll_empty((DLL *)clip->requestp_head) )
1662 {
1663 release_conn( conn_id, 0, 0);
1664 }
1665 }
1666 break;
1667 }
1668 }
1669 }while(more);
1670 ENABLE_AST
1671 }
1672 {
1673 DISABLE_AST
1674 servp->delay_delete = 0;
1675 if(servp->to_delete)
1676 {
1677 dis_remove_service(servp->id);
1678 }
1679 ENABLE_AST
1680 }
1681
1682 return(found);
1683}
1684
1685int dis_get_n_clients(unsigned service_id)
1686{
1687 register REQUEST *reqp;
1688 register SERVICE *servp;
1689 register int found = 0;
1690 char str[128];
1691
1692 DISABLE_AST
1693 if(!service_id)
1694 {
1695 sprintf(str, "Service Has Clients- Invalid service id");
1696 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1697 ENABLE_AST
1698 return(found);
1699 }
1700 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1701 if(!servp)
1702 {
1703 ENABLE_AST
1704 return(found);
1705 }
1706 if(servp->id != (int)service_id)
1707 {
1708 ENABLE_AST
1709 return(found);
1710 }
1711 reqp = servp->request_head;
1712 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1713 (DLL *) reqp)) )
1714 {
1715 found++;
1716 }
1717 ENABLE_AST
1718 return found;
1719}
1720
1721int dis_get_timeout(unsigned service_id, int client_id)
1722{
1723 register REQUEST *reqp;
1724 register SERVICE *servp;
1725 char str[128];
1726
1727 if(!service_id)
1728 {
1729 sprintf(str,"Get Timeout - Invalid service id");
1730 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1731 return(-1);
1732 }
1733 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1734 if(!servp)
1735 {
1736 return(-1);
1737 }
1738 reqp = servp->request_head;
1739 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1740 (DLL *) reqp)) )
1741 {
1742 if(reqp->conn_id == client_id)
1743 return(reqp->timeout);
1744 }
1745 return(-1);
1746}
1747
1748void dis_set_quality( unsigned serv_id, int quality )
1749{
1750 register SERVICE *servp;
1751 char str[128];
1752
1753 DISABLE_AST
1754 if(!serv_id)
1755 {
1756 sprintf(str,"Set Quality - Invalid service id");
1757 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1758 ENABLE_AST
1759 return;
1760 }
1761 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
1762 if(!servp)
1763 {
1764 ENABLE_AST
1765 return;
1766 }
1767 if(servp->id != (int)serv_id)
1768 {
1769 ENABLE_AST
1770 return;
1771 }
1772 servp->quality = quality;
1773 ENABLE_AST
1774}
1775
1776int dis_set_timestamp( unsigned serv_id, int secs, int millisecs )
1777{
1778 register SERVICE *servp;
1779 char str[128];
1780#ifdef WIN32
1781 struct timeb timebuf;
1782#else
1783 struct timeval tv;
1784 struct timezone *tz;
1785#endif
1786
1787 DISABLE_AST
1788 if(!serv_id)
1789 {
1790 sprintf(str,"Set Timestamp - Invalid service id");
1791 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1792 ENABLE_AST
1793 return(0);
1794 }
1795 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
1796 if(!servp)
1797 {
1798 ENABLE_AST
1799 return(0);
1800 }
1801 if(servp->id != (int)serv_id)
1802 {
1803 ENABLE_AST
1804 return(0);
1805 }
1806 if(secs == 0)
1807 {
1808#ifdef WIN32
1809 ftime(&timebuf);
1810 servp->user_secs = (int)timebuf.time;
1811 servp->user_millisecs = timebuf.millitm;
1812#else
1813 tz = 0;
1814 gettimeofday(&tv, tz);
1815 servp->user_secs = tv.tv_sec;
1816 servp->user_millisecs = tv.tv_usec / 1000;
1817#endif
1818 }
1819 else
1820 {
1821 servp->user_secs = secs;
1822/*
1823 servp->user_millisecs = (millisecs & 0xffff);
1824*/
1825 servp->user_millisecs = millisecs;
1826 }
1827 ENABLE_AST
1828 return(1);
1829}
1830
1831int dis_get_timestamp( unsigned serv_id, int *secs, int *millisecs )
1832{
1833 register SERVICE *servp;
1834 char str[128];
1835
1836 DISABLE_AST
1837 if(!serv_id)
1838 {
1839 sprintf(str,"Get Timestamp - Invalid service id");
1840 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1841 ENABLE_AST
1842 return(0);
1843 }
1844 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
1845 if(!servp)
1846 {
1847 ENABLE_AST
1848 return(0);
1849 }
1850 if(servp->id != (int)serv_id)
1851 {
1852 ENABLE_AST
1853 return(0);
1854 }
1855 if(servp->user_secs)
1856 {
1857 *secs = servp->user_secs;
1858 *millisecs = servp->user_millisecs;
1859 }
1860 else
1861 {
1862 *secs = 0;
1863 *millisecs = 0;
1864 }
1865 ENABLE_AST
1866 return(1);
1867}
1868
1869void dis_send_service(unsigned service_id, int *buffer, int size)
1870{
1871 register REQUEST *reqp, *prevp;
1872 register SERVICE *servp;
1873 static DIS_PACKET *dis_packet;
1874 static int packet_size = 0;
1875 int conn_id;
1876 char str[128];
1877
1878 DISABLE_AST
1879 if( !service_id ) {
1880 sprintf(str,"Send Service - Invalid service id");
1881 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1882 ENABLE_AST
1883 return;
1884 }
1885 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1886 if(!packet_size)
1887 {
1888 dis_packet = (DIS_PACKET *)malloc(DIS_HEADER+size);
1889 packet_size = DIS_HEADER + size;
1890 }
1891 else
1892 {
1893 if( DIS_HEADER+size > packet_size )
1894 {
1895 free(dis_packet);
1896 dis_packet = (DIS_PACKET *)malloc(DIS_HEADER+size);
1897 packet_size = DIS_HEADER+size;
1898 }
1899 }
1900 prevp = servp->request_head;
1901 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1902 (DLL *) prevp)) )
1903 {
1904 dis_packet->service_id = htovl(reqp->service_id);
1905 memcpy(dis_packet->buffer, buffer, size);
1906 dis_packet->size = htovl(DIS_HEADER + size);
1907
1908 conn_id = reqp->conn_id;
1909 if( !dna_write_nowait(conn_id, dis_packet, size + DIS_HEADER) )
1910 {
1911 release_conn(conn_id, 1, 0);
1912 }
1913 else
1914 prevp = reqp;
1915 }
1916 ENABLE_AST
1917}
1918
1919int dis_remove_service(unsigned service_id)
1920{
1921 register REQUEST *reqp, *auxp;
1922 register SERVICE *servp;
1923 REQUEST_PTR *reqpp;
1924 int found = 0;
1925 char str[128];
1926 int release_request();
1927 int dis_hash_service_remove();
1928 DIS_DNS_CONN *dnsp;
1929 int n_services;
1930 void do_dis_stop_serving_dns(DIS_DNS_CONN *);
1931
1932 DISABLE_AST
1933 if(!service_id)
1934 {
1935 sprintf(str,"Remove Service - Invalid service id");
1936 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1937 ENABLE_AST
1938 return(found);
1939 }
1940 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1941 if(!servp)
1942 {
1943 ENABLE_AST
1944 return(found);
1945 }
1946 if(servp->id != (int)service_id)
1947 {
1948 ENABLE_AST
1949 return(found);
1950 }
1951 if(servp->delay_delete)
1952 {
1953 servp->to_delete = 1;
1954 ENABLE_AST
1955 return(found);
1956 }
1957 /* remove from name server */
1958
1959 dnsp = servp->dnsp;
1960 unregister_service(dnsp, servp);
1961 /* Release client requests and remove from actual clients */
1962 reqp = servp->request_head;
1963 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1964 (DLL *) reqp)) )
1965 {
1966 remove_service(reqp->req_id);
1967 auxp = reqp->prev;
1968 reqpp = (REQUEST_PTR *) reqp->reqpp;
1969 release_request(reqp, reqpp, 1);
1970 found = 1;
1971 reqp = auxp;
1972 }
1973 if(servp->id == (int)dnsp->dis_service_id)
1974 dnsp->dis_service_id = 0;
1975 if(servp->id == (int)dnsp->dis_client_id)
1976 dnsp->dis_client_id = 0;
1977 dis_hash_service_remove(servp);
1978 id_free(servp->id, SRC_DIS);
1979 free(servp->request_head);
1980 free(servp);
1981/*
1982 if(dnsp != Default_DNS)
1983 {
1984 dnsp->dis_n_services--;
1985 n_services = dnsp->dis_n_services;
1986 }
1987 else
1988 {
1989 Dis_n_services--;
1990 n_services = Dis_n_services;
1991 }
1992*/
1993 dnsp->dis_n_services--;
1994 n_services = dnsp->dis_n_services;
1995
1996 ENABLE_AST
1997 if(dnsp->serving)
1998 {
1999 if(n_services == 5)
2000 {
2001/*
2002 dis_stop_serving();
2003*/
2004 do_dis_stop_serving_dns(dnsp);
2005 }
2006 }
2007 return(found);
2008}
2009
2010void do_dis_stop_serving_dns(DIS_DNS_CONN *dnsp)
2011{
2012register SERVICE *servp, *prevp;
2013void dim_stop_threads(void);
2014int dis_no_dns();
2015int hash_index, old_index;
2016extern int close_dns(long, int);
2017
2018 dnsp->serving = 0;
2019 dis_init();
2020/*
2021 dis_hash_service_init();
2022 prevp = 0;
2023 if(Dis_conn_id)
2024 {
2025 dna_close(Dis_conn_id);
2026 Dis_conn_id = 0;
2027 }
2028*/
2029 {
2030 DISABLE_AST
2031 if(dnsp->dns_timr_ent)
2032 {
2033 dtq_rem_entry(Dis_timer_q, dnsp->dns_timr_ent);
2034 dnsp->dns_timr_ent = NULL;
2035 }
2036 if(dnsp->dns_dis_conn_id)
2037 {
2038 dna_close(dnsp->dns_dis_conn_id);
2039 dnsp->dns_dis_conn_id = 0;
2040 }
2041 ENABLE_AST
2042 }
2043 {
2044 DISABLE_AST
2045 prevp = 0;
2046 hash_index = -1;
2047 old_index = -1;
2048 while( (servp = dis_hash_service_get_next(&hash_index, prevp, 0)) )
2049 {
2050 if(servp->dnsp == dnsp)
2051 {
2052 dis_remove_service(servp->id);
2053 if(old_index != hash_index)
2054 prevp = 0;
2055 }
2056 else
2057 {
2058 prevp = servp;
2059 old_index = hash_index;
2060 }
2061 }
2062 ENABLE_AST
2063 }
2064 dnsp->dis_first_time = 1;
2065 dnsp->dis_n_services = 0;
2066 dnsp->dis_dns_packet.size = 0;
2067 dnsp->dis_dns_packet.src_type = 0;
2068 close_dns(dnsp->dnsid, SRC_DIS);
2069/*
2070 if(dnsp != Default_DNS)
2071 {
2072 dll_remove(dnsp);
2073 free(dnsp);
2074 }
2075*/
2076/*
2077 if(dll_empty(DNS_head))
2078*/
2079 if(dis_no_dns())
2080 dis_stop_serving();
2081}
2082
2083void dis_stop_serving_dns(long dnsid)
2084{
2085 DIS_DNS_CONN *dnsp, *dis_find_dns();
2086
2087 dnsp = dis_find_dns(dnsid);
2088 do_dis_stop_serving_dns(dnsp);
2089}
2090
2091void dis_stop_serving()
2092{
2093register SERVICE *servp, *prevp;
2094void dim_stop_threads(void);
2095int hash_index;
2096
2097 Serving = 0;
2098 dis_init();
2099 if(Dis_conn_id)
2100 {
2101 dna_close(Dis_conn_id);
2102 Dis_conn_id = 0;
2103 }
2104/*
2105 if(Dns_dis_conn_id)
2106 {
2107 dna_close(Dns_dis_conn_id);
2108 Dns_dis_conn_id = 0;
2109 }
2110*/
2111 {
2112 DISABLE_AST
2113 prevp = 0;
2114 hash_index = -1;
2115 while( (servp = dis_hash_service_get_next(&hash_index, prevp, 0)) )
2116 {
2117 dis_remove_service(servp->id);
2118 prevp = 0;
2119 }
2120 ENABLE_AST
2121 }
2122/*
2123 if(Dis_conn_id)
2124 dna_close(Dis_conn_id);
2125 if(Dns_dis_conn_id)
2126 dna_close(Dns_dis_conn_id);
2127 Dns_dis_conn_id = 0;
2128*/
2129 Dis_first_time = 1;
2130/*
2131 if(Dns_timr_ent)
2132 {
2133 dtq_rem_entry(Dis_timer_q, Dns_timr_ent);
2134 Dns_timr_ent = NULL;
2135 }
2136*/
2137 dtq_delete(Dis_timer_q);
2138 Dis_timer_q = 0;
2139 dim_stop_threads();
2140}
2141
2142/* find service by name */
2143SERVICE *find_service(char *name)
2144{
2145 return(dis_hash_service_exists(name));
2146}
2147
2148CLIENT *find_client(int conn_id)
2149{
2150 register CLIENT *clip;
2151
2152 clip = (CLIENT *)
2153 dll_search( (DLL *) Client_head, &conn_id, sizeof(conn_id));
2154 return(clip);
2155}
2156
2157void release_all_requests(int conn_id, CLIENT *clip)
2158{
2159 register REQUEST_PTR *reqpp, *auxp;
2160 register REQUEST *reqp;
2161 int found = 0;
2162 int release_request();
2163 DIS_DNS_CONN *dnsp;
2164
2165 DISABLE_AST;
2166 if(clip)
2167 {
2168 reqpp = clip->requestp_head;
2169 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2170 (DLL *) reqpp)) )
2171 {
2172 auxp = reqpp->prev;
2173 reqp = (REQUEST *) reqpp->reqp;
2174 release_request(reqp, reqpp, 0);
2175 found = 1;
2176 reqpp = auxp;
2177 }
2178 dnsp = clip->dnsp;
2179 dll_remove(clip);
2180 free(clip->requestp_head);
2181 free(clip);
2182 }
2183 if(found)
2184 {
2185 Last_client = -conn_id;
2186 if(dnsp->dis_client_id)
2187 dis_update_service(dnsp->dis_client_id);
2188 }
2189 dna_close(conn_id);
2190 ENABLE_AST;
2191}
2192
2193CLIENT *check_delay_delete(int conn_id)
2194{
2195 register REQUEST_PTR *reqpp;
2196 register CLIENT *clip;
2197 register REQUEST *reqp;
2198 int found = 0;
2199
2200 DISABLE_AST;
2201 clip = find_client(conn_id);
2202 if(clip)
2203 {
2204 reqpp = clip->requestp_head;
2205 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2206 (DLL *) reqpp)) )
2207 {
2208 reqp = (REQUEST *) reqpp->reqp;
2209 if(reqp->delay_delete)
2210 {
2211 reqp->to_delete = 1;
2212 found = 1;
2213 }
2214 }
2215 }
2216 ENABLE_AST;
2217 if(found)
2218 {
2219 return((CLIENT *)-1);
2220 }
2221 return(clip);
2222}
2223
2224char *dis_get_error_services()
2225{
2226 return(dis_get_client_services(Error_conn_id));
2227}
2228
2229char *dis_get_client_services(int conn_id)
2230{
2231 register REQUEST_PTR *reqpp;
2232 register CLIENT *clip;
2233 register REQUEST *reqp;
2234 register SERVICE *servp;
2235
2236 int n_services = 0;
2237 int max_size;
2238 static int curr_allocated_size = 0;
2239 static char *service_info_buffer;
2240 char *buff_ptr;
2241
2242
2243 if(!conn_id)
2244 return((char *)0);
2245 {
2246 DISABLE_AST;
2247 clip = find_client(conn_id);
2248 if(clip)
2249 {
2250 reqpp = clip->requestp_head;
2251 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2252 (DLL *) reqpp)))
2253 {
2254 n_services++;
2255 }
2256 if(!n_services)
2257 {
2258 ENABLE_AST
2259 return((char *)0);
2260 }
2261 max_size = n_services * MAX_NAME;
2262 if(!curr_allocated_size)
2263 {
2264 service_info_buffer = (char *)malloc(max_size);
2265 curr_allocated_size = max_size;
2266 }
2267 else if (max_size > curr_allocated_size)
2268 {
2269 free(service_info_buffer);
2270 service_info_buffer = (char *)malloc(max_size);
2271 curr_allocated_size = max_size;
2272 }
2273 service_info_buffer[0] = '\0';
2274 buff_ptr = service_info_buffer;
2275 reqpp = clip->requestp_head;
2276 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2277 (DLL *) reqpp)) )
2278 {
2279 reqp = (REQUEST *) reqpp->reqp;
2280 servp = reqp->service_ptr;
2281 strcat(buff_ptr, servp->name);
2282 strcat(buff_ptr, "\n");
2283 buff_ptr += strlen(buff_ptr);
2284 }
2285 }
2286 else
2287 {
2288 ENABLE_AST
2289 return((char *)0);
2290 }
2291 ENABLE_AST;
2292 }
2293/*
2294 dim_print_date_time();
2295 dna_get_node_task(conn_id, node, task);
2296 printf("Client %s@%s uses services: \n", task, node);
2297 printf("%s\n",service_info_buffer);
2298*/
2299 return(service_info_buffer);
2300}
2301
2302int find_release_request(int conn_id, int service_id)
2303{
2304 register REQUEST_PTR *reqpp, *auxp;
2305 register CLIENT *clip;
2306 register REQUEST *reqp;
2307 int release_request();
2308
2309 DISABLE_AST
2310 clip = find_client(conn_id);
2311 if(clip)
2312 {
2313 reqpp = clip->requestp_head;
2314 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2315 (DLL *) reqpp)) )
2316 {
2317 reqp = (REQUEST *) reqpp->reqp;
2318 if(reqp->service_id == service_id)
2319 {
2320 if(reqp->delay_delete)
2321 {
2322 reqp->to_delete += 0x2;
2323 }
2324 else
2325 {
2326 auxp = reqpp->prev;
2327 release_request(reqp, reqpp, 0);
2328 reqpp = auxp;
2329 }
2330 }
2331 }
2332 if( dll_empty((DLL *)clip->requestp_head) )
2333 {
2334 release_conn( conn_id, 0, 0 );
2335 }
2336 }
2337 ENABLE_AST
2338 return(1);
2339}
2340
2341int release_request(REQUEST *reqp, REQUEST_PTR *reqpp, int remove)
2342{
2343 int conn_id;
2344 CLIENT *clip;
2345
2346 DISABLE_AST
2347 conn_id = reqp->conn_id;
2348 if(reqpp)
2349 dll_remove((DLL *)reqpp);
2350 dll_remove((DLL *)reqp);
2351 if(reqp->timr_ent)
2352 dtq_rem_entry(Dis_timer_q, reqp->timr_ent);
2353 id_free(reqp->req_id, SRC_DIS);
2354 free(reqp);
2355 free(reqpp);
2356/* Would do it too early, the client will disconnect anyway
2357*/
2358 if((remove) && (!Serving))
2359 {
2360 clip = find_client(conn_id);
2361 if(clip)
2362 {
2363 if( dll_empty((DLL *)clip->requestp_head) )
2364 {
2365 release_conn( conn_id, 0, 0);
2366 }
2367 }
2368 }
2369
2370 ENABLE_AST
2371 return(1);
2372}
2373
2374static int release_conn(int conn_id, int print_flg, int dns_flag)
2375{
2376 static int releasing = 0;
2377 CLIENT *clip;
2378 int do_exit_handler();
2379
2380 DISABLE_AST
2381 if(print_flg){}
2382 if(dns_flag)
2383 {
2384 recv_dns_dis_rout( conn_id, 0, 0, STA_DISC );
2385 ENABLE_AST
2386 return(0);
2387 }
2388#ifdef VMS
2389 if(print_flg)
2390 {
2391 dim_print_date_time();
2392 dna_get_node_task(conn_id, node, task);
2393 printf(" Couldn't write to client %s@%s, releasing connection %d\n",
2394 task, node, conn_id);
2395 fflush(stdout);
2396 }
2397#endif
2398 clip = check_delay_delete(conn_id);
2399 if(clip != (CLIENT *)-1)
2400 {
2401 if( Client_exit_user_routine != 0 )
2402 {
2403 releasing++;
2404 Curr_conn_id = conn_id;
2405 do_exit_handler(conn_id);
2406 releasing--;
2407 }
2408 if(!releasing)
2409 {
2410 release_all_requests(conn_id, clip);
2411 }
2412 }
2413 ENABLE_AST
2414 return(1);
2415}
2416
2417typedef struct cmnds{
2418 struct cmnds *next;
2419 long tag;
2420 int size;
2421 int buffer[1];
2422} DIS_CMND;
2423
2424static DIS_CMND *Cmnds_head = (DIS_CMND *)0;
2425
2426void std_cmnd_handler(long *tag, int *cmnd_buff, int *size)
2427{
2428 register DIS_CMND *new_cmnd;
2429/* queue the command */
2430
2431 if(!Cmnds_head)
2432 {
2433 Cmnds_head = (DIS_CMND *)malloc(sizeof(DIS_CMND));
2434 sll_init((SLL *) Cmnds_head);
2435 }
2436 new_cmnd = (DIS_CMND *)malloc((*size)+12);
2437 new_cmnd->next = 0;
2438 new_cmnd->tag = *tag;
2439 new_cmnd->size = *size;
2440 memcpy(new_cmnd->buffer, cmnd_buff, *size);
2441 sll_insert_queue((SLL *) Cmnds_head, (SLL *) new_cmnd);
2442}
2443
2444int dis_get_next_cmnd(long *tag, int *buffer, int *size)
2445{
2446 register DIS_CMND *cmndp;
2447 register int ret_val = -1;
2448
2449 DISABLE_AST
2450 if(!Cmnds_head)
2451 {
2452 Cmnds_head = (DIS_CMND *)malloc(sizeof(DIS_CMND));
2453 sll_init((SLL *) Cmnds_head);
2454 }
2455 if(*size == 0)
2456 {
2457 if( (cmndp = (DIS_CMND *) sll_get_head((SLL *) Cmnds_head)))
2458 {
2459 if(cmndp->size > 0)
2460 {
2461 *size = cmndp->size;
2462 *tag = cmndp->tag;
2463 ENABLE_AST
2464 return(-1);
2465 }
2466 }
2467 }
2468 if( (cmndp = (DIS_CMND *) sll_remove_head((SLL *) Cmnds_head)) )
2469 {
2470 if (*size >= cmndp->size)
2471 {
2472 *size = cmndp->size;
2473 ret_val = 1;
2474 }
2475 memcpy(buffer, cmndp->buffer, *size);
2476 *tag = cmndp->tag;
2477 free(cmndp);
2478 ENABLE_AST
2479 return(ret_val);
2480 }
2481 ENABLE_AST
2482 return(0);
2483}
2484
2485int dis_get_conn_id()
2486{
2487 return(Curr_conn_id);
2488}
2489
2490int dis_get_client(char *name)
2491{
2492 int ret = 0;
2493 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2494
2495 DISABLE_AST
2496
2497 if(Curr_conn_id)
2498 {
2499 dna_get_node_task(Curr_conn_id, node, task);
2500 strcpy(name,task);
2501 strcat(name,"@");
2502 strcat(name,node);
2503 ret = Curr_conn_id;
2504 }
2505 ENABLE_AST
2506 return(ret);
2507}
2508
2509#ifdef VMS
2510dis_convert_str(c_str, for_str)
2511char *c_str;
2512struct dsc$descriptor_s *for_str;
2513{
2514 int i;
2515
2516 strcpy(for_str->dsc$a_pointer, c_str);
2517 for(i = strlen(c_str); i< for_str->dsc$w_length; i++)
2518 for_str->dsc$a_pointer[i] = ' ';
2519}
2520#endif
2521
2522void client_info(long *tag, int **bufp, int *size, int *first_time)
2523{
2524 register CLIENT *clip;
2525 int curr_conns[MAX_CONNS];
2526 int i, index, max_size;
2527 static int curr_allocated_size = 0;
2528 static char *dns_info_buffer;
2529 register char *dns_client_info;
2530 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2531 DIS_DNS_CONN *dnsp = (DIS_DNS_CONN *)*tag;
2532
2533 max_size = sizeof(DNS_CLIENT_INFO);
2534 if(!curr_allocated_size)
2535 {
2536 dns_info_buffer = malloc(max_size);
2537 curr_allocated_size = max_size;
2538 }
2539 dns_client_info = dns_info_buffer;
2540 dns_client_info[0] = '\0';
2541 index = 0;
2542 if(*first_time)
2543 {
2544 clip = Client_head;
2545 while( (clip = (CLIENT *)dll_get_next( (DLL *) Client_head,
2546 (DLL*) clip)) )
2547 {
2548 if(clip->dnsp != dnsp)
2549 continue;
2550 curr_conns[index++] = clip->conn_id;
2551 }
2552 max_size = (index+1)*sizeof(DNS_CLIENT_INFO);
2553 if (max_size > curr_allocated_size)
2554 {
2555 free(dns_info_buffer);
2556 dns_info_buffer = malloc(max_size);
2557 curr_allocated_size = max_size;
2558 }
2559 dns_client_info = dns_info_buffer;
2560 dns_client_info[0] = '\0';
2561 }
2562 else
2563 {
2564 if(Last_client > 0)
2565 {
2566 strcat(dns_client_info,"+");
2567 curr_conns[index++] = Last_client;
2568 }
2569 else
2570 {
2571 strcat(dns_client_info,"-");
2572 curr_conns[index++] = -Last_client;
2573 }
2574 }
2575
2576 for(i=0; i<index;i++)
2577 {
2578 dna_get_node_task(curr_conns[i], node, task);
2579 strcat(dns_client_info,task);
2580 strcat(dns_client_info,"@");
2581 strcat(dns_client_info,node);
2582 strcat(dns_client_info,"|");
2583 }
2584 if(index)
2585 dns_client_info[strlen(dns_client_info)-1] = '\0';
2586 *bufp = (int *)dns_info_buffer;
2587 *size = strlen(dns_info_buffer)+1;
2588}
2589
2590void append_service(char *service_info_buffer, SERVICE *servp)
2591{
2592 char name[MAX_NAME], *ptr;
2593
2594 if(strstr(servp->name,"/RpcIn"))
2595 {
2596 strcpy(name,servp->name);
2597 ptr = (char *)strstr(name,"/RpcIn");
2598 *ptr = 0;
2599 strcat(service_info_buffer, name);
2600 strcat(service_info_buffer, "|");
2601 if(servp->def[0])
2602 {
2603 strcat(service_info_buffer, servp->def);
2604 }
2605 strcat(name,"/RpcOut");
2606 if( (servp = find_service(name)) )
2607 {
2608 strcat(service_info_buffer, ",");
2609 if(servp->def[0])
2610 {
2611 strcat(service_info_buffer, servp->def);
2612 }
2613 }
2614 strcat(service_info_buffer, "|RPC");
2615 strcat(service_info_buffer, "\n");
2616 }
2617 else if(strstr(servp->name,"/RpcOut"))
2618 {
2619/*
2620 if(servp->def[0])
2621 {
2622 strcat(service_info_buffer, servp->def);
2623 }
2624 strcat(service_info_buffer, "|RPC");
2625 strcat(service_info_buffer, "\n");
2626
2627*/
2628 }
2629 else
2630 {
2631 strcat(service_info_buffer, servp->name);
2632 strcat(service_info_buffer, "|");
2633 if(servp->def[0])
2634 {
2635 strcat(service_info_buffer, servp->def);
2636 }
2637 strcat(service_info_buffer, "|");
2638 if(servp->type == COMMAND)
2639 {
2640 strcat(service_info_buffer, "CMD");
2641 }
2642 strcat(service_info_buffer, "\n");
2643 }
2644}
2645
2646void service_info(long *tag, int **bufp, int *size, int *first_time)
2647{
2648 register SERVICE *servp;
2649 int max_size, done = 0;
2650 static int curr_allocated_size = 0;
2651 static char *service_info_buffer;
2652 char *buff_ptr;
2653 DIS_DNS_CONN *dnsp = (DIS_DNS_CONN *)*tag;
2654 int hash_index;
2655
2656 DISABLE_AST
2657 max_size = (dnsp->dis_n_services+10) * (MAX_NAME*2 + 4);
2658 if(!curr_allocated_size)
2659 {
2660 service_info_buffer = (char *)malloc(max_size);
2661 curr_allocated_size = max_size;
2662 }
2663 else if (max_size > curr_allocated_size)
2664 {
2665 free(service_info_buffer);
2666 service_info_buffer = (char *)malloc(max_size);
2667 curr_allocated_size = max_size;
2668 }
2669 service_info_buffer[0] = '\0';
2670 buff_ptr = service_info_buffer;
2671 servp = 0;
2672 hash_index = -1;
2673 if(*first_time)
2674 {
2675 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
2676 {
2677 if(servp->dnsp != dnsp)
2678 continue;
2679 if(servp->registered)
2680 {
2681 servp->registered = 2;
2682 append_service(buff_ptr, servp);
2683 buff_ptr += strlen(buff_ptr);
2684 }
2685 }
2686 }
2687 else
2688 {
2689 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
2690 {
2691 if(servp->dnsp != dnsp)
2692 continue;
2693 if(servp->registered == 1)
2694 {
2695 if(!done)
2696 {
2697 strcat(buff_ptr, "+");
2698 buff_ptr += strlen(buff_ptr);
2699 done = 1;
2700 }
2701 append_service(buff_ptr, servp);
2702 buff_ptr += strlen(buff_ptr);
2703 servp->registered = 2;
2704 }
2705 else if(servp->registered == 0)
2706 {
2707 strcat(buff_ptr, "-");
2708 buff_ptr += strlen(buff_ptr);
2709 append_service(buff_ptr, servp);
2710 buff_ptr += strlen(buff_ptr);
2711 }
2712 }
2713 }
2714 *bufp = (int *)service_info_buffer;
2715 *size = buff_ptr - service_info_buffer+1;
2716 ENABLE_AST
2717}
2718
2719void add_exit_handler(int *tag, int *bufp, int *size)
2720{
2721 EXIT_H *newp;
2722
2723 if(size){}
2724 if(tag){}
2725 if(*bufp)
2726 {
2727 if(!Exit_h_head)
2728 {
2729 Exit_h_head = (EXIT_H *)malloc(sizeof(EXIT_H));
2730 sll_init( (SLL *) Exit_h_head );
2731 }
2732 newp = (EXIT_H *)malloc(sizeof(EXIT_H));
2733 newp->conn_id = Curr_conn_id;
2734 newp->exit_id = *bufp;
2735 sll_insert_queue( (SLL *) Exit_h_head, (SLL *) newp );
2736 }
2737 else
2738 {
2739 if(!Exit_h_head)
2740 return;
2741 if((newp = (EXIT_H *)sll_search((SLL *) Exit_h_head,
2742 (char *)&Curr_conn_id, 4)) )
2743 {
2744 sll_remove( (SLL *) Exit_h_head, (SLL *) newp );
2745 }
2746 }
2747}
2748
2749void dis_set_client_exit_handler(int conn_id, int tag)
2750{
2751 EXIT_H *newp;
2752
2753 DISABLE_AST
2754 if(tag)
2755 {
2756 if(!Exit_h_head)
2757 {
2758 Exit_h_head = (EXIT_H *)malloc(sizeof(EXIT_H));
2759 sll_init( (SLL *) Exit_h_head );
2760 }
2761 if( (newp = (EXIT_H *)sll_search((SLL *) Exit_h_head,
2762 (char *)&conn_id, 4)) )
2763 {
2764 newp->conn_id = conn_id;
2765 newp->exit_id = tag;
2766 }
2767 else
2768 {
2769 newp = (EXIT_H *)malloc(sizeof(EXIT_H));
2770 newp->conn_id = conn_id;
2771 newp->exit_id = tag;
2772 sll_insert_queue( (SLL *) Exit_h_head, (SLL *) newp );
2773 }
2774 }
2775 else
2776 {
2777 if(!Exit_h_head)
2778 {
2779 ENABLE_AST
2780 return;
2781 }
2782 if( (newp = (EXIT_H *)sll_search((SLL *) Exit_h_head,
2783 (char *)&conn_id, 4)) )
2784 {
2785 sll_remove( (SLL *) Exit_h_head, (SLL *) newp );
2786 }
2787 }
2788 ENABLE_AST
2789}
2790
2791int do_exit_handler(int conn_id)
2792{
2793 register EXIT_H *exitp;
2794
2795 DISABLE_AST;
2796 if(!Exit_h_head)
2797 {
2798 ENABLE_AST;
2799 return(0);
2800 }
2801 while( (exitp = (EXIT_H *) sll_search_next_remove((SLL *) Exit_h_head,
2802 0, (char *) &conn_id, 4)) )
2803 {
2804 (Client_exit_user_routine)( &exitp->exit_id );
2805 free(exitp);
2806 }
2807 ENABLE_AST
2808 return(1);
2809}
2810
2811static void exit_handler(int *tag, int *bufp, int *size)
2812{
2813
2814 if(size){}
2815 if(tag){}
2816 if(Exit_user_routine)
2817 (Exit_user_routine)( bufp );
2818 else
2819 {
2820/*
2821 printf("%s PID %d Exiting!\n", Task_name, getpid());
2822*/
2823 exit(*bufp);
2824 }
2825}
2826
2827static void error_handler(int conn_id, int severity, int errcode, char *reason)
2828{
2829 int exit_tag, exit_code, exit_size;
2830 int last_conn_id;
2831
2832 if(Error_user_routine)
2833 {
2834 Error_conn_id = conn_id;
2835 last_conn_id = Curr_conn_id;
2836 Curr_conn_id = conn_id;
2837 (Error_user_routine)( severity, errcode, reason);
2838 Error_conn_id = 0;
2839 Curr_conn_id = last_conn_id;
2840 }
2841 else
2842 {
2843 dim_print_msg(reason, severity);
2844 }
2845 if(severity == DIM_FATAL)
2846 {
2847 exit_tag = 0;
2848 exit_code = errcode;
2849 exit_size = sizeof(int);
2850 exit_handler(&exit_tag, &exit_code, &exit_size);
2851 }
2852}
2853/*
2854#define MAX_HASH_ENTRIES 2000
2855*/
2856#define MAX_HASH_ENTRIES 5000
2857
2858static SERVICE *Service_hash_table[MAX_HASH_ENTRIES];
2859static int Service_new_entries[MAX_HASH_ENTRIES];
2860
2861int dis_hash_service_init()
2862{
2863 int i;
2864 static int done = 0;
2865
2866 if(!done)
2867 {
2868 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
2869 {
2870 Service_hash_table[i] = (SERVICE *) malloc(8);
2871 dll_init((DLL *) Service_hash_table[i]);
2872 Service_new_entries[i] = 0;
2873 }
2874 done = 1;
2875 }
2876 return(1);
2877}
2878
2879int dis_hash_service_insert(SERVICE *servp)
2880{
2881 int index;
2882 index = HashFunction(servp->name, MAX_HASH_ENTRIES);
2883 Service_new_entries[index]++;
2884 dll_insert_queue((DLL *) Service_hash_table[index],
2885 (DLL *) servp);
2886 return(1);
2887}
2888
2889int dis_hash_service_registered(int index, SERVICE *servp)
2890{
2891 servp->registered = 1;
2892 Service_new_entries[index]--;
2893 if(Service_new_entries[index] < 0)
2894 Service_new_entries[index] = 0;
2895 return 1;
2896}
2897
2898int dis_hash_service_remove(SERVICE *servp)
2899{
2900 dll_remove( (DLL *) servp );
2901 return(1);
2902}
2903
2904
2905SERVICE *dis_hash_service_exists(char *name)
2906{
2907 int index;
2908 SERVICE *servp;
2909
2910 index = HashFunction(name, MAX_HASH_ENTRIES);
2911 if( (servp = (SERVICE *) dll_search(
2912 (DLL *) Service_hash_table[index],
2913 name, strlen(name)+1)) )
2914 {
2915 return(servp);
2916 }
2917 return((SERVICE *)0);
2918}
2919
2920SERVICE *dis_hash_service_get_next(int *curr_index, SERVICE *prevp, int new_entries)
2921{
2922 int index;
2923 SERVICE *servp = 0;
2924/*
2925 if(!prevp)
2926 {
2927 index = -1;
2928 }
2929*/
2930 index = *curr_index;
2931 if(index == -1)
2932 {
2933 index++;
2934 prevp = Service_hash_table[index];
2935 }
2936 if(!prevp)
2937 {
2938 prevp = Service_hash_table[index];
2939 }
2940 do
2941 {
2942 if((!new_entries) || (Service_new_entries[index] > 0))
2943 {
2944 servp = (SERVICE *) dll_get_next(
2945 (DLL *) Service_hash_table[index],
2946 (DLL *) prevp);
2947 if(servp)
2948 break;
2949 }
2950 index++;
2951 if(index == MAX_HASH_ENTRIES)
2952 {
2953 *curr_index = -1;
2954 return((SERVICE *) 0);
2955 }
2956 prevp = Service_hash_table[index];
2957 } while(!servp);
2958 *curr_index = index;
2959 return(servp);
2960}
2961
2962DIS_DNS_CONN *dis_find_dns(long dnsid)
2963{
2964 DIS_DNS_CONN *dnsp;
2965
2966 dnsp = (DIS_DNS_CONN *)
2967 dll_search( (DLL *) DNS_head, &dnsid, sizeof(dnsid));
2968/*
2969 if(!dnsp)
2970 {
2971 dnsp = create_dns(dnsid);
2972 }
2973*/
2974 return dnsp;
2975}
2976
2977int dis_no_dns()
2978{
2979 DIS_DNS_CONN *dnsp;
2980
2981 dnsp = (DIS_DNS_CONN *) DNS_head;
2982 while ( (dnsp = (DIS_DNS_CONN *) dll_get_next( (DLL *) DNS_head, (DLL *) dnsp)))
2983 {
2984/*
2985 if(dnsp != Default_DNS)
2986 return 0;
2987*/
2988 if(dnsp->serving)
2989 return 0;
2990 }
2991 return 1;
2992}
2993
2994DIS_DNS_CONN *find_dns_by_conn_id(int conn_id)
2995{
2996 DIS_DNS_CONN *dnsp;
2997 extern long dns_get_dnsid();
2998 long dnsid;
2999
3000 dnsid = dns_get_dnsid(conn_id, SRC_DIS);
3001 dnsp = dis_find_dns(dnsid);
3002 if(!dnsp)
3003 dnsp = Default_DNS;
3004 return (DIS_DNS_CONN *)dnsp;
3005}
3006
3007void dis_print_hash_table()
3008{
3009 SERVICE *servp;
3010 int i;
3011 int n_entries, max_entry_index = 0;
3012 int max_entries = 0;
3013
3014 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
3015 {
3016 n_entries = 0;
3017 servp = Service_hash_table[i];
3018 while( (servp = (SERVICE *) dll_get_next(
3019 (DLL *) Service_hash_table[i],
3020 (DLL *) servp)) )
3021 {
3022 n_entries++;
3023 if(n_entries == 1)
3024 printf(" Name = %s\n",servp->name);
3025 }
3026 if(n_entries != 0)
3027 printf("HASH[%d] - %d entries\n", i, n_entries);
3028 if(n_entries > max_entries)
3029 {
3030 max_entries = n_entries;
3031 max_entry_index = i;
3032 }
3033 }
3034 printf("Maximum : HASH[%d] - %d entries\n", max_entry_index, max_entries);
3035 fflush(stdout);
3036}
3037
3038void dis_hash_print()
3039{
3040 SERVICE *servp;
3041 int hash_index;
3042
3043 servp = 0;
3044 hash_index = -1;
3045 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
3046 {
3047 printf("Name = %s\n",servp->name);
3048 }
3049}
3050
3051#ifdef VMS
3052/* CFORTRAN WRAPPERS */
3053FCALLSCFUN1(INT, dis_start_serving, DIS_START_SERVING, dis_start_serving,
3054 STRING)
3055FCALLSCFUN3(INT, dis_get_next_cmnd, DIS_GET_NEXT_CMND, dis_get_next_cmnd,
3056 PINT, PVOID, PINT)
3057FCALLSCFUN1(INT, dis_get_client, DIS_GET_CLIENT, dis_get_client,
3058 PSTRING)
3059FCALLSCFUN6(INT, dis_add_service, DIS_ADD_SERVICE, dis_add_service,
3060 STRING, PVOID, PVOID, INT, PVOID, INT)
3061FCALLSCSUB4( dis_add_cmnd, DIS_ADD_CMND, dis_add_cmnd,
3062 STRING, PVOID, PVOID, INT)
3063FCALLSCSUB1( dis_add_client_exit_handler, DIS_ADD_CLIENT_EXIT_HANDLER,
3064 dis_add_client_exit_handler,
3065 PVOID)
3066FCALLSCSUB2( dis_set_client_exit_handler, DIS_SET_CLIENT_EXIT_HANDLER,
3067 dis_set_client_exit_handler,
3068 INT, INT)
3069FCALLSCSUB1( dis_add_exit_handler, DIS_ADD_EXIT_HANDLER,
3070 dis_add_exit_handler,
3071 PVOID)
3072FCALLSCSUB1( dis_report_service, DIS_REPORT_SERVICE, dis_report_service,
3073 STRING)
3074FCALLSCSUB2( dis_convert_str, DIS_CONVERT_STR, dis_convert_str,
3075 PVOID, PVOID)
3076FCALLSCFUN1(INT, dis_update_service, DIS_UPDATE_SERVICE, dis_update_service,
3077 INT)
3078FCALLSCFUN1(INT, dis_remove_service, DIS_REMOVE_SERVICE, dis_remove_service,
3079 INT)
3080FCALLSCSUB3( dis_send_service, DIS_SEND_SERVICE, dis_send_service,
3081 INT, PVOID, INT)
3082FCALLSCSUB2( dis_set_quality, DIS_SET_QUALITY, dis_set_quality,
3083 INT, INT)
3084FCALLSCSUB3(INT, dis_set_timestamp, DIS_SET_TIMESTAMP, dis_set_timestamp,
3085 INT, INT, INT)
3086FCALLSCFUN2(INT, dis_selective_update_service, DIS_SELECTIVE_UPDATE_SERVICE,
3087 dis_selective_update_service,
3088 INT, PINT)
3089FCALLSCSUB3(INT, dis_get_timestamp, DIS_GET_TIMESTAMP, dis_get_timestamp,
3090 INT, PINT, PINT)
3091#endif
Note: See TracBrowser for help on using the repository browser.