~ubuntu-branches/ubuntu/quantal/xarchiver/quantal

« back to all changes in this revision

Viewing changes to src/rar.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>
 
2
 *  Copyright (C) 2008 Giuseppe Torelli - <colossus73@gmail.com>
3
3
 *
4
4
 *  This program is free software; you can redistribute it and/or modify
5
5
 *  it under the terms of the GNU General Public License as published by
18
18
 
19
19
#include "config.h"
20
20
#include "rar.h"
 
21
#include <unistd.h>
21
22
 
22
23
extern gboolean unrar;
23
 
static gboolean RarOpen (GIOChannel *ioc, GIOCondition cond, gpointer data);
24
 
GtkTreeIter iter;
 
24
extern void xa_reload_archive_content(XArchive *archive);
 
25
extern void xa_create_liststore ( XArchive *archive, gchar *columns_names[]);
25
26
 
26
 
void OpenRar ( XArchive *archive )
 
27
void xa_open_rar (XArchive *archive)
27
28
{
28
 
        jump_header = FALSE;
 
29
        unsigned short int i;
29
30
        gchar *command = NULL;
30
31
        gchar *rar = NULL;
 
32
        jump_header = read_filename = last_line = encrypted = FALSE;
31
33
 
32
34
        if (unrar)
 
35
        {
33
36
                rar = "unrar";
 
37
                archive->can_add = archive->has_sfx = FALSE;
 
38
        }
34
39
        else
 
40
        {
35
41
                rar = "rar";
 
42
                archive->can_add = archive->has_sfx = TRUE;
 
43
        }
36
44
 
37
 
        command = g_strconcat ( rar," vl -c- " , archive->escaped_path, NULL );
 
45
        command = g_strconcat ( rar," v " , archive->escaped_path, NULL );
 
46
        archive->can_extract = archive->has_test = archive->has_properties = TRUE;
38
47
        archive->dummy_size = 0;
39
48
    archive->nr_of_files = 0;
40
 
    archive->nr_of_dirs = 0;
41
 
        archive->parse_output = RarOpen;
42
 
        archive->format ="RAR";
43
 
        SpawnAsyncProcess ( archive , command , 0, 0);
 
49
    archive->nc = 10;
 
50
        archive->parse_output = xa_get_rar_line_content;
 
51
        archive->format = "RAR";
 
52
        xa_spawn_async_process (archive,command);
44
53
        g_free ( command );
 
54
 
45
55
        if ( archive->child_pid == 0 )
46
56
                return;
47
57
 
48
 
        char *names[]   = {(_("Filename")),(_("Original")),(_("Compressed")),(_("Ratio")),(_("Date")),(_("Time")),(_("Permissions")),(_("Checksum")),(_("Method")),(_("Version"))};
49
 
        GType types[]= {G_TYPE_STRING,G_TYPE_UINT64,G_TYPE_UINT64,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING};
50
 
    archive->has_passwd = FALSE;
51
 
        xa_create_liststore ( 10, names , (GType *)types, archive );
 
58
        GType types[]= {GDK_TYPE_PIXBUF,G_TYPE_STRING,G_TYPE_UINT64,G_TYPE_UINT64,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_POINTER};
 
59
        archive->column_types = g_malloc0(sizeof(types));
 
60
        for (i = 0; i < 12; i++)
 
61
                archive->column_types[i] = types[i];
 
62
 
 
63
        char *names[]= {(_("Original")),(_("Compressed")),(_("Ratio")),(_("Date")),(_("Time")),(_("Permissions")),(_("CRC")),(_("Method")),(_("Version")),NULL};
 
64
        xa_create_liststore (archive,names);
52
65
}
53
66
 
54
 
static gboolean RarOpen (GIOChannel *ioc, GIOCondition cond, gpointer data)
 
