10cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering/*** 20cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering This file is part of avahi. 3b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 40cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering avahi is free software; you can redistribute it and/or modify it 50cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering under the terms of the GNU Lesser General Public License as 60cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering published by the Free Software Foundation; either version 2.1 of the 70cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering License, or (at your option) any later version. 8b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 90cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering avahi is distributed in the hope that it will be useful, but WITHOUT 100cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 110cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 120cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering Public License for more details. 13b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 140cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering You should have received a copy of the GNU Lesser General Public 150cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering License along with avahi; if not, write to the Free Software 160cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 170cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering USA. 180cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering***/ 190cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 200cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#ifdef HAVE_CONFIG_H 210cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <config.h> 220cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#endif 230cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 240cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <stdlib.h> 250cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <stdio.h> 260cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <getopt.h> 270cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <assert.h> 280cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <string.h> 290cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <sys/types.h> 300cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <sys/socket.h> 310cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <locale.h> 320cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 330cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <avahi-common/simple-watch.h> 340cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <avahi-common/error.h> 358e46e738cae449bf44232c66e973c8e9e15fbcb5Robert Ginda#include "avahi-common/avahi-malloc.h" 360cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <avahi-common/domain.h> 37b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering#include <avahi-common/i18n.h> 380cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include <avahi-client/client.h> 390cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 400cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering#include "sigint.h" 410cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 420cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringtypedef enum { 43b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering COMMAND_UNSPEC, 440cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering COMMAND_HELP, 453ce8ea5ab89aba61220ef92545f23d4bd771ea41Lennart Poettering COMMAND_VERSION 460cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering} Command; 470cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 480cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringtypedef struct Config { 490cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering int verbose; 500cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering Command command; 510cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering} Config; 520cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 530cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringstatic AvahiSimplePoll *simple_poll = NULL; 540cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringstatic AvahiClient *client = NULL; 550cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 560cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringstatic void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) { 570cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering switch (state) { 580cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case AVAHI_CLIENT_FAILURE: 59b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Client failure, exiting: %s\n"), avahi_strerror(avahi_client_errno(c))); 600cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering avahi_simple_poll_quit(simple_poll); 610cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering break; 62b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 630cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case AVAHI_CLIENT_S_REGISTERING: 640cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case AVAHI_CLIENT_S_RUNNING: 650cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case AVAHI_CLIENT_S_COLLISION: 660cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case AVAHI_CLIENT_CONNECTING: 670cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering ; 680cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 690cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering} 700cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 710cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringstatic void help(FILE *f, const char *argv0) { 720cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering fprintf(f, 73b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering _("%s [options] <new host name>\n\n" 74b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering " -h --help Show this help\n" 75b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering " -V --version Show version\n" 76b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering " -v --verbose Enable verbose mode\n"), 770cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering argv0); 780cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering} 790cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 800cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringstatic int parse_command_line(Config *c, int argc, char *argv[]) { 810cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering int o; 820cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 830cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering static const struct option long_options[] = { 840cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering { "help", no_argument, NULL, 'h' }, 850cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering { "version", no_argument, NULL, 'V' }, 860cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering { "verbose", no_argument, NULL, 'v' }, 870cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering { NULL, 0, NULL, 0 } 880cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering }; 890cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 900cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering assert(c); 910cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 920cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering c->command = COMMAND_UNSPEC; 930cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering c->verbose = 0; 940cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 950cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering while ((o = getopt_long(argc, argv, "hVv", long_options, NULL)) >= 0) { 960cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 970cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering switch(o) { 980cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case 'h': 990cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering c->command = COMMAND_HELP; 1000cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering break; 1010cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case 'V': 1020cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering c->command = COMMAND_VERSION; 1030cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering break; 1040cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case 'v': 1050cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering c->verbose = 1; 1060cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering break; 1070cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering default: 1080cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering return -1; 1090cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 1100cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 1110cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1120cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (c->command == COMMAND_UNSPEC) { 1130cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (optind != argc-1) { 114b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Invalid number of arguments, expecting exactly one.\n")); 1150cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering return -1; 1160cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 1170cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 118b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 1190cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering return 0; 1200cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering} 1210cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1220cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringint main(int argc, char *argv[]) { 1230cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering int ret = 1, error; 1240cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering Config config; 1250cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering const char *argv0; 1260cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 127b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering avahi_init_i18n(); 128b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering setlocale(LC_ALL, ""); 129b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 1300cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if ((argv0 = strrchr(argv[0], '/'))) 1310cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering argv0++; 1320cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering else 1330cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering argv0 = argv[0]; 1340cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1350cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (parse_command_line(&config, argc, argv) < 0) 1360cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering goto fail; 1370cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1380cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering switch (config.command) { 1390cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case COMMAND_HELP: 1400cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering help(stdout, argv0); 1410cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering ret = 0; 1420cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering break; 143b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 1440cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering case COMMAND_VERSION: 1450cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering printf("%s "PACKAGE_VERSION"\n", argv0); 1460cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering ret = 0; 1470cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering break; 1480cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 149b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering case COMMAND_UNSPEC: 150b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 1510cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (!(simple_poll = avahi_simple_poll_new())) { 152b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Failed to create simple poll object.\n")); 1530cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering goto fail; 1540cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 155b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 1560cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (sigint_install(simple_poll) < 0) 1570cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering goto fail; 158b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 1590cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error))) { 160b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Failed to create client object: %s\n"), avahi_strerror(error)); 1610cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering goto fail; 1620cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 1630cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1640cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (config.verbose) { 1650cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering const char *version, *hn; 1660cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1670cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (!(version = avahi_client_get_version_string(client))) { 168b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Failed to query version string: %s\n"), avahi_strerror(avahi_client_errno(client))); 1690cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering goto fail; 1700cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 1710cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1720cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (!(hn = avahi_client_get_host_name_fqdn(client))) { 173b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Failed to query host name: %s\n"), avahi_strerror(avahi_client_errno(client))); 1740cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering goto fail; 1750cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 176b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 177b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Server version: %s; Host name: %s\n"), version, hn); 1780cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 1790cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1800cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (avahi_client_set_host_name(client, argv[optind]) < 0) { 181b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Failed to create host name resolver: %s\n"), avahi_strerror(avahi_client_errno(client))); 1820cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering goto fail; 1830cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 1840cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 1850cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (config.verbose) { 1860cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering const char *hn; 187b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 1880cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (!(hn = avahi_client_get_host_name_fqdn(client))) { 189b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Failed to query host name: %s\n"), avahi_strerror(avahi_client_errno(client))); 1900cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering goto fail; 1910cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 192b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 193b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering fprintf(stderr, _("Host name successfully changed to %s\n"), hn); 1940cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 195b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 1960cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering ret = 0; 1970cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering break; 1980cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering } 199b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 2000cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poetteringfail: 2010cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 2020cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (client) 2030cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering avahi_client_free(client); 2040cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 2050cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering sigint_uninstall(); 206b961e134cfaf3077dae0d83efa0fffeacf134fa7Lennart Poettering 2070cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering if (simple_poll) 2080cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering avahi_simple_poll_free(simple_poll); 2090cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering 2100cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering return ret; 2110cbaf99fc5eea82006dbc07f6c561e5d6d9cefbaLennart Poettering} 212