예제 #1
0
static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) {
        JournalRateLimitGroup *g;
        struct siphash state;

        assert(r);
        assert(id);

        g = new0(JournalRateLimitGroup, 1);
        if (!g)
                return NULL;

        g->id = strdup(id);
        if (!g->id)
                goto fail;

        siphash24_init(&state, r->hash_key);
        string_hash_func(g->id, &state);
        g->hash = siphash24_finalize(&state);

        journal_rate_limit_vacuum(r, ts);

        LIST_PREPEND(bucket, r->buckets[g->hash % BUCKETS_MAX], g);
        LIST_PREPEND(lru, r->lru, g);
        if (!g->lru_next)
                r->lru_tail = g;
        r->n_groups++;

        g->parent = r;
        return g;

fail:
        journal_rate_limit_group_free(g);
        return NULL;
}
예제 #2
0
파일: bus-slot.c 프로젝트: clemensg/systemd
sd_bus_slot *bus_slot_allocate(
                sd_bus *bus,
                bool floating,
                BusSlotType type,
                size_t extra,
                void *userdata) {

        sd_bus_slot *slot;

        assert(bus);

        slot = malloc0(offsetof(sd_bus_slot, reply_callback) + extra);
        if (!slot)
                return NULL;

        slot->n_ref = 1;
        slot->type = type;
        slot->bus = bus;
        slot->floating = floating;
        slot->userdata = userdata;

        if (!floating)
                sd_bus_ref(bus);

        LIST_PREPEND(slots, bus->slots, slot);

        return slot;
}
예제 #3
0
int address_new_static(Network *network, unsigned section, Address **ret) {
    _cleanup_address_free_ Address *address = NULL;

    if (section) {
        uint64_t key = section;
        address = hashmap_get(network->addresses_by_section, &key);
        if (address) {
            *ret = address;
            address = NULL;

            return 0;
        }
    }

    address = new0(Address, 1);
    if (!address)
        return -ENOMEM;

    address->family = AF_UNSPEC;

    address->network = network;

    LIST_PREPEND(static_addresses, network->static_addresses, address);

    if (section) {
        address->section = section;
        hashmap_put(network->addresses_by_section, &address->section, address);
    }

    *ret = address;
    address = NULL;

    return 0;
}
예제 #4
0
파일: device.c 프로젝트: aulanov/systemd
static int device_set_sysfs(Device *d, const char *sysfs) {
        Device *first;
        char *copy;
        int r;

        assert(d);

        if (streq_ptr(d->sysfs, sysfs))
                return 0;

        r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &string_hash_ops);
        if (r < 0)
                return r;

        copy = strdup(sysfs);
        if (!copy)
                return -ENOMEM;

        device_unset_sysfs(d);

        first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
        LIST_PREPEND(same_sysfs, first, d);

        r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
        if (r < 0) {
                LIST_REMOVE(same_sysfs, first, d);
                free(copy);
                return r;
        }

        d->sysfs = copy;

        return 0;
}
예제 #5
0
int route_new_static(Network *network, unsigned section, Route **ret) {
        _cleanup_route_free_ Route *route = NULL;
        int r;

        if (section) {
                route = hashmap_get(network->routes_by_section,
                                    UINT_TO_PTR(section));
                if (route) {
                        *ret = route;
                        route = NULL;

                        return 0;
                }
        }

        r = route_new(&route);
        if (r < 0)
                return r;

        route->protocol = RTPROT_STATIC;
        route->network = network;

        LIST_PREPEND(routes, network->static_routes, route);

        if (section) {
                route->section = section;
                hashmap_put(network->routes_by_section,
                            UINT_TO_PTR(route->section), route);
        }

        *ret = route;
        route = NULL;

        return 0;
}
예제 #6
0
파일: grdev.c 프로젝트: blueyed/systemd
static void tile_link(grdev_tile *tile, grdev_tile *parent) {
        grdev_display *display;
        grdev_tile *t;

        assert(tile);
        assert(!tile->parent);
        assert(!tile->display);
        assert(parent);
        assert(parent->type == GRDEV_TILE_NODE);

        display = parent->display;

        assert(!display || !display->enabled);

        ++parent->node.n_children;
        LIST_PREPEND(children_by_node, parent->node.child_list, tile);
        tile->parent = parent;

        if (display) {
                display->modified = true;
                TILE_FOREACH(tile, t) {
                        t->display = display;
                        if (t->type == GRDEV_TILE_LEAF) {
                                ++display->n_leafs;
                                if (display->enabled)
                                        pipe_enable(t->leaf.pipe);
                        }
                }
        }
예제 #7
0
파일: bus-track.c 프로젝트: Werkov/systemd
_public_ int sd_bus_track_new(
                sd_bus *bus,
                sd_bus_track **track,
                sd_bus_track_handler_t handler,
                void *userdata) {

        sd_bus_track *t;

        assert_return(bus, -EINVAL);
        assert_return(bus = bus_resolve(bus), -ENOPKG);
        assert_return(track, -EINVAL);

        if (!bus->bus_client)
                return -EINVAL;

        t = new0(sd_bus_track, 1);
        if (!t)
                return -ENOMEM;

        t->n_ref = 1;
        t->handler = handler;
        t->userdata = userdata;
        t->bus = sd_bus_ref(bus);

        LIST_PREPEND(tracks, bus->tracks, t);
        t->in_list = true;

        bus_track_add_to_queue(t);

        *track = t;
        return 0;
}
예제 #8
0
int route_new_static(Network *network, unsigned section, Route **ret) {
        _cleanup_route_free_ Route *route = NULL;

        if (section) {
                uint64_t key = section;

                route = hashmap_get(network->routes_by_section, &key);
                if (route) {
                        *ret = route;
                        route = NULL;

                        return 0;
                }
        }

        route = new0(Route, 1);
        if (!route)
                return -ENOMEM;

        route->family = AF_UNSPEC;

        route->network = network;

        LIST_PREPEND(static_routes, network->static_routes, route);

        if (section) {
                route->section = section;
                hashmap_put(network->routes_by_section, &route->section, route);
        }

        *ret = route;
        route = NULL;

        return 0;
}
예제 #9
0
파일: bus-track.c 프로젝트: Werkov/systemd
static void bus_track_add_to_queue(sd_bus_track *track) {
        assert(track);

        /* Adds the bus track object to the queue of objects we should dispatch next, subject to a number of
         * conditions. */

        /* Already in the queue? */
        if (track->in_queue)
                return;

        /* if we are currently in the process of adding a new name, then let's not enqueue this just yet, let's wait
         * until the addition is complete. */
        if (track->n_adding > 0)
                return;

        /* still referenced? */
        if (hashmap_size(track->names) > 0)
                return;

        /* Nothing to call? */
        if (!track->handler)
                return;

        /* Already closed? */
        if (!track->in_list)
                return;

        LIST_PREPEND(queue, track->bus->track_queue, track);
        track->in_queue = true;
}
예제 #10
0
파일: umount.c 프로젝트: nazgul77/systemd
static int loopback_list_get(MountPoint **head) {
        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
        struct udev_list_entry *item = NULL, *first = NULL;
        _cleanup_udev_unref_ struct udev *udev = NULL;
        int r;

        assert(head);

        udev = udev_new();
        if (!udev)
                return -ENOMEM;

        e = udev_enumerate_new(udev);
        if (!e)
                return -ENOMEM;

        r = udev_enumerate_add_match_subsystem(e, "block");
        if (r < 0)
                return r;

        r = udev_enumerate_add_match_sysname(e, "loop*");
        if (r < 0)
                return r;

        r = udev_enumerate_add_match_sysattr(e, "loop/backing_file", NULL);
        if (r < 0)
                return r;

        r = udev_enumerate_scan_devices(e);
        if (r < 0)
                return r;

        first = udev_enumerate_get_list_entry(e);
        udev_list_entry_foreach(item, first) {
                MountPoint *lb;
                _cleanup_udev_device_unref_ struct udev_device *d;
                char *loop;
                const char *dn;

                d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                if (!d)
                        return -ENOMEM;

                dn = udev_device_get_devnode(d);
                if (!dn)
                        continue;

                loop = strdup(dn);
                if (!loop)
                        return -ENOMEM;

                lb = new0(MountPoint, 1);
                if (!lb) {
                        free(loop);
                        return -ENOMEM;
                }

                lb->path = loop;
                LIST_PREPEND(mount_point, *head, lb);
        }
예제 #11
0
파일: umount.c 프로젝트: nazgul77/systemd
static int swap_list_get(MountPoint **head) {
        _cleanup_fclose_ FILE *proc_swaps = NULL;
        unsigned int i;
        int r;

        assert(head);

        proc_swaps = fopen("/proc/swaps", "re");
        if (!proc_swaps)
                return (errno == ENOENT) ? 0 : -errno;

        (void) fscanf(proc_swaps, "%*s %*s %*s %*s %*s\n");

        for (i = 2;; i++) {
                MountPoint *swap;
                char *dev = NULL, *d;
                int k;

                k = fscanf(proc_swaps,
                           "%ms " /* device/file */
                           "%*s " /* type of swap */
                           "%*s " /* swap size */
                           "%*s " /* used */
                           "%*s\n", /* priority */
                           &dev);

                if (k != 1) {
                        if (k == EOF)
                                break;

                        log_warning("Failed to parse /proc/swaps:%u.", i);
                        free(dev);
                        continue;
                }

                if (endswith(dev, " (deleted)")) {
                        free(dev);
                        continue;
                }

                r = cunescape(dev, UNESCAPE_RELAX, &d);
                free(dev);
                if (r < 0)
                        return r;

                swap = new0(MountPoint, 1);
                if (!swap) {
                        free(d);
                        return -ENOMEM;
                }

                swap->path = d;
                LIST_PREPEND(mount_point, *head, swap);
        }

        return 0;
}
예제 #12
0
/* create a new FDB entry or get an existing one. */
int fdb_entry_new_static(
                Network *network,
                unsigned section,
                FdbEntry **ret) {

        _cleanup_fdbentry_free_ FdbEntry *fdb_entry = NULL;
        struct ether_addr *mac_addr = NULL;

        assert(network);
        assert(ret);

        /* search entry in hashmap first. */
        if (section) {
                fdb_entry = hashmap_get(network->fdb_entries_by_section, UINT_TO_PTR(section));
                if (fdb_entry) {
                        *ret = fdb_entry;
                        fdb_entry = NULL;

                        return 0;
                }
        }

        if (network->n_static_fdb_entries >= STATIC_FDB_ENTRIES_PER_NETWORK_MAX)
                return -E2BIG;

        /* allocate space for MAC address. */
        mac_addr = new0(struct ether_addr, 1);
        if (!mac_addr)
                return -ENOMEM;

        /* allocate space for and FDB entry. */
        fdb_entry = new0(FdbEntry, 1);
        if (!fdb_entry) {
                /* free previously allocated space for mac_addr. */
                free(mac_addr);
                return -ENOMEM;
        }

        /* init FDB structure. */
        fdb_entry->network = network;
        fdb_entry->mac_addr = mac_addr;

        LIST_PREPEND(static_fdb_entries, network->static_fdb_entries, fdb_entry);
        network->n_static_fdb_entries++;

        if (section) {
                fdb_entry->section = section;
                hashmap_put(network->fdb_entries_by_section,
                            UINT_TO_PTR(fdb_entry->section), fdb_entry);
        }

        /* return allocated FDB structure. */
        *ret = fdb_entry;
        fdb_entry = NULL;

        return 0;
}
예제 #13
0
int operation_new(Manager *manager, Machine *machine, pid_t child, sd_bus_message *message, int errno_fd, Operation **ret) {
        Operation *o;
        int r;

        assert(manager);
        assert(child > 1);
        assert(message);
        assert(errno_fd >= 0);

        o = new0(Operation, 1);
        if (!o)
                return -ENOMEM;

        o->extra_fd = -1;

        r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
        if (r < 0) {
                free(o);
                return r;
        }

        o->pid = child;
        o->message = sd_bus_message_ref(message);
        o->errno_fd = errno_fd;

        LIST_PREPEND(operations, manager->operations, o);
        manager->n_operations++;
        o->manager = manager;

        if (machine) {
                LIST_PREPEND(operations_by_machine, machine->operations, o);
                o->machine = machine;
        }

        log_debug("Started new operation " PID_FMT ".", child);

        /* At this point we took ownership of both the child and the errno file descriptor! */

        if (ret)
                *ret = o;

        return 0;
}
예제 #14
0
static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
        _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
        sd_id128_t id;
        int r;

        assert(s);
        assert(fd >= 0);

        r = sd_id128_randomize(&id);
        if (r < 0)
                return log_error_errno(r, "Failed to generate stream ID: %m");

        stream = new0(StdoutStream, 1);
        if (!stream)
                return log_oom();

        stream->fd = -1;
        stream->priority = LOG_INFO;

        xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id));

        r = getpeercred(fd, &stream->ucred);
        if (r < 0)
                return log_error_errno(r, "Failed to determine peer credentials: %m");

        if (mac_selinux_use()) {
                r = getpeersec(fd, &stream->label);
                if (r < 0 && r != -EOPNOTSUPP)
                        (void) log_warning_errno(r, "Failed to determine peer security context: %m");
        }

        (void) shutdown(fd, SHUT_WR);

        r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
        if (r < 0)
                return log_error_errno(r, "Failed to add stream to event loop: %m");

        r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
        if (r < 0)
                return log_error_errno(r, "Failed to adjust stdout event source priority: %m");

        stream->fd = fd;

        stream->server = s;
        LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
        s->n_stdout_streams++;

        if (ret)
                *ret = stream;

        stream = NULL;

        return 0;
}
예제 #15
0
static int load_link(link_config_ctx *ctx, const char *filename) {
        _cleanup_(link_config_freep) link_config *link = NULL;
        _cleanup_fclose_ FILE *file = NULL;
        int r;

        assert(ctx);
        assert(filename);

        file = fopen(filename, "re");
        if (!file) {
                if (errno == ENOENT)
                        return 0;
                else
                        return -errno;
        }

        if (null_or_empty_fd(fileno(file))) {
                log_debug("Skipping empty file: %s", filename);
                return 0;
        }

        link = new0(link_config, 1);
        if (!link)
                return log_oom();

        link->mac_policy = _MACPOLICY_INVALID;
        link->wol = _WOL_INVALID;
        link->duplex = _DUP_INVALID;
        link->port = _NET_DEV_PORT_INVALID;
        link->autonegotiation = -1;

        memset(&link->features, 0xFF, sizeof(link->features));

        r = config_parse(NULL, filename, file,
                         "Match\0Link\0Ethernet\0",
                         config_item_perf_lookup, link_config_gperf_lookup,
                         CONFIG_PARSE_WARN, link);
        if (r < 0)
                return r;
        else
                log_debug("Parsed configuration file %s", filename);

        if (link->speed > UINT_MAX)
                return -ERANGE;

        link->filename = strdup(filename);
        if (!link->filename)
                return log_oom();

        LIST_PREPEND(links, ctx->links, link);
        link = NULL;

        return 0;
}
예제 #16
0
static void bus_track_add_to_queue(sd_bus_track *track) {
        assert(track);

        if (track->in_queue)
                return;

        if (!track->handler)
                return;

        LIST_PREPEND(queue, track->bus->track_queue, track);
        track->in_queue = true;
}
예제 #17
0
int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret) {
        _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
        _cleanup_route_free_ Route *route = NULL;
        int r;

        assert(network);
        assert(ret);
        assert(!!filename == (section_line > 0));

        if (filename) {
                r = network_config_section_new(filename, section_line, &n);
                if (r < 0)
                        return r;

                route = hashmap_get(network->routes_by_section, n);
                if (route) {
                        *ret = route;
                        route = NULL;

                        return 0;
                }
        }

        if (network->n_static_routes >= routes_max())
                return -E2BIG;

        r = route_new(&route);
        if (r < 0)
                return r;

        route->protocol = RTPROT_STATIC;

        if (filename) {
                route->section = n;
                n = NULL;

                r = hashmap_put(network->routes_by_section, route->section, route);
                if (r < 0)
                        return r;
        }

        route->network = network;
        LIST_PREPEND(routes, network->static_routes, route);
        network->n_static_routes++;

        *ret = route;
        route = NULL;

        return 0;
}
예제 #18
0
void device_attach(Device *d, Seat *s) {
        assert(d);
        assert(s);

        if (d->seat == s)
                return;

        if (d->seat)
                device_detach(d);

        d->seat = s;
        LIST_PREPEND(Device, devices, s->devices, d);

        seat_send_changed(s, "CanGraphical\0");
}
예제 #19
0
파일: iclass.c 프로젝트: burzumishi/e16
static ImageClass  *
ImageclassCreate(const char *name)
{
   ImageClass         *ic;

   ic = ECALLOC(ImageClass, 1);
   if (!ic)
      return NULL;

   LIST_PREPEND(ImageClass, &iclass_list, ic);

   ic->name = Estrdup(name);

   return ic;
}
static int load_link(link_config_ctx *ctx, const char *filename) {
        _cleanup_(link_config_freep) link_config *link = NULL;
        _cleanup_fclose_ FILE *file = NULL;
        int r;

        assert(ctx);
        assert(filename);

        file = fopen(filename, "re");
        if (!file) {
                if (errno == ENOENT)
                        return 0;
                else
                        return -errno;
        }

        if (null_or_empty_fd(fileno(file))) {
                log_debug("Skipping empty file: %s", filename);
                return 0;
        }

        link = new0(link_config, 1);
        if (!link)
                return log_oom();

        link->mac_policy = _MACPOLICY_INVALID;
        link->wol = _WOL_INVALID;
        link->duplex = _DUP_INVALID;

        r = config_parse(NULL, filename, file,
                         "Match\0Link\0Ethernet\0",
                         config_item_perf_lookup, link_config_gperf_lookup,
                         false, false, true, link);
        if (r < 0)
                return r;
        else
                log_debug("Parsed configuration file %s", filename);

        link->filename = strdup(filename);

        LIST_PREPEND(links, ctx->links, link);
        link = NULL;

        return 0;
}
예제 #21
0
int route_new_static(Network *network, unsigned section, Route **ret) {
        _cleanup_route_free_ Route *route = NULL;
        int r;

        assert(network);
        assert(ret);

        if (section) {
                route = hashmap_get(network->routes_by_section, UINT_TO_PTR(section));
                if (route) {
                        *ret = route;
                        route = NULL;

                        return 0;
                }
        }

        if (network->n_static_routes >= STATIC_ROUTES_PER_NETWORK_MAX)
                return -E2BIG;

        r = route_new(&route);
        if (r < 0)
                return r;

        route->protocol = RTPROT_STATIC;

        if (section) {
                route->section = section;

                r = hashmap_put(network->routes_by_section, UINT_TO_PTR(route->section), route);
                if (r < 0)
                        return r;
        }

        route->network = network;
        LIST_PREPEND(routes, network->static_routes, route);
        network->n_static_routes++;

        *ret = route;
        route = NULL;

        return 0;
}
예제 #22
0
static int match_new(Client *c, struct bus_match_component *components, unsigned n_components, Match **_m) {
        Match *m, *first;
        int r;

        assert(c);
        assert(_m);

        r = hashmap_ensure_allocated(&c->matches, string_hash_func, string_compare_func);
        if (r < 0)
                return r;

        m = new0(Match, 1);
        if (!m)
                return -ENOMEM;

        m->match = bus_match_to_string(components, n_components);
        if (!m->match) {
                r = -ENOMEM;
                goto fail;
        }

        m->cookie = ++c->next_cookie;

        first = hashmap_get(c->matches, m->match);
        LIST_PREPEND(matches, first, m);
        r = hashmap_replace(c->matches, m->match, first);
        if (r < 0) {
                LIST_REMOVE(matches, first, m);
                goto fail;
        }

        m->client = c;
        c->n_matches++;

        *_m = m;
        m = NULL;

        return 0;

fail:
        match_free(m);
        return r;
}
예제 #23
0
int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsQuestion *q) {
        _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
        int r;

        assert(ret);
        assert(s);
        assert(q);

        r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);
        if (r < 0)
                return r;

        t = new0(DnsTransaction, 1);
        if (!t)
                return -ENOMEM;

        t->dns_fd = -1;

        t->question = dns_question_ref(q);

        do
                random_bytes(&t->id, sizeof(t->id));
        while (t->id == 0 ||
               hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id)));

        r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
        if (r < 0) {
                t->id = 0;
                return r;
        }

        LIST_PREPEND(transactions_by_scope, s->transactions, t);
        t->scope = s;

        if (ret)
                *ret = t;

        t = NULL;

        return 0;
}
예제 #24
0
int netlink_slot_allocate(
                sd_netlink *nl,
                bool floating,
                NetlinkSlotType type,
                size_t extra,
                sd_netlink_destroy_t destroy_callback,
                void *userdata,
                const char *description,
                sd_netlink_slot **ret) {

        _cleanup_free_ sd_netlink_slot *slot = NULL;

        assert(nl);
        assert(ret);

        slot = malloc0(offsetof(sd_netlink_slot, reply_callback) + extra);
        if (!slot)
                return -ENOMEM;

        slot->n_ref = 1;
        slot->netlink = nl;
        slot->userdata = userdata;
        slot->destroy_callback = destroy_callback;
        slot->type = type;
        slot->floating = floating;

        if (description) {
                slot->description = strdup(description);
                if (!slot->description)
                        return -ENOMEM;
        }

        if (!floating)
                sd_netlink_ref(nl);

        LIST_PREPEND(slots, nl->slots, slot);

        *ret = TAKE_PTR(slot);

        return 0;
}
예제 #25
0
파일: cursors.c 프로젝트: burzumishi/e16
static void
ECursorCreate(const char *name, const char *image, int native_id,
	      unsigned int fg, unsigned int bg)
{
   ECursor            *ec;

   if ((!name) || (!image && native_id == -1))
      return;

   ec = ECALLOC(ECursor, 1);
   if (!ec)
      return;

   ec->name = Estrdup(name);

   ec->file = Estrdup(image);
   ec->fg = 0xff000000 | fg;
   ec->bg = 0xff000000 | bg;
   ec->native_id = native_id;

   LIST_PREPEND(ECursor, &cursor_list, ec);
}
예제 #26
0
static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
        HashmapBase *h;
        const struct hashmap_type_info *hi = &hashmap_type_info[type];
        bool use_pool;

        use_pool = is_main_thread();

        h = use_pool ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size);

        if (!h)
                return NULL;

        h->type = type;
        h->from_pool = use_pool;
        h->hash_ops = hash_ops ? hash_ops : &trivial_hash_ops;

        if (type == HASHMAP_TYPE_ORDERED) {
                OrderedHashmap *lh = (OrderedHashmap*)h;
                lh->iterate_list_head = lh->iterate_list_tail = IDX_NIL;
        }

        reset_direct_storage(h);

        if (!shared_hash_key_initialized) {
                random_bytes(shared_hash_key, sizeof(shared_hash_key));
                shared_hash_key_initialized= true;
        }

