Mercurial > ~mikael > mcabber > hg
view mcabber/mcabber/fifo_internal.c @ 2193:18fa5ecb1ef4
Make sure outgoing carbons won't set unread flag
Outgoing carbon copies received from other clients shouldn't set the
unread messages flag if it wasn't set before (regardless of the
'clear_unread_on_carbon' option).
---
mcabber/mcabber/hooks.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
author | Holger Weiß <holger@zedat.fu-berlin.de> |
---|---|
date | Tue, 28 Jul 2015 00:27:12 +0200 |
parents | 038c4d601011 |
children | f5402d705f67 |
line wrap: on
line source
/* * fifo_internal.c -- Read commands from a named pipe * * Copyright (C) 2008,2009 Mikael Berthe <mikael@lilotux.net> * Copyright (C) 2009 Myhailo Danylenko <isbear@ukrpost.net> * * 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 <stdlib.h> #include <glib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include "commands.h" #include "logprint.h" #include "utils.h" #include "settings.h" #include "main.h" static char *fifo_name = NULL; static GIOChannel *fifo_channel = NULL; static const char *FIFO_ENV_NAME = "MCABBER_FIFO"; static gboolean attach_fifo(const char *name); static guint fifo_callback(GIOChannel *channel, GIOCondition condition, gpointer data) { if (condition & (G_IO_IN|G_IO_PRI)) { GIOStatus chstat; gchar *buf; gsize endpos; chstat = g_io_channel_read_line(channel, &buf, NULL, &endpos, NULL); if (chstat == G_IO_STATUS_ERROR || chstat == G_IO_STATUS_EOF) { if (!attach_fifo(fifo_name)) scr_LogPrint(LPRINT_LOGNORM, "Reopening fifo failed! Fifo will not work from now!"); return FALSE; } if (buf) { guint logflag; guint fifo_ignore = settings_opt_get_int("fifo_ignore"); if (endpos) buf[endpos] = '\0'; if (settings_opt_get_int("fifo_hide_commands")) logflag = LPRINT_LOG; else logflag = LPRINT_LOGNORM; scr_LogPrint(logflag, "%s FIFO command: %s", (fifo_ignore ? "Ignoring" : "Executing"), buf); if (!fifo_ignore) { process_command(buf, TRUE); } g_free(buf); } } else if (condition & (G_IO_ERR|G_IO_NVAL|G_IO_HUP)) { if (!attach_fifo(fifo_name)) scr_LogPrint(LPRINT_LOGNORM, "Reopening fifo failed! Fifo will not work from now!"); return FALSE; } return TRUE; } static void fifo_destroy_callback(gpointer data) { GIOChannel *channel = (GIOChannel *)data; g_io_channel_unref(channel); channel = NULL; } static gboolean check_fifo(const char *name) { struct stat finfo; if (stat(name, &finfo) == -1) { /* some unknown error */ if (errno != ENOENT) return FALSE; /* fifo not yet exists */ if (mkfifo(name, S_IRUSR|S_IWUSR) != -1) return check_fifo(name); else return FALSE; } /* file exists */ if (S_ISFIFO(finfo.st_mode)) return TRUE; else return FALSE; } static gboolean attach_fifo(const char *name) { GSource *source; int fd = open (name, O_RDONLY|O_NONBLOCK); if (fd == -1) return FALSE; if (fifo_channel) g_io_channel_unref(fifo_channel); fifo_channel = g_io_channel_unix_new(fd); g_io_channel_set_flags(fifo_channel, G_IO_FLAG_NONBLOCK, NULL); g_io_channel_set_encoding(fifo_channel, NULL, NULL); g_io_channel_set_close_on_unref(fifo_channel, TRUE); source = g_io_create_watch(fifo_channel, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL); g_source_set_callback(source, (GSourceFunc)fifo_callback, (gpointer)fifo_channel, (GDestroyNotify)fifo_destroy_callback); g_source_attach(source, main_context); return TRUE; } void fifo_deinit(void) { unsetenv(FIFO_ENV_NAME); if (fifo_channel) g_source_remove_by_user_data(fifo_channel); /* channel itself should be destroyed by destruction callback */ /* destroy open fifo */ if (fifo_name) { /* well, that may create fifo, and then unlink, * but at least we will not destroy non-fifo data */ if (check_fifo(fifo_name)) unlink(fifo_name); g_free(fifo_name); fifo_name = NULL; } } // fifo_init_internal(path) // If path is NULL, reopen existing fifo, else open anew. static int fifo_init_internal(const char *fifo_path) { if (fifo_path) { fifo_deinit(); fifo_name = expand_filename(fifo_path); if (!check_fifo(fifo_name)) { scr_LogPrint(LPRINT_LOGNORM, "WARNING: Cannot create the FIFO. " "%s already exists and is not a pipe", fifo_name); g_free(fifo_name); fifo_name = NULL; return -1; } } else if (fifo_name) g_source_remove_by_user_data(fifo_channel); else return -1; if (!attach_fifo(fifo_name)) { scr_LogPrint(LPRINT_LOGNORM, "Error: Cannot open fifo"); return -1; } setenv(FIFO_ENV_NAME, fifo_name, 1); scr_LogPrint(LPRINT_LOGNORM, "FIFO initialized (%s)", fifo_path); return 1; } static gchar *fifo_guard(const gchar *key, const gchar *new_value) { if (new_value) fifo_init_internal(new_value); else fifo_deinit(); return g_strdup(new_value); } // Returns 1 in case of success, -1 on error int fifo_init(void) { const char *path = settings_opt_get("fifo_name"); static gboolean guard_installed = FALSE; if (!guard_installed) if (!(guard_installed = settings_set_guard("fifo_name", fifo_guard))) scr_LogPrint(LPRINT_DEBUG, "fifo: BUG: Cannot install option guard!"); if (path) return fifo_init_internal(path); return 1; } /* vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2: For Vim users... */