How to get the FQDN from script/C program in Solaris/Linux/AIX/whatever...

How to get the FQDN from script/C program in Solaris/Linux/AIX/whatever...

Post by Roland Main » Sat, 20 Jan 2001 12:14:55



Hi !

----

It looks like a silly question - unfortunalely it isn't...

How to get the FQDN(=Full Qualified Domain Name) of a
(Solaris/Linux/AIX/etc.) machine from a ksh script or from a C program
in a platform-independent manner (...what about POSIX ??) ?

On SuSE Linux it's not an issue:
-- snip --
% getent hosts `hostname` | awk '{print $2}'
sepia0.informatik.med.uni-giessen.de
-- snip --

But on "standard" Solaris the "short" name is returned:
-- snip --
% getent hosts `hostname` | awk '{print $2}'
puck
-- snip --

Adding the FQDN to /etc/inet/hosts(=/etc/hosts on BSD/Linux) does not
always work - NIS+ for example sorts shorter names first - if you select
NIS+ in /etc/nsswitch.conf before "files" (e.g. NIS+ nameservice before
/etc/inet/hosts) you'll always get the "short" name... ;-(

Any ideas ?

----

Bye,
Roland

--
  __ .  . __


  /O /==\ O\  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
 (;O/ \/ \O;) TEL +49 641 99-41370 FAX +49 641 99-41359

 
 
 

How to get the FQDN from script/C program in Solaris/Linux/AIX/whatever...

Post by Martin Pau » Sat, 20 Jan 2001 19:02:09



Quote:> It looks like a silly question - unfortunalely it isn't...

> How to get the FQDN(=Full Qualified Domain Name) of a
> (Solaris/Linux/AIX/etc.) machine from a ksh script or from a C program
> in a platform-independent manner (...what about POSIX ??) ?

You might want to take a look at /usr/lib/mail/sh/check-hostname
which comes with Solaris 8 (maybe 7, too). It tries to get the
FQDN in the same way that sendmail does.

Not sure how portable that is, or if there is simpler, standard
way of achieving this.

hth, mp.
--
                         Martin Paul | Systems Administrator

Liechtensteinstrasse 22, A-1090 Wien | Tel: 01 4277 38803
        http://www.par.univie.ac.at/ | Fax: 01 4277 9388

 
 
 

How to get the FQDN from script/C program in Solaris/Linux/AIX/whatever...

Post by J.A. Gutierre » Sat, 20 Jan 2001 21:22:16


In comp.unix.admin Roland Mainz <roland.ma...@informatik.med.uni-giessen.de> wrote:

: How to get the FQDN(=Full Qualified Domain Name) of a
: (Solaris/Linux/AIX/etc.) machine from a ksh script or from a C program
: in a platform-independent manner (...what about POSIX ??) ?

/*
 * attempt to construct a fully-qualified hostname
 *
 * not likely to work on multi-homed or multi-addressed machines
 *
 * David Laur, Rainsound, 9/96
 *
 * (converted from the C++ in my app)
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>

/* ---------------------------------------------------------------------- */

#ifdef sun
extern int gethostname( char *name, int namelen );
#endif

#ifndef __sgi
static char* hstrerror ( int errnum )
{
    switch (errnum) {
        case HOST_NOT_FOUND:    return "can't resolve name";
        case TRY_AGAIN:         return "name lookup timeout, try again";
        case NO_RECOVERY:       return "name server failure";
        case NO_DATA:           return "no data/address associated with name";
        default:                break;
    }
    return "unknown gethostbyname failure";

}

#endif
/* ---------------------------------------------------------------------- */
static int countDots ( char *name )
{
    int n;
    for (n=0; *name; ++name) if (*name=='.') ++n;
    return(n);

}

