cmd.c
author Myhailo Danylenko <isbear@ukrpost.net>
Sun, 08 Nov 2009 21:09:37 +0200
changeset 0 72ffcc3c584e
child 4 e305d7e562c4
permissions -rw-r--r--
Initial commit
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;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    94
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    95
					if (written - sent > HBB_BLOCKSIZE) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    96
						gchar *c = utf8 + sent + HBB_BLOCKSIZE;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    97
						c = g_utf8_find_prev_char (utf8 + sent, c);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    98
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    99
						if (!c) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   100
							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
   101
							break;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   102
						}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   103
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   104
						len  = c - utf8 - sent;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   105
						bbuf = g_strndup (utf8 + sent, len);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   106
					}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   107
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   108
					// XXX add command/sequence number as title?
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   109
					xmpp_send_msg (cb->jid, len ? bbuf : (utf8 + sent), ROSTER_TYPE_USER, NULL, FALSE /* ? */, &crypted, 0, &xep184);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   110
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   111
					if (crypted == -1) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   112
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   113
						scr_LogPrint (LPRINT_LOGNORM, "cmd: Encryption error. Message not sent.");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   114
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   115
						if (!len)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   116
							break;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   117
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   118
						g_free (bbuf);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   119
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   120
						continue;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   121
					}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   122
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   123
					hk_message_out (cb->jid, NULL, 0, len ? bbuf : (utf8 + sent), crypted, xep184);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   124
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   125
					if (!len)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   126
						break;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   127
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   128
					g_free (bbuf);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   129
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   130
					sent += len;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   131
				}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   132
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   133
				g_free (utf8);
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_string_erase (input, 0, bread);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   136
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   137
			} else {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   138
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   139
				scr_LogPrint (LPRINT_LOGNORM, "cmd: Character conversion error: %s", err->message);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   140
				cb->source = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   141
				return FALSE;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   142
			}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   143
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   144
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   145
	} else if (condition & (G_IO_ERR|G_IO_NVAL|G_IO_HUP)) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   146
		cb->source = 0;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   147
		return FALSE; // XXX
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   148
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   149
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   150
	return TRUE;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   151
}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   152
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   153
static void cmd_destroy_data (gpointer data)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   154
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   155
	cmd_cb_t *cb = (cmd_cb_t *) 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_channels = g_slist_remove (cmd_channels, 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
	// May conflict - will be called during source removal?
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   160
//	if (cb->source)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   161
//		g_source_remove (cb->source);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   162
	if (cb->channel)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   163
		g_io_channel_unref (cb->channel);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   164
	g_free (cb->jid);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   165
	g_free (cb);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   166
}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   167
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   168
static void do_cmd (char *arg)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   169
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   170
	int         fd[2];
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   171
	const char *jid = CURRENT_JID;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   172
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   173
	if (!*arg)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   174
		return;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   175
	
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   176
	if (!jid) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   177
		scr_LogPrint (LPRINT_LOGNORM, "Unsuitable buddy selected");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   178
		return;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   179
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   180
	
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   181
	if (pipe (fd)) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   182
		scr_LogPrint (LPRINT_LOGNORM, "Cannot create pipe: %s", strerror (errno));
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   183
		return;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   184
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   185
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   186
	{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   187
		int res = fork ();
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   188
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   189
		if (!res) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   190
			
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   191
			close (fd[0]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   192
			dup2 (fd[1], STDOUT_FILENO);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   193
			if (settings_opt_get_int ("cmd_redirect_stderr"))
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   194
				dup2 (fd[1], STDERR_FILENO);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   195
			else
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   196
				close (STDERR_FILENO);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   197
			close (STDIN_FILENO);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   198
			close (fd[1]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   199
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   200
			{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   201
				const char *shell = settings_opt_get ("cmd_shell");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   202
				if (!shell)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   203
					shell = getenv ("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 = "sh";
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   206
				execl (shell, shell, "-c", arg, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   207
			}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   208
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   209
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   210
		if (res == -1) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   211
			scr_LogPrint (LPRINT_NORMAL, "Cannot fork child: %s", strerror (errno));
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   212
			close (fd[0]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   213
			close (fd[1]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   214
			return;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   215
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   216
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   217
		close (fd[1]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   218
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   219
		GIOChannel *channel = g_io_channel_unix_new (fd[0]);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   220
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   221
		g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   222
		g_io_channel_set_encoding (channel, NULL, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   223
		g_io_channel_set_close_on_unref (channel, TRUE);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   224
		g_io_channel_set_buffered (channel, FALSE);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   225
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   226
		{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   227
			cmd_cb_t *cb = g_new (cmd_cb_t, 1);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   228
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   229
			cb->jid     = g_strdup (jid);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   230
			cb->input   = g_string_new (NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   231
			cb->channel = channel;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   232
			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
   233
		                                   cmd_reader, (gpointer) cb, cmd_destroy_data);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   234
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   235
			cmd_channels = g_slist_append (cmd_channels, cb);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   236
		}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   237
	}
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
const gchar *g_module_check_init(GModule *module)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   241
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   242
	cmd_add ("cmd", "", 0, 0, do_cmd, NULL);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   243
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   244
	return 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
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   247
void g_module_unload(GModule *module)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   248
{
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   249
	GSList *sel;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   250
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   251
	cmd_del ("cmd");
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   252
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   253
	for (sel = cmd_channels; sel; sel = sel->next) {
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   254
		cmd_cb_t *cb = (cmd_cb_t *) sel->data;
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   255
		if (cb->source)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   256
			g_source_remove (cb->source);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   257
		if (cb->channel)
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   258
			g_io_channel_unref (cb->channel);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   259
		g_free (cb->jid);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   260
		g_free (cb);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   261
	}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   262
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   263
	g_slist_free (cmd_channels);
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   264
}
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   265
72ffcc3c584e Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   266
/* vim: se ts=4 sw=4: */