示例#1
0
/* SYNTAX: NAMES [-yes] [<channels>] */
static void cmd_names(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
	g_return_if_fail(data != NULL);

	if (!IS_IRC_SERVER(server) || !server->connected)
		cmd_return_error(CMDERR_NOT_CONNECTED);
	if (*data == '\0') cmd_return_error(CMDERR_NOT_GOOD_IDEA);

	if (strcmp(data, "*") == 0) {
		if (!IS_IRC_CHANNEL(item))
			cmd_return_error(CMDERR_NOT_JOINED);

		data = item->name;
	}

	if (g_strcasecmp(data, "-YES") == 0)
		irc_send_cmd(server, "NAMES");
	else
		irc_send_cmdv(server, "NAMES %s", data);
}
示例#2
0
文件: dcc.c 项目: svn2github/irssi
static void dcc_reject(DCC_REC *dcc, IRC_SERVER_REC *server)
{
    char *str;

    g_return_if_fail(dcc != NULL);

    if (dcc->server != NULL) server = dcc->server;
    if (server != NULL && (dcc->type != DCC_TYPE_CHAT || dcc->starttime == 0))
    {
        signal_emit("dcc rejected", 1, dcc);
        str = g_strdup_printf("NOTICE %s :\001DCC REJECT %s %s\001",
                              dcc->nick, dcc_type2str(SWAP_SENDGET(dcc->type)), dcc->arg);

        irc_send_cmd(server, str);
        g_free(str);
    }

    signal_emit("dcc closed", 1, dcc);
    dcc_destroy(dcc);
}
示例#3
0
/* command: DCC CHAT */
static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
{
	DCC_REC *dcc;
	IPADDR own_ip;
	char *str, host[MAX_IP_LEN];
	int port, handle;

	g_return_if_fail(data != NULL);
	if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);

	dcc = dcc_find_item(DCC_TYPE_CHAT, data, NULL);
	if (dcc != NULL) {
		/* found from dcc list - so we're the connecting side.. */
		dcc_chat_connect(dcc);
		return;
	}

	/* send dcc chat request */
	if (server == NULL || !server->connected)
		cmd_return_error(CMDERR_NOT_CONNECTED);

	if (net_getsockname(server->handle, &own_ip, NULL) == -1)
		cmd_return_error(CMDERR_ERRNO);

	port = settings_get_int("dcc_port");
	handle = net_listen(&own_ip, &port);
	if (handle == -1)
		cmd_return_error(CMDERR_ERRNO);

	dcc = dcc_create(DCC_TYPE_CHAT, handle, data, "chat", server, NULL);
	dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ,
				   (GInputFunction) dcc_chat_listen, dcc);

	/* send the request */
	dcc_make_address(&own_ip, host);
	str = g_strdup_printf("PRIVMSG %s :\001DCC CHAT CHAT %s %d\001",
			      data, host, port);
	irc_send_cmd(server, str);
	g_free(str);
}
示例#4
0
static void query_send(IRC_SERVER_REC *server, int query)
{
	SERVER_QUERY_REC *rec;
	IRC_CHANNEL_REC *chanrec;
	GSList *chans;
	char *cmd, *chanstr_commas, *chanstr;
	int onlyone, count;

	rec = server->chanqueries;

        /* get the list of channels to query */
	onlyone = (server->no_multi_who && query == CHANNEL_QUERY_WHO) ||
		(server->no_multi_mode && CHANNEL_IS_MODE_QUERY(query));

	if (onlyone) {
                chans = rec->queries[query];
		rec->queries[query] =
			g_slist_remove_link(rec->queries[query], chans);

		chanrec = chans->data;
		chanstr_commas = g_strdup(chanrec->name);
		chanstr = g_strdup(chanrec->name);
                count = 1;
	} else {
		char *chanstr_spaces;

		chans = rec->queries[query];
                count = g_slist_length(chans);

		if (count > server->max_query_chans) {
			GSList *lastchan;

			lastchan = g_slist_nth(rec->queries[query],
					       server->max_query_chans-1);
                        count = server->max_query_chans;
			rec->queries[query] = lastchan->next;
			lastchan->next = NULL;
		} else {
                        rec->queries[query] = NULL;
		}

		chanstr_commas = gslistptr_to_string(chans, G_STRUCT_OFFSET(IRC_CHANNEL_REC, name), ",");
		chanstr_spaces = gslistptr_to_string(chans, G_STRUCT_OFFSET(IRC_CHANNEL_REC, name), " ");

		chanstr = g_strconcat(chanstr_commas, " ", chanstr_spaces, NULL);
		g_free(chanstr_spaces);
	}

	rec->current_query_type = query;
        rec->current_queries = chans;

	switch (query) {
	case CHANNEL_QUERY_MODE:
		cmd = g_strdup_printf("MODE %s", chanstr_commas);

		/* the stop-event is received once for each channel,
		   and we want to print 329 event (channel created). */
		server_redirect_event(server, "mode channel", count,
				      chanstr, -1, "chanquery abort",
				      "event 324", "chanquery mode",
                                      "event 329", "event 329",
				      "", "chanquery abort", NULL);
		break;

	case CHANNEL_QUERY_WHO:
		cmd = g_strdup_printf("WHO %s", chanstr_commas);

		server_redirect_event(server, "who",
				      server->one_endofwho ? 1 : count,
				      chanstr, -1,
				      "chanquery abort",
				      "event 315", "chanquery who end",
				      "event 352", "silent event who",
				      "", "chanquery abort", NULL);
		break;

	case CHANNEL_QUERY_BMODE:
		cmd = g_strdup_printf("MODE %s b", chanstr_commas);
		/* check all the multichannel problems with all
		   mode requests - if channels are joined manually
		   irssi could ask modes separately but afterwards
		   join the two b/e/I modes together */
		server_redirect_event(server, "mode b", count, chanstr, -1,
				      "chanquery abort",
				      "event 367", "chanquery ban",
				      "event 368", "chanquery ban end",
				      "", "chanquery abort", NULL);
		break;

	default:
                cmd = NULL;
	}

	irc_send_cmd(server, cmd);

	g_free(chanstr);
	g_free(chanstr_commas);
	g_free(cmd);
}
示例#5
0
static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args,
			      const char *data)
{
	GSList *tmp;
	if (!client->connected) {
		handle_client_connect_cmd(client, cmd, args);
		return;
	}

	if (g_strcmp0(cmd, "QUIT") == 0) {
		remove_client(client);
		return;
	}

	if (g_strcmp0(cmd, "PING") == 0) {
		/* Reply to PING, if the target parameter is either
		   proxy_adress, our own nick or empty. */
		char *params, *origin, *target;

		params = event_get_params(args, 2, &origin, &target);
		if (*target == '\0' ||
		    g_ascii_strcasecmp(target, client->proxy_address) == 0 ||
		    g_ascii_strcasecmp(target, client->nick) == 0) {
			proxy_outdata(client, ":%s PONG %s :%s\r\n",
				      client->proxy_address,
                                      client->proxy_address, origin);
			g_free(params);
			return;
		}
		g_free(params);
	}

	if (g_strcmp0(cmd, "PROXY") == 0) {
		if (g_ascii_strcasecmp(args, "CTCP ON") == 0) {
                        /* client wants all ctcps */
			client->want_ctcp = 1;
	                for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
				CLIENT_REC *rec = tmp->data;
				if ((g_ascii_strcasecmp(client->listen->ircnet,rec->listen->ircnet) == 0) &&
					/* kludgy way to check if the clients aren't the same */
					(client->recv_tag != rec->recv_tag)) {
						if (rec->want_ctcp == 1)
							proxy_outdata(rec, ":%s NOTICE %s :Another client is now receiving CTCPs sent to %s\r\n",
			                                      rec->proxy_address, rec->nick, rec->listen->ircnet);
						rec->want_ctcp = 0;
		                }

			}
			proxy_outdata(client, ":%s NOTICE %s :You're now receiving CTCPs sent to %s\r\n",
				      client->proxy_address, client->nick,client->listen->ircnet);
		} else if (g_ascii_strcasecmp(args, "CTCP OFF") == 0) {
                        /* client wants proxy to handle all ctcps */
			client->want_ctcp = 0;
			proxy_outdata(client, ":%s NOTICE %s :Proxy is now handling itself CTCPs sent to %s\r\n",
				      client->proxy_address, client->nick, client->listen->ircnet);
		} else {
			signal_emit("proxy client command", 3, client, args, data);
		}
		return;
	}

	if (client->server == NULL || !client->server->connected) {
		proxy_outdata(client, ":%s NOTICE %s :Not connected to server\r\n",
			      client->proxy_address, client->nick);
                return;
	}

        /* check if the command could be redirected */
	if (g_strcmp0(cmd, "WHO") == 0)
		grab_who(client, args);
	else if (g_strcmp0(cmd, "WHOWAS") == 0)
		proxy_redirect_event(client, "whowas", 1, args, -1);
	else if (g_strcmp0(cmd, "WHOIS") == 0) {
		char *p;

		/* convert dots to spaces */
		for (p = args; *p != '\0'; p++)
			if (*p == ',') *p = ' ';

		proxy_redirect_event(client, "whois", 1, args, TRUE);
	} else if (g_strcmp0(cmd, "ISON") == 0)
		proxy_redirect_event(client, "ison", 1, args, -1);
	else if (g_strcmp0(cmd, "USERHOST") == 0)
		proxy_redirect_event(client, "userhost", 1, args, -1);
	else if (g_strcmp0(cmd, "MODE") == 0) {
		/* convert dots to spaces */
		char *slist, *str, mode, *p;
		int argc;

		p = strchr(args, ' ');
		if (p != NULL) *p++ = '\0';
		mode = p == NULL ? '\0' : *p;

		slist = g_strdup(args);
		argc = 1;
		for (p = slist; *p != '\0'; p++) {
			if (*p == ',') {
				*p = ' ';
				argc++;
			}
		}

		/* get channel mode / bans / exception / invite list */
		str = g_strdup_printf("%s %s", args, slist);
		switch (mode) {
		case '\0':
			proxy_redirect_event(client, "mode channel", argc, str, -1);
			break;
		case 'b':
			proxy_redirect_event(client, "mode b", argc, str, -1);
			break;
		case 'e':
			proxy_redirect_event(client, "mode e", argc, str, -1);
			break;
		case 'I':
			proxy_redirect_event(client, "mode I", argc, str, -1);
			break;
		}
		g_free(str);
		g_free(slist);
	} else if (g_strcmp0(cmd, "PRIVMSG") == 0) {
		/* send the message to other clients as well */
		char *params, *target, *msg;

		params = event_get_params(args, 2 | PARAM_FLAG_GETREST,
					  &target, &msg);
		proxy_outserver_all_except(client, "PRIVMSG %s", args);

		ignore_next = TRUE;
		if (*msg != '\001' || msg[strlen(msg)-1] != '\001') {
	        	signal_emit(ischannel(*target) ?
				    "message own_public" : "message own_private", 4,
				    client->server, msg, target, target);
		} else if (strncmp(msg+1, "ACTION ", 7) == 0) {
			/* action */
                        msg[strlen(msg)-1] = '\0';
			signal_emit("message irc own_action", 3,
				    client->server, msg+8, target);
		} else {
                        /* CTCP */
			char *p;

			msg[strlen(msg)-1] = '\0';
			p = strchr(msg, ' ');
                        if (p != NULL) *p++ = '\0'; else p = "";

			signal_emit("message irc own_ctcp", 4,
				    client->server, msg+1, p, target);
		}
		ignore_next = FALSE;
		g_free(params);
	} else if (g_strcmp0(cmd, "PING") == 0) {
		proxy_redirect_event(client, "ping", 1, NULL, TRUE);
	} else if (g_strcmp0(cmd, "AWAY") == 0) {
		/* set the away reason */
		if (args != NULL) {
			g_free(client->server->away_reason);
			client->server->away_reason = g_strdup(args);
		}
	}

	irc_send_cmd(client->server, data);
}
示例#6
0
/*
 * putchan_raw <server_tag> <#chan> <text>
 * Use this instead of putserv so that can see own message
 *
 * "raw" because putchan in Tcl will do some string fixing on text
 *
 * all command parameters should be using unicode (internal) encoding.
 */
