diff options
Diffstat (limited to 'ircxmpp.c')
-rw-r--r-- | ircxmpp.c | 63 |
1 files changed, 59 insertions, 4 deletions
@@ -126,7 +126,8 @@ static void jid2ircuser (char * jid) { } static void bridge_forward (const char * f, const char * m, struct ircxmpp * ircxmpp, enum side s) { struct bridge * bridge = find_bridge(&ircxmpp->bridges, f, !s); - if (strstr(f, "ircxmpp_") || (ircxmpp->irchost && strstr(f, ircxmpp->irchost))) + if (strstr(f, "ircxmpp_") || (ircxmpp->irchost && strstr(f, ircxmpp->irchost)) + || (ircxmpp->domain && strstr(f, ircxmpp->domain))) return; LOG(ircxmpp, IRCXMPP_DEBUG, "sending text from %s to %s: %s", f, s == IRC ? "IRC" : "XMPP", m ? m : "[join only]"); @@ -136,9 +137,21 @@ static void bridge_forward (const char * f, const char * m, struct ircxmpp * irc bridge->ircxmpp = ircxmpp; bridge->side = !s; tsearch(bridge, &ircxmpp->bridges, bridge_compare); - if (s == IRC) + if (s == IRC) { + char buf[512+512+strlen(ircxmpp->domain)]; // for good measure, i think + char * cp = strchr(f, '@'); // 512+1+strlen is enough + if (cp) { // cmiiw + strncpy(buf, cp+1, 511); + buf[511] = '\0'; + } else + strcpy(buf, "unable.to.extract.domain.from.JID"); + *strchrnul(buf, '/') = '\0'; + if (buf[strlen(buf)-1] != '.') // jid domain can probably end with a dot. + strcat(buf, "."); // two consecutive dots would invalidate + strcat(buf, ircxmpp->domain); // the domain + ircxmpp->domain_setter(ircxmpp->domain_setter_userdata, buf); init_irc(bridge); - else { + } else { bridge->conn = xmpp_conn_new(bridge->ircxmpp->ctx); xmpp_conn_set_jid(bridge->conn, bridge->ircxmpp->jid); xmpp_conn_set_pass(bridge->conn, bridge->ircxmpp->password); @@ -469,6 +482,10 @@ static int irc_run_once_control (struct ircxmpp * ircxmpp) { /* returns nonzero LOG(ircxmpp, IRCXMPP_INFO, "CONNECTING control %s!ircxmpp@host", b); free(ircxmpp->ircnick); ircxmpp->ircnick = strdup(b); + char domain[512+strlen(ircxmpp->domain)]; + strcpy(domain, "čžš .. invalid domain so that we get our IP address as irchost .."); + strcat(domain, ircxmpp->domain); + ircxmpp->domain_setter(ircxmpp->domain_setter_userdata, domain); if (irc_connect(ircxmpp->irc, ircxmpp->hostname, ircxmpp->port, NULL, b, "ircxmpp", "http git.sijanec.eu/sijanec/ircxmpp")) { LOG(ircxmpp, IRCXMPP_ERROR, "control could not connect: %s", @@ -562,6 +579,7 @@ static void init_irc_control (struct ircxmpp * ircxmpp) { irc_run_once_control(ircxmpp); return; } +/* /IRC */ /* irc_is_connected(irc_session_t * session): 1 ali 0 */ static void default_log_handler (void * const u __attribute__((unused)), const enum ircxmpp_loglevel l, const char * const a, const char * const m) { char * t = "unspec"; @@ -581,7 +599,10 @@ static void default_log_handler (void * const u __attribute__((unused)), } fprintf(stderr, "[ircxmpp %s] %s: %s\n", t, a, m); } -/* /IRC */ /* irc_is_connected(irc_session_t * session): 1 ali 0 */ +static void default_domain_setter (void * u __attribute__((unused)), + const char * d __attribute__((unused))) { + return; // does nothing +} static void send_xmpp_logs_to_me (void * const u, const xmpp_log_level_t l, const char * const a, const char * const m) { enum ircxmpp_loglevel loglevel = IRCXMPP_ERROR; @@ -645,6 +666,20 @@ void ircxmpp_set_channel_password (struct ircxmpp * ircxmpp, const char * channe free(ircxmpp->channel_password); ircxmpp->channel_password = strdup(channel_password); } +void ircxmpp_set_domain_setter (struct ircxmpp * ircxmpp, ircxmpp_domain_setter setter) { + if (!setter) + setter = default_domain_setter; + ircxmpp->domain_setter = setter; +} +void ircxmpp_set_domain_setter_userdata (struct ircxmpp * ircxmpp, void * userdata) { + if (!userdata) + userdata = NULL; + ircxmpp->domain_setter_userdata = userdata; +} +void ircxmpp_set_domain (struct ircxmpp * ircxmpp, const char * domain) { + free(ircxmpp->domain); + ircxmpp->domain = strdup(domain); // this intentionally crashes +} static void obdelaj_bridge (const void * nodep, VISIT which __attribute__((unused)), int depth __attribute__((unused))) { struct bridge * bridge = *(struct bridge **) nodep; @@ -715,9 +750,11 @@ void ircxmpp_free (struct ircxmpp * ircxmpp) { free(ircxmpp->channel); free(ircxmpp->muc); free(ircxmpp->channel_password); + free(ircxmpp->domain); free(ircxmpp); } #else +#include "dns.c" int shouldexit = 0; void signalhandler (int s __attribute__((unused))) { shouldexit++; @@ -733,6 +770,7 @@ int main (void) { "multiple links can be specified by appending a consecutive number, starting with " \ "2, to every environment variable. first link is IX_*, second is IX_*2, and so on.\n" size_t handles_length = 0; + char * domain; // to know if we want to run dns server or not ircxmpp ** handles = NULL; while (1) { // note that if input config is invalid we leak memory before exiting char b[64]; // i don't free any allocated shit and just return, probably it's ok @@ -766,7 +804,21 @@ int main (void) { PREPARE_HANDLE(channel, "CHANNEL", str2str, 1); PREPARE_HANDLE(muc, "MUC", str2str, 1); PREPARE_HANDLE(channel_password, "CHPASS", str2str, 0); + PREPARE_HANDLE(domain, "DOMAIN", str2str, 0); + if (getenv(b)) + domain = getenv(b); } + struct dns * dns = dns_init(); + char buf[512+strlen(domain)]; + strcpy(buf, "ircxmpp.no.domain.set.yet."); + strcat(buf, domain); + dns_set_domain(dns, buf); + if (getenv("IX_DNS_PORT")) + dns_set_port(dns, atoi(getenv("IX_DNS_PORT"))); + if (getenv("IX_DNS_IP")) + dns_set_ip(dns, getenv("IX_DNS_IP")); + dns_set_log_handler(dns, dns_default_log_handler); + dns_set_log_userdata(dns, NULL); // so we don't read uninitialized values signal(SIGTERM, signalhandler); signal(SIGINT, signalhandler); // signal(SIGPIPE, SIG_IGN); @@ -777,12 +829,15 @@ int main (void) { .tv_sec = 0, .tv_nsec = getenv("IX_LOOPDELAY") ? atoi(getenv("IX_LOOPDELAY"))/1000 : 1e7 }; + if (domain) + dns_run_once(dns); nanosleep(&ts, NULL); } fprintf(stderr, "signal received, cleaning up!\n"); for (size_t i = 0; i < handles_length; i++) ircxmpp_free(handles[i]); free(handles); + dns_free(dns); return 0; } #endif |