summaryrefslogtreecommitdiffstats
path: root/wgtpkg-workdir.c
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2015-11-09 21:58:30 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2015-11-09 21:58:30 +0100
commitad9428741b9a8f91e68829433bd643eee101a665 (patch)
tree858d0f730ce57390bc7d4ce9ee8c5164670a39cb /wgtpkg-workdir.c
initial commit
Change-Id: Ib882fe057690e03e2f5d32ee7e0c594697dd46c8 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'wgtpkg-workdir.c')
-rw-r--r--wgtpkg-workdir.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/wgtpkg-workdir.c b/wgtpkg-workdir.c
new file mode 100644
index 0000000..4b0b08c
--- /dev/null
+++ b/wgtpkg-workdir.c
@@ -0,0 +1,166 @@
+/*
+ Copyright 2015 IoT.bzh
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+#include <syslog.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "wgtpkg.h"
+
+#ifndef PREDIR
+#define PREDIR "/tmp/"
+#endif
+
+static int mode = 0700;
+static char workdir[PATH_MAX];
+
+/* removes recursively the content of a directory */
+static int clean_dir()
+{
+ int cr;
+ DIR *dir;
+ struct dirent *ent;
+ struct {
+ struct dirent entry;
+ char spare[PATH_MAX];
+ } entry;
+
+ dir = opendir(".");
+ if (dir == NULL) {
+ syslog(LOG_ERR, "opendir failed in clean_dir");
+ return -1;
+ }
+
+ cr = -1;
+ for (;;) {
+ if (readdir_r(dir, &entry.entry, &ent) != 0) {
+ syslog(LOG_ERR, "readdir_r failed in clean_dir");
+ goto error;
+ }
+ if (ent == NULL)
+ break;
+ if (ent->d_name[0] == '.' && (ent->d_name[1] == 0
+ || (ent->d_name[1] == '.' && ent->d_name[2] == 0)))
+ continue;
+ cr = unlink(ent->d_name);
+ if (!cr)
+ continue;
+ if (errno != EISDIR) {
+ syslog(LOG_ERR, "unlink of %s failed in clean_dir", ent->d_name);
+ goto error;
+ }
+ if (chdir(ent->d_name)) {
+ syslog(LOG_ERR, "enter directory %s failed in clean_dir", ent->d_name);
+ goto error;
+ }
+ cr = clean_dir();
+ if (cr)
+ goto error;
+ if (chdir(".."))
+ goto error;
+ cr = rmdir(ent->d_name);
+ if (cr) {
+ syslog(LOG_ERR, "rmdir of %s failed in clean_dir", ent->d_name);
+ goto error;
+ }
+ }
+ cr = 0;
+error:
+ closedir(dir);
+ return cr;
+}
+
+/* removes the content of the working directory */
+int enter_workdir(int clean)
+{
+ int rc = chdir(workdir);
+ if (rc)
+ syslog(LOG_ERR, "entring workdir %s failed", workdir);
+ else if (clean)
+ rc = clean_dir();
+ return rc;
+}
+
+/* removes the working directory */
+void remove_workdir()
+{
+ enter_workdir(1);
+ chdir("..");
+ unlink(workdir);
+}
+
+int set_workdir(const char *name, int create)
+{
+ int rc;
+ size_t length;
+ struct stat s;
+
+ /* check the length */
+ length = strlen(name);
+ if (length >= sizeof workdir) {
+ syslog(LOG_ERR, "workdir name too long");
+ return -1;
+ }
+
+ rc = stat(name, &s);
+ if (rc) {
+ if (!create) {
+ syslog(LOG_ERR, "no workdir %s", name);
+ return -1;
+ }
+ rc = mkdir(name, mode);
+ if (rc) {
+ syslog(LOG_ERR, "can't create workdir %s", name);
+ return -1;
+ }
+
+ } else if (!S_ISDIR(s.st_mode)) {
+ syslog(LOG_ERR, "%s isn't a directory", name);
+ return -1;
+ }
+ memcpy(workdir, name, 1+length);
+ return 0;
+}
+
+/* install the widgets of the list */
+int make_workdir(int reuse)
+{
+ int i;
+
+ /* create a temporary directory */
+ for (i = 0 ; ; i++) {
+ if (i == INT_MAX) {
+ syslog(LOG_ERR, "exhaustion of workdirs");
+ return -1;
+ }
+ sprintf(workdir, PREDIR "PACK%d", i);
+ if (!mkdir(workdir, mode))
+ break;
+ if (errno != EEXIST) {
+ syslog(LOG_ERR, "error in creation of workdir %s: %m", workdir);
+ return -1;
+ }
+ if (reuse)
+ break;
+ }
+
+ return 0;
+}
+