Mercurial > ~mikael > mcabber > hg
view mcabber/src/hooks.c @ 430:d03663d2e7d9
Display error messages as specified in RFC3920 (9.3)
If possible, we display the child element corresponding to the stanza
error conditions defined in RFC3920. Error code and error text will
be displayed if available.
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Sun, 11 Sep 2005 22:01:57 +0200 |
parents | f8f3c7493457 |
children | b44be19d6229 |
line wrap: on
line source
/* * hooks.c -- Hooks layer * * Copyright (C) 2005 Mikael Berthe <bmikael@lists.lilotux.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 <sys/types.h> #include <unistd.h> #include "hooks.h" #include "screen.h" #include "roster.h" #include "histolog.h" #include "hbuf.h" static char *extcmd; inline void hk_message_in(const char *jid, time_t timestamp, const char *msg, const char *type) { int new_guy = FALSE; int message_flags; // If this user isn't in the roster, we add it if (!roster_exists(jid, jidsearch, ROSTER_TYPE_USER|ROSTER_TYPE_AGENT)) { roster_add_user(jid, NULL, NULL, ROSTER_TYPE_USER); new_guy = TRUE; } if (type && !strcmp(type, "error")) { message_flags = HBB_PREFIX_ERR | HBB_PREFIX_IN; scr_LogPrint(LPRINT_LOGNORM, "Error message received from <%s>", jid); } else message_flags = 0; // Note: the hlog_write should not be called first, because in some // cases scr_WriteIncomingMessage() will load the history and we'd // have the message twice... scr_WriteIncomingMessage(jid, msg, timestamp, message_flags); // We don't log the message if it is an error message if (!(message_flags & HBB_PREFIX_ERR)) hlog_write_message(jid, timestamp, FALSE, msg); // External command hk_ext_cmd(jid, 'M', 'R', NULL); // We need to rebuild the list if the sender is unknown or // if the sender is offline/invisible and hide_offline_buddies is set if (new_guy || (roster_getstatus(jid) == offline && buddylist_get_hide_offline_buddies())) { buddylist_build(); update_roster = TRUE; } } inline void hk_message_out(const char *jid, time_t timestamp, const char *msg) { scr_WriteOutgoingMessage(jid, msg); hlog_write_message(jid, timestamp, TRUE, msg); // External command hk_ext_cmd(jid, 'M', 'S', NULL); } inline void hk_statuschange(const char *jid, time_t timestamp, enum imstatus status, const char *status_msg) { scr_LogPrint(LPRINT_LOGNORM, "Buddy status has changed: [%c>%c] <%s> %s", imstatus2char[roster_getstatus(jid)], imstatus2char[status], jid, ((status_msg) ? status_msg : "")); roster_setstatus(jid, status, status_msg); buddylist_build(); scr_DrawRoster(); hlog_write_status(jid, 0, status, status_msg); // External command hk_ext_cmd(jid, 'S', imstatus2char[status], NULL); } inline void hk_mystatuschange(time_t timestamp, enum imstatus old_status, enum imstatus new_status, const char *msg) { if (!msg && (old_status == new_status)) return; scr_LogPrint(LPRINT_LOGNORM, "Your status has changed: [%c>%c] %s", imstatus2char[old_status], imstatus2char[new_status], ((msg) ? msg : "")); //hlog_write_status(NULL, 0, status); } /* External commands */ // hk_ext_cmd_init() // Initialize external command variable. // Can be called with parameter NULL to reset and free memory. void hk_ext_cmd_init(const char *command) { if (extcmd) { g_free(extcmd); extcmd = NULL; } if (command) extcmd = g_strdup(command); } // hk_ext_cmd() // Launch an external command (process) for the given event. // For now, data should be NULL. void hk_ext_cmd(const char *jid, guchar type, guchar info, const char *data) { pid_t pid; char *arg_type = NULL; char *arg_info = NULL; char *arg_data = NULL; char status_str[2]; if (!extcmd) return; // Prepare arg_* (external command parameters) switch (type) { case 'M': arg_type = "MSG"; if (info == 'R') arg_info = "IN"; else if (info == 'S') arg_info = "OUT"; break; case 'S': arg_type = "STATUS"; if (strchr(imstatus2char, tolower(info))) { status_str[0] = toupper(info); status_str[1] = 0; arg_info = status_str; } break; default: return; } if (!arg_type || !arg_info) return; if ((pid=fork()) == -1) { scr_LogPrint(LPRINT_LOGNORM, "Fork error, cannot launch external command."); return; } if (pid == 0) { // child if (execl(extcmd, extcmd, arg_type, arg_info, jid, arg_data, NULL) == -1) { // scr_LogPrint(LPRINT_LOGNORM, "Cannot execute external command."); exit(1); } } }