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

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