"Fossies" - the Fresh Open Source Software Archive 
Member "libisofs-1.5.4/doc/Tutorial" (8 Jul 2020, 19342 Bytes) of package /linux/misc/libisofs-1.5.4.tar.gz:
As a special service "Fossies" has tried to format the requested text file into HTML format (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
1 ===============================================================================
2 LIBISOFS DEVELOPMENT TUTORIAL
3 ===============================================================================
4
5 Creation date: 2008-Jan-27
6 Author: Vreixo Formoso
7 _______________________________________________________________________________
8
9 This is a little tutorial of how to use libisofs library for application
10 development.
11
12 Contents:
13 ---------
14
15 1. Introduction
16 1.1 Library initialization
17 1.2 Image context
18 1.3 Error reporting
19 2. Creating an image
20 2.1 Image tree manipulation
21 2.2 Set the write options
22 2.3 Obtaining a burn_source
23 3. Image growing and modification
24 3.1 Growing vs Modification
25 3.2 Image import
26 3.3 Generating a new image
27 4. Bootable images
28 5. Advanced features
29
30
31 -------------------------------------------------------------------------------
32 1. Introduction
33 -------------------------------------------------------------------------------
34
35 [TODO some lines about refcounts]
36
37 -------------------------------------------------------------------------------
38 1.1. Library initialization
39
40 Before any usage of the library, you have to call
41
42 iso_init()
43
44 in the same way, when you have finished using the library, you should call
45
46 iso_finish()
47
48 to free all resources reserved by the library.
49
50 -------------------------------------------------------------------------------
51 1.2. Image context
52
53 Libisofs is image-oriented, the core of libisofs usage is the IsoImage object.
54 Thus, the first you need to do is to get your own IsoImage object:
55
56 IsoImage *my_image;
57 iso_image_new("NEW DISC", &my_image);
58
59 An IsoImage is a context for image creation. It holds the files that will be
60 added to image, other related information and several options to customize
61 the behavior of libisofs when working with such Image. i.e., an IsoImage is
62 a context for libisofs operations. As such, you can work with several image
63 contexts at a time.
64
65 -------------------------------------------------------------------------------
66 1.3. Error reporting
67
68 In libisofs error reporting is done in two ways: with the return value of
69 the functions and with the message queue.
70
71 Error codes are negative numbers, defined in "libisofs.h" header. An
72 error code is associated with a given severity, either "DEBUG", "UPDATE",
73 "NOTE", "HINT", "WARNING", "SORRY", "FAILURE" and "FATAL". For the meaning
74 of each severity take a look at private header "libiso_msgs.h". Errors
75 reported by function return value are always "FAILURE" or "FATAL". Other kind
76 of errors are only reported with the message queue. You can get the severity
77 of any error message with iso_error_get_severity() function.
78
79 First of all, most libisofs functions return an integer. If such integer is
80 a negative number, it means the function has returned an error. The error code
81 and its severity is encoded in the return value (take a look at error codes in
82 libisofs.h header).
83
84 Additionally, libisofs reports most of its errors in a message queue. Error
85 messages on that queue can be printed directly to stderr or programmatically
86 retrieved. First of all, you should set the severity threshold over which an
87 error is printed or enqueued, with function:
88
89 iso_set_msgs_severities()
90
91 Errors enqueued can be retrieved with function:
92
93 iso_obtain_msgs()
94
95 Together with the code error, a text message and its severity, this function
96 also returns the image id. This is an identifier that uniquely identifies a
97 given image context. You can get the identifier of each IsoImage with the
98
99 iso_image_get_msg_id()
100
101 and that way distinguish what image has issued the message.
102
103
104 -------------------------------------------------------------------------------
105 2. Creating an Image
106 -------------------------------------------------------------------------------
107
108 An image is built from a set of files that you want to store together in an
109 ISO-9660 volume. We call the "iso tree" to the file hierarchy that will be
110 written to image. The image context, IsoImage, holds that tree, together with
111 configuration options and other properties of the image, that provide info
112 about the volume (such as the identifier, author, etc...).
113
114 All configuration options and volume properties are set by its corresponding
115 setters (iso_image_set_volset_id(), iso_image_set_publisher_id()...)
116
117 To create an image, you have to follow the following steps:
118
119 * Obtain the image context.
120 See "1.2 Image context" for details of how to obtain the IsoImage.
121 * Set the desired properties
122 * Prepare the iso tree with the files you want to add to image.
123 See "2.1 Image tree manipulation" for details
124 * Select the options for image generation.
125 See "2.2 Set the write options"
126 * Get the burn_source used to actually write the image.
127
128
129 -------------------------------------------------------------------------------
130 2.1 Image tree manipulation
131
132 libisofs maintains in memory a file tree (usually called the iso tree), that
133 represents the files and directories that will be written later to image. You
134 are allowed to make whatever changes you want to that tree, just like you do
135 to any "real" filesystem, before actually write it to image.
136
137 Unlike other ISO-9660 mastering tools, you have full control over the file
138 hierarchy that will be written to image, via the libisofs API. You can add
139 new files, create any file in image, change its name, attributes, etc The iso
140 tree behaves just like any other POSIX filesystem.
141
142 The root of the iso tree is created automatically when the IsoImage is
143 allocated, and you can't replace it. To get a reference to it you can use the
144 function:
145
146 iso_image_get_root()
147
148 * Iso tree objects
149
150 Each file in the image or iso tree is represented by an IsoNode instance. In
151 the same way a POSIX filesystem has several file types (regular files,
152 directories, symlinks...), the IsoNode has several subtypes:
153
154 IsoNode
155 |
156 ---------------------------------
157 | | | |
158 IsoDir IsoFile IsoSymlink IsoSpecial
159
160 where
161
162 - IsoDir represents a directory
163 - IsoFile represents a regular file
164 - IsoSymlink represents a symbolic linke
165 - IsoSpecial represents any other POSIX file, i.e. block and character
166 devices, FIFOs, sockets.
167
168 You can obtain the concrete type of an IsoNode with the iso_node_get_type()
169 function.
170
171 Many libisofs functions take or return an IsoNode. Many others, however,
172 require an specific type. You can safety cast any subtype to an IsoNode
173 object. In the same way, after ensuring you are dealing with the correct
174 subtype, you can downcast a given IsoNode to the specific subtype.
175
176 IsoDir *dir;
177 IsoNode *node;
178
179 node = (IsoNode*) dir;
180
181 if (iso_node_get_type(node) == LIBISO_DIR) {
182 dir = (IsoDir*) node;
183 ...
184 }
185
186 or with the provided macros:
187
188 IsoDir *dir;
189 IsoNode *node;
190
191 node = ISO_NODE(dir);
192
193 if (ISO_NODE_IS_DIR(node)) {
194 dir = ISO_DIR(node);
195 ...
196 }
197
198 * Adding files to the image
199
200 Files can be added to the image or iso tree either as new files or as files
201 from the filesystem.
202
203 In the first case, files are created directly on the image. They do not
204 correspond to any file in the filesystem. Provided functions are:
205
206 - iso_tree_add_new_dir()
207 - iso_tree_add_new_symlink()
208 - iso_tree_add_new_special()
209
210 On the other side, you can add local files to the image, either with the
211
212 iso_tree_add_node()
213
214 or with
215
216 iso_tree_add_dir_rec().
217
218 The first is intended to add a single file, while the last can be used to add,
219 recursively, a full directory (see below for details).
220
221 It is important to note that libisofs doesn't store any kind of link between
222 the IsoNode and the filesystem file it was created from. The above functions
223 just initialize a newly created IsoNode with the attributes of a given file in
224 the filesystem. After that, you can move the original file, change its
225 attributes or even delete it. The IsoNode in the image tree remains with the
226 original attributes. One exception to this rule are the contents of a regular
227 file. Libisofs does not make any copy of those contents until they're actually
228 written to image. Thus, you shouldn't modify, move or delete regular files
229 after adding them to the IsoImage.
230
231
232 * Recursive directory addition.
233
234 One common use case is to add a local directory to the image. While this can
235 be done with iso_tree_add_node(), handling the addition of directory children
236 in the application, libisofs provides a function suitable for this case:
237
238 iso_tree_add_dir_rec()
239
240 that takes care of adding all files inside a directory, recursing on directory
241 children. By default, this function adds all children. However, it is usual
242 that you don't want really this. For example, you may want to exclude some
243 kind of files (backup files, application sockets,...). Libisofs provides
244 several functions to customize the behavior of that function:
245
246 - iso_tree_set_follow_symlinks()
247 - iso_tree_set_ignore_hidden()
248 - iso_tree_set_ignore_special()
249 - iso_tree_add_exclude()
250
251 * Operations on iso tree
252
253 [TODO briefly explain how to add node, change attributes, ...]
254
255 * Replace mode
256
257 [TODO]
258
259 -------------------------------------------------------------------------------
260 2.2 Set the write options
261
262 Once you have prepared the iso tree, it is time to select the options for the
263 image writing.
264
265 These options affect the characteristics of the filesystem to create in the
266 image, but also can control how libisofs generates the image.
267
268 First of all you have to get an instance of IsoWriteOpts, with the function
269
270 iso_write_opts_new()
271
272 The several options available can be classified in:
273
274 - Extensions to add to the ISO-9660 image:
275
276 iso_write_opts_set_rockridge()
277 iso_write_opts_set_joliet()
278 iso_write_opts_set_iso1999()
279
280 RockRidge is highly recommended, in fact you should use it in all image. Joliet
281 is needed if you want to use your images in Windows system. Nowadays,
282 ISO-9660:1999 is no much useful, so in most cases you don't want such
283 extension.
284
285 - ISO-9660 options:
286
287 iso_write_opts_set_iso_level()
288 iso_write_opts_set_omit_version_numbers()
289 iso_write_opts_set_allow_deep_paths()
290 iso_write_opts_set_allow_longer_paths()
291 iso_write_opts_set_max_37_char_filenames()
292 iso_write_opts_set_no_force_dots()
293 iso_write_opts_set_allow_lowercase()
294 iso_write_opts_set_allow_full_ascii()
295
296 These control the options for the ISO-9660 filesystem. In most cases you won't
297 care about them, as it is the RockRidge or Joliet extensions what determine the
298 properties of the files once the image is mounted.
299
300 - File attributes options
301
302 iso_write_opts_set_replace_mode()
303 iso_write_opts_set_default_dir_mode()
304 iso_write_opts_set_default_file_mode()
305 iso_write_opts_set_default_uid()
306 iso_write_opts_set_default_gid()
307 iso_write_opts_set_replace_timestamps()
308 iso_write_opts_set_default_timestamp()
309 iso_write_opts_set_always_gmt()
310
311 They allow to set default attributes for files in image, despite of the real
312 attributes of the file on the local filesystem.
313
314 -------------------------------------------------------------------------------
315 2.3 Obtaining a burn_source
316
317 Finally, you get the burn_source used to write the image with the function:
318
319 iso_image_create_burn_source()
320
321 The returned burn_source is suitable for using with libburn, to directly burn
322 the image to a disc. Alternatively, you can use burn_source read() to get
323 the image contents (for example, to write them to a file, pipe...).
324
325 Before creating the burn_source, libisofs computes the size of the image, so
326 the get_size() function of the burn_source always returns the final image
327 size. It also starts a writing thread. All the operations needed to generate
328 the image are done by this thread, including read the original files contents.
329 The image is writing to a FIFO buffer, from which the burn_source will read.
330 The size of the buffer can be set in advanced with a property of the
331 IsoWriteOpts struct:
332
333 iso_write_opts_set_fifo_size()
334
335 You can get the state of the buffer in any moment, with the function:
336
337 iso_ring_buffer_get_status()
338
339 You can also cancel the writer thread at any time, with the cancel() function
340 of the burn_source.
341
342
343 -------------------------------------------------------------------------------
344 3. Image growing and modification
345 -------------------------------------------------------------------------------
346
347 -------------------------------------------------------------------------------
348 3.1 Growing vs Modification
349
350 Libisofs is not restricted only to create new images. It can also be used to
351 modify existing images. It supports two kind of image modifications, that we
352 have called image growing and image modification:
353
354 Image modification consists in generating a new image, based on the contents
355 of an existing image. In this mode, libisofs takes an image, the users modifies
356 its contents (adding new files, removing files, changing their names...), and
357 finally libisofs generates a completely new image.
358
359 On the other side, image growing is similar, with the difference that the new
360 image is dependent on the other, i.e., it refers to files of the other image.
361 Thus, it can't be mounted without the old image. The purpose of this kind of
362 images is to increment or add files to a multisession disc. The new image only
363 contains the new files. Old files are just references to the old image blocks.
364
365 The advantage of the growing approach is that the generated image is smaller,
366 as only the new files are written. This mode is suitable when you just want to
367 add some files to a very big image, or when dealing with write-once media, such
368 as CD-R. Both the time and space needed for the modification is much less than
369 with normal image modify.
370
371 The main problem of growing is that the new image needs to be recorded together
372 with the old image, in order to be mountable. The total size of the image
373 (old + new) is bigger (even much bigger) than a completely new image. So, if
374 you plan to distribute an image on Internet, or burn it to a disc, generate a
375 completely new image is usually a better alternative.
376
377 To be able to mount a grown image, the OS needs to now you have appended new
378 data to the original image. In multisession media (such as CD-R), the new data
379 is appended as a new session, so the OS can identify this and mount the image
380 propertly. However, when dealing with non-multisession media (such as DVD+RW)
381 or plain .iso files, the new data is just appended at the end of the old image,
382 and the OS has no way to know that the appended data is in fact a "new
383 session". The method introduced by Andy Polyakov in growisofs can be used in
384 those cases. It consists in overwrite the volume descriptors of the old image
385 with a new ones that refer to the newly appended contents.
386
387 -------------------------------------------------------------------------------
388 3.2 Image import
389
390 The first thing you need to do in order to modify or grow an image is to import
391 it, with the function:
392
393 iso_image_import()
394
395 It takes several arguments.
396
397 First, the image context, an IsoImage previously obtained with iso_image_new().
398 In most cases you will want to use an empty image. However, if you have already
399 added files to the image, they will be removed and replaced with the contents
400 of the image being imported.
401
402 The second parameter is an IsoDataSource instance. It abstracts the original
403 image, and it is used by libisofs to access its contents. You are free to
404 implement your own data source to access image contents. However, libisofs has
405 a simple implementation suitable for reading images on the local filesystem,
406 that can be used for import both .iso files and inserted media, via the block
407 device and POSIX functions. You can get it with
408
409 iso_data_source_new_from_file()
410
411 The third parameter of iso_image_import() is a pointer to an IsoReadOpts
412 struct. It holds the options for image reading. You get it with:
413
414 iso_read_opts_new()
415
416 and after calling iso_image_import() you should free it with
417
418 iso_read_opts_free()
419
420 Some options are related to select what extensions to read. Default options
421 are suitable for most users.
422
423 iso_read_opts_set_no_rockridge()
424 iso_read_opts_set_no_joliet()
425 iso_read_opts_set_no_iso1999()
426 iso_read_opts_set_preferjoliet()
427
428 If RockRidge extensions are not present, many files attributes can't be
429 obtained. In those cases libisofs uses default values. You have options to
430 configure what default values to use.
431
432 iso_read_opts_set_default_uid()
433 iso_read_opts_set_default_gid()
434 iso_read_opts_set_default_permissions()
435
436 If the original image has been created in another system with a different
437 charset, you may want to use:
438
439 iso_read_opts_set_input_charset()
440
441 to specify the encoding of the file names on image.
442
443 Finally, to import multisession images, you should tell libisofs that it must
444 read the last session. For that, you must set the block where the last session
445 starts:
446
447 iso_read_opts_set_start_block()
448
449 The last parameter for iso_image_import(), optional, is a pointer that will
450 be filled with a library-allocated IsoReadImageFeatures, that lets you access
451 some information about the image: size, extensions used,...
452
453 [TODO: explain that iso_image_import uses dir rec options]
454
455 -------------------------------------------------------------------------------
456 3.3 Generating a new image
457
458 After importing the image, the old image tree gets loaded. You are free to
459 make any changes to it: add new files, remove files, change names or
460 attributes... Refer to "2.1 Image tree manipulation" for details.
461
462 When it is ready, you can now create the new image. The process is the same as
463 explained in "2.2 Set the write options" and "2.3 Obtaining a burn_source".
464 However, there are some write options that should be taken into account.
465
466 First of all, you must select whether you want to grow or modify the image
467 (read "3.1 Growing vs Modification" for details). You must call
468
469 iso_write_opts_set_appendable()
470
471 An appendable image leads to image growing, and a non-appendable image leads
472 to a completelly new image (modification). An appendable image will be appended
473 after the old image (in a new session, for example). Thus, in those cases, the
474 first block of the image is not 0. You should set the correct lba of the first
475 block with:
476
477 iso_write_opts_set_ms_block()
478
479 That is usually the "Next Writable Address" on a multisession media, and a
480 value slightly greater than the old image size on .iso files or DVD+RW media.
481 You can obtain the old image size with the iso_read_image_features_get_size()
482 function.
483
484 In this last case (i.e., on a non multisession media), you will need to
485 overwrite the volume descriptors of the old image with the new ones. To do
486 this you need:
487
488 - Allocate a buffer of at least 64 KiBs.
489 - Initialize it with the first 64 KiBs of the original image.
490 - Pass the buffer to libisofs with the iso_write_opts_set_overwrite_buf()
491 option.
492 - After appending the new image, you have to overwrite the first 64 KiBs of
493 the original image with the new content of the buffer.
494
495
496 -------------------------------------------------------------------------------
497 4. Bootable images
498 -------------------------------------------------------------------------------
499
500
501
502 -------------------------------------------------------------------------------
503 5. Advanced features
504 -------------------------------------------------------------------------------
505
506