source: trunk/third/moira/lib/fixhost.c @ 24319

Revision 24319, 3.0 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: fixhost.c 3956 2010-01-05 20:56:56Z zacheiss $
2 *
3 * Canonicalize a hostname
4 *
5 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <mit-copyright.h>
11#include <moira.h>
12
13#include <sys/types.h>
14
15#ifdef HAVE_UNAME
16#include <sys/utsname.h>
17#endif
18
19#ifndef _WIN32
20#include <sys/socket.h>
21#include <netdb.h>
22#include <netinet/in.h>
23#endif /* _WIN32 */
24
25#include <ctype.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/lib/fixhost.c $ $Id: fixhost.c 3956 2010-01-05 20:56:56Z zacheiss $");
31
32static struct hostent *local_gethostbyname(void)
33{
34#ifdef HAVE_UNAME
35  struct utsname name;
36  uname(&name);
37  return gethostbyname(name.nodename);
38#else
39  char hostname[128];
40  gethostname(hostname, sizeof(hostname));
41  hostname[sizeof(hostname)-1] = 0;
42  return gethostbyname(hostname);
43#endif
44}
45
46static char *local_domain(void)
47{
48  static char *domain = NULL;
49  char *cp;
50  struct hostent *hp;
51
52  if (domain == NULL)
53    {
54      char hostbuf[256];
55
56      if (mr_host(hostbuf, sizeof(hostbuf)) == MR_SUCCESS)
57        {
58          cp = strchr(hostbuf, '.');
59          if (cp)
60            domain = strdup(++cp);
61        }
62      else
63        {
64          hp = local_gethostbyname();
65          if (hp)
66            {
67              cp = strchr(hp->h_name, '.');
68              if (cp)
69                domain = strdup(++cp);
70            }
71        }
72      if (!domain)
73        domain = "";
74    }
75
76  return domain;
77}
78
79/*
80 * Canonicalize hostname:
81 *  if it is in double-quotes, then strip the quotes and return the name.
82 *  if it is in the namespace, call the nameserver to expand it
83 *  otherwise uppercase it and append the default domain (using an, er,
84 *    undocumented global of the nameserver).
85 *
86 * Assumes that host was allocated using malloc(); it may be freed or
87 * realloc'ed, so the old pointer should not be considered valid.
88 */
89
90char *canonicalize_hostname(char *host)
91{
92  struct hostent *hp;
93  int len;
94  char *tbuf, *cp;
95
96  len = strlen(host);
97  if (len > 2 && host[0] == '"' && host[len - 1] == '"')
98    {
99      tbuf = malloc(len - 1);
100      if (!tbuf)
101        return NULL;
102      strncpy(tbuf, host + 1, len - 2);
103      tbuf[len - 2] = '\0';
104      free(host);
105      return tbuf;
106    }
107
108  if (strchr(host, '*') || strchr(host, '?') || *host == '[')
109    return host;
110
111  hp = gethostbyname(host);
112
113  if (hp)
114    {
115      host = realloc(host, strlen(hp->h_name) + 1);
116      if (host)
117        strcpy(host, hp->h_name);
118      return host;
119    }
120  else
121    {
122      /* can't get name from nameserver; fix up the format a bit */
123      cp = strchr(host, '.');
124      if (!cp)
125        {
126          tbuf = malloc(strlen(host) + strlen(local_domain()) + 2);
127          if (!tbuf)
128            return NULL;
129          sprintf(tbuf, "%s.%s", host, local_domain());
130          free(host);
131          host = tbuf;
132        }
133      else if (strcasecmp(cp + 1, local_domain()) != 0)
134        return host;
135
136      /* This is a host in our local domain, so capitalize it. */
137      for (cp = host; *cp; cp++)
138        *cp = toupper(*cp);
139      return host;
140    }
141}
Note: See TracBrowser for help on using the repository browser.