From 48f053dc87279e2e3cad561db5b744cbcbf32387 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Oct 2005 22:49:37 +0000 Subject: [PATCH] lookup service types in the service data base in avahi-browse git-svn-id: file:///home/lennart/svn/public/avahi/trunk@902 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-utils/Makefile.am | 7 ++- avahi-utils/avahi-browse.c | 70 ++++++++++++++++++----- avahi-utils/stdb.c | 113 +++++++++++++++++++++++++++++++++++++ avahi-utils/stdb.h | 30 ++++++++++ configure.ac | 23 ++++++++ docs/TODO | 2 +- 6 files changed, 229 insertions(+), 16 deletions(-) create mode 100644 avahi-utils/stdb.c create mode 100644 avahi-utils/stdb.h diff --git a/avahi-utils/Makefile.am b/avahi-utils/Makefile.am index d111a04..d3a1f39 100644 --- a/avahi-utils/Makefile.am +++ b/avahi-utils/Makefile.am @@ -90,6 +90,11 @@ bin_PROGRAMS = avahi-browse avahi_browse_SOURCES = avahi-browse.c sigint.c sigint.h avahi_browse_CFLAGS = $(AM_CFLAGS) -avahi_browse_LDADD = $(AM_LDADD) ../avahi-client/libavahi-client.la ../avahi-common/libavahi-common.la +avahi_browse_LDADD = $(AM_LDADD) ../avahi-client/libavahi-client.la ../avahi-common/libavahi-common.la -lgdbm + +if HAVE_GDBM +avahi_browse_SOURCES += stdb.h stdb.c +avahi_browse_CFLAGS += -DDATABASE_FILE=\"$(pkgdatadir)/service-types.db\" +endif endif diff --git a/avahi-utils/avahi-browse.c b/avahi-utils/avahi-browse.c index 09792a4..0bf58ef 100644 --- a/avahi-utils/avahi-browse.c +++ b/avahi-utils/avahi-browse.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,10 @@ #include "sigint.h" +#ifdef HAVE_GDBM +#include "stdb.h" +#endif + typedef enum { COMMAND_HELP, COMMAND_VERSION, @@ -56,9 +61,11 @@ typedef struct Config { int show_all; Command command; int resolve; +#ifdef HAVE_GDBM + int no_db_lookup; +#endif } Config; - typedef struct ServiceInfo ServiceInfo; struct ServiceInfo { @@ -123,6 +130,20 @@ static ServiceInfo *find_service(AvahiIfIndex interface, AvahiProtocol protocol, return NULL; } +static void print_service_line(Config *config, char c, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain) { + char ifname[IF_NAMESIZE]; + +#ifdef HAVE_GDBM + if (!config->no_db_lookup) + type = stdb_lookup(type); +#endif + + printf("%c %4s %4s %-*s %-20s %s\n", + c, + if_indextoname(interface, ifname), avahi_proto_to_string(protocol), + n_columns-35, name, type, domain); +} + static void service_resolver_callback( AvahiServiceResolver *r, AvahiIfIndex interface, @@ -146,19 +167,17 @@ static void service_resolver_callback( switch (event) { case AVAHI_RESOLVER_FOUND: { char address[AVAHI_ADDRESS_STR_MAX], *t; - char ifname[IF_NAMESIZE]; avahi_address_snprint(address, sizeof(address), a); t = avahi_string_list_to_string(txt); - printf("= %4s %4s %-*s %-20s %s\n" - " hostname = [%s]\n" + print_service_line(i->config, '=', interface, protocol, name, type, domain); + + printf(" hostname = [%s]\n" " address = [%s]\n" " port = [%i]\n" " txt = [%s]\n", - if_indextoname(interface, ifname), avahi_proto_to_string(protocol), - n_columns-35, name, type, domain, host_name, address, port, @@ -244,7 +263,6 @@ static void service_browser_callback( switch (event) { case AVAHI_BROWSER_NEW: { - char ifname[IF_NAMESIZE]; if (c->ignore_local && (flags & AVAHI_LOOKUP_RESULT_LOCAL)) break; @@ -253,13 +271,12 @@ static void service_browser_callback( add_service(c, interface, protocol, name, type, domain); - printf("+ %4s %4s %-*s %-20s %s\n", if_indextoname(interface, ifname), avahi_proto_to_string(protocol), n_columns-35, name, type, domain); + print_service_line(c, '+', interface, protocol, name, type, domain); break; } case AVAHI_BROWSER_REMOVE: { - char ifname[IF_NAMESIZE]; ServiceInfo *info; if (!(info = find_service(interface, protocol, name, type, domain))) @@ -267,7 +284,7 @@ static void service_browser_callback( remove_service(c, info); - printf("- %4s %4s %-*s %-20s %s\n", if_indextoname(interface, ifname), avahi_proto_to_string(protocol), n_columns-35, name, type, domain); + print_service_line(c, '-', interface, protocol, name, type, domain); break; } @@ -410,10 +427,13 @@ static void help(FILE *f, const char *argv0) { " -t --terminate Terminate after getting or more or less complete list\n" " -c --cache Terminate after dumping all entries from the cache\n" " -l --ignore-local Ignore local services\n" - " -r --resolve Resolve services found\n", - argv0, argv0); -} + " -r --resolve Resolve services found\n" +#ifdef HAVE_GDBM + " -k --no-db-lookup Don't lookup service types\n" +#endif + , argv0, argv0); +} static int parse_command_line(Config *c, int argc, char *argv[]) { int o; @@ -428,6 +448,9 @@ static int parse_command_line(Config *c, int argc, char *argv[]) { { "cache", no_argument, NULL, 'c' }, { "ignore-local", no_argument, NULL, 'l' }, { "resolve", no_argument, NULL, 'r' }, +#ifdef HAVE_GDBM + { "no-db-lookup", no_argument, NULL, 'k' }, +#endif { NULL, 0, NULL, 0 } }; @@ -441,9 +464,17 @@ static int parse_command_line(Config *c, int argc, char *argv[]) { c->ignore_local = c->resolve = 0; c->domain = c->stype = NULL; + +#ifdef HAVE_GDBM + c->no_db_lookup = 0; +#endif opterr = 0; - while ((o = getopt_long(argc, argv, "hVd:avtclr", long_options, NULL)) >= 0) { + while ((o = getopt_long(argc, argv, "hVd:avtclr" +#ifdef HAVE_GDBM + "k" +#endif + , long_options, NULL)) >= 0) { switch(o) { case 'h': @@ -473,6 +504,11 @@ static int parse_command_line(Config *c, int argc, char *argv[]) { case 'r': c->resolve = 1; break; +#ifdef HAVE_GDBM + case 'k': + c->no_db_lookup = 1; + break; +#endif default: fprintf(stderr, "Invalid command line argument: %c\n", o); return -1; @@ -503,6 +539,8 @@ int main(int argc, char *argv[]) { const char *argv0; char *ec; + setlocale(LC_ALL, ""); + if ((argv0 = strrchr(argv[0], '/'))) argv0++; else @@ -589,5 +627,9 @@ fail: avahi_string_list_free(browsed_types); +#ifdef HAVE_GDBM + stdb_shutdown(); +#endif + return ret; } diff --git a/avahi-utils/stdb.c b/avahi-utils/stdb.c new file mode 100644 index 0000000..53be776 --- /dev/null +++ b/avahi-utils/stdb.c @@ -0,0 +1,113 @@ +/* $Id$ */ + +/*** + 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. +***/ + +#include +#include +#include +#include +#include + +#include + +#include "stdb.h" + +static GDBM_FILE gdbm_file = NULL; +static char *buffer = NULL; + +static int init(void) { + + if (gdbm_file) + return 0; + + if (!(gdbm_file = gdbm_open((char*) DATABASE_FILE, 0, GDBM_READER, 0, NULL))) + return -1; + + return 0; +} + +const char* stdb_lookup(const char *name) { + datum key, data; + const char *loc; + + if (init() < 0) + goto fail; + + data.dptr = NULL; + data.dsize = 0; + + if ((loc = setlocale(LC_MESSAGES, NULL))) { + char k[256]; + + snprintf(k, sizeof(k), "%s[%s]", name, loc); + key.dptr = k; + key.dsize = strlen(k); + data = gdbm_fetch(gdbm_file, key); + + if (!data.dptr) { + char l[32], *e; + snprintf(l, sizeof(l), "%s", loc); + + if ((e = strchr(l, '@'))) { + *e = 0; + snprintf(k, sizeof(k), "%s[%s]", name, l); + key.dptr = k; + key.dsize = strlen(k); + data = gdbm_fetch(gdbm_file, key); + } + + if (!data.dptr) { + if ((e = strchr(l, '_'))) { + *e = 0; + snprintf(k, sizeof(k), "%s[%s]", name, l); + key.dptr = k; + key.dsize = strlen(k); + data = gdbm_fetch(gdbm_file, key); + } + } + } + } + + if (!data.dptr) { + key.dptr = (char*) name; + key.dsize = strlen(name); + data = gdbm_fetch(gdbm_file, key); + } + + if (!data.dptr) + goto fail; + + avahi_free(buffer); + buffer = avahi_strndup(data.dptr, data.dsize); + free(data.dptr); + + return buffer; + +fail: + + return name; +} + +void stdb_shutdown(void) { + if (gdbm_file) + gdbm_close(gdbm_file); + + avahi_free(buffer); +} diff --git a/avahi-utils/stdb.h b/avahi-utils/stdb.h new file mode 100644 index 0000000..92c2651 --- /dev/null +++ b/avahi-utils/stdb.h @@ -0,0 +1,30 @@ +#ifndef foostdbhfoo +#define foostdbhfoo + +/* $Id$ */ + +/*** + 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. +***/ + +#include + +const char* stdb_lookup(const char *name); +void stdb_shutdown(void); + +#endif diff --git a/configure.ac b/configure.ac index 005dc11..531e015 100644 --- a/configure.ac +++ b/configure.ac @@ -392,6 +392,28 @@ if test "x$HAVE_EXPAT" = "xyes" ; then fi AM_CONDITIONAL(HAVE_EXPAT, test "x$HAVE_EXPAT" = "xyes") +# +# GDBM +# +AC_ARG_ENABLE(gdbm, + AS_HELP_STRING([--disable-gdbm],[Disable use of GDBM]), + [case "${enableval}" in + yes) HAVE_GDBM=yes ;; + no) HAVE_GDBM=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-gdbm) ;; + esac], + [HAVE_GDBM=yes]) + +if test "x$HAVE_GDBM" = "xyes" ; then + AC_CHECK_LIB(gdbm, gdbm_open, [ AC_CHECK_HEADERS(gdbm.h, have_gdbm=true, have_gdbm=false) ], have_gdbm=false) + + if ! $have_gdbm ; then + AC_MSG_WARN([*** libgdbm not found ***]) + fi + AC_DEFINE([HAVE_GDBM],[],[Support for GDBM]) +fi +AM_CONDITIONAL(HAVE_GDBM, test "x$HAVE_GDBM" = "xyes") + # # libdaemon # @@ -696,6 +718,7 @@ echo " Enable GTK: ${HAVE_GTK} Enable D-BUS: ${HAVE_DBUS} Enable Expat: ${HAVE_EXPAT} + Enable GDBM: ${HAVE_GDBM} Enable libdaemon: ${HAVE_LIBDAEMON} Enable Python: ${HAVE_PYTHON} Enable pygtk: ${HAVE_PYGTK} diff --git a/docs/TODO b/docs/TODO index 4f8d12b..83b6cb9 100644 --- a/docs/TODO +++ b/docs/TODO @@ -6,7 +6,6 @@ for 0.6: * introduce AVAHI_CLIENT_FAILURE * Expose AvahiSRecordBrowser over D-BUS and implement in avahi-client [lathiat] * add support for defining browsing domains with an option in avahi-daemon.onf -* add service type database support to avahi-browse * avahi-client: do something about letting the client know if the daemon comes back from a DISCONNECTED state later: @@ -103,3 +102,4 @@ done: * unify argument order of functions returning a string in a user supplied buffer * add support for subtypes in static services * wrap avahi_server_add_record() via DBUS and in avahi-client [lathiat] +* add service type database support to avahi-browse -- 2.39.5