In article <[EMAIL PROTECTED]> you wrote:
> Guochun Shi wrote:
>> excellent, this fixed bug 952
>> 
>> -Guochun
>> 
>> linux-ha-cvs@lists.linux-ha.org wrote:
>> 
>>> linux-ha CVS committal
>>>
>>> Author  : sunjd
>>> Host    : Project : linux-ha
>>> Module  : lib
>>>
>>> Dir     : linux-ha/lib/plugins/stonith/external
>>>
>>>
>>> Modified Files:
>>>     ssh.in
>>>
>>> Log Message:
>>> bug952: avoid to freeze for a long time
>>> ===================================================================
>>> RCS file: 
>>> /home/cvs/linux-ha/linux-ha/lib/plugins/stonith/external/ssh.in,v
>>> retrieving revision 1.7
>>> retrieving revision 1.8
>>> diff -u -3 -r1.7 -r1.8
>>> --- ssh.in    17 Nov 2005 05:32:31 -0000    1.7
>>> +++ ssh.in    30 Nov 2005 02:28:37 -0000    1.8
>>> @@ -41,7 +41,7 @@
>>>     for j in 1 2 3
>>>         do
>>>           if
>>> -            ping -w0.5 -c1 "$1" >/dev/null 2>&1
>>> +            ping -w1 -c1 "$1" >/dev/null 2>&1
>>>           then
>>>             return 1
>>>           fi
>>> @@ -97,7 +97,7 @@
>>>     for h in $hostlist
>>>     do
>>>       if
>>> -        host $h 2>&1 | grep "not found:"
>>> +            ping -w1 -c1 "$h" 2>&1 | grep "unknown host"
> 
> 
> But, this change is in error.
> 
> You should not fail to verify the parameters just because the host is 
> down.  That's what the code originally did - and it's wrong.  Ping is 
> the wrong command to issue in this case.    On the other hand, this is 
> probably exactly what caused the problem in my site - since they aren't 
> in DNS, but only in /etc/hosts.
> 
> So, the right thing to do is write a function - maybe called checkhost() 
> which looks in /etc/hosts, and if it's not there, then use host as it 
> originally did.

I think it would be better to write a small c programme that exposes
gethostbyname as a shell command. This would honour the previling
nsswitch.conf and let libc worry about the details.

Something like the code below. Sorry its a bit over engineered,
I pieced it from code I had lying around the house.

-- 
Horms

/**********************************************************************
 * gethostbyname.c                                        December 2005
 * Horms                                             [EMAIL PROTECTED]
 *
 * gethostbyname
 * Expose gethostbyname as a shell command 
 * Copyright (C) 1999-2005  Horms and others
 *
 * Based on code from libvanessa_socket and libvanessa_logger
 * Copyright (C) 1999-2005  Horms and others
 * http://www.vergenet.net/linux/vanessa/
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307 USA
 *
 **********************************************************************/

#include <sys/types.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define NAME    "gethostbyname"
#define VERSION "0.9.0"
#define COPYRIGHT "Copyright (C) 1999-2005 by Horms and others"
#define WARRANTY  \
NAME " comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n" \
"are welcome to redistribute it under certain conditions. See the GNU\n"    \
"Lesser General Public Licence for details."

static char strherror_str[34];

/**********************************************************************
 * strherror_r
 * Returns a string describing the error code present in errnum
 * according to the errors for h_errno which is set by gethostbyname(3)
 * gethostbyaddr(3) and others. Analagous to strerror_r(3).
 * pre: errnum: Error to show as a string
 *      buf: buffer to write error string to
 *      n: length of buf in bytes
 * post: on success error string is written to buf
 *       on invalid input errno is set to -EINVAL
 *       if buf is too short then errno is set to -ERANGE
 * return: 0 on success
 *         -1 on error
 **********************************************************************/

static int strherror_r(int errnum, char *buf, size_t n)
{
        size_t len;
        char *str;

        switch(errnum) {
                case HOST_NOT_FOUND:
                        str = "Unknown host";
                        break;
                case NO_ADDRESS:
                /* case NO_DATA: */
                        str = "Host has no address";
                        break;
                case NO_RECOVERY:
                        str = "Non-recoverable name server error";
                        break;
                case TRY_AGAIN:
                        str = "Transient lookup error";
                        break;
                default:
                        errno = -EINVAL;
                        return -1;
        }

        len = strlen(str) + 1;
        if(len > n) {
                errno = -ERANGE;
                return -1;
        }

        memcpy(buf, str, len);
        return 0;
}


/**********************************************************************
 * strherror
 * Returns a string describing the error code present in errnum
 * according to the errors for h_errno which is set by gethostbyname(3)
 * gethostbyaddr(3) and others. Analagous to strerror_r(3).
 * pre: errnum: Error to show as a string
 * post: none on success
 *       on invalud input errno is set to -EINVAL
 *       if buf is too short then errno is set to -ERANGE
 * return: error string for errnum on success
 *         error string for newly set errno on error
 **********************************************************************/

static char * strherror(int errnum)
{
        int status;

        status = strherror_r(errnum, strherror_str, sizeof(strherror_str));
        if (status < 0) {
                return strerror(errno);
        }

        return strherror_str;
}


/**********************************************************************
 * host_in_addr
 * A host is given as a string either as a host name or IP address
 * as a dotted quad. The host is used to seed an in_addr structure
 * with a binary representation of the IP address of the host
 * in network byte order.
 * pre: host: hostname or IP address
 *            If NULL then INADDR_ANY will be converted to network
 *            byte order and used as the address.
 *      in: pointer to an in_addr structure.
 * post: none
 * return: 0 on success
 *         -1 on error
 **********************************************************************/

static int host_in_addr(const char *host, struct in_addr *in)
{
        struct hostent *hp;
        extern int h_errno;

        if (host == NULL) {
                in->s_addr = htonl(INADDR_ANY);
                return 0;
        } 

        if ((hp = gethostbyname(host)) == NULL) {
                fprintf(stderr, "host_in_addr %s: %s\n",
                        host, strherror(h_errno));
                return -1;
        }
        memcpy(in, hp->h_addr, hp->h_length);

        return 0;
}

/* Stuff below this comment may be relicenced GPL after contacting
 * Horms <[EMAIL PROTECTED]/
 * Stuff above this line is part of existing LGPL libraries and
 * should be broken out into a LGPL library if GPL licencing
 * is desired. */

static void version(FILE *fd) 
{
        fprintf(fd, "%s version %s\n%s\n\n%s\n",
                NAME, VERSION, COPYRIGHT, WARRANTY);
}

static void usage(int exit_status) 
{
        FILE *fd;
        
        fd = exit_status ? stderr : stdout;

        version(fd);
        fprintf(fd, "\n"
                "%s converts a hostname to an ip address using libc's "
                        "gethostbyname\n"
                "\n"
                "Usage: %s [OPTIONS] HOST\n"
                "\n"
                "Options:\n"
                "  -h|--help:    display this message and exit\n"
                "  -v|--version: version information and exit\n"
                "\n",
                NAME, NAME);

        exit(exit_status);
}


int main(int argc, char **argv)
{
        int i;
        const char *hostname = NULL;
        struct in_addr addr;

        for (i = 1; i < argc; i++) {
                if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
                        usage(0);
                }
                if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-v")) {
                        version(stdout);
                        return 0;
                }
                if (hostname) {
                        usage(1);
                }
                hostname = argv[i];
        }

        if (!hostname) {
                usage(1);
        }

        if (host_in_addr(hostname, &addr) < 0) {
                return -1;
        }

        printf("%s\n", inet_ntoa(addr));

        return 0;
}

_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to