#ifdef ENABLE_DEBUG_HASHMAP
        h->debug.func = func;
        h->debug.file = file;
        h->debug.line = line;
        assert_se(pthread_mutex_lock(&hashmap_debug_list_mutex) == 0);
        LIST_PREPEND(debug_list, hashmap_debug_list, &h->debug);
        assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0);
#endif

        return h;
}
예제 #27
0
int route_new_static(Network *network, unsigned section, Route **ret) {
        _cleanup_route_free_ Route *route = NULL;

        if (section) {
                route = hashmap_get(network->routes_by_section,
                                    UINT_TO_PTR(section));
                if (route) {
                        *ret = route;
                        route = NULL;

                        return 0;
                }
        }

        route = new0(Route, 1);
        if (!route)
                return -ENOMEM;

        route->family = AF_UNSPEC;
        route->scope = RT_SCOPE_UNIVERSE;
        route->protocol = RTPROT_STATIC;

        route->network = network;

        LIST_PREPEND(routes, network->static_routes, route);

        if (section) {
                route->section = section;
                hashmap_put(network->routes_by_section,
                            UINT_TO_PTR(route->section), route);
        }

        *ret = route;
        route = NULL;

        return 0;
}
예제 #28
0
static int server_init(Server *s, unsigned n_sockets) {
        int r;
        unsigned i;

        assert(s);
        assert(n_sockets > 0);

        zero(*s);

        s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
        if (s->epoll_fd < 0) {
                r = log_error_errno(errno,
                                    "Failed to create epoll object: %m");
                goto fail;
        }

        for (i = 0; i < n_sockets; i++) {
                struct epoll_event ev;
                Fifo *f;
                int fd;

                fd = SD_LISTEN_FDS_START+i;

                r = sd_is_fifo(fd, NULL);
                if (r < 0) {
                        log_error_errno(r, "Failed to determine file descriptor type: %m");
                        goto fail;
                }

                if (!r) {
                        log_error("Wrong file descriptor type.");
                        r = -EINVAL;
                        goto fail;
                }

                f = new0(Fifo, 1);
                if (!f) {
                        r = -ENOMEM;
                        log_error_errno(errno, "Failed to create fifo object: %m");
                        goto fail;
                }

                f->fd = -1;

                zero(ev);
                ev.events = EPOLLIN;
                ev.data.ptr = f;
                if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
                        r = -errno;
                        fifo_free(f);
                        log_error_errno(errno, "Failed to add fifo fd to epoll object: %m");
                        goto fail;
                }

                f->fd = fd;
                LIST_PREPEND(fifo, s->fifos, f);
                f->server = s;
                s->n_fifos++;
        }

        r = bus_connect_system_systemd(&s->bus);
        if (r < 0) {
                log_error_errno(r, "Failed to get D-Bus connection: %m");
                r = -EIO;
                goto fail;
        }

        return 0;

