Fri, 08 Jun 2018 19:58:17 +0200
adds file io abstraction functions
dav/Makefile | file | annotate | diff | comparison | revisions | |
dav/main.c | file | annotate | diff | comparison | revisions | |
dav/system.c | file | annotate | diff | comparison | revisions | |
dav/system.h | file | annotate | diff | comparison | revisions |
--- a/dav/Makefile Sun Jun 03 16:05:49 2018 +0200 +++ b/dav/Makefile Fri Jun 08 19:58:17 2018 +0200 @@ -36,6 +36,7 @@ DAV_SRC += error.c DAV_SRC += assistant.c DAV_SRC += tar.c +DAV_SRC += system.c SYNC_SRC = sync.c SYNC_SRC += config.c @@ -46,6 +47,7 @@ SYNC_SRC += assistant.c SYNC_SRC += libxattr.c SYNC_SRC += tags.c +SYNC_SRC += system.c DAV_OBJ = $(DAV_SRC:%.c=../build/tool/%$(OBJ_EXT)) SYNC_OBJ = $(SYNC_SRC:%.c=../build/tool/%$(OBJ_EXT))
--- a/dav/main.c Sun Jun 03 16:05:49 2018 +0200 +++ b/dav/main.c Fri Jun 08 19:58:17 2018 +0200 @@ -45,6 +45,7 @@ #include "config.h" #include "error.h" #include "assistant.h" +#include "system.h" #include "main.h" static DavContext *ctx; @@ -890,8 +891,8 @@ int isstdout = !strcmp(out, "-"); if(cmd_getoption(a, "keep") && !isstdout) { - struct stat s; - if(stat(out, &s)) { + SYS_STAT s; + if(sys_stat(out, &s)) { if(errno != ENOENT) { perror("stat"); } @@ -908,7 +909,7 @@ printf("get: %s\n", res->path); } - FILE *fout = isstdout ? stdout : fopen(out, "wb"); + FILE *fout = isstdout ? stdout : sys_fopen(out, "wb"); if(!fout) { fprintf(stderr, "cannot open output file\n"); return -1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/system.c Fri Jun 08 19:58:17 2018 +0200 @@ -0,0 +1,183 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2018 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> + +#include "system.h" + +void sys_freedirent(SysDirEnt *ent) { + free(ent->name); + free(ent); +} + +#ifndef _WIN32 +/* ---------- POSIX implementation ---------- */ + +SYS_DIR sys_opendir(const char *path) { + return opendir(path); +} + +SysDirEnt* sys_readdir(SYS_DIR dir) { + struct dirent *ent = readdir(dir); + if(ent) { + SysDirEnt *e = malloc(sizeof(SysDirEnt)); + e->name = strdup(ent->d_name); + return e; + } + return NULL; +} + +void sys_closedir(SYS_DIR dir) { + closedir(dir); +} + +FILE* sys_fopen(const char *path, const char *mode) { + return fopen(path, mode); +} + +int sys_stat(const char *path, SYS_STAT *s) { + return stat(path, s); +} + + +#else +/* ---------- Windows implementation ---------- */ + +static wchar_t* path2winpath(const char *path, int dir, int *newlen) { + size_t len = strlen(path); + size_t lenadd = dir ? 2 : 0; + + + wchar_t *wpath = calloc(len+lenadd, sizeof(wchar_t)); + int wlen = MultiByteToWideChar( + CP_UTF8, + 0, + path, + len, + wpath, + len+1 + ); + if(newlen) { + *newlen = wlen; + } + for(int i=0;i<wlen;i++) { + if(wpath[i] == L'/') { + wpath[i] = L'\\'; + } + } + + if(dir) { + if(wpath[wlen-1] != L'\\') { + wpath[wlen++] = L'\\'; + } + wpath[wlen++] = L'*'; + } + wpath[wlen] = 0; + + return wpath; +} + +SYS_DIR sys_opendir(const char *path) { + struct WinDir *dir = malloc(sizeof(struct WinDir)); + wchar_t *dirpath = path2winpath(path, TRUE, NULL); + if(!dirpath) { + fprintf(stderr, "Cannot convert path \"%s\" to UTF16\n", path); + free(dir); + return NULL; + } + dir->first = 1; + dir->handle = FindFirstFileW(dirpath, &dir->finddata); + free(dirpath); + if(dir->handle == INVALID_HANDLE_VALUE) { + free(dir); + return NULL; + } + return dir; +} + +SysDirEnt* sys_readdir(SYS_DIR dir) { + if(dir->first) { + dir->first = 0; + } else { + if(FindNextFileW(dir->handle, &dir->finddata) == 0) { + return NULL; + } + } + + size_t namelen = wcslen(dir->finddata.cFileName); + + char *name = malloc((namelen+1)*4); + int nlen = WideCharToMultiByte( + CP_UTF8, + 0, + dir->finddata.cFileName, + -1, + name, + 256, + NULL, + NULL); + if(nlen > 0) { + name[nlen] = 0; + SysDirEnt *ent = malloc(sizeof(SysDirEnt)); + ent->name = name; + return ent; + } else { + return NULL; + } +} + +void sys_closedir(SYS_DIR dir) { + FindClose(dir->handle); + free(dir); +} + +FILE* sys_fopen(const char *path, const char *mode) { + wchar_t *fpath = path2winpath(path, FALSE, NULL); + wchar_t *fmode = path2winpath(mode, FALSE, NULL); + + FILE *file = (fpath && fmode) ? _wfopen(fpath, fmode) : NULL; + free(fpath); + free(fmode); + return file; +} + +int sys_stat(const char *path, SYS_STAT *s) { + wchar_t *fpath = path2winpath(path, FALSE, NULL); + if(!fpath) { + fprintf(stderr, "Cannot convert path \"%s\" to UTF16\n", path); + return -1; + } + int ret = _wstat64(fpath, s); + free(fpath); + return ret; +} + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/system.h Fri Jun 08 19:58:17 2018 +0200 @@ -0,0 +1,75 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2018 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DAV_SYSTEM_H +#define DAV_SYSTEM_H + +#include <stdio.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> + +#ifdef _WIN32 +#include <Windows.h> +struct WinDir { + int first; + HANDLE handle; + WIN32_FIND_DATAW finddata; +}; +#define SYS_DIR struct WinDir* +#define SYS_STAT struct __stat64 + +#else +#define SYS_DIR DIR* +#define SYS_STAT struct stat +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SysDirEnt { + char *name; +} SysDirEnt; + +void sys_freedirent(SysDirEnt *ent); +SYS_DIR sys_opendir(const char *path); +SysDirEnt* sys_readdir(SYS_DIR dir); +void sys_closedir(SYS_DIR dir); + +FILE* sys_fopen(const char *path, const char *mode); + +int sys_stat(const char *path, SYS_STAT *s); + +#ifdef __cplusplus +} +#endif + +#endif /* DAV_SYSTEM_H */ +