static void net_cond_set(char *ifname, char *cond, int set) { char msg[MAX_ARG_LEN]; snprintf(msg, sizeof(msg), "net/%s/%s", ifname, cond); if (set) cond_set(msg); else cond_clear(msg); }
static int do_handle_event(char *event) { int i; for (i = 0; ev_list[i].event; i++) { ev_t *e = &ev_list[i]; size_t len = MAX(strlen(e->event), strlen(event)); if (!strncasecmp(e->event, event, len)) { e->cb(); return 0; } } if (event[0] == '-') cond_clear(&event[1]); else if (event[0] == '+') cond_set(&event[1]); else cond_set(event); return 0; }
static void nl_route(struct nlmsghdr *nlmsg) { struct rtmsg *r; struct rtattr *a; int la; int gw = 0, dst = 0, mask = 0, idx = 0; if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg))) { _e("Packet too small or truncated!"); return; } r = NLMSG_DATA(nlmsg); a = RTM_RTA(r); la = RTM_PAYLOAD(nlmsg); while (RTA_OK(a, la)) { void *data = RTA_DATA(a); switch (a->rta_type) { case RTA_GATEWAY: gw = *((int *)data); //_d("GW: 0x%04x", gw); break; case RTA_DST: dst = *((int *)data); mask = r->rtm_dst_len; //_d("MASK: 0x%04x", mask); break; case RTA_OIF: idx = *((int *)data); //_d("IDX: 0x%04x", idx); break; } a = RTA_NEXT(a, la); } if ((!dst && !mask) && (gw || idx)) { if (nlmsg->nlmsg_type == RTM_DELROUTE) cond_clear("net/route/default"); else cond_set("net/route/default"); } }
static void pidfile_callback(void *UNUSED(arg), int fd, int UNUSED(events)) { static char ev_buf[8 *(sizeof(struct inotify_event) + NAME_MAX + 1) + 1]; static char cond[MAX_ARG_LEN]; struct inotify_event *ev; ssize_t sz, len; char *basename; svc_t *svc; sz = read(fd, ev_buf, sizeof(ev_buf) - 1); if (sz <= 0) { _pe("invalid inotify event"); return; } ev_buf[sz] = 0; for (ev = (void *)ev_buf; sz > (ssize_t)sizeof(*ev); len = sizeof(*ev) + ev->len, ev = (void *)ev + len, sz -= len) { /* ev = (void *)(ev + 1) + ev->len, sz -= sizeof(*ev) + ev->len) { */ if (!ev->mask || !strstr(ev->name, ".pid")) continue; basename = strtok(ev->name, "."); if (!basename) continue; svc = svc_find_by_nameid(basename, 1); if (!svc) continue; /* TODO FIXME XXX WKZ check that pid is controlled by finit */ _d("%s: match %s", basename, svc->cmd); snprintf(cond, sizeof(cond), "svc%s", svc->cmd); if (ev->mask & (IN_CREATE | IN_ATTRIB)) { svc_started(svc); cond_set(cond); } else if (ev->mask & IN_DELETE) cond_clear(cond); } }
static void nl_link(struct nlmsghdr *nlmsg) { int la; char ifname[IFNAMSIZ + 1]; struct rtattr *a; struct ifinfomsg *i; if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) { _e("Packet too small or truncated!"); return; } i = NLMSG_DATA(nlmsg); a = (struct rtattr *)((char *)i + NLMSG_ALIGN(sizeof(struct ifinfomsg))); la = NLMSG_PAYLOAD(nlmsg, sizeof(struct ifinfomsg)); while (RTA_OK(a, la)) { if (a->rta_type == IFLA_IFNAME) { char msg[MAX_ARG_LEN]; strlcpy(ifname, RTA_DATA(a), sizeof(ifname)); switch (nlmsg->nlmsg_type) { case RTM_NEWLINK: /* * New interface has appearad, or interface flags has changed. * Check ifi_flags here to see if the interface is UP/DOWN */ if (i->ifi_change & IFF_UP) { snprintf(msg, sizeof(msg), "net/%s/up", ifname); if (i->ifi_flags & IFF_UP) cond_set(msg); else cond_clear(msg); } else { snprintf(msg, sizeof(msg), "net/%s/exist", ifname); cond_set(msg); } break; case RTM_DELLINK: /* NOTE: Interface has dissapeared, not link down ... */ snprintf(msg, sizeof(msg), "net/%s/exist", ifname); cond_clear(msg); break; case RTM_NEWADDR: _d("%s: New Address", ifname); break; case RTM_DELADDR: _d("%s: Deconfig Address", ifname); break; default: _d("%s: Msg 0x%x", ifname, nlmsg->nlmsg_type); break; } } a = RTA_NEXT(a, la); } }