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

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