示例#1
0
int main(int argc, char **argv)
{
	const char *filename;
	long lines;
	int ch;
	struct stat st;
	off_t size = 0;

	static const struct option longopts[] = {
		{ "lines",   required_argument, 0, 'n' },
		{ "version", no_argument,	0, 'V' },
		{ "help",    no_argument,	0, 'h' },
		{ NULL,      0, 0, 0 }
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	lines = old_style_option(&argc, argv);
	if (lines < 0)
		lines = DEFAULT_LINES;

	while ((ch = getopt_long(argc, argv, "n:N:Vh", longopts, NULL)) != -1)
		switch((char)ch) {
		case 'n':
		case 'N':
			lines = strtol_or_err(optarg,
					_("failed to parse number of lines"));
			break;
		case 'V':
			printf(_("%s from %s\n"), program_invocation_short_name,
						  PACKAGE_STRING);
			exit(EXIT_SUCCESS);
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}

	if (argc == optind)
		errx(EXIT_FAILURE, _("no input file specified"));

	filename = argv[optind];

	if (stat(filename, &st) != 0)
		err(EXIT_FAILURE, _("stat failed %s"), filename);

	size = st.st_size;;
	tailf(filename, lines);

#ifdef HAVE_INOTIFY_INIT
	if (!watch_file_inotify(filename, &size))
#endif
		watch_file(filename, &size);

	return EXIT_SUCCESS;
}
示例#2
0
static gid_t get_group(const char *s, const char *err)
{
    struct group *gr;
    long tmp;
    gr = getgrnam(s);
    if (gr)
        return gr->gr_gid;
    tmp = strtol_or_err(s, err);
    return tmp;
}
示例#3
0
static uid_t get_user(const char *s, const char *err)
{
    struct passwd *pw;
    long tmp;
    pw = getpwnam(s);
    if (pw)
        return pw->pw_uid;
    tmp = strtol_or_err(s, err);
    return tmp;
}
示例#4
0
static struct passwd *get_passwd(const char *s, uid_t *uid, const char *err)
{
	struct passwd *pw;
	long tmp;
	pw = getpwnam(s);
	if (pw) {
		*uid = pw->pw_uid;
	} else {
		tmp = strtol_or_err(s, err);
		*uid = tmp;
		pw = getpwuid(*uid);
	}
	return pw;
}
示例#5
0
int main(int argc, char **argv)
{
	int j, ct, opt, xflag = 0;
	long divisor = 0;

	static const struct option longopts[] = {
		{"divisor", required_argument, NULL, 'd'},
		{"sectors", no_argument,       NULL, 'x'},
		{"version", no_argument,       NULL, 'V'},
		{"help",    no_argument,       NULL, 'h'},
		{NULL, 0, NULL, 0}
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while ((opt = getopt_long(argc, argv, "d:xVh", longopts, NULL)) != -1)
		switch (opt) {
		case 'd':
			divisor =
			    strtol_or_err(optarg,
					  _("invalid divisor argument"));
			break;
		case 'x':
			xflag = 1;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage(stdout);
		default:
			errtryhelp(EXIT_FAILURE);
		}

	ct = argc - optind;

	if (ct <= 0)
		usage(stderr);

	for (j = optind; j < argc; j++)
		isosize(ct, argv[j], xflag, divisor);

	return EXIT_SUCCESS;
}
示例#6
0
/* parses -N option */
static long old_style_option(int *argc, char **argv)
{
	int i = 1, nargs = *argc;
	long lines = -1;

	while(i < nargs) {
		if (argv[i][0] == '-' && isdigit(argv[i][1])) {
			lines = strtol_or_err(argv[i] + 1,
					_("failed to parse number of lines"));
			nargs--;
			if (nargs - i)
				memmove(argv + i, argv + i + 1,
						sizeof(char *) * (nargs - i));
		} else
			i++;
	}
	*argc = nargs;
	return lines;
}
示例#7
0
static void parse_groups(struct privctx *opts, const char *str)
{
    char *groups = xstrdup(str);
    char *buf = groups;	/* We'll reuse it */
    char *c;
    size_t i = 0;

    opts->have_groups = 1;
    opts->num_groups = 0;
    while ((c = strsep(&groups, ",")))
        opts->num_groups++;

    /* Start again */
    strcpy(buf, str);	/* It's exactly the right length */
    groups = buf;

    opts->groups = xcalloc(opts->num_groups, sizeof(gid_t));
    while ((c = strsep(&groups, ",")))
        opts->groups[i++] = (gid_t) strtol_or_err(c,
                            _("Invalid supplementary group id"));

    free(groups);
}
示例#8
0
int main(int argc, char *argv[])
{
	struct itimerval timeout, old_timer;
	int have_timeout = 0;
	int type = LOCK_EX;
	int block = 0;
	int open_flags = 0;
	int fd = -1;
	int opt, ix;
	int do_close = 0;
	int status;
	/*
	 * The default exit code for lock conflict or timeout
	 * is specified in man flock.1
	 */
	int conflict_exit_code = 1;
	char **cmd_argv = NULL, *sh_c_argv[4];
	const char *filename = NULL;
	struct sigaction old_sa;

	static const struct option long_options[] = {
		{"shared", no_argument, NULL, 's'},
		{"exclusive", no_argument, NULL, 'x'},
		{"unlock", no_argument, NULL, 'u'},
		{"nonblocking", no_argument, NULL, 'n'},
		{"nb", no_argument, NULL, 'n'},
		{"timeout", required_argument, NULL, 'w'},
		{"wait", required_argument, NULL, 'w'},
		{"conflict-exit-code", required_argument, NULL, 'E'},
		{"close", no_argument, NULL, 'o'},
		{"help", no_argument, NULL, 'h'},
		{"version", no_argument, NULL, 'V'},
		{NULL, 0, NULL, 0}
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	if (argc < 2)
		usage(EX_USAGE);

	memset(&timeout, 0, sizeof timeout);

	optopt = 0;
	while ((opt =
		getopt_long(argc, argv, "+sexnouw:E:hV?", long_options,
			    &ix)) != EOF) {
		switch (opt) {
		case 's':
			type = LOCK_SH;
			break;
		case 'e':
		case 'x':
			type = LOCK_EX;
			break;
		case 'u':
			type = LOCK_UN;
			break;
		case 'o':
			do_close = 1;
			break;
		case 'n':
			block = LOCK_NB;
			break;
		case 'w':
			have_timeout = 1;
			strtotimeval_or_err(optarg, &timeout.it_value,
				_("invalid timeout value"));
			if (timeout.it_value.tv_sec + timeout.it_value.tv_usec == 0)
				errx(EX_USAGE, _("timeout cannot be zero"));
			break;
		case 'E':
			conflict_exit_code = strtos32_or_err(optarg,
				_("invalid exit code"));
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			exit(EX_OK);
		default:
			/* optopt will be set if this was an unrecognized
			 * option, i.e.  *not* 'h' or '?
			 */
			usage(optopt ? EX_USAGE : 0);
			break;
		}
	}

	if (argc > optind + 1) {
		/* Run command */
		if (!strcmp(argv[optind + 1], "-c") ||
		    !strcmp(argv[optind + 1], "--command")) {
			if (argc != optind + 3)
				errx(EX_USAGE,
				     _("%s requires exactly one command argument"),
				     argv[optind + 1]);
			cmd_argv = sh_c_argv;
			cmd_argv[0] = getenv("SHELL");
			if (!cmd_argv[0] || !*cmd_argv[0])
				cmd_argv[0] = _PATH_BSHELL;
			cmd_argv[1] = "-c";
			cmd_argv[2] = argv[optind + 2];
			cmd_argv[3] = 0;
		} else {
			cmd_argv = &argv[optind + 1];
		}

		filename = argv[optind];
		fd = open_file(filename, &open_flags);

	} else if (optind < argc) {
		/* Use provided file descriptor */
		fd = (int)strtol_or_err(argv[optind], "bad number");
	} else {
		/* Bad options */
		errx(EX_USAGE, _("requires file descriptor, file or directory"));
	}

	if (have_timeout) {
		if (timeout.it_value.tv_sec == 0 &&
		    timeout.it_value.tv_usec == 0) {
			/* -w 0 is equivalent to -n; this has to be
			 * special-cased because setting an itimer to zero
			 * means disabled!
			 */
			have_timeout = 0;
			block = LOCK_NB;
		} else
			setup_timer(&timeout, &old_timer, &old_sa, timeout_handler);
	}

	while (flock(fd, type | block)) {
		switch (errno) {
		case EWOULDBLOCK:
			/* -n option set and failed to lock. */
			exit(conflict_exit_code);
		case EINTR:
			/* Signal received */
			if (timeout_expired)
				/* -w option set and failed to lock. */
				exit(conflict_exit_code);
			/* otherwise try again */
			continue;
		case EIO:
		case EBADF:		/* since Linux 3.4 (commit 55725513) */
			/* Probably NFSv4 where flock() is emulated by fcntl().
			 * Let's try to reopen in read-write mode.
			 */
			if (!(open_flags & O_RDWR) &&
			    type != LOCK_SH &&
			    filename &&
			    access(filename, R_OK | W_OK) == 0) {

				close(fd);
				open_flags = O_RDWR;
				fd = open_file(filename, &open_flags);

				if (open_flags & O_RDWR)
					break;
			}
			/* go through */
		default:
			/* Other errors */
			if (filename)
				warn("%s", filename);
			else
				warn("%d", fd);
			exit((errno == ENOLCK
			      || errno == ENOMEM) ? EX_OSERR : EX_DATAERR);
		}
	}

	if (have_timeout)
		cancel_timer(&old_timer, &old_sa);

	status = EX_OK;

	if (cmd_argv) {
		pid_t w, f;
		/* Clear any inherited settings */
		signal(SIGCHLD, SIG_DFL);
		f = fork();

		if (f < 0) {
			err(EX_OSERR, _("fork failed"));
		} else if (f == 0) {
			if (do_close)
				close(fd);
			execvp(cmd_argv[0], cmd_argv);
			/* execvp() failed */
			warn(_("failed to execute %s"), cmd_argv[0]);
			_exit((errno == ENOMEM) ? EX_OSERR : EX_UNAVAILABLE);
		} else {
			do {
				w = waitpid(f, &status, 0);
				if (w == -1 && errno != EINTR)
					break;
			} while (w != f);

			if (w == -1) {
				status = EXIT_FAILURE;
				warn(_("waitpid failed"));
			} else if (WIFEXITED(status))
				status = WEXITSTATUS(status);
			else if (WIFSIGNALED(status))
				status = WTERMSIG(status) + 128;
			else
				/* WTF? */
				status = EX_OSERR;
		}
	}

	return status;
}
示例#9
0
int
main (int argc, char **argv)
{
  int c, n_ports, n_online;
  bool verbose = false, summary = false;
  char *critical = NULL, *warning = NULL;
  nagstatus status = STATE_OK;
  thresholds *my_threshold = NULL;

  unsigned long delay, count;
  unsigned int sleep_time = 1;

  set_program_name (argv[0]);

  while ((c = getopt_long (argc, argv,
			   "c:w:vi" GETOPT_HELP_VERSION_STRING,
			   longopts, NULL)) != -1)
    {
      switch (c)
	{
	default:
	  usage (stderr);
	case 'i':
	  summary = true;
	  break;
	case 'c':
	  critical = optarg;
	  break;
	case 'w':
	  warning = optarg;
	  break;
	case 'v':
	  verbose = true;
	  break;

	case_GETOPT_HELP_CHAR
	case_GETOPT_VERSION_CHAR

	}
    }

  if (summary)
    {
      fc_host_summary (verbose);
      return STATE_UNKNOWN;
    }

  delay = DELAY_DEFAULT, count = COUNT_DEFAULT;
  if (optind < argc)
    {
      delay = strtol_or_err (argv[optind++], "failed to parse argument");

      if (delay < 1)
	plugin_error (STATE_UNKNOWN, 0, "delay must be positive integer");
      else if (UINT_MAX < delay)
	plugin_error (STATE_UNKNOWN, 0, "too large delay value");

      sleep_time = delay;
    }

  if (optind < argc)
    count = strtol_or_err (argv[optind++], "failed to parse argument");

  status = set_thresholds (&my_threshold, warning, critical);
  if (status == NP_RANGE_UNPARSEABLE)
    usage (stderr);

  fc_host_statistics stats = {0};

  fc_host_status (&n_ports, &n_online, &stats, sleep_time, count);
  status = get_status (n_online, my_threshold);

  printf ("%s %s - Fiber Channel ports status: %d/%d Online "
	  "| rx_frames=%Lu tx_frames=%Lu"
	  " error_frames=%Lu"
	  " invalid_crc_count=%Lu"
	  " link_failure_count=%Lu"
	  " loss_of_signal_count=%Lu"
	  " loss_of_sync_count=%Lu\n",
	  program_name_short, state_text (status),
	  n_online, n_ports,
	  (unsigned long long) stats.rx_frames,
	  (unsigned long long) stats.tx_frames,
	  (unsigned long long) stats.error_frames,
	  (unsigned long long) stats.invalid_crc_count,
	  (unsigned long long) stats.link_failure_count,
	  (unsigned long long) stats.loss_of_signal_count,
	  (unsigned long long) stats.loss_of_sync_count
  );

  return status;
}
示例#10
0
文件: slabtop.c 项目: gs0622/procps
int main(int argc, char *argv[])
{
	int o;
	unsigned short old_rows;
	struct slab_info *slab_list = NULL;
	int run_once = 0, retval = EXIT_SUCCESS;

	static const struct option longopts[] = {
		{ "delay",	required_argument, NULL, 'd' },
		{ "sort",	required_argument, NULL, 's' },
		{ "once",	no_argument,	   NULL, 'o' },
		{ "help",	no_argument,	   NULL, 'h' },
		{ "version",	no_argument,	   NULL, 'V' },
		{  NULL, 0, NULL, 0 }
	};

#ifdef HAVE_PROGRAM_INVOCATION_NAME
	program_invocation_name = program_invocation_short_name;
#endif
	setlocale (LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	sort_func = DEF_SORT_FUNC;

	while ((o = getopt_long(argc, argv, "d:s:ohV", longopts, NULL)) != -1) {
		switch (o) {
		case 'd':
			errno = 0;
			delay = strtol_or_err(optarg, _("illegal delay"));
			if (delay < 1)
				xerrx(EXIT_FAILURE,
					_("delay must be positive integer"));
			break;
		case 's':
			sort_func = (int (*)(const struct slab_info*,
				const struct slab_info *)) set_sort_func(optarg[0]);
			break;
		case 'o':
			run_once=1;
			delay = 0;
			break;
		case 'V':
			printf(PROCPS_NG_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}
	}

	if (tcgetattr(STDIN_FILENO, &saved_tty) == -1)
		xwarn(_("terminal setting retrieval"));

	old_rows = rows;
	term_size(0);
	if (!run_once) {
		initscr();
		resizeterm(rows, cols);
		signal(SIGWINCH, term_size);
	}
	signal(SIGINT, sigint_handler);

	do {
		struct slab_info *curr;
		struct slab_stat stats;
		struct timeval tv;
		fd_set readfds;
		char c;
		int i;
		memset(&stats, 0, sizeof(struct slab_stat));

		if (get_slabinfo(&slab_list, &stats)) {
			retval = EXIT_FAILURE;
			break;
		}

		if (!run_once && old_rows != rows) {
			resizeterm(rows, cols);
			old_rows = rows;
		}

		move(0, 0);
		print_line(" %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %.2fK / %.2fK (%.1f%%)\n"
		       " %-35s: %.2fK / %.2fK / %.2fK\n\n",
		       /* Translation Hint: Next five strings must not
			* exceed 35 length in characters.  */
		       /* xgettext:no-c-format */
		       _("Active / Total Objects (% used)"),
		       stats.nr_active_objs, stats.nr_objs,
		       100.0 * stats.nr_active_objs / stats.nr_objs,
	               /* xgettext:no-c-format */
		       _("Active / Total Slabs (% used)"),
		       stats.nr_active_slabs, stats.nr_slabs,
		       100.0 * stats.nr_active_slabs / stats.nr_slabs,
	               /* xgettext:no-c-format */
		       _("Active / Total Caches (% used)"),
		       stats.nr_active_caches, stats.nr_caches,
		       100.0 * stats.nr_active_caches / stats.nr_caches,
	               /* xgettext:no-c-format */
		       _("Active / Total Size (% used)"),
		       stats.active_size / 1024.0, stats.total_size / 1024.0,
		       100.0 * stats.active_size / stats.total_size,
		       _("Minimum / Average / Maximum Object"),
		       stats.min_obj_size / 1024.0, stats.avg_obj_size / 1024.0,
		       stats.max_obj_size / 1024.0);

		slab_list = slabsort(slab_list);

		attron(A_REVERSE);
		/* Translation Hint: Please keep alignment of the
		 * following intact. */
		print_line("%-78s\n", _("  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME"));
		attroff(A_REVERSE);

		curr = slab_list;
		for (i = 0; i < rows - 8 && curr->next; i++) {
			print_line("%6u %6u %3u%% %7.2fK %6u %8u %9uK %-23s\n",
				curr->nr_objs, curr->nr_active_objs, curr->use,
				curr->obj_size / 1024.0, curr->nr_slabs,
				curr->objs_per_slab, (unsigned)(curr->cache_size / 1024),
				curr->name);
			curr = curr->next;
		}

		put_slabinfo(slab_list);
		if (!run_once) {
			refresh();
			FD_ZERO(&readfds);
			FD_SET(STDIN_FILENO, &readfds);
			tv.tv_sec = delay;
			tv.tv_usec = 0;
			if (select(STDOUT_FILENO, &readfds, NULL, NULL, &tv) > 0) {
				if (read(STDIN_FILENO, &c, 1) != 1)
					break;
				parse_input(c);
			}
		}
	} while (delay);

	tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_tty);
	free_slabinfo(slab_list);
	if (!run_once)
		endwin();
	return retval;
}
示例#11
0
int main (int argc, char *argv[])
{
    int errors, numsig, pid;
    char *ep, *arg, *p;
    int do_pid, do_kill, check_all;
    int *pids, *ip;

    progname = argv[0];
    if ((p = strrchr(progname, '/')) != NULL)
	    progname = p+1;

    setlocale(LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);

    numsig = SIGTERM;
    do_pid = (! strcmp (progname, "pid")); 	/* Yecch */
    do_kill = 0;
    check_all = 0;

    /*  loop through the arguments.
	actually, -a is the only option can be used with other options.
	`kill' is basically a one-option-at-most program.  */
    for (argc--, argv++; argc > 0; argc--, argv++) {
	arg = *argv;
	if (*arg != '-') {
	    break;
	}
	if (! strcmp (arg, "--")) {
	    argc--, argv++;
	    break;
	}
	if (! strcmp (arg, "-v") || ! strcmp (arg, "-V") ||
	    ! strcmp (arg, "--version")) {
	    printf(_("%s from %s\n"), progname, PACKAGE_STRING);
	    return 0;
	}
	if (! strcmp (arg, "-a")) {
	    check_all++;
	    continue;
	}
	if (! strcmp (arg, "-l")) {
	    if (argc < 2) {
		printsignals (stdout);
		return 0;
	    }
	    if (argc > 2) {
		return usage (1);
	    }
	    /* argc == 2, accept "kill -l $?" */
	    arg = argv[1];
	    if ((numsig = arg_to_signum (arg, 1)) < 0) {
		fprintf (stderr, _("%s: unknown signal %s\n"), progname, arg);
		return 1;
	    }
	    printsig (numsig);
	    return 0;
	}
	if (! strcmp (arg, "-p")) {
	    do_pid++;
	    if (do_kill)
		return usage (1);
	    continue;
	}
	if (! strcmp (arg, "-s")) {
	    if (argc < 2) {
		return usage (1);
	    }
	    do_kill++;
	    if (do_pid)
		return usage (1);
	    argc--, argv++;
	    arg = *argv;
	    if ((numsig = arg_to_signum (arg, 0)) < 0) {
		nosig (arg);
		return 1;
	    }
	    continue;
	}
	if (! strcmp (arg, "-q")) {
	    if (argc < 2)
		return usage (1);
	    argc--, argv++;
	    arg = *argv;
#ifdef HAVE_SIGQUEUE
	    sigdata.sival_int = strtol_or_err(arg, _("failed to parse sigval"));
	    use_sigval = 1;
#endif
	    continue;
	}
	/*  `arg' begins with a dash but is not a known option.
	    so it's probably something like -HUP, or -1/-n
	    try to deal with it.
	    -n could be signal n, or pid -n (i.e. process group n).
	    In case of doubt POSIX tells us to assume a signal.
	    If a signal has been parsed, assume it's a pid, break */
	if (do_kill)
	  break;
	arg++;
	if ((numsig = arg_to_signum (arg, 0)) < 0) {
	    return usage (1);
	}
	do_kill++;
	if (do_pid)
	    return usage (1);
	continue;
    }

    if (! *argv) {
	return usage (1);
    }
    if (do_pid) {
	numsig = -1;
    }

    /*  we're done with the options.
	the rest of the arguments should be process ids and names.
	kill them.  */
    for (errors = 0; (arg = *argv) != NULL; argv++) {
	pid = strtol (arg, &ep, 10);
	if (! *ep)
	    errors += kill_verbose (arg, pid, numsig);
	else {
	    pids = get_pids (arg, check_all);
	    if (! pids) {
		errors++;
		fprintf (stderr, _("%s: can't find process \"%s\"\n"),
			 progname, arg);
		continue;
	    }
	    for (ip = pids; *ip >= 0; ip++)
		errors += kill_verbose (arg, *ip, numsig);
	    free (pids);
	}
    }
    return (errors);
}
int
main (int argc, char **argv)
{
  int c;
  bool verbose = false;
  char *critical = NULL, *warning = NULL;
  nagstatus status = STATE_OK;
  thresholds *my_threshold = NULL;

  unsigned long long nctxt[2];
  unsigned int sleep_time = 1,
	   tog = 0;		/* toggle switch for cleaner code */
  unsigned long i, delay, count;

  set_program_name (argv[0]);

  while ((c = getopt_long (argc, argv,
			   "c:w:v" GETOPT_HELP_VERSION_STRING,
			   longopts, NULL)) != -1)
    {
      switch (c)
	{
	default:
	  usage (stderr);
	case 'c':
	  critical = optarg;
	  break;
	case 'w':
	  warning = optarg;
	  break;
	case 'v':
	  verbose = true;
	  break;

	case_GETOPT_HELP_CHAR
	case_GETOPT_VERSION_CHAR

	}
    }

  delay = DELAY_DEFAULT, count = COUNT_DEFAULT;
  if (optind < argc)
    {
      delay = strtol_or_err (argv[optind++], "failed to parse argument");

      if (delay < 1)
	plugin_error (STATE_UNKNOWN, 0, "delay must be positive integer");
      else if (UINT_MAX < delay)
	plugin_error (STATE_UNKNOWN, 0, "too large delay value");

      sleep_time = delay;
    }

  if (optind < argc)
    count = strtol_or_err (argv[optind++], "failed to parse argument");

  status = set_thresholds (&my_threshold, warning, critical);
  if (status == NP_RANGE_UNPARSEABLE)
    usage (stderr);

  unsigned long long dnctxt = nctxt[0] = cpu_stats_get_cswch ();
  if (verbose)
    printf ("ctxt = %Lu\n", dnctxt);

  for (i = 1; i < count; i++)
    {
      sleep (sleep_time);

      tog = !tog;
      nctxt[tog] = cpu_stats_get_cswch ();
      dnctxt = (nctxt[tog] - nctxt[!tog]) / sleep_time;

      if (verbose)
	printf ("ctxt = %Lu --> %Lu/s\n", nctxt[tog], dnctxt);
    }

  status = get_status (dnctxt, my_threshold);
  free (my_threshold);

  char *time_unit = (count > 1) ? "/s" : "";
  printf ("%s %s - number of context switches%s %Lu | cswch%s=%Lu\n",
	  program_name_short, state_text (status),
	  time_unit, dnctxt, time_unit, dnctxt);

  return status;
}
示例#13
0
/*
 * logger -- read and log utility
 * Reads from an input and arranges to write the result on the system log.
 */
int main (int argc, char **argv) {
    int ch, logflags, pri;
    char *tag, buf[MAX_LINE];
    char *usock = NULL;
    long timeout_ms = 100;
    long timeout_sec;
    long timeout_usec;
    int indent_mode = 0;
    char *udpserver = NULL;
    int LogSock = -1;
    long tmpport;

    static const struct option longopts[] = {
        { "id",       no_argument,        0, 'i' },
        { "stderr",   no_argument,        0, 's' },
        { "file",     required_argument,  0, 'f' },
        { "priority", required_argument,  0, 'p' },
        { "tag",      required_argument,  0, 't' },
        { "socket",   required_argument,  0, 'u' },
        { "udp",      no_argument,        0, 'd' },
        { "server",   required_argument,  0, 'n' },
        { "port",     required_argument,  0, 'P' },
        { "indent",   required_argument,  0, 'I' },
        { "version",  no_argument,        0, 'V' },
        { "help",     no_argument,        0, 'h' },
        { NULL,       0,                  0, 0   }
    };

    tag = NULL;
    pri = LOG_NOTICE;
    logflags = 0;

    while ((ch = getopt_long(argc, argv, "f:ip:st:u:dI:n:P:Vh", longopts, NULL)) != -1) {
        switch((char) ch) {
            case 'f': /* file to log */
                if (freopen(optarg, "r", stdin) == NULL)
                    err(EXIT_FAILURE, "file %s", optarg);
                break;

            case 'i': /* log process id also */
                logflags |= LOG_PID;
                break;

            case 'p': /* priority */
                pri = pencode(optarg);
                break;

            case 's': /* log to standard error */
                logflags |= LOG_PERROR;
                break;

            case 't': /* tag */
                tag = optarg;
                break;

            case 'u': /* unix socket */
                usock = optarg;
                break;

            case 'd':
                optd = 1; /* use datagrams */
                break;

            case 'n': /* udp socket */
                optd = 1; /* use datagrams because udp */
                udpserver = optarg;
                break;

            case 'P': /* change udp port */
                tmpport = strtol_or_err(optarg, "failed to parse port number");

                if (tmpport < 0 || 65535 < tmpport) {
                    errx(EXIT_FAILURE, "port `%ld' out of range", tmpport);
                }

                udpport = (int) tmpport;
                break;

            case 'V':
                printf("%s %s\n", PROGRAM_NAME, PROGRAM_VERSION);
                exit(EXIT_SUCCESS);

            case 'I':
                indent_mode = 1;
                timeout_ms = strtol_or_err(optarg, "failed to parse timeout number");

                if (timeout_ms < 1) {
                    errx(EXIT_FAILURE, "Invalid value for timeout %li", timeout_ms);
                }

                break;

            case 'h':
                usage(stdout);

            case '?':
            default:
                usage(stderr);
        }
    }

    argc -= optind;
    argv += optind;

    /* setup for logging */
    if (!usock && !udpserver) {
        openlog(tag ? tag : getlogin(), logflags, 0);
    } else if (udpserver) {
        LogSock = udpopenlog(udpserver, udpport);
    } else {
        LogSock = myopenlog(usock);
    }

    (void) fclose(stdout);

    /* log input line if appropriate */
    if (argc > 0) {
        char *p, *endp;
        size_t len;

        for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
            len = strlen(*argv);
            if (p + len > endp && p > buf) {
                if (!usock && !udpserver) {
                    syslog(pri, "%s", buf);
                } else {
                    mysyslog(LogSock, logflags, pri, tag, buf);
                }

                p = buf;
            }

            if (len > sizeof(buf) - 1) {
                if (!usock && !udpserver) {
                    syslog(pri, "%s", *argv++);
                } else {
                    mysyslog(LogSock, logflags, pri, tag, *argv++);
                }

            } else {
                if (p != buf) {
                    *p++ = ' ';
                }

                memmove(p, *argv++, len);
                *(p += len) = '\0';
            }
        }

        if (p != buf) {
            if (!usock && !udpserver) {
                syslog(pri, "%s", buf);
            } else {
                mysyslog(LogSock, logflags, pri, tag, buf);
            }
        }

    } else if (indent_mode) {
        int len;

        timeout_sec = timeout_ms / 1000;
        timeout_usec = (timeout_ms % 1000) * 1000;

        while ((len = readBlock(buf, MAX_LINE, timeout_sec, timeout_usec)) != EOF) {
            //fprintf(stderr, "Got buf %i\n", len);
            if (len > 0 && buf[len - 1] == '\n') {
                buf[len - 1] = '\0';
            }

            if (!usock && !udpserver) {
                syslog(pri, "%s", buf);
            } else {
                mysyslog(LogSock, logflags, pri, tag, buf);
            }
        }
    } else {
        while (fgets(buf, sizeof(buf), stdin) != NULL) {
            /* glibc is buggy and adds an additional newline, so we have to remove it here until glibc is fixed */
            int len = strlen(buf);

            if (len > 0 && buf[len - 1] == '\n') {
                buf[len - 1] = '\0';
            }

            if (!usock && !udpserver) {
                syslog(pri, "%s", buf);
            } else {
                mysyslog(LogSock, logflags, pri, tag, buf);
            }
        }
    }

    if (!usock && !udpserver) {
        closelog();
    } else {
        close(LogSock);
    }

    return EXIT_SUCCESS;
}
示例#14
0
文件: ionice.c 项目: Romutk/lab3.2n
int main(int argc, char *argv[])
{
	int ioprio = 4, set = 0, ioclass = IOPRIO_CLASS_BE, c;
	pid_t pid = 0;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) {
		switch (c) {
		case 'n':
			ioprio = strtol_or_err(optarg, _("failed to parse class data"));
			set |= 1;
			break;
		case 'c':
			ioclass = strtol_or_err(optarg, _("failed to parse class"));
			set |= 2;
			break;
		case 'p':
			pid = strtol_or_err(optarg, _("failed to parse pid"));
			break;
		case 't':
			tolerant = 1;
			break;
		case 'h':
			usage(EXIT_SUCCESS);
		default:
			usage(EXIT_FAILURE);
		}
	}

	switch (ioclass) {
		case IOPRIO_CLASS_NONE:
			if (set & 1)
				warnx(_("ignoring given class data for none class"));
			ioprio = 0;
			break;
		case IOPRIO_CLASS_RT:
		case IOPRIO_CLASS_BE:
			break;
		case IOPRIO_CLASS_IDLE:
			if (set & 1)
				warnx(_("ignoring given class data for idle class"));
			ioprio = 7;
			break;
		default:
			errx(EXIT_FAILURE, _("bad prio class %d"), ioclass);
	}

	if (!set) {
		ioprio_print(pid);

		for(; argv[optind]; ++optind) {
			pid = strtol_or_err(argv[optind], _("failed to parse pid"));
			ioprio_print(pid);
		}
	} else {
		if (pid) {
			ioprio_setpid(pid, ioprio, ioclass);

			for(; argv[optind]; ++optind)
			{
				pid = strtol_or_err(argv[optind], _("failed to parse pid"));
				ioprio_setpid(pid, ioprio, ioclass);
			}
		}
		else if (argv[optind]) {
			ioprio_setpid(0, ioprio, ioclass);
			execvp(argv[optind], &argv[optind]);
			/* execvp should never return */
			err(EXIT_FAILURE, _("executing %s failed"), argv[optind]);
		}
	}

	exit(EXIT_SUCCESS);
}
示例#15
0
int main(int argc, char **argv)
{
	cpu_set_t *new_set;
	pid_t pid = 0;
	int c, all_tasks = 0;
	int ncpus;
	size_t new_setsize, nbits;
	struct taskset ts;

	static const struct option longopts[] = {
		{ "all-tasks",	0, NULL, 'a' },
		{ "pid",	0, NULL, 'p' },
		{ "cpu-list",	0, NULL, 'c' },
		{ "help",	0, NULL, 'h' },
		{ "version",	0, NULL, 'V' },
		{ NULL,		0, NULL,  0  }
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

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

	while ((c = getopt_long(argc, argv, "+apchV", longopts, NULL)) != -1) {
		switch (c) {
		case 'a':
			all_tasks = 1;
			break;
		case 'p':
			pid = strtol_or_err(argv[argc - 1],
					    _("failed to parse pid"));
			break;
		case 'c':
			ts.use_list = 1;
			break;
		case 'V':
			printf("%s from %s\n", program_invocation_short_name,
			       PACKAGE_STRING);
			return EXIT_SUCCESS;
		case 'h':
			usage(stdout);
			break;
		default:
			usage(stderr);
			break;
		}
	}

	if ((!pid && argc - optind < 2)
	    || (pid && (argc - optind < 1 || argc - optind > 2)))
		usage(stderr);

	ncpus = get_max_number_of_cpus();
	if (ncpus <= 0)
		errx(EXIT_FAILURE, _("cannot determine NR_CPUS; aborting"));

	/*
	 * the ts->set is always used for the sched_getaffinity call
	 * On the sched_getaffinity the kernel demands a user mask of
	 * at least the size of its own cpumask_t.
	 */
	ts.set = cpuset_alloc(ncpus, &ts.setsize, &nbits);
	if (!ts.set)
		err(EXIT_FAILURE, _("cpuset_alloc failed"));

	/* buffer for conversion from mask to string */
	ts.buflen = 7 * nbits;
	ts.buf = xmalloc(ts.buflen);

	/*
	 * new_set is always used for the sched_setaffinity call
	 * On the sched_setaffinity the kernel will zero-fill its
	 * cpumask_t if the user's mask is shorter.
	 */
	new_set = cpuset_alloc(ncpus, &new_setsize, NULL);
	if (!new_set)
		err(EXIT_FAILURE, _("cpuset_alloc failed"));

	if (argc - optind == 1)
		ts.get_only = 1;

	else if (ts.use_list) {
		if (cpulist_parse(argv[optind], new_set, new_setsize, 0))
			errx(EXIT_FAILURE, _("failed to parse CPU list: %s"),
			     argv[optind]);
	} else if (cpumask_parse(argv[optind], new_set, new_setsize)) {
		errx(EXIT_FAILURE, _("failed to parse CPU mask: %s"),
		     argv[optind]);
	}

	if (all_tasks) {
		struct proc_tasks *tasks = proc_open_tasks(pid);
		while (!proc_next_tid(tasks, &ts.pid))
			do_taskset(&ts, new_setsize, new_set);
		proc_close_tasks(tasks);
	} else {
		ts.pid = pid;
		do_taskset(&ts, new_setsize, new_set);
	}

	free(ts.buf);
	cpuset_free(ts.set);
	cpuset_free(new_set);

	if (!pid) {
		argv += optind + 1;
		execvp(argv[0], argv);
		err(EXIT_FAILURE, _("executing %s failed"), argv[0]);
	}

	return EXIT_SUCCESS;
}
示例#16
0
int main(int argc, char **argv)
{
	int lines, row, col = 0;
	int i, opt;
	double av[3];
	static double max_scale = 0, scale_fact;
	long tmpdly;

	static const struct option longopts[] = {
		{"scale", required_argument, NULL, 's'},
		{"delay", required_argument, NULL, 'd'},
		{"help", no_argument, NULL, 'h'},
		{"version", no_argument, NULL, 'V'},
		{NULL, 0, NULL, 0}
	};
#ifdef HAVE_PROGRAM_INVOCATION_NAME
	program_invocation_name = program_invocation_short_name;
#endif
	setlocale (LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while ((opt =
		getopt_long(argc, argv, "s:d:Vh", longopts, NULL)) != -1)
		switch (opt) {
		case 's':
			max_scale = strtod_or_err(optarg, _("failed to parse argument"));
			if (max_scale < 0)
			        xerrx(EXIT_FAILURE, _("scale cannot be negative"));
			break;
		case 'd':
			tmpdly = strtol_or_err(optarg, _("failed to parse argument"));
			if (tmpdly < 1)
				xerrx(EXIT_FAILURE, _("delay must be positive integer"));
			else if (UINT_MAX < tmpdly)
				xerrx(EXIT_FAILURE, _("too large delay value"));
			dly = tmpdly;
			break;
		case 'V':
			printf(PROCPS_NG_VERSION);
			return EXIT_SUCCESS;
			break;
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}

	if (argc > optind)
		if ((fd = open(argv[optind], 1)) == -1)
			xerr(EXIT_FAILURE, _("can not open tty"));

	setsize(0);

	if (max_scale == 0)
		max_scale = nrows;

	scale_fact = max_scale;

	setjmp(jb);
	col = 0;
	alrm(0);

	while (1) {

		if (scale_fact < max_scale)
			scale_fact *= 2.0;	/* help it drift back up. */

		loadavg(&av[0], &av[1], &av[2]);

		do {
			lines = av[0] * scale_fact;
			row = nrows - 1;

			while (0 <= --lines) {
				*(screen + row * ncols + col) = '*';
				if (--row < 0) {
					scale_fact /= 2.0;
					break;
				}
			}
		} while (0 <= lines);

		while (row >= 0)
			*(screen + row-- * ncols + col) = ' ';

		for (i = 1;; ++i) {
			char *p;
			row = nrows - (i * scale_fact);
			if (row < 0)
				break;
			if (*(p = screen + row * ncols + col) == ' ')
				*p = '-';
			else
				*p = '=';
		}

		if (++col == ncols) {
			--col;
			memmove(screen, screen + 1, scr_size - 1);

			for (row = nrows - 2; row >= 0; --row)
				*(screen + row * ncols + col) = ' ';
		}
		i = sprintf(screen, " %.2f, %.2f, %.2f", av[0], av[1], av[2]);
		if (i > 0)
			screen[i] = ' ';

		if (write(fd, "\033[H", 3) < 0)
			xerr(EXIT_FAILURE, _("writing to tty failed"));
		if (write(fd, screen, scr_size - 1) < 0)
			xerr(EXIT_FAILURE, _("writing to tty failed"));
		pause();
	}
}
示例#17
0
int
main (int argc, char **argv)
{
  int c;
  bool verbose = false;
  char *critical = NULL, *warning = NULL;
  nagstatus status = STATE_OK;
  thresholds *my_threshold = NULL;

  unsigned long long nintr[2];
  unsigned int sleep_time = 1,
	   tog = 0,		/* toggle switch for cleaner code */
	   ncpus0, ncpus1;
  unsigned long i, delay, count,
	   *vintr[2] = { NULL, NULL };

  set_program_name (argv[0]);

  while ((c = getopt_long (argc, argv,
			   "c:w:v" GETOPT_HELP_VERSION_STRING,
			   longopts, NULL)) != -1)
    {
      switch (c)
	{
	default:
	  usage (stderr);
	case 'c':
	  critical = optarg;
	  break;
	case 'w':
	  warning = optarg;
	  break;
	case 'v':
	  verbose = true;
	  break;

	case_GETOPT_HELP_CHAR
	case_GETOPT_VERSION_CHAR

	}
    }

  delay = DELAY_DEFAULT, count = COUNT_DEFAULT;
  if (optind < argc)
    {
      delay = strtol_or_err (argv[optind++], "failed to parse argument");

      if (delay < 1)
	plugin_error (STATE_UNKNOWN, 0, "delay must be positive integer");
      else if (UINT_MAX < delay)
	plugin_error (STATE_UNKNOWN, 0, "too large delay value");

      sleep_time = delay;
    }

  if (optind < argc)
    count = strtol_or_err (argv[optind++], "failed to parse argument");

  status = set_thresholds (&my_threshold, warning, critical);
  if (status == NP_RANGE_UNPARSEABLE)
    usage (stderr);

  unsigned long long dnintr = nintr[0] = cpu_stats_get_intr ();
  if (verbose)
    printf ("intr = %Lu\n", dnintr);

  if (count <= 2)
    vintr[0] = proc_interrupts_get_nintr_per_cpu (&ncpus0);

  for (i = 1; i < count; i++)
    {
      sleep (sleep_time);

      tog = !tog;
      nintr[tog] = cpu_stats_get_intr ();

      dnintr = (nintr[tog] - nintr[!tog]) / sleep_time;
      if (verbose)
	printf ("intr = %Lu --> %Lu/s\n", nintr[tog], dnintr);

      if (count - 2 == i)
	vintr[0] = proc_interrupts_get_nintr_per_cpu (&ncpus0);
      else if (count - 1 == i)
	vintr[1] = proc_interrupts_get_nintr_per_cpu (&ncpus1);
    }

  status = get_status (dnintr, my_threshold);
  free (my_threshold);

  char *time_unit = (count > 1) ? "/s" : "";
  printf ("%s %s - number of interrupts%s %Lu | intr%s=%Lu",
	  program_name_short, state_text (status),
	  time_unit, dnintr, time_unit, dnintr);

  for (i = 0; i < MIN (ncpus0, ncpus1); i++)
    printf (" intr_cpu%lu%s=%lu", i, time_unit,
	    (count >
	     1) ? (vintr[1][i] - vintr[0][i]) / sleep_time : vintr[0][i]);
  printf ("\n");

  free (vintr[1]);
  free (vintr[0]);

  return status;
}
示例#18
0
文件: chrt.c 项目: mluscon/util-linux
int main(int argc, char **argv)
{
	int i, policy = SCHED_RR, priority = 0, verbose = 0, policy_flag = 0,
	    all_tasks = 0;
	struct sched_param sp;
	pid_t pid = -1;

	static const struct option longopts[] = {
		{ "all-tasks",  0, NULL, 'a' },
		{ "batch",	0, NULL, 'b' },
		{ "fifo",	0, NULL, 'f' },
		{ "idle",	0, NULL, 'i' },
		{ "pid",	0, NULL, 'p' },
		{ "help",	0, NULL, 'h' },
		{ "max",        0, NULL, 'm' },
		{ "other",	0, NULL, 'o' },
		{ "rr",		0, NULL, 'r' },
		{ "reset-on-fork", 0, NULL, 'R' },
		{ "verbose",	0, NULL, 'v' },
		{ "version",	0, NULL, 'V' },
		{ NULL,		0, NULL, 0 }
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	while((i = getopt_long(argc, argv, "+abfiphmoRrvV", longopts, NULL)) != -1)
	{
		int ret = EXIT_FAILURE;

		switch (i) {
		case 'a':
			all_tasks = 1;
			break;
		case 'b':
#ifdef SCHED_BATCH
			policy = SCHED_BATCH;
#endif
			break;
		case 'f':
			policy = SCHED_FIFO;
			break;
		case 'R':
#ifdef SCHED_RESET_ON_FORK
			policy_flag |= SCHED_RESET_ON_FORK;
#endif
			break;
		case 'i':
#ifdef SCHED_IDLE
			policy = SCHED_IDLE;
#endif
			break;
		case 'm':
			show_min_max();
			return EXIT_SUCCESS;
		case 'o':
			policy = SCHED_OTHER;
			break;
		case 'p':
			errno = 0;
			pid = strtol_or_err(argv[argc - 1], _("failed to parse pid"));
			break;
		case 'r':
			policy = SCHED_RR;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'V':
			printf("%s from %s\n", program_invocation_short_name,
					       PACKAGE_STRING);
			return EXIT_SUCCESS;
		case 'h':
			ret = EXIT_SUCCESS;
			/* fallthrough */
		default:
			show_usage(ret);
		}
	}

	if (((pid > -1) && argc - optind < 1) ||
	    ((pid == -1) && argc - optind < 2))
		show_usage(EXIT_FAILURE);

	if ((pid > -1) && (verbose || argc - optind == 1)) {
		if (all_tasks) {
			pid_t tid;
			struct proc_tasks *ts = proc_open_tasks(pid);

			if (!ts)
				err(EXIT_FAILURE, _("cannot obtain the list of tasks"));
			while (!proc_next_tid(ts, &tid))
				show_rt_info(tid, FALSE);
			proc_close_tasks(ts);
		} else
			show_rt_info(pid, FALSE);

		if (argc - optind == 1)
			return EXIT_SUCCESS;
	}

	errno = 0;
	priority = strtol_or_err(argv[optind], _("failed to parse priority"));

#ifdef SCHED_RESET_ON_FORK
	/* sanity check */
	if ((policy_flag & SCHED_RESET_ON_FORK) &&
	    !(policy == SCHED_FIFO || policy == SCHED_RR))
		errx(EXIT_FAILURE, _("SCHED_RESET_ON_FORK flag is suppoted for "
				     "SCHED_FIFO and SCHED_RR policies only"));
#endif

	policy |= policy_flag;

	if (pid == -1)
		pid = 0;
	sp.sched_priority = priority;

	if (all_tasks) {
		pid_t tid;
		struct proc_tasks *ts = proc_open_tasks(pid);

		if (!ts)
			err(EXIT_FAILURE, _("cannot obtain the list of tasks"));
		while (!proc_next_tid(ts, &tid))
			if (sched_setscheduler(tid, policy, &sp) == -1)
				err(EXIT_FAILURE, _("failed to set tid %d's policy"), tid);
		proc_close_tasks(ts);
	} else if (sched_setscheduler(pid, policy, &sp) == -1)
		err(EXIT_FAILURE, _("failed to set pid %d's policy"), pid);

	if (verbose)
		show_rt_info(pid, TRUE);

	if (!pid) {
		argv += optind + 1;
		execvp(argv[0], argv);
		perror("execvp");
		err(EXIT_FAILURE, _("failed to execute %s"), argv[0]);
	}

	return EXIT_SUCCESS;
}
示例#19
0
int
main (int argc, char **argv)
{
  int c, err;
  bool verbose, cpu_model, per_cpu_stats;
  unsigned long len, i, count, delay;
  char *critical = NULL, *warning = NULL;
  char *p = NULL, *cpu_progname;
  nagstatus currstatus, status;
  thresholds *my_threshold = NULL;

  float cpu_perc = 0.0;
  unsigned int tog = 0;		/* toggle switch for cleaner code */
  struct cpu_desc *cpudesc = NULL;

  set_program_name (argv[0]);

  len = strlen (program_name);
  if (len > 6 && !strncmp (program_name, "check_", 6))
    p = (char *) program_name + 6;
  else
    plugin_error (STATE_UNKNOWN, 0,
		  "bug: the plugin does not have a standard name");

  if (!strncmp (p, "iowait", 6))	/* check_iowait --> cpu_iowait */
    {
      cpu_progname = xstrdup ("iowait");
      program_shorthelp =
        xstrdup ("This plugin checks I/O wait bottlenecks\n");
    }
  else				/* check_cpu --> cpu_user (the default) */
    {
      cpu_progname = xstrdup ("user");;
      program_shorthelp =
        xstrdup ("This plugin checks the CPU (user mode) utilization\n");
    }

  err = cpu_desc_new (&cpudesc);
  if (err < 0)
    plugin_error (STATE_UNKNOWN, err, "memory exhausted");

  /* default values */
  verbose = per_cpu_stats = false;
  cpu_model = true;

  while ((c = getopt_long (
		argc, argv, "c:w:vifmp"
		GETOPT_HELP_VERSION_STRING, longopts, NULL)) != -1)
    {
      switch (c)
	{
	default:
	  usage (stderr);
	case 'i':
	  cpu_desc_read (cpudesc);
	  cpu_desc_summary (cpudesc);
	  return STATE_UNKNOWN;
	case 'm':
	  cpu_model = false;
	  break;
	case 'p':
	  per_cpu_stats = true;
	  break;
	case 'c':
	  critical = optarg;
	  break;
	case 'w':
	  warning = optarg;
	  break;
	case 'v':
	  verbose = true;
	  break;

	case_GETOPT_HELP_CHAR
	case_GETOPT_VERSION_CHAR

	}
    }

  delay = DELAY_DEFAULT, count = COUNT_DEFAULT;
  if (optind < argc)
    {
      delay = strtol_or_err (argv[optind++], "failed to parse argument");

      if (delay < 1)
	plugin_error (STATE_UNKNOWN, 0, "delay must be positive integer");
      else if (DELAY_MAX < delay)
	plugin_error (STATE_UNKNOWN, 0,
		      "too large delay value (greater than %d)", DELAY_MAX);
    }

  if (optind < argc)
    {
      count = strtol_or_err (argv[optind++], "failed to parse argument");
      if (COUNT_MAX < count)
	plugin_error (STATE_UNKNOWN, 0,
		      "too large count value (greater than %d)", COUNT_MAX);
    }

  status = set_thresholds (&my_threshold, warning, critical);
  if (status == NP_RANGE_UNPARSEABLE)
    usage (stderr);

  int ncpus = per_cpu_stats ? get_processor_number_total () + 1 : 1;

  jiff duser[ncpus], dsystem[ncpus], didle[ncpus],
       diowait[ncpus], dsteal[ncpus], ratio[ncpus];
  int debt[ncpus];			/* handle idle ticks running backwards */
  struct cpu_time cpuv[2][ncpus];
  jiff *cpu_value = strncmp (p, "iowait", 6) ? duser : diowait;
  const char *cpuname;

  cpu_stats_get_time (cpuv[0], ncpus);

  for (c = 0; c < ncpus; c++)
    {
      duser[c]   = cpuv[0][c].user + cpuv[0][c].nice;
      dsystem[c] = cpuv[0][c].system + cpuv[0][c].irq + cpuv[0][c].softirq;
      didle[c]   = cpuv[0][c].idle;
      diowait[c] = cpuv[0][c].iowait;
      dsteal[c]  = cpuv[0][c].steal;

      debt[c] = 0;
      ratio[c] = duser[c] + dsystem[c] + didle[c] + diowait[c] + dsteal[c];
      if (!ratio[c])
	ratio[c] = 1, didle[c] = 1;
    }

  for (i = 1; i < count; i++)
    {
      sleep (delay);
      tog = !tog;
      cpu_stats_get_time (cpuv[tog], ncpus);

      for (c = 0; c < ncpus; c++)
	{
	  duser[c] =
	    cpuv[tog][c].user - cpuv[!tog][c].user +
	    cpuv[tog][c].nice - cpuv[!tog][c].nice;
	  dsystem[c] =
	    cpuv[tog][c].system  - cpuv[!tog][c].system +
	    cpuv[tog][c].irq     - cpuv[!tog][c].irq +
	    cpuv[tog][c].softirq - cpuv[!tog][c].softirq;
	  didle[c]   = cpuv[tog][c].idle   - cpuv[!tog][c].idle;
	  diowait[c] = cpuv[tog][c].iowait - cpuv[!tog][c].iowait;
	  dsteal[c]  = cpuv[tog][c].steal  - cpuv[!tog][c].steal;

	  /* idle can run backwards for a moment -- kernel "feature" */
	  if (debt[c])
	    {
	      didle[c] = (int) didle[c] + debt[c];
	      debt[c] = 0;
	    }
	  if ((int) didle[c] < 0)
	    {
	      debt[c] = (int) didle[c];
	      didle[c] = 0;
	    }

	  ratio[c] = duser[c] + dsystem[c] + didle[c] + diowait[c] + dsteal[c];
	  if (!ratio[c])
	    ratio[c] = 1, didle[c] = 1;

	  if (NULL == (cpuname = cpuv[0][c].cpuname))
	    cpuname = "n/a";

	  if (verbose)
	    printf
	     ("%s_user=%.1f%%, %s_system=%.1f%%, %s_idle=%.1f%%, "
	      "%s_iowait=%.1f%%, %s_steal=%.1f%%\n"
	      , cpuname, 100.0 * duser[c]   / ratio[c]
	      , cpuname, 100.0 * dsystem[c] / ratio[c]
	      , cpuname, 100.0 * didle[c]   / ratio[c]
	      , cpuname, 100.0 * diowait[c] / ratio[c]
	      , cpuname, 100.0 * dsteal[c]  / ratio[c]);

	  dbg ("sum (%s_*) = %.1f%%\n", cpuname, (100.0 * duser[c] / ratio[c]) +
	       (100.0 * dsystem[c] / ratio[c]) + (100.0 * didle[c]  / ratio[c]) +
	       (100.0 * diowait[c] / ratio[c]) + (100.0 * dsteal[c] / ratio[c]));
	}
    }

  for (c = 0, status = STATE_OK; c < ncpus; c++)
    {
      cpu_perc = (100.0 * (cpu_value[c]) / ratio[c]);
      currstatus = get_status (cpu_perc, my_threshold);
      if (currstatus > status)
	status = currstatus;
    }

  cpu_desc_read (cpudesc);
  char *cpu_model_str =
    cpu_model ?	xasprintf ("(%s) ",
			   cpu_desc_get_model_name (cpudesc)) : NULL;

  printf ("%s %s%s - cpu %s %.1f%% |"
	  , program_name_short, cpu_model ? cpu_model_str : ""
	  , state_text (status), cpu_progname, cpu_perc);
  for (c = 0; c < ncpus; c++)
    {
      if ((cpuname = cpuv[0][c].cpuname))
        printf (" %s_user=%.1f%% %s_system=%.1f%% %s_idle=%.1f%%"
		" %s_iowait=%.1f%% %s_steal=%.1f%%"
		, cpuname, 100.0 * duser[c]   / ratio[c]
		, cpuname, 100.0 * dsystem[c] / ratio[c]
		, cpuname, 100.0 * didle[c]   / ratio[c]
		, cpuname, 100.0 * diowait[c] / ratio[c]
		, cpuname, 100.0 * dsteal[c]  / ratio[c]);
    }
  putchar ('\n');

  cpu_desc_unref (cpudesc);
  return status;
}