~ubuntu-branches/ubuntu/quantal/libarchive/quantal

« back to all changes in this revision

Viewing changes to libarchive/archive_write_set_format_cpio.c

  • Committer: Package Import Robot
  • Author(s): Andres Mejia
  • Date: 2012-02-23 19:29:24 UTC
  • mfrom: (8.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120223192924-73n4iedok5fwgsyr
Tags: 3.0.3-5
* Detect if locales or locales-all is installed for use with test suite.
* Bump Standards-Version to 3.9.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
 
40
40
#include "archive.h"
41
41
#include "archive_entry.h"
 
42
#include "archive_entry_locale.h"
42
43
#include "archive_private.h"
43
44
#include "archive_write_private.h"
44
45
 
45
46
static ssize_t  archive_write_cpio_data(struct archive_write *,
46
47
                    const void *buff, size_t s);
47
 
static int      archive_write_cpio_finish(struct archive_write *);
48
 
static int      archive_write_cpio_destroy(struct archive_write *);
 
48
static int      archive_write_cpio_close(struct archive_write *);
 
49
static int      archive_write_cpio_free(struct archive_write *);
49
50
static int      archive_write_cpio_finish_entry(struct archive_write *);
50
51
static int      archive_write_cpio_header(struct archive_write *,
51
52
                    struct archive_entry *);
 
53
static int      archive_write_cpio_options(struct archive_write *,
 
54
                    const char *, const char *);
52
55
static int      format_octal(int64_t, void *, int);
53
56
static int64_t  format_octal_recursive(int64_t, char *, int);
 
57
static int      write_header(struct archive_write *, struct archive_entry *);
54
58
 
55
59
struct cpio {
56
60
        uint64_t          entry_bytes_remaining;
60
64
        struct           { int64_t old; int new;} *ino_list;
61
65
        size_t            ino_list_size;
62
66
        size_t            ino_list_next;
63
 
};
64
 
 
65
 
struct cpio_header {
66
 
        char    c_magic[6];
67
 
        char    c_dev[6];
68
 
        char    c_ino[6];
69
 
        char    c_mode[6];
70
 
        char    c_uid[6];
71
 
        char    c_gid[6];
72
 
        char    c_nlink[6];
73
 
        char    c_rdev[6];
74
 
        char    c_mtime[11];
75
 
        char    c_namesize[6];
76
 
        char    c_filesize[11];
77
 
};
 
67
 
 
68
        struct archive_string_conv *opt_sconv;
 
69
        struct archive_string_conv *sconv_default;
 
70
        int               init_default_conversion;
 
71
};
 
72
 
 
73
#define c_magic_offset 0
 
74
#define c_magic_size 6
 
75
#define c_dev_offset 6
 
76
#define c_dev_size 6
 
77
#define c_ino_offset 12
 
78
#define c_ino_size 6
 
79
#define c_mode_offset 18
 
80
#define c_mode_size 6
 
81
#define c_uid_offset 24
 
82
#define c_uid_size 6
 
83
#define c_gid_offset 30
 
84
#define c_gid_size 6
 
85
#define c_nlink_offset 36
 
86
#define c_nlink_size 6
 
87
#define c_rdev_offset 42
 
88
#define c_rdev_size 6
 
89
#define c_mtime_offset 48
 
90
#define c_mtime_size 11
 
91
#define c_namesize_offset 59
 
92
#define c_namesize_size 6
 
93
#define c_filesize_offset 65
 
94
#define c_filesize_size 11
78
95
 
79
96
/*
80
97
 * Set output format to 'cpio' format.
85
102
        struct archive_write *a = (struct archive_write *)_a;
86
103
        struct cpio *cpio;
87
104
 
 
105
        archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
 
106
            ARCHIVE_STATE_NEW, "archive_write_set_format_cpio");
 
107
 
88
108
        /* If someone else was already registered, unregister them. */
89
 
        if (a->format_destroy != NULL)
90
 
                (a->format_destroy)(a);
 
109
        if (a->format_free != NULL)
 
110
                (a->format_free)(a);
91
111
 
92
 
        cpio = (struct cpio *)malloc(sizeof(*cpio));
 
112
        cpio = (struct cpio *)calloc(1, sizeof(*cpio));
93
113
        if (cpio == NULL) {
94
114
                archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
95
115
                return (ARCHIVE_FATAL);
96
116
        }
97
 
        memset(cpio, 0, sizeof(*cpio));
