Example #1
0
char *
base_name (char const *name)
{
  char const *base = last_component (name);
  size_t length;

  /* If there is no last component, then name is a file system root or the
     empty string.  */
  if (! *base)
    return xstrndup (name, base_len (name));

  /* Collapse a sequence of trailing slashes into one.  */
  length = base_len (base);
  if (ISSLASH (base[length]))
    length++;

  /* On systems with drive letters, `a/b:c' must return `./b:c' rather
     than `b:c' to avoid confusion with a drive letter.  On systems
     with pure POSIX semantics, this is not an issue.  */
  if (FILE_SYSTEM_PREFIX_LEN (base))
    {
      char *p = xmalloc (length + 3);
      p[0] = '.';
      p[1] = '/';
      memcpy (p + 2, base, length);
      p[length + 2] = '\0';
      return p;
    }

  /* Finally, copy the basename.  */
  return xstrndup (base, length);
}
Example #2
0
char *
mfile_name_concat (char const *dir, char const *abase, char **base_in_result)
{
  char const *dirbase = last_component (dir);
  size_t dirbaselen = base_len (dirbase);
  size_t dirlen = dirbase - dir + dirbaselen;
  size_t needs_separator = (dirbaselen && ! ISSLASH (dirbase[dirbaselen - 1]));

  char const *base = longest_relative_suffix (abase);
  size_t baselen = strlen (base);

  char *p_concat = malloc (dirlen + needs_separator + baselen + 1);
  char *p;

  if (p_concat == NULL)
    return NULL;

  p = mempcpy (p_concat, dir, dirlen);
  *p = DIRECTORY_SEPARATOR;
  p += needs_separator;

  if (base_in_result)
    *base_in_result = p - IS_ABSOLUTE_FILE_NAME (abase);

  p = mempcpy (p, base, baselen);
  *p = '\0';

  return p_concat;
}
Example #3
0
bool
strip_trailing_slashes (char *file)
{
  char *base = base_name (file);
  char *base_lim = base + base_len (base);
  bool had_slash = (*base_lim != '\0');
  *base_lim = '\0';
  return had_slash;
}
Example #4
0
static void
check_extension (char *file, size_t filelen, char e)
{
  char *base = last_component (file);
  size_t baselen = base_len (base);
  size_t baselen_max = HAVE_LONG_FILE_NAMES ? 255 : NAME_MAX_MINIMUM;

  if (HAVE_DOS_FILE_NAMES || NAME_MAX_MINIMUM < baselen)
    {
      /* The new base name is long enough to require a pathconf check.  */
      long name_max;

      /* Temporarily modify the buffer into its parent directory name,
         invoke pathconf on the directory, and then restore the buffer.  */
      char tmp[sizeof "."];
      memcpy (tmp, base, sizeof ".");
      strcpy (base, ".");
      errno = 0;
      name_max = pathconf (file, _PC_NAME_MAX);
      if (0 <= name_max || errno == 0)
        {
          long size = baselen_max = name_max;
          if (name_max != size)
            baselen_max = SIZE_MAX;
        }
      memcpy (base, tmp, sizeof ".");
    }

  if (HAVE_DOS_FILE_NAMES && baselen_max <= 12)
    {
      /* Live within DOS's 8.3 limit.  */
      char *dot = strchr (base, '.');
      if (!dot)
        baselen_max = 8;
      else
        {
          char const *second_dot = strchr (dot + 1, '.');
          baselen_max = (second_dot
                         ? second_dot - base
                         : dot + 1 - base + 3);
        }
    }

  if (baselen_max < baselen)
    {
      baselen = file + filelen - base;
      if (baselen_max <= baselen)
        baselen = baselen_max - 1;
      base[baselen] = e;
      base[baselen + 1] = '\0';
    }
}
Example #5
0
bool
strip_trailing_slashes (char *file)
{
  char *base = last_component (file);
  char *base_lim;
  bool had_slash;

  /* last_component returns "" for file system roots, but we need to turn
     `///' into `/'.  */
  if (! *base)
    base = file;
  base_lim = base + base_len (base);
  had_slash = (*base_lim != '\0');
  *base_lim = '\0';
  return had_slash;
}
Example #6
0
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;
}
Example #7
0
static char const *
expand_name (char *name, bool is_dir, char const *other_name)
{
    if (STREQ (name, "-"))
        fatal ("cannot interactively merge standard input");
    if (! is_dir)
        return name;
    else
    {
        /* Yield NAME/BASE, where BASE is OTHER_NAME's basename.  */
        char const *base = last_component (other_name);
        size_t namelen = strlen (name), baselen = base_len (base);
        bool insert_slash = *last_component (name) && name[namelen - 1] != '/';
        char *r = xmalloc (namelen + insert_slash + baselen + 1);
        memcpy (r, name, namelen);
        r[namelen] = '/';
        memcpy (r + namelen + insert_slash, base, baselen);
        r[namelen + insert_slash + baselen] = '\0';
        return r;
    }
}
Example #8
0
char *mfile_name_concat( char *dir, char *abase, char **base_in_result )
{
  char *dirbase = last_component( dir );
  size_t dirbaselen = base_len( dirbase );
  size_t dirlen = dirbaselen + ( dirbase - dir );
  size_t needs_separator = dirbaselen == 0 || dirbase[ dirbaselen - 1 ] == '/' ? 0 : 1;
  char *base = longest_relative_suffix( abase );
  size_t baselen = strlen( base );
  char *p_concat = malloc( ( baselen + needs_separator + dirlen + 1 ) * sizeof( char ) );
  char *p;
  if ( p_concat == 0 )
  {
    return 0;
  }
  p = mempcpy( p_concat, dir, dirlen );
  p[0] = '/';
  p = &p[ needs_separator ];
  if ( base_in_result != 0 )
    base_in_result[0] = &p[ ( abase[0] == '/' ) * -1 ];
  p = mempcpy( p, base, baselen );
  p[0] = 0;
  return p_concat;
}
Example #9
0
/* Rename the file SRC to DST.  This replacement is necessary on
   Windows, on which the system rename function will not replace
   an existing DST.  */
