Пример #1
0
int main(int argc, char* argv[])
{
	char dirname[256];
	UINT len;
	FILE *f = stdout;


	if (argc < 2) {
		fprintf(stderr, "Please specify directory.\n");
		return 1;
	}
	strcpy(dirname, argv[1]);
	header.magic = INITRD_MAGIC;
	header.inodecount = count_of_inodes(dirname, 1) + 1;
	header.entries = 0;
	if (!header.inodecount) return 2;
	len = sizeof(initrd_header) + header.inodecount * sizeof(initrd_inode);
	expand_initrd(len);
	memset(inodes, 0, header.inodecount * sizeof(initrd_inode));
	savedir(dirname, -1);
	*((initrd_header*)(filebuf)) = header;
	//f=fopen("initrd.img","w");
	fwrite(filebuf, filelen, 1, f);
	//fclose(f);
	return 0;
}
Пример #2
0
static int
copy_dir (const char *src_path_in, const char *dst_path_in, int new_dst,
	  const struct stat *src_sb, struct dir_list *ancestors,
	  const struct cp_options *x, int *copy_into_self)
{
  char *name_space;
  char *namep;
  struct cp_options non_command_line_options = *x;
  int ret = 0;

  name_space = savedir (src_path_in);
  if (name_space == NULL)
    {
      /* This diagnostic is a bit vague because savedir can fail in
         several different ways.  */
      error (0, errno, _("cannot access %s"), quote (src_path_in));
      return -1;
    }

  /* For cp's -H option, dereference command line arguments, but do not
     dereference symlinks that are found via recursive traversal.  */
  if (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS)
    non_command_line_options.xstat = lstat;

  namep = name_space;
  while (*namep != '\0')
    {
      int local_copy_into_self;
      char *src_path = path_concat (src_path_in, namep, NULL);
      char *dst_path = path_concat (dst_path_in, namep, NULL);

      if (dst_path == NULL || src_path == NULL)
	xalloc_die ();

      ret |= copy_internal (src_path, dst_path, new_dst, src_sb->st_dev,
			    ancestors, &non_command_line_options, 0,
			    &local_copy_into_self, NULL);
      *copy_into_self |= local_copy_into_self;

      free (dst_path);
      free (src_path);

      namep += strlen (namep) + 1;
    }
  free (name_space);
  return -ret;
}
Пример #3
0
UINT savefile(char *filename, UCHAR d_type, UINT parent_inode)
{
	if (d_type == DT_DIR)
		return savedir(filename, parent_inode);

	initrd_inode inode;
	UCHAR *data;
	FILE *f;

	createinode(filename, &inode, FS_FILE);
	fprintf(stderr, "\tOpen file %s\n", filename);
	header.entries++;
	data = expand_initrd(inode.size);

	f = fopen(filename, "r");
	fread(data, inode.size, 1, f);
	fclose(f);

	inodes[inode.inode] = inode;
	return inode.inode;
}
Пример #4
0
int c_flush(C_FILE * fptr)
{

	int it;

	if (!(fptr->c_flag & WRITE)) {
		fprintf(stderr, "no write access");
		return EOF;
	}
	fptr->c_seccnt += blksiz / seclth;
	/* caution: blockno() might evaluate its argument twice */
	if (putblock(blockno(fptr->c_blk), fptr->c_base, -1) == EOF)
		return EOF;
	fptr->c_blk++;
	if (fptr->c_blk == (use16bitptrs ? 8 : 16)) {
		fptr->c_dirp->blkcnt = (char) 0x80;
		savedir();
		/* create new extent */
		if ((it = creext(fptr->c_ext)) == 0) {
			fprintf(stderr, "can't create new extent, current: %d\n", fptr->c_ext);
			return EOF;
		}
		fptr->c_dirp = dirbuf + it;
		fptr->c_ext = it;
		fptr->c_blk = 0;
		fptr->c_seccnt = 0;
		fptr->c_extno++;
		fptr->c_dirp->extno = fptr->c_extno;
	}
	fptr->c_buf = fptr->c_base;
	fptr->c_cnt = blksiz;
	if ((it = alloc()) == '\0') {
		fprintf(stderr, "disk full\n");
		return EOF;
	}
	if (use16bitptrs) {
		fptr->c_dirp->pointers[2 * fptr->c_blk] = it & 0xff;
		fptr->c_dirp->pointers[2 * fptr->c_blk + 1] = (it >> 8) & 0xff;
	} else
Пример #5
0
/* Recursively scan the given directory DIR.
   DEVICE is the device number where DIR resides (for --one-file-system).
   If CMDLINE is true, the directory name was explicitly listed in the
   command line.
   Unless *PDIR is NULL, store there a pointer to the struct directory
   describing DIR. */
struct directory *
scan_directory (char *dir, dev_t device, bool cmdline)
{
  char *dirp = savedir (dir);	/* for scanning directory */
  namebuf_t nbuf;
  char *tmp;
  struct stat stat_data;
  struct directory *directory;
  char ch;
  
  if (! dirp)
    savedir_error (dir);

  tmp = xstrdup (dir);
  zap_slashes (tmp);
  
  if (deref_stat (dereference_option, tmp, &stat_data))
    {
      dir_removed_diag (tmp, cmdline, stat_diag);
      free (tmp);
      free (dirp);
      return NULL;
    }

  directory = procdir (tmp, &stat_data, device,
		       (cmdline ? PD_FORCE_INIT : 0),
		       &ch);
  
  free (tmp);

  nbuf = namebuf_create (dir);

  if (dirp && directory->children != NO_CHILDREN)
    {
      char *entry;	/* directory entry being scanned */
      dumpdir_iter_t itr;

      makedumpdir (directory, dirp);

      for (entry = dumpdir_first (directory->dump, 1, &itr);
	   entry;
	   entry = dumpdir_next (itr))
	{
	  char *full_name = namebuf_name (nbuf, entry + 1);

	  if (*entry == 'I') /* Ignored entry */
	    *entry = 'N';
	  else if (excluded_name (full_name))
	    *entry = 'N';
	  else
	    {
	      if (deref_stat (dereference_option, full_name, &stat_data))
		{
		  file_removed_diag (full_name, false, stat_diag);
		  *entry = 'N';
		  continue;
		}

	      if (S_ISDIR (stat_data.st_mode))
		{
		  int pd_flag = 0;
		  if (!recursion_option)
		    pd_flag |= PD_FORCE_CHILDREN | NO_CHILDREN;
		  else if (directory->children == ALL_CHILDREN)
		    pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
		  *entry = 'D';
		  procdir (full_name, &stat_data, device, pd_flag, entry);
		}

	      else if (one_file_system_option && device != stat_data.st_dev)
		*entry = 'N';

	      else if (*entry == 'Y')
		/* New entry, skip further checks */;

	      /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */

	      else if (OLDER_STAT_TIME (stat_data, m)
		       && (!after_date_option
			   || OLDER_STAT_TIME (stat_data, c)))
		*entry = 'N';
	      else
		*entry = 'Y';
	    }
	}
      free (itr);
    }

  namebuf_free (nbuf);

  if (dirp)
    free (dirp);

  return directory;
}
Пример #6
0
/* Examine the directories under directory_name and delete any
   files that were not there at the time of the back-up. */
static bool
try_purge_directory (char const *directory_name)
{
  char *current_dir;
  char *cur, *arc, *p;
  char *temp_stub = NULL;
  struct dumpdir *dump;

  if (!is_dumpdir (&current_stat_info))
    return false;

  current_dir = savedir (directory_name);

  if (!current_dir)
    /* The directory doesn't exist now.  It'll be created.  In any
       case, we don't have to delete any files out of it.  */
    return false;

  /* Verify if dump directory is sane */
  if (!dumpdir_ok (current_stat_info.dumpdir))
    return false;

  /* Process renames */
  for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1)
    {
      if (*arc == 'X')
	{
#define TEMP_DIR_TEMPLATE "tar.XXXXXX"
	  size_t len = strlen (arc + 1);
	  temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE);
	  memcpy (temp_stub, arc + 1, len);
	  temp_stub[len] = '/';
	  memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE,
		  sizeof TEMP_DIR_TEMPLATE);
	  if (!mkdtemp (temp_stub))
	    {
	      ERROR ((0, errno,
		      _("Cannot create temporary directory using template %s"),
		      quote (temp_stub)));
	      free (temp_stub);
	      free (current_dir);
	      return false;
	    }
	}
      else if (*arc == 'R')
	{
	  char *src, *dst;
	  src = arc + 1;
	  arc += strlen (arc) + 1;
	  dst = arc + 1;

	  /* Ensure that neither source nor destination are absolute file
	     names (unless permitted by -P option), and that they do not
	     contain dubious parts (e.g. ../).

	     This is an extra safety precaution. Besides, it might be
	     necessary to extract from archives created with tar versions
	     prior to 1.19. */

	  if (*src)
	    src = safer_name_suffix (src, false, absolute_names_option);
	  if (*dst)
	    dst = safer_name_suffix (dst, false, absolute_names_option);

	  if (*src == 0)
	    src = temp_stub;
	  else if (*dst == 0)
	    dst = temp_stub;

	  if (!rename_directory (src, dst))
	    {
	      free (temp_stub);
	      free (current_dir);
	      /* FIXME: Make sure purge_directory(dst) will return
		 immediately */
	      return false;
	    }
	}
    }

  free (temp_stub);

  /* Process deletes */
  dump = dumpdir_create (current_stat_info.dumpdir);
  p = NULL;
  for (cur = current_dir; *cur; cur += strlen (cur) + 1)
    {
      const char *entry;
      struct stat st;
      if (p)
	free (p);
      p = new_name (directory_name, cur);

      if (deref_stat (false, p, &st))
	{
	  if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed
				  dirs and check it here? */
	    {
	      stat_diag (p);
	      WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
		     quotearg_colon (p)));
	    }
	  continue;
	}

      if (!(entry = dumpdir_locate (dump, cur))
	  || (*entry == 'D' && !S_ISDIR (st.st_mode))
	  || (*entry == 'Y' && S_ISDIR (st.st_mode)))
	{
	  if (one_file_system_option && st.st_dev != root_device)
	    {
	      WARN ((0, 0,
		     _("%s: directory is on a different device: not purging"),
		     quotearg_colon (p)));
	      continue;
	    }

	  if (! interactive_option || confirm ("delete", p))
	    {
	      if (verbose_option)
		fprintf (stdlis, _("%s: Deleting %s\n"),
			 program_name, quote (p));
	      if (! remove_any_file (p, RECURSIVE_REMOVE_OPTION))
		{
		  int e = errno;
		  ERROR ((0, e, _("%s: Cannot remove"), quotearg_colon (p)));
		}
	    }
	}
    }
  free (p);
  dumpdir_free (dump);
  
  free (current_dir);
  return true;
}
Пример #7
0
static long
count_entry (char *ent, int top, dev_t last_dev)
{
  long size;

  if (((top && opt_dereference_arguments)
       ? stat (ent, &stat_buf)
       : (*xstat) (ent, &stat_buf)) < 0)
    {
      error (0, errno, "%s", path->text);
      exit_status = 1;
      return 0;
    }

  if (!opt_count_all
      && stat_buf.st_nlink > 1
      && hash_insert (stat_buf.st_ino, stat_buf.st_dev))
    return 0;			/* Have counted this already.  */

  if (output_size == size_bytes)
    size = stat_buf.st_size;
  else
    size = ST_NBLOCKS (stat_buf);

  tot_size += size;

  if (S_ISDIR (stat_buf.st_mode))
    {
      unsigned pathlen;
      dev_t dir_dev;
      char *name_space;
      char *namep;
      struct saved_cwd cwd;
      int through_symlink;
      struct stat e_buf;

      dir_dev = stat_buf.st_dev;

      if (opt_one_file_system && !top && last_dev != dir_dev)
	return 0;		/* Don't enter a new file system.  */

#ifndef S_ISDIR
# define S_ISDIR(s) 0
#endif
      /* If we're dereferencing symlinks and we're about to chdir through
	 a symlink, remember the current directory so we can return to it
	 later.  In other cases, chdir ("..") works fine.  */
      through_symlink = (xstat == stat
			 && lstat (ent, &e_buf) == 0
			 && S_ISLNK (e_buf.st_mode));
      if (through_symlink)
	if (save_cwd (&cwd))
	  exit (1);

      if (chdir (ent) < 0)
	{
	  error (0, errno, _("cannot change to directory %s"), path->text);
	  exit_status = 1;
	  return 0;
	}

      errno = 0;
      name_space = savedir (".", stat_buf.st_size);
      if (name_space == NULL)
	{
	  if (errno)
	    {
	      error (0, errno, "%s", path->text);
	      if (through_symlink)
		{
		  if (restore_cwd (&cwd, "..", path->text))
		    exit (1);
		  free_cwd (&cwd);
		}
	      else if (chdir ("..") < 0)
		  error (1, errno, _("cannot change to `..' from directory %s"),
			 path->text);
	      exit_status = 1;
	      return 0;
	    }
	  else
	    error (1, 0, _("virtual memory exhausted"));
	}

      /* Remember the current path.  */

      str_concatc (path, "/");
      pathlen = path->length;

      namep = name_space;
      while (*namep != 0)
	{
	  str_concatc (path, namep);

	  size += count_entry (namep, 0, dir_dev);

	  str_trunc (path, pathlen);
	  namep += strlen (namep) + 1;
	}
      free (name_space);
      if (through_symlink)
	{
	  restore_cwd (&cwd, "..", path->text);
	  free_cwd (&cwd);
	}
      else if (chdir ("..") < 0)
        error (1, errno,
	       _("cannot change to `..' from directory %s"), path->text);

      str_trunc (path, pathlen - 1); /* Remove the "/" we added.  */
      if (!opt_summarize_only || top)
	{
	  if (opt_human_readable)
	    {
	      char buf[LONGEST_HUMAN_READABLE + 1];
	      printf("%s\t%s\n",
		     human_readable (size, buf, LONGEST_HUMAN_READABLE + 1),
		     path->length > 0 ? path->text : "/");
	    }
	  else
	    {
	      printf ("%ld\t%s\n", (output_size == size_bytes
				    ? size
				    : convert_blocks (size, output_size)),
		      path->length > 0 ? path->text : "/");
	    }
	  fflush (stdout);
	}
      return opt_separate_dirs ? 0 : size;
    }
  else if (opt_all || top)
    {
      /* FIXME: make this an option.  */
      int print_only_dir_size = 0;
      if (!print_only_dir_size)
	{
	  if (opt_human_readable)
	    {
	      char buf[LONGEST_HUMAN_READABLE + 1];
	      printf("%s\t%s\n",
		     human_readable (size, buf, LONGEST_HUMAN_READABLE + 1),
		     path->length > 0 ? path->text : "/");
	    }
	  else
	    {
	      printf ("%ld\t%s\n", output_size == size_bytes ? size
		      : convert_blocks (size, output_size),
		      path->text);
	    }
	  fflush (stdout);
	}
    }

  return size;
}
Пример #8
0
void
huntmain(int argc,char **argv)
{
	/* read query from stdin, expect name of indexes in argv[1] */
	static FILE *fa, *fb, *fc;
	char indexname[PATH_MAX], *qitem[100], *rprog = 0;
	char grepquery[200];
	static char oldname[30] ;
	static int nhash = 0;
	static int maxhash = 0;
	int falseflg = 0, nitem, nfound, frtbl;
	static long *hpt = 0;
	unsigned *masterp;

# if D1
	fprintf(stderr, "in glue1 argc %d argv %o %o\n", argc, argv[0],argv[1]);
# endif
	savedir();
	while (argv[1][0] == '-')
	{
# if D1
		fprintf(stderr, "argv.1 is %s\n",argv[1]);
# endif
		switch(argv[1][1])
		{
		case 'a': /* all output, incl. false drops */
			falseflg = 1; 
			break;
		case 'r':
			argc--; 
			argv++;
			rprog = argv[1];
			break;
		case 'F': /* put out full text */
			full = setfrom(argv[1][2]);
			break;
		case 'T': /* put out tags */
			tags = setfrom(argv[1][2]);
			break;
		case 'i': /* input in argument string */
			argc--; 
			argv++;
			sinput = argv[1];
			break;
		case 's': /*text output to string */
		case 'o':
			argc--; 
			argv++;
			soutput = argv[1];
			if ((intptr_t) argv[2]<16000)
			{
				soutlen = (intptr_t) argv[2];
				argc--; 
				argv++;
			}
			break;
		case 't': /*tag output to string */
			argc--; 
			argv++;
			tagout = argv[1];
			if ((intptr_t)argv[2]<16000)
			{
				taglen = (intptr_t)argv[2];
				argc--; 
				argv++;
			}
			break;
		case 'l': /* specify length of lists */
			argc--; 
			argv++;
			lmaster = atoi(argv[1]);
# if D1
			fprintf(stderr, "lmaster now %d\n",lmaster);
# endif
			break;
		case 'C': 
			argc--; 
			argv++;
			colevel = atoi(argv[1]);
			break;
		}
		argc--; 
		argv++;
	}
	n_strcpy (indexname, todir(argv[1]), sizeof(indexname));
# if D1
	fprintf(stderr, "in huntmain indexname %s typeindex %d\n", indexname, typeindex);
# endif
	if (typeindex == 0 || strcmp (oldname, indexname) !=0)
	{
		n_strcpy (oldname, indexname, sizeof(oldname));
		unopen(fa); 
		unopen(fb); 
		unopen(fc);

		if (ckexist(indexname, ".ib"))
		{
# if D1
			fprintf(stderr, "found old index\n");
# endif
			fa = iopen(indexname, ".ia");
			fb = iopen(indexname, ".ib");
			fc = iopen(indexname, ".ic");
			typeindex =1;
# if D1
			fprintf(stderr, "opened f's as %o %o %o\n",fa,fb,fc);
# endif
			indexdate = gdate(fb);
			fread (&nhash, sizeof(nhash), 1, fa);
			fread (&iflong, sizeof(iflong), 1, fa);
			if (nhash > maxhash)
			{
				if (hpt)
					free (hpt);
				hpt=0;
				if (hfreq)
					free(hfreq);
				hfreq=0;
				maxhash=nhash;
# if D1
				fprintf(stderr, "Freed if needed maxhash %d\n",maxhash);
# endif
			}
			if (hpt==0)
				hpt = zalloc(nhash, sizeof(*hpt));
# if D1
			fprintf(stderr, "hpt now %o\n",hpt);
# endif
			if (hpt == NULL)
				err("No space for hash list (%d)", nhash);
			fread( hpt, sizeof(*hpt), nhash, fa);
			if (hfreq==0)
				hfreq=zalloc(nhash, sizeof(*hfreq));
			if (hfreq==NULL)
				err("No space for hash frequencies (%d)",
				    nhash);
			frtbl = fread(hfreq, sizeof(*hfreq), nhash, fa);
			hfrflg = (frtbl == nhash);
# if D1
			fprintf(stderr,"Read pointer files\n");
# endif
			if (master.a == NULL)
			{
				if (iflong)
					master.b = zalloc(lmaster, sizeof(long));
				else
					master.a = zalloc(lmaster, sizeof(int));
			}
			if (master.a == NULL)
				err("no space for answer list", 0);
		}
		else
			if (makefgrep(indexname))
				typeindex=2;
			else
			{
				err("No files %s\n", indexname);
				exit(1);
			}
	}

	if (iflong) 
		masterp = (unsigned *) master.b;
	else
		masterp = master.a;

# if D1
	fprintf(stderr, "typeindex now %d\n",typeindex);
# endif
	tagout[0]=0;
	if (typeindex==2)
	{
		grepcall(sinput, tagout, indexname);
# if D1
		fprintf(stderr, " back from grepcall\n");
# endif
		restodir();
		return;
	}
	nitem = getq(qitem);
# if D1
	fprintf(stderr, "approaching doquery fb %o\n", fb);
# endif
	nfound = doquery(hpt, nhash, fb, nitem, qitem, masterp);
# ifdef D1
	fprintf(stderr, "return from doquery with nfound %d\n", nfound);
# endif
	if (falseflg == 0)
		nfound = baddrop(masterp, nfound, fc, nitem, qitem, rprog, full);
# ifdef D1
	fprintf(stderr, "after baddrop with nfound %d\n",nfound);
	fprintf(stderr, "tagout is /%s/, sout /%s/\n",tagout, soutput);
# endif
	if (tags)
		result (masterp, nfound >tags ? tags : nfound, fc);
# if D1
	fprintf(stderr, "done with huntmain\n");
	fprintf(stderr, "tagout is /%s/\n", tagout);
	fprintf(stderr, "string out is /%s/\n", soutput);
# endif
	if (fgnamp>fgnames)
	{
		char **fgp;
		int k;
# if D1
		fprintf(stderr, "were %d bad files\n", fgnamp-fgnames);
# endif
		grepquery[0]=0;
		for(k=0; k<nitem; k++)
		{
			n_strcat(grepquery, " ", sizeof(grepquery));
			n_strcat(grepquery, qitem[k], sizeof(grepquery));
		}
		for(fgp=fgnames; fgp<fgnamp; fgp++)
		{
# if D1
			fprintf(stderr, "Now on %s query /%s/\n", *fgp, grepquery);
# endif
			makefgrep(*fgp);
			grepcall(grepquery, tagout, *fgp);
# if D1
			fprintf(stderr, "tagout now /%s/\n", tagout);
# endif
		}
	}
	restodir();
}
Пример #9
0
/* Remove FILE_NAME, returning 1 on success.  If FILE_NAME is a directory,
   then if OPTION is RECURSIVE_REMOVE_OPTION is set remove FILE_NAME
   recursively; otherwise, remove it only if it is empty.  If FILE_NAME is
   a directory that cannot be removed (e.g., because it is nonempty)
   and if OPTION is WANT_DIRECTORY_REMOVE_OPTION, then return -1.
   Return 0 on error, with errno set; if FILE_NAME is obviously the working
   directory return zero with errno set to zero.  */
