Example #1
0
void do_daemon() {
/* do_leap
 * Main LEAP daemon routine - Contains socket handler
 */
	char buffer[MAXIMUM_INPUT_STRING+1];
	char loginname[MAXIMUM_INPUT_STRING+1];
	char password[MAXIMUM_INPUT_STRING+1];
	char maincommand[MAXIMUM_INPUT_STRING+1];
	char tprompt[MAXIMUM_INPUT_STRING+1];
	char *result,*tresult,*plogin,*ppass;
	relation result_relation;
	int res,startscript=0;
	int serverSocket=0, on=0, port=0, status=0, childPid=0;
	struct hostent *hostPtr=NULL;
	char hostname[80]="";
	struct sockaddr_in serverName={0},clientName={0};
	struct linger linger={0};
	struct utsname sysinfo;
	int clientLength;
	tuple ctuple;

	clientLength=sizeof(clientName);

	tempdb=LEAPAPI_db_create(NULL,TEMPDB_NAME);
	res=relations_ddopen(tempdb);
	if (res!=RETURN_SUCCESS) {
		raise_error(ERROR_OPEN_DATABASE,FATAL,TEMPDB_NAME);		
	}

	/* Open the master database */
	master_db=LEAPAPI_db_create(NULL,MASTER_DB_NAME);
	res=relations_ddopen(master_db);
	if (res!=RETURN_SUCCESS) {
		raise_error(ERROR_OPEN_DATABASE,FATAL,MASTER_DB_NAME);		
	}

	if (strlen(dbtoopen)==0) {
		/* Open up the default user database */
		current_db=LEAPAPI_db_create(NULL,DEFAULT_DB);
	} else {
		current_db=LEAPAPI_db_create(NULL,dbtoopen);
	}

	res=relations_ddopen(current_db);
	if (res!=RETURN_SUCCESS) {
		raise_error(ERROR_OPEN_DATABASE,FATAL,database_name(current_db));		
	}
	
	set_variable(VAR_CURRENTDB,database_name(current_db));

	/* Check to see if the logins relation exists */
	result_relation=relation_find(master_db,LEAP_DD_LOGINS);	

	if (result_relation==NULL) {
		raise_error(ERROR_CANNOT_FIND_REL,NONFATAL,LEAP_DD_LOGINS);
		raise_message(MESSAGE,"Building %s",LEAP_DD_LOGINS);

        /* Build the leaplogins relation */
        sprintf(buffer,"(SUID,INTEGER,3),(NAME,string,25),(PASSWORD,string,25),(DEFAULTDB,string,25)");
        relation_insert(master_db,create_user_relation(master_db,buffer,LEAP_DD_LOGINS,FALSE,TRUE));

        vprocess_query(master_db,"add (%s) (%d,%s,%s,%s)",LEAP_DD_LOGINS,LEAP_SUID_DBA,LEAP_LOGIN_DBA,LEAP_PASS_DBA,MASTER_DB_NAME);
	} else {
		raise_message(MESSAGE,"Found %s!",LEAP_DD_LOGINS);
	}


	if (status_quiet!=TRUE) {
		raise_message(MESSAGE,"%s","Startup sequence initiated.");
	}

	terminate=FALSE;
	terminatenow=FALSE;

	if (status_quiet) {
			strcpy(current_prompt,"");
			set_prompt("");
	} else {
			strcpy(current_prompt,DEFAULT_PROMPT);
			set_prompt(DEFAULT_PROMPT);
	}

	if (configuration!=TRUE) {
		raise_message(MESSAGE,"Sourcing %s%s in %s",LEAP_STARTUP,LEAP_SOURCE_EXT,database_name(master_db));
		sprintf(buffer,"%s%s%s%s",database_dir(master_db),LEAP_SOURCE_DIR,LEAP_STARTUP,LEAP_SOURCE_EXT);
		assign_input_stream(buffer);
	} else {
		sprintf(buffer,"%s",configurationfile);
		assign_input_stream(buffer);
	}


	serverSocket=socket(PF_INET,SOCK_STREAM,0);

	if (serverSocket==-1) {
		raise_error(ERROR_SOCKETINIT,FATAL,"socket()");
	}

	on=1;

	status=setsockopt(serverSocket,SOL_SOCKET,SO_REUSEADDR,(const char *) &on,sizeof(on));

	if (status==-1) {
		raise_error(ERROR_SOCKETINIT,FATAL,"setsockopt(...,SO_REUSEADDR,...)");
	}
	
	linger.l_onoff=1;
	linger.l_linger=30;
	status=setsockopt(serverSocket,SOL_SOCKET,SO_LINGER,(const char *) &linger,sizeof(linger));
	if (status==-1) {
		raise_error(ERROR_SOCKETINIT,FATAL,"setsockopt(...,SO_LINGER,...)");
	}
		
	status=uname(&sysinfo);
	if (status==-1) {
		raise_error(ERROR_SOCKETINIT,FATAL,"uname");
	} else {
		strncpy(hostname,sysinfo.nodename,sizeof(hostname));
	}
		
	status=gethostname(hostname,sizeof(hostname));
	hostPtr=gethostbyname(hostname);

	if (hostPtr==NULL) {
		raise_error(ERROR_SOCKETINIT,FATAL,"gethostbyname");
	} 
	
	(void) memset(&serverName,0,sizeof(serverName));
	(void) memcpy(&serverName.sin_addr,hostPtr->h_addr,hostPtr->h_length);
	
	serverName.sin_family=AF_INET;
	serverName.sin_port=htons(LEAPD_PORT);
	status=bind(serverSocket,(struct sockaddr *) &serverName,sizeof(serverName));

	if (status<0) {
		raise_error(ERROR_SOCKETINIT,FATAL,"bind() - port %u - errno %u",LEAPD_PORT,errno);
	} else {
		raise_message(MESSAGE,"Daemon starting on machine %s, port %u",hostname,LEAPD_PORT);
	}

	status=listen(serverSocket,LEAPD_BACK_LOG);
	if (status==-1) {
		raise_error(ERROR_SOCKETINIT,FATAL,"listen()");
	}


	while (!terminatenow) {
			slaveSocket=accept(serverSocket,(struct sockaddr *) &clientName,&clientLength);

			if (slaveSocket==-1) {
				raise_error(ERROR_SOCKETINIT,FATAL,"accept()");
			}
				
			raise_message(MESSAGE,"Connection received from [%s]",inet_ntoa(clientName.sin_addr));

			raise_message(MESSAGE,"Authenication expected");

			strcpy(buffer,"Please authenticate yourself: ");
			write(slaveSocket,buffer,strlen(buffer));

			read(slaveSocket,loginname,MAXIMUM_INPUT_STRING);
			plogin=strtok(loginname,"\r\n");
			raise_message(MESSAGE,"Login [%s] connecting...",plogin);

			if (strcmp(plogin,"guest")==0) {
				strcpy(buffer,"Enter your e-mail address: ");
				write(slaveSocket,buffer,strlen(buffer));
			} else {
				strcpy(buffer,"Password: "******"project (select (%s) (%s='%s')) (%s)",LEAP_DD_LOGINS,LEAP_DDA_LOGINS_NAME,plogin,LEAP_DDA_LOGINS_PASSWORD);
			result_relation=process_query(master_db,buffer);

			status=read(slaveSocket,password,MAXIMUM_INPUT_STRING);
			ppass=strtok(password,"\r\n");

			if ((ppass!=NULL) && (status==2)) {
				*ppass='******';
			}

			ctuple=tuple_readfirst(result_relation,TUPLE_BUILD,NULL);
			if (ctuple!=NULL) {
				tuple_to_string(ctuple,buffer);
				raise_message(MESSAGE,"Password expected [%s]",buffer);
				raise_message(MESSAGE,"Password received [%s]",ppass);
			} else {
				if (strcmp(plogin,"guest")==0) {
					raise_message(MESSAGE,"Guest ID [%s]",ppass);
				} else {
					raise_message(MESSAGE,"No login [%s] exists!",plogin);
				}
			}
	
			if (((strcmp(plogin,"guest")==0))||(strcmp(buffer,ppass)==0)) {
					raise_message(MESSAGE,"Login [%s] validated!",plogin); 
					/* Enable daemon on - this will send io to client */
					status_daemon=TRUE;
				
					strcpy(buffer,"version");
					result_relation=process_query(current_db,buffer);

					/* Ok, socket is initialised! */
					while (!terminate) {

						write(slaveSocket,DEFAULT_PROMPT,sizeof(DEFAULT_PROMPT));
						status=read(slaveSocket,buffer,MAXIMUM_INPUT_STRING);
						/* Null terminate reqd....*/
						
						result=strtok(buffer,"\r\n");
						
						status_daemon=FALSE;
						raise_message(MESSAGE,"received: %s",result);
						status_daemon=TRUE;

						result_relation=process_query(current_db,result);

					}
					/* Disable daemon */
					status_daemon=FALSE;
			} else {
				raise_message(MESSAGE,"Invalid password for login [%s]",plogin);
			}

			/* Reset terminate - one client has disconnected */
			terminate=FALSE;

			raise_message(MESSAGE,"Connection closed");
			close(slaveSocket);
	}

	if (!status_quiet) { raise_message(MESSAGE,"Closing [%s] database.",database_name(current_db)); }
	
	relations_dispose_all(current_db);

	LEAPAPI_db_destroy(&current_db);

	raise_event(EVENT,"[current_db] closed.");

	if (!status_quiet) { raise_message(MESSAGE,"Closing [%s] database.",database_name(master_db)); }

	relations_dispose_all(master_db);
	
	LEAPAPI_db_destroy(&master_db);

	raise_event(EVENT,"[master_db] closed.");

	if (!status_quiet) { raise_message(MESSAGE,"Closing [%s] database.",database_name(tempdb)); }

	relations_dispose_all(tempdb);
	
	LEAPAPI_db_destroy(&tempdb);

	raise_event(EVENT,"[tempdb] closed.");
}
Example #2
0
void relations_convert_open(database db) {
/* relations_open
 * Load all of the relations in the specified database
 */
	boolean masterdb;
	DIR *directory;
	char dirpath[FILE_PATH_SIZE+1];
	char newdir[FILE_PATH_SIZE+1],ddname[FILE_PATH_SIZE+1];
	mode_t mode;
	tuple nt;
	relation ddrel;
	struct dirent *d;
	relation rel;

	masterdb=(strcmp(database_name(db),MASTER_DB_NAME)==0);

	leap_fprintf(stdout,"Converting database [%s] ",database_name(db));
	if (masterdb==TRUE) {
		leap_printf("(Master Database)\n");
	} else {
		leap_printf("(User Database)\n");
	}

	sprintf(dirpath,"%s%s",database_dir(db),LEAP_RELATION_DIR);
	directory=opendir(dirpath);
		
		if (directory!=NULL) {

			/* Create a backup directory for the old format
			 * relations.
			 */

			mode=sprintf(newdir,"%soldfmt",dirpath);
			mkdir(newdir,0777);
		
			d=readdir(directory);

			while (d!=NULL) {

#ifdef __MSDOS__
				/* See comment in util.c for list_source
				 * DOS filenames are always in capitals.
				 */
				downcase(d->d_name);
#endif

					if (strstr(d->d_name,LEAP_RELATION_EXT)!=NULL) {
						/* Read the relation from the disk */
						rel=relation_read(dirpath,d->d_name);
						/* Insert the relation into the database */
						relation_insert(db,rel);
					}

					d=readdir(directory);
				}		

			/* Close the directory */
			closedir(directory);
	}

	leap_fprintf(stdout,"Completed conversion of [%s]\n",database_name(db));
	
	leap_fprintf(stdout,"Updating [%s]...",LEAP_DD_RELATIONS);
	fflush(stdout);

	/* Open the leaprel database */
	sprintf(dirpath,"%s%s",database_dir(db),LEAP_RELATION_DIR);
	sprintf(ddname,"%s%s",LEAP_DD_RELATIONS,LEAP_NEW_RELATION_EXT);
	ddrel=relation_new_read(dirpath,ddname);

	/* Did the relation get returned? */
	if (ddrel!=NULL) {
	
		/* Prepare a tuple */
		nt=tuple_prepare(ddrel);
		
		/* Find the first relation in the database */
		rel=relation_findfirst(db);
		
		/* Whilst a relation is being returned */
		while( (rel!=NULL) && (strlen(relation_name(rel))>=0) ){

			/* TODO: Why does the relation name sometimes have nothing in it? */
		
			/* Populate the output tuple */
			
			/* Relation name */
			strcpy( tuple_d(nt,LEAP_DDA_RELATIONS_NAME_NO),relation_name(rel));
			
			/* Relation filename */
			sprintf(tuple_d(nt,LEAP_DDA_RELATIONS_FNAME_NO), "%s%s", relation_name(rel), LEAP_NEW_RELATION_EXT);
			
			/* Temporary status */
			if ( relation_temporary(rel) ) {
				strcpy( tuple_d(nt,LEAP_DDA_RELATIONS_TEMP_NO),TRUE_STRING);
			} else {
				strcpy( tuple_d(nt,LEAP_DDA_RELATIONS_TEMP_NO),FALSE_STRING);
			}

			/* Noattributes status */
			strcpy( tuple_d(nt,LEAP_DDA_RELATIONS_NOATTRIBS_NO),"1");
			
			/* Updated status */
			strcpy( tuple_d(nt,LEAP_DDA_RELATIONS_UPDATED_NO),FALSE_STRING);
			
			/* System relation status */			
			if ( relation_system(rel) ) {
				strcpy( tuple_d(nt,LEAP_DDA_RELATIONS_SYSTEM_NO),TRUE_STRING);
			} else {
				strcpy( tuple_d(nt,LEAP_DDA_RELATIONS_SYSTEM_NO),FALSE_STRING);
			}
		
			/* Write the tuple */
			(void)tuple_append(nt);
	
			/* Read the next relation */
			rel=relation_findnext(rel);
		}
		
		/* Dispose of the output tuple */
		tuple_dispose(&nt);
	} else {
		leap_fprintf(stderr,"\nERROR: System relation [%s] does not exist. See release NOTES\nin base directory!\n",
			LEAP_DD_RELATIONS);
		exit(1);
	}
	
	leap_fprintf(stdout,"Completed conversion.\n");
}
Example #3
0
static db_result_t
aql_execute(db_handle_t *handle, aql_adt_t *adt)
{
  uint8_t optype;
  int first_rel_arg;
  db_result_t result;
  relation_t *rel;
  aql_attribute_t *attr;
  attribute_t *relattr;

  optype = AQL_GET_TYPE(adt);
  if(optype == AQL_TYPE_NONE) {
    /* No-ops always succeed. These can be generated by
       empty lines or comments in the query language. */
    return DB_OK;
  }

  /* If the ASSIGN flag is set, the first relation in the array is
     the desired result relation. */
  first_rel_arg = !!(adt->flags & AQL_FLAG_ASSIGN);

  if(optype != AQL_TYPE_CREATE_RELATION &&
     optype != AQL_TYPE_REMOVE_RELATION &&
     optype != AQL_TYPE_JOIN) {
    rel = relation_load(adt->relations[first_rel_arg]);
    if(rel == NULL) {
      return DB_NAME_ERROR;
    }
  } else {
    rel = NULL;
  }

  result = DB_RELATIONAL_ERROR;
  switch(optype) {
  case AQL_TYPE_CREATE_ATTRIBUTE:
    attr = &adt->attributes[0];
    if(relation_attribute_add(rel, DB_STORAGE, attr->name, attr->domain, 
       attr->element_size) != NULL) {
      result = DB_OK;
    }
    break;
  case AQL_TYPE_CREATE_INDEX:
    relattr = relation_attribute_get(rel, adt->attributes[0].name);
    if(relattr == NULL) {
      result = DB_NAME_ERROR;
      break;
    }
    result = index_create(AQL_GET_INDEX_TYPE(adt), rel, relattr);
    break;
  case AQL_TYPE_CREATE_RELATION:
    if(relation_create(adt->relations[0], DB_STORAGE) != NULL) {
      result = DB_OK;
    }
    break;
  case AQL_TYPE_REMOVE_ATTRIBUTE:
    result = relation_attribute_remove(rel, adt->attributes[0].name);
    break;
  case AQL_TYPE_REMOVE_INDEX:
    relattr = relation_attribute_get(rel, adt->attributes[0].name);
    if(relattr != NULL) {
      if(relattr->index != NULL) {
        result = index_destroy(relattr->index);
      } else {
        result = DB_OK;
      }
    } else {
      result = DB_NAME_ERROR;
    }
    break;
  case AQL_TYPE_REMOVE_RELATION:
    result = relation_remove(adt->relations[0], 1);
    break;
#if DB_FEATURE_REMOVE
  case AQL_TYPE_REMOVE_TUPLES:
     /* Overwrite the attribute array with a full copy of the original 
        relation's attributes. */
    adt->attribute_count = 0;
    for(relattr = list_head(rel->attributes);
        relattr != NULL;
        relattr = relattr->next) {
      AQL_ADD_ATTRIBUTE(adt, relattr->name, DOMAIN_UNSPECIFIED, 0);
    }
    AQL_SET_FLAG(adt, AQL_FLAG_INVERSE_LOGIC);
#endif /* DB_FEATURE_REMOVE */
  case AQL_TYPE_SELECT:
    if(handle == NULL) {
      result = DB_ARGUMENT_ERROR;
      break;
    }
    result = relation_select(handle, rel, adt);
    break;
  case AQL_TYPE_INSERT:
    result = relation_insert(rel, adt->values);
    break;
#if DB_FEATURE_JOIN
  case AQL_TYPE_JOIN:
    if(handle == NULL) {
      result = DB_ARGUMENT_ERROR;
      break;
    }
    handle->left_rel = relation_load(adt->relations[first_rel_arg]);
    if(handle->left_rel == NULL) {
      break;
    }
    handle->right_rel = relation_load(adt->relations[first_rel_arg + 1]);
    if(handle->right_rel == NULL) {
      relation_release(handle->left_rel);
      break;
    }
    result = relation_join(handle, adt);
    break;
#endif /* DB_FEATURE_JOIN */
  default:
    break;
  }

  if(rel != NULL) {
    if(handle == NULL || !(handle->flags & DB_HANDLE_FLAG_PROCESSING)) {
      relation_release(rel);
    }
  }

  return result;
}