[GNU Manual] [No POSIX requirement] [Linux man] [FreeBSD man]
Summary
install - copy files and set attributes
Lines of code: 1060
Principal syscall: lchown(), chmod()
Support syscalls: fork(), execlp(), stat(), unlink()
Options: 32 (15 short, 17 long)
Lineage unclear -- not included in Research UNIX or System V
Added to Fileutils in October 1992 [First version]
Number of revisions: 294
The install utility shares many ideas with cp but also allows the user to change attributes after copy. The idea is that install prepares future usage for other users.
Helpers:announce_mkdir()
- Prints the created directorychange_attributes()
- Sets the attributes of a target file usingchmod()
change_timestamps()
- Sets file timestampcopy_file()
- Performs a file copycp_option_init()
- Initializes a copy options structure (cp_options
extra_mode()
- Tests input mode for no RWX permissionsget_ids()
- Initializes user and group for target (passwd
andgroup
structures)have_same_content()
- Tests two file for the same contentinstall_file_in_dir()
- Creates a directory and copies a fileinstall_file_in_file()
- Copies a file and sets new permissions/timestamps as necessaryinstall_file_in_file_parents()
- Recreates ancestor directories before copying filemake_ancestor()
- Creates an ancestor directorymkancesdirs_safe_wd()
- Creates parent directories without affecting working directoryneed_copy()
- Tests if a file must be copiedprocess_dir()
- Retrieves a command line file namesetdefaultfilecon()
- Change file context, if applicable (two definitions)strip()
- Removes symbol table from a target filetarget_directory_operand()
- Tests if a target is a directory
die()
- Exit with mandatory non-zero error and message to stderrerror()
- Outputs error message to standard error with possible process termination
Setup
install uses globals flags and variables to manage execution, including:
copy_only_if_needed
- Flag for the compare setting (-C)dir_arg
- Flag to make a directory instead of a filedir_mode
- The default mode for directoriesdir_mode_bits
- A subset of dir_mode bits (for make_dir_parents() in gnulib)group_id
- The gid of the target groupgroup_name
- The name string of the target groupmode
- The default mode for non-directory filesowner_id
- The uid of the target ownerowner_name
- The name string of the target ownerstrip_files
- Flag to strip the symbol table from the target file*strip_program
- The name of the program to strip the executable
main()
introduces list of local variables:
*backup_suffix
- The suffix to add to the file backupexit_status
- The final return status**file
- The source and destination file pointersmake_backups
- Flag for making backups (-b)mkdir_and_install
- Flag to create parent directories prior to copyingn_files
- The number of files provided by the userno_target_directory
- Flag to treat the target as a fileoptc
- The character for the next option to process*scontext
- The desired security context*specified_mode
- The target file mode bitsstrip_program_specified
- Flag to strip the target program*target_directory
- The name of the target directory*version_control_string
- The desired backup modex
- Thecp_options
struct to control copy
Before parsing begins, the copy options are initialized to default values via copy_option_init()
Parsing
Parsing install options answers the following questions to define the execution parameters
- Should we compare before copying to avoid redundancy?
- Should we create missing parent directories before copying?
- What is target file access mode, group, and owner?
- Should we create a backup first?
- Is there an associated security context?
- How much feedback should we provide the user?
Parsing failures
These failure cases are explicitly checked:
- Specifying multiple target directories
- Providing a security context without SELinux enabled
- Claiming a target to be a directory if it's not
- Specifying an unknown security context
- Attempting to set a context and preserve it
- Missing source or target operands
- Using both target and no-target options
- Trying to compare files while preserving timestamps
- Trying to compare files and strip symbol tables
- Trying to compare files without permission
- Unknown option used
User specified parsing failures result in a short error message followed by the usage instructions. Access related parsing errors die with an error message.
Execution
install starts with preliminary fact-finding: Gathering information on the target directory, preparing backup file names, compiling the access mode bits, and gather user/group information
stat()
target directory (if specified)- Prepare the backup file names
- Compiling access mode bits
- Gathering user and group information
Execution branches in three possible ways depending on if we have to create any directories. The base case is only copying files, which follows this procedure (install_file_in_file()
):
- If preserving timestamps, gather the information with
stat()
- Copy the files from source to destination using the options set during parsing
- Clean the target symbol table if required
- Transfer the timetamp information to the new file
- Set the new file attributes
The other two cases consider if we need to create the target directory first or if we have several levels of parent directories that need to be created. These procedures are install_file_in_dir()
and install_file_in_file_parents()
respectively. Both procdures create the directories and then call the base case of copying the file.
Failure cases:
- Unable to
stat()
source file or target directories - Directory creation failed
- Failure to unlink target file
- Unknown useror group specified
- Failure to strip target file (
fork()
orexeclp()
failed) - Failure to change ownership or permissions
- Unable to change timestamps
- Unable to change context
All failures at this stage output an error message to STDERR and return without displaying usage help