]> git.meshlink.io Git - catta/blob - src/alternative.c
move public headers into their own directory
[catta] / src / alternative.c
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 <string.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27 #include <assert.h>
28
29 #include <avahi/alternative.h>
30 #include <avahi/malloc.h>
31 #include <avahi/domain.h>
32 #include "utf8.h"
33
34 static void drop_incomplete_utf8(char *c) {
35     char *e;
36
37     e = strchr(c, 0) - 1;
38
39     while (e >= c) {
40
41         if (avahi_utf8_valid(c))
42             break;
43
44         assert(*e & 128);
45         *e = 0;
46
47         e--;
48     }
49 }
50
51 char *avahi_alternative_host_name(const char *s) {
52     const char *e;
53     char *r;
54
55     assert(s);
56
57     if (!avahi_is_valid_host_name(s))
58         return NULL;
59
60     if ((e = strrchr(s, '-'))) {
61         const char *p;
62
63         e++;
64
65         for (p = e; *p; p++)
66             if (!isdigit(*p)) {
67                 e = NULL;
68                 break;
69             }
70
71         if (e && (*e == '0' || *e == 0))
72             e = NULL;
73     }
74
75     if (e) {
76         char *c, *m;
77         size_t l;
78         int n;
79
80         n = atoi(e)+1;
81         if (!(m = avahi_strdup_printf("%i", n)))
82             return NULL;
83
84         l = e-s-1;
85
86         if (l >= AVAHI_LABEL_MAX-1-strlen(m)-1)
87             l = AVAHI_LABEL_MAX-1-strlen(m)-1;
88
89         if (!(c = avahi_strndup(s, l))) {
90             avahi_free(m);
91             return NULL;
92         }
93
94         drop_incomplete_utf8(c);
95
96         r = avahi_strdup_printf("%s-%s", c, m);
97         avahi_free(c);
98         avahi_free(m);
99
100     } else {
101         char *c;
102
103         if (!(c = avahi_strndup(s, AVAHI_LABEL_MAX-1-2)))
104             return NULL;
105
106         drop_incomplete_utf8(c);
107
108         r = avahi_strdup_printf("%s-2", c);
109         avahi_free(c);
110     }
111
112     assert(avahi_is_valid_host_name(r));
113
114     return r;
115 }
116
117 char *avahi_alternative_service_name(const char *s) {
118     const char *e;
119     char *r;
120
121     assert(s);
122
123     if (!avahi_is_valid_service_name(s))
124         return NULL;
125
126     if ((e = strstr(s, " #"))) {
127         const char *n, *p;
128         e += 2;
129
130         while ((n = strstr(e, " #")))
131             e = n + 2;
132
133         for (p = e; *p; p++)
134             if (!isdigit(*p)) {
135                 e = NULL;
136                 break;
137             }
138
139         if (e && (*e == '0' || *e == 0))
140             e = NULL;
141     }
142
143     if (e) {
144         char *c, *m;
145         size_t l;
146         int n;
147
148         n = atoi(e)+1;
149         if (!(m = avahi_strdup_printf("%i", n)))
150             return NULL;
151
152         l = e-s-2;
153
154         if (l >= AVAHI_LABEL_MAX-1-strlen(m)-2)
155             l = AVAHI_LABEL_MAX-1-strlen(m)-2;
156
157         if (!(c = avahi_strndup(s, l))) {
158             avahi_free(m);
159             return NULL;
160         }
161
162         drop_incomplete_utf8(c);
163
164         r = avahi_strdup_printf("%s #%s", c, m);
165         avahi_free(c);
166         avahi_free(m);
167     } else {
168         char *c;
169
170         if (!(c = avahi_strndup(s, AVAHI_LABEL_MAX-1-3)))
171             return NULL;
172
173         drop_incomplete_utf8(c);
174
175         r = avahi_strdup_printf("%s #2", c);
176         avahi_free(c);
177     }
178
179     assert(avahi_is_valid_service_name(r));
180
181     return r;
182 }