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

Last change on this file since 14064 was 13995, checked in by tbretz, 12 years ago
Switched to v19r35
File size: 69.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 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/*
1563 if( !dna_write_nowait(reqp->conn_id, dis_packet, DIS_HEADER) )
1564Has to be dna_write otherwise the client gets the message much before the DNS
1565*/
1566 if( !dna_write(reqp->conn_id, dis_packet, DIS_HEADER) )
1567 {
1568 dim_print_date_time();
1569 printf(" Server Removing Service: Couldn't write to Conn %3d : Client %s@%s\n",
1570 reqp->conn_id, Net_conns[reqp->conn_id].task, Net_conns[reqp->conn_id].node);
1571 fflush(stdout);
1572 release_conn(reqp->conn_id, 0, 0);
1573 }
1574}
1575
1576void execute_command(SERVICE *servp, DIC_PACKET *packet)
1577{
1578 int size;
1579 int format;
1580 FORMAT_STR format_data_cp[MAX_NAME/4], *formatp;
1581 static int *buffer;
1582 static int buffer_size = 0;
1583 int add_size;
1584
1585 size = vtohl(packet->size) - DIC_HEADER;
1586 add_size = size + (size/2);
1587 if(!buffer_size)
1588 {
1589 buffer = (int *)malloc(add_size);
1590 buffer_size = add_size;
1591 }
1592 else
1593 {
1594 if( add_size > buffer_size )
1595 {
1596 free(buffer);
1597 buffer = (int *)malloc(add_size);
1598 buffer_size = add_size;
1599 }
1600 }
1601
1602 dis_set_timestamp(servp->id, 0, 0);
1603 if(servp->user_routine != 0)
1604 {
1605 format = vtohl(packet->format);
1606 memcpy(format_data_cp, servp->format_data, sizeof(format_data_cp));
1607 if((format & 0xF) == ((MY_FORMAT) & 0xF))
1608 {
1609 for(formatp = format_data_cp; formatp->par_bytes; formatp++)
1610 {
1611 if(formatp->flags & IT_IS_FLOAT)
1612 formatp->flags |= (format & 0xf0);
1613 formatp->flags &= 0xFFF0; /* NOSWAP */
1614 }
1615 }
1616 else
1617 {
1618 for(formatp = format_data_cp; formatp->par_bytes; formatp++)
1619 {
1620 if(formatp->flags & IT_IS_FLOAT)
1621 formatp->flags |= (format & 0xf0);
1622 }
1623 }
1624 size = copy_swap_buffer_in(format_data_cp,
1625 buffer,
1626 packet->buffer, size);
1627 (servp->user_routine)(&servp->tag, buffer, &size);
1628 }
1629}
1630
1631void dis_report_service(char *serv_name)
1632{
1633 register SERVICE *servp;
1634 register REQUEST *reqp;
1635 int to_delete = 0, more;
1636
1637
1638 DISABLE_AST
1639 servp = find_service(serv_name);
1640 reqp = servp->request_head;
1641 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1642 (DLL *) reqp)) )
1643 {
1644 if((reqp->type & 0xFFF) != TIMED_ONLY)
1645 {
1646 execute_service(reqp->req_id);
1647 if(reqp->to_delete)
1648 to_delete = 1;
1649 }
1650 }
1651 if(to_delete)
1652 {
1653 do
1654 {
1655 more = 0;
1656 reqp = servp->request_head;
1657 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1658 (DLL *) reqp)) )
1659 {
1660 if(reqp->to_delete)
1661 {
1662 more = 1;
1663 release_conn(reqp->conn_id, 1, 0);
1664 break;
1665 }
1666 }
1667 }while(more);
1668 }
1669 ENABLE_AST
1670}
1671
1672int dis_update_service(unsigned service_id)
1673{
1674int do_update_service();
1675
1676 return(do_update_service(service_id,0));
1677}
1678
1679int dis_selective_update_service(unsigned service_id, int *client_ids)
1680{
1681int do_update_service();
1682
1683 return(do_update_service(service_id, client_ids));
1684}
1685
1686int check_client(REQUEST *reqp, int *client_ids)
1687{
1688 if(!client_ids)
1689 return(1);
1690 while(*client_ids)
1691 {
1692 if(reqp->conn_id == *client_ids)
1693 {
1694 return(1);
1695 }
1696 client_ids++;
1697 }
1698 return(0);
1699}
1700
1701int do_update_service(unsigned service_id, int *client_ids)
1702{
1703 register REQUEST *reqp;
1704 register SERVICE *servp;
1705 REQUEST_PTR *reqpp;
1706 CLIENT *clip;
1707 register int found = 0;
1708 int to_delete = 0, more, conn_id;
1709 char str[128];
1710 int release_request();
1711 int n_clients = 0;
1712
1713 DISABLE_AST
1714 if(Serving == -1)
1715 {
1716 ENABLE_AST
1717 return(found);
1718 }
1719 if(!service_id)
1720 {
1721 sprintf(str, "Update Service - Invalid service id");
1722 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1723 ENABLE_AST
1724 return(found);
1725 }
1726 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1727 if(!servp)
1728 {
1729 ENABLE_AST
1730 return(found);
1731 }
1732 if(servp->id != (int)service_id)
1733 {
1734 ENABLE_AST
1735 return(found);
1736 }
1737 servp->delay_delete = 1;
1738 reqp = servp->request_head;
1739 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1740 (DLL *) reqp)) )
1741 {
1742/*
1743if(Debug_on)
1744{
1745dim_print_date_time();
1746printf("Updating %s (id = %d, ptr = %08lX) for %s@%s (req_id = %d, req_ptr = %08lX)\n",
1747 servp->name, (int)service_id, (unsigned long)servp,
1748 Net_conns[reqp->conn_id].task, Net_conns[reqp->conn_id].node, reqp->req_id, (unsigned long)reqp);
1749}
1750*/
1751 if(check_client(reqp, client_ids))
1752 {
1753 reqp->delay_delete = 1;
1754 n_clients++;
1755 }
1756 }
1757 ENABLE_AST
1758 {
1759 DISABLE_AST
1760 Last_n_clients = n_clients;
1761 reqp = servp->request_head;
1762 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1763 (DLL *) reqp)) )
1764 {
1765 if(reqp->delay_delete && ((reqp->type & 0xFFF) != COMMAND))
1766 {
1767 if(check_client(reqp, client_ids))
1768 {
1769 if( (reqp->type & 0xFFF) != TIMED_ONLY )
1770 {
1771/*
1772 DISABLE_AST
1773*/
1774 execute_service(reqp->req_id);
1775 found++;
1776 ENABLE_AST
1777 {
1778 DISABLE_AST
1779 }
1780 }
1781 }
1782 }
1783 }
1784 ENABLE_AST
1785 }
1786 {
1787 DISABLE_AST
1788 reqp = servp->request_head;
1789 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1790 (DLL *) reqp)) )
1791 {
1792 if(check_client(reqp, client_ids))
1793 {
1794 reqp->delay_delete = 0;
1795 if(reqp->to_delete)
1796 to_delete = 1;
1797 }
1798 }
1799 ENABLE_AST
1800 }
1801 if(to_delete)
1802 {
1803 DISABLE_AST
1804 do
1805 {
1806 more = 0;
1807 reqp = servp->request_head;
1808 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1809 (DLL *) reqp)) )
1810 {
1811 if(reqp->to_delete & 0x1)
1812 {
1813 more = 1;
1814 reqp->to_delete = 0;
1815 release_conn(reqp->conn_id, 1, 0);
1816 break;
1817 }
1818 else if(reqp->to_delete & 0x2)
1819 {
1820 more = 1;
1821 reqp->to_delete = 0;
1822 reqpp = reqp->reqpp;
1823 conn_id = reqp->conn_id;
1824 release_request(reqp, reqpp, 1);
1825 clip = find_client(conn_id);
1826 if(clip)
1827 {
1828 if( dll_empty((DLL *)clip->requestp_head) )
1829 {
1830 release_conn( conn_id, 0, 0);
1831 }
1832 }
1833 break;
1834 }
1835 }
1836 }while(more);
1837 ENABLE_AST
1838 }
1839 {
1840 DISABLE_AST
1841 servp->delay_delete = 0;
1842 if(servp->to_delete)
1843 {
1844 dis_remove_service(servp->id);
1845 }
1846 ENABLE_AST
1847 }
1848
1849 return(found);
1850}
1851
1852int dis_get_n_clients(unsigned service_id)
1853{
1854 register REQUEST *reqp;
1855 register SERVICE *servp;
1856 register int found = 0;
1857 char str[128];
1858
1859 DISABLE_AST
1860 if(!service_id)
1861 {
1862 sprintf(str, "Service Has Clients- Invalid service id");
1863 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1864 ENABLE_AST
1865 return(found);
1866 }
1867 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1868 if(!servp)
1869 {
1870 ENABLE_AST
1871 return(found);
1872 }
1873 if(servp->id != (int)service_id)
1874 {
1875 ENABLE_AST
1876 return(found);
1877 }
1878 reqp = servp->request_head;
1879 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1880 (DLL *) reqp)) )
1881 {
1882 found++;
1883 }
1884 ENABLE_AST
1885 return found;
1886}
1887
1888int dis_get_timeout(unsigned service_id, int client_id)
1889{
1890 register REQUEST *reqp;
1891 register SERVICE *servp;
1892 char str[128];
1893
1894 if(!service_id)
1895 {
1896 sprintf(str,"Get Timeout - Invalid service id");
1897 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1898 return(-1);
1899 }
1900 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
1901 if(!servp)
1902 {
1903 return(-1);
1904 }
1905 reqp = servp->request_head;
1906 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
1907 (DLL *) reqp)) )
1908 {
1909 if(reqp->conn_id == client_id)
1910 return(reqp->timeout);
1911 }
1912 return(-1);
1913}
1914
1915void dis_set_quality( unsigned serv_id, int quality )
1916{
1917 register SERVICE *servp;
1918 char str[128];
1919
1920 DISABLE_AST
1921 if(!serv_id)
1922 {
1923 sprintf(str,"Set Quality - Invalid service id");
1924 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1925 ENABLE_AST
1926 return;
1927 }
1928 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
1929 if(!servp)
1930 {
1931 ENABLE_AST
1932 return;
1933 }
1934 if(servp->id != (int)serv_id)
1935 {
1936 ENABLE_AST
1937 return;
1938 }
1939 servp->quality = quality;
1940 ENABLE_AST
1941}
1942
1943int dis_set_timestamp( unsigned serv_id, int secs, int millisecs )
1944{
1945 register SERVICE *servp;
1946 char str[128];
1947#ifdef WIN32
1948 struct timeb timebuf;
1949#else
1950 struct timeval tv;
1951 struct timezone *tz;
1952#endif
1953
1954 DISABLE_AST
1955 if(!serv_id)
1956 {
1957 sprintf(str,"Set Timestamp - Invalid service id");
1958 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
1959 ENABLE_AST
1960 return(0);
1961 }
1962 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
1963 if(!servp)
1964 {
1965 ENABLE_AST
1966 return(0);
1967 }
1968 if(servp->id != (int)serv_id)
1969 {
1970 ENABLE_AST
1971 return(0);
1972 }
1973 if(secs == 0)
1974 {
1975#ifdef WIN32
1976 ftime(&timebuf);
1977 servp->user_secs = (int)timebuf.time;
1978 servp->user_millisecs = timebuf.millitm;
1979#else
1980 tz = 0;
1981 gettimeofday(&tv, tz);
1982 servp->user_secs = tv.tv_sec;
1983 servp->user_millisecs = tv.tv_usec / 1000;
1984#endif
1985 }
1986 else
1987 {
1988 servp->user_secs = secs;
1989/*
1990 servp->user_millisecs = (millisecs & 0xffff);
1991*/
1992 servp->user_millisecs = millisecs;
1993 }
1994 ENABLE_AST
1995 return(1);
1996}
1997
1998int dis_get_timestamp( unsigned serv_id, int *secs, int *millisecs )
1999{
2000 register SERVICE *servp;
2001 char str[128];
2002
2003 DISABLE_AST
2004 *secs = 0;
2005 *millisecs = 0;
2006 if(!serv_id)
2007 {
2008 sprintf(str,"Get Timestamp - Invalid service id");
2009 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
2010 ENABLE_AST
2011 return(0);
2012 }
2013 servp = (SERVICE *)id_get_ptr(serv_id, SRC_DIS);
2014 if(!servp)
2015 {
2016 ENABLE_AST
2017 return(0);
2018 }
2019 if(servp->id != (int)serv_id)
2020 {
2021 ENABLE_AST
2022 return(0);
2023 }
2024 if(servp->user_secs)
2025 {
2026 *secs = servp->user_secs;
2027 *millisecs = servp->user_millisecs;
2028 }
2029/*
2030 else
2031 {
2032 *secs = 0;
2033 *millisecs = 0;
2034 }
2035*/
2036 ENABLE_AST
2037 return(1);
2038}
2039
2040void dis_send_service(unsigned service_id, int *buffer, int size)
2041{
2042 register REQUEST *reqp, *prevp;
2043 register SERVICE *servp;
2044 static DIS_PACKET *dis_packet;
2045 static int packet_size = 0;
2046 int conn_id;
2047 char str[128];
2048
2049 DISABLE_AST
2050 if( !service_id ) {
2051 sprintf(str,"Send Service - Invalid service id");
2052 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
2053 ENABLE_AST
2054 return;
2055 }
2056 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
2057 if(!servp)
2058 {
2059 ENABLE_AST
2060 return;
2061 }
2062 if(!packet_size)
2063 {
2064 dis_packet = (DIS_PACKET *)malloc(DIS_HEADER+size);
2065 packet_size = DIS_HEADER + size;
2066 }
2067 else
2068 {
2069 if( DIS_HEADER+size > packet_size )
2070 {
2071 free(dis_packet);
2072 dis_packet = (DIS_PACKET *)malloc(DIS_HEADER+size);
2073 packet_size = DIS_HEADER+size;
2074 }
2075 }
2076 prevp = servp->request_head;
2077 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
2078 (DLL *) prevp)) )
2079 {
2080 dis_packet->service_id = htovl(reqp->service_id);
2081 memcpy(dis_packet->buffer, buffer, size);
2082 dis_packet->size = htovl(DIS_HEADER + size);
2083
2084 conn_id = reqp->conn_id;
2085 if( !dna_write_nowait(conn_id, dis_packet, size + DIS_HEADER) )
2086 {
2087 dim_print_date_time();
2088 printf(" Server Sending Service: Couldn't write to Conn %3d : Client %s@%s\n",conn_id,
2089 Net_conns[conn_id].task, Net_conns[conn_id].node);
2090 fflush(stdout);
2091 release_conn(conn_id, 1, 0);
2092 }
2093 else
2094 prevp = reqp;
2095 }
2096 ENABLE_AST
2097}
2098
2099int dis_remove_service(unsigned service_id)
2100{
2101 register REQUEST *reqp, *auxp;
2102 register SERVICE *servp;
2103 REQUEST_PTR *reqpp;
2104 int found = 0;
2105 char str[128];
2106 int release_request();
2107 int dis_hash_service_remove();
2108 DIS_DNS_CONN *dnsp;
2109 int n_services;
2110 void do_dis_stop_serving_dns(DIS_DNS_CONN *);
2111
2112 DISABLE_AST
2113 if(!service_id)
2114 {
2115 sprintf(str,"Remove Service - Invalid service id");
2116 error_handler(0, DIM_ERROR, DIMSVCINVAL, str);
2117 ENABLE_AST
2118 return(found);
2119 }
2120 servp = (SERVICE *)id_get_ptr(service_id, SRC_DIS);
2121 if(!servp)
2122 {
2123 ENABLE_AST
2124 return(found);
2125 }
2126 if(servp->id != (int)service_id)
2127 {
2128 ENABLE_AST
2129 return(found);
2130 }
2131if(Debug_on)
2132{
2133dim_print_date_time();
2134 printf("Removing service %s, delay_delete = %d\n",
2135 servp->name, servp->delay_delete);
2136}
2137 if(servp->delay_delete)
2138 {
2139 servp->to_delete = 1;
2140 ENABLE_AST
2141 return(found);
2142 }
2143 /* remove from name server */
2144
2145 dnsp = servp->dnsp;
2146 unregister_service(dnsp, servp);
2147 /* Release client requests and remove from actual clients */
2148 reqp = servp->request_head;
2149 while( (reqp = (REQUEST *) dll_get_next((DLL *)servp->request_head,
2150 (DLL *) reqp)) )
2151 {
2152 remove_service(reqp->req_id);
2153 auxp = reqp->prev;
2154 reqpp = (REQUEST_PTR *) reqp->reqpp;
2155 release_request(reqp, reqpp, 1);
2156 found = 1;
2157 reqp = auxp;
2158 }
2159 if(servp->id == (int)dnsp->dis_service_id)
2160 dnsp->dis_service_id = 0;
2161 if(servp->id == (int)dnsp->dis_client_id)
2162 dnsp->dis_client_id = 0;
2163 dis_hash_service_remove(servp);
2164 id_free(servp->id, SRC_DIS);
2165 free(servp->request_head);
2166 free(servp);
2167/*
2168 if(dnsp != Default_DNS)
2169 {
2170 dnsp->dis_n_services--;
2171 n_services = dnsp->dis_n_services;
2172 }
2173 else
2174 {
2175 Dis_n_services--;
2176 n_services = Dis_n_services;
2177 }
2178*/
2179 dnsp->dis_n_services--;
2180 n_services = dnsp->dis_n_services;
2181
2182 if(dnsp->serving)
2183 {
2184 if(n_services == 5)
2185 {
2186 if(Dis_conn_id)
2187 {
2188 dna_close(Dis_conn_id);
2189 Dis_conn_id = 0;
2190 }
2191 ENABLE_AST
2192/*
2193 dis_stop_serving();
2194*/
2195 do_dis_stop_serving_dns(dnsp);
2196 }
2197 else
2198 {
2199 ENABLE_AST
2200 }
2201 }
2202 else
2203 {
2204 ENABLE_AST
2205 }
2206 return(found);
2207}
2208
2209void do_dis_stop_serving_dns(DIS_DNS_CONN *dnsp)
2210{
2211register SERVICE *servp, *prevp;
2212void dim_stop_threads(void);
2213int dis_no_dns();
2214int hash_index, old_index;
2215extern int close_dns(long, int);
2216CLIENT *clip, *cprevp;
2217
2218 dnsp->serving = 0;
2219 dis_init();
2220/*
2221 dis_hash_service_init();
2222 prevp = 0;
2223 if(Dis_conn_id)
2224 {
2225 dna_close(Dis_conn_id);
2226 Dis_conn_id = 0;
2227 }
2228*/
2229 {
2230 DISABLE_AST
2231 if(dnsp->dns_timr_ent)
2232 {
2233 dtq_rem_entry(Dis_timer_q, dnsp->dns_timr_ent);
2234 dnsp->dns_timr_ent = NULL;
2235 }
2236 if(dnsp->dns_dis_conn_id)
2237 {
2238 dna_close(dnsp->dns_dis_conn_id);
2239 dnsp->dns_dis_conn_id = 0;
2240 }
2241 ENABLE_AST
2242 }
2243 {
2244 DISABLE_AST
2245 prevp = 0;
2246 hash_index = -1;
2247 old_index = -1;
2248 while( (servp = dis_hash_service_get_next(&hash_index, prevp, 0)) )
2249 {
2250 if(servp->dnsp == dnsp)
2251 {
2252 ENABLE_AST
2253 dis_remove_service(servp->id);
2254 {
2255 DISABLE_AST
2256 if(old_index != hash_index)
2257 prevp = 0;
2258 }
2259 }
2260 else
2261 {
2262 prevp = servp;
2263 old_index = hash_index;
2264 }
2265 }
2266 ENABLE_AST
2267 }
2268 {
2269 DISABLE_AST
2270 cprevp = Client_head;
2271 while( (clip = (CLIENT *)dll_get_next( (DLL *) Client_head,
2272 (DLL*) cprevp)) )
2273 {
2274 if(clip->dnsp != dnsp)
2275 {
2276 cprevp = clip;
2277 continue;
2278 }
2279 if( dll_empty((DLL *)clip->requestp_head) )
2280 {
2281if(Debug_on)
2282{
2283dim_print_date_time();
2284printf("Releasing conn %d, to %s@%s\n",
2285 clip->conn_id,
2286 Net_conns[clip->conn_id].task, Net_conns[clip->conn_id].node);
2287}
2288 release_conn( clip->conn_id, 0, 0);
2289 }
2290 else
2291 {
2292 cprevp = clip;
2293 }
2294 }
2295 ENABLE_AST
2296 }
2297if(Debug_on)
2298{
2299dim_print_date_time();
2300printf("Cleaning dnsp variables\n");
2301}
2302
2303 dnsp->dis_first_time = 1;
2304 dnsp->dis_n_services = 0;
2305 dnsp->dis_dns_packet.size = 0;
2306 dnsp->dis_dns_packet.src_type = 0;
2307 close_dns(dnsp->dnsid, SRC_DIS);
2308/*
2309 if(dnsp != Default_DNS)
2310 {
2311 dll_remove(dnsp);
2312 free(dnsp);
2313 }
2314*/
2315/*
2316 if(dll_empty(DNS_head))
2317*/
2318 if(dis_no_dns())
2319 dis_stop_serving();
2320}
2321
2322void dis_stop_serving_dns(long dnsid)
2323{
2324 DIS_DNS_CONN *dnsp, *dis_find_dns();
2325
2326 dnsp = dis_find_dns(dnsid);
2327 do_dis_stop_serving_dns(dnsp);
2328}
2329
2330void dis_stop_serving()
2331{
2332register SERVICE *servp, *prevp;
2333void dim_stop_threads(void);
2334int dis_find_client_conns();
2335int hash_index;
2336
2337/*
2338 if(Serving != -1)
2339*/
2340 Serving = 0;
2341 dis_init();
2342 if(Dis_conn_id)
2343 {
2344 dna_close(Dis_conn_id);
2345 Dis_conn_id = 0;
2346 }
2347/*
2348 if(Dns_dis_conn_id)
2349 {
2350 dna_close(Dns_dis_conn_id);
2351 Dns_dis_conn_id = 0;
2352 }
2353*/
2354 {
2355 DISABLE_AST
2356 prevp = 0;
2357 hash_index = -1;
2358 while( (servp = dis_hash_service_get_next(&hash_index, prevp, 0)) )
2359 {
2360 ENABLE_AST
2361 dis_remove_service(servp->id);
2362 {
2363 DISABLE_AST
2364 prevp = 0;
2365 }
2366 }
2367 ENABLE_AST
2368 }
2369/*
2370 if(Dis_conn_id)
2371 dna_close(Dis_conn_id);
2372 if(Dns_dis_conn_id)
2373 dna_close(Dns_dis_conn_id);
2374 Dns_dis_conn_id = 0;
2375*/
2376 Dis_first_time = 1;
2377/*
2378 if(Dns_timr_ent)
2379 {
2380 dtq_rem_entry(Dis_timer_q, Dns_timr_ent);
2381 Dns_timr_ent = NULL;
2382 }
2383*/
2384 dtq_delete(Dis_timer_q);
2385 Dis_timer_q = 0;
2386/*
2387 if(Serving != -1)
2388*/
2389 if(!dis_find_client_conns())
2390 dim_stop_threads();
2391}
2392
2393int dis_find_client_conns()
2394{
2395 int i;
2396 int n = 0;
2397
2398 for( i = 0; i< Curr_N_Conns; i++ )
2399 {
2400 if(Net_conns[i].channel != 0)
2401 {
2402 if(Dna_conns[i].read_ast == dis_insert_request)
2403 {
2404 dna_close(i);
2405 }
2406 else
2407 {
2408 n++;
2409 }
2410 }
2411 }
2412 return(n);
2413}
2414
2415/* find service by name */
2416SERVICE *find_service(char *name)
2417{
2418 return(dis_hash_service_exists(name));
2419}
2420
2421CLIENT *create_client(int conn_id, SERVICE *servp, int *new_client)
2422{
2423 CLIENT *clip;
2424
2425 *new_client = 0;
2426 if(!(clip = find_client(conn_id)))
2427 {
2428 /*
2429 dna_set_test_write(conn_id, 15);
2430 */
2431 clip = (CLIENT *)malloc(sizeof(CLIENT));
2432 clip->conn_id = conn_id;
2433 clip->dnsp = servp->dnsp;
2434 clip->requestp_head = (REQUEST_PTR *)malloc(sizeof(REQUEST_PTR));
2435 dll_init( (DLL *) clip->requestp_head );
2436 dll_insert_queue( (DLL *) Client_head, (DLL *) clip );
2437 *new_client = 1;
2438 }
2439 return clip;
2440}
2441
2442CLIENT *find_client(int conn_id)
2443{
2444 register CLIENT *clip;
2445
2446 clip = (CLIENT *)
2447 dll_search( (DLL *) Client_head, &conn_id, sizeof(conn_id));
2448 return(clip);
2449}
2450
2451void release_all_requests(int conn_id, CLIENT *clip)
2452{
2453 register REQUEST_PTR *reqpp, *auxp;
2454 register REQUEST *reqp;
2455 int found = 0;
2456 int release_request();
2457 DIS_DNS_CONN *dnsp;
2458
2459 DISABLE_AST;
2460 if(clip)
2461 {
2462 reqpp = clip->requestp_head;
2463 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2464 (DLL *) reqpp)) )
2465 {
2466 auxp = reqpp->prev;
2467 reqp = (REQUEST *) reqpp->reqp;
2468 release_request(reqp, reqpp, 0);
2469 found = 1;
2470 reqpp = auxp;
2471 }
2472 dnsp = clip->dnsp;
2473 dll_remove(clip);
2474 free(clip->requestp_head);
2475 free(clip);
2476 }
2477 if(found)
2478 {
2479 Last_client = -conn_id;
2480 if(dnsp->dis_client_id)
2481 dis_update_service(dnsp->dis_client_id);
2482 }
2483 dna_close(conn_id);
2484 ENABLE_AST;
2485}
2486
2487CLIENT *check_delay_delete(int conn_id)
2488{
2489 register REQUEST_PTR *reqpp;
2490 register CLIENT *clip;
2491 register REQUEST *reqp;
2492 int found = 0;
2493
2494 DISABLE_AST;
2495 clip = find_client(conn_id);
2496 if(clip)
2497 {
2498 reqpp = clip->requestp_head;
2499 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2500 (DLL *) reqpp)) )
2501 {
2502 reqp = (REQUEST *) reqpp->reqp;
2503 if(reqp->delay_delete)
2504 {
2505 reqp->to_delete = 1;
2506 found = 1;
2507 }
2508 }
2509 }
2510 ENABLE_AST;
2511 if(found)
2512 {
2513 return((CLIENT *)-1);
2514 }
2515 return(clip);
2516}
2517
2518char *dis_get_error_services()
2519{
2520 return(dis_get_client_services(Error_conn_id));
2521}
2522
2523char *dis_get_client_services(int conn_id)
2524{
2525 register REQUEST_PTR *reqpp;
2526 register CLIENT *clip;
2527 register REQUEST *reqp;
2528 register SERVICE *servp;
2529
2530 int n_services = 0;
2531 int max_size;
2532 static int curr_allocated_size = 0;
2533 static char *service_info_buffer;
2534 char *buff_ptr;
2535
2536
2537 if(!conn_id)
2538 return((char *)0);
2539 {
2540 DISABLE_AST;
2541 clip = find_client(conn_id);
2542 if(clip)
2543 {
2544 reqpp = clip->requestp_head;
2545 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2546 (DLL *) reqpp)))
2547 {
2548 n_services++;
2549 }
2550 if(!n_services)
2551 {
2552 ENABLE_AST
2553 return((char *)0);
2554 }
2555 max_size = n_services * MAX_NAME;
2556 if(!curr_allocated_size)
2557 {
2558 service_info_buffer = (char *)malloc(max_size);
2559 curr_allocated_size = max_size;
2560 }
2561 else if (max_size > curr_allocated_size)
2562 {
2563 free(service_info_buffer);
2564 service_info_buffer = (char *)malloc(max_size);
2565 curr_allocated_size = max_size;
2566 }
2567 service_info_buffer[0] = '\0';
2568 buff_ptr = service_info_buffer;
2569 reqpp = clip->requestp_head;
2570 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2571 (DLL *) reqpp)) )
2572 {
2573 reqp = (REQUEST *) reqpp->reqp;
2574 servp = reqp->service_ptr;
2575 strcat(buff_ptr, servp->name);
2576 strcat(buff_ptr, "\n");
2577 buff_ptr += strlen(buff_ptr);
2578 }
2579 }
2580 else
2581 {
2582 ENABLE_AST
2583 return((char *)0);
2584 }
2585 ENABLE_AST;
2586 }
2587/*
2588 dim_print_date_time();
2589 dna_get_node_task(conn_id, node, task);
2590 printf("Client %s@%s uses services: \n", task, node);
2591 printf("%s\n",service_info_buffer);
2592*/
2593 return(service_info_buffer);
2594}
2595
2596int find_release_request(int conn_id, int service_id)
2597{
2598 register REQUEST_PTR *reqpp, *auxp;
2599 register CLIENT *clip;
2600 register REQUEST *reqp;
2601 int release_request();
2602
2603 DISABLE_AST
2604 clip = find_client(conn_id);
2605 if(clip)
2606 {
2607 reqpp = clip->requestp_head;
2608 while( (reqpp = (REQUEST_PTR *) dll_get_next((DLL *)clip->requestp_head,
2609 (DLL *) reqpp)) )
2610 {
2611 reqp = (REQUEST *) reqpp->reqp;
2612 if(reqp->service_id == service_id)
2613 {
2614 if(reqp->delay_delete)
2615 {
2616 reqp->to_delete += 0x2;
2617 }
2618 else
2619 {
2620 auxp = reqpp->prev;
2621 release_request(reqp, reqpp, 0);
2622 reqpp = auxp;
2623 }
2624 }
2625 }
2626/* The client should close the connection (there may be commands)
2627 if( dll_empty((DLL *)clip->requestp_head) )
2628 {
2629 release_conn( conn_id, 0, 0 );
2630 }
2631*/
2632 }
2633 ENABLE_AST
2634 return(1);
2635}
2636
2637int release_request(REQUEST *reqp, REQUEST_PTR *reqpp, int remove)
2638{
2639 int conn_id;
2640 CLIENT *clip;
2641
2642 DISABLE_AST
2643 conn_id = reqp->conn_id;
2644 if(reqpp)
2645 dll_remove((DLL *)reqpp);
2646 dll_remove((DLL *)reqp);
2647 if(reqp->timr_ent)
2648 dtq_rem_entry(Dis_timer_q, reqp->timr_ent);
2649 id_free(reqp->req_id, SRC_DIS);
2650 free(reqp);
2651 if(reqpp)
2652 free(reqpp);
2653/* Would do it too early, the client will disconnect anyway
2654*/
2655 if((remove) && (Serving == 0))
2656 {
2657 clip = find_client(conn_id);
2658 if(clip)
2659 {
2660 if( dll_empty((DLL *)clip->requestp_head) )
2661 {
2662 release_conn( conn_id, 0, 0);
2663 }
2664 }
2665 }
2666
2667 ENABLE_AST
2668 return(1);
2669}
2670
2671static int release_conn(int conn_id, int print_flg, int dns_flag)
2672{
2673 static int releasing = 0;
2674 CLIENT *clip;
2675 int do_exit_handler();
2676
2677 DISABLE_AST
2678 if(print_flg){}
2679 if(dns_flag)
2680 {
2681 recv_dns_dis_rout( conn_id, 0, 0, STA_DISC );
2682 ENABLE_AST
2683 return(0);
2684 }
2685#ifdef VMS
2686 if(print_flg)
2687 {
2688 dim_print_date_time();
2689 dna_get_node_task(conn_id, node, task);
2690 printf(" Couldn't write to client %s@%s, releasing connection %d\n",
2691 task, node, conn_id);
2692 fflush(stdout);
2693 }
2694#endif
2695 clip = check_delay_delete(conn_id);
2696 if(clip != (CLIENT *)-1)
2697 {
2698 if( Client_exit_user_routine != 0 )
2699 {
2700 releasing++;
2701 Curr_conn_id = conn_id;
2702 do_exit_handler(conn_id);
2703 releasing--;
2704 }
2705 if(!releasing)
2706 {
2707 release_all_requests(conn_id, clip);
2708 }
2709 }
2710 ENABLE_AST
2711 return(1);
2712}
2713
2714typedef struct cmnds{
2715 struct cmnds *next;
2716 long tag;
2717 int size;
2718 int buffer[1];
2719} DIS_CMND;
2720
2721static DIS_CMND *Cmnds_head = (DIS_CMND *)0;
2722
2723void std_cmnd_handler(long *tag, int *cmnd_buff, int *size)
2724{
2725 register DIS_CMND *new_cmnd;
2726/* queue the command */
2727
2728 if(!Cmnds_head)
2729 {
2730 Cmnds_head = (DIS_CMND *)malloc(sizeof(DIS_CMND));
2731 sll_init((SLL *) Cmnds_head);
2732 }
2733 new_cmnd = (DIS_CMND *)malloc((*size)+12);
2734 new_cmnd->next = 0;
2735 new_cmnd->tag = *tag;
2736 new_cmnd->size = *size;
2737 memcpy(new_cmnd->buffer, cmnd_buff, *size);
2738 sll_insert_queue((SLL *) Cmnds_head, (SLL *) new_cmnd);
2739}
2740
2741int dis_get_next_cmnd(long *tag, int *buffer, int *size)
2742{
2743 register DIS_CMND *cmndp;
2744 register int ret_val = -1;
2745
2746 DISABLE_AST
2747 if(!Cmnds_head)
2748 {
2749 Cmnds_head = (DIS_CMND *)malloc(sizeof(DIS_CMND));
2750 sll_init((SLL *) Cmnds_head);
2751 }
2752 if(*size == 0)
2753 {
2754 if( (cmndp = (DIS_CMND *) sll_get_head((SLL *) Cmnds_head)))
2755 {
2756 if(cmndp->size > 0)
2757 {
2758 *size = cmndp->size;
2759 *tag = cmndp->tag;
2760 ENABLE_AST
2761 return(-1);
2762 }
2763 }
2764 }
2765 if( (cmndp = (DIS_CMND *) sll_remove_head((SLL *) Cmnds_head)) )
2766 {
2767 if (*size >= cmndp->size)
2768 {
2769 *size = cmndp->size;
2770 ret_val = 1;
2771 }
2772 memcpy(buffer, cmndp->buffer, *size);
2773 *tag = cmndp->tag;
2774 free(cmndp);
2775 ENABLE_AST
2776 return(ret_val);
2777 }
2778 ENABLE_AST
2779 return(0);
2780}
2781
2782int dis_get_conn_id()
2783{
2784 return(Curr_conn_id);
2785}
2786
2787int dis_get_client(char *name)
2788{
2789 int ret = 0;
2790 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2791
2792 DISABLE_AST
2793
2794 if(Curr_conn_id)
2795 {
2796 dna_get_node_task(Curr_conn_id, node, task);
2797 strcpy(name,task);
2798 strcat(name,"@");
2799 strcat(name,node);
2800 ret = Curr_conn_id;
2801 }
2802 ENABLE_AST
2803 return(ret);
2804}
2805
2806#ifdef VMS
2807dis_convert_str(c_str, for_str)
2808char *c_str;
2809struct dsc$descriptor_s *for_str;
2810{
2811 int i;
2812
2813 strcpy(for_str->dsc$a_pointer, c_str);
2814 for(i = strlen(c_str); i< for_str->dsc$w_length; i++)
2815 for_str->dsc$a_pointer[i] = ' ';
2816}
2817#endif
2818
2819void client_info(long *tag, int **bufp, int *size, int *first_time)
2820{
2821 register CLIENT *clip;
2822 int curr_conns[MAX_CONNS];
2823 int i, index, max_size;
2824 static int curr_allocated_size = 0;
2825 static char *dns_info_buffer;
2826 register char *dns_client_info;
2827 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2828 DIS_DNS_CONN *dnsp = (DIS_DNS_CONN *)*tag;
2829
2830 max_size = sizeof(DNS_CLIENT_INFO);
2831 if(!curr_allocated_size)
2832 {
2833 dns_info_buffer = malloc(max_size);
2834 curr_allocated_size = max_size;
2835 }
2836 dns_client_info = dns_info_buffer;
2837 dns_client_info[0] = '\0';
2838 index = 0;
2839 if(*first_time)
2840 {
2841 clip = Client_head;
2842 while( (clip = (CLIENT *)dll_get_next( (DLL *) Client_head,
2843 (DLL*) clip)) )
2844 {
2845 if(clip->dnsp != dnsp)
2846 continue;
2847 curr_conns[index++] = clip->conn_id;
2848 }
2849 max_size = (index+1)*sizeof(DNS_CLIENT_INFO);
2850 if (max_size > curr_allocated_size)
2851 {
2852 free(dns_info_buffer);
2853 dns_info_buffer = malloc(max_size);
2854 curr_allocated_size = max_size;
2855 }
2856 dns_client_info = dns_info_buffer;
2857 dns_client_info[0] = '\0';
2858 }
2859 else
2860 {
2861 if(Last_client > 0)
2862 {
2863 strcat(dns_client_info,"+");
2864 curr_conns[index++] = Last_client;
2865 }
2866 else
2867 {
2868 strcat(dns_client_info,"-");
2869 curr_conns[index++] = -Last_client;
2870 }
2871 }
2872
2873 for(i=0; i<index;i++)
2874 {
2875 dna_get_node_task(curr_conns[i], node, task);
2876 strcat(dns_client_info,task);
2877 strcat(dns_client_info,"@");
2878 strcat(dns_client_info,node);
2879 strcat(dns_client_info,"|");
2880 }
2881 if(index)
2882 dns_client_info[strlen(dns_client_info)-1] = '\0';
2883 *bufp = (int *)dns_info_buffer;
2884 *size = strlen(dns_info_buffer)+1;
2885}
2886
2887void append_service(char *service_info_buffer, SERVICE *servp)
2888{
2889 char name[MAX_NAME], *ptr;
2890
2891 if(strstr(servp->name,"/RpcIn"))
2892 {
2893 strcpy(name,servp->name);
2894 ptr = (char *)strstr(name,"/RpcIn");
2895 *ptr = 0;
2896 strcat(service_info_buffer, name);
2897 strcat(service_info_buffer, "|");
2898 if(servp->def[0])
2899 {
2900 strcat(service_info_buffer, servp->def);
2901 }
2902 strcat(name,"/RpcOut");
2903 if( (servp = find_service(name)) )
2904 {
2905 strcat(service_info_buffer, ",");
2906 if(servp->def[0])
2907 {
2908 strcat(service_info_buffer, servp->def);
2909 }
2910 }
2911 strcat(service_info_buffer, "|RPC");
2912 strcat(service_info_buffer, "\n");
2913 }
2914 else if(strstr(servp->name,"/RpcOut"))
2915 {
2916/*
2917 if(servp->def[0])
2918 {
2919 strcat(service_info_buffer, servp->def);
2920 }
2921 strcat(service_info_buffer, "|RPC");
2922 strcat(service_info_buffer, "\n");
2923
2924*/
2925 }
2926 else
2927 {
2928 strcat(service_info_buffer, servp->name);
2929 strcat(service_info_buffer, "|");
2930 if(servp->def[0])
2931 {
2932 strcat(service_info_buffer, servp->def);
2933 }
2934 strcat(service_info_buffer, "|");
2935 if(servp->type == COMMAND)
2936 {
2937 strcat(service_info_buffer, "CMD");
2938 }
2939 strcat(service_info_buffer, "\n");
2940 }
2941}
2942
2943void service_info(long *tag, int **bufp, int *size, int *first_time)
2944{
2945 register SERVICE *servp;
2946 int max_size, done = 0;
2947 static int curr_allocated_size = 0;
2948 static char *service_info_buffer;
2949 char *buff_ptr;
2950 DIS_DNS_CONN *dnsp = (DIS_DNS_CONN *)*tag;
2951 int hash_index;
2952
2953 DISABLE_AST
2954 max_size = (dnsp->dis_n_services+10) * (MAX_NAME*2 + 4);
2955 if(!curr_allocated_size)
2956 {
2957 service_info_buffer = (char *)malloc(max_size);
2958 curr_allocated_size = max_size;
2959 }
2960 else if (max_size > curr_allocated_size)
2961 {
2962 free(service_info_buffer);
2963 service_info_buffer = (char *)malloc(max_size);
2964 curr_allocated_size = max_size;
2965 }
2966 service_info_buffer[0] = '\0';
2967 buff_ptr = service_info_buffer;
2968 servp = 0;
2969 hash_index = -1;
2970 if(*first_time)
2971 {
2972 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
2973 {
2974 if(servp->dnsp != dnsp)
2975 continue;
2976 if(servp->registered)
2977 {
2978/*
2979 servp->registered = 2;
2980*/
2981 if((dnsp->updating_service_list) && (Last_n_clients > 1) &&
2982 (servp->registered == 1))
2983 continue;
2984 servp->registered = Last_n_clients+1;
2985 append_service(buff_ptr, servp);
2986 buff_ptr += strlen(buff_ptr);
2987 }
2988 }
2989 }
2990 else
2991 {
2992 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
2993 {
2994 if(servp->dnsp != dnsp)
2995 continue;
2996/*
2997 if(servp->registered == 1)
2998*/
2999 if(servp->registered == 0)
3000 {
3001 strcat(buff_ptr, "-");
3002 buff_ptr += strlen(buff_ptr);
3003 append_service(buff_ptr, servp);
3004 buff_ptr += strlen(buff_ptr);
3005 }
3006 else if(servp->registered < (Last_n_clients+1))
3007 {
3008 if(!done)
3009 {
3010 strcat(buff_ptr, "+");
3011 buff_ptr += strlen(buff_ptr);
3012 done = 1;
3013 }
3014 append_service(buff_ptr, servp);
3015 buff_ptr += strlen(buff_ptr);
3016/*
3017 servp->registered = 2;
3018*/
3019 servp->registered++;
3020 }
3021 }
3022 }
3023 *bufp = (int *)service_info_buffer;
3024 *size = buff_ptr - service_info_buffer+1;
3025 if(*size == 1)
3026 *size = -1;
3027 ENABLE_AST
3028}
3029
3030static void add_exit_handler_item(int conn_id, int tag)
3031{
3032 EXIT_H *newp;
3033
3034 DISABLE_AST
3035 if(!Exit_h_head)
3036 {
3037 Exit_h_head = (EXIT_H *)malloc(sizeof(EXIT_H));
3038 sll_init( (SLL *) Exit_h_head );
3039 }
3040 if( (newp = (EXIT_H *)sll_search((SLL *) Exit_h_head,
3041 (char *)&conn_id, 4)) )
3042 {
3043 newp->conn_id = conn_id;
3044 newp->exit_id = tag;
3045 strcpy(newp->node, Net_conns[conn_id].node);
3046 strcpy(newp->task, Net_conns[conn_id].task);
3047 }
3048 else
3049 {
3050 newp = (EXIT_H *)malloc(sizeof(EXIT_H));
3051 newp->conn_id = conn_id;
3052 newp->exit_id = tag;
3053 strcpy(newp->node, Net_conns[conn_id].node);
3054 strcpy(newp->task, Net_conns[conn_id].task);
3055 sll_insert_queue( (SLL *) Exit_h_head, (SLL *) newp );
3056 }
3057 ENABLE_AST
3058}
3059
3060static void rem_exit_handler_item(EXIT_H *exitp)
3061{
3062
3063 DISABLE_AST
3064 if(!Exit_h_head)
3065 {
3066 ENABLE_AST
3067 return;
3068 }
3069 sll_remove( (SLL *) Exit_h_head, (SLL *) exitp );
3070 free(exitp);
3071 ENABLE_AST
3072}
3073
3074static EXIT_H *find_exit_handler_item(int conn_id)
3075{
3076 EXIT_H *exitp;
3077
3078 DISABLE_AST;
3079 if(!Exit_h_head)
3080 {
3081 ENABLE_AST;
3082 return((EXIT_H *)0);
3083 }
3084 if( (exitp = (EXIT_H *) sll_search((SLL *) Exit_h_head, (char *) &conn_id, 4)) )
3085 {
3086 ENABLE_AST;
3087 return(exitp);
3088 }
3089 ENABLE_AST;
3090 return((EXIT_H *)0);
3091}
3092
3093static int check_exit_handler_item(EXIT_H *exitp, int conn_id)
3094{
3095 if( (!strcmp(exitp->node, Net_conns[conn_id].node)) &&
3096 (!strcmp(exitp->task, Net_conns[conn_id].task)))
3097 {
3098 return exitp->exit_id;
3099 }
3100 return 0;
3101}
3102
3103void add_exit_handler(int *tag, int *bufp, int *size)
3104{
3105 EXIT_H *exitp;
3106
3107 if(size){}
3108 if(tag){}
3109 if(*bufp)
3110 {
3111 add_exit_handler_item(Curr_conn_id, *bufp);
3112 }
3113 else
3114 {
3115 if((exitp = find_exit_handler_item(Curr_conn_id)))
3116 rem_exit_handler_item(exitp);
3117 }
3118}
3119
3120void dis_set_client_exit_handler(int conn_id, int tag)
3121{
3122 EXIT_H *exitp;
3123
3124 if(tag)
3125 {
3126 add_exit_handler_item(conn_id, tag);
3127 }
3128 else
3129 {
3130 if((exitp = find_exit_handler_item(conn_id)))
3131 rem_exit_handler_item(exitp);
3132 }
3133}
3134
3135
3136int do_exit_handler(int conn_id)
3137{
3138 register EXIT_H *exitp;
3139 int exit_id;
3140
3141 DISABLE_AST;
3142 if((exitp = find_exit_handler_item(conn_id)))
3143 {
3144 if((exit_id = check_exit_handler_item(exitp, conn_id)))
3145 {
3146 (Client_exit_user_routine)( &exit_id );
3147 }
3148 else
3149 {
3150 rem_exit_handler_item(exitp);
3151 }
3152 }
3153/*
3154 if(!Exit_h_head)
3155 {
3156 ENABLE_AST;
3157 return(0);
3158 }
3159 while( (exitp = (EXIT_H *) sll_search_next_remove((SLL *) Exit_h_head,
3160 0, (char *) &conn_id, 4)) )
3161 {
3162 (Client_exit_user_routine)( &exitp->exit_id );
3163 free(exitp);
3164 }
3165*/
3166 ENABLE_AST
3167 return(1);
3168}
3169
3170static void exit_handler(int *tag, int *bufp, int *size)
3171{
3172
3173 if(size){}
3174 if(tag){}
3175 if(Exit_user_routine)
3176 (Exit_user_routine)( bufp );
3177 else
3178 {
3179/*
3180 printf("%s PID %d Exiting!\n", Task_name, getpid());
3181*/
3182 exit(*bufp);
3183 }
3184}
3185
3186static void error_handler(int conn_id, int severity, int errcode, char *reason)
3187{
3188 int exit_tag, exit_code, exit_size;
3189 int last_conn_id;
3190
3191 if(Error_user_routine)
3192 {
3193 Error_conn_id = conn_id;
3194 last_conn_id = Curr_conn_id;
3195 Curr_conn_id = conn_id;
3196 (Error_user_routine)( severity, errcode, reason);
3197 Error_conn_id = 0;
3198 Curr_conn_id = last_conn_id;
3199 }
3200 else
3201 {
3202 dim_print_msg(reason, severity);
3203 }
3204 if(severity == DIM_FATAL)
3205 {
3206 exit_tag = 0;
3207 exit_code = errcode;
3208 exit_size = sizeof(int);
3209 exit_handler(&exit_tag, &exit_code, &exit_size);
3210 }
3211}
3212/*
3213#define MAX_HASH_ENTRIES 2000
3214*/
3215#define MAX_HASH_ENTRIES 5000
3216
3217static SERVICE *Service_hash_table[MAX_HASH_ENTRIES];
3218static int Service_new_entries[MAX_HASH_ENTRIES];
3219
3220int dis_hash_service_init()
3221{
3222 int i;
3223 static int done = 0;
3224
3225 if(!done)
3226 {
3227 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
3228 {
3229 Service_hash_table[i] = (SERVICE *) malloc(sizeof(SERVICE));
3230 dll_init((DLL *) Service_hash_table[i]);
3231 Service_new_entries[i] = 0;
3232 }
3233 done = 1;
3234 }
3235 return(1);
3236}
3237
3238int dis_hash_service_insert(SERVICE *servp)
3239{
3240 int index;
3241 index = HashFunction(servp->name, MAX_HASH_ENTRIES);
3242 Service_new_entries[index]++;
3243 dll_insert_queue((DLL *) Service_hash_table[index],
3244 (DLL *) servp);
3245 return(1);
3246}
3247
3248int dis_hash_service_registered(int index, SERVICE *servp)
3249{
3250 servp->registered = 1;
3251 Service_new_entries[index]--;
3252 if(Service_new_entries[index] < 0)
3253 Service_new_entries[index] = 0;
3254 return 1;
3255}
3256
3257int dis_hash_service_remove(SERVICE *servp)
3258{
3259 dll_remove( (DLL *) servp );
3260 return(1);
3261}
3262
3263
3264SERVICE *dis_hash_service_exists(char *name)
3265{
3266 int index;
3267 SERVICE *servp;
3268
3269 index = HashFunction(name, MAX_HASH_ENTRIES);
3270 if( (servp = (SERVICE *) dll_search(
3271 (DLL *) Service_hash_table[index],
3272 name, strlen(name)+1)) )
3273 {
3274 return(servp);
3275 }
3276 return((SERVICE *)0);
3277}
3278
3279SERVICE *dis_hash_service_get_next(int *curr_index, SERVICE *prevp, int new_entries)
3280{
3281 int index;
3282 SERVICE *servp = 0;
3283/*
3284 if(!prevp)
3285 {
3286 index = -1;
3287 }
3288*/
3289 index = *curr_index;
3290 if(index == -1)
3291 {
3292 index++;
3293 prevp = Service_hash_table[index];
3294 }
3295 if(!prevp)
3296 {
3297 prevp = Service_hash_table[index];
3298 }
3299 do
3300 {
3301 if((!new_entries) || (Service_new_entries[index] > 0))
3302 {
3303 servp = (SERVICE *) dll_get_next(
3304 (DLL *) Service_hash_table[index],
3305 (DLL *) prevp);
3306 if(servp)
3307 break;
3308 }
3309 index++;
3310 if(index == MAX_HASH_ENTRIES)
3311 {
3312 *curr_index = -1;
3313 return((SERVICE *) 0);
3314 }
3315 prevp = Service_hash_table[index];
3316 } while(!servp);
3317 *curr_index = index;
3318 return(servp);
3319}
3320
3321DIS_DNS_CONN *dis_find_dns(long dnsid)
3322{
3323 DIS_DNS_CONN *dnsp;
3324
3325 dnsp = (DIS_DNS_CONN *)
3326 dll_search( (DLL *) DNS_head, &dnsid, sizeof(dnsid));
3327/*
3328 if(!dnsp)
3329 {
3330 dnsp = create_dns(dnsid);
3331 }
3332*/
3333 return dnsp;
3334}
3335
3336int dis_no_dns()
3337{
3338 DIS_DNS_CONN *dnsp;
3339
3340 dnsp = (DIS_DNS_CONN *) DNS_head;
3341 while ( (dnsp = (DIS_DNS_CONN *) dll_get_next( (DLL *) DNS_head, (DLL *) dnsp)))
3342 {
3343/*
3344 if(dnsp != Default_DNS)
3345 return 0;
3346*/
3347 if(dnsp->serving)
3348 return 0;
3349 }
3350 return 1;
3351}
3352
3353DIS_DNS_CONN *find_dns_by_conn_id(int conn_id)
3354{
3355 DIS_DNS_CONN *dnsp;
3356 extern long dns_get_dnsid();
3357 long dnsid;
3358
3359 dnsid = dns_get_dnsid(conn_id, SRC_DIS);
3360 dnsp = dis_find_dns(dnsid);
3361 if(!dnsp)
3362 dnsp = Default_DNS;
3363 return (DIS_DNS_CONN *)dnsp;
3364}
3365
3366void dis_print_hash_table()
3367{
3368 SERVICE *servp;
3369 int i;
3370 int n_entries, max_entry_index = 0;
3371 int max_entries = 0;
3372
3373 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
3374 {
3375 n_entries = 0;
3376 servp = Service_hash_table[i];
3377 while( (servp = (SERVICE *) dll_get_next(
3378 (DLL *) Service_hash_table[i],
3379 (DLL *) servp)) )
3380 {
3381 n_entries++;
3382 if(n_entries == 1)
3383 printf(" Name = %s\n",servp->name);
3384 }
3385 if(n_entries != 0)
3386 printf("HASH[%d] - %d entries\n", i, n_entries);
3387 if(n_entries > max_entries)
3388 {
3389 max_entries = n_entries;
3390 max_entry_index = i;
3391 }
3392 }
3393 printf("Maximum : HASH[%d] - %d entries\n", max_entry_index, max_entries);
3394 fflush(stdout);
3395}
3396
3397void dis_hash_print()
3398{
3399 SERVICE *servp;
3400 int hash_index;
3401
3402 servp = 0;
3403 hash_index = -1;
3404 while( (servp = dis_hash_service_get_next(&hash_index, servp, 0)) )
3405 {
3406 printf("Name = %s\n",servp->name);
3407 }
3408}
3409
3410#ifdef VMS
3411/* CFORTRAN WRAPPERS */
3412FCALLSCFUN1(INT, dis_start_serving, DIS_START_SERVING, dis_start_serving,
3413 STRING)
3414FCALLSCFUN3(INT, dis_get_next_cmnd, DIS_GET_NEXT_CMND, dis_get_next_cmnd,
3415 PINT, PVOID, PINT)
3416FCALLSCFUN1(INT, dis_get_client, DIS_GET_CLIENT, dis_get_client,
3417 PSTRING)
3418FCALLSCFUN6(INT, dis_add_service, DIS_ADD_SERVICE, dis_add_service,
3419 STRING, PVOID, PVOID, INT, PVOID, INT)
3420FCALLSCSUB4( dis_add_cmnd, DIS_ADD_CMND, dis_add_cmnd,
3421 STRING, PVOID, PVOID, INT)
3422FCALLSCSUB1( dis_add_client_exit_handler, DIS_ADD_CLIENT_EXIT_HANDLER,
3423 dis_add_client_exit_handler,
3424 PVOID)
3425FCALLSCSUB2( dis_set_client_exit_handler, DIS_SET_CLIENT_EXIT_HANDLER,
3426 dis_set_client_exit_handler,
3427 INT, INT)
3428FCALLSCSUB1( dis_add_exit_handler, DIS_ADD_EXIT_HANDLER,
3429 dis_add_exit_handler,
3430 PVOID)
3431FCALLSCSUB1( dis_report_service, DIS_REPORT_SERVICE, dis_report_service,
3432 STRING)
3433FCALLSCSUB2( dis_convert_str, DIS_CONVERT_STR, dis_convert_str,
3434 PVOID, PVOID)
3435FCALLSCFUN1(INT, dis_update_service, DIS_UPDATE_SERVICE, dis_update_service,
3436 INT)
3437FCALLSCFUN1(INT, dis_remove_service, DIS_REMOVE_SERVICE, dis_remove_service,
3438 INT)
3439FCALLSCSUB3( dis_send_service, DIS_SEND_SERVICE, dis_send_service,
3440 INT, PVOID, INT)
3441FCALLSCSUB2( dis_set_quality, DIS_SET_QUALITY, dis_set_quality,
3442 INT, INT)
3443FCALLSCSUB3(INT, dis_set_timestamp, DIS_SET_TIMESTAMP, dis_set_timestamp,
3444 INT, INT, INT)
3445FCALLSCFUN2(INT, dis_selective_update_service, DIS_SELECTIVE_UPDATE_SERVICE,
3446 dis_selective_update_service,
3447 INT, PINT)
3448FCALLSCSUB3(INT, dis_get_timestamp, DIS_GET_TIMESTAMP, dis_get_timestamp,
3449 INT, PINT, PINT)
3450#endif
Note: See TracBrowser for help on using the repository browser.