1 /*  chat_user.c
2  *
3  *  copyright (c) 2000-2003 SeaD
4  *  see GPL for copying info
5  *
6  */
7 
8 #include <string.h>
9 #include "echat.h"
10 
11 #define SORT_LEN        8
12 
user_parse(void)13 void user_parse(void) {
14     register int n, m;
15 
16     for (m = 0; m < status->users; m++) {
17         for (n = 0; n < NICK_MAXLEN; n++)
18             if (buf[n] != status->user[m].nick[n]) break;
19         if ((buf[n] == CHR_NICK) && (n == strlen(status->user[m].nick))) {
20             strncpy(status->nick, status->user[m].nick, NICK_MAXLEN);
21             for (buf[n+1] = '\0'; n < STR_SIZE-n; n++) buf[n] = buf[n+1];
22             return;
23         }
24         if (((buf[n] == ' ') || (buf[n] == '\0')) && (n == strlen(status->user[m].nick))) {
25             strncpy(status->nick, status->user[m].nick, NICK_MAXLEN);
26             buf[n] = '\0';
27             return;
28         }
29         continue;
30     }
31     for (n = 0; n < NICK_MAXLEN; n++)
32         if ((buf[n] == ' ') || (buf[n] == '\0')) { buf[n] = '\0'; break; }
33     strncpy(status->nick, buf, NICK_MAXLEN);
34 }
35 
user_swap(struct user_t * user1,struct user_t * user2)36 void user_swap(struct user_t *user1, struct user_t *user2) {
37     struct user_t swp;
38 
39     memcpy(&swp, user1, sizeof(struct user_t));
40     memcpy(user1, user2, sizeof(struct user_t));
41     memcpy(user2, &swp, sizeof(struct user_t));
42 }
43 
user_sort(void)44 void user_sort(void) {
45     int fvr = 0;
46     register int n, m, l;
47 
48     for (n = 0; n < status->users; n++)
49         if (status->user[n].favorite) fvr++;
50     for (m = 0; m < fvr; m++)
51         for (n = fvr; n < status->users; n++)
52             if (status->user[m].favorite) break;
53             else if (status->user[n].favorite) {
54                 user_swap(&status->user[m], &status->user[n]); break;
55             }
56     for (l = SORT_LEN; l >= 0; l--)
57         for (m = fvr; m < status->users; m++)
58             for (n = fvr; n < status->users; n++)
59                 if (status->user_sort) {
60                     if (status->user[m].nick[l] == '\0') break;
61                     if ((unsigned char) status->user[m].nick[l] > (unsigned char) status->user[n].nick[l])
62                         user_swap(&status->user[m], &status->user[n]);
63                 } else {
64                     if (status->user[n].nick[l] == '\0') break;
65                     if ((unsigned char) status->user[n].nick[l] > (unsigned char) status->user[m].nick[l])
66                         user_swap(&status->user[m], &status->user[n]);
67                 }
68 }
69 
user_refresh(void)70 void user_refresh(void) {
71     user_sort();
72     refresh_users();
73     refresh_read();
74 }
75 
user_getnum(void)76 int user_getnum(void) {
77     register int n;
78 
79     for (n = 0; n < status->users; n++)
80         if (!strncmp(status->user[n].nick, status->nick, NICK_MAXLEN)) return (n);
81     for (n = 0; n < status->users; n++)
82         if (!strncmp(status->user[n].nick, config->nick, NICK_MAXLEN)) return (n);
83     return (-1);
84 }
85 
user_delfavorite(void)86 void user_delfavorite(void) {
87     register int n;
88 
89     for (n = 0; n < USERS_MAX-1; n++)
90         if (!strncmp(status->favorite[n], status->nick, NICK_MAXLEN)) break;
91     for (; n < USERS_MAX-1; n++)
92         strncpy(status->favorite[n], status->favorite[n+1], NICK_MAXLEN);
93     status->favorite[n][0] = '\0';
94 }
95 
user_addfavorite(void)96 void user_addfavorite(void) {
97     register int n;
98 
99     for (n = USERS_MAX-1; n > 0; n--)
100         strncpy(status->favorite[n], status->favorite[n-1], NICK_MAXLEN);
101     strncpy(status->favorite[0], status->nick, NICK_MAXLEN);
102 }
103 
user_parsfavorite(void)104 void user_parsfavorite(void) {                /* FIXME: /load command */
105     char str[NICK_MAXLEN];
106     register int n, m;
107 
108     for (n = 0; n < strlen(config->favorite); n++)
109         for (m = 0; m < NICK_MAXLEN; m++, n++)
110             if (((str[m] = config->favorite[n]) == CHR_NICK) || (str[m] == '\0')) {
111                 str[m] = '\0';
112                 strncpy(status->nick, str, NICK_MAXLEN);
113                 user_addfavorite();
114                 break;
115             }
116 }
117 
user_delignore(void)118 void user_delignore(void) {
119     register int n;
120 
121     for (n = 0; n < USERS_MAX-1; n++)
122         if (!strncmp(status->ignore[n], status->nick, NICK_MAXLEN)) break;
123     for (; n < USERS_MAX-1; n++)
124         strncpy(status->ignore[n], status->ignore[n+1], NICK_MAXLEN);
125     status->ignore[n][0] = '\0';
126 }
127 
user_addignore(void)128 void user_addignore(void) {
129     register int n;
130 
131     for (n = USERS_MAX-1; n > 0; n--)
132         strncpy(status->ignore[n], status->ignore[n-1], NICK_MAXLEN);
133     strncpy(status->ignore[0], status->nick, NICK_MAXLEN);
134 }
135 
user_parsignore(void)136 void user_parsignore(void) {                /* FIXME: /load command */
137     char str[NICK_MAXLEN];
138     register int n, m;
139 
140     for (n = 0; n < strlen(config->ignore); n++)
141         for (m = 0; m < NICK_MAXLEN; m++, n++)
142             if (((str[m] = config->ignore[n]) == CHR_NICK) || (str[m] == '\0')) {
143                 str[m] = '\0';
144                 strncpy(status->nick, str, NICK_MAXLEN);
145                 user_addignore();
146                 break;
147             }
148 }
149 
user_delban(void)150 void user_delban(void) {
151     register int n;
152 
153     for (n = 0; n < USERS_MAX-1; n++)
154         if (!strncmp(status->ban[n], status->address, ADDR_SIZE)) break;
155     for (; n < USERS_MAX-1; n++)
156         strncpy(status->ban[n], status->ban[n+1], ADDR_SIZE);
157     status->ban[n][0] = '\0';
158 }
159 
user_addban(void)160 void user_addban(void) {
161     register int n;
162 
163     for (n = USERS_MAX-1; n > 0; n--)
164         strncpy(status->ban[n], status->ban[n-1], ADDR_SIZE);
165     strncpy(status->ban[0], status->address, ADDR_SIZE);
166 }
167 
user_parsban(void)168 void user_parsban(void) {                /* FIXME: /load command */
169     char str[ADDR_SIZE+1];
170     register int n, m;
171 
172     for (n = 0; n < strlen(config->ban); n++)
173         for (m = 0; m < ADDR_SIZE+1; m++, n++)
174             if (((str[m] = config->ban[n]) == ' ') || (str[m] == '\0')) {
175                 str[m] = '\0';
176                 strncpy(status->address, str, ADDR_SIZE);
177                 user_addban();
178                 break;
179             }
180 }
181 
user_setban(void)182 int user_setban(void) {
183     register int n;
184 
185     strncpy(status->address, status->user[user_getnum()].addr, ADDR_SIZE);
186     for (n = 0; n < USERS_MAX; n++)
187         if (!strncmp(status->ban[n], status->address, ADDR_SIZE)) return 1;
188     return 0;
189 }
190 
user_setfavorite(void)191 int user_setfavorite(void) {
192     register int n;
193 
194     for (n = 0; n < USERS_MAX; n++)
195         if (!strncmp(status->favorite[n], status->nick, NICK_MAXLEN)) return 1;
196     return 0;
197 }
198 
user_favorite(void)199 int user_favorite(void) {
200     if (user_getnum() < 0) return 0;
201     return status->user[user_getnum()].favorite;
202 }
203 
user_setignore(void)204 int user_setignore(void) {
205     register int n;
206 
207     if (user_setban()) return 1;
208     for (n = 0; n < USERS_MAX; n++)
209         if (!strncmp(status->ignore[n], status->nick, NICK_MAXLEN)) return 1;
210     return 0;
211 }
212 
user_ignore(void)213 int user_ignore(void) {
214     if (user_getnum() < 0) return 0;
215     return status->user[user_getnum()].ignore;
216 }
217 
user_add(void)218 void user_add(void) {                /* FIXME: nick collisions */
219     register int n;
220 
221     for (n = 0; n < status->users; n++)
222         if (!strncmp(status->user[n].nick, status->nick, NICK_MAXLEN)) break;
223     if ((n == status->users) && (n < USERS_MAX-1)) status->users++;
224     strncpy(status->user[n].nick, status->nick, NICK_MAXLEN);
225     strncpy(status->user[n].addr, status->address, ADDR_SIZE);
226     status->user[n].mode = status->mode;
227     status->user[n].active = status->active;
228     status->user[n].favorite = user_setfavorite();
229     status->user[n].ignore = user_setignore();
230     user_refresh();
231 }
232 
user_del(void)233 void user_del(void) {
234     register int n;
235 
236     if ((n = user_getnum()) < 0) return;
237     status->mode = status->user[n].mode;
238     status->active = status->user[n].active;
239     for (; n < status->users; n++)
240         memcpy(&status->user[n], &status->user[n+1], sizeof(struct user_t));
241     status->users--;
242     user_refresh();
243 }
244 
user_rescan(void)245 void user_rescan(void) {
246     for (; status->users > 0;) {
247         strncpy(status->nick, status->user[status->users-1].nick, NICK_MAXLEN);
248         user_del();
249     }
250     send_herewho();
251 }
252 
user_nick(void)253 void user_nick(void) {
254     register int n;
255 
256     for (n = 0; n < status->users; n++) {
257         if (!strncmp(status->user[n].nick, status->channel, NICK_MAXLEN)) {
258             strncpy(status->user[n].nick, status->nick, NICK_MAXLEN);
259             status->user[n].favorite = user_setfavorite();
260             status->user[n].ignore = user_setignore();
261             break;
262         }
263     }
264     user_refresh();
265 }
266 
user_mode(void)267 void user_mode(void) {
268     status->user[user_getnum()].mode = status->mode;
269     refresh_room();
270     screen_show();
271     user_refresh();
272 }
273 
user_active(void)274 void user_active(void) {
275     status->user[user_getnum()].active = status->active;
276     user_refresh();
277 }
278