/* * 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); }