+ /* if an existing directory exist remove it if force */
+ rc = stat(dest, &s);
+ if (rc == 0) {
+ if (!S_ISDIR(s.st_mode)) {
+ ERROR("in move_workdir, can't overwrite regular file %s", dest);
+ errno = EEXIST;
+ return -1;
+ }
+ if (!force) {
+ ERROR("in move_workdir, can't overwrite regular file %s", dest);
+ errno = EEXIST;
+ return -1;
+ }
+ rc = remove_directory_content(dest);
+ if (rc) {
+ ERROR("in move_workdir, can't clean dir %s", dest);
+ return rc;
+ }
+ rc = rmdir(dest);
+ if (rc) {
+ ERROR("in move_workdir, can't remove dir %s", dest);
+ return rc;
+ }
+ } else {
+ /* check parent of dest */
+ iter = strrchr(dest, '/');
+ len = iter ? (size_t)(iter - dest) : 0;
+ if (len) {
+ /* is parent existing? */
+ copy = strndupa(dest, len);
+ rc = stat(copy, &s);
+ if (!rc) {
+ /* found an entry */
+ if (!S_ISDIR(s.st_mode)) {
+ ERROR("in move_workdir, '%s' isn't a directory", copy);
+ errno = ENOTDIR;
+ return -1;
+ }
+ } else if (!parents) {
+ /* parent entry not found but not allowed to create it */
+ ERROR("in move_workdir, parent directory '%s' not found: %m", copy);
+ return -1;
+ } else if (create_directory(copy, dirmode, 1)) {
+ ERROR("in move_workdir, creation of directory %s failed: %m", copy);
+ return -1;
+ }
+ }
+ }
+
+ /* try to rename now */
+ close(workdirfd);
+ workdirfd = -1;
+ rc = renameat(AT_FDCWD, workdir, AT_FDCWD, dest);
+ if (rc) {
+ ERROR("in move_workdir, renameat failed %s -> %s: %m", workdir, dest);
+ return -1;
+ }
+
+ return set_workdir(dest, 0);