/* 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 . */ #ifdef __linux__ #define _GNU_SOURCE #include #include #include #include #include // Defined in libcrypto: void arc4random_buf(void *buf, size_t nbytes); #define NO_READPASSPHRASE_H #define RPP_STDIN 1 static inline char * readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) { if (flags) { if (!fgets(buf, bufsiz, stdin)) return NULL; return strsep(&buf, "\n"); } return getpass(prompt); } typedef int _readfn(void *, char *, int); typedef int _writefn(void *, const char *, int); typedef fpos_t _seekfn(void *, fpos_t, int); typedef int _closefn(void *); struct _funopen { void *cookie; _readfn *readfn; _writefn *writefn; _closefn *closefn; }; static inline ssize_t _cookie_read(void *cookie, char *buf, size_t size) { struct _funopen *funopen = cookie; assert((size_t)(int)size == size); return funopen->readfn(funopen->cookie, buf, size); } static inline ssize_t _cookie_write(void *cookie, const char *buf, size_t size) { struct _funopen *funopen = cookie; assert((size_t)(int)size == size); return funopen->writefn(funopen->cookie, buf, size); } static inline int _cookie_close(void *cookie) { struct _funopen *funopen = cookie; int ret = (funopen->closefn ? funopen->closefn(funopen->cookie) : 0); free(cookie); return ret; } static const cookie_io_functions_t _cookie_fns = { .read = _cookie_read, .write = _cookie_write, .close = _cookie_close, }; static inline FILE * funopen( const void *cookie, _readfn *readfn, _writefn *writefn, _seekfn *seekfn, _closefn *closefn ) { struct _funopen *funopen = malloc(sizeof(*funopen)); if (!funopen) return NULL; assert(!seekfn); *funopen = (struct _funopen) { (void *)cookie, readfn, writefn, closefn }; const char *mode = (!readfn ? "w" : !writefn ? "r" : "r+"); return fopencookie(funopen, mode, _cookie_fns); } #endif /* __linux__ */