diff options
author | David Oberhollenzer <david.oberhollenzer@tele2.at> | 2018-02-25 14:33:19 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@tele2.at> | 2018-03-24 17:04:20 +0100 |
commit | 9a88f7da453eadc72d8f333700dbd80777feecd1 (patch) | |
tree | 8a096e37123ece1d20bcb4d0ae8e064bdd39747a /lib/src/srvscan.c |
Initial commit
Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
Diffstat (limited to 'lib/src/srvscan.c')
-rw-r--r-- | lib/src/srvscan.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/lib/src/srvscan.c b/lib/src/srvscan.c new file mode 100644 index 0000000..71ad4f9 --- /dev/null +++ b/lib/src/srvscan.c @@ -0,0 +1,93 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <stddef.h> +#include <dirent.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> +#include <fcntl.h> +#include <ctype.h> + +#include "service.h" + +int srvscan(const char *directory, service_list_t *list) +{ + int i, dfd, type, ret = 0; + struct dirent *ent; + const char *ptr; + service_t *srv; + struct stat sb; + DIR *dir; + + for (i = 0; i < TGT_MAX; ++i) + list->targets[i] = NULL; + + dir = opendir(directory); + if (dir == NULL) { + perror(directory); + return -1; + } + + dfd = dirfd(dir); + if (dfd < 0) { + perror(directory); + closedir(dir); + return -1; + } + + for (;;) { + errno = 0; + ent = readdir(dir); + + if (ent == NULL) { + if (errno != 0) { + perror(directory); + ret = -1; + } + break; + } + + for (ptr = ent->d_name; isalnum(*ptr) || *ptr == '_'; ++ptr) + ; + + if (*ptr != '\0' && *ptr != '@') + continue; + + if (fstatat(dfd, ent->d_name, &sb, AT_SYMLINK_NOFOLLOW)) { + fprintf(stderr, "stat %s/%s: %s\n", + directory, ent->d_name, strerror(errno)); + ret = -1; + continue; + } + + type = (sb.st_mode & S_IFMT); + + if (type != S_IFREG && type != S_IFLNK) + continue; + + srv = rdsrv(dfd, ent->d_name); + if (srv == NULL) { + ret = -1; + continue; + } + + srv->next = list->targets[srv->target]; + list->targets[srv->target] = srv; + } + + for (i = 0; i < TGT_MAX; ++i) { + if (list->targets[i] == NULL) + continue; + + errno = 0; + list->targets[i] = srv_tsort(list->targets[i]); + + if (errno != 0) { + fprintf(stderr, "sorting services read from %s: %s\n", + directory, strerror(errno)); + } + } + + closedir(dir); + return ret; +} |