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

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