2 * Copyright (C) 1998 Peter Zelezny.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 #include <sys/types.h>
38 GSList
*notify_list
= 0;
43 despacify_dup (char *str
)
45 char *p
, *res
= malloc (strlen (str
) + 1);
62 notify_netcmp (char *str
, void *serv
)
64 char *net
= despacify_dup (server_get_network (serv
, TRUE
));
66 if (rfc_casecmp (str
, net
) == 0)
69 return 0; /* finish & return FALSE from token_foreach() */
73 return 1; /* keep going... */
76 /* monitor this nick on this particular network? */
79 notify_do_network (struct notify
*notify
, server
*serv
)
81 if (!notify
->networks
) /* ALL networks for this nick */
84 if (token_foreach (notify
->networks
, ',', notify_netcmp
, serv
))
85 return FALSE
; /* network list doesn't contain this one */
90 struct notify_per_server
*
91 notify_find_server_entry (struct notify
*notify
, struct server
*serv
)
93 GSList
*list
= notify
->server_list
;
94 struct notify_per_server
*servnot
;
98 servnot
= (struct notify_per_server
*) list
->data
;
99 if (servnot
->server
== serv
)
104 /* not found, should we add it, or is this not a network where
105 we're monitoring this nick? */
106 if (!notify_do_network (notify
, serv
))
109 servnot
= malloc (sizeof (struct notify_per_server
));
112 memset (servnot
, 0, sizeof (struct notify_per_server
));
113 servnot
->server
= serv
;
114 servnot
->notify
= notify
;
115 notify
->server_list
= g_slist_prepend (notify
->server_list
, servnot
);
124 struct notify
*notify
;
125 GSList
*list
= notify_list
;
127 fh
= xchat_open_file ("notify.conf", O_TRUNC
| O_WRONLY
| O_CREAT
, 0600, XOF_DOMODE
);
132 notify
= (struct notify
*) list
->data
;
133 write (fh
, notify
->name
, strlen (notify
->name
));
134 if (notify
->networks
)
137 write (fh
, notify
->networks
, strlen (notify
->networks
));
153 fh
= xchat_open_file ("notify.conf", O_RDONLY
, 0, 0);
156 while (waitline (fh
, buf
, sizeof buf
, FALSE
) != -1)
158 if (buf
[0] != '#' && buf
[0] != 0)
160 sep
= strchr (buf
, ' ');
164 notify_adduser (buf
, sep
+ 1);
167 notify_adduser (buf
, NULL
);
174 static struct notify_per_server
*
175 notify_find (server
*serv
, char *nick
)
177 GSList
*list
= notify_list
;
178 struct notify_per_server
*servnot
;
179 struct notify
*notify
;
183 notify
= (struct notify
*) list
->data
;
185 servnot
= notify_find_server_entry (notify
, serv
);
192 if (!serv
->p_cmp (notify
->name
, nick
))
202 notify_announce_offline (server
* serv
, struct notify_per_server
*servnot
,
203 char *nick
, int quiet
)
207 sess
= serv
->front_session
;
209 servnot
->ison
= FALSE
;
210 servnot
->lastoff
= time (0);
212 EMIT_SIGNAL (XP_TE_NOTIFYOFFLINE
, sess
, nick
, serv
->servername
,
213 server_get_network (serv
, TRUE
), NULL
, 0);
214 fe_notify_update (nick
);
215 fe_notify_update (0);
219 notify_announce_online (server
* serv
, struct notify_per_server
*servnot
,
224 sess
= serv
->front_session
;
226 servnot
->lastseen
= time (0);
230 servnot
->ison
= TRUE
;
231 servnot
->laston
= time (0);
232 EMIT_SIGNAL (XP_TE_NOTIFYONLINE
, sess
, nick
, serv
->servername
,
233 server_get_network (serv
, TRUE
), NULL
, 0);
234 fe_notify_update (nick
);
235 fe_notify_update (0);
237 if (prefs
.whois_on_notifyonline
)
240 /* Let's do whois with idle time (like in /quote WHOIS %s %s) */
242 char *wii_str
= malloc (strlen (nick
) * 2 + 2);
243 sprintf (wii_str
, "%s %s", nick
, nick
);
244 serv
->p_whois (serv
, wii_str
);
249 /* handles numeric 601 */
252 notify_set_offline (server
* serv
, char *nick
, int quiet
)
254 struct notify_per_server
*servnot
;
256 servnot
= notify_find (serv
, nick
);
260 notify_announce_offline (serv
, servnot
, nick
, quiet
);
263 /* handles numeric 604 and 600 */
266 notify_set_online (server
* serv
, char *nick
)
268 struct notify_per_server
*servnot
;
270 servnot
= notify_find (serv
, nick
);
274 notify_announce_online (serv
, servnot
, nick
);
278 notify_watch (server
* serv
, char *nick
, int add
)
282 snprintf (tbuf
, sizeof (tbuf
), "WATCH +%s", nick
);
285 serv
->p_raw (serv
, tbuf
);
289 notify_watch_all (struct notify
*notify
, int add
)
292 GSList
*list
= serv_list
;
296 if (serv
->connected
&& serv
->end_of_motd
&& serv
->supports_watch
&&
297 notify_do_network (notify
, serv
))
298 notify_watch (serv
, notify
->name
, add
);
304 notify_flush_watches (server
* serv
, GSList
*from
, GSList
*end
)
308 struct notify
*notify
;
310 strcpy (tbuf
, "WATCH");
317 strcat (tbuf
, notify
->name
);
320 serv
->p_raw (serv
, tbuf
);
323 /* called when logging in. e.g. when End of motd. */
326 notify_send_watches (server
* serv
)
328 struct notify
*notify
;
334 point
= list
= notify_list
;
339 if (notify_do_network (notify
, serv
))
341 len
+= strlen (notify
->name
) + 2 /* + and space */;
344 notify_flush_watches (serv
, point
, list
);
345 len
= strlen (notify
->name
) + 2;
354 notify_flush_watches (serv
, point
, NULL
);
357 /* called when receiving a ISON 303 - should this func go? */
360 notify_markonline (server
*serv
, char *word
[])
362 struct notify
*notify
;
363 struct notify_per_server
*servnot
;
364 GSList
*list
= notify_list
;
369 notify
= (struct notify
*) list
->data
;
370 servnot
= notify_find_server_entry (notify
, serv
);
380 if (!serv
->p_cmp (notify
->name
, word
[i
]))
383 notify_announce_online (serv
, servnot
, notify
->name
);
387 /* FIXME: word[] is only a 32 element array, limits notify list to
389 if (i
> PDIWORDS
- 5)
391 /*fprintf (stderr, _("*** XCHAT WARNING: notify list too large.\n"));*/
395 if (!seen
&& servnot
->ison
)
397 notify_announce_offline (serv
, servnot
, notify
->name
, FALSE
);
401 fe_notify_update (0);
404 /* yuck! Old routine for ISON notify */
407 notify_checklist_for_server (server
*serv
)
410 struct notify
*notify
;
411 GSList
*list
= notify_list
;
414 strcpy (outbuf
, "ISON ");
418 if (notify_do_network (notify
, serv
))
421 strcat (outbuf
, notify
->name
);
422 strcat (outbuf
, " ");
423 if (strlen (outbuf
) > 460)
425 /* LAME: we can't send more than 512 bytes to the server, but *
426 * if we split it in two packets, our offline detection wouldn't *
428 /*fprintf (stderr, _("*** XCHAT WARNING: notify list too large.\n"));*/
436 serv
->p_raw (serv
, outbuf
);
440 notify_checklist (void) /* check ISON list */
443 GSList
*list
= serv_list
;
448 if (serv
->connected
&& serv
->end_of_motd
&& !serv
->supports_watch
)
450 notify_checklist_for_server (serv
);
458 notify_showlist (struct session
*sess
)
461 struct notify
*notify
;
462 GSList
*list
= notify_list
;
463 struct notify_per_server
*servnot
;
466 EMIT_SIGNAL (XP_TE_NOTIFYHEAD
, sess
, NULL
, NULL
, NULL
, NULL
, 0);
470 notify
= (struct notify
*) list
->data
;
471 servnot
= notify_find_server_entry (notify
, sess
->server
);
472 if (servnot
&& servnot
->ison
)
473 snprintf (outbuf
, sizeof (outbuf
), _(" %-20s online\n"), notify
->name
);
475 snprintf (outbuf
, sizeof (outbuf
), _(" %-20s offline\n"), notify
->name
);
476 PrintText (sess
, outbuf
);
481 sprintf (outbuf
, "%d", i
);
482 EMIT_SIGNAL (XP_TE_NOTIFYNUMBER
, sess
, outbuf
, NULL
, NULL
, NULL
, 0);
484 EMIT_SIGNAL (XP_TE_NOTIFYEMPTY
, sess
, NULL
, NULL
, NULL
, NULL
, 0);
488 notify_deluser (char *name
)
490 struct notify
*notify
;
491 struct notify_per_server
*servnot
;
492 GSList
*list
= notify_list
;
496 notify
= (struct notify
*) list
->data
;
497 if (!rfc_casecmp (notify
->name
, name
))
499 fe_notify_update (notify
->name
);
500 /* Remove the records for each server */
501 while (notify
->server_list
)
503 servnot
= (struct notify_per_server
*) notify
->server_list
->data
;
504 notify
->server_list
=
505 g_slist_remove (notify
->server_list
, servnot
);
508 notify_list
= g_slist_remove (notify_list
, notify
);
509 notify_watch_all (notify
, FALSE
);
510 if (notify
->networks
)
511 free (notify
->networks
);
514 fe_notify_update (0);
523 notify_adduser (char *name
, char *networks
)
525 struct notify
*notify
= malloc (sizeof (struct notify
));
528 memset (notify
, 0, sizeof (struct notify
));
529 if (strlen (name
) >= NICKLEN
)
531 notify
->name
= malloc (NICKLEN
);
532 safe_strcpy (notify
->name
, name
, NICKLEN
);
535 notify
->name
= strdup (name
);
538 notify
->networks
= despacify_dup (networks
);
539 notify
->server_list
= 0;
540 notify_list
= g_slist_prepend (notify_list
, notify
);
542 fe_notify_update (notify
->name
);
543 fe_notify_update (0);
544 notify_watch_all (notify
, TRUE
);
549 notify_is_in_list (server
*serv
, char *name
)
551 struct notify
*notify
;
552 GSList
*list
= notify_list
;
556 notify
= (struct notify
*) list
->data
;
557 if (!serv
->p_cmp (notify
->name
, name
))
566 notify_isnotify (struct session
*sess
, char *name
)
568 struct notify
*notify
;
569 struct notify_per_server
*servnot
;
570 GSList
*list
= notify_list
;
574 notify
= (struct notify
*) list
->data
;
575 if (!sess
->server
->p_cmp (notify
->name
, name
))
577 servnot
= notify_find_server_entry (notify
, sess
->server
);
578 if (servnot
&& servnot
->ison
)
590 GSList
*list
= notify_list
;
591 GSList
*nslist
, *srvlist
;
592 struct notify
*notify
;
593 struct notify_per_server
*servnot
;
599 /* Traverse the list of notify structures */
600 notify
= (struct notify
*) list
->data
;
601 nslist
= notify
->server_list
;
604 /* Look at each per-server structure */
605 servnot
= (struct notify_per_server
*) nslist
->data
;
607 /* Check the server is valid */
612 serv
= (struct server
*) srvlist
->data
;
613 if (servnot
->server
== serv
)
615 valid
= serv
->connected
; /* Only valid if server is too */
618 srvlist
= srvlist
->next
;
622 notify
->server_list
=
623 g_slist_remove (notify
->server_list
, servnot
);
625 nslist
= notify
->server_list
;
628 nslist
= nslist
->next
;
633 fe_notify_update (0);