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

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