static void net_disconnected(struct a_network *net) { /* TODO: timed reconnect */ a_log(LINFO, "Disconnected from %s, reconnecting...", net->name); net->state = NET_DISCONNECTED; net_start_connect(net); }
static int on_topic_update(int parc, const char *parv[], void *priv) { struct a_route_ctx *ctx = priv; const char *chan = NULL; const char *topic = NULL; if (!strcmp(ctx->msg.command, "TOPIC")) { if (parc < 5) return 0; chan = parv[3]; if (strlen(parv[4]) != 0) topic = parv[4]; } else if (!strcmp(ctx->msg.command, "332")) { if (parc < 6) return 0; chan = parv[4]; topic = parv[5]; } else if (!strcmp(ctx->msg.command, "331")) { if (parc < 6) return 0; chan = parv[4]; } if (chan == NULL) return 0; a_log(LINFO, "%s topic %s%s", chan, topic == NULL ? "unset" : "changed to ", topic == NULL ? "" : topic); netdata_chan_topic(ctx->net, chan, topic); return 0; }
static void a_network_resolve_cb(mowgli_dns_reply_t *reply, int reason, void *priv_arg) { struct a_network *net = priv_arg; const char *reason_str; /* assume something will go wrong for now */ net->state = NET_CANNOT_CONTINUE; if (reply == NULL) { switch (reason) { case MOWGLI_DNS_RES_NXDOMAIN: reason_str = "Nonexistent domain, cannot continue"; break; case MOWGLI_DNS_RES_INVALID: reason_str = "Invalid domain, cannot continue"; break; case MOWGLI_DNS_RES_TIMEOUT: reason_str = "Request timed out, trying again"; break; } a_log(LERROR, "Resolution of %s (%s) failed: %s", net->host, net->name, reason_str); if (reason == MOWGLI_DNS_RES_TIMEOUT) { net->state = NET_DISCONNECTED; net_start_connect(net); } return; } net_connect(net, reply->h_name, &reply->addr); }
static void parse_server(struct a_network *net, const char *spec) { char hostspec[1024]; char *portspec; /* snag the hostname */ snprintf(hostspec, 1024, "%s", spec); portspec = strchr(hostspec, '/'); if (portspec != NULL) *portspec = '\0'; net->host = mowgli_strdup(hostspec); /* snag the port */ portspec = strchr(spec, '/'); if (portspec == NULL) portspec = "/6667"; portspec++; net->use_ssl = false; if (portspec[0] == '+') { net->use_ssl = true; portspec++; } net->port = atoi(portspec); if (net->port < 1 || net->port > 65535) { a_log(LERROR, "Invalid port number %d, defaulting to 6667", net->port); net->port = 6667; } }
static int net_del_from_account(struct a_network *net) { a_log(LINFO, "Deleting network %s from account %s", net->name, net->acct->name); mowgli_patricia_delete(net->acct->networks, net->name); return 0; }
void operator()( boost::property_tree::ptree & s, object_type & obj ) { boost::property_tree::ptree al; state_getter< typename object_type::allele_type > a_log; a_log( al, obj.getAlleleSpace() ); boost::property_tree::ptree ft; clotho::utility::add_value_array( ft, obj.fitness_begin(), obj.fitness_end() ); s.put_child( "alleles" , al ); s.put_child( "fitness", ft ); }
static int on_RPL_WELCOME(int parc, const char *parv[], void *priv) { struct a_route_ctx *ctx = priv; a_log(LINFO, "Connected to %s!", ctx->net->name); mowgli_strput(&ctx->net->nd.nick, parv[3]); a_network_printf(ctx->net, "WHOIS %s", ctx->net->nick); irc_isupport_reset(ctx->net->nd.isupport); }
static int net_disconnect(struct a_network *net) { if (net->state == NET_DISCONNECTED) { a_log(LERROR, "Attempt to disconnect disconnected network"); return; } if (net->linebuf) { mowgli_linebuf_destroy(net->linebuf); net->linebuf = NULL; } return 0; }
/* :<acct> NET <name> <address> [<nick> [<user> [:<gecos>]]] */ static int db_net(int parc, const char *parv[], void *priv) { struct a_network *net; int line = (int)priv; if (parc < 3 || parc > 6) { a_log(LERROR, "Bad NET line on %d", line); return 0; } net = net_create(parv[1]); if (net == NULL) { a_log(LERROR, "Failed to allocate network!"); return 0; } mowgli_strput(&net->nick, parv[0]); parse_server(net, parv[2]); if (parc > 3) mowgli_strput(&net->nick, parv[3]); if (parc > 4) mowgli_strput(&net->ident, parv[4]); if (parc > 5) mowgli_strput(&net->gecos, parv[5]); if (net_add_to_account(net, parv[0]) < 0) { a_log(LERROR, "Failed to add network %s to account %s", net->name, parv[0]); goto fail; } net_start_connect(net); return 0; fail: net_destroy(net); return 0; }
static void netdata_chan_topic(struct a_network *net, const char *name, const char *topic) { struct a_net_chan *chan; chan = netdata_chan(net, name); if (chan == NULL) { a_log(LERROR, "Channel %s does not exist!", name); return; } mowgli_string_reset(chan->topic); if (topic != NULL) mowgli_string_append(chan->topic, topic, strlen(topic)); }
static int net_add_to_account(struct a_network *net, const char *acct_name) { struct a_account *acct; acct = a_account_find(acct_name); if (acct == NULL) { a_log(LERROR, "Could not find account %s", acct_name); return -1; } if (mowgli_patricia_retrieve(acct->networks, net->name) != NULL) { a_log(LERROR, "Network %s for %s already exists, ignoring duplicate configuration", net->name, acct->name); return -1; } a_log(LINFO, "Adding network %s to account %s", net->name, acct->name); mowgli_patricia_add(acct->networks, net->name, net); net->acct = acct; return 0; }
static void net_do_register(struct a_network *net) { if (net == NULL || net->state != NET_CONNECTED) return; a_log(LDEBUG, "Registering to %s", net->name); mowgli_hook_call("network.register", net); a_network_printf(net, "NICK %s", net->nick); a_network_printf(net, "USER %s * 8 :%s", net->ident, net->gecos); mowgli_strput(&net->nd.nick, net->nick); mowgli_strput(&net->nd.ident, net->ident); mowgli_strput(&net->nd.gecos, net->gecos); }
static void netdata_chan_del(struct a_network *net, const char *name) { struct a_net_chan *chan; chan = netdata_chan(net, name); if (chan == NULL) { a_log(LERROR, "Channel %s does not exist!", name); return; } mowgli_patricia_delete(net->nd.chans, name); mowgli_string_destroy(chan->topic); mowgli_free(chan->name); mowgli_free(chan); }
static int on_RPL_WHOISUSER(int parc, const char *parv[], void *priv) { struct a_route_ctx *ctx = priv; int map = irc_isupport_get_casemapping(ctx->net->nd.isupport); if (parc < 9) return 0; if (irc_casecmp(map, parv[4], ctx->net->nd.nick)) return 0; mowgli_strput(&ctx->net->nd.ident, parv[5]); mowgli_strput(&ctx->net->nd.host, parv[6]); mowgli_strput(&ctx->net->nd.gecos, parv[8]); a_log(LINFO, "I am %s!%s@%s :%s", ctx->net->nd.nick, ctx->net->nd.ident, ctx->net->nd.host, ctx->net->nd.gecos); return 0; }
static void net_start_connect(struct a_network *net) { struct sockaddr_in *addr4; struct sockaddr_in6 *addr6; mowgli_dns_query_t *query; mowgli_vio_sockaddr_t addr; if (net == NULL) return; if (net->state != NET_DISCONNECTED) return; if (net->host == NULL || net->port < 1 || net->port > 65535) return; query = &net->query; query->ptr = net; query->callback = a_network_resolve_cb; addr4 = (void*)&addr.addr; addr6 = (void*)&addr.addr; if (inet_pton(AF_INET, net->host, &addr4->sin_addr) > 0) { addr.addr.ss_family = AF_INET; net_connect(net, net->host, &addr); } else if (inet_pton(AF_INET6, net->host, &addr6->sin6_addr) > 0) { addr.addr.ss_family = AF_INET6; net_connect(net, net->host, &addr); } else { a_log(LDEBUG, "Resolving %s", net->host); net->state = NET_RESOLVING; mowgli_dns_gethost_byname(alicorn.dns, net->host, query, MOWGLI_DNS_T_A); } }
static int net_connect(struct a_network *net, char *h_name, mowgli_vio_sockaddr_t *addr) { char buf[65536]; net->linebuf = mowgli_linebuf_create(readline_cb, net); net->linebuf->shutdown_cb = shutdown_cb; net->linebuf->delim = "\n"; if (net->state == NET_CONNECTED) { a_log(LERROR, "Attempt to connect already-connected network"); return; } if (addr->addr.ss_family == AF_INET) { struct sockaddr_in *addr4 = (void*)&addr->addr; addr4->sin_port = htons(net->port); addr->addrlen = sizeof(struct sockaddr_in); inet_ntop(AF_INET, &addr4->sin_addr, buf, 65536); a_log(LDEBUG, "Connecting IPv4 %s/%d", buf, net->port); } else if (addr->addr.ss_family == AF_INET6) { struct sockaddr_in6 *addr6 = (void*)&addr->addr; addr6->sin6_port = net->port; addr->addrlen = sizeof(struct sockaddr_in); inet_ntop(AF_INET6, &addr6->sin6_addr, buf, 65536); a_log(LDEBUG, "Connecting IPv6 %s/%d", buf, net->port); } else { a_log(LERROR, "Unknown address family %d for %s (%s)", addr->addr.ss_family, h_name, net->name); return -1; } a_log(LNOTICE, "Connecting to %s (%s)", h_name, net->name); if (net->use_ssl) { if (mowgli_vio_openssl_setssl(net->linebuf->vio, NULL, NULL) != 0) { a_log(LERROR, "Failed to set SSL on %s", net->name); return -1; } } if (mowgli_vio_socket(net->linebuf->vio, AF_INET, SOCK_STREAM, 0) != 0) { a_log(LERROR, "Failed to create socket for %s", net->name); return -1; } mowgli_linebuf_attach_to_eventloop(net->linebuf, alicorn.eventloop); if (mowgli_vio_connect(net->linebuf->vio, addr) != 0) { a_log(LERROR, "Failed to connect to %s (%s)", h_name, net->name); return -1; } net->state = NET_CONNECTED; net_do_register(net); return 0; }