#ifdef HAVE_CONFIG_H # include "config.h" #endif #include "connection.h" #include "xwrap.h" #include <fcntl.h> #include <stdarg.h> #include <stdbool.h> #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> #include <time.h> #include <unistd.h> int ras_conn_init ( RasConn* conn, RasConnPerm perm, int domain, const char* name, const char* log_file, int id) { if (log_file == NULL || strcmp (log_file, "stderr") == 0) { conn->log = stderr; conn->log_fd = STDERR_FILENO; conn->log_file = NULL; conn->log_is_set = false; } else if (strcmp (log_file, "stdout") == 0) { conn->log = stdout; conn->log_fd = STDOUT_FILENO; conn->log_file = NULL; conn->log_is_set = false; } else { int fd = open (log_file, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); if (fd < 0) { return -1; } FILE* fp = fdopen (fd, "ab"); if (fp == NULL) { return -1; } setvbuf (fp, NULL, _IONBF, 0); conn->log = fp; conn->log_fd = fd; conn->log_file = xstrdup (log_file); conn->log_is_set = true; } char* dir_sep_loc = strrchr (name, '/'); if (dir_sep_loc != NULL) { name = dir_sep_loc + 1; } conn->domain = domain; conn->perm = perm; conn->id = id; conn->name = xsprintf ("%s-%d (%s-%s)", name, conn->id, domain == AF_UNIX ? "unix" : domain == AF_INET ? "ipv4" : domain == AF_INET6 ? "ipv6" : "unknown", perm == RAS_CONN_PERM_RESTRICTED ? "restricted" : perm == RAS_CONN_PERM_REGULAR ? "regular" : perm == RAS_CONN_PERM_ADMIN ? "admin" : "unknown"); conn->fd_is_set = false; return 0; } void ras_conn_destroy (RasConn* conn) { if (conn->fd_is_set) { close (conn->fd); } if (conn->log_is_set) { fclose (conn->log); } free (conn->log_file); free (conn->name); } void ras_conn_log (RasConn* conn, const char* format, ...) { va_list ap; time_t t; struct tm tmd; va_start (ap, format); time (&t); localtime_r (&t, &tmd); struct flock lock_info = { .l_type = F_WRLCK, .l_whence = SEEK_END, .l_start = 0, .l_len = 0 }; fcntl (conn->log_fd, F_SETLKW, &lock_info); fprintf (conn->log, "%04d-%02d-%02d %02d:%02d:%02d %s [%d]: ", tmd.tm_year + 1900, tmd.tm_mon + 1, tmd.tm_mday, tmd.tm_hour, tmd.tm_min, tmd.tm_sec, conn->name, getpid ()); vfprintf (conn->log, format, ap); putc ('\n', conn->log); lock_info.l_type = F_UNLCK; fcntl (conn->log_fd, F_SETLK, &lock_info); va_end (ap); }