cmd.c
author Myhailo Danylenko <isbear@ukrpost.net>
Wed, 02 Dec 2009 21:05:12 +0200
changeset 4 e305d7e562c4
parent 0 72ffcc3c584e
child 5 1b3263c96cbe
permissions -rw-r--r--
Fix sending to MUC rooms
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     1
/*
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     2
 * cmd.c                -- Send shell command output as messages
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     3
 *
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     4
 * Copyrigth (C) 2009      Myhailo Danylenko <isbear@ukrpost.net>
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     5
 *
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     6
 * This program is free software; you can redistribute it and/or modify
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     7
 * it under the terms of the GNU General Public License as published by
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     8
 * the Free Software Foundation; either version 2 of the License, or (at
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
     9
 * your option) any later version.
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    10
 *
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    11
 * This program is distributed in the hope that it will be useful, but
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    14
 * General Public License for more details.
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    15
 *
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    17
 * along with this program; if not, write to the Free Software
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    19
 * USA
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    20
 */
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    21
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    22
#include <stdlib.h>
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    23
#include <glib.h>
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    24
#include <gmodule.h>
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    25
#include <unistd.h>
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    26
#include <errno.h>
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    27
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    28
#include "commands.h"
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    29
#include "logprint.h"
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    30
#include "utils.h"
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    31
#include "settings.h"
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    32
#include "hbuf.h"
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    33
#include "xmpp.h"
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    34
#include "roster.h"
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    35
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    36
typedef struct {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    37
	gchar      *jid;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    38
	GString    *input;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    39
	guint       source;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    40
	GIOChannel *channel;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    41
} cmd_cb_t;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    42
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    43
static GSList  *cmd_channels = NULL;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    44
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    45
static gboolean cmd_reader (GIOChannel *channel, GIOCondition condition, gpointer data)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    46
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    47
	cmd_cb_t *cb = (cmd_cb_t *) data;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    48
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    49
	if (condition & (G_IO_IN|G_IO_PRI)) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    50
		GIOStatus    chstat;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    51
		static gchar buf[HBB_BLOCKSIZE];
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    52
		gsize        endpos;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    53
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    54
		chstat = g_io_channel_read_chars (channel, buf, HBB_BLOCKSIZE, &endpos, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    55
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    56
		if (chstat == G_IO_STATUS_ERROR || chstat == G_IO_STATUS_EOF) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    57
			cb->source = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    58
			return FALSE; // XXX
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    59
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    60
		
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    61
		if (endpos) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    62
			GString *input = cb->input;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    63
			gsize    bread   = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    64
			gsize    written = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    65
			GError  *err     = NULL;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    66
			gchar   *utf8    = NULL;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    67
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    68
			g_string_append_len (input, buf, endpos);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    69
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    70
			if (!lm_connection_is_authenticated (lconnection)) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    71
				scr_LogPrint (LPRINT_LOGNORM, "cmd: Connection is not ready, delaying data");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    72
				return TRUE;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    73
			}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    74
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    75
			// usual g_locale_to_utf8 seem to be unable to detect locale charset
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    76
			// maybe, proper solution will be to call setlocale on module loading,
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    77
			// but mcabber already does this, and I do not want to mess with it
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    78
			utf8 = g_convert (input->str, input->len, LocaleCharSet, "UTF-8", &bread, &written, &err);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    79
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    80
			if (err && err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE && bread) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    81
				err     = NULL;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    82
				written = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    83
				utf8 = g_convert (input->str, bread, LocaleCharSet, "UTF-8", &bread, &written, &err);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    84
			}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    85
			
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    86
			if (written) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    87
				gsize sent = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    88
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    89
				while (sent < written) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    90
					gint      crypted;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    91
					gpointer  xep184  = NULL;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    92
					gsize     len     = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    93
					gchar    *bbuf    = NULL;
4
e305d7e562c4 Fix sending to MUC rooms
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    94
					int       type    = roster_find (cb->jid, jidsearch, ROSTER_TYPE_ROOM) ? ROSTER_TYPE_ROOM : ROSTER_TYPE_USER;
0
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    95
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    96
					if (written - sent > HBB_BLOCKSIZE) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    97
						gchar *c = utf8 + sent + HBB_BLOCKSIZE;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    98
						c = g_utf8_find_prev_char (utf8 + sent, c);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    99
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   100
						if (!c) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   101
							scr_LogPrint (LPRINT_LOGNORM, "cmd: Cannot determine utf8 character end! End of data chunk will be discarded!");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   102
							break;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   103
						}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   104
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   105
						len  = c - utf8 - sent;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   106
						bbuf = g_strndup (utf8 + sent, len);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   107
					}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   108
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   109
					// XXX add command/sequence number as title?
4
e305d7e562c4 Fix sending to MUC rooms
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   110
					xmpp_send_msg (cb->jid, len ? bbuf : (utf8 + sent), type, NULL, FALSE /* ? */, &crypted, LM_MESSAGE_SUB_TYPE_NOT_SET, &xep184);
