static void print_service_line(Config *config, char c, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain, int nl) { char ifname[IF_NAMESIZE]; #if defined(HAVE_GDBM) || defined(HAVE_DBM) if (!config->no_db_lookup) type = stdb_lookup(type); #endif if (config->parsable) { char sn[AVAHI_DOMAIN_NAME_MAX], *e = sn; size_t l = sizeof(sn); printf("%c;%s;%s;%s;%s;%s%s", c, interface != AVAHI_IF_UNSPEC ? if_indextoname(interface, ifname) : ("n/a"), protocol != AVAHI_PROTO_UNSPEC ? avahi_proto_to_string(protocol) : ("n/a"), avahi_escape_label(name, strlen(name), &e, &l), type, domain, nl ? "\n" : ""); } else { char label[AVAHI_LABEL_MAX]; make_printable(name, label); printf("%c %6s %4s %-*s %-20s %s\n", c, interface != AVAHI_IF_UNSPEC ? if_indextoname(interface, ifname) : ("n/a"), protocol != AVAHI_PROTO_UNSPEC ? avahi_proto_to_string(protocol) : ("n/a"), n_columns-35, label, type, domain); } fflush(stdout); }
char *avahi_normalize_name(const char *s, char *ret_s, size_t size) { int empty = 1; char *r; assert(s); assert(ret_s); assert(size > 0); r = ret_s; *ret_s = 0; while (*s) { char label[AVAHI_LABEL_MAX]; if (!(avahi_unescape_label(&s, label, sizeof(label)))) return NULL; if (label[0] == 0) { if (*s == 0 && empty) return ret_s; return NULL; } if (!empty) { if (size < 1) return NULL; *(r++) = '.'; size--; } else empty = 0; avahi_escape_label(label, strlen(label), &r, &size); } return ret_s; }
int avahi_service_name_join(char *p, size_t size, const char *name, const char *type, const char *domain) { char escaped_name[AVAHI_LABEL_MAX*4]; char normalized_type[AVAHI_DOMAIN_NAME_MAX]; char normalized_domain[AVAHI_DOMAIN_NAME_MAX]; assert(p); /* Validity checks */ if ((name && !avahi_is_valid_service_name(name))) return AVAHI_ERR_INVALID_SERVICE_NAME; if (!avahi_is_valid_service_type_generic(type)) return AVAHI_ERR_INVALID_SERVICE_TYPE; if (!avahi_is_valid_domain_name(domain)) return AVAHI_ERR_INVALID_DOMAIN_NAME; /* Preparation */ if (name) { size_t l = sizeof(escaped_name); char *e = escaped_name, *r; r = avahi_escape_label(name, strlen(name), &e, &l); assert(r); } if (!(avahi_normalize_name(type, normalized_type, sizeof(normalized_type)))) return AVAHI_ERR_INVALID_SERVICE_TYPE; if (!(avahi_normalize_name(domain, normalized_domain, sizeof(normalized_domain)))) return AVAHI_ERR_INVALID_DOMAIN_NAME; /* Concatenation */ snprintf(p, size, "%s%s%s.%s", name ? escaped_name : "", name ? "." : "", normalized_type, normalized_domain); return AVAHI_OK; }
int avahi_service_name_split(const char *p, char *name, size_t name_size, char *type, size_t type_size, char *domain, size_t domain_size) { enum { NAME, TYPE, DOMAIN } state; int type_empty = 1, domain_empty = 1; assert(p); assert(type); assert(type_size > 0); assert(domain); assert(domain_size > 0); if (name) { assert(name_size > 0); *name = 0; state = NAME; } else state = TYPE; *type = *domain = 0; while (*p) { char buf[64]; if (!(avahi_unescape_label(&p, buf, sizeof(buf)))) return -1; switch (state) { case NAME: strlcpy(name, buf, name_size); state = TYPE; break; case TYPE: if (buf[0] == '_') { if (!type_empty) { if (!type_size) return AVAHI_ERR_NO_MEMORY; *(type++) = '.'; type_size --; } else type_empty = 0; if (!(avahi_escape_label(buf, strlen(buf), &type, &type_size))) return AVAHI_ERR_NO_MEMORY; break; } state = DOMAIN; /* fall through */ case DOMAIN: if (!domain_empty) { if (!domain_size) return AVAHI_ERR_NO_MEMORY; *(domain++) = '.'; domain_size --; } else domain_empty = 0; if (!(avahi_escape_label(buf, strlen(buf), &domain, &domain_size))) return AVAHI_ERR_NO_MEMORY; break; } } return 0; }