EXAMPLES<\/A>):
/' \
+ -e 's/Writing the result:<\/b>/\
Writing the result:<\/b>
/' \
+ -e 's/^-find \/ /\ \ -find \/ /' \
+ -e 's/Settings for data insertion:<\/b>/\
Settings for data insertion:<\/b>
\
/' \
+ -e 's/^$<\/b> ln -s/\ \ $<\/b> ln -s/' \
+ -e 's/Settings for result writing:<\/b>/\
Settings for result writing:<\/b>
\
/' \
+ -e 's/^706k = 706kB/\ \ 706k = 706kB/' \
+ -e 's/^5540k = 5540kB/\ \ 5540k = 5540kB/' \
+ -e 's/Exception processing:<\/b>/\
Exception processing:<\/b>
\
/' \
+ -e 's/Dialog mode control:<\/b>/\
Dialog mode control:<\/b>
\
/' \
+ -e 's/Drive and media related inquiry actions:<\/b>/\
Drive and media related inquiry actions:<\/b>
\
/' \
+ -e 's/Navigation in ISO image/\
Navigation in ISO image/' \
+ -e 's/^filesystem:<\/b>/filesystem:<\/b>
\
/' \
+ -e 's/Command compatibility emulations:<\/b>/\
Command compatibility emulations:<\/b>
\
/' \
+ -e 's/^−as
\
\−as' \
+ -e 's/Scripting, dialog and/\
Scripting, dialog and/' \
+ -e 's/^features:<\/b>/features:<\/b>
\
/' \
+ -e 's/Support for frontend/\
Support for frontend/' \
+ -e 's/^listening at stdout:<\/b>/listening at stdout:<\/b>
\
/' \
+ -e 's/xorriso -outdev \/dev\/sr2 \\ -blank fast \\ -pathspecs on/xorriso -outdev \/dev\/sr2 -blank fast -pathspecs on/' \
+ -e 's/\\ -add \\ \/sounds=\/home\/me\/sounds \\ \/pictures \\ -- \\ -rm_r \\/ -add \/sounds=\/home\/me\/sounds \/pictures -- -rm_r /' \
+ -e 's/\/sounds\/indecent \\ \’\/pictures\/\*private\*\’ \\/\/sounds\/indecent \’\/pictures\/*private*\’ /' \
+ -e 's/\/pictures\/confidential \\ -- \\ -add \\/\/pictures\/confidential -- -add/' \
+ -e 's/xorriso -dev \/dev\/sr2 \\ -rm_r \/sounds -- \\ -mv \\/xorriso -dev \/dev\/sr2 -rm_r \/sounds -- -mv /' \
+ -e 's/\/pictures\/confidential \\ \/pictures\/restricted \\ -- \\ -chmod/\/pictures\/confidential \/pictures\/restricted -- -chmod/' \
+ -e 's/go-rwx \/pictures\/restricted -- \\ -pathsspecs on \\ -add \\/go-rwx \/pictures\/restricted -- -pathsspecs on -add /' \
+ -e 's/\/sounds=\/home\/me\/prepared_for_dvd\/sounds_dummy /\/sounds=\/home\/me\/prepared_for_dvd\/sounds_dummy/' \
+ -e 's/\/movies=\/home\/me\/prepared_for_dvd\/movies \\ -- \\ -commit/\/movies=\/home\/me\/prepared_for_dvd\/movies -- -commit/' \
+ -e 's/xorriso -indev \/dev\/sr2 \\ -rm_r \/sounds -- \\/xorriso -indev \/dev\/sr2 -rm_r \/sounds -- /' \
+ -e 's/-outdev \/dev\/sr0 -blank fast \\ -commit -eject all/-outdev \/dev\/sr0 -blank fast -commit -eject all/' \
+ -e 's/See section FILES/See section FILES<\/A>/' \
+ -e 's/See section EXAMPLES/See section EXAMPLES<\/A>/' \
+ -e 's/<\/body>/
(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
+ <"$2" >"$htmlpage"
+
+ set +x
+
+ chmod u+rw,go+r,go-w "$htmlpage"
+ echo "Emerged file:"
+ ls -lL "$htmlpage"
+
+else
+
+ export BROWSER='cp "%s" '"$raw_html"
+ man -H "$manpage"
+ "$0" -work_as_filter "$raw_html"
+ rm "$raw_html"
+ rm "$man_dir"/man1
+
+fi
diff --git a/libisoburn/branches/ZeroOneSix/xorriso/make_timestamp.sh b/libisoburn/branches/ZeroOneSix/xorriso/make_timestamp.sh
new file mode 100755
index 00000000..d6cfcb57
--- /dev/null
+++ b/libisoburn/branches/ZeroOneSix/xorriso/make_timestamp.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Create version timestamp xorriso/xorriso_timestamp.h
+# to be executed within ./libisoburn-develop
+
+timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
+echo "Version timestamp : $timestamp"
+echo '#define Xorriso_timestamP "'"$timestamp"'"' >xorriso/xorriso_timestamp.h
+
diff --git a/libisoburn/branches/ZeroOneSix/xorriso/make_xorriso_standalone.sh b/libisoburn/branches/ZeroOneSix/xorriso/make_xorriso_standalone.sh
new file mode 100755
index 00000000..d146a528
--- /dev/null
+++ b/libisoburn/branches/ZeroOneSix/xorriso/make_xorriso_standalone.sh
@@ -0,0 +1,235 @@
+#!/bin/sh
+
+# make_xorriso_standalone.sh
+# Copyright 2008 Thomas Schmitt, scdbackup@gmx.net, GPL
+#
+# Not intended for general use in production installations !
+#
+# This is a development tool which expects a special setup of directories.
+# It is to be executed in a common parent of the directories
+# nglibisofs-develop libburn-develop libisoburn-develop
+#
+# Creates a standalone tree for building xorriso
+# from the contents of a unified libburnia development tree.
+#
+# The ./bootstrap script gets applied and a source tarball
+# is made.
+#
+# From that tree can be build a binary xorriso/xorriso
+# which at runtime depends only on libc and libpthread.
+# Execute in $lone_dir :
+#
+# ./configure && make
+#
+
+current_dir=$(pwd)
+lone_dir="$current_dir"/"xorriso-standalone"
+
+xorriso_rev=0.1.5
+# For unstable uploads:
+xorriso_pl=""
+# For stable releases:
+# xorriso_pl=".pl00"
+
+with_bootstrap_tarball=1
+
+create_dir() {
+ if mkdir "$1"
+ then
+ dummy=dummy
+ else
+ echo "Failed to create : $1" >&2
+ exit 1
+ fi
+}
+
+goto_dir() {
+ if cd "$1"
+ then
+ dummy=dummy
+ else
+ echo "Failed to cd $1" >&2
+ exit 1
+ fi
+}
+
+copy_files() {
+ if cp "$@"
+ then
+ dummy=dummy
+ else
+ echo "Failed to : cp " "$@" >&2
+ exit 1
+ fi
+}
+
+if test -e "$lone_dir"
+then
+ echo "Already existing : $lone_dir" >&2
+ exit 1
+fi
+
+
+# Top level directory
+
+goto_dir "$current_dir"/libisoburn-develop
+
+create_dir "$lone_dir"
+
+copy_files \
+ AUTHORS \
+ CONTRIBUTORS \
+ COPYRIGHT \
+ COPYING \
+ INSTALL \
+ acinclude.m4 \
+ aclocal.m4 \
+ bootstrap \
+ compile \
+ config.guess \
+ config.status \
+ config.sub \
+ depcomp \
+ install-sh \
+ libtool \
+ ltmain.sh \
+ missing \
+ mkinstalldirs \
+ version.h.in \
+ \
+ "$lone_dir"
+
+copy_files xorriso/configure_ac.txt "$lone_dir"/configure.ac
+
+copy_files xorriso/xorriso_makefile_am.txt "$lone_dir"/Makefile.am
+
+copy_files xorriso/xorriso_pc_in.txt "$lone_dir"/xorriso.pc.in
+
+copy_files xorriso/README "$lone_dir"/README
+
+# echo "See end of xorriso/changelog.txt" >"$lone_dir"/TODO
+
+
+# libisoburn
+
+create_dir "$lone_dir"/libisoburn
+copy_files \
+ libisoburn/*.[ch] \
+ "$lone_dir"/libisoburn
+
+xorriso/convert_man_to_html.sh
+
+create_dir "$lone_dir"/xorriso
+copy_files \
+ xorriso/xorrisoburn.[ch] \
+ xorriso/xorriso.[ch1] \
+ xorriso/xorriso_private.h \
+ xorriso/xorriso_timestamp.h \
+ xorriso/changelog.txt \
+ xorriso/xorriso_eng.html \
+ xorriso/man_1_xorriso.html \
+ "$lone_dir"/xorriso
+
+create_dir "$lone_dir"/test
+copy_files \
+ test/compare_file.c \
+ "$lone_dir"/test/compare_file.c
+
+
+# nglibisofs
+
+create_dir "$lone_dir"/libisofs
+create_dir "$lone_dir"/libisofs/filters
+goto_dir "$current_dir"/nglibisofs-develop
+copy_files libisofs/*.[ch] "$lone_dir"/libisofs
+copy_files libisofs/filters/*.[ch] "$lone_dir"/libisofs/filters
+copy_files COPYRIGHT "$lone_dir"/libisofs
+
+# To get a common version.h
+cat version.h.in >> "$lone_dir"/version.h.in
+
+
+# <<< obsoleted patchings
+
+if test 1 = 0
+then
+
+# Change GNU macro name to POSIX name
+sed -e 's/FNM_FILE_NAME/FNM_PATHNAME/g' \
+ "$lone_dir"/libisofs/tree.c
+
+# Filter out the semi-illegal TODO comments
+( cd "$lone_dir"/libisofs && grep '^[[:space:]]*//' *.[ch] | less )
+echo "Is it ok delete all shown //-lines ?"
+read yesno
+if test "$yesno" = "y" -o "$yesno" = "1"
+then
+ for i in "$lone_dir"/libisofs/*.[ch]
+ do
+ # first copy attributes
+ cp "$i" "$lone_dir"/libisofs/tmpfile
+ # now filter away // lines
+ grep -v '^[[:space:]]*//' <"$i" >"$lone_dir"/libisofs/tmpfile && \
+ mv "$lone_dir"/libisofs/tmpfile "$i"
+ done
+fi
+echo "Remaining // lines:"
+( cd "$lone_dir"/libisofs && grep '//' *.[ch] )
+
+fi
+
+
+
+# libburn
+
+create_dir "$lone_dir"/libburn
+goto_dir "$current_dir"/libburn-develop
+copy_files libburn/*.[ch] "$lone_dir"/libburn
+copy_files COPYRIGHT "$lone_dir"/libburn
+
+
+# To get a common version.h
+cat version.h.in >> "$lone_dir"/version.h.in
+
+
+# tarball
+
+if test "$with_bootstrap_tarball" = 1
+then
+
+tarball_dir="$current_dir"/xorriso-"$xorriso_rev"
+mv "$lone_dir" "$tarball_dir"
+
+goto_dir "$tarball_dir"
+
+./bootstrap
+
+# Remove unneeded temporary data from ./bootstrap
+rm -r ./autom4te.cache
+
+# Repair non-portable shell code output of ./bootstrap
+(
+ cd "$compile_dir" || exit 1
+ sed -e 's/^for ac_header in$/test -z 1 \&\& for ac_header in dummy/' \
+ < ./configure > ./configure-repaired
+ if test "$?" = 0
+ then
+ echo "$0: Empty 'for ac_header in' found in configure." >&2
+ fi
+ mv ./configure-repaired ./configure
+ chmod a+rx,go-w,u+w ./configure
+)
+
+cd "$current_dir"
+tar czf ./xorriso-"$xorriso_rev""$xorriso_pl".tar.gz $(basename "$tarball_dir")
+
+ls -l $(pwd)/xorriso-"$xorriso_rev""$xorriso_pl".tar.gz
+
+mv "$tarball_dir" "$lone_dir"
+
+fi
+
+echo "Done"
+echo "HINT: Now build xorriso/xorriso by:"
+echo " cd '$lone_dir' && ./configure && make"
+echo
diff --git a/libisoburn/branches/ZeroOneSix/xorriso/xorriso.1 b/libisoburn/branches/ZeroOneSix/xorriso/xorriso.1
new file mode 100644
index 00000000..96080d03
--- /dev/null
+++ b/libisoburn/branches/ZeroOneSix/xorriso/xorriso.1
@@ -0,0 +1,2125 @@
+.\" Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH XORRISO 1 "May, 15, 2008"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh disable hyphenation
+.\" .hy enable hyphenation
+.\" .ad l left justify
+.\" .ad b justify to both left and right margins
+.\" .nf disable filling
+.\" .fi enable filling
+.\" .br insert line break
+.\" .sp insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+xorriso - creates, loads, manipulates and writes ISO 9660 filesystem images
+with Rock Ridge extensions.
+.SH SYNOPSIS
+.B xorriso
+.RI [ settings | actions ]
+.br
+.SH DESCRIPTION
+.PP
+.B xorriso
+is a program which maps file objects from POSIX compliant
+filesystems into Rock Ridge enhanced ISO 9660 filesystems and allows
+session-wise manipulation of such filesystems. It can load the management
+information of existing ISO images and it writes the session results to
+optical media or to filesystem objects.
+.PP
+A special property of xorriso is that it needs neither an external ISO 9660
+formatter program nor an external burn program for CD or DVD but rather
+incorporates the libraries of libburnia-project.org .
+.SS
+.B Overview of features:
+.br
+Operates on an existing ISO image or creates a new one.
+.br
+Copies files from filesystem into the ISO image.
+.br
+Renames or deletes file objects in the ISO image.
+.br
+Changes file properties in the ISO image.
+.br
+Updates ISO subtrees incrementally to match given disk subtrees.
+.br
+Can write result as completely new image to optical media or
+filesystem objects.
+.br
+Can write result as add-on session to appendable multi-session media,
+to overwriteable media, to regular files, and to block devices.
+.br
+Scans for optical drives, blanks re-useable optical media.
+.br
+Reads its instructions from command line arguments, dialog, and batch files.
+.br
+Provides navigation commands for interactive ISO image manipulation.
+.br
+Adjustable thresholds for abort, exit value, and problem reporting.
+.SS
+.B General information paragraphs:
+.br
+Session model
+.br
+Media types and states
+.br
+Creating, Growing, Modifying
+.br
+Libburn drives
+.br
+Rock Ridge, POSIX, X/Open
+.br
+Command processing
+.br
+Dialog, Readline, Result pager
+.sp 1
+Maybe you first want to have a look at section EXAMPLES near the end of
+this text before reading the next few hundred lines of background information.
+.SS
+.B Session model:
+.br
+Unlike other filesystems, ISO 9660 is not intended for read-write operation but
+rather for being generated in a single sweep and being written to media as a
+.B session.
+.br
+The data content of the session is called filesystem
+.B image.
+.PP
+The written image in its session can then be mounted by the operating system
+for being used read-only. Linux is able to mount ISO images from block devices,
+which may represent optical media, other media or via a loop device even
+from regular disk files.
+.PP
+This session usage model has been extended on CD media by the concept of
+.B multi-session ,
+which allows to add information to the CD and gives the mount programs
+of the operating systems the addresses of the entry points of each
+session. The mount programs recognize block devices which represent
+CD media and will by default mount the image in the last session.
+.br
+This session usually contains an updated directory tree for the whole media
+which governs the data contents in all recorded sessions.
+So in the view of the mount program all sessions of a particular media
+together form a single filesystem image.
+.br
+Adding a session to an existing ISO image is in this text referred as
+\fBgrowing\fR.
+.br
+The multi-session model of the MMC standard does not apply to all media
+types. But program growisofs by Andy Polyakov showed how to extend this
+functionality to overwriteable media or disk files which carry valid ISO 9660
+filesystems. This expansion method is referred as emulated growing.
+.PP
+xorriso provides both ways of growing as well as an own method named
+\fBmodifying\fR which produces a completely new ISO image from the old
+one and the modifications. See paragraph Creating, Growing, Modifying below.
+.PP
+xorriso adopts the concept of multi-session by loading an eventual image
+directory tree, allowing to manipulate it by several actions, and to write
+the new image to the target media.
+.br
+The first session of a xorriso run begins by the definition of the input
+drive with the eventual ISO image or by the definition of an output drive.
+The session ends by command -commit which triggers writing. A -commit is
+done automatically when the program ends regularly.
+.PP
+After -commit a new session begins with the freshly written one as input.
+A new input drive can only be chosen as long as the loaded ISO image was
+not altered. Pending alteration can be revoked by command -rollback.
+.PP
+Writing a session to the target is supposed to be very expensive in terms of
+time and of consumed space on appendable or write-once media. Therefore all
+intended manipulations of a particular ISO image should be done in a single
+session.
+.br
+In some special situations (e.g. in a file-to-file situation) it can be
+useful to store intermediate states and to continue with image manipulations.
+.SS
+.B Media types and states:
+There are two families of media in the MMC standard:
+.br
+\fBMulti-session\fR media are CD-R, CD-RW, DVD-R, DVD+R, DVD+R/DL, and
+unformatted DVD-RW. These media provide a table of content which
+describes their existing sessions. See option \fB-toc\fR.
+.br
+\fBOverwriteable\fR media are DVD-RAM, DVD+RW, and formatted DVD-RW.
+They allow random write access but do not provide information about their
+session history. If they contain one or more ISO 9660 sessions and if the
+first session was written by xorriso, then a table of content can
+be emulated. Else only a single overall session will be visible.
+.br
+DVD-RW media can be formatted by -format full.
+They can be made unformatted by -blank deformat.
+.br
+Emulated drives are handled as overwriteable media if they are random
+read-write accessible. If they are only sequentially writeable then
+they are handled as blank multi-session media.
+.PP
+These media can assume several states in which they offer different
+capabilities.
+.br
+\fBBlank\fR media can be written from scratch. They contain no ISO image
+suitable for xorriso.
+.br
+Blank is the state of newly purchased optical media.
+With used CD-RW and DVD-RW it can be achieved by action -blank "as_needed".
+Overwriteable media are considered blank unless they contain an ISO image
+suitable for xorriso. Action -blank "as_needed" can be used to invalidate the
+image on overwriteable media, or to apply eventual mandatory formatting.
+.br
+\fBAppendable\fR media accept further sessions. Either they are MMC
+multi-session media in appendable state, or they are overwriteable media
+which contain an ISO image suitable for xorriso.
+.br
+Appendable is the state after writing a session with option -close off.
+.br
+\fBClosed\fR media cannot be written. They may contain an ISO image suitable
+for xorriso.
+.br
+Closed is the state of DVD-ROM media and of multi-session media which were
+written with option -close on. If the drive is incapable of writing it will
+probably show any media as closed CD-ROM resp. DVD-ROM.
+.br
+Overwriteable media assume this state in such read-only drives or if they
+contain unrecognizable data in the first 32 data blocks.
+.br
+\fBRead-only\fR drives may or may not show session histories of multi-session
+media. Often only the first and the last session are visible. Sometimes
+not even that. Option -rom_toc_scan might or might not help in such cases.
+.SS
+.B Creating, Growing, Modifying:
+.br
+A new empty ISO image gets \fBcreated\fR
+if there is no input drive with a valid
+ISO 9660 image plus Rock Ridge extensions when the first time an output drive
+is defined. This is achieved by option -dev on blank media or by option -outdev
+on media in any state.
+.br
+The new empty image can be populated with directories and files.
+Before it can be written, the media in the output drive must get into
+blank state if it was not blank already.
+.PP
+If there is a input drive with a valid ISO image, then this image gets loaded
+as foundation for manipulations and extension. The constellation of input
+and output drive determines which of two write methods will be used.
+They have quite different capabilities and constraints.
+.PP
+The method of \fBgrowing\fR adds new data to the existing media. These
+data comprise of eventual new file content and they override the existing
+ISO 9660 + Rock Ridge directory tree. It is possible to hide files from
+previous sessions but they still exist on media and with many types of
+optical media it is quite easy to recover them by mounting older sessions.
+.br
+Growing is achieved by option -dev.
+.PP
+The write method of \fBmodifying\fR produces compact filesystem
+images with no outdated files or directory trees. Modifying can write its
+images to target media which are completely unsuitable for multi-session
+operations. E.g. DVD-RW which were treated with -blank deformat_quickest,
+named pipes, character devices, sockets.
+On the other hand modified sessions cannot be written to appendable media
+but to blank media only.
+.br
+Modifying takes place whenever input drive and output drive are not the same.
+This is achieved by options -indev and -outdev.
+.br
+So for this method one needs either two optical drives or has to work with
+filesystem objects as source and/or target media.
+.SS
+.B Libburn drives:
+.br
+Input drive, i.e. source of an existing or empty ISO image, can be any random
+access readable libburn drive: optical media with readable data,
+blank optical media, regular files, block devices.
+.br
+Rock Ridge info must be present in existing ISO images and it will be generated
+by the program unconditionally.
+.PP
+Output drive, i.e. target for writing, can be any libburn drive.
+Some drive types do not support the method of growing but only the method
+of modifying. They all are suitable for newly created images.
+.br
+All drive file objects have to offer rw-permission to the user of xorriso.
+Even those which will not be useable for reading an ISO image.
+.PP
+MMC compliant (i.e. optical) drives on Linux usually get addressed by
+the path of their block device or of their generic character device. E.g.
+.br
+ -dev /dev/sr0
+.br
+ -dev /dev/hdc
+.br
+ -dev /dev/sg2
+.br
+Get a list of accessible drives by command
+.br
+ -devices
+.br
+It might be necessary to do this as
+.B superuser
+in order to see all drives and to then allow rw-access for the intended users.
+Consider to bundle the authorized users in a group like old "floppy".
+.PP
+Filesystem objects of nearly any type can be addressed by prefix "stdio:" and
+their path in the filesystem. E.g.:
+.br
+ -dev stdio:/tmp/pseudo_drive
+.br
+If path leads to a regular file or to a block device then the emulated drive
+is random access readable and can be used for the method of growing if it
+already contains a valid ISO 9660 image. Any other file type is not readable
+via "stdio:" and can only be used as target for the method of modifying.
+Non existing paths in existing directories are handled as empty regular files.
+.PP
+A very special kind of pseudo drive are open file descriptors. They are
+depicted by "stdio:/dev/fd/" and descriptor number (see man 2 open).
+.br
+Addresses "-" or "stdio:/dev/fd/1" depict standard output, which normally is
+the output channel for result texts.
+To prevent a fatal intermingling of ISO image and text messages, all result
+texts get redirected to stderr if -*dev "-" or "stdio:/dev/fd/1" is among
+the start arguments of the program.
+.br
+Standard output is currently suitable for creating a single new session
+per program run without dialog. Use in other situations is discouraged
+and several restrictions apply:
+.br
+It is not allowed to use standard output as pseudo drive if it was not
+among the start arguments. Do not try to fool this ban via backdoor addresses
+to stdout.
+.br
+If stdout is used as drive, then -use_readline is permanently disabled.
+Use of backdoors will cause severe memory and/or tty corruption.
+.PP
+Be aware that especially the superuser can write into any accessible file or
+device by using its path with the "stdio:" prefix. Addresses without prefix
+"stdio:" will only work if they lead to a MMC drive.
+.br
+One may use option
+.B -ban_stdio_write
+to surely prevent this risk and to allow only MMC drives.
+.SS
+.B Rock Ridge, POSIX, X/Open:
+.br
+.B Rock Ridge
+is the name of a set of additional informations which enhance
+an ISO 9660 filesystem so that it can represent a POSIX compliant filesystem
+with ownership, access permissions, symbolic links, and other attributes.
+.PP
+This is what xorriso uses for a decent representation of the disk files
+within the ISO image. Rock Ridge information is produced with any xorriso
+image and xorriso will load for manipulation only Rock Ridge enhanced images.
+.PP
+xorriso is not named "porriso" because POSIX only guarantees 14 characters
+of filename length. It is the X/Open System Interface standard XSI which
+demands a file name length of up to 255 characters and paths of up to 1024
+characters. Rock Ridge fulfills this demand.
+.SS
+.B Command processing:
+.br
+Commands are either actions or settings. They consist of a command word,
+followed by zero or more parameter words. If the list of parameter words
+is of variable length (indicated by "[...]" or "[***]") then it has to be
+terminated by either the word "--" or the end of argument list or an end of
+an input line.
+It is not an error if "--" appears after the parameters of a command
+with a fixed list length.
+.PP
+.B Pattern expansion
+is a property of some particular commands and not a general
+feature. It gets controlled by commands -iso_rr_pattern and -disk_pattern.
+Commands which eventually use pattern expansion all have variable argument
+lists which are marked in this man page by "[***]" rather than "[...]".
+.br
+Some other commands perform pattern matching unconditionally.
+.PP
+Command and parameter words are either read from program arguments, where one
+argument is one word, or from input lines where words are recognized similar
+to the quotation rules of a shell parser.
+.br
+xorriso is not a shell, although it might appear so on first glimpse.
+Be aware that the interaction of quotation marks and pattern symbols like "*"
+differs from the usual shell parsers. In xorriso, a quotation mark does not
+make a pattern symbol literal.
+.PP
+When the program begins then it first looks for argument -no_rc. If this is
+not present then it looks for its startup files and
+eventually reads their content as command input lines. Then it interprets
+the program arguments as commands and parameters and finally it enters
+dialog mode if command -dialog "on" was executed up to then.
+.PP
+The program ends either by command -end, or by the end of program arguments
+if not dialog was enabled up to that moment, or by a problem
+event which triggers the threshold of command -abort_on.
+.SS
+.B Dialog, Readline, Result pager:
+.br
+Dialog mode prompts for an input line, parses it into words, and performs
+them as commands with their parameters. It provides assisting services
+to make dialog more comfortable.
+.PP
+Readline is an enhancement for the input line. You may know it already from
+the bash shell. Whether it is available in xorriso depends on the availability
+of package readline-dev at the time when xorriso was built from its sourcecode.
+.br
+It allows to move the cursor over the text in the line by help of the
+Leftward and the Rightward arrow key.
+Text may be inserted at the cursor position. The Delete key removes the
+character under the cursor. Upward and Downward arrow keys navigate through
+the history of previous input lines.
+.br
+See man readline for more info about libreadline.
+.PP
+Option -page activates a builtin result text pager which may be convenient in
+dialog. After an action has put out the given number of terminal lines,
+the pager prompts the user for a line of input.
+.br
+An empty line lets xorriso resume work until the next page is put out.
+.br
+The single character "@" disables paging for the current action.
+.br
+"@@@", "x", "q", "X", or "Q" urge the current action to abort and suppress
+further result output.
+.br
+Any other line will be interpreted as new dialog line. The current action
+is urged to abort. Afterwards, the input line is executed.
+.PP
+Some actions apply paging to their info output, too.
+.br
+The urge to abort may or may not be obeyed by the current action. All actions
+try to abort as soon as possible.
+.br
+.SH OPTIONS
+.br
+All command words are shown with a leading dash although this dash is not
+mandatory for the option to be recognized. There may be future emulation
+modes, where dashes may become mandatory in order to distinguish options
+from file addresses.
+.br
+Normally any number of leading dashes is ignored with command words and
+inner dashes are interpreted as underscores.
+.TP
+.B Aquiring source and target drive:
+.TP
+\fB\-dev\fR address
+Set input and output drive to the same address and load an eventual ISO image.
+If there is no ISO image then create a blank one.
+Set the image expansion method to growing.
+.br
+This is only allowed as long as no changes are pending in the currently
+loaded ISO image. Eventually one has to perform -commit or -rollback first.
+Violation yields a FAILURE event.
+.br
+Special address string "-" means standard output, to which several restrictions
+apply. See above paragraph "Libburn drives".
+.br
+An empty address string "" gives up the current device
+without aquiring a new one.
+.TP
+\fB\-indev\fR address
+Set input drive and load an eventual ISO image. If the new input drive differs
+from -outdev then switch from growing to modifying. The same rules and
+restrictions apply as with -dev.
+.TP
+\fB\-outdev\fR address
+Set output drive and if it differs from the input drive then switch from
+growing to modifying. Unlike -dev and -indev this action does not load a
+new ISO image. So it can be performed even if there are pending changes.
+.br
+-outdev can be performed without previous -dev or -indev. In that case an
+empty ISO image with no changes pending is created. It can either be populated
+by help of -add or it can be discarded silently if -dev or -indev are
+performed afterwards.
+.br
+Special address string "-" means standard output, to which several restrictions
+apply. See above paragraph "Libburn drives".
+.br
+An empty address string "" gives up the current output drive
+without aquiring a new one. No writing is possible without an output drive.
+.TP
+\fB\-load\fR entity id
+Load a particular (possibly outdated) ISO image from a -dev or -indev which
+hosts more than one session. Usually all available sessions are shown with
+option -toc.
+.br
+entity depicts the kind of addressing. id depicts the particular
+address. The following entities are defined:
+.br
+"auto" with any id addresses the last session in -toc. This is the default.
+.br
+"session" with id being a number as of a line "ISO session", column "Idx".
+.br
+"track" with id being a number as of a line "ISO track", column "Idx".
+.br
+"lba" or "sbsector" with a number as of a line "ISO ...", column "sbsector".
+.br
+"volid" with a text as of a line "ISO ...", column "Volume Id".
+.br
+Adressing a non-existing entity or one which does not represent an ISO
+image will either abandon -indev or at least lead to a blank image.
+.br
+If an input drive is set at the moment when -load is executed, then the
+addressed ISO image is loaded immediately. Else, the setting will be pending
+until the next -dev or -indev. After the image has been loaded once, the
+setting is valid for -rollback until next -dev or -indev, where it
+will be reset to "auto".
+.TP
+\fB\-rom_toc_scan\fR "on"|"off"
+Read-only drives do not tell the actual media type but show any media as
+ROM (e.g. as DVD-ROM). The session history of MMC multi-session media might
+be truncated to first and last session or even be completely false.
+(The eventual emulated history of overwriteable media is not affected by this.)
+.br
+To have in case of failure a chance of getting the session history and
+especially the address of the last session, there is a scan for ISO 9660
+filesystem headers which might help but also might yield worse results
+than the drive's table of content. At its end it can cause read attempts
+to invalid addresses and thus ugly drive behavior.
+.br
+To be in effect, -rom_toc_scan has to be enabled by "on" before the -*dev
+command which aquires drive and media.
+.TP
+\fB\-ban_stdio_write\fR
+Allow for writing only the usage of MMC optical drives. Disallow
+to write the result into files of nearly arbitrary type.
+Once set, this command cannot be revoked.
+.TP
+.B Data manipulations:
+.PP
+The following commands expect file addresses of two kinds:
+.br
+.B disk_path
+is a path to an object in the local filesystem tree.
+.br
+.B iso_rr_path
+is the Rock Ridge name of a file object in the ISO image. (Do not
+confuse with the lowlevel ISO 9660 names visible if Rock Ridge gets ignored.)
+.PP
+Note that in the ISO image you are as powerful as the superuser. Access
+permissions of the existing files in the image do not apply to your write
+operations. They are intended to be in effect with the read-only mounted image.
+.PP
+If the iso_rr_path of a newly inserted file leads to an existing
+file object in the ISO image, then the following collision handling
+happens:
+.br
+If both objects are directories then they get merged by recursively inserting
+the subobjects from filesystem into ISO image.
+If other file types collide then the setting of command
+.B \-overwrite
+decides.
+.br
+Renaming of files has similar collision handling, but directories can only
+be replaced, not merged. Directories can hardly collide on renaming because
+of the shell-like behavior of -mv: if a file object hits an existing directory
+then it gets inserted rather than trying to replace that directory.
+Nevertheless, the overwriting rules apply if an operation of xorriso
+ever attempts to do such a replacement.
+.PP
+The commands in this section alter the ISO image and not the local filesystem.
+.TP
+\fB\-iso_rr_pattern\fR "on"|"ls"|"off"
+Set the pattern expansion mode for the iso_rr_path arguments of several
+commands which support this feature.
+.br
+.B Pattern expansion
+converts a list of pattern words into a list of existing file addresses.
+Eventual unmatched pattern words appear themselves in that result list, though.
+.br
+Pattern matching supports the usual shell parser wildcards '*' '?' '[xyz]'
+and respects '/' as separator which may only be matched literally.
+.br
+Setting "off" disables this feature for all commands which are marked in this
+man page by "iso_rr_path [***]" or "iso_rr_pattern [***]".
+.br
+Setting "on" enables it for all those commands.
+.br
+Setting "ls" enables it only for those which are marked by
+"iso_rr_pattern [***]".
+.br
+Default is "on".
+.TP
+\fB\-disk_pattern\fR "on"|"ls"|"off"
+Set the pattern expansion mode for the disk_path arguments of several
+commands which support this feature.
+.br
+Setting "off" disables this feature for all commands which are marked in this
+man page by "disk_path [***]" or "disk_pattern [***]".
+.br
+Setting "on" enables it for all those commands.
+.br
+Setting "ls" enables it only for those which are marked by
+"disk_pattern [***]".
+.br
+Default is "ls".
+.TP
+\fB\-add\fR pathspec [...] | disk_path [***]
+Insert the given files or directory trees from filesystem
+into the ISO image.
+.br
+If -pathspecs is set to "on" then pattern expansion is always disabled and
+character '=' has a special meaning. It eventually separates the ISO image path
+from the disk path:
+.br
+iso_rr_path=disk_path
+.br
+The separator '=' can be escaped by '\\'.
+If iso_rr_path does not begin with '/' then -cd is prepended.
+If disk_path does not begin with '/' then -cdx is prepended.
+.br
+If no '=' is given then the word is used as both, iso_rr_path and disk path.
+If in this case the word does not begin with '/' then -cdx is prepended to
+the disk_path and -cd is prepended to the iso_rr_path.
+.br
+If -pathspecs is set to "off" then eventual -disk_pattern expansion applies.
+The resulting words are used as both, iso_rr_path and disk path. Eventually
+-cdx gets prepended to disk_path and -cd to iso_rr_path.
+.TP
+\fB\-add_plainly\fR mode
+If set to mode "unknown" then any command word that does not begin with "-" and
+is not recognized as known command will be subject to a virtual -add command.
+I.e. it will be used as pathspec or as disk_path and added to the image.
+Eventually -disk_pattern expansion applies to disk_paths.
+.br
+Mode "dashed" is similar to "unknown" but also adds unrecognized command
+words even if they begin with "-".
+.br
+Mode "any" announces that all further words are to be added as pathspecs
+or disk_paths. This does not work in dialog mode.
+.br
+Mode "none" is the default. It prevents any words from being understood
+as files to add, if they are not parameters to appropriate commands.
+.TP
+\fB\-path_list\fR disk_path
+Like -add but read the parameter words from file disk_path
+or standard input if disk_path is "-".
+The list must contain exactly one pathspec resp. disk_path pattern per line.
+.TP
+\fB\-map\fR disk_path iso_rr_path
+Insert file object disk_path into the ISO image as iso_rr_path. If disk_path
+is a directory then its whole sub tree is inserted into the ISO image.
+.TP
+\fB\-map_single\fR disk_path iso_rr_path
+Like -map, but if disk_path is a directory then its sub tree is not inserted.
+.TP
+\fB\-update\fR disk_path iso_rr_path
+Compare file object disk_path with file object iso_rr_path. If they do not
+match, then perform the necessary image manipulations to make iso_rr_path
+a matching copy of disk_path. This comparison will imply lengthy content
+reading before a decision is made. On the other hand it strives for the
+smallest possible amount of add-on data which is needed to achieve the
+matching copy.
+.br
+If disk_path is a directory and iso_rr_path does not exist yet, then the
+whole subtree will be inserted. Else only directory attributes will be
+updated.
+.TP
+\fB\-update_r\fR disk_path iso_rr_path
+Like -update but working recursively. I.e. all file objects below both
+addresses get compared whether they have counterparts below the other address
+and whether both counterparts match. If there is a mismatch then the necessary
+update manipulation is done.
+.br
+Note that the comparison result may depend on option -follow. Its setting
+should always be the same as with the first adding of disk_path as iso_rr_path.
+.br
+If iso_rr_path does not exist yet, then it gets added. If disk_path does not
+exist, then iso_rr_path gets deleted.
+.br
+-update_r is also a convenient compromise between -add addressing and -cpr
+addressing: Its semantics is similar to -add and thus avoids the pitfalls
+inherited from cp -r behavior. Its syntax resembles cp, though.
+.TP
+\fB\-cut_out\fR disk_path byte_offset byte_count iso_rr_path
+Map a byte interval of a regular disk file into a regular file in the ISO
+image.
+This may be necessary if the disk file is larger than a single media, or if
+it exceeds the traditional limit of 2 GiB - 1 for old operating systems,
+or the limit of 4 GiB - 1 for newer ones.
+.br
+A clumsy remedy for this limit is to backup file pieces and to concatenate
+them at restore time. A well tested chopping size is 2047m.
+It is permissible to request a higher byte_count than available. The
+resulting file will be truncated to the correct size of a final piece.
+To request a byte_offset higher than available yields no file in
+the ISO image but a SORRY event.
+E.g:
+.br
+ -cut_out /my/disk/file 0 2047m \\
+.br
+ /file/part_1_of_3_at_0_with_2047m_of_5753194821 \\
+.br
+ -cut_out /my/disk/file 2047m 2047m \\
+.br
+ /file/part_2_of_3_at_2047m_with_2047m_of_5753194821 \\
+.br
+ -cut_out /my/disk/file 4094m 2047m \\
+.br
+ /file/part_3_of_3_at_4094m_with_2047m_of_5753194821
+.br
+-cut_out is coordinated with -compare* and -update* if the names of the
+part files follow a convention by which xorriso is able to recognize
+file parts and process them accordingly:
+.br
+A disk file gets mapped to an ISO directory containing its split parts
+as regular files. The parts have names which describe the splitting
+by 5 numbers which are separated by some non-numerical text:
+.br
+part_number, total_parts, byte_offset, byte_count, disk_file_size
+.br
+Scaling characters like "m" or "k" are taken into respect and may
+serve as separators as well. All digits are interpreted as decimal,
+even if leading zeros are present.
+.br
+Not all parts have to be present on the same media. But those parts
+which are present have to sit in the same directory. No other files
+are allowed in there. Parts have to be disjoint. Their numbers have
+to be plausible. E.g. byte_count must be valid as -cut_out argument
+and it must be the same with all parts.
+.br
+If the disk file grows enough to need new parts then those get added
+to the directory if it already contains all parts of the old disk file.
+If not all parts are present, then only those present parts will
+be updated.
+.TP
+\fB\-cpr\fR disk_path [***] iso_rr_path
+Insert the given files or directory trees from filesystem
+into the ISO image.
+.br
+The rules for generating the ISO addresses are similar as with
+shell command cp -r. Nevertheless, directories of the iso_rr_path
+are created if necessary. Especially a not yet existing iso_rr_path
+will be handled as directory if multiple disk_paths are present.
+The leafnames of the multiple disk_paths will be grafted under that
+directory as would be done with an existing directory.
+.br
+If a single disk_path is present then a non-existing iso_rr_path will
+get the same type as the disk_path.
+.br
+If a disk_path does not begin with '/' then -cdx is prepended.
+If the iso_rr_path does not begin with '/' then -cd is prepended.
+.TP
+\fB\-rm\fR iso_rr_path [***]
+Delete the given files from the ISO image.
+.br
+Note: This does not free any space on the -indev media, even if
+the deletion is committed to that same media.
+.br
+The image size will shrink if the image is written to a different
+media in modification mode.
+.TP
+\fB\-rm_r\fR iso_rr_path [***]
+Delete the given files or directory trees from the ISO image.
+See also the note with option -rm.
+.TP
+\fB\-mv\fR iso_rr_path [***] iso_rr_path
+Rename the given file objects in the ISO tree to the last
+argument in the list. Use the same rules as with shell command mv.
+.br
+If pattern expansion is enabled and if the last argument contains wildcard
+characters then it must match exactly one existing file address, or else the
+command fails with a FAILURE event.
+.TP
+\fB\-chown\fR uid iso_rr_path [***]
+Set ownership of file objects in the ISO image. uid may either be a decimal
+number or the name of a user known to the operating system.
+.TP
+\fB\-chown_r\fR uid iso_rr_path [***]
+Like -chown but affecting all files below eventual directories.
+.TP
+\fB\-chgrp\fR gid iso_rr_path [***]
+Set group attribute of file objects in the ISO image. gid may either be a
+decimal number or the name of a group known to the operating system.
+.TP
+\fB\-chgrp_r\fR gid iso_rr_path [***]
+Like -chgrp but affecting all files below eventual directories.
+.TP
+\fB\-chmod\fR mode iso_rr_path [***]
+Equivalent to shell command chmod in the ISO image.
+mode is either an octal number beginning with "0" or a comma separated
+list of statements of the form [ugoa]*[+-=][rwxst]* .
+.br
+Like: go-rwx,u+rwx .
+.br
+.B Personalities:
+u=user, g=group, o=others, a=all
+.br
+.B Operators:
++ adds given permissions, - revokes given permissions,
+= revokes all old permissions and then adds the given ones.
+.br
+.B Permissions:
+r=read, w=write, x=execute|inspect, s=setuid|setgid, t=sticky bit
+.br
+For octal numbers see man 2 stat.
+.TP
+\fB\-chmod_r\fR mode iso_rr_path [***]
+Like -chmod but affecting all files below eventual directories.
+.TP
+\fB\-alter_date\fR type timestring iso_rr_path [***]
+Alter the date entries of a file in the ISO image. type is
+one of "a", "m", "b" for access time, modification time,
+both times.
+.br
+timestring may be in the following formats
+(see also section EXAMPLES):
+.br
+As expected by program date:
+ MMDDhhmm[[CC]YY][.ss]]
+.br
+As produced by program date:
+ [Day] MMM DD hh:mm:ss [TZON] YYYY
+.br
+Relative times counted from current clock time:
+ +|-Number["s"|"h"|"d"|"w"|"m"|"y"]
+.br
+where "s" means seconds, "h" hours, "d" days, "w" weeks, "m"=30d,
+"y"=365.25d plus 1d added to multiplication result.
+.br
+Absolute seconds counted from Jan 1 1970:
+ =Number
+.br
+xorriso's own timestamps:
+ YYYY.MM.DD[.hh[mm[ss]]]
+.br
+scdbackup timestamps:
+ YYMMDD[.hhmm[ss]]
+.br
+where "A0" is year 2000, "B0" is 2010, etc.
+.TP
+\fB\-alter_date_r\fR type timestring iso_rr_path [***]
+Like -alter_date but affecting all files below eventual directories.
+.TP
+\fB\-find\fR iso_rr_path [-name pattern] [-type t] [-exec action [params]] --
+A very restricted substitute for shell command find in the ISO image.
+It performs an action on matching file objects at or below iso_rr_path.
+.br
+Optional -name pattern is not expanded but used for comparison with
+the particular file names of the eventual directory tree underneath
+iso_rr_path. If no -name pattern is given, then any file name matches.
+.br
+The optional -type test restricts matching to files of the given type:
+"block", "char", "dir", "pipe", "file", "link", "socket",
+"Xotic" which eventually matches what is not matched by the other types.
+.br
+Only the first letter is interpreted. E.g.: -find / -type d
+.br
+If a file matches then the action is performed. Default action is "echo",
+i.e. to print the address of the found file. Other actions are certain
+xorriso commands which get performed on the found files. These commands
+may have specific parameters. See also their particular descriptions.
+.br
+"chown" and "chown_r" change the ownership and get the user id as param. E.g.:
+.br
+ -find / -exec chown thomas --
+.br
+"chgrp" and "chgrp_r" change the group attribute and get the group id as param.
+E.g.:
+.br
+ -find / name 'news*' -type d -exec chgrp_r staff --
+.br
+"chmod" and "chmod_r" change access permissions and get a mode string as param.
+E.g.:
+.br
+ -find / -exec chmod a-w,a+r --
+.br
+"alter_date" and "alter_date_r" change the timestamps.
+They get a type character and a timestring as params.
+E.g.:
+.br
+ -find / -exec alter_date "m" "Dec 30 19:34:12 2007" --
+.br
+"lsdl" prints file information like shell command ls -dl.
+E.g.:
+.br
+ -find / -exec lsdl --
+.br
+"compare" performs command -compare with the found file address as iso_rr_path
+and the corresponding file address below its argument disk_path_start. For this
+the iso_rr_path of the -find command gets replaced by the disk_path_start.
+E.g.:
+.br
+ -find / -exec compare /home/thomas --
+.br
+"update" performs command -update with the found file address as iso_rr_path.
+The corresponding file address is determined like with above "compare".
+.br
+E.g.:
+.br
+ -find / -exec update /home/thomas --
+.br
+"rm" removes the found iso_rr_path from the image if it is not a directory with
+files in it. I.e. this "rm" includes "rmdir".
+.br
+E.g.:
+.br
+ -find / -name *.doc -exec rm --
+.br
+"rm_r" removes the found iso_rr_path from the image, including whole directory
+trees.
+.br
+E.g.:
+.br
+ -find /uh/oh -name *private* -exec rm_r --
+.br
+"find" performs another run of -find on the matching file address. It accepts
+the same params as -find, except iso_rr_path.
+E.g.:
+.br
+ -find / -name '???' -type d -exec find -name '[abc]*' -exec chmod a-w,a+r --
+.br
+If not used as last command in the line then the argument list
+needs to get terminated by "--".
+.TP
+\fB\-mkdir\fR iso_rr_path [...]
+Create empty directories if they do not exist yet.
+Existence as directory generates a WARNING event, existence as
+other file causes a FAILURE event.
+.TP
+\fB\-rmdir\fR iso_rr_path [***]
+Delete empty directories.
+.TP
+\fB\-\-\fR
+.br
+Mark end of particular action argument list.
+.TP
+\fB\-rollback\fR
+Discard the manipulated ISO image and reload it from -indev.
+.TP
+\fB\-rollback_end\fR
+Discard the manipulated ISO image. End program without loading a new image.
+.TP
+.B Writing the result:
+(see also paragraph about settings below)
+.TP
+\fB\-commit\fR
+Perform the write operation. Afterwards eventually make the
+-outdev the new -dev and load the image from there.
+Switch from eventual modifiying mode to growing mode.
+(A subsequent -outdev will activate modification mode.)
+-commit is performed automatically at end of program if there
+are uncommitted manipulations pending.
+So, to perform a final write operation with no new -dev
+and no new loading of image, rather execute option -end.
+To suppress a final write, execute -rollback -end.
+To eject outdev after write without new loading of image, use -commit_eject.
+.br
+
+Writing can last quite a while. It is not unnormal with several
+types of media that there is no progress visible for the first
+few minutes or that the drive gnaws on the media for a few
+minutes after all data have been transmitted.
+xorriso and the drives are in a client-server relationship.
+The drives have much freedom about what to do with the media.
+Some combinations of drives and media simply do not work,
+despite the promises by their vendors.
+If writing fails - or even the drive gets stuck and you need
+to reboot - then try other media or another drive. The reason
+for such failure is hardly ever in the code of the various
+burn programs but you may well try some of those listed below
+under SEE ALSO.
+.TP
+\fB\-eject\fR "in"|"out"|"all"
+Eject the media in -indev, resp. -outdev, resp. both drives.
+Note: It is not possible yet to effectively eject disk files.
+.TP
+\fB\-commit_eject\fR "in"|"out"|"all"|"none"
+Combined -commit and -eject. When writing has finished do not make
+-outdev the new -dev, and load no ISO image. Rather eject
+-indev and/or -outdev. Eventually give up any non-ejected drive.
+.TP
+\fB\-blank\fR mode
+Make media ready for writing from scratch (if not -dummy is activated).
+.br
+This affects only the -outdev not the -indev.
+If both drives are the same and if the ISO image was altered
+then this command leads to a FAILURE event.
+Defined modes are:
+ as_needed, fast, all, deformat, deformat_quickest
+.br
+"as_needed" cares for used CD-RW, DVD-RW and for used overwriteable media
+by applying -blank "fast". It applies -format "full" to yet unformatted
+DVD-RAM or BD-RE.
+.br
+"fast" and "all" make CD-RW and unformatted DVD-RW re-usable,
+or invalidate overwriteable ISO images.
+.br
+"deformat" converts overwriteable DVD-RW into unformatted ones.
+.br
+"deformat_quickest" is a faster way to deformat or blank DVD-RW
+but produces media which are only suitable for a single session.
+xorriso will write onto them only if option -close is set to "on".
+.br
+The progress reports issued by some drives while blanking are
+quite unrealistic. Do not conclude success or failure from the
+reported percentages. Blanking was successful if no SORRY event or
+worse occured.
+.TP
+\fB\-format\fR mode
+Convert unformatted DVD-RW into overwriteable ones, "de-ice" DVD+RW, format
+newly purchased BD-RE, re-format DVD-RAM or BD-RE.
+.br
+Defined modes are:
+.br
+ as_needed, full, fast, by_index_, fast_by_index_
+.br
+"as_needed" formats yet unformatted DVD-RW, DVD-RAM, BD-RE. Other media
+are left untouched.
+.br
+"full" (re-)formats DVD-RW, DVD+RW, DVD-RAM, BD-RE.
+.br
+"fast" does the same as "full" but tries to be quicker.
+.br
+"by_index_" selects a format out of the descriptor list issued by option
+-list_formats. The index number from that list is to be appended to the
+mode word. E.g: "by_index_3".
+.br
+"fast_by_index_" does the same as "by_index_" but tries to be quicker.
+.br
+The formatting action has no effect on media if -dummy is activated.
+.br
+Formatting is normally needed only once during the lifetime of a media,
+if ever. But it is a reason for re-formatting if:
+.br
+ DVD-RW was deformatted by -blank,
+.br
+ DVD+RW has read failures (re-formatting might help or not),
+.br
+ DVD-RAM or BD-RE shall change their amount of defect reserve.
+.br
+The progress reports issued by some drives while formatting are
+quite unrealistic. Do not conclude success or failure from the
+reported percentages. Formatting was successful if no SORRY event
+or worse occured. Be patient with apparently frozen progress.
+.TP
+\fB\-list_formats\fR
+Put out a list of format descriptors as reported by the output drive for
+the current media. The list gives the index number after "Format idx",
+a MMC format code, the announced size in blocks (like "2236704s")
+and the same size in MiB.
+.br
+MMC format codes are manifold. Most important are:
+"00h" general formatting, "01h" increases reserve space for DVD-RAM,
+"26h" for DVD+RW, "30h" for BD-RE with reserve space,
+"31h" for BD-RE without reserve space.
+.br
+Smaller format size with DVD-RAM or BD-RE means more reserve space.
+.TP
+.B Settings for data insertion:
+.TP
+\fB\-not_mgt\fR code[:code[...]]
+Control the behavior of the exclusion lists.
+.br
+Exclusion processing happens before disk_paths get mapped to the ISO image
+and before disk files get compared with image files.
+The absolute disk path of the source is matched against the -not_paths list.
+The leafname of the disk path is matched against the patterns in the -not_leaf
+list. If a match is detected then the disk path will not be regarded as an
+existing file and not be added to the ISO image.
+.br
+Several codes are defined.
+The _on/_off settings persist until they are revoked by their_off/_on
+counterparts.
+.br
+"erase" empties the lists which were accumulated by -not_paths and -not_leaf.
+.br
+"reset" is like "erase" but also re-installs default behavior.
+.br
+"off" disables exclusion processing temporarily without invalidating
+the lists and settings.
+.br
+"on" re-enables exclusion processing.
+.br
+"param_off" applies exclusion processing only to paths below disk_path
+parameter of commands. I.e. explicitely given disk_paths are exempted
+from exclusion processing.
+.br
+"param_on" applies exclusion processing to command parameters as well as
+to files below such parameters.
+.br
+"subtree_off" with "param_on" excludes parameter paths only if they
+match a -not_paths item exactly.
+.br
+"subtree_on" additionally excludes parameter paths which lead to a file
+address below any -not_paths item.
+.br
+"ignore_off" treats excluded disk files as if they were missing. I.e. they
+get reported with -compare and deleted from the image with -update.
+.br
+"ignore_on" keeps excluded files out of -compare or -update activities.
+.TP
+\fB\-not_paths\fR disk_path [***]
+Add the given paths to the list of excluded absolute disk paths. If a given
+path is relative, then the current -cdx is prepended to form an absolute path.
+Eventual pattern matching happens at definition time and not when exclusion
+checks are made.
+.br
+(Do not forget to end the list of disk_paths by "--")
+.TP
+\fB\-not_leaf\fR pattern
+Add a single shell parser style pattern to the list of exclusions for
+disk leafnames. These patterns are evaluated when the exclusion checks are
+made.
+.TP
+\fB\-follow\fR occasion[:occasion[...]]
+Enable or disable resolution of symbolic links and mountpoints under
+disk_paths. This applies to actions -add, -du*x, -ls*x, -findx,
+and to -disk_pattern expansion.
+.br
+There are two kinds of follow decisison to be made:
+.br
+"link" is the hop from a symbolic link to its target file object.
+If enabled then symbolic links are handled as their target file objects,
+else symbolic links are handled as themselves.
+.br
+"mount" is the hop from one filesystem to another subordinate filesystem.
+If enabled then mountpoint directories are handled as any other directory,
+else mountpoints are handled as empty directories if they are encountered in
+directory tree traversals.
+.br
+Less general than above occasions:
+.br
+"pattern" is mount and link hopping, but only during -disk_pattern expansion.
+.br
+"param" is link hopping for parameter words (after eventual pattern expansion).
+If enabled then -ls*x will show the link targets rather than the links
+themselves. -du*x, -findx, and -add will process the link targets but not
+follow links in an eventual directory tree below the targets (unless "link"
+is enabled).
+.br
+Occasions can be combined in a colon separated list. All occasions
+mentioned in the list will then lead to a positive follow decision.
+.br
+"off" prevents any positive follow decision. Use it if no other occasion
+applies.
+.br
+Shortcuts:
+.br
+"default" is equivalent to "pattern:mount:limit=100".
+.br
+"on" always decides positive. Equivalent to "link:mount".
+.br
+
+Not an occasion but an optional setting is:
+.br
+"limit=" which sets the maximum number of link hops.
+A link hop consists of a sequence of symbolic links and a final target
+of different type. Nevertheless those hops can loop. Example:
+.br
+ \fB$\fR ln -s .. uploop
+.br
+Link hopping has a builtin loop detection which stops hopping at the first
+repetition of a link target. Then the repeated link is handled as itself
+and not as its target.
+Regrettably one can construct link networks which
+cause exponential workload before their loops get detected.
+The number given with "limit=" can curb this workload at the risk of truncating
+an intentional sequence of link hops.
+.TP
+\fB\-pathspecs\fR "on"|"off"
+Control parameter interpretation with xorriso actions -add and -path_list.
+.br
+"on" enables pathspecs of the form
+.B target=source
+like with program mkisofs -graft-points.
+It also disables -disk_pattern expansion for command -add.
+.br
+"off" disables pathspecs of the form target=source
+and eventually enables -disk_pattern expansion.
+.TP
+\fB\-overwrite\fR "on"|"nondir"|"off"
+Allow or disallow to overwrite existing files in the
+ISO image by files with the same user defined name.
+.br
+With setting "off", name collisions cause FAILURE events.
+With setting "nondir", only directories are protected by such events, other
+existing file types get treated with -rm before the new file gets added.
+Setting "on" allows automatic -rm_r. I.e. a non-directory can replace an
+existing directory and all its subordinates.
+.TP
+\fB\-split_size\fR number["k"|"m"]
+Set the threshold for automatic splitting of regular files. Such splitting
+maps a large disk file onto a ISO directory with several part files in it.
+This is necessary if the size of the disk file exceeds 4 GiB - 1.
+Older operating systems can handle files only if they are smaller than 2 GiB.
+See also option -cut_out for more information about file parts.
+.br
+Default is 0 which will exclude files >= 4 GiB by a FAILURE event.
+A well tested -split_size is 2047m. Sizes of 4 GiB or more are not permissible.
+.TP
+.B Settings for result writing:
+.TP
+Rock Ridge info will be generated by the program unconditionally.
+.TP
+\fB\-joliet\fR "on"|"off"
+If enabled by "on", generate Joliet info additional to Rock Ridge info.
+.TP
+\fB\-volid\fR text
+Specifies the volume ID. xorriso accepts any text up to 32 characters,
+but according to rarely obeyed specs stricter rules apply:
+.br
+ECMA 119 demands character set [A-Z0-9_]. Like: "IMAGE_23"
+.br
+Joliet allows 16 UCS-2 characters. Like: "Windows name"
+.br
+Be aware that the volume id might get used automatically as name of the
+mount point when the media is inserted into a playful computer system.
+.br
+If an ISO image gets loaded while the volume ID is set to default "ISOIMAGE"
+or to "", then the volume ID of the loaded image will become the effective
+volume id for the next write run. But as soon as command -volid is performed
+afterwards, this pending id is overridden by the new setting.
+.br
+Consider this when setting -volid "ISOIMAGE" before executing -dev, -indev,
+or -rollback.
+If you insist in -volid "ISOIMAGE", set it again after those commands.
+.TP
+\fB\-uid\fR uid
+User id to be used for all files when the new ISO tree gets written to media.
+.TP
+\fB\-gid\fR gid
+Group id to be used for all files when the new ISO tree gets written to media.
+.TP
+\fB\-speed\fR number[k|m|c|d]
+Set the burn speed. Default is 0 = maximum speed.
+Speed can be given in media dependent numbers or as a
+desired throughput per second in MMC compliant kB (= 1000)
+or MB (= 1000 kB). Media x-speed factor can be set explicity
+by "c" for CD and "d" for DVD. Example speeds:
+.br
+ 706k = 706kB/s = 4c = 4xCD
+.br
+ 5540k = 5540kB/s = 4d = 4xDVD
+.br
+If there is no hint about the speed unit attached, then the
+media in the -outdev will decide. Default unit is CD = 176.4k.
+.br
+MMC drives usually activate their own idea of speed and take
+the speed value given by the burn program only as upper limit
+for their own decision.
+.TP
+\fB\-dummy\fR "on"|"off"
+If "on" simulate burning or refuse with FAILURE event if
+no simulation is possible, do neither blank nor format.
+.TP
+\fB-fs\fR number["k"|"m"]
+Set the size of the fifo buffer which smoothens the data
+stream from ISO image generation to media burning. Default
+is 4 MiB, minimum 64 kiB, maximum 1 GiB.
+The number may be followed by letter "k" or "m"
+which means unit is kiB (= 1024) or MiB (= 1024 kiB).
+.TP
+\fB\-close\fR "on"|"off"
+If "on" then mark the written media as not appendable
+any more (if possible at all with the given type of target media).
+.br
+This is the contrary of cdrecord, wodim, cdrskin option -multi,
+and is one aspect of growisofs option -dvd-compat.
+.TP
+\fB\-padding\fR number["k"|"m"]
+Append the given number of extra bytes to the image stream.
+This is a traditional remedy for a traditional bug in block
+device read drivers. Needed only for CD recordings in TAO mode.
+Since one can hardly predict on what media an image might end up,
+xorriso adds the traditional 300k of padding by default to all images.
+.br
+For images which will never get to a CD it is safe to use -padding 0 .
+.TP
+\fB\-boot_image\fR "any"|"isolinux" "discard"|"keep"|"patch"
+Defines the handling of an eventual boot image (El-Torito) which has been read
+from an existing ISO image. All types ("any") can be discarded or kept
+unaltered. The latter makes only sense if the format of the boot image is
+relocatable without content changes.
+.br
+The boot image type "isolinux" can be kept unaltered (not advisable), or
+discarded, or it can be patched to match its relocation. In the latter case
+the resulting ISO image is bootable if the boot image was really complying
+to the isolinux standard.
+.br
+Creation of new boot images is not yet possible.
+.br
+CAUTION:
+This is an expert option. xorriso is not an expert yet.
+It cannot recognize the inner form of boot images.
+So the user has already to know about the particular needs of the
+bootimage which is present on the input media.
+Most safe is the default: "any" "discard".
+.TP
+.B Exception processing:
+.PP
+Since the tasks of xorriso are manifold and prone to external influence, there
+may arise the need for xorriso to report and handle problem events.
+.br
+Those events get classified when they are detected by one of the software
+modules and forwarded to reporting and evaluation modules which decide about
+reactions. Event classes are sorted by severity:
+.br
+"NEVER" The upper end of the severity spectrum.
+.br
+"ABORT" The program is being aborted and on its way to end.
+.br
+"FATAL" The main purpose of the run failed
+or an important resource failed unexpectedly.
+.br
+"FAILURE" An important part of the job could not be performed.
+.br
+"MISHAP" A FAILURE which can be tolerated during ISO image generation.
+.br
+"SORRY" A less important part of the job could not be performed.
+.br
+"WARNING" A situation is suspicious of being not intended by the user.
+.br
+"HINT" A proposal to the user how to achieve better results.
+.br
+"NOTE" A harmless information about noteworthy circumstances.
+.br
+"UPDATE" A pacifier message during long running operations.
+.br
+"DEBUG" A message which would only interest the program developers.
+.br
+"ALL" The lower end of the severity spectrum.
+.TP
+\fB\-abort_on\fR severity
+Set the severity threshold for events to abort the program.
+.br
+Useful: "NEVER", "ABORT", "FATAL", "FAILURE" , "MISHAP", "SORRY"
+.br
+It may become necessary to abort the program anyway, despite
+the setting by this option. Expect not many "ABORT" events to
+be ignorable.
+.br
+A special property of this option is that it works preemptive if given as
+program start argument. I.e. the first -abort_on setting among the
+start arguments is in effect already when the first operations of xorriso
+begin. Only "-abort_on" with dash "-" is recognized that way.
+.TP
+\fB\-return_with\fR severity exit_value
+Set the threshold and exit_value to be returned at program end if no abort
+has happened. This is to allow xorriso to go on after problems but to get
+a failure indicating exit value from the program, nevertheless.
+Useful is a value lower than the -abort_on threshold, down to "WARNING".
+.br
+exit_value may be either 0 (indicating success to the starter of the program)
+or a number between 32 and 63. Some other exit_values are used by xorriso if
+it decides to abort the program run:
+.br
+1=abort due to external signal
+.br
+2=no program arguments given
+.br
+3=creation of xorriso main object failed
+.br
+4=failure to start libburnia-project.org libraries
+.br
+5=program abort during argument processing
+.br
+6=program abort during dialog processing
+.TP
+\fB\-report_about\fR severity
+Set the threshold for events to be reported.
+.br
+Useful: "SORRY", "WARNING", "HINT", "NOTE", "UPDATE", "DEBUG", "ALL"
+.br
+Regardless what is set by -report_about, messages get always reported if they
+reach the severity threshold of -abort_on .
+.br
+Event messages are sent to the info channel "I" which is usually stderr
+but may be influenced by command -pkt_output.
+Info messages which belong to no event get attributed severity "NOTE".
+.br
+A special property of this option is that the first -report_about setting
+among the start arguments is in effect already when the first operations
+of xorriso begin. Only "-report_about" with dash "-" is recognized that way.
+.TP
+\fB\-error_behavior\fR occasion behavior
+Control the program behavior at problem event occasions.
+.br
+For now this applies only to occasion "image_loading" which is given while
+an image tree is read from the input device. There are three behaviors
+available:
+.br
+"best_effort" goes on with reading after events with severity below FAILURE
+if the threshold of option -abort_on allows this.
+.br
+"failure" aborts image tree reading on first event of at least SORRY.
+It issues an own FAILURE event.
+.br
+"fatal" acts like "failure" but issues the own event as FATAL.
+This is the default.
+.TP
+.B Dialog mode control:
+.TP
+\fB\-dialog\fR "on"|"off"
+Enable or disable to enter dialog mode after all arguments
+are processed. In dialog mode input lines get prompted via
+readline or from stdin.
+.TP
+\fB\-page\fR length width
+Describe terminal to the text pager. See also above, paragraph Result pager.
+.br
+If parameter length is nonzero then the user gets prompted after that
+number of terminal lines. Zero length disables paging.
+.br
+Parameter width is the number of characters per terminal line. It is used
+to compute the number of terminal lines which get occupied by an output line.
+A usual terminal width is 80.
+.TP
+\fB\-use_readline\fR "on"|"off"
+If "on" then use readline for dialog. Else use plain stdin.
+.br
+See also above, paragraph Dialog, Readline, Result pager.
+.TP
+\fB\-reassure\fR "on"|"tree"|"off"
+If "on" then ask the user for "y" or "n":
+.br
+before deleting or overwriting any file in the ISO image,
+.br
+before rolling back pending image changes,
+.br
+before committing image changes to media,
+.br
+before changing the input drive,
+.br
+before blanking or formatting media,
+.br
+before ending the program.
+.br
+With setting "tree" the reassuring prompt will appear for an eventual
+directory only once and not for each file in its whole subtree.
+.br
+Setting "off" silently kills any kind of image file object resp. performs
+above irrevocable actions.
+.br
+To really produce user prompts, option -dialog needs to be set to "on".
+Note that the prompt does not appear in situations where file removal
+is forbidden by option -overwrite. -reassure only imposes an additional
+curb for removing existing file objects.
+.br
+Be aware that file objects get deleted from the ISO image immediately
+after confirmation. They are gone even if the running command gets aborted
+and its desired effect gets revoked. In case of severe mess-up, consider to
+use -rollback to revoke the whole session.
+.TP
+.B Drive and media related inquiry actions:
+.TP
+\fB\-toc\fR
+.br
+Show media specific table of content. This is the media session history,
+not the ISO image directory tree.
+.br
+In case of overwriteable media holding a valid ISO image, a single session
+gets fabricated from the ISO image size info. But if the first session on the
+overwriteable media was written by xorriso then in most cases a complete
+session history can be emulated.
+.br
+A drive which is incapable of writing may show any media as CD-ROM or DVD-ROM
+with only one or two sessions on it. The last of these sessions is supposed
+to be the most recent real session then.
+.br
+Some read-only drives and media show no usable session history at all.
+Eventually option -rom_toc_scan might help.
+.TP
+\fB\-devices\fR
+Show list of available MMC drives with the addresses of
+their libburn standard device files.
+.br
+This is only possible when no ISO image changes are pending.
+After this option was executed, there is no drive current
+and no image loaded. Eventually one has to aquire a drive again.
+.br
+In order to be visible, a device has to offer rw-permissions
+with its libburn standard device file. Thus it might be only the
+.B superuser
+who is able to see all drives.
+.br
+Drives which are occupied by other processes get not shown.
+.TP
+\fB\-print_size\fR
+Print the foreseeable consumption of 2048 byte blocks
+by next -commit. This can last a while as a -commit gets
+prepared and only in last moment is revoked by this option.
+.TP
+\fB\-tell_media_space\fR
+Print available space on output media and the free space after
+subtracting already foreseeable consumption by next -commit.
+.TP
+.B Navigation in ISO image and disk filesystem:
+.TP
+\fB\-cd\fR iso_rr_path
+Change the current working directory in the emerging ISO
+image as it is at the moment. This is prepended to iso_rr_paths
+which do not begin with '/'.
+.br
+It is possible to set the working directory to a path which does not exist
+yet in the ISO image. The necessary parent directories will be created when
+the first file object is inserted into that virtual directory.
+Use -mkdir if you want to enforce the existence of the directory already at
+first insertion.
+.TP
+\fB\-cdx\fR disk_path
+Change the current working directory on filesystem.
+To be prepended to disk_paths which do not begin with '/'.
+.TP
+\fB\-pwd\fR
+.br
+Tell the current working directory in the ISO image.
+.TP
+\fB\-pwdx\fR
+.br
+Tell the current working directory on local filesystem.
+.TP
+\fB\-ls\fR iso_rr_pattern [***]
+List files in the ISO image which match shell patterns
+(i.e. with wildcards '*' '?' '[a-z]').
+If a pattern does not begin with '/' then it is compared with addresses
+relative to -cd, the current working directory in the ISO image.
+.br
+Directories are listed by their content rather than as single file item.
+.br
+Pattern expansion may be disabled by command -iso_rr_pattern.
+.TP
+\fB\-lsd\fR iso_rr_pattern [***]
+Like -ls but listing directories as themselves and not by their content.
+This resembles shell command ls -d.
+.TP
+\fB\-lsl\fR iso_rr_pattern [***]
+Like -ls but also list some of the file attributes.
+Output format resembles shell command ls -ln.
+.TP
+\fB\-lsdl\fR iso_rr_pattern [***]
+Like -lsd but also list some of the file attributes.
+Output format resembles shell command ls -dln.
+.TP
+\fB\-lsx\fR disk_pattern [***]
+List files on local filesystem which match shell patterns. Patterns which do
+not begin with '/' are used relative to -cdx, the current working directory in
+the local filesystem.
+.br
+Directories are listed by their content rather than as single file item.
+.br
+Pattern expansion may be disabled by command -disk_pattern.
+.TP
+\fB\-lsdx\fR disk_pattern [***]
+Like -lsx but listing directories as themselves and not by their content.
+This resembles shell command ls -d.
+.TP
+\fB\-lslx\fR disk_pattern [***]
+Like -lsx but also listing some of the file attributes.
+Output format resembles shell command ls -ln.
+.TP
+\fB\-lsdlx\fR disk_pattern [***]
+Like -lsdx but also listing some of the file attributes.
+Output format resembles shell command ls -dln.
+.TP
+\fB\-du\fR iso_rr_pattern [***]
+Recursively list size of directories and files in the ISO image
+which match one of the patterns.
+similar to shell command du -k.
+.TP
+\fB\-dus\fR iso_rr_pattern [***]
+List size of directories and files in the ISO image
+which match one of the patterns.
+Similar to shell command du -sk.
+.TP
+\fB\-dux\fR disk_pattern [***]
+Recursively list size of directories and files in the local filesystem
+which match one of the patterns, similar to shell command du -k.
+.TP
+\fB\-dusx\fR disk_pattern [***]
+List size of directories and files in the local filesystem
+which match one of the patterns.
+Similar to shell command du -sk.
+.TP
+\fB\-findx\fR disk_path [-name pattern] [-type t] [-exec action [params]] --
+Like -find but operating on local filesystem and not on the ISO image.
+This is subject to the settings of -follow.
+.br
+Find accepts the same -type arguments as -find. Additionally it recognizes
+type "mountpoint" (or "m"). It matches subdirectories which reside on a
+different device than their parent. It never matches the disk_path
+given as start address for -findx.
+.br
+-findx accepts the -exec actions as does -find. But except the following few
+actions it will allways perform action "echo".
+.br
+"in_iso" iso_rr_path_start reports the path if its counterpart exist in
+the ISO image. For this the disk_path of the -find command gets replaced
+by iso_rr_path_start. E.g.:
+.br
+ -findx /home -exec in_iso /
+.br
+"not_in_iso" iso_rr_path_start reports the path if its counterpart does
+not exist in the ISO image. The report format is the same as with command
+-compare.
+E.g.
+.br
+ -findx /home/thomas -exec not_in_iso /thomas_on_cd
+.br
+"add_missing" iso_rr_path_start adds the counterpart if it does not yet
+exist in the ISO image.
+E.g.
+.br
+ -findx /home/thomas -exec add_missing /thomas_on_cd
+.br
+"is_full_in_iso" iso_rr_path_start reports if the counterpart in the ISO image
+contains files. To be used with -type "m" to report mount points.
+.br
+"empty_iso_dir" iso_rr_path_start deletes all files from the counterpart
+in the ISO image. To be used with -type "m" to truncate mount points.
+.TP
+\fB\-compare\fR disk_path iso_rr_path
+Compare attributes and eventual data file content of a fileobject in the
+local filesystem with a file object in the ISO image. The iso_rr_path may
+well point to an image file object which is not yet committed, i.e. of which
+the data content still resides in the local filesystem. Such data content is
+prone to externally caused changes.
+.br
+If iso_rr_path is empty then disk_path is used as path in the ISO image too.
+.br
+Differing attributes are reported in detail, differing content is summarized.
+Both to the result channel. In case of no differences no result lines are
+emitted.
+.TP
+\fB\-compare_r\fR disk_path iso_rr_path
+Like -compare but working recursively. I.e. all file objects below both
+addresses get compared whether they have counterparts below the other address
+and whether both counterparts match.
+.TP
+.B Command compatibility emulations:
+.PP
+Writing of ISO 9660 on CD is traditionally done by program mkisofs
+as ISO 9660 image producer and cdrecord as burn program.
+xorriso does not strive for their comprehensive emulation.
+Nevertheless it is ready to perform some of its core tasks under control
+of commands which in said programs trigger comparable actions.
+The scope is for now only a single first data track to be written to blank or
+overwriteable media. If possible the media will get closed afterwards.
+Multi-session is yet only possible via xorriso's own commands.
+.TP
+\fB\-as\fR personality option [options] --
+.br
+Performs its variable length option list as sparse emulation of the program
+depicted by the personality word. This is only allowed if no image changes
+are pending. The input drive is given up.
+.br
+
+Personality "\fBmkisofs\fR" accepts the options listed with:
+.br
+ -as mkisofs -help --
+.br
+Among them: -R (always on), -J, -graft-points, -o, -path-list, -m, -print-size,
+-V, -v, -version, pathspecs as with xorriso -add. A lot of options are not
+supported and lead to failure of the mkisofs emulation. Some are ignored,
+but better do not rely on this tolerance.
+.br
+-graft-points is equivalent to -pathspecs on. Note that pathspecs without "="
+are interpreted differently than with xorriso option -add. Directories get
+merged with the root directory of the ISO image, other filetypes get mapped
+into that root directory.
+.br
+Other than with the "cdrecord" personality there is no automatic -commit at
+the end of a "mkisofs" option list. Verbosity settings -v (= "UPDATE") and
+-quiet (= "SORRY") persist. The output file, eventually chosen with -o,
+persists until things happen like -commit, -rollback, -dev, or end of xorriso.
+.br
+If no output file was chosen before or during a "mkisofs" option list, then
+standard output (-outdev "-") will get into effect before pathspecs get
+added. If -o points to a regular file, then it will be truncated to 0 bytes
+when finally writing begins. This truncation does not happen if the drive
+is chosen by xorriso options before or after -as mkisofs.
+Directories and symbolic links are no valid -o targets.
+.br
+Writing to stdout is possible only if -as "mkisofs" was among the start
+arguments or if other start arguments pointed the output drive to
+standard output.
+.br
+Personalites "\fBgenisoimage\fR" and "\fBgenisofs\fR"
+are aliases for "mkisofs".
+.br
+
+Personality "\fBcdrecord\fR" accepts the options listed with:
+.br
+ -as cdrecord -help --
+.br
+Among them: -v, dev=, speed=, blank=, fs=, -eject, -atip, padsize=,
+track source file path or "-" for standard input as track source.
+.br
+It ignores most other options of cdrecord and cdrskin but refuses on
+-audio, -scanbus, -multi, -msinfo, --grow_overwriteable_iso,
+and on blanking modes unknown to xorriso.
+.br
+dev= must be given as xorriso device address. Adresses like 0,0,0 or ATA:1,1,0
+are not supported.
+.br
+If a track source is given, then an automatic -commit happens at the end of
+the "cdrecord" option list.
+.br
+A much more elaborate libburn based cdrecord emulator is the program cdrskin.
+.br
+Personalites "\fBwodim\fR" and "\fBcdrskin\fR" are aliases for "cdrecord".
+.TP
+.B Scripting, dialog and program control features:
+.TP
+\fB\-no_rc\fR
+.br
+Only if used as first command line argument this option
+prevents reading and interpretation of eventual startup
+files. See section FILES below.
+.TP
+\fB\-options_from_file\fR fileaddress
+Reads lines from fileaddress and executes them as dialog lines.
+.TP
+\fB\-help\fR
+.br
+Print helptext.
+.TP
+\fB\-version\fR
+Print program name and version.
+.TP
+\fB\-history\fR textline
+Copy textline into libreadline history.
+.TP
+\fB\-status\fR [mode|filter]
+Print the current settings of xorriso.
+Modes:
+.br
+ short... print only important or altered settings
+.br
+ long ... print all settings including defaults
+.br
+ long_history like long plus history lines
+.br
+Filters begin with '-' and are compared literally against the
+output lines of -status:long_history. A line is put out only
+if its start matches the filter text. No wildcards.
+.TP
+\fB\-status_history_max\fR number
+Set maximum number of history lines to be reported with -status "long_history".
+.TP
+\fB\-temp_mem_limit\fR number["k"|"m"]
+Set the maximum size of temporary memory to be used for image dependent
+buffering. Currently this applies to pattern expansion only.
+.br
+Default is 16m = 16 MiB, minimum 64k = 64 kiB, maximum 1024m = 1 GiB.
+.TP
+\fB\-print\fR text
+Print a text to result channel.
+.TP
+\fB\-prompt\fR text
+Show text at beginning of output line and
+wait for the user to hit the Enter key
+resp. to send a line via stdin.
+.TP
+\fB\-errfile_log\fR mode path|channel
+.br
+If problem events are related to input files from the filesystem, then their
+disk_paths can be logged to a file or to output channels R or I.
+.br
+Mode can either be "plain" or "marked". The latter causes marker lines which
+give the time of log start, burn session start, burn session end, log end
+or program end. In mode "plain", only the file paths are logged.
+.br
+If path is "-" or "-R" then the log is directed to the result channel.
+Path "-I" directs it to the info message channel. Any text that does not
+begin with "-" is used as path for a file to append the log lines.
+.br
+Problematic files can be recorded multiple times during one program run.
+If the program run aborts then the list might not be complete because
+some input file arguments might not have been processed at all.
+.br
+The errfile paths are transported as messages of very low priority "ERRFILE".
+This transport becomes visible with -report_about "ALL".
+.TP
+\fB\-session_log\fR path
+If path is not empty it gives the address of a plain text file where
+a log record gets appended after each session. This log can be used to
+determine the start_lba of a session for mount option sbsector= from
+date or volume id.
+.br
+Record format is: timestamp start_lba size volume-id
+.br
+The first three items are single words, the rest of the line is the volume id.
+.TP
+\fB\-end\fR
+.br
+End program immediately
+.TP
+\fB#\fR any text
+In dialog or file execution mode only and only as first
+non-whitespace in line:
+Do not execute the line but eventually store it in history.
+.TP
+.B Support for frontend programs talking into stdin and listening at stdout:
+.TP
+\fB\-pkt_output\fR "on"|"off"
+Consolidate text output on stdout and classify each
+line by a channel indicator:
+.br
+ 'R:' for result lines,
+.br
+ 'I:' for notes and error messages,
+.br
+ 'M:' for -mark texts.
+.br
+Next is a decimal number of which only bit 0 has a meaning for now.
+0 means no newline at end of payload, 1 means that the newline character at
+the end of the output line belongs to the payload. After another colon follows
+the payload text.
+.br
+Example:
+.br
+ I:1: enter option and arguments :
+.TP
+\fB\-logfile\fR channel fileaddress
+Copy output of a channel to the given file.
+.TP
+\fB\-mark\fR text
+If text is not empty it will get put out each time an
+action has been completed.
+.TP
+\fB\-prog\fR text
+Use text as this program's name in subsequent messages
+.TP
+\fB\-prog_help\fR text
+Use text as this program's name and perform -help.
+.br
+.SH EXAMPLES
+.SS
+.B Overview of examples:
+As superuser learn about available drives
+.br
+Blank media and compose a new ISO image as batch run
+.br
+A dialog session doing about the same
+.br
+Manipulating an existing ISO image on the same media
+.br
+Copy modified ISO image from one media to another
+.br
+Write a ISO image into a pipe (single-session only)
+.br
+Perform a single session run as of cdrtools traditions
+.br
+Adjust thresholds for verbosity, exit value and program abort
+.br
+Examples of input timestrings
+.br
+Incremental backup of a few directory trees
+.SS
+.B As superuser learn about available drives
+Consider to give rw permissions to those users or groups
+which shall be able to use the drives with xorriso.
+.br
+\fB$\fR xorriso -devices
+.br
+0 -dev '/dev/sr0' rwrw-- : '_NEC ' 'DVD_RW ND-4570A'
+.br
+1 -dev '/dev/sr1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
+.br
+2 -dev '/dev/sr2' rwrw-- : 'PHILIPS ' 'SPD3300L'
+.SS
+.B Blank media and compose a new ISO image as batch run
+Aquire drive /dev/sr2, blank media resp. invalidate existing ISO image.
+Add the files from hard disk directories /home/me/sounds and /pictures.
+Omit some unwanted stuff by removing it from the image directory tree.
+Re-add some wanted stuff.
+.br
+Because no -dialog "on" is given, the program will then end by committing the
+session to media.
+.br
+\fB$\fR cd /home/me
+.br
+\fB$\fR xorriso -outdev /dev/sr2 \\
+.br
+ -blank as_needed \\
+.br
+ -map /home/me/sounds /sounds \\
+.br
+ -map /home/me/pictures /pictures \\
+.br
+ -rm_r \\
+.br
+ /sounds/indecent \\
+.br
+ '/pictures/*private*' \\
+.br
+ /pictures/confidential \\
+.br
+ -- \\
+.br
+ -cd / \\
+.br
+ -add pictures/confidential/work*
+.br
+Note that '/pictures/*private*' is a pattern for iso_rr_paths
+while pictures/confidential/work* gets expanded by the shell
+with addresses from the hard disk.
+.SS
+.B A dialog session doing about the same
+.br
+-pathspecs is already given as start argument. The other activities
+are done as dialog input. The pager gets set to 20 lines of 80 characters.
+.br
+The drive is aquired by option -dev rather than -outdev in order to see
+the message about its current content. By option -blank this content is
+made ready for being overwritten and the loaded ISO image is made empty.
+.br
+In order to be able to eject the media, the session needs to be committed
+explicitely.
+.br
+.B $ xorriso -dialog on -page 20 80 -disk_pattern on
+.br
+enter option and arguments :
+.br
+.B \-dev /dev/sr2
+.br
+enter option and arguments :
+.br
+.B \-blank as_needed
+.br
+enter option and arguments :
+.br
+.B \-map /home/me/sounds /sounds -map /home/me/pictures /pictures
+.br
+enter option and arguments :
+.br
+.B \-rm_r /sounds/indecent /pictures/*private* /pictures/confidential
+.br
+enter option and arguments :
+.br
+.B \-cdx /home/me/pictures -cd /pictures
+.br
+enter option and arguments :
+.br
+.B \-add confidential/office confidential/factory
+.br
+enter option and arguments :
+.br
+.B \-du /
+.br
+enter option and arguments :
+.br
+.B \-commit -eject all -end
+.br
+.SS
+.B Manipulating an existing ISO image on the same media
+Load image from drive.
+Remove (i.e. hide) directory /sounds and its subordinates.
+Rename directory /pictures/confidential to /pictures/restricted.
+Change access permissions of directory /pictures/restricted.
+Add new directory trees /sounds and /movies. Burn to the same media and eject.
+.br
+\fB$\fR xorriso -dev /dev/sr2 \\
+.br
+ -rm_r /sounds -- \\
+.br
+ -mv \\
+.br
+ /pictures/confidential \\
+.br
+ /pictures/restricted \\
+.br
+ -- \\
+.br
+ -chmod go-rwx /pictures/restricted -- \\
+.br
+ -map /home/me/prepared_for_dvd/sounds_dummy /sounds \\
+.br
+ -map /home/me/prepared_for_dvd/movies /movies \\
+.br
+ -commit -eject all
+.SS
+.B Copy modified ISO image from one media to another
+Load image from input drive. Do the same manipulations as in the previous
+example. Aquire output drive and blank it. Burn the modified image as
+first and only session to the output drive.
+.br
+\fB$\fR xorriso -indev /dev/sr2 \\
+.br
+ -rm_r /sounds -- \\
+.br
+ ...
+.br
+ -outdev /dev/sr0 -blank as_needed \\
+.br
+ -commit -eject all
+.SS
+.B Write a ISO image into a pipe (single-session only)
+\fB$\fR xorriso -outdev - \\
+.br
+ ...
+.br
+ | gzip >image.iso.gz
+.SS
+.B Perform a single session run as of cdrtools traditions
+This shall illustrate how xorriso can act in either role.
+Between both processes there can be performed arbitrary transportation
+or filtering.
+.br
+\fB$\fR xorriso -as mkisofs -J -R /home/prepared_for_iso/tree | \\
+.br
+ xorriso -as cdrecord -v dev=/dev/sr0 blank=fast -eject -
+.SS
+.B Adjust thresholds for verbosity, exit value and program abort
+Be quite verbous, exit 32 if severity "FAILURE" was encountered,
+do not abort prematurely but forcibly go on until the end of commands.
+.br
+\fB$\fR xorriso ... \\
+.br
+ -report_about UPDATE \\
+.br
+ -return_with FAILURE 32 \\
+.br
+ -abort_on NEVER \\
+.br
+ ...
+.SS
+.B Examples of input timestrings
+.br
+As printed by program date:
+.B 'Thu Nov 8 14:51:13 CET 2007'
+.br
+The same without ignored parts:
+.B 'Nov 8 14:51:13 2007'
+.br
+The same as expected by date:
+.B 110814512007.13
+.br
+Four weeks in the future:
+.B +4w
+.br
+The current time:
+.B +0
+.br
+Three hours ago:
+.B \-3h
+.br
+Seconds since Jan 1 1970:
+.B =1194531416
+.SS
+.B Incremental backup of a few directory trees
+This does the following to directories /open_source_project and /personal_mail
+in the ISO image:
+create them if not existing yet,
+compare them with their disk counterparts,
+add disk file objects which are missing yet,
+overwrite those which are different on disk,
+and delete those which have vanished on disk.
+But do not add or overwrite files matching *.o, *.swp.
+.br
+\fB$\fR xorriso -dev /dev/sr0 \\
+.br
+ -volid PROJECTS_MAIL_"$(date '+%Y_%m_%d_%H%M%S')" \\
+.br
+ -not_leaf '*.o' -not_leaf '*.swp' \\
+.br
+ -update_r /home/thomas/open_source_projects /open_source_projects \\
+.br
+ -update_r /home/thomas/personal_mail /personal_mail \\
+.br
+ -commit -toc -eject all
+.br
+To be used several times on the same media, whenever an update of
+the two disk trees to the media is desired. Begin with blank media and start
+a new blank media when the run fails due to lack of remaining space on
+the old one.
+.br
+This makes most sense with backups on non-erasable media like CD-R,
+DVD-R, DVD+R if the full backup leaves substantial remaining capacity
+on media and if the expected changes are much smaller than the full backup.
+An update run will probably save no time but last longer than a full backup.
+Another good reason may be given if read speed is much higher than write speed.
+.br
+With \fBmount\fR option \fB"sbsector="\fR it is possible to access the session
+trees which represent the older backup versions. Multi-session media and
+most overwriteable media written by xorriso can tell
+the sbsector by xorriso option -toc.
+.br
+Another way to keep track of incremental sessions is to
+set before writing a suitable path for xorriso option -session_log where
+the sbsector number gets recorded as the second word in each line.
+.br
+With CD media, Linux mount accepts session numbers directly by its option
+"session=".
+.br
+\fBDo not write more than about 50 sessions\fR to one multi-session media.
+Theoretical limits are higher but in practice the media deteriorate more early.
+It might also be that your operating system has a session limit with mount.
+An overview of sessions is given by option -toc.
+.br
+Sessions on multi-session media are separated by several MB of unused blocks.
+So with small sessions the payload capacity can become substantially lower
+than the overall media capacity. If the remaining space on media does not
+suffice for the next gap, the drive is supposed to close the media
+automatically.
+.br
+\fBBetter do not use your youngest backup for -update_r\fR.
+Have at least two media which you use alternatingly. So only older backups
+get endangered by the new write operation, while the newest backup is
+stored safely on a different media.
+Always have a blank media ready to perform a full backup in case the update
+attempt fails due to insufficient remaining capacity.
+.br
+If you have enough re-useable media for a round-robin scheme then better do
+full backups with blank media each time. Blanking can be achieved by
+either a separate run:
+.br
+\fB$\fR xorriso -outdev /dev/sr0 -blank as_needed -eject all
+.br
+or in the update run by using option -blank "as_needed" before
+option -update_r.
+.br
+.SH FILES
+.SS
+.B Startup files:
+.br
+If not -no_rc is given as the first argument then xorriso attempts on startup
+to read and execute lines from the following files:
+.br
+ /etc/default/xorriso
+.br
+ /etc/opt/xorriso/rc
+.br
+ /etc/xorriso/xorriso.conf
+.br
+ $HOME/.xorrisorc
+.br
+The files are read in the sequence given above, but none of them is required
+for xorriso to function properly.
+.br
+.SH SEE ALSO
+.TP
+For mounting xorriso generated ISO 9660 images
+.br
+.BR mount(8)
+.TP
+Libreadline, a comfortable input line facility
+.BR readline(3)
+.TP
+Other programs which produce ISO 9660 images
+.br
+.BR mkisofs(8),
+.BR genisoimage(8)
+.TP
+Other programs which burn sessions to optical media
+.BR growisofs(1),
+.BR cdrecord(1),
+.BR wodim(1),
+.BR cdrskin(1)
+.br
+.SH AUTHOR
+Thomas Schmitt
+.br
+for libburnia-project.org
+.SH CREDITS
+xorriso is in part based on work by Vreixo Formoso who provides libisofs
+together with Mario Danic who also leads the libburnia team.
+Thanks to Andy Polyakov who invented emulated growing,
+to Derek Foreman and Ben Jansens who once founded libburn.
+.br
+Compliments towards Joerg Schilling whose cdrtools served me for ten years.
+
diff --git a/libisoburn/branches/ZeroOneSix/xorriso/xorriso.c b/libisoburn/branches/ZeroOneSix/xorriso/xorriso.c
new file mode 100644
index 00000000..0f43fb47
--- /dev/null
+++ b/libisoburn/branches/ZeroOneSix/xorriso/xorriso.c
@@ -0,0 +1,11883 @@
+
+/*
+
+ ( cd .. ; libisoburn-develop/xorriso/compile_xorriso.sh -g )
+
+or
+
+ cc -g -DXorriso_with_maiN -DXorriso_with_readlinE \
+ -DXorriso_build_timestamP='"'"$(date -u '+%Y.%m.%d.%H%M%S')"'"' \
+ -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
+ -o xorriso/xorriso \
+ xorriso/xorriso.c xorriso/xorrisoburn.c \
+ -lpthread -lreadline -lburn -lisofs -lisoburn
+
+or
+
+ cc -g -DXorriso_with_readlinE \
+ -DXorriso_build_timestamP='"'"$(date -u '+%Y.%m.%d.%H%M%S')"'"' \
+ -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
+ -c \
+ xorriso/xorriso.c xorriso/xorrisoburn.c
+
+*/
+
+/* Command line oriented batch and dialog tool which creates, loads,
+ manipulates and burns ISO 9660 filesystem images.
+
+ Copyright 2007-2008 Thomas Schmitt,
+
+ Initial code of this program was derived from program src/askme.c out
+ of scdbackup-0.8.8, Copyright 2007 Thomas Schmitt, BSD-License.
+
+ Provided under GPL version 2, with the announcement that this might
+ get changed in future. I would prefer BSD or a modified LGPL with no
+ option to choose any kind of future GPL version.
+ (This announcement affects only future releases of xorriso.
+ If you obtain a copy licensed as "GPL version 2" then this license is
+ not revocable for that particular copy, of course.)
+
+
+ Overview of xorriso architecture:
+
+ libburn provides the ability to read and write data.
+
+ libisofs interprets and manipulates ISO 9660 directory trees. It generates
+ the output stream which is handed over to libburn.
+
+ libisoburn encapsulates the connectivity issues between libburn and
+ libisofs. It also enables multi-session emulation on overwritable media
+ and random access file objects.
+ xorriso is intended as reference application of libisoburn.
+
+ xorrisoburn.[ch] encapsulate any usage of the libraries by xorriso.
+
+ xorriso.h exposes the public functions of xorriso which are intended
+ to be used by programs which link with xorriso.o. These functions are
+ direct equivalents of the xorriso interpreter commands.
+ There is also the API for handling event messages.
+
+ xorriso_private.h is not to be included by other software. It encapsulates
+ the inner interfaces of xorriso.
+
+ xorriso.c provides the command interpreter as described in xorriso.1.
+ It performs any activity that does not demand a reference to a symbol
+ of the library APIs. This includes:
+ - Interpretation of user input from arguments, dialog, and scripting.
+ - Output of result text and event messages.
+ - POSIX filesystem operations.
+ - Public functions which perform the particular xorriso commands.
+ - The main() function, if enabled by #define Xorriso_with_maiN.
+
+*/
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* eventually, this is done in xorriso_private.h : #include */
+
+#ifdef Xorriso_with_readlinE
+#ifdef Xorriso_with_old_readlinE
+#include
+#include
+#else /* Xorriso_with_old_readlinE */
+#include
+#include
+#endif /* ! Xorriso_with_old_readlinE */
+#endif /* Xorriso_with_readlinE */
+
+#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ));
+
+
+/* Diet facility: exclude help texts from binaries */
+/* This will eventually be redefined to eat up its content */
+#define AlN(x) x
+
+
+/* There is only one stage of diet: Xorriso_no_helP */
+#ifdef Xorriso_no_helP
+#undef AlN
+#define AlN(x)
+#endif
+
+
+/* ------------------------------------------------------------------------ */
+
+
+/* The official xorriso options API. "No shortcuts" */
+#include "xorriso.h"
+
+/* The inner isofs- and burn-library interface */
+#include "xorrisoburn.h"
+
+/* The inner description of XorrisO */
+#define Xorriso_is_xorriso_selF 1
+#include "xorriso_private.h"
+
+
+/* ------------------------------------------------------------------------ */
+
+
+#ifndef Xorriso_sfile_externaL
+
+
+char *Sfile_fgets(char *line, int maxl, FILE *fp)
+{
+ int l;
+ char *ret;
+
+ ret= fgets(line,maxl,fp);
+ if(ret==NULL)
+ return(NULL);
+ l= strlen(line);
+ if(l>0) if(line[l-1]=='\r') line[--l]= 0;
+ if(l>0) if(line[l-1]=='\n') line[--l]= 0;
+ if(l>0) if(line[l-1]=='\r') line[--l]= 0;
+ return(ret);
+}
+
+
+int Sfile_count_components(char *path, int flag)
+/*
+ bit0= do not ignore trailing slash
+ bit1= do not ignore empty components (other than the empty root name)
+*/
+{
+ int l,count= 0;
+ char *cpt;
+
+ l= strlen(path);
+ if(l==0)
+ return(0);
+ count= 1;
+ for(cpt= path+l-1;cpt>=path;cpt--) {
+ if(*cpt=='/') {
+ if(*(cpt+1)==0 && !(flag&1))
+ continue;
+ if(*(cpt+1)=='/' && !(flag&2))
+ continue;
+ count++;
+ }
+ }
+ return(count);
+}
+
+
+int Sfile_component_pointer(char *path, char **sourcept, int idx, int flag)
+/*
+ bit0= do not ignore trailing slash
+ bit1= do not ignore empty components (other than the empty root name)
+ bit2= accept 0 as '/'
+*/
+{
+ int count= 0;
+ char *spt;
+
+ for(spt= path;*spt!=0 || (flag&4);spt++) {
+ if(count>=idx) {
+ *sourcept= spt;
+ return(1);
+ }
+ if(*spt=='/' || *spt==0) {
+ if(*(spt+1)=='/' && !(flag&2))
+ continue;
+ if(*(spt+1)==0 && !(flag&1))
+ continue;
+ count++;
+ }
+ }
+ if((flag&1) && count>=idx)
+ return(1);
+ return(0);
+}
+
+
+int Sfile_leafname(char *path, char leafname[SfileadrL], int flag)
+{
+ int count, ret;
+ char *lpt;
+
+ leafname[0]= 0;
+ count= Sfile_count_components(path, 0);
+ if(count==0)
+ return(0);
+ ret= Sfile_component_pointer(path, &lpt, count-1, 0);
+ if(ret<=0)
+ return(ret);
+ if(Sfile_str(leafname, lpt, 0)<=0)
+ return(0);
+ lpt= strchr(leafname, '/');
+ if(lpt!=NULL)
+ *lpt= 0;
+ return(1);
+}
+
+
+int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag)
+{
+ int l;
+
+ l= strlen(path);
+ if(l+1>=SfileadrL)
+ return(0);
+ if(l==0) {
+ strcpy(path,"/");
+ l= 1;
+ } else if(path[l-1]!='/') {
+ path[l++]= '/';
+ path[l]= 0;
+ }
+ if(l+strlen(addon)>=SfileadrL)
+ return(0);
+ if(addon[0]=='/')
+ strcpy(path+l,addon+1);
+ else
+ strcpy(path+l,addon);
+ return(1);
+}
+
+
+int Sfile_prepend_path(char *prefix, char path[SfileadrL], int flag)
+{
+ int l, i;
+
+ l= strlen(path)+strlen(prefix)+1;
+ if(l>=SfileadrL) {
+
+#ifdef Not_yeT
+ /* >>> ??? how to transport messages to xorriso ? */
+ sprintf(xorriso->info_text,
+ "Combination of wd and relative address too long (%d > %d)",
+ l,SfileadrL-1);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+#endif
+
+ return(-1);
+ }
+ l-= strlen(path);
+ for(i= strlen(path)+1; i>=0; i--)
+ path[i+l]= path[i];
+ strcpy(path,prefix);
+ path[l-1]= '/';
+ return(1);
+}
+
+int Sfile_being_group_member(struct stat *stbuf, int flag)
+{
+ int i, suppl_groups;
+ gid_t *suppl_glist;
+
+ if (getegid()==stbuf->st_gid)
+ return(1);
+ suppl_groups= getgroups(0, NULL);
+ suppl_glist= (gid_t *) malloc((suppl_groups + 1) * sizeof(gid_t));
+ if (suppl_glist==NULL)
+ return(-1);
+ suppl_groups= getgroups(suppl_groups+1,suppl_glist);
+ for (i= 0; ist_gid) {
+ free((char *) suppl_glist);
+ return(1);
+ }
+ }
+ free((char *) suppl_glist);
+ return(0);
+}
+
+
+int Sfile_type(char *filename, int flag)
+/*
+ bit0= return -1 if file is missing
+ bit1= return a hardlink with siblings as type 5
+ bit2= evaluate eventual link target rather than the link object itself
+ bit3= return a socket or a char device as types 7 or 8 rather than 0
+*/
+/*
+ return:
+ 0=unknown
+ 1=regular
+ 2=directory
+ 3=symbolic link
+ 4=named pipe
+ 5=multiple hardlink (with bit1)
+ 6=block device
+ 7=socket (with bit3)
+ 8=character device (with bit3)
+*/
+{
+ struct stat stbuf;
+ if(flag&4) {
+ if(stat(filename,&stbuf)==-1) {
+ if(flag&1) return(-1);
+ else return(0);
+ }
+ } else {
+ if(lstat(filename,&stbuf)==-1) {
+ if(flag&1) return(-1);
+ else return(0);
+ }
+ }
+ if(S_ISREG(stbuf.st_mode)) {
+ if(flag&2)
+ if(stbuf.st_nlink>1)
+ return(5);
+ return(1);
+ }
+ if(S_ISDIR(stbuf.st_mode))
+ return(2);
+ if((stbuf.st_mode&S_IFMT)==S_IFLNK)
+ return(3);
+ if(S_ISFIFO(stbuf.st_mode))
+ return(4);
+ if(S_ISBLK(stbuf.st_mode))
+ return(6);
+ if(flag&8)
+ if((stbuf.st_mode&S_IFMT)==S_IFSOCK)
+ return(7);
+ if(flag&8)
+ if(S_ISCHR(stbuf.st_mode))
+ return(8);
+ return(0);
+}
+
+
+char *Sfile_datestr(time_t tim, short int flag)
+/*
+ bit0=with hours+minutes
+ bit1=with seconds
+
+ bit8= local time rather than UTC
+*/
+{
+ static char zeitcode[80]={"000000"};
+ char puff[80];
+ struct tm *azt;
+
+ if(flag&256)
+ azt = localtime(&tim);
+ else
+ azt = gmtime(&tim);
+
+ if(azt->tm_year>99)
+ sprintf(zeitcode,"%c%1.1d%2.2d%2.2d",
+ 'A'+(azt->tm_year-100)/10,azt->tm_year%10,
+ azt->tm_mon+1,azt->tm_mday);
+ else
+ sprintf(zeitcode,"%2.2d%2.2d%2.2d",
+ azt->tm_year,azt->tm_mon+1,azt->tm_mday);
+ if(flag&1){
+ sprintf(puff,".%2.2d%2.2d",azt->tm_hour,azt->tm_min);
+ strcat(zeitcode,puff);
+ }
+ if(flag&2){
+ sprintf(puff,"%2.2d",azt->tm_sec);
+ strcat(zeitcode,puff);
+ }
+
+ return(zeitcode);
+}
+
+
+int Sfile_scale(double value, char *result, int siz, double thresh, int flag)
+/*
+ bit0= eventually ommit 'b'
+ bit1= make text as short as possible
+ bit2= no fraction (if it would fit at all)
+*/
+{
+ char scale_c,scales[6],form[80];
+ int i,dec_siz= 0,avail_siz= 1;
+
+ strcpy(scales,"bkmgtp");
+ scale_c= scales[0];
+ for(i=1;scales[i]!=0;i++) {
+ if(value0)
+ sprintf(form,"%%%d.%df%%c",avail_siz,dec_siz);
+ else
+ sprintf(form,"%%%d.f%%c",siz-1);
+ sprintf(result,form,value,scale_c);
+ }
+ return(1);
+}
+
+
+int Sfile_off_t_text(char text[80], off_t num, int flag)
+{
+ char *tpt;
+ off_t hnum, scale= 1;
+ int digits= 0, d, i;
+
+ tpt= text;
+ hnum= num;
+ if(hnum<0) {
+ *(tpt++)= '-';
+ hnum= -num;
+ }
+ if(hnum<0) { /* it can stay nastily persistent */
+ strcpy(text, "_overflow_");
+ return(0);
+ }
+ for(i= 0; i<23; i++) { /* good for up to 70 bit = 10 exp 21.07... */
+ if(hnum==0)
+ break;
+ hnum/= 10;
+ if(hnum)
+ scale*= 10;
+ }
+ if(i==0) {
+ strcpy(text, "0");
+ return(1);
+ }
+ if(i==23) {
+ strcpy(text, "_overflow_");
+ return(0);
+ }
+ digits= i;
+ hnum= num;
+ for(; i>0; i--) {
+ d= hnum/scale;
+ tpt[digits-i]= '0'+d;
+ hnum= hnum%scale;
+ scale/= 10;
+ }
+ tpt[digits]= 0;
+ return(1);
+}
+
+
+int Sfile_destroy_argv(int *argc, char ***argv, int flag)
+{
+ int i;
+
+ if(*argc>0 && *argv!=NULL){
+ for(i=0;i<*argc;i++){
+ if((*argv)[i]!=NULL)
+ Smem_freE((*argv)[i]);
+ }
+ Smem_freE((char *) *argv);
+ }
+ *argc= 0;
+ *argv= NULL;
+ return(1);
+}
+
+
+int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
+ int flag)
+/*
+ bit0= read progname as first argument from line
+ bit1= just release argument list argv and return
+ bit2= abort with return(0) if incomplete quotes are found
+ bit3= eventually prepend missing '-' to first argument read from line
+*/
+{
+ int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc;
+ char *cpt,*start;
+ char buf[SfileadrL];
+
+ Sfile_destroy_argv(argc,argv,0);
+ if(flag&2) return(1);
+
+ for(pass=0;pass<2;pass++) {
+ cpt= line-1;
+ if(!(flag&1)){
+ argzaehl= line_start_argc= 1;
+ if(pass==0)
+ maxl= strlen(progname);
+ else
+ strcpy((*argv)[0],progname);
+ } else {
+ argzaehl= line_start_argc= 0;
+ if(pass==0) maxl= 0;
+ }
+ while(*(++cpt)!=0){
+ if(isspace(*cpt)) continue;
+ start= cpt;
+ buf[0]= 0;
+ cpt--;
+ while(*(++cpt)!=0) {
+ if(isspace(*cpt)) break;
+ if(*cpt=='"'){
+ l= cpt-start; bufl= strlen(buf);
+ if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
+ l= strlen(buf);
+ start= cpt+1;
+ while(*(++cpt)!=0) if(*cpt=='"') break;
+ if((flag&4) && *cpt==0)
+ return(0);
+ l= cpt-start; bufl= strlen(buf);
+ if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
+ start= cpt+1;
+ }else if(*cpt=='\''){
+ l= cpt-start; bufl= strlen(buf);
+ if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
+ l= strlen(buf);
+ start= cpt+1;
+ while(*(++cpt)!=0) if(*cpt=='\'') break;
+ if((flag&4) && *cpt==0)
+ return(0);
+ l= cpt-start; bufl= strlen(buf);
+ if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
+ start= cpt+1;
+ }
+ if(*cpt==0) break;
+ }
+ l= cpt-start;
+ bufl= strlen(buf);
+ if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
+ l= strlen(buf);
+ if(pass==0){
+ if(argzaehl==line_start_argc && (flag&8))
+ if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
+ l++;
+ if(l>maxl) maxl= l;
+ }else{
+ strcpy((*argv)[argzaehl],buf);
+ if(argzaehl==line_start_argc && (flag&8))
+ if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
+ sprintf((*argv)[argzaehl],"-%s", buf);
+ }
+ argzaehl++;
+ if(*cpt==0) break;
+ }
+ if(pass==0){
+ *argc= argzaehl;
+ if(argzaehl>0) {
+ *argv= (char **) Smem_malloC(argzaehl*sizeof(char *));
+ if(*argv==NULL)
+ return(-1);
+ }
+ for(i=0;i<*argc;i++) {
+ (*argv)[i]= (char *) Smem_malloC((maxl+1));
+ if((*argv)[i]==NULL)
+ return(-1);
+ }
+ }
+ }
+ return(1);
+}
+
+
+/* @param flag bit0= append */
+int Sfile_str(char target[SfileadrL], char *source, int flag)
+{
+ int l;
+
+ l= strlen(source);
+ if(flag&1)
+ l+= strlen(target);
+ if(l>=SfileadrL) {
+ fprintf(stderr, "--- Path string overflow (%d > %d). Malicious input ?\n",
+ l,SfileadrL-1);
+ return(0);
+ }
+ if(flag&1)
+ strcat(target, source);
+ else
+ strcpy(target, source);
+ return(1);
+}
+
+
+/** Combine environment variable HOME with given filename
+ @param filename Address relative to $HOME
+ @param fileadr Resulting combined address
+ @param fa_size Size of array fileadr
+ @param flag Unused yet
+ @return 1=ok , 0=no HOME variable , -1=result address too long
+*/
+int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag)
+{
+ char *home;
+
+ strcpy(fileadr,filename);
+ home= getenv("HOME");
+ if(home==NULL)
+ return(0);
+ if(strlen(home)+strlen(filename)+1>=fa_size)
+ return(-1);
+ strcpy(fileadr,home);
+ if(filename[0]!=0){
+ strcat(fileadr,"/");
+ strcat(fileadr,filename);
+ }
+ return(1);
+}
+
+
+/** Return a double representing seconds and microseconds since 1 Jan 1970 */
+double Sfile_microtime(int flag)
+{
+ struct timeval tv;
+ struct timezone tz;
+ gettimeofday(&tv,&tz);
+ return((double) (tv.tv_sec+1.0e-6*tv.tv_usec));
+}
+
+
+int Sfile_decode_datestr(struct tm *reply, char *text, int flag)
+/* YYMMDD[.hhmm[ss]] */
+{
+ int i,l;
+ time_t current_time;
+ struct tm *now;
+
+ current_time= time(0);
+ now= localtime(¤t_time);
+ for(i=0;i'9' && text[0]<'A') || text[0]>'Z')
+ return(0);
+ l= strlen(text);
+ for(i=1;i'9')
+ break;
+ if(i!=6)
+ return(0);
+ if(text[i]==0)
+ goto decode;
+ if(text[i]!='.' || (l!=11 && l!=13))
+ return(0);
+ for(i++;i'9')
+ break;
+ if(i!=l)
+ return(0);
+
+decode:;
+ reply->tm_hour= 0;
+ reply->tm_min= 0;
+ reply->tm_sec= 0;
+ i= 0;
+ if(text[0]>='A')
+ reply->tm_year= 100+(text[i]-'A')*10+text[1]-'0';
+ else
+ reply->tm_year= 10*(text[0]-'0')+text[1]-'0';
+ reply->tm_mon= 10*(text[2]-'0')+text[3]-'0'-1;
+ reply->tm_mday= 10*(text[4]-'0')+text[5]-'0';
+ if(l==6)
+ return(1);
+ reply->tm_hour= 10*(text[7]-'0')+text[8]-'0';
+ reply->tm_min= 10*(text[9]-'0')+text[10]-'0';
+ if(l==11)
+ return(1);
+ reply->tm_sec= 10*(text[11]-'0')+text[12]-'0';
+ return(1);
+}
+
+#endif /* Xorriso_sfile_externaL */
+
+
+/* --------------------------------- misc --------------------------------- */
+
+
+int Write_to_channel(char *text, int channel_no, int flag)
+/*
+ bit0= packet write disabled, write to stdin resp. stderr
+ bit1= text is the name of the log file for the given channel
+ bit2= text is the name of the consolidated packet log file for all channels
+bit15= with bit1 or bit2: close depicted log file
+*/
+{
+ char *rpt,*npt,ret= 1;
+ char prefix[16];
+ static int num_channels= 4;
+ static char channel_prefixes[4][4]= {".","R","I","M"};
+ static FILE *logfile_fp[4]= {NULL,NULL,NULL,NULL};
+ static FILE *pktlog_fp= NULL;
+
+ if(channel_no<0 || channel_no>=num_channels)
+ return(-1);
+
+ /* Logfiles */
+ if((flag&2) && logfile_fp[channel_no]!=NULL) {
+ fprintf(logfile_fp[channel_no],
+ "! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n",
+ channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
+ fclose(logfile_fp[channel_no]);
+ logfile_fp[channel_no]= NULL;
+ }
+ if((flag&4) && pktlog_fp!=NULL) {
+ fprintf(pktlog_fp,
+ "I:1:! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n",
+ channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
+ fclose(pktlog_fp);
+ pktlog_fp= NULL;
+ }
+ if(flag&(1<<15))
+ return(1);
+ if((flag&2)) {
+ logfile_fp[channel_no]= fopen(text,"a");
+ if(logfile_fp[channel_no]==NULL)
+ return(0);
+ fprintf(logfile_fp[channel_no],
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : %s : %s\n",
+ channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
+ fflush(logfile_fp[channel_no]);
+ }
+ if((flag&4)) {
+ pktlog_fp= fopen(text,"a");
+ if(pktlog_fp==NULL)
+ return(0);
+ fprintf(pktlog_fp,
+ "I:1:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : . : %s\n",
+ Sfile_datestr(time(0),1|2|256));
+ fflush(pktlog_fp);
+ }
+ if(flag&(2|4))
+ return(1);
+ if(flag&1) {
+ if(channel_no==1 || channel_no==3)
+ printf("%s",text);
+ if(channel_no==2 || channel_no==3)
+ fprintf(stderr,"%s",text);
+ if(logfile_fp[channel_no]!=NULL) {
+ fprintf(logfile_fp[channel_no],"%s",text);
+ fflush(logfile_fp[channel_no]);
+ }
+ if(pktlog_fp!=NULL)
+ return(1);
+ }
+ rpt= text;
+ sprintf(prefix,"%s:x: ",channel_prefixes[channel_no]);
+ while(*rpt!=0) {
+ npt= strchr(rpt,'\n');
+ if(npt==NULL)
+ prefix[2]= '0';
+ else
+ prefix[2]= '1';
+ if(!(flag&1)) {
+ ret= fwrite(prefix,5,1,stdout);
+ if(ret<=0)
+ return(0);
+ }
+ if(pktlog_fp!=NULL) {
+ ret= fwrite(prefix,5,1,pktlog_fp);
+ if(ret<=0)
+ return(0);
+ }
+ if(npt==NULL) {
+ if(!(flag&1)) {
+ ret= fwrite(rpt,strlen(rpt),1,stdout);
+ if(ret<=0)
+ return(0);
+ ret= fwrite("\n",1,1,stdout);
+ if(ret<=0)
+ return(0);
+ }
+ if(pktlog_fp!=NULL) {
+ ret= fwrite(rpt,strlen(rpt),1,pktlog_fp);
+ if(ret<=0)
+ return(0);
+ ret= fwrite("\n",1,1,pktlog_fp);
+ if(ret<=0)
+ return(0);
+ }
+ break;
+ } else {
+ if(!(flag&1)) {
+ ret= fwrite(rpt,npt+1-rpt,1,stdout);
+ if(ret<=0)
+ return(0);
+ }
+ if(pktlog_fp!=NULL) {
+ ret= fwrite(rpt,npt+1-rpt,1,pktlog_fp);
+ if(ret<=0)
+ return(0);
+ }
+ }
+ rpt= npt+1;
+ }
+ if(!(flag&1))
+ fflush(stdout);
+ if(pktlog_fp!=NULL)
+ fflush(pktlog_fp);
+ return(1);
+}
+
+
+int Strcmp(const void *pt1, const void *pt2)
+{
+ return(strcmp(*((char **) pt1), *((char **) pt2)));
+}
+
+
+int Sort_argv(int argc, char **argv, int flag)
+{
+ if(argc<=0)
+ return(2);
+ qsort(argv,(size_t) argc,sizeof(char *),Strcmp);
+ return(1);
+}
+
+
+FILE *Afile_fopen(char *filename, char *mode, int flag)
+/*
+ bit0= do not print error message on failure
+ bit6= write packeted error messages (see Write_to_channel())
+*/
+{
+ FILE *fp= NULL;
+ char errmsg[2*SfileadrL];
+
+ if(strcmp(filename,"-")==0) {
+ if(mode[0]=='a' || mode[0]=='w' ||
+ (mode[0]=='r' && mode[1]=='+') ||
+ (mode[0]=='r' && mode[1]=='b' && mode[2]=='+'))
+ fp= stdout;
+ else
+ fp= stdin;
+ } else if(strncmp(filename,"tcp:",4)==0){
+ sprintf(errmsg,"sorry - TCP/IP service isn't implemented yet.\n");
+ Write_to_channel(errmsg,2,!(flag&64));
+ } else if(strncmp(filename,"file:",5)==0){
+ fp= fopen(filename+5,mode);
+ } else {
+ fp= fopen(filename,mode);
+ }
+ if(fp==NULL){
+ if(!(flag&1)) {
+ sprintf(errmsg,"failed to open file '%s' in %s mode\n",filename,mode);
+ if(errno>0)
+ sprintf(errmsg+strlen(errmsg)," %s\n",strerror(errno));
+ Write_to_channel(errmsg,2,!(flag&64));
+ }
+ return(NULL);
+ }
+ return(fp);
+}
+
+
+/** Convert a text into a number of type double and multiply it by unit code
+ [kmgtpe] (2^10 to 2^60) or [s] (2048). (Also accepts capital letters.)
+ @param text Input like "42", "2k", "3.14m" or "-1g"
+ @param flag Bitfield for control purposes:
+ bit0= return -1 rathern than 0 on failure
+ @return The derived double value
+*/
+double Scanf_io_size(char *text, int flag)
+/*
+ bit0= default value -1 rather than 0
+*/
+{
+ int c;
+ double ret= 0.0;
+
+ if(flag&1)
+ ret= -1.0;
+ if(text[0]==0)
+ return(ret);
+ sscanf(text,"%lf",&ret);
+ c= text[strlen(text)-1];
+ if(c=='k' || c=='K') ret*= 1024.0;
+ if(c=='m' || c=='M') ret*= 1024.0*1024.0;
+ if(c=='g' || c=='G') ret*= 1024.0*1024.0*1024.0;
+ if(c=='t' || c=='T') ret*= 1024.0*1024.0*1024.0*1024.0;
+ if(c=='p' || c=='P') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0;
+ if(c=='e' || c=='E') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0*1024.0;
+ if(c=='s' || c=='S') ret*= 2048.0;
+ return(ret);
+}
+
+
+int Decode_date_input_format(struct tm *erg, char *text, int flag)
+/* MMDDhhmm[[CC]YY][.ss]] */
+{
+ int i,l,year;
+ time_t current_time;
+ struct tm *now;
+
+ current_time= time(0);
+ now= localtime(¤t_time);
+ for(i=0;i'9')
+ break;
+ if(i!=8 && i!=10 && i!=12)
+ return(0);
+ if(text[i]==0)
+ goto decode;
+ if(text[i]!='.' || l!=15)
+ return(0);
+ i++;
+ if(text[i]<'0'||text[i]>'9')
+ return(0);
+ i++;
+ if(text[i]<'0'||text[i]>'9')
+ return(0);
+
+decode:;
+ /* MMDDhhmm[[CC]YY][.ss]] */
+ i= 0;
+ erg->tm_mon= 10*(text[0]-'0')+text[1]-'0'-1;
+ erg->tm_mday= 10*(text[2]-'0')+text[3]-'0';
+ erg->tm_hour= 10*(text[4]-'0')+text[5]-'0';
+ erg->tm_min= 10*(text[6]-'0')+text[7]-'0';
+ erg->tm_sec= 0;
+ if(l==8)
+ return(1);
+ if(l>10){
+ year= 1000*(text[8]-'0')+100*(text[9]-'0')+10*(text[10]-'0')+(text[11]-'0');
+ }else{
+ year= 1900+10*(text[8]-'0')+(text[9]-'0');
+ if(year<1970)
+ year+= 100;
+ }
+ erg->tm_year= year-1900;
+ if(l<=12)
+ return(1);
+ erg->tm_sec= 10*(text[13]-'0')+text[14]-'0';
+ return(1);
+}
+
+
+int Decode_date_weekday(char *text, int flag)
+{
+ int i;
+ static char days[][4]= {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", ""};
+
+ for(i= 0; days[i][0]!=0; i++)
+ if(strncmp(text,days[i],3)==0)
+ return(i);
+ if((strlen(text)==3 || (strlen(text)==4 && text[3]==',')) &&
+ isalpha(text[0]) && isalpha(text[1]) && isalpha(text[2]))
+ return(7);
+ return(-1);
+}
+
+
+int Decode_date_month(char *text, int flag)
+{
+ int i;
+ static char months[][4]= {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
+
+ for(i= 0; months[i][0]!=0; i++)
+ if(strncmp(text,months[i],3)==0)
+ return(i);
+ return(-1);
+}
+
+
+/* @return -1=not a number, -2=not a day , 1 to 31 day of month */
+int Decode_date_mday(char *text, int flag)
+{
+ int ret, i;
+
+ for(i= 0; text[i]!=0; i++)
+ if(!isdigit(text[i]))
+ return(-1);
+ if(strlen(text)>2 || text[0]==0)
+ return(-2);
+ sscanf(text, "%d", &ret);
+ if(ret<=0 || ret>31)
+ return(-2);
+ return(ret);
+}
+
+int Decode_date_hms(char *text, struct tm *erg, int flag)
+{
+ int i, hour= -1, minute= -1, second= 0;
+
+ for(i= 0; i<9; i+= 3) {
+ if(i==6&&text[i]==0)
+ break;
+ if(!isdigit(text[i]))
+ return(-1);
+ if(!isdigit(text[i+1]))
+ return(-1);
+ if(text[i+2]!=':' && !(text[i+2]==0 && i>=3))
+ return(-1);
+ if(i==0)
+ sscanf(text+i,"%d",&hour);
+ else if(i==3)
+ sscanf(text+i,"%d",&minute);
+ else
+ sscanf(text+i,"%d",&second);
+ }
+ if(hour<0 || hour>23 || minute<0 || minute>59 || second>59)
+ return(-1);
+ erg->tm_hour= hour;
+ erg->tm_min= minute;
+ erg->tm_sec= second;
+ return(1);
+}
+
+
+/* @return -1=not a number, -2=not a year , >=0 years AD */
+int Decode_date_year(char *text, int flag)
+{
+ int ret, i;
+
+ for(i= 0; text[i]!=0; i++)
+ if(!isdigit(text[i]))
+ return(-1);
+ if(strlen(text)!=4)
+ return(-2);
+ sscanf(text, "%d", &ret);
+ if(ret<0 || ret>3000)
+ return(-2);
+ return(ret);
+}
+
+
+int Decode_date_timezone(char *text, struct tm *erg, int flag)
+{
+ int i;
+ static char tzs[][5]= {"GMT", "CET", "CEST", "0000", ""};
+
+ for(i= 0; tzs[i][0]!=0; i++)
+ if(strcmp(text,tzs[i])==0) {
+
+ /* ??? >>> what to do with timezone info ? Add to ->tm_hour ? */
+
+ return(1);
+ }
+ if(text[0]=='+' || text[0]=='-') {
+ for(i= 1; text[i]!=0; i++)
+ if(!isdigit(text[i]))
+ return(-1);
+ if(i!=5)
+ return(-1);
+
+ /* ??? >>> what to do with timezone info ? Add to ->tm_hour ? */
+
+ return(1);
+ } else {
+ for(i= 0; text[i]!=0; i++)
+ if(text[i]<'A' || text[i]>'Z')
+ return(-1);
+ if(i!=3 && i!=4)
+ return(-1);
+ return(2);
+ }
+}
+
+
+int Decode_date_output_format(struct tm *erg, char *text, int flag)
+/* Thu Nov 8 09:07:50 CET 2007 */
+/* Sat, 03 Nov 2007 08:58:30 +0100 */
+/* Nov 7 23:24 */
+{
+ int ret, i, argc= 0, seen_year= 0, seen_month= 0, seen_day= 0, seen_time= 0;
+ char **argv= NULL;
+ struct tm *now;
+ time_t timep;
+
+ memset(erg, 0, sizeof(*erg));
+ erg->tm_isdst= -1;
+ ret= Sfile_make_argv("xorriso", text, &argc, &argv, 0);
+ if(ret<=0)
+ goto ex;
+ for(i= 1; i=0) {
+ seen_month= 1;
+ erg->tm_mon= ret;
+ continue;
+ }
+ }
+ if(!seen_day) {
+ ret= Decode_date_mday(argv[i], 0);
+ if(ret>0) {
+ seen_day= 1;
+ erg->tm_mday= ret;
+ continue;
+ }
+ if(ret==-2) /* first pure number must be day of month */
+ {ret= 0; goto ex;}
+ }
+ if(!seen_time) {
+ ret= Decode_date_hms(argv[i], erg, 0);
+ if(ret>0) {
+ seen_time= 1;
+ continue;
+ }
+ }
+ if(!seen_year) {
+ ret= Decode_date_year(argv[i], 0);
+ if(ret>0) {
+ erg->tm_year= ret-1900;
+ seen_year= 1;
+ continue;
+ }
+ }
+
+ /* ignorants have to stay at the end of the loop */
+
+ ret= Decode_date_timezone(argv[i], erg, 0);
+ if(ret>=0)
+ continue;
+ ret= Decode_date_weekday(argv[i], 0);
+ if(ret>=0)
+ continue; /* ignore weekdays */
+
+ {ret= 0; goto ex;} /* unrecognizable component */
+ }
+
+ if(!(seen_day && seen_month))
+ {ret= 0; goto ex;}
+ if(!seen_year) { /* then use this year */
+ timep= time(NULL);
+ now= localtime(&timep);
+ erg->tm_year= now->tm_year;
+ }
+ ret= 1;
+ex:
+ Sfile_make_argv("", "", &argc, &argv, 2); /* release storage */
+ return(ret);
+}
+
+
+int Decode_xorriso_timestamp(struct tm *erg, char *code, int flag)
+ /* 2007.11.07.225624 */
+{
+ char buf[20];
+ int year,month,day,hour= 0,minute= 0,second= 0, i, l, mem;
+
+ memset(erg, 0, sizeof(*erg));
+ erg->tm_isdst= -1;
+
+ l= strlen(code);
+ if(l>17 || l<10)
+ return(0);
+ strcpy(buf, code);
+ for(i= 0; buf[i]!=0 && i<4; i++)
+ if(!isdigit(buf[i]))
+ return(0);
+ if(buf[4]!='.')
+ return(0);
+ buf[4]= 0;
+ sscanf(buf, "%d", &year);
+ if(year<1900 || year>3000)
+ return(0);
+ if(!(isdigit(buf[5]) && isdigit(buf[6]) && buf[7]=='.'))
+ return(0);
+ buf[7]= 0;
+ sscanf(buf+5, "%d", &month);
+ if(month<1 || month>12)
+ return(0);
+ if(!(isdigit(buf[8]) && isdigit(buf[9]) && (buf[10]=='.' || buf[10]==0)))
+ return(0);
+ buf[10]= 0;
+ sscanf(buf+8, "%d", &day);
+ if(day<1 || day>31)
+ return(0);
+ if(l==10)
+ goto done;
+ if(!(isdigit(buf[11]) && isdigit(buf[12]) &&
+ (isdigit(buf[13]) || buf[13]==0)))
+ return(0);
+ mem= buf[13];
+ buf[13]= 0;
+ sscanf(buf+11, "%d", &hour);
+ buf[13]= mem;
+ if(hour<0 || hour>23)
+ return(0);
+ if(l==13)
+ goto done;
+ if(!(isdigit(buf[13]) && isdigit(buf[14]) &&
+ (isdigit(buf[15]) || buf[15]==0)))
+ return(0);
+ mem= buf[15];
+ buf[15]= 0;
+ sscanf(buf+13, "%d", &minute);
+ buf[15]= mem;
+ if(minute<0 || minute>59)
+ return(0);
+ if(l==15)
+ goto done;
+ if(!(isdigit(buf[15]) && isdigit(buf[16]) && buf[17]==0))
+ return(0);
+ sscanf(buf+15, "%d", &second);
+ if(second<0 || second>59)
+ return(0);
+
+done:;
+ erg->tm_year= year-1900;
+ erg->tm_mon= month-1;
+ erg->tm_mday= day;
+ erg->tm_hour= hour;
+ erg->tm_min= minute;
+ erg->tm_sec= second;
+ return(1);
+}
+
+
+time_t Decode_timestring(char *code, time_t *date, int flag)
+{
+ char *cpt,scale_chr;
+ double value,seconds;
+ struct tm result_tm;
+ int seconds_valid= 0;
+
+ *date= 0;
+ cpt= code;
+ if(code[0]=='-' || code[0]=='+' || code[0]=='='){
+ if(code[1]==0)
+ return(0);
+ if(!isdigit(code[1]))
+ return(0);
+ value= -1;
+ if(code[0]=='=') {
+ seconds= 0;
+ sscanf(code+1,"%lf",&value);
+ } else {
+ seconds= time(NULL);
+ sscanf(code,"%lf",&value);
+ }
+ scale_chr= code[strlen(code)-1];
+ if(isalpha(scale_chr))
+ scale_chr= tolower(scale_chr);
+ if (scale_chr=='s') seconds+= 1.0*value;
+ else if(scale_chr=='h') seconds+= 3600.0*value;
+ else if(scale_chr=='d') seconds+= 86400.0*value;
+ else if(scale_chr=='w') seconds+= 86400.0*7.0*value;
+ else if(scale_chr=='m') seconds+= 86400.0*31.0*value;
+ else if(scale_chr=='y') seconds+= 86400.0*(365.25*value+1.0);
+ else seconds+= 1.0*value;
+ seconds_valid= 1;
+ goto completed;
+ } else if(Sfile_decode_datestr(&result_tm,code,0)>0) {
+ /* YYMMDD[.hhmm[ss]] */
+ result_tm.tm_isdst= -1;
+ seconds= mktime(&result_tm);
+ seconds_valid= 1;
+ goto completed;
+ } else if(Decode_date_input_format(&result_tm,code,0)>0) {
+ /* MMDDhhmm[[CC]YY][.ss]] */
+ result_tm.tm_isdst= -1;
+ seconds= mktime(&result_tm);
+ seconds_valid= 1;
+ goto completed;
+ } else if(Decode_xorriso_timestamp(&result_tm, code, 0)>0) {
+ /* 2007.11.07.225624 */
+ seconds= mktime(&result_tm);
+ seconds_valid= 1;
+ goto completed;
+ } else if(Decode_date_output_format(&result_tm, code, 0)>0) {
+ /* Thu Nov 8 09:07:50 CET 2007 */;
+ /* Sat, 03 Nov 2007 08:58:30 +0100 */;
+ /* Nov 7 23:24 */;
+ seconds= mktime(&result_tm);
+ seconds_valid= 1;
+ goto completed;
+ }
+ return(0);
+completed:;
+ if(!seconds_valid)
+ return(0);
+ *date= seconds;
+ return(1);
+}
+
+
+/* @param flag bit0=with year and seconds
+ bit1=timestamp format YYYY.MM.DD.hhmmss
+*/
+char *Ftimetxt(time_t t, char timetext[40], int flag)
+{
+ char *rpt;
+ struct tm tms, *tmpt;
+ static char months[12][4]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ tmpt= localtime_r(&t, &tms);
+ rpt= timetext;
+ rpt[0]= 0;
+ if(tmpt==0)
+ sprintf(rpt+strlen(rpt), "%12.f", (double) t);
+ else if (flag&2)
+ sprintf(rpt+strlen(rpt), "%4.4d.%2.2d.%2.2d.%2.2d%2.2d%2.2d",
+ 1900+tms.tm_year, tms.tm_mon, tms.tm_mday,
+ tms.tm_hour, tms.tm_min, tms.tm_sec);
+ else if (flag&1)
+ sprintf(rpt+strlen(rpt), "%2d %3s %4.4d %2.2d:%2.2d:%2.2d",
+ tms.tm_mday, months[tms.tm_mon], 1900+tms.tm_year,
+ tms.tm_hour, tms.tm_min, tms.tm_sec);
+ else if(time(NULL)-t < 180*86400 && time(NULL)-t >= 0)
+ sprintf(rpt+strlen(rpt), "%3s %2d %2.2d:%2.2d",
+ months[tms.tm_mon], tms.tm_mday, tms.tm_hour, tms.tm_min);
+ else
+ sprintf(rpt+strlen(rpt), "%3s %2d %4.4d",
+ months[tms.tm_mon], tms.tm_mday, 1900+tms.tm_year);
+ return(timetext);
+}
+
+
+/* @param flag bit0= single letters */
+char *Ftypetxt(mode_t st_mode, int flag)
+{
+ if(flag&1)
+ goto single_letters;
+ if(S_ISDIR(st_mode))
+ return("directory");
+ else if(S_ISREG(st_mode))
+ return("regular_file");
+ else if(S_ISLNK(st_mode))
+ return("symbolic_link");
+ else if(S_ISBLK(st_mode))
+ return("block_device");
+ else if(S_ISCHR(st_mode))
+ return("char_device");
+ else if(S_ISFIFO(st_mode))
+ return("name_pipe");
+ else if(S_ISSOCK(st_mode))
+ return("unix_socket");
+ return("unknown");
+single_letters:;
+ if(S_ISDIR(st_mode))
+ return("d");
+ else if(S_ISREG(st_mode))
+ return("-");
+ else if(S_ISLNK(st_mode))
+ return("l");
+ else if(S_ISBLK(st_mode))
+ return("b");
+ else if(S_ISCHR(st_mode))
+ return("c");
+ else if(S_ISFIFO(st_mode))
+ return("p");
+ else if(S_ISSOCK(st_mode))
+ return("s");
+ return("?");
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+
+#ifndef Xorriso_sregex_externaL
+
+#ifndef Smem_malloC
+#define Smem_malloC malloc
+#endif
+#ifndef Smem_freE
+#define Smem_freE free
+#endif
+
+
+int Sregex_string_cut(char **handle, char *text, int len, int flag)
+/*
+ bit0= append (text!=NULL)
+*/
+{
+ int l=0;
+ char *old_handle;
+
+ if((flag&1)&&*handle!=NULL)
+ l+= strlen(*handle);
+ old_handle= *handle;
+ if(text!=NULL) {
+ l+= len;
+ *handle= TSOB_FELD(char,l+1);
+ if(*handle==NULL) {
+ *handle= old_handle;
+ return(0);
+ }
+ if((flag&1) && old_handle!=NULL)
+ strcpy(*handle,old_handle);
+ else
+ (*handle)[0]= 0;
+ if(len>0)
+ strncat(*handle,text,len);
+ } else {
+ *handle= NULL;
+ }
+ if(old_handle!=NULL)
+ Smem_freE(old_handle);
+ return(1);
+}
+
+
+int Sregex_string(char **handle, char *text, int flag)
+/*
+ bit0= append (text!=NULL)
+*/
+{
+ int ret,l=0;
+
+ if(text!=NULL)
+ l= strlen(text);
+
+/* #define Sregex_looking_for_contenT 1 */
+#ifdef Sregex_looking_for_contenT
+ /* a debugging point if a certain text content has to be caught */
+ if(text!=NULL)
+ if(strcmp(text,"clear")==0)
+ ret= 0;
+#endif
+
+ ret= Sregex_string_cut(handle,text,l,flag&1);
+ return(ret);
+}
+
+#endif /* Xorriso_sregex_externaL */
+
+
+#ifndef Xorriso_text_shellsafe_externaL
+
+char *Text_shellsafe(char *in_text, char *out_text, int flag)
+{
+ int l,i,w=0;
+
+ /* enclose everything by hard quotes */
+ l= strlen(in_text);
+ out_text[w++]= '\'';
+ for(i=0;i5*SfileadrL)
+ goto overflow;
+ /* escape hard quote within the text */
+ out_text[w++]= '\'';
+ out_text[w++]= '"';
+ out_text[w++]= '\'';
+ out_text[w++]= '"';
+ out_text[w++]= '\'';
+ } else {
+ if(w+3>5*SfileadrL) {
+overflow:;
+ strncpy(out_text, "'xorriso: TEXT MUCH TOO LONG ... ",33);
+ break;
+ }
+ out_text[w++]= in_text[i];
+ }
+ }
+ out_text[w++]= '\'';
+ out_text[w++]= 0;
+ return(out_text);
+}
+
+
+#endif /* ! Xorriso_text_shellsafe_externaL */
+
+
+
+
+#ifndef Xorriso_fileliste_externaL
+
+/* ??? ts A71006 : Is this compatible with mkisofs pathspecs ?
+ I dimly remember so */
+
+int Fileliste__target_source_limit(char *line, char sep, char **limit_pt,
+ int flag)
+{
+ char *npt;
+
+ for(npt= line;*npt!=0;npt++) {
+ if(*npt=='\\') {
+ if(*(npt+1)!=0)
+ npt++;
+ continue;
+ }
+ if(*npt=='=')
+ break;
+ }
+ if(*npt==0)
+ npt= NULL;
+ (*limit_pt)= npt;
+ return(npt!=NULL);
+}
+
+#endif /* ! Xorriso_fileliste_externaL */
+
+
+/* ------------------------------------------------------------------------ */
+/* DirseQ : crawl along a directory's content list */
+
+static int Dirseq_buffer_sizE= 100;
+
+struct DirseQ {
+ char adr[SfileadrL];
+ DIR *dirpt;
+ int count;
+ char **buffer;
+ int buffer_size;
+ int buffer_fill;
+ int buffer_rpt;
+
+ struct DirseQ *next;
+};
+
+int Dirseq_destroy(struct DirseQ **o, int flag);
+int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count,
+ int max_replies, int flag);
+
+
+int Dirseq_new(struct DirseQ **o, char *adr, int flag)
+/*
+ bit0= with non-fatal errors do not complain about failed opendir()
+*/
+{
+ int ret,i,severe_error;
+ struct DirseQ *m;
+
+ m= *o= TSOB_FELD(struct DirseQ,1);
+ if(m==NULL)
+ return(-1);
+ m->adr[0]= 0;
+ m->dirpt= NULL;
+ m->count= 0;
+ m->buffer= NULL;
+ m->buffer_size= 0;
+ m->buffer_fill= 0;
+ m->buffer_rpt= 0;
+ m->next= NULL;
+ if(Sfile_str(m->adr, adr, 0)<=0)
+ {ret= 0; goto failed;}
+ m->buffer= TSOB_FELD(char *,Dirseq_buffer_sizE);
+ if(m->buffer==NULL)
+ {ret= -1; goto failed;}
+ m->buffer_size= Dirseq_buffer_sizE;
+ for(i= 0;ibuffer_size;i++)
+ m->buffer[i]= NULL;
+ if(adr[0]==0)
+ m->dirpt= opendir(".");
+ else
+ m->dirpt= opendir(adr);
+ if(m->dirpt==NULL) {
+ severe_error= (errno && errno!=ENOENT && errno!=EACCES && errno!=ENOTDIR);
+ if(severe_error || !(flag&1))
+ fprintf(stderr,"opendir(%s) failed : %s\n",adr,strerror(errno));
+ ret= -severe_error;
+ goto failed;
+ }
+ return(1);
+failed:;
+ Dirseq_destroy(o,0);
+ return(ret);
+}
+
+
+int Dirseq_destroy(struct DirseQ **o, int flag)
+{
+ int i;
+
+ if(*o==NULL)
+ return(0);
+ if((*o)->dirpt!=NULL)
+ closedir((*o)->dirpt);
+ if((*o)->buffer!=NULL) {
+ for(i=0;i<(*o)->buffer_size;i++)
+ if((*o)->buffer[i]!=NULL)
+ free((*o)->buffer[i]);
+ free((char *) (*o)->buffer);
+ }
+ free((char *) *o);
+ (*o)= NULL;
+ return(1);
+}
+
+
+int Dirseq_set_next(struct DirseQ *o, struct DirseQ *next, int flag)
+{
+ o->next= next;
+ return(1);
+}
+
+
+int Dirseq_get_next(struct DirseQ *o, struct DirseQ **next, int flag)
+{
+ *next= o->next;
+ return(1);
+}
+
+
+int Dirseq_get_adr(struct DirseQ *o, char **adrpt, int flag)
+{
+ *adrpt= o->adr;
+ return(1);
+}
+
+
+int Dirseq_rewind(struct DirseQ *o, int flag)
+{
+ rewinddir(o->dirpt);
+ return(1);
+}
+
+
+int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag)
+/*
+flag:
+ bit0= permission to use buffer
+ bit1= do not increment counter
+ bit2= ignore buffer in any case
+ bit3= do not exclude '.' and '..'
+ bit4= sort buffer
+ bit5= sort only incomplete last buffer
+return:
+ <0 error
+ 0= no more entries available
+ 1= ok, reply is valid
+*/
+{
+ int ret;
+ struct dirent *entry;
+ char *name;
+
+ static int override_flag_0= 0,override_flag_1= 32;
+ flag= (flag&~override_flag_0)|override_flag_1;
+
+ if((flag&1) && o->buffer_rpt>=o->buffer_fill) {
+ /* permission to buffer and buffer empty : load a buffer */
+ ret= Dirseq_next_adrblock(o,o->buffer,&(o->buffer_fill),
+ o->buffer_size,2|4|(flag&16));
+ if(ret<=0)
+ return(ret);
+ o->buffer_rpt= 0;
+ if((flag&32) && o->buffer_fillbuffer_size && o->buffer_fill>0)
+ Sort_argv(o->buffer_fill,o->buffer,0);
+ }
+ if(o->buffer_rptbuffer_fill && !(flag&4)) {
+ ret= Sfile_str(reply,o->buffer[o->buffer_rpt],0);
+ Sregex_string(&(o->buffer[o->buffer_rpt]),NULL,0);
+ if(ret<=0)
+ return(-1);
+ (o->buffer_rpt)++;
+ if(!(flag&2))
+ o->count++;
+ return(1);
+ }
+ do {
+ entry= readdir(o->dirpt);
+ if(entry==NULL) {
+ /* >>> how to distinguish error from EOF , do i need a (FILE *) ? */
+ return(0);
+ }
+ if(strlen(entry->d_name)>=SfileadrL) {
+ fprintf(stderr,"--- oversized directory entry (number %d) :\n %s",
+ o->count+1,entry->d_name);
+ return(-1);
+ }
+ name= entry->d_name;
+ if(flag&8)
+ break;
+ /* skip "." and ".." */
+ } while(name[0]=='.' && ((name[1]=='.' && name[2]==0) || name[1]==0));
+ if(Sfile_str(reply,name,0)<=0)
+ return(-1);
+ if(!(flag&2))
+ o->count++;
+ return(1);
+}
+
+
+int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count,
+ int max_replies, int flag)
+/* @param replies A vector of Sregex_string pointers */
+/*
+flag:
+ bit0= permission to use buffer
+ bit1= do not increment counter
+ bit2= ignore buffer in any case
+ bit4= sort replies
+return:
+ <0 error
+ 0= no more entries available
+ 1= ok, reply is valid
+*/
+{
+ int i,ret;
+ char reply[SfileadrL];
+
+ *reply_count= 0;
+ for(i=0;itext= NULL;
+ s->next= s->prev= NULL;
+
+ if(data_len<=0)
+ {ret= -1; goto failed;}
+ s->text= Smem_malloC(data_len);
+ if(s->text==NULL)
+ {ret= -1; goto failed;}
+ if(!(flag&2))
+ memcpy(s->text,data,data_len);
+
+ if(link==NULL) {
+ ;
+ } else if(flag&1) {
+ s->next= link;
+ s->prev= link->prev;
+ if(link->prev!=NULL)
+ link->prev->next= s;
+ link->prev= s;
+ } else {
+ s->prev= link;
+ s->next= link->next;
+ if(link->next!=NULL)
+ link->next->prev= s;
+ link->next= s;
+ }
+ *lstring= s;
+ return(1);
+failed:;
+ *lstring= s;
+ Lstring_destroy(lstring,0);
+ return(-1);
+}
+
+
+/*
+ @param flag Bitfield for control purposes
+ bit0= insert before link rather than after it
+*/
+int Lstring_new(struct LstrinG **lstring, char *text, struct LstrinG *link,
+ int flag)
+{
+ int ret;
+
+ ret= Lstring_new_binary(lstring,text,strlen(text)+1,link,flag&1);
+ return(ret);
+}
+
+
+/*
+ @param flag Bitfield for control purposes
+ bit0= do not set *lstring to NULL
+*/
+int Lstring_destroy(struct LstrinG **lstring, int flag)
+{
+ struct LstrinG *s;
+
+ s= *lstring;
+ if(s==NULL)
+ return(0);
+ if(s->prev!=NULL)
+ s->prev->next= s->next;
+ if(s->next!=NULL)
+ s->next->prev= s->prev;
+ if(s->text!=NULL)
+ Smem_freE(s->text);
+ Smem_freE((char *) s);
+ if(!(flag&1))
+ *lstring= NULL;
+ return(1);
+}
+
+
+int Lstring_destroy_all(struct LstrinG **lstring, int flag)
+{
+ struct LstrinG *s,*next;
+
+ if((*lstring)==NULL)
+ return(0);
+ for(s= *lstring; s->prev!=NULL; s= s->prev);
+ for(;s!=NULL;s= next){
+ next= s->next;
+ Lstring_destroy(&s,0);
+ }
+ *lstring= NULL;
+ return(1);
+}
+
+
+int Lstring_append_binary(struct LstrinG **entry, char *data, int data_len,
+ int flag)
+{
+ struct LstrinG *target= NULL,*newby;
+
+ if(*entry!=NULL)
+ for(target= *entry; target->next!=NULL; target= target->next);
+ if(Lstring_new_binary(&newby, data, data_len, target, 0)<=0)
+ return(-1);
+ if(*entry==NULL)
+ *entry= newby;
+ return(1);
+}
+
+
+#endif /* Xorriso_sregex_externaL */
+
+
+/* ------------------------------ LinkiteM -------------------------------- */
+
+struct LinkiteM {
+ char *link_path;
+ dev_t target_dev;
+ ino_t target_ino;
+ int link_count;
+ struct LinkiteM *next;
+};
+
+int Linkitem_destroy(struct LinkiteM **o, int flag);
+
+
+int Linkitem_new(struct LinkiteM **o, char *link_path, dev_t target_dev,
+ ino_t target_ino, struct LinkiteM *next, int flag)
+{
+ struct LinkiteM *m;
+
+ m= *o= TSOB_FELD(struct LinkiteM,1);
+ if(m==NULL)
+ return(-1);
+ m->target_dev= target_dev;
+ m->target_ino= target_ino;
+ m->next= next;
+ m->link_count= 1;
+ if(next!=NULL)
+ m->link_count= m->next->link_count+1;
+ m->link_path= strdup(link_path);
+ if(m->link_path==NULL)
+ goto failed;
+ return(1);
+failed:;
+ Linkitem_destroy(o, 0);
+ return(-1);
+}
+
+
+int Linkitem_destroy(struct LinkiteM **o, int flag)
+{
+ if((*o)==NULL)
+ return(0);
+ if((*o)->link_path!=NULL)
+ free((*o)->link_path);
+ free((char *) (*o));
+ *o= NULL;
+ return(1);
+}
+
+
+int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag)
+{
+ struct LinkiteM *m, *m_next= NULL;
+
+ /* Prevent memory corruption */
+ for(m= *o; m!=to; m= m->next)
+ if(m==NULL) { /* this may actually not happen */
+ *o= to;
+ return(-1);
+ }
+
+ for(m= *o; m!=to; m= m_next) {
+ m_next= m->next;
+ Linkitem_destroy(&m, 0);
+ }
+ *o= to;
+ return(1);
+}
+
+
+int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino,
+ struct LinkiteM **result, int flag)
+{
+ struct LinkiteM *m;
+
+ for(m= stack; m!=NULL; m= m->next) {
+ if(target_dev == m->target_dev && target_ino == m->target_ino) {
+ *result= m;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+
+/* ------------------------------- FindjoB -------------------------------- */
+
+
+struct FindjoB {
+ char *start_path;
+
+ char *name_expr;
+ regex_t name_re;
+ regmatch_t name_match;
+
+ /* b = blockdev
+ c = chardev
+ d = directory
+ p = fifo
+ f = reg
+ - = reg
+ s = socket
+ m = subordinate mountpoint (does never match find start directory)
+ X = other
+ 0x0 = test inactive
+ */
+ char file_type;
+
+
+ /* 0= echo
+ 1= rm (also rmdir)
+ 2= rm_r
+>>> 3= mv target
+ 4= chown user
+ 5= chgrp group
+ 6= chmod mode_and mode_or
+ 7= alter_date type date
+ 8= lsdl
+ 9= chown_r user
+ 10= chgrp_r group
+ 11= chmod_r mode_and mode_or
+ 12= alter_date_r type date
+ 13= find
+ 14= compare disk_equivalent_of_start_path
+ 15= in_iso iso_rr_equivalent_of_start_path
+ 16= not_in_iso iso_rr_equiv
+ 17= update disk_equiv
+ 18= add_missing iso_rr_equiv
+ 19= empty_iso_dir iso_rr_equiv
+ 20= is_full_in_iso iso_rr_equiv
+ */
+ int action;
+ char *target;
+ uid_t user;
+ gid_t group;
+ mode_t mode_and, mode_or;
+ int type; /* see Xorriso_set_time flag */
+ time_t date;
+ struct FindjoB *subjob;
+
+};
+
+int Findjob_destroy(struct FindjoB **job, int flag);
+
+
+int Findjob_new(struct FindjoB **o, char *start_path, int flag)
+{
+ struct FindjoB *m;
+
+ m= *o= TSOB_FELD(struct FindjoB,1);
+ if(m==NULL)
+ return(-1);
+ m->start_path= NULL;
+ m->name_expr= NULL;
+ m->file_type= 0;
+ m->action= 0; /* print */
+ m->target= NULL; /* a mere pointer, not managed memory */
+ m->user= 0;
+ m->group= 0;
+ m->type= 0;
+ m->date= 0;
+ m->subjob= NULL;
+ m->start_path= strdup(start_path);
+ if(m->start_path==NULL)
+ goto failed;
+ return(1);
+failed:;
+ Findjob_destroy(o, 0);
+ return(-1);
+}
+
+
+int Findjob_destroy(struct FindjoB **o, int flag)
+{
+ struct FindjoB *m;
+
+ m= *o;
+ if(m==NULL)
+ return(0);
+ if(m->start_path!=NULL)
+ free(m->start_path);
+ if(m->name_expr!=NULL) {
+ regfree(&(m->name_re));
+ free(m->name_expr);
+ }
+ Findjob_destroy(&(m->subjob), 0);
+ free((char *) m);
+ *o= NULL;
+ return(1);
+}
+
+
+int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag)
+{
+ if(o->start_path!=NULL)
+ free(o->start_path);
+ if(start_path!=NULL) {
+ o->start_path= strdup(start_path);
+ if(o->start_path==NULL)
+ return(-1);
+ } else
+ o->start_path= NULL;
+ return(1);
+}
+
+
+int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag)
+{
+ *start_path= o->start_path;
+ return(1);
+}
+
+
+int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag)
+{
+ char regexpr[2*SfileadrL+2];
+
+ if(o->name_expr!=NULL) {
+ regfree(&(o->name_re));
+ free(o->name_expr);
+ o->name_expr= NULL;
+ }
+ if(strlen(name_expr)>=SfileadrL)
+ return(0);
+ o->name_expr= strdup(name_expr);
+ if(o->name_expr==NULL)
+ return(-1);
+ Xorriso__bourne_to_reg(name_expr, regexpr, 0);
+ if(regcomp(&(o->name_re), regexpr, 0)!=0)
+ return(0);
+ return(1);
+}
+
+
+int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag)
+{
+ static char known[]= {"bcdpf-lsmX"};
+
+ if(file_type!=0)
+ if(strchr(known, file_type)==NULL)
+ return(0);
+ o->file_type= file_type;
+ return(1);
+}
+
+
+/* @return 0=no match , 1=match , <0 = error
+*/
+int Findjob_test(struct FindjoB *o, char *name,
+ struct stat *boss_stbuf, struct stat *stbuf,
+ int depth, int flag)
+{
+ int ret;
+
+ if(o->name_expr!=NULL) {
+ ret= regexec(&(o->name_re),name,1,&(o->name_match),0);
+ if(ret!=0)
+ return(0);
+ }
+
+ if(o->file_type!=0) {
+ if(S_ISBLK(stbuf->st_mode)) {
+ if(o->file_type!='b')
+ return(0);
+ } else if(S_ISCHR(stbuf->st_mode)) {
+ if(o->file_type!='c')
+ return(0);
+ } else if(S_ISDIR(stbuf->st_mode)) {
+ if(o->file_type=='m') {
+ if(boss_stbuf==NULL)
+ return(0);
+ if(boss_stbuf->st_dev == stbuf->st_dev)
+ return(0);
+ } else if(o->file_type!='d')
+ return(0);
+ } else if(S_ISFIFO(stbuf->st_mode)) {
+ if(o->file_type!='p')
+ return(0);
+ } else if(S_ISREG(stbuf->st_mode)) {
+ if(o->file_type!='f' && o->file_type!='-')
+ return(0);
+ } else if(((stbuf->st_mode)&S_IFMT)==S_IFLNK) {
+ if(o->file_type!='l')
+ return(0);
+ } else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) {
+ if(o->file_type!='s')
+ return(0);
+ } else {
+ if(o->file_type!='X')
+ return(0);
+ }
+ }
+
+ /* ??? >>> more tests to come ?*/;
+
+ return(1);
+}
+
+
+int Findjob_get_action(struct FindjoB *o, int flag)
+{
+ return(o->action);
+}
+
+
+/* @return <0 error, >=0 see above struct FindjoB.action
+*/
+int Findjob_get_action_parms(struct FindjoB *o, char **target,
+ uid_t *user, gid_t *group,
+ mode_t *mode_and, mode_t *mode_or,
+ int *type, time_t *date, struct FindjoB **subjob,
+ int flag)
+{
+ *target= o->target;
+ *user= o->user;
+ *group= o->group;
+ *mode_and= o->mode_and;
+ *mode_or= o->mode_or;
+ *type= o->type;
+ *date= o->date;
+ *subjob= o->subjob;
+ return(o->action);
+}
+
+
+int Findjob_set_action_target(struct FindjoB *o, int action, char *target,
+ int flag)
+{
+ o->action= action;
+ o->target= target;
+ return(1);
+}
+
+
+/* @param flag bit0= recursive
+*/
+int Findjob_set_action_chown(struct FindjoB *o, uid_t user,int flag)
+{
+ int ret;
+
+ if(flag&1) {
+ o->action= 0;
+ Findjob_destroy(&(o->subjob), 0);
+ ret= Findjob_new(&(o->subjob), "", 0);
+ if(ret<=0)
+ return(-1);
+ Findjob_set_action_chown(o->subjob, user, 0);
+ o->action= 9;
+ } else {
+ o->action= 4;
+ o->user= user;
+ }
+ return(1);
+}
+
+
+/* @param flag bit0= recursive
+*/
+int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag)
+{
+ int ret;
+
+ if(flag&1) {
+ o->action= 0;
+ Findjob_destroy(&(o->subjob), 0);
+ ret= Findjob_new(&(o->subjob), "", 0);
+ if(ret<=0)
+ return(-1);
+ Findjob_set_action_chgrp(o->subjob, group, 0);
+ o->action= 10;
+ } else {
+ o->action= 5;
+ o->group= group;
+ }
+ return(1);
+}
+
+
+/* @param flag bit0= recursive
+*/
+int Findjob_set_action_chmod(struct FindjoB *o,
+ mode_t mode_and, mode_t mode_or, int flag)
+{
+ int ret;
+
+ if(flag&1) {
+ o->action= 0;
+ Findjob_destroy(&(o->subjob), 0);
+ ret= Findjob_new(&(o->subjob), "", 0);
+ if(ret<=0)
+ return(-1);
+ Findjob_set_action_chmod(o->subjob, mode_and, mode_or, 0);
+ o->action= 11;
+ } else {
+ o->action= 6;
+ o->mode_and= mode_and;
+ o->mode_or= mode_or;
+ }
+ return(1);
+}
+
+
+/* @param flag bit0= recursive
+*/
+int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag)
+{
+ int ret;
+
+ if(flag&1) {
+ o->action= 0;
+ Findjob_destroy(&(o->subjob), 0);
+ ret= Findjob_new(&(o->subjob), "", 0);
+ if(ret<=0)
+ return(-1);
+ Findjob_set_action_ad(o->subjob, type, date, 0);
+ o->action= 12;
+ } else {
+ o->action= 7;
+ o->type= type;
+ o->date= date;
+ }
+ return(1);
+}
+
+
+int Findjob_set_action_subjob(struct FindjoB *o, int action,
+ struct FindjoB *subjob, int flag)
+{
+ o->action= action;
+ Findjob_destroy(&(o->subjob), 0);
+ o->subjob= subjob;
+ return(1);
+}
+
+
+/* ---------------------------- SplitparT ------------------------- */
+
+
+struct SplitparT {
+ char *name;
+ int partno;
+ int total_parts;
+ off_t offset;
+ off_t bytes;
+ off_t total_bytes;
+};
+
+
+int Splitparts_new(struct SplitparT **o, int count, int flag)
+{
+ int i;
+
+ (*o)= TSOB_FELD(struct SplitparT, count);
+ if((*o)==NULL)
+ return(-1);
+ for(i= 0; i0) {
+ Sfile_off_t_text(adr+strlen(adr), offset / (1024*1024), 0);
+ strcat(adr, "m");
+ } else
+ Sfile_off_t_text(adr+strlen(adr), offset, 0);
+ strcat(adr, "_with_");
+ if((bytes % (1024*1024))==0) {
+ Sfile_off_t_text(adr+strlen(adr), bytes / (1024*1024), 0);
+ strcat(adr, "m");
+ } else
+ Sfile_off_t_text(adr+strlen(adr), bytes, 0);
+ strcat(adr, "_of_");
+ Sfile_off_t_text(adr+strlen(adr), total_bytes, 0);
+ return(1);
+}
+
+
+/* ---------------------------- End SplitparT ------------------------- */
+
+/* ------------------------------ ExclusionS ------------------------------ */
+
+struct ExclusionS {
+
+ /* Absolute input patterns which lead to not_paths */
+ struct LstrinG *not_paths_descr;
+
+ /* Actually banned absolute paths */
+ struct LstrinG *not_paths;
+
+ /* Input patterns which lead to not_leafs */
+ struct LstrinG *not_leafs_descr;
+
+ /* Compiled not_leaf patterns. Caution: not char[] but regex_t */
+ struct LstrinG *not_leafs;
+
+};
+
+
+int Exclusions_new(struct ExclusionS **o, int flag)
+{
+ struct ExclusionS *m;
+
+ m= *o= TSOB_FELD(struct ExclusionS, 1);
+ if(m==NULL)
+ return(-1);
+ m->not_paths_descr= NULL;
+ m->not_paths= NULL;
+ m->not_leafs_descr= NULL;
+ m->not_leafs= NULL;
+ return(1);
+}
+
+
+int Exclusions_destroy(struct ExclusionS **o, int flag)
+{
+ struct LstrinG *s,*next;
+
+ if((*o)==NULL)
+ return(0);
+ Lstring_destroy_all(&((*o)->not_paths_descr), 0);
+ Lstring_destroy_all(&((*o)->not_paths), 0);
+ Lstring_destroy_all(&((*o)->not_leafs_descr), 0);
+ for(s= (*o)->not_leafs; s!=NULL; s= next){
+ next= s->next;
+ regfree((regex_t *) s->text);
+ Lstring_destroy(&s, 0);
+ }
+ (*o)= NULL;
+ return(1);
+}
+
+
+int Exclusions_add_not_paths(struct ExclusionS *o, int descrc, char **descrs,
+ int pathc, char **paths, int flag)
+{
+ struct LstrinG *s, *new_s;
+ int i, ret;
+
+ s= NULL;
+ if(o->not_paths_descr!=NULL)
+ for(s= o->not_paths_descr; s->next!=NULL; s= s->next);
+ for(i= 0; inot_paths_descr==NULL)
+ o->not_paths_descr= new_s;
+ s= new_s;
+ }
+ s= NULL;
+ if(o->not_paths!=NULL)
+ for(s= o->not_paths; s->next!=NULL; s= s->next);
+ for(i= 0; inot_paths==NULL)
+ o->not_paths= new_s;
+ s= new_s;
+ }
+ return(1);
+}
+
+
+/* @return -1=cannot store , 0=cannot compile regex , 1=ok
+*/
+int Exclusions_add_not_leafs(struct ExclusionS *o, char *not_leafs_descr,
+ regex_t *re, int flag)
+{
+ int ret;
+
+ ret= Lstring_append_binary(&(o->not_leafs_descr),
+ not_leafs_descr, strlen(not_leafs_descr)+1, 0);
+ if(ret<=0)
+ return(-1);
+ ret= Lstring_append_binary(&(o->not_leafs), (char *) re, sizeof(regex_t), 0);
+ if(ret<=0)
+ return(-1);
+ return(1);
+}
+
+
+/* @param flag bit0= whole subtree is banned with -not_paths
+ @return 0=no match , 1=not_paths , 2=not_leafs, <0=error
+*/
+int Exclusions_match(struct ExclusionS *o, char *abs_path, int flag)
+{
+ struct LstrinG *s;
+ char leaf[SfileadrL], *leaf_pt;
+ regmatch_t match[1];
+ int ret, was_non_slash, l;
+
+ /* test abs_paths */
+ if(flag&1) {
+ for(s= o->not_paths; s!=NULL; s= s->next) {
+ l= strlen(s->text);
+ if(strncmp(abs_path, s->text, l)==0)
+ if(abs_path[l]=='/' || abs_path[l]==0)
+ return(1);
+ }
+ } else {
+ for(s= o->not_paths; s!=NULL; s= s->next)
+ if(strcmp(abs_path, s->text)==0)
+ return(1);
+ }
+
+ /* determine leafname */
+ was_non_slash= 0;
+ for(leaf_pt= abs_path+strlen(abs_path); leaf_pt>abs_path; leaf_pt--) {
+ if(*leaf_pt=='/') {
+ if(was_non_slash) {
+ leaf_pt++;
+ break;
+ }
+ } else if(*leaf_pt!=0)
+ was_non_slash= 1;
+ }
+ if(strlen(leaf_pt)>=SfileadrL)
+ return(-1);
+ strcpy(leaf, leaf_pt);
+ leaf_pt= strchr(leaf, '/');
+ if(leaf_pt!=NULL)
+ *leaf_pt= 0;
+
+ /* test with leaf expressions */
+ for(s= o->not_leafs; s!=NULL; s= s->next) {
+ ret= regexec((regex_t *) s->text, leaf, 1, match, 0);
+ if(ret==0)
+ return(2);
+ }
+ return(0);
+}
+
+
+int Exclusions_get_descrs(struct ExclusionS *o,
+ struct LstrinG **not_paths_descr,
+ struct LstrinG **not_leafs_descr, int flag)
+{
+ *not_paths_descr= o->not_paths_descr;
+ *not_leafs_descr= o->not_leafs_descr;
+ return(1);
+}
+
+
+/* ---------------------------- End ExclusionS ---------------------------- */
+
+/* ------------------------------- Xorriso -------------------------------- */
+
+/** The list of startup file names */
+#define Xorriso_rc_nuM 4
+
+static char Xorriso_sys_rc_nameS[Xorriso_rc_nuM][80]= {
+ "/etc/default/xorriso",
+ "/etc/opt/xorriso/rc",
+ "/etc/xorriso/xorriso.conf",
+ "placeholder for $HOME/.xorrisorc"
+};
+
+
+int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
+{
+ int i, ret;
+ struct XorrisO *m;
+
+ *xorriso= m= TSOB_FELD(struct XorrisO,1);
+ if(m==NULL)
+ return(-1);
+ m->libs_are_started= 0;
+ strncpy(m->progname,progname,sizeof(m->progname)-1);
+ m->progname[sizeof(m->progname)-1]= 0;
+ if(getcwd(m->initial_wdx,sizeof(m->initial_wdx)-1)==NULL)
+ m->initial_wdx[0]= 0;
+ m->no_rc= 0;
+
+ m->rc_filename_count= Xorriso_rc_nuM;
+ for(i=0;irc_filename_count-1;i++)
+ strcpy(m->rc_filenames[i],Xorriso_sys_rc_nameS[i]);
+ m->rc_filenames[m->rc_filename_count-1][0]= 0;
+
+ m->wdi[0]= 0;
+ strcpy(m->wdx, m->initial_wdx);
+ m->did_something_useful= 0;
+ m->add_plainly= 0;
+ m->split_size= 0;
+ m->do_joliet= 0;
+ m->do_follow_pattern= 1;
+ m->do_follow_param= 0;
+ m->do_follow_links= 0;
+ m->follow_link_limit= 100;
+ m->do_follow_mount= 1;
+ m->do_global_uid= 0;
+ m->global_uid= 0;
+ strcpy(m->volid, "ISOIMAGE");
+ m->loaded_volid[0]= 0;
+ m->volid_default= 1;
+ m->publisher[0]= 0;
+ m->session_logfile[0]= 0;
+ m->session_lba= -1;
+ m->session_blocks= 0;
+ m->do_global_gid= 0;
+ m->global_gid= 0;
+ m->do_global_mode= 0;
+ m->global_dir_mode= 0555;
+ m->global_file_mode= 0444;
+ m->do_overwrite= 2;
+ m->do_reassure= 0;
+ m->toc_emulation_flag= 0;
+ m->image_start_mode= 0;
+ m->image_start_value[0]= 0;
+ m->indev[0]= 0;
+ m->in_drive_handle= NULL;
+ m->in_volset_handle= NULL;
+ m->volset_change_pending= 0;
+ m->no_volset_present= 0;
+ m->outdev[0]= 0;
+ m->out_drive_handle= NULL;
+ m->dev_fd_1= -1;
+ m->ban_stdio_write= 0;
+ m->do_dummy= 0;
+ m->do_close= 0;
+ m->speed= 0;
+ m->fs= 4*512; /* 4 MiB */
+ m->padding= 300*1024;
+ m->keep_boot_image= 0;
+ m->patch_isolinux_image= 0;
+ m->allow_graft_points= 0;
+ m->dialog= 0;
+ m->search_mode= 0;
+ m->structured_search= 1;
+ m->do_iso_rr_pattern= 1;
+ m->do_disk_pattern= 2;
+ m->temp_mem_limit= 16*1024*1024;
+ m->disk_exclusions= NULL;
+ m->disk_excl_mode= 1;
+ m->use_stdin= 0;
+ m->result_page_length= 0;
+ m->result_page_width= 80;
+ m->mark_text[0]= 0;
+ m->packet_output= 0;
+ for(i=0; i<4; i++)
+ m->logfile[i][0]= 0;
+ m->status_history_max= Xorriso_status_history_maX;
+ strcpy(m->report_about_text, "UPDATE");
+ Xorriso__text_to_sev(m->report_about_text, &m->report_about_severity, 0);
+ m->library_msg_direct_print= 0;
+ strcpy(m->abort_on_text,"FATAL");
+ Xorriso__text_to_sev(m->abort_on_text, &m->abort_on_severity, 0);
+ m->problem_status= 0;
+ m->problem_status_text[0]= 0;
+ m->errfile_log[0]= 0;
+ m->errfile_fp= NULL;
+ m->img_read_error_mode= 2; /* abort faulty image reading with FATAL */
+ strcpy(m->return_with_text, "SORRY");
+ Xorriso__text_to_sev(m->return_with_text, &m->return_with_severity, 0);
+ m->return_with_value= 32;
+ m->eternal_problem_status= 0;
+ m->eternal_problem_status_text[0]= 0;
+ m->re= NULL;
+ /* >>> ??? how to initialize m->match[0] ? */
+ m->re_constants= NULL;
+ m->re_count= 0;
+ m->re_fill= 0;
+ m->reg_expr[0]= 0;
+ m->run_state= 0;
+ m->is_dialog= 0;
+ m->bar_is_fresh= 0;
+ m->pending_option[0]= 0;
+ m->request_to_abort= 0;
+ m->request_not_to_ask= 0;
+ m->idle_time= 0.0;
+ m->re_failed_at= -1;
+ m->prepended_wd= 0;
+ m->insert_count= 0;
+ m->insert_bytes= 0;
+ m->error_count= 0;
+ m->pacifier_interval= 1.0;
+ m->pacifier_count= 0;
+ m->pacifier_total= 0;
+ m->pacifier_fifo= NULL;
+ m->start_time= 0.0;
+ m->last_update_time= 0.0;
+ m->find_compare_result= 1;
+ m->result_line[0]= 0;
+ m->result_line_counter= 0;
+ m->result_page_counter= 0;
+ m->result_open_line_len= 0;
+ m->info_text[0]= 0;
+
+ ret= Exclusions_new(&(m->disk_exclusions), 0);
+ if(ret<=0)
+ goto failure;
+
+ return(1);
+failure:;
+ Xorriso_destroy(xorriso, 0);
+ return(-1);
+}
+
+
+int Xorriso_destroy_re(struct XorrisO *m, int flag)
+{
+ int i;
+
+ if(m->re!=NULL) {
+ for(i=0;ire_fill;i++) {
+ if(m->re_constants!=NULL)
+ if(m->re_constants[i]!=NULL)
+ continue; /* ,->re[i] was never subject to regcomp() */
+ regfree(&(m->re[i]));
+ }
+ free((char *) m->re);
+ m->re= NULL;
+ }
+
+ if(m->re_constants!=NULL) {
+ for(i=0;ire_fill;i++)
+ if(m->re_constants[i]!=NULL)
+ free(m->re_constants[i]);
+ free((char *) m->re_constants);
+ m->re_constants= NULL;
+ }
+ m->re_count= 0;
+ m->re_fill= 0;
+ return(1);
+}
+
+
+/* @param flag bit0= global shutdown of libraries */
+int Xorriso_destroy(struct XorrisO **xorriso, int flag)
+{
+ struct XorrisO *m;
+
+ m= *xorriso;
+ if(m==NULL)
+ return(0);
+ Xorriso_destroy_re(m,0);
+ Exclusions_destroy(&(m->disk_exclusions), 0);
+ Xorriso_detach_libraries(m, flag&1);
+
+ free((char *) m);
+ *xorriso= NULL;
+ return(1);
+}
+
+
+int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize,
+ int flag)
+/*
+ bit0= do not write to history
+ bit1= do not read input (but eventually write to history)
+ bit2= do not write to history line which begin with "-history:" or "-history "
+*/
+{
+ char *cpt= NULL;
+ int ret;
+#ifdef Xorriso_with_readlinE
+ int l;
+ static char last_input[SfileadrL]= {""};
+#endif /* ! Xorriso_with_readlinE */
+ double tdiff;
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday(&tv,&tz);
+ tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec);
+
+ fflush(stdout);
+
+#ifdef Xorriso_with_readlinE
+
+ if(xorriso->use_stdin || xorriso->dev_fd_1>=0) {
+ if(flag&2)
+ {ret= 1; goto ex;}
+ if(Sfile_fgets(line,linesize-1,stdin)==NULL) {
+ /* need a very dramatic end */
+ kill(getpid(),SIGHUP);
+ {ret= -1; goto ex;}
+ }
+ {ret= 1; goto ex;}
+ }
+ if(flag&2) {
+ cpt= NULL;
+ } else {
+ cpt= readline("");
+ if(cpt==NULL) {
+ /* need a very dramatic end */
+ kill(getpid(),SIGHUP);
+ {ret= -1; goto ex;}
+ }
+ l= strlen(cpt);
+ if(l>=linesize) {
+ strncpy(line,cpt,linesize-1);
+ line[sizeof(line)-1]= 0;
+ } else
+ strcpy(line,cpt);
+ }
+ if(line[0]!=0 && strcmp(last_input,line)!=0 && !(flag&1))
+ if(!((flag&4) &&
+ (strncmp(line,"-history:",9)==0 || strncmp(line,"-history ",9)==0))) {
+ add_history(line);
+ strncpy(last_input,line,sizeof(last_input)-1);
+ last_input[sizeof(last_input)-1]= 0;
+ }
+
+#else /* Xorriso_with_readlinE */
+
+ if(flag&2)
+ {ret= 1; goto ex;}
+ if(Sfile_fgets(line,linesize-1,stdin)==NULL) {
+ /* need a very dramatic end */
+ kill(getpid(),SIGHUP);
+ {ret= -1; goto ex;}
+ }
+
+#endif /* ! Xorriso_with_readlinE */
+
+ ret= 1;
+ex:;
+ if(cpt!=NULL)
+ free(cpt);
+ gettimeofday(&tv,&tz);
+ xorriso->idle_time+= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff;
+ return(ret);
+}
+
+
+int Xorriso_request_confirmation(struct XorrisO *xorriso, int flag)
+/*
+ bit0= important operation going on:
+ demand confirmation of abort, only abort on @@@
+ bit1= mark '@' and '@@' by return 4
+ bit2= accept: i|n= ignore | do not remove , r|y= retry | remove , q|x= abort
+ bit3= @@@ = 'done reading' rather than 'abort'
+ bit4= in non-dialog mode return 6 rather than 1
+*/
+/* return: <=0 error
+ 1= go on | do not remove existing file
+ 2= abort
+ 3= redo request for confirmation
+ 4= see flag bit1
+ (5= skip volume)
+ 6= retry failed operation | remove existing file
+ */
+{
+ int ret;
+ char line[SfileadrL],*cpt,previous_line[SfileadrL];
+ char *abort_req_text,*abort_really_text;
+
+ if(!xorriso->dialog) {
+ if(flag&16)
+ return(6);
+ return(1);
+ }
+ if(flag&8) {
+ abort_req_text= "request to end";
+ abort_really_text= "done reading";
+ } else {
+ abort_req_text= "request to abort";
+ abort_really_text= "abort this command";
+ }
+ ret= Xorriso_dialog_input(xorriso,line,sizeof(line),1);
+ xorriso->result_line_counter= 0;
+ xorriso->result_page_counter++;
+ if(ret<=0)
+ if(xorriso->result_page_length>0)
+ xorriso->result_page_length= -xorriso->result_page_length;
+
+ cpt= line;
+ if(strcmp(cpt,"@@@")==0 ||
+ strcmp(cpt,"x")==0 || strcmp(cpt,"X")==0 ||
+ strcmp(cpt,"q")==0 || strcmp(cpt,"Q")==0) {
+ if(flag&1) {
+ strcpy(previous_line,cpt);
+ sprintf(xorriso->info_text,
+ "... [%s = %s registered. Really %s ? (y/n) ] ...\n",
+ cpt,abort_req_text,abort_really_text);
+ Xorriso_info(xorriso,0);
+ ret= Xorriso_dialog_input(xorriso,line,sizeof(line),1);
+ if(ret<=0)
+ return(ret);
+ cpt= line;
+ if(strcmp(cpt,previous_line)==0 ||
+ ((*cpt=='Y' || *cpt=='y' || *cpt=='j' || *cpt=='J' || *cpt=='1') &&
+ *(cpt+1)==0)) {
+ xorriso->request_to_abort= 1;
+ sprintf(xorriso->info_text,
+ "------- ( %s confirmed )\n",abort_req_text);
+ Xorriso_info(xorriso,0);
+ return(2);
+ }
+ sprintf(xorriso->info_text, "....... ( %s revoked )\n",abort_req_text);
+ Xorriso_info(xorriso,0);
+ return(3);
+ }
+ xorriso->request_to_abort= 1;
+ sprintf(xorriso->info_text,
+"----------- [%s = request to abort registered. Operation ends ] ------------\n",
+ cpt);
+ Xorriso_info(xorriso,0);
+ return(2);
+ } else if(*cpt=='@') {
+ if(strcmp(cpt,"@@")==0) {
+ goto klammer_affe;
+
+ } else if(strcmp(cpt,"@")==0) {
+klammer_affe:;
+ if(xorriso->result_page_length>0)
+ xorriso->result_page_length= -xorriso->result_page_length;
+ if(flag&1) {
+ sprintf(xorriso->info_text,
+"... [@ = prompt suppression registered. Prompting disabled temporarily ] ...\n");
+ Xorriso_info(xorriso,0);
+ }
+
+ } else {
+ Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */
+ sprintf(xorriso->info_text,
+ "--- Unrecognized input beginning with @. Please enter someting else.\n");
+ Xorriso_info(xorriso,0);
+ return(3);
+ }
+ if(flag&2)
+ return(4);
+ if(flag&1)
+ return(3);
+ return(1);
+ } else if(flag&4) {
+
+ if(strcmp(cpt,"i")==0 || strcmp(cpt,"I")==0 ||
+ strcmp(cpt,"n")==0 || strcmp(cpt,"N")==0 ||
+ *cpt==0) {
+ return(1);
+ } else if(strcmp(cpt,"r")==0 || strcmp(cpt,"R")==0 ||
+ strcmp(cpt,"y")==0 || strcmp(cpt,"Y")==0) {
+ return(6);
+ } else {
+ /* >>> unknown input */
+ sprintf(xorriso->info_text,
+ "--- Please enter one of : empty line, i,n, r,y, q,x, @, @@@\n");
+ Xorriso_info(xorriso,0);
+ return(3);
+ }
+
+ } else if(*cpt!=0 && !(flag&1)) {
+ Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */
+ strcpy(xorriso->pending_option,cpt);
+ xorriso->request_to_abort= 1;
+ sprintf(xorriso->info_text,
+"-------------- [ Input of option registered. Operation ends ] ---------------\n");
+ Xorriso_info(xorriso,0);
+ return(2);
+
+ } else if(*cpt!=0) {
+ Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */
+ sprintf(xorriso->info_text,
+ "--- Please enter one of : empty line, @, @@@\n");
+ Xorriso_info(xorriso,0);
+ return(3);
+ }
+ return(1);
+}
+
+
+int Xorriso_predict_linecount(struct XorrisO *xorriso, char *line,
+ int *linecount, int flag)
+{
+ int width,l;
+ char *spt,*ept;
+
+ *linecount= 0;
+ spt= line;
+ width= xorriso->result_page_width;
+ while(1) {
+ ept= strchr(spt,'\n');
+ if(ept==NULL)
+ l= strlen(spt);
+ else
+ l= ept-spt;
+ l+= xorriso->result_open_line_len;
+ if(ept!=NULL && l==0)
+ (*linecount)++;
+ else {
+ (*linecount)+= l/width;
+ if(ept==NULL) {
+ xorriso->result_open_line_len= l%width;
+ break;
+ }
+ (*linecount)+= !!(l%width);
+ }
+ xorriso->result_open_line_len= 0;
+ spt= ept+1;
+ }
+ return(1);
+}
+
+
+int Xorriso_pager(struct XorrisO *xorriso, char *line, int flag)
+/*
+ bit1= mark '@' by return 4
+*/
+/* return: <=0 error , 1=go on , 2=abort , 4=see flag bit1*/
+{
+ int ret,linecount;
+ char info_text[10*SfileadrL];
+
+ if(xorriso->result_page_length<=0 || xorriso->request_not_to_ask)
+ return(1);
+ Xorriso_predict_linecount(xorriso,line,&linecount,0);
+ if(xorriso->result_line_counter+linecount>xorriso->result_page_length) {
+ask_for_page:;
+ strcpy(info_text,xorriso->info_text);
+ sprintf(xorriso->info_text,"\n");
+ Xorriso_info(xorriso,0);
+ sprintf(xorriso->info_text,
+".... [Press Enter to continue. @,Enter avoids further stops. @@@ aborts] ....\n");
+ Xorriso_info(xorriso,0);
+ ret= Xorriso_request_confirmation(xorriso,flag&2);
+ strcpy(xorriso->info_text,info_text);
+ if(ret<=0)
+ return(ret);
+ if(ret==2)
+ return(2);
+ if(ret==3)
+ goto ask_for_page;
+ }
+ xorriso->result_line_counter+= linecount;
+ return(1);
+}
+
+
+int Xorriso_result(struct XorrisO *xorriso, int flag)
+/*
+ bit0= no considerations or computations or dialog. Just put out.
+*/
+{
+ int ret;
+
+ if(flag&1)
+ goto put_it_out;
+ if(xorriso->request_to_abort)
+ return(1);
+ if(xorriso->result_page_length>0) {
+ ret= Xorriso_pager(xorriso,xorriso->result_line,2);
+ if(ret<=0)
+ return(ret);
+ if(ret==2)
+ return(1);
+ if(xorriso->request_to_abort)
+ return(1);
+ }
+put_it_out:;
+ xorriso->bar_is_fresh= 0;
+ ret= Write_to_channel(xorriso->result_line,1,!xorriso->packet_output);
+ return(ret);
+}
+
+
+int Xorriso_info(struct XorrisO *xorriso, int flag)
+/*
+ bit0= use pager (as with result)
+ bit1= permission to suppress output
+ bit2= insist in showing output
+*/
+{
+ int ret;
+ static int note_sev= 0;
+
+ if(flag&2)
+ if(xorriso->request_to_abort)
+ return(1);
+
+ if(note_sev==0)
+ Xorriso__text_to_sev("NOTE", ¬e_sev, 0);
+ if(note_sevreport_about_severity &&
+ note_sevabort_on_severity && !(flag&4))
+ return(1);
+
+ if(flag&1) {
+ ret= Xorriso_pager(xorriso,xorriso->info_text,2);
+ if(ret<=0)
+ return(ret);
+ if(ret==2)
+ return(1);
+ if(flag&2)
+ if(xorriso->request_to_abort)
+ return(1);
+ }
+ xorriso->bar_is_fresh= 0;
+ ret= Write_to_channel(xorriso->info_text,2,!xorriso->packet_output);
+ return(ret);
+}
+
+
+int Xorriso_mark(struct XorrisO *xorriso, int flag)
+{
+ int ret= 1,r_ret,i_ret;
+
+ if(xorriso->mark_text[0]==0)
+ return(1);
+ if(xorriso->packet_output)
+ ret= Write_to_channel(xorriso->mark_text,3,0);
+ else {
+ sprintf(xorriso->result_line,"%s\n",xorriso->mark_text);
+ r_ret= Xorriso_result(xorriso,1);
+ strcpy(xorriso->info_text,xorriso->result_line);
+ i_ret= Xorriso_info(xorriso,0);
+ if(r_ret==0 || i_ret==0)
+ ret= 0;
+ }
+ return(ret);
+}
+
+
+int Xorriso_restxt(struct XorrisO *xorriso, char *text)
+{
+ int ret;
+
+ strncpy(xorriso->result_line,text,sizeof(xorriso->result_line)-1);
+ xorriso->result_line[sizeof(xorriso->result_line)-1]= 0;
+ ret= Xorriso_result(xorriso,0);
+ return(ret);
+}
+
+
+int Xorriso_pacifier_reset(struct XorrisO *xorriso, int flag)
+{
+ xorriso->start_time= Sfile_microtime(0);
+ xorriso->last_update_time= xorriso->start_time;
+ xorriso->pacifier_count= 0;
+ xorriso->pacifier_total= 0;
+ return(1);
+}
+
+
+/* This call is to be issued by long running workers in short intervals.
+ It will check whether enough time has elapsed since the last pacifier
+ message and eventually issue an update message.
+ @param what_done A sparse description of the action, preferrably in past
+ tense. E.g. "done" , "files added".
+ @param count The number of objects processed so far.
+ Is ignored if <=0.
+ @param todo The number of objects to be done in total.
+ Is ignored if <=0.
+ @param current_object A string telling the object currently processed.
+ Ignored if "".
+ @param flag bit0= report unconditionally, no time check
+ bit1= report count <=0 (no thank you for being patient then)
+ bit6= report with carriage return rather than line feed
+*/
+int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done,
+ off_t count, off_t todo, char *current_object,
+ int flag)
+{
+ double current_time, since;
+ char count_text[80];
+
+ current_time= Sfile_microtime(0);
+ if(current_time - xorriso->last_update_time < xorriso->pacifier_interval
+ && !(flag&1))
+ return(1);
+ xorriso->last_update_time= Sfile_microtime(0);
+ since= current_time - xorriso->start_time;
+ if((flag&1)&&since<1.0)
+ since= 1.0;
+ if(count<=0.0 && !(flag&2)) {
+ sprintf(xorriso->info_text,
+ "Thank you for being patient since %.f seconds", since);
+ } else if(todo<=0.0) {
+ if(count<10000000)
+ sprintf(count_text, "%.f", (double) count);
+ else
+ Sfile_scale((double) count, count_text, 7, 1e5, 1);
+ sprintf(xorriso->info_text, "%s %s in %.f %s",
+ count_text, what_done, since, (flag&64) ? "s" : "seconds");
+ } else {
+ sprintf(xorriso->info_text, "%.f of %.f %s in %.f seconds",
+ (double) count, (double) todo, what_done, since);
+ }
+ if(current_object[0]!=0)
+ sprintf(xorriso->info_text+strlen(xorriso->info_text),
+ ", now at %s", current_object);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", (flag&64));
+ return(1);
+}
+
+
+int Xorriso_reset_counters(struct XorrisO *xorriso, int flag)
+{
+ xorriso->error_count= 0;
+ xorriso->insert_count= 0;
+ xorriso->insert_bytes= 0;
+ Xorriso_pacifier_reset(xorriso, 0);
+ return(1);
+}
+
+
+int Xorriso__bourne_to_reg(char bourne_expr[], char reg_expr[], int flag)
+/* reg_expr should be twice as large as bourne_expr ( + 2 to be exact) */
+/* return: 2= bourne_expr is surely a constant */
+{
+ char *wpt,*lpt;
+ int backslash= 0,is_constant= 1,in_square_brackets= 0;
+ int first_in_square_brackets=0;
+
+ wpt= reg_expr;
+ lpt= bourne_expr;
+
+ *(wpt++)= '^';
+
+ while(*lpt!=0){
+ if(first_in_square_brackets>0)
+ first_in_square_brackets--;
+ if(!backslash){
+ switch(*lpt){
+ case '?':
+ *(wpt++)= '.';
+ is_constant= 0;
+ break;case '*':
+ *(wpt++)= '.';
+ *(wpt++)= '*';
+ is_constant= 0;
+ break;case '.':
+ *(wpt++)= '\\';
+ *(wpt++)= '.';
+ break;case '+':
+ *(wpt++)= '\\';
+ *(wpt++)= '+';
+ break;case '[':
+ *(wpt++)= *lpt;
+ first_in_square_brackets= 2;
+ in_square_brackets= 1;
+ is_constant= 0;
+ break;case ']':
+ *(wpt++)= *lpt;
+ in_square_brackets= 0;
+ break;case '!':
+ if(first_in_square_brackets)
+ *(wpt++)= '^';
+ else if(in_square_brackets)
+ *(wpt++)= '!';
+ else {
+ *(wpt++)= '\\';
+ *(wpt++)= '!';
+ }
+ break;case '^':
+ if(in_square_brackets)
+ *(wpt++)= '^';
+ else
+ *(wpt++)= '\\';
+ *(wpt++)= '^';
+ break;case '$':
+ *(wpt++)= '\\';
+ *(wpt++)= '$';
+ break;case '\\':
+ backslash= 1;
+ *(wpt++)= '\\';
+ is_constant= 0;
+ break;default:
+ *(wpt++)= *lpt;
+ }
+ } else {
+ backslash= 0;
+ *(wpt++)= *lpt;
+ }
+ lpt++;
+ }
+ *(wpt++)= '$';
+ *wpt= 0;
+ return(1+(is_constant>0));
+}
+
+
+/* @param flag bit0= do not augment relative structured search by xorriso->wdi
+ bit1= return 2 if bonked at start point by ..
+ (caller then aborts or retries without bit0)
+ bit2= eventually prepend wdx rather than wdi
+ @return <=0 error, 1= ok, 2= with bit1: relative pattern exceeds start point
+*/
+int Xorriso_prepare_regex(struct XorrisO *xorriso, char *adr, int flag)
+{
+ int l,ret,i,count,bonked= 0,is_constant,is_still_relative= 0;
+ char *cpt,*npt,adr_part[2*SfileadrL],absolute_adr[2*SfileadrL],*adr_start,*wd;
+
+ if(flag&4)
+ wd= xorriso->wdx;
+ else
+ wd= xorriso->wdi;
+
+ if(xorriso->search_mode>=2 && xorriso->search_mode<=4) {
+ if(xorriso->search_mode==3 || xorriso->search_mode==4) {
+ l= strlen(adr)+strlen(wd)+1;
+ if(l*2+2>sizeof(xorriso->reg_expr) || l*2+2>sizeof(adr_part)) {
+ sprintf(xorriso->info_text,"Search pattern too long");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ }
+ Xorriso_destroy_re(xorriso,0);
+ if(xorriso->structured_search && xorriso->search_mode==3) {
+ if(adr[0]!='/')
+ is_still_relative= 1;
+ if(is_still_relative && !(flag&1)) {
+ /* relative expression : prepend working directory */
+ sprintf(absolute_adr,"%s/%s",wd,adr);
+ adr_start= absolute_adr;
+ xorriso->prepended_wd= 1;
+ is_still_relative= 0;
+ } else
+ adr_start= adr;
+ /* count slashes */;
+ cpt= adr_start;
+ while(*cpt=='/')
+ cpt++;
+ for(i= 0;1;i++) {
+ cpt= strchr(cpt,'/');
+ if(cpt==NULL)
+ break;
+ while(*cpt=='/')
+ cpt++;
+ }
+ count= i+1;
+ xorriso->re= TSOB_FELD(regex_t,count);
+ if(xorriso->re==NULL)
+ return(-1);
+ xorriso->re_constants= TSOB_FELD(char *,count);
+ if(xorriso->re_constants==NULL)
+ return(-1);
+ for(i= 0;ire_constants[i]= NULL;
+ xorriso->re_count= count;
+ xorriso->re_fill= 0;
+
+ /* loop over slash chunks*/;
+ cpt= adr_start;
+ xorriso->re_fill= 0;
+ while(*cpt=='/')
+ cpt++;
+ for(i= 0;i=sizeof(adr_part))
+ return(-1);
+ strcpy(adr_part,cpt);
+ } else {
+ if(npt-cpt>=sizeof(adr_part))
+ return(-1);
+ strncpy(adr_part,cpt,npt-cpt);
+ adr_part[npt-cpt]= 0;
+ }
+
+ if(adr_part[0]==0)
+ goto next_adr_part;
+ if(adr_part[0]=='.' && adr_part[1]==0 &&
+ (xorriso->re_fill>0 || ire_fill<=1) {
+ bonked= 1;
+ goto next_adr_part;
+ }
+ if(xorriso->re_constants[xorriso->re_fill-1]!=NULL) {
+ free(xorriso->re_constants[xorriso->re_fill-1]);
+ xorriso->re_constants[xorriso->re_fill-1]= NULL;
+ } else
+ regfree(&(xorriso->re[xorriso->re_fill-1]));
+ (xorriso->re_fill)--;
+ goto next_adr_part;
+ }
+ if(strcmp(adr_part,"*")==0) {
+ adr_part[0]= 0;
+ ret= 2;
+ } else
+ ret= Xorriso__bourne_to_reg(adr_part,xorriso->reg_expr,0);
+ if(ret==2) {
+ if(Sregex_string(&(xorriso->re_constants[xorriso->re_fill]),adr_part,0)
+ <=0)
+ return(-1);
+ } else {
+ if(regcomp(&(xorriso->re[xorriso->re_fill]),xorriso->reg_expr,0)!=0)
+ goto cannot_compile;
+ }
+ xorriso->re_fill++;
+next_adr_part:;
+ if(i==count-1)
+ break;
+ cpt= npt+1;
+ while(*cpt=='/')
+ cpt++;
+ }
+ if(bonked) {
+ if(flag&2)
+ return(2);
+ sprintf(xorriso->info_text, "Your '..' bonked at the %s directory.",
+ is_still_relative ? "working" : "root");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0);
+ return(0);
+ }
+
+ Xorriso__bourne_to_reg(adr_start,xorriso->reg_expr,0); /* just for show */
+
+ } else {
+ is_constant= 0;
+ if(strcmp(adr,"*")==0 || adr[0]==0) {
+ is_constant= 1;
+ } else if(xorriso->search_mode==3 || xorriso->search_mode==4) {
+ ret= Xorriso__bourne_to_reg(adr,xorriso->reg_expr,0);
+ is_constant= (ret==2);
+ } else {
+ if(strlen(adr)>=sizeof(xorriso->reg_expr))
+ return(-1);
+ strcpy(xorriso->reg_expr,adr);
+ }
+ xorriso->re_count= 0; /* tells matcher that this is not structured */
+ xorriso->re_constants= TSOB_FELD(char *,1);
+ if(xorriso->re_constants==NULL)
+ return(-1);
+ xorriso->re_constants[0]= NULL;
+ if(is_constant) {
+ if(strcmp(adr,"*")==0) {
+ if(Sregex_string(&(xorriso->re_constants[0]),"",0)<=0)
+ return(-1);
+ } else {
+ if(Sregex_string(&(xorriso->re_constants[0]),adr,0)<=0)
+ return(-1);
+ }
+ xorriso->re_fill= 1;
+ } else {
+ xorriso->re= TSOB_FELD(regex_t,1);
+ if(xorriso->re==NULL)
+ return(-1);
+ if(regcomp(&(xorriso->re[0]),xorriso->reg_expr,0)!=0) {
+cannot_compile:;
+ sprintf(xorriso->info_text, "Cannot compile regular expression : %s",
+ xorriso->reg_expr);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0);
+ return(0);
+ }
+ }
+
+ }
+ }
+ return(1);
+}
+
+
+/* @return 0=match , else no match
+*/
+int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at,
+ int flag)
+/*
+ bit0= do not shortcut last component of to_match
+ bit2= retry beginning at failed last component
+*/
+{
+ int ret,i,re_start= 0,reg_nomatch= -1;
+ char *cpt,*npt,adr_part[SfileadrL],*mpt;
+
+ reg_nomatch= REG_NOMATCH;
+
+ *failed_at= 0;
+ if(!(xorriso->structured_search && xorriso->re_count>0)) {
+ if(xorriso->re_constants!=NULL)
+ if(xorriso->re_constants[0]!=NULL) {
+ if(xorriso->re_constants[0][0]==0)
+ return(0);
+ if(strcmp(xorriso->re_constants[0],to_match)!=0)
+ return(reg_nomatch);
+ return(0);
+ }
+ ret= regexec(&(xorriso->re[0]),to_match,1,xorriso->match,0);
+ return(ret);
+ }
+
+ cpt= to_match;
+ while(*cpt=='/')
+ cpt++;
+ if(flag&4)
+ re_start= xorriso->re_failed_at;
+ if(re_start<0)
+ re_start= 0;
+ for(i= re_start;ire_fill;i++) {
+ *failed_at= i;
+ npt= strchr(cpt,'/');
+ if(npt==NULL) {
+ if(ire_fill-1 && !(flag&1))
+ return(reg_nomatch); /* this must be the last expression part */
+ mpt= cpt;
+ } else {
+ strncpy(adr_part,cpt,npt-cpt);
+ adr_part[npt-cpt]= 0;
+ mpt= adr_part;
+ }
+ if(xorriso->re_constants[i]!=NULL) {
+ if(xorriso->re_constants[i][0]!=0) /* empty constant matches anything */
+ if(strcmp(xorriso->re_constants[i],mpt)!=0)
+ return(reg_nomatch);
+ } else {
+ ret= regexec(&(xorriso->re[i]),mpt,1,xorriso->match,0);
+ if(ret!=0)
+ return(ret);
+ }
+ if(npt==NULL) {
+ if(i>=xorriso->re_fill-1)
+ return(0); /* MATCH */
+ *failed_at= i+1;
+ return(reg_nomatch);
+ }
+ cpt= npt+1;
+ while(*cpt=='/')
+ cpt++;
+ }
+ *failed_at= xorriso->re_fill;
+ return(reg_nomatch);
+}
+
+
+/* @param flag bit0= simple readlink(): no normalization, no multi-hop
+*/
+int Xorriso_resolve_link(struct XorrisO *xorriso,
+ char *link_path, char result_path[SfileadrL], int flag)
+{
+ ssize_t l;
+ struct stat stbuf;
+ int link_count= 0, ret, show_errno= 0;
+ char buf[SfileadrL], dirbuf[SfileadrL], *lpt, *spt, sfe[5*SfileadrL];
+ static int link_limit= 100;
+
+ if(!(flag&1))
+ if(stat(link_path, &stbuf)==-1)
+ if(errno==ELOOP) {
+ show_errno= errno;
+ goto too_many_hops;
+ }
+ lpt= link_path;
+ while(1) {
+ l= readlink(lpt, buf, SfileadrL-1);
+ if(l==-1) {
+handle_error:;
+ Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0);
+ sprintf(xorriso->info_text, "Cannot obtain link target of : %s",
+ Text_shellsafe(link_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
+handle_abort:;
+ if(strcmp(lpt, link_path)!=0) {
+ sprintf(xorriso->info_text,
+ "Problem occured with intermediate path : %s",
+ Text_shellsafe(lpt, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
+ }
+ return(0);
+ }
+ buf[l]= 0;
+ if(l==0) {
+ Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0);
+ sprintf(xorriso->info_text, "Empty link target with : %s",
+ Text_shellsafe(link_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
+ goto handle_abort;
+ }
+
+ if(flag&1) {
+ strcpy(result_path, buf);
+ return(1);
+ }
+
+ /* normalize relative to disk_path */
+ if(Sfile_str(dirbuf, lpt, 0)<=0)
+ return(-1);
+ while(1) {
+ spt= strrchr(dirbuf,'/');
+ if(spt!=NULL) {
+ *spt= 0;
+ if(*(spt+1)!=0)
+ break;
+ } else
+ break;
+ }
+ ret= Xorriso_normalize_img_path(xorriso, dirbuf, buf, result_path, 2|4);
+ if(ret<=0)
+ return(ret);
+
+ if(lstat(result_path, &stbuf)==-1) {
+ lpt= result_path;
+ goto handle_error;
+ }
+ if(!S_ISLNK(stbuf.st_mode))
+ break;
+
+ lpt= result_path;
+ link_count++;
+ if(link_count>link_limit) {
+too_many_hops:;
+ Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0);
+ sprintf(xorriso->info_text, "Too many link hops with : %s",
+ Text_shellsafe(link_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, show_errno,
+ "FAILURE",0);
+ return(0);
+ }
+ }
+ return(1);
+}
+
+
+int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp,
+ int flag)
+/*
+bit1= do only report to fp
+*/
+{
+ int ret,l;
+
+ if(filter!=NULL)
+ if(filter[0]=='-') {
+ l= strlen(filter);
+ if(strncmp(filter,xorriso->result_line,l)!=0)
+ return(2);
+ }
+ if(!(flag&2))
+ Xorriso_result(xorriso,0);
+ if(fp!=NULL) {
+ ret= fwrite(xorriso->result_line,strlen(xorriso->result_line),1,fp);
+ if(ret<=0)
+ return(ret);
+ }
+ return(1);
+}
+
+
+int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
+/*
+ bit0= do only report non-default settings
+ bit1= do only report to fp
+ bit2= report current -resume status even if bit0 is set, but only if valid
+ bit3= report readline history
+ bit4= report -resume options indirectly as
+ -options_from_file:${resume_state_file}_pos
+*/
+{
+ int is_default, no_defaults, i, ret, adr_mode;
+ char *line, sfe[5*SfileadrL], mode[80], *form, *treatment;
+ static char channel_prefixes[4][4]= {".","R","I","M"};
+ static char load_names[][20]= {"auto", "session", "track", "lba", "volid"};
+ static int max_load_mode= 4;
+ struct LstrinG *paths, *leafs;
+
+ no_defaults= flag&1;
+ line= xorriso->result_line;
+
+ if(xorriso->no_rc) {
+ sprintf(line,"-no_rc\n");
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+ is_default= 0;
+ if(xorriso->dialog)
+ sprintf(line,"-dialog on\n");
+ else {
+ sprintf(line,"-dialog off\n");
+ is_default= 1;
+ }
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->result_page_length==0 && xorriso->result_page_width==80);
+ sprintf(line,"-page %d %d\n",
+ (xorriso->result_page_length>=0?xorriso->result_page_length
+ :-xorriso->result_page_length),
+ xorriso->result_page_width);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->use_stdin==0);
+ sprintf(line,"-use_readline %s\n", (xorriso->use_stdin?"off":"on"));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= !xorriso->packet_output;
+ sprintf(line,"-pkt_output %s\n",(xorriso->packet_output?"on":"off"));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ for(i=0;i<4;i++) {
+ is_default= (xorriso->logfile[i]!=0);
+ sprintf(line,"-logfile %s %s\n",
+ channel_prefixes[i],Text_shellsafe(xorriso->logfile[i],sfe,0));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+
+ is_default= (xorriso->errfile_log[0]==0);
+ sprintf(line,"-errfile_log %s\n",Text_shellsafe(xorriso->errfile_log,sfe,0));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->img_read_error_mode==2);
+ treatment= "best_effort";
+ if(xorriso->img_read_error_mode==1)
+ treatment= "failure";
+ else if(xorriso->img_read_error_mode==2)
+ treatment= "fatal";
+ sprintf(line,"-error_behavior image_loading %s\n", treatment);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->mark_text[0]==0);
+ sprintf(line,"-mark %s\n",Text_shellsafe(xorriso->mark_text,sfe,0));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->temp_mem_limit==16*1024*1024);
+ if((xorriso->temp_mem_limit/1024/1024)*1024*1024==xorriso->temp_mem_limit)
+ sprintf(line,"-temp_mem_limit %dm\n", xorriso->temp_mem_limit/1024/1024);
+ else
+ sprintf(line,"-temp_mem_limit %dk\n", xorriso->temp_mem_limit/1024);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+
+ sprintf(line,"-prog %s\n",Text_shellsafe(xorriso->progname,sfe,0));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ if(xorriso->ban_stdio_write) {
+ sprintf(line,"-ban_stdio_write\n");
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+
+ is_default= (xorriso->keep_boot_image==0 && xorriso->patch_isolinux_image==0);
+ form= "any";
+ treatment= "discard";
+ if(xorriso->patch_isolinux_image) {
+ form= "isolinux";
+ treatment= "patch";
+ } else if(xorriso->keep_boot_image) {
+ treatment= "keep";
+ }
+ sprintf(line,"-boot_image %s %s\n", form, treatment);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ sprintf(line,"-cd %s\n",
+ (xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'"));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ sprintf(line,"-cdx %s\n",
+ (xorriso->wdx[0] ? Text_shellsafe(xorriso->wdx,sfe,0) : "'/'"));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->split_size==0);
+ strcpy(line,"-split_size ");
+ if(xorriso->split_size % (1024*1024) || xorriso->split_size==0) {
+ Sfile_off_t_text(line+strlen(line), xorriso->split_size, 0);
+ } else {
+ Sfile_off_t_text(line+strlen(line), xorriso->split_size / (1024*1024), 0);
+ strcat(line, "m");
+ }
+ strcat(line, "\n");
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->add_plainly==0);
+ sprintf(line,"-add_plainly %s\n",
+ (xorriso->add_plainly == 1 ? "unknown" :
+ xorriso->add_plainly == 2 ? "dashed" :
+ xorriso->add_plainly == 3 ? "any" : "none"));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ ret= Exclusions_get_descrs(xorriso->disk_exclusions, &paths, &leafs, 0);
+ if(ret>0) {
+ for(; paths!=NULL; paths= paths->next) {
+ sprintf(line,"-not_paths %s --\n", Text_shellsafe(paths->text, sfe, 0));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+ for(; leafs!=NULL; leafs= leafs->next) {
+ sprintf(line,"-not_leaf %s\n", Text_shellsafe(leafs->text, sfe, 0));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+ }
+
+ is_default= (xorriso->disk_excl_mode==1);
+ sprintf(line, "-not_mgt %s:%s:%s:%s\n",
+ (xorriso->disk_excl_mode&1 ? "on" : "off"),
+ (xorriso->disk_excl_mode&2 ? "param_on" : "param_off"),
+ (xorriso->disk_excl_mode&4 ? "subtree_on" : "subtree_off"),
+ (xorriso->disk_excl_mode&8 ? "ignore_on" : "ignore_off"));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->do_iso_rr_pattern==1);
+ sprintf(line,"-iso_rr_pattern %s\n",
+ (xorriso->do_iso_rr_pattern == 1 ? "on" :
+ (xorriso->do_iso_rr_pattern == 2 ? "ls" : "off")));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->do_disk_pattern==2);
+ sprintf(line,"-disk_pattern %s\n",
+ (xorriso->do_disk_pattern == 1 ? "on" :
+ (xorriso->do_disk_pattern == 2 ? "ls" : "off")));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= xorriso->volid_default;
+ sprintf(line,"-volid %s\n",Text_shellsafe(xorriso->volid,sfe,0));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ if(is_default && xorriso->loaded_volid[0] &&
+ strcmp(xorriso->loaded_volid, xorriso->volid)!=0 && !no_defaults) {
+ sprintf(line,"# loaded image effective -volid %s\n",
+ Text_shellsafe(xorriso->loaded_volid,sfe,0));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+
+ is_default= (xorriso->publisher[0]==0);
+ sprintf(line,"-publisher %s\n",Text_shellsafe(xorriso->publisher,sfe,0));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->do_joliet==0);
+ sprintf(line,"-joliet %s\n", (xorriso->do_joliet == 1 ? "on" : "off"));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ if(xorriso->do_global_uid) {
+ sprintf(line,"-uid %lu\n", (unsigned long) xorriso->global_uid);
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+
+ if(xorriso->do_global_gid) {
+ sprintf(line,"-gid %lu\n", (unsigned long) xorriso->global_gid);
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+
+ is_default= !xorriso->allow_graft_points;
+ sprintf(line,"-pathspecs %s\n", xorriso->allow_graft_points ? "on" : "off");
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->do_follow_pattern && (!xorriso->do_follow_param)
+ && xorriso->do_follow_mount && (!xorriso->do_follow_links)
+ && xorriso->follow_link_limit==100);
+ mode[0]= 0;
+ if(xorriso->do_follow_pattern &&
+ !(xorriso->do_follow_links && xorriso->do_follow_mount))
+ strcat(mode,":pattern");
+ if(xorriso->do_follow_param && !(xorriso->do_follow_links))
+ strcat(mode,":param");
+ if(xorriso->do_follow_links)
+ strcat(mode,":link");
+ if(xorriso->do_follow_mount)
+ strcat(mode,":mount");
+ if(mode[0]==0)
+ strcpy(mode, ":off");
+ sprintf(mode+strlen(mode), ":limit=%d", xorriso->follow_link_limit);
+ sprintf(line,"-follow %s\n", mode+1);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->do_overwrite==2);
+ sprintf(line,"-overwrite %s\n",(xorriso->do_overwrite == 1 ? "on" :
+ (xorriso->do_overwrite == 2 ? "nondir" : "off")));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= !xorriso->do_reassure;
+ sprintf(line,"-reassure %s\n",(xorriso->do_reassure == 1 ? "on" :
+ (xorriso->do_reassure == 2 ? "tree" : "off")));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= !xorriso->do_close;
+ sprintf(line,"-close %s\n",(xorriso->do_close ? "on" : "off"));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= !xorriso->do_dummy;
+ sprintf(line,"-dummy %s\n",(xorriso->do_dummy ? "on" : "off"));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->speed==0);
+ sprintf(line,"-speed %dkB/s\n", xorriso->speed);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->fs==4*512);
+ if((xorriso->fs/512)*512==xorriso->fs)
+ sprintf(line,"-fs %dm\n", xorriso->fs/512);
+ else
+ sprintf(line,"-fs %dk\n", xorriso->fs*2);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->padding==300*1024);
+ sprintf(line,"-padding %dk\n", xorriso->padding/1024);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (strcmp(xorriso->report_about_text,"UPDATE")==0);
+ sprintf(line,"-report_about %s\n",xorriso->report_about_text);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (xorriso->session_logfile[0]==0);
+ sprintf(line,"-session_log %s\n",
+ Text_shellsafe(xorriso->session_logfile,sfe,0));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (strcmp(xorriso->return_with_text,"SORRY")==0 &&
+ xorriso->return_with_value==32);
+ sprintf(line,"-return_with %s %d\n",
+ xorriso->return_with_text, xorriso->return_with_value);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ is_default= (strcmp(xorriso->abort_on_text,"FATAL")==0);
+ sprintf(line,"-abort_on %s\n",xorriso->abort_on_text);
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ if(xorriso->status_history_max!=Xorriso_status_history_maX || !no_defaults) {
+ sprintf(line,"-status_history_max %d\n",xorriso->status_history_max);
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+
+#ifdef Xorriso_with_readlinE
+
+ if((flag&8) && xorriso->status_history_max>0) {
+ HIST_ENTRY **hl;
+ int hc,i;
+
+ hl= history_list();
+ if(hl!=NULL) {
+ for(hc= 0;hl[hc]!=NULL;hc++);
+ if(hc>0)
+ if(strcmp(hl[hc-1]->line,"-end")==0)
+ hc--;
+ if(hc>=xorriso->status_history_max)
+ i= hc-xorriso->status_history_max;
+ else
+ i= 0;
+ for(;iline,sfe,0));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+ }
+ }
+
+#endif /* Xorriso_with_readlinE */
+
+ is_default= !(xorriso->toc_emulation_flag&1);
+ sprintf(line,"-rom_toc_scan %s\n",
+ xorriso->toc_emulation_flag&1 ? "on" : "off");
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+
+ adr_mode= xorriso->image_start_mode & 0xffff;
+ if(adr_mode>=0 && adr_mode<=max_load_mode) {
+ is_default= (adr_mode==0);
+ sprintf(line,"-load %s ", load_names[adr_mode]);
+ if(adr_mode==0)
+ sprintf(line+strlen(line),"''\n");
+ else if(adr_mode>=1 && adr_mode<=3)
+ sprintf(line+strlen(line),"%s\n", xorriso->image_start_value);
+ else
+ sprintf(line+strlen(line),"%s\n",
+ Text_shellsafe(xorriso->image_start_value, sfe, 0));
+ if(!(is_default && no_defaults))
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+
+ if(strcmp(xorriso->indev,xorriso->outdev)==0) {
+ sprintf(line,"-dev %s\n", Text_shellsafe(xorriso->indev,sfe,0));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ } else {
+ sprintf(line,"-indev %s\n", Text_shellsafe(xorriso->indev,sfe,0));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ sprintf(line,"-outdev %s\n", Text_shellsafe(xorriso->outdev,sfe,0));
+ Xorriso_status_result(xorriso,filter,fp,flag&2);
+ }
+
+ return(1);
+}
+
+
+/* @param flag bit2= this is a disk_pattern
+ @return <=0 failure , 1 pattern ok , 2 pattern needed prepended wd */
+int Xorriso_prepare_expansion_pattern(struct XorrisO *xorriso, char *pattern,
+ int flag)
+{
+ int ret, prepwd= 0;
+
+ ret= Xorriso_prepare_regex(xorriso, pattern, 1|2|(flag&4));
+ if(ret==2) {
+ ret= Xorriso_prepare_regex(xorriso, pattern, flag&4);
+ prepwd= 1;
+ }
+ if(ret<=0) {
+ sprintf(xorriso->info_text,
+ "Cannot compile pattern to regular expression: %s", pattern);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1+prepwd);
+}
+
+
+/* @param flag bit0= count results rather than storing them
+ bit1= unexpected change of number is a FATAL event
+ @return <=0 error , 1 is root (end processing) ,
+ 2 is not root (go on processing)
+*/
+int Xorriso_check_for_root_pattern(struct XorrisO *xorriso,
+ int *filec, char **filev, int count_limit, off_t *mem, int flag)
+{
+ if(xorriso->re_fill!=0)
+ return(2);
+ /* This is the empty pattern representing root */
+ if(flag&1) {
+ (*filec)++;
+ (*mem)+= 8;
+ } else {
+ if(*filec >= count_limit) {
+ sprintf(xorriso->info_text,
+ "Number of matching files changed unexpectedly (> %d)",
+ count_limit);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
+ (flag&2 ? "FATAL" : "WARNING"), 0);
+ return(flag&2 ? -1 : 0);
+ }
+ filev[*filec]= strdup("/");
+ if(filev[*filec]==NULL) {
+ Xorriso_no_pattern_memory(xorriso, (off_t) 2, 0);
+ return(-1);
+ }
+ (*filec)++;
+ }
+ return(1);
+}
+
+
+/* @param flag bit0= prepend wd only if name does not begin by '/'
+ bit1= normalize image path
+ bit2= prepend wd (automatically done if wd[0]!=0)
+ bit3= (with bit1) this is an address in the disk world
+*/
+int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name,
+ char adr[], int flag)
+{
+ char norm_adr[SfileadrL];
+ int ret;
+
+ if((wd[0]!=0 || (flag&4)) && !((flag&1) && name[0]=='/')) {
+ if(strlen(wd)+1>=SfileadrL)
+ goto much_too_long;
+ strcpy(adr, wd);
+ if(name[0])
+ if(Sfile_add_to_path(adr, name, 0)<=0) {
+much_too_long:;
+ Xorriso_much_too_long(xorriso, (int) (strlen(adr)+strlen(name)+1), 2);
+ return(0);
+ }
+ } else {
+ if(strlen(name)+1>=SfileadrL)
+ goto much_too_long;
+ strcpy(adr, name);
+ }
+ if(flag&2) {
+ ret= Xorriso_normalize_img_path(xorriso, "", adr, norm_adr,
+ 1|2|((flag&8)>>1));
+ if(ret<=0)
+ return(ret);
+ if(norm_adr[0]==0)
+ strcpy(norm_adr, "/");
+ strcpy(adr, norm_adr);
+ }
+ return(1);
+}
+
+
+/*
+ @param result Bitfield indicationg type of mismatch
+ bit11= cannot open regular disk file
+ bit12= cannot open iso file
+ bit13= early eof of disk file
+ bit14= early eof of iso file
+ bit15= content bytes differ
+ @param flag bit0= mtimes of both file objects are equal
+ bit29= do not issue pacifier messages
+ bit31= do not issue result messages
+ @return >0 ok , <=0 error
+*/
+int Xorriso_compare_2_contents(struct XorrisO *xorriso, char *common_adr,
+ char *disk_adr, off_t disk_size,
+ off_t offset, off_t bytes,
+ char *iso_adr, off_t iso_size,
+ int *result, int flag)
+{
+ int fd1= -1, ret, r1, r2, done, wanted, i, was_error= 0;
+ void *stream2= NULL;
+ off_t r1count= 0, r2count= 0, diffcount= 0, first_diff= -1;
+ char *respt, buf1[32*1024], buf2[32*1024], offset_text[80];
+
+ respt= xorriso->result_line;
+
+ fd1= open(disk_adr, O_RDONLY);
+ if(fd1==-1) {
+ sprintf(respt, "- %s (DISK) : cannot open() : %s\n",
+ disk_adr, strerror(errno));
+cannot_address:;
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 2048;
+ return(0);
+ }
+ if(offset>0)
+ if(lseek(fd1, offset, SEEK_SET)==-1) {
+ sprintf(respt, "- %s (DISK) : cannot lseek(%.f) : %s\n",
+ disk_adr, (double) offset, strerror(errno));
+ close(fd1);
+ goto cannot_address;
+ }
+
+ ret= Xorriso_iso_file_open(xorriso, iso_adr, &stream2, 0);
+ if(ret<=0) {
+ sprintf(respt, "- %s (ISO) : cannot open() file in ISO image\n", iso_adr);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ close(fd1);
+ (*result)|= 4096;
+ return(0);
+ }
+
+ done= 0;
+ while(!done) {
+
+ wanted= sizeof(buf1);
+ if(r1count+offset+wanted>disk_size)
+ wanted= disk_size-r1count-offset;
+ if(r1count+wanted>bytes)
+ wanted= bytes-r1count;
+ r1= 0;
+ while(wanted>0) {
+ ret= read(fd1, buf1, wanted);
+ if(ret<=0)
+ break;
+ wanted-= ret;
+ r1+= ret;
+ }
+
+ wanted= sizeof(buf2);
+ if(r2count+wanted>iso_size)
+ wanted= iso_size-r2count;
+/*
+ if(r2count+wanted>bytes)
+ wanted= bytes-r2count;
+*/
+ if(wanted>0)
+ r2= Xorriso_iso_file_read(xorriso, stream2, buf2, wanted, 0);
+ else
+ r2= 0;
+
+ if(r1<0 || r2<0)
+ was_error= 1;
+
+ if(r1<=0 && r2<=0)
+ break;
+ if(r1<=0) {
+ if(r1<0)
+ r1= 0;
+ if(disk_size > r1count + r1 + offset) {
+ sprintf(respt, "- %s (DISK) : early EOF after %.f bytes\n",
+ disk_adr, (double) r1count);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 8196;
+ }
+ (*result)|= (1<<15);
+ }
+ r1count+= r1;
+ if(r2<=0 || r2 r2count + r2) {
+ sprintf(respt, "- %s (ISO) : early EOF after %.f bytes\n",
+ iso_adr, (double) r2count);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= (1<<14);
+ }
+ (*result)|= (1<<15);
+ done= 1;
+ }
+ if(r2>r1) {
+ if(disk_size > r1count + r1 + offset) {
+ sprintf(respt, "- %s (DISK) : early EOF after %.f bytes\n",
+ disk_adr, (double) r1count);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 8196;
+ }
+ (*result)|= (1<<15);
+ done= 1;
+ }
+ r2count+= r2;
+ if(r1>r2)
+ r1= r2;
+ for(i= 0; ipacifier_count+= r1;
+ if(flag&(1<<31))
+ Xorriso_pacifier_callback(xorriso, "content bytes read",
+ xorriso->pacifier_count, 0, "", 0);
+ else
+ Xorriso_pacifier_callback(xorriso, "bytes", xorriso->pacifier_count, 0,
+ "", 1<<6);
+ }
+ }
+ if(diffcount>0 || r1count!=r2count) {
+ if(first_diff<0)
+ first_diff= (r1count>r2count ? r2count : r1count);
+ offset_text[0]= 0;
+ if(offset>0)
+ sprintf(offset_text, "%.f+", (double) offset);
+ sprintf(respt, "%s %s : differs by at least %.f bytes. First at %s%.f\n",
+ common_adr, (flag&1 ? "CONTENT": "content"),
+ (double) (diffcount + abs(r1count-r2count)),
+ offset_text, (double) first_diff);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= (1<<15);
+ }
+ if(fd1!=-1)
+ close(fd1);
+ Xorriso_iso_file_close(xorriso, &stream2, 0);
+ if(was_error)
+ return(-1);
+ return(1);
+}
+
+
+/*
+ @param result Bitfield indicationg type of mismatch
+ bit0= disk_adr not existing
+ bit1= iso_adr not existing
+ bit2= access permissions
+ bit3= file type
+ bit4= user id
+ bit5= group id
+ bit6= minor, major with device file
+ bit7= size
+ bit8= mtime
+ bit9= atime
+ bit10= ctime
+ bit11= cannot open regular disk file
+ bit12= cannot open iso file
+ bit13= early eof of disk file
+ bit14= early eof of iso file
+ bit15= content bytes differ
+ bit16= symbolic link on disk pointing to dir, dir in iso
+ bit17= file chunks detected and compared
+ bit18= incomplete chunk collection encountered
+ @param flag bit0= compare atime
+ bit1= compare ctime
+ bit2= check only existence of both file objects
+ count one or both missing as "difference"
+ bit27= for Xorriso_path_is_excluded(): bit0
+ bit28= examine eventual disk_path link target rather than link
+ bit29= do not issue pacifier messages
+ bit30= omit adr_common_tail in report messages
+ bit31= do not issue result messages
+ @return 1=files match properly , 0=difference detected , -1=error
+*/
+int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
+ char *iso_adr, char *adr_common_tail,
+ int *result, int flag)
+{
+ struct stat s1, s2, stbuf;
+ int ret, missing= 0, is_split= 0, i, was_error= 0;
+ char *respt;
+ char a[5*SfileadrL], sfe[5*SfileadrL];
+ char ttx1[40], ttx2[40];
+ struct SplitparT *split_parts= NULL;
+ int split_count= 0;
+
+ char part_path[SfileadrL], *part_name;
+ int partno, total_parts= 0;
+ off_t offset, bytes, total_bytes;
+
+ *result= 0;
+ respt= xorriso->result_line;
+
+ if(!(xorriso->disk_excl_mode&8)) {
+ ret= Xorriso_path_is_excluded(xorriso, disk_adr, 2 | !!(flag&(1<<27)));
+ if(ret>0) {
+ sprintf(respt , "? %s (DISK) : exluded by %s\n",
+ Text_shellsafe(disk_adr, sfe, 0),
+ (ret==1 ? "-not_paths" : "-not_leaf"));
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ missing= 1;
+ (*result)|= 1;
+ }
+ }
+ if(!missing) {
+ if(flag&(1<<28))
+ ret= stat(disk_adr, &s1);
+ else
+ ret= lstat(disk_adr, &s1);
+ if(ret==-1) {
+ sprintf(respt , "? %s (DISK) : cannot lstat() : %s\n",
+ Text_shellsafe(disk_adr, sfe, 0), strerror(errno));
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ missing= 1;
+ (*result)|= 1;
+ }
+ }
+ if(missing)
+ strcpy(a, "?");
+ else
+ strcpy(a, Ftypetxt(s1.st_mode, 1));
+ strcat(a, " ");
+ if(adr_common_tail[0])
+ strcat(a, Text_shellsafe(adr_common_tail, sfe, 0));
+ else
+ strcat(a, "'.'");
+ strcat(a, " :");
+ if(flag&(1<<30))
+ a[0]= 0;
+
+ ret= Xorriso_iso_lstat(xorriso, iso_adr, &s2, 0);
+ if(ret<0) {
+ sprintf(respt, "? %s (ISO) : cannot find this file in ISO image\n",
+ Text_shellsafe(iso_adr, sfe, 0));
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ missing= 1;
+ (*result)|= 2;
+ }
+
+ if((flag&4)||missing)
+ {ret= !missing; goto ex;}
+
+
+ /* Splitfile parts */
+ if((S_ISREG(s1.st_mode) || S_ISBLK(s1.st_mode)) && S_ISDIR(s2.st_mode)) {
+ is_split= Xorriso_identify_split(xorriso, iso_adr, NULL, &split_parts,
+ &split_count, &s2, 0);
+ if(is_split>0)
+ (*result)|= (1<<17);
+ else
+ is_split= 0;
+ }
+
+ /* Attributes */
+ if(s1.st_mode != s2.st_mode) {
+ if((s1.st_mode&~S_IFMT)!=(s2.st_mode&~S_IFMT)) {
+ sprintf(respt, "%s st_mode : %7.7o <> %7.7o\n",
+ a, s1.st_mode, s2.st_mode);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 4;
+ }
+ if((s1.st_mode&S_IFMT)!=(s2.st_mode&S_IFMT)) {
+ sprintf(respt, "%s type : %s <> %s\n",
+ a, Ftypetxt(s1.st_mode, 0), Ftypetxt(s2.st_mode, 0));
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 8;
+ if((s1.st_mode&S_IFMT) == S_IFLNK) {
+ /* check whether link target type matches */
+ ret= stat(disk_adr, &stbuf);
+ if(ret!=-1)
+ if(S_ISDIR(stbuf.st_mode) && S_ISDIR(s2.st_mode))
+ (*result)|= (1<<16);
+ }
+ }
+ }
+ if(s1.st_uid != s2.st_uid) {
+ sprintf(respt, "%s st_uid : %d <> %d\n", a, s1.st_uid, s2.st_uid);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 16;
+ }
+ if(s1.st_gid != s2.st_gid) {
+ sprintf(respt, "%s st_gid : %d <> %d\n", a, s1.st_gid, s2.st_gid);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 32;
+ }
+ if((S_ISCHR(s1.st_mode) && S_ISCHR(s2.st_mode)) ||
+ (S_ISBLK(s1.st_mode) && S_ISBLK(s2.st_mode))) {
+ if(s1.st_rdev != s2.st_rdev) {
+ sprintf(respt, "%s %s st_rdev : %lu <> %lu\n", a,
+ (S_ISCHR(s1.st_mode) ? "S_IFCHR" : "S_IFBLK"),
+ (unsigned long) s1.st_rdev, (unsigned long) s1.st_rdev);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 64;
+ }
+ }
+ if(S_ISREG(s2.st_mode) && s1.st_size != s2.st_size) {
+ sprintf(respt, "%s st_size : %.f <> %.f diff= %.f\n",
+ a, (double) s1.st_size, (double) s2.st_size,
+ ((double) s1.st_size) - (double) s2.st_size);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 128;
+ }
+ if(s1.st_mtime != s2.st_mtime) {
+ sprintf(respt, "%s st_mtime : %s <> %s diff= %.f s\n",
+ a, Ftimetxt(s1.st_mtime, ttx1, 0),
+ Ftimetxt(s2.st_mtime, ttx2, 0),
+ ((double) s1.st_mtime) - (double) s2.st_mtime);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 256;
+ }
+ if(flag&1) {
+ if(s1.st_atime != s2.st_atime) {
+ sprintf(respt, "%s st_atime : %s <> %s diff= %.f s\n",
+ a, Ftimetxt(s1.st_atime, ttx1, 0),
+ Ftimetxt(s2.st_atime, ttx2, 0),
+ ((double) s1.st_atime) - (double) s2.st_atime);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 512;
+ }
+ }
+ if(flag&2) {
+ if(s1.st_ctime != s2.st_ctime) {
+ sprintf(respt, "%s st_ctime : %s <> %s diff= %.f s\n",
+ a, Ftimetxt(s1.st_ctime, ttx1, 0),
+ Ftimetxt(s2.st_ctime, ttx2, 0),
+ ((double) s1.st_ctime) - (double) s2.st_ctime);
+ if(!(flag&(1<<31)))
+ Xorriso_result(xorriso,0);
+ (*result)|= 1024;
+ }
+ }
+ if(S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)) {
+ /* Content */
+ if(is_split) {
+ for(i= 0; i0 && split_count!=total_parts) {
+ sprintf(xorriso->info_text,
+ "- %s/* (ISO) : Not all split parts present (%d of %d)\n",
+ iso_adr, split_count, total_parts);
+ if(!(flag&(1<<31)))
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 1);
+ (*result)|= 1<<18;
+ }
+ } else {
+ ret= Xorriso_compare_2_contents(xorriso, a, disk_adr, s1.st_size,
+ (off_t) 0, s1.st_size,
+ iso_adr, s2.st_size, result,
+ (s1.st_mtime==s2.st_mtime) | (flag&((1<<29)|(1<<31))));
+ if(ret<0)
+ was_error= 1;
+ }
+
+ }
+ if(was_error)
+ ret= -1;
+ else
+ ret= (((*result)&~((1<<17)|(1<<18)))==0);
+ex:;
+ if(split_parts!=NULL)
+ Splitparts_destroy(&split_parts, split_count, 0);
+ return(ret);
+}
+
+
+/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
+ Set to NULL if calling this function from outside ISO world
+ @param flag bit0= update rather than compare
+ bit1= find[ix] is in recursion
+ @return <=0 error, 1= ok , 2= iso_path was deleted
+ 3=ok, do not dive into directory (e.g. because it is a split file)
+*/
+int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter,
+ char *iso_path, char *iso_prefix, char *disk_prefix,
+ int flag)
+{
+ int ret, result, uret, follow_links, deleted= 0;
+ char disk_path[SfileadrL], adrc[SfileadrL];
+
+ if(strncmp(iso_path, iso_prefix, strlen(iso_prefix))!=0)
+ return(-1);
+ if(strlen(disk_prefix)+strlen(iso_path)-strlen(iso_prefix)>=SfileadrL)
+ return(-1);
+ if(iso_path[strlen(iso_prefix)]=='/')
+ strcpy(adrc, iso_path+strlen(iso_prefix)+1);
+ else
+ strcpy(adrc, iso_path+strlen(iso_prefix));
+
+ ret= Xorriso_make_abs_adr(xorriso, disk_prefix, adrc, disk_path, 4|8);
+ if(ret<=0)
+ return(ret);
+
+ /* compare exclusions against disk_path resp. leaf name */
+ if(xorriso->disk_excl_mode&8)
+ ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&2));
+ else
+ ret= 0;
+ if(ret<0)
+ return(ret);
+ if(ret>0)
+ return(3);
+
+ follow_links= (xorriso->do_follow_links ||
+ (xorriso->do_follow_param && !(flag&2))) <<28;
+ ret= Xorriso_compare_2_files(xorriso, disk_path, iso_path, adrc, &result,
+ 2 | follow_links | ((!(flag&2))<<27) | ((flag&1)<<31));
+ /* was once: | ((!(flag&1))<<29) */
+ if(retfind_compare_result)
+ xorriso->find_compare_result= ret;
+ if(flag&1) {
+ if(ret<=0) {
+ if(ret<0)
+ if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
+ return(ret);
+ uret= Xorriso_update_interpreter(xorriso, boss_iter, result,
+ disk_path, iso_path, (flag&2)<<1);
+ if(uret<=0)
+ ret= 0;
+ if(uret==2)
+ deleted= 1;
+ }
+ }
+ if(ret<0)
+ return(ret);
+ if(deleted)
+ return(2);
+ if(result&(1<<17))
+ return(3);
+ return(ret);
+}
+
+
+/* @param flag bit0= count result rather than storing it
+ bit1= unexpected change of number is a FATAL event
+*/
+int Xorriso_register_matched_adr(struct XorrisO *xorriso,
+ char *adr, int count_limit,
+ int *filec, char **filev, off_t *mem, int flag)
+{
+ int l;
+
+ if(flag&1) {
+ (*filec)++;
+ l= strlen(adr)+1;
+ (*mem)+= sizeof(char *)+l;
+ if(l % sizeof(char *))
+ (*mem)+= sizeof(char *)-(l % sizeof(char *));
+ } else {
+ if(*filec >= count_limit) {
+ sprintf(xorriso->info_text,
+ "Number of matching files changed unexpectedly (> %d)",
+ count_limit);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
+ (flag&2 ? "FATAL" : "WARNING"), 0);
+ return(flag&2 ? -1 : 0);
+ }
+ filev[*filec]= strdup(adr);
+ if(filev[*filec]==NULL) {
+ Xorriso_no_pattern_memory(xorriso, (off_t) (strlen(adr)+1), 0);
+ return(-1);
+ }
+ (*filec)++;
+ }
+ return(1);
+}
+
+
+/* @param flag bit0= count results rather than storing them
+ bit1= this is a recursion
+ bit2= prepend wd (automatically done if wd[0]!=0)
+ @return <=0 error , 1 ok , 2 could not open directory
+*/
+int Xorriso_obtain_pattern_files_x(
+ struct XorrisO *xorriso, char *wd, char *dir_adr,
+ int *filec, char **filev, int count_limit, off_t *mem,
+ int *dive_count, int flag)
+{
+ int ret, failed_at, follow_mount, follow_links;
+ struct DirseQ *dirseq= NULL;
+ struct stat stbuf;
+ dev_t dir_dev;
+ char *path;
+
+#ifdef Xorriso_fat_local_meM
+ char adr[SfileadrL], name[SfileadrL], path_data[SfileadrL];
+#else /* Xorriso_fat_local_meM */
+ char *adr= NULL, *name= NULL, *path_data= NULL;
+
+ adr= malloc(SfileadrL);
+ name= malloc(SfileadrL);
+ path_data= malloc(SfileadrL);
+ if(adr==NULL || name==NULL || path_data==NULL) {
+ Xorriso_no_malloc_memory(xorriso, &adr, 0);
+ {ret= -1; goto ex;}
+ }
+#endif /* ! Xorriso_fat_local_meM */
+
+ follow_mount= (xorriso->do_follow_mount || xorriso->do_follow_pattern);
+ follow_links= (xorriso->do_follow_links || xorriso->do_follow_pattern);
+ if(!(flag&2))
+ *dive_count= 0;
+ else
+ (*dive_count)++;
+
+ ret= Xorriso_check_for_root_pattern(xorriso, filec, filev, count_limit,
+ mem, flag&1);
+ if(ret!=2)
+ goto ex;
+
+ if(lstat(dir_adr, &stbuf)==-1)
+ {ret= 2; goto ex;}
+ dir_dev= stbuf.st_dev;
+ if(S_ISLNK(stbuf.st_mode)) {
+ if(stat(dir_adr, &stbuf)==-1)
+ {ret= 2; goto ex;}
+ if(dir_dev != stbuf.st_dev && !follow_mount)
+ {ret= 2; goto ex;}
+ }
+ ret= Dirseq_new(&dirseq, dir_adr, 1);
+ if(ret<0) {
+ sprintf(xorriso->info_text, "Cannot obtain disk directory iterator");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ {ret= -1; goto ex;}
+ }
+ if(ret==0)
+ {ret= 2; goto ex;}
+
+ while(1) {
+ ret= Dirseq_next_adr(dirseq,name,0);
+ if(ret==0)
+ break;
+ if(ret<0) {
+ sprintf(xorriso->info_text,"Failed to obtain next directory entry");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ {ret= -1; goto ex;}
+ }
+
+ ret= Xorriso_make_abs_adr(xorriso, wd, name, adr, flag&4);
+ if(ret<=0)
+ goto ex;
+
+ ret= Xorriso_regexec(xorriso, adr, &failed_at, 1);
+ if(ret>0) { /* no match */
+ if(failed_at <= *dive_count) /* no hope for a match */
+ continue;
+ path= adr;
+ if(adr[0]!='/') {
+ path= path_data;
+ ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, adr, path, 1|4);
+ if(ret<=0)
+ goto ex;
+ }
+
+ if(follow_links)
+ ret= stat(path,&stbuf);
+ else
+ ret= lstat(path,&stbuf);
+ if(ret==-1)
+ continue;
+ if(!S_ISDIR(stbuf.st_mode))
+ continue;
+ if(dir_dev != stbuf.st_dev && !follow_mount)
+ continue;
+
+ /* dive deeper */
+ ret= Xorriso_obtain_pattern_files_x(xorriso, adr, path,
+ filec, filev, count_limit, mem, dive_count, flag|2);
+ if(ret<=0)
+ goto ex;
+ } else {
+ ret= Xorriso_register_matched_adr(xorriso, adr, count_limit,
+ filec, filev, mem, flag&1);
+ if(ret<0)
+ goto ex;
+ if(ret==0)
+ break;
+ }
+ }
+ ret= 1;
+ex:;
+
+#ifndef Xorriso_fat_local_meM
+ if(adr!=NULL)
+ free(adr);
+ if(name!=NULL)
+ free(name);
+ if(path_data!=NULL)
+ free(path_data);
+#endif /* ! Xorriso_fat_local_meM */
+
+ Dirseq_destroy(&dirseq,0);
+ if(flag&2)
+ (*dive_count)--;
+ return(ret);
+}
+
+
+int Xorriso_eval_nonmatch(struct XorrisO *xorriso, char *pattern,
+ int *nonconst_mismatches, off_t *mem, int flag)
+{
+ int k,l;
+
+ /* Is this a constant pattern ? */
+ for(k= 0; kre_fill; k++) {
+ if(xorriso->re_constants[k]==NULL)
+ break;
+ if(xorriso->re_constants[k][0]==0)
+ break;
+ }
+ if(kre_fill)
+ (*nonconst_mismatches)++; /* it is not */
+
+ l= strlen(pattern)+1;
+ (*mem)+= sizeof(char *)+l;
+ if(l % sizeof(char *))
+ (*mem)+= sizeof(char *)-(l % sizeof(char *));
+ return(1);
+}
+
+
+/* @param flag bit0= a match count !=1 is a SORRY event
+ bit1= a match count !=1 is a FAILURE event
+*/
+int Xorriso_check_matchcount(struct XorrisO *xorriso,
+ int count, int nonconst_mismatches, int num_patterns,
+ char **patterns, int flag)
+{
+ char sfe[5*SfileadrL];
+
+ if((flag&1) && (count!=1 || nonconst_mismatches)){
+ if(count-nonconst_mismatches>0)
+ sprintf(xorriso->info_text,
+ "Pattern match with more than one file object");
+ else
+ sprintf(xorriso->info_text, "No pattern match with any file object");
+ if(num_patterns==1)
+ sprintf(xorriso->info_text+strlen(xorriso->info_text), ": %s",
+ Text_shellsafe(patterns[0], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
+ (flag&2 ? "FAILURE" : "SORRY"), 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+int Xorriso_no_pattern_memory(struct XorrisO *xorriso, off_t mem, int flag)
+{
+ char mem_text[80];
+
+ Sfile_scale((double) mem, mem_text,5,1e4,1);
+ sprintf(xorriso->info_text,
+ "Cannot allocate enough memory (%s) for pattern expansion",
+ mem_text);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ return(1);
+}
+
+
+int Xorriso_no_malloc_memory(struct XorrisO *xorriso, char **to_free, int flag)
+{
+ if(to_free!=NULL)
+ if(*to_free!=NULL) {
+ /* Eventual memory sacrifice to get on going */
+ free(*to_free);
+ *to_free= NULL;
+ }
+ sprintf(xorriso->info_text, "Out of virtual memory");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "ABORT", 0);
+ return(1);
+}
+
+
+int Xorriso_alloc_pattern_mem(struct XorrisO *xorriso, off_t mem,
+ int count, char ***filev, int flag)
+{
+ char mem_text[80], limit_text[80];
+
+ Sfile_scale((double) mem, mem_text,5,1e4,0);
+ sprintf(xorriso->info_text,
+ "Temporary memory needed for pattern expansion : %s", mem_text);
+ if(!(flag&1))
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+ if(mem > xorriso->temp_mem_limit) {
+ Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1);
+ sprintf(xorriso->info_text,
+ "List of matching file addresses exceeds -temp_mem_limit (%s > %s)",
+ mem_text, limit_text);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+
+ (*filev)= (char **) calloc(count, sizeof(char *));
+ if(*filev==NULL) {
+ Xorriso_no_pattern_memory(xorriso, mem, 0);
+ return(-1);
+ }
+ return(1);
+}
+
+
+/* @param flag bit0= a match count !=1 is a FAILURE event
+ bit1= with bit0 tolerate 0 matches if pattern is a constant
+*/
+int Xorriso_expand_disk_pattern(struct XorrisO *xorriso,
+ int num_patterns, char **patterns, int extra_filec,
+ int *filec, char ***filev, off_t *mem, int flag)
+{
+ int ret, count= 0, abs_adr= 0, i, was_count, was_filec;
+ int nonconst_mismatches= 0, dive_count= 0;
+ char sfe[5*SfileadrL], dir_adr[SfileadrL];
+
+ *filec= 0;
+ *filev= NULL;
+
+ xorriso->search_mode= 3;
+ xorriso->structured_search= 1;
+
+ for(i= 0; iwdx);
+ if(dir_adr[0]==0)
+ strcpy(dir_adr, "/");
+ ret= Sfile_type(dir_adr, 1|4);
+ if(ret!=2) {
+ Xorriso_msgs_submit(xorriso, 0, dir_adr, 0, "ERRFILE", 0);
+ sprintf(xorriso->info_text,
+ "Address set by -cdx is not a directory: %s",
+ Text_shellsafe(dir_adr, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ }
+ }
+
+ /* count the matches */
+ was_count= count;
+ ret= Xorriso_obtain_pattern_files_x(xorriso, "", dir_adr, &count, NULL, 0,
+ mem, &dive_count, 1 | abs_adr);
+ if(ret<=0)
+ goto ex;
+ if(was_count==count && strcmp(patterns[i],"*")!=0 && (flag&3)!=1) {
+ count++;
+ ret= Xorriso_eval_nonmatch(xorriso, patterns[i],
+ &nonconst_mismatches, mem, 0);
+ if(ret<=0)
+ goto ex;
+ }
+ }
+
+ ret= Xorriso_check_matchcount(xorriso, count, nonconst_mismatches,
+ num_patterns, patterns, (flag&1)|2);
+ if(ret<=0)
+ goto ex;
+
+ count+= extra_filec;
+ mem+= extra_filec*sizeof(char *);
+
+ if(count<=0)
+ {ret= 0; goto ex;}
+
+ ret= Xorriso_alloc_pattern_mem(xorriso, *mem, count, filev, 0);
+ if(ret<=0)
+ goto ex;
+
+ /* now store addresses */
+ for(i= 0; iwdx);
+
+ was_filec= *filec;
+ ret= Xorriso_obtain_pattern_files_x(xorriso, "", dir_adr, filec, *filev,
+ count, mem, &dive_count, abs_adr);
+ if(ret<=0)
+ goto ex;
+
+ if(was_filec == *filec && strcmp(patterns[i],"*")!=0) {
+ (*filev)[*filec]= strdup(patterns[i]);
+ if((*filev)[*filec]==NULL) {
+ (*mem)= strlen(patterns[i])+1;
+ Xorriso_no_pattern_memory(xorriso, *mem, 0);
+ ret= -1; goto ex;
+ }
+ (*filec)++;
+ }
+ }
+
+ ret= 1;
+ex:;
+ if(ret<=0) {
+ if(filev!=NULL)
+ Sfile_destroy_argv(&count, filev, 0);
+ *filec= 0;
+ }
+ return(ret);
+}
+
+
+/* @param flag bit0= command without pattern capability
+ bit1= disk_pattern rather than iso_rr_pattern
+*/
+int Xorriso_warn_of_wildcards(struct XorrisO *xorriso, char *path, int flag)
+{
+ if(strchr(path,'*')!=NULL || strchr(path,'?')!=NULL ||
+ strchr(path,'[')!=NULL) {
+ if(flag&1) {
+ sprintf(xorriso->info_text,
+ "Pattern expansion of wildcards \"*?[\" does not apply to this command");
+ } else {
+ sprintf(xorriso->info_text,
+ "Pattern expansion of wildcards \"*?[\" is disabled by command %s",
+ (flag&2) ? "-disk_pattern" : "-iso_rr_pattern");
+ }
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ sprintf(xorriso->info_text,"Pattern seen: %s\n", path);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ return(1);
+ }
+ return(0);
+}
+
+
+/* @param flag bit0= do not warn of wildcards
+ bit1= these are disk_paths
+*/
+int Xorriso_end_idx(struct XorrisO *xorriso,
+ int argc, char **argv, int idx, int flag)
+{
+ int i, warned= 0;
+
+ for(i= idx; ido_disk_pattern==1 && !(flag&4);
+ else
+ do_expand= xorriso->do_iso_rr_pattern==1 && !(flag&4);
+ if(flag&256) {
+ if(*optv=argv+argc)
+ Sfile_destroy_argv(optc, optv, 0);
+ return(1);
+ }
+ if(idx>=argc) {
+ *end_idx= argc;
+ *optc= 0;
+ *optv= NULL;
+ sprintf(xorriso->info_text, "%s : Not enough arguments given", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ *end_idx= Xorriso_end_idx(xorriso, argc, argv, idx,
+ ((flag&1) || do_expand) | (flag&2));
+ if(*end_idx<0)
+ return(*end_idx);
+ if((flag&16) && (*end_idx)>idx)
+ (*end_idx)--;
+ *optc= *end_idx - idx;
+ *optv= argv+idx;
+ if(*optc<=0 || !do_expand)
+ return(1);
+ patterns= calloc(*optc, sizeof(char *));
+ if(patterns==NULL) {
+no_memory:;
+ sprintf(xorriso->info_text,
+ "%s : Cannot allocate enough memory for pattern expansion", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ {ret= -1; goto ex;}
+ }
+ nump= 0;
+ if(flag&8) {
+ was_empty= 1;
+ mem+= strlen(argv[idx + *optc - 1])+1+sizeof(char *);
+ }
+ for(i= 0; i<*optc-!!(flag&8); i++) {
+ if(argv[i + idx][0]==0) {
+ was_empty++;
+ mem+= sizeof(char *); /* as upper limit for size of an empty string */
+ continue;
+ }
+ patterns[nump++]= argv[i + idx];
+ }
+ if(nump<=0) { /* Only empty texts. May the caller get happy with them. */
+ free(patterns);
+ return(1);
+ }
+ if(flag&2)
+ ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, was_empty,
+ &filec, &filev, &mem, (flag>>5)&3);
+ else
+ ret= Xorriso_expand_pattern(xorriso, nump, patterns, was_empty,
+ &filec, &filev, &mem, (flag>>5)&3);
+ if(ret<=0)
+ {ret= 0; goto ex;}
+ for(i= 0; iinfo_text, "Pattern expansion yields %d items:", filec);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+ l= 0;
+ xorriso->info_text[0]= 0;
+ for(i= 0; iinfo_text);
+ if(l>0 && l+1+strlen(filev[i])>60) {
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+ xorriso->info_text[0]= 0;
+ l= 0;
+ }
+ sprintf(xorriso->info_text+l, " %s", filev[i]);
+ }
+ l= strlen(xorriso->info_text);
+ if(l>0)
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+}
+#endif /* Xorriso_verbous_pattern_expansioN */
+
+ ret= 1;
+ex:;
+ if(ret<=0) {
+ if(patterns!=NULL)
+ free((char *) patterns);
+ Sfile_destroy_argv(&filec, &filev, 0);
+ } else {
+ *optc= filec;
+ *optv= filev;
+ }
+ return(ret);
+}
+
+
+int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80],
+ int flag)
+{
+ strcpy(severity, xorriso->problem_status_text);
+ return(xorriso->problem_status);
+}
+
+
+int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity,
+ int flag)
+{
+ char *sev_text= "ALL";
+ int sev, ret;
+
+ if(severity[0])
+ sev_text= severity;
+ ret= Xorriso__text_to_sev(sev_text, &sev, 0);
+ if(ret<=0)
+ return(0);
+ xorriso->problem_status= sev;
+ strcpy(xorriso->problem_status_text, sev_text);
+ if(sev > xorriso->eternal_problem_status) {
+ xorriso->eternal_problem_status= sev;
+ strcpy(xorriso->eternal_problem_status_text, sev_text);
+ }
+ return(1);
+}
+
+
+/* @param flag bit0-7= purpose
+ 0= ERRFILE
+ 1= mark line (only to be put out if enabled)
+*/
+int Xorriso_process_errfile(struct XorrisO *xorriso,
+ int error_code, char msg_text[], int os_errno,
+ int flag)
+{
+ char ttx[41];
+ int purpose;
+
+ if(strlen(msg_text)>SfileadrL)
+ return(-1);
+
+ purpose= flag&255;
+ if(purpose==1 && !(xorriso->errfile_mode&1))
+ return(2);
+ if(xorriso->errfile_fp!=NULL) {
+ if(purpose==1)
+ fprintf(xorriso->errfile_fp, "----------------- %s %s\n",
+ msg_text, Ftimetxt(time(0), ttx, 1));
+ else
+ fprintf(xorriso->errfile_fp, "%s\n", msg_text);
+ fflush(xorriso->errfile_fp);
+ return(1);
+ }
+ if(xorriso->errfile_log[0]==0)
+ return(1);
+ if(strcmp(xorriso->errfile_log, "-")==0 ||
+ strcmp(xorriso->errfile_log, "-R")==0) {
+ if(purpose==1)
+ sprintf(xorriso->result_line, "----------------- %s %s\n",
+ msg_text, Ftimetxt(time(0), ttx, 1));
+ else
+ sprintf(xorriso->result_line, "%s\n", msg_text);
+ Xorriso_result(xorriso, 1);
+ return(1);
+ }
+ if(strcmp(xorriso->errfile_log, "-I")==0) {
+ if(purpose==1)
+ sprintf(xorriso->info_text, "ERRFILE_MARK=%s %s\n",
+ msg_text, Ftimetxt(time(0), ttx, 1));
+ else
+ sprintf(xorriso->info_text, "ERRFILE=%s", msg_text);
+ Xorriso_info(xorriso, 0);
+ return(1);
+ }
+ return(2);
+}
+
+
+/* Note: It is ok to submit xorriso->info_text as msg_text here. */
+/* flag:
+ bit0= for Xorriso_info() : use pager (as with result)
+ bit1= for Xorriso_info() : permission to suppress output
+ bit2..5= name prefix
+ 0="xorriso"
+ 1="libisofs"
+ 2="libburn"
+ 3="libisoburn"
+ else: ""
+ bit6= append carriage return rather than line feed (if not os_errno)
+*/
+int Xorriso_msgs_submit(struct XorrisO *xorriso,
+ int error_code, char msg_text[], int os_errno,
+ char severity[], int flag)
+{
+ int ret, lt, li, sev, i;
+ char *sev_text= "FATAL", prefix[80];
+ static char pfx_list[20][16]= {
+ "xorriso : ", "libisofs: ", "libburn : ", "libisoburn: ",
+ "", "", "", "", "", "", "", "", "", "", "", "" };
+
+ if(strcmp(severity, "ERRFILE")==0)
+ Xorriso_process_errfile(xorriso, error_code, msg_text, os_errno, 0);
+
+ /* Set problem status */
+ ret= Xorriso__text_to_sev(severity, &sev, 0);
+ if(ret<=0)
+ Xorriso__text_to_sev(sev_text, &sev, 0);
+ else
+ sev_text= severity;
+ if(xorriso->problem_statusproblem_status= sev;
+ strcpy(xorriso->problem_status_text, sev_text);
+ }
+ if(xorriso->eternal_problem_statuseternal_problem_status= sev;
+ strcpy(xorriso->eternal_problem_status_text, sev_text);
+ }
+
+ /* Report problem event */
+ if(sevreport_about_severity && sevabort_on_severity)
+ return(2);
+ sprintf(prefix,"%s%s : ", pfx_list[(flag>>2)&15], sev_text);
+ li= strlen(prefix);
+ lt= strlen(msg_text);
+ if(lt>sizeof(xorriso->info_text)-li-2)
+ lt= sizeof(xorriso->info_text)-li-2;
+ if(msg_text==xorriso->info_text) {
+ for(i= lt; i>=0; i--)
+ msg_text[i+li]= msg_text[i];
+ for(i=0; iinfo_text, prefix);
+ strncpy(xorriso->info_text+li, msg_text, lt);
+ }
+ if((flag&64) && os_errno<=0)
+ xorriso->info_text[li+lt]= '\r';
+ else
+ xorriso->info_text[li+lt]= '\n';
+ xorriso->info_text[li+lt+1]= 0;
+ Xorriso_info(xorriso,4|(flag&3));
+ if(os_errno>0) {
+ sprintf(xorriso->info_text, "%ssys : %s\n",
+ pfx_list[(flag>>2)&15], strerror(os_errno));
+ Xorriso_info(xorriso,4|(flag&3));
+ }
+ return(1);
+}
+
+
+/**
+ @param flag bit0= do not issue own event messages
+ bit1= take xorriso->request_to_abort as reason for abort
+ @return Gives the advice:
+ 2= pardon was given, go on
+ 1= no problem, go on
+ 0= function failed but xorriso would not abort, go on
+ <0= do abort
+ -1 = due to problem_status
+ -2 = due to xorriso->request_to_abort
+*/
+int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag)
+{
+ static int sev= 0;
+ if(sev==0)
+ Xorriso__text_to_sev("SORRY", &sev, 0);
+
+ if((flag&2) && xorriso->request_to_abort)
+ return(-2);
+
+ Xorriso_process_msg_queues(xorriso, 0);
+ if(ret>0 && xorriso->problem_status <= 0)
+ return(1);
+
+ if(xorriso->problem_status < xorriso->abort_on_severity &&
+ xorriso->problem_status > 0) {
+ if(xorriso->problem_status >= sev && !(flag&1)) {
+ sprintf(xorriso->info_text,
+ "xorriso : NOTE : Tolerated problem event of severity '%s'\n",
+ xorriso->problem_status_text);
+ Xorriso_info(xorriso, 0);/* submit not as problem event */
+ }
+ ret= 2;
+ } else if(xorriso->problem_status > 0) {
+ sprintf(xorriso->info_text,
+ "xorriso : aborting : -abort_on '%s' encountered '%s'\n",
+ xorriso->abort_on_text, xorriso->problem_status_text);
+ if(!(flag&1))
+ Xorriso_info(xorriso, 0);/* submit not as problem event */
+ ret= -1;
+ } else if(ret>0)
+ ret= 1;
+ else
+ ret= 2;
+ return(ret);
+}
+
+
+int Xorriso_convert_uidstring(struct XorrisO *xorriso, char *uid_string,
+ uid_t *uid, int flag)
+{
+ double num;
+ char text[80];
+ struct passwd *pwd;
+
+ sscanf(uid_string, "%lf", &num);
+ sprintf(text,"%.f",num);
+ if(strcmp(text,uid_string)==0) {
+ *uid= num;
+ return(1);
+ }
+ pwd= getpwnam(uid_string);
+ if(pwd==NULL) {
+ sprintf(xorriso->info_text, "-uid: Not a known user: '%s'", uid_string);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ *uid= pwd->pw_uid;
+ return(1);
+}
+
+
+int Xorriso_convert_gidstring(struct XorrisO *xorriso, char *gid_string,
+ gid_t *gid, int flag)
+{
+ double num;
+ char text[80];
+ struct group *grp;
+
+ sscanf(gid_string, "%lf", &num);
+ sprintf(text,"%.f",num);
+ if(strcmp(text,gid_string)==0) {
+ *gid= num;
+ return(1);
+ }
+ grp= getgrnam(gid_string);
+ if(grp==NULL) {
+ sprintf(xorriso->info_text, "-gid: Not a known group: '%s'", gid_string);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ *gid= grp->gr_gid;
+ return(1);
+}
+
+
+int Xorriso_convert_modstring(struct XorrisO *xorriso, char *cmd, char *mode,
+ mode_t *mode_and, mode_t *mode_or, int flag)
+{
+ int who_val= 0;
+ char sfe[5*SfileadrL], *mpt, *vpt, *opt;
+ unsigned int num= 0;
+ mode_t mode_val,mask;
+
+ *mode_and= ~1;
+ *mode_or= 0;
+ if(mode[0]=='0') {
+ *mode_and= 0;
+ sscanf(mode,"%o",&num);
+ *mode_or= num;
+ } else if(strchr(mode,'+')!=NULL || strchr(mode,'-')!=NULL
+ || strchr(mode,'=')!=NULL) {
+ /* [ugoa][+-][rwxst] */;
+ for(mpt= mode; mpt!=NULL; mpt= strchr(mpt, ',')) {
+ if(*mpt==',')
+ mpt++;
+ if(strlen(mpt)<2)
+ goto unrecognizable;
+ who_val= 0;
+ for(vpt= mpt; *vpt!='+' && *vpt!='-' && *vpt!='='; vpt++) {
+ if(*vpt=='u')
+ who_val|= 4;
+ else if(*vpt=='g')
+ who_val|= 2;
+ else if(*vpt=='o')
+ who_val|= 1;
+ else if(*vpt=='a')
+ who_val|= 7;
+ else
+ goto unrecognizable;
+ }
+ opt= vpt;
+ mode_val= 0;
+ for(vpt= opt+1; *vpt!=0 && *vpt!=','; vpt++) {
+ if(*vpt=='r') {
+ if(who_val&4)
+ mode_val|= S_IRUSR;
+ if(who_val&2)
+ mode_val|= S_IRGRP;
+ if(who_val&1)
+ mode_val|= S_IROTH;
+ } else if(*vpt=='w') {
+ if(who_val&4)
+ mode_val|= S_IWUSR;
+ if(who_val&2)
+ mode_val|= S_IWGRP;
+ if(who_val&1)
+ mode_val|= S_IWOTH;
+ } else if(*vpt=='x') {
+ if(who_val&4)
+ mode_val|= S_IXUSR;
+ if(who_val&2)
+ mode_val|= S_IXGRP;
+ if(who_val&1)
+ mode_val|= S_IXOTH;
+ } else if(*vpt=='s') {
+ if(who_val&4)
+ mode_val|= S_ISUID;
+ if(who_val&2)
+ mode_val|= S_ISGID;
+ } else if(*vpt=='t') {
+ if(who_val&1)
+ mode_val|= S_ISVTX;
+ } else
+ goto unrecognizable;
+ }
+ if(*opt=='+') {
+ (*mode_or)|= mode_val;
+ } else if(*opt=='=') {
+ mask= 0;
+ if(who_val&1)
+ mask|= S_IRWXO|S_ISVTX;
+ if(who_val&2)
+ mask|= S_IRWXG|S_ISGID;
+ if(who_val&4)
+ mask|= S_IRWXU|S_ISUID;
+ (*mode_and)&= ~(mask);
+ (*mode_or)= ((*mode_or) & ~mask) | mode_val;
+ } else if(*opt=='-') {
+ (*mode_or)&= ~mode_val;
+ (*mode_and)&= ~mode_val;
+ }
+ }
+ } else {
+unrecognizable:;
+ sprintf(xorriso->info_text,
+ "%s: Unrecognizable or faulty permission mode %s\n", cmd,
+ Text_shellsafe(mode, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+int Xorriso_convert_datestring(struct XorrisO *xorriso, char *cmd,
+ char *time_type, char *timestring,
+ int *t_type, time_t *t, int flag)
+{
+ int ret;
+
+ if(strcmp(time_type, "a")==0)
+ (*t_type)|= 1;
+ else if(strcmp(time_type, "m")==0)
+ (*t_type)|= 4;
+ else if(strcmp(time_type, "b")==0)
+ (*t_type)|= 5;
+ else {
+ sprintf(xorriso->info_text, "%s: Unrecognized type '%s'", cmd, time_type);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ ret= Decode_timestring(timestring, t, 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text, "%s: Cannot decode timestring '%s'", cmd,
+ timestring);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ sprintf(xorriso->info_text, "Understanding timestring '%s' as: %s",
+ timestring, ctime(t));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+ return(1);
+}
+
+
+/* @param flag bit0=path is in source filesystem , bit1= unconditionally */
+int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag)
+{
+ if(len>=SfileadrL || (flag&2)) {
+ sprintf(xorriso->info_text,
+ "Path given for %s is much too long (%d)",
+ ((flag&1) ? "local filesystem" : "ISO image"), len);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag)
+{
+ sprintf(xorriso->info_text, "%s: cannot set create find job object", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ return(1);
+}
+
+
+/* @param flag bit1= do not report memory usage as DEBUG
+*/
+int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag)
+{
+ char mem_text[80], limit_text[80];
+
+ Sfile_scale((double) mem, mem_text,5,1e4,0);
+ if(!(flag&2)) {
+ sprintf(xorriso->info_text,
+ "Temporary memory needed for result sorting : %s", mem_text);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+ }
+ if(mem > xorriso->temp_mem_limit) {
+ Sfile_scale((double) xorriso->temp_mem_limit,limit_text,5,1e4,1);
+ sprintf(xorriso->info_text,
+ "Cannot sort. List of matching files exceeds -temp_mem_limit (%s > %s)",
+ mem_text, limit_text);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* @param flag bit0= for Xorriso_msgs_submit: use pager
+ bit1= do not issue warnings
+*/
+int Xorriso_hop_link(struct XorrisO *xorriso, char *link_path,
+ struct LinkiteM **link_stack, struct stat *stbuf, int flag)
+{
+ int ret;
+ struct LinkiteM *litm;
+ char sfe[5*SfileadrL];
+
+ if(*link_stack != NULL) {
+ if((*link_stack)->link_count>=xorriso->follow_link_limit) {
+ sprintf(xorriso->info_text,
+ "Too many symbolic links in single tree branch at : %s",
+ Text_shellsafe(link_path, sfe, 0));
+ if(!(flag&2))
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,"WARNING",flag&1);
+ return(0);
+ }
+ }
+ ret= stat(link_path, stbuf);
+ if(ret==-1)
+ return(0);
+ ret= Linkitem_find(*link_stack, stbuf->st_dev, stbuf->st_ino, &litm, 0);
+ if(ret>0) {
+ sprintf(xorriso->info_text,
+ "Detected symbolic link loop around : %s",
+ Text_shellsafe(link_path, sfe, 0));
+ if(!(flag&2))
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", flag&1);
+ return(0);
+ }
+ ret= Linkitem_new(&litm, link_path, stbuf->st_dev, stbuf->st_ino,
+ *link_stack, 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text,
+ "Cannot add new item to link loop prevention stack");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", flag&1);
+ return(-1);
+ }
+ *link_stack= litm;
+ return(1);
+}
+
+
+/* @param flag bit0= do not only sum up sizes but also print subdirs
+ bit1= this is a recursion
+ @return <=0 error , 1 ok , 2 could not open directory
+*/
+int Xorriso_show_dux_subs(struct XorrisO *xorriso,
+ char *abs_path, char *rel_path, off_t *size,
+ off_t boss_mem,
+ struct LinkiteM *link_stack,
+ int flag)
+{
+ int i, ret, no_sort= 0, filec= 0, l, j, fc, no_dive, is_link;
+ char **filev= NULL, *namept;
+ off_t sub_size, report_size, mem= 0;
+ struct DirseQ *dirseq= NULL;
+ struct stat stbuf;
+ dev_t dir_dev;
+ struct LinkiteM *own_link_stack;
+
+#ifdef Xorriso_fat_local_meM
+ char path[SfileadrL], show_path[SfileadrL], name[SfileadrL], sfe[5*SfileadrL];
+#else /* Xorriso_fat_local_meM */
+ char *path= NULL, *show_path= NULL, *name= NULL, *sfe= NULL;
+
+ sfe= malloc(5*SfileadrL);
+ path= malloc(SfileadrL);
+ show_path= malloc(SfileadrL);
+ name= malloc(SfileadrL);
+ if(path==NULL || show_path==NULL || name==NULL || sfe==NULL) {
+ Xorriso_no_malloc_memory(xorriso, &sfe, 0);
+ {ret= -1; goto ex;}
+ }
+
+#endif /* ! Xorriso_fat_local_meM */
+
+ own_link_stack= link_stack;
+ namept= name;
+ *size= 0;
+
+ if(lstat(abs_path, &stbuf)==-1)
+ {ret= 2; goto ex;}
+ dir_dev= stbuf.st_dev;
+ if(S_ISLNK(stbuf.st_mode)) {
+ if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&2))))
+ {ret= 2; goto ex;}
+ if(stat(abs_path, &stbuf)==-1)
+ {ret= 2; goto ex;}
+ if(dir_dev != stbuf.st_dev &&
+ !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&2))))
+ {ret= 2; goto ex;}
+ }
+ ret= Dirseq_new(&dirseq, abs_path, 1);
+ if(ret<0) {
+ sprintf(xorriso->info_text, "Cannot obtain disk directory iterator");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ {ret= -1; goto ex;}
+ }
+ if(ret==0)
+ {ret= 2; goto ex;}
+
+ while(1) {
+ Linkitem_reset_stack(&own_link_stack, link_stack, 0);
+ ret= Dirseq_next_adr(dirseq,name,0);
+ if(ret<0)
+ goto ex;
+ if(ret==0)
+ break;
+
+ sub_size= 0;
+ strcpy(show_path, rel_path);
+ if(Sfile_add_to_path(show_path, name, 0)<=0)
+ goto much_too_long;
+
+ strcpy(path, abs_path);
+ if(Sfile_add_to_path(path, name, 0)<=0) {
+much_too_long:;
+ Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2);
+ {ret= -1; goto ex;}
+ }
+ no_dive= 0;
+
+ ret= lstat(path, &stbuf);
+ if(ret==-1)
+ continue;
+ is_link= S_ISLNK(stbuf.st_mode);
+ if(is_link && xorriso->do_follow_links) {
+ ret= Xorriso_hop_link(xorriso, path, &own_link_stack, &stbuf, 1);
+ if(ret<0)
+ {ret= -1; goto ex;}
+ if(ret!=1)
+ no_dive= 1;
+ }
+ if(!S_ISDIR(stbuf.st_mode))
+ no_dive= 1;
+ if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount)
+ no_dive= 1;
+ if(!no_dive) {
+ filec++;
+ l= strlen(rel_path)+1;
+ mem+= l;
+ if(l % sizeof(char *))
+ mem+= sizeof(char *)-(l % sizeof(char *));
+ if(flag&1) /* diving and counting is done further below */
+ continue;
+ ret= Xorriso_show_dux_subs(xorriso, path, show_path, &sub_size, boss_mem,
+ own_link_stack,2);
+ if(ret<0)
+ goto ex;
+ if(ret==0)
+ continue;
+ }
+
+/*
+ sub_size+= stbuf.st_size+strlen(name)+1;
+*/
+ sub_size+= stbuf.st_size+2048;
+ if(sub_size>0)
+ (*size)+= sub_size;
+ }
+
+ if(filec<=0 || !(flag&1))
+ {ret= 1; goto ex;}
+
+ /* Try to get a sorted list of directory names */
+ mem+= (filec+1)*sizeof(char *);
+ ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2);
+ if(ret<0)
+ goto ex;
+ Dirseq_rewind(dirseq, 0);
+ if(ret==0) {
+no_sort_possible:;
+ no_sort= 1;
+ } else {
+ filev= (char **) calloc(filec+1, sizeof(char *));
+ if(filev==NULL)
+ goto no_sort_possible;
+ else {
+ for(i= 0; ido_follow_links) {
+ ret= stat(path,&stbuf);
+ if(ret==-1)
+ continue;
+ }
+ if(!S_ISDIR(stbuf.st_mode))
+ continue;
+ if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount)
+ continue;
+
+ if(fc>=filec) { /* Number of files changed (or programming error) */
+revoke_sorting:;
+ for(j=0; j1)
+ Sort_argv(filec, filev, 0);
+ }
+ }
+
+ for(i= 0; (no_sort || irequest_to_abort); i++) {
+ Linkitem_reset_stack(&own_link_stack, link_stack, 0);
+ if(no_sort) {
+ ret= Dirseq_next_adr(dirseq,name,0);
+ if(ret<0)
+ goto ex;
+ if(ret==0)
+ break;
+ } else
+ namept= filev[i];
+
+ sub_size= 0;
+ strcpy(show_path, rel_path);
+ if(Sfile_add_to_path(show_path, namept, 0)<=0)
+ goto much_too_long;
+ strcpy(path, abs_path);
+ if(Sfile_add_to_path(path, namept, 0)<=0)
+ goto much_too_long;
+ no_dive= 0;
+
+ ret= lstat(path,&stbuf);
+ if(ret==-1)
+ continue;
+ is_link= S_ISLNK(stbuf.st_mode);
+ if(is_link && xorriso->do_follow_links) {
+ ret= Xorriso_hop_link(xorriso, path, &own_link_stack, &stbuf, 1);
+ if(ret<0)
+ {ret= -1; goto ex;}
+ if(ret!=1)
+ continue;
+ }
+ if(!S_ISDIR(stbuf.st_mode))
+ continue;
+ if(dir_dev == stbuf.st_dev || xorriso->do_follow_mount) {
+ ret= Xorriso_show_dux_subs(xorriso, path, show_path, &sub_size,
+ boss_mem+mem, own_link_stack, 2|(flag&1));
+ if(ret<0)
+ goto ex;
+ }
+
+/*
+ sub_size+= stbuf.st_size+strlen(namept)+1;
+*/
+ sub_size+= stbuf.st_size+2048;
+ if(sub_size>0)
+ (*size)+= sub_size;
+ report_size= sub_size/1024;
+ if(report_size*1024result_line, "%7.f ",(double) (report_size));
+ sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
+ Text_shellsafe(show_path, sfe, 0));
+ Xorriso_result(xorriso, 0);
+ }
+
+ ret= 1;
+ex:;
+
+#ifndef Xorriso_fat_local_meM
+ if(sfe!=NULL)
+ free(sfe);
+ if(path!=NULL)
+ free(path);
+ if(show_path!=NULL)
+ free(show_path);
+ if(name!=NULL)
+ free(name);
+#endif /* ! Xorriso_fat_local_meM */
+
+ Linkitem_reset_stack(&own_link_stack, link_stack, 0);
+ Dirseq_destroy(&dirseq, 0);
+ if(filev!=NULL) {
+ for(i=0; iresult_line;
+ rpt[0]= 0;
+ st_mode= stbuf->st_mode;
+
+ if(S_ISDIR(st_mode))
+ strcat(rpt, "d");
+ else if(S_ISREG(st_mode))
+ strcat(rpt, "-");
+ else if(S_ISLNK(st_mode))
+ strcat(rpt, "l");
+ else if(S_ISBLK(st_mode))
+ strcat(rpt, "b");
+ else if(S_ISCHR(st_mode))
+ strcat(rpt, "c");
+ else if(S_ISFIFO(st_mode))
+ strcat(rpt, "p");
+ else if(S_ISSOCK(st_mode))
+ strcat(rpt, "s");
+ else
+ strcat(rpt, "?");
+
+ Xorriso__mode_to_perms(st_mode, perms, 0);
+ strcat(rpt, perms);
+
+ sprintf(rpt+strlen(rpt),"%4u ",(unsigned int) stbuf->st_nlink);
+
+ sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_uid);
+ sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_gid);
+ sprintf(rpt+strlen(rpt), "%8.f ", (double) stbuf->st_size);
+
+ Ftimetxt(stbuf->st_mtime, rpt+strlen(rpt), 0);
+ strcat(rpt, " ");
+
+ return(1);
+}
+
+
+struct DirentrY {
+ char *adr;
+ struct DirentrY *next;
+};
+
+
+int Xorriso_sorted_dir_x(struct XorrisO *xorriso, char *dir_path,
+ int *filec, char ***filev, off_t boss_mem, int flag)
+{
+ int count= 0, ret;
+ char name[SfileadrL];
+ struct DirseQ *dirseq= NULL;
+ off_t mem;
+ struct DirentrY *last= NULL, *current= NULL;
+
+ *filec= 0;
+ *filev= NULL;
+ mem= boss_mem;
+ ret= Dirseq_new(&dirseq, dir_path, 1);
+ if(ret<=0)
+ goto ex;
+ while(1) { /* loop over directory content */
+ ret= Dirseq_next_adr(dirseq,name,0);
+ if(ret==0)
+ break;
+ if(ret<0)
+ goto ex;
+ mem+= strlen(name)+8+sizeof(struct DirentrY)+sizeof(char *);
+ if(mem>xorriso->temp_mem_limit)
+ {ret= 0; goto ex;}
+
+ current= (struct DirentrY *) calloc(1, sizeof(struct DirentrY));
+ if(current==NULL)
+ {ret= -1; goto ex;}
+ current->adr= NULL;
+ current->next= last;
+ last= current;
+ last->adr= strdup(name);
+ if(last->adr==NULL)
+ {ret= -1; goto ex;}
+ count++;
+ }
+ *filec= count;
+ if(count==0)
+ {ret= 1; goto ex;}
+ (*filev)= (char **) calloc(count, sizeof(char *));
+ if(*filev==NULL)
+ {ret= -1; goto ex; }
+ count= 0;
+ for(current= last; current!=NULL; current= last) {
+ last= current->next;
+ (*filev)[count++]= current->adr;
+ free((char *) current);
+ }
+ Sort_argv(*filec, *filev, 0);
+ ret= 1;
+ex:;
+ for(current= last; current!=NULL; current= last) {
+ last= current->next;
+ free(current->adr);
+ free((char *) current);
+ }
+ return(ret);
+}
+
+
+/* @param flag bit0= long format
+ bit1= do not print count of nodes
+ bit2= du format
+ bit3= print directories as themselves (ls -d)
+*/
+int Xorriso_lsx_filev(struct XorrisO *xorriso, char *wd,
+ int filec, char **filev, off_t boss_mem, int flag)
+{
+ int i, ret, was_error= 0, dfilec= 0, pass, passes;
+ char sfe[5*SfileadrL], sfe2[5*SfileadrL], path[SfileadrL];
+ char *rpt, link_target[SfileadrL], **dfilev= NULL;
+ off_t size;
+ struct stat stbuf;
+
+ rpt= xorriso->result_line;
+
+ Sort_argv(filec, filev, 0);
+
+ /* Count valid nodes, warn of invalid ones */
+ for(i= 0; iinfo_text, "Not found in local filesystem: %s",
+ Text_shellsafe(path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 1);
+ was_error++;
+ continue;
+ }
+ }
+
+ if((flag&8) && !(flag&(2|4))) {
+ sprintf(xorriso->info_text,"Valid local files found: %d\n",filec-was_error);
+ Xorriso_info(xorriso,1);
+ if(filec-was_error<=0)
+ return(!was_error);
+ }
+
+ passes= 1+!(flag&(4|8));
+ for(pass= 0; passrequest_to_abort); i++) {
+ ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4);
+ if(ret<=0)
+ continue;
+ ret= lstat(path, &stbuf);
+ if(ret==-1)
+ continue;
+ if(S_ISLNK(stbuf.st_mode) &&
+ (xorriso->do_follow_links || xorriso->do_follow_param)) {
+ ret= stat(path, &stbuf);
+ if(ret==-1)
+ ret= lstat(path, &stbuf);
+ if(ret==-1)
+ continue;
+ }
+ if(S_ISDIR(stbuf.st_mode) && !(flag&(4|8))) {
+ if(pass==0)
+ continue;
+ if(filec>1) {
+ strcpy(xorriso->result_line, "\n");
+ Xorriso_result(xorriso,0);
+ sprintf(xorriso->result_line, "%s:\n", Text_shellsafe(filev[i], sfe,0));
+ Xorriso_result(xorriso,0);
+ }
+ ret= Xorriso_sorted_dir_x(xorriso, path, &dfilec, &dfilev, boss_mem, 0);
+ if(ret<=0) {
+
+ /* >>> DirseQ loop and single item Xorriso_lsx_filev() */;
+
+ } else {
+ if(flag&1) {
+ sprintf(xorriso->result_line, "total %d\n", dfilec);
+ Xorriso_result(xorriso,0);
+ }
+ Xorriso_lsx_filev(xorriso, path,
+ dfilec, dfilev, boss_mem, (flag&1)|2|8);
+ }
+ if(dfilec>0)
+ Sfile_destroy_argv(&dfilec, &dfilev, 0);
+ continue;
+ } else
+ if(pass>0)
+ continue;
+ link_target[0]= 0;
+ rpt[0]= 0;
+ if((flag&5)==1) {
+ ret= Xorriso_format_ls_l(xorriso, &stbuf, 0);
+ if(ret<=0)
+ continue;
+ if(S_ISLNK(stbuf.st_mode)) {
+ ret= Xorriso_resolve_link(xorriso, path, link_target, 1);
+ if(ret<=0)
+ link_target[0]= 0;
+ }
+ } else if(flag&4) { /* -du or -dus */
+ size= stbuf.st_size;
+ if(S_ISDIR(stbuf.st_mode)) {
+ ret= Xorriso_show_dux_subs(xorriso, path, filev[i], &size, boss_mem,
+ NULL, flag&1);
+ if(ret<0)
+ return(-1);
+ if(ret==0)
+ continue;
+ }
+ sprintf(rpt, "%7.f ",(double) (size/1024));
+ }
+ if(link_target[0])
+ sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n",
+ Text_shellsafe(filev[i], sfe, 0),
+ Text_shellsafe(link_target, sfe2, 0));
+ else
+ sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
+ Text_shellsafe(filev[i], sfe, 0));
+ Xorriso_result(xorriso, 0);
+ }
+ return(!was_error);
+}
+
+
+/* @param flag bit0= recursion
+*/
+int Xorriso_findx_action(struct XorrisO *xorriso, struct FindjoB *job,
+ char *abs_path, char *show_path, int depth, int flag)
+{
+ int ret= 0, type, action= 0, dpl= 0, compare_result, uret;
+ uid_t user= 0;
+ gid_t group= 0;
+ time_t date= 0;
+ mode_t mode_or= 0, mode_and= ~1;
+ char *target, sfe[5*SfileadrL], *disk_prefix, iso_path[SfileadrL];
+ struct FindjoB *subjob;
+ struct stat stbuf;
+
+ action= Findjob_get_action_parms(job, &target, &user, &group,
+ &mode_and, &mode_or, &type, &date, &subjob, 0);
+ if(action<0)
+ action= 0;
+ if(action<0)
+ action= 0;
+ if(action==15 || action==16 || action==18 || action==19 || action==20) {
+ /* in_iso , not_in_iso, add_missing , empty_iso_dir , is_full_in_iso */
+ Findjob_get_start_path(job, &disk_prefix, 0);
+ if(strncmp(abs_path, disk_prefix, strlen(disk_prefix))!=0)
+ {ret= -1; goto ex;}
+ dpl= strlen(disk_prefix);
+ if(strlen(target)+strlen(abs_path)-dpl >= SfileadrL)
+ {ret= -1; goto ex;}
+ if(abs_path[dpl]=='/')
+ dpl++;
+ ret= Xorriso_make_abs_adr(xorriso, target, abs_path+dpl, iso_path, 4);
+ if(ret<=0)
+ {goto ex;}
+
+ }
+ if(action==15) { /* in_iso */
+ ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0);
+ if(ret<0)
+ {ret= 1; goto ex;}
+ sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0));
+ Xorriso_result(xorriso, 0);
+ ret= 1;
+ } else if(action==16) { /* not_in_iso */
+ ret= Xorriso_compare_2_files(xorriso, abs_path, iso_path, abs_path+dpl,
+ &compare_result, 4);
+ if(retfind_compare_result)
+ xorriso->find_compare_result= ret;
+ if(ret>=0)
+ ret= 1;
+ } else if(action==18) { /* add_missing */
+ ret= Xorriso_compare_2_files(xorriso, abs_path, iso_path, abs_path+dpl,
+ &compare_result, 4|(1<<31));
+ if(retfind_compare_result)
+ xorriso->find_compare_result= ret;
+ if(ret==0) {
+ uret= Xorriso_update_interpreter(xorriso, NULL, compare_result,
+ abs_path, iso_path, (flag&1)<<2);
+ if(uret<=0)
+ ret= 0;
+ }
+ if(ret>=0)
+ ret= 1;
+ } else if(action==19) { /* empty_iso_dir */
+ ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0);
+ if(ret<0)
+ {ret= 1; goto ex;}
+ if(!S_ISDIR(stbuf.st_mode))
+ {ret= 1; goto ex;}
+ ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, iso_path, 1|32);
+ if(ret>0) {
+ sprintf(xorriso->info_text, "Emptied directory %s",
+ Text_shellsafe(iso_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
+ }
+ } else if(action==20) { /* is_full_in_iso */
+ ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0);
+ if(ret<0)
+ {ret= 1; goto ex;}
+ if(!S_ISDIR(stbuf.st_mode))
+ {ret= 1; goto ex;}
+ strcpy(sfe, xorriso->wdi);
+ strcpy(xorriso->wdi, iso_path);
+ ret= Xorriso_ls(xorriso, 4|8);
+ strcpy(xorriso->wdi, sfe);
+ if(ret>0) {
+ sprintf(xorriso->result_line,
+ "d %s (ISO) : non-empty directory (would not match mount point)\n",
+ Text_shellsafe(iso_path, sfe, 0));
+ Xorriso_result(xorriso,0);
+ }
+ {ret= 1; goto ex;}
+ } else {
+ sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0));
+ Xorriso_result(xorriso, 0);
+ ret= 1;
+ }
+ex:;
+ if(action==15 || action==16 || action==18 || action==19 || action==20)
+ if(xorriso->no_volset_present)
+ xorriso->request_to_abort= 1; /* Need an image. No use to try again. */
+ return(ret);
+}
+
+
+/* @param flag bit0=recursion
+*/
+int Xorriso_findx(struct XorrisO *xorriso, struct FindjoB *job,
+ char *abs_dir_parm, char *dir_path,
+ struct stat *dir_stbuf, int depth,
+ struct LinkiteM *link_stack, int flag)
+{
+ int ret,is_link, no_dive;
+ struct DirseQ *dirseq= NULL;
+ struct stat stbuf;
+ struct LinkiteM *own_link_stack;
+ char *abs_dir_path, *namept;
+
+#ifdef Xorriso_fat_local_meM
+ char name[SfileadrL], path[SfileadrL], sfe[5*SfileadrL];
+ char abs_dir_path_data[SfileadrL], abs_path[SfileadrL];
+#else /* Xorriso_fat_local_meM */
+ char *name= NULL, *path= NULL, *sfe= NULL;
+ char *abs_dir_path_data= NULL, *abs_path= NULL;
+
+ sfe= malloc(5*SfileadrL);
+ name= malloc(SfileadrL);
+ path= malloc(SfileadrL);
+ abs_dir_path_data= malloc(SfileadrL);
+ abs_path= malloc(SfileadrL);
+ if(name==NULL || sfe==NULL || path==NULL ||
+ abs_dir_path_data==NULL || abs_path==NULL) {
+ Xorriso_no_malloc_memory(xorriso, &sfe, 0);
+ {ret= -1; goto ex;}
+ }
+#endif /* ! Xorriso_fat_local_meM */
+
+ own_link_stack= link_stack;
+ abs_dir_path= abs_dir_parm;
+ if(abs_dir_path[0]==0) {
+ ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, dir_path,
+ abs_dir_path_data, 1|2|8);
+ if(ret<=0)
+ goto ex;
+ abs_dir_path= abs_dir_path_data;
+ ret= Xorriso_path_is_excluded(xorriso, abs_dir_path, !(flag&1));
+ if(ret<0)
+ goto ex;
+ if(ret>0)
+ {ret= 0; goto ex;}
+ ret= lstat(abs_dir_path, dir_stbuf);
+ if(ret==-1)
+ {ret= 0; goto ex;}
+ if(S_ISLNK(dir_stbuf->st_mode) &&
+ (xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
+ if(stat(abs_dir_path, &stbuf)!=-1)
+ if(dir_stbuf->st_dev == stbuf.st_dev ||
+ (xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1))))
+ memcpy(dir_stbuf, &stbuf, sizeof(struct stat));
+
+ namept= strrchr(dir_path, '/');
+ if(namept==NULL)
+ namept= dir_path;
+ else
+ namept++;
+ ret= Findjob_test(job, namept, NULL, dir_stbuf, depth, 0);
+ if(ret<0)
+ goto ex;
+ if(ret>0) {
+ ret= Xorriso_findx_action(xorriso, job, abs_dir_path, dir_path, depth,
+ flag&1);
+ if(ret<=0) {
+ if(xorriso->request_to_abort)
+ goto ex;
+ if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
+ goto ex;
+ }
+ }
+ }
+ if(xorriso->request_to_abort)
+ {ret= 1; goto ex;}
+ if(!S_ISDIR(dir_stbuf->st_mode))
+ {ret= 2; goto ex;}
+
+ ret= Dirseq_new(&dirseq, abs_dir_path, 1);
+ if(ret<0) {
+ sprintf(xorriso->info_text, "Cannot obtain disk directory iterator");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ {ret= -1; goto ex;}
+ }
+ if(ret==0)
+ {ret= 2; goto ex;}
+
+ while(!xorriso->request_to_abort) {
+ Linkitem_reset_stack(&own_link_stack, link_stack, 0);
+ ret= Dirseq_next_adr(dirseq,name,0);
+ if(ret==0)
+ break;
+ if(ret<0) {
+ sprintf(xorriso->info_text,"Failed to obtain next directory entry");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ {ret= -1; goto ex;}
+ }
+ ret= Xorriso_make_abs_adr(xorriso, abs_dir_path, name, abs_path, 1);
+ if(ret<=0)
+ goto ex;
+ ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4);
+ if(ret<=0)
+ goto ex;
+ ret= Xorriso_path_is_excluded(xorriso, abs_path, 0); /* (is never param) */
+ if(ret<0)
+ goto ex;
+ if(ret>0)
+ continue;
+ ret= lstat(abs_path, &stbuf);
+ if(ret==-1)
+ continue;
+ no_dive= 0;
+
+ is_link= S_ISLNK(stbuf.st_mode);
+ if(is_link && xorriso->do_follow_links) {
+ ret= Xorriso_hop_link(xorriso, abs_path, &own_link_stack, &stbuf, 2);
+ if(ret<0)
+ {ret= -1; goto ex;}
+ if(ret!=1)
+ no_dive= 1;
+ }
+ ret= Findjob_test(job, name, dir_stbuf, &stbuf, depth, 0);
+ if(ret<0)
+ goto ex;
+ if(ret>0) {
+ ret= Xorriso_findx_action(xorriso, job, abs_path, path, depth, flag&1);
+ if(ret<=0) {
+ if(xorriso->request_to_abort)
+ goto ex;
+ if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
+ goto ex;
+ }
+ }
+ if(!S_ISDIR(stbuf.st_mode))
+ no_dive= 1;
+ if(dir_stbuf->st_dev != stbuf.st_dev && !xorriso->do_follow_mount)
+ no_dive= 1;
+ if(!no_dive) {
+ ret= Xorriso_findx(xorriso, job, abs_path, path, &stbuf, depth+1,
+ own_link_stack, flag|1);
+ if(ret<0)
+ goto ex;
+ }
+ }
+
+ ret= 1;
+ex:;
+
+#ifndef Xorriso_fat_local_meM
+ if(sfe!=NULL)
+ free(sfe);
+ if(name!=NULL)
+ free(name);
+ if(path!=NULL)
+ free(path);
+ if(abs_dir_path_data!=NULL)
+ free(abs_dir_path_data);
+ if(abs_path!=NULL)
+ free(abs_path);
+#endif /* ! Xorriso_fat_local_meM */
+
+ Dirseq_destroy(&dirseq, 0);
+ return(ret);
+}
+
+
+/* @param flag bit0= a non-existing target of multiple sources is a directory
+ bit1= all paths except the last one are disk_paths
+ @return <=0 iis error, 1= leaf file object, 2= directory
+*/
+int Xorriso_cpmv_args(struct XorrisO *xorriso, char *cmd,
+ int argc, char **argv, int *idx,
+ int *optc, char ***optv, char eff_dest[SfileadrL],
+ int flag)
+{
+ int destc= 0, is_dir=0, end_idx, ret, i;
+ char **destv= NULL;
+ char sfe[5*SfileadrL];
+
+ end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx,
+ (xorriso->do_iso_rr_pattern==1)|(flag&2));
+ if(end_idx - *idx < 2) {
+ sprintf(xorriso->info_text, "%s: not enough arguments", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ {ret= 0; goto ex;}
+ }
+
+ ret= Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, optc, optv,
+ (flag&2)|16); /* ignore last argument */
+ if(ret<=0)
+ goto ex;
+ /* demand one match, or 0 with a constant */
+ ret= Xorriso_opt_args(xorriso, cmd, argc, argv, end_idx, &end_idx, &destc,
+ &destv, 32|64);
+ if(ret<=0)
+ goto ex;
+
+ /* Evaluate target address */
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest, 1);
+ if(ret<0)
+ {ret= 0; goto ex;}
+ if(ret==2 || ((flag&1) && *optc > 1 && ret==0)) {
+ is_dir= 1;
+ } else if(*optc > 1) {
+ for(i= 0; i<*optc; i++)
+ Xorriso_msgs_submit(xorriso, 0, (*optv)[i], 0, "ERRFILE", 0);
+ sprintf(xorriso->info_text,
+ "%s: more than one origin given, destination is a non-directory: %s",
+ cmd, Text_shellsafe(destv[0], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ {ret= 0; goto ex;}
+ }
+ if(ret==0) { /* compute complete eff_dest */
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0],eff_dest,2);
+ if(ret<0)
+ {ret= 0; goto ex;}
+ }
+
+ ret= 1+is_dir;
+ex:;
+ Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &destc, &destv,
+ 256);
+ (*idx)= end_idx;
+ return(ret);
+}
+
+
+/** @return -1= abort , 0= no , 1= yes
+*/
+int Xorriso_reassure(struct XorrisO *xorriso, char *cmd, char *which_will,
+ int flag)
+{
+ int ret;
+
+ if(!xorriso->do_reassure)
+ return(1);
+ sprintf(xorriso->info_text, "Really perform %s which will %s ? (y/n)\n",
+ cmd, which_will);
+ Xorriso_info(xorriso, 4);
+ do {
+ ret= Xorriso_request_confirmation(xorriso, 2|4|16);
+ } while(ret==3);
+ if(ret==6 || ret==4) {
+ sprintf(xorriso->info_text, "%s confirmed", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ return(1);
+ }
+ if(ret==2) {
+ sprintf(xorriso->info_text, "%s aborted", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ return(-1);
+ }
+ sprintf(xorriso->info_text, "%s revoked", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ return(0);
+}
+
+
+/* @param flag bit0+1= what to aquire after giving up outdev
+ 0=none, 1=indev, 2=outdev, 3=both
+*/
+int Xorriso_reaquire_outdev(struct XorrisO *xorriso, int flag)
+{
+ int ret, aq_flag;
+ char drive_name[SfileadrL], sfe[5*SfileadrL];
+
+ aq_flag= flag&3;
+ strcpy(drive_name, xorriso->outdev);
+ Xorriso_give_up_drive(xorriso, aq_flag);
+ if(aq_flag==0) {
+ sprintf(xorriso->info_text,"Gave up -outdev %s",
+ Text_shellsafe(xorriso->outdev, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ return(1);
+ }
+ sprintf(xorriso->info_text,"Re-aquiring -outdev %s",
+ Text_shellsafe(drive_name, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ ret= Xorriso_aquire_drive(xorriso, drive_name, aq_flag);
+ if(ret<=0) {
+ sprintf(xorriso->info_text,"Could not re-aquire -outdev %s",
+ Text_shellsafe(xorriso->outdev, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(ret);
+ }
+ return(1);
+}
+
+
+/* micro version of cdrskin */
+int Xorriso_cdrskin(struct XorrisO *xorriso, char *whom, int argc, char **argv,
+ int flag)
+{
+ int ret, i, k, mem_do_close, aq_ret, eject_ret;
+ int do_atip= 0, do_checkdrive= 0, do_eject= 0, do_scanbus= 0;
+ int do_toc= 0, do_verbous= 0, do_version= 0, do_help= 0;
+ char track_source[SfileadrL], sfe[5*SfileadrL], dev_adr[SfileadrL], *cpt;
+ char mem_report_about_text[80], *report_about= "SORRY", blank_mode[80];
+ char speed[80];
+
+ /* cdrecord 2.01 options which are not scheduled for implementation, yet */
+ static char ignored_partial_options[][41]= {
+ "timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=",
+ "pregap=", "defpregap=", "mcn=", "isrc=", "index=", "textfile=",
+ "pktsize=", "cuefile=",
+ "gracetime=", "minbuf=",
+
+ "assert_write_lba=", "fifo_start_at=", "dev_translation=",
+ "drive_scsi_dev_family=", "fallback_program=", "modesty_on_drive=",
+ "tao_to_sao_tsize=",
+
+ "direct_write_amount=", "write_start_address=", "msifile=",
+
+ "tsize=",
+
+ ""
+ };
+ static char ignored_full_options[][41]= {
+ "-d", "-Verbose", "-V", "-silent", "-s", "-setdropts", "-prcap",
+ "-reset", "-abort", "-overburn", "-ignsize", "-useinfo",
+ "-fix", "-nofix",
+ "-raw", "-raw96p", "-raw16",
+ "-clone", "-text", "-mode2", "-xa", "-xa1", "-xa2", "-xamix",
+ "-cdi", "-preemp", "-nopreemp", "-copy", "-nocopy",
+ "-scms", "-shorttrack", "-noshorttrack", "-packet", "-noclose",
+ "-media-info", "-minfo",
+ "-isosize", "-load", "-lock", "-raw96r", "-sao", "-dao", "-swab",
+ "-tao", "-waiti", "-force", "-format",
+
+ "--adjust_speed_to_drive", "--allow_emulated_drives", "--allow_setuid",
+ "--allow_untested_media", "--any_track", "--demand_a_drive",
+ "--fifo_disable", "--fifo_start_empty", "--fill_up_media",
+ "--list_ignored_options", "--no_rc", "--no_convert_fs_adr",
+ "--prodvd_cli_compatible", "--single_track",
+
+ "--tell_media_space",
+
+ ""
+ };
+
+ static char helptext[][80]= {
+"Usage: xorriso -as cdrecord [options|source_addresses]",
+"Note: This is not cdrecord. See xorriso -help, xorriso -version, man xorriso",
+"Options:",
+"\t-version\tprint version information and exit emulation",
+"\t--devices\tprint list of available MMC drives and exit emulation",
+"\tdev=target\tpseudo-SCSI target to use as CD-Recorder",
+"\t-v\t\tincrement verbose level by one",
+"\t-checkdrive\tcheck if a driver for the drive is present",
+"\t-inq\t\tdo an inquiry for the drive and exit emulation",
+"\tspeed=#\t\tset speed of drive",
+"\tblank=type\tblank a CD-RW disc (see blank=help)",
+"\tfs=#\t\tSet fifo size to # (0 to disable, default is 4 MB)",
+"\t-eject\t\teject the disk after doing the work",
+"\t-toc\t\tretrieve and print TOC/PMA data",
+"\t-atip\t\tretrieve media state, print \"Is *erasable\"",
+"\tpadsize=#\tAmount of padding",
+"\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)",
+"\t-pad\t\tpadsize=30k",
+"\t-nopad\t\tDo not pad",
+"\t-help\t\tprint this text to stderr and exit emulation",
+"Actually this is the integrated ISO RockRidge filesystem manipulator xorriso",
+"lending its libburn capabilities to a very limited cdrecord emulation.",
+"Only a single data track can be burnt to blank or overwriteable media which",
+"will be finalized afterwards if possible.",
+"A much more elaborate cdrecord emulator is cdrskin from the same project.",
+"@End_of_helptexT@"
+};
+/* "\t-scanbus\tscan the SCSI bus and exit emulation", */
+
+static char blank_help[][80]= {
+"Blanking options:",
+"\tall\t\tblank the entire disk",
+"\tdisc\t\tblank the entire disk",
+"\tdisk\t\tblank the entire disk",
+"\tfast\t\tminimally blank the entire disk",
+"\tminimal\t\tminimally blank the entire disk",
+"\tdeformat\t\tblank a formatted DVD-RW",
+"\tdeformat_quickest\t\tminimally blank a formatted DVD-RW to DAO only",
+"@End_of_helptexT@"
+};
+
+ strcpy(mem_report_about_text, xorriso->report_about_text);
+ mem_do_close= xorriso->do_close;
+
+ track_source[0]= 0;
+ dev_adr[0]= 0;
+ blank_mode[0]= 0;
+ speed[0]= 0;
+
+ if(xorriso->in_drive_handle != NULL) {
+ ret= Xorriso_option_dev(xorriso, "", 1); /* give up indev */
+ if(ret!=1)
+ return(ret);
+ }
+
+
+ /* Assess plan, make settings */
+ for(i= 0; iinfo_text, "-as %s: %s",
+ whom, Text_shellsafe(argv[i], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+
+ for(k=0;ignored_partial_options[k][0]!=0;k++) {
+ if(argv[i][0]=='-')
+ if(strncmp(argv[i]+1,ignored_partial_options[k],
+ strlen(ignored_partial_options[k]))==0)
+ goto no_volunteer;
+ if(strncmp(argv[i],ignored_partial_options[k],
+ strlen(ignored_partial_options[k]))==0)
+ goto no_volunteer;
+ }
+ for(k=0;ignored_full_options[k][0]!=0;k++)
+ if(strcmp(argv[i],ignored_full_options[k])==0)
+ goto no_volunteer;
+ if(0) {
+no_volunteer:;
+ sprintf(xorriso->info_text, "-as %s: Ignored option %s",
+ whom, Text_shellsafe(argv[i], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ continue;
+ }
+
+ if(strcmp(argv[i], "-atip")==0) {
+ do_atip= 1;
+ } else if(strcmp(argv[i], "-audio")==0) {
+ sprintf(xorriso->info_text, "-as %s: Option -audio not supported.", whom);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ } else if(strncmp(argv[i], "-blank=", 7)==0 ||
+ strncmp(argv[i], "blank=", 6)==0) {
+ cpt= strchr(argv[i], '=')+1;
+ if(strcmp(cpt,"all")==0 || strcmp(cpt,"disc")==0
+ || strcmp(cpt,"disk")==0) {
+ strcpy(blank_mode, "all");
+ } else if(strcmp(cpt,"fast")==0 || strcmp(cpt,"minimal")==0) {
+ strcpy(blank_mode, "fast");
+ } else if(strcmp(cpt,"help")==0) {
+ strcpy(blank_mode, "help");
+ } else if(strcmp(cpt,"deformat")==0 ||
+ strcmp(cpt,"deformat_sequential")==0 ||
+ strcmp(cpt,"deformat_quickest")==0 ||
+ strcmp(cpt,"deformat_sequential_quickest")==0) {
+ strcpy(blank_mode, cpt);
+ } else {
+ sprintf(xorriso->info_text,
+ "-as %s: blank=%s not supported. See blank=help .",
+ whom, Text_shellsafe(argv[i], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ }
+ } else if(strcmp(argv[i], "-checkdrive")==0) {
+ do_checkdrive= 1;
+ } else if(strcmp(argv[i], "-data")==0) {
+ /* ok */;
+ } else if(strncmp(argv[i], "-dev=", 5)==0 ||
+ strncmp(argv[i], "dev=", 4)==0) {
+ cpt= strchr(argv[i], '=')+1;
+ ret= Xorriso_option_dev(xorriso, cpt, 2|8); /* overwriteables as blank */
+ if(ret<=0)
+ goto ex;
+ } else if(strncmp(argv[i],"driveropts=", 11)==0 ||
+ strncmp(argv[i],"-driveropts=", 12)==0) {
+ if(strcmp(argv[i]+11, "help")==0) {
+ fprintf(stderr,"Driver options:\n");
+ fprintf(stderr,
+ "burnfree\tPrepare writer to use BURN-Free technology\n");
+ }
+ } else if(strcmp(argv[i], "-dummy")==0) {
+ xorriso->do_dummy= 1;
+ } else if(strcmp(argv[i], "-eject")==0) {
+ do_eject= 1;
+ } else if(strncmp(argv[i], "-fs=", 4)==0 || strncmp(argv[i], "fs=", 3)==0) {
+ cpt= strchr(argv[i], '=')+1;
+ ret= Xorriso_option_fs(xorriso, cpt, 0);
+ if(ret<=0)
+ goto ex;
+ } else if(strcmp(argv[i], "-inq")==0) {
+ do_checkdrive= 2;
+ } else if(strcmp(argv[i], "-nopad")==0) {
+ xorriso->padding= 0;
+ } else if(strcmp(argv[i], "-pad")==0) {
+ xorriso->padding= 15*2048;
+ } else if(strncmp(argv[i], "-padsize=", 9)==0 ||
+ strncmp(argv[i], "padsize=", 8)==0) {
+ cpt= strchr(argv[i], '=')+1;
+ ret= Xorriso_option_padding(xorriso, cpt, 0);
+ if(ret<=0)
+ goto ex;
+ } else if(strncmp(argv[i], "-speed=", 7)==0 ||
+ strncmp(argv[i], "speed=", 6)==0) {
+ cpt= strchr(argv[i], '=')+1;
+ strncpy(speed, cpt, 79);
+ speed[79]= 0;
+ } else if(strcmp(argv[i], "-multi")==0) {
+ sprintf(xorriso->info_text, "-as %s: Option -multi not supported.", whom);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ } else if(strcmp(argv[i], "-msinfo")==0) {
+ sprintf(xorriso->info_text, "-as %s: Option -msinfo not supported.",whom);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ } else if(strcmp(argv[i], "--devices")==0) {
+ do_scanbus= 2;
+ } else if(strcmp(argv[i], "-scanbus")==0) {
+ sprintf(xorriso->info_text, "-as %s: Option -scanbus not supported.",
+ whom);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+
+/* do_scanbus= 1; */
+ } else if(strcmp(argv[i], "-toc")==0) {
+ do_toc= 1;
+ } else if(strcmp(argv[i], "--grow_overwriteable_iso")==0) {
+ sprintf(xorriso->info_text,
+ "-as %s: Option --grow_overwriteable_iso not supported.",
+ whom);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i],"-verbose")==0) {
+ do_verbous++;
+ } else if(strcmp(argv[i], "-vv")==0) {
+ do_verbous+= 2;
+ } else if(strcmp(argv[i], "-vvv")==0) {
+ do_verbous+= 3;
+ } else if(strcmp(argv[i], "-version")==0) {
+ do_version= 1;
+ } else if(strcmp(argv[i], "-help")==0) {
+ do_help= 1;
+ } else if(argv[i][0]=='-' && argv[i][1]!=0) {
+ sprintf(xorriso->info_text, "-as %s: Unknown option %s",
+ whom, Text_shellsafe(argv[i], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ } else {
+ if(track_source[0]) {
+ sprintf(xorriso->info_text, "-as %s: Surplus track source %s",
+ whom, Text_shellsafe(argv[i], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ sprintf(xorriso->info_text, "First and only track source is %s",
+ Text_shellsafe(track_source, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ ret= 0; goto ex;
+ }
+ if(Sfile_str(track_source, argv[i], 0)<=0)
+ {ret= -1; goto ex;}
+ }
+ }
+
+ /* Perform actions */
+ Xorriso_option_report_about(xorriso, "NOTE", 0);
+ if(do_version) {
+ sprintf(xorriso->result_line, "Cdrecord 2.01-Emulation Copyright (C) 2008 see libburnia-project.org xorriso\n");
+ Xorriso_result(xorriso, 1);
+ Xorriso_option_version(xorriso, 0);
+ ret= 1; goto ex;
+ }
+ if(do_help) {
+ for(i= 0; strcmp(helptext[i], "@End_of_helptexT@")!=0; i++) {
+ sprintf(xorriso->info_text, "%s\n", helptext[i]);
+ Xorriso_info(xorriso,0);
+ }
+ ret= 1; goto ex;
+ }
+ if(do_scanbus) {
+ if(do_scanbus==1)
+ /* >>> would need -scanbus compatible output and input format */;
+ else
+ Xorriso_option_devices(xorriso, 0);
+ ret= 1; goto ex;
+ }
+ if(strcmp(blank_mode, "help")==0) {
+ for(i= 0; strcmp(blank_help[i], "@End_of_helptexT@")!=0; i++) {
+ sprintf(xorriso->info_text, "%s\n", blank_help[i]);
+ Xorriso_info(xorriso,0);
+ }
+ ret= 1; goto ex;
+ }
+
+ if(!(do_checkdrive || do_atip || do_toc || blank_mode[0] || track_source[0] ||
+ do_eject))
+ {ret= 1; goto ex;}
+
+ if(xorriso->out_drive_handle==NULL) {
+ sprintf(xorriso->info_text, "-as %s: No output drive selected", whom);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ }
+ if(speed[0]) {
+ ret= Xorriso_option_speed(xorriso, speed, 0);
+ if(ret<=0)
+ goto ex;
+ }
+
+ if(do_verbous<=0)
+ report_about= "SORRY";
+ else if(do_verbous<=2)
+ report_about= "UPDATE";
+ else if(do_verbous==3)
+ report_about= "DEBUG";
+ else
+ report_about= "ALL";
+ Xorriso_option_report_about(xorriso, report_about, 0);
+
+ if(do_checkdrive) {
+ ret= Xorriso_atip(xorriso, 2-(do_checkdrive==2));
+ if(ret<=0)
+ goto ex;
+ }
+ if(do_atip) {
+ ret= Xorriso_atip(xorriso, 0);
+ if(ret<=0)
+ goto ex;
+ }
+ if(do_toc) {
+ ret= Xorriso_option_toc(xorriso, 0);
+ if(ret<=0)
+ goto ex;
+ }
+ if(blank_mode[0]) {
+ ret= Xorriso_option_blank(xorriso, blank_mode, 0);
+ if(ret<=0)
+ goto ex;
+ }
+ if(track_source[0]) {
+ xorriso->do_close= 1;
+ ret= Xorriso_burn_track(xorriso, track_source, 0);
+ aq_ret= Xorriso_reaquire_outdev(xorriso, 2*(ret>0));
+ if(ret<=0 && ret=0) {
+ eject_ret= Xorriso_option_eject(xorriso, "out", 0);
+ if(eject_retinfo_text, "-as %s: Job could not be performed properly.",
+ whom);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ }
+ Xorriso_option_report_about(xorriso, mem_report_about_text, 0);
+ xorriso->do_close= mem_do_close;
+ return(ret);
+}
+
+
+/* micro emulation of mkisofs */
+int Xorriso_genisofs(struct XorrisO *xorriso, char *whom,
+ int argc, char **argv, int flag)
+{
+ int ret, i, k, was_path= 0, was_other_option= 0, mem_graft_points;
+ int do_print_size= 0, idx_offset= 0, fd, idx;
+ char sfe[5*SfileadrL], adr[SfileadrL+8], ra_text[80], pathspec[2*SfileadrL];
+ char *ept, *add_pt, eff_path[SfileadrL];
+
+ /* mkisofs 2.01 options which are not scheduled for implementation, yet */
+ static char ignored_arg0_options[][41]= {
+ "-allow-leading-dots", "-ldots", "-allow-lowercase", "-allow-multidot",
+ "-cache-inodes", "-no-cache-inodes", "-check-oldnames", "-d", "-D",
+ "-joliet-long", "-l", "-L", "-max-iso9660-filenames", "-N", "-nobak",
+ "-no-bak", "-force-rr", "-r", "-relaxed-filenames", "-T", "-U",
+ "-no-iso-translate",
+ ""
+ };
+ static char ignored_arg1_options[][41]= {
+ "-A", "-biblio", "-check-session", "-p", "-root",
+ "-old-root", "-sysid", "-table-name",
+ ""
+ };
+ static char helptext[][80]= {
+"Usage: xorriso -as mkisofs [options] file...",
+"Note: This is not mkisofs. See xorriso -help, xorriso -version, man xorriso",
+"Options:",
+" -f, -follow-links Follow symbolic links",
+" -graft-points Allow to use graft points for filenames",
+" -help Print option help",
+" -J, -joliet Generate Joliet directory information",
+" -no-pad Do not pad output",
+" -o FILE, -output FILE Set output file name",
+" -m GLOBFILE, -exclude GLOBFILE",
+" Exclude file name",
+" -exclude-list FILE File with list of file names to exclude",
+" -pad Pad output by 300k (default)",
+" -path-list FILE File with list of pathnames to process",
+" -print-size Print estimated filesystem size and exit",
+" -quiet Run quietly",
+" -R, -rock Generate Rock Ridge directory information",
+" -V ID, -volid ID Set Volume ID",
+" -v, -verbose Verbose",
+" -version Print the current version",
+"@End_of_helptexT@"
+};
+
+ strcpy(ra_text, xorriso->report_about_text);
+
+ if(xorriso->in_drive_handle != NULL) {
+ ret= Xorriso_option_dev(xorriso, "", 1); /* give up indev */
+ if(ret!=1)
+ return(ret);
+ }
+
+ adr[0]= 0;
+ for(i= 0; iresult_line,
+"mkisofs 2.01-Emulation Copyright (C) 2008 see libburnia-project.org xorriso\n"
+ );
+ fd= xorriso->dev_fd_1;
+ if(fd<0)
+ fd= 1;
+ write(fd, xorriso->result_line, strlen(xorriso->result_line));
+ fsync(fd);
+ Xorriso_option_version(xorriso, 0);
+
+ } else if(strcmp(argv[i], "-o")==0 || strcmp(argv[i], "-output")==0) {
+ if(i+1>=argc)
+ goto not_enough_args;
+ i++;
+ adr[0]= 0;
+ if(strcmp(argv[i],"-")!=0)
+ strcpy(adr, "stdio:");
+ if(Sfile_str(adr+strlen(adr), argv[i], 0)<=0)
+ {ret= -1; goto ex;}
+ } else if(strcmp(argv[i], "-help")==0) {
+ Xorriso_option_report_about(xorriso, "NOTE", 0);
+ for(i= 0; strcmp(helptext[i], "@End_of_helptexT@")!=0; i++) {
+ sprintf(xorriso->info_text, "%s\n", helptext[i]);
+ Xorriso_info(xorriso,0);
+ }
+ Xorriso_option_report_about(xorriso, ra_text, 0);
+ } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i], "-verbose")==0) {
+ strcpy(ra_text, "UPDATE");
+ } else if(strcmp(argv[i], "-quiet")==0) {
+ strcpy(ra_text, "SORRY");
+ } else if(strcmp(argv[i], "-f")==0 || strcmp(argv[i], "-follow-links")==0) {
+ ret= Xorriso_option_follow(xorriso, "on", 0);
+ if(ret<=0)
+ goto ex;
+ } else
+ was_other_option= 1;
+ }
+ Xorriso_option_report_about(xorriso, ra_text, 0);
+ if(adr[0]) {
+ if(strncmp(adr, "stdio:", 6)==0 && strncmp(adr, "stdio:/dev/fd/", 14)!=0) {
+ ret= Sfile_type(adr+6, 1);
+ if(ret==-1) {
+ /* ok */;
+ } else if(ret==2 || ret==3) {
+ sprintf(xorriso->info_text,
+ "-as %s: Cannot accept %s as target: -o %s",
+ whom, (ret==3 ? "symbolic link" : "directory"),
+ Text_shellsafe(adr+6, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ }
+ }
+ /* Regard overwriteable as blank, truncate regular files on write start */
+ ret= Xorriso_option_dev(xorriso, adr, 2|8|16);
+ if(ret<=0)
+ goto ex;
+ }
+ if(!was_other_option)
+ {ret= 1; goto ex;}
+ if(xorriso->out_drive_handle==NULL) {
+ ret= Xorriso_option_dev(xorriso, "-", 2|4); /* set outdev to stdout */
+ if(ret<=0)
+ return(ret);
+ }
+
+ xorriso->padding= 300*1024;
+
+ for(i= 0; iinfo_text, "-as %s: %s",
+ whom, Text_shellsafe(argv[i], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+ idx_offset= 0;
+ for(k=0;ignored_arg0_options[k][0]!=0;k++)
+ if(strcmp(argv[i],ignored_arg0_options[k])==0)
+ goto no_volunteer;
+ for(k=0;ignored_arg1_options[k][0]!=0;k++)
+ if(strcmp(argv[i],ignored_arg1_options[k])==0) {
+ i++;
+ idx_offset= -1;
+ goto no_volunteer;
+ }
+ if(0) {
+no_volunteer:;
+ sprintf(xorriso->info_text, "-as %s: Ignored option %s",
+ whom, Text_shellsafe(argv[i+idx_offset], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ continue;
+ }
+
+ if(strcmp(argv[i], "-version")==0) {
+ /* was already handled in first argument scan */;
+
+ } else if(strcmp(argv[i], "-R")==0 || strcmp(argv[i], "-rock")==0) {
+ /* ok */;
+ } else if(strcmp(argv[i], "-J")==0 || strcmp(argv[i], "-joliet")==0) {
+ xorriso->do_joliet= 1;
+ } else if(strcmp(argv[i], "-graft-points")==0) {
+ xorriso->allow_graft_points= 1;
+ } else if(strcmp(argv[i], "-path-list")==0) {
+ if(i+1>=argc) {
+not_enough_args:;
+ sprintf(xorriso->info_text, "-as %s: Not enough arguments to option %s",
+ whom, argv[i]);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ }
+ i++;
+ ret= Xorriso_option_path_list(xorriso, argv[i], 0);
+ if(ret<=0)
+ goto ex;
+ } else if(strcmp(argv[i], "-f")==0 || strcmp(argv[i], "-follow-links")==0) {
+ /* was already handled in first argument scan */;
+ } else if(strcmp(argv[i], "-pad")==0) {
+ xorriso->padding= 300*1024;
+ } else if(strcmp(argv[i], "-no-pad")==0) {
+ xorriso->padding= 0;
+ } else if(strcmp(argv[i], "-print-size")==0) {
+ do_print_size= 1;
+ } else if(strcmp(argv[i], "-o")==0) {
+ i++;
+ /* was already handled in first argument scan */;
+ } else if(strcmp(argv[i], "-help")==0) {
+ /* was already handled in first argument scan */;
+ } else if(strcmp(argv[i], "-V")==0 || strcmp(argv[i], "-volid")==0) {
+ if(i+1>=argc)
+ goto not_enough_args;
+ i++;
+ ret= Xorriso_option_volid(xorriso, argv[i], 0);
+ if(ret<=0)
+ goto ex;
+ } else if(strcmp(argv[i], "-P")==0 || strcmp(argv[i], "-publisher")==0) {
+ if(i+1>=argc)
+ goto not_enough_args;
+ i++;
+ ret= Xorriso_option_publisher(xorriso, argv[i], 0);
+ if(ret<=0)
+ goto ex;
+ } else if(strcmp(argv[i], "-m")==0 || strcmp(argv[i], "-exclude")==0 ||
+ strcmp(argv[i], "-x")==0 || strcmp(argv[i], "-old-exclude")==0) {
+ if(i+1>=argc)
+ goto not_enough_args;
+ i++;
+ if(strchr(argv[i], '/')!=NULL) {
+ idx= i;
+ ret= Xorriso_option_not_paths(xorriso, i+1, argv, &idx, 0);
+ } else
+ ret= Xorriso_option_not_leaf(xorriso, argv[i], 0);
+ if(ret<=0)
+ goto ex;
+ } else if(strcmp(argv[i], "-exclude-list")==0) {
+ if(i+1>=argc)
+ goto not_enough_args;
+ i++;
+ ret= Xorriso_option_not_leaf(xorriso, argv[i], 0);
+ if(ret<=0)
+ goto ex;
+ } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i], "-quiet")==0) {
+ /* was already handled in first argument scan */;
+
+ } else if(argv[i][0]=='-' && argv[i][1]!=0) {
+ sprintf(xorriso->info_text, "-as %s: Unknown option %s",
+ whom, Text_shellsafe(argv[i], sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ } else {
+ int zero= 0;
+
+ /* implementing mkisofs tendency to map single-path pathspecs to / */
+ if((!xorriso->allow_graft_points) ||
+ Fileliste__target_source_limit(argv[i], '=', &ept, 0)<=0) {
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, argv[i],
+ eff_path, 2|4);
+ if(ret<=0)
+ goto ex;
+ ret= Sfile_type(eff_path,
+ 1|((xorriso->do_follow_param||xorriso->do_follow_links)<<2));
+ if(ret==2) {
+ strcpy(pathspec, "/=");
+ } else {
+ pathspec[0]= '/';
+ pathspec[1]= 0;
+ ret= Sfile_leafname(eff_path, pathspec+1, 0);
+ if(ret>0)
+ strcat(pathspec, "=");
+ else
+ pathspec[0]= 0;
+ }
+ strcat(pathspec, eff_path);
+ add_pt= pathspec;
+ } else
+ add_pt= argv[i];
+ mem_graft_points= xorriso->allow_graft_points;
+ xorriso->allow_graft_points= 1;
+ ret= Xorriso_option_add(xorriso, 1, &add_pt, &zero, was_path<<1);
+ xorriso->allow_graft_points= mem_graft_points;
+ if(ret<=0)
+ goto ex;
+ was_path= 1;
+ }
+ }
+ if(do_print_size) {
+ ret= Xorriso_option_print_size(xorriso, 1);
+ if(ret<=0)
+ goto ex;
+ }
+
+ ret= 1;
+ex:;
+ if(was_path && !do_print_size)
+ Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
+ xorriso->pacifier_total, "", 1);
+ if(do_print_size && xorriso->volset_change_pending)
+ Xorriso_option_rollback(xorriso, 0);
+ return(ret);
+}
+
+
+/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
+ Set to NULL if calling this function from outside ISO world
+ @param flag bit2= -follow: this is not a command parameter
+ @return <=0 error, 1= ok , 2= iso_rr_path has been deleted ,
+ 3= no action taken
+*/
+int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter,
+ int compare_result, char *disk_path,
+ char *iso_rr_path, int flag)
+{
+ int ret, deleted= 0, is_split= 0, i, loop_count;
+ char sfe[5*SfileadrL];
+ struct stat stbuf;
+ struct SplitparT *split_parts= NULL;
+ int split_count= 0;
+ char part_path[SfileadrL], *part_name;
+ int partno, total_parts, new_total_parts;
+ off_t offset, bytes, total_bytes, disk_size, first_bytes;
+
+ if((compare_result&3)==3) {
+ sprintf(xorriso->info_text, "Missing on disk and in ISO: disk_path %s",
+ Text_shellsafe(disk_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1);
+ xorriso->find_compare_result= -1;
+ ret= 3; goto ex;
+ }
+
+ if(compare_result&((1<<11)|(1<<13))) {
+ /* cannot open regular disk file, early eof of disk file */
+ sprintf(xorriso->info_text, "Problems with reading disk file %s",
+ Text_shellsafe(disk_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1);
+ xorriso->find_compare_result= -1;
+ ret= 1; goto ex;
+ }
+ xorriso->info_text[0]= 0;
+ is_split= !!(compare_result & (1<<17));
+
+ if(compare_result&(8|64)) {
+ /* file type, minor+major with device file */
+ ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1); /* rm_r */
+ if(ret>0) {
+ deleted= 1;
+ ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, iso_rr_path,
+ (off_t) 0, (off_t) 0, 2|(flag&4));
+ }
+ sprintf(xorriso->info_text, "Deleted and re-added ");
+
+ } else if(compare_result&(1)) {
+delete:;
+ /* disk_adr not existing */
+ ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1);
+ deleted= 1;
+ sprintf(xorriso->info_text, "Deleted ");
+
+ } else if(compare_result&(2|128|(1<<12)|(1<<14)|(1<<15))) {
+ /* iso_adr not existing, size, cannot open iso file, early eof of iso file
+ content bytes differ */
+
+ if(is_split) {
+ ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL,
+ &split_parts, &split_count, &stbuf, 0);
+ if(ret<=0)
+ {ret= -1; goto ex;} /* (should not happen) */
+ ret= lstat(disk_path, &stbuf);
+ if(ret==-1)
+ goto delete;
+ disk_size= stbuf.st_size;
+ Splitparts_get(split_parts, 0, &part_name, &partno, &total_parts,
+ &offset, &first_bytes, &total_bytes, 0);
+ new_total_parts= disk_size/first_bytes;
+ if(disk_size % first_bytes)
+ new_total_parts++;
+
+ loop_count= split_count;
+ /* If disk file grew over part limit and all parts are present:
+ add new parts */
+ if(new_total_parts > total_parts && split_count == total_parts)
+ loop_count= new_total_parts;
+
+ for(i= 0; iSfileadrL) {
+ Xorriso_much_too_long(xorriso, strlen(part_path)+160, 2);
+ ret= 0; goto ex;
+ }
+ Splitpart__compose(part_path+strlen(iso_rr_path)+1, partno,
+ new_total_parts, offset, first_bytes, disk_size, 0);
+ ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, part_path,
+ offset, bytes, 2|(flag&4)|8);
+ if(ret<=0)
+ goto ex;
+ }
+ /* Copy file attributes to iso_rr_path, augment r-perms by x-perms */
+ ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 2);
+ if(ret<=0)
+ goto ex;
+ } else
+ ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, iso_rr_path,
+ (off_t) 0, (off_t) 0, 2|(flag&4));
+ sprintf(xorriso->info_text, "Added/overwrote ");
+
+ } else if(compare_result&(4|16|32|256|512|1024)) {
+ /* access permissions, user id, group id, mtime, atime, ctime */
+
+ if(is_split) {
+ ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL,
+ &split_parts, &split_count, &stbuf, 0);
+ if(ret<=0)
+ {ret= -1; goto ex;} /* (should not happen) */
+ for(i= 0; iinfo_text, "Adjusted attributes of ");
+
+ } else
+ ret= 1;
+ if(ret>0 && xorriso->info_text[0]) {
+ strcat(xorriso->info_text, Text_shellsafe(iso_rr_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
+ }
+ ret= 1;
+ex:;
+ if(split_parts!=NULL)
+ Splitparts_destroy(&split_parts, split_count, 0);
+ if(ret<=0)
+ return(ret);
+ if(deleted)
+ return(2);
+ return(ret);
+}
+
+
+int Xorriso_write_session_log(struct XorrisO *xorriso, int flag)
+{
+ FILE *fp= NULL;
+ char sfe[5*SfileadrL], timetext[40], *rpt, *wpt;
+
+ if(xorriso->session_logfile[0]==0)
+ return(2);
+ fp= fopen(xorriso->session_logfile, "a");
+ if(fp==0) {
+ sprintf(xorriso->info_text, "-session_log: Cannot open file %s",
+ Text_shellsafe(xorriso->session_logfile, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ wpt= sfe;
+ for(rpt= xorriso->volid; *rpt!=0; rpt++) {
+ if(*rpt=='\n') {
+ *(wpt++)= '\\';
+ *(wpt++)= 'n';
+ } else
+ *(wpt++)= *rpt;
+ }
+ *wpt= 0;
+ fprintf(fp, "%s %d %d %s\n",
+ Ftimetxt(time(0), timetext, 2), xorriso->session_lba,
+ xorriso->session_blocks, sfe);
+ fclose(fp);
+ return(1);
+}
+
+
+/* @param flag bit0= path is a command parameter
+*/
+int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag)
+{
+ int ret;
+ char sfe[5*SfileadrL];
+
+ if(!(xorriso->disk_excl_mode&1)) /* exclusion is off */
+ return(0);
+ if((flag&1) && !(xorriso->disk_excl_mode&2)) /* params are exempted */
+ return(0);
+ ret= Exclusions_match(xorriso->disk_exclusions, path,
+ !!(xorriso->disk_excl_mode&4));
+ if(ret<0) {
+ sprintf(xorriso->info_text,
+ "Error during disk file exclusion decision");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ }
+ if(ret>0 && (flag&1)) {
+ sprintf(xorriso->info_text, "Disk path parameter excluded by %s : %s",
+ (ret==1 ? "-not_paths" : "-not_leaf"), Text_shellsafe(path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ }
+ return(ret);
+}
+
+
+/* ---------------------------- Options API ------------------------ */
+
+
+/* Option -abort_on */
+int Xorriso_option_abort_on(struct XorrisO *xorriso, char *severity, int flag)
+{
+ int ret, sev;
+ char sfe[5*SfileadrL];
+
+ ret= Xorriso__text_to_sev(severity, &sev, 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text,
+ "-abort_on: Not a known severity name : %s",
+ Text_shellsafe(severity, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(ret);
+ }
+ if(Sfile_str(xorriso->abort_on_text,severity,0)<=0)
+ return(-1);
+ xorriso->abort_on_severity= sev;
+ Xorriso_set_abort_severity(xorriso, 0);
+ return(1);
+}
+
+
+/* Option -add */
+/* @param flag bit0=do not report the added item
+ bit1=do not reset pacifier, no final pacifier message
+*/
+int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int i, end_idx, ret, was_failure= 0, fret, optc= 0, split;
+ char target[SfileadrL], source[SfileadrL], *ept, eff_path[SfileadrL];
+ char **optv= NULL, *rpt, *wpt;
+
+ ret= Xorriso_opt_args(xorriso, "-add", argc, argv, *idx, &end_idx,
+ &optc, &optv, ((!!xorriso->allow_graft_points)<<2)|2);
+ if(ret<=0)
+ goto ex;
+
+ if(!(flag&2))
+ Xorriso_pacifier_reset(xorriso, 0);
+ for(i= 0; iallow_graft_points) {
+ ret= Fileliste__target_source_limit(target, '=', &ept, 0);
+ if(ret>0) {
+ *ept= 0;
+ strcpy(source, ept+1);
+ split= 1;
+ }
+ /* unescape \= */;
+ if(split)
+ rpt= wpt= target;
+ else
+ rpt= wpt= source;
+ for(; *rpt!=0; rpt++) {
+ if(*rpt=='\\')
+ if(*(rpt+1)=='=')
+ continue;
+ *(wpt++)= *rpt;
+ }
+ *wpt= 0;
+ }
+ if(split==0) {
+ strcpy(target, source);
+ } else if(target[0]!='/') {
+ ret= Sfile_prepend_path(xorriso->wdi, target, 0);
+ if(ret<=0)
+ goto problem_handler;
+ }
+
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, target, eff_path, 2);
+ if(ret<=0)
+ goto problem_handler;
+ strcpy(target, eff_path);
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, source,eff_path,2|4);
+ if(ret<=0)
+ goto problem_handler;
+ strcpy(source, eff_path);
+
+ ret= Xorriso_graft_in(xorriso, NULL, source, target, (off_t)0, (off_t)0, 0);
+ if(ret<=0 || xorriso->request_to_abort)
+ goto problem_handler;
+ sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n",
+ (ret>1 ? "directory" : "file"), target, source);
+ if(!(flag&1))
+ Xorriso_info(xorriso, 0);
+
+ continue; /* regular bottom of loop */
+problem_handler:;
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ if(!(flag&2))
+ Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
+ xorriso->pacifier_total, "", 1);
+ ret= 1;
+ex:;
+ (*idx)= end_idx;
+ Xorriso_opt_args(xorriso, "-add", argc, argv, *idx, &end_idx, &optc, &optv,
+ 256);
+ if(ret<=0)
+ return(ret);
+ return(!was_failure);
+}
+
+
+/* Option -add_plainly "none"|"unknown" */
+int Xorriso_option_add_plainly(struct XorrisO *xorriso, char *mode,int flag)
+{
+ if(strcmp(mode, "none")==0)
+ xorriso->add_plainly= 0;
+ if(strcmp(mode, "unknown")==0)
+ xorriso->add_plainly= 1;
+ else if(strcmp(mode, "dashed")==0)
+ xorriso->add_plainly= 2;
+ else if(strcmp(mode, "any")==0)
+ xorriso->add_plainly= 3;
+ else {
+ sprintf(xorriso->info_text, "-add_plainly: unknown mode '%s'", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -alter_date , -alter_date_r */
+/* @param flag bit0=recursive (-alter_date_r)
+*/
+int Xorriso_option_alter_date(struct XorrisO *xorriso,
+ char *time_type, char *timestring,
+ int argc, char **argv, int *idx, int flag)
+{
+ int i, ret, was_failure= 0, t_type= 0, end_idx, fret;
+ time_t t;
+ int optc= 0;
+ char **optv= NULL;
+ struct FindjoB *job= NULL;
+ struct stat dir_stbuf;
+
+ ret= Xorriso_opt_args(xorriso, "-alter_date", argc, argv, *idx, &end_idx,
+ &optc, &optv, 0);
+ if(ret<=0)
+ goto ex;
+ ret= Xorriso_convert_datestring(xorriso, "-alter_date", time_type, timestring,
+ &t_type, &t, 0);
+ if(ret<=0)
+ goto ex;
+ for(i= 0; i0 && !xorriso->request_to_abort)
+ continue; /* regular bottom of loop */
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ ret= 1;
+ex:;
+ (*idx)= end_idx;
+ Xorriso_opt_args(xorriso, "-alter_date", argc, argv, *idx, &end_idx, &optc,
+ &optv, 256);
+ Findjob_destroy(&job, 0);
+ if(ret<=0)
+ return(ret);
+ return(!was_failure);
+}
+
+
+/* Option -as */
+/* @param flag bit0=do not report the added item
+ bit1=do not reset pacifier, no final pacifier message
+*/
+int Xorriso_option_as(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int end_idx, ret, idx_count;
+
+ end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1);
+ idx_count= end_idx-(*idx);
+ if(end_idx<=0) {
+ if(idx_count<1)
+ sprintf(xorriso->info_text,
+ "-as : Not enough arguments given. Needed: whom do_what");
+ else
+ sprintf(xorriso->info_text,
+ "-as %s : Not enough arguments given. Needed: do_what",
+ argv[*idx]);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ }
+ if(strcmp(argv[*idx], "cdrecord")==0 || strcmp(argv[*idx], "wodim")==0 ||
+ strcmp(argv[*idx], "cdrskin")==0) {
+ ret= Xorriso_cdrskin(xorriso, argv[*idx], end_idx-(*idx)-1, argv+(*idx)+1,
+ 0);
+ if(ret<=0)
+ goto ex;
+ } else if(strcmp(argv[*idx], "mkisofs")==0 ||
+ strcmp(argv[*idx], "genisoimage")==0 ||
+ strcmp(argv[*idx], "genisofs")==0) {
+ ret= Xorriso_genisofs(xorriso, argv[*idx], end_idx-(*idx)-1, argv+(*idx)+1,
+ 0);
+ if(ret<=0)
+ goto ex;
+ } else {
+ sprintf(xorriso->info_text,
+ "-as : Not a known emulation personality: '%s'", argv[*idx]);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0; goto ex;
+ }
+
+ ret= 1;
+ex:;
+ (*idx)= end_idx;
+ return(ret);
+}
+
+
+
+/* Option -ban_stdio_write */
+int Xorriso_option_ban_stdio_write(struct XorrisO *xorriso, int flag)
+{
+ xorriso->ban_stdio_write= 1;
+ return(1);
+}
+
+
+/* Option -blank and -format */
+/* @param flag bit0= format rather than blank
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag)
+{
+ char drive_name[SfileadrL], *cmd= "-blank";
+ int aq_ret, ret, aq_flag= 2, mode_flag, as_needed= 0, idx;
+
+ if(flag&1)
+ cmd= "-format";
+ if(xorriso->out_drive_handle == NULL) {
+ sprintf(xorriso->info_text,
+ "%s: No output drive set by -dev -or -outdev", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ if(xorriso->in_drive_handle == xorriso->out_drive_handle) {
+ if(xorriso->volset_change_pending) {
+ sprintf(xorriso->info_text,
+ "%s: Image changes pending. -commit or -rollback first.", cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ aq_flag= 3;
+ }
+ ret= Xorriso_reassure(xorriso, cmd,
+ "possibly make unreadable data on outdev", 0);
+ if(ret<=0)
+ return(2);
+
+ if(strcmp(mode, "as_needed")==0)
+ as_needed= 1;
+ else if(strcmp(mode, "all")==0 || strcmp(mode, "full")==0)
+ mode_flag= 0;
+ else if((strcmp(mode, "deformat")==0 ||
+ strcmp(mode, "deformat_sequential")==0) && !(flag&1))
+ mode_flag= 2;
+ else if((strcmp(mode, "deformat_quickest")==0 ||
+ strcmp(mode, "deformat_sequential_quickest")==0) && !(flag&1))
+ mode_flag= 3;
+ else if(strcmp(mode, "fast")==0)
+ mode_flag= 1;
+ else if(strncmp(mode, "by_index_", 9)==0 && (flag&1)) {
+ mode_flag= 128;
+ idx= -1;
+ if(strlen(mode)>9)
+ sscanf(mode+9, "%d", &idx);
+ if(idx<0 || idx>255) {
+unusable_index:;
+ sprintf(xorriso->info_text,
+ "-format: mode '%s' provides unusable index number", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ mode_flag|= (idx<<8);
+ } else if(strncmp(mode, "fast_by_index_", 14)==0 && (flag&1)) {
+ mode_flag= 1 | 128;
+ idx= -1;
+ if(strlen(mode)>14)
+ sscanf(mode+14, "%d", &idx);
+ if(idx<0 || idx>255)
+ goto unusable_index;
+ mode_flag|= (idx<<8);
+ } else if(mode[0]==0)
+ mode_flag= !(flag&1);
+ else {
+ sprintf(xorriso->info_text,
+ "%s: Unknown %s mode '%s'",
+ cmd, ((flag&1) ? "-format" : "-blank"), mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ if(as_needed)
+ ret= Xorriso_blank_as_needed(xorriso, (flag&1)<<2);
+ else if(flag&1)
+ ret= Xorriso_format_media(xorriso, mode_flag & 0xff81);
+ else
+ ret= Xorriso_blank_media(xorriso, mode_flag&3);
+ if(ret==0)
+ return(ret);
+ strcpy(drive_name, xorriso->outdev);
+ if(ret!=2) {
+ if(ret<=0)
+ aq_flag= 0;
+ aq_ret= Xorriso_reaquire_outdev(xorriso, aq_flag);
+ if(ret<=0 && retkeep_boot_image= 1;
+ xorriso->patch_isolinux_image= 0;
+ } else if(strcmp(treatpt, "discard")==0) {
+ xorriso->keep_boot_image= 0;
+ xorriso->patch_isolinux_image= 0;
+ } else
+ was_ok= 0;
+ } else if(strcmp(formpt, "isolinux")==0) {
+ if(strcmp(treatpt, "patch")==0) {
+ xorriso->keep_boot_image= 1;
+ xorriso->patch_isolinux_image= 1;
+ } else if(strcmp(treatpt, "keep")==0) {
+ xorriso->keep_boot_image= 1;
+ xorriso->patch_isolinux_image= 0;
+ } else if(strcmp(treatpt, "discard")==0) {
+ xorriso->keep_boot_image= 0;
+ xorriso->patch_isolinux_image= 0;
+ } else
+ was_ok= 0;
+ } else
+ was_ok= 0;
+ if(!was_ok) {
+ sprintf(xorriso->info_text, "Unrecognized options with -boot_image: %s %s",
+ form, treatment);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -cd alias -cdi */
+int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag)
+{
+ char sfe[5*SfileadrL], path[SfileadrL], eff_path[SfileadrL];
+ int ret;
+
+ if (strlen(iso_rr_path)>sizeof(xorriso->wdi)) {
+ sprintf(xorriso->info_text,"-cdi: iso_rr_path too long (%d > %d)",
+ (int) strlen(iso_rr_path), (int) sizeof(xorriso->wdi)-1);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ Xorriso_warn_of_wildcards(xorriso, iso_rr_path, 1);
+ sprintf(xorriso->info_text,"previous working directory:\n");
+ Xorriso_info(xorriso,0);
+ sprintf(xorriso->result_line,"%s/\n",Text_shellsafe(xorriso->wdi, sfe, 0));
+ Xorriso_result(xorriso,0);
+ if(strcmp(iso_rr_path,"/")==0 || iso_rr_path[0]==0) {
+ strcpy(xorriso->wdi,"");
+ Xorriso_option_pwdi(xorriso, 0);
+ return(1);
+ } else if(iso_rr_path[0]!='/') {
+ strcpy(path, xorriso->wdi);
+ if(Sfile_add_to_path(path,iso_rr_path,0)<=0)
+ return(-1);
+ } else {
+ if(Sfile_str(path,iso_rr_path,0)<=0)
+ return(-1);
+ }
+
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
+ if(ret<0)
+ return(ret);
+ if(ret==0) {
+ sprintf(xorriso->info_text, "-cdi: not existing yet in ISO image : %s",
+ Text_shellsafe(path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2);
+ if(ret<=0)
+ return(ret);
+ } else if(ret!=2) {
+ sprintf(xorriso->info_text, "-cdi: not a directory : %s",
+ Text_shellsafe(eff_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ strcpy(xorriso->wdi, eff_path);
+
+ Xorriso_option_pwdi(xorriso, 0);
+ return(1);
+}
+
+
+/* Option -cdx */
+int Xorriso_option_cdx(struct XorrisO *xorriso, char *disk_path, int flag)
+{
+ char sfe[5*SfileadrL], path[SfileadrL], eff_path[SfileadrL];
+ int ret;
+
+ if (strlen(disk_path)>sizeof(xorriso->wdx)) {
+ sprintf(xorriso->info_text,"-cdx: disk_path too long (%d > %d)",
+ (int) strlen(disk_path), (int) sizeof(xorriso->wdx)-1);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ Xorriso_warn_of_wildcards(xorriso, disk_path, 1|2);
+ sprintf(xorriso->info_text,"previous working directory on hard disk:\n");
+ Xorriso_info(xorriso,0);
+ sprintf(xorriso->result_line,"%s/\n",Text_shellsafe(xorriso->wdx, sfe, 0));
+ Xorriso_result(xorriso,0);
+ if(strcmp(disk_path,"/")==0) {
+ strcpy(xorriso->wdx,"");
+ Xorriso_option_pwdx(xorriso, 0);
+ return(1);
+ } else if(disk_path[0]!='/') {
+ strcpy(path, xorriso->wdx);
+ if(Sfile_add_to_path(path,disk_path,0)<=0)
+ return(-1);
+ } else {
+ if(Sfile_str(path,disk_path,0)<=0)
+ return(-1);
+ }
+
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, path, eff_path, 2|4);
+ if(ret<=0)
+ return(ret);
+ if(eff_path[0]) {
+ ret= Sfile_type(eff_path,1|4|8);
+ if(ret<0) {
+ Xorriso_msgs_submit(xorriso, 0, eff_path, 0, "ERRFILE", 0);
+ sprintf(xorriso->info_text,"-cdx: file not found : %s",
+ Text_shellsafe(eff_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ if(ret!=2) {
+ Xorriso_msgs_submit(xorriso, 0, eff_path, 0, "ERRFILE", 0);
+ sprintf(xorriso->info_text,
+ "-cdx: not a directory : %s",
+ Text_shellsafe(eff_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ }
+ if(Sfile_str(xorriso->wdx,eff_path,0)<=0)
+ return(-1);
+ Xorriso_option_pwdx(xorriso, 0);
+ return(1);
+}
+
+
+/* Option -chgrp alias -chgrpi , chgrp_r alias chgrpi */
+/* @param flag bit0=recursive (-chgrp_r)
+*/
+int Xorriso_option_chgrpi(struct XorrisO *xorriso, char *gid,
+ int argc, char **argv, int *idx, int flag)
+{
+ int i, ret, was_failure= 0, end_idx, fret;
+ gid_t gid_number;
+ int optc= 0;
+ char **optv= NULL;
+ struct FindjoB *job= NULL;
+ struct stat dir_stbuf;
+
+ ret= Xorriso_opt_args(xorriso, "-chgrpi", argc, argv, *idx, &end_idx, &optc,
+ &optv, 0);
+ if(ret<=0)
+ goto ex;
+ ret= Xorriso_convert_gidstring(xorriso, gid, &gid_number, 0);
+ if(ret<=0)
+ goto ex;
+ for(i= 0; i0 && !xorriso->request_to_abort)
+ continue; /* regular bottom of loop */
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ ret= 1;
+ex:;
+ (*idx)= end_idx;
+ Xorriso_opt_args(xorriso, "-chgrpi", argc, argv, *idx, &end_idx, &optc, &optv,
+ 256); /* clean up */
+ if(ret<=0)
+ return(ret);
+ Findjob_destroy(&job, 0);
+ return(!was_failure);
+}
+
+
+/* Option -chmod alias -chmodi , -chmod_r alias chmod_ri */
+/* @param flag bit0=recursive (-chmod_r)
+*/
+int Xorriso_option_chmodi(struct XorrisO *xorriso, char *mode,
+ int argc, char **argv, int *idx, int flag)
+{
+ int i, ret, was_failure= 0, end_idx, fret;
+ mode_t mode_and= ~0, mode_or= 0;
+ int optc= 0;
+ char **optv= NULL;
+ struct FindjoB *job= NULL;
+ struct stat dir_stbuf;
+
+ ret= Xorriso_opt_args(xorriso, "-chmodi", argc, argv, *idx, &end_idx, &optc,
+ &optv, 0);
+ if(ret<=0)
+ goto ex;
+ ret= Xorriso_convert_modstring(xorriso, "-chmodi",
+ mode, &mode_and, &mode_or, 0);
+ if(ret<=0)
+ goto ex;
+ for(i= 0; i0 && !xorriso->request_to_abort)
+ continue; /* regular bottom of loop */
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ ret= 0; goto ex;
+ }
+ ret= 1;
+ex:;
+ (*idx)= end_idx;
+ Xorriso_opt_args(xorriso, "-chmodi", argc, argv, *idx, &end_idx, &optc, &optv,
+ 256);
+ Findjob_destroy(&job, 0);
+ if(ret<=0)
+ return(ret);
+ return(!was_failure);
+}
+
+
+/* Option -chown alias -chowni , chown_r alias chown_ri */
+/* @param flag bit0=recursive (-chown_r)
+*/
+int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid,
+ int argc, char **argv, int *idx, int flag)
+{
+ int i, ret, was_failure= 0, end_idx, fret;
+ uid_t uid_number;
+ int optc= 0;
+ char **optv= NULL;
+ struct FindjoB *job= NULL;
+ struct stat dir_stbuf;
+
+ ret= Xorriso_opt_args(xorriso, "-chowni", argc, argv, *idx, &end_idx,
+ &optc, &optv, 0);
+ if(ret<=0)
+ goto ex;
+ ret= Xorriso_convert_uidstring(xorriso, uid, &uid_number, 0);
+ if(ret<=0)
+ goto ex;
+ for(i= 0; i0 && !xorriso->request_to_abort)
+ continue; /* regular bottom of loop */
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ ret= 0; goto ex;
+ }
+ ret= 1;
+ex:;
+ (*idx)= end_idx;
+ Xorriso_opt_args(xorriso, "-chowni", argc, argv, *idx, &end_idx,
+ &optc, &optv, 256);
+ Findjob_destroy(&job, 0);
+ if(ret<=0)
+ return(ret);
+ return(!was_failure);
+}
+
+
+/* Option -close "on"|"off" */
+int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag)
+{
+ xorriso->do_close= !!strcmp(mode, "off");
+ return(1);
+}
+
+
+/* Option -commit */
+/* @param flag bit0= leave indrive and outdrive aquired as they were,
+ i.e. do not aquire outdrive as new in-out-drive
+ bit1= do not perform eventual -reassure
+ @return <=0 error , 1 success, 2 revoked by -reassure , 3 no change pending
+*/
+int Xorriso_option_commit(struct XorrisO *xorriso, int flag)
+{
+ int ret;
+ char newdev[SfileadrL];
+
+ if(!xorriso->volset_change_pending) {
+ sprintf(xorriso->info_text, "-commit: No image modifications pending");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ return(3);
+ }
+ if(!(flag&2)) {
+ ret= Xorriso_reassure(xorriso, "-commit",
+ "write the pending image changes to media", 0);
+ if(ret<=0)
+ return(2);
+ }
+ Xorriso_process_errfile(xorriso, 0, "burn session start", 0, 1);
+ ret= Xorriso_write_session(xorriso, 0);
+ Xorriso_process_errfile(xorriso, 0, "burn session end", 0, 1);
+ if(ret<=0)
+ return(ret);
+ Xorriso_write_session_log(xorriso, 0);
+ xorriso->volset_change_pending= 0;
+ xorriso->no_volset_present= 0;
+ if(flag&1)
+ return(1);
+ strcpy(newdev, xorriso->outdev);
+ ret= Xorriso_option_dev(xorriso, newdev, 3|4);
+ return(ret);
+}
+
+
+/* Option -commit_eject */
+/* @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_commit_eject(struct XorrisO *xorriso, char *which, int flag)
+{
+ int ret, eret;
+
+ ret= Xorriso_option_commit(xorriso, 1);
+ if(ret<=0 || ret==2 || ret==3)
+ return(ret);
+ if(strcmp(which, "none")==0)
+ eret= 1;
+ else
+ eret= Xorriso_option_eject(xorriso, which, 1);
+ ret= Xorriso_option_dev(xorriso, "", 3|4);
+ if(eretwdx, disk_path, eff_origin,
+ 2|4);
+ if(ret<=0)
+ return(ret);
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_dest, 2);
+ if(ret<=0)
+ return(ret);
+
+ if(xorriso->disk_excl_mode&8)
+ ret= Xorriso_path_is_excluded(xorriso, eff_origin, 1);
+ else
+ ret= 0;
+ if(ret!=0)
+ goto report_outcome;
+ if(!(flag&2)) {
+ Xorriso_pacifier_reset(xorriso, 0);
+ mem_lut= xorriso->last_update_time;
+ }
+ mem_pci= xorriso->pacifier_interval;
+ xorriso->pacifier_interval= 5.0;
+
+ if(flag&8) {
+ xorriso->find_compare_result= 1;
+ argv[0]= eff_dest;
+ argv[1]= "-exec";
+ argv[2]= "compare";
+ argv[3]= eff_origin;
+ zero= 0;
+ ret= Xorriso_option_find(xorriso, 4, argv, &zero, 2); /* -findi */
+ if(ret>0) {
+ argv[0]= eff_origin;
+ argv[1]= "-exec";
+ argv[2]= "not_in_iso";
+ argv[3]= eff_dest;
+ zero= 0;
+ ret= Xorriso_option_find(xorriso, 4, argv, &zero, 1|2); /* -findx */
+ if(ret>0 && !xorriso->do_follow_mount) {
+ argv[0]= eff_origin;
+ argv[1]= "-type";
+ argv[2]= "m";
+ argv[3]= "-exec";
+ argv[4]= "is_full_in_iso";
+ argv[5]= eff_dest;
+ zero= 0;
+ ret= Xorriso_option_find(xorriso, 6, argv, &zero, 1|2); /* -findx */
+ }
+ if(ret>0)
+ ret= xorriso->find_compare_result;
+ else
+ ret= -1;
+ } else
+ ret= -1;
+ } else {
+ follow_links= (xorriso->do_follow_links || xorriso->do_follow_param) << 28;
+ ret= Xorriso_compare_2_files(xorriso, eff_origin, eff_dest, "", &result,
+ 2 | follow_links | ((flag&4)<<27) | (1<<30));
+ }
+
+ xorriso->pacifier_interval= mem_pci;
+ if(mem_lut!=xorriso->last_update_time && !(flag&2))
+ Xorriso_pacifier_callback(xorriso, "content bytes read",
+ xorriso->pacifier_count, 0, "", 1);
+report_outcome:;
+ if(ret>0) {
+ sprintf(xorriso->result_line,
+ "Both file objects match as far as expectable.\n");
+ } else if(ret==0) {
+ sprintf(xorriso->result_line, "Differences detected.\n");
+ } else {
+ sprintf(xorriso->result_line, "Comparison failed due to error.\n");
+ }
+ if(flag&1)
+ Xorriso_result(xorriso,0);
+ if(ret<0)
+ return(ret);
+ return(1);
+}
+
+
+/* Option -cpr alias -cpri */
+int Xorriso_option_cpri(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy;
+ char eff_origin[SfileadrL], eff_dest[SfileadrL];
+ char dest_dir[SfileadrL], leafname[SfileadrL];
+ int optc= 0;
+ char **optv= NULL;
+
+ ret= Xorriso_cpmv_args(xorriso, "-cpri", argc, argv, idx,
+ &optc, &optv, eff_dest, 1|2);
+ if(ret<=0)
+ goto ex;
+ if(ret==2) {
+ is_dir= 1;
+ strcpy(dest_dir, eff_dest);
+ }
+
+ /* Perform graft-ins */
+ Xorriso_pacifier_reset(xorriso, 0);
+ for(i= 0; irequest_to_abort; i++) {
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, optv[i], eff_origin,
+ 2|4);
+ if(ret<=0 || xorriso->request_to_abort)
+ goto problem_handler;
+ if(is_dir) {
+ ret= Sfile_leafname(eff_origin, leafname, 0);
+ if(ret<=0)
+ goto problem_handler;
+ strcpy(eff_dest, dest_dir);
+ ret= Sfile_add_to_path(eff_dest, leafname, 0);
+ if(ret<=0) {
+ printf(xorriso->info_text, "Effective path gets much too long (%d)",
+ strlen(eff_dest)+strlen(leafname)+1);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ goto problem_handler;
+ }
+ }
+ ret= Xorriso_graft_in(xorriso, NULL, eff_origin, eff_dest,
+ (off_t) 0, (off_t) 0, 0);
+ if(ret<=0 || xorriso->request_to_abort)
+ goto problem_handler;
+ sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n",
+ (ret>1 ? "directory" : "file"), eff_dest, eff_origin);
+ if(!(flag&1))
+ Xorriso_info(xorriso, 0);
+ continue; /* regular bottom of loop */
+problem_handler:;
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
+ xorriso->pacifier_total, "", 1);
+ ret= !was_failure;
+ex:;
+ Xorriso_opt_args(xorriso, "-cpri",
+ argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256);
+ return(ret);
+}
+
+
+/* SPLIT : proposed target format
+ part_{partno}_of_{total_parts}_at_{offset}_with_{bytes}_of_{total_bytes}
+*/
+
+/* Option -cut_out */
+int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path,
+ char *start, char *count, char *iso_rr_path, int flag)
+{
+ int ret;
+ double num;
+ off_t startbyte, bytecount;
+
+ num= Scanf_io_size(start, 0);
+ if(num<0 || num > 1.0e18) { /* 10^18 = 10^3 ^ 6 < 2^10 ^ 6 = 2^60 */
+ sprintf(xorriso->info_text,
+ "-cut_out: startbyte address negative or much too large (%s)", start);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ startbyte= num;
+ num= Scanf_io_size(count, 0);
+ if(num<=0 || num > 1.0e18) {
+ sprintf(xorriso->info_text,
+ "-cut_out: bytecount zero, negative or much too large (%s)", count);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ bytecount= num;
+ sprintf(xorriso->info_text,
+ "-cut_out from %s , byte %.f to %.f, and graft as %s",
+ disk_path, (double) startbyte, (double) (startbyte+bytecount),
+ iso_rr_path);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
+
+ ret= Xorriso_cut_out(xorriso, disk_path, startbyte, bytecount,
+ iso_rr_path, 0);
+ return(ret);
+}
+
+
+/* Options -dev , -indev, -outdev */
+/** @param flag bit0= use as indev
+ bit1= use as outdev
+ bit2= do not -reassure
+ bit3= regard overwriteable media as blank
+ bit4= if the drive is a regular disk file: truncate it to
+ the write start address
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_dev(struct XorrisO *xorriso, char *in_adr, int flag)
+{
+ int ret;
+ char sfe[5*SfileadrL], *adr;
+
+ adr= in_adr;
+ if(strcmp(in_adr, "-")==0)
+ adr= "stdio:/dev/fd/1";
+ if(strncmp(adr, "stdio:", 6)==0) {
+ if(strlen(adr)==6 || strcmp(adr, "stdio:/")==0 ||
+ strcmp(adr, "stdio:.")==0 || strcmp(adr, "stdio:..")==0 ||
+ strcmp(adr, "stdio:-")==0) {
+ sprintf(xorriso->info_text,
+ "No suitable path given by device address '%s'", adr);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ if(xorriso->ban_stdio_write) {
+ sprintf(xorriso->info_text,
+ "Drive address banned by -ban_stdio_write : '%s'", adr);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ }
+
+ if(xorriso->volset_change_pending && (flag&1)) {
+ sprintf(xorriso->info_text,
+ "%s: Image changes pending. -commit or -rollback first",
+ (flag&2) ? "-dev" : "-indev");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ if((flag&1) && !(flag&4)) {
+ ret= Xorriso_reassure(xorriso, (flag&2) ? "-dev" : "-indev",
+ "eventually discard the current image", 0);
+ if(ret<=0)
+ return(2);
+ }
+
+ if(adr[0]==0) {
+ if((flag&1) && xorriso->in_drive_handle != NULL) {
+ if(xorriso->in_drive_handle == xorriso->out_drive_handle)
+ sprintf(xorriso->info_text,"Giving up -dev %s",
+ Text_shellsafe(xorriso->indev, sfe, 0));
+ else
+ sprintf(xorriso->info_text,"Giving up -indev %s",
+ Text_shellsafe(xorriso->indev, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ }
+ if((flag&2) && xorriso->in_drive_handle != NULL &&
+ xorriso->in_drive_handle != xorriso->out_drive_handle) {
+ sprintf(xorriso->info_text,"Giving up -outdev %s",
+ Text_shellsafe(xorriso->outdev, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ }
+ ret= Xorriso_give_up_drive(xorriso, flag&3);
+ } else
+ ret= Xorriso_aquire_drive(xorriso, adr, (flag&3)|((flag&(8|16))>>1));
+ if(ret<=0)
+ return(ret);
+ if(xorriso->in_drive_handle == NULL)
+ xorriso->image_start_mode= 0; /* session setting is invalid by now */
+ return(1);
+}
+
+
+/* Option -devices */
+/* @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_devices(struct XorrisO *xorriso, int flag)
+{
+ int ret;
+ char sfe[5*SfileadrL];
+
+ if(xorriso->volset_change_pending) {
+ sprintf(xorriso->info_text,
+ "-devices: Image changes pending. -commit or -rollback first");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ ret= Xorriso_reassure(xorriso, "-devices",
+ "eventually discard the current image", 0);
+ if(ret<=0)
+ return(2);
+ xorriso->info_text[0]= 0;
+ if(xorriso->in_drive_handle!=NULL || xorriso->out_drive_handle!=NULL) {
+ if(xorriso->in_drive_handle == xorriso->out_drive_handle) {
+ sprintf(xorriso->info_text, "Gave up -dev %s",
+ Text_shellsafe(xorriso->indev, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ }else {
+ if(xorriso->in_drive_handle!=NULL) {
+ sprintf(xorriso->info_text, "Gave up -indev %s",
+ Text_shellsafe(xorriso->indev, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ }
+ if(xorriso->out_drive_handle!=NULL) {
+ sprintf(xorriso->info_text, "Gave up -outdev %s",
+ Text_shellsafe(xorriso->outdev, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ }
+ }
+ Xorriso_give_up_drive(xorriso, 3);
+ }
+ ret= Xorriso_show_devices(xorriso, 0);
+ return(ret);
+}
+
+
+/* Option -dialog "on"|"off" */
+int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag)
+{
+ xorriso->dialog= !!strcmp(mode, "off");
+ return(1);
+}
+
+
+/* Option -disk_pattern "on"|"ls"|"off" */
+int Xorriso_option_disk_pattern(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode, "off")==0)
+ xorriso->do_disk_pattern= 0;
+ else if(strcmp(mode, "on")==0)
+ xorriso->do_disk_pattern= 1;
+ else if(strcmp(mode, "ls")==0)
+ xorriso->do_disk_pattern= 2;
+ else {
+ sprintf(xorriso->info_text, "-disk_pattern: unknown mode '%s'", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -dummy "on"|"off" */
+int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag)
+{
+ xorriso->do_dummy= !!strcmp(mode, "off");
+ return(1);
+}
+
+
+/* Option -eject */
+/* @param flag bit0=do not report toc of eventually remaining drives
+*/
+int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag)
+{
+ int gu_flag= 4, ret;
+
+ if(strncmp(which,"in",2)==0)
+ gu_flag|= 1;
+ else if(strncmp(which,"out",3)==0)
+ gu_flag|= 2;
+ else
+ gu_flag|= 3;
+ if((gu_flag&1) && xorriso->volset_change_pending) {
+ sprintf(xorriso->info_text,
+ "-eject: Image changes pending. -commit or -rollback first");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ if(flag&1)
+ gu_flag|= 8;
+ ret= Xorriso_give_up_drive(xorriso, gu_flag);
+ return(ret);
+}
+
+
+/* Options -end , and -rollback_end */
+/* @param flag bit0= discard pending changes
+ bit1= do not -reassure
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_end(struct XorrisO *xorriso, int flag)
+{
+ int ret;
+ char *cmd, *which_will;
+
+ if(flag&1)
+ cmd= "-rollback_end";
+ else
+ cmd= "-end";
+ if(xorriso->volset_change_pending) {
+ if(flag&1)
+ which_will= "end the program discarding image changes";
+ else
+ which_will= "commit image changes and then end the program";
+ } else {
+ which_will= "end the program";
+ }
+ if(!(flag&2)) {
+ ret= Xorriso_reassure(xorriso, cmd, which_will, 0);
+ if(ret<=0)
+ return(2);
+ }
+
+ if(xorriso->volset_change_pending) {
+ if(flag&1) {
+ xorriso->volset_change_pending= 0;
+ } else {
+ ret= Xorriso_option_commit(xorriso, 1);
+ xorriso->volset_change_pending= 0; /* no further tries to commit */
+ if(ret<=0)
+ return(ret);
+ }
+ }
+ ret= Xorriso_give_up_drive(xorriso, 3);
+ if(ret<=0)
+ return(ret);
+ return(1);
+}
+
+
+/* Option -errfile_log marked|plain path|-|"" */
+int Xorriso_option_errfile_log(struct XorrisO *xorriso,
+ char *mode, char *path, int flag)
+{
+ int ret, mode_word;
+ FILE *fp= NULL;
+ char sfe[5*SfileadrL];
+
+ if(path[0]==0 || path[0]=='-') {
+ /* ok */;
+ } else {
+ fp= fopen(path, "a");
+ if(fp==0) {
+ sprintf(xorriso->info_text, "-errfile_log: Cannot open file %s",
+ Text_shellsafe(path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ }
+ mode_word= xorriso->errfile_mode;
+ if(strcmp(mode, "marked")==0)
+ mode_word|= 1;
+ else if(strcmp(mode, "plain")==0)
+ mode_word&= ~1;
+ else {
+ sprintf(xorriso->info_text, "-errfile_log: Unknown mode %s",
+ Text_shellsafe(mode, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+
+ Xorriso_process_errfile(xorriso, 0, "log end", 0, 1);
+ if(xorriso->errfile_fp!=NULL)
+ fclose(xorriso->errfile_fp);
+ xorriso->errfile_fp= fp;
+ xorriso->errfile_mode= mode_word;
+ ret= Sfile_str(xorriso->errfile_log, path, 0);
+ if(ret>0)
+ ret= Xorriso_process_errfile(xorriso, 0, "log start", 0, 1);
+ if(ret<=0)
+ return(ret);
+ return(1);
+}
+
+
+/* Option -error_behavior */
+int Xorriso_option_error_behavior(struct XorrisO *xorriso,
+ char *occasion, char *behavior, int flag)
+{
+ if(strcmp(occasion, "image_loading")==0) {
+ if(strcmp(behavior, "best_effort")==0)
+ xorriso->img_read_error_mode= 0;
+ else if(strcmp(behavior, "failure")==0 || strcmp(behavior, "FAILURE")==0)
+ xorriso->img_read_error_mode= 1;
+ else if(strcmp(behavior, "fatal")==0 || strcmp(behavior, "FATAL")==0)
+ xorriso->img_read_error_mode= 2;
+ else {
+ sprintf(xorriso->info_text,
+ "-error_behavior: with 'image_loading': unknown behavior '%s'",
+ behavior);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ } else {
+ sprintf(xorriso->info_text, "-error_behavior: unknown occasion '%s'",
+ occasion);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -follow */
+int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag)
+{
+ int was_fl, was_fm, was_fpr, was_fpt, l;
+ double num;
+ char *cpt, *npt;
+
+ was_fpt= xorriso->do_follow_pattern;
+ was_fpr= xorriso->do_follow_param;
+ was_fl= xorriso->do_follow_links;
+ was_fm= xorriso->do_follow_mount;
+ xorriso->do_follow_pattern= 0;
+ xorriso->do_follow_param= 0;
+ xorriso->do_follow_links= 0;
+ xorriso->do_follow_mount= 0;
+ npt= cpt= mode;
+ for(cpt= mode; npt!=NULL; cpt= npt+1) {
+ npt= strchr(cpt,':');
+ if(npt==NULL)
+ l= strlen(cpt);
+ else
+ l= npt-cpt;
+ if(l==0)
+ goto unknown_mode;
+ if(strncmp(cpt, "off", l)==0) {
+ xorriso->do_follow_pattern= 0;
+ xorriso->do_follow_param= 0;
+ xorriso->do_follow_links= 0;
+ xorriso->do_follow_mount= 0;
+ } else if(strncmp(cpt, "on", l)==0) {
+ xorriso->do_follow_pattern= 1;
+ xorriso->do_follow_param= 1;
+ xorriso->do_follow_links= 1;
+ xorriso->do_follow_mount= 1;
+ } else if(strncmp(cpt, "default", l)==0) {
+ xorriso->do_follow_pattern= 1;
+ xorriso->do_follow_param= 0;
+ xorriso->do_follow_links= 0;
+ xorriso->do_follow_mount= 1;
+ xorriso->follow_link_limit= 100;
+ } else if(strncmp(cpt, "link", l)==0 || strncmp(cpt,"links", l)==0) {
+ xorriso->do_follow_links= 1;
+ } else if(strncmp(cpt, "mount", l)==0) {
+ xorriso->do_follow_mount= 1;
+ } else if(strncmp(cpt,"param", l)==0) {
+ xorriso->do_follow_param= 1;
+ } else if(strncmp(cpt, "pattern", l)==0) {
+ xorriso->do_follow_pattern= 1;
+ } else if(strncmp(cpt, "limit=", 6)==0) {
+ sscanf(cpt+6, "%lf", &num);
+ if(num<=0 || num>1.0e6) {
+ sprintf(xorriso->info_text, "-follow: Value too %s with '%s'",
+ num<=0 ? "small" : "large", cpt+6);
+ goto sorry_ex;
+ }
+ xorriso->follow_link_limit= num;
+ } else {
+unknown_mode:;
+ if(linfo_text, "-follow: unknown mode '%s'", cpt);
+ else
+ sprintf(xorriso->info_text, "-follow: oversized mode parameter (%d)",l);
+sorry_ex:
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ xorriso->do_follow_pattern= was_fpt;
+ xorriso->do_follow_param= was_fpr;
+ xorriso->do_follow_links= was_fl;
+ xorriso->do_follow_mount= was_fm;
+ return(0);
+ }
+ }
+ return(1);
+}
+
+
+/* Option -find alias -findi, and -findx */
+/* @param flag bit0= -findx rather than -findi
+ bit1= do not reset pacifier, no final pacifier message
+ do not reset find_compare_result
+ bit2= do not count deleted files with rm and rm_r
+*/
+int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int ret, i, end_idx, type= 0, action, deleter= 0;
+ struct FindjoB *job, *first_job= NULL, *new_job;
+ char *start_path, sfe[5*SfileadrL], *cpt, other_path_start[SfileadrL];
+ struct stat dir_stbuf;
+ uid_t user= 0;
+ gid_t group= 0;
+ time_t date= 0;
+ mode_t mode_or= 0, mode_and= ~1;
+ double mem_lut= 0.0;
+
+ end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1);
+ start_path= ".";
+ if(end_idx > *idx && start_path[0]!=0)
+ start_path= argv[*idx];
+ ret= Findjob_new(&first_job, start_path, 0);
+ if(ret<=0) {
+ Xorriso_no_findjob(xorriso, "-find[ix]", 0);
+ {ret= -1; goto ex;}
+ }
+ job= first_job;
+ if(!(flag&2))
+ xorriso->find_compare_result= 1;
+ for(i= *idx+1; i=end_idx) {
+not_enough_arguments:;
+ sprintf(xorriso->info_text,
+ "-find[ix]: not enough arguments with -exec %s",
+ Text_shellsafe(argv[i], sfe, 0));
+ goto sorry_ex;
+ }
+ i++;
+ ret= Findjob_set_name_expr(job, argv[i], 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text, "-find[ix]: cannot set -name expression %s",
+ Text_shellsafe(argv[i], sfe, 0));
+ goto sorry_ex;
+ }
+ } else if(strcmp(argv[i], "-exec")==0) {
+ if(i+1>=end_idx)
+ goto not_enough_arguments;
+ i++;
+ cpt= argv[i];
+ if(*cpt=='-')
+ cpt++;
+ if(strcmp(cpt, "echo")==0) {
+ Findjob_set_action_target(job, 0, NULL, 0);
+ } else if(strcmp(cpt, "rm")==0) {
+ Findjob_set_action_target(job, 1, NULL, 0);
+ deleter= 1;
+ } else if(strcmp(cpt, "rm_r")==0) {
+ Findjob_set_action_target(job, 2, NULL, 0);
+ deleter= 1;
+
+#ifdef NIX
+/* >>> not implemented yet */;
+ } else if(strcmp(cpt, "mv")==0) {
+ if(i+1>=end_idx)
+ goto not_enough_arguments;
+ i++;
+ Findjob_set_action_target(job, 3, argv[i], 0);
+#endif
+
+ } else if(strcmp(cpt, "chown")==0 || strcmp(cpt, "chown_r")==0) {
+ if(i+1>=end_idx)
+ goto not_enough_arguments;
+ i++;
+ ret= Xorriso_convert_uidstring(xorriso, argv[i], &user, 0);
+ if(ret<=0)
+ goto ex;
+ ret= Findjob_set_action_chown(job, user, strlen(cpt)>5);
+ if(ret<=0) {
+ Xorriso_no_findjob(xorriso, "-find -exec chown_r", 0);
+ goto ex;
+ }
+ } else if(strcmp(cpt, "chgrp")==0 || strcmp(cpt, "chgrp_r")==0) {
+ if(i+1>=end_idx)
+ goto not_enough_arguments;
+ i++;
+ ret= Xorriso_convert_gidstring(xorriso, argv[i], &group, 0);
+ if(ret<=0)
+ goto ex;
+ ret= Findjob_set_action_chgrp(job, group, strlen(cpt)>5);
+ if(ret<=0) {
+ Xorriso_no_findjob(xorriso, "-find -exec chgrp_r", 0);
+ goto ex;
+ }
+ } else if(strcmp(cpt, "chmod")==0 || strcmp(cpt, "chmod_r")==0) {
+ if(i+1>=end_idx)
+ goto not_enough_arguments;
+ i++;
+ ret= Xorriso_convert_modstring(xorriso, "-find -exec chmod",
+ argv[i], &mode_and, &mode_or, 0);
+ if(ret<=0)
+ goto ex;
+ ret= Findjob_set_action_chmod(job, mode_and, mode_or, strlen(cpt)>5);
+ if(ret<=0) {
+ Xorriso_no_findjob(xorriso, "-find -exec chmod_r", 0);
+ goto ex;
+ }
+ } else if(strcmp(cpt, "alter_date")==0 || strcmp(cpt, "alter_date_r")==0){
+ if(i+2>=end_idx)
+ goto not_enough_arguments;
+ i+= 2;
+ ret= Xorriso_convert_datestring(xorriso, "-find -exec alter_date",
+ argv[i-1], argv[i], &type, &date, 0);
+ if(ret<=0)
+ goto ex;
+ ret= Findjob_set_action_ad(job, type, date, strlen(cpt)>10);
+ if(ret<=0) {
+ Xorriso_no_findjob(xorriso, "-find -exec alter_date_r", 0);
+ goto ex;
+ }
+ } else if(strcmp(cpt, "lsdl")==0) {
+ Findjob_set_action_target(job, 8, NULL, 0);
+
+ } else if(strcmp(cpt, "find")==0) {
+ ret= Findjob_new(&new_job, "", 0);
+ if(ret<=0) {
+ Xorriso_no_findjob(xorriso, "-find[ix]", 0);
+ {ret= -1; goto ex;}
+ }
+ Findjob_set_action_subjob(job, 13, new_job, 0);
+ job= new_job;
+
+ } else if(strcmp(cpt, "compare")==0 || strcmp(cpt, "update")==0) {
+ if(i+1>=end_idx)
+ goto not_enough_arguments;
+ i++;
+ action= 14;
+ if(strcmp(cpt, "update")==0)
+ action= 17;
+ ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, argv[i],
+ other_path_start, 1|2|4|8);
+ if(ret<=0)
+ goto ex;
+ Findjob_set_action_target(job, action, other_path_start, 0);
+ ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, start_path,sfe, 1|2|4);
+ if(ret<=0)
+ goto ex;
+ Findjob_set_start_path(job, sfe, 0);
+ if(!(flag&2)) {
+ Xorriso_pacifier_reset(xorriso, 0);
+ mem_lut= xorriso->last_update_time;
+ }
+ } else if(strcmp(cpt, "in_iso")==0 ||
+ strcmp(cpt, "not_in_iso")==0 ||
+ strcmp(cpt, "add_missing")==0 ||
+ strcmp(cpt, "empty_iso_dir")==0 ||
+ strcmp(cpt, "is_full_in_iso")==0) {
+ if(i+1>=end_idx)
+ goto not_enough_arguments;
+ i++;
+ ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, argv[i],
+ other_path_start, 1|2|4);
+ if(ret<=0)
+ goto ex;
+ if(strcmp(cpt, "in_iso")==0)
+ action= 15;
+ else if(strcmp(cpt, "add_missing")==0)
+ action= 18;
+ else if(strcmp(cpt, "empty_iso_dir")==0)
+ action= 19;
+ else if(strcmp(cpt, "is_full_in_iso")==0)
+ action= 20;
+ else
+ action= 16;
+ Findjob_set_action_target(job, action, other_path_start, 0);
+ ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, start_path, sfe,
+ 1|2|4|8);
+ if(ret<=0)
+ goto ex;
+ Findjob_set_start_path(job, sfe, 0);
+
+ } else {
+ sprintf(xorriso->info_text, "-find -exec: unknown action %s",
+ Text_shellsafe(argv[i], sfe, 0));
+ goto sorry_ex;
+ }
+ } else if(strcmp(argv[i], "-type")==0) {
+ if(i+1>=end_idx)
+ goto not_enough_arguments;
+ i++;
+ ret= Findjob_set_file_type(job, argv[i][0], 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text, "-find[ix]: unknown -type '%c'",argv[i][0]);
+ goto sorry_ex;
+ }
+ } else {
+ sprintf(xorriso->info_text, "-find[ix]: unknown option %s",
+ Text_shellsafe(argv[i], sfe, 0));
+sorry_ex:;
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ {ret= 0; goto ex;}
+ }
+ }
+ if(flag&1)
+ ret= Xorriso_findx(xorriso, first_job, "", start_path, &dir_stbuf, 0, NULL,
+ 0);
+ else
+ ret= Xorriso_findi(xorriso, first_job, NULL, (off_t) 0, NULL,
+ start_path, &dir_stbuf, 0, (flag&4)>>1);
+ex:;
+ if(deleter && !(flag&2))
+ Xorriso_pacifier_callback(xorriso, "iso_rr_paths deleted",
+ xorriso->pacifier_count, 0, "", 1|2);
+ else if(mem_lut!=xorriso->last_update_time && mem_lut!=0.0 && !(flag&2))
+ Xorriso_pacifier_callback(xorriso, "content bytes read",
+ xorriso->pacifier_count, 0, "", 1);
+ Findjob_destroy(&first_job, 0);
+ (*idx)= end_idx;
+ return(ret);
+}
+
+
+/* Option -fs */
+int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag)
+{
+ double num;
+
+ num= Scanf_io_size(size, 0);
+ if(num < 64*1024 || num > 1024.0 * 1024.0 * 1024.0) {
+ sprintf(xorriso->info_text, "-fs: wrong size %.f (allowed: %.f - %.f)",
+ num, 64.0 * 1024.0, 1024.0 * 1024.0 * 1024.0);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ xorriso->fs= num / 2048.0;
+ if(xorriso->fs * 2048 < num)
+ xorriso->fs++;
+ return(1);
+}
+
+
+/* Option -gid */
+int Xorriso_option_gid(struct XorrisO *xorriso, char *gid, int flag)
+{
+ int ret;
+
+ xorriso->do_global_gid= 0;
+ if(gid[0]==0 || strcmp(gid,"-")==0)
+ return(1);
+ ret= Xorriso_convert_gidstring(xorriso, gid, &(xorriso->global_gid), 0);
+ if(ret>0)
+ xorriso->do_global_gid= 1;
+ return(ret);
+}
+
+
+/* Option -help and part of -prog_help */
+int Xorriso_option_help(struct XorrisO *xorriso, int flag)
+{
+ static char text[][80]={
+
+#ifdef Xorriso_no_helP
+
+"This binary program does not contain a help text.",
+"If available, read: man 1 xorriso",
+
+#else
+
+"This program creates, loads, manipulates and writes ISO 9660 filesystem",
+"images with Rock Ridge extensions. Write targets can be drives with optical",
+"media or local filesystem objects.",
+"",
+"Preparation options:",
+"Drive addresses are either /dev/... as listed with option -devices or",
+"disk files with prefix \"stdio:\", e.g. stdio:/tmp/pseudo_drive .",
+" -dev address Set input and output drive and load eventual ISO image.",
+" Set the image expansion method to growing.",
+" -indev address Set input drive and load eventual ISO image. Switch from",
+" growing to modifying.",
+" -outdev address",
+" Set output drive and switch from growing to modifying.",
+" -load \"session\"|\"track\"|\"lba\"|\"sbsector\"|\"volid\"|\"auto\" id",
+" Load a particular (outdated) ISO image from a -dev or",
+" -indev which hosts more than one session.",
+" -rom_toc_scan \"on\"|\"off\"",
+" Enable scanning for ISO sessions on read-only drives/media.",
+" -ban_stdio_write",
+" Allow for writing only the usage of optical drives.",
+" -blank \"fast\"|\"all\"|\"deformat\"|\"deformat_quickest\"",
+" Blank media resp. invalidate ISO image on media.",
+" -format \"as_needed\"|\"full\"|\"fast\"|\"by_index_#\"|\"fast_by_index_#\"",
+" Format BD-RE, DVD-RAM, DVD-RW, DVD+RW.",
+" -volid volume_id",
+" Specifies the volume ID text. (32 chars out of [A-Z0-9_])",
+" -publisher name",
+" Specifies the publisher name. (128 chars)",
+" -joliet \"on\"|\"off\"",
+" Generate Joliet info additional to Rock Ridge info.",
+" -bootimage \"any\"|\"isolinux\" \"discard\"|\"keep\"|\"patch\"",
+" Whether to discard or keep an exiting El-Torito boot image.",
+"",
+" -uid uid User id to be used for the whole multi-session ISO image.",
+" -gid gid Group id for the same purpose.",
+"",
+" -devices Show list of available optical drives and their addresses.",
+"",
+" -toc Show media specific table of content (sessions).",
+"",
+" -list_formats Show media specific list of format descriptors.",
+"",
+" -print_size Print the foreseeable consumption by next -commit.",
+"",
+" -tell_media_space",
+" Print foreseeable available space on output media",
+"",
+"Manipulation options:",
+"disk_path is a path to an object in the local filesystem tree.",
+"iso_rr_path is the Rock Ridge name of a file object in the ISO image.",
+"pathspec is either a disk_path or (if allowed) a pair: iso_rr_path=disk_path",
+"Options with variable length path list [...] need \"--\" as end mark",
+"if they are followed by another option. In dialog and with options read from",
+"files, the line end serves as such a mark. With program arguments this mark",
+"can be omitted only with the last option in the list of arguments.",
+"Options marked by [***] have variable argument length and perform pattern",
+"expansion if enabled by -iso_rr_pattern resp. -disk_pattern.",
+"",
+" -pathspecs \"on\"|\"off\" Allow or disallow pathspecs of form ",
+" iso_rr_path=disk_path . Only \"off\" allows eventual",
+" -disk_pattern expansion.",
+" -add pathspec [...] | disk_path [***]",
+" Insert the given files or directory trees from",
+" filesystem into the ISO image. Much like mkisofs.",
+" -add_plainly \"none\"|\"unknown\"|\"dashed\"|\"any\"",
+" Whether to add lonely arguments as pathspec resp. disk_path.",
+" -path_list disk_path",
+" Like -add but read the pathspecs from file disk_path.",
+"",
+" -map disk_path iso_rr_path",
+" Insert disk file object at the given iso_rr_path.",
+" -map_single disk_path iso_rr_path",
+" Like -map but with directory do not insert its sub tree.",
+" -update disk_path iso_rr_path",
+" Compare both file objects and do what is necessary to make",
+" iso_rr_path a matching copy of disk_path.",
+" -update_r disk_path iso_rr_path",
+" Like -update but affecting all files below directories.",
+" -cut_out disk_path byte_offset byte_count iso_rr_path",
+" Map a byte interval of a regular disk file into a regular",
+" file in the ISO image.",
+"",
+" -cpr disk_path [***] iso_rr_path",
+" Insert the given files or directory trees from filesystem",
+" into the ISO image, according to the rules of cp -r.",
+"",
+" -rm iso_rr_path [***]",
+" Delete the given files from the ISO image.",
+" -rm_r iso_rr_path [***]",
+" Delete the given directory trees from ISO image.",
+" -mv iso_rr_path [***] iso_rr_path",
+" Rename the given file objects in the ISO tree to the last",
+" argument in the list.",
+" -chown uid iso_rr_path [***]",
+" Equivalent to chown in the ISO image.",
+" -chown_r uid iso_rr_path [***]",
+" Like -chown but affecting all files below directories.",
+" -chgrp gid iso_rr_path [***]",
+" Equivalent to chgrp in the ISO image.",
+" -chgrp_r gid iso_rr_path [***]",
+" Like -chgrp but affecting all files below directories.",
+" -chmod mode iso_rr_path [***]",
+" Equivalent to chmod in the ISO image.",
+" -chmod_r mode iso_rr_path [***]",
+" Like -chmod but affecting all files below directories.",
+" -alter_date type timestring iso_rr_path [***]",
+" Alter the date entries of a file in the ISO image. type is",
+" one of \"a\", \"m\", \"b\" for:",
+" access time, modification time, both times.",
+" -alter_date_r type timestring iso_rr_path [***]",
+" Like -alter_date but affecting all files below directories.",
+" -find iso_rr_path [-name pattern] [-type t] [-exec action [params]]",
+" performs an action on files below the current working",
+" directory in the ISO image. If -name pattern is given",
+" then only files with matching leaf names are processed.",
+" If -type is given then only files with matching type are",
+" processed. Types: block,char,dir,pipe,file,link,socket.",
+" action may be one of: echo, chown, chown_r, chgrp, chgrp_r",
+" chmod, chmod_r, alter_date, alter_date_r, lsdl, compare,",
+" rm, rm_r, compare, update, find.",
+" params are their arguments except iso_rr_path.",
+" I.e. echo, lsdl, rm, rm_r have no params at all.",
+" -mkdir iso_rr_path [...]",
+" Create empty directories if they do not exist yet.",
+" -rmdir iso_rr_path [***]",
+" Delete empty directories.",
+" -- Mark end of particular action argument list.",
+"",
+" -not_paths disk_path [***]",
+" Add the given paths to the list of excluded absolute paths.",
+" -not_leaf pattern",
+" Add the given pattern to the list of leafname exclusions.",
+" -not_list disk_path",
+" Read lines from disk_path and use as -not_paths (with \"/\")",
+" or as -not_leaf (without \"/\").",
+" -not_mgt \"reset\"|\"on\"|\"off\"|\"param_on\"|\"subtree_on\"|\"ignore_on\"",
+" Control effect of exclusion lists.",
+" -follow \"on\"|\"pattern:param:link:mount:limit=#\"|\"default\"|\"off\"",
+" Follow symbolic links and mount points within disk_path.",
+" -overwrite \"on\"|\"nondir\"|\"off\"",
+" Allow or disallow to overwrite existing files in ISO image.",
+" -split_size number[\"k\"|\"m\"]",
+" Set the threshold for automatic splitting of regular files.",
+" -reassure \"on\"|\"tree\"|\"off\"",
+" If \"on\" then ask the user for \"y\" or \"n\" with any",
+" file before deleting or overwriting it in the ISO image.",
+"",
+"Write-to-media options:",
+"",
+" -rollback Discard the manipulated ISO image and reload it.",
+"",
+" -commit Perform the write operation and then perform -dev outdrive.",
+" Hint: To perform a final write operation with no new -dev",
+" and no new loading of image, execute option -end.",
+" -commit_eject \"in\"|\"out\"|\"all\"|\"none\"",
+" Like -commit but rather eject than load image from outdrive.",
+" Give up any unejected drive afterwards.",
+" -close \"on\"|\"off\"",
+" If \"on\" then mark the written media as not appendable.",
+" -padding number[\"k\"|\"m\"]",
+" Append extra bytes to image stream. (Default is 300k)",
+" -dummy \"on\"|\"off\"",
+" If \"on\" simulate burning. Refuse if media cannot simulate.",
+" -speed number[\"k\"|\"m\"|\"[x]CD\"|\"[x]DVD\"]",
+" Set the burn speed. Default is 0 = maximum speed.",
+" -fs number[\"k\"|\"m\"]",
+" Set the size of the fifo buffer. (Default is 4m)",
+" -eject \"in\"|\"out\"|\"all\"",
+" Immediately eject the media in -indev, resp. -outdev,",
+" resp. both.",
+"",
+"Navigation options:",
+"",
+" -cd iso_rr_path Change working directory in the ISO image. iso_rr_paths",
+" which do not begin with '/' will be inserted beginning at",
+" the path given with -cd. -ls patterns will eventually",
+" looked up at this path.",
+" -cdi disk_path Same as -cd disk_path",
+" -cdx disk_path Change the current working directory in the local",
+" filesystem. disk_paths which do not begin with '/'",
+" will be looked up beginning at the path given with -cdx.",
+" -lsx patterns will eventually be looked up at this path.",
+" -pwd tells the current working directory in the ISO image.",
+" -pwdi same as -pwd.",
+" -pwdx tells the current working directory in the local filesystem.",
+"",
+" -iso_rr_pattern \"on\"|\"ls\"|\"off\"",
+" Enable or disable pattern expansions for ISO image commands",
+" marked by [***]. \"ls\" restricts it to -ls and -du.",
+" -disk_pattern \"on\"|\"ls\"|\"off\"",
+" Enable or disable pattern expansions for local filesystem",
+" commands marked by [***]. \"ls\" restricts to -ls*x and -du*x.",
+"",
+" -ls pattern [***] lists files of the ISO image which match one of the",
+" given shell parser patterns. (I.e. wildcards '*' '?').",
+" Directories are listed by their content.",
+" -lsd pattern [***] like -ls but listing directories as single items.",
+" -lsl pattern [***] like -ls but also telling some file attributes.",
+" -lsdl pattern [***] like -lsd but also telling some file attributes.",
+"",
+" -lsx pattern [***] lists files of the local filesystem which match one",
+" of the patterns. Directories are listed by their content.",
+" -lsdx pattern [***] like -lsx but listing directories as single items.",
+" -lslx pattern [***] like -lsx but also telling some file attributes.",
+" -lsdlx pattern [***] like -lsdx but also telling some file attributes.",
+"",
+" -du pattern [***] recursively lists sizes of files or directories in the",
+" ISO image which match one of the shell parser patterns.",
+" -dux pattern [***] recursively lists sizes of files or directories in the",
+" local filesystem which match one of the shell parser",
+" patterns.",
+" -dus pattern [***] like -du but summing up subdirectories without",
+" listing them explicitely.",
+" -dusx pattern [***] like -dux but summing up subdirectories without",
+" listing them explicitely.",
+"",
+" -findx disk_path [-name pattern] [-type t] [-exec action [params]]",
+" Like -find but operating on local filesystem. Most -exec",
+" actions are defaulted to action is always echo. Supported",
+" actions are: in_iso, not_in_iso, is_full_in_iso,",
+" add_missing, empty_iso_dir.",
+"",
+" -compare disk_path iso_rr_path",
+" compare attributes and in case of regular data files the",
+" content of filesystem object and ISO object.",
+" -compare_r disk_path iso_rr_path ",
+" Like -compare but affecting all files below directories.",
+"",
+"Compatibility emulation (argument list may be ended by --):",
+" -as mkisofs [-help|-o|-R|-J|-V|-P|-f|-graft-points|-path-list|pathspecs]",
+" Perform some mkisofs gestures, understand pathspecs as mkisofs",
+" does. Commit happens outside emulation at usual occasions.",
+" -as cdrecord [-help|-v|dev=|speed=|blank=|fs=|-eject|-atip|padsize=|path|-]",
+" Perform some cdrecord gestures, eventually write at most one",
+" data track to blank or overwriteable media.",
+"",
+"General options:",
+" -help Print this text",
+" -abort_on severity Set the threshhold for events to abort the program.",
+" Useful severities: NEVER, ABORT, FATAL, FAILURE, SORRY, WARNING",
+" -return_with severity exit_value Set the threshhold for events to return",
+" at program end the given exit_value even if not aborted.",
+" exit_value may be 0 or 32 to 63.",
+" -report_about severity Set the threshhold for events to be reported.",
+" Use -abort_on severities or: HINT, NOTE, UPDATE, DEBUG, ALL",
+" -dialog After all arguments are processed, enter dialog mode.",
+" In this mode you may enter searchtexts or any of the options",
+" described here. One per line.",
+" -dialog_reset Revoke -dialog (works only if given as argument)",
+" -page len width Prompt user after len output lines (0=no prompt).",
+" width (default 80) can adjust line number computation",
+" to the output terminal's line width.",
+#ifdef Xorriso_with_readlinE
+" -use_stdin Use raw standard input even if libreadline is available",
+" -use_readline Use libreadline for dialog if available",
+" -history text Copy text into libreadline history. This command",
+" itself is not copied to the history list.",
+#endif /* Xorriso_with_readlinE */
+" -pkt_output \"on\"|\"off\" Direct output to stdout and prefix each line",
+" by a short header which tells channel id and a mode number.",
+" Each such output packet is finalized by a newline.",
+" Channel ids are 'R:' for result lines, 'I:' for notes",
+" and error messages, 'M:' for -mark texts. Bit 0 of the",
+" mode number tells whether the newline is also part of the",
+" packet payload. Example of a info message with newline:",
+" I:1: enter option text :",
+" -pkt_output:on is intended for use by frontend programs.",
+" -logfile channel fileaddress Copy output of a channel to the given file.",
+" channel may be 'R','I','M' as with -pkt_output or '.'",
+" for the consolidated -pkt_output stream.",
+" -mark text If text is not empty it will get put out each time an",
+" option is completed.",
+" -temp_mem_limit number[\"k\"|\"m\"]",
+" Set the maximum size for pattern expansion. (Default is 16m)",
+" -prog text Use text as this program's name in subsequent messages",
+" -prog_help text Use text as this program's name and perform -help",
+" -status mode|filter Report the current settings of persistent options.",
+" Modes:",
+" short... print only important or altered options",
+" long ... print options even if they have default settings",
+" long_history like long plus -history: lines",
+" Filters begin with '-' and are compared literally against the",
+" output lines of -status long_history. A line is put out only",
+" if its start matches the filter.",
+" -status_history_max number Maximum number of history lines to be reported",
+" with -status:long_history",
+" -options_from_file fileaddress",
+" Reads lines from the given file and executes them as program",
+" options.",
+" -no_rc Only if used as first command line argument this option",
+" prevents reading and interpretation of startup files.",
+" -print text",
+" Print a text to result channel.",
+" -prompt text",
+" Wait for Enter key resp. for a line of input at stdin.",
+" -errfile_log mode path|channel",
+" Log disk paths of files involved in problem events.",
+" -session_log path",
+" Set path of a file where a log record gets appended after",
+" each session. Form: timestamp start_lba size volume-id",
+" # any text Is ignored. In dialog mode the input line will be stored in",
+" the eventual readline history, nevertheless.",
+" -version Tell program and version number",
+" -end End program. Commit eventual pending changes.",
+" -rollback_end",
+" End program. Discard pending changes.",
+"",
+"",
+"Option -page causes a user prompt after the given number of result lines.",
+"Empty input resumes output until the next prompt. Other input may be:",
+" @ suppresses paging until the current action is done",
+" @@ suppresses further result output but continues the action",
+" @@@ aborts the current action",
+" other aborts the current action and executes input as new",
+" option",
+"",
+
+#endif /* ! Xorriso_no_helP */
+
+"@ENDE_OF_HELPTEXT_(HOPEFULLY_UNIQUELY_SILLY_TEXT)@"
+ };
+
+ char *tpt= NULL;
+ int i,pass;
+
+ Xorriso_restxt(xorriso,"\n");
+ sprintf(xorriso->result_line,"usage: %s [settings|actions]\n",
+ xorriso->progname);
+ Xorriso_result(xorriso,0);
+ Xorriso_restxt(xorriso,"\n");
+ for(pass=0;pass<1;pass++) {
+ for(i=0;1;i++) {
+ if(pass==0)
+ tpt= text[i];
+
+ if(strcmp(tpt,"@ENDE_OF_HELPTEXT_(HOPEFULLY_UNIQUELY_SILLY_TEXT)@")==0)
+ break;
+ sprintf(xorriso->result_line,"%s\n",tpt);
+ Xorriso_result(xorriso,0);
+ if(xorriso->request_to_abort)
+ return(1);
+ }
+ }
+ Xorriso_restxt(xorriso,"\n");
+ return(1);
+}
+
+
+/* Option -history */
+int Xorriso_option_history(struct XorrisO *xorriso, char *line, int flag)
+{
+ Xorriso_dialog_input(xorriso,line,strlen(line)+1,2);
+ return(1);
+}
+
+
+/* Option -iso_rr_pattern "on"|"ls"|"off" */
+int Xorriso_option_iso_rr_pattern(struct XorrisO *xorriso, char *mode,int flag)
+{
+ if(strcmp(mode, "off")==0)
+ xorriso->do_iso_rr_pattern= 0;
+ else if(strcmp(mode, "on")==0)
+ xorriso->do_iso_rr_pattern= 1;
+ else if(strcmp(mode, "ls")==0)
+ xorriso->do_iso_rr_pattern= 2;
+ else {
+ sprintf(xorriso->info_text, "-iso_rr_pattern: unknown mode '%s'", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -joliet "on"|"off" */
+int Xorriso_option_joliet(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode, "off")==0)
+ xorriso->do_joliet= 0;
+ else if(strcmp(mode, "on")==0)
+ xorriso->do_joliet= 1;
+ else {
+ sprintf(xorriso->info_text, "-joliet: unknown mode '%s'", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -list_formats */
+int Xorriso_option_list_formats(struct XorrisO *xorriso, int flag)
+{
+ int ret;
+
+ ret= Xorriso_list_formats(xorriso, 0);
+ return(ret);
+}
+
+
+/* Option -load session|track|sbsector value */
+/* @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_load(struct XorrisO *xorriso, char *adr_mode,
+ char *adr_value, int flag)
+{
+ double num;
+ int ret, l;
+
+ if(xorriso->volset_change_pending) {
+ sprintf(xorriso->info_text,
+ "-load: Image changes pending. -commit or -rollback first");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ ret= Xorriso_reassure(xorriso, "-load", "loads an alternative image", 0);
+ if(ret<=0)
+ return(2);
+ if(strcmp(adr_mode, "auto")==0)
+ xorriso->image_start_mode= 0;
+ else if(strcmp(adr_mode, "session")==0)
+ xorriso->image_start_mode= 1;
+ else if(strcmp(adr_mode, "track")==0)
+ xorriso->image_start_mode= 2;
+ else if(strcmp(adr_mode, "lba")==0 || strcmp(adr_mode, "sbsector")==0)
+ xorriso->image_start_mode= 3;
+ else if(strcmp(adr_mode, "volid")==0)
+ xorriso->image_start_mode= 4;
+ else {
+ sprintf(xorriso->info_text, "-load: unknown address mode '%s'", adr_mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ l= strlen(adr_value);
+ if(l==0)
+ xorriso->image_start_mode= 0;
+
+ if(xorriso->image_start_mode>=1 && xorriso->image_start_mode<= 3) {
+ num= Scanf_io_size(adr_value, 0);
+ if(xorriso->image_start_mode==3 &&
+ (adr_value[l-1]<'0' || adr_value[l-1]>'9'))
+ num/= 2048.0;
+ sprintf(xorriso->image_start_value, "%.f", num);
+ } else {
+ if(strlen(adr_value)>80) {
+ sprintf(xorriso->info_text, "-load: address value too long (80 < %d)",
+ (int) strlen(adr_value));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ strcpy(xorriso->image_start_value, adr_value);
+ }
+ xorriso->image_start_mode|= (1<<30); /* enable non-default msc1 processing */
+ if(strlen(xorriso->indev)>0) {
+ ret= Xorriso_option_rollback(xorriso, 1); /* Load image, no -reassure */
+ if(ret<=0)
+ return(ret);
+ }
+ return(1);
+}
+
+
+/* Option -logfile */
+int Xorriso_option_logfile(struct XorrisO *xorriso, char *channel,
+ char *fileadr, int flag)
+{
+ int hflag,channel_no= 0, ret;
+
+ if(channel[0]==0) {
+logfile_wrong_form:;
+ sprintf(xorriso->info_text,"Wrong form. Correct would be: -logfile \".\"|\"R\"|\"I\"|\"M\" file_address");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ hflag= 2;
+ if(channel[0]=='R')
+ channel_no= 1;
+ else if(channel[0]=='I')
+ channel_no= 2;
+ else if(channel[0]=='M')
+ channel_no= 3;
+ else if(channel[0]=='.')
+ hflag= 4;
+ else
+ goto logfile_wrong_form;
+ if(strcmp(fileadr,"-")==0 || fileadr[0]==0)
+ hflag|= (1<<15);
+ xorriso->logfile[channel_no][0]= 0;
+ ret= Write_to_channel(fileadr,channel_no,hflag);
+ if(ret<=0) {
+ sprintf(xorriso->info_text, "Cannot open logfile: %s", fileadr);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ } else if(!(hflag&(1<<15)))
+ if(Sfile_str(xorriso->logfile[channel_no], fileadr, 0)<=0)
+ return(-1);
+ return(ret>0);
+}
+
+
+/* Options -ls alias -lsi and -lsl alias -lsli
+ and -lsd alias -lsdi and -lsdl alias -lsdli
+ and -du alias -dui and -dus alias -dusi
+ @param flag bit0= long format (-lsl , -du)
+ bit1= do not expand patterns but use literally
+ bit2= du rather than ls
+ bit3= list directories as themselves (ls -d)
+*/
+int Xorriso_option_lsi(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int ret, end_idx, filec= 0, nump, i;
+ char **filev= NULL, **patterns= NULL;
+ off_t mem= 0;
+ struct stat stbuf;
+
+ end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1);
+ if(xorriso->do_iso_rr_pattern==0)
+ flag|= 2;
+
+ nump= end_idx - *idx;
+ if((flag&2) && nump>0 ) {
+ ;
+ } else if(nump <= 0) {
+ if(Xorriso_iso_lstat(xorriso, xorriso->wdi, &stbuf, 0)<0) {
+ sprintf(xorriso->info_text,
+ "Current -cd path does not yet exist in the ISO image");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ {ret= 0; goto ex;}
+ }
+ if(!S_ISDIR(stbuf.st_mode)) {
+ sprintf(xorriso->info_text,
+ "Current -cd meanwhile points to a non-directory in ISO image");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ {ret= 0; goto ex;}
+ }
+ patterns= calloc(1, sizeof(char *));
+ if(patterns == NULL) {
+no_memory:;
+ sprintf(xorriso->info_text,
+ "Cannot allocate enough memory for pattern expansion");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ {ret= -1; goto ex;}
+ }
+ nump= 1;
+ if(flag&8)
+ patterns[0]= ".";
+ else
+ patterns[0]= "*";
+ flag&= ~2;
+ } else {
+ patterns= calloc(nump, sizeof(char *));
+ if(patterns==NULL)
+ goto no_memory;
+ for(i= 0; iwdi, nump, argv + (*idx), mem,
+ flag&(1|4|8));
+ } else if(nump==1 && strcmp(patterns[0],"*")==0 && !(flag&4)){
+ /* save temporary memory by calling simpler function */
+ ret= Xorriso_ls(xorriso, (flag&1)|4);
+ } else {
+ ret= Xorriso_expand_pattern(xorriso, nump, patterns, 0, &filec, &filev,
+ &mem, 0);
+ if(ret<=0)
+ {ret= 0; goto ex;}
+ ret= Xorriso_ls_filev(xorriso, xorriso->wdi, filec, filev, mem,
+ flag&(1|4|8));
+ }
+ if(ret<=0)
+ {ret= 0; goto ex;}
+
+ ret= 1;
+ex:;
+ if(patterns!=NULL)
+ free((char *) patterns);
+ Sfile_destroy_argv(&filec, &filev, 0);
+ (*idx)= end_idx;
+ return(ret);
+}
+
+
+/* Options -lsx, -lslx, -lsdx , -lsdlx , -dux , -dusx
+ @param flag bit0= long format (-lslx , -dux)
+ bit1= do not expand patterns but use literally
+ bit2= du rather than ls
+ bit3= list directories as themselves (ls -d)
+*/
+int Xorriso_option_lsx(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int ret, end_idx, filec= 0, nump, i;
+ char **filev= NULL, **patterns= NULL;
+ off_t mem= 0;
+
+ end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1|2);
+ if(xorriso->do_disk_pattern==0)
+ flag|= 2;
+
+ nump= end_idx - *idx;
+ if((flag&2) && nump>0) {
+ ;
+ } else if(nump <= 0) {
+ patterns= calloc(1, sizeof(char *));
+ if(patterns == NULL) {
+no_memory:;
+ sprintf(xorriso->info_text,
+ "Cannot allocate enough memory for pattern expansion");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
+ {ret= -1; goto ex;}
+ }
+ nump= 1;
+ if(flag&8)
+ patterns[0]= ".";
+ else
+ patterns[0]= "*";
+ flag&= ~2;
+ } else {
+ patterns= calloc(nump, sizeof(char *));
+ if(patterns==NULL)
+ goto no_memory;
+ for(i= 0; iwdx,
+ nump, argv + (*idx), mem, flag&(1|4|8));
+
+#ifdef Not_yeT
+ } else if(nump==1 && strcmp(patterns[0],"*")==0 && !(flag&4)){
+ /* save temporary memory by calling simpler function */
+ ret= Xorriso_ls(xorriso, (flag&1)|4);
+#endif
+
+ } else {
+ ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, 0, &filec, &filev,
+ &mem, 0);
+ if(ret<=0)
+ {ret= 0; goto ex;}
+ ret= Xorriso_lsx_filev(xorriso, xorriso->wdx, filec, filev, mem,
+ flag&(1|4|8));
+ }
+ if(ret<=0)
+ {ret= 0; goto ex;}
+
+ ret= 1;
+ex:;
+ if(patterns!=NULL)
+ free((char *) patterns);
+ Sfile_destroy_argv(&filec, &filev, 0);
+ (*idx)= end_idx;
+ return(ret);
+}
+
+
+/* Option -map , -map_single */
+/* @param flag bit0=do not report the added item
+ bit1=do not reset pacifier, no final pacifier message
+ bit5=eventually do not insert directory tree
+*/
+int Xorriso_option_map(struct XorrisO *xorriso, char *disk_path,
+ char *iso_path, int flag)
+{
+ int ret;
+ char eff_origin[SfileadrL], eff_dest[SfileadrL];
+
+ if(!(flag&2))
+ Xorriso_pacifier_reset(xorriso, 0);
+
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_origin,
+ 2|4);
+ if(ret<=0)
+ return(ret);
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_path, eff_dest,
+ 2);
+ if(ret<=0)
+ return(ret);
+ ret= Xorriso_graft_in(xorriso, NULL, eff_origin, eff_dest,
+ (off_t) 0, (off_t) 0, 2|(flag&32));
+ if(!(flag&2))
+ Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
+ xorriso->pacifier_total, "", 1);
+ if(ret<=0)
+ return(ret);
+
+ if(!(flag&1)) {
+ sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n",
+ (ret>1 ? "directory" : "file"), eff_dest, eff_origin);
+ Xorriso_info(xorriso,0);
+ }
+ return(1);
+}
+
+
+/* Option -mark */
+int Xorriso_option_mark(struct XorrisO *xorriso, char *mark, int flag)
+{
+ if(mark[0]==0)
+ xorriso->mark_text[0]= 0;
+ else
+ strncpy(xorriso->mark_text,mark,sizeof(xorriso->mark_text)-1);
+ xorriso->mark_text[sizeof(xorriso->mark_text)-1]= 0;
+ return(1);
+}
+
+
+/* Option -mkdir alias -mkdiri */
+int Xorriso_option_mkdiri(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int i, end_idx, ret, was_failure= 0, fret;
+
+ end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 0);
+
+ for(i= *idx; i0 && !xorriso->request_to_abort)
+ continue; /* regular bottom of loop */
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ ret= 1;
+ex:;
+ (*idx)= end_idx;
+ if(ret<=0)
+ return(ret);
+ return(!was_failure);
+}
+
+
+/* Option -mv alias -mvi */
+int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int i, end_idx_dummy, ret, is_dir= 0, was_failure= 0, fret;
+ char sfe[5*SfileadrL], sfe2[5*SfileadrL];
+ char eff_origin[SfileadrL], eff_dest[SfileadrL], dest_dir[SfileadrL];
+ char leafname[SfileadrL];
+ int optc= 0;
+ char **optv= NULL;
+
+ ret= Xorriso_cpmv_args(xorriso, "-mvi", argc, argv, idx,
+ &optc, &optv, eff_dest, 0);
+ if(ret<=0)
+ goto ex;
+ if(ret==2) {
+ is_dir= 1;
+ strcpy(dest_dir, eff_dest);
+ }
+ /* Perform movements */
+ for(i= 0; iwdi,optv[i],eff_origin,0);
+ if(ret<=0 || xorriso->request_to_abort)
+ goto problem_handler;
+ if(is_dir) {
+ ret= Sfile_leafname(eff_origin, leafname, 0);
+ if(ret<=0)
+ goto problem_handler;
+ strcpy(eff_dest, dest_dir);
+ ret= Sfile_add_to_path(eff_dest, leafname, 0);
+ if(ret<=0) {
+ printf(xorriso->info_text, "Effective path gets much too long (%d)",
+ strlen(eff_dest)+strlen(leafname)+1);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ goto problem_handler;
+ }
+ }
+ ret= Xorriso_rename(xorriso, NULL, eff_origin, eff_dest, 0);
+ if(ret<=0 || xorriso->request_to_abort)
+ goto problem_handler;
+ sprintf(xorriso->info_text, "Renamed in ISO image: %s to %s\n",
+ Text_shellsafe(eff_origin,sfe,0),Text_shellsafe(eff_dest,sfe2,0));
+ Xorriso_info(xorriso, 0);
+
+ continue; /* regular bottom of loop */
+problem_handler:;
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ ret= !was_failure;
+ex:;
+ Xorriso_opt_args(xorriso, "-mvi",
+ argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256);
+ return(ret);
+}
+
+
+/* Option -no_rc */
+int Xorriso_option_no_rc(struct XorrisO *xorriso, int flag)
+{
+ xorriso->no_rc= 1;
+ return(1);
+}
+
+
+/* Option -not_leaf */
+int Xorriso_option_not_leaf(struct XorrisO *xorriso, char *pattern, int flag)
+{
+ regex_t re;
+ char regexpr[2*SfileadrL+2], sfe[5*SfileadrL];
+ int ret;
+
+ Xorriso__bourne_to_reg(pattern, regexpr, 0);
+ if(regcomp(&re, regexpr, 0)!=0)
+ {ret= 0; goto cannot_add;}
+ ret= Exclusions_add_not_leafs(xorriso->disk_exclusions, pattern, &re, 0);
+ if(ret<=0) {
+cannot_add:;
+ sprintf(xorriso->info_text,"Cannot add pattern: -not_leaf %s",
+ Text_shellsafe(pattern, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(ret);
+ }
+ return(1);
+}
+
+
+/* Option -not_list */
+int Xorriso_option_not_list(struct XorrisO *xorriso, char *adr, int flag)
+{
+ int ret, linecount= 0, insertcount= 0, null= 0;
+ FILE *fp= NULL;
+ char *argpt, sfe[5*SfileadrL], line[SfileadrL];
+
+ Xorriso_pacifier_reset(xorriso, 0);
+ if(adr[0]==0) {
+ sprintf(xorriso->info_text,"Empty file name given with -not_list");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ return(0);
+ }
+ fp= Afile_fopen(adr,"rb",((!!xorriso->packet_output)<<6));
+ if(fp==NULL)
+ return(0);
+ while(1) {
+ if(Sfile_fgets(line,sizeof(line),fp)==NULL) {
+ ret= 1;
+ if(ferror(fp)) {
+ Xorriso_msgs_submit(xorriso, 0, "Error on reading text line",
+ errno, "FAILURE", 0);
+ ret= 0;
+ }
+ goto ex;
+ }
+ linecount++;
+ if(line[0]==0)
+ continue;
+ if(strchr(line, '/')!=NULL) {
+ argpt= line;
+ null= 0;
+ ret= Xorriso_option_not_paths(xorriso, 1, &argpt, &null, 0);
+ } else
+ ret= Xorriso_option_not_leaf(xorriso, line, 0);
+ if(ret<=0)
+ goto ex;
+ insertcount++;
+ }
+ ret= 1;
+ex:;
+ if(fp!=NULL)
+ fclose(fp);
+ if(ret<=0) {
+ sprintf(xorriso->info_text, "Aborted reading of file %s in line number %d",
+ Text_shellsafe(adr, sfe, 0), linecount);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ }
+ sprintf(xorriso->info_text, "Added %d exclusion list items from file %s\n",
+ insertcount, Text_shellsafe(adr, sfe, 0));
+ Xorriso_info(xorriso,0);
+ return(ret);
+}
+
+
+/* Option -not_mgt */
+int Xorriso_option_not_mgt(struct XorrisO *xorriso, char *setting, int flag)
+{
+ int ret;
+ char what_data[SfileadrL], *what, *what_next;
+
+ if(Sfile_str(what_data, setting, 0)<=0) {
+ sprintf(xorriso->info_text,
+ "-not_mgt: setting string is much too long (%d)",
+ (int) strlen(setting));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ for(what= what_data; what!=NULL; what= what_next) {
+ what_next= strchr(what, ':');
+ if(what_next!=NULL) {
+ *what_next= 0;
+ what_next++;
+ }
+
+ if(strcmp(what, "reset")==0 || strcmp(what, "erase")==0) {
+ if(strcmp(what, "reset")==0)
+ xorriso->disk_excl_mode= 1;
+ Exclusions_destroy(&(xorriso->disk_exclusions), 0);
+ ret= Exclusions_new(&(xorriso->disk_exclusions), 0);
+ if(ret<=0) {
+ Xorriso_no_malloc_memory(xorriso, NULL, 0);
+ return(ret);
+ }
+ } else if(strcmp(what, "on")==0) {
+ xorriso->disk_excl_mode|= 1;
+ } else if(strcmp(what, "off")==0) {
+ xorriso->disk_excl_mode&= ~1;
+ } else if(strcmp(what, "param_on")==0) {
+ xorriso->disk_excl_mode|= 2;
+ } else if(strcmp(what, "param_off")==0) {
+ xorriso->disk_excl_mode&= ~2;
+ } else if(strcmp(what, "subtree_on")==0) {
+ xorriso->disk_excl_mode|= 4;
+ } else if(strcmp(what, "subtree_off")==0) {
+ xorriso->disk_excl_mode&= ~4;
+ } else if(strcmp(what, "ignore_on")==0) {
+ xorriso->disk_excl_mode|= 8;
+ } else if(strcmp(what, "ignore_off")==0) {
+ xorriso->disk_excl_mode&= ~8;
+ } else {
+ sprintf(xorriso->info_text, "-not_mgt: unknown setting '%s'", what);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ }
+ return(1);
+}
+
+
+/* Option -not_paths */
+int Xorriso_option_not_paths(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int ret, end_idx, num_descr, dummy, optc= 0, i;
+ char **descr= NULL, **optv= NULL, sfe[5*SfileadrL], eff_path[SfileadrL];
+
+
+ end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx,
+ xorriso->do_disk_pattern==1);
+ if(end_idx<=0)
+ return(end_idx);
+ num_descr= end_idx - *idx;
+ if(num_descr<=0)
+ {ret= 1; goto ex;}
+
+ /* produce absolute patterns */
+ descr= TSOB_FELD(char *, num_descr);
+ if(descr==NULL) {
+no_memory:;
+ Xorriso_no_pattern_memory(xorriso, sizeof(char *) * (off_t) num_descr, 0);
+ ret= -1; goto ex;
+ }
+ for(i= 0; iwdx, argv[i+*idx],
+ eff_path, 2|4);
+ if(ret<=0)
+ goto ex;
+ descr[i]= strdup(eff_path);
+ if(descr[i]==NULL)
+ goto no_memory;
+ }
+
+ ret= Xorriso_opt_args(xorriso, "-not_paths",
+ num_descr, descr, 0, &dummy, &optc, &optv, 2);
+ if(ret<=0)
+ goto ex;
+ ret= Exclusions_add_not_paths(xorriso->disk_exclusions,
+ num_descr, descr, optc, optv, 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text,"Cannot add path list: -not_paths %s%s --",
+ Text_shellsafe(argv[*idx], sfe, 0), (num_descr>1 ? " ..." : ""));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ }
+ex:;
+ (*idx)= end_idx;
+ Xorriso_opt_args(xorriso, "-not_paths",
+ num_descr, descr, 0, &dummy, &optc, &optv, 256);
+ if(descr!=NULL) {
+ for(i= 0; iinfo_text,"Empty file name given with -options_from_file");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ Text_shellsafe(adr,shellsafe,0);
+ if(xorriso->is_dialog) {
+ sprintf(xorriso->info_text,"+ performing command lines from file %s :\n",
+ shellsafe);
+ Xorriso_info(xorriso,1);
+ }
+ fp= Afile_fopen(adr,"rb",((!!xorriso->packet_output)<<6));
+ if(fp==NULL)
+ return(0);
+ while(1) {
+ if(Sfile_fgets(line,sizeof(line),fp)==NULL) {
+ ret= 1;
+ if(ferror(fp))
+ ret= 0;
+ break;
+ }
+ linecount++;
+ if(line[0]==0 || line[0]=='#')
+ continue;
+
+ if(flag&1) {
+ ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv, 4|8);
+ if(ret<=0)
+ goto problem_handler;
+ ret= Xorriso_prescan_args(xorriso,argc,argv,1);
+ Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */
+ if(ret==0)
+ {ret= 3; goto ex;}
+ if(ret<0)
+ goto problem_handler;
+ } else {
+ if(xorriso->is_dialog) {
+ sprintf(xorriso->info_text,"+ %d: %s\n",linecount,line);
+ Xorriso_info(xorriso,1);
+ }
+ ret= Xorriso_execute_option(xorriso,line,1|(1<<16));
+ if(ret==3)
+ goto ex;
+ if(ret<=0)
+ goto problem_handler;
+ }
+
+ continue; /* regular bottom of loop */
+problem_handler:;
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ex:;
+ Xorriso_reset_counters(xorriso,0);
+ if(fp!=NULL)
+ fclose(fp);
+ if(ret<=0) {
+ sprintf(xorriso->info_text,
+ "error triggered by line %d of file:\n %s\n",
+ linecount,shellsafe);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 1);
+ }
+ if(ret!=1)
+ return(ret);
+ return(!was_failure);
+}
+
+
+/* Option -overwrite "on"|"nondir"|"off" */
+int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode, "off")==0)
+ xorriso->do_overwrite= 0;
+ else if(strcmp(mode, "on")==0)
+ xorriso->do_overwrite= 1;
+ else if(strcmp(mode, "nondir")==0)
+ xorriso->do_overwrite= 2;
+ else {
+ sprintf(xorriso->info_text, "-overwrite: unknown mode '%s'", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -padding */
+int Xorriso_option_padding(struct XorrisO *xorriso, char *size, int flag)
+{
+ double num;
+
+ num= Scanf_io_size(size, 0);
+ if(num < 0 || num > 1024.0 * 1024.0 * 1024.0) {
+ sprintf(xorriso->info_text, "-padding: wrong size %.f (allowed: %.f - %.f)",
+ num, 0.0, 1024.0 * 1024.0 * 1024.0);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ xorriso->padding= num;
+ if(xorriso->padding/2048 != num/2048.0)
+ xorriso->padding++;
+ return(1);
+}
+
+
+/* Option -page */
+int Xorriso_option_page(struct XorrisO *xorriso, int len, int width, int flag)
+{
+ if(len<0 || width<=0) {
+ sprintf(xorriso->info_text,
+ "Improper numeric value of arguments of -page: %d %d",
+ len, width);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ xorriso->result_page_length= len;
+ xorriso->result_page_width= width;
+ return(1);
+}
+
+
+/* Option -path-list */
+int Xorriso_option_path_list(struct XorrisO *xorriso, char *adr, int flag)
+{
+ int ret,linecount= 0, insertcount= 0, null= 0, was_failure= 0, fret= 0;
+ int was_ferror= 0;
+ FILE *fp= NULL;
+ char *argpt, sfe[5*SfileadrL],line[SfileadrL];
+
+ Xorriso_pacifier_reset(xorriso, 0);
+ if(adr[0]==0) {
+ sprintf(xorriso->info_text,"Empty file name given with -path-list");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ return(0);
+ }
+ fp= Afile_fopen(adr,"rb",((!!xorriso->packet_output)<<6));
+ if(fp==NULL)
+ return(0);
+ while(1) {
+ if(Sfile_fgets(line,sizeof(line),fp)==NULL) {
+ ret= 1;
+ if(ferror(fp))
+ was_ferror= 1;
+ break;
+ }
+ linecount++;
+ if(line[0]==0)
+ continue;
+ argpt= line;
+ null= 0;
+ ret= Xorriso_option_add(xorriso, 1, &argpt, &null, 1|2);
+ if(ret<=0 || xorriso->request_to_abort)
+ goto problem_handler;
+ insertcount++;
+
+ continue; /* regular bottom of loop */
+problem_handler:;
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ ret= 1;
+ex:;
+ if(fp!=NULL)
+ fclose(fp);
+ Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
+ xorriso->pacifier_total, "", 1);
+ if(ret<=0) {
+ sprintf(xorriso->info_text, "Aborted reading of file %s in line number %d",
+ Text_shellsafe(adr, sfe, 0), linecount);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
+ (fret==-2 ? "NOTE" : "FAILURE"), 0);
+ }
+ ret= !was_ferror;
+ sprintf(xorriso->info_text, "Added %d items from file %s\n",
+ insertcount, Text_shellsafe(adr, sfe, 0));
+ Xorriso_info(xorriso,0);
+ if(ret<=0)
+ return(ret);
+ return(!was_failure);
+}
+
+
+/* Option -pathspecs */
+int Xorriso_option_pathspecs(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode, "off")==0)
+ xorriso->allow_graft_points= 0;
+ else if(strcmp(mode, "on")==0)
+ xorriso->allow_graft_points= 1;
+ else {
+ sprintf(xorriso->info_text, "-pathspecs: unknown mode '%s'", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -pkt_output */
+int Xorriso_option_pkt_output(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode,"off")==0)
+ xorriso->packet_output= 0;
+ else
+ xorriso->packet_output= 1;
+ return(1);
+}
+
+
+/* Option -print */
+int Xorriso_option_print(struct XorrisO *xorriso, char *text, int flag)
+{
+ sprintf(xorriso->result_line,"%s\n",text);
+ Xorriso_result(xorriso,1);
+ return(1);
+}
+
+
+/* Option -print_size
+ @param flag bit0= report in mkisofs compatible form on real stdout
+*/
+int Xorriso_option_print_size(struct XorrisO *xorriso, int flag)
+{
+ int ret, fd;
+
+ if(!xorriso->volset_change_pending) {
+ sprintf(xorriso->info_text,"-print_size: No image modifications pending");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ sprintf(xorriso->result_line,"Image size : 0s\n");
+ Xorriso_result(xorriso,0);
+ return(2);
+ }
+ ret= Xorriso_write_session(xorriso, 1);
+ if(ret<=0) {
+ sprintf(xorriso->info_text,"-print_size: Failed to set up virtual -commit");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ if(flag&1) {
+ sprintf(xorriso->result_line,"%d\n", ret);
+ fd= xorriso->dev_fd_1;
+ if(fd<0)
+ fd= 1;
+ write(fd, xorriso->result_line, strlen(xorriso->result_line));
+ fsync(fd);
+ } else {
+ sprintf(xorriso->result_line,"Image size : %ds\n", ret);
+ Xorriso_result(xorriso,0);
+ }
+ return(1);
+}
+
+
+/* Option -prog */
+int Xorriso_option_prog(struct XorrisO *xorriso, char *name, int flag)
+{
+ if(strlen(name)>=sizeof(xorriso->progname)) {
+ sprintf(xorriso->info_text,
+ "Name too long with option -prog (%d > %d)",
+ (int) strlen(name), (int) sizeof(xorriso->progname)-1);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ if(Sfile_str(xorriso->progname,name,0)<=0)
+ return(-1);
+ return(1);
+}
+
+
+/* Option -prog_help */
+int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag)
+{
+ int ret;
+
+ ret= Xorriso_option_prog(xorriso, name, 0);
+ if(ret<=0)
+ return(ret);
+ ret= Xorriso_option_help(xorriso, 0);
+ return(ret);
+}
+
+
+/* Option -prompt */
+int Xorriso_option_prompt(struct XorrisO *xorriso, char *text, int flag)
+{
+ int ret;
+ char line[80];
+
+ strncpy(xorriso->result_line,text,sizeof(xorriso->result_line)-1);
+ xorriso->result_line[sizeof(xorriso->result_line)-1]= 0;
+ Xorriso_result(xorriso,0);
+ ret= Xorriso_dialog_input(xorriso, line, sizeof(line),1);
+ return(ret);
+}
+
+
+/* Option -publisher */
+int Xorriso_option_publisher(struct XorrisO *xorriso, char *name, int flag)
+{
+ int ret;
+
+ if(strlen(name)>=sizeof(xorriso->publisher)) {
+ sprintf(xorriso->info_text,
+ "Name too long with option -publisher (%d > %d)",
+ (int) strlen(name), (int) sizeof(xorriso->publisher)-1);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ ret= Xorriso_set_publisher(xorriso, name, 0);
+ if(ret<=0)
+ return(ret);
+ if(Sfile_str(xorriso->publisher,name,0)<=0)
+ return(-1);
+ return(1);
+}
+
+
+/* Option -pwd alias -pwdi */
+int Xorriso_option_pwdi(struct XorrisO *xorriso, int flag)
+{
+ sprintf(xorriso->info_text,"current working directory in ISO image:\n");
+ Xorriso_info(xorriso,0);
+ sprintf(xorriso->result_line,"%s/\n",xorriso->wdi);
+ Xorriso_result(xorriso,0);
+ return(1);
+}
+
+
+/* Option -pwdx */
+int Xorriso_option_pwdx(struct XorrisO *xorriso, int flag)
+{
+ sprintf(xorriso->info_text,"current working directory on hard disk:\n");
+ Xorriso_info(xorriso,0);
+ sprintf(xorriso->result_line,"%s/\n",xorriso->wdx);
+ Xorriso_result(xorriso,0);
+ return(1);
+}
+
+
+/* Option -reassure "on"|"tree"|"off" */
+int Xorriso_option_reassure(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode, "off")==0)
+ xorriso->do_reassure= 0;
+ else if(strcmp(mode, "on")==0)
+ xorriso->do_reassure= 1;
+ else if(strcmp(mode, "tree")==0)
+ xorriso->do_reassure= 2;
+ else {
+ sprintf(xorriso->info_text, "-reassure: unknown mode '%s'", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -report_about */
+int Xorriso_option_report_about(struct XorrisO *xorriso, char *severity,
+ int flag)
+{
+ int ret, sev;
+ char sfe[5*SfileadrL];
+
+ ret= Xorriso__text_to_sev(severity, &sev, 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text,
+ "-report_about: Not a known severity name : %s",
+ Text_shellsafe(severity, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ return(ret);
+ }
+ if(Sfile_str(xorriso->report_about_text,severity,0)<=0)
+ return(-1);
+ xorriso->report_about_severity= sev;
+ return(1);
+}
+
+
+/* Option -return_with */
+int Xorriso_option_return_with(struct XorrisO *xorriso, char *severity,
+ int exit_value, int flag)
+{
+ int ret, sev;
+ char sfe[5*SfileadrL];
+
+ ret= Xorriso__text_to_sev(severity, &sev, 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text,
+ "-return_with: Not a known severity name : %s",
+ Text_shellsafe(severity, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(ret);
+ }
+ if(exit_value && (exit_value < 32 || exit_value > 63)) {
+ sprintf(xorriso->info_text,
+ "-return_with: Not an allowed exit_value. Use 0, or 32 to 63.");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ if(Sfile_str(xorriso->return_with_text,severity,0)<=0)
+ return(-1);
+ xorriso->return_with_severity= sev;
+ return(1);
+}
+
+
+/* Options -rm alias -rmi , -rm_r alias -rm_ri , -rmdir alias -rmdiri */
+/* @param flag bit0=recursive , bit1= remove empty directory: rmdir */
+int Xorriso_option_rmi(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag)
+{
+ int i, ret, end_idx, was_failure= 0, fret;
+ char path[SfileadrL], eff_path[SfileadrL], sfe[5*SfileadrL];
+ int optc= 0;
+ char **optv= NULL;
+
+ ret= Xorriso_opt_args(xorriso, "-rm*i",
+ argc, argv, *idx, &end_idx, &optc, &optv, 0);
+ if(ret<=0)
+ goto ex;
+ for(i= 0; iwdi, path, 0);
+ if(ret<=0)
+ goto problem_handler;
+ }
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
+ if(ret<0)
+ goto problem_handler;
+ if(ret==0) {
+ sprintf(xorriso->info_text,
+ "Cannot find path %s in loaded ISO image for removal",
+ Text_shellsafe(path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ goto problem_handler;
+ }
+ strcpy(path, eff_path);
+
+ ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, path, flag&(1|2));
+ if(ret<=0 || xorriso->request_to_abort)
+ goto problem_handler;
+ if(ret<3) {
+ sprintf(xorriso->info_text, "Removed from ISO image: %s '%s'\n",
+ ((flag&2) ? "directory" : (ret>1 ? "subtree" : "file")), path);
+ Xorriso_info(xorriso, 0);
+ }
+
+ continue; /* regular bottom of loop */
+problem_handler:;
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
+ if(fret>=0)
+ continue;
+ goto ex;
+ }
+ ret= 1;
+ex:;
+ (*idx)= end_idx;
+ Xorriso_opt_args(xorriso, "-rm*i",
+ argc, argv, *idx, &end_idx, &optc, &optv, 256);
+ if(ret<=0)
+ return(ret);
+ return(!was_failure);
+}
+
+
+/* Option -rollback */
+/* @param flag bit0= do not -reassure
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_rollback(struct XorrisO *xorriso, int flag)
+{
+ int ret;
+ char indev[SfileadrL], *which_will;
+
+ if(xorriso->volset_change_pending)
+ which_will= "revoke the pending image changes";
+ else
+ which_will= "reload the image";
+ if(!(flag&1)) {
+ ret= Xorriso_reassure(xorriso, "-rollback", which_will, 0);
+ if(ret<=0)
+ return(2);
+ }
+
+ if(Sfile_str(indev, xorriso->indev, 0)<=0)
+ return(-1);
+ ret= Xorriso_give_up_drive(xorriso, 1|8);
+ if(ret<=0)
+ return(ret);
+ xorriso->image_start_mode&= ~(1<<31); /* reactivate eventual -load address */
+ ret= Xorriso_option_dev(xorriso, indev, 1|4);
+ return(ret);
+}
+
+
+/* Option -rom_toc_scan */
+int Xorriso_option_rom_toc_scan(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode, "off")==0)
+ xorriso->toc_emulation_flag= 0;
+ else if(strcmp(mode, "on")==0)
+ xorriso->toc_emulation_flag= 1;
+ else {
+ sprintf(xorriso->info_text, "-rom_toc_scan: unknown mode '%s'", mode);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ return(1);
+}
+
+
+/* Option -session_log */
+int Xorriso_option_session_log(struct XorrisO *xorriso, char *path, int flag)
+{
+ if(Sfile_str(xorriso->session_logfile, path, 0)<=0)
+ return(-1);
+ return(1);
+}
+
+
+/* Option -speed */
+int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag)
+{
+ int is_cd= 1, unit_found= 0, ret, profile_number;
+ double num;
+ char *cpt, profile_name[80];
+
+ if(speed[0]==0 || strcmp(speed, "any")==0) {
+ xorriso->speed= 0; /* full speed */
+ return(1);
+ }
+
+ sscanf(speed,"%lf",&num);
+ for(cpt= speed+strlen(speed)-1; cpt>=speed; cpt--)
+ if(isdigit(*cpt) || *cpt=='.')
+ break;
+ cpt++;
+
+ if(*cpt=='k' || *cpt=='K') {
+ /* is merchand kilobyte, stays merchand kilobyte */
+ unit_found= 1;
+ } else if(*cpt=='m' || *cpt=='M') {
+ num*= 1000;
+ unit_found= 1;
+ } else if(*cpt=='x' || *cpt=='X')
+ cpt++;
+
+ if(*cpt=='c' || *cpt=='C') {
+cd_speed:;
+ num*= 176.4;
+ } else if(*cpt=='d' || *cpt=='D') {
+dvd_speed:;
+ num*= 1385;
+ } else if (!unit_found) {
+ ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
+ is_cd= (ret==2);
+ if(is_cd)
+ goto cd_speed;
+ else
+ goto dvd_speed;
+ }
+
+ if(num> 2.0e9) {
+ sprintf(xorriso->info_text,
+ "-speed: Value too large or not recognizable: '%s'", speed);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ xorriso->speed= num;
+ if(xorriso->speedspeed++;
+ return(1);
+}
+
+
+/* Option -split_size */
+int Xorriso_option_split_size(struct XorrisO *xorriso, char *size, int flag)
+{
+ double num;
+ static off_t limit= ((off_t) 4) * ((off_t) 1024*1024*1024) - (off_t) 1;
+
+ num= Scanf_io_size(size, 0);
+ if(num > limit) {
+ sprintf(xorriso->info_text, "-split_size: too large %.f (allowed: %.f)",
+ num, (double) limit);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ } else if(num < 0)
+ num= 0.0;
+ xorriso->split_size= num;
+ return(1);
+}
+
+
+/* Option -status */
+int Xorriso_option_status(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode,"short")==0)
+ Xorriso_status(xorriso,NULL,NULL,1);
+ else if(strcmp(mode,"long")==0)
+ Xorriso_status(xorriso,NULL,NULL,0);
+ else if(strcmp(mode,"long_history")==0)
+ Xorriso_status(xorriso,NULL,NULL,8);
+ else if(mode[0]=='-')
+ Xorriso_status(xorriso,mode,NULL,8);
+ else
+ Xorriso_status(xorriso,NULL,NULL,1);
+ return(1);
+}
+
+
+/* Option -status_history_max */
+int Xorriso_option_status_history_max(struct XorrisO *xorriso, int num,
+ int flag)
+{
+ if(num>=0 && num<1000000)
+ xorriso->status_history_max= num;
+ return(1);
+}
+
+
+/* Option -tell_media_space */
+int Xorriso_option_tell_media_space(struct XorrisO *xorriso, int flag)
+{
+ int ret, free_space= 0, media_space= 0;
+
+ ret= Xorriso_tell_media_space(xorriso, &media_space, &free_space, 0);
+ if(ret<=0) {
+ sprintf(xorriso->info_text, "Cannot -tell_media_space");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ if(free_space<0) {
+ sprintf(xorriso->info_text,
+ "Pending image size larger than free space on media");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ }
+ sprintf(xorriso->result_line, "Media space : %ds\n", media_space);
+ Xorriso_result(xorriso, 0);
+ sprintf(xorriso->result_line, "After commit : %ds\n", free_space);
+ Xorriso_result(xorriso, 0);
+ return(1);
+}
+
+
+/* Option -temp_mem_limit */
+int Xorriso_option_temp_mem_limit(struct XorrisO *xorriso, char *size,
+ int flag)
+{
+ double num;
+
+ num= Scanf_io_size(size, 0);
+ if(num < 64.0 * 1024.0 || num > 1024.0 * 1024.0 * 1024.0) {
+ sprintf(xorriso->info_text,
+ "-temp_mem_limit: wrong size %.f (allowed: %.f - %.f)",
+ num, 64.0 * 1024.0, 1024.0 * 1024.0 * 1024.0);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
+ return(0);
+ }
+ xorriso->temp_mem_limit= num;
+ return(1);
+}
+
+
+/* Option -toc */
+int Xorriso_option_toc(struct XorrisO *xorriso, int flag)
+{
+ int ret, in_ret= 1000;
+
+ if(strcmp(xorriso->indev,xorriso->outdev)==0)
+ ret= Xorriso_toc(xorriso, 0);
+ else {
+ if(xorriso->indev[0]!=0)
+ in_ret= Xorriso_toc(xorriso, 0);
+ if(xorriso->indev[0]!=0 && xorriso->outdev[0]!=0) {
+ strcpy(xorriso->result_line, "-------------: ---------------------------------------------------------------\n");
+ Xorriso_result(xorriso,0);
+ }
+ ret= 1;
+ if(xorriso->outdev[0]!=0)
+ ret= Xorriso_toc(xorriso, 2);
+ if(in_retdo_global_uid= 0;
+ if(uid[0]==0 || strcmp(uid,"-")==0)
+ return(1);
+ ret= Xorriso_convert_uidstring(xorriso, uid, &(xorriso->global_uid), 0);
+ if(ret>0)
+ xorriso->do_global_uid= 1;
+ return(ret);
+}
+
+
+/* Options -update and -update_r
+ @param flag bit0= issue start and summary message
+ bit1= do not reset pacifier, no final pacifier message
+ bit2= do not issue pacifier messages at all
+ bit3= recursive: -update_r
+*/
+int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path,
+ char *iso_path, int flag)
+{
+ int ret, mem_pci, zero= 0, result, uret, follow_links;
+ int not_in_iso= 0, not_on_disk= 0;
+ double mem_lut= 0.0, start_time;
+ char *ipth, *argv[6], sfe[5*SfileadrL];
+ char eff_origin[SfileadrL], eff_dest[SfileadrL];
+ struct stat stbuf;
+
+ start_time= Sfile_microtime(0);
+
+ ipth= iso_path;
+ if(ipth[0]==0)
+ ipth= disk_path;
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_origin,
+ 2|4);
+ if(ret<=0)
+ return(ret);
+ ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_dest, 2);
+ if(ret<=0)
+ return(ret);
+
+ if(!(flag&2)) {
+ Xorriso_pacifier_reset(xorriso, 0);
+ mem_lut= xorriso->last_update_time;
+ }
+ mem_pci= xorriso->pacifier_interval;
+ xorriso->pacifier_interval= 5.0;
+
+ if(flag&1) {
+ sprintf(xorriso->info_text, "Updating %s to",
+ Text_shellsafe(eff_origin, sfe, 0));
+ sprintf(xorriso->info_text+strlen(xorriso->info_text), " %s\n",
+ Text_shellsafe(eff_dest, sfe, 0));
+ Xorriso_info(xorriso,0);
+ }
+ if(xorriso->disk_excl_mode&8)
+ ret= Xorriso_path_is_excluded(xorriso, eff_origin, 1);
+ else
+ ret= 0;
+ if(ret!=0)
+ goto report_outcome;
+ if(flag&8) {
+ xorriso->find_compare_result= 1;
+ ret= Xorriso_iso_lstat(xorriso, eff_dest, &stbuf, 0);
+ if(ret >= 0) {
+ argv[0]= eff_dest;
+ argv[1]= "-exec";
+ argv[2]= "update";
+ argv[3]= eff_origin;
+ zero= 0;
+ ret= Xorriso_option_find(xorriso, 4, argv, &zero, 2); /* -findi */
+ } else if(ret==-2) { /* severe error (e.g. lack of image) */
+ ret= -1;
+ goto report_outcome;
+ } else {
+ not_in_iso= 1;
+ ret= 1;
+ }
+ if(ret>0) {
+ ret= lstat(eff_origin, &stbuf);
+ if(ret != -1) {
+ argv[0]= eff_origin;
+ argv[1]= "-exec";
+ argv[2]= "add_missing";
+ argv[3]= eff_dest;
+ zero= 0;
+ ret= Xorriso_option_find(xorriso, 4, argv, &zero, 1|2); /* -findx */
+ if(ret>0 && !xorriso->do_follow_mount) {
+ argv[0]= eff_origin;
+ argv[1]= "-type";
+ argv[2]= "m";
+ argv[3]= "-exec";
+ argv[4]= "empty_iso_dir";
+ argv[5]= eff_dest;
+ zero= 0;
+ ret= Xorriso_option_find(xorriso, 6, argv, &zero, 1|2); /* -findx */
+ }
+ if(ret>0)
+ ret= xorriso->find_compare_result;
+ else
+ ret= -1;
+ } else {
+ ret= xorriso->find_compare_result;
+ not_on_disk= 1;
+ }
+ } else
+ ret= -1;
+ if(not_on_disk && not_in_iso) {
+ sprintf(xorriso->info_text, "Missing on disk and in ISO: disk_path %s",
+ Text_shellsafe(disk_path, sfe, 0));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1);
+ ret= -1;
+ }
+ } else {
+ /* compare ctime too, no filename reporting, eventually silent */
+ follow_links= (xorriso->do_follow_links || xorriso->do_follow_param) <<28;
+ ret= Xorriso_compare_2_files(xorriso, eff_origin, eff_dest, "", &result,
+ 2 | follow_links | ((flag&4)<<27) | (3<<30));
+ if(ret==0) {
+ uret= Xorriso_update_interpreter(xorriso, NULL, result, eff_origin,
+ eff_dest, 0);
+ if(uret<=0)
+ ret= -1;
+ if(uret==3)
+ ret= -1;
+ }
+ }
+ xorriso->pacifier_interval= mem_pci;
+ if(mem_lut!=xorriso->last_update_time && !(flag&2))
+ Xorriso_pacifier_callback(xorriso, "content bytes read",
+ xorriso->pacifier_count, 0, "", 1);
+report_outcome:;
+ if(ret>0) {
+ sprintf(xorriso->info_text,
+ "No file object needed update.");
+ } else if(ret==0) {
+ sprintf(xorriso->info_text, "Differences detected and updated.");
+ } else {
+ sprintf(xorriso->info_text,
+ "Not ok. Comparison or update failed due to error.");
+ }
+ sprintf(xorriso->info_text+strlen(xorriso->info_text),
+ " (runtime %.1f s)\n", Sfile_microtime(0)-start_time);
+ if(flag&1)
+ Xorriso_info(xorriso,0);
+ if(ret<0)
+ return(ret);
+ return(1);
+}
+
+
+/* Option -use_readline */
+int Xorriso_option_use_readline(struct XorrisO *xorriso, char *mode, int flag)
+{
+ if(strcmp(mode,"off")==0)
+ xorriso->use_stdin= 1;
+ else
+ xorriso->use_stdin= 0;
+ return(1);
+}
+
+
+/* Option -version */
+int Xorriso_option_version(struct XorrisO *xorriso, int flag)
+{
+ sprintf(xorriso->result_line,
+ "xorriso %s : RockRidge filesystem manipulator\n",
+ Xorriso_program_versioN);
+ sprintf(xorriso->result_line+strlen(xorriso->result_line),
+"Copyright (C) 2008, Thomas Schmitt , libburnia project\n");
+ Xorriso_result(xorriso, 0);
+ sprintf(xorriso->result_line,
+ "xorriso version : %s\n", Xorriso_program_versioN);
+ sprintf(xorriso->result_line+strlen(xorriso->result_line),
+ "Version timestamp : %s\n",Xorriso_timestamP);
+ sprintf(xorriso->result_line+strlen(xorriso->result_line),
+ "Build timestamp : %s\n",Xorriso_build_timestamP);
+ Xorriso_result(xorriso, 0);
+ Xorriso_report_lib_versions(xorriso, 0);
+ return(1);
+}
+
+
+/* Option -volid */
+int Xorriso_option_volid(struct XorrisO *xorriso, char *volid, int flag)
+{
+ int warn_shell= 0, warn_ecma= 0, i, ret;
+ static char shell_chars[]= {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-+=:.,~@"};
+ static char ecma_chars[]= {"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"};
+
+ for(i=0; volid[i]!=0; i++) {
+ if(strchr(shell_chars, volid[i])==NULL)
+ warn_shell= 1;
+ if(strchr(ecma_chars, volid[i])==NULL)
+ warn_ecma= 1;
+ }
+ if(i>32) {
+ sprintf(xorriso->info_text, "-volid: Text too long (%d > 32)", i);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ return(0);
+ }
+ if(warn_shell) {
+ sprintf(xorriso->info_text,
+ "-volid text problematic as automatic mount point name");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ }
+ if(xorriso->do_joliet && strlen(volid)>16) {
+ sprintf(xorriso->info_text,
+ "-volid text is too long for Joliet (%d > 16)",(int) strlen(volid));
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ }
+ if(warn_ecma) {
+ sprintf(xorriso->info_text,
+ "-volid text does not comply to ISO 9660 / ECMA 119 rules");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
+ }
+ strcpy(xorriso->volid, volid);
+ ret= Xorriso_set_volid(xorriso, volid, 0);
+ if(ret<=0)
+ return(ret);
+ xorriso->volid_default= (strcmp(xorriso->volid, "ISOIMAGE")==0 ||
+ xorriso->volid[0]==0);
+ return(1);
+}
+
+
+/* ---------------------------- End Options API ------------------------ */
+
+
+/* @return <0 error , >=0 number of skipped dashes
+*/
+int Xorriso_normalize_command(struct XorrisO *xorriso, char *original_cmd,
+ int argno, char *cmd_data, int sizeof_cmd_data,
+ char **cmd, int flag)
+{
+ int was_dashed= 0;
+ char *dash_pt;
+
+ if(strlen(original_cmd)>= sizeof_cmd_data) {
+ if(argno>=0)
+ sprintf(xorriso->info_text, "Oversized argument #%d (length %d)\n",
+ argno, (int) strlen(original_cmd));
+ else
+ sprintf(xorriso->info_text, "Oversized option (length %d)\n",
+ (int) strlen(original_cmd));
+ return(-1);
+ }
+ strcpy(cmd_data, original_cmd);
+ *cmd= cmd_data;
+ if(strcmp(*cmd, "--")==0)
+ return(1);
+ while((*cmd)[0]=='-') {
+ if((*cmd)[1]==0)
+ break;
+ was_dashed++;
+ (*cmd)++;
+ }
+ for(dash_pt= *cmd; *dash_pt!=0; dash_pt++)
+ if(*dash_pt=='-')
+ *dash_pt= '_';
+ return(1);
+}
+
+
+int Xorriso_interpreter(struct XorrisO *xorriso,
+ int argc, char **argv, int *idx, int flag)
+/*
+return:
+ <=0 error , 1 = success , 2 = problem event ignored , 3 = end program run
+*/
+/*
+ bit0= recursion
+*/
+{
+ int ret, was_dashed, end_ret;
+ int num1, num2;
+ char *cmd, *original_cmd, cmd_data[2*SfileadrL], *arg1, *arg2;
+
+ if(xorriso==NULL)
+ return(0);
+ if(xorriso->is_dialog) {
+ xorriso->result_line_counter= xorriso->result_page_counter= 0;
+ if(xorriso->result_page_length<0)
+ xorriso->result_page_length= -xorriso->result_page_length;
+ }
+
+next_command:;
+ xorriso->prepended_wd= 0;
+ xorriso->request_to_abort= xorriso->request_not_to_ask= 0;
+ Xorriso_set_problem_status(xorriso, "", 0);
+ if((*idx)add_plainly==3 && cmd[0] && !xorriso->is_dialog) {
+ (*idx)++;
+ goto add_plain_argument;
+ }
+ was_dashed= 0;
+
+#ifdef NIX
+
+ if(cmd[0]=='-' && cmd[1]!='-' && cmd[1]!=0) {
+ was_dashed= 1;
+ cmd++;
+ }
+
+#else /* NIX */
+
+ ret= Xorriso_normalize_command(xorriso, original_cmd, -1,
+ cmd_data, sizeof(cmd_data), &cmd, 0);
+ if(ret<0)
+ goto eval_any_problems;
+ was_dashed= ret;
+
+#endif /* ! NIX */
+
+ (*idx)++;
+
+ if((*idx)10);
+
+ } else if(strcmp(cmd,"as")==0) {
+ ret= Xorriso_option_as(xorriso, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"ban_stdio_write")==0) {
+ ret= Xorriso_option_ban_stdio_write(xorriso, 0);
+
+ } else if(strcmp(cmd,"blank")==0) {
+ (*idx)++;
+ ret= Xorriso_option_blank(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"boot_image")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_boot_image(xorriso, arg1, arg2, 0);
+
+ } else if(strcmp(cmd,"cd")==0 || strcmp(cmd,"cdi")==0) {
+ (*idx)++;
+ ret= Xorriso_option_cdi(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"cdx")==0) {
+ (*idx)++;
+ ret= Xorriso_option_cdx(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"chgrp")==0 || strcmp(cmd,"chgrpi")==0) {
+ (*idx)+= 1;
+ ret= Xorriso_option_chgrpi(xorriso, arg1, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"chgrp_r")==0 || strcmp(cmd,"chgrp_ri")==0) {
+ (*idx)+= 1;
+ ret= Xorriso_option_chgrpi(xorriso, arg1, argc, argv, idx, 1);
+
+ } else if(strcmp(cmd,"chmod")==0 || strcmp(cmd,"chmodi")==0) {
+ (*idx)+= 1;
+ ret= Xorriso_option_chmodi(xorriso, arg1, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"chmod_r")==0 || strcmp(cmd,"chmod_ri")==0) {
+ (*idx)+= 1;
+ ret= Xorriso_option_chmodi(xorriso, arg1, argc, argv, idx, 1);
+
+ } else if(strcmp(cmd,"chown_r")==0 || strcmp(cmd,"chown_ri")==0) {
+ (*idx)+= 1;
+ ret= Xorriso_option_chowni(xorriso, arg1, argc, argv, idx, 1);
+
+ } else if(strcmp(cmd,"chown")==0 || strcmp(cmd,"chowni")==0) {
+ (*idx)+= 1;
+ ret= Xorriso_option_chowni(xorriso, arg1, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"close")==0) {
+ (*idx)++;
+ ret= Xorriso_option_close(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"commit")==0) {
+ ret= Xorriso_option_commit(xorriso, 0);
+
+ } else if(strcmp(cmd,"commit_eject")==0) {
+ (*idx)++;
+ ret= Xorriso_option_commit_eject(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"compare")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_compare(xorriso, arg1, arg2, 1);
+
+ } else if(strcmp(cmd,"compare_r")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_compare(xorriso, arg1, arg2, 1|8);
+
+ } else if(strcmp(cmd,"cpr")==0 || strcmp(cmd,"cpri")==0) {
+ ret= Xorriso_option_cpri(xorriso, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"cut_out")==0) {
+ (*idx)+= 4;
+ if((*idx)>argc) {
+ sprintf(xorriso->info_text,
+ "-cut_out: Not enough arguments. Needed are: disk_path start count so_rr_path");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ ret= 0;
+ } else
+ ret= Xorriso_option_cut_out(xorriso, arg1, arg2,
+ argv[(*idx)-2], argv[(*idx)-1], 0);
+
+ } else if(strcmp(cmd,"dev")==0) {
+ (*idx)++;
+ ret= Xorriso_option_dev(xorriso, arg1, 3);
+
+ } else if(strcmp(cmd,"devices")==0) {
+ ret= Xorriso_option_devices(xorriso, 0);
+
+ } else if(strcmp(cmd,"dummy")==0) {
+ (*idx)++;
+ ret= Xorriso_option_dummy(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"dialog")==0) {
+ (*idx)++;
+ ret= Xorriso_option_dialog(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"disk_pattern")==0) {
+ (*idx)++;
+ ret= Xorriso_option_disk_pattern(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"du")==0 || strcmp(cmd,"dui")==0 ||
+ strcmp(cmd,"dus")==0 || strcmp(cmd,"dusi")==0) {
+ ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]!='s')|4);
+
+ } else if(strcmp(cmd,"dux")==0 || strcmp(cmd,"dusx")==0) {
+ ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]!='s')|4);
+
+ } else if(strcmp(cmd,"eject")==0) {
+ (*idx)++;
+ ret= Xorriso_option_eject(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"end")==0) {
+ end_ret= Xorriso_option_end(xorriso, 0);
+ ret= Xorriso_eval_problem_status(xorriso, ret, 0);
+ if(ret<0)
+ return(ret);
+ if(end_ret!=2)
+ {ret= 3; goto ex;}
+
+ } else if(strcmp(cmd,"errfile_log")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_errfile_log(xorriso, arg1, arg2, 0);
+
+ } else if(strcmp(cmd,"error_behavior")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_error_behavior(xorriso, arg1, arg2, 0);
+
+ } else if(strcmp(cmd,"iso_rr_pattern")==0) {
+ (*idx)++;
+ ret= Xorriso_option_iso_rr_pattern(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"follow")==0) {
+ (*idx)++;
+ ret= Xorriso_option_follow(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"find")==0 || strcmp(cmd,"findi")==0) {
+ ret= Xorriso_option_find(xorriso, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"findx")==0) {
+ ret= Xorriso_option_find(xorriso, argc, argv, idx, 1);
+
+ } else if(strcmp(cmd,"format")==0) {
+ (*idx)++;
+ ret= Xorriso_option_blank(xorriso, arg1, 1);
+
+ } else if(strcmp(cmd,"fs")==0) {
+ (*idx)++;
+ ret= Xorriso_option_fs(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"gid")==0) {
+ (*idx)++;
+ ret= Xorriso_option_gid(xorriso,arg1,0);
+
+ } else if(strcmp(cmd,"help")==0) {
+ Xorriso_option_help(xorriso,0);
+
+ } else if(strcmp(cmd,"history")==0) {
+ /* add to readline history */
+ (*idx)++;
+ ret= Xorriso_option_history(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"indev")==0) {
+ (*idx)++;
+ ret= Xorriso_option_dev(xorriso, arg1, 1);
+
+ } else if(strcmp(cmd,"joliet")==0) {
+ (*idx)++;
+ ret= Xorriso_option_joliet(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"list_formats")==0) {
+ ret= Xorriso_option_list_formats(xorriso, 0);
+
+ } else if(strcmp(cmd,"load")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_load(xorriso, arg1, arg2, 0);
+
+ } else if(strcmp(cmd,"logfile")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_logfile(xorriso, arg1, arg2, 0);
+
+ } else if(strcmp(cmd,"ls")==0 || strcmp(cmd,"lsi")==0 ||
+ strcmp(cmd,"lsl")==0 || strcmp(cmd,"lsli")==0) {
+ ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]=='l'));
+
+ } else if(strcmp(cmd,"lsd")==0 || strcmp(cmd,"lsdi")==0 ||
+ strcmp(cmd,"lsdl")==0 || strcmp(cmd,"lsdli")==0) {
+ ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[3]=='l')|8);
+
+ } else if(strcmp(cmd,"lsdx")==0 || strcmp(cmd,"lsdlx")==0) {
+ ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[3]=='l')|8);
+
+ } else if(strcmp(cmd,"lsx")==0 || strcmp(cmd,"lslx")==0) {
+ ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]=='l'));
+
+ } else if(strcmp(cmd,"map")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_map(xorriso, arg1, arg2, 0);
+
+ } else if(strcmp(cmd,"map_single")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_map(xorriso, arg1, arg2, 32);
+
+ } else if(strcmp(cmd,"mark")==0) {
+ (*idx)++;
+ ret= Xorriso_option_mark(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"mv")==0 || strcmp(cmd,"mvi")==0) {
+ ret= Xorriso_option_mvi(xorriso, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"mkdir")==0 || strcmp(cmd,"mkdiri")==0) {
+ ret= Xorriso_option_mkdiri(xorriso, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"no_rc")==0) {
+ ret= Xorriso_option_no_rc(xorriso, 0);
+
+ } else if(strcmp(cmd,"not_leaf")==0) {
+ (*idx)++;
+ ret= Xorriso_option_not_leaf(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"not_list")==0) {
+ (*idx)++;
+ ret= Xorriso_option_not_list(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"not_mgt")==0) {
+ (*idx)++;
+ ret= Xorriso_option_not_mgt(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"not_paths")==0) {
+ ret= Xorriso_option_not_paths(xorriso, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"options_from_file")==0) {
+ (*idx)++;
+ ret= Xorriso_option_options_from_file(xorriso,arg1,0);
+ if(ret==3)
+ goto ex;
+
+ } else if(strcmp(cmd,"overwrite")==0) {
+ (*idx)++;
+ ret= Xorriso_option_overwrite(xorriso,arg1,0);
+
+ } else if(strcmp(cmd,"outdev")==0) {
+ (*idx)++;
+ ret= Xorriso_option_dev(xorriso, arg1, 2);
+
+ } else if(strcmp(cmd,"padding")==0) {
+ (*idx)++;
+ ret= Xorriso_option_padding(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"page")==0) {
+ (*idx)+= 2;
+ num1= num2= 0;
+ sscanf(arg1,"%d",&num1);
+ sscanf(arg2,"%d",&num2);
+ if(num1<0)
+ num1= 0;
+ if(arg1[0]==0)
+ num1= 16;
+ if(num2<=0)
+ num2= 80;
+ ret= Xorriso_option_page(xorriso, num1, num2, 0);
+
+ } else if(strcmp(cmd,"path-list")==0 || strcmp(cmd,"path_list")==0) {
+ (*idx)++;
+ ret= Xorriso_option_path_list(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"pathspecs")==0) {
+ (*idx)++;
+ ret= Xorriso_option_pathspecs(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"pkt_output")==0) {
+ (*idx)++;
+ ret= Xorriso_option_pkt_output(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"print")==0) {
+ (*idx)++;
+ ret= Xorriso_option_print(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"print_size")==0) {
+ Xorriso_option_print_size(xorriso, 0);
+
+ } else if(strcmp(cmd,"prompt")==0) {
+ (*idx)++;
+ ret= Xorriso_option_prompt(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"prog")==0) {
+ (*idx)++;
+ ret= Xorriso_option_prog(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"publisher")==0) {
+ (*idx)++;
+ Xorriso_option_publisher(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"pwd")==0 || strcmp(cmd,"pwdi")==0) {
+ Xorriso_option_pwdi(xorriso, 0);
+
+ } else if(strcmp(cmd,"pwdx")==0) {
+ Xorriso_option_pwdx(xorriso, 0);
+
+ } else if(strcmp(cmd,"reassure")==0) {
+ (*idx)++;
+ ret= Xorriso_option_reassure(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"report_about")==0) {
+ (*idx)++;
+ ret= Xorriso_option_report_about(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"return_with")==0) {
+ (*idx)+= 2;
+ num2= 0;
+ sscanf(arg2,"%d",&num2);
+ ret= Xorriso_option_return_with(xorriso, arg1, num2, 0);
+
+ } else if(strcmp(cmd,"rm")==0 || strcmp(cmd,"rmi")==0) {
+ ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 0);
+
+ } else if(strcmp(cmd,"rm_r")==0 || strcmp(cmd,"rm_ri")==0) {
+ ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 1);
+
+ } else if(strcmp(cmd,"rmdir")==0 || strcmp(cmd,"rmdiri")==0) {
+ ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 2);
+
+ } else if(strcmp(cmd,"rollback")==0) {
+ ret= Xorriso_option_rollback(xorriso, 0);
+
+ } else if(strcmp(cmd,"rollback_end")==0) {
+ end_ret= Xorriso_option_end(xorriso, 1);
+ ret= Xorriso_eval_problem_status(xorriso, ret, 0);
+ if(ret<0)
+ return(ret);
+ if(end_ret!=2)
+ {ret= 3; goto ex;}
+
+ } else if(strcmp(cmd,"rom_toc_scan")==0) {
+ (*idx)++;
+ Xorriso_option_rom_toc_scan(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"session_log")==0) {
+ (*idx)++;
+ ret= Xorriso_option_session_log(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"speed")==0) {
+ (*idx)++;
+ ret= Xorriso_option_speed(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"split_size")==0) {
+ (*idx)++;
+ ret= Xorriso_option_split_size(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"status")==0) {
+ (*idx)++;
+ ret= Xorriso_option_status(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"status_history_max")==0) {
+ (*idx)++;
+ sscanf(arg1,"%d",&num1);
+ ret= Xorriso_option_status_history_max(xorriso, num1, 0);
+
+ } else if(strcmp(cmd,"tell_media_space")==0) {
+ Xorriso_option_tell_media_space(xorriso, 0);
+
+ } else if(strcmp(cmd,"temp_mem_limit")==0) {
+ (*idx)++;
+ ret= Xorriso_option_temp_mem_limit(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"test")==0) { /* This option does not exist. */
+ ;
+
+ } else if(strcmp(cmd,"toc")==0) {
+ Xorriso_option_toc(xorriso, 0);
+
+ } else if(strcmp(cmd,"uid")==0) {
+ (*idx)++;
+ ret= Xorriso_option_uid(xorriso,arg1,0);
+
+ } else if(strcmp(cmd,"update")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_update(xorriso, arg1, arg2, 1);
+
+ } else if(strcmp(cmd,"update_r")==0) {
+ (*idx)+= 2;
+ ret= Xorriso_option_update(xorriso, arg1, arg2, 1|8);
+
+ } else if(strcmp(cmd,"volid")==0) {
+ (*idx)++;
+ ret= Xorriso_option_volid(xorriso,arg1,0);
+
+ } else if(strcmp(cmd,"use_readline")==0) {
+ (*idx)++;
+ ret= Xorriso_option_use_readline(xorriso, arg1, 0);
+
+ } else if(strcmp(cmd,"version")==0){
+ ret= Xorriso_option_version(xorriso, 0);
+
+ } else if(strcmp(cmd,"--")==0){
+ /* tis ok */;
+
+ } else if(was_dashed) {
+ if(xorriso->add_plainly>1)
+ goto add_plain_argument;
+unknown_option:;
+ sprintf(xorriso->info_text, "=== Not a known option:\n === '%s'\n",
+ original_cmd);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
+ {ret= 0; goto eval_any_problems;}
+
+ } else {
+ if(xorriso->add_plainly<=0)
+ goto unknown_option;
+add_plain_argument:;
+ (*idx)--;
+ ret= Xorriso_option_add(xorriso, (*idx)+1, argv, idx, 0);
+ (*idx)++;
+
+ }
+
+eval_any_problems:
+ ret= Xorriso_eval_problem_status(xorriso, ret, 0);
+ if(ret<0)
+ return(ret);
+
+ if(*idxis_dialog) && !(flag&1))
+ Xorriso_mark(xorriso,0);
+ fflush(stdout);
+ return(ret);
+}
+
+
+int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag)
+/*
+ bit0-bit15 are forwarded to Xorriso_interpreter
+
+ bit16= no pageing of info lines
+ bit17= print === bar even if xorriso->found<0
+*/
+{
+ int ret,argc= 0, idx= 1;
+ char **argv= NULL;
+ double tdiff;
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday(&tv,&tz);
+ Xorriso_reset_counters(xorriso,0);
+ xorriso->idle_time= 0.0;
+ tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec);
+
+ /* parse line into args */
+ ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv, 4);
+ if(ret<=0)
+ goto ex;
+ if(argc<2)
+ {ret= 1; goto ex;}
+ if(argv[1][0]=='#')
+ {ret= 1; goto ex;}
+
+ ret= Xorriso_interpreter(xorriso, argc, argv, &idx, flag&0xffff);
+ if(ret<0)
+ goto ex;
+ gettimeofday(&tv,&tz);
+ tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff-xorriso->idle_time;
+ if(tdiff<0.001)
+ tdiff= 0.001;
+ if(xorriso->error_count>0) {
+ sprintf(xorriso->info_text,
+ "----------------------------- %7.f errors encountered\n",
+ xorriso->error_count);
+ Xorriso_info(xorriso,!(flag&(1<<16)));
+ }
+
+ /* ??? >>> print elapsed time tdiff ? */;
+
+ if((flag&(1<<17)) && !xorriso->bar_is_fresh) {
+ sprintf(xorriso->info_text,"============================\n");
+ Xorriso_info(xorriso,0);
+ xorriso->bar_is_fresh= 1;
+ }
+ Xorriso_reset_counters(xorriso,0);
+ex:;
+ Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */
+ return(ret);
+}
+
+
+int Xorriso_dialog(struct XorrisO *xorriso, int flag)
+{
+ int ret,first_round;
+ char line[2*SfileadrL];
+
+ xorriso->is_dialog= 1;
+ for(first_round= 1;1;first_round= 0) {
+ if(xorriso->pending_option[0]!=0) {
+ Xorriso_mark(xorriso,0);
+ strcpy(line,xorriso->pending_option);
+ xorriso->pending_option[0]= 0;
+ } else {
+ if(!xorriso->bar_is_fresh) {
+ sprintf(xorriso->info_text,"============================\n");
+ Xorriso_info(xorriso,0);
+ xorriso->bar_is_fresh= 1;
+ }
+ sprintf(xorriso->info_text,"enter option and arguments :\n");
+ Xorriso_info(xorriso,0);
+ Xorriso_mark(xorriso,0);
+ ret= Xorriso_dialog_input(xorriso,line,sizeof(line),4);
+ if(ret<=0)
+ break;
+ }
+ sprintf(xorriso->info_text,
+ "==============================================================\n");
+ Xorriso_info(xorriso,0);
+
+ ret= Xorriso_execute_option(xorriso,line,1<<17);
+ if(ret<0)
+ goto ex;
+ if(ret==3)
+ break;
+ xorriso->did_something_useful= 1;
+ xorriso->no_volset_present= 0; /* Re-enable "No ISO image present." */
+ }
+ ret= 1;
+ex:;
+ xorriso->is_dialog= 0;
+ return(ret);
+}
+
+
+int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag)
+{
+ if(xorriso->dev_fd_1>=0)
+ return(2);
+ xorriso->dev_fd_1= dup(1);
+ close(1);
+ dup2(2,1);
+ return(1);
+}
+
+
+int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv,
+ int flag)
+/*
+ bit0= do not interpret argv[1]
+*/
+/*
+ return:
+ <0 error
+ 0 end program
+ 1 ok, go on
+*/
+{
+ int i, ret, was_dashed, num2;
+ int was_report_about= 0, was_abort_on= 0, was_return_with= 0;
+ char *cmd, *original_cmd, cmd_data[5*SfileadrL], *arg1, *arg2;
+
+ for(i=1+(flag&1);i1)
+ xorriso->did_something_useful= 1;
+ if(i==1 && argc==2) {
+ if(strcmp(cmd,"prog_help")==0) {
+ i++;
+ Xorriso_option_prog_help(xorriso,arg1,0);
+ xorriso->did_something_useful= 1;
+ return(0);
+ } else if(strcmp(cmd,"help")==0) {
+ Xorriso_option_help(xorriso,0);
+ xorriso->did_something_useful= 1;
+ return(0);
+ }
+ } else if(i==1 && strcmp(cmd,"no_rc")==0) {
+ ret= Xorriso_option_no_rc(xorriso, 0);
+ if(ret<=0)
+ return(ret);
+
+ } else if((strcmp(cmd,"dev")==0 || strcmp(cmd,"outdev")==0 ||
+ strcmp(cmd,"indev")==0) &&
+ (strcmp(arg1,"stdio:/dev/fd/1")==0 || strcmp(arg1,"-")==0) &&
+ xorriso->dev_fd_1<0) {
+ /* Detach fd 1 from externally perceived stdout and attach it to stderr.
+ Keep dev_fd_1 connected to external stdout. dev_fd_1 is to be used when
+ "stdio:/dev/fd/1" is interpreted as drive address.
+ */
+protect_stdout:;
+ Xorriso_protect_stdout(xorriso, 0);
+ sprintf(xorriso->info_text,
+ "Encountered - or stdio:/dev/fd/1 as possible write target.");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ sprintf(xorriso->info_text,
+ "Redirecting nearly all text message output to stderr.");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ sprintf(xorriso->info_text, "Disabling use of libreadline.");
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+
+ } else if(strcmp(cmd,"abort_on")==0 && was_dashed) {
+ i++;
+ if(!was_abort_on)
+ Xorriso_option_abort_on(xorriso, arg1, 0);
+ was_abort_on= 1;
+
+ } else if(strcmp(cmd,"report_about")==0 && was_dashed) {
+ i++;
+ if(!was_report_about)
+ Xorriso_option_report_about(xorriso, arg1, 0);
+ was_report_about= 1;
+
+ } else if(strcmp(cmd,"return_with")==0 && was_dashed) {
+ i+= 2;
+ num2= 0;
+ sscanf(arg2,"%d",&num2);
+ if(!was_return_with)
+ Xorriso_option_return_with(xorriso, arg1, num2, 0);
+ was_return_with= 1;
+
+ } else if(strcmp(cmd,"as")==0 && was_dashed) {
+ if(strcmp(arg1, "mkisofs")==0 || strcmp(arg1, "genisoimage")==0 ||
+ strcmp(arg1, "genisofs")==0)
+ goto protect_stdout;
+
+ }
+ }
+ return(1);
+}
+
+
+/** Load content startup files into preskin cache */
+int Xorriso_read_rc(struct XorrisO *xorriso, int flag)
+{
+ int ret,i,was_failure= 0,fret;
+
+ i= xorriso->rc_filename_count-1;
+ Sfile_home_adr_s(".xorrisorc", xorriso->rc_filenames[i],
+ sizeof(xorriso->rc_filenames[i]),0);
+ for(i=0;irc_filename_count;i++) {
+ ret= Sfile_type(xorriso->rc_filenames[i],1|8);
+ if(ret!=1)
+ continue;
+ ret= Xorriso_option_options_from_file(xorriso,xorriso->rc_filenames[i],0);
+ if(ret>1)
+ return(ret);
+ if(ret==1)
+ continue; /* regular bottom of loop */
+ was_failure= 1;
+ fret= Xorriso_eval_problem_status(xorriso, ret, 1);
+ if(fret>=0)
+ continue;
+ return(ret);
+ }
+ return(!was_failure);
+}
+
+
+int Xorriso_make_return_value(struct XorrisO *xorriso, int flag)
+{
+ int exit_value= 0;
+
+ if(xorriso->eternal_problem_status >= xorriso->return_with_severity)
+ exit_value= xorriso->return_with_value;
+ if(exit_value) {
+ sprintf(xorriso->info_text,
+ "-return_with %s %d triggered by problem severity %s",
+ xorriso->return_with_text, exit_value,
+ xorriso->eternal_problem_status_text);
+ Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
+ }
+ return(exit_value);
+}
+
+
+#ifdef Xorriso_with_maiN
+
+int main(int argc, char **argv)
+{
+
+#else
+
+int Xorriso_main(int argc, char **argv)
+{
+
+#endif /* Xorriso_with_maiN */
+
+ int ret,i;
+ struct XorrisO *xorriso= NULL;
+
+ if(argc<2) {
+ fprintf(stderr,
+ "xorriso %s : RockRidge filesystem manipulator, libburnia project.\n\n",
+ Xorriso_program_versioN);
+ fprintf(stderr,"usage : %s [options]\n",
+ argv[0]);
+ fprintf(stderr," More is told by option -help\n");
+ exit(2);
+ }
+ ret= Xorriso_new(&xorriso,argv[0],0);
+ if(ret<=0) {
+ fprintf(stderr,"Creation of XorrisO object failed. (not enough memory ?)\n");
+ exit(3);
+ }
+
+ /* The prescan of arguments performs actions which have to happen before
+ the normal processing of startup files and arguments.
+ */
+ ret= Xorriso_prescan_args(xorriso,argc,argv,0);
+ if(ret==0)
+ goto end_sucessfully;
+ if(ret<0)
+ exit(5);
+
+ fprintf(stderr,
+ "xorriso %s : RockRidge filesystem manipulator, libburnia project.\n\n",
+ Xorriso_program_versioN);
+ ret= Xorriso_startup_libraries(xorriso, 0);
+ if(ret<=0)
+ exit(4);
+ Xorriso_process_msg_queues(xorriso, 0);
+
+ /* Interpret startup file */
+ if(!xorriso->no_rc) {
+ ret= Xorriso_read_rc(xorriso, 0);
+ if(ret==3)
+ goto end_sucessfully;
+ if(ret<=0)
+ exit(5);
+ }
+
+ /* Interpret program arguments */
+ i= 1;
+ ret= Xorriso_interpreter(xorriso,argc,argv,&i,0);
+ if(ret==3)
+ goto end_sucessfully;
+ if(ret<=0)
+ exit(5);
+
+ if(xorriso->dialog) {
+ ret= Xorriso_dialog(xorriso,0);
+ if(ret<=0)
+ exit(6);
+ }
+end_sucessfully:;
+ Xorriso_process_msg_queues(xorriso, 0);
+ if(xorriso->volset_change_pending)
+ Xorriso_option_end(xorriso, 2);
+ Xorriso_process_msg_queues(xorriso, 0);
+ ret= Xorriso_make_return_value(xorriso, 0);
+ Xorriso_process_errfile(xorriso, 0, "xorriso end", 0, 1);
+ Xorriso_destroy(&xorriso,1);
+ exit(ret);
+}
+
diff --git a/libisoburn/branches/ZeroOneSix/xorriso/xorriso.h b/libisoburn/branches/ZeroOneSix/xorriso/xorriso.h
new file mode 100644
index 00000000..cc9d6b1a
--- /dev/null
+++ b/libisoburn/branches/ZeroOneSix/xorriso/xorriso.h
@@ -0,0 +1,495 @@
+
+/* Command line oriented batch and dialog tool which creates, loads,
+ manipulates and burns ISO 9660 filesystem images.
+
+ Copyright 2007-2008 Thomas Schmitt,
+
+ Provided under GPL version 2.
+
+ This file contains the public option interface of xorriso.
+*/
+
+#ifndef Xorriso_includeD
+#define Xorriso_includeD yes
+
+/** Opaque handle of the xorriso runtime context */
+struct XorrisO;
+
+
+/* --------------------- Fundamental Management ------------------- */
+
+/* Create a new xorriso object and tell it the program name to be used
+ with messages.
+*/
+int Xorriso_new(struct XorrisO ** xorriso, char *progname, int flag);
+
+
+/* Make global library initializations.
+ This must be done with the first xorriso object that gets created and
+ with the first xorriso object that gets created after Xorriso_destroy(,1).
+*/
+int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag);
+
+
+/* Destroy xorriso object when it is no longer needed.
+ @param flag bit0= Make global librariy shutdown.
+ Use only with last xorriso object to be destroyed.
+
+*/
+int Xorriso_destroy(struct XorrisO **xorriso, int flag);
+
+
+/* --------------------- Problem Status and Message API ------------------- */
+
+
+/** Submit a problem message to the xorriso problem reporting and handling
+ system. This will eventually increase problem status rank, which may
+ at certain stages in the program be pardoned and reset to 0.
+ The pardon is governed by Xorriso_option_abort_on() and by the anger
+ of the affected program part. If no pardon has been given, then the problem
+ status reaches the caller of option functions.
+ Problem status should be inquired by Xorriso_eval_problem_status() and be
+ reset before next option execution by Xorriso_set_problem_status().
+ The problem status itself does not cause the failure of option functions.
+ But in case of failures for other reasons, a remnant overly severe problem
+ status can cause overly harsh program reactions.
+ @param xorriso The environment handle
+ @param error_code The unique error code of your message.
+ Submit 0 if you do not have reserved error codes within
+ the libburnia project.
+ @param msg_text Not more than 8196 characters of message text.
+ A final newline character gets appended automatically.
+ @param os_errno Eventual errno related to the message. Submit 0 if
+ the message is not related to a operating system error.
+ @param severity One of "ABORT", "FATAL", "SORRY", "WARNING", "HINT",
+ "NOTE", "UPDATE", "DEBUG". Defaults to "FATAL".
+ @param flag Bitfield for control purposes
+ bit0= use pager (as with result)
+ bit1= permission to suppress output
+ @return 1 if message was delivered, <=0 if failure
+*/
+int Xorriso_msgs_submit(struct XorrisO *xorriso,
+ int error_code, char msg_text[], int os_errno,
+ char severity[], int flag);
+
+
+/** Evaluate an advise whether to abort or whether to go on with option
+ processing. This should be called after any option function was processed.
+ It updates the problem status by processing the library message queues
+ and then it uses this status and the submitted return value ot the
+ option function to evaluate the situation.
+ @param xorriso The environment handle
+ @param ret The return value of the previously called option function
+ @param flag bit0= do not issue own event messages
+ bit1= take xorriso->request_to_abort as reason for abort
+ @return Gives the advice:
+ 2= pardon was given, go on
+ 1= no problem, go on
+ 0= function failed but xorriso would not abort, go on
+ <0= do abort
+ -1 = due to xorriso->problem_status
+ or due to ret<0
+ -2 = due to xorriso->request_to_abort
+*/
+int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag);
+
+
+/** Set the current problem status of the xorriso handle.
+ @param xorriso The environment handle
+ @param severity A severity text. Empty text resets to "No Problem".
+ @param flag Unused yet. Submit 0.
+ @return <=0 failure (e.g. wrong severity text), 1 success.
+*/
+int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity,
+ int flag);
+
+
+/* The next two functions are part of Xorriso_eval_problem_status().
+ You may use them to build an own advisor function or to drain the
+ library message queues more frequently.
+*/
+
+/** Obtain the current problem status of the xorriso handle.
+ @param xorriso The environment handle
+ @param severity The severity text matching the current problem status
+ @param flag Unused yet. Submit 0.
+ @return The severity rank number. 0= no problem occured.
+*/
+int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80],
+ int flag);
+
+
+/** Forward any pending messages from the library message queues to the
+ xorriso message system which puts out on info channel. This registers
+ the severity of the library events like the severity of a message submitted
+ via Xorriso_msgs_submit().
+ xorriso sets the message queues of the libraries to queuing "ALL".
+ So it is essential that they get drained regularly.
+ @param xorriso The environment handle
+ @param flag Unused yet. Submit 0.
+ @return 1 on success, <=0 if failure
+*/
+int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag);
+
+
+
+/* ---------------------------- Options API ------------------------ */
+/* See man 1 xorriso for explanation of the particular options */
+/*
+ Before each call to an option function, there should happen:
+ Xorriso_set_problem_status() with empty severity text.
+
+ After each call to an option function, there should happen:
+ Xorriso_eval_problem_status()
+ One should follow its eventual advice to abort.
+*/
+
+
+/* Option -abort_on */
+int Xorriso_option_abort_on(struct XorrisO *xorriso, char *severity, int flag);
+
+/* Option -add */
+/* @param flag bit0=do not report the added item
+ bit1=do not reset pacifier, no final pacifier message
+*/
+int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Option -add_plainly "on"|"off" */
+int Xorriso_option_add_plainly(struct XorrisO *xorriso, char *mode,
+ int flag);
+
+
+/* Option -alter_date, alter_date_r */
+/* @param flag bit0=recursive (-alter_date_r)
+*/
+int Xorriso_option_alter_date(struct XorrisO *xorriso,
+ char *time_type, char *timestring,
+ int argc, char **argv, int *idx, int flag);
+
+/* Option -ban_stdio_write */
+int Xorriso_option_ban_stdio_write(struct XorrisO *xorriso, int flag);
+
+/* Option -blank and -format */
+/* @param flag bit0= format rather than blank
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -boot_image */
+int Xorriso_option_boot_image(struct XorrisO *xorriso, char *form,
+ char *treatment, int flag);
+
+/* Option -cd alias -cdi */
+int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag);
+
+/* Option -cdx */
+int Xorriso_option_cdx(struct XorrisO *xorriso, char *disk_path, int flag);
+
+/* Option -chgrp alias -chgrpi , chgrp_r alias chgrpi */
+/* @param flag bit0=recursive (-chgrp_r)
+*/
+int Xorriso_option_chgrpi(struct XorrisO *xorriso, char *gid,
+ int argc, char **argv, int *idx, int flag);
+
+/* Option -chmod alias -chmodi , -chmod_r alias chmod_ri */
+/* @param flag bit0=recursive (-chmod_r)
+*/
+int Xorriso_option_chmodi(struct XorrisO *xorriso, char *mode,
+ int argc, char **argv, int *idx, int flag);
+
+/* Option -chown alias -chowni , chown_r alias chown_ri */
+/* @param flag bit0=recursive (-chown_r)
+*/
+int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid,
+ int argc, char **argv, int *idx, int flag);
+
+/* Option -close "on"|"off" */
+int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -commit */
+/* @param flag bit0= leave indrive and outdrive aquired as they were,
+ i.e. do not aquire outdrive as new in-out-drive
+ bit1= do not perform eventual -reassure
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_commit(struct XorrisO *xorriso, int flag);
+
+/* Option -commit_eject */
+/* @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_commit_eject(struct XorrisO *xorriso, char *which, int flag);
+
+/* Option -compare and -compare_r
+ @param flag bit0= issue summary message
+ bit1= do not reset pacifier, no final pacifier message
+ bit2= do not issue pacifier messages at all
+ bit3= recursive: -compare_r
+*/
+int Xorriso_option_compare(struct XorrisO *xorriso, char *disk_path,
+ char *iso_path, int flag);
+
+/* Option -cpr alias -cpri */
+int Xorriso_option_cpri( struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Option -cut_out */
+int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path,
+ char *start, char *count, char *iso_rr_path, int flag);
+
+/* Options -dev , -indev, -outdev */
+/* @param flag bit0=use as indev , bit1= use as outdev
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_dev(struct XorrisO *xorriso, char *adr, int flag);
+
+/* Option -devices */
+/* @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_devices(struct XorrisO *xorriso, int flag);
+
+/* Option -dialog "on"|"off" */
+int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -disk_pattern "on"|"ls"|"off" */
+int Xorriso_option_disk_pattern(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -dummy "on"|"off" */
+int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -eject */
+/* @param flag bit0=do not report toc of eventually remaining drives
+*/
+int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag);
+
+/* Options -end , and -rollback_end */
+/* @param flag bit0= discard pending changes
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_end(struct XorrisO *xorriso, int flag);
+
+/* Option -errfile_log marked|plain path|-|"" */
+int Xorriso_option_errfile_log(struct XorrisO *xorriso,
+ char *mode, char *path, int flag);
+
+/* Option -error_behavior */
+int Xorriso_option_error_behavior(struct XorrisO *xorriso,
+ char *occasion, char *behavior, int flag);
+
+/* Option -iso_rr_pattern "on"|"ls"|"off" */
+int Xorriso_option_iso_rr_pattern(struct XorrisO *xorriso, char *mode,
+ int flag);
+
+/* Option -follow */
+int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -find alias -findi, and -findx */
+/* @param flag bit0= -findx rather than -findi
+ bit1= do not reset pacifier, no final pacifier message
+ do not reset find_compare_result
+*/
+int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Option -fs */
+int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag);
+
+/* Option -gid */
+int Xorriso_option_gid(struct XorrisO *xorriso, char *gid, int flag);
+
+/* Option -help and part of -prog_help */
+int Xorriso_option_help(struct XorrisO *xorriso, int flag);
+
+/* Option -history */
+int Xorriso_option_history(struct XorrisO *xorriso, char *line, int flag);
+
+/* Option -joliet "on"|"off" */
+int Xorriso_option_joliet(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -list_formats */
+int Xorriso_option_list_formats(struct XorrisO *xorriso, int flag);
+
+/* Option -load session|track|sbsector value */
+/* @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_load(struct XorrisO *xorriso, char *adr_mode,
+ char *adr_value, int flag);
+
+/* Option -logfile */
+int Xorriso_option_logfile(struct XorrisO *xorriso, char *channel,
+ char *fileadr, int flag);
+
+/* Options -ls alias -lsi and -lsl alias -lsli
+ and -lsd alias -lsdi and -lsdl alias -lsdli
+ and -du alias -dui and -dus alias -dusi
+ @param flag bit0= long format (-lsl , -du)
+ bit1= do not expand patterns but use literally
+ bit2= du rather than ls
+ bit3= list directories as themselves (ls -d)
+*/
+int Xorriso_option_lsi(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Options -lsx, -lslx, -lsdx , -lsdlx , -dux , -dusx
+ @param flag bit0= long format (-lslx , -dux)
+ bit1= do not expand patterns but use literally
+ bit2= du rather than ls
+ bit3= list directories as themselves (ls -d)
+*/
+int Xorriso_option_lsx(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Option -map */
+/* @param flag bit0=do not report the added item
+ bit1=do not reset pacifier, no final pacifier message
+*/
+int Xorriso_option_map(struct XorrisO *xorriso, char *disk_path,
+ char *iso_path, int flag);
+
+/* Option -mark */
+int Xorriso_option_mark(struct XorrisO *xorriso, char *mark, int flag);
+
+/* Option -mkdir alias -mkdiri */
+int Xorriso_option_mkdiri(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Option -mv alias -mvi */
+int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Option -no_rc */
+int Xorriso_option_no_rc(struct XorrisO *xorriso, int flag);
+
+/* Option -not_leaf */
+int Xorriso_option_not_leaf(struct XorrisO *xorriso, char *pattern, int flag);
+
+/* Option -not_paths */
+int Xorriso_option_not_paths(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Option -options_from_file*/
+/* @return <=0 error , 1 = success , 3 = request to end program run */
+int Xorriso_option_options_from_file(struct XorrisO *xorriso, char *adr,
+ int flag);
+
+/* Option -overwrite "on"|"nondir"|"off" */
+int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -padding */
+int Xorriso_option_padding(struct XorrisO *xorriso, char *size, int flag);
+
+/* Option -page */
+int Xorriso_option_page(struct XorrisO *xorriso, int len, int width, int flag);
+
+/* Option -path-list */
+int Xorriso_option_path_list(struct XorrisO *xorriso, char *adr, int flag);
+
+/* Option -pathspecs */
+int Xorriso_option_pathspecs(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -pkt_output */
+int Xorriso_option_pkt_output(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -print */
+int Xorriso_option_print(struct XorrisO *xorriso, char *text, int flag);
+
+/* Option -print_size
+ @param flag bit0= report in mkisofs compatible form on real stdout
+*/
+int Xorriso_option_print_size(struct XorrisO *xorriso, int flag);
+
+/* Option -prog */
+int Xorriso_option_prog(struct XorrisO *xorriso, char *name, int flag);
+
+/* Option -prog_help */
+int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag);
+
+/* Option -publisher */
+int Xorriso_option_publisher(struct XorrisO *xorriso, char *name, int flag);
+
+/* Option -pwd alias -pwdi */
+int Xorriso_option_pwdi(struct XorrisO *xorriso, int flag);
+
+/* Option -pwdx */
+int Xorriso_option_pwdx(struct XorrisO *xorriso, int flag);
+
+/* Option -reassure "on"|"tree"|"off" */
+int Xorriso_option_reassure(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -report_about */
+int Xorriso_option_report_about(struct XorrisO *xorriso, char *severity,
+ int flag);
+
+/* Option -return_with */
+int Xorriso_option_return_with(struct XorrisO *xorriso, char *severity,
+ int exit_value, int flag);
+
+/* Option -revoke_exclusions */
+int Xorriso_option_revoke_exclusions(struct XorrisO *xorriso, int flag);
+
+/* Options -rm alias -rmi , -rm_r alias -rm_ri , -rmdir alias -rmdiri */
+/* @param flag bit0=recursive , bit2= remove empty directory: rmdir */
+int Xorriso_option_rmi(struct XorrisO *xorriso, int argc, char **argv,
+ int *idx, int flag);
+
+/* Option -rollback */
+/* @param flag bit0= do not -reassure
+ @return <=0 error , 1 success, 2 revoked by -reassure
+*/
+int Xorriso_option_rollback(struct XorrisO *xorriso, int flag);
+
+/* Option -rom_toc_scan */
+int Xorriso_option_rom_toc_scan(struct XorrisO *xorriso, char *mode,
+ int flag);
+
+/* Option -session_log */
+int Xorriso_option_session_log(struct XorrisO *xorriso, char *path, int flag);
+
+/* Option -speed */
+int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag);
+
+/* Option -split_size */
+int Xorriso_option_split_size(struct XorrisO *xorriso, char *s, int flag);
+
+/* Option -status */
+int Xorriso_option_status(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -status_history_max */
+int Xorriso_option_status_history_max(struct XorrisO *xorriso, int num1,
+ int flag);
+
+/* Option -tell_media_space */
+int Xorriso_option_tell_media_space(struct XorrisO *xorriso, int flag);
+
+/* Option -temp_mem_limit */
+int Xorriso_option_temp_mem_limit(struct XorrisO *xorriso, char *size,
+ int flag);
+
+/* Option -toc */
+int Xorriso_option_toc(struct XorrisO *xorriso, int flag);
+
+/* Option -uid */
+int Xorriso_option_uid(struct XorrisO *xorriso, char *uid, int flag);
+
+/* Options -update and -update_r
+ @param flag bit0= issue summary message
+ bit1= do not reset pacifier, no final pacifier message
+ bit2= do not issue pacifier messages at all
+ bit3= recursive: -update_r
+*/
+int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path,
+ char *iso_path, int flag);
+
+/* Option -use_readline */
+int Xorriso_option_use_readline(struct XorrisO *xorriso, char *mode, int flag);
+
+/* Option -version */
+int Xorriso_option_version(struct XorrisO *xorriso, int flag);
+
+/* Option -volid */
+int Xorriso_option_volid(struct XorrisO *xorriso, char *volid, int flag);
+
+
+#endif /* Xorriso_includeD */
+
+
diff --git a/libisoburn/branches/ZeroOneSix/xorriso/xorriso_eng.html b/libisoburn/branches/ZeroOneSix/xorriso/xorriso_eng.html
new file mode 100644
index 00000000..3cfad486
--- /dev/null
+++ b/libisoburn/branches/ZeroOneSix/xorriso/xorriso_eng.html
@@ -0,0 +1,461 @@
+
+
+
+
+
+
+xorriso homepage english
+
+
+
+
+
+
+ Homepage of
+ xorriso
+
+ISO 9660 Rock Ridge Filesystem Manipulator for Linux
+
+
+
+
Purpose:
+xorriso maps file objects from POSIX compliant filesystems
+into Rock Ridge enhanced ISO 9660 filesystems and allows
+session-wise manipulation of such filesystems. It can load the management
+information of existing ISO images and it writes the session results to
+optical media or to filesystem objects.
+
+
+
+
+
+