Example #1
0
string
kpse_readable_file P1C(const_string, name)
{
  string ret;

#ifdef WIN32
  unsigned int st = 0;
#else /* ! WIN32 */
  struct stat st;
#endif

  kpse_normalize_path((string)name);
  if (READABLE (name, st)) {
      ret = (string) name;
#ifdef ENAMETOOLONG
  } else if (errno == ENAMETOOLONG) {
      ret = kpse_truncate_filename (name);

      /* Perhaps some other error will occur with the truncated name, so
         let's call access again.  */
      if (!READABLE (ret, st)) { /* Failed.  */
          if (ret != name) free (ret);
          ret = NULL;
      }
#endif /* ENAMETOOLONG */
  } else { /* Some other error.  */
      if (errno == EACCES) { /* Maybe warn them if permissions are bad.  */
          if (!kpse_tex_hush ("readable")) {
              perror (name);
          }
      }
      ret = NULL;
  }
  return ret;
}
Example #2
0
boolean
dir_p P1C(const_string, fn)
{
  /* FIXME : using the stat() replacement in gnuw32, 
	 we could avoid this win32 specific code. However,
	 I wonder if it would be as fast as this one is ?
  */
#ifdef WIN32
  int fa;

  kpse_normalize_path((string)fn);
  fa = GetFileAttributes(fn);

  if (KPSE_DEBUG_P(KPSE_DEBUG_STAT)) {
    if (fa == 0xFFFFFFFF) {
      fprintf(stderr, "failed to get file attributes for %s (%d)\n",
	      fn, GetLastError());
    } else {
      fprintf(stderr, "path %s %s a directory\n",
	      fn , (fa & FILE_ATTRIBUTE_DIRECTORY) ? 
	      "is"  : "is not");
    }
  }
  return (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
#else
  struct stat stats;
  return stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode);
#endif
}
Example #3
0
search_list P4C(const_string, path,  const_string*, names,
                boolean, must_exist,  boolean, all)
{
  str_list_type ret_list;
  const_string* namep;
  string elt;
  boolean done = false;

#ifdef __DJGPP__
  /* We will use `stat' heavily, so let's request for
     the fastest possible version of `stat', by telling
     it what members of struct stat do we really need.

     We need to set this on each call because this is a
     library function; the caller might need other options
     from `stat'.  Thus save the flags and restore them
     before exit.

     This call tells `stat' that we do NOT need to recognize
     executable files (neither by an extension nor by a magic
     signature); that we do NOT need time stamp of root directories;
     and that we do NOT need the write access bit in st_mode.

     Note that `kpse_set_progname' needs the EXEC bits,
     but it was already called by the time we get here.  */
  unsigned short save_djgpp_flags  = _djstat_flags;

  _djstat_flags = _STAT_EXEC_MAGIC | _STAT_EXEC_EXT
		  | _STAT_ROOT_TIME | _STAT_WRITEBIT;
#endif

  ret_list = str_list_init();

  if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) {
    DEBUGF1  ("start search(files=[%s", *names);
    for (namep = names+1; *namep != NULL; namep++) {
      fputc(' ', stderr);
      fputs(*namep, stderr);
    }
    fprintf (stderr, "], must_exist=%d, find_all=%d, path=%s).\n",
             must_exist, all, path);
  }
  
  /* No need to do any expansion on names.  */

  for (namep = names; *namep; namep++) {
      if (kpse_absolute_p(*namep, true) && kpse_readable_file(*namep)) {
          str_list_add(&ret_list, xstrdup(*namep));
          /* I know, I know... */
          goto out;
      }
  }

  /* Look at each path element in turn. */
  for (elt = kpse_path_element (path); !done && elt;
       elt = kpse_path_element (NULL))
  {
    str_list_type *found;
    boolean allow_disk_search = true;
    if (elt[0] == '!' && elt[1] == '!') {
      /* !! magic -> disallow disk searches. */
      allow_disk_search = false;
      elt += 2;
    }

    /* See elt-dirs.c for side effects of this function. */
    kpse_normalize_path(elt);

    /* Try ls-R, unless we're searching for texmf.cnf. */
    found = first_search ? NULL : kpse_db_search_list(names, elt, all);

    /* Search the filesystem if (1) the path spec allows it, and either
         (2a) we are searching for texmf.cnf ; or
         (2b) no db exists; or 
         (2c) no db's are relevant to this elt; or
         (3) MUST_EXIST && NAME was not in the db.
       In (2*), `found' will be NULL.
       In (3),  `found' will be an empty list. */
    if (allow_disk_search && (!found || (must_exist && !STR_LIST(*found)))) {
      str_llist_type *dirs = kpse_element_dirs (elt);
      if (dirs && *dirs) {
        if (!found)
          found = XTALLOC1 (str_list_type);
        *found = dir_list_search_list (dirs, names, all);
      }
    }

    /* Did we find anything? */
    if (found && STR_LIST (*found)) {
      if (all) {
        str_list_concat (&ret_list, *found);
      } else {
        str_list_add (&ret_list, STR_LIST_ELT (*found, 0));
        done = true;
      }
    }
  }

 out:
  if (STR_LIST_LENGTH (ret_list) == 0
      || (all && STR_LIST_LAST_ELT (ret_list) != NULL))
    str_list_add (&ret_list, NULL);

  if (first_search) {
    first_search = false;
  } else {
    /* Record the filenames we found, if desired.  And wrap them in a
       debugging line if we're doing that.  */
    if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) {
      DEBUGF1 ("search([%s", *names);
      for (namep = names+1; *namep != NULL; namep++) {
        fputc(' ', stderr);
        fputs(*namep, stderr);
      }
      fputs ("]) =>", stderr);
    }
    log_search (ret_list);
    if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH))
      putc ('\n', stderr);
  }

