4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
25 #include <sys/types.h>
30 static int mode = 0700;
31 static char workdir[PATH_MAX];
33 /* removes recursively the content of a directory */
34 static int clean_dirfd(int dirfd)
44 dir = fdopendir(dirfd);
46 syslog(LOG_ERR, "opendir failed in clean_dirfd");
52 if (readdir_r(dir, &entry.entry, &ent) != 0) {
53 syslog(LOG_ERR, "readdir_r failed in clean_dirfd");
58 if (ent->d_name[0] == '.' && (ent->d_name[1] == 0
59 || (ent->d_name[1] == '.' && ent->d_name[2] == 0)))
61 cr = unlinkat(dirfd, ent->d_name, 0);
64 if (errno != EISDIR) {
65 syslog(LOG_ERR, "unlink of %s failed in clean_dirfd", ent->d_name);
68 fd = openat(dirfd, ent->d_name, O_DIRECTORY|O_RDONLY);
70 syslog(LOG_ERR, "opening directory %s failed in clean_dirfd", ent->d_name);
77 cr = unlinkat(dirfd, ent->d_name, AT_REMOVEDIR);
79 syslog(LOG_ERR, "rmdir of %s failed in clean_dirfd", ent->d_name);
89 /* removes recursively the content of a directory */
90 static int clean_dir(const char *directory)
94 fd = openat(AT_FDCWD, directory, O_DIRECTORY|O_RDONLY);
96 syslog(LOG_ERR, "opening directory %s failed in clean_dir", directory);
104 /* removes the content of the working directory */
105 int enter_workdir(int clean)
107 int rc = chdir(workdir);
109 syslog(LOG_ERR, "entring workdir %s failed", workdir);
111 rc = clean_dir(workdir);
115 /* removes the working directory */
116 void remove_workdir()
123 int set_workdir(const char *name, int create)
129 /* check the length */
130 length = strlen(name);
131 if (length >= sizeof workdir) {
132 syslog(LOG_ERR, "workdir name too long");
140 syslog(LOG_ERR, "no workdir %s", name);
143 rc = mkdir(name, mode);
145 syslog(LOG_ERR, "can't create workdir %s", name);
149 } else if (!S_ISDIR(s.st_mode)) {
150 syslog(LOG_ERR, "%s isn't a directory", name);
154 memcpy(workdir, name, 1+length);
158 int make_workdir_base(const char *root, const char *prefix, int reuse)
162 n = snprintf(workdir, sizeof workdir, "%s/%s", root, prefix);
163 if (n >= sizeof workdir) {
164 syslog(LOG_ERR, "workdir prefix too long");
168 r = (int)(sizeof workdir) - n;
170 /* create a temporary directory */
171 for (i = 0 ; ; i++) {
173 syslog(LOG_ERR, "exhaustion of workdirs");
176 l = snprintf(workdir + n, r, "%d", i);
178 syslog(LOG_ERR, "computed workdir too long");
182 if (!mkdir(workdir, mode))
184 if (errno != EEXIST) {
185 syslog(LOG_ERR, "error in creation of workdir %s: %m", workdir);
195 int make_workdir(int reuse)
197 return make_workdir_base(".", "PACK", reuse);
202 int result = open(workdir, O_PATH|O_DIRECTORY);
204 syslog(LOG_ERR, "can't get fd for workdir %.*s: %m", PATH_MAX, workdir);
208 int move_workdir(const char *dest, int parents, int force)