98
117
        a->format_data = cpio;
99
 
 
100
 
        a->pad_uncompressed = 1;
101
118
        a->format_name = "cpio";
 
119
        a->format_options = archive_write_cpio_options;
102
120
        a->format_write_header = archive_write_cpio_header;
103
121
        a->format_write_data = archive_write_cpio_data;
104
122
        a->format_finish_entry = archive_write_cpio_finish_entry;
105
 
        a->format_finish = archive_write_cpio_finish;
106
 
        a->format_destroy = archive_write_cpio_destroy;
 
123
        a->format_close = archive_write_cpio_close;
 
124
        a->format_free = archive_write_cpio_free;
107
125
        a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
108
126
        a->archive.archive_format_name = "POSIX cpio";
109
127
        return (ARCHIVE_OK);
110
128
}
111
129
 
 
130
static int
 
131
archive_write_cpio_options(struct archive_write *a, const char *key,
 
132
    const char *val)
 
133
{
 
134
        struct cpio *cpio = (struct cpio *)a->format_data;
 
135
        int ret = ARCHIVE_FAILED;
 
136
 
 
137
        if (strcmp(key, "hdrcharset")  == 0) {
 
138
                if (val == NULL || val[0] == 0)
 
139
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
140
                            "%s: hdrcharset option needs a character-set name",
 
141
                            a->format_name);
 
142
                else {
 
143
                        cpio->opt_sconv = archive_string_conversion_to_charset(
 
144
                            &a->archive, val, 0);
 
145
                        if (cpio->opt_sconv != NULL)
 
146
                                ret = ARCHIVE_OK;
 
147
                        else
 
148
                                ret = ARCHIVE_FATAL;
 
149
                }
 
150
        } else
 
151
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
152
                    "%s: unknown keyword ``%s''", a->format_name, key);
 
153
 
 
154
        return (ret);
 
155
}
 
156
 
112
157
/*
113
158
 * Ino values are as long as 64 bits on some systems; cpio format
114
159
 * only allows 18 bits and relies on the ino values to identify hardlinked
174
219
        return (ino_new);
175
220
}
176
221
 
 
222
 
 
223
static struct archive_string_conv *
 
224
get_sconv(struct archive_write *a)
 
225
{
 
226
        struct cpio *cpio;
 
227
        struct archive_string_conv *sconv;
 
228
 
 
229
        cpio = (struct cpio *)a->format_data;
 
230
        sconv = cpio->opt_sconv;
 
231
        if (sconv == NULL) {
 
232
                if (!cpio->init_default_conversion) {
 
233
                        cpio->sconv_default =
 
234
                            archive_string_default_conversion_for_write(
 
235
                              &(a->archive));
 
236
                        cpio->init_default_conversion = 1;
 
237
                }
 
238
                sconv = cpio->sconv_default;
 
239
        }
 
240
        return (sconv);
 
241
}
 
242
 
177
243
static int
178
244
archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
179
245
{
 
246
        const char *path;
 
247
        size_t len;
 
248
 
 
249
        if (archive_entry_filetype(entry) == 0) {
 
250
                archive_set_error(&a->archive, -1, "Filetype required");
 
251
                return (ARCHIVE_FAILED);
 
252
        }
 
253
 
 
254
        if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
 
255
            && errno == ENOMEM) {
 
256
                archive_set_error(&a->archive, ENOMEM,
 
257
                    "Can't allocate memory for Pathname");
 
258
                return (ARCHIVE_FATAL);
 
259
        }
 
260
        if (len == 0 || path == NULL || path[0] == '\0') {
 
261
                archive_set_error(&a->archive, -1, "Pathname required");
 
262
                return (ARCHIVE_FAILED);
 
263
        }
 
264
 
 
265
        if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
 
266
                archive_set_error(&a->archive, -1, "Size required");
 
267
                return (ARCHIVE_FAILED);
 
268
        }
 
269
        return write_header(a, entry);
 
270
}
 
271
 
 
272
static int
 
273
write_header(struct archive_write *a, struct archive_entry *entry)
 
274
{
180
275
        struct cpio *cpio;
181
276
        const char *p, *path;
182
 
        int pathlength, ret, ret2;
 
277
        int pathlength, ret, ret_final;
183
278
        int64_t ino;
184
 
        struct cpio_header       h;
 
279
        char h[76];
 
280
        struct archive_string_conv *sconv;
 
281
        size_t len;
185
282
 
186
283
        cpio = (struct cpio *)a->format_data;
187
 
        ret2 = ARCHIVE_OK;
188
 
 
189
 
        path = archive_entry_pathname(entry);
190
 
        pathlength = (int)strlen(path) + 1; /* Include trailing null. */
191
 
 
192
 
        memset(&h, 0, sizeof(h));
193
 
        format_octal(070707, &h.c_magic, sizeof(h.c_magic));
194
 
        format_octal(archive_entry_dev(entry), &h.c_dev, sizeof(h.c_dev));
 
284
        ret_final = ARCHIVE_OK;
 
285
        sconv = get_sconv(a);
 
286
 
 
287
        ret = archive_entry_pathname_l(entry, &path, &len, sconv);
 
288
        if (ret != 0) {
 
289
                if (errno == ENOMEM) {
 
290
                        archive_set_error(&a->archive, ENOMEM,
 
291
                            "Can't allocate memory for Pathname");
 
292
                        return (ARCHIVE_FATAL);
 
293
                }
 
294
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
295
                    "Can't translate pathname '%s' to %s",
 
296
                    archive_entry_pathname(entry),
 
297
                    archive_string_conversion_charset_name(sconv));
 
298
                ret_final = ARCHIVE_WARN;
 
299
        }
 
300
        /* Include trailing null. */
 
301
        pathlength = (int)len + 1;
 
302
 
 
303
        memset(h, 0, sizeof(h));
 
304
        format_octal(070707, h + c_magic_offset, c_magic_size);
 
305
        format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size);
195
306
 
196
307
        ino = synthesize_ino_value(cpio, entry);
197
308
        if (ino < 0) {
203
314
                    "Too many files for this cpio format");
204
315
                return (ARCHIVE_FATAL);
205
316
        }
206
 
        format_octal(ino & 0777777, &h.c_ino, sizeof(h.c_ino));
 
317
        format_octal(ino & 0777777, h + c_ino_offset, c_ino_size);
207
318
 
208
 
        format_octal(archive_entry_mode(entry), &h.c_mode, sizeof(h.c_mode));
209
 
        format_octal(archive_entry_uid(entry), &h.c_uid, sizeof(h.c_uid));
210
 
        format_octal(archive_entry_gid(entry), &h.c_gid, sizeof(h.c_gid));
211
 
        format_octal(archive_entry_nlink(entry), &h.c_nlink, sizeof(h.c_nlink));
 
319
        /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
 
320
        format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
 
321
        format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
 
322
        format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
 
323
        format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
212
324
        if (archive_entry_filetype(entry) == AE_IFBLK
213
325
            || archive_entry_filetype(entry) == AE_IFCHR)
214
 
            format_octal(archive_entry_dev(entry), &h.c_rdev, sizeof(h.c_rdev));
 
326
            format_octal(archive_entry_dev(entry), h + c_rdev_offset, c_rdev_size);
215
327
        else
216
 
            format_octal(0, &h.c_rdev, sizeof(h.c_rdev));
217
 
        format_octal(archive_entry_mtime(entry), &h.c_mtime, sizeof(h.c_mtime));
218
 
        format_octal(pathlength, &h.c_namesize, sizeof(h.c_namesize));
 
328
            format_octal(0, h + c_rdev_offset, c_rdev_size);
 
329
        format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
 
330
        format_octal(pathlength, h + c_namesize_offset, c_namesize_size);
219
331
 
220
332
        /* Non-regular files don't store bodies. */
221
333
        if (archive_entry_filetype(entry) != AE_IFREG)
222
334
                archive_entry_set_size(entry, 0);
223
335
 
224
336
        /* Symlinks get the link written as the body of the entry. */
225
 
        p = archive_entry_symlink(entry);
226
 
        if (p != NULL  &&  *p != '\0')
227
 
                format_octal(strlen(p), &h.c_filesize, sizeof(h.c_filesize));
 
337
        ret = archive_entry_symlink_l(entry, &p, &len, sconv);
 
338
        if (ret != 0) {
 
339
                if (errno == ENOMEM) {
 
340
                        archive_set_error(&a->archive, ENOMEM,
 
341
                            "Can't allocate memory for Linkname");
 
342
                        return (ARCHIVE_FATAL);
 
343
                }
 
344
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
345
                    "Can't translate linkname '%s' to %s",
 
346
                    archive_entry_symlink(entry),
 
347
                    archive_string_conversion_charset_name(sconv));
 