67
void xa_get_rar_line_content (gchar *line, gpointer data)
55
68
{
56
69
        XArchive *archive = data;
57
 
        gchar **fields = NULL;
58
 
        gchar *line = NULL;
59
 
        GIOStatus status = G_IO_STATUS_NORMAL;
60
 
 
61
 
        if (cond & (G_IO_IN | G_IO_PRI) )
62
 
        {
63
 
                do
64
 
                {
65
 
                        /* This to avoid inserting in the list RAR's copyright message */
66
 
                        if (jump_header == FALSE )
67
 
                        {
68
 
                                status = g_io_channel_read_line ( ioc, &line, NULL, NULL, NULL );
69
 
                                if (line == NULL)
70
 
                                        break;
71
 
                                if  (strncmp (line , "--------" , 8) == 0)
72
 
                                {
73
 
                                        jump_header = TRUE;
74
 
                                        odd_line = TRUE;
75
 
                                }
76
 
                                g_free (line);
77
 
                                break;
78
 
                        }
79
 
                        if ( jump_header && odd_line )
80
 
                        {
81
 
                                /* Now read the filename */
82
 
                                status = g_io_channel_read_line ( ioc, &line, NULL, NULL, NULL );
83
 
                                if ( line == NULL )
84
 
                                        break;
85
 
                                /* This to avoid inserting in the liststore the last line of Rar output */
86
 
                                if (strncmp (line, "--------", 8) == 0 || strncmp (line, "\x0a",1) == 0)
87
 
                                {
88
 
                                        g_free (line);
89
 
                                        status = g_io_channel_read_line ( ioc, &line, NULL, NULL, NULL );
90
 
                                        g_free (line);
91
 
                                        break;
92
 
                                }
93
 
                                gtk_list_store_append (archive->liststore, &iter);
94
 
                                line[ strlen(line) - 1 ] = '\000';
95
 
                                if (line[0] == '*')
96
 
                                        archive->has_passwd = TRUE;
97
 
                                /* This to avoid the white space or the * before the first char of the filename */
98
 
                                line++;
99
 
                                gtk_list_store_set (archive->liststore, &iter,0,line,-1);
100
 
                                /* Restore the pointer before freeing it */
101
 
                                line--;
102
 
                                g_free (line);
103
 
                                odd_line = ! odd_line;
104
 
                                break;
105
 
                        }
106
 
                        else
107
 
                        {
108
 
                                /* Now read the rest of the data */
109
 
                                status = g_io_channel_read_line ( ioc, &line, NULL, NULL, NULL );
110
 
                                if ( line == NULL)
111
 
                                        break;
112
 
                                fields = split_line (line,9);
113
 
                                if (fields[5] == NULL)
114
 
                                        break;
115
 
                                if ( strstr (fields[5] , "d") == NULL && strstr (fields[5] , "D") == NULL )
116
 
                                        archive->nr_of_files++;
117
 
                                else
118
 
                                        archive->nr_of_dirs++;
119
 
                                for (x = 0; x < 9; x++)
120
 
                                {
121
 
                                        if (x == 0 || x == 1)
122
 
                                                gtk_list_store_set (archive->liststore, &iter,x+1,strtoll(fields[x],NULL,0),-1);
123
 
                                        else
124
 
                                                gtk_list_store_set (archive->liststore, &iter,x+1,fields[x],-1);
125
 
                                }
126
 
                                while ( gtk_events_pending() )
127
 
                                        gtk_main_iteration();
128
 
                                archive->dummy_size += strtoll(fields[0],NULL,0);
129
 
                                g_strfreev ( fields );
130
 
                                g_free (line);
131
 
                                odd_line = ! odd_line;
132
 
                        }
133
 
                }
134
 
                while (status == G_IO_STATUS_NORMAL);
135
 
 
136
 
                if (status == G_IO_STATUS_ERROR || status == G_IO_STATUS_EOF)
137
 
                        goto done;
138
 
        }
139
 
        else if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL) )
