Exemple #1
0
static void verify_scoreboard_file(void) {
    struct stat sbuf;

    if (stat(util_get_scoreboard(), &sbuf) < 0) {
        fprintf(stderr, "%s: unable to stat '%s': %s\n", program,
                util_get_scoreboard(), strerror(errno));
        exit(1);
    }
}
Exemple #2
0
static int check_scoreboard_file(void) {
    struct stat sbuf;

    if (stat(util_get_scoreboard(), &sbuf) < 0)
        return -1;

    return 0;
}
Exemple #3
0
static int check_scoreboard_file(void) {
  struct stat st;

  if (stat(util_get_scoreboard(), &st) < 0) {
    return -1;
  }

  return 0;
}
Exemple #4
0
static void process_opts(int argc, char *argv[]) {
    int optc = 0;
    const char *prgopts = "DS:d:f:hIiUV";

    while ((optc = getopt(argc, argv, prgopts)) != -1) {
        switch (optc) {
        case 'D':
            display_mode = 0U;
            display_mode |= FTPTOP_SHOW_DOWNLOAD;
            break;

        case 'S':
            server_name = strdup(optarg);
            break;

        case 'd':
            delay = atoi(optarg);

            if (delay < 0) {
                fprintf(stderr, "%s: negative delay illegal: %d\n", program,
                        delay);
                exit(1);
            }

            if (delay > 15) {
                fprintf(stderr, "%s: delay of 0-15 seconds only supported\n",
                        program);
                exit(1);
            }

            break;

        case 'f':
            if (util_set_scoreboard(optarg) < 0) {
                fprintf(stderr, "%s: unable to use scoreboard '%s': %s\n",
                        program, optarg, strerror(errno));
                exit(1);
            }
            break;

        case 'h':
            usage();
            break;

        case 'I':
            display_mode = 0U;
            display_mode |= FTPTOP_SHOW_IDLE;
            break;

        case 'i':
            display_mode &= ~FTPTOP_SHOW_IDLE;
            break;

        case 'U':
            display_mode = 0U;
            display_mode |= FTPTOP_SHOW_UPLOAD;
            break;

        case 'V':
            show_version();
            break;

        case '?':
            break;

        default:
            break;
        }
    }

    /* First attempt to check the supplied/default scoreboard path.  If this is
     * incorrect, try the config file kludge.
     */
    if (check_scoreboard_file() < 0) {
        scan_config_file();

        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);
        }
    }
}
Exemple #5
0
int main(int argc, char **argv) {
  int c = 0, res = 0;
  int verbose = FALSE;
  char *cp, *progname = *argv;
  const char *cmdopts = "c:f:hv";

  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 'v':
        verbose = TRUE;
        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);
    }
  }

  res = util_scoreboard_scrub(verbose);
  if (res < 0) {
    fprintf(stderr, "error scrubbing scoreboard %s: %s\n",
      util_get_scoreboard(), strerror(errno));
    return 1;
  }

  return 0;
}
Exemple #6
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;
}
Exemple #7
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;
}
Exemple #8
0
int util_scoreboard_scrub(int verbose) {
  int fd = -1, res = 0;
  off_t curr_offset = 0;
  struct flock lock;
  pr_scoreboard_entry_t sce;

  if (verbose) {
    fprintf(stdout, "scrubbing ScoreboardFile %s\n", util_get_scoreboard());
  }

  /* Manually open the scoreboard.  It won't hurt if the process already
   * has a descriptor opened on the scoreboard file.
   */
  fd = open(util_get_scoreboard(), O_RDWR);
  if (fd < 0) {
    if (verbose) {
      fprintf(stdout, "error opening scoreboard: %s", strerror(errno));
    }

    return -1;
  }

  /* Lock the entire scoreboard. */
  lock.l_type = F_WRLCK;
  lock.l_whence = 0;

  lock.l_start = 0;
  lock.l_len = 0;

  /* We can afford to block/wait until we obtain our lock on the file. */
  while (fcntl(fd, F_SETLKW, &lock) < 0) {
    int xerrno = errno;

    if (xerrno == EINTR) {
      continue;
    }

    (void) close(fd);
    errno = xerrno;
    return -1;
  }

  /* Skip past the scoreboard header. */
  curr_offset = lseek(fd, (off_t) sizeof(pr_scoreboard_header_t), SEEK_SET);
  if (curr_offset < 0) {
    int xerrno = errno;

    /* Release the scoreboard. */
    lock.l_type = F_UNLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    while (fcntl(fd, F_SETLKW, &lock) < 0) {
      if (errno == EINTR) {
        continue;
      }
    }

    /* Don't need the descriptor anymore. */
    (void) close(fd);

    errno = xerrno;
    return -1;
  }

  memset(&sce, 0, sizeof(sce));

  while (read(fd, &sce, sizeof(sce)) == sizeof(sce)) {

    /* Check to see if the PID in this entry is valid.  If not, erase
     * the slot.
     */
    if (sce.sce_pid &&
        kill(sce.sce_pid, 0) < 0 &&
        errno == ESRCH) {

      /* OK, the recorded PID is no longer valid. */
      if (verbose) {
        fprintf(stdout, "scrubbing scoreboard slot for PID %u",
          (unsigned int) sce.sce_pid);
      }

      /* Rewind to the start of this slot. */
      if (lseek(fd, curr_offset, SEEK_SET) < 0) {
        if (verbose) {
          fprintf(stdout, "error scrubbing scoreboard: %s",
            strerror(errno));
        }
      }

      memset(&sce, 0, sizeof(sce));
      while (write(fd, &sce, sizeof(sce)) != sizeof(sce)) {
        if (errno == EINTR) {
          continue;
        }

        if (verbose) {
          fprintf(stdout, "error scrubbing scoreboard: %s",
            strerror(errno));
        }
      }
    }

    /* Mark the current offset. */
    curr_offset = lseek(fd, (off_t) 0, SEEK_CUR);
    if (curr_offset < 0) {
      res = -1;
      break;
    }
  }

  /* Release the scoreboard. */
  lock.l_type = F_UNLCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = 0;
  lock.l_len = 0;

  while (fcntl(fd, F_SETLKW, &lock) < 0) {
    if (errno == EINTR) {
      continue;
    }
  }

  /* Don't need the descriptor anymore. */
  (void) close(fd);

  return res;
}