/* ---------------------------------------------------------------------- */
char* gethostnameFullyQualified ( void )
{
   /* a fully qualified name is one that an arbitrary
    * internet host could use to find this host (assuming
    * that the various DNS pieces are working properly)
    * for example: spanky.hipsters.com
    *
    * some sites maintain local subdomains, so a full name
    * might be: niles.CS.Rudeboy.EDU
    *
    * under some conditions the 'gethostname' routine returns
    * either the fully qualified name, or just the first word.
    * (i.e. for IRIX, depends on the definition of /etc/sys_id)
    *
    * note that the old routine getdomainname only returns the
    * current NIS "domain" name, which is just a database grouping,
    * it is often set to the same string as the internet domain,
    * but not always. Also it's documented as 'backward compatible only'
    * under IRIX, and not at all on the Sun.
    *
    * also, at some sites one of the gethostbyname h_aliases is the
    * fully qualified name rather than the h_name "official" name
    *
    * the only solution that really deals with situations like
    * multi-homed hosts or multi-network gateway hosts is to have
    * some sysadmin specify the FQ-hostname in a file, much as
    * sendmail requires.
    *
    * note that the return value is new[] memory and should be
    * freed by the caller
    *
    * the criteria used by this heuristic: the more dots in a name the
    * better, i.e. longer names are likely to be more resolvable from
    * external sites.
    */

    char host[774];
    struct hostent *hp;
    char *fqname=NULL;
    char *result;
    int nd;

    host[0] = 0;

    if (-1 == gethostname(host, sizeof(host))) {
        perror("warning - getting local hostname");
        /* not a general solution, but for the 95% case of (my app)
         * talking to itself on the same host, "localhost" will do
         */
        strcpy(host,"localhost");
    }
    fqname = host;
    nd = countDots(fqname);

    hp = gethostbyname(host);
    if (!hp) {
        fprintf(stderr, "warning - can't gethostbyname(%s): %s\n",
            host, hstrerror(h_errno));
    } else {
        char **nm;
        if (nd <= countDots(hp->h_name)) {
            fqname = hp->h_name;
            nd = countDots(fqname);
        }

        for (nm = hp->h_aliases; *nm; ++nm) {
            int d = countDots(*nm);
            if (d > nd) {fqname = *nm; nd=d;}
        }
    }
    if (2 > nd) {
       /* still need to find a domain, look through the usual suspects:
        *    LOCALDOMAIN env variable
        *    domain defn from /etc/resolv.conf
        *    /etc/defaultdomain  (sun only?)
        */
        FILE *fp = NULL;
        char domain[1024];
        char *e = getenv("LOCALDOMAIN");
        if (e) strcpy(domain, e);
        else domain[0] = 0;

        if( !domain[0] && NULL != (fp=fopen("/etc/resplv.conf","r")) ) {
            nd = 0;
            while( fgets(domain, sizeof(domain), fp) ) {
                if( 0==strncmp("domain ",domain,7) ) {
                    nd = strlen(domain) - 7;
                    memmove(domain, domain+7, nd);
                }
            }
            domain[nd] = 0;  /* nul terminate (or reset empty) */
            fclose(fp);
        }

        if( !domain[0] && NULL != (fp=fopen("/etc/defaultdomain","r")) ) {
            fgets(domain, sizeof(domain), fp);
            fclose(fp);
        }

        if( domain[0] ) {
            /* trim blanks */
            int first = 0;
            nd = strlen(domain) - 1;
            while (first <= nd && isspace(domain[first])) ++first;
            while (nd > first && isspace(domain[nd])) domain[nd--] = 0;

            if (domain[first]) {
                if (fqname != host) strcpy(host,fqname);
                if ('.'!=domain[first]) strcat(host,".");
                strcat(host,domain+first);
                fqname = host;
            }
        }
    }

    result = malloc(1+strlen(fqname));
    strcpy(result,fqname);
    return(result);

}

/* ---------------------------------------------------------------------- */

main ()
{
        int             uid             = getuid();
        struct passwd   *pwd    = getpwuid( uid );
    char        *fqname = gethostnameFullyQualified();

        if ( NULL == ( pwd = getpwuid ( uid )))
        {
        printf( "%d@%s\n" , uid , fqname);
        }
        else
        {
            printf( "%s@%s\n", pwd->pw_name, fqname);
        }
    free(fqname);

    return(0);

}

/* ---------------------------------------------------------------------- */
--
PGP and other useless info at      \                 La ciencia-ficcion es
http://www.cps.unizar.es/~spd/      \                 ese futuro en el que
finger://daphne.cps.unizar.es/spd    \                 lo seguro es que ya
ftp://ivo.cps.unizar.es/pub/          \    (F. Alfaro)  no seremos jovenes
 
 
 

How to get the FQDN from script/C program in Solaris/Linux/AIX/whatever...

Post by Darren Dunha » Sun, 21 Jan 2001 03:18:21



Quote:> It looks like a silly question - unfortunalely it isn't...
> How to get the FQDN(=Full Qualified Domain Name) of a
> (Solaris/Linux/AIX/etc.) machine from a ksh script or from a C program
> in a platform-independent manner (...what about POSIX ??) ?
> On SuSE Linux it's not an issue:
> -- snip --
> % getent hosts `hostname` | awk '{print $2}'
> sepia0.informatik.med.uni-giessen.de
> -- snip --

I'm assuming that's because the FQDN is listed first in /etc/hosts, and
is therefore 'the hostname' (or because DNS precedes some other
database, and DNS will always return the FQDN).

Quote:> But on "standard" Solaris the "short" name is returned:
> -- snip --
> % getent hosts `hostname` | awk '{print $2}'
> puck
> -- snip --
> Adding the FQDN to /etc/inet/hosts(=/etc/hosts on BSD/Linux) does not
> always work - NIS+ for example sorts shorter names first

That's not true.  It will do that if you put short names first in NIS+.
It's simply returning the data that is in the database.

Some sites list long names first.

 - if you select

Quote:> NIS+ in /etc/nsswitch.conf before "files" (e.g. NIS+ nameservice before
> /etc/inet/hosts) you'll always get the "short" name... ;-(

You're asking getent for "the name".  If NIS+ lists a short name, that
is "the name".

An FQDN to me implies DNS.  If you're interested in the reverse DNS for
an IP address, you should probably ask DNS, rather than the general host
lookup tables (as implied by getent).

Normally, I'd do it in perl, but I imagine you could query 'nslookup' in
a script without too much trouble.

nslookup host | grep Name

--

Unix System Administrator                    Taos - The SysAdmin Company
Got some Dr Pepper?                           San Francisco, CA bay area
      < Please move on, ...nothing to see here,  please disperse >