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