int
rpl_rename (char const *src, char const *dst)
{
  int error;
  size_t src_len = strlen (src);
  size_t dst_len = strlen (dst);
  char *src_base = last_component (src);
  char *dst_base = last_component (dst);
  bool src_slash;
  bool dst_slash;
  bool dst_exists;
  struct stat src_st;
  struct stat dst_st;

  /* Filter out dot as last component.  */
  if (!src_len || !dst_len)
    {
      errno = ENOENT;
      return -1;
    }
  if (*src_base == '.')
    {
      size_t len = base_len (src_base);
      if (len == 1 || (len == 2 && src_base[1] == '.'))
        {
          errno = EINVAL;
          return -1;
        }
    }
  if (*dst_base == '.')
    {
      size_t len = base_len (dst_base);
      if (len == 1 || (len == 2 && dst_base[1] == '.'))
        {
          errno = EINVAL;
          return -1;
        }
    }

  /* Presence of a trailing slash requires directory semantics.  If
     the source does not exist, or if the destination cannot be turned
     into a directory, give up now.  Otherwise, strip trailing slashes
     before calling rename.  There are no symlinks on mingw, so stat
     works instead of lstat.  */
  src_slash = ISSLASH (src[src_len - 1]);
  dst_slash = ISSLASH (dst[dst_len - 1]);
  if (stat (src, &src_st))
    return -1;
  if (stat (dst, &dst_st))
    {
      if (errno != ENOENT || (!S_ISDIR (src_st.st_mode) && dst_slash))
        return -1;
      dst_exists = false;
    }
  else
    {
      if (S_ISDIR (dst_st.st_mode) != S_ISDIR (src_st.st_mode))
        {
          errno = S_ISDIR (dst_st.st_mode) ? EISDIR : ENOTDIR;
          return -1;
        }
      dst_exists = true;
    }

  /* There are no symlinks, so if a file existed with a trailing
     slash, it must be a directory, and we don't have to worry about
     stripping strip trailing slash.  However, mingw refuses to
     replace an existing empty directory, so we have to help it out.
     And canonicalize_file_name is not yet ported to mingw; however,
     for directories, getcwd works as a viable alternative.  Ensure
     that we can get back to where we started before using it; later
     attempts to return are fatal.  Note that we can end up losing a
     directory if rename then fails, but it was empty, so not much
     damage was done.  */
  if (dst_exists && S_ISDIR (dst_st.st_mode))
    {
      char *cwd = getcwd (NULL, 0);
      char *src_temp;
      char *dst_temp;
      if (!cwd || chdir (cwd))
        return -1;
      if (IS_ABSOLUTE_FILE_NAME (src))
        {
          dst_temp = chdir (dst) ? NULL : getcwd (NULL, 0);
          src_temp = chdir (src) ? NULL : getcwd (NULL, 0);
        }
      else
        {
          src_temp = chdir (src) ? NULL : getcwd (NULL, 0);
          if (!IS_ABSOLUTE_FILE_NAME (dst) && chdir (cwd))
            abort ();
          dst_temp = chdir (dst) ? NULL : getcwd (NULL, 0);
        }
      if (chdir (cwd))
        abort ();
      free (cwd);
      if (!src_temp || !dst_temp)
        {
          free (src_temp);
          free (dst_temp);
          errno = ENOMEM;
          return -1;
        }
      src_len = strlen (src_temp);
      if (strncmp (src_temp, dst_temp, src_len) == 0
          && (ISSLASH (dst_temp[src_len]) || dst_temp[src_len] == '\0'))
        {
          error = dst_temp[src_len];
          free (src_temp);
          free (dst_temp);
          if (error)
            {
              errno = EINVAL;
              return -1;
            }
          return 0;
        }
      if (rmdir (dst))
        {
          error = errno;
          free (src_temp);
          free (dst_temp);
          errno = error;
          return -1;
        }
      free (src_temp);
      free (dst_temp);
    }

  /* MoveFileEx works if SRC is a directory without any flags, but
     fails with MOVEFILE_REPLACE_EXISTING, so try without flags first.
     Thankfully, MoveFileEx handles hard links correctly, even though
     rename() does not.  */
  if (MoveFileEx (src, dst, 0))
    return 0;

  /* Retry with MOVEFILE_REPLACE_EXISTING if the move failed
     due to the destination already existing.  */
  error = GetLastError ();
  if (error == ERROR_FILE_EXISTS || error == ERROR_ALREADY_EXISTS)
    {
      if (MoveFileEx (src, dst, MOVEFILE_REPLACE_EXISTING))
        return 0;

      error = GetLastError ();
    }

  switch (error)
    {
    case ERROR_FILE_NOT_FOUND:
    case ERROR_PATH_NOT_FOUND:
    case ERROR_BAD_PATHNAME:
    case ERROR_DIRECTORY:
      errno = ENOENT;
      break;

    case ERROR_ACCESS_DENIED:
    case ERROR_SHARING_VIOLATION:
      errno = EACCES;
      break;

    case ERROR_OUTOFMEMORY:
      errno = ENOMEM;
      break;

    case ERROR_CURRENT_DIRECTORY:
      errno = EBUSY;
      break;

    case ERROR_NOT_SAME_DEVICE:
      errno = EXDEV;
      break;

    case ERROR_WRITE_PROTECT:
      errno = EROFS;
      break;

    case ERROR_WRITE_FAULT:
    case ERROR_READ_FAULT:
    case ERROR_GEN_FAILURE:
      errno = EIO;
      break;

    case ERROR_HANDLE_DISK_FULL:
    case ERROR_DISK_FULL:
    case ERROR_DISK_TOO_FRAGMENTED:
      errno = ENOSPC;
      break;

    case ERROR_FILE_EXISTS:
    case ERROR_ALREADY_EXISTS:
      errno = EEXIST;
      break;

    case ERROR_BUFFER_OVERFLOW:
    case ERROR_FILENAME_EXCED_RANGE:
      errno = ENAMETOOLONG;
      break;

    case ERROR_INVALID_NAME:
    case ERROR_DELETE_PENDING:
      errno = EPERM;        /* ? */
      break;

# ifndef ERROR_FILE_TOO_LARGE
/* This value is documented but not defined in all versions of windows.h.  */
#  define ERROR_FILE_TOO_LARGE 223
# endif
    case ERROR_FILE_TOO_LARGE:
      errno = EFBIG;
      break;

    default:
      errno = EINVAL;
      break;
    }

  return -1;
}
Example #10
0
int
rpl_rename (char const *src, char const *dst)
{
  size_t src_len = strlen (src);
  size_t dst_len = strlen (dst);
  char *src_temp = (char *) src;
  char *dst_temp = (char *) dst;
  bool src_slash;
  bool dst_slash;
  bool dst_exists;
  int ret_val = -1;
  int rename_errno = ENOTDIR;
  struct stat src_st;
  struct stat dst_st;

  if (!src_len || !dst_len)
    return rename (src, dst); /* Let strace see the ENOENT failure.  */

# if RENAME_DEST_EXISTS_BUG
  {
    char *src_base = last_component (src);
    char *dst_base = last_component (dst);
    if (*src_base == '.')
      {
        size_t len = base_len (src_base);
        if (len == 1 || (len == 2 && src_base[1] == '.'))
          {
            errno = EINVAL;
            return -1;
          }
      }
    if (*dst_base == '.')
      {
        size_t len = base_len (dst_base);
        if (len == 1 || (len == 2 && dst_base[1] == '.'))
          {
            errno = EINVAL;
            return -1;
          }
      }
  }
# endif /* RENAME_DEST_EXISTS_BUG */

  src_slash = src[src_len - 1] == '/';
  dst_slash = dst[dst_len - 1] == '/';

# if !RENAME_HARD_LINK_BUG && !RENAME_DEST_EXISTS_BUG
  /* If there are no trailing slashes, then trust the native
     implementation unless we also suspect issues with hard link
     detection or file/directory conflicts.  */
  if (!src_slash && !dst_slash)
    return rename (src, dst);
# endif /* !RENAME_HARD_LINK_BUG && !RENAME_DEST_EXISTS_BUG */

  /* Presence of a trailing slash requires directory semantics.  If
     the source does not exist, or if the destination cannot be turned
     into a directory, give up now.  Otherwise, strip trailing slashes
     before calling rename.  */
  if (lstat (src, &src_st))
    return -1;
  if (lstat (dst, &dst_st))
    {
      if (errno != ENOENT || (!S_ISDIR (src_st.st_mode) && dst_slash))
        return -1;
      dst_exists = false;
    }
  else
    {
      if (S_ISDIR (dst_st.st_mode) != S_ISDIR (src_st.st_mode))
        {
          errno = S_ISDIR (dst_st.st_mode) ? EISDIR : ENOTDIR;
          return -1;
        }
# if RENAME_HARD_LINK_BUG
      if (SAME_INODE (src_st, dst_st))
        return 0;
# endif /* RENAME_HARD_LINK_BUG */
      dst_exists = true;
    }

# if (RENAME_TRAILING_SLASH_SOURCE_BUG || RENAME_DEST_EXISTS_BUG        \
      || RENAME_HARD_LINK_BUG)
  /* If the only bug was that a trailing slash was allowed on a
     non-existing file destination, as in Solaris 10, then we've
     already covered that situation.  But if there is any problem with
     a trailing slash on an existing source or destination, as in
     Solaris 9, or if a directory can overwrite a symlink, as on
     Cygwin 1.5, or if directories cannot be created with trailing
     slash, as on NetBSD 1.6, then we must strip the offending slash
     and check that we have not encountered a symlink instead of a
     directory.

     Stripping a trailing slash interferes with POSIX semantics, where
     rename behavior on a symlink with a trailing slash operates on
     the corresponding target directory.  We prefer the GNU semantics
     of rejecting any use of a symlink with trailing slash, but do not
     enforce them, since Solaris 10 is able to obey POSIX semantics
     and there might be clients expecting it, as counter-intuitive as
     those semantics are.

     Technically, we could also follow the POSIX behavior by chasing a
     readlink trail, but that is harder to implement.  */
  if (src_slash)
    {
      src_temp = strdup (src);
      if (!src_temp)
        {
          /* Rather than rely on strdup-posix, we set errno ourselves.  */
          rename_errno = ENOMEM;
          goto out;
        }
      strip_trailing_slashes (src_temp);
      if (lstat (src_temp, &src_st))
        {
          rename_errno = errno;
          goto out;
        }
      if (S_ISLNK (src_st.st_mode))
        goto out;
    }
  if (dst_slash)
    {
      dst_temp = strdup (dst);
      if (!dst_temp)
        {
          rename_errno = ENOMEM;
          goto out;
        }
      strip_trailing_slashes (dst_temp);
      if (lstat (dst_temp, &dst_st))
        {
          if (errno != ENOENT)
            {
              rename_errno = errno;
              goto out;
            }
        }
      else if (S_ISLNK (dst_st.st_mode))
        goto out;
    }
