/* File: orient_xsb.c - find out where xsb stuff is ** Author(s): kifer ** Contact: xsb-contact@cs.sunysb.edu ** ** Copyright (C) The Research Foundation of SUNY, 1998 ** ** XSB is free software; you can redistribute it and/or modify it under the ** terms of the GNU Library General Public License as published by the Free ** Software Foundation; either version 2 of the License, or (at your option) ** any later version. ** ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ** FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for ** more details. ** ** You should have received a copy of the GNU Library General Public License ** along with XSB; if not, write to the Free Software Foundation, ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: orient_xsb.c,v 1.13.4.1 2003/06/25 16:40:20 lfcastro Exp $ ** */ #include "xsb_config.h" #ifdef WIN_NT #include #include #else #include #endif #include #include #include #include #include #include #include /* wind2unix.h must be included after sys/stat.h */ #include "wind2unix.h" #include "export.h" #include "basicdefs.h" #include "basictypes.h" #include "cell_xsb.h" #include "error_xsb.h" #include "extensions_xsb.h" char executable[MAXPATHLEN] = {'\0'}; /* This is set to a real name below */ char *install_dir; /* installation directory */ char *xsb_config_file; /* XSB configuration file */ char *user_home; /* the user $HOME dir or install dir, if $HOME is null */ extern xsbBool is_absolute_filename(char *); DllExport extern char * call_conv strip_names_from_path(char*, int); static void check_create_dir(char *); extern void transform_cygwin_pathname(char *); char current_dir[MAXPATHLEN]; char xsbinfo_dir[MAXPATHLEN]; void set_xsbinfo_dir () { struct stat *fileinfo = malloc(1*sizeof(struct stat)); char old_xinitrc[MAXPATHLEN], new_xinitrc[MAXPATHLEN], user_config_dir[MAXPATHLEN], user_arch_dir[MAXPATHLEN]; int retcode; if (!fileinfo) { xsb_abort("No core memory to allocate stat structure.\n"); } sprintf(xsbinfo_dir, "%s%c.xsb", user_home, SLASH); sprintf(old_xinitrc, "%s%c.xsbrc", user_home, SLASH); sprintf(new_xinitrc, "%s%cxsbrc", xsbinfo_dir, SLASH); sprintf(user_config_dir, "%s%cconfig", xsbinfo_dir, SLASH); sprintf(user_arch_dir, "%s%c%s", user_config_dir, SLASH, FULL_CONFIG_NAME); /* Create USER_HOME/.xsb directory, if it doesn't exist. */ check_create_dir(xsbinfo_dir); check_create_dir(user_config_dir); check_create_dir(user_arch_dir); retcode = stat(old_xinitrc, fileinfo); if ((retcode == 0) && (stat(new_xinitrc, fileinfo) != 0)) { xsb_warn("It appears that you have an old-style `.xsbrc' file!\n The XSB initialization file is now %s.\n If your `.xinitrc' defines the `library_directory' predicate,\n please consult the XSB manual for the new conventions.", new_xinitrc); } free(fileinfo); } /* Check if PATH exists. Create if it doesn't. Bark if it can't create or if PATH exists, but isn't a directory. */ static void check_create_dir(char *path) { struct stat *fileinfo = malloc(1*sizeof(struct stat)); int retcode = stat(path, fileinfo); if (!fileinfo) { xsb_abort("No core memory to allocate stat structure.\n"); } if (retcode == 0 && ! S_ISDIR(fileinfo->st_mode)) { xsb_warn("File `%s' is not a directory!\n XSB uses this directory to store data.", path); /* exit(1); */ } if (retcode != 0) #ifdef WIN_NT retcode = mkdir(path); #else retcode = mkdir(path, 0755); #endif if (retcode != 0) { xsb_warn("Cannot create directory `%s'!\n XSB uses this directory to store data.", path); /* exit(1); */ } free(fileinfo); } /* uses the global executable var */ char *xsb_executable_full_path(char *myname) { struct stat fileinfo; char *path = getenv("PATH"); int len, found = 0; char *pathcounter, save; static char myname_augmented[MAXPATHLEN]; #ifndef WIN_NT int link_len; #endif #ifndef WIN_NT #ifndef SIMPLESCALAR /* Unix */ /* if we can read symlink, then it is a symlink */ if ( (link_len = readlink(myname, myname_augmented, MAXPATHLEN)) > 0 ) { /* we can't assume that the value of the link is null-terminated */ if ( *(myname_augmented+link_len) != '\0' ) *(myname_augmented+link_len+1) = '\0'; } else strcpy(myname_augmented, myname); #endif #else /* Windows doesn't seem to have readlink() */ strcpy(myname_augmented, myname); /* if executable doesn't end with .exe, then add it */ if ( *(myname_augmented + strlen(myname) - 4) != '.' || tolower(*(myname_augmented + strlen(myname) - 3)) != 'e' || tolower(*(myname_augmented + strlen(myname) - 2)) != 'x' || tolower(*(myname_augmented + strlen(myname) - 1)) != 'e' ) sprintf(myname_augmented, "%s.exe", myname); #endif #ifdef WIN_NT /* CygWin32 uses absolute paths like this: ///dir1/dir2/... actually /cygdrive//.... If we find such a path, we transform it to a windows-like pathname. This assumes that XSB has been compiled using the native Windows API, and is being run from CygWin32 bash (like from the test scripts). */ transform_cygwin_pathname(myname_augmented); #endif if (is_absolute_filename(myname_augmented)) strcpy(executable, myname_augmented); else { getcwd(current_dir, MAXPATHLEN-1); sprintf(executable, "%s%c%s", current_dir, SLASH, myname_augmented); } /* found executable by prepending cwd */ if (!stat(executable, &fileinfo)) return executable; /* Otherwise, search PATH environment var. This code is a modified "which" shell builtin */ pathcounter = path; while (*pathcounter != '\0' && found == 0) { len = 0; while (*pathcounter != PATH_SEPARATOR && *pathcounter != '\0') { len++; pathcounter++; } /* save the separator ':' (or ';' on NT and replace it with \0) */ save = *pathcounter; *pathcounter = '\0'; /* Now `len' holds the length of the PATH component we are currently looking at. `pathcounter' points to the end of this component. */ sprintf(executable, "%s%c%s", pathcounter - len, SLASH, myname_augmented); /* restore the separator and addvance the pathcounter */ *pathcounter = save; if (*pathcounter) pathcounter++; #ifdef WIN_NT found = (0 == access(executable, 02)); /* readable */ #else found = (0 == access(executable, 01)); /* executable */ #endif if (found) return executable; } /* XSB executable isn't found after searching PATH */ fprintf(stderr, "*************************************************************\n"); fprintf(stderr, "PANIC!!! Cannot determine the full name of the XSB executable!\n"); fprintf(stderr, "Please report this problem using the XSB bug tracking system accessible from\n"); fprintf(stderr, "\t http://sourceforge.net/projects/xsb\n"); fprintf(stderr, "*************************************************************\n"); exit(1); /* This return is needed just to pacify the compiler */ return FALSE; } void set_install_dir() { /* strip 4 levels, since executable is always of this form: install_dir/config//bin/xsb */ install_dir = strip_names_from_path(executable, 4); if (install_dir == NULL) { fprintf(stderr, "*************************************************************\n"); fprintf(stderr, "PANIC!! Can't find the XSB installation directory.\n"); fprintf(stderr, "Perhaps, you moved the XSB executable out of \n"); fprintf(stderr, "its normal place in the XSB directory structure?\n"); fprintf(stderr, "*************************************************************\n"); exit(1); } } void set_config_file() { int retcode; struct stat fileinfo; /* The config file is in the lib directory at the same level as the xsb executable. */ xsb_config_file = strip_names_from_path(executable, 2); sprintf(xsb_config_file+strlen(xsb_config_file), "%clib%cxsb_configuration%s", SLASH, SLASH,XSB_SRC_EXTENSION_STRING); /* Perform sanity checks: xsb_config_file must be in install_dir/config This is probably redundant */ if ( strncmp(install_dir, xsb_config_file, strlen(install_dir)) != 0 || (strstr(xsb_config_file, "config") == NULL) ) { fprintf(stderr, "*************************************************************\n"); fprintf(stderr, "PANIC!! The file configuration%s\n", XSB_SRC_EXTENSION_STRING); fprintf(stderr, "is not where it is expected: %s%cconfig%c%s%clib\n", install_dir, SLASH, SLASH, FULL_CONFIG_NAME, SLASH); fprintf(stderr, "Perhaps you moved the XSB executable %s\n", executable); fprintf(stderr, "away from its usual place?\n"); fprintf(stderr, "*************************************************************\n"); exit(1); } /* Check if configuration.P exists and is readable */ retcode = stat(xsb_config_file, &fileinfo); #ifdef WIN_NT if ( (retcode != 0) || !(S_IREAD & fileinfo.st_mode) ) { #else if ( (retcode != 0) || !(S_IRUSR & fileinfo.st_mode) ) { #endif fprintf(stderr, "*************************************************************\n"); fprintf(stderr, "PANIC! XSB configuration file %s\n", xsb_config_file); fprintf(stderr, "doesn't exist or is not readable by you.\n"); fprintf(stderr, "*************************************************************\n"); exit(1); } } #ifdef WIN_NT void transform_cygwin_pathname(char*); #endif void set_user_home() { user_home = (char *) getenv("HOME"); if ( user_home == NULL ) user_home = install_dir; #ifdef WIN_NT transform_cygwin_pathname(user_home); #endif }