1*2b9c0f9fSriastradh /* $NetBSD: pax.c,v 1.52 2024/08/05 13:37:27 riastradh Exp $ */ 2b5b29542Sagc 3b5b29542Sagc /*- 4ed6ed8e6Sagc * Copyright (c) 1992 Keith Muller. 5b5b29542Sagc * Copyright (c) 1992, 1993 6b5b29542Sagc * The Regents of the University of California. All rights reserved. 7b5b29542Sagc * 8b5b29542Sagc * This code is derived from software contributed to Berkeley by 9b5b29542Sagc * Keith Muller of the University of California, San Diego. 10b5b29542Sagc * 11b5b29542Sagc * Redistribution and use in source and binary forms, with or without 12b5b29542Sagc * modification, are permitted provided that the following conditions 13b5b29542Sagc * are met: 14b5b29542Sagc * 1. Redistributions of source code must retain the above copyright 15b5b29542Sagc * notice, this list of conditions and the following disclaimer. 16b5b29542Sagc * 2. Redistributions in binary form must reproduce the above copyright 17b5b29542Sagc * notice, this list of conditions and the following disclaimer in the 18b5b29542Sagc * documentation and/or other materials provided with the distribution. 19b5b29542Sagc * 3. Neither the name of the University nor the names of its contributors 20b5b29542Sagc * may be used to endorse or promote products derived from this software 21b5b29542Sagc * without specific prior written permission. 22b5b29542Sagc * 23b5b29542Sagc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24b5b29542Sagc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25b5b29542Sagc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26b5b29542Sagc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27b5b29542Sagc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28b5b29542Sagc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29b5b29542Sagc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30b5b29542Sagc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31b5b29542Sagc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32b5b29542Sagc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33b5b29542Sagc * SUCH DAMAGE. 34b5b29542Sagc */ 3549f0ad86Scgd 36171d6532Slukem #if HAVE_NBTOOL_CONFIG_H 37171d6532Slukem #include "nbtool_config.h" 38171d6532Slukem #endif 39171d6532Slukem 40f3cd6022Schristos #include <sys/cdefs.h> 41171d6532Slukem #if !defined(lint) 422fe2731dSlukem __COPYRIGHT("@(#) Copyright (c) 1992, 1993\ 432fe2731dSlukem The Regents of the University of California. All rights reserved."); 4449f0ad86Scgd #if 0 4549f0ad86Scgd static char sccsid[] = "@(#)pax.c 8.2 (Berkeley) 4/18/94"; 4649f0ad86Scgd #else 47*2b9c0f9fSriastradh __RCSID("$NetBSD: pax.c,v 1.52 2024/08/05 13:37:27 riastradh Exp $"); 4849f0ad86Scgd #endif 498b35abe2Sjtc #endif /* not lint */ 508b35abe2Sjtc 518b35abe2Sjtc #include <sys/param.h> 52481188eaSjoerg #include <sys/resource.h> 538b35abe2Sjtc #include <sys/stat.h> 548b35abe2Sjtc #include <sys/time.h> 55481188eaSjoerg #include <errno.h> 560c612021Schristos #include <fcntl.h> 57481188eaSjoerg #include <paths.h> 588b35abe2Sjtc #include <signal.h> 59481188eaSjoerg #include <stdio.h> 608b35abe2Sjtc #include <stdlib.h> 619b3e4b9eSmrg #include <string.h> 62481188eaSjoerg #include <time.h> 63481188eaSjoerg #include <unistd.h> 64db822d22Slukem #include <util.h> 658b35abe2Sjtc #include "pax.h" 668b35abe2Sjtc #include "extern.h" 67c1bd745cSlukem static int gen_init(void); 688b35abe2Sjtc 698b35abe2Sjtc /* 708b35abe2Sjtc * PAX main routines, general globals and some simple start up routines 718b35abe2Sjtc */ 728b35abe2Sjtc 738b35abe2Sjtc /* 748b35abe2Sjtc * Variables that can be accessed by any routine within pax 758b35abe2Sjtc */ 76860d26c6Schristos int act = ERROR; /* read/write/append/copy */ 778b35abe2Sjtc FSUB *frmt = NULL; /* archive format type */ 788b35abe2Sjtc int cflag; /* match all EXCEPT pattern/file */ 7937fed211Schristos int cwdfd = -1; /* starting cwd */ 808b35abe2Sjtc int dflag; /* directory member match only */ 818b35abe2Sjtc int iflag; /* interactive file/archive rename */ 828b35abe2Sjtc int kflag; /* do not overwrite existing files */ 838b35abe2Sjtc int lflag; /* use hard links when possible */ 848b35abe2Sjtc int nflag; /* select first archive member match */ 858b35abe2Sjtc int tflag; /* restore access time after read */ 868b35abe2Sjtc int uflag; /* ignore older modification time files */ 878b35abe2Sjtc int vflag; /* produce verbose output */ 881fbe6b7eStron int Aflag; /* honor absolute path */ 898b35abe2Sjtc int Dflag; /* same as uflag except inode change time */ 908b35abe2Sjtc int Hflag; /* follow command line symlinks (write only) */ 918b35abe2Sjtc int Lflag; /* follow symlinks when writing */ 9255026d54Slukem int Mflag; /* treat stdin as an mtree(8) specfile */ 93702d1ca5Schristos int Vflag; /* produce somewhat verbose output (no listing) */ 948b35abe2Sjtc int Xflag; /* archive files with same device id only */ 958b35abe2Sjtc int Yflag; /* same as Dflg except after name mode */ 968b35abe2Sjtc int Zflag; /* same as uflg except after name mode */ 978b35abe2Sjtc int vfpart; /* is partial verbose output in progress */ 988b35abe2Sjtc int patime = 1; /* preserve file access time */ 998b35abe2Sjtc int pmtime = 1; /* preserve file modification times */ 1000c612021Schristos int nodirs; /* do not create directories as needed */ 101b60cafe2Smrg int pfflags = 1; /* preserve file flags */ 1028b35abe2Sjtc int pmode; /* preserve file mode bits */ 1038b35abe2Sjtc int pids; /* preserve file uid/gid */ 1040c612021Schristos int rmleadslash = 0; /* remove leading '/' from pathnames */ 1058b35abe2Sjtc int exit_val; /* exit value */ 1068b35abe2Sjtc int docrc; /* check/create file crc */ 1071301238aSsimonb int to_stdout; /* extract to stdout */ 1088b35abe2Sjtc char *dirptr; /* destination dir in a copy */ 1090c612021Schristos char *ltmfrmt; /* -v locale time format (if any) */ 1105820cbfaSchristos const char *argv0; /* root of argv[0] */ 1118b35abe2Sjtc sigset_t s_mask; /* signal mask for cleanup critical sect */ 11244303cadSchristos FILE *listf; /* file pointer to print file list to */ 1130c612021Schristos char *tempfile; /* tempfile to use for mkstemp(3) */ 1140c612021Schristos char *tempbase; /* basename of tempfile to use for mkstemp(3) */ 1150c612021Schristos int forcelocal; /* force local operation even if the name 1160c612021Schristos * contains a : 1170c612021Schristos */ 118ca541391Schristos int secure = 1; /* don't extract names that contain .. */ 1198b35abe2Sjtc 1208b35abe2Sjtc /* 1218b35abe2Sjtc * PAX - Portable Archive Interchange 1228b35abe2Sjtc * 1238b35abe2Sjtc * A utility to read, write, and write lists of the members of archive 1248b35abe2Sjtc * files and copy directory hierarchies. A variety of archive formats 1258b35abe2Sjtc * are supported (some are described in POSIX 1003.1 10.1): 1268b35abe2Sjtc * 1278b35abe2Sjtc * ustar - 10.1.1 extended tar interchange format 1288b35abe2Sjtc * cpio - 10.1.2 extended cpio interchange format 1298b35abe2Sjtc * tar - old BSD 4.3 tar format 1308b35abe2Sjtc * binary cpio - old cpio with binary header format 1318b35abe2Sjtc * sysVR4 cpio - with and without CRC 1328b35abe2Sjtc * 1338b35abe2Sjtc * This version is a superset of IEEE Std 1003.2b-d3 1348b35abe2Sjtc * 1358b35abe2Sjtc * Summary of Extensions to the IEEE Standard: 1368b35abe2Sjtc * 1378b35abe2Sjtc * 1 READ ENHANCEMENTS 1388b35abe2Sjtc * 1.1 Operations which read archives will continue to operate even when 1398b35abe2Sjtc * processing archives which may be damaged, truncated, or fail to meet 1408b35abe2Sjtc * format specs in several different ways. Damaged sections of archives 1418b35abe2Sjtc * are detected and avoided if possible. Attempts will be made to resync 1428b35abe2Sjtc * archive read operations even with badly damaged media. 1438b35abe2Sjtc * 1.2 Blocksize requirements are not strictly enforced on archive read. 1448b35abe2Sjtc * Tapes which have variable sized records can be read without errors. 1458b35abe2Sjtc * 1.3 The user can specify via the non-standard option flag -E if error 1468b35abe2Sjtc * resync operation should stop on a media error, try a specified number 1478b35abe2Sjtc * of times to correct, or try to correct forever. 1488b35abe2Sjtc * 1.4 Sparse files (lseek holes) stored on the archive (but stored with blocks 1498b35abe2Sjtc * of all zeros will be restored with holes appropriate for the target 1508b35abe2Sjtc * filesystem 1518b35abe2Sjtc * 1.5 The user is notified whenever something is found during archive 1528b35abe2Sjtc * read operations which violates spec (but the read will continue). 1538b35abe2Sjtc * 1.6 Multiple archive volumes can be read and may span over different 1548b35abe2Sjtc * archive devices 1558b35abe2Sjtc * 1.7 Rigidly restores all file attributes exactly as they are stored on the 1568b35abe2Sjtc * archive. 1578b35abe2Sjtc * 1.8 Modification change time ranges can be specified via multiple -T 1588b35abe2Sjtc * options. These allow a user to select files whose modification time 1598b35abe2Sjtc * lies within a specific time range. 1608b35abe2Sjtc * 1.9 Files can be selected based on owner (user name or uid) via one or more 1618b35abe2Sjtc * -U options. 1628b35abe2Sjtc * 1.10 Files can be selected based on group (group name or gid) via one o 1638b35abe2Sjtc * more -G options. 164f8adf56dSitohy * 1.11 File modification time can be checked against existing file after 1658b35abe2Sjtc * name modification (-Z) 1668b35abe2Sjtc * 1678b35abe2Sjtc * 2 WRITE ENHANCEMENTS 1688b35abe2Sjtc * 2.1 Write operation will stop instead of allowing a user to create a flawed 1698b35abe2Sjtc * flawed archive (due to any problem). 170f8adf56dSitohy * 2.2 Archives written by pax are forced to strictly conform to both the 1718ce1f4ffSmsaitoh * archive and pax the specific format specifications. 1728b35abe2Sjtc * 2.3 Blocking size and format is rigidly enforced on writes. 1738b35abe2Sjtc * 2.4 Formats which may exhibit header overflow problems (they have fields 1748b35abe2Sjtc * too small for large file systems, such as inode number storage), use 1758b35abe2Sjtc * routines designed to repair this problem. These techniques still 1768b35abe2Sjtc * conform to both pax and format specifications, but no longer truncate 1778b35abe2Sjtc * these fields. This removes any restrictions on using these archive 1788b35abe2Sjtc * formats on large file systems. 1798b35abe2Sjtc * 2.5 Multiple archive volumes can be written and may span over different 1808b35abe2Sjtc * archive devices 1818b35abe2Sjtc * 2.6 A archive volume record limit allows the user to specify the number 1828b35abe2Sjtc * of bytes stored on an archive volume. When reached the user is 1838b35abe2Sjtc * prompted for the next archive volume. This is specified with the 184f8adf56dSitohy * non-standard -B flag. The limit is rounded up to the next blocksize. 1858b35abe2Sjtc * 2.7 All archive padding during write use zero filled sections. This makes 1868b35abe2Sjtc * it much easier to pull data out of flawed archive during read 1878b35abe2Sjtc * operations. 1888b35abe2Sjtc * 2.8 Access time reset with the -t applies to all file nodes (including 1898b35abe2Sjtc * directories). 1908b35abe2Sjtc * 2.9 Symbolic links can be followed with -L (optional in the spec). 1918b35abe2Sjtc * 2.10 Modification or inode change time ranges can be specified via 1928b35abe2Sjtc * multiple -T options. These allow a user to select files whose 1938b35abe2Sjtc * modification or inode change time lies within a specific time range. 1948b35abe2Sjtc * 2.11 Files can be selected based on owner (user name or uid) via one or more 1958b35abe2Sjtc * -U options. 1968b35abe2Sjtc * 2.12 Files can be selected based on group (group name or gid) via one o 1978b35abe2Sjtc * more -G options. 1988b35abe2Sjtc * 2.13 Symlinks which appear on the command line can be followed (without 1998b35abe2Sjtc * following other symlinks; -H flag) 2008b35abe2Sjtc * 2018b35abe2Sjtc * 3 COPY ENHANCEMENTS 2028b35abe2Sjtc * 3.1 Sparse files (lseek holes) can be copied without expanding the holes 2038b35abe2Sjtc * into zero filled blocks. The file copy is created with holes which are 2048b35abe2Sjtc * appropriate for the target filesystem 2058b35abe2Sjtc * 3.2 Access time as well as modification time on copied file trees can be 2068b35abe2Sjtc * preserved with the appropriate -p options. 2078b35abe2Sjtc * 3.3 Access time reset with the -t applies to all file nodes (including 2088b35abe2Sjtc * directories). 2098b35abe2Sjtc * 3.4 Symbolic links can be followed with -L (optional in the spec). 2108b35abe2Sjtc * 3.5 Modification or inode change time ranges can be specified via 2118b35abe2Sjtc * multiple -T options. These allow a user to select files whose 2128b35abe2Sjtc * modification or inode change time lies within a specific time range. 2138b35abe2Sjtc * 3.6 Files can be selected based on owner (user name or uid) via one or more 2148b35abe2Sjtc * -U options. 2158b35abe2Sjtc * 3.7 Files can be selected based on group (group name or gid) via one o 2168b35abe2Sjtc * more -G options. 2178b35abe2Sjtc * 3.8 Symlinks which appear on the command line can be followed (without 2188b35abe2Sjtc * following other symlinks; -H flag) 219f8adf56dSitohy * 3.9 File inode change time can be checked against existing file before 2208b35abe2Sjtc * name modification (-D) 221f8adf56dSitohy * 3.10 File inode change time can be checked against existing file after 2228b35abe2Sjtc * name modification (-Y) 223f8adf56dSitohy * 3.11 File modification time can be checked against existing file after 2248b35abe2Sjtc * name modification (-Z) 2258b35abe2Sjtc * 2268b35abe2Sjtc * 4 GENERAL ENHANCEMENTS 2278b35abe2Sjtc * 4.1 Internal structure is designed to isolate format dependent and 2288b35abe2Sjtc * independent functions. Formats are selected via a format driver table. 2298b35abe2Sjtc * This encourages the addition of new archive formats by only having to 2308b35abe2Sjtc * write those routines which id, read and write the archive header. 2318b35abe2Sjtc */ 2328b35abe2Sjtc 2338b35abe2Sjtc /* 2348b35abe2Sjtc * main() 2358b35abe2Sjtc * parse options, set up and operate as specified by the user. 2368b35abe2Sjtc * any operational flaw will set exit_val to non-zero 2378b35abe2Sjtc * Return: 0 if ok, 1 otherwise 2388b35abe2Sjtc */ 2398b35abe2Sjtc 2408b35abe2Sjtc int 2418b35abe2Sjtc main(int argc, char **argv) 2428b35abe2Sjtc { 2435820cbfaSchristos const char *tmpdir; 2440c612021Schristos size_t tdlen; 245b419a254Sdsl int rval; 2460c612021Schristos 2478a22d7d4Sgrant setprogname(argv[0]); 2488a22d7d4Sgrant 24944303cadSchristos listf = stderr; 25044303cadSchristos 2510c612021Schristos /* 25237fed211Schristos * parse options, determine operational mode 25337fed211Schristos */ 25437fed211Schristos options(argc, argv); 25537fed211Schristos 25637fed211Schristos /* 25737fed211Schristos * general init 25837fed211Schristos */ 25937fed211Schristos if ((gen_init() < 0) || (tty_init() < 0)) 260cdec4ac1Sdsl return exit_val; 26137fed211Schristos 26237fed211Schristos /* 2633716b768Sriastradh * For any actions other than LIST, keep a reference to cwd, so 2643716b768Sriastradh * we can always come back home. 26596495ab1Sriastradh * 26696495ab1Sriastradh * For EXTRACT (pax -r) without --insecure, also save the path 26796495ab1Sriastradh * to cwd to check for escape attempts. 2680c612021Schristos */ 2693716b768Sriastradh if (act != LIST) { 2700c612021Schristos cwdfd = open(".", O_RDONLY); 2710c612021Schristos if (cwdfd < 0) { 2723716b768Sriastradh syswarn(1, errno, 2733716b768Sriastradh "Can't open current working directory."); 274cdec4ac1Sdsl return exit_val; 2750c612021Schristos } 27696495ab1Sriastradh if (act == EXTRACT && secure) { 27715ea30ebSchristos if (updatepath() == -1) 278cdec4ac1Sdsl return exit_val; 2793716b768Sriastradh } 28096495ab1Sriastradh } 2810c612021Schristos 2820c612021Schristos /* 2830c612021Schristos * Where should we put temporary files? 2840c612021Schristos */ 2850c612021Schristos if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') 2860c612021Schristos tmpdir = _PATH_TMP; 2870c612021Schristos tdlen = strlen(tmpdir); 2880c612021Schristos while(tdlen > 0 && tmpdir[tdlen - 1] == '/') 2890c612021Schristos tdlen--; 2900c612021Schristos tempfile = malloc(tdlen + 1 + sizeof(_TFILE_BASE)); 2910c612021Schristos if (tempfile == NULL) { 2920c612021Schristos tty_warn(1, "Cannot allocate memory for temp file name."); 293cdec4ac1Sdsl return exit_val; 2940c612021Schristos } 2950c612021Schristos if (tdlen) 2960c612021Schristos memcpy(tempfile, tmpdir, tdlen); 2970c612021Schristos tempbase = tempfile + tdlen; 2980c612021Schristos *tempbase++ = '/'; 2990c612021Schristos 300789b7159Schristos (void)time(&starttime); 301789b7159Schristos #ifdef SIGINFO 302789b7159Schristos (void)signal(SIGINFO, ar_summary); 303789b7159Schristos #endif 3048b35abe2Sjtc /* 3058b35abe2Sjtc * select a primary operation mode 3068b35abe2Sjtc */ 3078b35abe2Sjtc switch (act) { 3088b35abe2Sjtc case EXTRACT: 309b419a254Sdsl rval = extract(); 3108b35abe2Sjtc break; 3118b35abe2Sjtc case ARCHIVE: 312b419a254Sdsl rval = archive(); 3138b35abe2Sjtc break; 3148b35abe2Sjtc case APPND: 3150c612021Schristos if (gzip_program != NULL) 3160c612021Schristos err(1, "cannot gzip while appending"); 317b419a254Sdsl rval = append(); 3188461b5b8Schristos /* 3198461b5b8Schristos * Check if we tried to append on an empty file and 3208461b5b8Schristos * turned into ARCHIVE mode. 3218461b5b8Schristos */ 322d4ba6227Schristos if (act == -ARCHIVE) { 323d4ba6227Schristos act = ARCHIVE; 324b419a254Sdsl rval = archive(); 325d4ba6227Schristos } 3268b35abe2Sjtc break; 3278b35abe2Sjtc case COPY: 328b419a254Sdsl rval = copy(); 3298b35abe2Sjtc break; 3308b35abe2Sjtc default: 3318b35abe2Sjtc case LIST: 332b419a254Sdsl rval = list(); 3338b35abe2Sjtc break; 3348b35abe2Sjtc } 335b419a254Sdsl if (rval != 0) 336b419a254Sdsl exit_val = 1; 337cdec4ac1Sdsl return exit_val; 3388b35abe2Sjtc } 3398b35abe2Sjtc 3408b35abe2Sjtc /* 3418b35abe2Sjtc * sig_cleanup() 3428b35abe2Sjtc * when interrupted we try to do whatever delayed processing we can. 3438b35abe2Sjtc * This is not critical, but we really ought to limit our damage when we 3448b35abe2Sjtc * are aborted by the user. 3458b35abe2Sjtc * Return: 3468b35abe2Sjtc * never.... 3478b35abe2Sjtc */ 3488b35abe2Sjtc 349074c0c6eSjoerg __dead static void 3508b35abe2Sjtc sig_cleanup(int which_sig) 3518b35abe2Sjtc { 3528b35abe2Sjtc /* 3538b35abe2Sjtc * restore modes and times for any dirs we may have created 3548b35abe2Sjtc * or any dirs we may have read. Set vflag and vfpart so the user 3558b35abe2Sjtc * will clearly see the message on a line by itself. 3568b35abe2Sjtc */ 3578b35abe2Sjtc vflag = vfpart = 1; 358b2f78261Sjmc #ifdef SIGXCPU 3598b35abe2Sjtc if (which_sig == SIGXCPU) 360885e5587Sdsl tty_warn(1, "CPU time limit reached, cleaning up."); 3618b35abe2Sjtc else 362b2f78261Sjmc #endif 363885e5587Sdsl tty_warn(1, "Signal caught, cleaning up."); 3648b35abe2Sjtc 3658fbcc555Smatt /* delete any open temporary file */ 3668fbcc555Smatt if (xtmp_name) 3678fbcc555Smatt (void)unlink(xtmp_name); 3688b35abe2Sjtc ar_close(); 3698b35abe2Sjtc proc_dir(); 3708b35abe2Sjtc if (tflag) 3718b35abe2Sjtc atdir_end(); 372b7fac28cSlukem 373db822d22Slukem (void)raise_default_signal(which_sig); 3748b35abe2Sjtc exit(1); 3758b35abe2Sjtc } 3768b35abe2Sjtc 3778b35abe2Sjtc /* 3788b35abe2Sjtc * gen_init() 3798b35abe2Sjtc * general setup routines. Not all are required, but they really help 3808b35abe2Sjtc * when dealing with a medium to large sized archives. 3818b35abe2Sjtc */ 3828b35abe2Sjtc 3838b35abe2Sjtc static int 3848b35abe2Sjtc gen_init(void) 3858b35abe2Sjtc { 3868b35abe2Sjtc struct rlimit reslimit; 3878b35abe2Sjtc struct sigaction n_hand; 3888b35abe2Sjtc struct sigaction o_hand; 3898b35abe2Sjtc 3908b35abe2Sjtc /* 3918b35abe2Sjtc * Really needed to handle large archives. We can run out of memory for 3928b35abe2Sjtc * internal tables really fast when we have a whole lot of files... 3938b35abe2Sjtc */ 3948b35abe2Sjtc if (getrlimit(RLIMIT_DATA , &reslimit) == 0){ 3958b35abe2Sjtc reslimit.rlim_cur = reslimit.rlim_max; 3968b35abe2Sjtc (void)setrlimit(RLIMIT_DATA , &reslimit); 3978b35abe2Sjtc } 3988b35abe2Sjtc 3998b35abe2Sjtc /* 4008b35abe2Sjtc * should file size limits be waived? if the os limits us, this is 4018b35abe2Sjtc * needed if we want to write a large archive 4028b35abe2Sjtc */ 4038b35abe2Sjtc if (getrlimit(RLIMIT_FSIZE , &reslimit) == 0){ 4048b35abe2Sjtc reslimit.rlim_cur = reslimit.rlim_max; 4058b35abe2Sjtc (void)setrlimit(RLIMIT_FSIZE , &reslimit); 4068b35abe2Sjtc } 4078b35abe2Sjtc 4088b35abe2Sjtc /* 4098b35abe2Sjtc * increase the size the stack can grow to 4108b35abe2Sjtc */ 4118b35abe2Sjtc if (getrlimit(RLIMIT_STACK , &reslimit) == 0){ 4128b35abe2Sjtc reslimit.rlim_cur = reslimit.rlim_max; 4138b35abe2Sjtc (void)setrlimit(RLIMIT_STACK , &reslimit); 4148b35abe2Sjtc } 4158b35abe2Sjtc 416a328e341Stv #ifdef RLIMIT_RSS 4178b35abe2Sjtc /* 4188b35abe2Sjtc * not really needed, but doesn't hurt 4198b35abe2Sjtc */ 4208b35abe2Sjtc if (getrlimit(RLIMIT_RSS , &reslimit) == 0){ 4218b35abe2Sjtc reslimit.rlim_cur = reslimit.rlim_max; 4228b35abe2Sjtc (void)setrlimit(RLIMIT_RSS , &reslimit); 4238b35abe2Sjtc } 424a328e341Stv #endif 4258b35abe2Sjtc 4268b35abe2Sjtc /* 4270c612021Schristos * Handle posix locale 4280c612021Schristos * 4290c612021Schristos * set user defines time printing format for -v option 4300c612021Schristos */ 4310c612021Schristos ltmfrmt = getenv("LC_TIME"); 4320c612021Schristos 4330c612021Schristos /* 4348b35abe2Sjtc * signal handling to reset stored directory times and modes. Since 4358b35abe2Sjtc * we deal with broken pipes via failed writes we ignore it. We also 4368ce1f4ffSmsaitoh * deal with any file size limit through failed writes. CPU time 4378b35abe2Sjtc * limits are caught and a cleanup is forced. 4388b35abe2Sjtc */ 4398b35abe2Sjtc if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) || 4408b35abe2Sjtc (sigaddset(&s_mask,SIGINT) < 0)||(sigaddset(&s_mask,SIGHUP) < 0) || 441b2f78261Sjmc (sigaddset(&s_mask,SIGPIPE) < 0)||(sigaddset(&s_mask,SIGQUIT)<0)){ 442f3cd6022Schristos tty_warn(1, "Unable to set up signal mask"); 443cdec4ac1Sdsl return -1; 4448b35abe2Sjtc } 445b2f78261Sjmc #ifdef SIGXCPU 446b2f78261Sjmc if (sigaddset(&s_mask,SIGXCPU) < 0) { 447b2f78261Sjmc tty_warn(1, "Unable to set up signal mask"); 448cdec4ac1Sdsl return -1; 449b2f78261Sjmc } 450b2f78261Sjmc #endif 451b2f78261Sjmc #ifdef SIGXFSZ 452b2f78261Sjmc if (sigaddset(&s_mask,SIGXFSZ) < 0) { 453b2f78261Sjmc tty_warn(1, "Unable to set up signal mask"); 454cdec4ac1Sdsl return -1; 455b2f78261Sjmc } 456b2f78261Sjmc #endif 457b2f78261Sjmc 4580c612021Schristos memset(&n_hand, 0, sizeof n_hand); 4598b35abe2Sjtc n_hand.sa_mask = s_mask; 4608b35abe2Sjtc n_hand.sa_flags = 0; 4618b35abe2Sjtc n_hand.sa_handler = sig_cleanup; 4628b35abe2Sjtc 4638b35abe2Sjtc if ((sigaction(SIGHUP, &n_hand, &o_hand) < 0) && 4648b35abe2Sjtc (o_hand.sa_handler == SIG_IGN) && 465f8f9f441Scheusov (sigaction(SIGHUP, &o_hand, NULL) < 0)) 4668b35abe2Sjtc goto out; 4678b35abe2Sjtc 4688b35abe2Sjtc if ((sigaction(SIGTERM, &n_hand, &o_hand) < 0) && 4698b35abe2Sjtc (o_hand.sa_handler == SIG_IGN) && 470f8f9f441Scheusov (sigaction(SIGTERM, &o_hand, NULL) < 0)) 4718b35abe2Sjtc goto out; 4728b35abe2Sjtc 4738b35abe2Sjtc if ((sigaction(SIGINT, &n_hand, &o_hand) < 0) && 4748b35abe2Sjtc (o_hand.sa_handler == SIG_IGN) && 475f8f9f441Scheusov (sigaction(SIGINT, &o_hand, NULL) < 0)) 4768b35abe2Sjtc goto out; 4778b35abe2Sjtc 4788b35abe2Sjtc if ((sigaction(SIGQUIT, &n_hand, &o_hand) < 0) && 4798b35abe2Sjtc (o_hand.sa_handler == SIG_IGN) && 480f8f9f441Scheusov (sigaction(SIGQUIT, &o_hand, NULL) < 0)) 4818b35abe2Sjtc goto out; 4828b35abe2Sjtc 483b2f78261Sjmc #ifdef SIGXCPU 4848b35abe2Sjtc if ((sigaction(SIGXCPU, &n_hand, &o_hand) < 0) && 4858b35abe2Sjtc (o_hand.sa_handler == SIG_IGN) && 486f8f9f441Scheusov (sigaction(SIGXCPU, &o_hand, NULL) < 0)) 4878b35abe2Sjtc goto out; 488b2f78261Sjmc #endif 4898b35abe2Sjtc n_hand.sa_handler = SIG_IGN; 490b2f78261Sjmc if (sigaction(SIGPIPE, &n_hand, &o_hand) < 0) 4918b35abe2Sjtc goto out; 492b2f78261Sjmc #ifdef SIGXFSZ 493b2f78261Sjmc if (sigaction(SIGXFSZ, &n_hand, &o_hand) < 0) 494b2f78261Sjmc goto out; 495b2f78261Sjmc #endif 496cdec4ac1Sdsl return 0; 4978b35abe2Sjtc 4988b35abe2Sjtc out: 4998b35abe2Sjtc syswarn(1, errno, "Unable to set up signal handler"); 500cdec4ac1Sdsl return -1; 5018b35abe2Sjtc } 502