#ifdef __DJGPP__
  /* Undo any side effects.  */
  _djstat_flags = save_djgpp_flags;
#endif
  
  return STR_LIST (ret_list);
}
Example #4
0
static str_list_type
path_search P4C(const_string, path,  string, name,
                boolean, must_exist,  boolean, all)
{
  string elt;
  str_list_type ret_list;
  boolean done = false;
  ret_list = str_list_init (); /* some compilers lack struct initialization */

  for (elt = kpse_path_element (path); !done && elt;
       elt = kpse_path_element (NULL)) {
    str_list_type *found;
    boolean allow_disk_search = true;

    if (*elt == '!' && *(elt + 1) == '!') {
      /* Those magic leading chars in a path element means don't search the
         disk for this elt.  And move past the magic to get to the name.  */
      allow_disk_search = false;
      elt += 2;
    }

    /* See elt-dirs.c for side effects of this function */
    kpse_normalize_path(elt);
    
    /* Try ls-R, unless we're searching for texmf.cnf.  Our caller
       (search), also tests first_search, and does the resetting.  */
    found = first_search ? NULL : kpse_db_search (name, elt, all);

    /* Search the filesystem if (1) the path spec allows it, and either
         (2a) we are searching for texmf.cnf ; or
         (2b) no db exists; or 
         (2c) no db's are relevant to this elt; or
         (3) MUST_EXIST && NAME was not in the db.
       In (2*), `found' will be NULL.
       In (3),  `found' will be an empty list. */
    if (allow_disk_search && (!found || (must_exist && !STR_LIST (*found)))) {
      str_llist_type *dirs = kpse_element_dirs (elt);
      if (dirs && *dirs) {
        if (!found)
          found = XTALLOC1 (str_list_type);
        *found = dir_list_search (dirs, name, all);
      }
    }
    
    /* Did we find anything anywhere?  */
    if (found && STR_LIST (*found))
      if (all)
        str_list_concat (&ret_list, *found);
      else {
        str_list_add (&ret_list, STR_LIST_ELT (*found, 0));
        done = true;
      }

    /* Free the list space, if any (but not the elements).  */
    if (found) {
      str_list_free (found);
      free (found);
    }
  }

  /* Free the expanded name we were passed.  It can't be in the return
     list, since the path directories got unconditionally prepended.  */
  free (name);
  
  return ret_list;
}