1 /*
2  * Copyright (c) 2007 Vreixo Formoso
3  * Copyright (c) 2009 - 2017 Thomas Schmitt
4  *
5  * This file is part of the libisofs project; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License version 2
7  * or later as published by the Free Software Foundation.
8  * See COPYING file for details.
9  */
10 #ifndef LIBISO_IMAGE_H_
11 #define LIBISO_IMAGE_H_
12 
13 #include "libisofs.h"
14 #include "node.h"
15 #include "fsource.h"
16 #include "builder.h"
17 
18 /* Size of a inode recycling window. Each new window causes a tree traversal.
19    Window memory consumption is ISO_USED_INODE_RANGE / 8.
20    This must be a power of 2 smaller than 30 bit and larger than 8 bit.
21    Here: 32 kB memory for 256k inodes.
22 */
23 #define ISO_USED_INODE_RANGE (1 << 18)
24 
25 /* How many warnings to issue about name collisions during iso_image_import()
26 */
27 #define ISO_IMPORT_COLL_WARN_MAX 10
28 
29 /*
30  * Image is a context for image manipulation.
31  * Global objects such as the message_queues must belogn to that
32  * context. Thus we will have, for example, a msg queue per image,
33  * so images are completely independent and can be managed together.
34  * (Useful, for example, in Multiple-Document-Interface GUI apps.
35  * [The stuff we have in init belongs really to image!]
36  */
37 
38 struct Iso_Image
39 {
40 
41     int refcount;
42 
43     IsoDir *root;
44 
45     char *volset_id;
46 
47     char *volume_id; /**< Volume identifier. */
48     char *publisher_id; /**< Volume publisher. */
49     char *data_preparer_id; /**< Volume data preparer. */
50     char *system_id; /**< Volume system identifier. */
51     char *application_id; /**< Volume application id */
52     char *copyright_file_id;
53     char *abstract_file_id;
54     char *biblio_file_id;
55     char *creation_time;
56     char *modification_time;
57     char *expiration_time;
58     char *effective_time;
59     char application_use[512];
60 
61     /* el-torito boot catalog */
62     struct el_torito_boot_catalog *bootcat;
63 
64     /* Eventually loaded system area data, or NULL */
65     char *system_area_data;
66     /* Prescribed/detected options, see iso_write_opts_set_system_area() */
67     /* >>> Needs to be coordinated with .imported_sa_info->system_area_options
68     */
69     int system_area_options;
70 
71    /*
72     * Up to 15 boot files can be referred by a MIPS Big Endian Volume Header.
73       The mips_boot_file_paths are ISO 9660 Rock Ridge paths.
74     */
75     int num_mips_boot_files;
76     char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
77 
78     /* A data file of which the position and size shall be written after
79        a SUN Disk Label.
80     */
81     IsoFile *sparc_core_node;
82 
83     /*
84      * Parameters for HP-PA PALO boot sector. cmdline is a string. The other
85      * four are absolute paths to data files in the ISO image.
86      */
87     char *hppa_cmdline;
88     char *hppa_bootloader;
89     char *hppa_kernel_32;
90     char *hppa_kernel_64;
91     char *hppa_ramdisk;
92 
93     /* Absolute DEC Alpha boot image path in the ISO image */
94     char *alpha_boot_image;
95 
96     /* image identifier, for message origin identifier */
97     int id;
98 
99     /**
100      * Default filesystem to use when adding files to the image tree.
101      */
102     IsoFilesystem *fs;
103 
104     /**
105      * Block storage of imported ISO if demanded by IsoReadOpts.
106      */
107     IsoDataSource *import_src;
108 
109     /*
110      * Default builder to use when adding files to the image tree.
111      */
112     IsoNodeBuilder *builder;
113 
114     /**
115      * Whether to follow symlinks or just add them as symlinks
116      */
117     unsigned int follow_symlinks : 1;
118 
119     /**
120      * Whether to skip hidden files
121      */
122     unsigned int ignore_hidden : 1;
123 
124     /**
125      * Flags that determine what special files should be ignore. It is a
126      * bitmask:
127      * bit0: ignore FIFOs
128      * bit1: ignore Sockets
129      * bit2: ignore char devices
130      * bit3: ignore block devices
131      */
132     int ignore_special;
133 
134     /**
135      * Whether to ignore ACL when inserting nodes into the image.
136      * Not in effect with loading a complete ISO image but only with image
137      * manipulation.
138      */
139     unsigned int builder_ignore_acl : 1;
140 
141     /**
142      * Whether to ignore EAs when inserting nodes into the image.
143      * Not in effect with loading a complete ISO image but only with image
144      * manipulation. ACL does not count as EA.
145      */
146     unsigned int builder_ignore_ea : 1;
147 
148     /**
149      * If not builder_ignore_ea : import all xattr namespaces from local
150      *                            filesystem, not only "user.
151      */
152     unsigned int builder_take_all_ea : 1;
153 
154     /**
155      * Files to exclude. Wildcard support is included.
156      */
157     char** excludes;
158     int nexcludes;
159 
160     /**
161      * if the dir already contains a node with the same name, whether to
162      * replace or not the old node with the new.
163      */
164     enum iso_replace_mode replace;
165 
166     /* TODO
167     enum iso_replace_mode (*confirm_replace)(IsoFileSource *src, IsoNode *node);
168     */
169 
170     /**
171      * What to do in case of name longer than truncate_length:
172      *  0= throw FAILURE
173      *  1= truncate to truncate_length with MD5 of whole name at end
174      */
175     int truncate_mode;
176     int truncate_length;
177 
178     /**
179      * This is a convenience buffer for name truncation during image
180      * manipulation where libisofs is not thread-safe anyway.
181      */
182     char truncate_buffer[4096];
183 
184     /**
185      * When this is not NULL, it is a pointer to a function that will
186      * be called just before a file will be added. You can control where
187      * the file will be in fact added or ignored.
188      *
189      * @return
190      *      1 add, 0 ignore, < 0 cancel
191      */
192     int (*report)(IsoImage *image, IsoFileSource *src);
193 
194     /**
195      * User supplied data
196      */
197     void *user_data;
198     void (*user_data_free)(void *ptr);
199 
200     /**
201      * Inode number management. inode_counter is taken over from
202      * IsoImageFilesystem._ImageFsData after image import.
203      * It is to be used with img_give_ino_number()
204      * This is a Rock Ridge file serial number. Thus 32 bit.
205     */
206     uint32_t inode_counter;
207     /*
208      * A bitmap of used inode numbers in an interval beginning at
209      * used_inodes_start and holding ISO_USED_INODE_RANGE bits.
210      * If a bit is set, then the corresponding inode number is occupied.
211      * This interval is kept around inode_counter and eventually gets
212      * advanced by ISO_USED_INODE_RANGE numbers in a tree traversal
213      * done by img_collect_inos(). The value will stay in the 32 bit range,
214      * although used_inodes_start is 64 bit to better handle rollovers.
215      */
216     uint8_t *used_inodes;
217     uint64_t used_inodes_start;
218 
219     /**
220      * Array of MD5 checksums as announced by xattr "isofs.ca" of the
221      * root node. Array element 0 contains an overall image checksum for the
222      * block range checksum_start_lba,checksum_end_lba. Element size is
223      * 16 bytes. IsoFile objects in the image may have xattr "isofs.cx"
224      * which gives their index in checksum_array.
225      */
226     uint32_t checksum_start_lba;
227     uint32_t checksum_end_lba;
228     uint32_t checksum_idx_count;
229     char *checksum_array;
230 
231     /**
232      * Whether a write run has been started by iso_image_create_burn_source()
233      * and has not yet been finished.
234      */
235     int generator_is_running;
236 
237     /* Pointers to directories or files which shall be get a HFS+ blessing.
238      * libisofs/hfsplus.c et.al. will compare these pointers
239      * with the ->node pointer of Ecma119Nodes.
240      * See libisofs.h
241      */
242     IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
243 
244     /* Counts the name collisions while iso_image_import() */
245     size_t collision_warnings;
246 
247     /* Contains the assessment of boot aspects of the loaded image */
248     struct iso_imported_sys_area *imported_sa_info;
249 
250     /* Whether some local filesystem xattr namespace could not be explored
251      * during node building.
252      */
253     int blind_on_local_get_attrs;
254 
255 };
256 
257 
258 /* Apply truncation mode to name, using image->truncate_buffer to perform
259    truncation if needed.
260 
261    Warning: Not thread-safe !
262 */
263 int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
264                             int flag);
265 
266 
267 /* Collect the bitmap of used inode numbers in the range of
268    _ImageFsData.used_inodes_start + ISO_USED_INODE_RANGE
269    @param flag bit0= recursion is active
270 */
271 int img_collect_inos(IsoImage *image, IsoDir *dir, int flag);
272 
273 /**
274  * A global counter for inode numbers for the ISO image filesystem.
275  * On image import it gets maxed by the eventual inode numbers from PX
276  * entries. Up to the first 32 bit rollover it simply increments the counter.
277  * After the first rollover it uses a look ahead bitmap which gets filled
278  * by a full tree traversal. It covers the next inode numbers to come
279  * (somewhere between 1 and ISO_USED_INODE_RANGE which is quite many)
280  * and advances when being exhausted.
281  * @param image The image where the number shall be used
282  * @param flag  bit0= reset count (Caution: image must get new inos then)
283  * @return
284  *     Since 0 is used as default and considered self-unique,
285  *     the value 0 should only be returned in case of error.
286  */
287 uint32_t img_give_ino_number(IsoImage *image, int flag);
288 
289 /* @param flag bit0= overwrite any ino, else only ino == 0
290                bit1= install inode with non-data, non-directory files
291                bit2= install inode with directories
292                bit3= with bit2: install inode on parameter dir
293 */
294 int img_make_inos(IsoImage *image, IsoDir *dir, int flag);
295 
296 
297 /* Free the checksum array of an image and reset its layout parameters
298 */
299 int iso_image_free_checksums(IsoImage *image, int flag);
300 
301 
302 /* Equip an ISO image with a new checksum array buffer (after isofs.ca and
303    isofs.cx have already been adjusted).
304 */
305 int iso_image_set_checksums(IsoImage *image, char *checksum_array,
306                             uint32_t start_lba, uint32_t end_lba,
307                             uint32_t idx_count, int flag);
308 
309 
310 int iso_image_set_pvd_times(IsoImage *image,
311                             char *creation_time, char *modification_time,
312                             char *expiration_time, char *effective_time);
313 
314 
315 /* Collects boot block information obtained from the system area of
316    imported images
317 */
318 struct iso_imported_sys_area {
319 
320     int refcount;
321 
322     /* Whether there was some System Area data at all */
323     int is_not_zero;
324 
325     /* Giving the error number if the assessment ended by an error */
326     int overall_return;
327 
328     /* Block address of loaded Primar Volume Descriptor */
329     uint32_t pvd_block;
330 
331     /* Size of the imported ISO image */
332     uint32_t image_size;
333 
334     /* see libisofs.h : iso_write_opts_set_system_area() */
335     int system_area_options;
336 
337     /* The perceived MBR partitions */
338     struct iso_mbr_partition_request **mbr_req;
339     int mbr_req_count;
340 
341     /* see ecma119.h : struct ecma119_image , struct iso_write_opts */
342     /* Effective partition table parameter: 1 to 63, 0= disabled/default */
343     int partition_secs_per_head;
344     /* 1 to 255, 0= disabled/default */
345     int partition_heads_per_cyl;
346 
347     /* see ecma119.h :  struct iso_write_opts */
348     uint32_t partition_offset;
349 
350     /* 2048-byte start LBA and block count of PreP partition */
351     uint32_t prep_part_start;
352     uint32_t prep_part_size;
353 
354     /* see ecma119.h : struct ecma119_image */
355     struct iso_apm_partition_request **apm_req;
356     int apm_req_count;
357     int apm_req_flags;
358     /* Number of found "GapNN", "ISO9660_data" partitions in APM */
359     int apm_gap_count;
360 
361     /* see ecma119.h : struct iso_write_opts */
362     int apm_block_size;
363 
364     /* >>> see ecma119.h : struct iso_write_opts */
365     int hfsp_block_size;
366 
367     /* see ecma119.h : struct ecma119_image */
368     struct iso_gpt_partition_request **gpt_req;
369     int gpt_req_count;
370     int gpt_req_flags;
371 
372     /* see ecma119.h : struct ecma119_image */
373     uint8_t gpt_disk_guid[16];
374     /* Start of GPT entries in System Area, block size 512 */
375     uint64_t gpt_part_start;
376     uint32_t gpt_max_entries;
377     uint64_t gpt_first_lba;
378     uint64_t gpt_last_lba;
379     uint64_t gpt_backup_lba;
380     char *gpt_backup_comments;
381     uint32_t gpt_head_crc_found;
382     uint32_t gpt_head_crc_should;
383     uint32_t gpt_array_crc_found;
384     uint32_t gpt_array_crc_should;
385 
386     /* see image.h : struct Iso_Image */
387     int num_mips_boot_files;
388     char **mips_boot_file_paths; /* ISO 9660 Rock Ridge Paths */
389     struct iso_mips_voldir_entry **mips_vd_entries;
390 
391     /* see ecma119.h : struct ecma119_image */
392     /* Memorized ELF parameters from MIPS Little Endian boot file */
393     uint32_t mipsel_e_entry;
394     uint32_t mipsel_p_offset;
395     uint32_t mipsel_p_vaddr;
396     uint32_t mipsel_p_filesz;
397     uint32_t mipsel_seg_start;
398     char *mipsel_boot_file_path;
399 
400     /* see image.h : struct Iso_Image */
401     char *sparc_disc_label;
402     int sparc_secs_per_head;
403     int sparc_heads_per_cyl;
404     struct iso_sun_disk_label_entry *sparc_entries;
405     int sparc_entry_count;
406 
407     /* grub2-sparc-core : a node in the ISO image
408                           published at bytes 0x228 to 0x233
409     */
410     uint64_t sparc_grub2_core_adr;
411     uint32_t sparc_grub2_core_size;
412     IsoFile *sparc_core_node;
413 
414     /* see image.h : struct Iso_Image */
415     int hppa_hdrversion;
416     char *hppa_cmdline;
417     uint32_t hppa_kern32_adr;
418     uint32_t hppa_kern32_len;
419     uint32_t hppa_kern64_adr;
420     uint32_t hppa_kern64_len;
421     uint32_t hppa_ramdisk_adr;
422     uint32_t hppa_ramdisk_len;
423     uint32_t hppa_bootloader_adr;
424     uint32_t hppa_bootloader_len;
425     uint32_t hppa_ipl_entry;
426     char *hppa_kernel_32;
427     char *hppa_kernel_64;
428     char *hppa_ramdisk;
429     char *hppa_bootloader;
430 
431     uint64_t alpha_boot_image_size;
432     uint64_t alpha_boot_image_adr;
433     char *alpha_boot_image;
434 
435     /* Some block addresses of active and first session:
436          PVD, L Pathtable, Opt L, M Pathtable, Opt M, root directory
437     */
438     uint32_t meta_struct_blocks[12];
439     int num_meta_struct_blocks;
440 };
441 
442 int iso_imported_sa_new(struct iso_imported_sys_area **sa_info, int flag);
443 
444 int iso_imported_sa_unref(struct iso_imported_sys_area **sa_info, int flag);
445 
446 
447 #endif /*LIBISO_IMAGE_H_*/
448