fail:
        server_done(s);

        return r;
}
예제 #29
0
int config_parse_dnssd_txt(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
        _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
        DnssdService *s = userdata;
        DnsTxtItem *last = NULL;

        assert(filename);
        assert(lvalue);
        assert(rvalue);
        assert(s);

        if (isempty(rvalue)) {
                /* Flush out collected items */
                s->txt_data_items = dnssd_txtdata_free_all(s->txt_data_items);
                return 0;
        }

        txt_data = new0(DnssdTxtData, 1);
        if (!txt_data)
                return log_oom();

        for (;;) {
                _cleanup_free_ char *word = NULL;
                _cleanup_free_ char *key = NULL;
                _cleanup_free_ char *value = NULL;
                _cleanup_free_ void *decoded = NULL;
                size_t length = 0;
                DnsTxtItem *i;
                int r;

                r = extract_first_word(&rvalue, &word, NULL,
                                       EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX);
                if (r == 0)
                        break;
                if (r == -ENOMEM)
                        return log_oom();
                if (r < 0)
                        return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);

                r = split_pair(word, "=", &key, &value);
                if (r == -ENOMEM)
                        return log_oom();
                if (r == -EINVAL)
                        key = TAKE_PTR(word);

                if (!ascii_is_valid(key)) {
                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring: %s", key);
                        return -EINVAL;
                }

                switch (ltype) {

                case DNS_TXT_ITEM_DATA:
                        if (value) {
                                r = unbase64mem(value, strlen(value), &decoded, &length);
                                if (r == -ENOMEM)
                                        return log_oom();
                                if (r < 0)
                                        return log_syntax(unit, LOG_ERR, filename, line, r,
                                                          "Invalid base64 encoding, ignoring: %s", value);
                        }

                        r = dnssd_txt_item_new_from_data(key, decoded, length, &i);
                        if (r < 0)
                                return log_oom();
                        break;

                case DNS_TXT_ITEM_TEXT:
                        r = dnssd_txt_item_new_from_string(key, value, &i);
                        if (r < 0)
                                return log_oom();
                        break;

                default:
                        assert_not_reached("Unknown type of Txt config");
                }

                LIST_INSERT_AFTER(items, txt_data->txt, last, i);
                last = i;
        }

        if (!LIST_IS_EMPTY(txt_data->txt)) {
                LIST_PREPEND(items, s->txt_data_items, txt_data);
                txt_data = NULL;
        }

        return 0;
}
예제 #30
0
파일: main.c 프로젝트: mikeleib/buxton
/**
 * Entry point into bt-daemon
 * @param argc Number of arguments passed
 * @param argv An array of string arguments
 * @returns EXIT_SUCCESS if the operation succeeded, otherwise EXIT_FAILURE
 */
