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 36static 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 53char *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 119char *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} 185