aboutsummaryrefslogtreecommitdiffstats
path: root/irc.c
blob: 583242199ce98cbdfe7fa3bdd867b8d08b90f301 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

#include <sys/socket.h>
#include <sys/types.h>

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "irc.h"

static int tcp_connect(const char *host, int port)
{
	struct sockaddr_in addr;
	struct hostent *h;
	int sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
		return sock;

	h = gethostbyname(host);
	if (h == NULL)
		return -1;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
	memcpy(&addr.sin_addr, h->h_addr, h->h_length);
        if (connect(sock, (struct sockaddr *) &addr, 
	    sizeof(struct sockaddr_in))) {
		close(sock);
		sock = -1;
	}
	return sock;
}

struct irc_session *irc_connect(const char* server, int port, const char *nick,
				const char *pass)
{
	char buf[256];
	struct irc_session *sess;

	sess = malloc(sizeof(struct irc_session));
	if (sess == NULL)
		return NULL;

	sess->nick = nick;
	sess->server = server;
	sess->fd = tcp_connect(server, port);
	if (sess->fd < 0)
		return NULL;

	/* login */
	if (pass)
		irc_send(sess, "PASS", pass);
	irc_send(sess, "NICK", nick);
	snprintf(buf, sizeof(buf), "%s localhost %s :%s", nick, server, nick);
	irc_send(sess, "USER", buf);
	return sess;
}

int irc_send(struct irc_session *s, const char *command, const char *args)
{
	char buf[4096];
	snprintf(buf, sizeof(buf), "%s %s\r\n", command, args);
	return write(s->fd, buf, strlen(buf));
}

int irc_send_chan(struct irc_session *s, const char *chan, const char *msg)
{
	char buf[4096];
	snprintf(buf, sizeof(buf), "%s :%s", chan, msg);
	return irc_send(s, "PRIVMSG", buf);
}

int irc_send_ping(struct irc_session *s)
{
	return irc_send(s, "PING", s->server);
}

int irc_close(struct irc_session *s, const char *msg)
{
	if (s->fd > 0) {
		irc_send(s, "QUIT", msg ? msg : "");
		close(s->fd);
	}
	free(s);
}