348
                ret_final = ARCHIVE_WARN;
 
349
        }
 
350
        if (len > 0 && p != NULL  &&  *p != '\0')
 
351
                ret = format_octal(strlen(p), h + c_filesize_offset,
 
352
                    c_filesize_size);
228
353
        else
229
 
                format_octal(archive_entry_size(entry),
230
 
                    &h.c_filesize, sizeof(h.c_filesize));
 
354
                ret = format_octal(archive_entry_size(entry),
 
355
                    h + c_filesize_offset, c_filesize_size);
 
356
        if (ret) {
 
357
                archive_set_error(&a->archive, ERANGE,
 
358
                    "File is too large for cpio format.");
 
359
                return (ARCHIVE_FAILED);
 
360
        }
231
361
 
232
 
        ret = (a->compressor.write)(a, &h, sizeof(h));
 
362
        ret = __archive_write_output(a, h, sizeof(h));
233
363
        if (ret != ARCHIVE_OK)
234
364
                return (ARCHIVE_FATAL);
235
365
 
236
 
        ret = (a->compressor.write)(a, path, pathlength);
 
366
        ret = __archive_write_output(a, path, pathlength);
237
367
        if (ret != ARCHIVE_OK)
238
368
                return (ARCHIVE_FATAL);
239
369
 
240
370
        cpio->entry_bytes_remaining = archive_entry_size(entry);
241
371
 
242
372
        /* Write the symlink now. */
243
 
        if (p != NULL  &&  *p != '\0')
244
 
                ret = (a->compressor.write)(a, p, strlen(p));
245
 
 
246
 
        if (ret == ARCHIVE_OK)
247
 
                ret = ret2;
248
 
        return (ret);
 
373
        if (p != NULL  &&  *p != '\0') {
 
374
                ret = __archive_write_output(a, p, strlen(p));
 
375
                if (ret != ARCHIVE_OK)
 
376
                        return (ARCHIVE_FATAL);
 
377
        }
 
378
        return (ret_final);
249
379
}
250
380
 
251
381
static ssize_t
258
388
        if (s > cpio->entry_bytes_remaining)
259
389
                s = cpio->entry_bytes_remaining;
260
390
 
261
 
        ret = (a->compressor.write)(a, buff, s);
 
391
        ret = __archive_write_output(a, buff, s);
262
392
        cpio->entry_bytes_remaining -= s;
263
393
        if (ret >= 0)
264
394
                return (s);
297
427
}
298
428
 
299
429
static int
300
 
archive_write_cpio_finish(struct archive_write *a)
 
430
archive_write_cpio_close(struct archive_write *a)
301
431
{
302
432
        int er;
303
433
        struct archive_entry *trailer;
304
434
 
305
 
        trailer = archive_entry_new();
 
435
        trailer = archive_entry_new2(NULL);
306
436
        /* nlink = 1 here for GNU cpio compat. */
307
437
        archive_entry_set_nlink(trailer, 1);
 
438
        archive_entry_set_size(trailer, 0);
308
439
        archive_entry_set_pathname(trailer, "TRAILER!!!");
309
 
        er = archive_write_cpio_header(a, trailer);
 
440
        er = write_header(a, trailer);
310
441
        archive_entry_free(trailer);
311
442
        return (er);
312
443
}
313
444
 
314
445
static int
315
 
archive_write_cpio_destroy(struct archive_write *a)
 
446
archive_write_cpio_free(struct archive_write *a)
316
447
{
317
448
        struct cpio *cpio;
318
449
 
327
458
archive_write_cpio_finish_entry(struct archive_write *a)
328
459
{
329
460
        struct cpio *cpio;
330
 
        size_t to_write;
331
 
        int ret;
332
461
 
333
462
        cpio = (struct cpio *)a->format_data;
334
 
        ret = ARCHIVE_OK;
335
 
        while (cpio->entry_bytes_remaining > 0) {
336
 
                to_write = cpio->entry_bytes_remaining < a->null_length ?
337
 
                    cpio->entry_bytes_remaining : a->null_length;
338
 
                ret = (a->compressor.write)(a, a->nulls, to_write);
339
 
                if (ret != ARCHIVE_OK)
340
 
                        return (ret);
341
 
                cpio->entry_bytes_remaining -= to_write;
342
 
        }
343
 
        return (ret);
 
463
        return (__archive_write_nulls(a, cpio->entry_bytes_remaining));
344
464
}