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

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