Prevent wrapper.c from flooding the IRC server.
[iii.git] / patches / ii-1.4-usernames.diff
blobe2e599e8d358e63fc5b00ad5c9a035aad8aa0fa2
1 diff -r d93eaacde742 ii.c
2 --- a/ii.c Fri Jun 25 10:55:05 2010 +0200
3 +++ b/ii.c Tue Jul 27 17:48:23 2010 -0500
4 @@ -26,10 +26,17 @@
6 enum { TOK_NICKSRV = 0, TOK_USER, TOK_CMD, TOK_CHAN, TOK_ARG, TOK_TEXT, TOK_LAST };
8 +typedef struct Nick Nick;
9 +struct Nick {
10 + char *name;
11 + Nick *next;
12 +};
14 typedef struct Channel Channel;
15 struct Channel {
16 int fd;
17 char *name;
18 + Nick *nicks;
19 Channel *next;
22 @@ -128,18 +135,25 @@
23 c->next = channels;
24 channels = c;
26 + c->nicks = NULL;
27 c->fd = fd;
28 c->name = strdup(name);
31 static void rm_channel(Channel *c) {
32 Channel *p;
33 + Nick *n, *nn;
34 if(channels == c) channels = channels->next;
35 else {
36 for(p = channels; p && p->next != c; p = p->next);
37 if(p->next == c)
38 p->next = c->next;
40 + for(n = c->nicks; n; n = nn) {
41 + nn = n->next;
42 + free(n->name);
43 + free(n);
44 + }
45 free(c->name);
46 free(c);
48 @@ -217,6 +231,76 @@
49 fclose(out);
52 +static Channel *lookup_chan(const char *name) {
53 + Channel *c;
54 + for(c = channels; c; c = c->next)
55 + if(!strcmp(name, c->name))
56 + return c;
57 + return NULL;
60 +static void add_name(const char *chan, const char *name) {
61 + Channel *c;
62 + Nick *n;
63 + if(!(c = lookup_chan(chan))) return;
64 + for(n = c->nicks; n; n = n->next)
65 + if(!strcmp(name, n->name)) return;
66 + if(!(n = malloc(sizeof(Nick)))) {
67 + perror("ii: cannot allocate memory");
68 + exit(EXIT_FAILURE);
69 + }
70 + n->name = strdup(name);
71 + n->next = c->nicks;
72 + c->nicks = n;
75 +static int rm_name(const char *chan, const char *name) {
76 + Channel *c;
77 + Nick *n, *pn = NULL;
78 + if(!(c = lookup_chan(chan))) return 0;
79 + for(n = c->nicks; n; pn = n, n = n->next) {
80 + if(!strcmp(name, n->name)) {
81 + if(pn) pn->next = n->next;
82 + else c->nicks = n->next;
83 + free(n->name);
84 + free(n);
85 + return 1;
86 + }
87 + }
88 + return 0;
91 +static void proc_names(const char *chan, char *names) {
92 + char *p;
93 + if(!(p = strtok(names," "))) return;
94 + do {
95 + if(*p == '@' || *p == '+')
96 + p++;
97 + add_name(chan,p);
98 + } while((p = strtok(NULL," ")));
101 +static void quit_name(const char *name, const char *user, const char *text) {
102 + Channel *c;
103 + for(c = channels; c; c = c->next) {
104 + if(c->name && rm_name(c->name, name)) {
105 + snprintf(message, PIPE_BUF, "-!- %s(%s) has quit \"%s\"", name, user, text ? text : "");
106 + print_out(c->name, message);
111 +static void nick_name(const char *old, const char *new) {
112 + Channel *c;
113 + for(c = channels; c; c = c->next) {
114 + if(c->name && rm_name(c->name, old)) {
115 + add_name(c->name, new);
116 + snprintf(message, PIPE_BUF, "-!- %s changed nick to \"%s\"", old, new);
117 + print_out(c->name, message);
122 static void proc_channels_privmsg(char *channel, char *buf) {
123 snprintf(message, PIPE_BUF, "<%s> %s", nick, buf);
124 print_out(channel, message);
125 @@ -342,6 +426,14 @@
126 snprintf(message, PIPE_BUF, "PONG %s\r\n", argv[TOK_TEXT]);
127 write(irc, message, strlen(message));
128 return;
129 + } else if(!strncmp("353", argv[TOK_CMD], 4)) {
130 + p = strtok(argv[TOK_ARG]," ");
131 + if(!(p = strtok(NULL," ")))
132 + return;
133 + snprintf(message, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
134 + print_out(0, message);
135 + proc_names(p, argv[TOK_TEXT]);
136 + return;
137 } else if(!argv[TOK_NICKSRV] || !argv[TOK_USER]) { /* server command */
138 snprintf(message, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
139 print_out(0, message);
140 @@ -356,19 +448,24 @@
142 argv[TOK_CHAN] = argv[TOK_TEXT];
143 snprintf(message, PIPE_BUF, "-!- %s(%s) has joined %s", argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_TEXT]);
144 + add_name(argv[TOK_CHAN],argv[TOK_NICKSRV]);
145 } else if(!strncmp("PART", argv[TOK_CMD], 5)) {
146 snprintf(message, PIPE_BUF, "-!- %s(%s) has left %s", argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_CHAN]);
147 + rm_name(argv[TOK_CHAN],argv[TOK_NICKSRV]);
148 } else if(!strncmp("MODE", argv[TOK_CMD], 5))
149 snprintf(message, PIPE_BUF, "-!- %s changed mode/%s -> %s %s", argv[TOK_NICKSRV], argv[TOK_CMD + 1] ? argv[TOK_CMD + 1] : "" , argv[TOK_CMD + 2]? argv[TOK_CMD + 2] : "", argv[TOK_CMD + 3] ? argv[TOK_CMD + 3] : "");
150 - else if(!strncmp("QUIT", argv[TOK_CMD], 5))
151 - snprintf(message, PIPE_BUF, "-!- %s(%s) has quit \"%s\"", argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
152 - else if(!strncmp("NICK", argv[TOK_CMD], 5))
153 - snprintf(message, PIPE_BUF, "-!- %s changed nick to %s", argv[TOK_NICKSRV], argv[TOK_TEXT]);
154 - else if(!strncmp("TOPIC", argv[TOK_CMD], 6))
155 + else if(!strncmp("QUIT", argv[TOK_CMD], 5)) {
156 + quit_name(argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_TEXT]);
157 + return;
158 + } else if(!strncmp("NICK", argv[TOK_CMD], 5)) {
159 + nick_name(argv[TOK_NICKSRV], argv[TOK_TEXT]);
160 + return;
161 + } else if(!strncmp("TOPIC", argv[TOK_CMD], 6))
162 snprintf(message, PIPE_BUF, "-!- %s changed topic to \"%s\"", argv[TOK_NICKSRV], argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
163 - else if(!strncmp("KICK", argv[TOK_CMD], 5))
164 + else if(!strncmp("KICK", argv[TOK_CMD], 5)) {
165 snprintf(message, PIPE_BUF, "-!- %s kicked %s (\"%s\")", argv[TOK_NICKSRV], argv[TOK_ARG], argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
166 - else if(!strncmp("NOTICE", argv[TOK_CMD], 7))
167 + rm_name(argv[TOK_CHAN],argv[TOK_NICKSRV]);
168 + } else if(!strncmp("NOTICE", argv[TOK_CMD], 7))
169 snprintf(message, PIPE_BUF, "-!- \"%s\")", argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
170 else if(!strncmp("PRIVMSG", argv[TOK_CMD], 8))
171 snprintf(message, PIPE_BUF, "<%s> %s", argv[TOK_NICKSRV], argv[TOK_TEXT] ? argv[TOK_TEXT] : "");