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

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