Beispiel #1
0
int recursive_rmdir(char* dir)
{
    DIR * dirh;
    struct dirent * dire;
    struct stat statbuf;
    char fname[PATH_MAX];
    int ret;
    
    dirh = opendir(dir);
    if(!dirh)
    {
        fprintf(stderr, "Error: failed to open dir: %s\n", dir);
        return -1;
    }

    while((dire = readdir(dirh)) != NULL)
    {
        if(strcmp(dire->d_name, ".") == 0 ||
           strcmp(dire->d_name, "..") == 0)
        {
            continue;
        }

        sprintf(fname, "%s/%s", dir, dire->d_name);
        ret = stat(fname, &statbuf);
        if(ret == -1)
        {
            perror("stat");
            return -1;
        }

        if(S_ISDIR(statbuf.st_mode))
        {
            ret = recursive_rmdir(fname);
            if(ret < 0)
            {
                return ret;
            }
        }
        else if(S_ISREG(statbuf.st_mode))
        {
            unlink(fname);
        }
    }
    
    ret = closedir(dirh);
    if(ret < 0)
    {
        perror("closedir");
        return -1;
    }

    ret = rmdir(dir);
    if(ret < 0)
    {
        perror("rmdir");
    }

    return 0;
}
/* recursive rmdir to remove the left-overs from unstuff */
static void
recursive_rmdir (const char *path)
{
	GDir *dir;
	const char *dirname;

	dir = g_dir_open (path, 0, NULL);
	if (dir == NULL)
		return;

	dirname = g_dir_read_name (dir);
	while (dirname != NULL)
	{
		char *full_path;

		if (strcmp (dirname, ".") == 0 || strcmp (dirname, "..") == 0)
			continue;

		full_path = g_build_filename (path, dirname, NULL);
		recursive_rmdir (full_path);
		g_free (full_path);

		dirname = g_dir_read_name (dir);
	}

	rmdir (path);

	g_dir_close (dir);
}
Beispiel #3
0
static int
recursive_rmdir (char *dirpath)
{
	DIR *dir;
	struct dirent *de;
	char pathbuf[MAXPATHLEN];
	struct stat sb;
	int err;

	dir = opendir(dirpath);
	if (!dir)
		return 1;
	while ((de = readdir(dir))) {
		if (de->d_name[0] == '.' && ((de->d_name[1] == '.' && !de->d_name[2]) || !de->d_name[1]))
			continue;
		snprintf(pathbuf, MAXPATHLEN, "%s/%s", dirpath, de->d_name);
		if ((err = SYS_lstat(pathbuf, &sb)))
			goto ret;
		if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode))
			err = recursive_rmdir(pathbuf);
		else
			err = unlink(pathbuf);
		if (err)
			goto ret;
	}
	closedir(dir);
	return rmdir(dirpath);
