static void tlog_json_sink_cleanup(struct tlog_sink *sink) { struct tlog_json_sink *json_sink = (struct tlog_json_sink *)sink; assert(json_sink != NULL); tlog_json_chunk_cleanup(&json_sink->chunk); free(json_sink->message_buf); json_sink->message_buf = NULL; free(json_sink->terminal); json_sink->terminal = NULL; free(json_sink->username); json_sink->username = NULL; free(json_sink->recording); json_sink->recording = NULL; free(json_sink->hostname); json_sink->hostname = NULL; if (json_sink->writer_owned) { tlog_json_writer_destroy(json_sink->writer); json_sink->writer_owned = false; } }
/** * Create the log sink according to configuration. * * @param psink Location for the created sink pointer. * @param conf Configuration JSON object. * * @return Global return code. */ static tlog_grc create_log_sink(struct tlog_sink **psink, struct json_object *conf) { tlog_grc grc; int64_t num; const char *str; struct json_object *obj; struct tlog_sink *sink = NULL; struct tlog_json_writer *writer = NULL; int fd = -1; char *fqdn = NULL; struct passwd *passwd; unsigned int session_id; /* * Create the writer */ if (!json_object_object_get_ex(conf, "writer", &obj)) { fprintf(stderr, "Writer type is not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } str = json_object_get_string(obj); if (strcmp(str, "file") == 0) { struct json_object *conf_file; /* Get file writer conf container */ if (!json_object_object_get_ex(conf, "file", &conf_file)) { fprintf(stderr, "File writer parameters are not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } /* Get the file path */ if (!json_object_object_get_ex(conf_file, "path", &obj)) { fprintf(stderr, "Log file path is not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } str = json_object_get_string(obj); /* Open the file */ fd = open(str, O_WRONLY | O_CREAT | O_APPEND, S_IRWXU | S_IRWXG); if (fd < 0) { grc = TLOG_GRC_ERRNO; fprintf(stderr, "Failed opening log file \"%s\": %s\n", str, tlog_grc_strerror(grc)); goto cleanup; } /* Create the writer, letting it take over the FD */ grc = tlog_fd_json_writer_create(&writer, fd, true); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed creating file writer: %s\n", tlog_grc_strerror(grc)); goto cleanup; } fd = -1; } else if (strcmp(str, "syslog") == 0) { struct json_object *conf_syslog; int facility; int priority; /* Get syslog writer conf container */ if (!json_object_object_get_ex(conf, "syslog", &conf_syslog)) { fprintf(stderr, "Syslog writer parameters are not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } /* Get facility */ if (!json_object_object_get_ex(conf_syslog, "facility", &obj)) { fprintf(stderr, "Syslog facility is not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } str = json_object_get_string(obj); facility = tlog_syslog_facility_from_str(str); if (facility < 0) { fprintf(stderr, "Unknown syslog facility: %s\n", str); grc = TLOG_RC_FAILURE; goto cleanup; } /* Get priority */ if (!json_object_object_get_ex(conf_syslog, "priority", &obj)) { fprintf(stderr, "Syslog priority is not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } str = json_object_get_string(obj); priority = tlog_syslog_priority_from_str(str); if (priority < 0) { fprintf(stderr, "Unknown syslog priority: %s\n", str); grc = TLOG_RC_FAILURE; goto cleanup; } /* Create the writer */ openlog("tlog", LOG_NDELAY, facility); grc = tlog_syslog_json_writer_create(&writer, priority); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed creating syslog writer: %s\n", tlog_grc_strerror(grc)); goto cleanup; } } else { fprintf(stderr, "Unknown writer type: %s\n", str); grc = TLOG_RC_FAILURE; goto cleanup; } /* * Create the sink */ /* Get host FQDN */ grc = get_fqdn(&fqdn); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed retrieving host FQDN: %s\n", tlog_grc_strerror(grc)); goto cleanup; } /* Get session ID */ grc = get_session_id(&session_id); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed retrieving session ID: %s\n", tlog_grc_strerror(grc)); goto cleanup; } /* Get effective user entry */ errno = 0; passwd = getpwuid(geteuid()); if (passwd == NULL) { if (errno == 0) { grc = TLOG_RC_FAILURE; fprintf(stderr, "User entry not found\n"); } else { grc = TLOG_GRC_ERRNO; fprintf(stderr, "Failed retrieving user entry: %s\n", tlog_grc_strerror(grc)); } goto cleanup; } /* Get the maximum payload size */ if (!json_object_object_get_ex(conf, "payload", &obj)) { fprintf(stderr, "Maximum payload size is not specified\n"); grc = TLOG_RC_FAILURE; goto cleanup; } num = json_object_get_int64(obj); /* Create the sink, letting it take over the writer */ grc = tlog_json_sink_create(&sink, writer, true, fqdn, passwd->pw_name, session_id, (size_t)num); if (grc != TLOG_RC_OK) { fprintf(stderr, "Failed creating log sink: %s\n", tlog_grc_strerror(grc)); goto cleanup; } writer = NULL; *psink = sink; sink = NULL; grc = TLOG_RC_OK; cleanup: if (fd >= 0) { close(fd); } tlog_json_writer_destroy(writer); free(fqdn); tlog_sink_destroy(sink); return grc; }