/*
 * hostnamelong.c
 * 2005-June-17, version 0.2
 * Copyright (C) 2005 Randy Dunlap <rdunlap@xenotime.net>
 *
 * Test long hostnames (up to 256 bytes including nul terminator)
 * and the new sys_uname_long() syscall.
 */


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

#ifndef __NR_uname_long
#ifdef __i386__
#define __NR_uname_long		317
#endif
#ifdef __x86_64__
#define __NR_uname_long		279
#endif
#endif

#define __NEW_UTS_LEN	64

/* for (POSIX) IEEE Std. 1003.1, 2004 edition */
#define __POSIX_HOST_NAME_MAX	255	/* not including terminating NUL char */

struct long_utsname {
	char sysname[__NEW_UTS_LEN + 1];	/* O/S name */
	char nodename[__POSIX_HOST_NAME_MAX + 1]; /* hostname, but keep field
					* name same as other structs here */
	char release[__NEW_UTS_LEN + 1];	/* O/S release level */
	char version[__NEW_UTS_LEN + 1];	/* version level of release */
	char machine[__NEW_UTS_LEN + 1];	/* machine hardware type */
	char domainname[__NEW_UTS_LEN + 1];
};

_syscall2 (long, sethostname, char *, name, int, len);
_syscall1 (long, uname_long, struct long_utsname *, utsname);

void usage (void)
{
	fprintf (stderr, "usage: hostnamelong [new_hostname] {empty => get various names}\n");
	exit (1);
}

int do_sethostname (char *hostname, int len)
{
	int retval;

	retval = sethostname (hostname, len);
	printf ("sethostname: syscall retval = %d\n", retval);
	if (retval < 0)
		perror ("sethostname");
	return retval;
}

/*
 * gethostname(), get uname(), get uname_long()
 */
void do_get_names (void)
{
	char hostname[__POSIX_HOST_NAME_MAX + 1];
	struct utsname unamebuf;
	struct long_utsname lunamebuf;
	int retval;

	retval = gethostname (hostname, sizeof(hostname));
	printf ("gethostname: syscall retval = %d, hostname=%s=\n",
		retval, hostname);
	if (retval < 0)
		perror ("hostname_long");

	retval = uname (&unamebuf);
	printf ("uname: syscall retval = %d, sysname=%s=, nodename=%s=, release=%s=, version=%s=, machine=%s=\n",
		retval, unamebuf.sysname, unamebuf.nodename,
		unamebuf.release, unamebuf.version, unamebuf.machine);

	retval = uname_long (&lunamebuf);
	printf ("uname_long: syscall retval = %d, sysname=%s=, nodename=%s=, release=%s=, version=%s=, machine=%s=, domainname=%s=\n",
		retval, lunamebuf.sysname, lunamebuf.nodename,
		lunamebuf.release, lunamebuf.version, lunamebuf.machine,
		lunamebuf.domainname);

}

int main (int argc, char *argv[])
{
	if (argc < 1 || argc > 2)
		usage();

	if (argv[1])
		do_sethostname (argv[1], strlen(argv[1]));
	else
		do_get_names ();

	exit (0);
} // end main

// end hostnamelong.c