140
 
        {
141
 
done:   g_io_channel_shutdown ( ioc,TRUE,NULL );
142
 
                g_io_channel_unref (ioc);
143
 
                gtk_tree_view_set_model (GTK_TREE_VIEW(archive->treeview), archive->model);
144
 
                g_object_unref (archive->model);
145
 
                return FALSE;
146
 
        }
147
 
        return TRUE;
148
 
}
 
70
        XEntry *entry;
 
71
        gpointer item[9];
 
72
        unsigned short int i = 0;
 
73
        unsigned int linesize,n,a;
 
74
        gboolean dir = FALSE;
 
75
        static gchar *filename;
 
76
 
 
77
        if (last_line)
 
78
                return;
 
79
 
 
80
        if (jump_header == FALSE)
 
81
        {
 
82
                if (strncmp(line,"Comment:",8) == 0)
 
83
                {
 
84
                        jump_comment = archive->has_comment = TRUE;
 
85
                        archive->comment = g_string_new("");
 
86
                        archive->comment = g_string_append(archive->comment,&line[9]);
 
87
                        return;
 
88
                }
 
89
                if (jump_comment == TRUE)
 
90
                {
 
91
                        if (strncmp(line,"Pathname/Comment",16) != 0)
 
92
                        {       archive->comment = g_string_append(archive->comment,line);
 
93
                                return;
 
94
                        }
 
95
                        jump_comment = FALSE;
 
96
                }
 
97
                if (line[0] == '-')
 
98
                {
 
99
                        jump_header = TRUE;
 
100
                        return;
 
101
                }
 
102
                return;
 
103
        }
 
104
 
 
105
        if (read_filename == FALSE)
 
106
        {
 
107
                linesize = strlen(line);
 
108
                if(line[0] == '*')
 
109
                {
 
110
                        archive->has_passwd = TRUE;
 
111
                        encrypted = TRUE;
 
112
                }
 
113
                else if (line[0] == '-')
 
114
                {
 
115
                        last_line = TRUE;
 
116
                        return;
 
117
                }
 
118
                line[linesize - 1] = '\0';
 
119
                filename = g_strdup(line+1);
 
120
                read_filename = TRUE;
 
121
        }
 
122
        else
 
