Пример #1
0
static int
deep_remove_dir (const char *path)
{
    DIR		  *dirp;
    struct dirent *dp;

    if (rmdir (path) != 0)
    {
	if (errno == ENOTEMPTY
	    || errno == EEXIST
	    /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug
	       (it defines ENOTEMPTY and EEXIST to 17 but actually
	       returns 87).  */
	    || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87))
	{
	    if ((dirp = CVS_OPENDIR (path)) == NULL)
		/* If unable to open the directory return
		 * an error
		 */
		return -1;

	    errno = 0;
	    while ((dp = CVS_READDIR (dirp)) != NULL)
	    {
		char *buf;

		if (strcmp (dp->d_name, ".") == 0 ||
			    strcmp (dp->d_name, "..") == 0)
		    continue;

		buf = Xasprintf ("%s/%s", path, dp->d_name);

		/* See comment in unlink_file_dir explanation of why we use
		   isdir instead of just calling unlink and checking the
		   status.  */
		if (isdir (buf)) 
		{
		    if (deep_remove_dir (buf))
		    {
			CVS_CLOSEDIR (dirp);
			free (buf);
			return -1;
		    }
		}
		else
		{
		    if (CVS_UNLINK (buf) != 0)
		    {
			CVS_CLOSEDIR (dirp);
			free (buf);
			return -1;
		    }
		}
		free (buf);

		errno = 0;
	    }
	    if (errno != 0)
	    {
		int save_errno = errno;
		CVS_CLOSEDIR (dirp);
		errno = save_errno;
		return -1;
	    }
	    CVS_CLOSEDIR (dirp);
	    return rmdir (path);
	}
	else
	    return -1;
    }

    /* Was able to remove the directory return 0 */
    return 0;
}
Пример #2
0
Файл: ignore.c Проект: aosm/cvs
/*
 * Process the current directory, looking for files not in ILIST and
 * not on the global ignore list for this directory.  If we find one,
 * call PROC passing it the name of the file and the update dir.
 * ENTRIES is the entries list, which is used to identify known
 * directories.  ENTRIES may be NULL, in which case we assume that any
 * directory with a CVS administration directory is known.
 */
void
ignore_files (List *ilist, List *entries, const char *update_dir,
              Ignore_proc proc)
{
    int subdirs;
    DIR *dirp;
    struct dirent *dp;
    struct stat sb;
    char *file;
    const char *xdir;
    List *files;
    Node *p;

    /* Set SUBDIRS if we have subdirectory information in ENTRIES.  */
    if (entries == NULL)
	subdirs = 0;
    else
    {
	struct stickydirtag *sdtp = entries->list->data;

	subdirs = sdtp == NULL || sdtp->subdirs;
    }

    /* we get called with update_dir set to "." sometimes... strip it */
    if (strcmp (update_dir, ".") == 0)
	xdir = "";
    else
	xdir = update_dir;

    dirp = CVS_OPENDIR (".");
    if (dirp == NULL)
    {
	error (0, errno, "cannot open current directory");
	return;
    }

    ign_add_file (CVSDOTIGNORE, 1);
    wrap_add_file (CVSDOTWRAPPER, 1);

    /* Make a list for the files.  */
    files = getlist ();

    while (errno = 0, (dp = CVS_READDIR (dirp)) != NULL)
    {
	file = dp->d_name;
	if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0)
	    continue;
	if (findnode_fn (ilist, file) != NULL)
	    continue;
	if (subdirs)
	{
	    Node *node;

	    node = findnode_fn (entries, file);
	    if (node != NULL
		&& ((Entnode *) node->data)->type == ENT_SUBDIR)
	    {
		char *p;
		int dir;

		/* For consistency with past behaviour, we only ignore
		   this directory if there is a CVS subdirectory.
		   This will normally be the case, but the user may
		   have messed up the working directory somehow.  */
		p = Xasprintf ("%s/%s", file, CVSADM);
		dir = isdir (p);
		free (p);
		if (dir)
		    continue;
	    }
	}

	/* We could be ignoring FIFOs and other files which are neither
	   regular files nor directories here.  */
	if (ign_name (file))
	    continue;

	if (
#ifdef DT_DIR
	    dp->d_type != DT_UNKNOWN ||
#endif
	    lstat (file, &sb) != -1)
	{

	    if (
#ifdef DT_DIR
		dp->d_type == DT_DIR
		|| (dp->d_type == DT_UNKNOWN && S_ISDIR (sb.st_mode))
#else
		S_ISDIR (sb.st_mode)
#endif
		)
	    {
		if (!subdirs)
		{
		    char *temp = Xasprintf ("%s/%s", file, CVSADM);
		    if (isdir (temp))
		    {
			free (temp);
			continue;
		    }
		    free (temp);
		}
	    }
#ifdef S_ISLNK
	    else if (
#ifdef DT_DIR
		     dp->d_type == DT_LNK
		     || (dp->d_type == DT_UNKNOWN && S_ISLNK (sb.st_mode))
#else
		     S_ISLNK (sb.st_mode)
#endif
		     )
	    {
		continue;
	    }
#endif
	}

	p = getnode ();
	p->type = FILES;
	p->key = xstrdup (file);
	(void) addnode (files, p);
    }
    if (errno != 0)
	error (0, errno, "error reading current directory");
    (void) CVS_CLOSEDIR (dirp);

    sortlist (files, fsortcmp);
    for (p = files->list->next; p != files->list; p = p->next)
	(*proc) (p->key, xdir);
    dellist (&files);
}