source: branches/FACT++_part_filenames/dim/src/dis.c@ 19365

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