ret:
	closedir(dir);

	return err;
}
Beispiel #4
0
static void create_user_full(struct user *user)
{
	char trace_path[] = "/tmp/ctfwriter_XXXXXX";
	struct bt_ctf_field_type *ft;
	struct bt_ctf_field *field;
	struct bt_ctf_clock *clock;
	int ret;

	if (!bt_mkdtemp(trace_path)) {
		perror("# perror");
	}

	user->writer = bt_ctf_writer_create(trace_path);
	assert(user->writer);
	user->tc = bt_ctf_writer_get_trace(user->writer);
	assert(user->tc);
	user->sc = bt_ctf_stream_class_create("sc");
	assert(user->sc);
	clock = bt_ctf_clock_create("the_clock");
	assert(clock);
	ret = bt_ctf_stream_class_set_clock(user->sc, clock);
	assert(!ret);
	ret = bt_ctf_clock_set_value(clock, 23);
	assert(!ret);
	BT_PUT(clock);
	user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
	assert(user->stream);
	user->ec = bt_ctf_event_class_create("ec");
	assert(user->ec);
	ft = create_integer_struct();
	assert(ft);
	ret = bt_ctf_event_class_set_payload_type(user->ec, ft);
	BT_PUT(ft);
	assert(!ret);
	ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
	assert(!ret);
	user->event = bt_ctf_event_create(user->ec);
	assert(user->event);
	field = bt_ctf_event_get_payload(user->event, "payload_8");
	assert(field);
	ret = bt_ctf_field_unsigned_integer_set_value(field, 10);
	assert(!ret);
	BT_PUT(field);
	field = bt_ctf_event_get_payload(user->event, "payload_16");
	assert(field);
	ret = bt_ctf_field_unsigned_integer_set_value(field, 20);
	assert(!ret);
	BT_PUT(field);
	field = bt_ctf_event_get_payload(user->event, "payload_32");
	assert(field);
	ret = bt_ctf_field_unsigned_integer_set_value(field, 30);
	assert(!ret);
	BT_PUT(field);
	ret = bt_ctf_stream_append_event(user->stream, user->event);
	assert(!ret);
	recursive_rmdir(trace_path);
}
Beispiel #5
0
static bool recursive_rmdir(const char *dirname)
{
	struct dirent dirent, *direntp;
	DIR *dir;
	bool ret = false;
	char pathname[MAXPATHLEN];

	dir = opendir(dirname);
	if (!dir) {
		fprintf(stderr, "%s: failed to open %s: %s\n", __func__, dirname, strerror(errno));
		return false;
	}

	while (!readdir_r(dir, &dirent, &direntp)) {
		struct stat mystat;
		int rc;

		if (!direntp)
			break;

		if (!strcmp(direntp->d_name, ".") ||
		    !strcmp(direntp->d_name, ".."))
			continue;

		rc = snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name);
		if (rc < 0 || rc >= MAXPATHLEN) {
			fprintf(stderr, "pathname too long\n");
			continue;
		}

		ret = lstat(pathname, &mystat);
		if (ret) {
			fprintf(stderr, "%s: failed to stat %s: %s\n", __func__, pathname, strerror(errno));
			continue;
		}
		if (S_ISDIR(mystat.st_mode)) {
			if (!recursive_rmdir(pathname))
				fprintf(stderr, "Error removing %s\n", pathname);
		}
	}

	ret = true;
	if (closedir(dir) < 0) {
		fprintf(stderr, "%s: failed to close directory %s: %s\n", __func__, dirname, strerror(errno));
		ret = false;
	}

	if (rmdir(dirname) < 0) {
		fprintf(stderr, "%s: failed to delete %s: %s\n", __func__, dirname, strerror(errno));
		ret = false;
	}

	return ret;
}
Beispiel #6
0
bool cgfs_remove(const char *controller, const char *cg)
{
	size_t len;
	char *dirnam, *tmpc = find_mounted_controller(controller);

	if (!tmpc)
		return false;
	/* basedir / tmpc / cg \0 */
	len = strlen(basedir) + strlen(tmpc) + strlen(cg) + 3;
	dirnam = alloca(len);
	snprintf(dirnam, len, "%s/%s/%s", basedir,tmpc, cg);
	return recursive_rmdir(dirnam);
}
Beispiel #7
0
/*
 * Remove the provided directory totally from the filesystem.  This
 * is done in a recursive fashion for any files and directories
 * contained within that directory.  Any problem in this operation
 * should cause -1 to be returned and errno to contain the error.
 */
