Beispiel #1
0
char *
base_name (char const *name)
{
  char const *base = name + FILESYSTEM_PREFIX_LEN (name);
  char const *p;

  for (p = base; *p; p++)
    {
      if (ISSLASH (*p))
	{
	  /* Treat multiple adjacent slashes like a single slash.  */
	  do p++;
	  while (ISSLASH (*p));

	  /* If the file name ends in slash, use the trailing slash as
	     the basename if no non-slashes have been found.  */
	  if (! *p)
	    {
	      if (ISSLASH (*base))
		base = p - 1;
	      break;
	    }

	  /* *P is a non-slash preceded by a slash.  */
	  base = p;
	}
    }

  return (char *) base;
}
char *base_name(char const *name) {
  char const *base = name + FILESYSTEM_PREFIX_LEN(name);
  char const *p;

  // kill drive letter, if present (on Win32)  /* GGRIII */
  if((p = strchr(base, ':'))) {
    // drive letter is present
    base = p + 1;
  }

  for(p = base; *p; p++) {

    if(ISSLASH(*p)) {
      /* Treat multiple adjacent slashes like a single slash.  */
      do
	p++;
      while (ISSLASH(*p));

      /* If the file name ends in slash, use the trailing slash as
         the basename if no non-slashes have been found.  */
      if(!*p) {
	if(ISSLASH(*base))
	  base = p - 1;
	break;
      }

      /* *P is a non-slash preceded by a slash.  */
      base = p;
    }
  }

  return (char *)base;
}
/* Concatenate a directory pathname, a relative pathname and an optional
   suffix.  The directory may end with the directory separator.  The second
   argument may not start with the directory separator (it is relative).
   Return a freshly allocated pathname.  */
char *
concatenated_pathname (const char *directory, const char *filename,
		       const char *suffix)
{
  char *result;
  char *p;

  if (strcmp (directory, ".") == 0)
    {
      /* No need to prepend the directory.  */
      result = (char *) xmalloc (strlen (filename)
				 + (suffix != NULL ? strlen (suffix) : 0)
				 + 1);
      p = result;
    }
  else
    {
      size_t directory_len = strlen (directory);
      int need_slash =
	(directory_len > FILESYSTEM_PREFIX_LEN (directory)
	 && !ISSLASH (directory[directory_len - 1]));
      result = (char *) xmalloc (directory_len + need_slash
				 + strlen (filename)
				 + (suffix != NULL ? strlen (suffix) : 0)
				 + 1);
      memcpy (result, directory, directory_len);
      p = result + directory_len;
      if (need_slash)
	*p++ = '/';
    }
  p = stpcpy (p, filename);
  if (suffix != NULL)
    stpcpy (p, suffix);
  return result;
}
char *
path_concat (const char *dir, const char *base, char **base_in_result)
{
  char *p;
  char *p_concat;
  size_t baselen;
  size_t dirlen;

  if (!dir)
    {
      p_concat = strdup (base);
      if (base_in_result)
        *base_in_result = p_concat;
      return p_concat;
    }

  /* DIR is not empty. */
  baselen = base_len (base);
  dirlen = strlen (dir);

  p_concat = malloc (dirlen + baselen + 2);
  if (!p_concat)
    return 0;

  p = mempcpy (p_concat, dir, dirlen);

  if (FILESYSTEM_PREFIX_LEN (dir) < dirlen)
    {
      if (ISSLASH (*(p - 1)) && ISSLASH (*base))
	--p;
      else if (!ISSLASH (*(p - 1)) && !ISSLASH (*base))
	*p++ = DIRECTORY_SEPARATOR;
    }

  if (base_in_result)
    *base_in_result = p;

  memcpy (p, base, baselen);
  p[baselen] = '\0';

  return p_concat;
}
Beispiel #5
0
char *
base_name (char const *name)
{
  char const *base = name += FILESYSTEM_PREFIX_LEN (name);
  int all_slashes = 1;
  char const *p;

  for (p = name; *p; p++)
    {
      if (ISSLASH (*p))
	base = p + 1;
      else
	all_slashes = 0;
    }

  /* If NAME is all slashes, arrange to return `/'.  */
  if (*base == '\0' && ISSLASH (*name) && all_slashes)
    --base;

  return (char *) base;
}
Beispiel #6
0
/* Strip directory and suffix from filenames */
char * ft_basename (char const *fpath)
{
  char const *base = fpath += FILESYSTEM_PREFIX_LEN (fpath);
  int all_slashes = 1;
  char const *p;

  for (p = fpath; *p; p++) {
      if (ISSLASH (*p)) {
        base = p + 1;
      } else {
        all_slashes = 0;
      }
  }

  /* If NAME is all slashes, arrange to return `/'.  */
  if (*base == '\0' && ISSLASH (*fpath) && all_slashes) {
    --base;
  }

  return (char *) base;
}
Beispiel #7
0
/* Replace '/' with '\0' in FILENAME if it marks a place that
   needs testing for the existence of directory.  Return the address
   of the last location replaced, or 0 if none were replaced.  */
