source: trunk/third/evolution/e-util/e-host-utils.c @ 16787

Revision 16787, 3.8 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16786, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* e-host-utils.c
3 *
4 * Copyright (C) 2001  Ximian, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: Chris Toshok
21 */
22
23#include <config.h>
24#include <glib.h>
25#include "e-host-utils.h"
26#include <string.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <errno.h>
30
31#ifndef HAVE_GETHOSTBYNAME_R
32G_LOCK_DEFINE_STATIC (gethost_mutex);
33#endif
34
35/**
36 * e_gethostbyname_r:
37 * @name: the host to resolve
38 * @host: a buffer pointing to a struct hostent to use for storage
39 * @buf: a buffer to use for hostname storage
40 * @buflen: the size of @buf
41 * @herr: a pointer to a variable to store an error code in
42 *
43 * Resolves the hostname @name, in a hopefully-reentrant fashion.
44 *
45 * Return value: 0 on success, ERANGE if @buflen is too small,
46 * "something else" otherwise (in which case *@herr will be set to
47 * one of the gethostbyname() error codes).
48 **/
49int
50e_gethostbyname_r (const char *name, struct hostent *host,
51                   char *buf, int buflen, int *herr)
52{
53#ifdef HAVE_GETHOSTBYNAME_R
54#ifdef GETHOSTBYNAME_R_FIVE_ARGS
55        if (gethostbyname_r(name, host, buf, buflen, herr))
56                return 0;
57        else
58                return errno;
59#else
60        struct hostent *hp;
61        int retval;
62
63        retval = gethostbyname_r(name, host, buf, buflen, &hp, herr);
64        if (hp != NULL)
65                *herr = 0;
66        return retval;
67#endif
68#else
69        int i;
70        char *p;
71        struct hostent *h;
72        int req_length;
73        int num_aliases = 0, num_addrs = 0;
74
75        G_LOCK (gethost_mutex);
76
77        h = gethostbyname (name);
78
79        if (!h) {
80                *herr = h_errno;
81                G_UNLOCK (gethost_mutex);
82                return -1;
83        }
84
85        /* check to make sure we have enough room in our buffer */
86        req_length = 0;
87        if (h->h_aliases) {
88                for (i = 0; h->h_aliases[i]; i ++)
89                        req_length += strlen (h->h_aliases[i]) + 1;
90                num_aliases = i;
91        }
92        if (h->h_addr_list) {
93                for (i = 0; h->h_addr_list[i]; i ++)
94                        req_length += h->h_length;
95                num_addrs = i;
96        }
97
98        req_length += sizeof (char*) * (num_aliases + 1);
99        req_length += sizeof (char*) * (num_addrs + 1);
100        req_length += strlen (h->h_name) + 1;
101
102        if (buflen < req_length) {
103                *herr = ERANGE;
104                G_UNLOCK (gethost_mutex);
105                return ERANGE;
106        }
107
108        /* we store the alias/addr pointers in the buffer - figure out
109           their addresses here. */
110        p = buf;
111        if (num_aliases) {
112                host->h_aliases = (char**)p;
113                p += sizeof (char*) * (num_aliases + 1);
114        }
115        else
116                host->h_aliases = NULL;
117        if (num_addrs) {
118                host->h_addr_list = (char**)p;
119                p += sizeof(char*) * (num_addrs + 1);
120        }
121        else
122                host->h_addr_list = NULL;
123
124        /* copy the host name into the buffer */
125        host->h_name = p;
126        strcpy (p, h->h_name);
127        p += strlen (h->h_name) + 1;
128        host->h_addrtype = h->h_addrtype;
129        host->h_length = h->h_length;
130
131        /* copy the aliases/addresses into the buffer, and assign the
132           pointers into the hostent */
133        *p = 0;
134        if (num_aliases) {
135                for (i = 0; i < num_aliases; i ++) {
136                        strcpy (p, h->h_aliases[i]);
137                        host->h_aliases[i] = p;
138                        p += strlen (h->h_aliases[i]);
139                }
140                host->h_aliases[num_aliases] = NULL;
141        }
142
143        if (num_addrs) {
144                for (i = 0; i < num_addrs; i ++) {
145                        memcpy (p, h->h_addr_list[i], h->h_length);
146                        host->h_addr_list[i] = p;
147                        p += h->h_length;
148                }
149                host->h_addr_list[num_addrs] = NULL;
150        }
151
152        G_UNLOCK (gethost_mutex);
153
154        return 0;
155#endif
156}
Note: See TracBrowser for help on using the repository browser.