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

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