Home | History | Annotate | Download | only in avahi-core
      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 <stdlib.h>
     25 #include <assert.h>
     26 #include <string.h>
     27 #include <unistd.h>
     28 #include <ctype.h>
     29 #include <sys/utsname.h>
     30 #include <stdio.h>
     31 
     32 #include "avahi-common/avahi-malloc.h"
     33 
     34 #include "log.h"
     35 #include "domain-util.h"
     36 #include "util.h"
     37 
     38 static void strip_bad_chars(char *s) {
     39     char *p, *d;
     40 
     41     s[strcspn(s, ".")] = 0;
     42 
     43     for (p = s, d = s; *p; p++)
     44         if ((*p >= 'a' && *p <= 'z') ||
     45             (*p >= 'A' && *p <= 'Z') ||
     46             (*p >= '0' && *p <= '9') ||
     47             *p == '-')
     48             *(d++) = *p;
     49 
     50     *d = 0;
     51 }
     52 
     53 #ifdef __linux__
     54 static int load_lsb_distrib_id(char *ret_s, size_t size) {
     55     FILE *f;
     56 
     57     assert(ret_s);
     58     assert(size > 0);
     59 
     60     if (!(f = fopen("/etc/lsb-release", "r")))
     61         return -1;
     62 
     63     while (!feof(f)) {
     64         char ln[256], *p;
     65 
     66         if (!fgets(ln, sizeof(ln), f))
     67             break;
     68 
     69         if (strncmp(ln, "DISTRIB_ID=", 11))
     70             continue;
     71 
     72         p = ln + 11;
     73         p += strspn(p, "\"");
     74         p[strcspn(p, "\"")] = 0;
     75 
     76         snprintf(ret_s, size, "%s", p);
     77 
     78         fclose(f);
     79         return 0;
     80     }
     81 
     82     fclose(f);
     83     return -1;
     84 }
     85 #endif
     86 
     87 char *avahi_get_host_name(char *ret_s, size_t size) {
     88     assert(ret_s);
     89     assert(size > 0);
     90 
     91     if (gethostname(ret_s, size) >= 0) {
     92         ret_s[size-1] = 0;
     93         strip_bad_chars(ret_s);
     94     } else
     95         *ret_s = 0;
     96 
     97     if (strcmp(ret_s, "localhost") == 0 || strncmp(ret_s, "localhost.", 10) == 0) {
     98         *ret_s = 0;
     99         avahi_log_warn("System host name is set to 'localhost'. This is not a suitable mDNS host name, looking for alternatives.");
    100     }
    101 
    102     if (*ret_s == 0) {
    103         /* No hostname was set, so let's take the OS name */
    104 
    105 #ifdef __linux__
    106 
    107         /* Try LSB distribution name first */
    108         if (load_lsb_distrib_id(ret_s, size) >= 0) {
    109             strip_bad_chars(ret_s);
    110             avahi_strdown(ret_s);
    111         }
    112 
    113         if (*ret_s == 0)
    114 #endif
    115 
    116         {
    117             /* Try uname() second */
    118             struct utsname utsname;
    119 
    120             if (uname(&utsname) >= 0) {
    121                 snprintf(ret_s, size, "%s", utsname.sysname);
    122                 strip_bad_chars(ret_s);
    123                 avahi_strdown(ret_s);
    124             }
    125 
    126             /* Give up */
    127             if (*ret_s == 0)
    128                 snprintf(ret_s, size, "unnamed");
    129         }
    130     }
    131 
    132     if (size >= AVAHI_LABEL_MAX)
    133 	ret_s[AVAHI_LABEL_MAX-1] = 0;
    134 
    135     return ret_s;
    136 }
    137 
    138 char *avahi_get_host_name_strdup(void) {
    139     char t[AVAHI_DOMAIN_NAME_MAX];
    140 
    141     if (!(avahi_get_host_name(t, sizeof(t))))
    142         return NULL;
    143 
    144     return avahi_strdup(t);
    145 }
    146 
    147 int avahi_binary_domain_cmp(const char *a, const char *b) {
    148     assert(a);
    149     assert(b);
    150 
    151     if (a == b)
    152         return 0;
    153 
    154     for (;;) {
    155         char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *p;
    156         int r;
    157 
    158         p = avahi_unescape_label(&a, ca, sizeof(ca));
    159         assert(p);
    160         p = avahi_unescape_label(&b, cb, sizeof(cb));
    161         assert(p);
    162 
    163         if ((r = strcmp(ca, cb)))
    164             return r;
    165 
    166         if (!*a && !*b)
    167             return 0;
    168     }
    169 }
    170 
    171 int avahi_domain_ends_with(const char *domain, const char *suffix) {
    172     assert(domain);
    173     assert(suffix);
    174 
    175     for (;;) {
    176         char dummy[AVAHI_LABEL_MAX], *r;
    177 
    178         if (*domain == 0)
    179             return 0;
    180 
    181         if (avahi_domain_equal(domain, suffix))
    182             return 1;
    183 
    184         r = avahi_unescape_label(&domain, dummy, sizeof(dummy));
    185         assert(r);
    186     }
    187 }
    188 
    189