示例#1
0
static void add_static_host_to_server(StaticHost *h)
{

    if (!h->group)
        if (!(h->group = avahi_s_entry_group_new (avahi_server, entry_group_callback, h))) {
            avahi_log_error("avahi_s_entry_group_new() failed: %s", avahi_strerror(avahi_server_errno(avahi_server)));
            return;
        }

    if (avahi_s_entry_group_is_empty(h->group)) {
        AvahiProtocol p;
        int err;
        const AvahiServerConfig *config;
        config = avahi_server_get_config(avahi_server);
        
        p = (h->address.proto == AVAHI_PROTO_INET && config->publish_a_on_ipv6) ||
            (h->address.proto == AVAHI_PROTO_INET6 && config->publish_aaaa_on_ipv4) ? AVAHI_PROTO_UNSPEC : h->address.proto;
        
        if ((err = avahi_server_add_address(avahi_server, h->group, AVAHI_IF_UNSPEC, p, 0, h->host, &h->address)) < 0) {
            avahi_log_error ("Static host name %s: avahi_server_add_address failure: %s", h->host, avahi_strerror(err));
            return;
        }

        avahi_s_entry_group_commit (h->group);
    }
}
示例#2
0
int avahi_caps_reduce(void) {
    int ret = 0;
    cap_t caps;
    static cap_value_t cap_values[] = { CAP_SYS_CHROOT, CAP_SETUID, CAP_SETGID };
    
    /* Let's reduce our caps to the minimum set and tell Linux to keep
     * them across setuid(). This is called before we drop
     * privileges. */
    
    caps = cap_init();
    assert(caps);
    cap_clear(caps);

    cap_set_flag(caps, CAP_EFFECTIVE, 3, cap_values, CAP_SET);
    cap_set_flag(caps, CAP_PERMITTED, 3, cap_values, CAP_SET);
    
    if (cap_set_proc(caps) < 0) {
        avahi_log_error("cap_set_proc() failed: %s", strerror(errno));
        ret = -1;
    }
    cap_free(caps);

    /* Retain capabilities across setuid() */
    if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
        avahi_log_error("prctl(PR_SET_KEEPCAPS) failed: %s", strerror(errno));
        ret = -1;
    }

    return ret;
}
示例#3
0
int avahi_caps_reduce2(void) {
    int ret = 0;
    cap_t caps;
    static cap_value_t cap_values[] = { CAP_SYS_CHROOT };

    /* Reduce our caps to the bare minimum and tell Linux not to keep
     * them across setuid(). This is called after we drop
     * privileges. */
    
    /* No longer retain caps across setuid() */
    if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) {
        avahi_log_error("prctl(PR_SET_KEEPCAPS) failed: %s", strerror(errno));
        ret = -1;
    }

    caps = cap_init();
    assert(caps);
    cap_clear(caps);

    /* setuid() zeroed our effective caps, let's get them back */
    cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_values, CAP_SET);
    cap_set_flag(caps, CAP_PERMITTED, 1, cap_values, CAP_SET);

    if (cap_set_proc(caps) < 0) {
        avahi_log_error("cap_set_proc() failed: %s", strerror(errno));
        ret = -1;
    }
    cap_free(caps);

    return ret;
}
示例#4
0
AvahiCache *avahi_cache_new(AvahiServer *server, AvahiInterface *iface) {
    AvahiCache *c;
    assert(server);

    if (!(c = avahi_new(AvahiCache, 1))) {
        avahi_log_error(__FILE__": Out of memory.");
        return NULL; /* OOM */
    }

    c->server = server;
    c->interface = iface;

    if (!(c->hashmap = avahi_hashmap_new((AvahiHashFunc) avahi_key_hash, (AvahiEqualFunc) avahi_key_equal, NULL, NULL))) {
        avahi_log_error(__FILE__": Out of memory.");
        avahi_free(c);
        return NULL; /* OOM */
    }

    AVAHI_LLIST_HEAD_INIT(AvahiCacheEntry, c->entries);
    c->n_entries = 0;

    c->last_rand_timestamp = 0;

    return c;
}
示例#5
0
AvahiNetlink *avahi_netlink_new(const AvahiPoll *poll_api, uint32_t groups, void (*cb) (AvahiNetlink *nl, struct nlmsghdr *n, void* userdata), void* userdata) {
    int fd = -1;
    struct sockaddr_nl addr;
    AvahiNetlink *nl = NULL;

    assert(poll_api);
    assert(cb);

    if ((fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
        avahi_log_error(__FILE__": socket(PF_NETLINK): %s", strerror(errno));
        return NULL;
    }
    
    memset(&addr, 0, sizeof(addr));
    addr.nl_family = AF_NETLINK;
    addr.nl_groups = groups;
    addr.nl_pid = getpid();

    if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        avahi_log_error(__FILE__": bind(): %s", strerror(errno));
        goto fail;
    }

    if (!(nl = avahi_new(AvahiNetlink, 1))) {
        avahi_log_error(__FILE__": avahi_new() failed.");
        goto fail;
    }

    nl->poll_api = poll_api;
    nl->fd = fd;
    nl->seq = 0;
    nl->callback = cb;
    nl->userdata = userdata;

    if (!(nl->buffer = avahi_new(uint8_t, nl->buffer_length = 64*1024))) {
        avahi_log_error(__FILE__": avahi_new() failed.");
        goto fail;
    }

    if (!(nl->watch = poll_api->watch_new(poll_api, fd, AVAHI_WATCH_IN, socket_event, nl))) {
        avahi_log_error(__FILE__": Failed to create watch.");
        goto fail;
    }
    
    return nl;

fail:

    if (fd >= 0)
        close(fd);

    if (nl) {
        avahi_free(nl->buffer);
        avahi_free(nl);
    }

    return NULL;
}
示例#6
0
void static_service_load(int in_chroot) {
    StaticServiceGroup *g, *n;
    glob_t globbuf;
    int globret;
    char **p;

    for (g = groups; g; g = n) {
        struct stat st;

        n = g->groups_next;

        if (stat(g->filename, &st) < 0) {

            if (errno == ENOENT)
                avahi_log_info("Service group file %s vanished, removing services.", g->filename);
            else
                avahi_log_warn("Failed to stat() file %s, ignoring: %s", g->filename, strerror(errno));

            static_service_group_free(g);
        } else if (st.st_mtime != g->mtime) {
            avahi_log_info("Service group file %s changed, reloading.", g->filename);

            if (static_service_group_load(g) < 0) {
                avahi_log_warn("Failed to load service group file %s, removing service.", g->filename);
                static_service_group_free(g);
            }
        }
    }

    memset(&globbuf, 0, sizeof(globbuf));

    if ((globret = glob(in_chroot ? "/services/*.service" : AVAHI_SERVICE_DIR "/*.service", GLOB_ERR, NULL, &globbuf)) != 0)

        switch (globret) {
#ifdef GLOB_NOSPACE
	    case GLOB_NOSPACE:
	        avahi_log_error("Not enough memory to read service directory "AVAHI_SERVICE_DIR".");
	        break;
#endif
#ifdef GLOB_NOMATCH
            case GLOB_NOMATCH:
	        avahi_log_info("No service file found in "AVAHI_SERVICE_DIR".");
	        break;
#endif
            default:
	        avahi_log_error("Failed to read "AVAHI_SERVICE_DIR".");
	        break;
        }

    else {
        for (p = globbuf.gl_pathv; *p; p++)
            load_file(*p);

        globfree(&globbuf);
    }
}
示例#7
0
static int make_runtime_dir(void) {
    int r = -1;
    mode_t u;
    int reset_umask = 0;
    struct passwd *pw;
    struct group * gr;
    struct stat st;

//Edison modify username 20131023
    char dut_user[128];
    memset(dut_user, 0, 128);
    
    strncpy(dut_user, nvram_safe_get("http_username"), 128);

    if (!(pw = getpwnam(dut_user))) {
	avahi_log_error( "Failed to find user '%s'.",dut_user);
        return -1;
    }

    if (!(gr = getgrnam(AVAHI_GROUP))) {
        avahi_log_error( "Failed to find group '"AVAHI_GROUP"'.");
        return -1;
    }

    u = umask(0000);
    reset_umask = 1;

    if (mkdir(AVAHI_DAEMON_RUNTIME_DIR, 0755) < 0 && errno != EEXIST) {
        avahi_log_error("mkdir(\""AVAHI_DAEMON_RUNTIME_DIR"\"): %s", strerror(errno));
        goto fail;
    }

    chown(AVAHI_DAEMON_RUNTIME_DIR, pw->pw_uid, gr->gr_gid);

    if (stat(AVAHI_DAEMON_RUNTIME_DIR, &st) < 0) {
        avahi_log_error("stat(): %s\n", strerror(errno));
        goto fail;
    }

    if (!S_ISDIR(st.st_mode) || st.st_uid != pw->pw_uid || st.st_gid != gr->gr_gid) {
        avahi_log_error("Failed to create runtime directory "AVAHI_DAEMON_RUNTIME_DIR".");
        goto fail;
    }

    r = 0;

fail:
    if (reset_umask)
        umask(u);
    return r;
}
示例#8
0
文件: main.c 项目: Dessperado/avahi
static AvahiSEntryGroup* add_dns_servers(AvahiServer *s, AvahiSEntryGroup* g, char **l) {
    char **p;

    assert(s);
    assert(l);

    if (!g)
        g = avahi_s_entry_group_new(s, NULL, NULL);

    assert(avahi_s_entry_group_is_empty(g));

    for (p = l; *p; p++) {
        AvahiAddress a;

        if (!avahi_address_parse(*p, AVAHI_PROTO_UNSPEC, &a))
            avahi_log_warn("Failed to parse address '%s', ignoring.", *p);
        else
            if (avahi_server_add_dns_server_address(s, g, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, NULL, AVAHI_DNS_SERVER_RESOLVE, &a, 53) < 0) {
                avahi_s_entry_group_free(g);
                avahi_log_error("Failed to add DNS server address: %s", avahi_strerror(avahi_server_errno(s)));
                return NULL;
            }
    }

    avahi_s_entry_group_commit(g);

    return g;
}
示例#9
0
static void new_announcer(AvahiServer *s, AvahiInterface *i, AvahiEntry *e) {
    AvahiAnnouncer *a;

    assert(s);
    assert(i);
    assert(e);
    assert(!e->dead);

    if (!avahi_interface_match(i, e->interface, e->protocol) || !i->announcing || !avahi_entry_is_commited(e))
        return;

    /* We don't want duplicate announcers */
    if (get_announcer(s, e, i))
        return;

    if ((!(a = avahi_new(AvahiAnnouncer, 1)))) {
        avahi_log_error(__FILE__": Out of memory.");
        return;
    }

    a->server = s;
    a->interface = i;
    a->entry = e;
    a->time_event = NULL;

    AVAHI_LLIST_PREPEND(AvahiAnnouncer, by_interface, i->announcers, a);
    AVAHI_LLIST_PREPEND(AvahiAnnouncer, by_entry, e->announcers, a);

    go_to_initial_state(a);
}
示例#10
0
void avahi_dbus_entry_group_callback(AvahiServer *s, AvahiSEntryGroup *g, AvahiEntryGroupState state, void* userdata) {
    EntryGroupInfo *i = userdata;
    DBusMessage *m;
    int32_t t;
    const char *e;

    assert(s);
    assert(g);
    assert(i);

    m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "StateChanged");

    if (!m) {
        avahi_log_error("Failed allocate message");
        return;
    }

    t = (int32_t) state;
    if (state == AVAHI_ENTRY_GROUP_FAILURE)
        e = avahi_error_number_to_dbus(avahi_server_errno(s));
    else if (state == AVAHI_ENTRY_GROUP_COLLISION)
        e = AVAHI_DBUS_ERR_COLLISION;
    else
        e = AVAHI_DBUS_ERR_OK;

    dbus_message_append_args(
        m,
        DBUS_TYPE_INT32, &t,
        DBUS_TYPE_STRING, &e,
        DBUS_TYPE_INVALID);
    dbus_message_set_destination(m, i->client->name);
    dbus_connection_send(server->bus, m, NULL);
    dbus_message_unref(m);
}
示例#11
0
static AvahiResponseJob* job_new(AvahiResponseScheduler *s, AvahiRecord *record, AvahiResponseJobState state) {
    AvahiResponseJob *rj;
    
    assert(s);
    assert(record);

    if (!(rj = avahi_new(AvahiResponseJob, 1))) {
        avahi_log_error(__FILE__": Out of memory");
        return NULL;
    }
    
    rj->scheduler = s;
    rj->record = avahi_record_ref(record);
    rj->time_event = NULL;
    rj->flush_cache = 0;
    rj->querier_valid = 0;
    
    if ((rj->state = state) == AVAHI_SCHEDULED) 
        AVAHI_LLIST_PREPEND(AvahiResponseJob, jobs, s->jobs, rj);
    else if (rj->state == AVAHI_DONE)
        AVAHI_LLIST_PREPEND(AvahiResponseJob, jobs, s->history, rj);
    else  /* rj->state == AVAHI_SUPPRESSED */
        AVAHI_LLIST_PREPEND(AvahiResponseJob, jobs, s->suppressed, rj);

    return rj;
}
示例#12
0
int avahi_netlink_work(AvahiNetlink *nl, int block) {
    ssize_t bytes;
    struct nlmsghdr *p;
    
    assert(nl);
    
    if ((bytes = recv(nl->fd, nl->buffer, nl->buffer_length, block ? 0 : MSG_DONTWAIT)) < 0) {
        
        if (errno == EAGAIN || errno == EINTR)
            return 0;
        
        avahi_log_error(__FILE__": recv() failed: %s", strerror(errno));
        return -1;
    }

    p = (struct nlmsghdr *) nl->buffer;
    
    assert(nl->callback);
    
    for (; bytes > 0; p = NLMSG_NEXT(p, bytes)) {
        if (!NLMSG_OK(p, (size_t) bytes)) {
            avahi_log_warn(__FILE__": packet truncated");
            return -1;
        }
        
        nl->callback(nl, p, nl->userdata);
    }
    
    return 0;
}
static void entry_group_callback(AvahiServer *s, AVAHI_GCC_UNUSED AvahiSEntryGroup *eg, AvahiEntryGroupState state, void* userdata) {
    StaticHost *h;

    assert(s);
    assert(eg);

    h = userdata;

    switch (state) {

        case AVAHI_ENTRY_GROUP_COLLISION:
            avahi_log_error("Host name conflict for \"%s\", not established.", h->host);
            break;

        case AVAHI_ENTRY_GROUP_ESTABLISHED:
            avahi_log_notice ("Static host name \"%s\" successfully established.", h->host);
            break;

        case AVAHI_ENTRY_GROUP_FAILURE:
            avahi_log_notice ("Failed to establish static host name \"%s\": %s.", h->host, avahi_strerror (avahi_server_errno (s)));
            break;
        
        case AVAHI_ENTRY_GROUP_UNCOMMITED:
        case AVAHI_ENTRY_GROUP_REGISTERING:
            ;
    }
}
示例#14
0
文件: main.c 项目: Dessperado/avahi
static int make_runtime_dir(void) {
    int r = -1;
    mode_t u;
    int reset_umask = 0;
    struct passwd *pw;
    struct group * gr;
    struct stat st;

    if (!(pw = getpwnam(AVAHI_USER))) {
        avahi_log_error( "Failed to find user '"AVAHI_USER"'.");
        goto fail;
    }

    if (!(gr = getgrnam(AVAHI_GROUP))) {
        avahi_log_error( "Failed to find group '"AVAHI_GROUP"'.");
        goto fail;
    }

    u = umask(0000);
    reset_umask = 1;

    if (mkdir(AVAHI_DAEMON_RUNTIME_DIR, 0755) < 0 && errno != EEXIST) {
        avahi_log_error("mkdir(\""AVAHI_DAEMON_RUNTIME_DIR"\"): %s", strerror(errno));
        goto fail;
    }

    chown(AVAHI_DAEMON_RUNTIME_DIR, pw->pw_uid, gr->gr_gid);

    if (stat(AVAHI_DAEMON_RUNTIME_DIR, &st) < 0) {
        avahi_log_error("stat(): %s\n", strerror(errno));
        goto fail;
    }

    if (!S_ISDIR(st.st_mode) || st.st_uid != pw->pw_uid || st.st_gid != gr->gr_gid) {
        avahi_log_error("Failed to create runtime directory "AVAHI_DAEMON_RUNTIME_DIR".");
        goto fail;
    }

    r = 0;

fail:
    if (reset_umask)
        umask(u);
    return r;
}
示例#15
0
文件: netlink.c 项目: anastiel/avahi
int avahi_netlink_work(AvahiNetlink *nl, int block) {
    ssize_t bytes;
    struct msghdr smsg;
    struct cmsghdr *cmsg;
    struct ucred *cred;
    struct iovec iov;
    struct nlmsghdr *p;
    char cred_msg[CMSG_SPACE(sizeof(struct ucred))];

    assert(nl);

    iov.iov_base = nl->buffer;
    iov.iov_len = nl->buffer_length;

    smsg.msg_name = NULL;
    smsg.msg_namelen = 0;
    smsg.msg_iov = &iov;
    smsg.msg_iovlen = 1;
    smsg.msg_control = cred_msg;
    smsg.msg_controllen = sizeof(cred_msg);
    smsg.msg_flags = (block ? 0 : MSG_DONTWAIT);

    if ((bytes = recvmsg(nl->fd, &smsg, 0)) < 0) {
        if (errno == EAGAIN || errno == EINTR)
            return 0;

        avahi_log_error(__FILE__": recvmsg() failed: %s", strerror(errno));
        return -1;
    }

    cmsg = CMSG_FIRSTHDR(&smsg);

    if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS) {
        avahi_log_warn("No sender credentials received, ignoring data.");
        return -1;
    }

    cred = (struct ucred*) CMSG_DATA(cmsg);

    if (cred->pid != 0)
        return -1;

    p = (struct nlmsghdr *) nl->buffer;

    assert(nl->callback);

    for (; bytes > 0; p = NLMSG_NEXT(p, bytes)) {
        if (!NLMSG_OK(p, (size_t) bytes)) {
            avahi_log_warn(__FILE__": packet truncated");
            return -1;
        }

        nl->callback(nl, p, nl->userdata);
    }

    return 0;
}
static void add_static_host_to_server(StaticHost *h)
{
    AvahiAddress a;
    int err;

    if (!h->group)
        h->group = avahi_s_entry_group_new (avahi_server, entry_group_callback, h);

    if (!avahi_address_parse (h->ip, AVAHI_PROTO_UNSPEC, &a)) {
        avahi_log_error("Static host name %s: avahi_address_parse failed", h->host);
        return;
    }

    if ((err = avahi_server_add_address(avahi_server, h->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, h->host, &a))) {
        avahi_log_error ("Static host name %s: avahi_server_add_address failure: %s", h->host, avahi_strerror(err));
        return;
    }

    avahi_s_entry_group_commit (h->group);
}
示例#17
0
AvahiWideAreaLookupEngine *avahi_wide_area_engine_new(AvahiServer *s) {
    AvahiWideAreaLookupEngine *e;
    
    assert(s);

    e = avahi_new(AvahiWideAreaLookupEngine, 1);
    e->server = s;
    e->cleanup_dead = 0;

    /* Create sockets */
    e->fd_ipv4 = s->config.use_ipv4 ? avahi_open_unicast_socket_ipv4() : -1;
    e->fd_ipv6 = s->config.use_ipv6 ? avahi_open_unicast_socket_ipv6() : -1;

    if (e->fd_ipv4 < 0 && e->fd_ipv6 < 0) {
        avahi_log_error(__FILE__": Failed to create wide area sockets: %s", strerror(errno));

        if (e->fd_ipv6 >= 0)
            close(e->fd_ipv6);

        if (e->fd_ipv4 >= 0)
            close(e->fd_ipv4);
        
        avahi_free(e);
        return NULL;
    }

    /* Create watches */

    e->watch_ipv4 = e->watch_ipv6 = NULL;
    
    if (e->fd_ipv4 >= 0)
        e->watch_ipv4 = s->poll_api->watch_new(e->server->poll_api, e->fd_ipv4, AVAHI_WATCH_IN, socket_event, e);
    if (e->fd_ipv6 >= 0)
        e->watch_ipv6 = s->poll_api->watch_new(e->server->poll_api, e->fd_ipv6, AVAHI_WATCH_IN, socket_event, e);

    e->n_dns_servers = e->current_dns_server = 0;
    e->next_id = (uint16_t) rand();

    /* Initialize cache */
    AVAHI_LLIST_HEAD_INIT(AvahiWideAreaCacheEntry, e->cache);
    e->cache_by_key = avahi_hashmap_new((AvahiHashFunc) avahi_key_hash, (AvahiEqualFunc) avahi_key_equal, (AvahiFreeFunc) avahi_key_unref, NULL);
    e->cache_n_entries = 0;

    /* Initialize lookup list */
    e->lookups_by_id = avahi_hashmap_new((AvahiHashFunc) avahi_int_hash, (AvahiEqualFunc) avahi_int_equal, NULL, NULL);
    e->lookups_by_key = avahi_hashmap_new((AvahiHashFunc) avahi_key_hash, (AvahiEqualFunc) avahi_key_equal, (AvahiFreeFunc) avahi_key_unref, NULL);
    AVAHI_LLIST_HEAD_INIT(AvahiWideAreaLookup, e->lookups);

    return e;
}
示例#18
0
static void server_work(AVAHI_GCC_UNUSED AvahiWatch *watch, int fd, AvahiWatchEvent events, void *userdata) {
    Server *s = userdata;

    assert(s);

    if (events & AVAHI_WATCH_IN) {
        int cfd;

        if ((cfd = accept(fd, NULL, NULL)) < 0)
            avahi_log_error("accept(): %s", strerror(errno));
        else
            client_new(s, cfd);
    }
}
示例#19
0
static void load_file(char *n) {
    StaticServiceGroup *g;
    assert(n);

    for (g = groups; g; g = g->groups_next)
        if (strcmp(g->filename, n) == 0)
            return;

    avahi_log_info("Loading service file %s.", n);

    g = static_service_group_new(n);
    if (static_service_group_load(g) < 0) {
        avahi_log_error("Failed to load service group file %s, ignoring.", g->filename);
        static_service_group_free(g);
    }
}
示例#20
0
文件: netlink.c 项目: anastiel/avahi
int avahi_netlink_send(AvahiNetlink *nl, struct nlmsghdr *m, unsigned *ret_seq) {
    assert(nl);
    assert(m);

    m->nlmsg_seq = nl->seq++;
    m->nlmsg_flags |= NLM_F_ACK;

    if (send(nl->fd, m, m->nlmsg_len, 0) < 0) {
        avahi_log_error(__FILE__": send(): %s", strerror(errno));
        return -1;
    }

    if (ret_seq)
        *ret_seq = m->nlmsg_seq;

    return 0;
}
示例#21
0
int avahi_caps_drop_all(void) {
    cap_t caps;
    int ret = 0;

    /* Drop all capabilities and turn ourselves into a normal user process */

    caps = cap_init();
    assert(caps);
    cap_clear(caps);
    
    if (cap_set_proc(caps) < 0) {
        avahi_log_error("cap_set_proc() failed: %s", strerror(errno));
        ret = -1;
    }
    cap_free(caps);
    
    return ret;
}
示例#22
0
AvahiProbeScheduler *avahi_probe_scheduler_new(AvahiInterface *i) {
    AvahiProbeScheduler *s;

    assert(i);

    if (!(s = avahi_new(AvahiProbeScheduler, 1))) {
        avahi_log_error(__FILE__": Out of memory");
        return NULL;
    }
        
    s->interface = i;
    s->time_event_queue = i->monitor->server->time_event_queue;

    AVAHI_LLIST_HEAD_INIT(AvahiProbeJob, s->jobs);
    AVAHI_LLIST_HEAD_INIT(AvahiProbeJob, s->history);
    
    return s;
}
示例#23
0
AvahiQueryScheduler *avahi_query_scheduler_new(AvahiInterface *i) {
    AvahiQueryScheduler *s;
    assert(i);

    if (!(s = avahi_new(AvahiQueryScheduler, 1))) {
        avahi_log_error(__FILE__": Out of memory");
        return NULL; /* OOM */
    }

    s->interface = i;
    s->time_event_queue = i->monitor->server->time_event_queue;
    s->next_id = 0;

    AVAHI_LLIST_HEAD_INIT(AvahiQueryJob, s->jobs);
    AVAHI_LLIST_HEAD_INIT(AvahiQueryJob, s->history);
    AVAHI_LLIST_HEAD_INIT(AvahiKnownAnswer, s->known_answers);

    return s;
}
示例#24
0
文件: main.c 项目: JDsolution/ipnc
static void signal_callback(AvahiWatch *watch, AVAHI_GCC_UNUSED int fd, AVAHI_GCC_UNUSED AvahiWatchEvent event, AVAHI_GCC_UNUSED void *userdata) {
    int sig;
    const AvahiPoll *poll_api;

    assert(watch);
    assert(simple_poll_api);

    poll_api = avahi_simple_poll_get(simple_poll_api);

    if ((sig = daemon_signal_next()) <= 0) {
        avahi_log_error("daemon_signal_next() failed");
        poll_api->watch_free(watch);
        return;
    }

    switch (sig) {
        case SIGINT:
        case SIGQUIT:
        case SIGTERM:
            avahi_log_info(
                    "Got %s, quitting.",
                    sig == SIGINT ? "SIGINT" :
                    (sig == SIGQUIT ? "SIGQUIT" : "SIGTERM"));
            avahi_simple_poll_quit(simple_poll_api);
            break;

        case SIGHUP:
            avahi_log_info("Got SIGHUP, reloading.");

            reload_config();
            break;

        case SIGUSR1:
            avahi_log_info("Got SIGUSR1, dumping record data.");
            avahi_server_dump(avahi_server, dump, NULL);
            break;

        default:
            avahi_log_warn("Got spurious signal, ignoring.");
            break;
    }
}
示例#25
0
文件: main.c 项目: Dessperado/avahi
static void kqueue_callback(AvahiWatch *watch, int fd, AVAHI_GCC_UNUSED AvahiWatchEvent event, AVAHI_GCC_UNUSED void *userdata) {
    struct kevent ev;
    struct timespec nullts = { 0, 0 };
    int res;

    assert(fd == kq);
    assert(watch);

    res = kevent(kq, NULL, 0, &ev, 1, &nullts);

    if (res > 0) {
        /* Sleep for a half-second to avoid potential races
         * during install/uninstall. */
        usleep(500000);
        avahi_log_info("Files changed, reloading.");
        reload_config();
    } else {
        avahi_log_error("Failed to read kqueue event: %s", avahi_strerror(errno));
    }
}
示例#26
0
文件: main.c 项目: Dessperado/avahi
static void inotify_callback(AvahiWatch *watch, int fd, AVAHI_GCC_UNUSED AvahiWatchEvent event, AVAHI_GCC_UNUSED void *userdata) {
    char* buffer;
    int n = 0;

    assert(fd == inotify_fd);
    assert(watch);

    ioctl(inotify_fd, FIONREAD, &n);
    if (n <= 0)
        n = 128;

    buffer = avahi_malloc(n);
    if (read(inotify_fd, buffer, n) < 0 ) {
        avahi_free(buffer);
        avahi_log_error("Failed to read inotify event: %s", avahi_strerror(errno));
        return;
    }
    avahi_free(buffer);

    avahi_log_info("Files changed, reloading.");
    reload_config();
}
示例#27
0
static void* known_answer_walk_callback(AvahiCache *c, AvahiKey *pattern, AvahiCacheEntry *e, void* userdata) {
    AvahiQueryScheduler *s = userdata;
    AvahiKnownAnswer *ka;

    assert(c);
    assert(pattern);
    assert(e);
    assert(s);

    if (avahi_cache_entry_half_ttl(c, e))
        return NULL;

    if (!(ka = avahi_new0(AvahiKnownAnswer, 1))) {
        avahi_log_error(__FILE__": Out of memory");
        return NULL;
    }

    ka->scheduler = s;
    ka->record = avahi_record_ref(e->record);

    AVAHI_LLIST_PREPEND(AvahiKnownAnswer, known_answer, s->known_answers, ka);
    return NULL;
}
示例#28
0
static AvahiProbeJob* job_new(AvahiProbeScheduler *s, AvahiRecord *record, int done) {
    AvahiProbeJob *pj;
    
    assert(s);
    assert(record);

    if (!(pj = avahi_new(AvahiProbeJob, 1))) {
        avahi_log_error(__FILE__": Out of memory");
        return NULL; /* OOM */
    }
    
    pj->scheduler = s;
    pj->record = avahi_record_ref(record);
    pj->time_event = NULL;
    pj->chosen = 0;

    if ((pj->done = done))
        AVAHI_LLIST_PREPEND(AvahiProbeJob, jobs, s->history, pj);
    else
        AVAHI_LLIST_PREPEND(AvahiProbeJob, jobs, s->jobs, pj);

    return pj;
}
示例#29
0
static AvahiQueryJob* job_new(AvahiQueryScheduler *s, AvahiKey *key, int done) {
    AvahiQueryJob *qj;

    assert(s);
    assert(key);

    if (!(qj = avahi_new(AvahiQueryJob, 1))) {
        avahi_log_error(__FILE__": Out of memory");
        return NULL;
    }

    qj->scheduler = s;
    qj->key = avahi_key_ref(key);
    qj->time_event = NULL;
    qj->n_posted = 1;
    qj->id = s->next_id++;

    if ((qj->done = done))
        AVAHI_LLIST_PREPEND(AvahiQueryJob, jobs, s->history, qj);
    else
        AVAHI_LLIST_PREPEND(AvahiQueryJob, jobs, s->jobs, qj);

    return qj;
}
示例#30
0
文件: main.c 项目: Dessperado/avahi
static int load_config_file(DaemonConfig *c) {
    int r = -1;
    AvahiIniFile *f;
    AvahiIniFileGroup *g;

    assert(c);

    if (!(f = avahi_ini_file_load(c->config_file ? c->config_file : AVAHI_CONFIG_FILE)))
        goto finish;

    for (g = f->groups; g; g = g->groups_next) {

        if (strcasecmp(g->name, "server") == 0) {
            AvahiIniFilePair *p;

            for (p = g->pairs; p; p = p->pairs_next) {

                if (strcasecmp(p->key, "host-name") == 0) {
                    avahi_free(c->server_config.host_name);
                    c->server_config.host_name = avahi_strdup(p->value);
                } else if (strcasecmp(p->key, "domain-name") == 0) {
                    avahi_free(c->server_config.domain_name);
                    c->server_config.domain_name = avahi_strdup(p->value);
                } else if (strcasecmp(p->key, "browse-domains") == 0) {
                    char **e, **t;

                    e = avahi_split_csv(p->value);

                    for (t = e; *t; t++) {
                        char cleaned[AVAHI_DOMAIN_NAME_MAX];

                        if (!avahi_normalize_name(*t, cleaned, sizeof(cleaned))) {
                            avahi_log_error("Invalid domain name \"%s\" for key \"%s\" in group \"%s\"\n", *t, p->key, g->name);
                            avahi_strfreev(e);
                            goto finish;
                        }

                        c->server_config.browse_domains = avahi_string_list_add(c->server_config.browse_domains, cleaned);
                    }

                    avahi_strfreev(e);

                    c->server_config.browse_domains = filter_duplicate_domains(c->server_config.browse_domains);
                } else if (strcasecmp(p->key, "use-ipv4") == 0)
                    c->server_config.use_ipv4 = is_yes(p->value);
                else if (strcasecmp(p->key, "use-ipv6") == 0)
                    c->server_config.use_ipv6 = is_yes(p->value);
                else if (strcasecmp(p->key, "check-response-ttl") == 0)
                    c->server_config.check_response_ttl = is_yes(p->value);
                else if (strcasecmp(p->key, "allow-point-to-point") == 0)
                    c->server_config.allow_point_to_point = is_yes(p->value);
                else if (strcasecmp(p->key, "use-iff-running") == 0)
                    c->server_config.use_iff_running = is_yes(p->value);
                else if (strcasecmp(p->key, "disallow-other-stacks") == 0)
                    c->server_config.disallow_other_stacks = is_yes(p->value);
                else if (strcasecmp(p->key, "host-name-from-machine-id") == 0) {
                    if (*(p->value) == 'y' || *(p->value) == 'Y') {
                        char *machine_id = get_machine_id();
                        if (machine_id != NULL) {
                            avahi_free(c->server_config.host_name);
                            c->server_config.host_name = machine_id;
                        }
                    }
                }
#ifdef HAVE_DBUS
                else if (strcasecmp(p->key, "enable-dbus") == 0) {

                    if (*(p->value) == 'w' || *(p->value) == 'W') {
                        c->fail_on_missing_dbus = 0;
                        c->enable_dbus = 1;
                    } else if (*(p->value) == 'y' || *(p->value) == 'Y') {
                        c->fail_on_missing_dbus = 1;
                        c->enable_dbus = 1;
                    } else {
                        c->enable_dbus = 0;
                    }
                }
#endif
                else if (strcasecmp(p->key, "allow-interfaces") == 0) {
                    char **e, **t;

                    avahi_string_list_free(c->server_config.allow_interfaces);
                    c->server_config.allow_interfaces = NULL;
                    e = avahi_split_csv(p->value);

                    for (t = e; *t; t++)
                        c->server_config.allow_interfaces = avahi_string_list_add(c->server_config.allow_interfaces, *t);

                    avahi_strfreev(e);
                } else if (strcasecmp(p->key, "deny-interfaces") == 0) {
                    char **e, **t;

                    avahi_string_list_free(c->server_config.deny_interfaces);
                    c->server_config.deny_interfaces = NULL;
                    e = avahi_split_csv(p->value);

                    for (t = e; *t; t++)
                        c->server_config.deny_interfaces = avahi_string_list_add(c->server_config.deny_interfaces, *t);

                    avahi_strfreev(e);
                } else if (strcasecmp(p->key, "ratelimit-interval-usec") == 0) {
                    AvahiUsec k;

                    if (parse_usec(p->value, &k) < 0) {
                        avahi_log_error("Invalid ratelimit-interval-usec setting %s", p->value);
                        goto finish;
                    }

                    c->server_config.ratelimit_interval = k;

                } else if (strcasecmp(p->key, "ratelimit-burst") == 0) {
                    unsigned k;

                    if (parse_unsigned(p->value, &k) < 0) {
                        avahi_log_error("Invalid ratelimit-burst setting %s", p->value);
                        goto finish;
                    }

                    c->server_config.ratelimit_burst = k;

                } else if (strcasecmp(p->key, "cache-entries-max") == 0) {
                    unsigned k;

                    if (parse_unsigned(p->value, &k) < 0) {
                        avahi_log_error("Invalid cache-entries-max setting %s", p->value);
                        goto finish;
                    }

                    c->server_config.n_cache_entries_max = k;
#ifdef HAVE_DBUS
                } else if (strcasecmp(p->key, "clients-max") == 0) {
                    unsigned k;

                    if (parse_unsigned(p->value, &k) < 0) {
                        avahi_log_error("Invalid clients-max setting %s", p->value);
                        goto finish;
                    }

                    c->n_clients_max = k;
                } else if (strcasecmp(p->key, "objects-per-client-max") == 0) {
                    unsigned k;

                    if (parse_unsigned(p->value, &k) < 0) {
                        avahi_log_error("Invalid objects-per-client-max setting %s", p->value);
                        goto finish;
                    }

                    c->n_objects_per_client_max = k;
                } else if (strcasecmp(p->key, "entries-per-entry-group-max") == 0) {
                    unsigned k;

                    if (parse_unsigned(p->value, &k) < 0) {
                        avahi_log_error("Invalid entries-per-entry-group-max setting %s", p->value);
                        goto finish;
                    }

                    c->n_entries_per_entry_group_max = k;
#endif
                } else {
                    avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name);
                    goto finish;
                }
            }

        } else if (strcasecmp(g->name, "publish") == 0) {
            AvahiIniFilePair *p;

            for (p = g->pairs; p; p = p->pairs_next) {

                if (strcasecmp(p->key, "publish-addresses") == 0)
                    c->server_config.publish_addresses = is_yes(p->value);
                else if (strcasecmp(p->key, "publish-hinfo") == 0)
                    c->server_config.publish_hinfo = is_yes(p->value);
                else if (strcasecmp(p->key, "publish-workstation") == 0)
                    c->server_config.publish_workstation = is_yes(p->value);
                else if (strcasecmp(p->key, "publish-domain") == 0)
                    c->server_config.publish_domain = is_yes(p->value);
                else if (strcasecmp(p->key, "publish-resolv-conf-dns-servers") == 0)
                    c->publish_resolv_conf = is_yes(p->value);
                else if (strcasecmp(p->key, "disable-publishing") == 0)
                    c->server_config.disable_publishing = is_yes(p->value);
                else if (strcasecmp(p->key, "disable-user-service-publishing") == 0)
                    c->disable_user_service_publishing = is_yes(p->value);
                else if (strcasecmp(p->key, "add-service-cookie") == 0)
                    c->server_config.add_service_cookie = is_yes(p->value);
                else if (strcasecmp(p->key, "publish-dns-servers") == 0) {
                    avahi_strfreev(c->publish_dns_servers);
                    c->publish_dns_servers = avahi_split_csv(p->value);
                } else if (strcasecmp(p->key, "publish-a-on-ipv6") == 0)
                    c->server_config.publish_a_on_ipv6 = is_yes(p->value);
                else if (strcasecmp(p->key, "publish-aaaa-on-ipv4") == 0)
                    c->server_config.publish_aaaa_on_ipv4 = is_yes(p->value);
                else {
                    avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name);
                    goto finish;
                }
            }

        } else if (strcasecmp(g->name, "wide-area") == 0) {
            AvahiIniFilePair *p;

            for (p = g->pairs; p; p = p->pairs_next) {

                if (strcasecmp(p->key, "enable-wide-area") == 0)
                    c->server_config.enable_wide_area = is_yes(p->value);
                else {
                    avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name);
                    goto finish;
                }
            }

        } else if (strcasecmp(g->name, "reflector") == 0) {
            AvahiIniFilePair *p;

            for (p = g->pairs; p; p = p->pairs_next) {

                if (strcasecmp(p->key, "enable-reflector") == 0)
                    c->server_config.enable_reflector = is_yes(p->value);
                else if (strcasecmp(p->key, "reflect-ipv") == 0)
                    c->server_config.reflect_ipv = is_yes(p->value);
                else {
                    avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name);
                    goto finish;
                }
            }

        } else if (strcasecmp(g->name, "rlimits") == 0) {
            AvahiIniFilePair *p;

            for (p = g->pairs; p; p = p->pairs_next) {

                if (strcasecmp(p->key, "rlimit-as") == 0) {
                    c->rlimit_as_set = 1;
                    c->rlimit_as = atoi(p->value);
                } else if (strcasecmp(p->key, "rlimit-core") == 0) {
                    c->rlimit_core_set = 1;
                    c->rlimit_core = atoi(p->value);
                } else if (strcasecmp(p->key, "rlimit-data") == 0) {
                    c->rlimit_data_set = 1;
                    c->rlimit_data = atoi(p->value);
                } else if (strcasecmp(p->key, "rlimit-fsize") == 0) {
                    c->rlimit_fsize_set = 1;
                    c->rlimit_fsize = atoi(p->value);
                } else if (strcasecmp(p->key, "rlimit-nofile") == 0) {
                    c->rlimit_nofile_set = 1;
                    c->rlimit_nofile = atoi(p->value);
                } else if (strcasecmp(p->key, "rlimit-stack") == 0) {
                    c->rlimit_stack_set = 1;
                    c->rlimit_stack = atoi(p->value);
                } else if (strcasecmp(p->key, "rlimit-nproc") == 0) {
#ifdef RLIMIT_NPROC
                    c->rlimit_nproc_set = 1;
                    c->rlimit_nproc = atoi(p->value);
#else
                    avahi_log_error("Ignoring configuration key \"%s\" in group \"%s\"\n", p->key, g->name);
#endif
                } else {
                    avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name);
                    goto finish;
                }

            }

        } else {
            avahi_log_error("Invalid configuration file group \"%s\".\n", g->name);
            goto finish;
        }
    }

    r = 0;

finish:

    if (f)
        avahi_ini_file_free(f);

    return r;
}