/*
* ncpwrapper.c
*
* This file is part of gncpmount.
*
* gncpmount 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 3 of the License, or
* (at your option) any later version.
*
* gncpmount 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 gncpmount. If not, see .
*
* Author: Jan Lipovsky
*
*/
#include "ncpwrapper.h"
/** TData structure */
typedef struct struc_data
{
gchar *m1format;
gchar *m1;
gchar *m2format;
gchar *m2;
gint count;
GtkMessageType msgtype;
gboolean show;
gboolean stdout_end;
gboolean stderr_end;
gint timeout;
} TData;
/** data structure to comunicate between callbacks */
TData data;
/**
* Fill data structure
*/
void fill_data (TData *data,
const gchar *m1format,
const gchar *m1,
const gchar *m2format,
const gchar *m2,
GtkMessageType type,
const gboolean show)
{
if(data->m1 != NULL)
g_free(data->m1);
if(data->m1format != NULL)
g_free(data->m1format);
if(data->m2 != NULL)
g_free(data->m2);
if(data->m2format != NULL)
g_free(data->m2format);
data->m1 = g_strdup(m1);
data->m1format = g_strdup(m1format);
data->m2 = g_strdup(m2);
data->m2format= g_strdup(m2format);
data->msgtype = type;
data->count++;
data->show = show;
}
/**
* Catch termination of the process
*/
static void
cb_child_watch(GPid pid)
{
/* Close pid */
g_spawn_close_pid( pid );
}
/**
* Timeout loop, show messages
*/
static gboolean
cb_timeout( TData *data )
{
if(data->show)
{
data->show = FALSE;
show_message( data->msgtype, data->m1format, data->m1, data->m2format, data->m2);
}
if(data->stderr_end && data->stdout_end)
{
if(data->count == 0)
show_message(GTK_MESSAGE_INFO, _("Mounting successful"), "",_("Mounted to \"%s\" directory."),cmd_params.mount_point);
g_source_remove(data->timeout);
}
return( TRUE );
}
/**
* Catch messages on stdout
*/
static gboolean
cb_out_watch( GIOChannel *channel,
GIOCondition cond,
TData *data)
{
GString *string;
gchar *tmp;
gsize size;
if( cond == G_IO_HUP )
{
data->stdout_end = TRUE;
g_io_channel_unref( channel );
return( FALSE );
}
string = g_string_new("");
while (g_io_channel_read_line( channel, &tmp, &size, NULL, NULL) == G_IO_STATUS_NORMAL)
{
if(tmp != NULL)
string = g_string_append (string, tmp);
g_free( tmp );
}
fill_data (data,"%s", _("ncpmount output"),"%s",string->str, GTK_MESSAGE_INFO, TRUE);
g_string_free(string, TRUE);
return( TRUE );
}
/**
* Catch messages on stdout
*/
static gboolean
cb_err_watch( GIOChannel *channel,
GIOCondition cond,
TData *data)
{
GString *string;
gchar *tmp;
gsize size;
if( cond == G_IO_HUP )
{
data->stderr_end = TRUE;
g_io_channel_unref( channel );
return( FALSE );
}
string = g_string_new("");
while (g_io_channel_read_line( channel, &tmp, &size, NULL, NULL) == G_IO_STATUS_NORMAL)
{
if(tmp != NULL)
string = g_string_append (string, tmp);
g_free( tmp );
}
fill_data (data, "%s", _("ncpmount error"),"%s",string->str, GTK_MESSAGE_ERROR, TRUE);
g_string_free(string, TRUE);
return( TRUE );
}
/**
* Run ncpmount and adds wotches to stdout and stderr
*/
void run_ncpmount()
{
GIOChannel *out_ch, *err_ch;
GError *gerror = NULL;
GPid pid;
gint out, err, argc;
gboolean ret;
gchar *command = get_ncpmount_command(TRUE, NULL);
gchar **argv;
/*gchar **argv = g_strsplit(command, " ", 0);*/
if(!g_shell_parse_argv (command,&argc,&argv,&gerror))
{
g_warning(gerror->message);
show_message( GTK_MESSAGE_ERROR,"ERROR: %s", "Shell parse argv fail","%s",gerror->message);
g_error_free(gerror);
return;
}
/*puts (command);*/
g_free(argv[0]);
argv[0] = g_strdup(NCPMOUNT_PATH);
/* gchar *argv[] = {"/usr/bin/ncpmount", "-v", NULL};*/
/* Spawn child process */
ret = g_spawn_async_with_pipes( NULL, argv, NULL,
G_SPAWN_DO_NOT_REAP_CHILD, NULL,
NULL, &pid, NULL, &out, &err, &gerror);
if( !ret )
{
g_warning(gerror->message);
show_message( GTK_MESSAGE_ERROR,"ERROR: %s", "Spawn failed!","%s",gerror->message);
g_error_free(gerror);
return;
}
/* function to catch termination of the process. */
g_child_watch_add( pid, (GChildWatchFunc)cb_child_watch, &data);
/* Create channels that will be used to read data from pipes. */
#ifdef G_OS_WIN32
out_ch = g_io_channel_win32_new_fd( out );
err_ch = g_io_channel_win32_new_fd( err );
#else
out_ch = g_io_channel_unix_new( out );
err_ch = g_io_channel_unix_new( err );
#endif
/* Add watches to channels */
g_io_add_watch( err_ch, G_IO_IN | G_IO_HUP, (GIOFunc)cb_err_watch, &data );
g_io_add_watch( out_ch, G_IO_IN | G_IO_HUP, (GIOFunc)cb_out_watch, &data );
/* Init data structure */
data.count = 0;
data.stderr_end = FALSE;
data.stdout_end = FALSE;
/* Add timeout collback */
data.timeout = g_timeout_add( 100, (GSourceFunc)cb_timeout, &data );
g_strfreev(argv);
g_free(command);
}