Coverage Report

Created: 2023-06-07 06:18

/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