int recursive_rmdir(char *directory) {
   DIR *d = NULL;
   struct dirent *dir = NULL;
   char *name = NULL;
   int i = 0;
   struct stat s;
   unsigned int size = 0;

   if (directory == NULL) {
      errno = EINVAL;
      return -1;
   }
   if ((d = opendir(directory)) == NULL)
      return -1;
   while ((dir = readdir(d)) != NULL) {
      if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))
         continue;
      size = strlen(directory) + strlen(dir->d_name) + 2;
      name = (char *)malloc(size * sizeof(char));
      if (name == NULL) {
         closedir(d);
         errno = ENOMEM;
         return -1;
      }
      snprintf(name, size, "%s%c%s", directory, FILE_SEPARATOR, dir->d_name);
      if (lstat(name, &s) == -1) {
         closedir(d);
         free(name);
         return -1;
      }
      if (S_ISDIR(s.st_mode)) {
         i = recursive_rmdir(name);
      } else {
         i = unlink(name);
      }
      free(name);
      if (i == -1) {
         closedir(d);
         return -1;
      }
   }
   closedir(d);
   rmdir(directory);

   return 0;
}
Beispiel #8
0
/*
 * Recursively delete a cgroup.
 * Cgroup files can't be deleted, but are cleaned up when you remove the
 * containing directory.  A directory cannot be removed until all its
 * children are removed, and can't be removed if any tasks remain.
 *
 * We allow any task which may write under /a/b to delete any cgroups
 * under that, even if, say, it technically is not allowed to remove
 * /a/b/c/d/.
 */
static int recursive_rmdir(char *path)
{
	struct dirent dirent, *direntp;
	DIR *dir;
	char pathname[MAXPATHLEN];
	int failed = 0;

	dir = opendir(path);
	if (!dir) {
		nih_error("%s: Failed to open dir %s for recursive deletion", __func__, path);
		return -1;
	}

	while (!readdir_r(dir, &dirent, &direntp)) {
		struct stat mystat;
		int rc;

		if (!direntp)
			break;
		if (!strcmp(direntp->d_name, ".") ||
		    !strcmp(direntp->d_name, ".."))
			continue;
		rc = snprintf(pathname, MAXPATHLEN, "%s/%s", path, direntp->d_name);
		if (rc < 0 || rc >= MAXPATHLEN) {
			failed = 1;
			continue;
		}
		rc = lstat(pathname, &mystat);
		if (rc) {
			failed = 1;
			continue;
		}
		if (S_ISDIR(mystat.st_mode)) {
			if (recursive_rmdir(pathname) < 0)
				failed = 1;
		}
	}

	if (closedir(dir) < 0)
		failed = 1;
	if (rmdir(path) < 0)
		failed = 1;

	return failed ? -1 : 0;
}
Beispiel #9
0
int recursive_rmdir(char *dirname)
{
	struct dirent dirent, *direntp;
	DIR *dir;
	int ret;
	char pathname[MAXPATHLEN];

	dir = opendir(dirname);
	if (!dir) {
		WARN("failed to open directory: %m");
		return -1;
	}

	while (!readdir_r(dir, &dirent, &direntp)) {
		struct stat mystat;
		int rc;

		if (!direntp)
			break;

		if (!strcmp(direntp->d_name, ".") ||
		    !strcmp(direntp->d_name, ".."))
			continue;

		rc = snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name);
		if (rc < 0 || rc >= MAXPATHLEN) {
			ERROR("pathname too long");
			continue;
		}
		ret = stat(pathname, &mystat);
		if (ret)
			continue;
		if (S_ISDIR(mystat.st_mode))
			recursive_rmdir(pathname);
	}

	ret = rmdir(dirname);

	if (closedir(dir))
		ERROR("failed to close directory");
	return ret;


}
Beispiel #10
0
static int lxc_one_cgroup_destroy(struct mntent *mntent, const char *cgpath)
{
	char cgname[MAXPATHLEN];
	char *cgmnt = mntent->mnt_dir;
	int rc;

	rc = snprintf(cgname, MAXPATHLEN, "%s/%s", cgmnt, cgpath);
	if (rc < 0 || rc >= MAXPATHLEN) {
		ERROR("name too long");
		return -1;
	}
	DEBUG("destroying %s\n", cgname);
	if (recursive_rmdir(cgname)) {
		SYSERROR("failed to remove cgroup '%s'", cgname);
		return -1;
	}

	DEBUG("'%s' unlinked", cgname);

	return 0;
}
Beispiel #11
0
int lxc_one_cgroup_destroy(struct mntent *mntent, const char *name)
{
	char cgname[MAXPATHLEN], initcgroup[MAXPATHLEN];
	char *cgmnt = mntent->mnt_dir;
	int flags = get_cgroup_flags(mntent);
	int rc;

	rc = snprintf(cgname, MAXPATHLEN, "%s%s%s/%s", cgmnt,
		get_init_cgroup(NULL, mntent, initcgroup),
		(flags & CGROUP_NS_CGROUP) ? "" : "/lxc", name);
	if (rc < 0 || rc >= MAXPATHLEN) {
		ERROR("name too long");
		return -1;
	}
	DEBUG("destroying %s\n", cgname);
	if (recursive_rmdir(cgname)) {
		SYSERROR("failed to remove cgroup '%s'", cgname);
		return -1;
	}

	DEBUG("'%s' unlinked", cgname);

	return 0;
}
Beispiel #12
0
int remove_main(const char *controller, const char *cgroup, struct ucred p,
		struct ucred r, int recursive, int32_t *existed)
{
	char rcgpath[MAXPATHLEN];
	size_t cgroup_len;
	nih_local char *working = NULL, *copy = NULL, *wcgroup = NULL;
	char *p1;

