AFIO(1)
Okay bestie, welcome to afio(1) from the General Commands Manual π It's giving archive queen, and it's iconic at moving files around π
β¨ NAME β¨
afio β manipulate archives and files π¦
πΈ SYNOPSIS πΈ
... | afio -o [ options ] archive : write (create) archive
afio -i [ options ] archive : install (unpack) archive
afio -t [ options ] archive : list table-of-contents of archive
afio -r [ options ] archive : verify archive against filesystem
afio -p [ options ] directory [ ... ] : copy files
Five modes, babe: -o writes, -i installs, -t lists, -r verifies, and -p copies π
π DESCRIPTION π
Afio manipulates groups of files, copying them within the (collective) filesystem or between the filesystem and an afio archive π§
With -o, it reads pathnames from the standard input and writes an archive π¦
With -t, it reads an archive and writes a table-of-contents to the standard output π
With -i, it installs the contents of an archive relative to the working directory π‘
With -p, it reads pathnames from the standard input and copies the files to each directory. It cannot be combined with the -Z option π«
With -r, it reads an archive and verifies it against the filesystem. This is super useful for checking tape archives to make sure they have no bit errors π The verification compares file contents, but not permission bits and non-file filesystem entities. So it cannot be used as a reliable tool to detect every possible change made to a filesystem. Not a full security check, bestie π
Afio creates missing directories as necessary, with permissions to match their parents π
Afio also removes leading slashes from pathnames, making all paths relative to the current directory. This is a safety feature to prevent inadvertent overwriting of system files when doing restores π‘οΈ To suppress this safety feature, the -A option must be used while writing an archive, but also when reading (installing), verifying, and cataloging an existing archive π
Afio supports compression while archiving, with the -Z option. It compresses individual files in the archive, not the entire archive datastream, which makes afio compressed archives much more robust than tar zc' type archives π₯
Afio supports multi-volume archives during interactive operation, meaning when /dev/tty is accessible and SIGINT is not being ignored β¨
β¨ OPTIONS β¨
-@ addressβ Sends an email to address whenever a volume change (tape change, floppy change) is needed, and again when the entire operation is complete. It usessendmail(1)to send the mail π§-aβ Preserves the last access times (atimes) of the files read when making or verifying an archive. Warning: if you use this option, afio will change the last inode changed times (ctimes) of these files. So it cannot be used together with an incremental backup scheme that relies on the ctimes being preserved π-b sizeβ Reads or writes size-character archive blocks. The suffixesb,k,mandgmean multiples of 512, kilobytes, megabytes and gigabytes, respectively. It defaults to5120for compatibility withcpio(1). In some cases, notably when using ftape with some tape drives,-b 10kis needed for compatibility. Also,-b 10kis the default block size used bytar(1), so it's usually a good choice if your tape setup is known to work withtar(1)πΏ-c countβ Buffers count archive blocks between I/O operations. A large count is recommended for efficient use with streaming magnetic tape drives, because it reduces the number of tape stops and restarts ποΈ-dβ Don't create missing directories π ββοΈ-e boundβ Pads the archive to a multiple of bound characters. It recognizes the same suffixes as-s. It defaults to1x(the-bblock size) for compatibility withcpio(1)π§-fβ Spawns a child process to actually write to the archive. It's a clumsy form of double-buffering, but it works π«Ά It requires-sfor multi-volume archive support.-gβ Changes to input file directories. This avoids quadratic filesystem behavior with long, similar pathnames π¦ It requires all absolute pathnames, including those for the-oarchive and the-pdirectories.-zβ π Prints execution statistics! This one's for human eyes, bestie, so other programs using it is officially discouraged π-Aβ πΏ Stops afio from turning absolute paths into relative ones, so the leading slash stays put. This covers path names written into an archive, and also path names read out of an archive duringread(install),verify, and cataloging operations.-Bβ π¦ If you use-v, this prints the byte offset where each file starts in the archive. If your tape drive can start reading from any position, the-Boutput is seriously useful for quick selective restores.-D controlscriptβ π Sets the control script name tocontrolscript. Check the section on control files below for the full scoop π-E [+]filename | -E CS | -E CIβ π« When you're making an archive with compressed files using-Z, this turns off compression attempts for files with certain extensions. It speeds things up because afio stops trying to gzip stuff that's already compressed! By default, if you don't give a specific-Eoption, files with these extensions won't be compressed:.Z .z .gz .bz2 .tgz .arc .zip .rar .lzh .lha .uc2 .tpz .taz .tgz .rpm .zoo .deb .gif .jpeg .jpg .tif .tiff .png .pdf .arj .avi .bgb .cab .cpn .hqx .jar .mp3 .mpg .mpq .pic .pkz .psn .sit .ogg and .smk. Extension matching is also case-insensitive by default, so it does the right thing with MS-DOS based filesystems π«Ά The-E filenameform replaces the default list by reading a new list of extensions fromfilename, separated by whitespace.filenamecan have comments preceded by a#. The extensions should usually start with a dot, but they don't have to. For example, the extensiontzwill match the file namehertz. The-E +filenameform (with a+in front offilename) adds extensions to the built-in default list instead of replacing the whole thing. To make extension matching case-sensitive, add-E CSto the command line.-E CIinvokes the (default) case-insensitive comparison. See also the-6option, which offers another way to suppress compression β¨-Fβ πΎ This is a floppy disk, so-sis required! It causes floppy writing inO_SYNCmode under Linux. With kernel version 1.1.54 and above, afio can detect some floppy errors while writing. It uses shared memory if that's compiled in, otherwise it mallocs as needed (a 3b1 won't be able to malloc the memory it needs without shared memory). Either way, afio assumes you can malloc/shmalloc a chunk of memory the size of one disk. Examples: 795k: 3.5" (720k drive), 316k (360k drive). At the end of each disk, this message pops up:
Ready for disk [#] on [output]
(remove the disk when the light goes out)
Type "go" (or "GO") when ready to proceed
(or "quit" to abort):
-G factorβ ποΈ Sets the gzip(1) compression speed factor, used when compressing with-Z. Factor1is the fastest with the least compression, and9is the slowest with the best compression. The default is6. See also the gzip(1) manual page. If you have a slow machine or a fast backup medium, a low factor can speed up your backup. On large (>200k) files,-G 1typically zips twice as fast as-G 6, while still getting a better result than compress(1). For small files, the zip speed is mainly determined by how long it takes gzip(1) to get invoked, so check the-Toption for that π’-H promptscriptβ π¬ Runs a script instead of the normal prompt before moving on to the next archive volume. The script gets the volume number, archive specification, and the reason for switching volumes as arguments. It should exit with0for OK and1for abort. Other exit codes are treated as fatal errors. As of afio version 2.5.2,promptscriptcan be a file name with spaces or other special characters π-Jβ π Tries to keep going after a media write error during a backup. Normally afio aborts with a fatal error, but this option lets it push through.-Kβ π Verifies the output against what's in the memory copy of the disk (-Frequired). If writing or verifying fails, this menu pops up:
[Writing/Verify] of disk [disk #] has FAILED!
Enter 1 to RETRY this disk
Enter 2 to REFORMAT this disk before a RETRY
Enter quit to ABORT this backup
π¨ Heads up: afio does not currently process the answers1and2the right way! The menu above is only useful because it tells you something is wrong.
-L Log_file_pathβ π Specifies the file where errors and the final totals get logged.-M sizeβ π§ Sets the maximum amount of memory used for temporary storage of compression results when using-Z. The default is-M 250m(250 megabytes). If the compressed version of a file is larger than this (or if afio runs out of virtual memory), gzip(1) runs twice on that file. The first run figures out the length of the result, and the second run gets the compressed data itself π€―-P prognameβ π Usesprognameinstead of the standard gzip(1) for compression and decompression with-Z. For example,-Z -P bzip2writes and installs archives using bzip2(1) compression. Ifprognamedoesn't take command line options in the style of gzip(1) (-c,-d, and-<number>), you can use the-Qoption to supply the right ones. The compression program must have this property: if the output file size exceeds the-Mvalue, then running the compression program a second time on the same input must produce output of exactly the same size. (See also the-Moption description.) The GnuPG (gpg) encryption program does not meet this length-preserving criterion unless its built-in compression is disabled. See the examples in the afio sourcescript3/directory. See also the-Q,-Uand-3options π-Q optβ π Passesoptto the compression or decompression program used with-Z. To pass multiple options, use-Qmultiple times. If no-Qflag is present, the standard options get passed:-c -6when the program is called for compression, and-c -dwhen it's called for decompression. If you want no options at all passed to the program, use the special case-Q ""π-R Disk format command stringβ π οΈ This is the command that runs when you enter 2 to reformat the disk after a failed verify. The default,fdformat /dev/fd0H1440, can be changed to a given system's default by editing the Makefile. You're also prompted for formatting whenever a disk change is requested.-Sβ π Stops afio from ignoring a leading slash in the pattern or file name when matching-yand-Ypatterns. See also-A.-T thresholdβ β±οΈ Only compresses a file with-Zif its length is at leastthreshold. The default is-T 0k. This is super handy if you have a slow machine or a fast backup medium.-T 3ktypically halves the number of gzip(1) invocations, saving about 30% of computation time, while making an archive only 5% longer. The combination-T 8k -G 1typically saves 70% of computation time and gives a 20% size increase, so it might be a good alternative to not using-Zat all. These numbers depend heavily on the kind of files in the archive and the processor-i/o speed ratio on your machine. See also the-2option.-Uβ π When used with-Z, this forces compressed versions of all files to be stored, even if they end up bigger than the originals. It also ignores any (default) values of-Tand-2. This is useful when-Pand-Qreplace gzip with an encryption program to make an archive with encrypted files. Due to internal limitations of afio, using this flag forces file content to be written with each hard linked file, rather than only once for every set of hard linked files.
WARNING: Using-Uwill also cause compression (or whatever operation-Pindicates) on files larger than 2 GB, if any are present in the input. Not all compression programs might handle such huge files correctly. Recent Linux versions of gzip, bzip2, and gpg have all been tested and seem to work OK. If your setup is obscure, some testing might be warranted π
-W filenameβ π Treats each line infilenameas a-Ypattern. See-Y.-Y patternβ π· Doesn't process files whose names match the shell wildcardpattern. See also-yand-W.-Zβ okay bestie, this one is SO iconic π When you create an archive, it squishes the files going in, and when you install one, it unsquishes them again β¨ The best part:afio -Zcompresses each file individually and leaves the archive headers uncompressed π«Ά So it's way more fault-tolerant against read errors on the backup medium thantar zcstyle archives. That's main character energy for protecting your stuff π‘οΈ- When you make an archive with
-Z, afio runsgzipon each file it encounters, and only keeps the compressed version if it's smaller than the original π It needsgzip(1)to be in your path, so make sure it's findable π - To keep things speedy, compression is skipped on a file if any of these are true πββοΈ
- the file is very small (see the
-Toption) - the file is very large (see the
-2option) - the file has a certain extension, so it probably contains compressed data already (see the
-Eoption) - the file pathname matches a certain pattern, as set by the
-6option - the file has hard links (this is an internal limitation of afio, but this limitation doesn't apply if the
-loption is also used)
- the file is very small (see the
- No matter what, if you use
-U, the compression program always runs and the compressed result always gets stored π - When installing an archive with compressed files, you need
-Zso afio automatically uncompresses the files it squished earlier π§ - Want a different compressor? The
-Poption lets you do the (un)compression with programs other than gzip. Check out the-P(and-Qand-3) options for the deets π¦ - And the
-Goption gives you yet another way to tune the compression process π
- When you make an archive with
-0β use filenames terminated with'\0'instead of'\n'. Hobbies: keeping your filenames weird π- With
find ... -print0 | afio -o -0 ..., it handles ANY input filename, even one with a newline in it π - With
afio -t -0 ... | ..., the table of contents output can be parsed unambiguously, even if filenames have newlines π -0also affects how the files given by-w fileand-W fileget parsed. If-0comes before them on the command line, the pattern lines in those files should be terminated with'\0'instead of'\n'π- A second
-0toggles it back off π - This is super useful when you're using multiple pattern files or combining with the
-toption β¨
- With
-1warnings-to-ignore β controls whether afio should exit with a nonzero code after printing certain warnings, and whether those warnings get printed at all π This is really handy when you're calling afio from inside a backup script or program. afio exits nonzero on various 'hard' errors, and also (with the default-1value) when it has printed certain warnings during execution. warnings-to-ignore is a list of letters that decides how warnings get handled.- The default is
-1 mc. - For afio versions 2.4.3 and earlier, the default was
-1 a. - For afio versions 2.4.4 and 2.4.5, the default was
-1 ''. - The letters are:
aβ ignore all possible warnings on exit. If this letter is used, printing a warning will never cause a nonzero exit code πmβ ignore in the exit code any warning about missing files. These get printed when creating an archive and a file whose name was read from standard input isn't found πcβ ignore in the exit code the warning that the archive being created won't be fully compatible with cpio or afio versions 2.4.7 or lowerCβ same asc, but the warning message won't even be printed π€«Mβ suppresses all warning messages associated with Multivolume archive handling, like "Output limit reached" and "Continuing" πΌdβ ignore in the exit code any warnings about changed files. These get printed when creating an archive and a file being archived changes while it's being written in. The changing is detected by checking the file modification time stamp β°rβ ignore certain warnings during the verify (-r) operation. If this letter is used, some verification errors that are very probably due to filesystem changes during or after the backup was made get ignored when determining the exit code. The two verification errors that are ignored are: 1) a file in the archive is no longer present on the filesystem, and 2) the file contents in the archive and on the filesystem are different, but the file lengths or the file modification times are also different. So the difference in contents is probably because the file on the filesystem got changed πsβ ignore in the exit code the warning printed when the protection code (as described in the section about the-8option) rewrites a suspicious path name for a file or symlink that's being unpacked π‘οΈlβ ignore in the exit code the warning printed when the-8 nosymlinksoption is used and a symlink is encountered πnβ ignore in the exit code a particular class of no-such-file warnings. It ignores these when they happen after the file has already been successfully opened. This unusual situation can happen when archiving files on Windows smbfs filesystems. Due to a Windows problem, smbfs files with non-ASCII characters in their names can sometimes be opened but not read πΈ When the-Zoption is used, thenletter is (currently) only implemented for files smaller than the size indicated by the-Toption, so in that case the-Toption is also needed for this letter to have any effect.
- The default is
-2maximum-file-size-to-compress β do not compress any files larger than this size when making a compressed archive with-Z. The default is-2 200m(200 Megabytes) π This cutoff lowers the risk that a major portion of a large file gets lost to small media errors.- If a media error happens while reading a file that afio stored in compressed form, afio and gzip won't be able to restore the rest of that file. That's usually an acceptable risk for small files π₯Ί
- For very large files, though, the risk of losing a big chunk of data this way is usually way too big π
- The special case
-2 0eliminates any maximum size cutoff.
-3filedescriptor-nr β rewinds the filedescriptor before invoking the (un)compression program when using-Z. This is useful when the-Pand-Qoptions swap out gzip for certain encryption programs, to make or read an archive with encrypted files π The rewinding is needed to interface correctly with some encryption programs that read their key from an open filedescriptor.- If the
-Pprogram name matchespgporgpg, you must use-3or afio will report an error π¨ - The special case
-3 0suppresses that error message without rewinding any file descriptor. -3 0may also be needed to successfully read back encrypted archives made with afio version 2.4.5 and older.
- If the
-4β Deprecated, bestie π₯ The intended effect of this option is now achieved by default, as long as-5isn't used. This option could still be useful for compatibility with machines running an older version of afio. It writes the archive with theextended ASCIIformat headers, which use 4-byte inode numbers. Archives using extended ASCII format headers aren't compatible with any other archiver π ββοΈ This option was useful for reliably creating and restoring sets of files with lots of internal hard links, like a news spool π°-5β refuse to create an archive that's incompatible with cpio(1) π« With this option, afio will never write anylarge ASCIIfile headers that are incompatible with cpio(1). Instead, it'll fail with an error code. See the ARCHIVE PORTABILITY section above for more info on usinglarge ASCIIfile headers.
-6 is a whole thing, so buckle up π
Ok so this is the part of the page where the options get extra specific. Keep every detail in mind, bestie, because the facts don't change even if the vibe does π«Ά
β¨ OPTIONS (continued) β¨
-6filename β okay so while you're making an archive with compressed files using-Z, this option lets you turn off compression attempts for files that match certain shell patterns π§. It's giving speed boost, because afio stops trying togzipstuff that's already compressed π. It reads shell wildcard patterns from filename, treating each line as its own pattern π. Any file whose name matches gets skipped for compression when you use-Zπ ββοΈ. Pattern matching works exactly like the-yoption, so no surprises there β¨. Also, see the-Eoption: its default settings will further restrict compression attempts πΈ.-Ehandles compression based on file extensions, but-6is mainly for excluding all files in certain subdirectory trees from compression π³. (Sis, that last line ends in two periods, that's just how the original is written π)-7β this one is a switch that toggles between shell wildcard pattern matching and exact name matching, meaning wildcard characters don't get interpreted at all π¦. It applies to the patterns given in-y,-Y,-w, and-Wπ. If you put-7in front of any of those options, the patterns are treated as literal strings that must match the file name exactly, except possibly in leading slashes π. This is super handy for the rare cases where file names in the archive, or names of files being archived, have wildcard characters in them themselves π₯. Here's an example, which is honestly iconic π:
find /tmp -print0 | afio -ov -Y '*.jpg' -7 -Y '/tmp/a[12]*4' -0 archive
So this archives all files under /tmp, even files with a '\n' character in the name π, except for .jpg files and the file with the exact name /tmp/a[12]*4 β¨. A second use of -7 toggles matching for later -y, -Y, -w, and -W options back to shell wildcard pattern matching π.
-8directive β this is the symlink control panel, and it's a lot π. Thenosymlinksdirective applies to both archive creation and unpacking π. When creating, it stops any symlink entry from going into the archive π ββοΈ. When unpacking, it stops any symlink entry in the archive from being unpacked π«. This directive does not change how existing symlinks on the filesystem are interpreted during path resolution, which is when afio resolves the directory name parts in front of the last/in a path name πΊοΈ.
The allowinsecurepaths directive is about security during unpacking π‘οΈ. Since version 2.5.2, afio has protection mechanisms for potentially untrusted archives π«Ά. By default (since 2.5.2), on unpacking, afio inspects every pathname in the archive to check for a .. subpath π. If there are any, that's almost almost certainly an attacker's handiwork π€. The goal would be to overwrite system or user files with new contents using specially built paths like ../../../../../etc/password or ../../../../../home/a_user/.bashrc that lead to config files π. So if any .. subpaths show up, afio issues a warning, rewrites every '..' in the pathname to 'XX', and unpacks the entry to that rewritten path instead π§±. The allowinsecurepaths directive turns off that rewriting of likely-insecure path names π
ββοΈ.
Also, while unpacking, afio protects against archives with insecure path names that start with a leading / π·. It strips off the leading / before using the path name, so the entry ends up relative to the current working directory π. You can disable that stripping with the -A option π§.
The allowinsecuresymlinks directive adds to that protection for untrusted archives π. By default (since 2.5.2), on unpacking, afio inspects every symlink destination in the archive for a leading / or a .. subpath π. If either shows up, afio warns, rewrites them to X or XX, and uses the result as the unpacked symlink destination π©Ή. The allowinsecuresymlinks directive disables that protective rewriting π«.
Some background drama, because it's wild π: an attacking archive with an insecure symlink usually has a file entry right after the symlink, with a path that follows the symlink to somewhere a system or user config file can be overwritten π±. An attacker can most easily make such an archive if they control the entire archive creation process π΅οΈββοΈ. But there's another scenario: the attacker is an untrusted end user on a multi-user system, and a trusted sysadmin is backing up a live filesystem that has directories the untrusted user controls π§βπ». That user could exploit race conditions in the backup by making temporary symlinks and files in their own home directory πββοΈ. The result is archive contents that would modify system config files when unpacked later, if the protection were disabled with the allowinsecuresymlinks directive β οΈ.
These protection mechanisms only cover symlinks. A untrusted archive attack using specially constructed hard link entries is theoretically possible with some archivers, but it is not possible with afio, because of the special way afio represents hard links in an archive π.
-9β do not round down any-svolume sizes to the nearest-bblock size π. See the-soption π«Ά.
π ARCHIVE PORTABILITY π
afio archives are portable between different types of UNIX systems, because they only contain ASCII-formatted header information π.
Except in special cases (discussed below), afio creates archives in the same format as ASCII cpio(1) archives π. So cpio(1) can usually restore an afio archive if afio isn't available on a system π. With most cpio versions, unpack an ASCII format archive with cpio -c, and for GNU cpio(1), use cpio -H odc π§ . When unpacking with cpio, compressed files inside an afio -Z archive are not uncompressed by cpio π
ββοΈ. Instead, they get created on the filesystem as compressed files with a .z extension π¦.
Unfortunately, the ASCII cpio format can't represent some files and file properties that a modern UNIX filesystem can have π. If afio runs into those, it uses an afio-specific 'large ASCII' header for the files concerned πͺ. Archives with large ASCII headers can't be fully unpacked by cpio, or by afio versions before 2.4.8 π«.
When creating an archive, afio uses the large ASCII header for these situations π:
- A file is larger than 2 GB π
- The archive contains more than 64K files that have hard links π
- A file, directory, or special file has a UID or GID value larger than 65535 πͺͺ
The -5 option always preserves cpio compatibility π«Ά. It makes afio fail rather than produce an incompatible archive in the cases above π.
Archives made with the (deprecated) -4 option are also not compatible with cpio β οΈ. They are compatible with afio versions 2.4.4 and later π.
π¦ ARCHIVE FILE FORMAT π¦
An afio archive file has a simple format π§. The archive starts with a file header for the first file, followed by the contents of that first file π. Those contents are either the exact bytes, or the exact contents in some compressed format ποΈ. The first file's data is immediately followed by the second file's header, and so on π. At the very end, there's a special end of archive header, usually followed by some padding bytes π.
A multi-volume afio archive is just a normal archive split into multiple parts π§©. There are no special volume-level data headers, so volumes can be split and merged by external programs, as long as the data stays in the correct order πͺ‘. That also means the contents of a single file can cross volume boundaries π. You can do selective restores of files at known volume locations by feeding only the volumes you need to afio, as long as the -k option is used π―.
The contents of hard linked files are only stored once in the archive, unless the -l option is used π. The file headers for the second, third, and later occurrences of a hard linked file have no data after them π. This makes selective restores of hard-linked files tricky π΅βπ«: if later occurrences need to be restored correctly, the first occurrence always has to be selected too π
β¨.
β¨ NOTES β¨
okay bestie, this part is all about special-case archive names π afio has a few tricks up its sleeve here.
- Use
-to read from the standard input or write to the standard output, respectively. Heads up, this turns off multi-volume archive handling π - Start a command string with
!to run it. The command runs once for each archive volume, with its standard input or output piped to afio. It's supposed to produce a zero exit code when everything is fine β¨ - Use
system:fileto get at an archive in file on system. Honestly this is just a fancy version of pipelining π¦ It needs a 4.2BSD-style remote shell (rsh(1C)) and a remote copy of afio. - The full glow-up version is
[user@]host[%rsh][=afio]:file. The optionaluser@part is the user name on the remote host, the optional%rshis the (local) name of the remote shell command to use, and the optional=afiois the name of the remote copy of the afio command π§ - Anything else is a local file or device. If an output file doesn't exist yet, afio creates it πΈ
- When you use
-sto kick off multi-volume processing,%Vin the file/device name or command string gets swapped for the current volume number, and%Sgets swapped for the current volume size. If you actually want a single%character, write%%π
Afio also has some cool recovery skills π§ It can read obsolete binary cpio(1) archives, including ones from machines with reversed byte order, but it cannot write them π And if an archive gets corrupted, afio searches for a valid magic number to recover. Ngl, this is pretty simplistic, but much like a disassembler, it almost always works πβ¨
β¨ CONTROL FILES β¨
Afio archives can hold so-called control files π Unlike normal archive entries, a control file is not unpacked to the filesystem. Each one has a label and some data. When afio runs into a control file while reading an archive, it feeds the label and data to a so-called control script. You supply that script, and it can do special stuff based on the label and data it gets from afio π
π·οΈ Control file labels
The control file mechanism can be used for loads of things π For example, you can put archive descriptions at the very beginning of the archive, or embed lists of files to move before unpacking the rest of the archive.
To tell uses apart, the label should show which program made the control file and what the data is for. It should look like programname.kindofdata, where programname is the name of the backup program that generated the control file, and kindofdata is what the control file data means. Some examples:
tbackup.movelist tbackup.updatescript
blebberfiler.archivecontents
backup_script_of_Joe_User.archivedescription
The user-supplied control script should check the label to decide what to do with the data π§ That way, control files with labels it doesn't recognise can just be ignored, and afio archives keep some portability between the different programs that restore or index them π«Ά
Control file labels that are meant to be portable between different backup programs could be defined in the future β¨
π οΈ Making control files
When making an archive, afio reads a stream containing the names of the files (directories, ...) to put in the archive π That stream can also contain `control file generators'. These are lines in this format:
//--sourcename label
Here, the //-- sequence tells afio that a control file should be made. sourcename is the path to a file containing the control file data, and label is the control file label. The sourcename must be a regular file or a symlink to a regular file π¦
A control file will show up as //--CONTROL_FILE/label in an archive listing, where label is the control file label π
π¬ Control scripts
A control script is supplied to afio with the -D controlscript command line option π The controlscript must be an executable program. It runs whenever afio encounters a control file during a -i -t or -r operation π₯ Afio passes the control file label to the script as an argument, and the script reads the control file data from its standard input. If the script exits with a non-zero exit status, afio issues a warning message β οΈ
If afio hits a control file and there's no -D option, it'll warn you too π To suppress that warning and ignore all control scripts, use -D "" π€«
Here's an example control script π§
#!/bin/sh
if [ $1 = "afio_example.headertext" ]; then
#the headertext control file is supposed to be packed as the first
#entry of the archive
echo Archive header:
cat -
echo Unpack this archive? y/n
#stdout is still connected to the tty, read the reply from stdout
read yn <&1
if [ "$yn" = n ]; then
#abort
kill $PPID
fi
else
echo Ignoring unknown control file.
cat - >/dev/null
fi
Afio never compresses control file data when storing it in an archive, even when -Z is used π«ποΈ
When a control file is encountered by cpio(1), or by an afio with a version number below 2.4.1, the data gets unpacked to the filesystem and named CONTROL_FILE/label, where label is the control file label. Yikes π
β¨ BUGS β¨
okay bestie, let's spill the tea β afio has a few known issues, and I'm not going to pretend otherwise π«
- Honestly? There are too many options π
- Pathnames are restricted to 1023 characters, and 255 meaningful elements (where each element is a pathname component separated by a
/) π - afio doesn't use the same default block size as tar(1). tar(1) uses 10 KB, while afio uses 5 KB by default. Some tape drives only work with a 10 KB block size, and for those you need the afio option
-b 10kto make the tape work πΌ - There's no sequence information within multi-volume archives, so input sequence errors generally masquerade as data corruption π΅ A solution would probably be mutually exclusive with cpio(1) compatibility.
- The floppy handling code (the
-F,-fand-Koptions) has buggy error handling π afio doesn't let you retry a failed floppy write on a different floppy, and it can't recover from a verify error. If write or verify errors do happen with the floppy code, it's best to restart afio completely. Making backups to floppies should really be done with a more specialised backup program that wraps afio πΎ
The Linux floppy drivers below kernel version 1.1.54 don't let afio find out about floppy write errors while writing. If you're running a kernel below 1.1.54, afio will happily fail to write to (say) a write protected disk and won't report anything wrong! The only ways to find out about write errors in this case are watching the kernel messages, or switching on the verify (-K) option. π
- The remote archive facilities (
host:/filearchive names) haven't been exhaustively tested. They've seen a lot of real-life use, though, so bugs in the error handling and error reporting for remote archives are possible π°οΈ - An archive created with a command like
find /usr/src/linux -print | afio -o ...won't contain the ownership and permissions of the/usrand/usr/srcdirectories. If those directories are missing when you restore, afio recreates them with some default ownership and permissions π³ - afio can't restore time stamps on symlinks. Also, on operating systems without an
lchown(2)system call, afio can't restore owner/group information on symlinks. (Linux haslchownsince kernel version 2.1.86.) π - afio tries to restore the modification time stamps of directories in the archive correctly. However, if it exits prematurely, the modification times won't be restored correctly β°
- A restore using decompression will fail if the
gzipbinary used by afio is overwritten (by afio or another program) during the restore. It'll also fail if any shared libraries needed to startgzipare overwritten during the restore. afio should not normally be used to overwrite system files on a running system. If it's used that way, a flag like-Y /bin/gzipcan often be added to prevent failure π¨ - The
-roption verifies the file contents of the archived files against the files on the filesystem, but it doesn't cross-check details like permission bits on files. It also doesn't check that archived directories or other non-file entities still exist on the filesystem π - Hard links are a whole saga π§Ά There are four problems:
- Due to internal limitations, files with hard links can't be stored in compressed form, unless the
-lor-Uoptions are used. Those force each hard linked file to be stored separately. - Archives which contain hard links and were made with older (pre-2.4.8) versions of afio, or with cpio, can't always be correctly unpacked. This is really a problem in the archives and not in the current version of afio. The risk of incorrect unpacking gets greater the more files or hard links the archive has.
- In a selective restore, if the selection predicates don't select the first copy of a file with archive-internal hard links, then all subsequent copies, if selected, won't be correctly restored.
- Unless the
-4option is used, the inode number fields in the archive headers for files with hard links will sometimes not contain the actual (least significant 16 bits of) inode number of the original file.
- Due to internal limitations, files with hard links can't be stored in compressed form, unless the
- Some Linux kernels don't allow you to create a hard link to a symbolic link. afio will try to re-create such hard links when unpacking an archive, but it might fail due to kernel restrictions π
- Due to internal limitations of afio, the
-Uoption forces the writing of file content with each hard linked file, rather than only once for every set of hard linked files π - Without super-user privileges, afio can't unpack a file into a directory it has no write permissions for, even if it just created that directory itself. This can be a problem when trying to restore directory structures created by some source code control tools like RCS π
- If block or character device files are packed into an archive on one operating system (e.g. Linux) and unpacked on another that uses different sizes for the major and minor device number data types (e.g. Solaris), the major and minor numbers of the device files won't be restored correctly. This can be a problem if the operating systems share a cross-mounted filesystem. A workaround is to use
tar(1)for the device files π§Έ
π‘οΈ SECURITY CONSIDERATIONS π‘οΈ
okay bestie, this section is literally the most important one π«Άπ so let's get into it!!
Security considerations pop up when you're unpacking archives from untrusted sources π The recommended move is to unpack those archives into a temporary, empty destination directory that other system users can't get into, and to run afio as a normal user, so no superuser privileges π
ββοΈ As of version 2.5.2, afio has security measures turned on by default to protect against a whole class of attacks where specially crafted path names and/or symlink destinations in an archive trick afio into creating or modifying system or user files outside of the destination directory. The full scoop on these attacks and measures is under the -8 option π
On UNIX multi-user systems with untrusted users, there are several known attacks where, unless the system administrator is super careful, end users can exploit backup and restore activities on user filesystems to mess with data or operational security π For a rundown of some issues and precautions, check the security section of the GNU tar manual, at http://www.gnu.org/software/tar/manual/html_node/Security.html π¦
An archive from an untrusted source could, in theory, contain malformed data designed to set off a buffer overflow attack when afio reads the archive during a -t or -i operation π± The afio archive processing code is pretty robust and has passed some automated code checking tools, but no formal review has been done to guarantee there are no buffer overflow vulnerabilities π Running afio in a sandboxed virtual machine or from inside chroot(8) will boost security when handling archives from untrusted sources, but the most secure option is to never touch such archives at all π₯
β¨ EXAMPLES β¨
Okay, examples time, and these are so useful π
Create an archive with compressed files:
find .... | afio -o -v -Z /dev/fd0H1440
Install (unpack) an archive with compressed files:
afio -i -v -Z archive
Install (unpack) an archive with compressed files, protecting newer existing files:
afio -i -v -Z -n archive
Create an archive with compressed files on floppy disks:
find .... | afio -o -v -s 1440k -F -Z /dev/fd0H1440
Create an archive with all file contents encrypted by pgp:
export PGPPASSFD=3
find .... | afio -ovz -Z -U -P pgp -Q -fc -Q +verbose=0 -3 3 archive
3<passphrasefile
Create an archive on recordable CDs using the cdrecord utility to write each CD:
find .... | afio -o -b 2048 -s325000x -v '!cdrecord .... -'
Extract a single named file from an archive on /dev/tape:
afio -i -v -Z -y /home/me/thedir/thefile /dev/tape
(If these do not exist yet, afio will also create the enclosing directories home/me/myfiledir under current working directory.)
Extract files matching a pattern from an archive on /dev/tape:
afio -i -v -Z -y '/home/me/*' /dev/tape
(If these do not exist yet, afio will also create the enclosing directories home/me under current working directory.)
If your filesystem cannot handle files larger than 2GB, but you want to make an archive on that filesystem that is larger than 2GB, you can use this trick to split the archive into multiple files of 1 GB each π§:
find /home | afio -o ... - | split -b1024m - archive.
The files will be called archive.aa, archive.ab, etc. To restore the whole archive, use:
cat archive.* | afio -i ... -
The wildcard expansion by the shell ensures that cat reads the parts in the right (alphabetic) order π
π¦ SEE ALSO π¦
cpio(1), find(1), tar(1), compress(1), gzip(1) π
πΈ WEB SITE AND INTERNET RESOURCES πΈ
The afio home page is at http://members.chello.nl/~k.holtman/afio.html π See the home page for info on submitting questions, bug reports, patches, etc.
π AUTHORS π
Mark Brukhartz Jeff Buhrt Dave Gymer Andrew Stevens Koen Holtman (current maintainer) koen.holtman@ieee.org Anders Baekgaard
Too many other people to list here have contributed code, patches, ideas, and bug reports π«Ά Many of these are mentioned in the HISTORY file that comes with the sources β¨
afio, you're a whole icon ππ Source & version info, and date: AFIO(1) β same as the footer, obviously, we don't mess with the facts π Stay iconic, bestie π
π¦ where this page comes from
- debian bookworm: afio 2.5.2-3+b1 Β· Custom
- debian trixie: afio 2.5.2-3+b1 Β· Custom
- ubuntu jammy: afio 2.5.2-3 Β· Custom
- ubuntu noble: afio 2.5.2-3 Β· Custom
- ubuntu resolute: afio 2.5.2-3build1 Β· Custom
- ubuntu stonking: afio 2.5.2-3build1 Β· Custom
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms