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 "alternative.h" 30 #include "avahi-malloc.h" 31 #include "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 } 183