123
        {
 
124
                linesize = strlen(line);
 
125
                archive->nr_of_files++;
 
126
                /* Size */
 
127
                for(n=0; n < linesize && line[n] == ' '; n++);
 
128
                a = n;
 
129
                for(; n < linesize && line[n] != ' '; n++);
 
130
                line[n]='\0';
 
131
                item[i] = line + a;
 
132
                archive->dummy_size += g_ascii_strtoull(item[i],NULL,0);
 
133
                i++;
 
134
                n++;
 
135
                
 
136
                /* Compressed */
 
137
                for(; n < linesize && line[n] == ' '; n++);
 
138
                a = n;
 
139
                for(; n < linesize && line[n] != ' '; n++);
 
140
                line[n]='\0';
 
141
                item[i] = line + a;
 
142
                i++;
 
143
                n++;
 
144
 
 
145
                /* Ratio */
 
146
                for(; n < linesize && line[n] == ' '; n++);
 
147
                a = n;
 
148
                for(; n < linesize && line[n] != ' '; n++);
 
149
                line[n] = '\0';
 
150
                item[i] = line + a;
 
151
                i++;
 
152
                n++;
 
153
 
 
154
                /* Date */
 
155
                for(; n < linesize && line[n] == ' '; n++);
 
156
                a = n;
 
157
                for(; n < linesize && line[n] != ' '; n++);
 
158
                line[n] = '\0';
 
159
                item[i] = line + a;
 
160
                i++;
 
161
                n++;
 
162
 
 
163
                /* Time */
 
164
                for(; n < linesize && line[n] == ' '; n++);
 
165
                a = n;
 
166
                for(; n < linesize && line[n] != ' '; n++);
 
167
                line[n] = '\0';
 
168
                item[i] = line + a;
 
169
                i++;
 
170
                n++;
 
171
 
 
172
                /* Permissions */
 
173
                for(; n < linesize && line[n] == ' '; n++);
 
174
                a = n;
 
175
                for(; n < linesize && line[n] != ' '; n++);
 
176
                line[n] = '\0';
 
177
                if ((line+a)[0] == 'd')
 
178
                        dir = TRUE;
 
179
                item[i] = line + a;
 
180
                i++;
 
181
                n++;
 
182
 
 
183
                /* CRC */
 
184
                for(; n < linesize && line[n] == ' '; n++);
 
185
                a = n;
 
186
                for(; n < linesize && line[n] != ' '; n++);
 
187
                line[n] = '\0';
 
188
                item[i] = line + a;
 
189
                i++;
 
190
                n++;
 
191
 
 
192
                /* Method */
 
193
                for(; n < linesize && line[n] == ' '; n++);
 
194
                a = n;
 
195
                for(; n < linesize && line[n] != ' '; n++);
 
196
                line[n] = '\0';
 
197
                item[i] = line + a;
 
198
                i++;
 
199
                n++;
 
200
 
 
201
                /* version */
 
202
                for(; n < linesize && line[n] == ' '; n++);
 
203
                a = n;
 
204
                for(; n < linesize && line[n] != ' ' && line[n] != '\n'; n++);
 
205
                line[n] = '\0';
 
206
                item[i] = line + a;
 
207
 
 
208
                /* Work around for rar which doesn't
 
209
                 * output / with directories */
 
210
                if (dir)
 
211
                {
 
212
                        gchar *filename_with_slash = g_strconcat (filename,"/",NULL);
 
213
                        g_free (filename);
 
214
                        filename = filename_with_slash;
 
215
                }
 
216
                entry = xa_set_archive_entries_for_each_row (archive,filename,item);
 
217
                if (entry != NULL)
 
218
                        entry->is_encrypted = encrypted;
 
219
                g_free(filename);
 
220
                read_filename = FALSE;
 
221
                encrypted = FALSE;
 
222
        }
 
223
}
 
224
 
 
225
void xa_rar_delete (XArchive *archive,GSList *names)
 
226
{
 
227
        gchar *command,*e_filename = NULL;
 
228
        GSList *list = NULL,*_names;
 
229
        GString *files = g_string_new("");
 
230
 
 
231
        _names = names;
 
232
        while (_names)
 
233
        {
 
234
                e_filename  = xa_escape_filename((gchar*)_names->data,"$'`\"\\!?* ()[]&|:;<>#");
 
235
                g_string_prepend (files,e_filename);
 
236
                g_string_prepend_c (files,' ');
 
237
                _names = _names->next;
 
238
        }
 
239
        g_slist_foreach(names,(GFunc)g_free,NULL);
 
240
        g_slist_free(names);
 
241
        
 
242
        command = g_strconcat ("rar d ",archive->escaped_path," ",files->str,NULL);
 
243
        g_string_free(files,TRUE);
 
244
        list = g_slist_append(list,command);
 
245
 
 
246
        xa_run_command (archive,list);
 
247
        if (archive->status == XA_ARCHIVESTATUS_DELETE)
 
248
                xa_reload_archive_content(archive);
 
249
}
 
250
 
 
251
void xa_rar_add (XArchive *archive,GString *files,gchar *compression_string)
 
