~ubuntu-branches/ubuntu/karmic/xarchiver/karmic

« back to all changes in this revision

Viewing changes to src/rpm.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-11-07 14:54:00 UTC
  • mfrom: (1.1.7 upstream) (2.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20081107145400-z0j3jmgads8coae2
Tags: 0.5.1-1
MergingĀ upstreamĀ versionĀ 0.5.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  Copyright (C) 2006 Giuseppe Torelli - <colossus73@gmail.com>
3
 
 *  Copyright (C) 2006 Benedikt Meurer - <benny@xfce.org>
 
2
 *  Copyright (C) 2008 Giuseppe Torelli - <colossus73@gmail.com>
4
3
 *
5
4
 *  This program is free software; you can redistribute it and/or modify
6
5
 *  it under the terms of the GNU General Public License as published by
20
19
#include "config.h"
21
20
#include "rpm.h"
22
21
#include "string_utils.h"
23
 
 
24
 
extern int output_fd, input_fd;
25
 
FILE *stream;
26
 
int fd;
27
 
gchar *cpio_tmp = NULL;
28
 
gchar *tmp = NULL;
29
 
gchar buffer[2048];
30
 
gsize bytes_read = 0;
31
 
gsize bytes_written = 0;
32
 
GIOStatus status;
33
 
GError *error = NULL;
34
 
GIOChannel *ioc_cpio , *input_ioc, *output_ioc;
35
 
 
36
 
void OpenRPM ( XArchive *archive )
 
22
extern gboolean batch_mode;
 
23
 
 
24
void xa_open_rpm (XArchive *archive)
37
25
{
38
26
        unsigned char bytes[8];
39
 
    int dl,il,sigsize,offset;
40
 
    gchar *ibs;
 
27
        unsigned short int i;
 
28
    int dl,il,sigsize,offset,response;
 
29
    gchar *ibs,*executable;
 
30
    gchar *gzip_tmp = NULL;
 
31
        GSList *list = NULL;
 
32
        FILE *stream;
 
33
        gboolean result;
41
34
 
42
35
    signal (SIGPIPE, SIG_IGN);
43
36
    stream = fopen ( archive->path , "r" );
44
37
        if (stream == NULL)
45
38
    {
46
39
        gchar *msg = g_strdup_printf (_("Can't open RPM file %s:") , archive->path);
47
 
                response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow) , GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,
48
 
                msg,g_strerror (errno));
 
40
                response = xa_show_message_dialog (GTK_WINDOW (xa_main_window) , GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,
 
41
                msg,g_strerror(errno));
49
42
                g_free (msg);
50
43
                return;
51
44
    }
 
45
    archive->can_extract = archive->has_properties = TRUE;
 
46
    archive->can_add = archive->has_sfx = archive->has_test = FALSE;
52
47
    archive->dummy_size = 0;
53
48
    archive->nr_of_files = 0;
54
 
    archive->nr_of_dirs = 0;
 
49
    archive->nc = 8;
55
50
        archive->format ="RPM";
56
 
        char *names[]= {(_("Filename")),(_("Permission")),(_("Symbolic Link")),(_("Hard Link")),(_("Owner")),(_("Group")),(_("Size"))};
57
 
        GType types[]= {G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_UINT64};
58
 
        xa_create_liststore ( 7, names , (GType *)types, archive );
 
51
 
 
52
        char *names[]= {(_("Points to")),(_("Size")),(_("Permission")),(_("Date")),(_("Hard Link")),(_("Owner")),(_("Group")),NULL};
 
53
        GType types[]= {GDK_TYPE_PIXBUF,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_UINT64,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_POINTER};
 
54
        archive->column_types = g_malloc0(sizeof(types));
 
55
        for (i = 0; i < 10; i++)
 
56
                archive->column_types[i] = types[i];
 
57
 
 
58
        xa_create_liststore (archive,names);
59
59
    if (fseek ( stream, 104 , SEEK_CUR ) )
