]> andersk Git - moira.git/blob - lib/fixhost.c
off-by-one error in dequoting quoted hostnames
[moira.git] / lib / fixhost.c
1 /* $Id$
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 #include <sys/socket.h>
15 #include <sys/utsname.h>
16
17 #include <netdb.h>
18 #include <netinet/in.h>
19
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 RCSID("$Header$");
26
27 /*
28  * Canonicalize hostname:
29  *  if it is in double-quotes, then strip the quotes and return the name.
30  *  if it is in the namespace, call the nameserver to expand it
31  *  otherwise uppercase it and append the default domain (using an, er,
32  *    undocumented global of the nameserver).
33  *
34  * Assumes that host was allocated using malloc(); it may be freed or
35  * realloc'ed, so the old pointer should not be considered valid.
36  */
37
38 char *canonicalize_hostname(char *host)
39 {
40   struct hostent *hp;
41   int len;
42   int has_dot = 0;
43   char *tbuf, *cp;
44
45   len = strlen(host);
46   if (len > 2 && host[0] == '"' && host[len - 1] == '"')
47     {
48       tbuf = malloc(len - 1);
49       if (!tbuf)
50         return NULL;
51       strncpy(tbuf, host + 1, len - 2);
52       tbuf[len - 2] = '\0';
53       free(host);
54       return tbuf;
55     }
56
57   if (strchr(host, '*') || strchr(host, '?') || !strcmp(host, "[NONE]"))
58     return host;
59
60   hp = gethostbyname(host);
61
62   if (hp)
63     {
64       host = realloc(host, strlen(hp->h_name) + 1);
65       if (host)
66         strcpy(host, hp->h_name);
67       return host;
68     }
69   else
70     {
71       /* can't get name from nameserver; fix up the format a bit */
72       for (cp = host; *cp; cp++)
73         {
74           if (islower(*cp))
75             *cp = toupper(*cp);
76           has_dot |= (*cp == '.');
77         }
78       if (!has_dot)
79         {
80           static char *domain = NULL;
81
82           if (domain == NULL)
83             {
84               struct utsname name;
85
86               uname(&name);
87               hp = gethostbyname(name.nodename);
88               if (hp)
89                 {
90                   cp = strchr(hp->h_name, '.');
91                   if (cp)
92                     domain = strdup(++cp);
93                   if (!domain)
94                     domain = "";
95                 }
96               else
97                 domain = "";
98             }
99           tbuf = malloc(strlen(host) + strlen(domain) + 2);
100           if (!tbuf)
101             return NULL;
102           sprintf(tbuf, "%s.%s", host, domain);
103           free(host);
104           host = tbuf;
105         }
106       return host;
107     }
108 }
This page took 0.488833 seconds and 5 git commands to generate.