ii-1.8-usernames.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
ii-1.8-usernames.diff (6438B)
---
1 diff --git a/ii.c b/ii.c
2 index 6583792..f5ed614 100644
3 --- a/ii.c
4 +++ b/ii.c
5 @@ -33,15 +33,23 @@ size_t strlcpy(char *, const char *, size_t);
6
7 enum { TOK_NICKSRV = 0, TOK_USER, TOK_CMD, TOK_CHAN, TOK_ARG, TOK_TEXT, TOK_LAST };
8
9 +typedef struct Nick Nick;
10 +struct Nick {
11 + char name[32];
12 + Nick *next;
13 +};
14 +
15 typedef struct Channel Channel;
16 struct Channel {
17 int fdin;
18 char name[IRC_CHANNEL_MAX]; /* channel name (normalized) */
19 char inpath[PATH_MAX]; /* input path */
20 char outpath[PATH_MAX]; /* output path */
21 + Nick *nicks;
22 Channel *next;
23 };
24
25 +static void add_name(Channel *, const char *);
26 static Channel * channel_add(const char *);
27 static Channel * channel_find(const char *);
28 static Channel * channel_join(const char *);
29 @@ -61,10 +69,14 @@ static void handle_server_output(int);
30 static int isnumeric(const char *);
31 static void loginkey(int, const char *);
32 static void loginuser(int, const char *, const char *);
33 +static void nick_name(const char *, const char *);
34 static void proc_channels_input(int, Channel *, char *);
35 static void proc_channels_privmsg(int, Channel *, char *);
36 +static void proc_names(Channel *, char *);
37 static void proc_server_cmd(int, char *);
38 +static void quit_name(const char *, const char *, const char *);
39 static int read_line(int, char *, size_t);
40 +static int rm_name(Channel *, const char *);
41 static void run(int, const char *);
42 static void setup(void);
43 static void sighandler(int);
44 @@ -236,6 +248,7 @@ channel_new(const char *name)
45 c->next = NULL;
46 strlcpy(c->name, name, sizeof(c->name));
47 channel_normalize_name(c->name);
48 + c->nicks = NULL;
49
50 create_filepath(c->inpath, sizeof(c->inpath), ircpath,
51 channelpath, "in");
52 @@ -294,6 +307,7 @@ static void
53 channel_rm(Channel *c)
54 {
55 Channel *p;
56 + Nick *n, *nn;
57
58 if (channels == c) {
59 channels = channels->next;
60 @@ -303,6 +317,10 @@ channel_rm(Channel *c)
61 if (p && p->next == c)
62 p->next = c->next;
63 }
64 + for (n = c->nicks; n; n = nn) {
65 + nn = n->next;
66 + free(n);
67 + }
68 free(c);
69 }
70
71 @@ -318,6 +336,70 @@ channel_leave(Channel *c)
72 channel_rm(c);
73 }
74
75 +static void
76 +add_name(Channel *c, const char *name) {
77 + Nick *n;
78 + for (n = c->nicks; n; n = n->next)
79 + if (!strcmp(name, n->name)) return;
80 + if (!(n = calloc(1, sizeof(Nick)))) {
81 + fprintf(stderr, "%s: calloc: %s\n", argv0, strerror(errno));
82 + exit(1);
83 + }
84 + strlcpy(n->name, name, sizeof(n->name));
85 + n->next = c->nicks;
86 + c->nicks = n;
87 +}
88 +
89 +static int
90 +rm_name(Channel *c, const char *name) {
91 + Nick *n, *pn = NULL;
92 + for (n = c->nicks; n; pn = n, n = n->next) {
93 + if (!strcmp(name, n->name)) {
94 + if (pn)
95 + pn->next = n->next;
96 + else
97 + c->nicks = n->next;
98 + free(n);
99 + return 1;
100 + }
101 + }
102 + return 0;
103 +}
104 +
105 +static void
106 +proc_names(Channel *c, char *names) {
107 + char *p;
108 + if (!(p = strtok(names," "))) return;
109 + do {
110 + if (*p == '@' || *p == '+')
111 + p++;
112 + add_name(c,p);
113 + } while ((p = strtok(NULL," ")));
114 +}
115 +
116 +static void
117 +quit_name(const char *name, const char *user, const char *text) {
118 + Channel *c;
119 + for (c = channels; c; c = c->next) {
120 + if (rm_name(c, name)) {
121 + snprintf(msg, PIPE_BUF, "-!- %s(%s) has quit \"%s\"", name, user, text ? text : "");
122 + channel_print(c, msg);
123 + }
124 + }
125 +}
126 +
127 +static void
128 +nick_name(const char *old, const char *new) {
129 + Channel *c;
130 + for (c = channels; c; c = c->next) {
131 + if (rm_name(c, old)) {
132 + add_name(c, new);
133 + snprintf(msg, PIPE_BUF, "-!- %s changed nick to \"%s\"", old, new);
134 + channel_print(c, msg);
135 + }
136 + }
137 +}
138 +
139 static void
140 loginkey(int ircfd, const char *key)
141 {
142 @@ -590,6 +672,15 @@ proc_server_cmd(int fd, char *buf)
143 snprintf(msg, sizeof(msg), "PONG %s\r\n", argv[TOK_TEXT]);
144 ewritestr(fd, msg);
145 return;
146 + } else if (!strcmp("353", argv[TOK_CMD])) {
147 + p = strtok(argv[TOK_ARG]," ");
148 + if (!(p = strtok(NULL," ")))
149 + return;
150 + snprintf(msg, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
151 + channel_print(channelmaster, msg);
152 + if ((c = channel_find(p)))
153 + proc_names(c, argv[TOK_TEXT]);
154 + return;
155 } else if (!argv[TOK_NICKSRV] || !argv[TOK_USER]) {
156 /* server command */
157 snprintf(msg, sizeof(msg), "%s%s",
158 @@ -605,9 +696,13 @@ proc_server_cmd(int fd, char *buf)
159 argv[TOK_CHAN] = argv[TOK_TEXT];
160 snprintf(msg, sizeof(msg), "-!- %s(%s) has joined %s",
161 argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_CHAN]);
162 + if ((c = channel_find(argv[TOK_CHAN])))
163 + add_name(c, argv[TOK_NICKSRV]);
164 } else if (!strcmp("PART", argv[TOK_CMD]) && argv[TOK_CHAN]) {
165 snprintf(msg, sizeof(msg), "-!- %s(%s) has left %s",
166 argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_CHAN]);
167 + if ((c = channel_find(argv[TOK_CHAN])))
168 + rm_name(c, argv[TOK_NICKSRV]);
169 /* if user itself leaves, don't write to channel (don't reopen channel). */
170 if (!strcmp(argv[TOK_NICKSRV], nick))
171 return;
172 @@ -618,17 +713,18 @@ proc_server_cmd(int fd, char *buf)
173 argv[TOK_ARG] ? argv[TOK_ARG] : "",
174 argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
175 } else if (!strcmp("QUIT", argv[TOK_CMD])) {
176 - snprintf(msg, sizeof(msg), "-!- %s(%s) has quit \"%s\"",
177 - argv[TOK_NICKSRV], argv[TOK_USER],
178 - argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
179 + quit_name(argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_TEXT]);
180 + return;
181 } else if (!strncmp("NICK", argv[TOK_CMD], 5) && argv[TOK_TEXT] &&
182 !strcmp(_nick, argv[TOK_TEXT])) {
183 strlcpy(nick, _nick, sizeof(nick));
184 snprintf(msg, sizeof(msg), "-!- changed nick to \"%s\"", nick);
185 channel_print(channelmaster, msg);
186 + nick_name(argv[TOK_NICKSRV], argv[TOK_TEXT]);
187 + return;
188 } else if (!strcmp("NICK", argv[TOK_CMD]) && argv[TOK_TEXT]) {
189 - snprintf(msg, sizeof(msg), "-!- %s changed nick to %s",
190 - argv[TOK_NICKSRV], argv[TOK_TEXT]);
191 + nick_name(argv[TOK_NICKSRV], argv[TOK_TEXT]);
192 + return;
193 } else if (!strcmp("TOPIC", argv[TOK_CMD])) {
194 snprintf(msg, sizeof(msg), "-!- %s changed topic to \"%s\"",
195 argv[TOK_NICKSRV],
196 @@ -637,6 +733,8 @@ proc_server_cmd(int fd, char *buf)
197 snprintf(msg, sizeof(msg), "-!- %s kicked %s (\"%s\")",
198 argv[TOK_NICKSRV], argv[TOK_ARG],
199 argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
200 + if ((c = channel_find(argv[TOK_CHAN])))
201 + rm_name(c, argv[TOK_ARG]);
202 } else if (!strcmp("NOTICE", argv[TOK_CMD])) {
203 snprintf(msg, sizeof(msg), "-!- \"%s\")",
204 argv[TOK_TEXT] ? argv[TOK_TEXT] : "");