Tue, 13 Nov 2018 23:33:59 +0100
fixes dav_session_get_href() generating random names when encrypt-name is disabled
/* * 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 <sys/stat.h> #include <sys/types.h> #ifndef _WIN32 #include <unistd.h> #endif #include "system.h" void sys_freedirent(SysDirEnt *ent) { free(ent->name); free(ent); } #ifndef _WIN32 /* ---------- POSIX implementation ---------- */ SYS_DIR sys_opendir(const char *path) { DIR *dir = opendir(path); if(!dir) { return NULL; } SysDir *d = malloc(sizeof(SysDir)); d->dir = dir; d->ent = NULL; return d; } SysDirEnt* sys_readdir(SYS_DIR dir) { if(dir->ent) { free(dir->ent->name); free(dir->ent); dir->ent = NULL; } struct dirent *ent = readdir(dir->dir); if(ent) { SysDirEnt *e = malloc(sizeof(SysDirEnt)); e->name = strdup(ent->d_name); dir->ent = e; return e; } return NULL; } void sys_closedir(SYS_DIR dir) { closedir(dir->dir); if(dir->ent) { free(dir->ent->name); free(dir->ent); } free(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); } int sys_rename(const char *oldpath, const char *newpath) { return rename(oldpath, newpath); } int sys_unlink(const char *path) { return unlink(path); } int sys_mkdir(const char *path) { return mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); } #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+1, 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; } dir->ent = NULL; return dir; } SysDirEnt* sys_readdir(SYS_DIR dir) { if(dir->ent) { free(dir->ent->name); free(dir->ent); dir->ent = NULL; } 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; dir->ent = ent; return ent; } else { return NULL; } } void sys_closedir(SYS_DIR dir) { if(dir->ent) { free(dir->ent->name); free(dir->ent); } 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; } int sys_rename(const char *oldpath, const char *newpath) { wchar_t *o = path2winpath(oldpath, FALSE, NULL); wchar_t *n = path2winpath(newpath, FALSE, NULL); if(!o || !n) { return -1; } struct __stat64 s; if(!_wstat64(n, &s)) { if(_wunlink(n)) { fprintf(stderr, "sys_rename: cannot delete existing file: %ls\n", n); } } int ret = _wrename(o, n); free(o); free(n); return ret; } int sys_unlink(const char *path) { wchar_t *wpath = path2winpath(path, FALSE, NULL); if(!wpath) { fprintf(stderr, "sys_unlink: cannot convert path\n"); return -1; } int ret = _wunlink(wpath); free(wpath); return ret; } int sys_mkdir(const char *path) { wchar_t *wpath = path2winpath(path, FALSE, NULL); if(!wpath) { fprintf(stderr, "sys_mkdir: cannot convert path\n"); return -1; } int ret = _wmkdir(wpath); free(wpath); return ret; } #endif