source: trunk/FACT++/dim/src/dis.c@ 12408

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