Lephisto/src/lfile.c

190 lines
3.8 KiB
C

#include <string.h>
#include <stdarg.h>
#ifdef LINUX
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#endif
#include "lephisto.h"
#include "log.h"
#include "lfile.h"
/* Return lephisto's base path. */
static char lephisto_base[128] = "\0";
char* lfile_basePath(void) {
char* home;
if(lephisto_base[0] == '\0') {
#ifdef LINUX
home = getenv("HOME");
#else
#error "Needs implentation."
#endif
snprintf(lephisto_base, PATH_MAX, "%s/.lephisto/", home);
}
return lephisto_base;
}
/* Check if a directory exists, and create it if it doesn't. */
/* Based on lephisto_base. */
int lfile_dirMakeExist(const char* path) {
char file[PATH_MAX];
#ifdef LINUX
struct stat buf;
if(strcmp(path, ".")==0) {
strncpy(file, lfile_basePath(), PATH_MAX);
file[PATH_MAX-1] = '\0';
}
else
snprintf(file, PATH_MAX, "%s%s", lfile_basePath(), path);
stat(file, &buf);
if(!S_ISDIR(buf.st_mode))
if(mkdir(file, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
WARN("Dir '%s' does not exist and unable to create", path);
return -1;
}
#else
#error "Needs implentation."
#endif
return 0;
}
/* Check if a file exists. */
int lfile_fileExists(const char* path, ...) {
char file[PATH_MAX], name[PATH_MAX];
va_list ap;
size_t l;
l = 0;
if(path == NULL) return -1;
else { /* Get the message. */
va_start(ap, path);
vsnprintf(name, PATH_MAX-l, path, ap);
l = strlen(name);
va_end(ap);
}
snprintf(file, PATH_MAX, "%s%s", lfile_basePath(), name);
#ifdef LINUX
struct stat buf;
if(stat(file, &buf)==0) /* Stat worked, file must exist. */
return 1;
#else
#error "Needs implementation."
#endif
return 0;
}
/* List all the files in a dir (besides . and ..). */
char** lfile_readDir(int* lfiles, const char* path) {
char file[PATH_MAX];
char** files;
snprintf(file, PATH_MAX, "%s%s", lfile_basePath(), path);
#ifdef LINUX
int i, j, k, n;
DIR* d;
struct dirent *dir;
char* name;
int mfiles;
struct stat sb;
time_t* tt, *ft;
char** tfiles;
(*lfiles) = 0;
mfiles = 100;
tfiles = malloc(sizeof(char*)*mfiles);
tt = malloc(sizeof(time_t)*mfiles);
d = opendir(file);
if(d == NULL)
return NULL;
/* Get the file list. */
while((dir = readdir(d)) != NULL) {
name = dir->d_name;
/* Skip hidden directories. */
if(name[0] == '.')
continue;
/* Stat the file. */
snprintf(file, PATH_MAX, "%s%s/%s", lfile_basePath(), path, name);
if(stat(file, &sb) == -1)
continue; /* Unable to stat. */
/* Enough memory? */
if((*lfiles)+1 > mfiles) {
mfiles += 100;
tfiles = realloc(files, sizeof(char*) * mfiles);
tt = realloc(tt, sizeof(time_t) * mfiles);
}
/* Write the information. */
tfiles[(*lfiles)] = strdup(name);
tt[(*lfiles)] = sb.st_mtime;
(*lfiles)++;
}
closedir(d);
/* Sort by last changed date. */
if((*lfiles) > 0) {
/* Need to allocate some stuff. */
files = malloc(sizeof(char*)*(*lfiles));
ft = malloc(sizeof(time_t)*(*lfiles));
/* Fill the list. */
for(i = 0; i < (*lfiles); i++) {
n = -1;
/* Get the next lowest. */
for(j = 0; j < (*lfiles); j++) {
/* Is lower? */
if((n == -1) || (tt[j] > tt[n])) {
/* Check if it's already there. */
for(k = 0; k < i; k++)
if(strcmp(files[k], tfiles[j])==0)
break;
/* New lowest. */
if(k >= i)
n = j;
}
}
files[i] = tfiles[n];
ft[i] = tt[n];
}
free(ft);
} else
files = NULL;
/* Free temp stuff. */
free(tfiles);
free(tt);
#else
#error "Needs implementation."
#endif
/* What if we find nothing? */
if((*lfiles) == 0) {
free(files);
files = NULL;
}
return files;
}