Added byline
[anjuta.git] / plugins / project-wizard / tar.c
blob36028345d95391184cdecbdb4a248d79f426072a
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 tar.c
4 Copyright (C) 2010 Sebastien Granjoux
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <config.h>
23 #include "tar.h"
25 #include <libanjuta/interfaces/ianjuta-wizard.h>
27 /*---------------------------------------------------------------------------*/
29 #define TMP_DEF_FILENAME "NPWDEFXXXXXX"
30 #define TMP_TPL_FILENAME "NPWTPLXXXXXX"
32 #define FILE_BUFFER_SIZE 4096
34 /* Type
35 *---------------------------------------------------------------------------*/
37 typedef struct _NPWTarPacket NPWTarPacket;
39 struct _NPWTarPacket
41 gint stdout;
42 gint stderr;
43 gpointer callback;
44 gpointer data;
45 GFile *tarfile;
46 GFile *destination;
49 /* Helper functions
50 *---------------------------------------------------------------------------*/
52 /* Tar Packet object
53 *---------------------------------------------------------------------------*/
55 static void
56 npw_tar_packet_free (NPWTarPacket *pack)
58 g_object_unref (pack->tarfile);
59 if (pack->destination) g_object_unref (pack->destination);
60 g_free (pack);
63 /* Public functions
64 *---------------------------------------------------------------------------*/
66 static void
67 on_tar_listed (GPid pid,
68 gint status,
69 gpointer data)
71 NPWTarPacket *pack = (NPWTarPacket *)data;
73 if (pack->callback != NULL)
75 GIOChannel *output;
76 GList *list;
77 GString *line;
78 GIOStatus status;
80 list = NULL;
81 line = g_string_new (NULL);
82 output = g_io_channel_unix_new (pack->stdout);
85 gsize terminator;
87 status = g_io_channel_read_line_string (output, line, &terminator, NULL);
88 if (status == G_IO_STATUS_NORMAL)
90 g_string_truncate (line, terminator);
92 list = g_list_prepend (list, g_strdup (line->str));
93 continue;
96 while (status == G_IO_STATUS_AGAIN);
97 g_io_channel_shutdown (output, TRUE, NULL);
98 g_io_channel_unref (output);
99 g_string_free (line, TRUE);
101 list = g_list_reverse (list);
102 ((NPWTarListFunc)pack->callback) (pack->tarfile, list, pack->data, NULL);
104 g_list_foreach (list, (GFunc)g_free, NULL);
105 g_list_free (list);
108 g_spawn_close_pid(pid);
111 static void
112 on_tar_completed (GPid pid,
113 gint status,
114 gpointer data)
116 NPWTarPacket *pack = (NPWTarPacket *)data;
118 if (pack->callback != NULL)
120 GError *error = NULL;
121 if (status != 0)
123 GIOChannel *stderr;
124 gchar *message;
125 gsize length;
127 stderr = g_io_channel_unix_new (pack->stderr);
128 g_io_channel_read_to_end (stderr, &message, &length, &error);
129 if (error != NULL)
131 error = g_error_new_literal (IANJUTA_WIZARD_ERROR, 0, message);
133 g_io_channel_shutdown (stderr, TRUE, NULL);
134 g_io_channel_unref (stderr);
137 ((NPWTarCompleteFunc)pack->callback) (pack->destination, pack->tarfile, pack->data, error);
138 g_clear_error (&error);
141 g_spawn_close_pid(pid);
144 /* Public functions
145 *---------------------------------------------------------------------------*/
147 gboolean
148 npw_tar_list (GFile *tarfile, NPWTarListFunc list, gpointer data, GError **error)
150 gchar *argv [] = {"tar", "--force-local", "--no-wildcards", "-tzf", NULL, NULL};
151 gchar *prog;
152 gchar *filename;
153 GPid pid;
154 gboolean ok;
155 NPWTarPacket *pack;
157 /* Use gtar if available */
158 prog = g_find_program_in_path ("gtar");
159 filename = g_file_get_path (tarfile);
160 argv[4] = filename;
162 /* Execute tar command asynchronously */
163 pack = g_new0(NPWTarPacket, 1);
164 pack->callback = (gpointer)list;
165 pack->data = data;
166 pack->tarfile = g_object_ref (tarfile);
167 ok = g_spawn_async_with_pipes (NULL, argv, NULL,
168 G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
169 NULL, NULL,
170 &pid,
171 NULL,
172 &pack->stdout,
173 NULL,
174 error);
176 if (ok)
178 g_child_watch_add_full (G_PRIORITY_HIGH_IDLE, pid, on_tar_listed, pack, (GDestroyNotify)npw_tar_packet_free);
181 g_free (filename);
182 g_free (prog);
184 return ok;
187 gboolean
188 npw_tar_extract (GFile *destination, GFile *tarfile, NPWTarCompleteFunc complete, gpointer data, GError **error)
190 gchar *argv [] = {"tar", "--force-local", "--no-wildcards", "-C", NULL, "-xzf", NULL, NULL};
191 gchar *prog;
192 gchar *filename;
193 gchar *dirname;
194 GPid pid;
195 gboolean ok;
196 NPWTarPacket *pack;
198 /* Use gtar if available */
199 prog = g_find_program_in_path ("gtar");
200 dirname = g_file_get_path (destination);
201 argv[4] = dirname;
202 filename = g_file_get_path (tarfile);
203 argv[6] = filename;
205 /* Execute tar command asynchronously */
206 pack = g_new0(NPWTarPacket, 1);
207 pack->callback = (gpointer)complete;
208 pack->data = data;
209 pack->tarfile = g_object_ref (tarfile);
210 pack->destination = g_object_ref (destination);
211 ok = g_spawn_async_with_pipes (NULL, argv, NULL,
212 G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
213 NULL, NULL,
214 &pid,
215 NULL,
216 NULL,
217 &pack->stderr,
218 error);
220 if (ok)
222 g_child_watch_add_full (G_PRIORITY_HIGH_IDLE, pid, on_tar_completed, pack, (GDestroyNotify)npw_tar_packet_free);
225 g_free (filename);
226 g_free (dirname);
227 g_free (prog);
229 return ok;