/*
 *   Copyright (c) 2000 David Parsons. All rights reserved.
 *   
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *  3. All advertising materials mentioning features or use of this
 *     software must display the following acknowledgement:
 *     
 *   This product includes software developed by David Parsons
 *   (orc@pell.chi.il.us)
 *
 *  4. My name may not be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *     
 *  THIS SOFTWARE IS PROVIDED BY DAVID PARSONS ``AS IS'' AND ANY
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 *  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
 *  PARSONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 *  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 *  THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * hostname:  set/get the machine hostname, dnsdomainname, (yp)domainname
 */

#include <stdio.h>
#include <basis/options.h>
#include <sys/utsname.h>
#include <netdb.h>
#include <string.h>

char bfr[1024];	/* 1k big enough for a domain name? */

struct x_option options[] = {
    { 's', 's', "host",   0, "Show the host part of the hostname" },
    { 'f', 'f', "fqdn",   0, "Show the entire hostname, including dns domain" },
    { 'd', 'd', "domain", 0, "Show the dns domain for the hostname" },
    { '?', '?', "help",   0, "Show this help message" },
    { 'V', 'V', "version",0, "Show version information" },
} ;
#define NR_OPTIONS (sizeof options/sizeof options[0])

main(argc, argv)
int argc;
char **argv;
{
    enum { SHORT, FQDN, DOMAIN} mode = FQDN;
    int opt;
    int ret;
    int isdom;
    char *pgm;
    struct utsname current;
    struct hostent *ha;
    extern char *basename();

    x_opterr = 1;

    pgm = basename(argv[0]);

    isdom = strcasecmp(pgm, "domainname") == 0;

    if (uname(&current) != 0) {
	fprintf(stderr, "%s:", pgm);
	perror("uname");
	exit(1);
    }

    while ( (opt = x_getopt(argc, argv, NR_OPTIONS, options)) != EOF)
	switch (opt) {
	case 's': mode = SHORT;	break;
	case 'f': mode = FQDN;  break;
	case 'd': mode = DOMAIN;break;
	default:
	case '?':
		showopts(stderr, NR_OPTIONS, options);
		exit( opt == '?' ? 0 : 1);
	case 'V':
		puts("$Revision: 1.2 $");
		exit(0);
	}

    argc -= x_optind;
    argv += x_optind;

    if (argc > 0) {
	/* set host or domain */
	if (isdom)
	    ret = setdomainname(argv[0], strlen(argv[0]));
	else
	    ret = sethostname(argv[0], strlen(argv[0]));
	if (ret != 0) {
	    fprintf(stderr, "%s: ", pgm);
	    perror(isdom ? "while setting domain" : "while setting hostname");
	    exit(1);
	}
	exit(0);
    }
    else if (isdom)
	puts(current.domainname);
    else {
	char *dot = strchr(current.nodename, '.');

	switch (mode) {
	case SHORT:
		if (dot) *dot = 0;
		puts(current.nodename);
		break;
	default:
		if (dot)
		    puts(current.nodename);
		else if ( (ha = gethostbyname(current.nodename)) != 0)
		    puts(ha->h_name);
		else
		    exit(1);
		break;
	case DOMAIN:
		if (dot)
		    puts(++dot);
		else if ( (ha = gethostbyname(current.nodename)) != 0) {
		    if ( (dot = strchr(ha->h_name, '.')) != 0 )
			puts(++dot);
		    else
			exit(1);
		}
		else
		    exit(1);
		break;
	}
    }

} /* main */
