/*** This file is part of avahi. avahi is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. avahi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with avahi; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <string.h> #include <stdlib.h> #include <ctype.h> #include <assert.h> #include "alternative.h" #include "avahi-malloc.h" #include "domain.h" #include "utf8.h" static void drop_incomplete_utf8(char *c) { char *e; e = strchr(c, 0) - 1; while (e >= c) { if (avahi_utf8_valid(c)) break; assert(*e & 128); *e = 0; e--; } } char *avahi_alternative_host_name(const char *s) { const char *e; char *r; assert(s); if (!avahi_is_valid_host_name(s)) return NULL; if ((e = strrchr(s, '-'))) { const char *p; e++; for (p = e; *p; p++) if (!isdigit(*p)) { e = NULL; break; } if (e && (*e == '0' || *e == 0)) e = NULL; } if (e) { char *c, *m; size_t l; int n; n = atoi(e)+1; if (!(m = avahi_strdup_printf("%i", n))) return NULL; l = e-s-1; if (l >= AVAHI_LABEL_MAX-1-strlen(m)-1) l = AVAHI_LABEL_MAX-1-strlen(m)-1; if (!(c = avahi_strndup(s, l))) { avahi_free(m); return NULL; } drop_incomplete_utf8(c); r = avahi_strdup_printf("%s-%s", c, m); avahi_free(c); avahi_free(m); } else { char *c; if (!(c = avahi_strndup(s, AVAHI_LABEL_MAX-1-2))) return NULL; drop_incomplete_utf8(c); r = avahi_strdup_printf("%s-2", c); avahi_free(c); } assert(avahi_is_valid_host_name(r)); return r; } char *avahi_alternative_service_name(const char *s) { const char *e; char *r; assert(s); if (!avahi_is_valid_service_name(s)) return NULL; if ((e = strstr(s, " #"))) { const char *n, *p; e += 2; while ((n = strstr(e, " #"))) e = n + 2; for (p = e; *p; p++) if (!isdigit(*p)) { e = NULL; break; } if (e && (*e == '0' || *e == 0)) e = NULL; } if (e) { char *c, *m; size_t l; int n; n = atoi(e)+1; if (!(m = avahi_strdup_printf("%i", n))) return NULL; l = e-s-2; if (l >= AVAHI_LABEL_MAX-1-strlen(m)-2) l = AVAHI_LABEL_MAX-1-strlen(m)-2; if (!(c = avahi_strndup(s, l))) { avahi_free(m); return NULL; } drop_incomplete_utf8(c); r = avahi_strdup_printf("%s #%s", c, m); avahi_free(c); avahi_free(m); } else { char *c; if (!(c = avahi_strndup(s, AVAHI_LABEL_MAX-1-3))) return NULL; drop_incomplete_utf8(c); r = avahi_strdup_printf("%s #2", c); avahi_free(c); } assert(avahi_is_valid_service_name(r)); return r; }