int
putchan_raw(ClientData clientData, Tcl_Interp* interp, int objc,
	Tcl_Obj* const objv[])
{
	(void) clientData;

	if (objc != 4) {
		Tcl_Obj* str = Tcl_ObjPrintf("wrong # args: should be \"putchan_raw"
			" server_tag channel text\"");
		Tcl_SetObjResult(interp, str);
		return TCL_ERROR;
	}
	Tcl_Obj* const server_tag = objv[1];
	Tcl_Obj* const target = objv[2];
	Tcl_Obj* const msg = objv[3];

	// find the server in Irssi.
	SERVER_REC* server_rec = server_find_tag(Tcl_GetString(server_tag));
	if (server_rec == NULL) {
		Tcl_Obj* str = Tcl_ObjPrintf("server with tag '%s' not found",
			Tcl_GetString(server_tag));
		Tcl_SetObjResult(interp, str);
		return TCL_ERROR;
	}
	// find the channel on this server in Irssi.
	CHANNEL_REC* channel_rec = channel_find(server_rec, Tcl_GetString(target));
	if (channel_rec == NULL) {
		Tcl_Obj* str = Tcl_ObjPrintf("channel '%s' not found on server '%s'",
			Tcl_GetString(target), Tcl_GetString(server_tag));
		Tcl_SetObjResult(interp, str);
		return TCL_ERROR;
	}

	// create the full command string to send to the IRC server.
	// PRIVMSG <target> :<msg>

	// this is how we used to create the command but I am concerned it
	// is not dealing with encoding correctly.
	//Tcl_Obj* send_str = Tcl_ObjPrintf("PRIVMSG %s :%s", target, msg);

	// try to be more careful with how we build the string.
	// -1 means take everything up to first NULL.
	Tcl_Obj* send_str = Tcl_NewStringObj("PRIVMSG ", -1);
	if (!send_str) {
		return TCL_ERROR;
	}
	Tcl_AppendObjToObj(send_str, target);
	Tcl_AppendToObj(send_str, " :", strlen(" :"));
	Tcl_AppendObjToObj(send_str, msg);

	// send the command to the server.
	// from ByteArrObj docs:
	// "Obtaining the string representation of a byte-array object (by calling Tcl_GetStringFromObj) produces a properly formed UTF-8 sequence with a one-to-one mapping between the bytes in the internal representation and the UTF-8 characters in the string representation."
	irc_send_cmd((IRC_SERVER_REC*) server_rec, Tcl_GetString(send_str));
	// this frees the object. unsure if I actually need to call this, but it
	// seems like it doesn't matter if I do!
	Tcl_DecrRefCount(send_str);

	// write the message to Irssi so we see it ourselves.
	print_message_public(server_rec, channel_rec, Tcl_GetString(target),
		server_rec->nick, NULL, Tcl_GetString(msg));

	//signal_emit("message own_public", 3, server, text, chan);
	return TCL_OK;
}
示例#7
0
文件: irc.c 项目: 91D2/pvpgn
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;
}
示例#8
0
文件: irc.c 项目: 91D2/pvpgn
extern int irc_authenticate(t_connection * conn, char const * passhash)
{
    t_hash h1;
    t_hash h2;
    t_account * a;
    char const * temphash;
    char const * username;

    char const * tempapgar;

    if (!conn) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
	return 0;
    }
    if (!passhash) {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL passhash");
	return 0;
    }
    username = conn_get_loggeduser(conn);
    if (!username) {
	/* redundant sanity check */
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn->protocol.loggeduser");
	return 0;
    }
    a = accountlist_find_account(username);
    if (!a) {
    	irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* user does not exist */
	return 0;
    }

    if (connlist_find_connection_by_account(a) && prefs_get_kick_old_login()==0) {
            irc_send_cmd(conn,"NOTICE",":Authentication rejected (already logged in) ");
    }
    else if (account_get_auth_lock(a)==1) {
            irc_send_cmd(conn,"NOTICE",":Authentication rejected (account is locked) "); 
    }
    else
    {
     	if((conn_get_wol(conn) == 1)) {
    	    temphash = account_get_wol_apgar(a);
    	    tempapgar = conn_wol_get_apgar(conn);
    	    
    	    if(temphash == NULL) {
        		account_set_wol_apgar(a,tempapgar);
        		temphash = account_get_wol_apgar(a);
    	    }
    	    
    	    if(tempapgar == NULL) {
                irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* bad APGAR */
                conn_increment_passfail_count(conn);
                return 0;
            }
    	    
    	    if(strcmp(temphash,tempapgar) == 0) {
				bnetd_log(username, addr_num_to_ip_str(conn_get_addr(conn)), "IRC", "LOGIN", NULL, 1, 0);
                conn_login(conn,a,username);
    	        conn_set_state(conn,conn_state_loggedin);
        	    conn_set_clienttag(conn,CLIENTTAG_WWOL_UINT); /* WWOL hope here is ok */
        		return 1;
    	    }
    	    else {
        		conn_increment_passfail_count(conn);
        		return 0;
    	    }
    	}

        hash_set_str(&h1,passhash);
        temphash = account_get_pass(a);	
        hash_set_str(&h2,temphash);
        if (hash_eq(h1,h2)) {
			bnetd_log(username, addr_num_to_ip_str(conn_get_addr(conn)), "IRC", "LOGIN", NULL, 1, 0);
            conn_login(conn,a,username);
            conn_set_state(conn,conn_state_loggedin);
            conn_set_clienttag(conn,CLIENTTAG_IIRC_UINT); /* IIRC hope here is ok */
            irc_send_cmd(conn,"NOTICE",":Authentication successful. You are now logged in.");
	    return 1;
        } else {
            irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* wrong password */
	    conn_increment_passfail_count(conn);
        }
    }
    return 0;
}