int main(int argc, char **argv) { pr_scoreboard_entry_t *score = NULL; pid_t mpid = 0; time_t uptime = 0; unsigned int count = 0, total = 0; int c = 0, res = 0; char *server_name = NULL; struct scoreboard_class classes[MAX_CLASSES]; char *cp, *progname = *argv; const char *cmdopts = "S:c:f:ho:v"; unsigned char verbose = FALSE; unsigned long outform = 0; memset(classes, 0, MAX_CLASSES * sizeof(struct scoreboard_class)); cp = strrchr(progname, '/'); if (cp != NULL) progname = cp+1; opterr = 0; while ((c = #ifdef HAVE_GETOPT_LONG getopt_long(argc, argv, cmdopts, opts, NULL) #else /* HAVE_GETOPT_LONG */ getopt(argc, argv, cmdopts) #endif /* HAVE_GETOPT_LONG */ ) != -1) { switch (c) { case 'h': show_usage(progname, 0); case 'v': verbose = TRUE; break; case 'f': util_set_scoreboard(optarg); break; case 'c': config_filename = strdup(optarg); break; case 'o': /* Check the given outform parameter. */ if (strcmp(optarg, "compat") == 0) { outform |= OF_COMPAT; break; } else if (strcmp(optarg, "oneline") == 0) { outform |= OF_ONELINE; break; } fprintf(stderr, "unknown outform value: '%s'\n", optarg); return 1; case 'S': server_name = strdup(optarg); break; case '?': fprintf(stderr, "unknown option: %c\n", (char) optopt); show_usage(progname, 1); } } /* First attempt to check the supplied/default scoreboard path. If this is * incorrect, try the config file kludge. */ if (check_scoreboard_file() < 0) { char *path; path = util_scan_config(config_filename, "ScoreboardFile"); if (path) { util_set_scoreboard(path); free(path); } if (check_scoreboard_file() < 0) { fprintf(stderr, "%s: %s\n", util_get_scoreboard(), strerror(errno)); fprintf(stderr, "(Perhaps you need to specify the ScoreboardFile with -f, or change\n"); fprintf(stderr," the compile-time default directory?)\n"); exit(1); } } count = 0; if ((res = util_open_scoreboard(O_RDONLY)) < 0) { switch (res) { case -1: fprintf(stderr, "unable to open scoreboard: %s\n", strerror(errno)); return 1; case UTIL_SCORE_ERR_BAD_MAGIC: fprintf(stderr, "scoreboard is corrupted or old\n"); return 1; case UTIL_SCORE_ERR_OLDER_VERSION: fprintf(stderr, "scoreboard version is too old\n"); return 1; case UTIL_SCORE_ERR_NEWER_VERSION: fprintf(stderr, "scoreboard version is too new\n"); return 1; } } mpid = util_scoreboard_get_daemon_pid(); uptime = util_scoreboard_get_daemon_uptime(); if (!mpid) { printf("inetd FTP daemon:\n"); } else { printf("standalone FTP daemon [%u], up for %s\n", (unsigned int) mpid, show_uptime(uptime)); } if (server_name) printf("ProFTPD Server '%s'\n", server_name); while ((score = util_scoreboard_entry_read()) != NULL) { int downloading = FALSE, uploading = FALSE; register unsigned int i = 0; /* If a ServerName was given, skip unless the scoreboard entry matches. */ if (server_name && strcmp(server_name, score->sce_server_label) != 0) continue; if (!count++) { if (total) printf(" - %d user%s\n\n", total, total > 1 ? "s" : ""); total = 0; } /* Tally up per-Class counters. */ for (i = 0; i != MAX_CLASSES; i++) { if (classes[i].score_class == 0) { classes[i].score_class = strdup(score->sce_class); classes[i].score_count++; break; } if (strcasecmp(classes[i].score_class, score->sce_class) == 0) { classes[i].score_count++; break; } } total++; if (strcmp(score->sce_cmd, "RETR") == 0 || strcmp(score->sce_cmd, "READ") == 0 || strcmp(score->sce_cmd, "scp download") == 0) { downloading = TRUE; } else { if (strcmp(score->sce_cmd, "STOR") == 0 || strcmp(score->sce_cmd, "STOU") == 0 || strcmp(score->sce_cmd, "APPE") == 0 || strcmp(score->sce_cmd, "WRITE") == 0 || strcmp(score->sce_cmd, "scp upload") == 0) { uploading = TRUE; } } if (outform & OF_COMPAT) { if ((downloading || uploading) && score->sce_xfer_size > 0) { if (downloading) { printf("%5d %-6s (%s%%) %s %s\n", (int) score->sce_pid, show_time(&score->sce_begin_idle), percent_complete(score->sce_xfer_size, score->sce_xfer_done), score->sce_cmd, score->sce_cmd_arg); } else { printf("%5d %-6s (n/a) %s %s\n", (int) score->sce_pid, show_time(&score->sce_begin_idle), score->sce_cmd, score->sce_cmd_arg); } } else { printf("%5d %-6s %s %s\n", (int) score->sce_pid, show_time(&score->sce_begin_idle), score->sce_cmd, score->sce_cmd_arg); } if (verbose) { if (score->sce_client_addr[0]) { printf(" (host: %s [%s])\n", score->sce_client_name, score->sce_client_addr); } if (score->sce_protocol[0]) { printf(" (protocol: %s)\n", score->sce_protocol); } if (score->sce_cwd[0]) { printf(" (cwd: %s)\n", score->sce_cwd); } if (score->sce_class[0]) { printf(" (class: %s)\n", score->sce_class); } } continue; } /* Has the client authenticated yet, or not? */ if (strcmp(score->sce_user, "(none)")) { /* Is the client idle? */ if (strcmp(score->sce_cmd, "idle") == 0) { /* These printf() calls needs to be split up, as show_time() returns * a pointer to a static buffer, and pushing two invocations onto * the stack means that the times thus formatted will be incorrect. */ printf("%5d %-8s [%6s] ", (int) score->sce_pid, score->sce_user, show_time(&score->sce_begin_session)); printf("%6s %s", show_time(&score->sce_begin_idle), score->sce_cmd); if (verbose && !(outform & OF_ONELINE)) printf("\n"); } else { if (downloading) { printf("%5d %-8s [%6s] (%3s%%) %s %s", (int) score->sce_pid, score->sce_user, show_time(&score->sce_begin_session), percent_complete(score->sce_xfer_size, score->sce_xfer_done), score->sce_cmd, score->sce_cmd_arg); } else { printf("%5d %-8s [%6s] (n/a) %s %s", (int) score->sce_pid, score->sce_user, show_time(&score->sce_begin_session), score->sce_cmd, score->sce_cmd_arg); } if (verbose) { printf("%sKB/s: %3.2f%s", (outform & OF_ONELINE) ? " " : "\n\t", (score->sce_xfer_len / 1024.0) / (score->sce_xfer_elapsed / 1000), (outform & OF_ONELINE) ? "" : "\n"); } } /* Display additional information, if requested. */ if (verbose) { if (score->sce_client_addr[0]) { printf("%sclient: %s [%s]%s", (outform & OF_ONELINE) ? " " : "\t", score->sce_client_name, score->sce_client_addr, (outform & OF_ONELINE) ? "" : "\n"); } if (score->sce_server_addr[0]) { printf("%sserver: %s (%s)%s", (outform & OF_ONELINE) ? " " : "\t", score->sce_server_addr, score->sce_server_label, (outform & OF_ONELINE) ? "" : "\n"); } if (score->sce_protocol[0]) { printf("%sprotocol: %s%s", (outform & OF_ONELINE) ? " " : "\t", score->sce_protocol, (outform & OF_ONELINE) ? "" : "\n"); } if (score->sce_cwd[0]) { printf("%slocation: %s%s", (outform & OF_ONELINE) ? " " : "\t", score->sce_cwd, (outform & OF_ONELINE) ? "" : "\n"); } if (score->sce_class[0]) { printf("%sclass: %s", (outform & OF_ONELINE) ? " " : "\t", score->sce_class); } printf("%s", "\n"); } else { printf("%s", "\n"); } } else { printf("%5d %-8s [%6s] (authenticating)", (int) score->sce_pid, score->sce_user, show_time(&score->sce_begin_session)); /* Display additional information, if requested. */ if (verbose) { if (score->sce_client_addr[0]) { printf("%sclient: %s [%s]%s", (outform & OF_ONELINE) ? " " : "\n\t", score->sce_client_name, score->sce_client_addr, (outform & OF_ONELINE) ? "" : "\n"); } if (score->sce_server_addr[0]) { printf("%sserver: %s (%s)%s", (outform & OF_ONELINE) ? " " : "\t", score->sce_server_addr, score->sce_server_label, (outform & OF_ONELINE) ? "" : "\n"); } if (score->sce_protocol[0]) { printf("%sprotocol: %s%s", (outform & OF_ONELINE) ? " " : "\t", score->sce_protocol, (outform & OF_ONELINE) ? "" : "\n"); } if (score->sce_class[0]) { printf("%sclass: %s", (outform & OF_ONELINE) ? " " : "\t", score->sce_class); } } printf("%s", "\n"); } } util_close_scoreboard(); if (total) { register unsigned int i = 0; for (i = 0; i != MAX_CLASSES; i++) { if (classes[i].score_class == 0) break; printf("Service class %-20s - %3lu user%s\n", classes[i].score_class, classes[i].score_count, classes[i].score_count > 1 ? "s" : ""); } } else { printf("no users connected\n"); } if (server_name) { free(server_name); server_name = NULL; } return 0; }
static void scoreboard_close(void) { util_close_scoreboard(); }
int main(int argc, char **argv) { pr_scoreboard_entry_t *score = NULL; pid_t oldpid = 0, mpid; unsigned int count = 0, total = 0; int c = 0, res = 0; char *server_name = NULL; struct scoreboard_class classes[MAX_CLASSES]; char *cp, *progname = *argv; const char *cmdopts = "S:c:f:h"; register unsigned int i; memset(classes, 0, MAX_CLASSES * sizeof(struct scoreboard_class)); cp = strrchr(progname, '/'); if (cp != NULL) progname = cp + 1; opterr = 0; while ((c = #ifdef HAVE_GETOPT_LONG getopt_long(argc, argv, cmdopts, opts, NULL) #else /* HAVE_GETOPT_LONG */ getopt(argc, argv, cmdopts) #endif /* HAVE_GETOPT_LONG */ ) != -1) { switch (c) { case 'h': show_usage(progname, 0); break; case 'f': util_set_scoreboard(optarg); break; case 'c': config_filename = strdup(optarg); break; case 'S': server_name = strdup(optarg); break; case '?': fprintf(stderr, "unknown option: %c\n", (char) optopt); show_usage(progname, 1); break; } } /* First attempt to check the supplied/default scoreboard path. If this is * incorrect, try the config file kludge. */ if (check_scoreboard_file() < 0) { char *path; path = util_scan_config(config_filename, "ScoreboardFile"); if (path) { util_set_scoreboard(path); free(path); } if (check_scoreboard_file() < 0) { fprintf(stderr, "%s: %s\n", util_get_scoreboard(), strerror(errno)); fprintf(stderr, "(Perhaps you need to specify the ScoreboardFile with -f, or change\n"); fprintf(stderr," the compile-time default directory?)\n"); exit(1); } } count = 0; res = util_open_scoreboard(O_RDONLY); if (res < 0) { switch (res) { case UTIL_SCORE_ERR_BAD_MAGIC: fprintf(stderr, "error opening scoreboard: bad/corrupted file\n"); return 1; case UTIL_SCORE_ERR_OLDER_VERSION: fprintf(stderr, "error opening scoreboard: bad version (too old)\n"); return 1; case UTIL_SCORE_ERR_NEWER_VERSION: fprintf(stderr, "error opening scoreboard: bad version (too new)\n"); return 1; default: fprintf(stderr, "error opening scoreboard: %s\n", strerror(errno)); return 1; } } mpid = util_scoreboard_get_daemon_pid(); errno = 0; while ((score = util_scoreboard_entry_read()) != NULL) { if (errno) break; if (!count++ || oldpid != mpid) { if (total) printf(" - %d user%s\n\n", total, total > 1 ? "s" : ""); if (!mpid) { printf("inetd FTP connections:\n"); } else { printf("Master proftpd process %u:\n", (unsigned int) mpid); } if (server_name) printf("ProFTPD Server '%s'\n", server_name); oldpid = mpid; total = 0; } /* If a ServerName was given, skip unless the scoreboard entry matches. */ if (server_name && strcmp(server_name, score->sce_server_label) != 0) { continue; } for (i = 0; i != MAX_CLASSES; i++) { if (classes[i].score_class == 0) { classes[i].score_class = strdup(score->sce_class); classes[i].score_count++; break; } if (strcasecmp(classes[i].score_class, score->sce_class) == 0) { classes[i].score_count++; break; } } total++; } util_close_scoreboard(); /* Print out the total. */ if (total) { for (i = 0; i != MAX_CLASSES; i++) { if (classes[i].score_class == 0) break; printf("Service class %-20s - %3lu %s\n", classes[i].score_class, classes[i].score_count, classes[i].score_count > 1 ? "users" : "user"); } } else { if (!mpid) { printf("inetd FTP connections:\n"); } else { printf("Master proftpd process %u:\n", (unsigned int) mpid); } printf("0 users\n"); } if (server_name) { free(server_name); } return 0; }