This appendix describes genfile, an auxiliary program used in the GNU tar testsuite. If you are not interested in developing GNU tar, skip this appendix.

Initially, genfile was used to generate data files for the testsuite, hence its name. However, new operation modes were being implemented as the testsuite grew more sophisticated, and now genfile is a multi-purpose instrument.

There are three basic operation modes:

File Generation
     This is the default mode. In this mode, genfile generates data files.

File Status
     In this mode genfile displays status of specified files.

Synchronous Execution.
     In this mode genfile executes the given program with --checkpoint option and executes a set of actions when specified checkpoints are reached.

Generate Mode
=============

In this mode genfile creates a data file for the test suite. The size of the file is given with the --length (-l) option. By default the file contents is written to the standard output, this can be changed using --file (-f) command line option. Thus, the following two commands are equivalent:

     genfile --length 100 > outfile
     genfile --length 100 --file outfile

If --length is not given, genfile will generate an empty (zero-length) file.

You can instruct genfile to create several files at one go, by giving it --files-from (-T) option followed by a name of file containing a list of file names. Using dash (-) instead of the file name causes genfile to read file list from the standard input. For example:

     # Read file names from file file.list
     genfile --files-from file.list
     # Read file names from standard input
     genfile --files-from -

The list file is supposed to contain one file name per line. To use file lists separated by ASCII NUL character, use --null (-0) command line option:

     genfile --null --files-from file.list

The default data pattern for filling the generated file consists of first 256 letters of ASCII code, repeated enough times to fill the entire file. This behavior can be changed with --pattern option. This option takes a mandatory argument, specifying pattern name to use. Currently two patterns are implemented:

--pattern=default
     The default pattern as described above.

--pattern=zero
     Fills the file with zeroes.

If no file name was given, the program exits with the code 0.  Otherwise, it exits with 0 only if it was able to create a file of the specified length.

Special option --sparse (-s) instructs genfile to create a sparse file. Sparse files consist of data fragments, separated by holes or blocks of zeros. On many operating systems, actual disk storage is not allocated for holes, but they are counted in the length of the file. To create a sparse file, genfile should know where to put data fragments, and what data to use to fill them. So, when --sparse is given the rest of the command line specifies a so-called file map.

The file map consists of any number of fragment descriptors. Each descriptor is composed of two values: a number, specifying fragment offset from the end of the previous fragment or, for the very first fragment, from the beginning of the file, and contents string, i.e., a string of characters, specifying the pattern to fill the fragment with. File offset can be suffixed with the following quantifiers:

k
K
     The number is expressed in kilobytes.

m
M
     The number is expressed in megabytes.

g
G
     The number is expressed in gigabytes.

For each letter in contents string genfile will generate a block of data, filled with this letter and will write it to the fragment. The size of block is given by --block-size option. It defaults to 512. Thus, if the string consists of N characters, the resulting file fragment will contain N*BLOCK-SIZE of data.

Last fragment descriptor can have only file offset part. In this case genfile will create a hole at the end of the file up to the given offset.

For example, consider the following invocation:

     genfile --sparse --file sparsefile 0 ABCD 1M EFGHI 2000K

It will create 3101184-bytes long file of the following structure:

Offset    Length         Contents
0         4*512=2048     Four 512-byte blocks, filled with
letters A, B, C and D.
2048      1046528        Zero bytes
1050624   5*512=2560     Five blocks, filled with letters
E, F, G, H, I.
1053184    2048000       Zero bytes

The exit code of genfile --status command is 0 only if created file is actually sparse.

Status Mode
===========

In status mode, genfile prints file system status for each file specified in the command line. This mode is toggled by --stat (-S) command line option. An optional argument to this option specifies output format: a comma-separated list of struct stat fields to be displayed. This list can contain following identifiers should we also support % notations as in stat(1)??:

name
     The file name.

dev
st_dev
     Device number in decimal.

ino
st_ino
     Inode number.

mode[.NUMBER]
st_mode[.NUMBER]
     File mode in octal.  Optional NUMBER specifies octal mask to be applied to the mode before outputting.  For example, --stat mode.777 will preserve lower nine bits of it.  Notice, that you can use any punctuation character in place of ..

nlink
st_nlink
     Number of hard links.

uid
st_uid
     User ID of owner.

gid
st_gid
     Group ID of owner.

size
st_size
     File size in decimal.

blksize
st_blksize
     The size in bytes of each file block.

blocks
st_blocks
     Number of blocks allocated.

atime
st_atime
     Time of last access.

mtime
st_mtime
     Time of last modification

ctime
st_ctime
     Time of last status change

sparse
     A boolean value indicating whether the file is sparse.

Modification times are displayed in UTC as UNIX timestamps, unless suffixed with H (for ``human-readable''), as in ctimeH, in which case usual tar tv output format is used.

The default output format is: name,dev,ino,mode, nlink,uid,gid,size,blksize,blocks,atime,mtime,ctime.

For example, the following command will display file names and corresponding times of last access for each file in the current working directory:

     genfile --stat=name,atime *

Exec Mode
=========

This mode is designed for testing the behavior of paxutils commands when some of the files change during archiving. It is an experimental mode.

The Exec Mode is toggled by --run command line option (or its alias -r). The argument to this option gives the command line to be executed. The actual command line is constructed by inserting --checkpoint option between the command name and its first argument (if any). Due to this, the argument to --run may not use traditional tar option syntax, i.e., the following is wrong:

     # Wrong!
     genfile --run 'tar cf foo bar'

Use the following syntax instead:

     genfile --run 'tar -cf foo bar'

The rest of command line after --run or its equivalent specifies checkpoint values and actions to be executed upon reaching them. Checkpoint values are introduced with --checkpoint command line option. Argument to this option is the number of checkpoint in decimal.

Any number of actions may be specified after a checkpoint. Available actions are

--cut FILE
--truncate FILE
     Truncate FILE to the size specified by previous --length option (or 0, if it is not given).

--append FILE
     Append data to FILE. The size of data and its pattern are given by previous --length and pattern options.

--touch FILE
     Update the access and modification times of FILE. These timestamps are changed to the current time, unless --date option was given, in which case they are changed to the specified time. Argument to --date option is a date specification in an almost arbitrary format (see Date input formats).

--exec COMMAND
     Execute given shell command.

Option --verbose instructs genfile to print on standard output notifications about checkpoints being executed and to verbosely describe exit status of the command.

While the command is being executed its standard output remains connected to descriptor 1. All messages it prints to file descriptor 2, except checkpoint notifications, are forwarded to standard error.

Genfile exits with the exit status of the executed command.