extsay/extsay.c
changeset 21 9798e3aaa851
parent 20 4fbed301c014
child 22 b6b45c2eb022
equal deleted inserted replaced
20:4fbed301c014 21:9798e3aaa851
     1 /*
       
     2    Copyright 2009,2010 Andreas Fett
       
     3    Copyright 2010 Mikael Berthe
       
     4 
       
     5   Module "extsay"     -- adds a /extsay command
       
     6                          Spawns an external editor
       
     7   Original code from Andreas Fett.
       
     8 
       
     9 This module is free software: you can redistribute it and/or modify
       
    10 it under the terms of the GNU General Public License as published by
       
    11 the Free Software Foundation, either version 2 of the License, or
       
    12 (at your option) any later version.
       
    13 
       
    14 This program is distributed in the hope that it will be useful,
       
    15 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    17 GNU General Public License for more details.
       
    18 
       
    19 You should have received a copy of the GNU General Public License
       
    20 along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    21 */
       
    22 
       
    23 #include <unistd.h>
       
    24 #include <stdlib.h>
       
    25 #include <sys/wait.h>
       
    26 #include <glib/gstdio.h>
       
    27 
       
    28 #include <mcabber/modules.h>
       
    29 #include <mcabber/commands.h>
       
    30 #include <mcabber/screen.h>
       
    31 
       
    32 static void extsay_init(void);
       
    33 static void extsay_uninit(void);
       
    34 
       
    35 /* Module description */
       
    36 module_info_t info_extsay = {
       
    37         .branch         = MCABBER_BRANCH,
       
    38         .api            = MCABBER_API_VERSION,
       
    39         .version        = "0.01",
       
    40         .description    = "Use external editor to send a message\n"
       
    41                           "WARNING: use at your own risk - "
       
    42                           "mcabber is stuck while you write a message, "
       
    43                           "this is not recommended!",
       
    44         .requires       = NULL,
       
    45         .init           = extsay_init,
       
    46         .uninit         = extsay_uninit,
       
    47         .next           = NULL,
       
    48 };
       
    49 
       
    50 // XXX Not very clean, internal function...
       
    51 char *load_message_from_file(const char *filename);
       
    52 
       
    53 static char* spawn_editor() {
       
    54   GError *err = NULL;
       
    55   gchar *argv[] = { NULL, NULL };
       
    56   gchar *tmpfile = NULL;
       
    57   gchar *tmpl = "mcabber-XXXXXX";
       
    58   gchar *msg;
       
    59   gboolean ret;
       
    60   gint fd;
       
    61   gint exit_status = 0;
       
    62 
       
    63   argv[0] = (gchar*)g_getenv("EDITOR");
       
    64   if (argv[0] == NULL) {
       
    65     scr_LogPrint(LPRINT_NORMAL, "Environment variable EDITOR not set.");
       
    66     return NULL;
       
    67   }
       
    68 
       
    69   fd = g_file_open_tmp(tmpl, &tmpfile, &err);
       
    70   if ( fd < 0 ) {
       
    71     scr_LogPrint(LPRINT_NORMAL, err->message);
       
    72     g_error_free(err);
       
    73     return NULL;
       
    74   }
       
    75   close(fd);
       
    76 
       
    77   argv[1] = tmpfile;
       
    78 
       
    79   endwin();
       
    80   ret = g_spawn_sync(NULL, argv, NULL,
       
    81                      G_SPAWN_CHILD_INHERITS_STDIN|G_SPAWN_SEARCH_PATH,
       
    82                      NULL, NULL, NULL, NULL, &exit_status, &err);
       
    83 
       
    84   raw();
       
    85   readline_refresh_screen();
       
    86 
       
    87   if (!ret) {
       
    88     scr_LogPrint(LPRINT_NORMAL, err->message);
       
    89     return NULL;
       
    90   }
       
    91 
       
    92   if (WEXITSTATUS(exit_status) != EXIT_SUCCESS) {
       
    93     scr_LogPrint(LPRINT_NORMAL,
       
    94                  "Editor exited with error, discarding message.");
       
    95     return NULL;
       
    96   }
       
    97 
       
    98   msg = load_message_from_file(tmpfile);
       
    99 
       
   100   if (g_unlink(tmpfile) != 0)
       
   101     scr_LogPrint(LPRINT_NORMAL, "Warning, could not remove temp file.");
       
   102 
       
   103   return msg;
       
   104 }
       
   105 
       
   106 static void do_extsay(char *args)
       
   107 {
       
   108   char *msg = spawn_editor();
       
   109   if (msg) {
       
   110     say_cmd(msg, 0);
       
   111     g_free(msg);
       
   112   }
       
   113 }
       
   114 
       
   115 /* Initialization */
       
   116 static void extsay_init(void)
       
   117 {
       
   118   /* Add command */
       
   119   cmd_add("extsay", "Use external editor to write a message",
       
   120           0, 0, do_extsay, NULL);
       
   121   scr_LogPrint(LPRINT_NORMAL, "Loading module extsay...\n"
       
   122                "** Be careful, everything is on hold while you run the "
       
   123                "external editor.\n"
       
   124                "** Do not run it for too long!"
       
   125                );
       
   126 }
       
   127 
       
   128 /* Deinitialization */
       
   129 static void extsay_uninit(void)
       
   130 {
       
   131   /* Unregister command */
       
   132   cmd_del("extsay");
       
   133 }
       
   134 
       
   135 /* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */