#include "common.h"
#include <getopt.h>
#include <error.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/utsname.h>
#include <errno.h>
struct toprint_struct {
unsigned kernel_name : 1;
unsigned kernel_release : 1;
unsigned kernel_version : 1;
unsigned machine : 1;
};
static void print_name(const struct utsname *name, const struct toprint_struct *toprint)
{
int print_separator;
print_separator = 0;
if (toprint->kernel_name) {
if (print_separator)
putchar(' ');
fputs(name->sysname, stdout);
print_separator = 1;
}
if (toprint->kernel_release) {
if (print_separator)
putchar(' ');
fputs(name->release, stdout);
print_separator = 1;
}
if (toprint->kernel_version) {
if (print_separator)
putchar(' ');
fputs(name->version, stdout);
print_separator = 1;
}
if (toprint->machine) {
if (print_separator)
putchar(' ');
fputs(name->machine, stdout);
print_separator = 1;
}
if (print_separator)
putchar('\n');
}
static void print_system_info(const struct toprint_struct *toprint)
{
struct utsname name;
if (uname(&name) == -1)
error(EXIT_FAILURE, errno, "cannot get system name");
print_name(&name, toprint);
}
static void __attribute__ ((noreturn)) die_bad_usage()
{
fprintf(stderr, "Try `%s --help' for more information.\n", program_invocation_name);
exit(EXIT_FAILURE);
}
static void print_help()
{
printf("Usage: %s [OPTION]...\n", program_invocation_name);
puts("Print certain system information. With no OPTION, same as -s.");
putchar('\n');
puts(" -a, --all print all information, in the following order:");
puts(" -s, --kernel-name print the kernel name");
puts(" -r, --kernel-release print the kernel release");
puts(" -v, --kernel-version print the kernel version");
puts(" -m, --machine print the machine hardware name");
puts(" -h, --help display this help and exit");
}
int main(int argc, char **argv)
{
static const struct toprint_struct print_none = {
.kernel_name = 0,
.kernel_release = 0,
.kernel_version = 0,
.machine = 0,
};
static const struct toprint_struct print_all = {
.kernel_name = 1,
.kernel_release = 1,
.kernel_version = 1,
.machine = 1,
};
static const struct toprint_struct default_toprint = {
.kernel_name = 1,
.kernel_release = 0,
.kernel_version = 0,
.machine = 0,
};
static const struct option longopts[] = {
{"all", no_argument, NULL, 'a'},
{"kernel-name", no_argument, NULL, 's'},
{"kernel-release", no_argument, NULL, 'r'},
{"kernel-version", no_argument, NULL, 'v'},
{"machine", no_argument, NULL, 'm'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
struct toprint_struct toprint;
int c;
atexit(close_stdout);
toprint = print_none;
while ((c = getopt_long(argc, argv, "asrvmh", longopts, NULL)) != -1)
switch (c) {
case 'a':
toprint = print_all;
break;
case 's':
toprint.kernel_name = 1;
break;
case 'r':
toprint.kernel_release = 1;
break;
case 'v':
toprint.kernel_version = 1;
break;
case 'm':
toprint.machine = 1;
break;
case 'h':
print_help();
return EXIT_SUCCESS;
case '?':
die_bad_usage();
}
if (optind < argc) {
error(0, 0, "extra operand `%s'", argv[optind]);
die_bad_usage();
}
if (!toprint.kernel_name
&& !toprint.kernel_release
&& !toprint.kernel_version
&& !toprint.machine)
toprint = default_toprint;
print_system_info(&toprint);
return EXIT_SUCCESS;
}