extsay-ng/extsay.c
author Mikael Berthe <mikael@lilotux.net>
Sat, 13 Oct 2012 14:34:18 +0200
changeset 44 3f94f3522960
parent 40 5cd4b42ada91
permissions -rw-r--r--
[killpresence] Add a command /probe to send a presence probe

/*
 *  Module "extsay"     -- adds a /extsay command
 *                         Spawns an external editor, using screen
 *                         See the README file
 *
 * Copyright (C) 2010 Mikael Berthe <mikael@lilotux.net>
 *
 * This module 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, see <http://www.gnu.org/licenses/>.
 */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <glib/gstdio.h>

#include <mcabber/modules.h>
#include <mcabber/commands.h>
#include <mcabber/settings.h>
#include <mcabber/compl.h>
#include <mcabber/utils.h>
#include <mcabber/logprint.h>

static void extsay_init(void);
static void extsay_uninit(void);

/* Module description */
module_info_t info_extsay = {
        .branch         = MCABBER_BRANCH,
        .api            = MCABBER_API_VERSION,
        .version        = "0.02",
        .description    = "Use external editor to send a message",
        .requires       = NULL,
        .init           = extsay_init,
        .uninit         = extsay_uninit,
        .next           = NULL,
};

#ifdef MCABBER_API_HAVE_CMD_ID
static gpointer extsay_cmdid;
#endif


// Run the external helper script with parameters
static void screen_run_script(const gchar *args)
{
  GError *err = NULL;
  gchar *argv[] = { "screen", "-r", "-X", "screen", NULL,
                    NULL, NULL, NULL, NULL };
  gchar strwinheight[32];
  gchar *fpath;
  gboolean winsplit, ret;

  // screen -r -X screen $path/extsay.sh [jid [winsplit [height]]]
  fpath = (gchar*)settings_opt_get("extsay_script_path");

  // Helper script path
  if (!fpath || !fpath[0]) {
    scr_log_print(LPRINT_NORMAL, "Please set option 'extsay_script_path'.");
    return;
  }
  fpath = expand_filename(fpath);
  argv[4] = fpath;

  // Helper script parameter #1
  if (args && *args)
    argv[5] = (gchar*)args;
  else
    argv[5] = ".";

  // Update parameters for the helper script
  winsplit = settings_opt_get_int("extsay_split_win");
  if (winsplit) {
    gint winheight = settings_opt_get_int("extsay_win_height");
    argv[6] = "winsplit";       // Helper script parameter #2
    if (winheight > 0 && winheight < 256) {
      snprintf(strwinheight, sizeof strwinheight, "%d", winheight);
      argv[7] = strwinheight;   // Helper script parameter #3
    }
  }

  ret = g_spawn_async(NULL, argv, NULL,
                      G_SPAWN_SEARCH_PATH |
                        G_SPAWN_STDOUT_TO_DEV_NULL|G_SPAWN_STDERR_TO_DEV_NULL,
                      NULL, NULL, NULL, &err);

  if (!ret)
    scr_LogPrint(LPRINT_NORMAL, err->message);

  g_free(fpath);
}

static void do_extsay(gchar *args)
{
  gboolean expandfjid = FALSE;
  gchar *fjid;

  if (args && !strncmp(args, "." JID_RESOURCE_SEPARATORSTR, 2))
    expandfjid = TRUE;

  if (!args || !*args || expandfjid || !g_strcmp0(args, ".")) {
    const gchar *res = args+2;
    gpointer bud;

    if (!current_buddy) {
      scr_LogPrint(LPRINT_NORMAL, "Please select a buddy.");
      return;
    }

    bud = BUDDATA(current_buddy);
    if (!(buddy_gettype(bud) &
          (ROSTER_TYPE_USER|ROSTER_TYPE_AGENT|ROSTER_TYPE_ROOM))) {
      scr_LogPrint(LPRINT_NORMAL, "This is not a user.");
      return;
    }

    args = (gchar*)buddy_getjid(bud);
    if (expandfjid && *res) {
      char *res_utf8 = to_utf8(res);
      fjid = g_strdup_printf("%s%c%s", args, JID_RESOURCE_SEPARATOR, res_utf8);
      g_free(res_utf8);
    } else {
      fjid = g_strdup(args);
    }
  } else {
    fjid = to_utf8(args);
  }

  if (check_jid_syntax(fjid))
    scr_LogPrint(LPRINT_NORMAL, "Please specify a valid Jabber ID.");
  else
    screen_run_script(fjid); // Launch helper script with resulting JID

  g_free(fjid);
}

static void extsay_init(void)
{
#ifdef MCABBER_API_HAVE_CMD_ID
  extsay_cmdid = cmd_add("extsay", "Use external editor to write a message",
                         COMPL_JID, 0, do_extsay, NULL);
#else
  cmd_add("extsay", "Use external editor to write a message",
          COMPL_JID, 0, do_extsay, NULL);
#endif
}

static void extsay_uninit(void)
{
#ifdef MCABBER_API_HAVE_CMD_ID
  cmd_del(extsay_cmdid);
#else
  cmd_del("extsay");
#endif
}

/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */