Mon, 12 Aug 2024 21:20:17 +0200
fix memory leak in case handle_request fails (some illegal requests)
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2022 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 WS_PG_VFS_H #define WS_PG_VFS_H #include "../../public/nsapi.h" #include "../../public/vfs.h" #include "config.h" #include <libpq-fe.h> #include <libpq/libpq-fs.h> #ifdef __cplusplus extern "C" { #endif #define PG_ETAG_MAXLEN 48 typedef struct PgVFS { ResourceData *pg_resource; PGconn *connection; char root_resource_id_str[32]; int64_t root_resource_id; } PgVFS; typedef struct PgFile { int64_t resource_id; int64_t parent_id; WSBool iscollection; Oid oid; int fd; int oflags; char etag[PG_ETAG_MAXLEN]; struct stat s; } PgFile; typedef struct PgDir { VFSFile *file; PGresult *result; int row; int nrows; } PgDir; void* pg_vfs_init(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config); VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb, void *initData); VFS* pg_vfs_create_from_resourcedata(Session *sn, Request *rq, PgRepository *repo, ResourceData *resdata); /* * Resolve a path into a parent_id and resource name * * Only absolute paths are supported, therefore path[0] must be '/' * * If the resource is not found, res_errno is set to ENOENT */ int pg_resolve_path( PGconn *connection, const char *path, const char *root_id, int64_t *parent_id, int64_t *resource_id, Oid *oid, const char **resource_name, WSBool *iscollection, struct stat *s, char *etag, int *res_errno); void pg_set_stat( struct stat *s, const char *iscollection, const char *lastmodified, const char *creationdate, const char *contentlength); int pg_create_file( VFSContext *ctx, PgVFS *pg, const char *path, int64_t *new_resource_id, int64_t *res_parent_id, Oid *oid, const char **resource_name, struct stat *s, WSBool collection); int pg_remove_res( VFSContext *ctx, PgVFS *pg, int64_t resource_id, Oid oid); int pg_update_resource(PgVFS *pg, int64_t resource_id, int64_t contentlength); SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags); int pg_vfs_stat(VFSContext *ctx, const char *path, struct stat *buf); int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf); VFS_DIR pg_vfs_opendir(VFSContext *ctx, const char *path); VFS_DIR pg_vfs_fdopendir(VFSContext *ctx, SYS_FILE fd); int pg_vfs_mkdir(VFSContext *ctx, const char *path); int pg_vfs_unlink(VFSContext *ctx, const char *path); int pg_vfs_rmdir(VFSContext *ctx, const char *path); ssize_t pg_vfs_io_read(SYS_FILE fd, void *buf, size_t nbyte); ssize_t pg_vfs_io_write(SYS_FILE fd, const void *buf, size_t nbyte); ssize_t pg_vfs_io_pread(SYS_FILE fd, void *buf, size_t nbyte, off_t offset); ssize_t pg_vfs_io_pwrite(SYS_FILE fd, const void *buf, size_t nbyte, off_t offset); off_t pg_vfs_io_seek(SYS_FILE fd, off_t offset, int whence); off_t pg_vfs_io_tell(SYS_FILE fd); void pg_vfs_io_close(SYS_FILE fd); const char *pg_vfs_io_getetag(SYS_FILE fd); int pg_vfs_dirio_readdir(VFS_DIR dir, VFS_ENTRY *entry, int getstat); void pg_vfs_dirio_close(VFS_DIR dir); time_t pg_convert_timestamp(const char *timestamp); int pg_convert_timestamp_tm(const char *timestamp, struct tm *tm); #ifdef __cplusplus } #endif #endif /* WS_PG_VFS_H */