diff --git a/alpine/packages/transfused/Makefile b/alpine/packages/transfused/Makefile index d5739d5b7..f8a9b420f 100644 --- a/alpine/packages/transfused/Makefile +++ b/alpine/packages/transfused/Makefile @@ -1,6 +1,9 @@ .PHONY: all -DEPS=transfused.c +HDR=transfused.h transfused_log.h +SRC=transfused.c transfused_log.c +DEPS=$(HDR) $(SRC) + all: Dockerfile $(DEPS) docker build -t transfused:build . @@ -8,7 +11,7 @@ all: Dockerfile $(DEPS) chmod 755 transfused transfused: $(DEPS) - gcc -g -static -Wall -Werror -o transfused transfused.c + gcc -g -static -Wall -Werror -o transfused $(SRC) clean: rm -f transfused diff --git a/alpine/packages/transfused/etc/init.d/transfused b/alpine/packages/transfused/etc/init.d/transfused index a2731d051..063322c5d 100755 --- a/alpine/packages/transfused/etc/init.d/transfused +++ b/alpine/packages/transfused/etc/init.d/transfused @@ -13,16 +13,28 @@ start() ebegin "Starting FUSE socket passthrough" - PIDFILE=/var/run/transfused.pid - LOGFILE=/var/log/transfused.log + if cat /proc/cmdline | grep -q 'com.docker.driverDir' + then + DRIVERDIR="/Mac$(cat /proc/cmdline | sed -e 's/.*com.docker.driverDir="//' -e 's/".*//')" + RUNTIME_LOGFILE=${DRIVERDIR}/log/transfused.log + else + ID=$(LC_CTYPE=C tr -dc A-Za-z0-9 < /dev/urandom | head -c 8) + RUNTIME_LOGFILE="/Mac/private/tmp/transfused_${ID}.log" + fi + + PIDFILE=/var/run/transfused.pid + STARTUP_LOGFILE=/var/transfused_start.log + MOUNT_TRIGGER=/Mac start-stop-daemon --start --quiet \ --background \ --exec /sbin/transfused \ --pidfile ${PIDFILE} \ - --stderr "${LOGFILE}" \ - --stdout "${LOGFILE}" \ - -- -p "${PIDFILE}" + -- \ + -p "${PIDFILE}" \ + -l "${STARTUP_LOGFILE}" \ + -m "${MOUNT_TRIGGER}" \ + -t "${RUNTIME_LOGFILE}" eend $? "Failed to start transfused" } diff --git a/alpine/packages/transfused/transfused.c b/alpine/packages/transfused/transfused.c index 64b5e369c..7ad5aaf0f 100644 --- a/alpine/packages/transfused/transfused.c +++ b/alpine/packages/transfused/transfused.c @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -17,6 +17,11 @@ #include #include +#include +#include + +#include "transfused_log.h" + #define COPY_BUFSZ 65536 #define DEFAULT_FUSERMOUNT "/bin/fusermount" @@ -33,23 +38,16 @@ char * default_fusermount = DEFAULT_FUSERMOUNT; char * default_socket9p_root = DEFAULT_SOCKET9P_ROOT; char * usage = "usage: transfused [-p pidfile] [-9 socket9p_root] [-f fusermount]\n" + " [-l logfile] [-m mount_trigger] [-t triggerlog]\n" " -p pidfile\tthe path at which to write the pid of the process\n" " -9 " DEFAULT_SOCKET9P_ROOT "\tthe root of the 9p socket file system\n" - " -f " DEFAULT_FUSERMOUNT "\tthe fusermount executable to use\n"; + " -f " DEFAULT_FUSERMOUNT "\tthe fusermount executable to use\n" + " -l logfile\tthe log file to use before the mount trigger\n" + " -m mount_trigger\tthe mountpoint to use to trigger log switchover\n" + " -t triggerlog\tthe file to use after the trigger\n"; int debug = 0; -typedef struct { - char * socket9p_root; - char * fusermount; - char * pidfile; -} parameters; - -typedef struct { - parameters * params; - long id; -} connection_state; - typedef struct { char * descr; long connection; @@ -64,15 +62,6 @@ pid_t gettid() { return syscall(SYS_gettid); } -void die(int exit_code, const char * perror_arg, const char * fmt, ...) { - va_list argp; - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); - if (perror_arg != NULL) perror(perror_arg); - exit(exit_code); -} - void * must_malloc(char *const descr, size_t size) { void * ptr; @@ -82,7 +71,29 @@ void * must_malloc(char *const descr, size_t size) { return ptr; } -char ** read_opts(connection_state * connection, char * buf) { +void cond_init(char *const descr, pthread_cond_t * cond, + const pthread_condattr_t *restrict attr) { + if ((errno = pthread_cond_init(cond, attr))) + die(1, "", "cond init %s: ", descr); +} + +void lock_init(char *const descr, pthread_mutex_t * mutex, + const pthread_mutexattr_t *restrict attr) { + if ((errno = pthread_mutex_init(mutex, attr))) + die(1, "", "lock init %s: ", descr); +} + +void lock(char *const descr, pthread_mutex_t * mutex) { + if ((errno = pthread_mutex_lock(mutex))) + die(1, "", "lock %s: ", descr); +} + +void unlock(char *const descr, pthread_mutex_t * mutex) { + if ((errno = pthread_mutex_unlock(mutex))) + die(1, "", "unlock %s: ", descr); +} + +char ** read_opts(connection_t * connection, char * buf) { int read_fd; char * read_path; int read_count; @@ -159,7 +170,7 @@ void copy(copy_thread_state * copy_state) { die(1, "", "copy %s trace: error writing %s: ", descr, trace_path); if (write_count != read_count) - die(1, NULL, "copy %s trace: read %d but only wrote %d\n", + die(1, NULL, "copy %s trace: read %d but only wrote %d", descr, read_count, write_count); close(trace_fd); @@ -170,7 +181,7 @@ void copy(copy_thread_state * copy_state) { if (write_count == -1) die(1, "", "copy %s: error writing: ", descr); if (write_count != read_count) - die(1, NULL, "copy %s: read %d but only wrote %d\n", + die(1, NULL, "copy %s: read %d but only wrote %d", descr, read_count, write_count); } @@ -203,6 +214,10 @@ void * copy_clean_to(copy_thread_state * copy_state) { return NULL; } +void * copy_clean_to_thread(void * copy_state) { + return (copy_clean_to((copy_thread_state *) copy_state)); +} + int recv_fd(int sock) { int ret; int fd = -1; @@ -239,8 +254,7 @@ int recv_fd(int sock) { } // optv must be null-terminated -int get_fuse_sock(char * fusermount, char *const optv[]) { - int optc; +int get_fuse_sock(connection_t * conn, int optc, char *const optv[]) { char ** argv; char * envp[2]; pid_t fusermount_pid; @@ -249,13 +263,17 @@ int get_fuse_sock(char * fusermount, char *const optv[]) { int fd; // prepare argv from optv - for (optc = 0; optv[optc] != NULL; optc++) {} - argv = (char **) must_malloc("fusermount argv", (optc + 2) * sizeof(char *)); - argv[0] = fusermount; + argv[0] = conn->params->fusermount; memcpy(&argv[1], optv, (optc + 1) * sizeof(char *)); + lock("get_fuse_sock fd_lock", &conn->params->fd_lock); + log_time_locked(conn,"mount "); + for (int i = 0; argv[i]; i++) log_continue_locked(conn, "%s ",argv[i]); + log_continue_locked(conn, "\n"); + unlock("get_fuse_sock fd_lock", &conn->params->fd_lock); + // make the socket over which we'll be sent the FUSE socket fd if (socketpair(PF_UNIX, SOCK_STREAM, 0, fuse_socks)) die(1, "Couldn't create FUSE socketpair", ""); @@ -269,7 +287,7 @@ int get_fuse_sock(char * fusermount, char *const optv[]) { // fork and exec fusermount fusermount_pid = fork(); if (!fusermount_pid) // child - if (execve(fusermount, argv, envp)) + if (execve(argv[0], argv, envp)) die(1, "Failed to execute fusermount", ""); // parent @@ -282,16 +300,16 @@ int get_fuse_sock(char * fusermount, char *const optv[]) { // wait for fusermount to return waitpid(fusermount_pid, &status, 0); if (!WIFEXITED(status)) - die(1, NULL, "fusermount terminated abnormally\n"); + die(1, NULL, "fusermount terminated abnormally"); if (WEXITSTATUS(status)) - die(1, NULL, "fusermount exited with code %d\n", WEXITSTATUS(status)); + die(1, NULL, "fusermount exited with code %d", WEXITSTATUS(status)); - if (debug) fprintf(stderr, "about to recv_fd from fusermount\n"); + if (debug) log_time(conn, "about to recv_fd from fusermount\n"); fd = recv_fd(fuse_socks[1]); if (fd == -1) - die(1, NULL, "Couldn't receive fd over FUSE socket\n"); + die(1, NULL, "Couldn't receive fd over FUSE socket"); // close the read end of the socket close(fuse_socks[1]); @@ -299,7 +317,7 @@ int get_fuse_sock(char * fusermount, char *const optv[]) { return fd; } -void start_reader(connection_state * connection, int fuse) { +void start_reader(connection_t * connection, int fuse) { int read_fd; char * read_path; pthread_t child; @@ -326,13 +344,14 @@ void start_reader(connection_state * connection, int fuse) { connection->id); if ((errno = pthread_detach(child))) - die (1, "", "couldn't detach read copy thread for connection '%ld': ", - connection->id); + die(1, "", "couldn't detach read copy thread for connection %ld: ", + connection->id); } -void do_write(connection_state * connection, int fuse) { +void start_writer(connection_t * connection, int fuse) { int write_fd; char * write_path; + pthread_t child; copy_thread_state * copy_state; if (asprintf(&write_path, "%s/connections/%ld/write", @@ -350,33 +369,76 @@ void do_write(connection_state * connection, int fuse) { copy_state->tag = "write"; copy_state->from = fuse; copy_state->to = write_fd; - copy_clean_to(copy_state); + if ((errno = pthread_create(&child, NULL, + copy_clean_to_thread, copy_state))) + die(1, "", "Couldn't create write copy thread for connection %ld: ", + connection->id); + + if ((errno = pthread_detach(child))) + die(1, "", "couldn't detach write copy thread for connection %ld: ", + connection->id); } -void * mount_connection(connection_state * connection) { +void * mount_connection(connection_t * conn) { + int optc; char ** optv; int fuse; char * buf; + pthread_mutex_t copy_lock; + pthread_cond_t copy_halt; + int should_halt = 0; buf = (char *) must_malloc("read_opts packet malloc", COPY_BUFSZ); - optv = read_opts(connection, buf); - fuse = get_fuse_sock(connection->params->fusermount, optv); - free(optv); + optv = read_opts(conn, buf); + + for (optc = 0; optv[optc] != NULL; optc++) {} + + fuse = get_fuse_sock(conn, optc, optv); free(buf); - start_reader(connection, fuse); - do_write(connection, fuse); - free(connection); + lock_init("copy_lock", ©_lock, NULL); + cond_init("copy_halt", ©_halt, NULL); + + start_reader(conn, fuse); + start_writer(conn, fuse); + + // trigger? + // TODO: strcmp scares me + // TODO: append logfile to trigger_log + if (conn->params->mount_trigger != NULL + && conn->params->trigger_log != NULL + && 0 == strcmp(optv[optc - 1], conn->params->mount_trigger)) { + + lock("trigger mount fd_lock", &conn->params->fd_lock); + log_time_locked(conn, "Log mount trigger fired on %s, logging to %s\n", + conn->params->mount_trigger, conn->params->trigger_log); + conn->params->trigger_fd = open(conn->params->trigger_log, + O_WRONLY | O_CREAT, 0600); + if (conn->params->trigger_fd == -1) + die(1, "", "Couldn't open trigger log %s: ", conn->params->trigger_log); + unlock("trigger mount fd_lock", &conn->params->fd_lock); + } + + free(optv); + + lock("copy lock", ©_lock); + while (!should_halt) + if ((errno = pthread_cond_wait(©_halt, ©_lock))) + die(1, "", "Couldn't wait for copy halt for connection %ld: ", + conn->id); + unlock("copy lock", ©_lock); + + free(conn); return NULL; } void * mount_thread(void * connection) { - return mount_connection((connection_state *) connection); + return mount_connection((connection_t *) connection); } -void write_pid(connection_state * connection) { +void write_pid(connection_t * connection) { int write_fd; char * write_path; pid_t pid = gettid(); @@ -401,7 +463,7 @@ void write_pid(connection_state * connection) { die(1, "Error writing pid", ""); if (write_count != pid_s_len) - die(1, NULL, "Error writing pid %s to socket: only wrote %d bytes\n", + die(1, NULL, "Error writing pid %s to socket: only wrote %d bytes", pid_s, write_count); close(write_fd); @@ -409,7 +471,7 @@ void write_pid(connection_state * connection) { free(write_path); } -void perform_syscall(uint8_t syscall, char path[]) { +void perform_syscall(connection_t * conn, uint8_t syscall, char path[]) { char * name; int r = 0; @@ -444,7 +506,7 @@ void perform_syscall(uint8_t syscall, char path[]) { die(1, NULL, "Unknown event syscall %" PRIu8, syscall); } - if (r != 0) fprintf(stderr, "Event %s error: %s", name, strerror(errno)); + if (r != 0) log_time(conn, "Event %s error: %s\n", name, strerror(errno)); } void * event_thread(void * connection_ptr) { @@ -452,7 +514,7 @@ void * event_thread(void * connection_ptr) { int read_fd; int read_count, event_len, path_len; void * buf; - connection_state * connection = connection_ptr; + connection_t * connection = connection_ptr; char * path; uint8_t syscall; @@ -476,19 +538,19 @@ void * event_thread(void * connection_ptr) { event_len = (int) ntohs(*((uint16_t *) buf)); - if (debug) fprintf(stderr, "read %d bytes from connection %ld\n", - read_count, connection->id); + if (debug) log_time(connection, "read %d bytes from connection %ld\n", + read_count, connection->id); if (read_count != event_len) { - fprintf(stderr, "event thread: only read %d of %d\n", - read_count, event_len); + log_time(connection, "event thread: only read %d of %d\n", + read_count, event_len); msg = must_malloc("event hex", read_count * 2 + 1); for (int i = 0; i < read_count; i++) { sprintf(((char *) msg) + (i * 2),"%02x",(int) (((char *) buf)[i])); } ((char *) msg)[read_count * 2] = 0; - fprintf(stderr, "message: %s\n", (char *) msg); + log_time(connection, "message: %s\n", (char *) msg); free(msg); continue; @@ -501,7 +563,7 @@ void * event_thread(void * connection_ptr) { syscall = *(((uint8_t *) buf) + 4 + path_len); // TODO: should this be in another thread? - perform_syscall(syscall, path); + perform_syscall(connection, syscall, path); } close(read_fd); @@ -529,8 +591,14 @@ void parse_parameters(int argc, char * argv[], parameters * params) { params->pidfile = NULL; params->socket9p_root = NULL; params->fusermount = NULL; + params->logfile = NULL; + params->logfile_fd = 0; + params->mount_trigger = NULL; + params->trigger_log = NULL; + params->trigger_fd = 0; + lock_init("fd_lock", ¶ms->fd_lock, NULL); - while ((c = getopt(argc, argv, ":p:9:f:")) != -1) { + while ((c = getopt(argc, argv, ":p:9:f:l:m:t:")) != -1) { switch(c) { case 'p': @@ -545,6 +613,18 @@ void parse_parameters(int argc, char * argv[], parameters * params) { params->fusermount = optarg; break; + case 'l': + params->logfile = optarg; + break; + + case 'm': + params->mount_trigger = optarg; + break; + + case 't': + params->trigger_log = optarg; + break; + case ':': fprintf(stderr, "Option -%c requires a path argument\n", optopt); errflg++; @@ -567,20 +647,47 @@ void parse_parameters(int argc, char * argv[], parameters * params) { } if (params->pidfile != NULL && access(params->pidfile, W_OK)) - if (errno != ENOENT) - die(2, "", "-p %s path to pidfile must be writable: ", params->pidfile); + if (errno != ENOENT) { + fprintf(stderr, "-p %s path to pidfile must be writable: ", + params->pidfile); + perror(""); + exit(2); + } if (params->fusermount == NULL) params->fusermount = default_fusermount; - if (access(params->fusermount, X_OK)) - die(2, "", "-f %s path to fusermount must be executable: ", - params->fusermount); + if (access(params->fusermount, X_OK)) { + fprintf(stderr, "-f %s path to fusermount must be executable: ", + params->fusermount); + perror(""); + exit(2); + } if (params->socket9p_root == NULL) params->socket9p_root = default_socket9p_root; - if (access(params->socket9p_root, X_OK)) - die(2, "", "-9 %s path to socket 9p root directory must be executable: ", - params->socket9p_root); + if (access(params->socket9p_root, X_OK)) { + fprintf(stderr, + "-9 %s path to socket 9p root directory must be executable: ", + params->socket9p_root); + perror(""); + exit(2); + } + + if (params->logfile != NULL && access(params->logfile, W_OK)) + if (errno != ENOENT) { + fprintf(stderr, "-l %s path to logfile must be writable: ", + params->logfile); + perror(""); + exit(2); + } + + if (params->mount_trigger != NULL + && access(params->mount_trigger, F_OK)) { + fprintf(stderr, "-m %s path to mount point must exist: ", + params->mount_trigger); + perror(""); + exit(2); + } } void write_pidfile(char * pidfile) { @@ -603,7 +710,7 @@ void write_pidfile(char * pidfile) { die(1, "", "Error writing pidfile %s: ", pidfile); if (write_count != pid_s_len) - die(1, NULL, "Error writing %s to pidfile %s: only wrote %d bytes\n", + die(1, NULL, "Error writing %s to pidfile %s: only wrote %d bytes", pid_s, pidfile, write_count); close(fd); @@ -617,11 +724,16 @@ void process_events(char * events_path, int events, parameters * params) { int read_count; long conn_id; pthread_t child; - connection_state * conn; + connection_t * conn; char * connection_type; void * (*connection_handler_thread)(void *); while (1) { + conn = (connection_t *) must_malloc("connection state", + sizeof(connection_t)); + conn->params = params; + conn->id = 0; + read_count = read(events, buf, ID_LEN - 1); if (read_count == -1) { die(1, "", "Error reading events path %s: ", events_path); @@ -629,7 +741,7 @@ void process_events(char * events_path, int events, parameters * params) { // TODO: this is probably the 9p server's fault due to // not dropping the read 0 to force short read if // the real read is flushed - fprintf(stderr, "read 0 from event stream %s\n", events_path); + log_time(conn, "read 0 from event stream %s\n", events_path); continue; } @@ -643,12 +755,9 @@ void process_events(char * events_path, int events, parameters * params) { conn_id = strtol(buf + 1, NULL, 10); if (errno) die(1, "failed", "Connection id of string '%s'", buf); - if (debug) fprintf(stderr, "handle connection %ld\n", conn_id); - - conn = (connection_state *) must_malloc("connection state", - sizeof(connection_state)); conn->id = conn_id; - conn->params = params; + + if (debug) log_time(conn, "handle connection %ld\n", conn_id); switch (buf[0]) { case 'm': @@ -672,7 +781,7 @@ void process_events(char * events_path, int events, parameters * params) { die(1, "", "Couldn't detach thread for %s connection '%ld': ", connection_type, conn_id); - if (debug) fprintf(stderr, "thread spawned\n"); + if (debug) log_time(conn, "thread spawned\n"); } } @@ -680,20 +789,37 @@ int main(int argc, char * argv[]) { int events; parameters params; char * events_path; + struct rlimit core_limit; + + core_limit.rlim_cur = RLIM_INFINITY; + core_limit.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &core_limit)) + die(1, "", "Couldn't set RLIMIT_CORE to RLIM_INFINITY"); + + openlog(argv[0], LOG_CONS | LOG_PERROR | LOG_NDELAY, LOG_DAEMON); parse_parameters(argc, argv, ¶ms); setup_debug(); if (params.pidfile != NULL) write_pidfile(params.pidfile); + if (params.logfile != NULL) { + params.logfile_fd = open(params.logfile, O_WRONLY | O_APPEND | O_CREAT); + if (params.logfile_fd == -1) + die(1, "", "Couldn't open log file %s: ", params.logfile); + } + if (asprintf(&events_path, "%s/events", params.socket9p_root) == -1) die(1, "Couldn't allocate events path", ""); events = open(events_path, O_RDONLY | O_CLOEXEC); if (events != -1) process_events(events_path, events, ¶ms); - fprintf(stderr, "Failed to open events path %s: %s\n", - events_path, strerror(errno)); + connection_t top; + top.params = ¶ms; + top.id = 0; + log_time(&top, "Failed to open events path %s: %s\n", + events_path, strerror(errno)); free(events_path); return 1; } diff --git a/alpine/packages/transfused/transfused.h b/alpine/packages/transfused/transfused.h new file mode 100644 index 000000000..56383b14e --- /dev/null +++ b/alpine/packages/transfused/transfused.h @@ -0,0 +1,22 @@ +#include + +typedef struct { + char * socket9p_root; + char * fusermount; + char * pidfile; + char * logfile; + char * mount_trigger; + char * trigger_log; + pthread_mutex_t fd_lock; + int logfile_fd; + int trigger_fd; +} parameters; + +typedef struct { + parameters * params; + long id; +} connection_t; + +void lock(char *const descr, pthread_mutex_t * mutex); + +void unlock(char *const descr, pthread_mutex_t * mutex); diff --git a/alpine/packages/transfused/transfused_log.c b/alpine/packages/transfused/transfused_log.c new file mode 100644 index 000000000..4d8375a15 --- /dev/null +++ b/alpine/packages/transfused/transfused_log.c @@ -0,0 +1,117 @@ +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "transfused.h" + +void log_timestamp(int fd) { + char timestamp[26]; + int msec; + struct tm* tm_info; + struct timeval tv; + + gettimeofday(&tv, NULL); + + msec = lrint(tv.tv_usec/1000.0); + if (msec >= 1000) { + msec -= 1000; + tv.tv_sec++; + } + + tm_info = localtime(&tv.tv_sec); + + strftime(timestamp, 26, "%Y-%m-%d %H:%M:%S", tm_info); + dprintf(fd, "%s.%03d ", timestamp, msec); +} + +void die(int exit_code, const char * perror_arg, const char * fmt, ...) { + va_list argp; + int in_errno = errno; + va_start(argp, fmt); + vsyslog(LOG_CRIT, fmt, argp); + va_end(argp); + if (perror_arg != NULL) { + if (*perror_arg != 0) + syslog(LOG_CRIT, "%s: %s", perror_arg, strerror(in_errno)); + else + syslog(LOG_CRIT, "%s", strerror(in_errno)); + } + exit(exit_code); +} + +void vlog_locked(connection_t * conn, const char * fmt, va_list args) { + int fd = conn->params->trigger_fd; + if (fd != 0) { + vdprintf(fd, fmt, args); + } else { + vsyslog(LOG_INFO, fmt, args); + fd = conn->params->logfile_fd; + if (fd != 0) { + vdprintf(fd, fmt, args); + } + } +} + +void vlog_time_locked(connection_t * conn, const char * fmt, va_list args) { + int fd = conn->params->trigger_fd; + if (fd != 0) log_timestamp(fd); + else { + fd = conn->params->logfile_fd; + if (fd != 0) log_timestamp(fd); + } + vlog_locked(conn, fmt, args); +} + +void log_time_locked(connection_t * connection, const char * fmt, ...) { + va_list args; + + va_start(args, fmt); + + vlog_time_locked(connection, fmt, args); + + va_end(args); +} + +void log_time(connection_t * connection, const char * fmt, ...) { + va_list args; + + va_start(args, fmt); + + lock("log_time fd_lock", &connection->params->fd_lock); + vlog_time_locked(connection, fmt, args); + unlock("log_time fd_lock", &connection->params->fd_lock); + + va_end(args); +} + +void log_continue_locked(connection_t * connection, const char * fmt, ...) { + va_list args; + + va_start(args, fmt); + + vlog_locked(connection, fmt, args); + + va_end(args); +} + +void log_continue(connection_t * connection, const char * fmt, ...) { + va_list args; + + va_start(args, fmt); + + lock("log_continue fd_lock", &connection->params->fd_lock); + vlog_locked(connection, fmt, args); + unlock("log_continue fd_lock", &connection->params->fd_lock); + + va_end(args); +} diff --git a/alpine/packages/transfused/transfused_log.h b/alpine/packages/transfused/transfused_log.h new file mode 100644 index 000000000..ed8f4d4c2 --- /dev/null +++ b/alpine/packages/transfused/transfused_log.h @@ -0,0 +1,15 @@ +#include "transfused.h" + +void die(int exit_code, const char * perror_arg, const char * fmt, ...); + +void vlog_locked(connection_t * conn, const char * fmt, va_list args); + +void vlog_time_locked(connection_t * conn, const char * fmt, va_list args); + +void log_time_locked(connection_t * connection, const char * fmt, ...); + +void log_time(connection_t * connection, const char * fmt, ...); + +void log_continue_locked(connection_t * connection, const char * fmt, ...); + +void log_continue(connection_t * connection, const char * fmt, ...);