"Fossies" - the Fresh Open Source Software Archive

Member "libisofs-1.5.4/demo/demo.c" (8 Jul 2020, 26740 Bytes) of package /linux/misc/libisofs-1.5.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "demo.c": 1.4.4_vs_1.4.6.

    1 
    2 /*
    3  * Copyright (c) 2007 - 2016 Vreixo Formoso, 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 
   11 static char helptext[][80] = {
   12 "",
   13 "This is a collection of libisofs gestures which formerly were distinct",
   14 "programs. The first argument chooses the gesture:",
   15 "  -tree  absolute_directory_path",
   16 "               Import a directory and print the resulting iso tree.",
   17 "  -find  absolute_directory_path",      
   18 "               Import a directory, find matching nodes and print the",
   19 "               resulting iso tree.",
   20 "  -iso  [options] directory output_file",
   21 "               Create an iso image from a local directory. For options see",
   22 "               output of -iso -h",
   23 "  -iso_read  image_file",
   24 "               Output the contents of an iso image.",
   25 "  -iso_cat  image_file path_in_image",
   26 "               Extract a file from a given ISO image and put out its content",
   27 "               to stdout. The file is addressed by path_in_image. The ISO",
   28 "               image does not get loaded but rather the lookups are done",
   29 "               directly in the image file.",
   30 "  -iso_modify  image_file absolute_directory_path output_file",
   31 "               Load an iso image, add a directory, and write complete image.",
   32 "  -iso_ms  image_lba nwa image_file directory_path output_file",
   33 "               Load an iso image, add a directory, and write as add-on",
   34 "               session which shall be appended to the old image.",
   35 "               image_lba gives the block address of the start of the most",
   36 "               recent session in the image_file. nwa gives the block address",
   37 "               where the add-on session will be appended to the image.",
   38 "@"
   39 };
   40 
   41 
   42 #define LIBISOFS_WITHOUT_LIBBURN yes
   43 #include "libisofs.h"
   44 
   45 #include <stdio.h>
   46 #include <stdlib.h>
   47 #include <string.h>
   48 #include <sys/types.h>
   49 #include <sys/stat.h>
   50 #include <unistd.h>
   51 #include <getopt.h>
   52 #include <fcntl.h>
   53 #include <err.h>
   54 #include <limits.h>
   55 #include <errno.h>
   56 
   57 
   58 #ifndef PATH_MAX
   59 #define PATH_MAX Libisofs_default_path_maX
   60 #endif
   61 
   62 
   63 /* ----------------------------- utilities -------------------------- */
   64 
   65 
   66 void demo_report_iso_err(int err, char *occasion)
   67 {
   68     char *severity;
   69 
   70     fprintf(stderr, "%s : err = 0x%X", occasion, (unsigned int) err);
   71     if (err < 0) {
   72         iso_sev_to_text(iso_error_get_severity(err), &severity);
   73         fprintf(stderr, " -> %s '%s'", severity, iso_error_to_msg(err));
   74     }
   75     fprintf(stderr, "\n");
   76 }
   77 
   78 
   79 /* ------------------------- from demo/tree.c ----------------------- */
   80 
   81 static void
   82 print_permissions(mode_t mode)
   83 {
   84     char perm[10];
   85     
   86     /* TODO suid, sticky... */
   87     
   88     perm[9] = '\0';
   89     perm[8] = mode & S_IXOTH ? 'x' : '-';
   90     perm[7] = mode & S_IWOTH ? 'w' : '-';
   91     perm[6] = mode & S_IROTH ? 'r' : '-';
   92     perm[5] = mode & S_IXGRP ? 'x' : '-';
   93     perm[4] = mode & S_IWGRP ? 'w' : '-';
   94     perm[3] = mode & S_IRGRP ? 'r' : '-';
   95     perm[2] = mode & S_IXUSR ? 'x' : '-';
   96     perm[1] = mode & S_IWUSR ? 'w' : '-';
   97     perm[0] = mode & S_IRUSR ? 'r' : '-';
   98     printf("[%s]",perm);
   99 }
  100 
  101 static void 
  102 tree_print_dir(IsoDir *dir, int level) 
  103 {
  104     int i;
  105     IsoDirIter *iter;
  106     IsoNode *node;
  107     char *sp;
  108 
  109     sp = calloc(1, level * 2 + 1);
  110     
  111     for (i = 0; i < level * 2; i += 2) {
  112         sp[i] = '|';
  113         sp[i+1] = ' ';
  114     }
  115     
  116     if (level > 0)
  117         sp[level * 2 - 1] = '-';
  118     sp[level * 2] = '\0';
  119     
  120     iso_dir_get_children(dir, &iter);
  121     while (iso_dir_iter_next(iter, &node) == 1) {
  122         
  123         if (ISO_NODE_IS_DIR(node)) {
  124             printf("%s+[D] ", sp);
  125             print_permissions(iso_node_get_permissions(node));
  126             printf(" %s\n", iso_node_get_name(node));
  127             tree_print_dir(ISO_DIR(node), level+1);
  128         } else if (ISO_NODE_IS_FILE(node)) {
  129             printf("%s-[F] ", sp);
  130             print_permissions(iso_node_get_permissions(node));
  131             printf(" %s\n", iso_node_get_name(node) );
  132         } else if (ISO_NODE_IS_SYMLINK(node)) {
  133             printf("%s-[L] ", sp);
  134             print_permissions(iso_node_get_permissions(node));
  135             printf(" %s -> %s \n", iso_node_get_name(node),
  136                    iso_symlink_get_dest(ISO_SYMLINK(node)) );
  137         } else {
  138             printf("%s-[C] ", sp);
  139             print_permissions(iso_node_get_permissions(node));
  140             printf(" %s\n", iso_node_get_name(node) );
  141         } 
  142     }
  143     iso_dir_iter_free(iter);
  144     free(sp);
  145 }
  146 
  147 int gesture_tree(int argc, char **argv)
  148 {
  149     int result;
  150     IsoImage *image;
  151     
  152     if (argc != 2) {
  153 need_abs_path:;
  154         fprintf (stderr, "You need to specify a valid absolute path\n");
  155         return 1;
  156     }
  157     if (argv[1][0] != '/')
  158         goto need_abs_path;
  159 
  160     iso_init();
  161     iso_set_msgs_severities("NEVER", "ALL", "");
  162     
  163     result = iso_image_new("volume_id", &image);
  164     if (result < 0) {
  165         printf ("Error creating image\n");
  166         return 1;
  167     }
  168     
  169     result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]);
  170     if (result < 0) {
  171         printf ("Error adding directory %d\n", result);
  172         return 1;
  173     }
  174     
  175     printf("================= IMAGE =================\n");
  176     tree_print_dir(iso_image_get_root(image), 0);
  177     printf("\n\n");
  178     
  179     iso_image_unref(image);
  180     iso_finish();
  181     return 0;
  182 }
  183 
  184 
  185 /* ------------------------- from demo/find.c ----------------------- */
  186 
  187 static void 
  188 find_print_dir(IsoDir *dir) 
  189 {
  190     IsoDirIter *iter;
  191     IsoNode *node;
  192     IsoFindCondition *cond, *c1, *c2;
  193     
  194     c1 = iso_new_find_conditions_name("*a*");
  195     c2 = iso_new_find_conditions_mode(S_IFREG);
  196     cond = iso_new_find_conditions_and(c1, c2);
  197     iso_dir_find_children(dir, cond, &iter);
  198     while (iso_dir_iter_next(iter, &node) == 1) {
  199         char *path = iso_tree_get_node_path(node);
  200         printf(" %s\n", path);
  201         free(path);
  202     }
  203     iso_dir_iter_free(iter);
  204 }
  205 
  206 int gesture_find(int argc, char **argv)
  207 {
  208     int result;
  209     IsoImage *image;
  210     
  211     if (argc != 2) {
  212 need_abs_path:;
  213         fprintf (stderr, "You need to specify a valid absolute path\n");
  214         return 1;
  215     }
  216     if (argv[1][0] != '/')
  217         goto need_abs_path;
  218 
  219     iso_init();
  220     iso_set_msgs_severities("NEVER", "ALL", "");
  221     
  222     result = iso_image_new("volume_id", &image);
  223     if (result < 0) {
  224         printf ("Error creating image\n");
  225         return 1;
  226     }
  227     
  228     result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]);
  229     if (result < 0) {
  230         printf ("Error adding directory %d\n", result);
  231         return 1;
  232     }
  233     
  234     find_print_dir(iso_image_get_root(image));
  235     
  236     iso_image_unref(image);
  237     iso_finish();
  238     return 0;
  239 }
  240 
  241 
  242 /* ------------------------- from demo/iso.c ----------------------- */
  243 
  244 
  245 static const char * const optstring = "JRIL:b:hV:";
  246 extern char *optarg;
  247 extern int optind;
  248 
  249 void iso_usage(char **argv)
  250 {
  251     printf("%s [OPTIONS] DIRECTORY OUTPUT\n", argv[0]);
  252 }
  253 
  254 void iso_help()
  255 {
  256     printf(
  257         "Options:\n"
  258         "  -J        Add Joliet support\n"
  259         "  -R        Add Rock Ridge support\n"
  260         "  -I        Add ISO 9660:1999 support\n"
  261         "  -V label  Volume Label\n"
  262         "  -L <num>  Set the ISO level (1 or 2)\n"
  263         "  -b file   Specifies a boot image to add to image\n"
  264         "  -h        Print this message\n"
  265     );
  266 }
  267 
  268 int iso_callback(IsoFileSource *src)
  269 {
  270     char *path = iso_file_source_get_path(src);
  271     printf("CALLBACK: %s\n", path);
  272     free(path);
  273     return 1;
  274 }
  275 
  276 int gesture_iso(int argc, char **argv)
  277 {
  278     int result;
  279     int c;
  280     IsoImage *image;
  281     struct burn_source *burn_src;
  282     unsigned char buf[2048];
  283     FILE *fp = NULL;
  284     IsoWriteOpts *opts;
  285     char *volid = "VOLID";
  286     char *boot_img = NULL;
  287     int rr = 0, j = 0, iso1999 = 0, level = 1;
  288 
  289     while ((c = getopt(argc, argv, optstring)) != -1) {
  290         switch(c) {
  291         case 'h':
  292             iso_usage(argv);
  293             iso_help();
  294             goto ex;
  295             break;
  296         case 'J':
  297             j = 1;
  298             break;
  299         case 'R':
  300             rr = 1;
  301             break;
  302         case 'I':
  303             iso1999 = 1;
  304             break;
  305         case 'L':
  306             level = atoi(optarg);
  307             break;
  308         case 'b':
  309             boot_img = optarg;
  310             break;
  311         case 'V':
  312             volid = optarg;
  313             break;
  314         case '?':
  315             iso_usage(argv);
  316             goto ex;
  317             break;
  318         }
  319     }
  320 
  321     if (argc < 2) {
  322         printf ("Please pass directory from which to build ISO\n");
  323         iso_usage(argv);
  324         goto ex;
  325     }
  326     if (argc < 3) {
  327         printf ("Please supply output file\n");
  328         iso_usage(argv);
  329         goto ex;
  330     }
  331 
  332     fp = fopen(argv[optind+1], "w");
  333     if (fp == NULL) {
  334         err(1, "error opening output file");
  335         goto ex;
  336     }
  337 
  338     result = iso_init();
  339     if (result < 0) {
  340         printf ("Can't initialize libisofs\n");
  341         goto ex;
  342     }
  343     iso_set_msgs_severities("NEVER", "ALL", "");
  344 
  345     result = iso_image_new(volid, &image);
  346     if (result < 0) {
  347         printf ("Error creating image\n");
  348         goto ex;
  349     }
  350     iso_tree_set_follow_symlinks(image, 0);
  351     iso_tree_set_ignore_hidden(image, 0);
  352     iso_tree_set_ignore_special(image, 0);
  353     iso_set_abort_severity("SORRY");
  354     /*iso_tree_set_report_callback(image, callback);*/
  355 
  356     result = iso_tree_add_dir_rec(image, iso_image_get_root(image),
  357                                   argv[optind]);
  358     if (result < 0) {
  359         printf ("Error adding directory %d\n", result);
  360         goto ex;
  361     }
  362 
  363     if (boot_img) {
  364         /* adds El-Torito boot info. Tunned for isolinux */
  365         ElToritoBootImage *bootimg;
  366         result = iso_image_set_boot_image(image, boot_img, ELTORITO_NO_EMUL,
  367                                      "/isolinux/boot.cat", &bootimg);
  368         if (result < 0) {
  369             printf ("Error adding boot image %d\n", result);
  370             goto ex;
  371         }
  372         el_torito_set_load_size(bootimg, 4);
  373         el_torito_patch_isolinux_image(bootimg);
  374     }
  375 
  376     result = iso_write_opts_new(&opts, 0);
  377     if (result < 0) {
  378         printf ("Cannot create write opts, error %d\n", result);
  379         goto ex;
  380     }
  381     iso_write_opts_set_iso_level(opts, level);
  382     iso_write_opts_set_rockridge(opts, rr);
  383     iso_write_opts_set_joliet(opts, j);
  384     iso_write_opts_set_iso1999(opts, iso1999);
  385 
  386     result = iso_image_create_burn_source(image, opts, &burn_src);
  387     if (result < 0) {
  388         printf ("Cannot create image, error %d\n", result);
  389         goto ex;
  390     }
  391 
  392     iso_write_opts_free(opts);
  393 
  394     while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
  395         result = fwrite(buf, 1, 2048, fp);
  396         if (result < 2048) {
  397             printf ("Cannot write block. errno= %d\n", errno);
  398             goto ex;
  399         }
  400     }
  401     fclose(fp);
  402     burn_src->free_data(burn_src);
  403     free(burn_src);
  404 
  405     iso_image_unref(image);
  406     iso_finish();
  407     return 0;
  408 ex:;
  409     if (fp != NULL)
  410       fclose(fp);
  411     return 1;
  412 }
  413 
  414 
  415 /* ------------------------- from demo/iso_read.c ----------------------- */
  416 
  417 
  418 static void
  419 iso_read_print_type(mode_t mode)
  420 {
  421     switch(mode & S_IFMT) {
  422     case S_IFSOCK: printf("[S] "); break;
  423     case S_IFLNK: printf("[L] "); break;
  424     case S_IFREG: printf("[R] "); break;
  425     case S_IFBLK: printf("[B] "); break;
  426     case S_IFDIR: printf("[D] "); break;
  427     case S_IFIFO: printf("[F] "); break;
  428     }
  429 }
  430 
  431 static void
  432 iso_read_print_file_src(IsoFileSource *file)
  433 {
  434     struct stat info;
  435     char *name;
  436     iso_file_source_lstat(file, &info);
  437     iso_read_print_type(info.st_mode);
  438     print_permissions(info.st_mode);
  439     printf(" %10.f ", (double) info.st_size);
  440     /* printf(" {%ld,%ld} ", (long)info.st_dev, (long)info.st_ino); */
  441     name = iso_file_source_get_name(file);
  442     printf(" %s", name);
  443     free(name);
  444     if (S_ISLNK(info.st_mode)) {
  445         char buf[PATH_MAX];
  446         iso_file_source_readlink(file, buf, PATH_MAX);
  447         printf(" -> %s\n", buf);
  448     }
  449     printf("\n");
  450 }
  451 
  452 static void
  453 iso_read_print_dir(IsoFileSource *dir, int level)
  454 {
  455     int ret, i;
  456     IsoFileSource *file;
  457     struct stat info;
  458     char *sp;
  459 
  460     sp = calloc(1, level * 2 + 1);
  461 
  462     for (i = 0; i < level * 2; i += 2) {
  463         sp[i] = '|';
  464         sp[i+1] = ' ';
  465     }
  466 
  467     if (level > 0)
  468         sp[level * 2 - 1] = '-';
  469     sp[level * 2] = '\0';
  470 
  471     ret = iso_file_source_open(dir);
  472     if (ret < 0) {
  473         printf ("Can't open dir %d\n", ret);
  474     }
  475     while ((ret = iso_file_source_readdir(dir, &file)) == 1) {
  476         printf("%s", sp);
  477         iso_read_print_file_src(file);
  478         ret = iso_file_source_lstat(file, &info);
  479         if (ret < 0) {
  480             break;
  481         }
  482         if (S_ISDIR(info.st_mode)) {
  483             iso_read_print_dir(file, level + 1);
  484         }
  485         iso_file_source_unref(file);
  486     }
  487     iso_file_source_close(dir);
  488     if (ret < 0) {
  489         printf ("Can't print dir\n");
  490     }
  491     free(sp);
  492 }
  493 
  494 int gesture_iso_read(int argc, char **argv)
  495 {
  496     int result, initialized = 0, return_val = 1;
  497     IsoImageFilesystem *fs = NULL;
  498     IsoDataSource *src = NULL;
  499     IsoFileSource *root = NULL;
  500     IsoReadOpts *ropts = NULL;
  501 
  502     if (argc != 2) {
  503         printf ("You need to specify a valid path\n");
  504         goto ex;
  505     }
  506 
  507     result = iso_init();
  508     if (result < 0) {
  509         demo_report_iso_err(result, "Cannot init libisofs");
  510         goto ex;
  511     }
  512     initialized = 1;
  513 
  514     iso_set_msgs_severities("NEVER", "ALL", "");
  515 
  516     result = iso_data_source_new_from_file(argv[1], &src);
  517     if (result < 0) {
  518         demo_report_iso_err(result, "Error creating data source");
  519         goto ex;
  520     }
  521     result = iso_read_opts_new(&ropts, 0);
  522     if (result < 0) {
  523         demo_report_iso_err(result, "Error creating read options");
  524         goto ex;
  525     }
  526     result = iso_image_filesystem_new(src, ropts, 1, &fs);
  527     if (result < 0) {
  528         demo_report_iso_err(result, "Error creating filesystem");
  529         goto ex;
  530     }
  531     iso_read_opts_free(ropts);
  532     ropts = NULL;
  533 
  534     printf("\nVOLUME INFORMATION\n");
  535     printf("==================\n\n");
  536 
  537     printf("Vol. id: %s\n", iso_image_fs_get_volume_id(fs));
  538     printf("Publisher: %s\n", iso_image_fs_get_publisher_id(fs));
  539     printf("Data preparer: %s\n", iso_image_fs_get_data_preparer_id(fs));
  540     printf("System: %s\n", iso_image_fs_get_system_id(fs));
  541     printf("Application: %s\n", iso_image_fs_get_application_id(fs));
  542     printf("Copyright: %s\n", iso_image_fs_get_copyright_file_id(fs));
  543     printf("Abstract: %s\n", iso_image_fs_get_abstract_file_id(fs));
  544     printf("Biblio: %s\n", iso_image_fs_get_biblio_file_id(fs));
  545 
  546     printf("\nDIRECTORY TREE\n");
  547     printf("==============\n");
  548 
  549     result = fs->get_root(fs, &root);
  550     if (result < 0) {
  551         demo_report_iso_err(result, "Cannot get root object");
  552         goto ex;
  553     }
  554     /* iso_read_print_file_src(root); */
  555     iso_read_print_dir(root, 0);
  556 
  557     return_val = 0;
  558 ex:;
  559     if (root != NULL)
  560         iso_file_source_unref(root);
  561     if (ropts != NULL)
  562         iso_read_opts_free(ropts);
  563     if (fs != NULL) {
  564         fs->close(fs);
  565         iso_filesystem_unref((IsoFilesystem*)fs);
  566     }
  567     if (src != NULL)
  568         iso_data_source_unref(src);
  569     if (initialized)
  570         iso_finish();
  571     return return_val;
  572 }
  573 
  574 
  575 /* ------------------------- from demo/iso_cat.c ----------------------- */
  576 
  577 
  578 int gesture_iso_cat(int argc, char **argv)
  579 {
  580     int res, write_ret, ret;
  581     IsoFilesystem *fs = NULL;
  582     IsoFileSource *file = NULL;
  583     struct stat info;
  584     IsoDataSource *src = NULL;
  585     IsoReadOpts *opts = NULL;
  586 
  587     if (argc != 3) {
  588         fprintf(stderr, "Usage: -iso_cat /path/to/image /path/to/file\n");
  589         return 1;
  590     }
  591 
  592     res = iso_init();
  593     if (res < 0) {
  594         demo_report_iso_err(res, "Cannot init libisofs");
  595         return 1;
  596     }
  597 
  598     /* Important Note:
  599        From here on memory objects get created which need to be freed in
  600        the end. Therefore in case of problems no direct return, but rather
  601        a hop to label "ex:", where cleanup happens.
  602      */
  603 
  604     res = iso_data_source_new_from_file(argv[1], &src);
  605     if (res < 0) {
  606         demo_report_iso_err(res, "Error creating data source object");
  607         ret = 1; goto ex;
  608     }
  609 
  610     res = iso_read_opts_new(&opts, 0);
  611     if (res < 0) {
  612         demo_report_iso_err(res, "Error creating read options object");
  613         ret = 1; goto ex;
  614     }
  615     res = iso_image_filesystem_new(src, opts, 1, &fs);
  616     if (res < 0) {
  617         demo_report_iso_err(res, "Error creating filesystem object");
  618         ret = 1; goto ex;
  619     }
  620     iso_read_opts_free(opts);
  621     opts = NULL;
  622 
  623     res = fs->get_by_path(fs, argv[2], &file);
  624     if (res < 0) {
  625         demo_report_iso_err(res, "Cannot get file object with given path");
  626         ret = 1; goto ex;
  627     }
  628 
  629     res = iso_file_source_lstat(file, &info);
  630     if (res < 0) {
  631         demo_report_iso_err(res,
  632                          "Cannot inquire type of file object with given path");
  633         ret = 1; goto ex;
  634     }
  635 
  636     if (S_ISDIR(info.st_mode)) {
  637         fprintf(stderr, "Path refers to a directory!!\n");
  638         ret = 1; goto ex;
  639     } else {
  640         char buf[1024];
  641         res = iso_file_source_open(file);
  642         if (res < 0) {
  643             demo_report_iso_err(res,
  644                                 "Cannot open file object with given path");
  645             ret = 1; goto ex;
  646         }
  647         while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
  648             write_ret = fwrite(buf, 1, res, stdout);
  649             if (write_ret < res) {
  650                 printf ("Cannot write block to stdout. errno= %d\n", errno);
  651                 iso_file_source_close(file);
  652                 ret = 1; goto ex;
  653             }
  654         }
  655         iso_file_source_close(file);
  656         if (res < 0) {
  657             demo_report_iso_err(res, "Error while reading data content");
  658             fprintf(stderr, "Error reading, err = 0x%X\n", (unsigned int) res);
  659             ret = 1; goto ex;
  660         }
  661     }
  662 
  663     ret = 0;
  664 ex:;
  665     if (file != NULL)
  666         iso_file_source_unref(file);
  667     if (fs != NULL)
  668         iso_filesystem_unref(fs);
  669     if (opts != NULL)
  670         iso_read_opts_free(opts);
  671     if (src != NULL)
  672         iso_data_source_unref(src);
  673     iso_finish();
  674     return ret;
  675 }
  676 
  677 
  678 /* ------------------------- from demo/iso_modify.c ----------------------- */
  679 
  680 
  681 void iso_modify_usage(char **argv)
  682 {
  683     printf("%s IMAGE DIRECTORY OUTPUT\n", argv[0]);
  684 }
  685 
  686 int gesture_iso_modify(int argc, char **argv)
  687 {
  688     int result, return_val = 1, initialized = 0;
  689     IsoImage *image = NULL;
  690     IsoDataSource *src = NULL;
  691     struct burn_source *burn_src = NULL;
  692     unsigned char buf[2048];
  693     FILE *fp = NULL;
  694     IsoWriteOpts *opts = NULL;
  695     IsoReadOpts *ropts = NULL;
  696     
  697     if (argc < 4) {
  698         iso_modify_usage(argv);
  699         goto ex;
  700     }
  701     
  702     fp = fopen(argv[3], "w");
  703     if (fp == NULL) {
  704         err(1, "error opening output file");
  705         goto ex;
  706     }
  707 
  708     result = iso_init();
  709     if (result < 0) {
  710         demo_report_iso_err(result, "Cannot init libisofs");
  711         goto ex;
  712     }
  713     initialized = 1;
  714     iso_set_msgs_severities("NEVER", "ALL", "");
  715     
  716     /* create the data source to accesss previous image */
  717     result = iso_data_source_new_from_file(argv[1], &src);
  718     if (result < 0) {
  719         demo_report_iso_err(result, "Error creating data source");
  720         goto ex;
  721     }
  722     
  723     /* create the image context */
  724     result = iso_image_new("volume_id", &image);
  725     if (result < 0) {
  726         demo_report_iso_err(result, "Error creating image");
  727         goto ex;
  728     }
  729     iso_tree_set_follow_symlinks(image, 0);
  730     iso_tree_set_ignore_hidden(image, 0);
  731     
  732     /* import previous image */
  733     result = iso_read_opts_new(&ropts, 0);
  734     if (result < 0) {
  735         demo_report_iso_err(result, "Error creating read options");
  736         goto ex;
  737     }
  738     result = iso_image_import(image, src, ropts, NULL);
  739     if (result < 0) {
  740         demo_report_iso_err(result, "Error importing previous session");
  741         goto ex;
  742     }
  743     /* (One could of course keep them alive until cleanup) */
  744     iso_read_opts_free(ropts);
  745     ropts = NULL;
  746     iso_data_source_unref(src);
  747     src = NULL;
  748     
  749     /* add new dir */
  750     result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
  751     if (result < 0) {
  752         demo_report_iso_err(result, "Error adding directory");
  753         goto ex;
  754     }
  755     
  756     /* Generate a new image with both previous and added contents.
  757        Profile 1 means Rock Ridge and ISO level 3.
  758     */
  759     result = iso_write_opts_new(&opts, 1);
  760     if (result < 0) {
  761         demo_report_iso_err(result, "Cannot create write opts");
  762         goto ex;
  763     }
  764     /* Prefer specs violation over relocation deep directories */
  765     iso_write_opts_set_allow_deep_paths(opts, 1);
  766 
  767     /* For MS-Windows readers : iso_write_opts_set_joliet(opts, 1); */
  768  
  769     result = iso_image_create_burn_source(image, opts, &burn_src);
  770     if (result < 0) {
  771         demo_report_iso_err(result, "Cannot create image object");
  772         goto ex;
  773     }
  774     iso_write_opts_free(opts);
  775     opts = NULL;
  776     
  777     while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
  778         result = fwrite(buf, 1, 2048, fp);
  779         if (result < 2048) {
  780             fprintf (stderr, "Cannot write block. errno= %d\n", errno);
  781             goto ex;
  782         }
  783     }
  784 
  785     return_val = 0;
  786 ex:
  787     if (fp != NULL)
  788         fclose(fp);
  789     if (opts != NULL)
  790         iso_write_opts_free(opts);
  791     if (burn_src != NULL) {
  792         burn_src->free_data(burn_src);
  793         free(burn_src);
  794     }
  795     if (image != NULL)
  796         iso_image_unref(image);
  797     if (ropts != NULL)
  798         iso_read_opts_free(ropts);
  799     if (src != NULL)
  800         iso_data_source_unref(src);
  801     if (initialized)
  802         iso_finish();
  803     return return_val;
  804 }
  805 
  806 
  807 /* ------------------------- from demo/iso_ms.c ----------------------- */
  808 
  809 
  810 void iso_ms_usage(char **argv)
  811 {
  812     printf("%s LSS NWA DISC DIRECTORY OUTPUT\n", argv[0]);
  813 }
  814 
  815 int gesture_iso_ms(int argc, char **argv)
  816 {
  817     int result, return_val = 1, initialized = 0;
  818     IsoImage *image = NULL;
  819     IsoDataSource *src = NULL;
  820     struct burn_source *burn_src = NULL;
  821     unsigned char buf[2048];
  822     FILE *fp = NULL;
  823     IsoWriteOpts *opts = NULL;
  824     IsoReadOpts *ropts = NULL;
  825     uint32_t ms_block;
  826     
  827     if (argc < 6) {
  828         iso_ms_usage(argv);
  829         goto ex;
  830     }
  831 
  832     if (strcmp(argv[3], argv[5]) == 0) {
  833         fprintf(stderr,
  834                 "image_file and output_file must not be the same file.\n");
  835         goto ex;
  836     }
  837 
  838     fp = fopen(argv[5], "w");
  839     if (!fp) {
  840         err(1, "error opening output file");
  841         goto ex;
  842     }
  843 
  844     result = iso_init();
  845     if (result < 0) {
  846         demo_report_iso_err(result, "Cannot init libisofs");
  847         goto ex;
  848     }
  849     initialized = 1;
  850 
  851     iso_set_msgs_severities("NEVER", "ALL", "");
  852     
  853     /* create the data source to accesss previous image */
  854     result = iso_data_source_new_from_file(argv[3], &src);
  855     if (result < 0) {
  856         demo_report_iso_err(result, "Error creating data source");
  857         goto ex;
  858     }
  859     
  860     /* create the image context */
  861     result = iso_image_new("volume_id", &image);
  862     if (result < 0) {
  863         demo_report_iso_err(result, "Error creating image");
  864         goto ex;
  865     }
  866     iso_tree_set_follow_symlinks(image, 0);
  867     iso_tree_set_ignore_hidden(image, 0);
  868     
  869     /* import previous image */
  870     result = iso_read_opts_new(&ropts, 0);
  871     if (result < 0) {
  872         fprintf(stderr, "Error creating read options\n");
  873         goto ex;
  874     }
  875     iso_read_opts_set_start_block(ropts, atoi(argv[1]));
  876     result = iso_image_import(image, src, ropts, NULL);
  877     iso_read_opts_free(ropts);
  878     ropts = NULL;
  879     iso_data_source_unref(src);
  880     src = NULL;
  881     if (result < 0) {
  882         demo_report_iso_err(result, "Error importing previous session");
  883         goto ex;
  884     }
  885     
  886     /* add new dir */
  887     result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
  888     if (result < 0) {
  889         demo_report_iso_err(result, "Error adding directory");
  890         goto ex;
  891     }
  892     
  893     /* generate a multisession image with new contents */
  894     result = iso_write_opts_new(&opts, 1);
  895     if (result < 0) {
  896         demo_report_iso_err(result, "Cannot create write opts");
  897         goto ex;
  898     }
  899     
  900     /* round up to 32kb aligment = 16 block */
  901     ms_block =  atoi(argv[2]);
  902     iso_write_opts_set_ms_block(opts, ms_block);
  903     iso_write_opts_set_appendable(opts, 1);
  904 
  905     result = iso_image_create_burn_source(image, opts, &burn_src);
  906     if (result < 0) {
  907         printf ("Cannot create image, error %d\n", result);
  908         goto ex;
  909     }
  910     iso_write_opts_free(opts);
  911     opts = NULL;
  912     
  913     while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
  914         result = fwrite(buf, 1, 2048, fp);
  915         if (result < 2048) {
  916             printf ("Cannot write block. errno= %d\n", errno);
  917             goto ex;
  918         }
  919     }
  920 
  921     return_val = 0;
  922 ex:;
  923     if (burn_src != NULL) {
  924         burn_src->free_data(burn_src);
  925         free(burn_src);
  926     }
  927     if (opts != NULL)
  928         iso_write_opts_free(opts);
  929     if (image)
  930         iso_image_unref(image);
  931     if (ropts != NULL)
  932         iso_read_opts_free(ropts);
  933     if (src != NULL)
  934         iso_data_source_unref(src);
  935     if (initialized)
  936         iso_finish();
  937     if (fp != NULL)
  938         fclose(fp);
  939     return return_val;
  940 }
  941 
  942 
  943 /* ------------------------- switcher ----------------------- */
  944 
  945 
  946 int main(int argc, char **argv)
  947 {
  948     char *gesture;
  949     int i;
  950 
  951     if (argc < 2) {
  952 usage:;
  953         fprintf(stderr, "usage: %s gesture [gesture_options]\n", argv[0]);
  954         for (i = 0; helptext[i][0] != '@'; i++)
  955              fprintf(stderr, "%s\n", helptext[i]);
  956         exit(1);
  957     }
  958     for (gesture = argv[1]; *gesture == '-'; gesture++);
  959     if (strcmp(gesture, "tree") == 0) {
  960         gesture_tree(argc - 1, &(argv[1]));
  961     } else if(strcmp(gesture, "find") == 0) {
  962         gesture_find(argc - 1, &(argv[1]));
  963     } else if(strcmp(gesture, "iso") == 0) {
  964         gesture_iso(argc - 1, &(argv[1]));
  965     } else if(strcmp(gesture, "iso_read") == 0) {
  966         gesture_iso_read(argc - 1, &(argv[1]));
  967     } else if(strcmp(gesture, "iso_cat") == 0) {
  968         gesture_iso_cat(argc - 1, &(argv[1]));
  969     } else if(strcmp(gesture, "iso_modify") == 0) {
  970         gesture_iso_modify(argc - 1, &(argv[1]));
  971     } else if(strcmp(gesture, "iso_ms") == 0) {
  972         gesture_iso_ms(argc - 1, &(argv[1]));
  973     } else {
  974         goto usage;
  975     }
  976     exit(0);
  977 }