static char *
replace_slashes (char *filename)
{
  char *f;
  char *last_location_replaced = 0;
  char const *component_start;

  for (f = filename + FILESYSTEM_PREFIX_LEN (filename);  ISSLASH (*f);  f++)
    continue;

  component_start = f;

  for (; *f; f++)
    if (ISSLASH (*f))
      {
	char *slash = f;

	/* Treat multiple slashes as if they were one slash.  */
	while (ISSLASH (f[1]))
	  f++;

	/* Ignore slashes at the end of the path.  */
	if (! f[1])
	  break;

	/* "." and ".." need not be tested.  */
	if (! (slash - component_start <= 2
	       && component_start[0] == '.' && slash[-1] == '.'))
	  {
	    *slash = '\0';
	    last_location_replaced = slash;
	  }

	component_start = f + 1;
      }

  return last_location_replaced;
}
Beispiel #8
0
char *basename(char const *name)
{
	char const *base = name += FILESYSTEM_PREFIX_LEN(name);
	int all_slashes = 1;
	char const *p;

	for (p = name; *p; p++)
	{
		if (ISSLASH(*p))
			base = p + 1;
		else
			all_slashes = 0;
	}

	/* If NAME is all slashes, arrange to return `/'. */
	if (*base == '\0' && ISSLASH(*name) && all_slashes)
		--base;

	/* Make sure the last byte is not a slash. */
	//assert(all_slashes || !ISSLASH(*(p - 1)));

	return (char *)base;
}
Beispiel #9
0
void
move_file (char const *from, int volatile *from_needs_removal,
	   char *to, mode_t mode, int backup)
{
  struct stat to_st;
  int to_errno = ! backup ? -1 : stat (to, &to_st) == 0 ? 0 : errno;

  if (backup)
    {
      int try_makedirs_errno = 0;
      char *bakname;

      if (origprae || origbase)
	{
	  char const *p = origprae ? origprae : "";
	  char const *b = origbase ? origbase : "";
	  char const *o = base_name (to);
	  size_t plen = strlen (p);
	  size_t tlen = o - to;
	  size_t blen = strlen (b);
	  size_t osize = strlen (o) + 1;
	  bakname = xmalloc (plen + tlen + blen + osize);
	  memcpy (bakname, p, plen);
	  memcpy (bakname + plen, to, tlen);
	  memcpy (bakname + plen + tlen, b, blen);
	  memcpy (bakname + plen + tlen + blen, o, osize);
	  for (p += FILESYSTEM_PREFIX_LEN (p);  *p;  p++)
	    if (ISSLASH (*p))
	      {
		try_makedirs_errno = ENOENT;
		break;
	      }
	}
      else
	{
	  bakname = find_backup_file_name (to, backup_type);
	  if (!bakname)
	    memory_fatal ();
	}

      if (to_errno)
	{
	  int fd;

	  if (debug & 4)
	    say ("Creating empty unreadable file %s\n", quotearg (bakname));

	  try_makedirs_errno = ENOENT;
	  unlink (bakname);
	  while ((fd = creat (bakname, 0)) < 0)
	    {
	      if (errno != try_makedirs_errno)
		pfatal ("Can't create file %s", quotearg (bakname));
	      makedirs (bakname);
	      try_makedirs_errno = 0;
	    }
	  if (close (fd) != 0)
	    pfatal ("Can't close file %s", quotearg (bakname));
	}
      else
	{
	  if (debug & 4)
	    say ("Renaming file %s to %s\n",
		 quotearg_n (0, to), quotearg_n (1, bakname));
	  while (rename (to, bakname) != 0)
	    {
	      if (errno != try_makedirs_errno)
		pfatal ("Can't rename file %s to %s",
			quotearg_n (0, to), quotearg_n (1, bakname));
	      makedirs (bakname);
	      try_makedirs_errno = 0;
	    }
	}

      free (bakname);
    }

  if (from)
    {
      if (debug & 4)
	say ("Renaming file %s to %s\n",
	     quotearg_n (0, from), quotearg_n (1, to));

      if (rename (from, to) == 0)
	*from_needs_removal = 0;
      else
	{
	  int to_dir_known_to_exist = 0;

	  if (errno == ENOENT
	      && (to_errno == -1 || to_errno == ENOENT))
	    {
	      makedirs (to);
	      to_dir_known_to_exist = 1;
	      if (rename (from, to) == 0)
		{
		  *from_needs_removal = 0;
		  return;
		}
	    }

	  if (errno == EXDEV)
	    {
	      if (! backup)
		{
		  if (unlink (to) == 0)
		    to_dir_known_to_exist = 1;
		  else if (errno != ENOENT)
		    pfatal ("Can't remove file %s", quotearg (to));
		}
	      if (! to_dir_known_to_exist)
		makedirs (to);
	      copy_file (from, to, 0, mode);
	      return;
	    }

	  pfatal ("Can't rename file %s to %s",
		  quotearg_n (0, from), quotearg_n (1, to));
	}
    }
  else if (! backup)
    {
      if (debug & 4)
	say ("Removing file %s\n", quotearg (to));
      if (unlink (to) != 0)
	pfatal ("Can't remove file %s", quotearg (to));
    }
}
static
#endif
const char *
compute_curr_prefix (const char *orig_installprefix,
		     const char *orig_installdir,
		     const char *curr_pathname)
{
  const char *curr_installdir;
  const char *rel_installdir;

  if (curr_pathname == NULL)
    return NULL;

  if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix))
      != 0)
    
    return NULL;
  rel_installdir = orig_installdir + strlen (orig_installprefix);

  
  {
    const char *p_base = curr_pathname + FILESYSTEM_PREFIX_LEN (curr_pathname);
    const char *p = curr_pathname + strlen (curr_pathname);
    char *q;

    while (p > p_base)
      {
	p--;
	if (ISSLASH (*p))
	  break;
      }

    q = (char *) xmalloc (p - curr_pathname + 1);
#ifdef NO_XMALLOC
    if (q == NULL)
      return NULL;
#endif
    memcpy (q, curr_pathname, p - curr_pathname);
    q[p - curr_pathname] = '\0';
    curr_installdir = q;
  }

  {
    const char *rp = rel_installdir + strlen (rel_installdir);
    const char *cp = curr_installdir + strlen (curr_installdir);
    const char *cp_base =
      curr_installdir + FILESYSTEM_PREFIX_LEN (curr_installdir);

    while (rp > rel_installdir && cp > cp_base)
      {
	bool same = false;
	const char *rpi = rp;
	const char *cpi = cp;

	while (rpi > rel_installdir && cpi > cp_base)
	  {
	    rpi--;
	    cpi--;
	    if (ISSLASH (*rpi) || ISSLASH (*cpi))
	      {
		if (ISSLASH (*rpi) && ISSLASH (*cpi))
		  same = true;
		break;
	      }
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
	    
	    if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi)
		!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
	      break;
#else
	    if (*rpi != *cpi)
	      break;
#endif
	  }
	if (!same)
	  break;
	rp = rpi;
	cp = cpi;
      }

    if (rp > rel_installdir)
      
      return NULL;

    {
      size_t curr_prefix_len = cp - curr_installdir;
      char *curr_prefix;

      curr_prefix = (char *) xmalloc (curr_prefix_len + 1);
#ifdef NO_XMALLOC
      if (curr_prefix == NULL)
	return NULL;
#endif
      memcpy (curr_prefix, curr_installdir, curr_prefix_len);
      curr_prefix[curr_prefix_len] = '\0';

      return curr_prefix;
    }
  }
}
Beispiel #11
0
static
#endif
const char *
compute_curr_prefix (const char *orig_installprefix,
		     const char *orig_installdir,
		     const char *curr_pathname)
{
  const char *curr_installdir;
  const char *rel_installdir;

  if (curr_pathname == NULL)
    return NULL;

  /* Determine the relative installation directory, relative to the prefix.
     This is simply the difference between orig_installprefix and
     orig_installdir.  */
  if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix))
      != 0)
    /* Shouldn't happen - nothing should be installed outside $(prefix).  */
    return NULL;
  rel_installdir = orig_installdir + strlen (orig_installprefix);

  /* Determine the current installation directory.  */
  {
    const char *p_base = curr_pathname + FILESYSTEM_PREFIX_LEN (curr_pathname);
    const char *p = curr_pathname + strlen (curr_pathname);
    char *q;

    while (p > p_base)
      {
	p--;
	if (ISSLASH (*p))
	  break;
      }

    q = (char *) xmalloc (p - curr_pathname + 1);
#ifdef NO_XMALLOC
    if (q == NULL)
      return NULL;
#endif
    memcpy (q, curr_pathname, p - curr_pathname);
    q[p - curr_pathname] = '\0';
    curr_installdir = q;
  }

  /* Compute the current installation prefix by removing the trailing
     rel_installdir from it.  */
  {
    const char *rp = rel_installdir + strlen (rel_installdir);
    const char *cp = curr_installdir + strlen (curr_installdir);
    const char *cp_base =
      curr_installdir + FILESYSTEM_PREFIX_LEN (curr_installdir);

    while (rp > rel_installdir && cp > cp_base)
      {
	bool same = false;
	const char *rpi = rp;
	const char *cpi = cp;

	while (rpi > rel_installdir && cpi > cp_base)
	  {
	    rpi--;
	    cpi--;
	    if (ISSLASH (*rpi) || ISSLASH (*cpi))
	      {
		if (ISSLASH (*rpi) && ISSLASH (*cpi))
		  same = true;
		break;
	      }
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
	    /* Win32, OS/2, DOS - case insignificant filesystem */
	    if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi)
		!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
	      break;
#else
	    if (*rpi != *cpi)
	      break;
#endif
	  }
	if (!same)
	  break;
	/* The last pathname component was the same.  opi and cpi now point
	   to the slash before it.  */
	rp = rpi;
	cp = cpi;
      }

    if (rp > rel_installdir)
      /* Unexpected: The curr_installdir does not end with rel_installdir.  */
      return NULL;

    {
      size_t curr_prefix_len = cp - curr_installdir;
      char *curr_prefix;

      curr_prefix = (char *) xmalloc (curr_prefix_len + 1);
#ifdef NO_XMALLOC
      if (curr_prefix == NULL)
	return NULL;
#endif
      memcpy (curr_prefix, curr_installdir, curr_prefix_len);
      curr_prefix[curr_prefix_len] = '\0';

      return curr_prefix;
    }
  }
}