📄 notify.c
字号:
/* X-Chat * Copyright (C) 1998 Peter Zelezny. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */#include <stdio.h>#include <string.h>#include "../../config.h"#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <time.h>#include "xchat.h"#include "notify.h"#include "cfgfiles.h"#include "plugin.h"#include "fe.h"#include "text.h"#include "util.h"#include "xchatc.h"GSList *notify_list = 0;int notify_tag = 0;static struct notify_per_server *notify_find_server_entry (struct notify *notify, struct server *serv){ GSList *list = notify->server_list; struct notify_per_server *servnot; while (list) { servnot = (struct notify_per_server *) list->data; if (servnot->server == serv) return servnot; list = list->next; } servnot = malloc (sizeof (struct notify_per_server)); if (servnot) { memset (servnot, 0, sizeof (struct notify_per_server)); servnot->server = serv; notify->server_list = g_slist_prepend (notify->server_list, servnot); } return servnot;}voidnotify_save (void){ int fh; char buf[256]; struct notify *notify; GSList *list = notify_list; snprintf (buf, sizeof buf, "%s/notify.conf", get_xdir ()); fh = open (buf, O_TRUNC | O_WRONLY | O_CREAT | OFLAGS, 0600); if (fh != -1) { while (list) { notify = (struct notify *) list->data; write (fh, notify->name, strlen (notify->name)); write (fh, "\n", 1); list = list->next; } close (fh); }}voidnotify_load (void){ int fh; char buf[256]; snprintf (buf, sizeof buf, "%s/notify.conf", get_xdir ()); fh = open (buf, O_RDONLY | OFLAGS); if (fh != -1) { while (waitline (fh, buf, sizeof buf) != -1) { if (*buf != '#') notify_adduser (buf); } close (fh); }}static struct notify_per_server *notify_find (server *serv, char *nick){ GSList *list = notify_list; struct notify_per_server *servnot; struct notify *notify; while (list) { notify = (struct notify *) list->data; servnot = notify_find_server_entry (notify, serv); if (!servnot) { list = list->next; continue; } if (!strcasecmp (notify->name, nick)) return servnot; list = list->next; } return 0;}static voidnotify_announce_offline (server * serv, struct notify_per_server *servnot, char *nick, int quiet){ session *sess; sess = serv->front_session; if (prefs.show_notify_in_front_session && menu_sess) sess = menu_sess; servnot->ison = FALSE; servnot->lastoff = time (0); if (!quiet) EMIT_SIGNAL (XP_TE_NOTIFYOFFLINE, sess, nick, serv->servername, NULL, NULL, 0); fe_notify_update (nick); fe_notify_update (0);}static voidnotify_announce_online (server * serv, struct notify_per_server *servnot, char *nick){ char buf[256]; session *sess; sess = serv->front_session; if (prefs.show_notify_in_front_session && menu_sess) sess = menu_sess; servnot->lastseen = time (0); if (servnot->ison) return; servnot->ison = TRUE; servnot->laston = time (0); EMIT_SIGNAL (XP_TE_NOTIFYONLINE, sess, nick, serv->servername, NULL, NULL, 0); fe_notify_update (nick); fe_notify_update (0); if (prefs.whois_on_notifyonline) { snprintf (buf, sizeof (buf), "WHOIS %s\r\n", nick); tcp_send (serv, buf); }}/* handles numeric 601 */voidnotify_set_offline (server * serv, char *nick, int quiet){ struct notify_per_server *servnot; servnot = notify_find (serv, nick); if (!servnot) return; notify_announce_offline (serv, servnot, nick, quiet);}/* handles numeric 604 and 600 */voidnotify_set_online (server * serv, char *nick){ struct notify_per_server *servnot; servnot = notify_find (serv, nick); if (!servnot) return; notify_announce_online (serv, servnot, nick);}static voidnotify_watch (server * serv, char *nick, int add){ char tbuf[256]; snprintf (tbuf, sizeof (tbuf), "WATCH +%s\r\n", nick); if (!add) tbuf[6] = '-'; tcp_send (serv, tbuf);}static voidnotify_watch_all (char *nick, int add){ server *serv; GSList *list = serv_list; while (list) { serv = list->data; if (serv->connected && serv->end_of_motd && serv->supports_watch) notify_watch (serv, nick, add); list = list->next; }}static voidnotify_flush_watches (server * serv, GSList *from, GSList *end){ char tbuf[512]; GSList *list; struct notify *notify; strcpy (tbuf, "WATCH"); list = from; while (list != end) { notify = list->data; strcat (tbuf, " +"); strcat (tbuf, notify->name); list = list->next; } strcat (tbuf, "\r\n"); tcp_send (serv, tbuf);}/* called when logging in. e.g. when End of motd. */voidnotify_send_watches (server * serv){ struct notify *notify; GSList *list; GSList *point; int len; len = 0; point = list = notify_list; while (list) { notify = list->data; len += strlen (notify->name) + 2 /* + and space */; if (len > 500) { notify_flush_watches (serv, point, list); len = 0; point = list; } list = list->next; } if (point) notify_flush_watches (serv, point, NULL);}/* called when receiving a ISON 303 - should this func go? */voidnotify_markonline (server *serv, char *word[]){ struct notify *notify; struct notify_per_server *servnot; GSList *list = notify_list; int i, seen; while (list) { notify = (struct notify *) list->data; servnot = notify_find_server_entry (notify, serv); if (!servnot) { list = list->next; continue; } i = 4; seen = FALSE; while (*word[i]) { if (!strcasecmp (notify->name, word[i])) { seen = TRUE; notify_announce_online (serv, servnot, notify->name); break; } i++; /* FIXME: word[] is only a 32 element array, limits notify list to about 27 people */ if (i > PDIWORDS - 5) { /*fprintf (stderr, _("*** XCHAT WARNING: notify list too large.\n"));*/ break; } } if (!seen && servnot->ison) { notify_announce_offline (serv, servnot, notify->name, FALSE); } list = list->next; } fe_notify_update (0);}/* yuck! Old routine for ISON notify */intnotify_checklist (void){ char *outbuf; struct server *serv; struct notify *notify; GSList *list = notify_list; int i = 0; if (!list) return 1; outbuf = malloc (512); strcpy (outbuf, "ISON "); while (list) { i++; notify = (struct notify *) list->data; strcat (outbuf, notify->name); strcat (outbuf, " "); if (strlen (outbuf) > 460) { /* LAME: we can't send more than 512 bytes to the server, but * * if we split it in two packets, our offline detection wouldn't * work */ /*fprintf (stderr, _("*** XCHAT WARNING: notify list too large.\n"));*/ break; } list = list->next; } if (i) { GSList *list = serv_list; strcat (outbuf, "\r\n"); while (list) { serv = (struct server *) list->data; if (serv->connected && serv->end_of_motd && !serv->supports_watch) tcp_send (serv, outbuf); list = list->next; } } free (outbuf); return 1;}voidnotify_showlist (struct session *sess){ char outbuf[256]; struct notify *notify; GSList *list = notify_list; struct notify_per_server *servnot; int i = 0; EMIT_SIGNAL (XP_TE_NOTIFYHEAD, sess, NULL, NULL, NULL, NULL, 0); while (list) { i++; notify = (struct notify *) list->data; servnot = notify_find_server_entry (notify, sess->server); if (servnot && servnot->ison) sprintf (outbuf, _(" %-20s online\n"), notify->name); else sprintf (outbuf, _(" %-20s offline\n"), notify->name); PrintText (sess, outbuf); list = list->next; } if (i) { sprintf (outbuf, "%d", i); EMIT_SIGNAL (XP_TE_NOTIFYNUMBER, sess, outbuf, NULL, NULL, NULL, 0); } else EMIT_SIGNAL (XP_TE_NOTIFYEMPTY, sess, NULL, NULL, NULL, NULL, 0);}intnotify_deluser (char *name){ struct notify *notify; struct notify_per_server *servnot; GSList *list = notify_list; while (list) { notify = (struct notify *) list->data; if (!strcasecmp (notify->name, name)) { fe_notify_update (notify->name); /* Remove the records for each server */ while (notify->server_list) { servnot = (struct notify_per_server *) notify->server_list->data; notify->server_list = g_slist_remove (notify->server_list, servnot); free (servnot); } notify_list = g_slist_remove (notify_list, notify); notify_watch_all (name, FALSE); free (notify->name); free (notify); fe_notify_update (0); return 1; } list = list->next; } return 0;}voidnotify_adduser (char *name){ struct notify *notify = malloc (sizeof (struct notify)); if (notify) { memset (notify, 0, sizeof (struct notify)); notify->name = strdup (name); notify->server_list = 0; notify_list = g_slist_prepend (notify_list, notify); notify_checklist (); fe_notify_update (notify->name); fe_notify_update (0); notify_watch_all (name, TRUE); }}intnotify_isnotify (struct session *sess, char *name){ struct notify *notify; struct notify_per_server *servnot; GSList *list = notify_list; while (list) { notify = (struct notify *) list->data; if (!strcasecmp (notify->name, name)) { servnot = notify_find_server_entry (notify, sess->server); if (servnot && servnot->ison) return TRUE; } list = list->next; } return FALSE;}voidnotify_cleanup (){ GSList *list = notify_list; GSList *nslist, *srvlist; struct notify *notify; struct notify_per_server *servnot; struct server *serv; int valid; while (list) { /* Traverse the list of notify structures */ notify = (struct notify *) list->data; nslist = notify->server_list; while (nslist) { /* Look at each per-server structure */ servnot = (struct notify_per_server *) nslist->data; /* Check the server is valid */ valid = FALSE; srvlist = serv_list; while (srvlist) { serv = (struct server *) srvlist->data; if (servnot->server == serv) { valid = serv->connected; /* Only valid if server is too */ break; } srvlist = srvlist->next; } if (!valid) { notify->server_list = g_slist_remove (notify->server_list, servnot); nslist = notify->server_list; } else { nslist = nslist->next; } } list = list->next; } fe_notify_update (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -