/* 
   elmo - ELectronic Mail Operator

   Copyright (C) 2004 rzyjontko

   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; version 2.

   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.  

   ----------------------------------------------------------------------

*/
/****************************************************************************
 *    IMPLEMENTATION HEADERS
 ****************************************************************************/

#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>

#include "run.h"
#include "rstring.h"
#include "ask.h"
#include "read.h"
#include "eprintf.h"
#include "ecurses.h"
#include "error.h"
#include "gettext.h"
#include "file.h"
#include "wrapbox.h"
#include "mailreader.h"
#include "xmalloc.h"

/****************************************************************************
 *    IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE DATA
 ****************************************************************************/
/****************************************************************************
 *    INTERFACE DATA
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTIONS
 ****************************************************************************/

static int
run_me (rstring_t *cmd)
{
        int   status;
        pid_t pid;
        
        endwin ();
        
        pid = fork ();

        if (pid == 0){
                execvp (cmd->array[0], cmd->array);
                _exit (EXIT_FAILURE);
        }
        else if (pid < 0)
                status = -1;
        else if (waitpid (pid, & status, 0) != pid)
                status = -1;

        doupdate ();
        curs_set (0);

        if (status == -1){
                error_ (errno, _("execution of %s failed"), cmd->array[0]);
        }
        
        return status;
}


static int
is_format (const char *str)
{
        while (*str){
                if (isspace (*str) || *str == '%')
                        return 1;
                str++;
        }
        return 0;
}


static char *
dump_to_file (str_t *str)
{
        char *fname;
        FILE *fp;

        fp = file_temp_file (& fname);

        if (fp == NULL || fname == NULL){
                return NULL;
        }
        
        if (fwrite (str->str, 1, str->len, fp) != str->len){
                error_ (errno, "fwrite");
                fname = NULL;
        }

        fclose (fp);
        return fname;
}


/****************************************************************************
 *    INTERFACE FUNCTIONS
 ****************************************************************************/


int
run (char *cmd)
{
        int        ret;
        rstring_t *args;

        args = rstring_split_re (cmd, "[ \t]+");
        ret  = run_me (args);
        rstring_delete (args);

        return ret;
}



int
run_mime (mail_t *mail, mime_t *mime)
{
        eprintf_command_t cmd;
        char   *handler;
        str_t  *buf;
        char   *fname;
        char   *command;
        int     ret;
        
        if (mail == NULL || mime == NULL)
                return 1;

        handler = mime_get_handler (mime);

        if (handler == NULL)
                return 1;

        if (strcmp (handler, "elmo") == 0){
                mailreader_change_mime (mail, mime);
                return 2;
        }
        
        buf = wrapbox_mail_body (mail, mime, 1);
        if (buf == NULL){
                error_ (errno, _("opening attachment"));
                return 1;
        }

        fname = dump_to_file (buf);
        if (fname == NULL){
                str_destroy (buf);
                return 1;
        }

        cmd.fname     = fname;
        cmd.command   = NULL;
        cmd.lineno    = -1;
        cmd.mime_type = mime->type;

        command       = eprintf_command (handler, & cmd);
        ret           = run (command);

        unlink (fname);
        
        str_destroy (buf);
        xfree (command);
        xfree (fname);
        return ret;
}



int
run_editor (char *fname, int lineno, int col, int pos)
{
        eprintf_command_t cmd;
        rstring_t        *args;
        char             *editor  = ask_for_default ("editor", NULL);
        char             *command = NULL;
        int               ret;

        if (! editor || ! *editor)
                editor = getenv ("EDITOR");

        if (! editor || ! *editor)
                editor = read_argument ("Editor: ", NULL, COMPLETE_FILES,
                                        HIDE_NO);

        if (! editor || ! *editor)
                return 1;

        cmd.command   = editor;
        cmd.fname     = fname;
        cmd.lineno    = lineno;
        cmd.col       = col;
        cmd.pos       = pos;
        cmd.mime_type = NULL;

        if (is_format (editor)){
                command = eprintf_command (editor, & cmd);
        }
        else {
                command = eprintf_command ("%c %f", & cmd);
        }

        args = rstring_split_re (command, "[ \t]+");
        args->allocated_first = 1;

        ret = run_me (args);

        rstring_delete (args);

        return ret;
}


/****************************************************************************
 *    INTERFACE CLASS BODIES
 ****************************************************************************/
/****************************************************************************
 *
 *    END MODULE run.c
 *
 ****************************************************************************/


syntax highlighted by Code2HTML, v. 0.9.1