"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