Ejemplo n.º 1
0
Archivo: statx04.c Proyecto: kraj/ltp
static void test_unflagged(void)
{
	struct statx buf;

	TEST(statx(AT_FDCWD, TESTDIR_UNFLAGGED, 0, 0, &buf));
	if (TST_RET == 0)
		tst_res(TPASS,
			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)",
			TESTDIR_UNFLAGGED);
	else
		tst_brk(TFAIL | TTERRNO,
			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)",
			TESTDIR_UNFLAGGED);

	if ((buf.stx_attributes & STATX_ATTR_COMPRESSED) == 0)
		tst_res(TPASS, "STATX_ATTR_COMPRESSED flag is not set");
	else
		tst_res(TFAIL, "STATX_ATTR_COMPRESSED flag is set");

	if ((buf.stx_attributes & STATX_ATTR_APPEND) == 0)
		tst_res(TPASS, "STATX_ATTR_APPEND flag is not set");
	else
		tst_res(TFAIL, "STATX_ATTR_APPEND flag is set");

	if ((buf.stx_attributes & STATX_ATTR_IMMUTABLE) == 0)
		tst_res(TPASS, "STATX_ATTR_IMMUTABLE flag is not set");
	else
		tst_res(TFAIL, "STATX_ATTR_IMMUTABLE flag is set");

	if ((buf.stx_attributes & STATX_ATTR_NODUMP) == 0)
		tst_res(TPASS, "STATX_ATTR_NODUMP flag is not set");
	else
		tst_res(TFAIL, "STATX_ATTR_NODUMP flag is set");
}
Ejemplo n.º 2
0
Archivo: gnu.c Proyecto: VanL/zrt
void
__tar_collect_and_sort_names (void)
{
  struct name *n, *n_next;
  int num_names;
  struct stat statbuf;

  __tar_name_gather ();

  if (gnu_dumpfile)
    __tar_read_dir_file ();
  if (!namelist)
    __tar_addname (".");
  for (n = namelist; n; n = n_next)
    {
      n_next = n->next;
      if (n->found || n->dir_contents)
	continue;
      if (n->regexp)		/* FIXME just skip regexps for now */
	continue;
      if (n->change_dir)
	if (chdir (n->change_dir) < 0)
	  {
	    ERROR ((0, errno, _("Cannot chdir to %s"), n->change_dir));
	    continue;
	  }

      if (
#ifdef AIX
	  statx (n->name, &statbuf, STATSIZE, STX_HIDDEN | STX_LINK)
#else
	  lstat (n->name, &statbuf) < 0
#endif
	  )
	{
	  ERROR ((0, errno, _("Cannot stat %s"), n->name));
	  continue;
	}
      if (S_ISDIR (statbuf.st_mode))
	{
	  n->found++;
	  __tar_add_dir_name (n->name, statbuf.st_dev);
	}
    }

  num_names = 0;
  for (n = namelist; n; n = n->next)
    num_names++;
  namelist = (struct name *)
    __tar_merge_sort ((voidstar) namelist, (unsigned) num_names,
		(char *) (&(namelist->next)) - (char *) namelist, __tar_name_cmp);

  for (n = namelist; n; n = n->next)
    {
      n->found = 0;
    }
  if (gnu_dumpfile)
    __tar_write_dir_file ();
}
Ejemplo n.º 3
0
time_t
get_file_btime (const char *path)
{
    static int not_implemented = 0;

    int flags = AT_NO_AUTOMOUNT;
    unsigned int mask = STATX_BTIME;
    struct statx stxbuf;
    long ret = 0;
    time_t btime;

    btime = 0;

    if (not_implemented)
    {
        return btime;
    }

    memset (&stxbuf, 0xbf, sizeof(stxbuf));
    errno = 0;

    ret = statx (AT_FDCWD, path, flags, mask, &stxbuf);

    if (ret < 0)
    {
        if (errno == ENOSYS)
        {
            printf("nemo-creation-date: kernel needs to be (>= 4.15) - file creation dates not available\n");
            not_implemented = 1;
        }

        return btime;
    }

    btime = (&stxbuf)->stx_btime.tv_sec;

    return btime;
}
Ejemplo n.º 4
0
void
collect_and_sort_names (void)
{
  struct name *name;
  struct name *next_name;
  int counter;
  struct stat stat_info;

  name_gather ();

  if (listed_incremental_option)
    read_directory_file ();

  if (!name_list_head)
    add_name (".");

  for (name = name_list_head; name; name = next_name)
    {
      next_name = name->next;
      if (name->match_found || name->dir_contents)
	continue;
      if (name->is_wildcard)	/* FIXME: just skip wildcards for now */
	continue;
      if (name->change_dir)
	if (chdir (name->change_dir) < 0)
	  {
	    ERROR ((0, errno, _("Cannot chdir to %s"), name->change_dir));
	    continue;
	  }

      if (
#ifdef AIX
	  statx (name->name, &stat_info, STATSIZE, STX_HIDDEN | STX_LINK)
#else
	  lstat (name->name, &stat_info) < 0
#endif
	  )
	{
	  ERROR ((0, errno, _("Cannot stat %s"), name->name));
	  continue;
	}
      if (S_ISDIR (stat_info.st_mode))
	{
	  name->match_found = true;
	  add_hierarchy_to_namelist (name->name, stat_info.st_dev);
	}
    }

  counter = 0;
  for (name = name_list_head; name; name = name->next)
    counter++;
  name_list_head = (struct name *)
    merge_sort ((voidstar) name_list_head, counter,
		(char *) (&(name_list_head->next)) - (char *) name_list_head,
		compare_names);

  for (name = name_list_head; name; name = name->next)
    name->match_found = false;

  if (listed_incremental_option)
    write_dir_file ();
}
Ejemplo n.º 5
0
char *
get_directory_contents (char *path, dev_t device)
{
  struct accumulator *accumulator;

  /* Recursively scan the given PATH.  */

  {
    DIR *dirp = opendir (path);	/* for scanning directory */
    struct dirent *entry;	/* directory entry being scanned */
    char *name_buffer;		/* directory, `/', and directory member */
    size_t name_buffer_size;	/* allocated size of name_buffer, minus 2 */
    size_t name_length;		/* used length in name_buffer */
    struct directory *directory; /* for checking if already already seen */
    bool all_children;

    if (dirp == NULL)
      {
	ERROR ((0, errno, _("Cannot open directory %s"), path));
	return NULL;
      }
    errno = 0;			/* FIXME: errno should be read-only */

    name_buffer_size = strlen (path) + NAME_FIELD_SIZE;
    name_buffer = xmalloc (name_buffer_size + 2);
    strcpy (name_buffer, path);
    if (path[strlen (path) - 1] != '/')
      strcat (name_buffer, "/");
    name_length = strlen (name_buffer);

    directory = find_directory (path);
    all_children = directory ? directory->all_new : false;

    accumulator = new_accumulator ();

    while (entry = readdir (dirp), entry)
      {
	struct stat stat_info;

	/* Skip `.' and `..'.  */

	if (is_dot_or_dotdot (entry->d_name))
	  continue;

	if (NAMLEN (entry) + name_length >= name_buffer_size)
	  {
	    while (NAMLEN (entry) + name_length >= name_buffer_size)
	      name_buffer_size += NAME_FIELD_SIZE;
	    name_buffer = (char *)
	      xrealloc (name_buffer, name_buffer_size + 2);
	  }
	strcpy (name_buffer + name_length, entry->d_name);

	if (dereference_option
#ifdef AIX
	    ? statx (name_buffer, &stat_info, STATSIZE, STX_HIDDEN)
	    : statx (name_buffer, &stat_info, STATSIZE, STX_HIDDEN | STX_LINK)
#else
	    ? stat (name_buffer, &stat_info)
	    : lstat (name_buffer, &stat_info)
#endif
	    )
	  {
	    ERROR ((0, errno, _("Cannot stat %s"), name_buffer));
	    continue;
	  }

	if ((one_file_system_option && device != stat_info.st_dev)
	    || (exclude_option && check_exclude (name_buffer)))
	  add_to_accumulator (accumulator, "N", (size_t) 1);

#ifdef AIX
	else if (S_ISHIDDEN (stat_info.st_mode))
	  {
	    add_to_accumulator (accumulator, "D", (size_t) 1);
	    strcat (entry->d_name, "A");
	    entry->d_namlen++;
	  }
#endif

	else if (S_ISDIR (stat_info.st_mode))
	  {
	    if (directory = find_directory (name_buffer), directory)
	      {
		/* The same file can have two different devices if an NFS
		   directory is mounted in multiple locations, which is
		   relatively common when automounting.  For avoiding
		   spurious incremental redumping of directories, we have to
		   plainly consider all NFS devices as equal, relying on the
		   i-node only to establish differences.

		   Devices having the high bit set usually are NFS devices.  */

		/* FIXME: Göran Uddeborg <*****@*****.**> says, on
		   1996-09-20, that SunOS 5/Solaris 2 uses unsigned long for
		   the device number type.  */

		if ((((short) directory->device_number >= 0
		      || (short) stat_info.st_dev >= 0)
		     && directory->device_number != stat_info.st_dev)
		    || directory->inode_number != stat_info.st_ino)
		  {
		    if (verbose_option)
		      WARN ((0, 0, _("Directory %s has been renamed"),
			     name_buffer));
		    directory->all_new = true;
		    directory->device_number = stat_info.st_dev;
		    directory->inode_number = stat_info.st_ino;
		  }
		directory->dir_text = "";
	      }
	    else
	      {
		if (verbose_option)
		  WARN ((0, 0, _("Directory %s is new"), name_buffer));
		note_directory (name_buffer,
				stat_info.st_dev, stat_info.st_ino, "");
		directory = find_directory (name_buffer);
		directory->all_new = true;
	      }
	    if (all_children && directory)
	      directory->all_new = true;

	    add_to_accumulator (accumulator, "D", (size_t) 1);
	  }

	else
	  if (all_children || FILE_IS_NEW_ENOUGH (&stat_info))
	    add_to_accumulator (accumulator, "Y", (size_t) 1);
	  else
	    add_to_accumulator (accumulator, "N", (size_t) 1);

	add_to_accumulator (accumulator, entry->d_name, NAMLEN (entry) + 1);
      }
    add_to_accumulator (accumulator, "\000\000", (size_t) 2);

    free (name_buffer);
    closedir (dirp);
  }

  /* Sort the contents of the directory, now that we have it all.  */

  {
    char *pointer = get_accumulator (accumulator);
    size_t counter;
    char *cursor;
    char *buffer;
    char **array;
    char **array_cursor;

    counter = 0;
    for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
      counter++;

    if (counter == 0)
      {
	delete_accumulator (accumulator);
	return NULL;
      }

    array = (char **) xmalloc (sizeof (char *) * (counter + 1));

    array_cursor = array;
    for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
      *array_cursor++ = cursor;
    *array_cursor = NULL;

    qsort ((voidstar) array, counter, sizeof (char *), compare_dirents);

    buffer = (char *) xmalloc ((size_t) (cursor - pointer + 2));

    cursor = buffer;
    for (array_cursor = array; *array_cursor; array_cursor++)
      {
	char *string = *array_cursor;

	while ((*cursor++ = *string++))
	  continue;
      }
    *cursor = '\0';

    delete_accumulator (accumulator);
    free (array);
    return buffer;
  }
}
int
__xstat (int ver, const char *pathname, struct stat *st)
{
  assert (ver == 0);
  return statx (pathname, st, sizeof (*st), STX_NORMAL);
}
Ejemplo n.º 7
0
int main()
{
  int fd;
  char cwd[128];
  struct stat sbuf;
  struct utimbuf ubuf;
#ifdef __NR_statx
  struct statx stx;
#endif

  getcwd(cwd, 128);
  //staptest// getcwd (XXXX, 128) = NNNN

  fd = creat("foobar", S_IREAD|S_IWRITE);
  //staptest// [[[[open ("foobar", O_WRONLY|O_CREAT[[[[.O_LARGEFILE]]]]?|O_TRUNC!!!!creat ("foobar"!!!!openat (AT_FDCWD, "foobar", O_WRONLY|O_CREAT|O_TRUNC]]]], 0600) = NNNN

  fstat(fd, &sbuf);
  //staptest// fstat (NNNN, XXXX) = 0

  fstat(-1, &sbuf);
  //staptest// fstat (-1, XXXX) = -NNNN (EBADF)

  // Here we specify -1 to both arguments, to avoid a SIGSEGV.
  fstat(-1, (struct stat *)-1);
#if __WORDSIZE != 64
  // Notice we're not checking for 0x[f]+ here for the 2nd
  // argument. On RHEL[67] {x86_64,s390x}, for a 32-bit exe, glibc
  // substituted a real structure address (verified with strace).
  // staptest// fstat (-1, XXXX) = -NNNN
#else
  //staptest// fstat (-1, 0x[f]+) = -NNNN
#endif

#ifdef __NR_statx
  memset(&stx, 0xbf, sizeof(stx));
  statx(AT_FDCWD, "foobar", AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, &stx);
  //staptest// statx (AT_FDCWD, "foobar", AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, XXXX) = 0

  statx((int)-1, "foobar", AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, &stx);
  //staptest// statx (-1, "foobar", AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, XXXX) = -NNNN (EBADF)

  statx(AT_FDCWD, (const char *)-1, AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, &stx);
#ifdef __s390__
  //staptest// statx (AT_FDCWD, 0x[7]?[f]+, AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, XXXX) = -NNNN (EFAULT)
#else
  //staptest// statx (AT_FDCWD, 0x[f]+, AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, XXXX) = -NNNN (EFAULT)
#endif

  statx(AT_FDCWD, "foobar", (unsigned)-1, AT_STATX_FORCE_SYNC, &stx);
  //staptest// statx (AT_FDCWD, "foobar", AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|XXXX, AT_STATX_FORCE_SYNC, XXXX) = -NNNN (EINVAL)

  statx(AT_FDCWD, "foobar", AT_SYMLINK_NOFOLLOW, (unsigned)-1, &stx);
  //staptest// statx (AT_FDCWD, "foobar", AT_SYMLINK_NOFOLLOW, 0x[f]+, XXXX) = NNNN

  statx(AT_FDCWD, "foobar", AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, (struct statx *)-1);
#ifdef __s390__
  //staptest// statx (AT_FDCWD, "foobar", AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, 0x[7]?[f]+) = -NNNN (EFAULT)
#else
  //staptest// statx (AT_FDCWD, "foobar", AT_SYMLINK_NOFOLLOW, AT_STATX_FORCE_SYNC, 0x[f]+) = -NNNN (EFAULT)
#endif
#endif

  close(fd);

  stat("foobar", &sbuf);
  //staptest// [[[[stat ("foobar", XXXX!!!!fstatat (AT_FDCWD, "foobar", XXXX, 0x0]]]]) = 0

  stat((char *)-1, &sbuf);
#if defined(__s390__)
  //staptest// stat (0x[7]?[f]+, XXXX) = -NNNN
#else
  //staptest// [[[[stat (0x[f]+, XXXX!!!!fstatat (AT_FDCWD, 0x[f]+, XXXX, 0x0]]]]) = -NNNN
#endif

  // Here we specify -1 to both arguments, to avoid a SIGSEGV.
  stat((char *)-1, (struct stat *)-1);
#if __WORDSIZE != 64
  // Notice we're not checking for 0x[f]+ here for the 2nd
  // argument. On RHEL[67] {x86_64,s390x}, for a 32-bit exe, glibc
  // substituted a real structure address (verified with strace).
  //staptest// stat (0x[7]?[f]+, XXXX) = -NNNN
#else
  //staptest// [[[[stat (0x[f]+, 0x[f]+!!!!fstatat (AT_FDCWD, 0x[f]+, 0x[f]+, 0x0]]]]) = -NNNN
#endif

  lstat("foobar", &sbuf);
  //staptest// [[[[lstat ("foobar", XXXX!!!!fstatat (AT_FDCWD, "foobar", XXXX, AT_SYMLINK_NOFOLLOW]]]]) = 0

  lstat((char *)-1, &sbuf);
#if defined(__s390__)
  //staptest// lstat (0x[7]?[f]+, XXXX) = -NNNN (EFAULT)
#else
  //staptest// [[[[lstat (0x[f]+, XXXX!!!!fstatat (AT_FDCWD, 0x[f]+, XXXX, AT_SYMLINK_NOFOLLOW]]]]) = -NNNN (EFAULT)
#endif

  // Here we specify -1 to both arguments, to avoid a SIGSEGV.
  lstat((char *)-1, (struct stat *)-1);
#if __WORDSIZE != 64
  // Notice we're not checking for 0x[f]+ here for the 2nd
  // argument. On RHEL[67] {x86_64,s390x}, for a 32-bit exe, glibc
  // substituted a real structure address (verified with strace).
  //staptest// lstat (0x[7]?[f]+, XXXX) = -NNNN
#else
  //staptest// [[[[lstat (0x[f]+, 0x[f]+!!!!fstatat (AT_FDCWD, 0x[f]+, 0x[f]+, AT_SYMLINK_NOFOLLOW]]]]) = -NNNN
#endif

#if GLIBC_SUPPORT
  fstatat(AT_FDCWD, "foobar", &sbuf, AT_SYMLINK_NOFOLLOW);
  //staptest// fstatat (AT_FDCWD, "foobar", XXXX, AT_SYMLINK_NOFOLLOW) = 0

  fstatat(-1, "foobar", &sbuf, AT_SYMLINK_NOFOLLOW);
  //staptest// fstatat (-1, "foobar", XXXX, AT_SYMLINK_NOFOLLOW) = -NNNN (EBADF)

  fstatat(AT_FDCWD, (char *)-1, &sbuf, AT_SYMLINK_NOFOLLOW);
#if defined(__s390__)
  //staptest// fstatat (AT_FDCWD, 0x[7]?[f]+, XXXX, AT_SYMLINK_NOFOLLOW) = -NNNN (EFAULT)
#else
  //staptest// fstatat (AT_FDCWD, 0x[f]+, XXXX, AT_SYMLINK_NOFOLLOW) = -NNNN (EFAULT)
#endif

  // Try to avoid a SIGSEGV.
  fstatat(-1, "foobar", (struct stat *)-1, AT_SYMLINK_NOFOLLOW);
#if __WORDSIZE != 64
  // Notice we're not checking for 0x[f]+ here for the 3rd
  // argument. On RHEL[67] {x86_64,s390x}, for a 32-bit exe, glibc
  // substituted a real structure address (verified with strace).
  //staptest// fstatat (-1, "foobar", XXXX, AT_SYMLINK_NOFOLLOW) = -NNNN
#else
  //staptest// fstatat (-1, "foobar", 0x[f]+, AT_SYMLINK_NOFOLLOW) = -NNNN
#endif

  fstatat(AT_FDCWD, "foobar", &sbuf, -1);
  //staptest// fstatat (AT_FDCWD, "foobar", XXXX, AT_[^ ]+|XXXX) = -NNNN (EINVAL)
#endif

  ubuf.actime = 1;
  ubuf.modtime = 1135641600;
  utime("foobar", &ubuf);
#if defined(__aarch64__)
  //staptest// utimensat (AT_FDCWD, "foobar", \[1.[0]+\]\[1135641600.[0]+\], 0x0) =
#elif defined(__ia64__) || defined(__arm__)
  //staptest// utimes ("foobar", \[1.000000\]\[1135641600.000000\]) =
#else
  //staptest// utime ("foobar", \[Thu Jan  1 00:00:01 1970, Tue Dec 27 00:00:00 2005\]) = 0
#endif

  ubuf.actime =  1135690000;
  ubuf.modtime = 1135700000;
  utime("foobar", &ubuf);
#if defined(__aarch64__)
  //staptest// utimensat (AT_FDCWD, "foobar", \[1135690000.[0]+\]\[1135700000.[0]+\], 0x0) =
#elif defined(__ia64__) || defined(__arm__)
  //staptest// utimes ("foobar", \[1135690000.000000\]\[1135700000.000000\]) =
#else
  //staptest// utime ("foobar", \[Tue Dec 27 13:26:40 2005, Tue Dec 27 16:13:20 2005\]) = 0
#endif

  ubuf.actime = 1;
  ubuf.modtime = 1135641600;
  utime((char *)-1, &ubuf);
#if defined(__aarch64__)
  //staptest// utimensat (AT_FDCWD, 0x[f]+, \[1.[0]+\]\[1135641600.[0]+\], 0x0) = -NNNN
#elif defined(__ia64__) || defined(__arm__)
  //staptest// utimes (0x[f]+, \[1.000000\]\[1135641600.000000\]) = -NNNN
#elif defined(__s390__)
  //staptest// utime (0x[7]?[f]+, \[Thu Jan  1 00:00:01 1970, Tue Dec 27 00:00:00 2005\]) = -NNNN
#else
  //staptest// utime (0x[f]+, \[Thu Jan  1 00:00:01 1970, Tue Dec 27 00:00:00 2005\]) = -NNNN
#endif

#if defined(__ia64__) || defined(__arm__) || defined(__aarch64__)
  // Avoid a SIGSEGV by specifying NULL, not -1.
  utime("foobar", (struct utimbuf *)NULL);
  //staptest// [[[[utimes ("foobar", NULL!!!!utimensat (AT_FDCWD, "foobar", NULL, 0x0]]]]) = NNNN
#else
  utime("foobar", (struct utimbuf *)-1);
  //staptest// utime ("foobar", \[Thu Jan  1 00:00:00 1970, Thu Jan  1 00:00:00 1970\]) = -NNNN
#endif


  return 0;
}
Ejemplo n.º 8
0
void
collect_and_sort_names (void)
{
  struct name *name;
  struct name *next_name;
  int num_names;
  struct stat statbuf;

  name_gather ();

  if (listed_incremental_option)
    read_directory_file ();

  if (!namelist)
    addname (".");

  for (name = namelist; name; name = next_name)
    {
      next_name = name->next;
      if (name->found || name->dir_contents)
	continue;
      if (name->regexp)		/* FIXME: just skip regexps for now */
	continue;
      if (name->change_dir)
	if (chdir (name->change_dir) < 0)
	  {
	    ERROR ((0, errno, _("Cannot chdir to %s"), name->change_dir));
	    continue;
	  }

      if (
#ifdef AIX
	  statx (name->name, &statbuf, STATSIZE, STX_HIDDEN | STX_LINK)
#else
	  lstat (name->name, &statbuf) < 0
#endif
	  )
	{
	  ERROR ((0, errno, _("Cannot stat %s"), name->name));
	  continue;
	}
      if (S_ISDIR (statbuf.st_mode))
	{
	  name->found = 1;
	  add_hierarchy_to_namelist (name->name, statbuf.st_dev);
	}
    }

  num_names = 0;
  for (name = namelist; name; name = name->next)
    num_names++;
  namelist = (struct name *)
    merge_sort ((voidstar) namelist, num_names,
		(char *) (&(namelist->next)) - (char *) namelist,
		compare_names);

  for (name = namelist; name; name = name->next)
    name->found = 0;

  if (listed_incremental_option)
    write_dir_file ();
}
Ejemplo n.º 9
0
Archivo: gnu.c Proyecto: VanL/zrt
char *
__tar_get_dir_contents (char *p, int device)
{
  DIR *dirp;
  register struct dirent *d;
  char *new_buf;
  char *namebuf;
  int bufsiz;
  int len;
  voidstar the_buffer;
  char *buf;
  size_t n_strs;
#if 0
  int n_size;
#endif
  char *p_buf;
  char **vec, **p_vec;

  errno = 0;
  dirp = opendir (p);
  bufsiz = strlen (p) + NAMSIZ;
  namebuf = tar_xmalloc ((size_t) (bufsiz + 2));
  if (!dirp)
    {
      ERROR ((0, errno, _("Cannot open directory %s"), p));
      new_buf = NULL;
    }
  else
    {
      struct dirname *dp;
      int all_children;

      dp = __tar_get_dir (p);
      all_children = dp ? dp->allnew : 0;
      strcpy (namebuf, p);
      if (p[strlen (p) - 1] != '/')
	strcat (namebuf, "/");
      len = strlen (namebuf);

      the_buffer = __tar_init_buffer ();
      while (d = readdir (dirp), d)
	{
	  struct stat hs;

	  /* Skip `.' and `..'.  */

	  if (__tar_is_dot_or_dotdot (d->d_name))
	    continue;
	  if ((int) NAMLEN (d) + len >= bufsiz)
	    {
	      bufsiz += NAMSIZ;
	      namebuf = (char *) tar_realloc (namebuf, (size_t) (bufsiz + 2));
	    }
	  strcpy (namebuf + len, d->d_name);
#ifdef AIX
	  if (flag_follow_links ? statx (namebuf, &hs, STATSIZE, STX_HIDDEN)
	      : statx (namebuf, &hs, STATSIZE, STX_HIDDEN | STX_LINK))
#else
	  if (flag_follow_links ? stat (namebuf, &hs) : lstat (namebuf, &hs))
#endif
	    {
	      ERROR ((0, errno, _("Cannot stat %s"), namebuf));
	      continue;
	    }
	  if ((flag_local_filesys && device != hs.st_dev)
	      || (flag_exclude && __tar_check_exclude (namebuf)))
	    __tar_add_buffer (the_buffer, "N", 1);
#ifdef AIX
	  else if (S_ISHIDDEN (hs.st_mode))
	    {
	      __tar_add_buffer (the_buffer, "D", 1);
	      strcat (d->d_name, "A");
	      d->d_namlen++;
	    }
#endif /* AIX */
	  else if (S_ISDIR (hs.st_mode))
	    {
	      if (dp = __tar_get_dir (namebuf), dp)
		{
		  if (dp->dev != hs.st_dev
		      || dp->ino != hs.st_ino)
		    {
		      if (flag_verbose)
			WARN ((0, 0, _("Directory %s has been renamed"),
			       namebuf));
		      dp->allnew = 1;
		      dp->dev = hs.st_dev;
		      dp->ino = hs.st_ino;
		    }
		  dp->dir_text = "";
		}
	      else
		{
		  if (flag_verbose)
		    WARN ((0, 0, _("Directory %s is new"), namebuf));
		  __tar_add_dir (namebuf, hs.st_dev, hs.st_ino, "");
		  dp = __tar_get_dir (namebuf);
		  dp->allnew = 1;
		}
	      if (all_children && dp)
		dp->allnew = 1;

	      __tar_add_buffer (the_buffer, "D", 1);
	    }
	  else if (!all_children
		   && flag_new_files
		   && new_time > hs.st_mtime
		   && (flag_new_files > 1
		       || new_time > hs.st_ctime))
	    __tar_add_buffer (the_buffer, "N", 1);
	  else
	    __tar_add_buffer (the_buffer, "Y", 1);
	  __tar_add_buffer (the_buffer, d->d_name, (int) (NAMLEN (d) + 1));
	}
      __tar_add_buffer (the_buffer, "\000\000", 2);
      closedir (dirp);

      /* Well, we've read in the contents of the dir, now sort them.  */

      buf = __tar_get_buffer (the_buffer);
      if (buf[0] == '\0')
	{
	  __tar_flush_buffer (the_buffer);
	  new_buf = NULL;
	}
      else
	{
	  n_strs = 0;
	  for (p_buf = buf; *p_buf;)
	    {
	      int tmp;

	      tmp = strlen (p_buf) + 1;
	      n_strs++;
	      p_buf += tmp;
	    }
	  vec = (char **) tar_xmalloc (sizeof (char *) * (n_strs + 1));
	  for (p_vec = vec, p_buf = buf; *p_buf; p_buf += strlen (p_buf) + 1)
	    *p_vec++ = p_buf;
	  *p_vec = 0;
	  qsort ((voidstar) vec, n_strs, sizeof (char *), __tar_dirent_cmp);
	  new_buf = (char *) tar_xmalloc ((size_t) (p_buf - buf + 2));
	  for (p_vec = vec, p_buf = new_buf; *p_vec; p_vec++)
	    {
	      char *p_tmp;

	      for (p_tmp = *p_vec; (*p_buf++ = *p_tmp++); )
		;
	    }
	  *p_buf++ = '\0';
	  free (vec);
	  __tar_flush_buffer (the_buffer);
	}
    }
  free (namebuf);
  return new_buf;
}