~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to libblkid/src/superblocks/iso9660.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1999 by Andries Brouwer
 
3
 * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
 
4
 * Copyright (C) 2001 by Andreas Dilger
 
5
 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
 
6
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
 
7
 *
 
8
 * Inspired also by libvolume_id by
 
9
 *     Kay Sievers <kay.sievers@vrfy.org>
 
10
 *
 
11
 * This file may be redistributed under the terms of the
 
12
 * GNU Lesser General Public License.
 
13
 */
 
14
#include <stdio.h>
 
15
#include <stdlib.h>
 
16
#include <unistd.h>
 
17
#include <string.h>
 
18
#include <stdint.h>
 
19
 
 
20
#include "superblocks.h"
 
21
 
 
22
/* PVD - Primary volume descriptor */
 
23
struct iso_volume_descriptor {
 
24
        unsigned char   vd_type;
 
25
        unsigned char   vd_id[5];
 
26
        unsigned char   vd_version;
 
27
        unsigned char   flags;
 
28
        unsigned char   system_id[32];
 
29
        unsigned char   volume_id[32];
 
30
        unsigned char   unused[8];
 
31
        unsigned char   space_size[8];
 
32
        unsigned char   escape_sequences[8];
 
33
} __attribute__((packed));
 
34
 
 
35
#define ISO_SUPERBLOCK_OFFSET           0x8000
 
36
#define ISO_SECTOR_SIZE                 0x800
 
37
#define ISO_VD_OFFSET                   (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE)
 
38
#define ISO_VD_SUPPLEMENTARY            0x2
 
39
#define ISO_VD_END                      0xff
 
40
#define ISO_VD_MAX                      16
 
41
 
 
42
struct high_sierra_volume_descriptor {
 
43
        unsigned char   foo[8];
 
44
        unsigned char   type;
 
45
        unsigned char   id[5];
 
46
        unsigned char   version;
 
47
        unsigned char   unused1;
 
48
        unsigned char   system_id[32];
 
49
        unsigned char   volume_id[32];
 
50
} __attribute__((packed));
 
51
 
 
52
/* returns 1 if the begin of @ascii is equal to @utf16 string.
 
53
 */
 
54
static int ascii_eq_utf16be(unsigned char *ascii,
 
55
                        unsigned char *utf16, size_t len)
 
56
{
 
57
        size_t a, u;
 
58
 
 
59
        for (a = 0, u = 0; u < len; a++, u += 2) {
 
60
                if (utf16[u] != 0x0 || ascii[a] != utf16[u + 1])
 
61
                        return 0;
 
62
        }
 
63
        return 1;
 
64
}
 
65
 
 
66
/* old High Sierra format */
 
67
static int probe_iso9660_hsfs(blkid_probe pr, const struct blkid_idmag *mag)
 
68
{
 
69
        struct high_sierra_volume_descriptor *iso;
 
70
 
 
71
        iso = blkid_probe_get_sb(pr, mag, struct high_sierra_volume_descriptor);
 
72
        if (!iso)
 
73
                return -1;
 
74
 
 
75
        blkid_probe_set_version(pr, "High Sierra");
 
76
        blkid_probe_set_label(pr, iso->volume_id, sizeof(iso->volume_id));
 
77
        return 0;
 
78
}
 
79
 
 
80
/* iso9660 [+ Microsoft Joliet Extension] */
 
81
static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
 
82
{
 
83
        struct iso_volume_descriptor *iso;
 
84
        unsigned char label[32];
 
85
        int i;
 
86
        int off;
 
87
 
 
88
        if (strcmp(mag->magic, "CDROM") == 0)
 
89
                return probe_iso9660_hsfs(pr, mag);
 
90
 
 
91
        iso = blkid_probe_get_sb(pr, mag, struct iso_volume_descriptor);
 
92
        if (!iso)
 
93
                return -1;
 
94
 
 
95
        memcpy(label, iso->volume_id, sizeof(label));
 
96
 
 
97
        /* Joliet Extension */
 
98
        off = ISO_VD_OFFSET;
 
99
        for (i = 0; i < ISO_VD_MAX; i++) {
 
100
                iso = (struct iso_volume_descriptor *)
 
101
                        blkid_probe_get_buffer(pr,
 
102
                                        off,
 
103
                                        sizeof(struct iso_volume_descriptor));
 
104
 
 
105
                if (iso == NULL || iso->vd_type == ISO_VD_END)
 
106
                        break;
 
107
                if (iso->vd_type != ISO_VD_SUPPLEMENTARY)
 
108
                        continue;
 
109
 
 
110
                if (memcmp(iso->escape_sequences, "%/@", 3) == 0 ||
 
111
                    memcmp(iso->escape_sequences, "%/C", 3) == 0 ||
 
112
                    memcmp(iso->escape_sequences, "%/E", 3) == 0) {
 
113
 
 
114
                        blkid_probe_set_version(pr, "Joliet Extension");
 
115
 
 
116
                        /* Is the Joliet (UTF16BE) label equal to the label in
 
117
                         * the PVD? If yes, use PVD label.  The Jolied version
 
118
                         * of the label could be trimed (because UTF16..).
 
119
                         */
 
120
                        if (ascii_eq_utf16be(label, iso->volume_id, 32))
 
121
                                break;
 
122
 
 
123
                        blkid_probe_set_utf8label(pr,
 
124
                                        iso->volume_id,
 
125
                                        sizeof(iso->volume_id),
 
126
                                        BLKID_ENC_UTF16BE);
 
127
                        goto has_label;
 
128
                }
 
129
                off += ISO_SECTOR_SIZE;
 
130
        }
 
131
 
 
132
        /* Joliet not found, let use standard iso label */
 
133
        blkid_probe_set_label(pr, label, sizeof(label));
 
134
 
 
135
has_label:
 
136
        return 0;
 
137
}
 
138
 
 
139
 
 
140
const struct blkid_idinfo iso9660_idinfo =
 
141
{
 
142
        .name           = "iso9660",
 
143
        .usage          = BLKID_USAGE_FILESYSTEM,
 
144
        .probefunc      = probe_iso9660,
 
145
        .flags          = BLKID_IDINFO_TOLERANT,
 
146
        .magics         =
 
147
        {
 
148
                { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 },
 
149
                { .magic = "CDROM", .len = 5, .kboff = 32, .sboff = 9 },
 
150
                { NULL }
 
151
        }
 
152
};
 
153