]> git.street.me.uk Git - andy/viking.git/blob - src/babel.c
Copying libcurl.m4
[andy/viking.git] / src / babel.c
1 /*
2  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3  *
4  * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #include "viking.h"
23 #include "gpx.h"
24 #include "babel.h"
25 #include "sys/wait.h"
26
27 /* in the future we could have support for other shells (change command strings), or not use a shell at all */
28 #define BASH_LOCATION "/bin/bash"
29
30 gboolean a_babel_convert( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, gpointer user_data )
31 {
32   int fd_src;
33   FILE *f;
34   gchar *name_src;
35   gboolean ret = FALSE;
36   gchar *bargs = g_strconcat(babelargs, " -i gpx");
37
38   if ((fd_src = g_file_open_tmp("tmp-viking.XXXXXX", &name_src, NULL)) < 0) {
39     ret = FALSE;
40   } else {
41     f = fdopen(fd_src, "w");
42     a_gpx_write_file(vt, f);
43     fclose(f);
44     ret = a_babel_convert_from ( vt, bargs, cb, name_src, user_data );
45   }
46
47   g_free(bargs);
48   remove(name_src);
49   g_free(name_src);
50   return ret;
51 }
52
53 gboolean babel_general_convert_from( VikTrwLayer *vt, BabelStatusFunc cb, gchar **args, const gchar *name_dst, gpointer user_data )
54 {
55   gboolean ret;
56   GPid pid;
57   gint babel_stdin, babel_stdout, babel_stderr;
58   FILE *f;
59
60
61   if (!g_spawn_async_with_pipes (NULL, args, NULL, 0, NULL, NULL, &pid, &babel_stdin, &babel_stdout, &babel_stderr, NULL)) {
62     //    if (!g_spawn_async_with_pipes (NULL, args, NULL, 0, NULL, NULL, NULL, &babel_stdin, &babel_stdout, NULL, NULL)) {
63     ret = FALSE;
64   } else {
65     gchar line[512];
66     FILE *diag;
67     diag = fdopen(babel_stdout, "r");
68     setvbuf(diag, NULL, _IONBF, 0);
69
70     while (fgets(line, sizeof(line), diag)) {
71       if ( cb )
72         cb(BABEL_DIAG_OUTPUT, line, user_data);
73     }
74     if ( cb )
75       cb(BABEL_DONE, NULL, user_data);
76     fclose(diag);
77     waitpid(pid, NULL, 0);
78     g_spawn_close_pid(pid);
79
80     f = fopen(name_dst, "r");
81     a_gpx_read_file ( vt, f );
82      fclose(f);
83     ret = TRUE;
84   }
85     
86   return ret;
87 }
88
89 gboolean a_babel_convert_from( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, const char *from, gpointer user_data )
90 {
91   int fd_dst;
92   gchar *name_dst;
93   gchar *cmd;
94   gboolean ret = FALSE;
95   gchar **args;  
96
97   if ((fd_dst = g_file_open_tmp("tmp-viking.XXXXXX", &name_dst, NULL)) < 0) {
98     ret = FALSE;
99   } else {
100     gchar *gpsbabel_loc;
101     close(fd_dst);
102
103     gpsbabel_loc = g_find_program_in_path("gpsbabel");
104
105     if (gpsbabel_loc ) {
106       gchar *unbuffer_loc = g_find_program_in_path("unbuffer");
107       cmd = g_strdup_printf ( "%s%s%s %s -o gpx %s %s",
108                               unbuffer_loc ? unbuffer_loc : "",
109                               unbuffer_loc ? " " : "",
110                               gpsbabel_loc,
111                               babelargs,
112                               from,
113                               name_dst );
114
115       if ( unbuffer_loc )
116         g_free ( unbuffer_loc );
117
118       args = g_strsplit(cmd, " ", 0);
119       ret = babel_general_convert_from ( vt, cb, args, name_dst, user_data );
120       g_strfreev(args);
121       g_free ( cmd );
122     }
123   }
124
125   remove(name_dst);
126   g_free(name_dst);
127   return ret;
128 }
129
130 gboolean a_babel_convert_from_shellcommand ( VikTrwLayer *vt, const char *input_cmd, const char *input_type, BabelStatusFunc cb, gpointer user_data )
131 {
132   int fd_dst;
133   gchar *name_dst;
134   gboolean ret = FALSE;
135   gchar **args;  
136
137   if ((fd_dst = g_file_open_tmp("tmp-viking.XXXXXX", &name_dst, NULL)) < 0) {
138     ret = FALSE;
139   } else {
140     gchar *shell_command = g_strdup_printf("%s | gpsbabel -i %s -f - -o gpx -F %s", input_cmd, input_type, name_dst);
141     printf("%s\n", shell_command);
142     close(fd_dst);
143
144     args = g_malloc(sizeof(gchar *)*4);
145     args[0] = BASH_LOCATION;
146     args[1] = "-c";
147     args[2] = shell_command;
148     args[3] = NULL;
149
150     ret = babel_general_convert_from ( vt, cb, args, name_dst, user_data );
151     g_free ( args );
152     g_free ( shell_command );
153   }
154
155   remove(name_dst);
156   g_free(name_dst);
157   return ret;
158 }
159
160 gboolean babel_general_convert_to( VikTrwLayer *vt, BabelStatusFunc cb, gchar **args, const gchar *name_src, gpointer user_data )
161 {
162   gboolean ret;
163   GPid pid;
164   gint babel_stdin, babel_stdout, babel_stderr;
165
166   if (!a_file_export(vt, name_src, FILE_TYPE_GPX)) {
167     fprintf(stderr, "babel_general_convert_to(): error exporting to %s\n", name_src);
168     return(FALSE);
169   }
170
171   if (!g_spawn_async_with_pipes (NULL, args, NULL, 0, NULL, NULL, &pid, &babel_stdin, &babel_stdout, &babel_stderr, NULL)) {
172     ret = FALSE;
173   } else {
174     gchar line[512];
175     FILE *diag;
176     diag = fdopen(babel_stdout, "r");
177     setvbuf(diag, NULL, _IONBF, 0);
178
179     while (fgets(line, sizeof(line), diag)) {
180       if ( cb )
181         cb(BABEL_DIAG_OUTPUT, line, user_data);
182     }
183     if ( cb )
184       cb(BABEL_DONE, NULL, user_data);
185     fclose(diag);
186     waitpid(pid, NULL, 0);
187     g_spawn_close_pid(pid);
188
189     ret = TRUE;
190   }
191     
192   return ret;
193 }
194
195 gboolean a_babel_convert_to( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, const char *to, gpointer user_data )
196 {
197   int fd_src;
198   gchar *name_src;
199   gchar *cmd;
200   gboolean ret = FALSE;
201   gchar **args;  
202
203   if ((fd_src = g_file_open_tmp("tmp-viking.XXXXXX", &name_src, NULL)) < 0) {
204     ret = FALSE;
205   } else {
206     gchar *gpsbabel_loc;
207     close(fd_src);
208
209     gpsbabel_loc = g_find_program_in_path("gpsbabel");
210
211     if (gpsbabel_loc ) {
212       gchar *unbuffer_loc = g_find_program_in_path("unbuffer");
213       cmd = g_strdup_printf ( "%s%s%s %s -i gpx %s %s",
214                               unbuffer_loc ? unbuffer_loc : "",
215                               unbuffer_loc ? " " : "",
216                               gpsbabel_loc,
217                               babelargs,
218                               name_src,
219                               to);
220
221       if ( unbuffer_loc )
222         g_free ( unbuffer_loc );
223 #ifdef DBG
224       fprintf(stderr, "cmd=%s\n", cmd);
225 #endif /* DBG */
226       args = g_strsplit(cmd, " ", 0);
227       ret = babel_general_convert_to ( vt, cb, args, name_src, user_data );
228       g_strfreev(args);
229       g_free ( cmd );
230     }
231   }
232
233   remove(name_src);
234   g_free(name_src);
235   return ret;
236 }