	*existed = 1;

	if (!sane_cgroup(cgroup)) {
		nih_error("%s: unsafe cgroup", __func__);
		return -1;
	}

	// Get r's current cgroup in rcgpath
	if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
		nih_error("%s: Could not determine the requested cgroup", __func__);
		return -1;
	}

	cgroup_len = strlen(cgroup);

	if (strlen(rcgpath) + cgroup_len > MAXPATHLEN) {
		nih_error("%s: Path name too long", __func__);
		return -1;
	}

	wcgroup = NIH_MUST( nih_strdup(NULL, cgroup) );
	if (!normalize_path(wcgroup))
		return -1;

	working = NIH_MUST( nih_strdup(NULL, rcgpath) );
	NIH_MUST( nih_strcat(&working, NULL, "/") );
	NIH_MUST( nih_strcat(&working, NULL, wcgroup) );

	if (!dir_exists(working)) {
		*existed = -1;
		return 0;
	}
	// must have write access to the parent dir
	copy = NIH_MUST( nih_strdup(NULL, working) );
	if (!(p1 = strrchr(copy, '/')))
		return -1;
	*p1 = '\0';
	if (!may_access(r.pid, r.uid, r.gid, copy, O_WRONLY)) {
		nih_error("%s: pid %d (%u:%u) may not remove %s", __func__,
			r.pid, r.uid, r.gid, copy);
		return -1;
	}

	if (!recursive) {
		if (rmdir(working) < 0) {
			nih_error("%s: Failed to remove %s: %s", __func__, working, strerror(errno));
			return -1;
		}
	} else if (recursive_rmdir(working) < 0)
			return -1;

	nih_info(_("Removed %s for %d (%u:%u)"), working, r.pid,
		 r.uid, r.gid);
	return 0;
}
Beispiel #13
0
static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
{
	connection_struct *conn = fsp->conn;
	struct smb_filename *smb_dname = fsp->fsp_name;
	int ret;

	SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));

	/* Might be a symlink. */
	if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
		return map_nt_error_from_unix(errno);
	}

	if (S_ISLNK(smb_dname->st.st_ex_mode)) {
		/* Is what it points to a directory ? */
		if(SMB_VFS_STAT(conn, smb_dname) != 0) {
			return map_nt_error_from_unix(errno);
		}
		if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
			return NT_STATUS_NOT_A_DIRECTORY;
		}
		ret = SMB_VFS_UNLINK(conn, smb_dname);
	} else {
		ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
	}
	if (ret == 0) {
		notify_fname(conn, NOTIFY_ACTION_REMOVED,
			     FILE_NOTIFY_CHANGE_DIR_NAME,
			     smb_dname->base_name);
		return NT_STATUS_OK;
	}

	if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), SNUM(conn))) {
		/*
		 * Check to see if the only thing in this directory are
		 * vetoed files/directories. If so then delete them and
		 * retry. If we fail to delete any of them (and we *don't*
		 * do a recursive delete) then fail the rmdir.
		 */
		SMB_STRUCT_STAT st;
		const char *dname = NULL;
		char *talloced = NULL;
		long dirpos = 0;
		struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
						  smb_dname->base_name, NULL,
						  0);

		if(dir_hnd == NULL) {
			errno = ENOTEMPTY;
			goto err;
		}

		while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
					    &talloced)) != NULL) {
			if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
				TALLOC_FREE(talloced);
				continue;
			}
			if (!is_visible_file(conn, smb_dname->base_name, dname,
					     &st, false)) {
				TALLOC_FREE(talloced);
				continue;
			}
			if(!IS_VETO_PATH(conn, dname)) {
				TALLOC_FREE(dir_hnd);
				TALLOC_FREE(talloced);
				errno = ENOTEMPTY;
				goto err;
			}
			TALLOC_FREE(talloced);
		}

		/* We only have veto files/directories.
		 * Are we allowed to delete them ? */

		if(!lp_delete_veto_files(SNUM(conn))) {
			TALLOC_FREE(dir_hnd);
			errno = ENOTEMPTY;
			goto err;
		}

		/* Do a recursive delete. */
		RewindDir(dir_hnd,&dirpos);
		while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
					    &talloced)) != NULL) {
			struct smb_filename *smb_dname_full = NULL;
			char *fullname = NULL;
			bool do_break = true;

			if (ISDOT(dname) || ISDOTDOT(dname)) {
				TALLOC_FREE(talloced);
				continue;
			}
			if (!is_visible_file(conn, smb_dname->base_name, dname,
					     &st, false)) {
				TALLOC_FREE(talloced);
				continue;
			}

			fullname = talloc_asprintf(ctx,
					"%s/%s",
					smb_dname->base_name,
					dname);

			if(!fullname) {
				errno = ENOMEM;
				goto err_break;
			}

			smb_dname_full = synthetic_smb_fname(
				talloc_tos(), fullname, NULL, NULL);
			if (smb_dname_full == NULL) {
				errno = ENOMEM;
				goto err_break;
			}

			if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
				goto err_break;
			}
			if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
				if(!recursive_rmdir(ctx, conn,
						    smb_dname_full)) {
					goto err_break;
				}
				if(SMB_VFS_RMDIR(conn,
					smb_dname_full->base_name) != 0) {
					goto err_break;
				}
			} else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
				goto err_break;
			}

			/* Successful iteration. */
			do_break = false;

		 err_break:
			TALLOC_FREE(fullname);
			TALLOC_FREE(smb_dname_full);
			TALLOC_FREE(talloced);
			if (do_break)
				break;
		}
		TALLOC_FREE(dir_hnd);
		/* Retry the rmdir */
		ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
	}

  err:

	if (ret != 0) {
		DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
			 "%s\n", smb_fname_str_dbg(smb_dname),
			 strerror(errno)));
		return map_nt_error_from_unix(errno);
	}

	notify_fname(conn, NOTIFY_ACTION_REMOVED,
		     FILE_NOTIFY_CHANGE_DIR_NAME,
		     smb_dname->base_name);

	return NT_STATUS_OK;
}
Beispiel #14
0
bool recursive_rmdir(TALLOC_CTX *ctx,
		     connection_struct *conn,
		     struct smb_filename *smb_dname)
{
	const char *dname = NULL;
	char *talloced = NULL;
	bool ret = True;
	long offset = 0;
	SMB_STRUCT_STAT st;
	struct smb_Dir *dir_hnd;

	SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));

	dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
	if(dir_hnd == NULL)
		return False;

	while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
		struct smb_filename *smb_dname_full = NULL;
		char *fullname = NULL;
		bool do_break = true;

		if (ISDOT(dname) || ISDOTDOT(dname)) {
			TALLOC_FREE(talloced);
			continue;
		}

		if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
				     false)) {
			TALLOC_FREE(talloced);
			continue;
		}

		/* Construct the full name. */
		fullname = talloc_asprintf(ctx,
				"%s/%s",
				smb_dname->base_name,
				dname);
		if (!fullname) {
			errno = ENOMEM;
			goto err_break;
		}

		smb_dname_full = synthetic_smb_fname(talloc_tos(), fullname,
						     NULL, NULL);
		if (smb_dname_full == NULL) {
			errno = ENOMEM;
			goto err_break;
		}

		if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
			goto err_break;
		}

		if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
			if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
				goto err_break;
			}
			if(SMB_VFS_RMDIR(conn,
					 smb_dname_full->base_name) != 0) {
				goto err_break;
			}
		} else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
			goto err_break;
		}

		/* Successful iteration. */
		do_break = false;

	 err_break:
		TALLOC_FREE(smb_dname_full);
		TALLOC_FREE(fullname);
		TALLOC_FREE(talloced);
		if (do_break) {
			ret = false;
			break;
		}
	}
	TALLOC_FREE(dir_hnd);
	return ret;
}
Beispiel #15
0
void
rcv_file_delete (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0;
	char dir[MAXPATHLEN], filename[NAME_MAX], oldbuf[MAXPATHLEN];
	char rsrcpath_old[MAXPATHLEN];
	struct stat sb, rsb;
	int err;

	dir[0] = 0;

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
		}
	dh_end()

	if (!fnlen && !dir[0]) {
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}

	if (dir[0]) {
		if (fnlen)
			snprintf(oldbuf, sizeof(oldbuf), "%s/%s", dir, filename);
		else
			strcpy(oldbuf, dir);
	} else {
		snprintf(oldbuf, sizeof(oldbuf), "%s/%s", ROOTDIR, filename);
	}
	if (check_dropbox(htlc, oldbuf)) {
		snd_strerror(htlc, EPERM);
		return;
	}

	if (log_delete)
		hxd_log("%s:%s:%u - delete %s", htlc->name, htlc->login, htlc->uid, oldbuf);

	if (SYS_lstat(oldbuf, &sb)) {
		snd_strerror(htlc, errno);
		return;
	}

