📄 pure-ftpwho.c
字号:
#include <config.h>#ifndef FTPWHO#include <stdio.h>int main(void){ puts("Please compile the server with --with-ftpwho\n" "to use this feature. Thank you."); return 0;}#else# include "ftpd.h"# include "dynamic.h"# include "ftpwho-update.h"# ifndef HAVE_GETOPT_LONG# include "bsd-getopt_long.h"# else# include <getopt.h># endif# ifdef WITH_DMALLOC# include <dmalloc.h># endifint mmap_fd = -1;static signed char html_raw;static signed char html_cgi;static signed char verbose;static signed char dont_resolve_ip;static struct flock lock;void ftpwho_unlock(void) { lock.l_type = F_UNLCK; while (fcntl(mmap_fd, F_SETLK, &lock) < 0) { if (errno != EINTR) { return; } }}void ftpwho_lock(void){ lock.l_type = F_RDLCK; while (fcntl(mmap_fd, F_SETLKW, &lock) < 0) { if (errno != EINTR) { return; } } }static RETSIGTYPE sigfpe(int sig){ (void) sig; fprintf(stderr, "* Arithmetic exception *\n\n" "Please report what you were doing when it happened.\n" "You know, the author of this program is not very good\n" "at mathematics :)\n"); exit(EXIT_FAILURE);}static RETSIGTYPE sigsegv(int sig){ (void) sig; fprintf(stderr, "* This version of pure-ftpwho is not compatible *\n" "* with the version of the server. *\n" "* Please reinstall properly, and try again. *\n"); exit(EXIT_FAILURE);}static void fixlimits(void){#ifdef HAVE_SETRLIMIT static struct rlimit lim; lim.rlim_max = lim.rlim_cur = MAX_CPU_TIME; setrlimit(RLIMIT_CPU, &lim); lim.rlim_max = lim.rlim_cur = MAX_DATA_SIZE; setrlimit(RLIMIT_DATA, &lim);# ifndef DEBUG lim.rlim_max = lim.rlim_cur = 0; setrlimit(RLIMIT_CORE, &lim);# endif#endif}void logfile(const int facility, const char *format, ...){ va_list va; (void) facility; va_start(va, format); vfprintf(stderr, format, va); fprintf(stderr, "\n"); va_end(va);}static inline int checkproc(const pid_t proc){ return kill(proc, 0) == 0;}/* Text output */static void text_output_header(void){ if (verbose == 0) { puts("\n""+------+---------+-------+------+-------------------------------------------+\n""| PID | Login |For/Spd| What | File/IP |\n""+------+---------+-------+------+-------------------------------------------+"); } else { puts("\n""+------+---------+-------+------+-------------------------------------------+\n""| PID | Login |For/Spd| What | File/Remote IP/Size(Kb)/Local IP |\n""+------+---------+-------+------+-------------------------------------------+"); }}static void text_output_line(const pid_t pid, const char * const account, const unsigned long since, const unsigned long xfer_since, const char * const state, const char * const filename, const char * const hbuf, const char * const local_hbuf, const char * const local_port, const off_t restartat, const off_t total_size, const off_t current_size){ unsigned long bandwidth = 0UL; long double pct; int pcti = 0; if (current_size > (off_t) 0 && current_size > restartat) { if (xfer_since > 0UL) { bandwidth = (unsigned long) ((current_size - restartat) / xfer_since); } if ((long double) total_size > 0.0L) { pct = ((long double) current_size * 100.0) / (long double) total_size; pcti = (int) (pct + 0.5L); if (pcti > 100) { pcti = 100; /* should never happen */ } } } printf("|%5lu | %-8s| %02lu:%02lu | %s | %-42s|\n", (unsigned long) pid, account, (since / 60UL) / 60UL, (since / 60UL) % 60UL, state, filename); printf("| '' | '' |"); if (bandwidth > 0UL) { if (bandwidth < 1024UL) { printf("%4lub/s|", bandwidth); } else { bandwidth /= 1024UL; if (bandwidth < 1024UL) { printf("%4luK/s|", bandwidth); } else { bandwidth /= 1024UL; if (bandwidth < 1024UL) { printf("%4luM/s|", bandwidth); } else { bandwidth /= 1024UL; if (bandwidth < 1024UL) { printf("%4luG/s|", bandwidth); } else { printf(" '' |"); } } } } } else { printf(" '' |"); } if (pcti > 0) { printf(" %3d%% |", pcti); } else { printf(" '' |"); } printf(" ->%39.39s |\n", hbuf); if (verbose != 0) { if (current_size > 0) { if (total_size > 0) { printf("| '' | '' | | | Total size:%9llu Transfered:%9llu |\n", (unsigned long long) (total_size / 1024), (unsigned long long) (current_size / 1024)); } else { printf("| '' | '' | | | Transfered: %-29llu |\n", (unsigned long long) (current_size / 1024)); } } printf("| '' | '' | | | <-%33.33s:%-5.5s |\n", local_hbuf, local_port); } puts("+------+---------+-------+------+-------------------------------------------+");}static void text_output_footer(void){ puts("");}static char *xml_escaped(const char *const s_) { static char buf[MAXPATHLEN + 32U]; const unsigned char *s = (const unsigned char *) s_; char *bufpnt = buf; size_t left = sizeof buf - (size_t) 1U; while (left > (size_t) 0U && *s != 0U) { if (ISCTRLCODE(*s)) { if (left <= (size_t) 0U) { *bufpnt = 0; return buf; } *bufpnt++ = '?'; left--; goto next; } switch (*s) { case '<': if (left < sizeof "<" - (size_t) 1U) { *bufpnt = 0; return buf; } *bufpnt++ = '&'; *bufpnt++ = 'l'; *bufpnt++ = 't'; *bufpnt++ = ';'; left -= sizeof "<" - (size_t) 1U; break; case '>': if (left < sizeof ">" - (size_t) 1U) { *bufpnt = 0; return buf; } *bufpnt++ = '&'; *bufpnt++ = 'g'; *bufpnt++ = 't'; *bufpnt++ = ';'; left -= sizeof ">" - (size_t) 1U; break; case '&': if (left < sizeof "&" - (size_t) 1U) { *bufpnt = 0; return buf; } *bufpnt++ = '&'; *bufpnt++ = 'a'; *bufpnt++ = 'm'; *bufpnt++ = 'p'; *bufpnt++ = ';'; left -= sizeof "&" - (size_t) 1U; break; default: *bufpnt++ = (char) *s; left--; } next: s++; } *bufpnt = 0; return buf; }/* HTML output */static char *html_escaped(const char *const s_) { return xml_escaped(s_);}static void html_output_header(void){ if (html_cgi != 0) { puts("Content-Type: text/html\n"); } if (html_raw == 0) { puts("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n" " \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n" "<head>\n" " <meta http-equiv=\"Content-Type\"\n" " content=\"text/html; charset=ISO-8859-15\" />\n" " <title>Pure-FTPd server status</title>\n" " <style type=\"text/css\">\n" "html {\n" " background-color: #369;\n" "}\n" "body {\n" " background-color: #fff;\n" " color: #000;\n" " margin: 12px;\n" " padding: 8px;\n" " border: 2px solid #000;\n" " font-family: \"Trebuchet MS\",Verdana,Geneva,Arial,Helvetica,sans-serif;\n" " font-size: 0.8em;\n" "}\n" "h1 {\n" " text-align: center;\n" " border-bottom: 1px solid #666;\n" " margin: 0.5em 1em;\n" "}\n" "#ftp-status {\n" " text-align: center;\n" "}\n" "table {\n" " margin: 0 auto;\n" "}\n" "thead th {\n" " background-color: #369;\n" " color: #fff;\n" "}\n" "th,td {\n" " padding: 0.1em 0.5em;\n" "}\n" "tr:hover {\n" " background-color: #def;\n" "}\n" " </style>\n" "</head>\n" "<body>\n" "<h1>Pure-FTPd server status</h1>"); } puts("<div id=\"ftp-status\">\n" " <table summary=\"Pure-FTPd server status\">\n" " <thead>\n" " <tr>\n" " <th scope=\"col\">PID</th>\n" " <th scope=\"col\">Account</th>\n" " <th scope=\"col\">Time</th>\n" " <th scope=\"col\">State</th>\n" " <th scope=\"col\" abbr=\"File\">File name</th>\n" " <th scope=\"col\" abbr=\"Peer\">Remote host</th>\n" " <th scope=\"col\" abbr=\"Kb\">Kbytes</th>\n" " <th scope=\"col\" abbr=\"Local\">Local host</th>\n" " </tr>\n" " </thead>\n" " <tbody>");}static void html_output_line(const pid_t pid, const char * const account, const unsigned long since, const unsigned long xfer_since, const char * const state, const char * const filename, const char * const hbuf, const char * const local_hbuf, const char * const local_port, const off_t restartat, const off_t total_size, const off_t current_size){ puts(" <tr>"); printf(" <th scope=\"row\">%lu</th>\n", (unsigned long) pid); printf(" <td>%s</td>\n", *account == 0 ? " " : html_escaped(account)); printf(" <td>%02lu:%02lu</td>\n", (since / 60UL) / 60UL, (since / 60UL) % 60UL); printf(" <td>%s</td>\n", html_escaped(state)); printf(" <td>%s</td>\n", *filename == 0 ? " " : html_escaped(filename)); printf(" <td>%s</td>\n", html_escaped(hbuf)); if (current_size > (off_t) 0) { unsigned long bandwidth; if (xfer_since > 0UL && current_size > restartat) { bandwidth = (unsigned long) ((current_size - restartat) / (xfer_since * 1024UL)); } else { bandwidth = 0UL; } if ((long double) total_size > 0.0L) { long double pct; int pcti; pct = ((long double) current_size * 100.0L) / (long double) total_size; pcti = (int) (pct + 0.5L); if (pcti > 100) { pcti = 100; /* should never happen */ } printf(" <td>%llu/%llu (%d%% - %lu KB/s)</td>\n", (unsigned long long) (current_size / 1024), (unsigned long long) (total_size / 1024), pcti, bandwidth); } else { printf(" <td>%llu (%lu KB/s)</td>\n", (unsigned long long) (current_size / 1024), bandwidth); } } else { puts(" <td> </td>"); } printf(" <td>%s:", html_escaped(local_hbuf)); printf("%s</td>\n", html_escaped(local_port)); puts(" </tr>");}static void html_output_footer(void){ puts(" </tbody>\n" " </table>\n" "</div>"); if (html_raw == 0) { puts("</body>\n" "</html>"); }}/* XML output */static void xml_output_header(void){ puts("<?xml version=\"1.0\" encoding=\"ISO-8859-15\"?>\n" "<status>");}static void xml_output_line(const pid_t pid, const char * const account, const unsigned long since, const unsigned long xfer_since, const char * const state, const char * const filename, const char * const hbuf, const char * const local_hbuf, const char * const local_port, const off_t restartat, const off_t total_size, const off_t current_size){ printf(" <client"); printf(" pid=\"%lu\"", (unsigned long) pid); printf(" account=\"%s\"", xml_escaped(account)); printf(" time=\"%lu\"", since); printf(" state=\"%s\"", state); printf(" file=\"%s\"", xml_escaped(filename)); printf(" host=\"%s\"", xml_escaped(hbuf)); printf(" localhost=\"%s\"", xml_escaped(local_hbuf)); printf(" localport=\"%s\"", xml_escaped(local_port));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -