ii-1.8-usernames.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
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,… | |
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(err… | |
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 \"… | |
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… | |
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[TO… | |
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… | |
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… | |
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… | |
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_T… | |
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\""… | |
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 \"%… | |
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] : ""); |