summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorBert <ber.t@gmx.com>2011-04-08 10:23:42 +0200
committerBert <ber.t@gmx.com>2011-04-08 10:23:42 +0200
commita90bd1c833b3475e434bd2de95ab9dd0347f1780 (patch)
treea7500bd675b360719eaf0f9e4b3727b864991864 /util.c
parente9996882cb55c5b6974a3448f29bda32d6aa373d (diff)
downloadnsxiv-a90bd1c833b3475e434bd2de95ab9dd0347f1780.tar.zst
Refactored recursive directory util functions
Diffstat (limited to 'util.c')
-rw-r--r--util.c178
1 files changed, 99 insertions, 79 deletions
diff --git a/util.c b/util.c
index a8ebe73..e16de94 100644
--- a/util.c
+++ b/util.c
@@ -18,7 +18,6 @@
#include <stdlib.h>
#include <string.h>
-#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -28,7 +27,6 @@
#include "util.h"
#define DNAME_CNT 512
-#define FNAME_CNT 1024
#define FNAME_LEN 1024
void cleanup();
@@ -161,7 +159,105 @@ end:
return path;
}
-int create_dir_rec(const char *path) {
+int r_opendir(r_dir_t *rdir, const char *dirname) {
+ if (!rdir || !dirname || !*dirname)
+ return -1;
+
+ if (!(rdir->dir = opendir(dirname))) {
+ rdir->name = NULL;
+ rdir->stack = NULL;
+ return -1;
+ }
+
+ rdir->stcap = DNAME_CNT;
+ rdir->stack = (char**) s_malloc(rdir->stcap * sizeof(char*));
+ rdir->stlen = 0;
+
+ rdir->name = (char*) dirname;
+ rdir->d = 0;
+
+ return 0;
+}
+
+int r_closedir(r_dir_t *rdir) {
+ int ret = 0;
+
+ if (!rdir)
+ return -1;
+
+ if (rdir->stack) {
+ while (rdir->stlen > 0)
+ free(rdir->stack[--rdir->stlen]);
+ free(rdir->stack);
+ rdir->stack = NULL;
+ }
+
+ if (rdir->dir) {
+ if (!(ret = closedir(rdir->dir)))
+ rdir->dir = NULL;
+ }
+
+ if (rdir->d && rdir->name) {
+ free(rdir->name);
+ rdir->name = NULL;
+ }
+
+ return ret;
+}
+
+char* r_readdir(r_dir_t *rdir) {
+ size_t len;
+ char *filename;
+ struct dirent *dentry;
+ struct stat fstats;
+
+ if (!rdir || !rdir->dir || !rdir->name)
+ return NULL;
+
+ while (1) {
+ if (rdir->dir && (dentry = readdir(rdir->dir))) {
+ if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
+ continue;
+
+ len = strlen(rdir->name) + strlen(dentry->d_name) + 2;
+ filename = (char*) s_malloc(len);
+ snprintf(filename, len, "%s%s%s", rdir->name,
+ rdir->name[strlen(rdir->name)-1] == '/' ? "" : "/",
+ dentry->d_name);
+
+ if (!stat(filename, &fstats) && S_ISDIR(fstats.st_mode)) {
+ /* put subdirectory on the stack */
+ if (rdir->stlen == rdir->stcap) {
+ rdir->stcap *= 2;
+ rdir->stack = (char**) s_realloc(rdir->stack,
+ rdir->stcap * sizeof(char*));
+ }
+ rdir->stack[rdir->stlen++] = filename;
+ continue;
+ }
+ return filename;
+ }
+
+ if (rdir->stlen > 0) {
+ /* open next subdirectory */
+ closedir(rdir->dir);
+ if (rdir->d)
+ free(rdir->name);
+ rdir->name = rdir->stack[--rdir->stlen];
+ rdir->d = 1;
+ if (!(rdir->dir = opendir(rdir->name)))
+ warn("could not open directory: %s", rdir->name);
+ continue;
+ }
+
+ /* no more entries */
+ break;
+ }
+
+ return NULL;
+}
+
+int r_mkdir(const char *path) {
char *dir, *d;
struct stat stats;
int err = 0;
@@ -202,82 +298,6 @@ int create_dir_rec(const char *path) {
return err;
}
-int fncmp(const void *a, const void *b) {
- return strcoll(*((char* const*) a), *((char* const*) b));
-}
-
-char** read_dir_rec(const char *dirname) {
- int dcnt, didx, fcnt, fidx;
- char **dnames, **fnames, *filename;
- unsigned char first;
- size_t len;
- DIR *dir;
- struct dirent *dentry;
- struct stat fstats;
-
- if (!dirname)
- return NULL;
-
- dcnt = DNAME_CNT;
- didx = first = 1;
- dnames = (char**) s_malloc(dcnt * sizeof(char*));
- dnames[0] = (char*) dirname;
-
- fcnt = FNAME_CNT;
- fidx = 0;
- fnames = (char**) s_malloc(fcnt * sizeof(char*));
-
- while (didx > 0) {
- dirname = dnames[--didx];
- if (!(dir = opendir(dirname))) {
- warn("could not open directory: %s", dirname);
- } else {
- while ((dentry = readdir(dir))) {
- if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
- continue;
-
- len = strlen(dirname) + strlen(dentry->d_name) + 2;
- filename = (char*) s_malloc(len * sizeof(char));
- snprintf(filename, len, "%s%s%s", dirname,
- dirname[strlen(dirname)-1] == '/' ? "" : "/", dentry->d_name);
-
- if (!stat(filename, &fstats) && S_ISDIR(fstats.st_mode)) {
- if (didx == dcnt) {
- dcnt *= 2;
- dnames = (char**) s_realloc(dnames, dcnt * sizeof(char*));
- }
- dnames[didx++] = filename;
- } else {
- if (fidx + 1 == fcnt) {
- fcnt *= 2;
- fnames = (char**) s_realloc(fnames, fcnt * sizeof(char*));
- }
- fnames[fidx++] = filename;
- }
- }
- closedir(dir);
- }
-
- if (!first)
- free((void*) dirname);
- else
- first = 0;
- }
-
- if (!fidx) {
- free(fnames);
- fnames = NULL;
- } else {
- if (fidx > 1)
- qsort(fnames, fidx, sizeof(char*), fncmp);
- fnames[fidx] = NULL;
- }
-
- free(dnames);
-
- return fnames;
-}
-
char* readline(FILE *stream) {
size_t len;
char *buf, *s, *end;