2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* babel.c: running external programs and redirecting to TRWLayers.
23 * GPSBabel may not be necessary for everything -- for instance,
24 * use a_babel_convert_from_shellcommand with input_file_type == NULL
25 * for an external program that outputs GPX.
40 #include <glib/gstdio.h>
42 /* in the future we could have support for other shells (change command strings), or not use a shell at all */
43 #define BASH_LOCATION "/bin/bash"
45 gboolean a_babel_convert( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, gpointer user_data )
51 gchar *bargs = g_strconcat(babelargs, " -i gpx", NULL);
53 if ((fd_src = g_file_open_tmp("tmp-viking.XXXXXX", &name_src, NULL)) < 0) {
56 f = fdopen(fd_src, "w");
57 a_gpx_write_file(vt, f);
59 ret = a_babel_convert_from ( vt, bargs, cb, name_src, user_data );
68 /* Runs args[0] with the arguments and uses the GPX module
69 * to import the GPX data into layer vt. Assumes that upon
70 * running the command, the data will appear in the (usually
71 * temporary) file name_dst.
73 * cb: callback that is run upon new data from STDOUT (?)
74 * (TODO: STDERR would be nice since we usually redirect STDOUT)
75 * user_data: passed along to cb
77 * returns TRUE on success
79 gboolean babel_general_convert_from( VikTrwLayer *vt, BabelStatusFunc cb, gchar **args, const gchar *name_dst, gpointer user_data )
83 gint babel_stdin, babel_stdout, babel_stderr;
87 if (!g_spawn_async_with_pipes (NULL, args, NULL, 0, NULL, NULL, &pid, &babel_stdin, &babel_stdout, &babel_stderr, NULL)) {
88 // if (!g_spawn_async_with_pipes (NULL, args, NULL, 0, NULL, NULL, NULL, &babel_stdin, &babel_stdout, NULL, NULL)) {
93 diag = fdopen(babel_stdout, "r");
94 setvbuf(diag, NULL, _IONBF, 0);
96 while (fgets(line, sizeof(line), diag)) {
98 cb(BABEL_DIAG_OUTPUT, line, user_data);
101 cb(BABEL_DONE, NULL, user_data);
103 waitpid(pid, NULL, 0);
104 g_spawn_close_pid(pid);
106 f = fopen(name_dst, "r");
107 a_gpx_read_file ( vt, f );
115 gboolean a_babel_convert_from( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, const char *from, gpointer user_data )
120 gboolean ret = FALSE;
123 if ((fd_dst = g_file_open_tmp("tmp-viking.XXXXXX", &name_dst, NULL)) < 0) {
129 gpsbabel_loc = g_find_program_in_path("gpsbabel");
132 gchar *unbuffer_loc = g_find_program_in_path("unbuffer");
133 cmd = g_strdup_printf ( "%s%s%s %s -o gpx %s %s",
134 unbuffer_loc ? unbuffer_loc : "",
135 unbuffer_loc ? " " : "",
142 g_free ( unbuffer_loc );
144 args = g_strsplit(cmd, " ", 0);
145 ret = babel_general_convert_from ( vt, cb, args, name_dst, user_data );
156 /* Runs the input command in a shell (bash) and optionally uses GPSBabel to convert from input_file_type.
157 * If input_file_type is NULL, doesn't use GPSBabel. Input must be GPX (or Geocaching *.loc)
159 * Uses babel_general_convert_from to actually run the command. This function
160 * prepares the command and temporary file, and sets up the arguments for bash.
162 gboolean a_babel_convert_from_shellcommand ( VikTrwLayer *vt, const char *input_cmd, const char *input_file_type, BabelStatusFunc cb, gpointer user_data )
166 gboolean ret = FALSE;
169 if ((fd_dst = g_file_open_tmp("tmp-viking.XXXXXX", &name_dst, NULL)) < 0) {
172 gchar *shell_command;
173 if ( input_file_type )
174 shell_command = g_strdup_printf("%s | gpsbabel -i %s -f - -o gpx -F %s", input_cmd, input_file_type, name_dst);
176 shell_command = g_strdup_printf("%s > %s", input_cmd, name_dst);
178 g_debug("%s: %s", __FUNCTION__, shell_command);
181 args = g_malloc(sizeof(gchar *)*4);
182 args[0] = BASH_LOCATION;
184 args[2] = shell_command;
187 ret = babel_general_convert_from ( vt, cb, args, name_dst, user_data );
189 g_free ( shell_command );
197 gboolean babel_general_convert_to( VikTrwLayer *vt, BabelStatusFunc cb, gchar **args, const gchar *name_src, gpointer user_data )
201 gint babel_stdin, babel_stdout, babel_stderr;
203 if (!a_file_export(vt, name_src, FILE_TYPE_GPX)) {
204 g_warning("%s(): error exporting to %s", __FUNCTION__, name_src);
208 if (!g_spawn_async_with_pipes (NULL, args, NULL, 0, NULL, NULL, &pid, &babel_stdin, &babel_stdout, &babel_stderr, NULL)) {
213 diag = fdopen(babel_stdout, "r");
214 setvbuf(diag, NULL, _IONBF, 0);
216 while (fgets(line, sizeof(line), diag)) {
218 cb(BABEL_DIAG_OUTPUT, line, user_data);
221 cb(BABEL_DONE, NULL, user_data);
223 waitpid(pid, NULL, 0);
224 g_spawn_close_pid(pid);
232 gboolean a_babel_convert_to( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, const char *to, gpointer user_data )
237 gboolean ret = FALSE;
240 if ((fd_src = g_file_open_tmp("tmp-viking.XXXXXX", &name_src, NULL)) < 0) {
246 gpsbabel_loc = g_find_program_in_path("gpsbabel");
249 gchar *unbuffer_loc = g_find_program_in_path("unbuffer");
250 cmd = g_strdup_printf ( "%s%s%s %s -i gpx %s %s",
251 unbuffer_loc ? unbuffer_loc : "",
252 unbuffer_loc ? " " : "",
259 g_free ( unbuffer_loc );
260 g_debug ( "%s: %s", __FUNCTION__, cmd );
261 args = g_strsplit(cmd, " ", 0);
262 ret = babel_general_convert_to ( vt, cb, args, name_src, user_data );