#if defined(CONFIG_HFS)
	if (!hxd_cfg.operation.hfs)
		goto skiphfs;
	if (hxd_cfg.files.fork == HFS_FORK_CAP) {
		if (!S_ISDIR(sb.st_mode) && !resource_path(rsrcpath_old, oldbuf, &rsb)
		    && !S_ISDIR(rsb.st_mode)) {
			if (unlink(rsrcpath_old)) {
				snd_strerror(htlc, errno);
				return;
			}
		}
	}
	if (!finderinfo_path(rsrcpath_old, oldbuf, &rsb)) {
		if (unlink(rsrcpath_old)) {
			snd_strerror(htlc, errno);
			return;
		}
	}
skiphfs:
#endif /* CONFIG_HFS */

	if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode))
		err = recursive_rmdir(oldbuf);
	else
		err = unlink(oldbuf);

	if (err)
		snd_strerror(htlc, errno);
	else
		hlwrite(htlc, HTLS_HDR_TASK, 0, 0);
}
Beispiel #16
0
int migrate_collection(void * config, void * sconfig)
{
    char old_coll_path[PATH_MAX];
    char version[256];
    int ret;

    struct filesystem_configuration_s * fs_config = 
        (struct filesystem_configuration_s *) config;
    struct server_configuration_s * server_config =
        (struct server_configuration_s *) sconfig;

    memset(version, 0, 256);
    /* find version of source storage space */
    ret = src_get_version(
        server_config->storage_path, 
        fs_config->coll_id, 
        fs_config->file_system_name,
        version, 254);
    if(ret < 0)
    {
        fprintf(stderr, 
                "Error: failed to read version of src storage space\n"
                "       for filesystem: %s (%08x)\n",
                fs_config->file_system_name, fs_config->coll_id);
        return ret;
    }
        
    /* call the appropriate translation routine based on the version */
    if(strncmp(version, "0.0.1", 5) == 0)
    {
        sprintf(old_coll_path, "%s/%08x-old-%s",
                server_config->storage_path, 
                fs_config->coll_id, version);

        ret = access(old_coll_path, F_OK);
        if(ret == 0)
        {
            if(opts.cleanup_set)
            {
                /* user asked to remove this old collection instead
                 * of creating it
                 */
                if(verbose) printf("VERBOSE Removing old collection at: %s\n",
                                   old_coll_path);
                ret = recursive_rmdir(old_coll_path);
                if(ret < 0)
                {
                    fprintf(stderr, 
                            "Error: failed to remove %s\n", 
                            old_coll_path);
                    return -1;
                }
                return 0;
            }

            if(verbose) printf("VERBOSE %s already exists.\n", 
                               old_coll_path);
            fprintf(stderr, 
                    "Error: unable to confirm availability of backup subdirectory (%s)\n"
                    "       for migration of fs: %s (%08x).\n", 
                    old_coll_path,
                    fs_config->file_system_name,
                    fs_config->coll_id);
            fprintf(stderr, 
                    "Error: please make sure that the migration "
                    "has not already been performed.\n");
            return -1;
        }

        ret = translate_0_0_1(
            server_config->storage_path, old_coll_path, 
            fs_config->file_system_name, 
            fs_config->coll_id);
        if(ret < 0)
        {
            fprintf(stderr, 
                    "Error: failed to translate from %s collection\n"
                    "       for fs: %s (%08x).\n",
                    version, fs_config->file_system_name, fs_config->coll_id);
            return -1;
        }

        if(opts.cleanup_set)
        {
            /* user asked to remove this old collection instead
             * of creating it
             */
            if(verbose) printf("VERBOSE Removing old collection at: %s\n",
                               old_coll_path);
            ret = unlink(old_coll_path);
            if(ret < 0)
            {
                perror("unlink");
                return -1;
            }
        }
    }
    else
    {
        if(opts.cleanup_set)
        {
            /* user asked to remove this old collection instead
             * of creating it, but we don't know what the version
             * is anymore
             */
            DIR * storage_dir;
            struct dirent * next_dirent;
            char collname[PATH_MAX];
            int collname_length;
            int removed_olddirs = 0;

            collname_length = sprintf(collname, "%08x-old", fs_config->coll_id);

            storage_dir = opendir(server_config->storage_path);
            if(!storage_dir)
            {
                fprintf(stderr, "Error: failed to open directory: %s\n",
                        server_config->storage_path);
                return -1;
            }

            while((next_dirent = readdir(storage_dir)) != NULL)
            {
                int d_namelen = strlen(next_dirent->d_name);
                if(collname_length < d_namelen &&
                   strncmp(next_dirent->d_name, collname, collname_length) == 0)
                {
                    char old_coll_path[PATH_MAX];

                    sprintf(old_coll_path, "%s/%s",
                            server_config->storage_path, next_dirent->d_name);

                    /* found an old version, delete it */
                    if(verbose) 
                        printf("VERBOSE Removing old collection at: %s\n",
                               old_coll_path);
                    ret = recursive_rmdir(old_coll_path);
                    if(ret < 0)
                    {
                        fprintf(
                            stderr, 
                            "Error: failed to remove old collection at: %s\n",
                            old_coll_path);
                        closedir(storage_dir);
                        return -1;
                    }
                    removed_olddirs = 1;
                }
            }

            if(removed_olddirs == 0)
            {
                printf("\nWARNING: No old collections with name \"%s\" "
                       "were found to cleanup.\n",
                       fs_config->file_system_name);
            }

            closedir(storage_dir);
        }
        else
        {
            /* complain if we don't recognize the version */
            fprintf(stderr, 
                    "Error: unknown collection version: %s\n"
                    "       for fs: %s (%08x).\n", 
                    version, fs_config->file_system_name, fs_config->coll_id);
            return -1;
        }
    }

    return 0;
}