/*
- Copyright 2015 IoT.bzh
+ Copyright (C) 2015-2019 IoT.bzh
+
+ author: José Bollo <jose.bollo@iot.bzh>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
#include <string.h>
#include <errno.h>
#include <assert.h>
-#include <syslog.h>
#include <dirent.h>
#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <sys/stat.h>
-#include "wgtpkg.h"
+#include "verbose.h"
+#include "wgtpkg-workdir.h"
+#include "wgtpkg-files.h"
struct fdb {
unsigned int count;
return UINT_MAX;
len = sizeof(distributor_file_prefix)-1;
- if (memcmp(name, distributor_file_prefix, len))
+ if (strncmp(name, distributor_file_prefix, len))
return 0;
if (name[len] <= '0' || name[len] > '9')
return 0;
while ('0' <= name[len] && name[len] <= '9') {
nid = 10 * id + (unsigned int)(name[len++] - '0');
if (nid < id || nid == UINT_MAX) {
- syslog(LOG_WARNING, "number too big for %s", name);
+ WARNING("number too big for %s", name);
return 0;
}
id = nid;
/* allocations */
grow = realloc(allfiles.files, (allfiles.count + 1) * sizeof(struct filedesc *));
if (grow == NULL) {
- syslog(LOG_ERR, "realloc failed in get_filedesc");
+ ERROR("realloc failed in get_filedesc");
return NULL;
}
allfiles.files = grow;
if (sig) {
grow = realloc(allsignatures.files, (allsignatures.count + 1) * sizeof(struct filedesc *));
if (grow == NULL) {
- syslog(LOG_ERR, "second realloc failed in get_filedesc");
+ ERROR("second realloc failed in get_filedesc");
return NULL;
}
allsignatures.files = grow;
result = malloc(sizeof(struct filedesc) + strlen(name));
if (!result) {
- syslog(LOG_ERR, "calloc failed in get_filedesc");
+ ERROR("calloc failed in get_filedesc");
return NULL;
}
else if (desc->type == type_unset)
desc->type = type;
else {
- syslog(LOG_ERR, "redeclaration of %s in file_add", name);
+ ERROR("redeclaration of %s in file_add", name);
errno = EEXIST;
desc = NULL;
}
len = asprintf(&name, "%s%u%s", distributor_file_prefix, number, distributor_file_suffix);
if (len < 0)
- syslog(LOG_ERR, "asprintf failed in create_signature");
+ ERROR("asprintf failed in create_signature");
else {
assert(len > 0);
result = file_of_name(name);
allfiles.files[i]->flags &= flag_signature;
}
-static int fill_files_rec(char name[PATH_MAX], int offset)
+static int fill_files_rec(char name[PATH_MAX], unsigned offset)
{
- int len, err;
+ int err, fd;
+ unsigned len;
DIR *dir;
struct dirent *ent;
+ struct stat st;
- if (offset == 0)
- dir = opendir(".");
- else {
- dir = opendir(name);
- name[offset++] = '/';
+ fd = openat(workdirfd, offset ? name : ".", O_DIRECTORY|O_RDONLY);
+ if (fd < 0) {
+ ERROR("openat %.*s failed in fill_files_rec", offset, name);
+ return -1;
}
+ dir = fdopendir(fd);
if (!dir) {
- syslog(LOG_ERR, "opendir %.*s failed in zwr", offset, name);
+ ERROR("opendir %.*s failed in fill_files_rec", offset, name);
+ close(fd);
return -1;
}
+ if (offset)
+ name[offset++] = '/';
ent = readdir(dir);
while (ent != NULL) {
- len = strlen(ent->d_name);
+ len = (unsigned)strlen(ent->d_name);
if (ent->d_name[0] == '.' && (len == 1 ||
(ent->d_name[1] == '.' && len == 2)))
;
else if (offset + len >= PATH_MAX) {
closedir(dir);
- syslog(LOG_ERR, "name too long in fill_files_rec");
+ ERROR("name too long in fill_files_rec");
errno = ENAMETOOLONG;
return -1;
} else {
memcpy(name + offset, ent->d_name, 1+len);
+ if (ent->d_type == DT_UNKNOWN) {
+ fstatat(fd, ent->d_name, &st, 0);
+ if (S_ISREG(st.st_mode))
+ ent->d_type = DT_REG;
+ else if (S_ISDIR(st.st_mode))
+ ent->d_type = DT_DIR;
+ }
switch (ent->d_type) {
case DT_DIR:
if (file_add_directory(name) == NULL) {