# endif /* RENAME_TRAILING_SLASH_SOURCE_BUG || RENAME_DEST_EXISTS_BUG
           || RENAME_HARD_LINK_BUG */
Example #11
0
static enum numbered_backup_result
numbered_backup (char **buffer, size_t buffer_size, size_t filelen)
{
  enum numbered_backup_result result = BACKUP_IS_NEW;
  DIR *dirp;
  struct dirent *dp;
  char *buf = *buffer;
  size_t versionlenmax = 1;
  char *base = last_component (buf);
  size_t base_offset = base - buf;
  size_t baselen = base_len (base);

  /* Temporarily modify the buffer into its parent directory name,
     open the directory, and then restore the buffer.  */
  char tmp[sizeof "."];
  memcpy (tmp, base, sizeof ".");
  strcpy (base, ".");
  dirp = opendir (buf);
  memcpy (base, tmp, sizeof ".");
  strcpy (base + baselen, ".~1~");

  if (!dirp)
    return result;

  while ((dp = readdir (dirp)) != NULL)
    {
      char const *p;
      char *q;
      bool all_9s;
      size_t versionlen;
      size_t new_buflen;

      if (! REAL_DIR_ENTRY (dp) || _D_EXACT_NAMLEN (dp) < baselen + 4)
        continue;

      if (memcmp (buf + base_offset, dp->d_name, baselen + 2) != 0)
        continue;

      p = dp->d_name + baselen + 2;

      /* Check whether this file has a version number and if so,
         whether it is larger.  Use string operations rather than
         integer arithmetic, to avoid problems with integer overflow.  */

      if (! ('1' <= *p && *p <= '9'))
        continue;
      all_9s = (*p == '9');
      for (versionlen = 1; ISDIGIT (p[versionlen]); versionlen++)
        all_9s &= (p[versionlen] == '9');

      if (! (p[versionlen] == '~' && !p[versionlen + 1]
             && (versionlenmax < versionlen
                 || (versionlenmax == versionlen
                     && memcmp (buf + filelen + 2, p, versionlen) <= 0))))
        continue;

      /* This directory has the largest version number seen so far.
         Append this highest numbered extension to the file name,
         prepending '0' to the number if it is all 9s.  */

      versionlenmax = all_9s + versionlen;
      result = (all_9s ? BACKUP_IS_LONGER : BACKUP_IS_SAME_LENGTH);
      new_buflen = filelen + 2 + versionlenmax + 1;
      if (buffer_size <= new_buflen)
        {
          buf = xnrealloc (buf, 2, new_buflen);
          buffer_size = new_buflen * 2;
        }
      q = buf + filelen;
      *q++ = '.';
      *q++ = '~';
      *q = '0';
      q += all_9s;
      memcpy (q, p, versionlen + 2);

      /* Add 1 to the version number.  */

      q += versionlen;
      while (*--q == '9')
        *q = '0';
      ++*q;
    }

  closedir (dirp);
  *buffer = buf;
  return result;
}
Example #12
0
bool
same_name(const char *source, const char *dest)
{
  /* Compare the basenames.  */
  char const *source_basename = last_component(source);
  char const *dest_basename = last_component(dest);
  size_t source_baselen = base_len(source_basename);
  size_t dest_baselen = base_len(dest_basename);
  bool identical_basenames =
    ((source_baselen == dest_baselen)
     && (memcmp(source_basename, dest_basename, dest_baselen) == 0));
  bool compare_dirs = identical_basenames;
  bool same = false;

#if ! _POSIX_NO_TRUNC && HAVE_PATHCONF && (defined(_PC_NAME_MAX) || defined(_POSIX_NAME_MAX))
  /* This implementation silently truncates components of file names. If
   * the base names might be truncated, check whether the truncated
   * base names are the same, while checking the directories.  */
  size_t slen_max = (HAVE_LONG_FILE_NAMES ? 255 : _POSIX_NAME_MAX);
  size_t min_baselen = MIN(source_baselen, dest_baselen);
  if ((slen_max <= min_baselen)
      && (memcmp(source_basename, dest_basename, slen_max) == 0)) {
	  compare_dirs = true;
  }
#else
  /* use 'MIN' macro: */
  size_t min_baselen = MIN(source_baselen, dest_baselen);
  /* dummy condition to use value stored to it: */
  if ((min_baselen == source_baselen) || (min_baselen == dest_baselen)) {
	  ;
  }
#endif /* !_POSIX_NO_TRUNC && HAVE_PATHCONF && (_PC_NAME_MAX || _POSIX_NAME_MAX) */

  if (compare_dirs) {
      struct stat source_dir_stats;
      struct stat dest_dir_stats;
      char *source_dirname, *dest_dirname;

      /* Compare the parent directories (via the device and inode numbers).  */
      source_dirname = dir_name(source);
      dest_dirname = dir_name(dest);

      if (stat(source_dirname, &source_dir_stats)) {
          /* Should NOT happen.  */
          error (1, errno, "%s", source_dirname);
	  }

      if (stat(dest_dirname, &dest_dir_stats)) {
          /* Should NOT happen.  */
          error (1, errno, "%s", dest_dirname);
	  }

      same = SAME_INODE(source_dir_stats, dest_dir_stats);

#if ! _POSIX_NO_TRUNC && HAVE_PATHCONF && defined _PC_NAME_MAX
      if (same && ! identical_basenames) {
          long name_max = (errno = 0, pathconf(dest_dirname, _PC_NAME_MAX));
          if (name_max < 0) {
              if (errno) {
                  /* Should NOT happen.  */
                  error(1, errno, "%s", dest_dirname);
			  }
              same = false;
		  } else
			  same = ((name_max <= min_baselen)
					  && (memcmp(source_basename, dest_basename,
								 name_max) == 0));
	  }
#endif /* !_POSIX_NO_TRUNC && HAVE_PATHCONF && _PC_NAME_MAX */

      free(source_dirname);
      free(dest_dirname);
  }

  return same;
}
Example #13
0
int
main (void)
{
  struct test *t;
  bool ok = true;

  for (t = tests; t->name; t++)
    {
      char *dir = dir_name (t->name);
      int dirlen = dir_len (t->name);
      char *last = last_component (t->name);
      char *base = base_name (t->name);
      int baselen = base_len (base);
      char *stripped = strdup (t->name);
      bool modified = strip_trailing_slashes (stripped);
      bool absolute = IS_ABSOLUTE_FILE_NAME (t->name);
      if (! (strcmp (dir, t->dir) == 0
             && (dirlen == strlen (dir)
                 || (dirlen + 1 == strlen (dir) && dir[dirlen] == '.'))))
        {
          ok = false;
          printf ("dir_name '%s': got '%s' len %d,"
                  " expected '%s' len %ld\n",
                  t->name, dir, dirlen,
                  t->dir, (unsigned long) strlen (t->dir));
        }
      if (strcmp (last, t->last))
        {
          ok = false;
          printf ("last_component '%s': got '%s', expected '%s'\n",
                  t->name, last, t->last);
        }
      if (! (strcmp (base, t->base) == 0
             && (baselen == strlen (base)
                 || (baselen + 1 == strlen (base)
                     && ISSLASH (base[baselen])))))
        {
          ok = false;
          printf ("base_name '%s': got '%s' len %d,"
                  " expected '%s' len %ld\n",
                  t->name, base, baselen,
                  t->base, (unsigned long) strlen (t->base));
        }
      if (strcmp (stripped, t->stripped) || modified != t->modified)
        {
          ok = false;
          printf ("strip_trailing_slashes '%s': got %s %s, expected %s %s\n",
                  t->name, stripped, modified ? "changed" : "unchanged",
                  t->stripped, t->modified ? "changed" : "unchanged");
        }
      if (t->absolute != absolute)
        {
          ok = false;
          printf ("'%s': got %s, expected %s\n", t->name,
                  absolute ? "absolute" : "relative",
                  t->absolute ? "absolute" : "relative");
        }
      free (dir);
      free (base);
      free (stripped);
    }
  return ok ? 0 : 1;
}
Example #14
0
extern char strip_trailing_slashes(char *__T34544056); static void __zvm_this_file_init(void); static __attribute__((__constructor__)) void __zvm_file_constructor(void); char strip_trailing_slashes( char *file)
{ auto char __T34690784; auto int __zvm_memchk_nesting_nr; auto void *__zvm_prev_stack_end; auto char __T33175560;
auto char *base;
auto char *base_lim = 0xaaaaaaaaaaaaaaaa;
auto char had_slash;
# 32
__zvm_memchk_nesting_nr = (__zvm_memchk_push_function("strip_trailing_slashes", 0, "/home/release/apps/grep2.5.3/grep-2.9/lib/stripslash.c", 31)); __zvm_memchk_add_stack_object("/home/release/apps/grep2.5.3/grep-2.9/lib/stripslash.c", ((int)31), ((void *)((unsigned long)(&base))), ((unsigned long)8), ((unsigned long)1), ((const char *)((unsigned long)"base")), ((int)__zvm_memchk_nesting_nr)); __ZVM_DECL_LOCAL_MLS(); __zvm_mls_scope_in(__zvm_cc_var, 1, file, (__zvm_varinfo + 1U)); __ZVM_PUSH_FUNC_INIT((__zvm_funcinfo + 2U)); __zcov_update_counter(0); __ZVM_PUSH_FUNC((__zvm_funcinfo + 0U));
base = (((void *)(__zvm_mls_set_instrumented(__zvm_cc_var))) , ((char *)(__zvm_mls_ptr_init((last_component(((const char *)file))))))); {
# 39
if ((!((int)((*((char *)(__zvm_component_reference_inline((__zvm_varinfo + 2U), ((void *)((unsigned long)base)), ((long)0L), ((int)1), ((void *)((unsigned long)__zvm_cc_var)))))))))) { __zcov_update_counter(1);
((void *)(__zvm_mls_set_instrumented(__zvm_cc_var))) , ((char *)(__zvm_mls_ptr_assignment((__zvm_varinfo + 3U), __zvm_cc_var, (&base), file, 0))); } else  { __zcov_update_counter(2); } } __zcov_update_counter(3); __ZVM_PUSH_FUNC((__zvm_funcinfo + 1U));
((void *)(__zvm_mls_set_instrumented(__zvm_cc_var))) , ((char *)(__zvm_mls_ptr_assignment((__zvm_varinfo + 4U), __zvm_cc_var, (&base_lim), (base + (base_len(((const char *)base)))), 0)));
had_slash = ((char)((((int)((*((char *)(__zvm_component_reference_inline((__zvm_varinfo + 5U), ((void *)((unsigned long)base_lim)), ((long)0L), ((int)1), ((void *)((unsigned long)__zvm_cc_var)))))))) != 0) != 0));
(*((char *)(__zvm_component_reference_inline((__zvm_varinfo + 6U), ((void *)((unsigned long)base_lim)), ((long)0L), ((int)1), ((void *)((unsigned long)__zvm_cc_var)))))) = ((char)0); { __T33175560 = had_slash; __zvm_mls_scope_out("/home/release/apps/grep2.5.3/grep-2.9/lib/stripslash.c", 43, __zvm_cc_var, __zvm_mls_return_unused, 0, 3, 0, base, "base", base_lim, "base_lim", file, "file"); __ZVM_POP_FUNC_END(); { __T34690784 = __T33175560; __zvm_memchk_pop_function("strip_trailing_slashes", __zvm_memchk_nesting_nr); return __T34690784; } }

} static void __zvm_this_file_init(void) {   } static __attribute__((__constructor__)) void __zvm_file_constructor(void) {  __zvm_file_ctr(((void *)__zvm_dirnames)); __zvm_this_file_init(); __zvm_local_init_inline(); __zvm_dr_varinfo_init(((void *)__zvm_varinfo), zvm_file_option); __zvm_update_align(4U); }
Example #15
0
bool
same_name (const char *source, const char *dest)
{
  /* Compare the basenames.  */
  char const *source_basename = last_component (source);
  char const *dest_basename = last_component (dest);
  size_t source_baselen = base_len (source_basename);
  size_t dest_baselen = base_len (dest_basename);
  bool identical_basenames =
    (source_baselen == dest_baselen
     && memcmp (source_basename, dest_basename, dest_baselen) == 0);
  bool compare_dirs = identical_basenames;
  bool same = false;

#if ! _POSIX_NO_TRUNC && HAVE_PATHCONF && defined _PC_NAME_MAX
  /* This implementation silently truncates components of file names.  If
     the base names might be truncated, check whether the truncated
     base names are the same, while checking the directories.  */
  size_t slen_max = HAVE_LONG_FILE_NAMES ? 255 : _POSIX_NAME_MAX;
  size_t min_baselen = MIN (source_baselen, dest_baselen);
  if (slen_max <= min_baselen
      && memcmp (source_basename, dest_basename, slen_max) == 0)
    compare_dirs = true;
#endif

  if (compare_dirs)
    {
      struct stat source_dir_stats;
      struct stat dest_dir_stats;
      char *source_dirname, *dest_dirname;

      /* Compare the parent directories (via the device and inode numbers).  */
      source_dirname = dir_name (source);
      dest_dirname = dir_name (dest);

      if (stat (source_dirname, &source_dir_stats))
        {
          /* Shouldn't happen.  */
          error (1, errno, "%s", source_dirname);
        }

      if (stat (dest_dirname, &dest_dir_stats))
        {
          /* Shouldn't happen.  */
          error (1, errno, "%s", dest_dirname);
        }

      same = SAME_INODE (source_dir_stats, dest_dir_stats);

#if ! _POSIX_NO_TRUNC && HAVE_PATHCONF && defined _PC_NAME_MAX
      if (same && ! identical_basenames)
        {
          long name_max = (errno = 0, pathconf (dest_dirname, _PC_NAME_MAX));
          if (name_max < 0)
            {
              if (errno)
                {
                  /* Shouldn't happen.  */
                  error (1, errno, "%s", dest_dirname);
                }
              same = false;
            }
          else
            same = (name_max <= min_baselen
                    && memcmp (source_basename, dest_basename, name_max) == 0);
        }
#endif

      free (source_dirname);
      free (dest_dirname);
    }

  return same;
}