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