static void cmd_alrt (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf) { char *p, *str; u_int32_t uid; u_int16_t style, len; struct htlc_conn *htlcp; int n, i = 1; char errbuf[sizeof(big_chatbuf)]; char nickbuf[sizeof(big_chatbuf)]; if (!htlc->access.can_broadcast) { cmd_denied(htlc, cid, "alert"); return; } p = chatbuf; uid = atou32(p); if (!uid && strncmp(p, "0 ", 2) && nick_to_uid(p, &uid)) { while (*p && *p != ' ') { p++; i++; } snprintf(nickbuf, i, "%s", chatbuf); snprintf(errbuf, MAX_CHAT - 7, "no such user \"%s\"", nickbuf); cmd_err(htlc, cid, "alert", errbuf); return; } htlcp = isclient(uid); if (!htlcp) { snprintf(errbuf, MAX_CHAT - 7, "no such user (uid:%u)", uid); cmd_err(htlc, cid, "alert", errbuf); return; } n = 1; while (*p && *p != ' ') { p++; n++; } if (!strlen(p) > 0) return; style = htons(1); str = &chatbuf[n]; len = strlen(str); if (isclient(htlcp->uid) != 0) { hlwrite(htlcp, HTLS_HDR_MSG, 0, 2, HTLS_DATA_STYLE, 2, &style, HTLS_DATA_MSG, len, str); } }
static void cmd_mon (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf) { struct htlc_conn *htlcp; u_int32_t uid; if (!htlc->access.disconnect_users) { cmd_denied(htlc, cid, "mon"); return; } uid = atou32(chatbuf); htlcp = isclient(uid); if (!htlcp) return; if (!htlcp->access_extra.access_volatile) return; htlcp->access.send_msgs = 1; }
void tests_util(void) { U32 u = 0; S32 s = 0; hello(); /* * streq() tests. */ /* Simple equality. */ NX_ASSERT(streq("foo", "foo")); /* Simple inequality. */ NX_ASSERT(!streq("foo", "bar")); NX_ASSERT(!streq("bar", "foo")); /* Inequality towards the end of the string. */ NX_ASSERT(!streq("foo", "fob")); NX_ASSERT(!streq("fob", "foo")); /* Inequality of different length strings. */ NX_ASSERT(!streq("foo", "foobar")); NX_ASSERT(!streq("foobar", "foo")); /* Inequality vs. the empty string. */ NX_ASSERT(!streq("foo", "")); NX_ASSERT(!streq("", "foo")); /* The border case of the empty string. */ NX_ASSERT(streq("", "")); /* * streqn() tests. */ /* Simple equality. */ NX_ASSERT(streqn("foo", "foo", 3)); /* Simple inequality. */ NX_ASSERT(!streqn("foo", "bar", 3)); NX_ASSERT(!streqn("bar", "foo", 3)); /* Inequality towards the end of the string. */ NX_ASSERT(!streqn("foo", "fob", 3)); NX_ASSERT(!streqn("fob", "foo", 3)); /* Inequality of different length strings. */ NX_ASSERT(!streqn("foo", "foobar", 6)); NX_ASSERT(!streqn("foobar", "foo", 6)); /* Inequality vs. the empty string. */ NX_ASSERT(!streqn("foo", "", 3)); NX_ASSERT(!streqn("", "foo", 3)); /* Equality of the empty string, no matter the given length. */ NX_ASSERT(streqn("", "", 42)); /* Equality of unequal strings if length == 0 */ NX_ASSERT(streqn("bleh", "foo", 0)); /* Prefix equality of unequal strings */ NX_ASSERT(streqn("feh", "foo", 1)); /* * atou32() tests. */ NX_ASSERT(atou32("42", &u) && u == 42); NX_ASSERT(atou32("0", &u) && u == 0); NX_ASSERT(atou32("00000000000000", &u) && u == 0); NX_ASSERT(atou32("0042", &u) && u == 42); NX_ASSERT(!atou32("arthur", &u)); /* 4294967295 is 2^32-1, aka U32_MAX */ NX_ASSERT(atou32("4294967295", &u) && u == 4294967295U); NX_ASSERT(!atou32("4294967296", &u)); /* TODO: massive overflows don't get caught because of our naive * checking logic. Need to fix. */ NX_ASSERT(atou32("9999999999", &u)); /* * atos32() tests. */ NX_ASSERT(atos32("42", &s) && s == 42); NX_ASSERT(atos32("-42", &s) && s == -42); NX_ASSERT(atos32("0", &s) && s == 0); NX_ASSERT(atos32("-0", &s) && s == 0); NX_ASSERT(atos32("00000000000000", &s) && s == 0); NX_ASSERT(atos32("0042", &s) && s == 42); NX_ASSERT(atos32("-0042", &s) && s == -42); NX_ASSERT(!atos32("arthur", &s)); /* 2147483647 is 2^32-1, aka S32_MAX */ NX_ASSERT(atos32("2147483647", &s) && s == 2147483647); NX_ASSERT(atos32("-2147483647", &s) && s == -2147483647); NX_ASSERT(!atos32("2147483648", &s)); /* TODO: We should be able to represent -2^31, but our conversion logic * considers it an error. Fix it if one day we actually need -2^31. */ NX_ASSERT(!atos32("-2147483648", &s)); /* TODO: massive overflows and underflows don't get caught because * of our naive checking logic. Need to fix. */ NX_ASSERT(atos32("9999999999", &s)); NX_ASSERT(atos32("-9999999999", &s)); goodbye(); }
static void cmd_kick (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf, int ban) { char *p, *str; u_int32_t uid; struct htlc_conn *htlcp; int n, i = 1; char errbuf[sizeof(big_chatbuf)]; char nickbuf[sizeof(big_chatbuf)]; if (!htlc->access.disconnect_users) { if (!ban) cmd_denied(htlc, cid, "kick"); else cmd_denied(htlc, cid, "ban"); return; } p = chatbuf; uid = atou32(p); if (!uid && strncmp(p, "0 ", 2) && nick_to_uid(p, &uid)) { while (*p && *p != ' ') { p++; i++; } snprintf(nickbuf, i, "%s", chatbuf); snprintf(errbuf, MAX_CHAT - 7, "no such user \"%s\"", nickbuf); if (!ban) cmd_err(htlc, cid, "kick", errbuf); else cmd_err(htlc, cid, "ban", errbuf); return; } htlcp = isclient(uid); if (!htlcp) { snprintf(errbuf, MAX_CHAT - 7, "no such user (uid:%u)", uid); cmd_err(htlc, cid, "kick", errbuf); return; } if(ban) ban = hxd_cfg.options.ban_time; n = 1; while (*p && *p != ' ') { p++; n++; } if ((htlcp = isclient(uid))) { if (htlcp->access.cant_be_disconnected) { snprintf(errbuf, MAX_CHAT - 7, "%s cannot be disconnected.", htlcp->name); cmd_err(htlc, cid, "kick", errbuf); return; } str = &chatbuf[n]; if (strlen(p)) user_kick(htlcp, ban, htlc, str); else user_kick(htlcp, ban, htlcp, " "); } }
static void cmd_0wn (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf) { char *p, *str; u_int32_t uid; int x, n, i=0; struct htlc_conn *htlcp; char nickbuf[sizeof(big_chatbuf)]; char errbuf[sizeof(big_chatbuf)]; char abuf[HOSTLEN+1]; if (!htlc->access_extra.user_0wn) { cmd_denied(htlc, cid, "0wn"); return; } p = chatbuf; uid = atou32(p); if (!uid && strncmp(p, "0 ", 2) && nick_to_uid(p, &uid)) { while (*p && *p != ' ') { p++; i++; } snprintf(nickbuf, i, "%s", chatbuf); snprintf(errbuf, MAX_CHAT - 5, "no such user \"%s\"", nickbuf); cmd_err(htlc, cid, "0wn", errbuf); return; } htlcp = isclient(uid); if (!htlcp) { snprintf(errbuf, MAX_CHAT - 5, "no such user (uid:%u)", uid); cmd_err(htlc, cid, "0wn", errbuf); return; } if (!htlcp->access_extra.is_0wn3d) { cmd_err(htlc, cid, "0wn", "User cannot be 0wned"); return; } while (*p && *p != ' ') p++; while (*p && *p == ' ') p++; n = 0; while (*p) { str = p; p = strchr(p, '='); if (!p) break; *p = 0; p++; x = user_0wn(htlcp, str, p); if (x) { n++; if (x == 3) break; } while (*p && *p != ' ') p++; while (*p && *p == ' ') p++; } inaddr2str(abuf, &htlc->sockaddr); if (n) { snd_user_change(htlcp); hxd_log("%s@%s:%u - %s:%u:%u:%s owned %s:%u:%u:%s - %s", htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT), htlc->name, htlc->icon, htlc->uid, htlc->login, htlcp->name, htlcp->icon, htlcp->uid, htlcp->login, str); } }
static void cmd_access (struct htlc_conn *htlc, u_int32_t cid, char *chatbuf) { char *p, *str; u_int32_t uid; int val; struct htlc_conn *htlcp; char errbuf[MAX_CHAT]; char nickbuf[32]; int f[2], i = 1; char abuf[HOSTLEN+1]; if (!htlc->access_extra.user_access) { cmd_denied(htlc, cid, "access"); return; } p = chatbuf; uid = atou32(p); if (!strncmp(p, "0 ", 2)) uid = 0; else if (!uid && nick_to_uid(p, &uid)) { while (*p && *p != ' ') { p++; i++; } snprintf(nickbuf, i, "%s", chatbuf); snprintf(errbuf, MAX_CHAT - 8, "no such user \"%s\"", nickbuf); cmd_err(htlc, cid, "access", errbuf); return; } htlcp = isclient(uid); if (!htlcp) { snprintf(errbuf, MAX_CHAT - 8, "no such user (uid:%u)", uid); cmd_err(htlc, cid, "access", errbuf); return; } if (!htlcp->access_extra.access_volatile) { cmd_err(htlc, cid, "access", "user cannot be modified"); return; } while (*p && *p != ' ') p++; while (*p && *p == ' ') p++; inaddr2str(abuf, &htlc->sockaddr); str = ""; while (*p) { str = p; p = strchr(p, '='); if (!p) break; *p = 0; p++; val = *p == '1' ? 1 : 0; p++; f[0] = access_extra_set(&htlcp->access_extra, str, val); f[1] = set_access_bit(&htlcp->access, str, val); if (f[0] && f[1]) { snprintf(errbuf, MAX_CHAT - 8, "unknown argument \"%s\"", str); cmd_err(htlc, cid, "access", errbuf); return; } while (*p && *p != ' ') p++; while (*p && *p == ' ') p++; } hxd_log("%s@%s:%u - %s:%u:%u:%s modified access of %s:%u:%u:%s - %s", htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT), htlc->name, htlc->icon, htlc->uid, htlc->login, htlcp->name, htlcp->icon, htlcp->uid, htlcp->login, str); user_access_update(htlcp); snd_user_change(htlcp); }