252
{
 
253
        GSList *list = NULL;
 
254
        gchar *command = NULL;
 
255
 
 
256
        if (archive->location_entry_path != NULL)
 
257
                archive->working_dir = g_strdup(archive->tmp);
 
258
 
 
259
        if (compression_string == NULL)
 
260
                compression_string = "3";
 
261
        if (archive->passwd != NULL)
 
262
                command = g_strconcat ( "rar a ",
 
263
                                                                        archive->update ? "-u " : "",
 
264
                                                                        archive->freshen ? "-f " : "",
 
265
                                                                        archive->solid_archive ? "-s " : "",
 
266
                                                                        archive->remove_files ? "-df " : "",
 
267
                                                                        "-p" , archive->passwd,
 
268
                                                                        "-idp ",
 
269
                                                                        "-m",compression_string," ",
 
270
                                                                        archive->escaped_path,
 
271
                                                                        files->str,NULL);
 
272
        else
 
273
                command = g_strconcat ( "rar a ",
 
274
                                                                        archive->update ? "-u " : "",
 
275
                                                                        archive->freshen ? "-f " : "",
 
276
                                                                        archive->solid_archive ? "-s " : "",
 
277
                                                                        archive->remove_files ? "-df " : "",
 
278
                                                                        "-idp ",
 
279
                                                                        "-m",compression_string," ",
 
280
                                                                        archive->escaped_path,
 
281
                                                                        files->str,NULL);
 
282
 
 
283
        g_string_free(files,TRUE);
 
284
        list = g_slist_append(list,command);
 
285
 
 
286
        xa_run_command (archive,list);
 
287
        xa_reload_archive_content(archive);
 
288
}
 
289
 
 
290
gboolean xa_rar_extract(XArchive *archive,GSList *files)
 
291
{
 
292
        gchar *rar, *command, *e_filename = NULL;
 
293
        GSList *list = NULL,*_files = NULL;
 
294
        GString *names = g_string_new("");
 
295
        gboolean result = FALSE;
 
296
 
 
297
        _files = files;
 
298
        if (unrar)
 
299
                rar = "unrar";
 
300
        else
 
301
                rar = "rar";
 
302
 
 
303
        while (_files)
 
304
        {
 
305
                e_filename = xa_escape_filename((gchar*)_files->data,"$'`\"\\!?* ()[]&|:;<>#");
 
306
                g_string_prepend (names,e_filename);
 
307
                g_string_prepend_c (names,' ');
 
308
                _files = _files->next;
 
309
        }
 
310
        g_slist_foreach(_files,(GFunc)g_free,NULL);
 
311
        g_slist_free(_files);
 
312
        
 
313
        if (archive->passwd != NULL)
 
314
                command = g_strconcat (rar," ",archive->full_path ? "x " : "e ",
 
315
                                                                                archive->freshen ? "-f " : "" , archive->update ? "-u " : "",
 
316
                                                                                " -p",archive->passwd,
 
317
                                                                                archive->overwrite ? " -o+" : " -o-",
 
318
                                                                                " -idp ",
 
319
                                                                                archive->escaped_path,names->str," ",archive->extraction_path , NULL );
 
320
        else
 
321
                command = g_strconcat (rar," ",archive->full_path ? "x " : "e ",
 
322
                                                                                archive->freshen ? "-f " : "" , archive->update ? "-u " : "",
 
323
                                                                                archive->overwrite ? "-o+" : "-o-",
 
324
                                                                                " -idp ",
 
325
                                                                                archive->escaped_path,names->str," ",archive->extraction_path , NULL );
 
326
        g_string_free(names,TRUE);
 
327
        list = g_slist_append(list,command);
 
328
 
 
329
        result = xa_run_command (archive,list);
 
330
        return result;
 
331
}
 
332
 
 
333
void xa_rar_test (XArchive *archive)
 
334
{
 
335
        gchar *rar = NULL;
 
336
        gchar *command = NULL;
 
337
        GSList *list = NULL;
 
338
 
 
339
        if (unrar)
 
340
                rar = "unrar";
 
341
        else
 
342
                rar = "rar";
 
343
 
 
344
        archive->status = XA_ARCHIVESTATUS_TEST;
 
345
        if (archive->passwd != NULL)
 
346
                command = g_strconcat (rar," t -idp -p" , archive->passwd ," " , archive->escaped_path, NULL);
 
347
        else
 
348
                command = g_strconcat (rar," t -idp " , archive->escaped_path, NULL);
 
349
 
 
350
        list = g_slist_append(list,command);
 
351
        xa_run_command (archive,list);
 
352
 }