/*
 * uname.c, by tlh
 *
 * The uname program for system information: kernel name, kernel
 * release, kernel release, machine, processor, platform, os and
 * hostname.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/utsname.h>


enum uname_fields {
	UN_SYSNAME,
	UN_NODENAME,
	UN_RELEASE,
	UN_VERSION,
	UN_MACHINE,
#if NOT_IMPLEMENTED_PROCESSOR
	UN_PROCESSOR,
#endif
	UN_HARDWARE,
#if NOT_IMPLEMENTED_OS
	UN_OS,
#endif
	UN_NR_FIELDS
};


void usage(FILE *stream, const char *progname)
{
	fprintf(stream,
		"Usage: %s [OPTION] . . .\n"
		"Print system information,  No options defaults to -s.\n"
		"\n"
		"  -a   print all the information in the same order as follows below\n"
		"  -s   kernel name\n"
		"  -n   network node name (hostname)\n"
		"  -r   kernel release\n"
		"  -v   kernel version\n"
		"  -m   machine hardware name\n"
#if NOT_IMPLEMENTED_PROCESSOR
		"  -p   processor type\n"
#endif
		"  -i   hardware platform\n"
#if NOT_IMPLEMENTED_OS
		"  -o   operating system\n"
#endif
		"\n"
		"  -h   help/usage\n"
		"\n",
		progname);
}


char *make_hardware(const char *machine)
{
	char *hardware;

	if (! (hardware = strdup(machine))) {
		fprintf(stderr, "strdup() failed: %s\n",
			strerror(errno));
		goto end;
	}
	if (strlen(hardware) == 4
	    && hardware[0] == 'i'
	    && hardware[2] == '8'
	    && hardware[3] == '6') {
		hardware[1] = '3';
	}
 end:
	return hardware;
}


int main(int argc, char *argv[])
{
	int ec = 1;
	int opt;
	int i;
	int nr_pr;
	struct utsname buf;
	char *uname_fields[UN_NR_FIELDS] = { NULL };

	if (-1 == uname(&buf)) {
		fprintf(stderr, "uname() failure: %s\n", strerror(errno));
		goto end;
	}

	if (1 == argc)
		/* no options given - default to -s */
		uname_fields[UN_SYSNAME] = buf.sysname;

	while ((opt = getopt(argc, argv, "asnrvmpioh")) != -1) {
		switch (opt) {
		case 'a':
			uname_fields[UN_SYSNAME] = buf.sysname;
			uname_fields[UN_NODENAME] = buf.nodename;
			uname_fields[UN_RELEASE] = buf.release;
			uname_fields[UN_VERSION] = buf.version;
			uname_fields[UN_MACHINE] = buf.machine;
			uname_fields[UN_HARDWARE] = make_hardware(buf.machine);
			if (! uname_fields[UN_HARDWARE])
				goto end;
			break;
		case 's':
			uname_fields[UN_SYSNAME] = buf.sysname;
			break;
		case 'n':
			uname_fields[UN_NODENAME] = buf.nodename;
			break;
		case 'r':
			uname_fields[UN_RELEASE] = buf.release;
			break;
		case 'v':
			uname_fields[UN_VERSION] = buf.version;
			break;
		case 'm':
			uname_fields[UN_MACHINE] = buf.machine;
			break;
#if NOT_IMPLEMENTED_PROCESSOR
		case 'p':
			break;
#endif
		case 'i':
			uname_fields[UN_HARDWARE] = make_hardware(buf.machine);
			if (! uname_fields[UN_HARDWARE])
				goto end;
			break;
#if NOT_IMPLEMENTED_OS
		case 'o':
			break;
#endif
		case 'h':
			usage(stdout, argv[0]);
			ec = 0;
			goto end;
			break;
		default:
			usage(stderr, argv[0]);
			goto end;
			break;
		}
	}

	for (nr_pr = 0, i = UN_SYSNAME; i < UN_NR_FIELDS; i++) {
		if (! uname_fields[i])
			continue;
		if (nr_pr)
			fputc(' ', stdout);
		fputs(uname_fields[i], stdout);
		nr_pr++;
	}
	fputc('\n', stdout);

	ec = 0;

 end:
	if (uname_fields[UN_HARDWARE])
		free(uname_fields[UN_HARDWARE]);
	return ec;
}