int
remove_any_file (const char *file_name, enum remove_option option)
{
  /* Try unlink first if we cannot unlink directories, as this saves
     us a system call in the common case where we're removing a
     non-directory.  */
  bool try_unlink_first = cannot_unlink_dir ();

  if (try_unlink_first)
    {
      if (unlinkat (chdir_fd, file_name, 0) == 0)
	return 1;

      /* POSIX 1003.1-2001 requires EPERM when attempting to unlink a
	 directory without appropriate privileges, but many Linux
	 kernels return the more-sensible EISDIR.  */
      if (errno != EPERM && errno != EISDIR)
	return 0;
    }

  if (safer_rmdir (file_name) == 0)
    return 1;

  switch (errno)
    {
    case ENOTDIR:
      return !try_unlink_first && unlinkat (chdir_fd, file_name, 0) == 0;

    case 0:
    case EEXIST:
#if defined ENOTEMPTY && ENOTEMPTY != EEXIST
    case ENOTEMPTY:
#endif
      switch (option)
	{
	case ORDINARY_REMOVE_OPTION:
	  break;

	case WANT_DIRECTORY_REMOVE_OPTION:
	  return -1;

	case RECURSIVE_REMOVE_OPTION:
	  {
	    char *directory = savedir (file_name);
	    char const *entry;
	    size_t entrylen;

	    if (! directory)
	      return 0;

	    for (entry = directory;
		 (entrylen = strlen (entry)) != 0;
		 entry += entrylen + 1)
	      {
		char *file_name_buffer = new_name (file_name, entry);
		int r = remove_any_file (file_name_buffer,
                                         RECURSIVE_REMOVE_OPTION);
		int e = errno;
		free (file_name_buffer);

		if (! r)
		  {
		    free (directory);
		    errno = e;
		    return 0;
		  }
	      }

	    free (directory);
	    return safer_rmdir (file_name) == 0;
	  }
	}
      break;
    }

  return 0;
}
Пример #10
0
Файл: incremen.c Проект: xrg/tar
/* Recursively scan the given directory. */
static const char *
scan_directory (char *dir, dev_t device)
{
  char *dirp = savedir (dir);	/* for scanning directory */
  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 stat stat_data;
  struct directory *directory;
  
  if (! dirp)
    savedir_error (dir);

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

  if (deref_stat (dereference_option, name_buffer, &stat_data))
    {
      stat_diag (name_buffer);
      /* FIXME: used to be
           children = CHANGED_CHILDREN;
	 but changed to: */
      free (name_buffer);
      free (dirp);
      return NULL;
    }

  directory = procdir (name_buffer, &stat_data, device, 0, NULL);

  if (dirp && directory->children != NO_CHILDREN)
    {
      char *entry;	/* directory entry being scanned */
      size_t entrylen;	/* length of directory entry */
      dumpdir_iter_t itr;

      makedumpdir (directory, dirp);

      for (entry = dumpdir_first (directory->dump, 1, &itr);
	   entry;
	   entry = dumpdir_next (itr))
	{
	  entrylen = strlen (entry);
	  if (name_buffer_size <= entrylen - 1 + name_length)
	    {
	      do
		name_buffer_size += NAME_FIELD_SIZE;
	      while (name_buffer_size <= entrylen - 1 + name_length);
	      name_buffer = xrealloc (name_buffer, name_buffer_size + 2);
	    }
	  strcpy (name_buffer + name_length, entry + 1);

	  if (*entry == 'I') /* Ignored entry */
	    *entry = 'N';
	  else if (excluded_name (name_buffer))
	    *entry = 'N';
	  else
	    {
	      if (deref_stat (dereference_option, name_buffer, &stat_data))
		{
		  stat_diag (name_buffer);
		  *entry = 'N';
		  continue;
		}

	      if (S_ISDIR (stat_data.st_mode))
		{
		  int pd_flag = (verbose_option ? PD_VERBOSE : 0);
		  if (!recursion_option)
		    pd_flag |= PD_FORCE_CHILDREN | NO_CHILDREN;
		  else if (directory->children == ALL_CHILDREN)
		    pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
		  *entry = 'D';
		  procdir (name_buffer, &stat_data, device, pd_flag, entry);
		}

	      else if (one_file_system_option && device != stat_data.st_dev)
		*entry = 'N';

	      else if (*entry == 'Y')
		/* New entry, skip further checks */;

	      /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */

	      else if (OLDER_STAT_TIME (stat_data, m)
		       && (!after_date_option
			   || OLDER_STAT_TIME (stat_data, c)))
		*entry = 'N';
	      else
		*entry = 'Y';
	    }
	}
      free (itr);
    }

  free (name_buffer);
  if (dirp)
    free (dirp);

  return directory->dump ? directory->dump->contents : NULL;
}