978 lines
26 KiB
C
978 lines
26 KiB
C
|
|
/*
|
|
* Copyright (c) 2007 - 2016 Vreixo Formoso, Thomas Schmitt
|
|
*
|
|
* This file is part of the libisofs project; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License version 2
|
|
* or later as published by the Free Software Foundation.
|
|
* See COPYING file for details.
|
|
*/
|
|
|
|
static char helptext[][80] = {
|
|
"",
|
|
"This is a collection of libisofs gestures which formerly were distinct",
|
|
"programs. The first argument chooses the gesture:",
|
|
" -tree absolute_directory_path",
|
|
" Import a directory and print the resulting iso tree.",
|
|
" -find absolute_directory_path",
|
|
" Import a directory, find matching nodes and print the",
|
|
" resulting iso tree.",
|
|
" -iso [options] directory output_file",
|
|
" Create an iso image from a local directory. For options see",
|
|
" output of -iso -h",
|
|
" -iso_read image_file",
|
|
" Output the contents of an iso image.",
|
|
" -iso_cat image_file path_in_image",
|
|
" Extract a file from a given ISO image and put out its content",
|
|
" to stdout. The file is addressed by path_in_image. The ISO",
|
|
" image does not get loaded but rather the lookups are done",
|
|
" directly in the image file.",
|
|
" -iso_modify image_file absolute_directory_path output_file",
|
|
" Load an iso image, add a directory, and write complete image.",
|
|
" -iso_ms image_lba nwa image_file directory_path output_file",
|
|
" Load an iso image, add a directory, and write as add-on",
|
|
" session which shall be appended to the old image.",
|
|
" image_lba gives the block address of the start of the most",
|
|
" recent session in the image_file. nwa gives the block address",
|
|
" where the add-on session will be appended to the image.",
|
|
"@"
|
|
};
|
|
|
|
|
|
#define LIBISOFS_WITHOUT_LIBBURN yes
|
|
#include "libisofs.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <getopt.h>
|
|
#include <fcntl.h>
|
|
#include <err.h>
|
|
#include <limits.h>
|
|
#include <errno.h>
|
|
|
|
|
|
#ifndef PATH_MAX
|
|
#define PATH_MAX Libisofs_default_path_maX
|
|
#endif
|
|
|
|
|
|
/* ----------------------------- utilities -------------------------- */
|
|
|
|
|
|
void demo_report_iso_err(int err, char *occasion)
|
|
{
|
|
char *severity;
|
|
|
|
fprintf(stderr, "%s : err = 0x%X", occasion, (unsigned int) err);
|
|
if (err < 0) {
|
|
iso_sev_to_text(iso_error_get_severity(err), &severity);
|
|
fprintf(stderr, " -> %s '%s'", severity, iso_error_to_msg(err));
|
|
}
|
|
fprintf(stderr, "\n");
|
|
}
|
|
|
|
|
|
/* ------------------------- from demo/tree.c ----------------------- */
|
|
|
|
static void
|
|
print_permissions(mode_t mode)
|
|
{
|
|
char perm[10];
|
|
|
|
/* TODO suid, sticky... */
|
|
|
|
perm[9] = '\0';
|
|
perm[8] = mode & S_IXOTH ? 'x' : '-';
|
|
perm[7] = mode & S_IWOTH ? 'w' : '-';
|
|
perm[6] = mode & S_IROTH ? 'r' : '-';
|
|
perm[5] = mode & S_IXGRP ? 'x' : '-';
|
|
perm[4] = mode & S_IWGRP ? 'w' : '-';
|
|
perm[3] = mode & S_IRGRP ? 'r' : '-';
|
|
perm[2] = mode & S_IXUSR ? 'x' : '-';
|
|
perm[1] = mode & S_IWUSR ? 'w' : '-';
|
|
perm[0] = mode & S_IRUSR ? 'r' : '-';
|
|
printf("[%s]",perm);
|
|
}
|
|
|
|
static void
|
|
tree_print_dir(IsoDir *dir, int level)
|
|
{
|
|
int i;
|
|
IsoDirIter *iter;
|
|
IsoNode *node;
|
|
char *sp;
|
|
|
|
sp = calloc(1, level * 2 + 1);
|
|
|
|
for (i = 0; i < level * 2; i += 2) {
|
|
sp[i] = '|';
|
|
sp[i+1] = ' ';
|
|
}
|
|
|
|
if (level > 0)
|
|
sp[level * 2 - 1] = '-';
|
|
sp[level * 2] = '\0';
|
|
|
|
iso_dir_get_children(dir, &iter);
|
|
while (iso_dir_iter_next(iter, &node) == 1) {
|
|
|
|
if (ISO_NODE_IS_DIR(node)) {
|
|
printf("%s+[D] ", sp);
|
|
print_permissions(iso_node_get_permissions(node));
|
|
printf(" %s\n", iso_node_get_name(node));
|
|
tree_print_dir(ISO_DIR(node), level+1);
|
|
} else if (ISO_NODE_IS_FILE(node)) {
|
|
printf("%s-[F] ", sp);
|
|
print_permissions(iso_node_get_permissions(node));
|
|
printf(" %s\n", iso_node_get_name(node) );
|
|
} else if (ISO_NODE_IS_SYMLINK(node)) {
|
|
printf("%s-[L] ", sp);
|
|
print_permissions(iso_node_get_permissions(node));
|
|
printf(" %s -> %s \n", iso_node_get_name(node),
|
|
iso_symlink_get_dest(ISO_SYMLINK(node)) );
|
|
} else {
|
|
printf("%s-[C] ", sp);
|
|
print_permissions(iso_node_get_permissions(node));
|
|
printf(" %s\n", iso_node_get_name(node) );
|
|
}
|
|
}
|
|
iso_dir_iter_free(iter);
|
|
free(sp);
|
|
}
|
|
|
|
int gesture_tree(int argc, char **argv)
|
|
{
|
|
int result;
|
|
IsoImage *image;
|
|
|
|
if (argc != 2) {
|
|
need_abs_path:;
|
|
fprintf (stderr, "You need to specify a valid absolute path\n");
|
|
return 1;
|
|
}
|
|
if (argv[1][0] != '/')
|
|
goto need_abs_path;
|
|
|
|
iso_init();
|
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
|
|
|
result = iso_image_new("volume_id", &image);
|
|
if (result < 0) {
|
|
printf ("Error creating image\n");
|
|
return 1;
|
|
}
|
|
|
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]);
|
|
if (result < 0) {
|
|
printf ("Error adding directory %d\n", result);
|
|
return 1;
|
|
}
|
|
|
|
printf("================= IMAGE =================\n");
|
|
tree_print_dir(iso_image_get_root(image), 0);
|
|
printf("\n\n");
|
|
|
|
iso_image_unref(image);
|
|
iso_finish();
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* ------------------------- from demo/find.c ----------------------- */
|
|
|
|
static void
|
|
find_print_dir(IsoDir *dir)
|
|
{
|
|
IsoDirIter *iter;
|
|
IsoNode *node;
|
|
IsoFindCondition *cond, *c1, *c2;
|
|
|
|
c1 = iso_new_find_conditions_name("*a*");
|
|
c2 = iso_new_find_conditions_mode(S_IFREG);
|
|
cond = iso_new_find_conditions_and(c1, c2);
|
|
iso_dir_find_children(dir, cond, &iter);
|
|
while (iso_dir_iter_next(iter, &node) == 1) {
|
|
char *path = iso_tree_get_node_path(node);
|
|
printf(" %s\n", path);
|
|
free(path);
|
|
}
|
|
iso_dir_iter_free(iter);
|
|
}
|
|
|
|
int gesture_find(int argc, char **argv)
|
|
{
|
|
int result;
|
|
IsoImage *image;
|
|
|
|
if (argc != 2) {
|
|
need_abs_path:;
|
|
fprintf (stderr, "You need to specify a valid absolute path\n");
|
|
return 1;
|
|
}
|
|
if (argv[1][0] != '/')
|
|
goto need_abs_path;
|
|
|
|
iso_init();
|
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
|
|
|
result = iso_image_new("volume_id", &image);
|
|
if (result < 0) {
|
|
printf ("Error creating image\n");
|
|
return 1;
|
|
}
|
|
|
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]);
|
|
if (result < 0) {
|
|
printf ("Error adding directory %d\n", result);
|
|
return 1;
|
|
}
|
|
|
|
find_print_dir(iso_image_get_root(image));
|
|
|
|
iso_image_unref(image);
|
|
iso_finish();
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* ------------------------- from demo/iso.c ----------------------- */
|
|
|
|
|
|
static const char * const optstring = "JRIL:b:hV:";
|
|
extern char *optarg;
|
|
extern int optind;
|
|
|
|
void iso_usage(char **argv)
|
|
{
|
|
printf("%s [OPTIONS] DIRECTORY OUTPUT\n", argv[0]);
|
|
}
|
|
|
|
void iso_help()
|
|
{
|
|
printf(
|
|
"Options:\n"
|
|
" -J Add Joliet support\n"
|
|
" -R Add Rock Ridge support\n"
|
|
" -I Add ISO 9660:1999 support\n"
|
|
" -V label Volume Label\n"
|
|
" -L <num> Set the ISO level (1 or 2)\n"
|
|
" -b file Specifies a boot image to add to image\n"
|
|
" -h Print this message\n"
|
|
);
|
|
}
|
|
|
|
int iso_callback(IsoFileSource *src)
|
|
{
|
|
char *path = iso_file_source_get_path(src);
|
|
printf("CALLBACK: %s\n", path);
|
|
free(path);
|
|
return 1;
|
|
}
|
|
|
|
int gesture_iso(int argc, char **argv)
|
|
{
|
|
int result;
|
|
int c;
|
|
IsoImage *image;
|
|
struct burn_source *burn_src;
|
|
unsigned char buf[2048];
|
|
FILE *fp = NULL;
|
|
IsoWriteOpts *opts;
|
|
char *volid = "VOLID";
|
|
char *boot_img = NULL;
|
|
int rr = 0, j = 0, iso1999 = 0, level = 1;
|
|
|
|
while ((c = getopt(argc, argv, optstring)) != -1) {
|
|
switch(c) {
|
|
case 'h':
|
|
iso_usage(argv);
|
|
iso_help();
|
|
goto ex;
|
|
break;
|
|
case 'J':
|
|
j = 1;
|
|
break;
|
|
case 'R':
|
|
rr = 1;
|
|
break;
|
|
case 'I':
|
|
iso1999 = 1;
|
|
break;
|
|
case 'L':
|
|
level = atoi(optarg);
|
|
break;
|
|
case 'b':
|
|
boot_img = optarg;
|
|
break;
|
|
case 'V':
|
|
volid = optarg;
|
|
break;
|
|
case '?':
|
|
iso_usage(argv);
|
|
goto ex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (argc < 2) {
|
|
printf ("Please pass directory from which to build ISO\n");
|
|
iso_usage(argv);
|
|
goto ex;
|
|
}
|
|
if (argc < 3) {
|
|
printf ("Please supply output file\n");
|
|
iso_usage(argv);
|
|
goto ex;
|
|
}
|
|
|
|
fp = fopen(argv[optind+1], "w");
|
|
if (fp == NULL) {
|
|
err(1, "error opening output file");
|
|
goto ex;
|
|
}
|
|
|
|
result = iso_init();
|
|
if (result < 0) {
|
|
printf ("Can't initialize libisofs\n");
|
|
goto ex;
|
|
}
|
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
|
|
|
result = iso_image_new(volid, &image);
|
|
if (result < 0) {
|
|
printf ("Error creating image\n");
|
|
goto ex;
|
|
}
|
|
iso_tree_set_follow_symlinks(image, 0);
|
|
iso_tree_set_ignore_hidden(image, 0);
|
|
iso_tree_set_ignore_special(image, 0);
|
|
iso_set_abort_severity("SORRY");
|
|
/*iso_tree_set_report_callback(image, callback);*/
|
|
|
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image),
|
|
argv[optind]);
|
|
if (result < 0) {
|
|
printf ("Error adding directory %d\n", result);
|
|
goto ex;
|
|
}
|
|
|
|
if (boot_img) {
|
|
/* adds El-Torito boot info. Tunned for isolinux */
|
|
ElToritoBootImage *bootimg;
|
|
result = iso_image_set_boot_image(image, boot_img, ELTORITO_NO_EMUL,
|
|
"/isolinux/boot.cat", &bootimg);
|
|
if (result < 0) {
|
|
printf ("Error adding boot image %d\n", result);
|
|
goto ex;
|
|
}
|
|
el_torito_set_load_size(bootimg, 4);
|
|
el_torito_patch_isolinux_image(bootimg);
|
|
}
|
|
|
|
result = iso_write_opts_new(&opts, 0);
|
|
if (result < 0) {
|
|
printf ("Cannot create write opts, error %d\n", result);
|
|
goto ex;
|
|
}
|
|
iso_write_opts_set_iso_level(opts, level);
|
|
iso_write_opts_set_rockridge(opts, rr);
|
|
iso_write_opts_set_joliet(opts, j);
|
|
iso_write_opts_set_iso1999(opts, iso1999);
|
|
|
|
result = iso_image_create_burn_source(image, opts, &burn_src);
|
|
if (result < 0) {
|
|
printf ("Cannot create image, error %d\n", result);
|
|
goto ex;
|
|
}
|
|
|
|
iso_write_opts_free(opts);
|
|
|
|
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
|
result = fwrite(buf, 1, 2048, fp);
|
|
if (result < 2048) {
|
|
printf ("Cannot write block. errno= %d\n", errno);
|
|
goto ex;
|
|
}
|
|
}
|
|
fclose(fp);
|
|
burn_src->free_data(burn_src);
|
|
free(burn_src);
|
|
|
|
iso_image_unref(image);
|
|
iso_finish();
|
|
return 0;
|
|
ex:;
|
|
if (fp != NULL)
|
|
fclose(fp);
|
|
return 1;
|
|
}
|
|
|
|
|
|
/* ------------------------- from demo/iso_read.c ----------------------- */
|
|
|
|
|
|
static void
|
|
iso_read_print_type(mode_t mode)
|
|
{
|
|
switch(mode & S_IFMT) {
|
|
case S_IFSOCK: printf("[S] "); break;
|
|
case S_IFLNK: printf("[L] "); break;
|
|
case S_IFREG: printf("[R] "); break;
|
|
case S_IFBLK: printf("[B] "); break;
|
|
case S_IFDIR: printf("[D] "); break;
|
|
case S_IFIFO: printf("[F] "); break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
iso_read_print_file_src(IsoFileSource *file)
|
|
{
|
|
struct stat info;
|
|
char *name;
|
|
iso_file_source_lstat(file, &info);
|
|
iso_read_print_type(info.st_mode);
|
|
print_permissions(info.st_mode);
|
|
printf(" %10.f ", (double) info.st_size);
|
|
/* printf(" {%ld,%ld} ", (long)info.st_dev, (long)info.st_ino); */
|
|
name = iso_file_source_get_name(file);
|
|
printf(" %s", name);
|
|
free(name);
|
|
if (S_ISLNK(info.st_mode)) {
|
|
char buf[PATH_MAX];
|
|
iso_file_source_readlink(file, buf, PATH_MAX);
|
|
printf(" -> %s\n", buf);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
static void
|
|
iso_read_print_dir(IsoFileSource *dir, int level)
|
|
{
|
|
int ret, i;
|
|
IsoFileSource *file;
|
|
struct stat info;
|
|
char *sp;
|
|
|
|
sp = calloc(1, level * 2 + 1);
|
|
|
|
for (i = 0; i < level * 2; i += 2) {
|
|
sp[i] = '|';
|
|
sp[i+1] = ' ';
|
|
}
|
|
|
|
if (level > 0)
|
|
sp[level * 2 - 1] = '-';
|
|
sp[level * 2] = '\0';
|
|
|
|
ret = iso_file_source_open(dir);
|
|
if (ret < 0) {
|
|
printf ("Can't open dir %d\n", ret);
|
|
}
|
|
while ((ret = iso_file_source_readdir(dir, &file)) == 1) {
|
|
printf("%s", sp);
|
|
iso_read_print_file_src(file);
|
|
ret = iso_file_source_lstat(file, &info);
|
|
if (ret < 0) {
|
|
break;
|
|
}
|
|
if (S_ISDIR(info.st_mode)) {
|
|
iso_read_print_dir(file, level + 1);
|
|
}
|
|
iso_file_source_unref(file);
|
|
}
|
|
iso_file_source_close(dir);
|
|
if (ret < 0) {
|
|
printf ("Can't print dir\n");
|
|
}
|
|
free(sp);
|
|
}
|
|
|
|
int gesture_iso_read(int argc, char **argv)
|
|
{
|
|
int result, initialized = 0, return_val = 1;
|
|
IsoImageFilesystem *fs = NULL;
|
|
IsoDataSource *src = NULL;
|
|
IsoFileSource *root = NULL;
|
|
IsoReadOpts *ropts = NULL;
|
|
|
|
if (argc != 2) {
|
|
printf ("You need to specify a valid path\n");
|
|
goto ex;
|
|
}
|
|
|
|
result = iso_init();
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Cannot init libisofs");
|
|
goto ex;
|
|
}
|
|
initialized = 1;
|
|
|
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
|
|
|
result = iso_data_source_new_from_file(argv[1], &src);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error creating data source");
|
|
goto ex;
|
|
}
|
|
result = iso_read_opts_new(&ropts, 0);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error creating read options");
|
|
goto ex;
|
|
}
|
|
result = iso_image_filesystem_new(src, ropts, 1, &fs);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error creating filesystem");
|
|
goto ex;
|
|
}
|
|
iso_read_opts_free(ropts);
|
|
ropts = NULL;
|
|
|
|
printf("\nVOLUME INFORMATION\n");
|
|
printf("==================\n\n");
|
|
|
|
printf("Vol. id: %s\n", iso_image_fs_get_volume_id(fs));
|
|
printf("Publisher: %s\n", iso_image_fs_get_publisher_id(fs));
|
|
printf("Data preparer: %s\n", iso_image_fs_get_data_preparer_id(fs));
|
|
printf("System: %s\n", iso_image_fs_get_system_id(fs));
|
|
printf("Application: %s\n", iso_image_fs_get_application_id(fs));
|
|
printf("Copyright: %s\n", iso_image_fs_get_copyright_file_id(fs));
|
|
printf("Abstract: %s\n", iso_image_fs_get_abstract_file_id(fs));
|
|
printf("Biblio: %s\n", iso_image_fs_get_biblio_file_id(fs));
|
|
|
|
printf("\nDIRECTORY TREE\n");
|
|
printf("==============\n");
|
|
|
|
result = fs->get_root(fs, &root);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Cannot get root object");
|
|
goto ex;
|
|
}
|
|
/* iso_read_print_file_src(root); */
|
|
iso_read_print_dir(root, 0);
|
|
|
|
return_val = 0;
|
|
ex:;
|
|
if (root != NULL)
|
|
iso_file_source_unref(root);
|
|
if (ropts != NULL)
|
|
iso_read_opts_free(ropts);
|
|
if (fs != NULL) {
|
|
fs->close(fs);
|
|
iso_filesystem_unref((IsoFilesystem*)fs);
|
|
}
|
|
if (src != NULL)
|
|
iso_data_source_unref(src);
|
|
if (initialized)
|
|
iso_finish();
|
|
return return_val;
|
|
}
|
|
|
|
|
|
/* ------------------------- from demo/iso_cat.c ----------------------- */
|
|
|
|
|
|
int gesture_iso_cat(int argc, char **argv)
|
|
{
|
|
int res, write_ret, ret;
|
|
IsoFilesystem *fs = NULL;
|
|
IsoFileSource *file = NULL;
|
|
struct stat info;
|
|
IsoDataSource *src = NULL;
|
|
IsoReadOpts *opts = NULL;
|
|
|
|
if (argc != 3) {
|
|
fprintf(stderr, "Usage: -iso_cat /path/to/image /path/to/file\n");
|
|
return 1;
|
|
}
|
|
|
|
res = iso_init();
|
|
if (res < 0) {
|
|
demo_report_iso_err(res, "Cannot init libisofs");
|
|
return 1;
|
|
}
|
|
|
|
/* Important Note:
|
|
From here on memory objects get created which need to be freed in
|
|
the end. Therefore in case of problems no direct return, but rather
|
|
a hop to label "ex:", where cleanup happens.
|
|
*/
|
|
|
|
res = iso_data_source_new_from_file(argv[1], &src);
|
|
if (res < 0) {
|
|
demo_report_iso_err(res, "Error creating data source object");
|
|
ret = 1; goto ex;
|
|
}
|
|
|
|
res = iso_read_opts_new(&opts, 0);
|
|
if (res < 0) {
|
|
demo_report_iso_err(res, "Error creating read options object");
|
|
ret = 1; goto ex;
|
|
}
|
|
res = iso_image_filesystem_new(src, opts, 1, &fs);
|
|
if (res < 0) {
|
|
demo_report_iso_err(res, "Error creating filesystem object");
|
|
ret = 1; goto ex;
|
|
}
|
|
iso_read_opts_free(opts);
|
|
opts = NULL;
|
|
|
|
res = fs->get_by_path(fs, argv[2], &file);
|
|
if (res < 0) {
|
|
demo_report_iso_err(res, "Cannot get file object with given path");
|
|
ret = 1; goto ex;
|
|
}
|
|
|
|
res = iso_file_source_lstat(file, &info);
|
|
if (res < 0) {
|
|
demo_report_iso_err(res,
|
|
"Cannot inquire type of file object with given path");
|
|
ret = 1; goto ex;
|
|
}
|
|
|
|
if (S_ISDIR(info.st_mode)) {
|
|
fprintf(stderr, "Path refers to a directory!!\n");
|
|
ret = 1; goto ex;
|
|
} else {
|
|
char buf[1024];
|
|
res = iso_file_source_open(file);
|
|
if (res < 0) {
|
|
demo_report_iso_err(res,
|
|
"Cannot open file object with given path");
|
|
ret = 1; goto ex;
|
|
}
|
|
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
|
write_ret = fwrite(buf, 1, res, stdout);
|
|
if (write_ret < res) {
|
|
printf ("Cannot write block to stdout. errno= %d\n", errno);
|
|
iso_file_source_close(file);
|
|
ret = 1; goto ex;
|
|
}
|
|
}
|
|
iso_file_source_close(file);
|
|
if (res < 0) {
|
|
demo_report_iso_err(res, "Error while reading data content");
|
|
fprintf(stderr, "Error reading, err = 0x%X\n", (unsigned int) res);
|
|
ret = 1; goto ex;
|
|
}
|
|
}
|
|
|
|
ret = 0;
|
|
ex:;
|
|
if (file != NULL)
|
|
iso_file_source_unref(file);
|
|
if (fs != NULL)
|
|
iso_filesystem_unref(fs);
|
|
if (opts != NULL)
|
|
iso_read_opts_free(opts);
|
|
if (src != NULL)
|
|
iso_data_source_unref(src);
|
|
iso_finish();
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* ------------------------- from demo/iso_modify.c ----------------------- */
|
|
|
|
|
|
void iso_modify_usage(char **argv)
|
|
{
|
|
printf("%s IMAGE DIRECTORY OUTPUT\n", argv[0]);
|
|
}
|
|
|
|
int gesture_iso_modify(int argc, char **argv)
|
|
{
|
|
int result, return_val = 1, initialized = 0;
|
|
IsoImage *image = NULL;
|
|
IsoDataSource *src = NULL;
|
|
struct burn_source *burn_src = NULL;
|
|
unsigned char buf[2048];
|
|
FILE *fp = NULL;
|
|
IsoWriteOpts *opts = NULL;
|
|
IsoReadOpts *ropts = NULL;
|
|
|
|
if (argc < 4) {
|
|
iso_modify_usage(argv);
|
|
goto ex;
|
|
}
|
|
|
|
fp = fopen(argv[3], "w");
|
|
if (fp == NULL) {
|
|
err(1, "error opening output file");
|
|
goto ex;
|
|
}
|
|
|
|
result = iso_init();
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Cannot init libisofs");
|
|
goto ex;
|
|
}
|
|
initialized = 1;
|
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
|
|
|
/* create the data source to accesss previous image */
|
|
result = iso_data_source_new_from_file(argv[1], &src);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error creating data source");
|
|
goto ex;
|
|
}
|
|
|
|
/* create the image context */
|
|
result = iso_image_new("volume_id", &image);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error creating image");
|
|
goto ex;
|
|
}
|
|
iso_tree_set_follow_symlinks(image, 0);
|
|
iso_tree_set_ignore_hidden(image, 0);
|
|
|
|
/* import previous image */
|
|
result = iso_read_opts_new(&ropts, 0);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error creating read options");
|
|
goto ex;
|
|
}
|
|
result = iso_image_import(image, src, ropts, NULL);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error importing previous session");
|
|
goto ex;
|
|
}
|
|
/* (One could of course keep them alive until cleanup) */
|
|
iso_read_opts_free(ropts);
|
|
ropts = NULL;
|
|
iso_data_source_unref(src);
|
|
src = NULL;
|
|
|
|
/* add new dir */
|
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error adding directory");
|
|
goto ex;
|
|
}
|
|
|
|
/* Generate a new image with both previous and added contents.
|
|
Profile 1 means Rock Ridge and ISO level 3.
|
|
*/
|
|
result = iso_write_opts_new(&opts, 1);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Cannot create write opts");
|
|
goto ex;
|
|
}
|
|
/* Prefer specs violation over relocation deep directories */
|
|
iso_write_opts_set_allow_deep_paths(opts, 1);
|
|
|
|
/* For MS-Windows readers : iso_write_opts_set_joliet(opts, 1); */
|
|
|
|
result = iso_image_create_burn_source(image, opts, &burn_src);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Cannot create image object");
|
|
goto ex;
|
|
}
|
|
iso_write_opts_free(opts);
|
|
opts = NULL;
|
|
|
|
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
|
result = fwrite(buf, 1, 2048, fp);
|
|
if (result < 2048) {
|
|
fprintf (stderr, "Cannot write block. errno= %d\n", errno);
|
|
goto ex;
|
|
}
|
|
}
|
|
|
|
return_val = 0;
|
|
ex:
|
|
if (fp != NULL)
|
|
fclose(fp);
|
|
if (opts != NULL)
|
|
iso_write_opts_free(opts);
|
|
if (burn_src != NULL) {
|
|
burn_src->free_data(burn_src);
|
|
free(burn_src);
|
|
}
|
|
if (image != NULL)
|
|
iso_image_unref(image);
|
|
if (ropts != NULL)
|
|
iso_read_opts_free(ropts);
|
|
if (src != NULL)
|
|
iso_data_source_unref(src);
|
|
if (initialized)
|
|
iso_finish();
|
|
return return_val;
|
|
}
|
|
|
|
|
|
/* ------------------------- from demo/iso_ms.c ----------------------- */
|
|
|
|
|
|
void iso_ms_usage(char **argv)
|
|
{
|
|
printf("%s LSS NWA DISC DIRECTORY OUTPUT\n", argv[0]);
|
|
}
|
|
|
|
int gesture_iso_ms(int argc, char **argv)
|
|
{
|
|
int result, return_val = 1, initialized = 0;
|
|
IsoImage *image = NULL;
|
|
IsoDataSource *src = NULL;
|
|
struct burn_source *burn_src = NULL;
|
|
unsigned char buf[2048];
|
|
FILE *fp = NULL;
|
|
IsoWriteOpts *opts = NULL;
|
|
IsoReadOpts *ropts = NULL;
|
|
uint32_t ms_block;
|
|
|
|
if (argc < 6) {
|
|
iso_ms_usage(argv);
|
|
goto ex;
|
|
}
|
|
|
|
if (strcmp(argv[3], argv[5]) == 0) {
|
|
fprintf(stderr,
|
|
"image_file and output_file must not be the same file.\n");
|
|
goto ex;
|
|
}
|
|
|
|
fp = fopen(argv[5], "w");
|
|
if (!fp) {
|
|
err(1, "error opening output file");
|
|
goto ex;
|
|
}
|
|
|
|
result = iso_init();
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Cannot init libisofs");
|
|
goto ex;
|
|
}
|
|
initialized = 1;
|
|
|
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
|
|
|
/* create the data source to accesss previous image */
|
|
result = iso_data_source_new_from_file(argv[3], &src);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error creating data source");
|
|
goto ex;
|
|
}
|
|
|
|
/* create the image context */
|
|
result = iso_image_new("volume_id", &image);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error creating image");
|
|
goto ex;
|
|
}
|
|
iso_tree_set_follow_symlinks(image, 0);
|
|
iso_tree_set_ignore_hidden(image, 0);
|
|
|
|
/* import previous image */
|
|
result = iso_read_opts_new(&ropts, 0);
|
|
if (result < 0) {
|
|
fprintf(stderr, "Error creating read options\n");
|
|
goto ex;
|
|
}
|
|
iso_read_opts_set_start_block(ropts, atoi(argv[1]));
|
|
result = iso_image_import(image, src, ropts, NULL);
|
|
iso_read_opts_free(ropts);
|
|
ropts = NULL;
|
|
iso_data_source_unref(src);
|
|
src = NULL;
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error importing previous session");
|
|
goto ex;
|
|
}
|
|
|
|
/* add new dir */
|
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Error adding directory");
|
|
goto ex;
|
|
}
|
|
|
|
/* generate a multisession image with new contents */
|
|
result = iso_write_opts_new(&opts, 1);
|
|
if (result < 0) {
|
|
demo_report_iso_err(result, "Cannot create write opts");
|
|
goto ex;
|
|
}
|
|
|
|
/* round up to 32kb aligment = 16 block */
|
|
ms_block = atoi(argv[2]);
|
|
iso_write_opts_set_ms_block(opts, ms_block);
|
|
iso_write_opts_set_appendable(opts, 1);
|
|
|
|
result = iso_image_create_burn_source(image, opts, &burn_src);
|
|
if (result < 0) {
|
|
printf ("Cannot create image, error %d\n", result);
|
|
goto ex;
|
|
}
|
|
iso_write_opts_free(opts);
|
|
opts = NULL;
|
|
|
|
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
|
result = fwrite(buf, 1, 2048, fp);
|
|
if (result < 2048) {
|
|
printf ("Cannot write block. errno= %d\n", errno);
|
|
goto ex;
|
|
}
|
|
}
|
|
|
|
return_val = 0;
|
|
ex:;
|
|
if (burn_src != NULL) {
|
|
burn_src->free_data(burn_src);
|
|
free(burn_src);
|
|
}
|
|
if (opts != NULL)
|
|
iso_write_opts_free(opts);
|
|
if (image)
|
|
iso_image_unref(image);
|
|
if (ropts != NULL)
|
|
iso_read_opts_free(ropts);
|
|
if (src != NULL)
|
|
iso_data_source_unref(src);
|
|
if (initialized)
|
|
iso_finish();
|
|
if (fp != NULL)
|
|
fclose(fp);
|
|
return return_val;
|
|
}
|
|
|
|
|
|
/* ------------------------- switcher ----------------------- */
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
char *gesture;
|
|
int i;
|
|
|
|
if (argc < 2) {
|
|
usage:;
|
|
fprintf(stderr, "usage: %s gesture [gesture_options]\n", argv[0]);
|
|
for (i = 0; helptext[i][0] != '@'; i++)
|
|
fprintf(stderr, "%s\n", helptext[i]);
|
|
exit(1);
|
|
}
|
|
for (gesture = argv[1]; *gesture == '-'; gesture++);
|
|
if (strcmp(gesture, "tree") == 0) {
|
|
gesture_tree(argc - 1, &(argv[1]));
|
|
} else if(strcmp(gesture, "find") == 0) {
|
|
gesture_find(argc - 1, &(argv[1]));
|
|
} else if(strcmp(gesture, "iso") == 0) {
|
|
gesture_iso(argc - 1, &(argv[1]));
|
|
} else if(strcmp(gesture, "iso_read") == 0) {
|
|
gesture_iso_read(argc - 1, &(argv[1]));
|
|
} else if(strcmp(gesture, "iso_cat") == 0) {
|
|
gesture_iso_cat(argc - 1, &(argv[1]));
|
|
} else if(strcmp(gesture, "iso_modify") == 0) {
|
|
gesture_iso_modify(argc - 1, &(argv[1]));
|
|
} else if(strcmp(gesture, "iso_ms") == 0) {
|
|
gesture_iso_ms(argc - 1, &(argv[1]));
|
|
} else {
|
|
goto usage;
|
|
}
|
|
exit(0);
|
|
}
|