1 /*
2 * notify.c: a few handy routines to notify you when people enter and leave irc
3 *
4 * Written By Michael Sandrof
5 * Copyright(c) 1990
6 * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
7 *
8 * Modified Colten Edwards 96
9 */
10
11
12 #include "irc.h"
13 static char cvsrevision[] = "$Id: notify.c 457 2013-11-11 21:29:05Z tcava $";
14 CVS_REVISION(notify_c)
15 #include "struct.h"
16
17 #include "list.h"
18 #include "notify.h"
19 #include "ircaux.h"
20 #include "who.h"
21 #include "hook.h"
22 #include "server.h"
23 #include "output.h"
24 #include "vars.h"
25 #include "timer.h"
26 #include "misc.h"
27 #include "status.h"
28 #include "userlist.h"
29 #include "hash2.h"
30 #include "cset.h"
31 #include "server.h"
32 #define MAIN_SOURCE
33 #include "modval.h"
34
35 extern Server *server_list;
36
37 #define NOTIFY_LIST(s) (&(server_list[s].notify_list))
38 #define NOTIFY_MAX(s) (NOTIFY_LIST(s)->max)
39 #define NOTIFY_ITEM(s, i) (NOTIFY_LIST(s)->list[i])
40
41 #define WATCH_LIST(s) (&(server_list[s].watch_list))
42 #define WATCH_MAX(s) (WATCH_LIST(s)->max)
43 #define WATCH_ITEM(s, i) (WATCH_LIST(s)->list[i])
44
45 void batch_notify_userhost (char *);
46 void dispatch_notify_userhosts (void);
47 void notify_userhost_dispatch (UserhostItem *, char *, char *);
48 void notify_userhost_reply (char *, char *);
49
rebuild_notify_ison(int server)50 void rebuild_notify_ison (int server)
51 {
52 char *stuff;
53 int i;
54 if (from_server == -1)
55 return;
56 stuff = NOTIFY_LIST(from_server)->ison;
57
58 if (NOTIFY_LIST(from_server)->ison)
59 NOTIFY_LIST(from_server)->ison[0] = 0;
60
61 for (i = 0; i < NOTIFY_MAX(from_server); i++)
62 {
63 m_s3cat(&(NOTIFY_LIST(from_server)->ison),
64 space, NOTIFY_ITEM(from_server, i)->nick);
65 }
66 }
67
rebuild_all_ison(void)68 void rebuild_all_ison (void)
69 {
70 int i;
71 int ofs = from_server;
72 for (i = 0; i < server_list_size(); i++)
73 {
74 from_server = i;
75 rebuild_notify_ison(i);
76 }
77 from_server = ofs;
78 }
79
80
81
ison_notify(char * AskedFor,char * AreOn)82 void ison_notify(char *AskedFor, char *AreOn)
83 {
84 char *NextAsked;
85 char *NextGot;
86
87 NextGot = next_arg(AreOn, &AreOn);
88 while ((NextAsked = next_arg(AskedFor, &AskedFor)) != NULL)
89 {
90 if (NextGot && !my_stricmp(NextAsked, NextGot))
91 {
92 notify_mark(NextAsked, NULL, 1, 1);
93 NextGot = next_arg(AreOn, &AreOn);
94 }
95 else
96 notify_mark(NextAsked, NULL, 0, 1);
97 }
98 dispatch_notify_userhosts();
99 }
100
101
add_to_notify_queue(char * buffer)102 void add_to_notify_queue(char *buffer)
103 {
104 char *lame = LOCAL_COPY(buffer);
105 isonbase(lame, ison_notify);
106 }
107
notify_count(int server,int * on,int * off)108 void notify_count(int server, int *on, int *off)
109 {
110 NotifyItem *tmp;
111 int i;
112 if (server <= -1)
113 return;
114
115 if (on) *on = 0;
116 if (off) *off = 0;
117 for (i = 0; i < NOTIFY_MAX(server); i++)
118 {
119 tmp = NOTIFY_ITEM(server, i);
120 if (tmp->flag)
121 {
122 if (on) (*on)++;
123 }
124 else
125 {
126 if (off) (*off)++;
127 }
128 }
129 }
130
131 /* Rewritten, -lynx */
show_notify_list(int all)132 void show_notify_list(int all)
133 {
134 int count = 0;
135 int i;
136 char lastseen[20];
137 char period[20];
138 char timeson[20];
139 NotifyItem *tmp;
140
141 if (from_server == -1)
142 return;
143
144 for (i = 0; i < NOTIFY_MAX(from_server); i++)
145 {
146 tmp = NOTIFY_ITEM(from_server, i);
147 if (tmp->flag)
148 {
149 if (count == 0)
150 {
151 if (do_hook(NOTIFY_HEADER_LIST, "%s", "Online users"))
152 {
153 put_it("%s", convert_output_format("$G Online Users", NULL, NULL));
154 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_ON_FSET), "%s %s %s %s %s", "Nick", "UserHost", "Times", "Period", "Last seen"));
155 }
156 }
157 strcpy(period, ltoa(tmp->period));
158 strcpy(timeson, ltoa(tmp->times));
159 strcpy(lastseen, ltoa(now - tmp->added));
160 if (do_hook(NOTIFY_LIST, "%s %s %d %s %s %s", tmp->nick, tmp->host?tmp->host:"unknown@unknown", tmp->flag, timeson, period, lastseen))
161 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_ON_FSET), "%s %s %s %s %s", tmp->nick, tmp->host?tmp->host:tmp->looking, timeson, lastseen, "now" ));
162 count++;
163 }
164 }
165 count = 0;
166 for (i = 0; i < NOTIFY_MAX(from_server); i++)
167 {
168 tmp = NOTIFY_ITEM(from_server, i);
169 if ((all && !tmp->flag) || (tmp->times && !tmp->flag))
170 {
171 if (count == 0)
172 {
173 if (do_hook(NOTIFY_HEADER_LIST, "%s", "Offline users"))
174 {
175 put_it("%s", convert_output_format("$G Offline Users", NULL, NULL));
176 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_OFF_FSET), "%s %s %s %s %s", "Nick", "UserHost", "Times", "Period", "Last seen"));
177 }
178 }
179 strcpy(period, ltoa(tmp->period));
180 strcpy(timeson, ltoa(tmp->times));
181 strcpy(lastseen, ltoa(now - tmp->lastseen));
182 if (do_hook(NOTIFY_LIST, "%s %s %d %s %s %s", tmp->nick, tmp->host?tmp->host:"unknown@unknown", tmp->flag, timeson, period, lastseen))
183 {
184 if (!tmp->times)
185 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_OFF_FSET), "%s %s %s %s %s", tmp->nick, tmp->host?tmp->host:tmp->looking, "never", "none", "n/a"));
186 else
187 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_OFF_FSET), "%s %s %s %s %s", tmp->nick, tmp->host?tmp->host:tmp->looking, timeson, period, lastseen));
188 }
189 count++;
190 }
191 }
192 }
193
194 /* notify: the NOTIFY command. Does the whole ball-o-wax */
BUILT_IN_COMMAND(notify)195 BUILT_IN_COMMAND(notify)
196 {
197 char *nick,
198 *list = NULL,
199 *ptr;
200 int no_nicks = 1;
201 int do_ison = 0;
202 int servnum = from_server;
203 int shown = 0;
204 NotifyItem *new_n;
205
206 malloc_strcpy(&list, empty_string);
207 while ((nick = next_arg(args, &args)))
208 {
209 for (no_nicks = 0; nick; nick = ptr)
210 {
211 char *host = NULL;
212 shown = 0;
213 if ((ptr = strchr(nick, ',')) != NULL)
214 *ptr++ = 0;
215 if ((host = strchr(nick, '!')))
216 *host++ = 0;
217 else
218 host = "*@*";
219
220 if (*nick == '-')
221 {
222 nick++;
223
224 if (*nick)
225 {
226 for (servnum = 0; servnum < server_list_size(); servnum++)
227 {
228 if ((new_n = (NotifyItem *)remove_from_array(
229 (Array *)NOTIFY_LIST(servnum), nick)))
230 {
231 new_free(&new_n->nick);
232 new_free(&new_n->host);
233 new_free(&new_n->looking);
234 new_free((char **)&new_n);
235
236 if (!shown)
237 {
238 bitchsay("%s!%s removed from notification list", nick, host);
239 shown = 1;
240 }
241 }
242 else
243 {
244 if (!shown)
245 {
246 bitchsay("%s!%s is not on the notification list", nick, host);
247 shown = 1;
248 }
249 }
250 }
251 }
252 else
253 {
254 for (servnum = 0; servnum < server_list_size(); servnum++)
255 {
256 while ((new_n = (NotifyItem *)array_pop(
257 (Array *)NOTIFY_LIST(servnum), 0)))
258 {
259 new_free(&new_n->nick);
260 new_free(&new_n->host);
261 new_free(&new_n->looking);
262 new_free((char **)&new_n);
263 }
264 }
265 bitchsay("Notify list cleared");
266 }
267 }
268 else
269 {
270 /* compatibility */
271 if (*nick == '+')
272 nick++;
273
274 if (*nick)
275 {
276 int added = 0;
277 if (strchr(nick, '*'))
278 bitchsay("Wildcards not allowed in NOTIFY nicknames!");
279 else
280 {
281 for (servnum = 0; servnum < server_list_size(); servnum++)
282 {
283
284 if ((new_n = (NotifyItem *)array_lookup(
285 (Array *)NOTIFY_LIST(servnum), nick, 0, 0)))
286 {
287 malloc_strcpy(&new_n->looking, host);
288 new_n->flag = 0;
289 continue; /* Already there! */
290 }
291
292 new_n = (NotifyItem *)new_malloc(sizeof(NotifyItem));
293 new_n->nick = m_strdup(nick);
294 new_n->looking = m_strdup(host);
295 new_n->host = NULL;
296 new_n->flag = 0;
297 add_to_array((Array *)NOTIFY_LIST(servnum),
298 (Array_item *)new_n);
299 added = 1;
300 }
301 if (added)
302 {
303 m_s3cat(&list, space, new_n->nick);
304 do_ison = 1;
305 }
306 bitchsay("%s!%s added to the notification list", nick, host);
307 }
308 } else
309 show_notify_list(1);
310 }
311 }
312 }
313
314 if (do_ison && get_int_var(NOTIFY_VAR))
315 {
316 int ofs = from_server;
317 for (servnum = 0; servnum < server_list_size(); servnum++)
318 {
319 from_server = servnum;
320 if (is_server_connected(from_server) && list && *list)
321 add_to_notify_queue(list);
322 }
323 from_server = ofs;
324 }
325
326 new_free(&list);
327 rebuild_all_ison();
328 if (no_nicks)
329 show_notify_list(0);
330 }
331
332 /*
333 * do_notify: This simply goes through the notify list, sending out a WHOIS
334 * for each person on it. This uses the fancy whois stuff in whois.c to
335 * figure things out.
336 */
do_notify(void)337 void do_notify(void)
338 {
339 int old_from_server = from_server;
340 int servnum;
341 static time_t last_notify = 0;
342 int interval = get_int_var(NOTIFY_INTERVAL_VAR);
343 time_t current_time = time(NULL);
344
345 if (current_time < last_notify)
346 last_notify = current_time;
347 else if (!interval || interval > (current_time - last_notify))
348 return; /* Not yet */
349
350 last_notify = current_time;
351
352 if (!server_list_size() || !get_int_var(NOTIFY_VAR))
353 return;
354 for (servnum = 0; servnum < server_list_size(); servnum++)
355 {
356 if (is_server_connected(servnum) && !get_server_watch(servnum))
357 {
358 from_server = servnum;
359 if (NOTIFY_LIST(servnum)->ison && *NOTIFY_LIST(servnum)->ison)
360 {
361 char *lame = LOCAL_COPY(NOTIFY_LIST(servnum)->ison);
362 isonbase(lame, ison_notify);
363 }
364 }
365 }
366 from_server = old_from_server;
367 return;
368 }
369
check_auto_invite(char * nick,char * userhost)370 void check_auto_invite(char *nick, char *userhost)
371 {
372 #ifdef WANT_USERLIST
373 ChannelList *chan = NULL;
374 UserList *tmp = NULL;
375 for (chan = get_server_channels(from_server); chan; chan = chan->next)
376 {
377 if ((tmp = lookup_userlevelc("*", userhost, chan->channel, NULL)))
378 {
379 NickList *n = NULL;
380 n = find_nicklist_in_channellist(nick, chan, 0);
381 if (!n && chan->have_op && get_cset_int_var(chan->csets, AINV_CSET) && (tmp->flags & ADD_INVITE) && get_cset_int_var(chan->csets, AINV_CSET))
382 {
383 bitchsay("Auto-inviting %s to %s", nick, chan->channel);
384 send_to_server("NOTICE %s :Auto-invite from %s", nick, get_server_nickname(from_server));
385 send_to_server("INVITE %s %s%s%s", nick, chan->channel, chan->key?space:empty_string, chan->key?chan->key:empty_string);
386 }
387 }
388 tmp = NULL;
389 }
390 #endif
391 }
392
393
394
395
396 static char *batched_notify_userhosts = NULL;
397 static int batched_notifies = 0;
398
batch_notify_userhost(char * nick)399 void batch_notify_userhost (char *nick)
400 {
401 m_s3cat(&batched_notify_userhosts, space, nick);
402 batched_notifies++;
403 }
404
dispatch_notify_userhosts(void)405 void dispatch_notify_userhosts (void)
406 {
407 if (batched_notify_userhosts)
408 {
409 if (x_debug & DEBUG_NOTIFY)
410 yell("Dispatching notifies to server [%d], [%s]", from_server, batched_notify_userhosts);
411 userhostbase(batched_notify_userhosts, notify_userhost_dispatch, 1, NULL);
412 new_free(&batched_notify_userhosts);
413 batched_notifies = 0;
414 }
415 }
416
notify_userhost_dispatch(UserhostItem * stuff,char * nick,char * text)417 void notify_userhost_dispatch (UserhostItem *stuff, char *nick, char *text)
418 {
419 char userhost[BIG_BUFFER_SIZE + 1];
420
421 snprintf(userhost, sizeof userhost, "%s@%s", stuff->user, stuff->host);
422 notify_userhost_reply(stuff->nick, userhost);
423 }
424
425 #if 0
426 <MadHack> #0 0x809a571 in n_malloc_strcpy ()
427 <MadHack> #1 0x80b400e in notify_userhost_reply ()
428 <MadHack> #2 0x80b3f65 in notify_userhost_dispatch ()
429 <MadHack> #3 0x80d2ef0 in userhost_returned ()
430 <MadHack> #4 0x80b61bd in numbered_command ()
431 hard_uh_notify is on
432 #endif
433
notify_userhost_reply(char * nick,char * userhost)434 void notify_userhost_reply (char *nick, char *userhost)
435 {
436 NotifyItem *tmp;
437
438 if ((tmp = (NotifyItem *)array_lookup(
439 (Array *)NOTIFY_LIST(from_server), nick, 0, 0)))
440 {
441 set_display_target(nick, LOG_CRAP);
442 malloc_strcpy(&tmp->nick, nick);
443 if (userhost)
444 {
445 malloc_strcpy(&tmp->host, userhost);
446 if (!wild_match(tmp->looking, userhost))
447 {
448 reset_display_target();
449 return;
450 }
451 check_auto_invite(nick, userhost);
452 }
453 if ((do_hook(NOTIFY_SIGNON_LIST, "%s %s", tmp->nick, tmp->host?tmp->host:empty_string)))
454 {
455 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_SIGNON_FSET), "%s %s %s",update_clock(GET_TIME),tmp->nick,tmp->host?tmp->host:empty_string));
456 logmsg(LOG_NOTIFY, tmp->nick, 0, "%s(%s) has logged on", tmp->host ? tmp->host : empty_string, tmp->looking);
457 }
458 malloc_strcpy(&last_notify_nick, nick);
459 reset_display_target();
460 }
461 }
462
463
464 /*
465 * notify_mark: This marks a given person on the notify list as either on irc
466 * (if flag is 1), or not on irc (if flag is 0). If the person's status has
467 * changed since the last check, a message is displayed to that effect. If
468 * the person is not on the noTify list, this call is ignored
469 * doit if passed as 0 means it comes from a join, or a msg, etc, not from
470 * an ison reply. 1 is the other..
471 */
notify_mark(char * nick,char * userhost,int flag,int doit)472 void notify_mark(char *nick, char *userhost, int flag, int doit)
473 {
474 NotifyItem *tmp;
475 int count = 0;
476 int loc = 0;
477
478 if ((tmp = (NotifyItem *)find_array_item(
479 (Array *)NOTIFY_LIST(from_server), nick,
480 &count, &loc)) && count < 0)
481 {
482 if (flag)
483 {
484 if (tmp->host && !wild_match(tmp->looking, tmp->host))
485 {
486 tmp->flag = 0;
487 return;
488 }
489 if (tmp->flag != 1)
490 {
491 batch_notify_userhost(nick);
492 tmp->lastseen = 0;
493 if (!tmp->added)
494 tmp->added = now;
495 tmp->times++;
496 }
497 tmp->flag = 1;
498 if (!doit)
499 dispatch_notify_userhosts();
500 }
501 else
502 {
503 if (tmp->flag == 1)
504 {
505 const char *who = NULL;
506 unsigned long level = 0;
507 save_display_target(&who, &level);
508 set_display_target(nick, LOG_NOTIFY);
509 check_orig_nick(nick);
510 if ((do_hook(NOTIFY_SIGNOFF_LIST, "%s %s", tmp->nick, tmp->host?tmp->host:empty_string)) && doit)
511 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_SIGNOFF_FSET), "%s %s %s",update_clock(GET_TIME),tmp->nick,tmp->host?tmp->host:empty_string));
512 tmp->period += now - tmp->added;
513 tmp->lastseen = now;
514 logmsg(LOG_NOTIFY, tmp->nick, 0, "%s(%s) has logged off", tmp->host ? tmp->host : empty_string, tmp->looking);
515 restore_display_target(who, level);
516 }
517 tmp->flag = 0;
518 }
519 }
520 }
521
save_notify(FILE * fp)522 void save_notify(FILE *fp)
523 {
524 int i = 0;
525 if (server_list_size() && NOTIFY_MAX(0))
526 {
527 fprintf(fp, "NOTIFY");
528 for (i = 0; i < NOTIFY_MAX(0); i++)
529 fprintf(fp, " %s!%s", NOTIFY_ITEM(0, i)->nick, NOTIFY_ITEM(0, i)->looking);
530 fprintf(fp, "\n");
531 }
532 if (NOTIFY_MAX(0) && do_hook(SAVEFILE_LIST, "Notify %d", NOTIFY_MAX(0)))
533 bitchsay("Saved %d Notify entries", NOTIFY_MAX(0));
534 }
535
536 /* I hate broken compilers -mrg */
537 static char *vals[] = { "NOISY", "QUIET", "OLD", NULL };
538
set_notify_handler(Window * win,char * value,int unused)539 void set_notify_handler(Window *win, char *value, int unused)
540 {
541 int len;
542 int i;
543 char *s;
544
545 if (!value)
546 value = empty_string;
547 for (i = 0, len = strlen(value); (s = vals[i]); i++)
548 if (0 == my_strnicmp(value, s, len))
549 break;
550 set_string_var(NOTIFY_HANDLER_VAR, s);
551 return;
552 }
553
make_notify_list(int servnum)554 void make_notify_list (int servnum)
555 {
556 NotifyItem *tmp;
557 char *list = NULL;
558 int i;
559
560 server_list[servnum].notify_list.func = (alist_func)global[MY_STRICMP];
561 server_list[servnum].notify_list.hash = HASH_INSENSITIVE;
562
563 if (!get_int_var(NOTIFY_VAR))
564 return;
565 for (i = 0; i < NOTIFY_MAX(0); i++)
566 {
567 tmp = (NotifyItem *)new_malloc(sizeof(NotifyItem));
568 tmp->nick = m_strdup(NOTIFY_ITEM(0, i)->nick);
569 tmp->looking = m_strdup(NOTIFY_ITEM(0, i)->looking);
570 tmp->flag = 0;
571
572 add_to_array ((Array *)NOTIFY_LIST(servnum),
573 (Array_item *)tmp);
574 m_s3cat(&list, space, tmp->nick);
575 }
576 if (list)
577 isonbase(list, ison_notify);
578 new_free(&list);
579 }
580
get_notify_nicks(int showserver,int showon,char * nick,int extra)581 char *get_notify_nicks (int showserver, int showon, char *nick, int extra)
582 {
583 char *list = NULL;
584 int i = 0;
585
586 if (showserver < 0 || showserver >= server_list_size())
587 return m_strdup(empty_string);
588
589 if (nick && *nick)
590 {
591 NotifyItem *tmp;
592 for (i = 0; i < NOTIFY_MAX(showserver); i++)
593 {
594 if (my_stricmp(nick, NOTIFY_ITEM(showserver, i)->nick))
595 continue;
596 tmp = NOTIFY_ITEM(from_server, i);
597 m_s3cat(&list, space, tmp->nick);
598 m_s3cat(&list, space, tmp->host);
599 m_s3cat(&list, space, ltoa(tmp->flag));
600 m_s3cat(&list, space, ltoa(tmp->period));
601 m_s3cat(&list, space, ltoa(tmp->times));
602 m_s3cat(&list, space, ltoa(tmp->lastseen));
603 break;
604 }
605 }
606 else
607 {
608 for (i = 0; i < NOTIFY_MAX(showserver); i++)
609 {
610 if (showon == -1 || showon == NOTIFY_ITEM(showserver, i)->flag)
611 m_s3cat(&list, space, NOTIFY_ITEM(showserver, i)->nick);
612 }
613 }
614 return list ? list : m_strdup(empty_string);
615 }
616
617
get_watch_nicks(int showserver,int showon,char * nick,int extra)618 char *get_watch_nicks (int showserver, int showon, char *nick, int extra)
619 {
620 char *list = NULL;
621 int i = 0;
622
623 if (showserver < 0 || showserver >= server_list_size())
624 return m_strdup(empty_string);
625
626 if (nick && *nick)
627 {
628 NotifyItem *tmp;
629 for (i = 0; i < WATCH_MAX(showserver); i++)
630 {
631 if (my_stricmp(nick, WATCH_ITEM(showserver, i)->nick))
632 continue;
633 tmp = WATCH_ITEM(from_server, i);
634 m_s3cat(&list, space, tmp->nick);
635 m_s3cat(&list, space, tmp->host);
636 m_s3cat(&list, space, ltoa(tmp->flag));
637 m_s3cat(&list, space, ltoa(tmp->period));
638 m_s3cat(&list, space, ltoa(tmp->times));
639 m_s3cat(&list, space, ltoa(tmp->lastseen));
640 break;
641 }
642 }
643 else
644 {
645 for (i = 0; i < WATCH_MAX(showserver); i++)
646 {
647 if (showon == -1 || showon == WATCH_ITEM(showserver, i)->flag)
648 m_s3cat(&list, space, WATCH_ITEM(showserver, i)->nick);
649 }
650 }
651 return list ? list : m_strdup(empty_string);
652 }
653
654
iswatch(int serv,char * list,int all)655 int iswatch(int serv, char *list, int all)
656 {
657 if (all)
658 {
659 int servnum;
660 for (servnum = 0; servnum < server_list_size(); servnum++)
661 {
662 if (get_server_watch(servnum) && is_server_connected(servnum))
663 my_send_to_server(servnum, "WATCH %s", list);
664 }
665 return 0;
666 }
667 if (get_server_watch(serv) && is_server_connected(serv))
668 my_send_to_server(serv, "WATCH %s", list);
669 return 0;
670 }
671
make_watch_list(int servnum)672 void make_watch_list (int servnum)
673 {
674 NotifyItem *tmp;
675 char *list = NULL;
676 int i;
677
678 server_list[servnum].watch_list.func = (alist_func)global[MY_STRICMP];
679 server_list[servnum].watch_list.hash = HASH_INSENSITIVE;
680
681 for (i = 0; i < WATCH_MAX(0); i++)
682 {
683 if (!(tmp = (NotifyItem *)array_lookup((Array *)WATCH_LIST(servnum), WATCH_ITEM(0, i)->nick, 0, 0)))
684 {
685 tmp = (NotifyItem *)new_malloc(sizeof(NotifyItem));
686 malloc_strcpy(&tmp->nick, WATCH_ITEM(0, i)->nick);
687 add_to_array ((Array *)WATCH_LIST(servnum), (Array_item *)tmp);
688 }
689 tmp->flag = 0;
690 if (!list)
691 list = m_opendup(space_plus, tmp->nick, NULL);
692 else
693 m_s3cat(&list, space_plus, tmp->nick);
694 }
695 if (list)
696 iswatch(servnum, list, 0);
697 new_free(&list);
698 }
699
700
show_watch_list(int all)701 void show_watch_list(int all)
702 {
703 #if 0
704 int i;
705 char *list = NULL;
706 if ((server != -1) && server < server_list_size() && WATCH_MAX(server))
707 {
708 put_it("Watch List");
709 for (i = 0; i < WATCH_MAX(server); i++)
710 m_s3cat(&list, space, WATCH_ITEM(server, i)->nick);
711 put_it("%s", list);
712 }
713 new_free(&list);
714 #endif
715 int i, count = 0;
716 char period[80], timeson[80], lastseen[80];
717 NotifyItem *tmp;
718
719 if (from_server == -1)
720 return;
721 for (i = 0; i < WATCH_MAX(from_server); i++)
722 {
723 tmp = WATCH_ITEM(from_server, i);
724 if (tmp->flag)
725 {
726 strcpy(period, ltoa(tmp->period));
727 strcpy(timeson, ltoa(tmp->times));
728 strcpy(lastseen, ltoa(now - tmp->added));
729 if (do_hook(WATCH_LIST, "%s %s %d %s %s %s", tmp->nick, tmp->host?tmp->host:"unknown@unknown", tmp->flag, timeson, period, lastseen))
730 {
731 if (!count)
732 {
733 put_it("%s", convert_output_format("$G Online Users", NULL, NULL));
734 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_ON_FSET), "%s %s %s %s %s", "Nick", "UserHost", "Times", "Period", "Last seen"));
735 }
736 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_ON_FSET), "%s %s %s %s %s", tmp->nick, tmp->host?tmp->host:tmp->looking, timeson, lastseen, "now" ));
737 }
738 count++;
739 }
740 }
741 count = 0;
742 for (i = 0; i < WATCH_MAX(from_server); i++)
743 {
744 tmp = WATCH_ITEM(from_server, i);
745 if ((all && !tmp->flag) || (tmp->times && !tmp->flag))
746 {
747 strcpy(period, ltoa(tmp->period));
748 strcpy(timeson, ltoa(tmp->times));
749 strcpy(lastseen, ltoa(now - tmp->lastseen));
750 if (do_hook(WATCH_LIST, "%s %s %d %s %s %s", tmp->nick, tmp->host?tmp->host:"unknown@unknown", tmp->flag, timeson, period, lastseen))
751 {
752 if (!count)
753 {
754 put_it("%s", convert_output_format("$G Offline Users", NULL, NULL));
755 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_OFF_FSET), "%s %s %s %s %s", "Nick", "UserHost", "Times", "Period", "Last seen"));
756 }
757
758 if (!tmp->times)
759 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_OFF_FSET), "%s %s %s %s %s", tmp->nick, tmp->host?tmp->host:tmp->looking, "never", "none", "n/a"));
760 else
761 put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTIFY_OFF_FSET), "%s %s %s %s %s", tmp->nick, tmp->host?tmp->host:tmp->looking, timeson, period, lastseen));
762 }
763 count++;
764 }
765 }
766
767 }
768
BUILT_IN_COMMAND(watchcmd)769 BUILT_IN_COMMAND(watchcmd)
770 {
771 char *nick;
772 char *list = NULL;
773 int servnum = 0;
774 if (args && *args)
775 {
776 while ((nick = next_arg(args, &args)))
777 {
778 NotifyItem *new_n;
779 int shown = 0;
780 if (*nick == '+')
781 {
782 int added = 0;
783 nick++;
784 if (!*nick)
785 {
786 show_watch_list(0);
787 continue;
788 }
789 if (strchr(nick, '*'))
790 bitchsay("Wildcards not allowed in WATCH nicknames!");
791 else
792 {
793 for (servnum = 0; servnum < server_list_size(); servnum++)
794 {
795 if ((new_n = (NotifyItem *)array_lookup(
796 (Array *)WATCH_LIST(servnum), nick, 0, 0)))
797 {
798 new_n->flag = 0;
799 continue; /* Already there! */
800 }
801 if (WATCH_MAX(servnum) >= (is_server_connected(servnum) ? get_server_watch(servnum) : 128))
802 {
803 bitchsay("Too many WATCH entries [%d]", get_server_watch(servnum));
804 continue;
805 }
806 new_n = (NotifyItem *)new_malloc(sizeof(NotifyItem));
807 new_n->nick = m_strdup(nick);
808 new_n->flag = 0;
809 add_to_array((Array *)WATCH_LIST(servnum),
810 (Array_item *)new_n);
811 added = 1;
812 }
813 if (added)
814 {
815 if (!list)
816 list = m_opendup(space_plus, new_n->nick, NULL);
817 else
818 m_s3cat(&list, space_plus, new_n->nick);
819 }
820 bitchsay("%s added to the watch list", nick);
821 }
822 }
823 else if (*nick == '-')
824 {
825 nick++;
826 if (!*nick)
827 continue;
828 for (servnum = 0; servnum < server_list_size(); servnum++)
829 {
830 if ((new_n = (NotifyItem *)remove_from_array(
831 (Array *)WATCH_LIST(servnum), nick)))
832 {
833 if (!list)
834 list = m_opendup(space_minus, nick, NULL);
835 else
836 m_s3cat(&list, space_minus, nick);
837 new_free(&new_n->nick);
838 new_free(&new_n->host);
839 new_free(&new_n->looking);
840 new_free((char **)&new_n);
841 if (!shown)
842 {
843 bitchsay("%s removed from watch list", nick);
844 shown = 1;
845 }
846 }
847 else
848 {
849 if (!shown)
850 {
851 bitchsay("%s is not on the watch list", nick);
852 shown = 1;
853 }
854 }
855 }
856 }
857 else if (*nick == 'S')
858 my_send_to_server(from_server, "%s S", command);
859 else if (*nick == 'L')
860 my_send_to_server(from_server, "%s L", command);
861 else if (*nick == 'l')
862 my_send_to_server(from_server, "%s l", command);
863 else if (*nick == 'C')
864 {
865 for (servnum = 0; servnum < server_list_size(); servnum++)
866 {
867 if (!get_server_watch(servnum))
868 continue;
869 while ((new_n = (NotifyItem *)array_pop(
870 (Array *)WATCH_LIST(servnum), 0)))
871 {
872 new_free(&new_n->nick);
873 new_free(&new_n->looking);
874 new_free(&new_n->host);
875 new_free((char **)&new_n);
876 }
877 if (get_server_watch(servnum) && is_server_connected(servnum))
878 my_send_to_server(servnum, "%s S", command);
879 }
880 bitchsay("Watch list cleared");
881 }
882 }
883 if (list)
884 iswatch(servnum, list, 1);
885 new_free(&list);
886 } else
887 show_watch_list(1);
888 }
889
save_watch(FILE * fp)890 void save_watch(FILE *fp)
891 {
892 int i = 0;
893 if (server_list_size() && WATCH_MAX(0))
894 {
895 fprintf(fp, "WATCH");
896 for (i = 0; i < WATCH_MAX(0); i++)
897 fprintf(fp, " +%s", WATCH_ITEM(0, i)->nick);
898 fprintf(fp, "\n");
899 }
900 if (WATCH_MAX(0) && do_hook(SAVEFILE_LIST, "Watch %d", WATCH_MAX(0)))
901 bitchsay("Saved %d Watch entries", WATCH_MAX(0));
902 }
903
show_watch_notify(char * from,int online,char ** args)904 void show_watch_notify(char *from, int online, char **args)
905 {
906 NotifyItem *new_n;
907 if ((new_n = (NotifyItem *)array_lookup((Array *)WATCH_LIST(from_server),
908 args[0], 0, 0)))
909 {
910 if (online)
911 {
912 new_free(&new_n->host);
913 new_n->host = m_opendup(args[1], "@", args[2], NULL);
914 if (!new_n->flag)
915 {
916 new_n->lastseen = 0;
917 if (!new_n->added)
918 new_n->added = now;
919 new_n->times++;
920 logmsg(LOG_NOTIFY, new_n->nick, 0, "%s has logged on", new_n->host ? new_n->host : empty_string);
921 }
922 new_n->period = my_atol(args[3]);
923 }
924 else
925 {
926 if (new_n->flag)
927 {
928 new_n->period = now - new_n->added;
929 new_n->lastseen = now;
930 logmsg(LOG_NOTIFY, new_n->nick, 0, "%s has logged off", new_n->host ? new_n->host : empty_string);
931 }
932 }
933 new_n->flag = online;
934 put_it("%s", convert_output_format(fget_string_var(online?FORMAT_WATCH_SIGNON_FSET:FORMAT_WATCH_SIGNOFF_FSET), "%s %s %s %s", args[0], args[1], args[2], args[3]));
935 }
936 }
937
send_watch(int server)938 void send_watch(int server)
939 {
940 int i;
941 char *list = NULL;
942 NotifyItem *tmp;
943 for (i = 0; i < WATCH_MAX(server); i++)
944 {
945 if (!(tmp = (NotifyItem *)array_lookup((Array *)WATCH_LIST(server), WATCH_ITEM(server, i)->nick, 0, 0)))
946 {
947 tmp = (NotifyItem *)new_malloc(sizeof(NotifyItem));
948 malloc_strcpy(&tmp->nick, WATCH_ITEM(server, i)->nick);
949 add_to_array ((Array *)WATCH_LIST(server), (Array_item *)tmp);
950 }
951 tmp->flag = 0;
952 if (!list)
953 list = m_opendup(space_plus, tmp->nick, NULL);
954 else
955 {
956 if ((strlen(list) + strlen(tmp->nick)) > 490)
957 {
958 iswatch(server, list, 0);
959 new_free(&list);
960 list = m_opendup(space_plus, tmp->nick, NULL);
961 }
962 else
963 m_s3cat(&list, space_plus, tmp->nick);
964 }
965 }
966 if (list)
967 iswatch(server, list, 0);
968 new_free(&list);
969 }
970