int xferlog_write(long xfertime, const char *remhost, off_t fsize, char *fname, char xfertype, char direction, char access_mode, char *user, char abort_flag, const char *action_flags) { const char *xfer_proto; char buf[LOGBUFFER_SIZE] = {'\0'}, fbuf[LOGBUFFER_SIZE] = {'\0'}; int have_ident = FALSE, len; char *rfc1413_ident = NULL; register unsigned int i = 0; if (xferlogfd == -1 || remhost == NULL || user == NULL || fname == NULL) { return 0; } for (i = 0; (i + 1 < sizeof(fbuf)) && fname[i] != '\0'; i++) { fbuf[i] = (PR_ISSPACE(fname[i]) || PR_ISCNTRL(fname[i])) ? '_' : fname[i]; } fbuf[i] = '\0'; rfc1413_ident = pr_table_get(session.notes, "mod_ident.rfc1413-ident", NULL); if (rfc1413_ident) { have_ident = TRUE; /* If the retrieved identity is "UNKNOWN", then change the string to be * "*", since "*" is to be logged in the xferlog, as per the doc, when * the authenticated user ID is not available. */ if (strncmp(rfc1413_ident, "UNKNOWN", 8) == 0) rfc1413_ident = "*"; } else { /* If an authenticated user ID is not available, log "*", as per the * xferlog man page/spec. */ rfc1413_ident = "*"; } xfer_proto = pr_session_get_protocol(0); len = snprintf(buf, sizeof(buf), "%s %ld %s %" PR_LU " %s %c %s %c %c %s %s %c %s %c\n", pr_strtime(time(NULL)), xfertime, remhost, (pr_off_t) fsize, fbuf, xfertype, action_flags, direction, access_mode, user, xfer_proto, have_ident ? '1' : '0', rfc1413_ident, abort_flag); buf[sizeof(buf)-1] = '\0'; pr_log_event_generate(PR_LOG_TYPE_XFERLOG, xferlogfd, -1, buf, len); return write(xferlogfd, buf, len); }
int pr_log_vwritefile(int logfd, const char *ident, const char *fmt, va_list msg) { char buf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; struct timeval now; struct tm *tm = NULL; size_t buflen, len; unsigned long millis; if (logfd < 0) { errno = EINVAL; return -1; } gettimeofday(&now, NULL); tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); if (tm == NULL) { return -1; } /* Prepend the timestamp */ len = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); buflen = len; buf[sizeof(buf)-1] = '\0'; /* Convert microsecs to millisecs. */ millis = now.tv_usec / 1000; len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); buflen += len; /* Prepend a small header */ len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s[%u]: ", ident, (unsigned int) (session.pid ? session.pid : getpid())); buflen += len; buf[sizeof(buf)-1] = '\0'; /* Affix the message */ len = vsnprintf(buf + buflen, sizeof(buf) - buflen - 1, fmt, msg); buflen += len; buf[sizeof(buf)-1] = '\0'; if (buflen < (sizeof(buf) - 1)) { buf[buflen++] = '\n'; } else { buf[sizeof(buf)-2] = '\n'; buflen++; } pr_log_event_generate(PR_LOG_TYPE_UNSPEC, logfd, -1, buf, buflen); while (write(logfd, buf, buflen) < 0) { if (errno == EINTR) { pr_signals_handle(); continue; } return -1; } return 0; }
static void log_write(int priority, int f, char *s, int discard) { unsigned int max_priority = 0, *ptr = NULL; char serverinfo[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; memset(serverinfo, '\0', sizeof(serverinfo)); if (main_server && main_server->ServerFQDN) { pr_netaddr_t *remote_addr = pr_netaddr_get_sess_remote_addr(); const char *remote_name = pr_netaddr_get_sess_remote_name(); snprintf(serverinfo, sizeof(serverinfo)-1, "%s", main_server->ServerFQDN); serverinfo[sizeof(serverinfo)-1] = '\0'; if (remote_addr && remote_name) { size_t serverinfo_len; serverinfo_len = strlen(serverinfo); snprintf(serverinfo + serverinfo_len, sizeof(serverinfo) - serverinfo_len, " (%s[%s])", remote_name, pr_netaddr_get_ipstr(remote_addr)); serverinfo[sizeof(serverinfo)-1] = '\0'; } } if (!discard && (logstderr || !main_server)) { char buf[LOGBUFFER_SIZE] = {'\0'}; size_t buflen, len; struct timeval now; struct tm *tm = NULL; unsigned long millis; gettimeofday(&now, NULL); tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); if (tm == NULL) { return; } len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); buflen = len; buf[sizeof(buf)-1] = '\0'; /* Convert microsecs to millisecs. */ millis = now.tv_usec / 1000; len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); buflen += len; buf[sizeof(buf)-1] = '\0'; if (*serverinfo) { len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s proftpd[%u] %s: %s\n", systemlog_host, (unsigned int) (session.pid ? session.pid : getpid()), serverinfo, s); } else { len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s proftpd[%u]: %s\n", systemlog_host, (unsigned int) (session.pid ? session.pid : getpid()), s); } buflen += len; buf[sizeof(buf)-1] = '\0'; pr_log_event_generate(PR_LOG_TYPE_SYSTEMLOG, STDERR_FILENO, priority, buf, buflen); fprintf(stderr, "%s", buf); return; } if (syslog_discard) { /* Only return now if we don't have any log listeners. */ if (pr_log_event_listening(PR_LOG_TYPE_SYSLOG) <= 0 && pr_log_event_listening(PR_LOG_TYPE_SYSTEMLOG) <= 0) { return; } } ptr = get_param_ptr(main_server->conf, "SyslogLevel", FALSE); if (ptr != NULL) { max_priority = *ptr; } else { /* Default SyslogLevel */ max_priority = default_level; } if (priority > max_priority) { /* Only return now if we don't have any log listeners. */ if (pr_log_event_listening(PR_LOG_TYPE_SYSLOG) <= 0 && pr_log_event_listening(PR_LOG_TYPE_SYSTEMLOG) <= 0) { return; } } if (systemlog_fd != -1) { char buf[LOGBUFFER_SIZE] = {'\0'}; size_t buflen, len; struct timeval now; struct tm *tm; unsigned long millis; gettimeofday(&now, NULL); tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); if (tm == NULL) { return; } len = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); buflen = len; buf[sizeof(buf) - 1] = '\0'; /* Convert microsecs to millisecs. */ millis = now.tv_usec / 1000; len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); buflen += len; buf[sizeof(buf) - 1] = '\0'; if (*serverinfo) { len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s proftpd[%u] %s: %s\n", systemlog_host, (unsigned int) (session.pid ? session.pid : getpid()), serverinfo, s); } else { len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s proftpd[%u]: %s\n", systemlog_host, (unsigned int) (session.pid ? session.pid : getpid()), s); } buflen += len; buf[sizeof(buf)-1] = '\0'; pr_log_event_generate(PR_LOG_TYPE_SYSTEMLOG, systemlog_fd, priority, buf, buflen); /* Now we need to enforce the discard, syslog_discard and SyslogLevel * filtering. */ if (discard) { return; } if (syslog_discard) { return; } if (priority > max_priority) { return; } while (write(systemlog_fd, buf, buflen) < 0) { if (errno == EINTR) { pr_signals_handle(); continue; } return; } return; } pr_log_event_generate(PR_LOG_TYPE_SYSLOG, syslog_sockfd, priority, s, strlen(s)); if (set_facility != -1) f = set_facility; if (!syslog_open) { syslog_sockfd = pr_openlog("proftpd", LOG_NDELAY|LOG_PID, f); if (syslog_sockfd < 0) { (void) pr_trace_msg(trace_channel, 1, "error opening syslog fd: %s", strerror(errno)); return; } syslog_open = TRUE; } else if (f != facility) { /* If this message is to be sent to a different log facility than a * default one (or the facility configured via SyslogFacility), then * OR in the facility with the priority value, as per the syslog(3) * docs. */ priority |= f; } if (*serverinfo) { pr_syslog(syslog_sockfd, priority, "%s - %s\n", serverinfo, s); } else { pr_syslog(syslog_sockfd, priority, "%s\n", s); } }
static int trace_write(const char *channel, int level, const char *msg, int discard) { char buf[PR_TUNABLE_BUFFER_SIZE]; size_t buflen, len; struct tm *tm; int use_conn_ips = FALSE; if (trace_logfd < 0) return 0; memset(buf, '\0', sizeof(buf)); if (!(trace_opts & PR_TRACE_OPT_USE_TIMESTAMP_MILLIS)) { time_t now; now = time(NULL); tm = pr_localtime(NULL, &now); len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); buflen = len; } else { struct timeval now; unsigned long millis; gettimeofday(&now, NULL); tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); buflen = len; /* Convert microsecs to millisecs. */ millis = now.tv_usec / 1000; len = snprintf(buf + buflen, sizeof(buf) - buflen, ",%03lu", millis); buflen += len; } if ((trace_opts & PR_TRACE_OPT_LOG_CONN_IPS) && session.c != NULL) { /* We can only support the "+ConnIPs" TraceOption if there actually * is a client connected in this process. We might be the daemon * process, in which there is no client. */ use_conn_ips = TRUE; } if (use_conn_ips == FALSE) { len = snprintf(buf + buflen, sizeof(buf) - buflen, " [%u] <%s:%d>: %s", (unsigned int) (session.pid ? session.pid : getpid()), channel, level, msg); buflen += len; } else { const char *client_ip, *server_ip; int server_port; client_ip = pr_netaddr_get_ipstr(session.c->remote_addr); server_ip = pr_netaddr_get_ipstr(session.c->local_addr); server_port = pr_netaddr_get_port(session.c->local_addr); len = snprintf(buf + buflen, sizeof(buf) - buflen, " [%u] (client %s, server %s:%d) <%s:%d>: %s", (unsigned int) (session.pid ? session.pid : getpid()), client_ip != NULL ? client_ip : "none", server_ip != NULL ? server_ip : "none", server_port, channel, level, msg); buflen += len; } buf[sizeof(buf)-1] = '\0'; if (buflen < (sizeof(buf) - 1)) { buf[buflen] = '\n'; buflen++; } else { buf[sizeof(buf)-2] = '\n'; } pr_log_event_generate(PR_LOG_TYPE_TRACELOG, trace_logfd, level, buf, buflen); if (discard) { /* This log message would not have been written to disk, so just discard * it. The discard value is TRUE when there's a log listener for * TraceLog logging events, and the Trace log level configuration would * otherwise have filtered out this log message. */ return 0; } return write(trace_logfd, buf, buflen); }