int main(int argc, char *argv[])
{
	int fd;
	int smackfd = -1;
	socklen_t addr_len;
	struct sockaddr_un remote;
	int descriptors;
	int ret;
	bool manual_start = false;
	struct sigaction sa;

	if (!buxton_cache_smack_rules())
		exit(EXIT_FAILURE);
	smackfd = buxton_watch_smack_rules();
	if (smackfd < 0 && errno)
		exit(EXIT_FAILURE);

	self.nfds_alloc = 0;
	self.accepting_alloc = 0;
	self.nfds = 0;
	self.buxton.client.direct = true;
	self.buxton.client.uid = geteuid();
	if (!buxton_direct_open(&self.buxton))
		exit(EXIT_FAILURE);

	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
	sa.sa_handler = my_handler;
	ret = sigaction(SIGINT, &sa, NULL);
	if (ret == -1)
		exit(EXIT_FAILURE);
	ret = sigaction(SIGTERM, &sa, NULL);
	if (ret == -1)
		exit(EXIT_FAILURE);

	/* For client notifications */
	self.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
	/* Store a list of connected clients */
	LIST_HEAD_INIT(client_list_item, self.client_list);

	descriptors = sd_listen_fds(0);
	if (descriptors < 0) {
		buxton_log("sd_listen_fds: %m\n");
		exit(EXIT_FAILURE);
	} else if (descriptors == 0) {
		/* Manual invocation */
		manual_start = true;
		union {
			struct sockaddr sa;
			struct sockaddr_un un;
		} sa;

		fd = socket(AF_UNIX, SOCK_STREAM, 0);
		if (fd < 0) {
			buxton_log("socket(): %m\n");
			exit(EXIT_FAILURE);
		}

		memset(&sa, 0, sizeof(sa));
		sa.un.sun_family = AF_UNIX;
		strncpy(sa.un.sun_path, BUXTON_SOCKET, sizeof(sa.un.sun_path) - 1);
		sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;

		ret = unlink(sa.un.sun_path);
		if (ret == -1 && errno != ENOENT) {
			exit(EXIT_FAILURE);
		}

		if (bind(fd, &sa.sa, sizeof(sa)) < 0) {
			buxton_log("bind(): %m\n");
			exit(EXIT_FAILURE);
		}

		chmod(sa.un.sun_path, 0666);

		if (listen(fd, SOMAXCONN) < 0) {
			buxton_log("listen(): %m\n");
			exit(EXIT_FAILURE);
		}
		add_pollfd(&self, fd, POLLIN | POLLPRI, true);
	} else {
		/* systemd socket activation */
		for (fd = SD_LISTEN_FDS_START + 0; fd < SD_LISTEN_FDS_START + descriptors; fd++) {
			if (sd_is_fifo(fd, NULL)) {
				add_pollfd(&self, fd, POLLIN, false);
				buxton_debug("Added fd %d type FIFO\n", fd);
			} else if (sd_is_socket_unix(fd, SOCK_STREAM, -1, BUXTON_SOCKET, 0)) {
				add_pollfd(&self, fd, POLLIN | POLLPRI, true);
				buxton_debug("Added fd %d type UNIX\n", fd);
			} else if (sd_is_socket(fd, AF_UNSPEC, 0, -1)) {
				add_pollfd(&self, fd, POLLIN | POLLPRI, true);
				buxton_debug("Added fd %d type SOCKET\n", fd);
			}
		}
	}

	if (smackfd >= 0) {
		/* add Smack rule fd to pollfds */
		add_pollfd(&self, smackfd, POLLIN | POLLPRI, false);
	}

	buxton_log("%s: Started\n", argv[0]);

	/* Enter loop to accept clients */
	for (;;) {
		ret = poll(self.pollfds, self.nfds, -1);

		if (ret < 0) {
			buxton_log("poll(): %m\n");
			if (errno == EINTR) {
				if (do_shutdown)
					break;
				else
					continue;
			}
			break;
		}
		if (ret == 0)
			continue;

		for (nfds_t i=0; i<self.nfds; i++) {
			client_list_item *cl = NULL;
			char discard[256];

			if (self.pollfds[i].revents == 0)
				continue;

			if (self.pollfds[i].fd == -1) {
				/* TODO: Remove client from list  */
				buxton_debug("Removing / Closing client for fd %d\n", self.pollfds[i].fd);
				del_pollfd(&self, i);
				continue;
			}

			if (smackfd >= 0) {
				if (self.pollfds[i].fd == smackfd) {
					if (!buxton_cache_smack_rules())
						exit(EXIT_FAILURE);
					buxton_log("Reloaded Smack access rules\n");
					/* discard inotify data itself */
					while (read(smackfd, &discard, 256) == 256);
					continue;
				}
			}

			if (self.accepting[i] == true) {
				struct timeval tv;
				int fd;
				int on = 1;

				addr_len = sizeof(remote);

				if ((fd = accept(self.pollfds[i].fd,
				    (struct sockaddr *)&remote, &addr_len)) == -1) {
					buxton_log("accept(): %m\n");
					break;
				}

				buxton_debug("New client fd %d connected through fd %d\n", fd, self.pollfds[i].fd);

				cl = malloc0(sizeof(client_list_item));
				if (!cl)
					exit(EXIT_FAILURE);

				LIST_INIT(client_list_item, item, cl);

				cl->fd = fd;
				cl->cred = (struct ucred) {0, 0, 0};
				LIST_PREPEND(client_list_item, item, self.client_list, cl);

				/* poll for data on this new client as well */
				add_pollfd(&self, cl->fd, POLLIN | POLLPRI, false);

				/* Mark our packets as high prio */
				if (setsockopt(cl->fd, SOL_SOCKET, SO_PRIORITY, &on, sizeof(on)) == -1)
					buxton_log("setsockopt(SO_PRIORITY): %m\n");

				/* Set socket recv timeout */
				tv.tv_sec = SOCKET_TIMEOUT;
				tv.tv_usec = 0;
				if (setsockopt(cl->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,
					       sizeof(struct timeval)) == -1)
					buxton_log("setsockopt(SO_RCVTIMEO): %m\n");

				/* check if this is optimal or not */
				break;
			}

			assert(self.accepting[i] == 0);
			if (smackfd >= 0)
				assert(self.pollfds[i].fd != smackfd);

			/* handle data on any connection */
			/* TODO: Replace with hash table lookup */
			LIST_FOREACH(item, cl, self.client_list)
				if (self.pollfds[i].fd == cl->fd)
					break;

			assert(cl);
			handle_client(&self, cl, i);
		}
	}

	buxton_log("%s: Closing all connections\n", argv[0]);

	if (manual_start)
		unlink(BUXTON_SOCKET);
	for (int i = 0; i < self.nfds; i++) {
		close(self.pollfds[i].fd);
	}
	for (client_list_item *i = self.client_list; i;) {
		client_list_item *j = i->item_next;
		free(i);
		i = j;
	}
	hashmap_free(self.notify_mapping);
	buxton_direct_close(&self.buxton);
	return EXIT_SUCCESS;
}