orient_xsb.c

00001 /* File:      orient_xsb.c - find out where xsb stuff is
00002 ** Author(s): kifer
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1998
00006 ** 
00007 ** XSB is free software; you can redistribute it and/or modify it under the
00008 ** terms of the GNU Library General Public License as published by the Free
00009 ** Software Foundation; either version 2 of the License, or (at your option)
00010 ** any later version.
00011 ** 
00012 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00013 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00015 ** more details.
00016 ** 
00017 ** You should have received a copy of the GNU Library General Public License
00018 ** along with XSB; if not, write to the Free Software Foundation,
00019 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020 **
00021 ** $Id: orient_xsb.c,v 1.17 2005/11/29 00:02:16 tswift Exp $
00022 ** 
00023 */
00024 
00025 
00026 
00027 #include "xsb_config.h"
00028 
00029 #ifdef WIN_NT
00030 #include <direct.h>
00031 #include <io.h>
00032 #else
00033 #include <unistd.h>
00034 #endif
00035 
00036 #include <fcntl.h>
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <ctype.h>
00040 #include <string.h>
00041 #include <sys/types.h>
00042 #include <sys/stat.h>
00043 /* wind2unix.h must be included after sys/stat.h */
00044 #include "wind2unix.h"
00045 #include "export.h"
00046 #include "basicdefs.h"
00047 #include "basictypes.h"
00048 #include "cell_xsb.h"
00049 #include "error_xsb.h"
00050 #include "extensions_xsb.h"
00051 #include "memory_xsb.h"
00052 
00053 char executable_path_gl[MAXPATHLEN] = {'\0'};   /* This is set to a real name below */
00054 
00055 char *install_dir_gl;                   /* installation directory */
00056 char *xsb_config_file_gl;               /* XSB configuration file */
00057 char *user_home_gl;                     /* the user $HOME dir or install dir,
00058                                            if $HOME is null */ 
00059 
00060 
00061 extern xsbBool is_absolute_filename(char *);
00062 DllExport extern char * call_conv strip_names_from_path(char*, int);
00063 
00064 static void check_create_dir(char *);
00065 
00066 extern void transform_cygwin_pathname(char *);
00067 
00068 char current_dir_gl[MAXPATHLEN];
00069 char xsbinfo_dir_gl[MAXPATHLEN];
00070 
00071 
00072 void set_xsbinfo_dir () {
00073   struct stat *fileinfo = mem_alloc(1*sizeof(struct stat),LEAK_SPACE);
00074   char old_xinitrc[MAXPATHLEN], new_xinitrc[MAXPATHLEN],
00075     user_config_dir[MAXPATHLEN], user_arch_dir[MAXPATHLEN];
00076   int retcode;
00077 
00078   if (!fileinfo) {
00079     xsb_abort("No core memory to allocate stat structure.\n");
00080   }
00081   sprintf(xsbinfo_dir_gl, "%s%c.xsb", user_home_gl, SLASH);
00082   sprintf(old_xinitrc, "%s%c.xsbrc", user_home_gl, SLASH);
00083   sprintf(new_xinitrc, "%s%cxsbrc", xsbinfo_dir_gl, SLASH);
00084   sprintf(user_config_dir, "%s%cconfig", xsbinfo_dir_gl, SLASH);
00085   sprintf(user_arch_dir, "%s%c%s", user_config_dir, SLASH, FULL_CONFIG_NAME);
00086 
00087   /* Create USER_HOME/.xsb directory, if it doesn't exist. */
00088   check_create_dir(xsbinfo_dir_gl);
00089   check_create_dir(user_config_dir);
00090   check_create_dir(user_arch_dir);
00091   retcode = stat(old_xinitrc, fileinfo);
00092 
00093   if ((retcode == 0) && (stat(new_xinitrc, fileinfo) != 0)) {
00094     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);
00095   }
00096   mem_dealloc(fileinfo,1*sizeof(struct stat),LEAK_SPACE);
00097 }
00098 
00099 
00100 /* Check if PATH exists. Create if it doesn't. Bark if it can't create or if
00101    PATH exists, but isn't a directory. */
00102 static void check_create_dir(char *path) {
00103   struct stat *fileinfo = mem_alloc(1*sizeof(struct stat),LEAK_SPACE);
00104   int retcode = stat(path, fileinfo);
00105 
00106   if (!fileinfo) {
00107     xsb_abort("No core memory to allocate stat structure.\n");
00108   }
00109 
00110   if (retcode == 0 && ! S_ISDIR(fileinfo->st_mode)) {
00111     xsb_warn("File `%s' is not a directory!\n           XSB uses this directory to store data.", path);
00112     /* exit(1); */
00113   }
00114 
00115   if (retcode != 0) 
00116 #ifdef WIN_NT
00117     retcode = mkdir(path);
00118 #else
00119     retcode = mkdir(path, 0755);
00120 #endif
00121 
00122   if (retcode != 0) {
00123     xsb_warn("Cannot create directory `%s'!\n           XSB uses this directory to store data.", path);
00124     /* exit(1); */
00125   }
00126   mem_dealloc(fileinfo,1*sizeof(struct stat),LEAK_SPACE);
00127 }
00128 
00129 /* uses the global executable var */
00130 char *xsb_executable_full_path(char *myname)
00131 {
00132   struct stat fileinfo;
00133   char *path = getenv("PATH");
00134   int len, found = 0;
00135   char *pathcounter, save;
00136   static char myname_augmented[MAXPATHLEN];
00137 #ifndef WIN_NT
00138   int link_len;
00139 #endif
00140 
00141 
00142 #ifndef WIN_NT
00143 #ifndef SIMPLESCALAR
00144   /* Unix */
00145   /* if we can read symlink, then it is a symlink */
00146   if ( (link_len = readlink(myname, myname_augmented, MAXPATHLEN)) > 0 ) {
00147     /* we can't assume that the value of the link is null-terminated */
00148     if ( *(myname_augmented+link_len) != '\0' )
00149       *(myname_augmented+link_len+1) = '\0';
00150   } else
00151     strcpy(myname_augmented, myname);
00152 #endif
00153 #else
00154   /* Windows doesn't seem to have readlink() */
00155   strcpy(myname_augmented, myname);
00156   /* if executable doesn't end with .exe, then add it */
00157   if ( *(myname_augmented + strlen(myname) - 4) != '.'
00158        || tolower(*(myname_augmented + strlen(myname) - 3)) != 'e'
00159        || tolower(*(myname_augmented + strlen(myname) - 2)) != 'x'
00160        || tolower(*(myname_augmented + strlen(myname) - 1)) != 'e' )
00161     sprintf(myname_augmented, "%s.exe", myname);
00162 #endif
00163 
00164 #ifdef WIN_NT
00165   /* CygWin32 uses absolute paths like this:
00166      //<drive letter>/dir1/dir2/...
00167      actually /cygdrive/<drive letter>/....
00168      If we find such a path, we transform it to a windows-like pathname.
00169      This assumes that XSB has been compiled using the native Windows
00170      API, and is being run from CygWin32 bash (like from the test
00171      scripts). */
00172   transform_cygwin_pathname(myname_augmented);
00173 #endif
00174 
00175   if (is_absolute_filename(myname_augmented))
00176     strcpy(executable_path_gl, myname_augmented);
00177   else {
00178     getcwd(current_dir_gl, MAXPATHLEN-1);
00179     sprintf(executable_path_gl, "%s%c%s", current_dir_gl, SLASH, myname_augmented);
00180   }
00181 
00182   /* found executable by prepending cwd */
00183   if (!stat(executable_path_gl, &fileinfo)) return executable_path_gl;
00184 
00185   /* Otherwise, search PATH environment var.
00186      This code is a modified "which" shell builtin */
00187   pathcounter = path;
00188   while (*pathcounter != '\0' && found == 0) {
00189     len = 0;
00190     while (*pathcounter != PATH_SEPARATOR && *pathcounter != '\0') {
00191       len++;
00192       pathcounter++;
00193     }
00194 
00195     /* save the separator ':' (or ';' on NT and replace it with \0) */
00196     save = *pathcounter;
00197     *pathcounter = '\0';
00198 
00199     /* Now `len' holds the length of the PATH component 
00200        we are currently looking at.
00201        `pathcounter' points to the end of this component. */
00202     sprintf(executable_path_gl, "%s%c%s", pathcounter - len, SLASH, myname_augmented);
00203 
00204     /* restore the separator and addvance the pathcounter */
00205     *pathcounter = save;
00206     if (*pathcounter) pathcounter++;
00207 
00208 #ifdef WIN_NT
00209     found = (0 == access(executable_path_gl, 02));      /* readable */
00210 #else
00211     found = (0 == access(executable_path_gl, 01));      /* executable */
00212 #endif
00213     if (found) return executable_path_gl;
00214   }
00215 
00216   /* XSB executable isn't found after searching PATH */
00217   fprintf(stderr,
00218           "*************************************************************\n");
00219   fprintf(stderr, 
00220           "PANIC!!! Cannot determine the full name of the XSB executable!\n");
00221   fprintf(stderr, 
00222           "Please report this problem using the XSB bug tracking system accessible from\n");
00223   fprintf(stderr, "\t http://sourceforge.net/projects/xsb\n");
00224   fprintf(stderr,
00225           "*************************************************************\n");
00226   exit(1);
00227   /* This return is needed just to pacify the compiler */
00228   return FALSE;
00229 }
00230 
00231 void set_install_dir() {
00232 
00233   /* strip 4 levels, since executable is always of this form:
00234      install_dir/config/<arch>/bin/xsb */
00235   install_dir_gl = strip_names_from_path(executable_path_gl, 4);
00236   if (install_dir_gl == NULL) {
00237     fprintf(stderr,
00238             "*************************************************************\n");
00239     fprintf(stderr, "PANIC!! Can't find the XSB installation directory.\n");
00240     fprintf(stderr, "Perhaps, you moved the XSB executable out of \n");
00241     fprintf(stderr, "its normal place in the XSB directory structure?\n");
00242     fprintf(stderr,
00243             "*************************************************************\n");
00244     exit(1);
00245   }
00246 }
00247 
00248 void set_config_file() {
00249   int retcode;
00250   struct stat fileinfo;
00251 
00252   /* The config file is in the lib directory at the same 
00253      level as the xsb executable. */
00254   xsb_config_file_gl = strip_names_from_path(executable_path_gl, 2);
00255   sprintf(xsb_config_file_gl+strlen(xsb_config_file_gl),
00256           "%clib%cxsb_configuration%s", SLASH, SLASH,XSB_SRC_EXTENSION_STRING);
00257 
00258   /* Perform sanity checks: xsb_config_file must be in install_dir/config
00259      This is probably redundant */
00260   if ( strncmp(install_dir_gl, xsb_config_file_gl, strlen(install_dir_gl)) != 0 
00261        || (strstr(xsb_config_file_gl, "config") == NULL) ) {
00262     fprintf(stderr,
00263             "*************************************************************\n");
00264     fprintf(stderr,
00265             "PANIC!! The file configuration%s\n", XSB_SRC_EXTENSION_STRING);
00266     fprintf(stderr,
00267             "is not where it is expected: %s%cconfig%c%s%clib\n",
00268             install_dir_gl, SLASH, SLASH, FULL_CONFIG_NAME, SLASH);
00269     fprintf(stderr, "Perhaps you moved the XSB executable %s\n", executable_path_gl);
00270     fprintf(stderr, "away from its usual place?\n");
00271     fprintf(stderr,
00272             "*************************************************************\n");
00273     exit(1);
00274   }
00275 
00276   /* Check if configuration.P exists and is readable */
00277   retcode = stat(xsb_config_file_gl, &fileinfo);
00278 #ifdef WIN_NT
00279   if ( (retcode != 0) || !(S_IREAD & fileinfo.st_mode) ) {
00280 #else
00281   if ( (retcode != 0) || !(S_IRUSR & fileinfo.st_mode) ) {
00282 #endif
00283     fprintf(stderr,
00284             "*************************************************************\n");
00285     fprintf(stderr, "PANIC! XSB configuration file %s\n", xsb_config_file_gl);
00286     fprintf(stderr, "doesn't exist or is not readable by you.\n");
00287     fprintf(stderr,
00288             "*************************************************************\n");
00289     exit(1);
00290   }
00291 }
00292 
00293 #ifdef WIN_NT
00294 void transform_cygwin_pathname(char*);
00295 #endif
00296 
00297 void set_user_home() {
00298   user_home_gl = (char *) getenv("HOME");
00299   if ( user_home_gl == NULL )
00300     user_home_gl = install_dir_gl;
00301 #ifdef WIN_NT
00302   transform_cygwin_pathname(user_home_gl);
00303 #endif
00304 }

Generated on Wed Jul 26 13:30:42 2006 for XSB by  doxygen 1.4.5