0
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   111
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   112
					if (crypted == -1) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   113
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   114
						scr_LogPrint (LPRINT_LOGNORM, "cmd: Encryption error. Message not sent.");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   115
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   116
						if (!len)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   117
							break;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   118
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   119
						g_free (bbuf);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   120
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   121
						continue;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   122
					}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   123
4
e305d7e562c4 Fix sending to MUC rooms
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   124
					if (type != ROSTER_TYPE_ROOM)
e305d7e562c4 Fix sending to MUC rooms
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   125
						hk_message_out (cb->jid, NULL, 0, len ? bbuf : (utf8 + sent), crypted, xep184);
0
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   126
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   127
					if (!len)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   128
						break;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   129
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   130
					g_free (bbuf);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   131
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   132
					sent += len;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   133
				}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   134
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   135
				g_free (utf8);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   136
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   137
				g_string_erase (input, 0, bread);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   138
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   139
			} else {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   140
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   141
				scr_LogPrint (LPRINT_LOGNORM, "cmd: Character conversion error: %s", err->message);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   142
				cb->source = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   143
				return FALSE;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   144
			}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   145
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   146
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   147
	} else if (condition & (G_IO_ERR|G_IO_NVAL|G_IO_HUP)) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   148
		cb->source = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   149
		return FALSE; // XXX
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   150
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   151
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   152
	return TRUE;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   153
}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   154
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   155
static void cmd_destroy_data (gpointer data)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   156
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   157
	cmd_cb_t *cb = (cmd_cb_t *) data;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   158
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   159
	cmd_channels = g_slist_remove (cmd_channels, data);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   160
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   161
	// May conflict - will be called during source removal?
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   162
//	if (cb->source)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   163
//		g_source_remove (cb->source);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   164
	if (cb->channel)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   165
		g_io_channel_unref (cb->channel);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   166
	g_free (cb->jid);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   167
	g_free (cb);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   168
}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   169
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   170
static void do_cmd (char *arg)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   171
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   172
	int         fd[2];
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   173
	const char *jid = CURRENT_JID;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   174
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   175
	if (!*arg)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   176
		return;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   177
	
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   178
	if (!jid) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   179
		scr_LogPrint (LPRINT_LOGNORM, "Unsuitable buddy selected");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   180
		return;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   181
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   182
	
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   183
	if (pipe (fd)) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   184
		scr_LogPrint (LPRINT_LOGNORM, "Cannot create pipe: %s", strerror (errno));
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   185
		return;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   186
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   187
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   188
	{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   189
		int res = fork ();
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   190
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   191
		if (!res) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   192
			
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   193
			close (fd[0]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   194
			dup2 (fd[1], STDOUT_FILENO);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   195
			if (settings_opt_get_int ("cmd_redirect_stderr"))
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   196
				dup2 (fd[1], STDERR_FILENO);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   197
			else
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   198
				close (STDERR_FILENO);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   199
			close (STDIN_FILENO);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   200
			close (fd[1]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   201
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   202
			{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   203
				const char *shell = settings_opt_get ("cmd_shell");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   204
				if (!shell)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   205
					shell = getenv ("SHELL");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   206
				if (!shell)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   207
					shell = "sh";
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   208
				execl (shell, shell, "-c", arg, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   209
			}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   210
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   211
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   212
		if (res == -1) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   213
			scr_LogPrint (LPRINT_NORMAL, "Cannot fork child: %s", strerror (errno));
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   214
			close (fd[0]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   215
			close (fd[1]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   216
			return;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   217
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   218
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   219
		close (fd[1]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   220
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   221
		GIOChannel *channel = g_io_channel_unix_new (fd[0]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   222
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   223
		g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   224
		g_io_channel_set_encoding (channel, NULL, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   225
		g_io_channel_set_close_on_unref (channel, TRUE);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   226
		g_io_channel_set_buffered (channel, FALSE);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   227
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   228
		{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   229
			cmd_cb_t *cb = g_new (cmd_cb_t, 1);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   230
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   231
			cb->jid     = g_strdup (jid);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   232
			cb->input   = g_string_new (NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   233
			cb->channel = channel;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   234
			cb->source  = g_io_add_watch_full (channel, 0, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   235
		                                   cmd_reader, (gpointer) cb, cmd_destroy_data);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   236
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   237
			cmd_channels = g_slist_append (cmd_channels, cb);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   238
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   239
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   240
}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   241
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   242
const gchar *g_module_check_init(GModule *module)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   243
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   244
	cmd_add ("cmd", "", 0, 0, do_cmd, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   245
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   246
	return NULL;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   247
}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   248
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   249
void g_module_unload(GModule *module)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   250
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   251
	GSList *sel;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   252
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   253
	cmd_del ("cmd");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   254
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   255
	for (sel = cmd_channels; sel; sel = sel->next) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   256
		cmd_cb_t *cb = (cmd_cb_t *) sel->data;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   257
		if (cb->source)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   258
			g_source_remove (cb->source);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   259
		if (cb->channel)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   260
			g_io_channel_unref (cb->channel);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   261
		g_free (cb->jid);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   262
		g_free (cb);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   263
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   264
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   265
	g_slist_free (cmd_channels);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   266
}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   267
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   268
/* vim: se ts=4 sw=4: */