60
60
    {
61
61
        fclose (stream);
62
 
        response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't fseek to position 104:"),g_strerror(errno));
 
62
        response = xa_show_message_dialog (GTK_WINDOW (xa_main_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't fseek to position 104:"),g_strerror(errno));
63
63
        return;
64
64
    }
65
65
    if ( fread ( bytes, 1, 8, stream ) == 0 )
66
66
        {
67
67
                fclose ( stream );
68
 
                response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't read data from file:"),g_strerror(errno));
 
68
                response = xa_show_message_dialog (GTK_WINDOW (xa_main_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't read data from file:"),g_strerror(errno));
69
69
                return;
70
70
    }
71
71
    il = 256 * ( 256 * ( 256 * bytes[0] + bytes[1]) + bytes[2] ) + bytes[3];
75
75
    if (fseek ( stream, offset  , SEEK_SET ) )
76
76
    {
77
77
        fclose (stream);
78
 
        response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't fseek in file:"),g_strerror(errno));
 
78
        response = xa_show_message_dialog (GTK_WINDOW (xa_main_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't fseek in file:"),g_strerror(errno));
79
79
        return;
80
80
    }
81
81
    if ( fread ( bytes, 1, 8, stream ) == 0 )
82
82
        {
83
83
                fclose ( stream );
84
 
                response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't read data from file:"),g_strerror(errno));
 
84
                response = xa_show_message_dialog (GTK_WINDOW (xa_main_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't read data from file:"),g_strerror(errno));
85
85
                return;
86
86
    }
87
87
    il = 256 * ( 256 * ( 256 * bytes[0] + bytes[1]) + bytes[2] ) + bytes[3];
90
90
        offset = offset + sigsize;
91
91
        fclose (stream);
92
92
 
93
 
        cpio_tmp = g_strdup ("/tmp/xarchiver-XXXXXX");
94
 
        fd = g_mkstemp ( cpio_tmp );
 
93
        /* Create a unique temp dir in /tmp */
 
94
        result = xa_create_temp_directory (archive);
 
95
        if (!result)
 
96
                return;
 
97
 
 
98
        gzip_tmp = g_strconcat (archive->tmp,"/file.gz_bz",NULL);
95
99
        ibs = g_strdup_printf ( "%u" , offset );
96
100
 
97
 
        //Now I run dd to have the bzip2 / gzip compressed cpio archive in /tmp
98
 
        gchar *command = g_strconcat ( "dd if=" , archive->escaped_path, " ibs=" , ibs , " skip=1 of=" , cpio_tmp , NULL );
 
101
        /* Now I run dd to have the bzip2 / gzip compressed cpio archive in /tmp */
 
102
        gchar *command = g_strconcat ( "dd if=",archive->escaped_path," ibs=",ibs," skip=1 of=",gzip_tmp,NULL);
99
103
        g_free (ibs);
100
 
        archive->parse_output = 0;
101
 
        SpawnAsyncProcess ( archive , command , 0, 0);
102
 
        g_free ( command );
103
 
        if ( archive->child_pid == 0 )
104
 
        {
105
 
                fclose ( stream );
106
 
                unlink ( cpio_tmp );
107
 
                g_free (cpio_tmp);
108
 
                return;
109
 
        }
110
 
        g_child_watch_add ( archive->child_pid , (GChildWatchFunc) DecompressCPIO , cpio_tmp );
111
 
}
112
 
 
113
 
GChildWatchFunc *DecompressCPIO (GPid pid , gint status , gpointer data)
114
 
{
115
 
        gint current_page;
116
 
 
117
 
        current_page = gtk_notebook_get_current_page(notebook);
118
 
        gchar *gzip = data;
119
 
        if ( WIFEXITED(status) )
120
 
        {
121
 
                if ( WEXITSTATUS (status) )
122
 
                {
123
 
            Update_StatusBar ( _("Operation failed."));
124
 
            gtk_widget_hide ( viewport2 );
125
 
                xa_set_window_title (MainWindow , NULL);
126
 
                    response = ShowGtkMessageDialog (GTK_WINDOW                 (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO,_("Error while extracting the cpio archive from the rpm one."),("Do you want to view the command line output?") );
127
 
            if (response == GTK_RESPONSE_YES)
128
 
                                xa_show_cmd_line_output (NULL);
129
 
            unlink ( cpio_tmp );
130
 
            g_free (cpio_tmp);
131
 
                        xa_set_button_state (1,1,0,0,0,0);
132
 
                        xa_hide_progress_bar_stop_button(archive[current_page]);
133
 
            return FALSE;
134
 
        }
135
 
    }
136
 
        cpio_tmp = xa_open_temp_file ( gzip );
137
 
    if (cpio_tmp != NULL)
138
 
                g_child_watch_add ( archive[current_page]->child_pid , (GChildWatchFunc) OpenCPIO , gzip );
139
 
    else
140
 
                return FALSE;
141
 
    return NULL;
142
 
}
143
 
 
144
 
GChildWatchFunc *OpenCPIO (GPid pid , gint exit_code , gpointer data)
145
 
{
146
 
        gint current_page;
147
 
 
148
 
        current_page = gtk_notebook_get_current_page(notebook);
149
 
        gchar *gzip = data;
150
 
    if ( WIFEXITED( exit_code ) )
151
 
    {
152
 
            if ( WEXITSTATUS ( exit_code ) )
153
 
        {
154
 
            Update_StatusBar ( _("Operation failed."));
155
 
            gtk_widget_hide ( viewport2 );
156
 
                xa_set_window_title (MainWindow , NULL);
157
 
                    response = ShowGtkMessageDialog (GTK_WINDOW                 (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO,_("An error occurred while decompressing the cpio archive."),_("Do you want to view the command line output?") );
158
 
                        if (response == GTK_RESPONSE_YES)
159
 
                                xa_show_cmd_line_output (NULL);
160
 
                        unlink ( cpio_tmp );
161
 
                        unlink ( gzip );
162
 
                        g_free (cpio_tmp);
163
 
                        xa_set_button_state (1,1,0,0,0,0);
164
 
                        xa_hide_progress_bar_stop_button(archive[current_page]);
165
 
                        return FALSE;
166
 
                }
167
 
        }
168
 
        /* Let's delete the tmp gzip compressed CPIO archive since we don't need it anymore */
169
 
        unlink ( gzip );
170
 
 
171
 
        /* Now I have to open the CPIO temp file in read mode and spawn the
172
 
        command cpio -tv with an input pipe so to receive the output from
173
 
        the opened CPIO temp file */
174
 
 
175
 
        archive[current_page]->parse_output = 0;
176
 
        SpawnAsyncProcess ( archive[current_page] , "cpio -tv" , 1, 0 );
177
 
        if ( archive[current_page]->child_pid == 0 )
178
 
        {
179
 
                unlink ( cpio_tmp );
180
 
                g_free ( cpio_tmp );
181
 
                return FALSE;
182
 
        }
183
 
        output_ioc = g_io_channel_unix_new ( output_fd );
184
 
        g_io_add_watch (output_ioc, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, ReadCPIOOutput, archive[current_page] );
185
 
        g_io_channel_set_encoding (output_ioc, locale , NULL);
186
 
        g_io_channel_set_flags ( output_ioc , G_IO_FLAG_NONBLOCK , NULL );
187
 
 
188
 
        input_ioc = g_io_channel_unix_new ( input_fd );
189
 
        g_io_add_watch (input_ioc, G_IO_IN|G_IO_OUT|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, WriteCPIOInput, NULL );
190
 
        g_io_channel_set_encoding (input_ioc, NULL , NULL);
191
 
 
192
 
        ioc_cpio = g_io_channel_new_file ( cpio_tmp , "r" , NULL );
193
 
        g_io_channel_set_encoding (ioc_cpio , NULL , NULL);
194
 
        g_io_channel_set_flags ( ioc_cpio , G_IO_FLAG_NONBLOCK , NULL );
195
 
 
196
 
        g_child_watch_add ( archive[current_page]->child_pid, (GChildWatchFunc) xa_watch_child, archive[current_page]);
197
 
  return NULL;
198
 
}
199
 
 
200
 
/* input pipe */
201
 
gboolean WriteCPIOInput (GIOChannel *ioc, GIOCondition cond, gpointer data)
202
 
{
203
 
        if (cond & (G_IO_IN | G_IO_PRI | G_IO_OUT) )
204
 
    {
205
 
                /* Doing so I write to the input pipe of the g_spawned "cpio -tv" so to produce the list of files in the cpio archive */
206
 
                status = g_io_channel_read_chars ( ioc_cpio , buffer, sizeof(buffer), &bytes_read, &error);
207
 
                if ( status != G_IO_STATUS_EOF)
208
 
                {
209
 
                        status = g_io_channel_write_chars ( ioc , buffer , bytes_read , &bytes_written , &error );
210
 
                        if (status == G_IO_STATUS_ERROR)
211
 
                        {
212
 
                                response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("An error occurred:"),error->message);
213
 
                                g_error_free (error);
214
 
                                CloseChannels ( ioc_cpio );
215
 
                                CloseChannels ( ioc );
216
 
                                return FALSE;
217
 
                        }
218
 
                        /*
219
 
                        while ( bytes_read != bytes_written )
220
 
                                status = g_io_channel_write_chars ( ioc , buffer + bytes_written , bytes_read - bytes_written , &bytes_written , &error );
221
 
                        g_print ("*Written:%d\tStatus:%d\n",bytes_written,status);
222
 
                        */
223
 
                        g_io_channel_flush ( ioc , NULL );
224
 
                        return TRUE;
225
 
                }
 
104
        list = g_slist_append(list,command);
 
105
        batch_mode = TRUE;
 
106
        result = xa_run_command (archive,list);
 
107
        if (result == FALSE)
 
108
        {       
 
109
                g_free (gzip_tmp);
 
110
                return;
 
111
        }
 
112
        if (xa_detect_archive_type (gzip_tmp) == XARCHIVETYPE_GZIP)
 
113
                executable = "gzip -dc ";
 
114
        else
 
115
                executable = "bzip2 -dc ";
 
116
 
 
117
        command = g_strconcat("sh -c \"",executable,gzip_tmp," > ",archive->tmp,"/file.cpio\"",NULL);
 
118
        g_free(gzip_tmp);
 
119
        list = NULL;
 
120
        list = g_slist_append(list,command);
 
121
        result = xa_run_command (archive,list);
 
122
        if (result == FALSE)
 
123
        {
 
124
                gtk_widget_set_sensitive(Stop_button,FALSE);
 
125
                xa_set_button_state (1,1,1,1,archive->can_add,archive->can_extract,0,archive->has_test,archive->has_properties,archive->has_passwd,0);
 
126
                gtk_label_set_text(GTK_LABEL(total_label),"");
 
127
                return;
 
128
        }
 
129
        /* And finally cpio to receive the content */
 
130
        command = g_strconcat ("sh -c \"cpio -tv < ",archive->tmp,"/file.cpio\"",NULL);
 
131
        archive->parse_output = xa_get_cpio_line_content;
 
132
        xa_spawn_async_process (archive,command);
 
133
        g_free(command);
 
134
}
 
135
 
 
136
void xa_get_cpio_line_content (gchar *line, gpointer data)
 
137
{
 
138
        XArchive *archive = data;
 
139
        XEntry *entry;
 
140
        gchar *filename;
 
141
        gpointer item[7];
 
142
        gint n = 0, a = 0 ,linesize = 0;
 
143
        gboolean dir = FALSE;
 
144
 
 
145
        linesize = strlen(line);
 
146
        archive->nr_of_files++;
 
147
 
 
148
        /* Permissions */
 
149
        line[10] = '\0';
 
150
        item[2] = line;
 
151
        a = 11;
 
152
 
 
153
        /* Hard Link */
 
154
        for(n=a; n < linesize && line[n] == ' '; ++n);
 
155
        line[++n] = '\0';
 
156
        item[4] = line + a;
 
157
        n++;
 
158
        a = n;
 
159
 
 
160
        /* Owner */
 
161
        for(; n < linesize && line[n] != ' '; ++n);
 
162
        line[n] = '\0';
 
163
        item[5] = line + a;
 
164
        n++;
 
165
 
 
166
        /* Group */
 
167
        for(; n < linesize && line[n] == ' '; ++n);
 
168
        a = n;
 
169
 
 
170
        for(; n < linesize && line[n] != ' '; ++n);
 
171
        line[n] = '\0';
 
172
        item[6] = line + a;
 
173
        n++;
 
174
 
 
175
        /* Size */      
 
176
        for(; n < linesize && line[n] == ' '; ++n);
 
177
        a = n;
 
178
 
 
179
        for(; n < linesize && line[n] != ' '; ++n);
 
180
        line[n] = '\0';
 
181
        item[1] = line + a;
 
182
        archive->dummy_size += g_ascii_strtoull(item[1],NULL,0);
 
183
        n++;
 
184
        
 
185
        /* Date */
 
186
        line[54] = '\0';
 
187
        item[3] = line + n;
 
188
        n = 55;
 
189
 
 
190
        line[linesize-1] = '\0';
 
191
        filename = line + n;
 
192
 
 
193
        /* Symbolic link */
 
194
        gchar *temp = g_strrstr (filename,"->"); 
 
195
        if (temp) 
 
196
        {
 
197
                a = 3;
 
198
                gint len = strlen(filename) - strlen(temp);
 
199
                item[0] = filename + a + len;
 
200
                filename[strlen(filename) - strlen(temp)] = '\0';
 
201
        }
 
202
        else
 
203
                item[0] = NULL;
 
204
 
 
205
        if(line[0] == 'd')
 
206
        {
 
207
                dir = TRUE;
 
208
                /* Work around for cpio, which does
 
209
                 * not output / with directories */
 
210
 
 
211
                if(line[linesize-2] != '/')
 
212
                        filename = g_strconcat(line + n, "/", NULL); 
226
213
                else
227
 
                {
228
 
                        CloseChannels ( ioc_cpio );
229
 
                        CloseChannels ( ioc );
230
 
                        return FALSE;
231
 
                }
232
 
        }
233
 
  return TRUE;
234
 
}
235
 
 
236
 
/* output pipe */
237
 
gboolean ReadCPIOOutput (GIOChannel *ioc, GIOCondition cond, gpointer data)
238
 
{
239
 
        XArchive *archive = data;
240
 
        gchar **fields = NULL;
241
 
    gchar *line = NULL;
242
 
    gchar *filename = NULL;
243
 
        GIOStatus status = G_IO_STATUS_NORMAL;
244
 
        GtkTreeIter iter;
245
 
        gchar *temp = NULL;
246
 
 
247
 
    /* Is there output from "cpio -tv" to read ? */
248
 
        if (cond & (G_IO_IN | G_IO_PRI) )
249
 
        {
250
 
                do
251
 
                {
252
 
                        status = g_io_channel_read_line ( ioc, &line, NULL, NULL , NULL );
253
 
                        if (line == NULL)
254
 
                                break;
255
 
 
256
 
                        fields = split_line (line , 5);
257
 
                        filename = get_last_field (line , 9);
258
 
                        gtk_list_store_append (archive->liststore, &iter);
259
 
                        if ( g_str_has_prefix(fields[0] , "d") == FALSE)
260
 
                                archive->nr_of_files++;
261
 
            else
262
 
                                archive->nr_of_dirs++;
263
 
 
264
 
                        temp = g_strrstr (filename,"->");
265
 
                        if (temp)
266
 
                        {
267
 
                                gtk_list_store_set (archive->liststore, &iter,2,g_strstrip(&temp[3]),-1);
268
 
                                temp = g_strstrip(g_strndup(filename, strlen(filename) - strlen(temp) ));
269
 
                                gtk_list_store_set (archive->liststore, &iter,0,temp,-1);
270
 
                                g_free (temp);
271
 
                        }
272
 
                        else
273
 
                        {
274
 
                                gtk_list_store_set (archive->liststore, &iter,2,NULL,-1);
275
 
                                gtk_list_store_set (archive->liststore, &iter,0,filename,-1);
276
 
                        }
277
 
 
278
 
                        gtk_list_store_set (archive->liststore, &iter,1,fields[0],-1);
279
 
                        gtk_list_store_set (archive->liststore, &iter,3,fields[1],-1);
280
 
                        gtk_list_store_set (archive->liststore, &iter,4,fields[2],-1);
281
 
                        gtk_list_store_set (archive->liststore, &iter,5,fields[3],-1);
282
 
                        gtk_list_store_set (archive->liststore, &iter,6,strtoll(fields[4],NULL,0),-1);
283
 
 
284
 
            while (gtk_events_pending() )
285
 
                                gtk_main_iteration();
286
 
 
287
 
            archive->dummy_size += strtoll(fields[4],NULL,0);
288
 
            g_strfreev ( fields );
289
 
                        g_free (line);
290
 
                }
291
 
                while (status == G_IO_STATUS_NORMAL);
292
 
 
293
 
                if (status == G_IO_STATUS_ERROR || status == G_IO_STATUS_EOF)
294
 
                        goto done;
295
 
        }
296
 
        else if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL) )
297
 
        {
298
 
done:   CloseChannels (ioc);
299
 
                gtk_tree_view_set_model (GTK_TREE_VIEW(archive->treeview), archive->model);
300
 
                g_object_unref (archive->model);
301
 
                archive->tmp = cpio_tmp;
302
 
                return FALSE;
303
 
        }
304
 
        return TRUE;
305
 
}
306
 
 
307
 
void CloseChannels ( GIOChannel *ioc )
308
 
{
309
 
    g_io_channel_shutdown ( ioc,TRUE,NULL );
310
 
    g_io_channel_unref (ioc);
311
 
}
312
 
 
313
 
gchar *xa_open_temp_file ( gchar *temp_path )
314
 
{
315
 
        gint current_page;
316
 
 
317
 
        current_page = gtk_notebook_get_current_page(notebook);
318
 
        gchar *command = NULL;
319
 
        tmp = g_strdup ("/tmp/xarchiver-XXXXXX");
320
 
        fd = g_mkstemp ( tmp );
321
 
        stream = fdopen ( fd , "w" );
322
 
        if ( stream == NULL)
323
 
        {
324
 
                response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't write to /tmp:"),g_strerror(errno) );
325
 
                g_free (tmp);
326
 
                return NULL;
327
 
        }
328
 
        if (xa_detect_archive_type ( NULL , temp_path ) == XARCHIVETYPE_GZIP)
329
 
                command = g_strconcat ( "gzip -dc " , temp_path , NULL );
 
214
                        filename = g_strdup(line + n); 
 
215
        }
330
216
        else
331
 
                command = g_strconcat ( "bzip2 -dc " , temp_path , NULL );
332
 
        archive[current_page]->parse_output = 0;
333
 
        SpawnAsyncProcess ( archive[current_page] , command , 0, 0);
334
 
        g_free ( command );
335
 
        if ( archive[current_page]->child_pid == 0 )
336
 
        {
337
 
                fclose ( stream );
338
 
                unlink ( tmp );
339
 
                g_free (tmp);
340
 
                return NULL;
341
 
        }
342
 
        GIOChannel *ioc = g_io_channel_unix_new ( output_fd );
343
 
        g_io_channel_set_encoding (ioc, NULL , NULL);
344
 
        g_io_channel_set_flags ( ioc , G_IO_FLAG_NONBLOCK , NULL );
345
 
        g_io_add_watch (ioc, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, ExtractToDifferentLocation, stream);
346
 
        return tmp;
 
217
                filename = g_strdup(line + n); 
 
218
        
 
219
        entry = xa_set_archive_entries_for_each_row (archive,filename,item);
 
220
        g_free (filename);
347
221
}
348
222
 
349
 
gboolean ExtractToDifferentLocation (GIOChannel *ioc, GIOCondition cond, gpointer data)
 
223
gboolean xa_rpm_extract(XArchive *archive,GSList *files)
350
224
{
351
 
        FILE *stream = data;
352
 
        gchar buffer[65536];
353
 
        gsize bytes_read;
354
 
        GIOStatus status;
355
 
        GError *error = NULL;
356
 
 
357
 
        if (cond & (G_IO_IN | G_IO_PRI) )
358
 
        {
359
 
                do
360
 
            {
361
 
                        status = g_io_channel_read_chars (ioc, buffer, sizeof(buffer), &bytes_read, &error);
362
 
                        if (bytes_read > 0)
363
 
                        {
364
 
                                /* Write the content of the bzip/gzip extracted file to the file pointed by the file stream */
365
 
                                fwrite (buffer, 1, bytes_read, stream);
366
 
                        }
367
 
                        else if (error != NULL)
368
 
                        {
369
 
                        response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK, _("An error occurred:"),error->message);
370
 
                        g_error_free (error);
371
 
                        return FALSE;
372
 
                        }
373
 
                }
374
 
                while (status == G_IO_STATUS_NORMAL);
375
 
 
376
 
                if (status == G_IO_STATUS_ERROR || status == G_IO_STATUS_EOF)
377
 
                goto done;
378
 
        }
379
 
        else if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL) )
380
 
        {
381
 
                done:
382
 
                fclose ( stream );
383
 
                g_io_channel_shutdown ( ioc,TRUE,NULL );
384
 
                g_io_channel_unref (ioc);
385
 
                return FALSE;
386
 
        }
387
 
        return TRUE;
 
225
        gchar *command = NULL,*e_filename = NULL;
 
226
        GSList *list = NULL,*_files = NULL;
 
227
        GString *names = g_string_new("");
 
228
        gboolean result = FALSE;
 
229
 
 
230
        _files = files;
 
231
        while (_files)
 
232
        {
 
233
                e_filename  = xa_escape_filename((gchar*)_files->data,"$'`\"\\!?* ()[]&|:;<>#");
 
234
                g_string_prepend (names,e_filename);
 
235
                g_string_prepend_c (names,' ');
 
236
                _files = _files->next;
 
237
        }
 
238
        g_slist_foreach(files,(GFunc)g_free,NULL);
 
239
        g_slist_free(files);
 
240
        
 
241
        chdir (archive->extraction_path);
 
242
        command = g_strconcat ( "sh -c \"cpio -id" , names->str," < ",archive->tmp,"/file.cpio\"",NULL);
 
243
 
 
244
        g_string_free(names,TRUE);
 
245
        list = g_slist_append(list,command);
 
246
        result = xa_run_command (archive,list);
 
247
        return result;
388
248
}
389