/src/avahi/avahi-core/domain-util.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /***  | 
2  |  |   This file is part of avahi.  | 
3  |  |  | 
4  |  |   avahi is free software; you can redistribute it and/or modify it  | 
5  |  |   under the terms of the GNU Lesser General Public License as  | 
6  |  |   published by the Free Software Foundation; either version 2.1 of the  | 
7  |  |   License, or (at your option) any later version.  | 
8  |  |  | 
9  |  |   avahi is distributed in the hope that it will be useful, but WITHOUT  | 
10  |  |   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  | 
11  |  |   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General  | 
12  |  |   Public License for more details.  | 
13  |  |  | 
14  |  |   You should have received a copy of the GNU Lesser General Public  | 
15  |  |   License along with avahi; if not, write to the Free Software  | 
16  |  |   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  | 
17  |  |   USA.  | 
18  |  | ***/  | 
19  |  |  | 
20  |  | #ifdef HAVE_CONFIG_H  | 
21  |  | #include <config.h>  | 
22  |  | #endif  | 
23  |  |  | 
24  |  | #include <stdlib.h>  | 
25  |  | #include <assert.h>  | 
26  |  | #include <string.h>  | 
27  |  | #include <unistd.h>  | 
28  |  | #include <ctype.h>  | 
29  |  | #include <sys/utsname.h>  | 
30  |  | #include <stdio.h>  | 
31  |  |  | 
32  |  | #include <avahi-common/malloc.h>  | 
33  |  |  | 
34  |  | #include "log.h"  | 
35  |  | #include "domain-util.h"  | 
36  |  | #include "util.h"  | 
37  |  |  | 
38  | 0  | static void strip_bad_chars(char *s) { | 
39  | 0  |     char *p, *d;  | 
40  |  | 
  | 
41  | 0  |     s[strcspn(s, ".")] = 0;  | 
42  |  | 
  | 
43  | 0  |     for (p = s, d = s; *p; p++)  | 
44  | 0  |         if ((*p >= 'a' && *p <= 'z') ||  | 
45  | 0  |             (*p >= 'A' && *p <= 'Z') ||  | 
46  | 0  |             (*p >= '0' && *p <= '9') ||  | 
47  | 0  |             *p == '-')  | 
48  | 0  |             *(d++) = *p;  | 
49  |  | 
  | 
50  | 0  |     *d = 0;  | 
51  | 0  | }  | 
52  |  |  | 
53  |  | #ifdef __linux__  | 
54  | 0  | static int load_id(char *ret_s, size_t size, const char *filename, const char *field) { | 
55  | 0  |     FILE *f;  | 
56  | 0  |     size_t flen;  | 
57  |  | 
  | 
58  | 0  |     assert(ret_s);  | 
59  | 0  |     assert(size > 0);  | 
60  | 0  |     assert(filename);  | 
61  | 0  |     assert(field);  | 
62  | 0  |     assert(strchr(field, '='));  | 
63  |  |  | 
64  | 0  |     if (!(f = fopen(filename, "r")))  | 
65  | 0  |         return -1;  | 
66  |  |  | 
67  | 0  |     flen = strlen(field);  | 
68  |  | 
  | 
69  | 0  |     while (!feof(f)) { | 
70  | 0  |         char ln[256], *p;  | 
71  |  | 
  | 
72  | 0  |         if (!fgets(ln, sizeof(ln), f))  | 
73  | 0  |             break;  | 
74  |  |  | 
75  | 0  |         if (strncmp(ln, field, flen))  | 
76  | 0  |             continue;  | 
77  |  |  | 
78  | 0  |         p = ln + flen;  | 
79  | 0  |         p += strspn(p, "\"");  | 
80  | 0  |         p[strcspn(p, "\"")] = 0;  | 
81  |  | 
  | 
82  | 0  |         snprintf(ret_s, size, "%s", p);  | 
83  |  | 
  | 
84  | 0  |         fclose(f);  | 
85  | 0  |         return 0;  | 
86  | 0  |     }  | 
87  |  |  | 
88  | 0  |     fclose(f);  | 
89  | 0  |     return -1;  | 
90  | 0  | }  | 
91  |  |  | 
92  | 0  | static int load_lsb_distrib_id(char *ret_s, size_t size) { | 
93  | 0  |     return load_id(ret_s, size, "/etc/lsb-release", "DISTRIB_ID=");  | 
94  | 0  | }  | 
95  |  |  | 
96  | 0  | static int load_os_hostname(char *ret_s, size_t size) { | 
97  | 0  |     int r;  | 
98  |  | 
  | 
99  | 0  |     r = load_id(ret_s, size, "/etc/os-release", "DEFAULT_HOSTNAME=");  | 
100  | 0  |     if (r < 0)  | 
101  | 0  |         r = load_id(ret_s, size, "/etc/os-release", "ID=");  | 
102  | 0  |     return r;  | 
103  | 0  | }  | 
104  |  | #endif  | 
105  |  |  | 
106  | 0  | char *avahi_get_host_name(char *ret_s, size_t size) { | 
107  | 0  |     assert(ret_s);  | 
108  | 0  |     assert(size > 0);  | 
109  |  |  | 
110  | 0  |     if (gethostname(ret_s, size) >= 0) { | 
111  | 0  |         ret_s[size-1] = 0;  | 
112  | 0  |         strip_bad_chars(ret_s);  | 
113  | 0  |     } else  | 
114  | 0  |         *ret_s = 0;  | 
115  |  | 
  | 
116  | 0  |     if (strcmp(ret_s, "localhost") == 0 || strncmp(ret_s, "localhost.", 10) == 0) { | 
117  | 0  |         *ret_s = 0;  | 
118  | 0  |         avahi_log_warn("System host name is set to 'localhost'. This is not a suitable mDNS host name, looking for alternatives."); | 
119  | 0  |     }  | 
120  |  | 
  | 
121  | 0  |     if (*ret_s == 0) { | 
122  |  |         /* No hostname was set, so let's take the OS name */  | 
123  |  | 
  | 
124  | 0  | #ifdef __linux__  | 
125  |  |  | 
126  |  |         /* Try os-release or LSB distribution name first */  | 
127  | 0  |         if (load_os_hostname(ret_s, size) >= 0 || load_lsb_distrib_id(ret_s, size) >= 0) { | 
128  | 0  |             strip_bad_chars(ret_s);  | 
129  | 0  |             avahi_strdown(ret_s);  | 
130  | 0  |         }  | 
131  |  | 
  | 
132  | 0  |         if (*ret_s == 0)  | 
133  | 0  | #endif  | 
134  |  |  | 
135  | 0  |         { | 
136  |  |             /* Try uname() second */  | 
137  | 0  |             struct utsname utsname;  | 
138  |  | 
  | 
139  | 0  |             if (uname(&utsname) >= 0) { | 
140  | 0  |                 snprintf(ret_s, size, "%s", utsname.sysname);  | 
141  | 0  |                 strip_bad_chars(ret_s);  | 
142  | 0  |                 avahi_strdown(ret_s);  | 
143  | 0  |             }  | 
144  |  |  | 
145  |  |             /* Give up */  | 
146  | 0  |             if (*ret_s == 0)  | 
147  | 0  |                 snprintf(ret_s, size, "unnamed");  | 
148  | 0  |         }  | 
149  | 0  |     }  | 
150  |  | 
  | 
151  | 0  |     if (size >= AVAHI_LABEL_MAX)  | 
152  | 0  |   ret_s[AVAHI_LABEL_MAX-1] = 0;  | 
153  |  | 
  | 
154  | 0  |     return ret_s;  | 
155  | 0  | }  | 
156  |  |  | 
157  | 0  | char *avahi_get_host_name_strdup(void) { | 
158  | 0  |     char t[AVAHI_DOMAIN_NAME_MAX];  | 
159  |  | 
  | 
160  | 0  |     if (!(avahi_get_host_name(t, sizeof(t))))  | 
161  | 0  |         return NULL;  | 
162  |  |  | 
163  | 0  |     return avahi_strdup(t);  | 
164  | 0  | }  | 
165  |  |  | 
166  | 0  | int avahi_binary_domain_cmp(const char *a, const char *b) { | 
167  | 0  |     assert(a);  | 
168  | 0  |     assert(b);  | 
169  |  |  | 
170  | 0  |     if (a == b)  | 
171  | 0  |         return 0;  | 
172  |  |  | 
173  | 0  |     for (;;) { | 
174  | 0  |         char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *p;  | 
175  | 0  |         int r;  | 
176  |  | 
  | 
177  | 0  |         p = avahi_unescape_label(&a, ca, sizeof(ca));  | 
178  | 0  |         assert(p);  | 
179  | 0  |         p = avahi_unescape_label(&b, cb, sizeof(cb));  | 
180  | 0  |         assert(p);  | 
181  |  |  | 
182  | 0  |         if ((r = strcmp(ca, cb)))  | 
183  | 0  |             return r;  | 
184  |  |  | 
185  | 0  |         if (!*a && !*b)  | 
186  | 0  |             return 0;  | 
187  | 0  |     }  | 
188  | 0  | }  | 
189  |  |  | 
190  | 0  | int avahi_domain_ends_with(const char *domain, const char *suffix) { | 
191  | 0  |     assert(domain);  | 
192  | 0  |     assert(suffix);  | 
193  |  |  | 
194  | 0  |     for (;;) { | 
195  | 0  |         char dummy[AVAHI_LABEL_MAX], *r;  | 
196  |  | 
  | 
197  | 0  |         if (*domain == 0)  | 
198  | 0  |             return 0;  | 
199  |  |  | 
200  | 0  |         if (avahi_domain_equal(domain, suffix))  | 
201  | 0  |             return 1;  | 
202  |  |  | 
203  | 0  |         r = avahi_unescape_label(&domain, dummy, sizeof(dummy));  | 
204  | 0  |         assert(r);  | 
205  | 0  |     }  | 
206  | 0  | }  | 
207  |  |  |