/* Copyright (C) 2019 C. McEnroe * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Additional permission under GNU GPL version 3 section 7: * * If you modify this Program, or any covered work, by linking or * combining it with OpenSSL (or a modified version of that library), * containing parts covered by the terms of the OpenSSL License and the * original SSLeay license, the licensors of this Program grant you * additional permission to convey the resulting work. Corresponding * Source for a non-source form of such a combination shall include the * source code for the parts of OpenSSL used as well as that of the * covered work. */ #include #include #include typedef int Read(void *, char *, int); typedef int Write(void *, const char *, int); typedef fpos_t Seek(void *, fpos_t, int); typedef int Close(void *); struct Funopen { void *cookie; Read *readfn; Write *writefn; Close *closefn; }; static ssize_t cookieRead(void *cookie, char *buf, size_t size) { struct Funopen *funopen = cookie; return funopen->readfn(funopen->cookie, buf, size); } static ssize_t cookieWrite(void *cookie, const char *buf, size_t size) { struct Funopen *funopen = cookie; return funopen->writefn(funopen->cookie, buf, size); } static int cookieClose(void *cookie) { struct Funopen *funopen = cookie; int ret = 0; if (funopen->closefn) ret = funopen->closefn(funopen->cookie); free(cookie); return ret; } FILE *funopen( const void *cookie, Read *readfn, Write *writefn, Seek *seekfn, Close *closefn ) { struct Funopen *funopen = malloc(sizeof(*funopen)); if (!funopen) return NULL; funopen->cookie = (void *)cookie; funopen->readfn = readfn; funopen->writefn = writefn; assert(!seekfn); funopen->closefn = closefn; cookie_io_functions_t fns = { .read = (readfn ? cookieRead : NULL), .write = (writefn ? cookieWrite : NULL), .close = cookieClose, }; return fopencookie(funopen, (!readfn ? "w" : !writefn ? "r" : "r+"), fns); }