/*********************************************************** * AOP Interpreter Communication Code * ************************************************************ * Description: * * * * Created by: avrami tzur * * At: Mon Aug 24 11:14:11 1992 * ***********************************************************/ /* INCLUDES */ # include "structures.h" # include "AOPcomm.h" # include "network.h" # include # include extern errno; /* DECLARATIONS */ int initInterpreterCommunication(char *user_name, int start_window); int registerPipe(int pipe_id, pipe_callback_function func ); int unregisterPipe(int pipe_id); void getInterpreterEvent(); full_address *resolveAgentAddress(char *agent_alias); static void sigio_func(int signal_num); static void processIO(); static void ErrSys(char *msg); static void readNetMessage(int socket_num); static void loadAliasTable(); static pipe_callback_struct * pipe_list[MAX_PIPES_NUM]; static int pipe_mask; static int sigflag=0; static int sig_num = -1; /* INTERNAL STRUCTURES */ typedef struct { char alias[ALIAS_NAME_SIZE]; char user[USER_NAME_SIZE]; char machine[MACHINE_NAME_SIZE]; } alias_to_user; static int alias_counter = 0; static alias_to_user *alias_table[100]; /* ============================================================ | initInterpreterCommunication() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | |==========================================================| */ int initInterpreterCommunication(char *user_name, int start_window) { int i; int socket_num; /* Initilize the internal structures. */ /* 1. The pipe list. */ for(i=0; idata); a=parse_interactive_input(msg->data)->head; /* Check if I have an alias for the sender. */ i=0; while(iuser,msg->header.from_user)==0&& strcasecmp(alias_table[i]->machine,msg->header.from_machine)==0){ /* Found it. */ break; } else i++; } if(i header.from_agent)+1+ strlen(alias_table[i]->alias)+1); sprintf(full_name, "%s@%s", msg->header.from_agent, alias_table[i]->alias); printf("The alias name is; %s\n",full_name); } else { /* Create the sender full name. */ full_name = (char *)malloc(strlen(msg->header.from_agent)+1+ strlen(msg->header.from_user)+1+ strlen(msg->header.from_machine)+1); sprintf(full_name, "%s@%s@%s", msg->header.from_agent, msg->header.from_user, msg->header.from_machine); printf("The full name is; %s\n",full_name); } from_a = lookup_term(full_name); to_a = functor_string(a->argument_array[0]->const_string); if(to_a != -1) { send_message(a->functor, to_a, from_a, a->argument_array[1]); } free(full_name); free(msg->data); free(msg); } } /* ============================================================ | getInterpreterEvent() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | |==========================================================| */ void getInterpreterEvent() { int fdmask, ret, i ; struct timeval timeout; /* Set the time out. */ timeout.tv_sec = 300; timeout.tv_usec = 0; fdmask = pipe_mask; signal(SIGALRM, sigio_func); ret = select(32, &fdmask, NULL, NULL, &timeout); if (ret == -1){ if(errno != EINTR) ErrSys("select error on events"); else printf("Alarm went off\n"); } else { if (ret == 0){ /* No events on pipes. */ printf("No events on pipes.\n"); } else { /* Find out which of the pipe is ready. */ for(i=0; ifunc)(i); } } } } } } /* ============================================================ | sigio_func() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | |==========================================================| */ static void sigio_func(int signal_num) { sigflag = 1; sig_num = signal_num; } /* ============================================================ | registerPipe() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | |==========================================================| */ int registerPipe(int pipe_id, pipe_callback_function func ) { /* Check that it is a valid pipe id. */ if((pipe_id >= MAX_PIPES_NUM ) || (pipe_id < 0)) return(-1); /* Check if the pipe is used. */ if(pipe_list[pipe_id] != NULL) return(-1); /* Set the pipe parameters. */ /*if(fcntl(pipe_id,F_SETOWN, getpid()) < 0) return(-1); if(fcntl(pipe_id,F_SETFL, FASYNC) < 0) return(-1); */ /* Register the pipe. */ /* 1. Allocate memory. */ printf("Registering the pipe: %d\n", pipe_id); pipe_list[pipe_id] = (pipe_callback_struct *)malloc(sizeof(pipe_callback_struct)); /* 2. Assign the callback function pointer. */ pipe_list[pipe_id]->func = func; /* 3. Add the pipe to the tracked pipes mask. */ printf("Before %d pipe num %d", pipe_mask, pipe_id); pipe_mask = pipe_mask | (1 << pipe_id); printf("After %d ", pipe_mask); return(1); } /* ============================================================ | unregisterPipe() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | |==========================================================| */ int unregisterPipe(int pipe_id) { /* Check that it is a valid pipe id. */ if((pipe_id >= MAX_PIPES_NUM ) || (pipe_id < 0)) return(-1); /* Check if the pipe is used. */ if(pipe_list[pipe_id] != NULL) { /* Pipe is used. */ /* 1. Free the memory. */ free(pipe_list[pipe_id]); /* 2. Remove the pipe from the mask. */ pipe_mask = pipe_mask ^ (1 << pipe_id); } return(1); } /* ============================================================ | ErrSys() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | |==========================================================| */ static void ErrSys(char *msg) { printf("Error: %s\n", msg); } /* ============================================================ | loadAliasTable() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | |==========================================================| */ static void loadAliasTable() { FILE *stream; struct stat dir_status; char *file_name = ".AOPalias"; alias_to_user *temp; if(stat(file_name,&dir_status) == -1){ /* No alias file. */ alias_counter = 0; } else { /* Open the file. */ if ((stream = fopen(file_name, "r")) == NULL) { ErrSys("Unable to open alias file."); } alias_counter = 0; while(!feof(stream)){ temp = (alias_to_user *)malloc(sizeof(alias_to_user)); fscanf(stream, "%s %s %s\n",temp->alias, temp->user, temp->machine); alias_table[alias_counter++] = temp; } fclose(stream); } } /* ============================================================ | resolveAgentAddress() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | |==========================================================| */ full_address *resolveAgentAddress(char *agent_alias) { full_address *ret = NULL; char *temp1, *temp2; int i; /* Parse the agent name. Agnet name can have two forms: 1. agent_name@user_name - in this case we look at the alias table for the user login name and the user machine. 2. agent_name@user_name@machine_name - in this case the user_name is the user login name and the machine_name is the user machine name. */ ret = (full_address *)malloc(sizeof(full_address)); ret->agent = (char *)malloc(strlen(agent_alias)+1); strcpy(ret->agent,agent_alias); temp1 = strchr(ret->agent, (int)'@'); if(temp1 == NULL) { /* Not a legal agent alias. */ free(ret->agent); free(ret); return(NULL); } else { /* Replace '@' with '\0' */ *(temp1++) = '\0'; /* Check if it is an alias or complete address. */ temp2 = strchr(temp1, (int)'@'); if(temp2 == NULL) { /* Look in the alias table. */ i=0; while(ialias, temp1)){ /* Found it. */ break; } else i++; } if(i user = alias_table[i]->user; ret->machine = alias_table[i]->machine; printf("Found the alias %s %s %s %s\n", agent_alias, ret->agent, ret->user, ret->machine); return(ret); } else { printf("Can not find %s\n",agent_alias); free(ret->agent); free(ret); return(NULL); } } else { /* It is a complete address. */ /* Replace '@' with '\0' */ *(temp2++) = '\0'; ret->user = temp1; ret->machine = temp2; return(ret); } } }