~ubuntu-branches/debian/wheezy/brasero/wheezy

« back to all changes in this revision

Viewing changes to libbrasero-media/burn-volume.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette, Pedro Fragoso, Luca Bruno, Josselin Mouette, Emilio Pozuelo Monfort
  • Date: 2009-06-24 18:59:46 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20090624185946-iyxkgf3gjptir5y3
Tags: 2.26.2-1
[ Pedro Fragoso ]
* Add myself to Maintainer field
  - Thanks Ondřej Surý
* New upstream version (Closes: #528945)
  - Split package into brasero, libbrasero-media0 and libbrasero-dev
  - Add Replaces to libbrasero-media0
  - Bump libgtk to 2.14.0
  - Remove libnotify Build-dep
  - Add Build-dep libnautilus-extension-dev (>= 2.22.2)
    and install it.
  - Add Build-dep to libsm-dev
  - Add Build-dep on intltool
* Install omf files to prevent crash on Help
* Move gstreamer0.10-plugins-bad to Suggests, and add
  dvdauthor and vcdimager
* Recommends gvfs (Closes: #491827)
* Pass --disable-scrollkeeper in DEB_CONFIGURE_EXTRA_FLAGS
* debian/patches/007-fix-gnome-doc-utils-path.patch:
  - Removed, not needed anymore
* debian/patches/008-fix-volume-identifier-crash.patch:
  - Removed, merged upstream
* debian/patches/011_nautilus_menu_move.patch:
 - Move CD/DVD Creator Menu to Acessories, taken from Ubuntu

[ Luca Bruno ]
* debian/control.in:
  - Add Build-Depend gtk-doc-tools 1.9.
* debian/patches/006-fix-libdvdcss.patch:
  - Removed as applied upstream.

[ Josselin Mouette ]
* New upstream release.
* Update build-dependencies.
* Move the translations and data to a new brasero-common package.
* Rewrite the descriptions.
* Add -dev depends to the development package.
* Remove inappropriate recommends in the library package.
* Let’s not forget dvd+rw-tools so that we can write DVDs too.
* Rework dependencies accordingly.
* Put the nautilus extension in brasero.
* Conflict against nautilus-cd-burner to avoid having two burning 
  extensions.
* Include clean-la.mk and gnome-version.mk; build-depend on 
  gnome-pkg-tools 0.7.
* Don’t run dh_makeshlibs on brasero and libbrasero-plugins.
* 011_nautilus_menu_move.patch: add NoDisplay=true, this icon is 
  duplicating existing functionality (brasero icon in sound&video 
  menu, and nautilus autorun).
* Update list of copyright holders.

[ Emilio Pozuelo Monfort ]
* debian/copyright: updated.

[ Josselin Mouette ]
* copyright: improve indentation, and point to versioned LGPL.
* 090_relibtoolize.patch: add a relibtoolization patch to avoid the 
  rpath crap.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 
2
/*
 
3
 * Libbrasero-media
 
4
 * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr>
 
5
 *
 
6
 * Libbrasero-media 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
 * The Libbrasero-media authors hereby grant permission for non-GPL compatible
 
12
 * GStreamer plugins to be used and distributed together with GStreamer
 
13
 * and Libbrasero-media. This permission is above and beyond the permissions granted
 
14
 * by the GPL license by which Libbrasero-media is covered. If you modify this code
 
15
 * you may extend this exception to your version of the code, but you are not
 
16
 * obligated to do so. If you do not wish to do so, delete this exception
 
17
 * statement from your version.
 
18
 * 
 
19
 * Libbrasero-media is distributed in the hope that it will be useful,
 
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
 * GNU Library General Public License for more details.
 
23
 * 
 
24
 * You should have received a copy of the GNU General Public License
 
25
 * along with this program; if not, write to:
 
26
 *      The Free Software Foundation, Inc.,
 
27
 *      51 Franklin Street, Fifth Floor
 
28
 *      Boston, MA  02110-1301, USA.
 
29
 */
 
30
 
 
31
#ifdef HAVE_CONFIG_H
 
32
#  include <config.h>
 
33
#endif
 
34
 
 
35
#include <errno.h>
 
36
#include <string.h>
 
37
#include <stdio.h>
 
38
#include <unistd.h>
 
39
 
 
40
#include <glib.h>
 
41
#include <glib/gi18n-lib.h>
 
42
 
 
43
#include "burn-volume-source.h"
 
44
#include "burn-volume.h"
 
45
#include "burn-iso9660.h"
 
46
#include "brasero-media.h"
 
47
#include "brasero-media-private.h"
 
48
#include "brasero-units.h"
 
49
 
 
50
struct _BraseroTagDesc {
 
51
        guint16 id;
 
52
        guint16 version;
 
53
        guchar checksum;
 
54
        guchar reserved;
 
55
        guint16 serial;
 
56
        guint16 crc;
 
57
        guint16 crc_len;
 
58
        guint32 location;
 
59
};
 
60
typedef struct _BraseroTagDesc BraseroTagDesc;
 
61
 
 
62
struct _BraseroAnchorDesc {
 
63
        BraseroTagDesc tag;
 
64
 
 
65
        guchar main_extent              [8];
 
66
        guchar reserve_extent           [8];
 
67
};
 
68
typedef struct _BraseroAnchorDesc BraseroAnchorDesc;
 
69
 
 
70
#define SYSTEM_AREA_SECTORS             16
 
71
#define ANCHOR_AREA_SECTORS             256
 
72
 
 
73
 
 
74
void
 
75
brasero_volume_file_free (BraseroVolFile *file)
 
76
{
 
77
        if (!file)
 
78
                return;
 
79
 
 
80
        if (file->isdir) {
 
81
                GList *iter;
 
82
 
 
83
                if (file->isdir_loaded) {
 
84
                        for (iter = file->specific.dir.children; iter; iter = iter->next)
 
85
                                brasero_volume_file_free (iter->data);
 
86
 
 
87
                        g_list_free (file->specific.dir.children);
 
88
                }
 
89
        }
 
90
        else {
 
91
                g_slist_foreach (file->specific.file.extents,
 
92
                                 (GFunc) g_free,
 
93
                                 NULL);
 
94
                g_slist_free (file->specific.file.extents);
 
95
        }
 
96
 
 
97
        g_free (file->rr_name);
 
98
        g_free (file->name);
 
99
        g_free (file);
 
100
}
 
101
 
 
102
static gboolean
 
103
brasero_volume_get_primary_from_file (BraseroVolSrc *vol,
 
104
                                      gchar *primary_vol,
 
105
                                      GError **error)
 
106
{
 
107
        BraseroVolDesc *desc;
 
108
 
 
109
        /* skip the first 16 blocks */
 
110
        if (BRASERO_VOL_SRC_SEEK (vol, SYSTEM_AREA_SECTORS, SEEK_CUR, error) == -1)
 
111
                return FALSE;
 
112
 
 
113
        if (!BRASERO_VOL_SRC_READ (vol, primary_vol, 1, error))
 
114
                return FALSE;
 
115
 
 
116
        /* make a few checks to ensure this is an ECMA volume */
 
117
        desc = (BraseroVolDesc *) primary_vol;
 
118
        if (memcmp (desc->id, "CD001", 5)
 
119
        &&  memcmp (desc->id, "BEA01", 5)
 
120
        &&  memcmp (desc->id, "BOOT2", 5)
 
121
        &&  memcmp (desc->id, "CDW02", 5)
 
122
        &&  memcmp (desc->id, "NSR02", 5)       /* usually UDF */
 
123
        &&  memcmp (desc->id, "NSR03", 5)       /* usually UDF */
 
124
        &&  memcmp (desc->id, "TEA01", 5)) {
 
125
                g_set_error (error,
 
126
                             BRASERO_MEDIA_ERROR,
 
127
                             BRASERO_MEDIA_ERROR_IMAGE_INVALID,
 
128
                             _("It does not appear to be a valid ISO image"));
 
129
                BRASERO_MEDIA_LOG ("Wrong volume descriptor, got %.5s", desc->id);
 
130
                return FALSE;
 
131
        }
 
132
 
 
133
        return TRUE;
 
134
}
 
135
 
 
136
gboolean
 
137
brasero_volume_get_size (BraseroVolSrc *vol,
 
138
                         gint64 block,
 
139
                         gint64 *nb_blocks,
 
140
                         GError **error)
 
141
{
 
142
        gboolean result;
 
143
        gchar buffer [ISO9660_BLOCK_SIZE];
 
144
 
 
145
        if (block && BRASERO_VOL_SRC_SEEK (vol, block, SEEK_SET, error) == -1)
 
146
                return FALSE;
 
147
 
 
148
        result = brasero_volume_get_primary_from_file (vol, buffer, error);
 
149
        if (!result)
 
150
                return FALSE;
 
151
 
 
152
        if (!brasero_iso9660_is_primary_descriptor (buffer, error))
 
153
                return FALSE;
 
154
 
 
155
        return brasero_iso9660_get_size (buffer, nb_blocks, error);
 
156
}
 
157
 
 
158
BraseroVolFile *
 
159
brasero_volume_get_files (BraseroVolSrc *vol,
 
160
                          gint64 block,
 
161
                          gchar **label,
 
162
                          gint64 *nb_blocks,
 
163
                          gint64 *data_blocks,
 
164
                          GError **error)
 
165
{
 
166
        gchar buffer [ISO9660_BLOCK_SIZE];
 
167
 
 
168
        if (BRASERO_VOL_SRC_SEEK (vol, block, SEEK_SET, error) == -1)
 
169
                return FALSE;
 
170
 
 
171
        if (!brasero_volume_get_primary_from_file (vol, buffer, error))
 
172
                return NULL;
 
173
 
 
174
        if (!brasero_iso9660_is_primary_descriptor (buffer, error))
 
175
                return NULL;
 
176
 
 
177
        if (label
 
178
        && !brasero_iso9660_get_label (buffer, label, error))
 
179
                return NULL;
 
180
 
 
181
        if (nb_blocks
 
182
        && !brasero_iso9660_get_size (buffer, nb_blocks, error))
 
183
                return NULL;
 
184
 
 
185
        return brasero_iso9660_get_contents (vol,
 
186
                                             buffer,
 
187
                                             data_blocks,
 
188
                                             error);
 
189
}
 
190
 
 
191
GList *
 
192
brasero_volume_load_directory_contents (BraseroVolSrc *vol,
 
193
                                        gint64 session_block,
 
194
                                        gint64 block,
 
195
                                        GError **error)
 
196
{
 
197
        gchar buffer [ISO9660_BLOCK_SIZE];
 
198
 
 
199
        if (BRASERO_VOL_SRC_SEEK (vol, session_block, SEEK_SET, error) == -1)
 
200
                return FALSE;
 
201
 
 
202
        if (!brasero_volume_get_primary_from_file (vol, buffer, error))
 
203
                return NULL;
 
204
 
 
205
        if (!brasero_iso9660_is_primary_descriptor (buffer, error))
 
206
                return NULL;
 
207
 
 
208
        return brasero_iso9660_get_directory_contents (vol,
 
209
                                                       buffer,
 
210
                                                       block,
 
211
                                                       error);
 
212
}
 
213
 
 
214
BraseroVolFile *
 
215
brasero_volume_get_file (BraseroVolSrc *vol,
 
216
                         const gchar *path,
 
217
                         gint64 volume_start_block,
 
218
                         GError **error)
 
219
{
 
220
        gchar buffer [ISO9660_BLOCK_SIZE];
 
221
 
 
222
        if (BRASERO_VOL_SRC_SEEK (vol, volume_start_block, SEEK_SET, error) == -1)
 
223
                return NULL;
 
224
 
 
225
        if (!brasero_volume_get_primary_from_file (vol, buffer, error))
 
226
                return NULL;
 
227
 
 
228
        if (!brasero_iso9660_is_primary_descriptor (buffer, error))
 
229
                return NULL;
 
230
 
 
231
        return brasero_iso9660_get_file (vol, path, buffer, error);
 
232
}
 
233
 
 
234
gchar *
 
235
brasero_volume_file_to_path (BraseroVolFile *file)
 
236
{
 
237
        GString *path;
 
238
        BraseroVolFile *parent;
 
239
        GSList *components = NULL, *iter, *next;
 
240
 
 
241
        if (!file)
 
242
                return NULL;
 
243
 
 
244
        /* make a list of all the components of the path by going up to root */
 
245
        parent = file->parent;
 
246
        while (parent && parent->name) {
 
247
                components = g_slist_prepend (components, BRASERO_VOLUME_FILE_NAME (parent));
 
248
                parent = parent->parent;
 
249
        }
 
250
 
 
251
        if (!components)
 
252
                return NULL;
 
253
 
 
254
        path = g_string_new (NULL);
 
255
        for (iter = components; iter; iter = next) {
 
256
                gchar *name;
 
257
 
 
258
                name = iter->data;
 
259
                next = iter->next;
 
260
                components = g_slist_remove (components, name);
 
261
 
 
262
                g_string_append_c (path, G_DIR_SEPARATOR);
 
263
                g_string_append (path, name);
 
264
        }
 
265
 
 
266
        g_slist_free (components);
 
267
        return g_string_free (path, FALSE);
 
268
}
 
269
 
 
270
BraseroVolFile *
 
271
brasero_volume_file_from_path (const gchar *ptr,
 
272
                               BraseroVolFile *parent)
 
273
{
 
274
        GList *iter;
 
275
        gchar *next;
 
276
        gint len;
 
277
 
 
278
        /* first determine the name of the directory / file to look for */
 
279
        if (!ptr || ptr [0] != '/' || !parent)
 
280
                return NULL;
 
281
 
 
282
        ptr ++;
 
283
        next = g_utf8_strchr (ptr, -1, G_DIR_SEPARATOR);
 
284
        if (!next)
 
285
                len = strlen (ptr);
 
286
        else
 
287
                len = next - ptr;
 
288
 
 
289
        for (iter = parent->specific.dir.children; iter; iter = iter->next) {
 
290
                BraseroVolFile *file;
 
291
 
 
292
                file = iter->data;
 
293
                if (!strncmp (ptr, BRASERO_VOLUME_FILE_NAME (file), len)) {
 
294
                        /* we've found it seek for the next if any */
 
295
                        if (!next)
 
296
                                return file;
 
297
 
 
298
                        ptr = next;
 
299
                        return brasero_volume_file_from_path (ptr, file);
 
300
                }
 
301
        }
 
302
 
 
303
        return NULL;
 
304
}
 
305
 
 
306
gint64
 
307
brasero_volume_file_size (BraseroVolFile *file)
 
308
{
 
309
        GList *iter;
 
310
        gint64 size = 0;
 
311
 
 
312
        if (!file->isdir) {
 
313
                GSList *extents;
 
314
 
 
315
                for (extents = file->specific.file.extents; extents; extents = extents->next) {
 
316
                        BraseroVolFileExtent *extent;
 
317
 
 
318
                        extent = extents->data;
 
319
                        size += extent->size;
 
320
                }
 
321
                return BRASERO_BYTES_TO_SECTORS (size, 2048);
 
322
        }
 
323
 
 
324
        for (iter = file->specific.dir.children; iter; iter = iter->next) {
 
325
                file = iter->data;
 
326
 
 
327
                if (file->isdir)
 
328
                        size += brasero_volume_file_size (file);
 
329
                else
 
330
                        size += BRASERO_BYTES_TO_SECTORS (file->specific.file.size_bytes, 2048);
 
331
        }
 
332
 
 
333
        return size;
 
334
}
 
335
 
 
336
BraseroVolFile *
 
337
brasero_volume_file_merge (BraseroVolFile *file1,
 
338
                           BraseroVolFile *file2)
 
339
{
 
340
        file1->specific.file.size_bytes += file2->specific.file.size_bytes;
 
341
        file1->specific.file.extents = g_slist_concat (file1->specific.file.extents,
 
342
                                                             file2->specific.file.extents);
 
343
 
 
344
        file2->specific.file.extents = NULL;
 
345
        brasero_volume_file_free (file2);
 
346
 
 
347
        return file1;
 
348
}
 
349