示例#1
0
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;
}
示例#2
0
static void scoreboard_close(void) {
    util_close_scoreboard();
}
示例#3
0
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;
}