int denora_event_push(char *source, int ac, char **av) { /* Thanks to w00t from the inspircd team for helping me to write this function * debug: Received: :rock.musichat.net PUSH TestBOT ::rock.musichat.net 242 TestBOT :Server up 1 days, 07:47:54 */ Server *s; char *num; char buf[NET_BUFSIZE]; if (denora->protocoldebug) { protocol_debug(source, ac, av); } num = myStrGetToken(av[1], ' ', 1); av[1] = myStrGetTokenRemainder(av[1], ' ', 3); if (!num || !av[1]) { alog(LOG_ERROR, "ERROR: Something wicked while handling the PUSH message (truncated message)"); return MOD_CONT; } if (!strcmp(num, "375")) { rdb_query(QUERY_LOW, "UPDATE %s SET motd=\'\' WHERE server=\'%s\'", ServerTable, source); } else if (!strcmp(num, "372")) { s = server_find(source); if (!s) { return MOD_CONT; } av[1]++; if (ac >= 2) { if (s->motd) { ircsnprintf(buf, NET_BUFSIZE - 1, "%s\n\r%s", s->motd, av[1]); free(s->motd); s->motd = sstrdup(buf); } else { s->motd = sstrdup(av[1]); } } } else if (!strcmp(num, "376")) { s = server_find(source); if (!s) { return MOD_CONT; } sql_motd_store(s); } else if (!strcmp(num, "242")) { av[1]++; sql_do_uptime(source, av[1]); } else if (!strcmp(num, "248")) { av[2] = myStrGetTokenRemainder(av[1], ' ', 1); av[1] = myStrGetToken(av[1], ' ', 1); /* possible memleak at this location */ sql_uline(av[2]); } return MOD_CONT; }
/** * Process numeric 372 messages * * @param source is the server that sent the message * @param ac is the array count * @param av is the array * * @return return is always MOD_CONT * */ int denora_event_372(char *source, int ac, char **av) { Server *s; char buf[NET_BUFSIZE]; SET_SEGV_LOCATION(); if (denora->protocoldebug) { protocol_debug(source, ac, av); } s = server_find(source); if (!s) { return MOD_CONT; } if (ac >= 2) { if (s->motd) { ircsnprintf(buf, NET_BUFSIZE - 1, "%s\n\r%s", s->motd, av[1]); free(s->motd); s->motd = sstrdup(buf); } else { s->motd = sstrdup(av[1]); } } return MOD_CONT; }
/* -1 if server not found, servid else */ int db_checkserver_online(char *serv) { int servid = 0; Server *s; #ifdef USE_MYSQL MYSQL_RES *mysql_res; #endif s = server_find(serv); if (s && s->sqlid) { return s->sqlid; } SET_SEGV_LOCATION(); if (!denora->do_sql) { return -1; } rdb_query(QUERY_HIGH, "SELECT servid FROM %s WHERE server=\'%s\' and online=\'Y\'", ServerTable, serv); #ifdef USE_MYSQL mysql_res = mysql_store_result(mysql); if (mysql_res) { SET_SEGV_LOCATION(); mysql_free_result(mysql_res); return 1; } #endif return servid; }
int denora_event_topic(char *source, int ac, char **av) { User *u; Server *s; char *newav[5]; if (denora->protocoldebug) protocol_debug(source, ac, av); if (ac < 4) return MOD_CONT; u = user_find(source); if (!u) s = server_find(source); newav[0] = av[0]; if (u) newav[1] = u->nick; else if (s) newav[1] = s->name; else newav[1] = source; newav[2] = av[ac - 2]; newav[3] = av[ac - 1]; newav[4] = '\0'; do_topic(4, newav); return MOD_CONT; }
int denora_event_mode(char *source, int ac, char **av) { if (denora->protocoldebug) { protocol_debug(source, ac, av); } if (ac < 2) return MOD_CONT; if (*av[0] == '#' || *av[0] == '&') { do_cmode(source, ac, av); } else { Server *s; s = server_find(source); if (s && *av[0]) { do_umode(av[0], ac, av); } else { do_umode(source, ac, av); } } return MOD_CONT; }
/* ABAAA M #ircops +v ABAAB */ int denora_event_mode(char *source, int ac, char **av) { User *u; Server *s; char *sender; if (denora->protocoldebug) protocol_debug(source, ac, av); if (ac < 2) return MOD_CONT; u = find_byuid(source); if (!u) { sender = source; } else { sender = u->nick; } if (*av[0] == '#' || *av[0] == '&') { do_cmode(source, ac, av); } else { s = server_find(source); if (s) sender = av[0]; do_umode(sender, ac, av); } return MOD_CONT; }
/* ABAAC AC ANAC] R :Trystan */ int denora_event_account(char *source, int ac, char **av) { Server *s; User *u; if (denora->protocoldebug) protocol_debug(source, ac, av); if ((ac < 2) || !source || !(s = server_find(source))) return MOD_CONT; u = find_byuid(av[0]); if (!u) return MOD_CONT; if (!strcmp(av[1], "R")) /* Set */ do_p10account(u, av[2], 0); else if (!strcmp(av[1], "M")) /* Rename */ do_p10account(u, av[2], 2); else if (!strcmp(av[1], "U")) /* Remove */ do_p10account(u, NULL, 1); else do_p10account(u, av[1], 0); /* For backward compatability */ return MOD_CONT; }
int denora_event_376(char *source, int ac, char **av) { Server *s; s = server_find(source); if (!s) { return MOD_CONT; } sql_motd_store(s); return MOD_CONT; }
void asuka_cmd_version(char *server) { Uid *ud; Server *s; ud = find_uid(s_StatServ); s = server_find(server); send_cmd((ud ? ud->uid : s_StatServ), "V :%s", (s ? (s->suid ? s->suid : server) : server)); }
void asuka_cmd_motd(char *sender, char *server) { Uid *ud; Server *s; ud = find_uid(sender); s = server_find(server); send_cmd((ud ? ud->uid : sender), "MO :%s", (s ? (s->suid ? s->suid : server) : server)); }
void asuka_cmd_stats(char *sender, const char *letter, char *server) { Uid *ud; Server *s; ud = find_uid(sender); s = server_find(server); send_cmd((ud ? ud->uid : sender), "R %s :%s", letter, (s ? (s->suid ? s->suid : server) : server)); }
/* * server_delete(const char *name) * * Finds and recursively destroys a server object. * * Inputs: * - name of server to find and destroy * * Outputs: * - nothing * * Side Effects: * - all users and servers attached to the target are recursively deleted */ void server_delete(const char *name) { server_t *s = server_find(name); if (!s) { slog(LG_DEBUG, "server_delete(): called for nonexistant server: %s", name); return; } server_delete_serv(s); }
void scarynet_cmd_ping(char *server) { Uid *ud; Server *s; struct timeval t; ud = find_uid(s_StatServ); s = server_find(server); gettimeofday(&t, NULL); send_cmd(p10id, "RI %s %s %ld %ld :<No client start time>", ((s && s->suid) ? s->suid : server), (ud ? ud->uid : s_StatServ), t.tv_sec, t.tv_usec); }
dbase_server *server_find(char *numeric, dbase_server *root) { if (root) { int i; dbase_server *tmp; if (!strcmp(numeric, root->numeric)) return root; for (i = 0; i < root->children_count; i++) if ((tmp = server_find(numeric, root->children[i]))) return tmp; } return NULL; }
int denora_event_eob(char *source, int ac, char **av) { Server *s; if (denora->protocoldebug) protocol_debug(source, ac, av); s = server_find(source); if (stricmp(s->name, denora->uplink) == 0) send_cmd(NULL, "%s EA", p10id); update_sync_state(source, SYNC_COMPLETE); return MOD_CONT; }
/* do_nick(const char *source, char *nick, char *username, char *host, char *server, char *realname, time_t ts, uint32 svid, uint32 ip, char *vhost, char *uid, int hopcount, char *modes, char *account) NICK Trystan 1 1148214497 +aiow tslee is.my.vhost plexus3.nomadirc.net 0 c-67-186-230-12.hsd1.ut.comcast.net :Dreams are answers to questions not yet asked 0 1 2 3 4 5 6 7 8 9 666 UID asdasd 1 1234817435 +ix Nesstest 566C206.B53EDE66.1DF57482.IP 66.63.160.250 666AAAAAD 0 66.63.160.250 :JasonX 0 1 2 3 4 5 6 7 8 9 10 [Feb 19 04:24:22.531142 2009] debug: Received: :57CAAEV6D NICK Miu :1235017456 [Feb 19 04:24:22.536789 2009] Source 57CAAEV6D [Feb 19 04:24:22.537026 2009] av[0] = Miu [Feb 19 04:24:22.537233 2009] av[1] = 1235017456 [Feb 19 04:24:22.537422 2009] Unknown NICK formatted message please report the following */ int denora_event_nick(char *source, int ac, char **av) { Server *s; User *user; char *temp; char *ipchar = NULL; if (denora->protocoldebug) { protocol_debug(source, ac, av); } temp = sstrdup(source); if (UseTS6 && ac == 11) { s = server_find(source); /* Source is always the server */ *source = '\0'; user = do_nick(source, av[0], av[4], av[9], s->name, av[10], strtoul(av[2], NULL, 10), 0, av[6], av[5], av[7], strtoul(av[1], NULL, 10), av[3], NULL); if (user) { denora_set_umode(user, 1, &av[3]); } } else if (ac == 10) { ipchar = host_resolve(av[8]); user = do_nick(source, av[0], av[4], av[8], av[6], av[9], strtoul(av[2], NULL, 10), strtoul(av[7], NULL, 0), ipchar, av[5], NULL, strtoul(av[1], NULL, 0), av[3], NULL); free(ipchar); } else if (ac == 2) { do_nick(source, av[0], NULL, NULL, NULL, NULL, strtoul(av[1], NULL, 10), 0, NULL, NULL, NULL, 0, NULL, NULL); } else { alog(LOG_DEBUG, "Unknown NICK formatted message please report the following"); protocol_debug(temp, ac, av); } free(temp); return MOD_CONT; }
int denora_event_sid(char *source, int ac, char **av) { Server *s; /* :42X SID trystan.nomadirc.net 2 43X :ircd-ratbox test server */ if (denora->protocoldebug) { protocol_debug(source, ac, av); } s = server_find(source); do_server(s->name, av[0], av[1], av[3], av[2]); return MOD_CONT; }
int cs_server_quit(int ac, char **av) { Server *s; SET_SEGV_LOCATION(); if (!ConnectServConnected) return MOD_CONT; s = server_find(av[0]); if (!s) { return MOD_CONT; } alog(LOG_NORMAL, "\2SERVER\2 %s has left the Network at %s for %s", s->name, s->uplink->name, (ac == 2) ? av[1] : ""); return MOD_CONT; }
/* (AB S trystan.nomadirc.net 2 0 1106520454 P10 ACAP] +h :Test Server) */ int denora_event_server(char *source, int ac, char **av) { Server *s; char uplinknum[3]; *uplinknum = '\0'; if (denora->protocoldebug) { protocol_debug(source, ac, av); } strlcpy(uplinknum, av[5], sizeof(uplinknum)); if (!denora->uplink) { denora->uplink = sstrdup(av[0]); } s = server_find(source); do_server((s ? s->name : source), av[0], av[1], av[7], uplinknum); return MOD_CONT; }
int cs_server_join(int ac, char **av) { Server *s; SET_SEGV_LOCATION(); if (!ConnectServConnected) return MOD_CONT; s = server_find(av[0]); if (!s) { return MOD_CONT; } alog(LOG_NORMAL, "\2SERVER\2 %s has joined the Network at %s", s->name, s->uplink->name); return MOD_CONT; }
void nefarious_cmd_ping(char *server) { /* AB G !1115872042.64217 denora.nomadirc.net 1115872042.64217 * [OUT]: AB RI AL ABAAB 1165972073 45741 :<No client start time> * [IN ]: AL RO ScaryNet.Org ABAAB 1165972073 45741 :<No client start time> */ Uid *ud; Server *s; struct timeval t; ud = find_uid(s_StatServ); s = server_find(server); gettimeofday(&t, NULL); send_cmd(p10id, "RI %s %s %ld %ld :<No client start time>", ((s && s->suid) ? s->suid : server), (ud ? ud->uid : s_StatServ), t.tv_sec, t.tv_usec); }
/* ABAAA M #ircops +v ABAAB */ int denora_event_mode(char *source, int ac, char **av) { User *u; User *v; Server *s; char *sender; char hhostbuf[255]; if (denora->protocoldebug) protocol_debug(source, ac, av); if (ac < 2) return MOD_CONT; u = find_byuid(source); if (!u) { sender = source; } else { sender = u->nick; } if (*av[0] == '#' || *av[0] == '&') { do_cmode(source, ac, av); } else { s = server_find(source); if (s) sender = av[0]; do_umode(sender, ac, av); if (strcmp(av[1], "x") != -1) { v = user_find(av[0]); if (v->account) { ircsnprintf(hhostbuf, sizeof(v->account) + sizeof(hhostbuf) + 2, "%s%s%s", HiddenPrefix, v->account, HiddenSuffix); change_user_host(v->nick, hhostbuf); } } } return MOD_CONT; }
void server_add(char *from, char *numeric, char *name, unsigned long linktime, char *desc) { dbase_server *ny; dbase_server *parent = NULL; numeric[2] = '\0'; ny = (dbase_server*) malloc(sizeof(dbase_server)); if ((parent = server_find(from, servers))) { parent->children = (dbase_server**)realloc(parent->children, sizeof(dbase_server*)*(++parent->children_count)); parent->children[parent->children_count -1] = ny; } else if (!from) { servers = ny; } else { /* BIG ERROR - got a server, but havent got it's "parent" */ } ny->parent = parent; strcpy(ny->numeric, numeric); ny->name = (char *)malloc(strlen(name)+1); strcpy(ny->name, name); ny->desc = (char *)malloc(strlen(desc)+1); strcpy(ny->desc, desc); ny->linktime = linktime; ny->children = NULL; ny->children_count = 0; }
/* serv should be db_escape'd before call */ int db_getserver(char *serv) { Server *s; int res = 0; #ifdef USE_MYSQL MYSQL_RES *mysql_res; #endif SET_SEGV_LOCATION(); s = server_find(serv); if (s && s->sqlid) { return s->sqlid; } if (!denora->do_sql) { return res; } if (!serv) { return res; } rdb_query(QUERY_HIGH, "SELECT servid FROM %s WHERE server=\'%s\'", ServerTable, serv); #ifdef USE_MYSQL mysql_res = mysql_store_result(mysql); if (mysql_res) { if (mysql_num_rows(mysql_res)) { mysql_row = mysql_fetch_row(mysql_res); res = strtol(mysql_row[0], NULL, 10); } SET_SEGV_LOCATION(); mysql_free_result(mysql_res); } #endif return res; }
int denora_event_account(char *source, int ac, char **av) { Server *s; User *u; if ((ac < 2) || !source || !(s = server_find(source))) return 0; /* source must be server. */ u = user_find(av[0]); if (!u) return 1; /* A QUIT probably passed the ACCOUNT. */ if (!strcmp(av[1], "R")) /* Set */ do_p10account(u, av[2], 0); else if (!strcmp(av[1], "M")) /* Rename */ do_p10account(u, av[2], 2); else if (!strcmp(av[1], "U")) /* Remove */ do_p10account(u, NULL, 1); else do_p10account(u, av[1], 0); /* For backward compatability */ return MOD_CONT; }
static void m_nick(sourceinfo_t *si, int parc, char *parv[]) { server_t *s; user_t *u; /* got the right number of args for an introduction? */ if (parc == 8) { s = server_find(parv[6]); if (!s) { slog(LG_DEBUG, "m_nick(): new user on nonexistant server: %s", parv[6]); return; } slog(LG_DEBUG, "m_nick(): new user on `%s': %s", s->name, parv[0]); u = user_add(parv[0], parv[4], parv[5], NULL, NULL, NULL, parv[7], s, atoi(parv[2])); if (u == NULL) return; user_mode(u, parv[3]); /* If server is not yet EOB we will do this later. * This avoids useless "please identify" -- jilles */ if (s->flags & SF_EOB) handle_nickchange(user_find(parv[0])); } /* if it's only 2 then it's a nickname change */ else if (parc == 2) { bool realchange; if (!si->su) { slog(LG_DEBUG, "m_nick(): server trying to change nick: %s", si->s != NULL ? si->s->name : "<none>"); return; } slog(LG_DEBUG, "m_nick(): nickname change from `%s': %s", si->su->nick, parv[0]); realchange = irccasecmp(si->su->nick, parv[0]); if (user_changenick(si->su, parv[0], atoi(parv[1]))) return; /* fix up +e if necessary -- jilles */ if (realchange && should_reg_umode(si->su)) /* changed nick to registered one, reset +e */ sts(":%s ENCAP * IDENTIFIED %s %s", ME, CLIENT_NAME(si->su), si->su->nick); /* It could happen that our PING arrived late and the * server didn't acknowledge EOB yet even though it is * EOB; don't send double notices in that case -- jilles */ if (si->su->server->flags & SF_EOB) handle_nickchange(si->su); } else { int i; slog(LG_DEBUG, "m_nick(): got NICK with wrong number of params"); for (i = 0; i < parc; i++) slog(LG_DEBUG, "m_nick(): parv[%d] = %s", i, parv[i]); } }
static void version_s(struct sockaddr_in *address) { char *p; time_t now = time(NULL); /* use return address on packet as host address for this server, since it isn't practical for the server to know it's own address; as is the case with multihomed machines */ char *host = inet_ntoa(address->sin_addr); if (verbose) fprintf(stderr, "server at %s responded\n", host); p = strtok(NULL,","); /* server type */ if (p == NULL) return; char type = p[0]; /* ignore paradise servers */ if (type == 'P') return; p = strtok(NULL,","); /* comment */ if (p == NULL) return; char *comment = strdup(p); if (strlen(comment) > LINE) comment[LINE] = '\0'; p = strtok(NULL,","); /* number of ports */ if (p == NULL) return; // int ports = atoi(p); /* not currently used */ // TODO: accept more than one port reply p = strtok(NULL,","); /* port */ if (p == NULL) return; int port = atoi(p); p = strtok(NULL,","); /* players */ if (p == NULL) return; int players = atoi(p); p = strtok(NULL,","); /* queue size */ if (p == NULL) return; // int queue = atoi(p); /* not currently used */ /* find in current server list? */ struct servers *sp = server_find(host, port); /* if it was not found, add it to the end of the list */ if (sp == NULL) { grow(1); sp = serverlist + num_servers; num_servers++; } /* add or update the entry */ strncpy(sp->address, host, LINE); sp->port = port; sp->age = 0; sp->when = now; sp->refresh = 1; sp->lifetime = 20; sp->players = players; if (type == 'u' && players == 0) { sp->status = statusNobody; } else { sp->status = statusOpen; } sp->typeflag = type; strncpy(sp->comment, comment, LINE); sp->pid = -1; sp->exitstatus = 0; sp->observer = 0; free(comment); }
static void version_r(struct sockaddr_in *address) { char *p; int servers, i; time_t now = time(NULL); /* number of servers */ p = strtok(NULL,"\n"); if (p == NULL) return; servers = atoi(p); /* sanity check on number of servers */ if (servers > 2048) return; if (servers < 0) return; if (verbose) fprintf(stderr, "metaserver at %s responded with %d server%s\n", inet_ntoa(address->sin_addr), servers, servers == 1 ? "" : "s" ); if (servers == 0) return; /* for each server listed by this metaserver packet */ for(i=0;i<servers;i++) { struct servers *sp = NULL; char *host, type; int port, status, age, players, queue, throwaway; throwaway = 0; host = strtok(NULL,","); /* hostname */ if (host == NULL) continue; p = strtok(NULL,","); /* port */ if (p == NULL) continue; port = atoi(p); p = strtok(NULL,","); /* status */ if (p == NULL) continue; status = atoi(p); /* ignore servers based on status */ if (status > statusLevel) throwaway++; /* the sp->why_dead workaround */ if (status == 6) if ((status - 3) <= statusLevel) throwaway--; p = strtok(NULL,","); /* age (of data in seconds) */ if (p == NULL) continue; age = atoi(p); p = strtok(NULL,","); /* players */ if (p == NULL) continue; players = atoi(p); p = strtok(NULL,","); /* queue size */ if (p == NULL) continue; queue = atoi(p); p = strtok(NULL,"\n"); /* server type */ if (p == NULL) continue; type = p[0]; /* ignore paradise servers */ if (type == 'P') throwaway++; /* if it's to be thrown away, do not add this server, skip to next */ if (throwaway) continue; /* find in current server list? */ sp = server_find(host, port); /* if it was found, check age */ if (sp != NULL) { if ((now-age) < (sp->when-sp->age)) { sp->age = now - (sp->when-sp->age); sp->when = now; sp->refresh = 1; sp->lifetime = 20; continue; } else { sp->age = age; sp->when = now; sp->lifetime = 20; } } else { /* not found, store it at the end of the list */ grow(1); sp = serverlist + num_servers; num_servers++; strncpy(sp->address,host,LINE); sp->port = port; sp->age = age; sp->when = now; sp->lifetime = 4; } sp->refresh = 1; /* from meta.h of metaserver code */ #define SS_WORKING 0 #define SS_QUEUE 1 #define SS_OPEN 2 #define SS_EMPTY 3 #define SS_NOCONN 4 #define SS_INIT 5 /* not a real metaserver number, but overcomes a limitation of dropping text */ /* description of sp->why_dead */ #define SS_TOUT 6 switch (status) { case SS_QUEUE: sp->status = statusWait; sp->players = queue; break; case SS_OPEN: sp->status = statusOpen; sp->players = players; break; case SS_EMPTY: sp->status = statusNobody; sp->players = 0; break; case SS_TOUT: sp->status = statusTout; sp->players = 0; break; case SS_NOCONN: /* no connection */ case SS_WORKING: /* metaserver should not return this */ case SS_INIT: /* nor this */ default: sp->status = statusNoConnect; sp->players = 0; break; } sp->typeflag = type; strcpy(sp->comment, ""); sp->pid = -1; sp->exitstatus = 0; sp->observer = 0; } }
static void m_nick(sourceinfo_t *si, int parc, char *parv[]) { server_t *s; user_t *u; bool realchange; /* -> NICK jilles 1 1136143909 ~jilles 192.168.1.5 jaguar.test :Jilles Tjoelker */ if (parc == 7) { s = server_find(parv[5]); if (!s) { slog(LG_DEBUG, "m_nick(): new user on nonexistant server: %s", parv[5]); return; } slog(LG_DEBUG, "m_nick(): new user on `%s': %s", s->name, parv[0]); u = user_add(parv[0], parv[3], parv[4], NULL, NULL, NULL, parv[6], s, atoi(parv[2])); if (u == NULL) return; /* Ok, we have the user ready to go. * Here's the deal -- if the user's SVID is before * the start time, and not 0, then check to see * if it's a registered account or not. * * If it IS registered, deal with that accordingly, * via handle_burstlogin(). --nenolod */ handle_nickchange(u); } /* if it's only 2 then it's a nickname change */ else if (parc == 2) { if (!si->su) { slog(LG_DEBUG, "m_nick(): server trying to change nick: %s", si->s != NULL ? si->s->name : "<none>"); return; } slog(LG_DEBUG, "m_nick(): nickname change from `%s': %s", si->su->nick, parv[0]); realchange = irccasecmp(si->su->nick, parv[0]); if (user_changenick(si->su, parv[0], atoi(parv[1]))) return; /* fix up +r if necessary -- jilles */ if (realchange && should_reg_umode(si->su)) /* changed nick to registered one, reset +r */ sts(":%s SVSMODE %s +rd %lu", nicksvs.nick, parv[0], (unsigned long)CURRTIME); handle_nickchange(si->su); } else { int i; slog(LG_DEBUG, "m_nick(): got NICK with wrong number of params"); for (i = 0; i < parc; i++) slog(LG_DEBUG, "m_nick(): parv[%d] = %s", i, parv[i]); } }
/* parses a P10 IRC stream */ static void p10_parse(char *line) { sourceinfo_t *si; char *pos; char *origin = NULL; char *command = NULL; char *message = NULL; char *parv[MAXPARC + 1]; static char coreLine[BUFSIZE]; int parc = 0; unsigned int i; pcommand_t *pcmd; /* clear the parv */ for (i = 0; i <= MAXPARC; i++) parv[i] = NULL; si = sourceinfo_create(); si->connection = curr_uplink->conn; si->output_limit = MAX_IRC_OUTPUT_LINES; if (line != NULL) { /* sometimes we'll get a blank line with just a \n on it... * catch those here... they'll core us later on if we don't */ if (*line == '\n') goto cleanup; if (*line == '\000') goto cleanup; /* copy the original line so we know what we crashed on */ memset((char *)&coreLine, '\0', BUFSIZE); mowgli_strlcpy(coreLine, line, BUFSIZE); slog(LG_RAWDATA, "-> %s", line); /* find the first space */ if ((pos = strchr(line, ' '))) { *pos = '\0'; pos++; /* if it starts with a : we have a prefix/origin * pull the origin off into `origin', and have pos for the * command, message will be the part afterwards */ if (*line == ':' || me.recvsvr) { origin = line; if (*origin == ':') { origin++; si->s = server_find(origin); si->su = user_find_named(origin); } else { si->s = server_find(origin); si->su = user_find(origin); } if ((message = strchr(pos, ' '))) { *message = '\0'; message++; command = pos; } else { command = pos; message = NULL; } } else { message = pos; command = line; } } if (!si->s && !si->su && me.recvsvr) { slog(LG_DEBUG, "p10_parse(): got message from nonexistant user or server: %s", origin); goto cleanup; } if (si->s == me.me) { slog(LG_INFO, "p10_parse(): got message supposedly from myself %s: %s", si->s->name, coreLine); goto cleanup; } if (si->su != NULL && si->su->server == me.me) { slog(LG_INFO, "p10_parse(): got message supposedly from my own client %s: %s", si->su->nick, coreLine); goto cleanup; } si->smu = si->su != NULL ? si->su->myuser : NULL; /* okay, the nasty part is over, now we need to make a * parv out of what's left */ if (message) { if (*message == ':') { message++; parv[0] = message; parc = 1; } else parc = tokenize(message, parv); } else parc = 0; /* now we should have origin (or NULL), command, and a parv * with it's accompanying parc... let's make ABSOLUTELY sure */ if (!command) { slog(LG_DEBUG, "p10_parse(): command not found: %s", coreLine); goto cleanup; } /* take the command through the hash table */ if ((pcmd = pcommand_find(command))) { if (si->su && !(pcmd->sourcetype & MSRC_USER)) { slog(LG_INFO, "p10_parse(): user %s sent disallowed command %s", si->su->nick, pcmd->token); goto cleanup; } else if (si->s && !(pcmd->sourcetype & MSRC_SERVER)) { slog(LG_INFO, "p10_parse(): server %s sent disallowed command %s", si->s->name, pcmd->token); goto cleanup; } else if (!me.recvsvr && !(pcmd->sourcetype & MSRC_UNREG)) { slog(LG_INFO, "p10_parse(): unregistered server sent disallowed command %s", pcmd->token); goto cleanup; } if (parc < pcmd->minparc) { slog(LG_INFO, "p10_parse(): insufficient parameters for command %s", pcmd->token); goto cleanup; } if (pcmd->handler) { pcmd->handler(si, parc, parv); } } } cleanup: object_unref(si); }