Home | History | Annotate | Download | only in avahi-common
      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