xref: /netbsd-src/bin/pax/gen_subs.c (revision a4c163faeed43399419f2760878e7b67814d5808)
1*a4c163faSchristos /*	$NetBSD: gen_subs.c,v 1.37 2018/11/30 00:53:11 christos 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)
4249f0ad86Scgd #if 0
4349f0ad86Scgd static char sccsid[] = "@(#)gen_subs.c	8.1 (Berkeley) 5/31/93";
4449f0ad86Scgd #else
45*a4c163faSchristos __RCSID("$NetBSD: gen_subs.c,v 1.37 2018/11/30 00:53:11 christos Exp $");
4649f0ad86Scgd #endif
478b35abe2Sjtc #endif /* not lint */
488b35abe2Sjtc 
498b35abe2Sjtc #include <sys/types.h>
508b35abe2Sjtc #include <sys/time.h>
518b35abe2Sjtc #include <sys/stat.h>
528b35abe2Sjtc #include <sys/param.h>
53d0e267dcSmycroft 
548b35abe2Sjtc #include <ctype.h>
55d0e267dcSmycroft #include <grp.h>
56d0e267dcSmycroft #include <pwd.h>
570c612021Schristos #include <vis.h>
58d0e267dcSmycroft #include <stdio.h>
598b35abe2Sjtc #include <stdlib.h>
608b35abe2Sjtc #include <string.h>
61d0e267dcSmycroft #include <time.h>
62d0e267dcSmycroft #include <tzfile.h>
63d0e267dcSmycroft #include <unistd.h>
64d0e267dcSmycroft 
658b35abe2Sjtc #include "pax.h"
668b35abe2Sjtc #include "extern.h"
678b35abe2Sjtc 
688b35abe2Sjtc /*
698b35abe2Sjtc  * a collection of general purpose subroutines used by pax
708b35abe2Sjtc  */
718b35abe2Sjtc 
728b35abe2Sjtc /*
738b35abe2Sjtc  * constants used by ls_list() when printing out archive members
748b35abe2Sjtc  */
758b35abe2Sjtc #define MODELEN 20
768b35abe2Sjtc #define DATELEN 64
778b35abe2Sjtc #define SIXMONTHS	 ((DAYSPERNYEAR / 2) * SECSPERDAY)
788b35abe2Sjtc #define CURFRMT		"%b %e %H:%M"
798b35abe2Sjtc #define OLDFRMT		"%b %e  %Y"
808b35abe2Sjtc #ifndef UT_NAMESIZE
818b35abe2Sjtc #define UT_NAMESIZE	8
828b35abe2Sjtc #endif
838b35abe2Sjtc #define UT_GRPSIZE	6
848b35abe2Sjtc 
858b35abe2Sjtc /*
865adf1dc2Schristos  * convert time to string
875adf1dc2Schristos  */
885adf1dc2Schristos static void
formattime(char * buf,size_t buflen,time_t when)895adf1dc2Schristos formattime(char *buf, size_t buflen, time_t when)
905adf1dc2Schristos {
915adf1dc2Schristos 	int error;
925adf1dc2Schristos 	struct tm tm;
935adf1dc2Schristos 	(void)localtime_r(&when, &tm);
945adf1dc2Schristos 
955adf1dc2Schristos 	if (when + SIXMONTHS <= time(NULL))
965adf1dc2Schristos 		error = strftime(buf, buflen, OLDFRMT, &tm);
975adf1dc2Schristos 	else
985adf1dc2Schristos 		error = strftime(buf, buflen, CURFRMT, &tm);
995adf1dc2Schristos 
1005adf1dc2Schristos 	if (error == 0)
1015adf1dc2Schristos 		buf[0] = '\0';
1025adf1dc2Schristos }
1035adf1dc2Schristos 
1045adf1dc2Schristos /*
1058b35abe2Sjtc  * ls_list()
1068b35abe2Sjtc  *	list the members of an archive in ls format
1078b35abe2Sjtc  */
1088b35abe2Sjtc 
1098b35abe2Sjtc void
ls_list(ARCHD * arcn,time_t now,FILE * fp)1100c612021Schristos ls_list(ARCHD *arcn, time_t now, FILE *fp)
1118b35abe2Sjtc {
11248250187Stls 	struct stat *sbp;
1138b35abe2Sjtc 	char f_mode[MODELEN];
1148b35abe2Sjtc 	char f_date[DATELEN];
1155adf1dc2Schristos 	const char *user, *group;
1168b35abe2Sjtc 
1178b35abe2Sjtc 	/*
1188b35abe2Sjtc 	 * if not verbose, just print the file name
1198b35abe2Sjtc 	 */
1208b35abe2Sjtc 	if (!vflag) {
1210c612021Schristos 		(void)fprintf(fp, "%s\n", arcn->name);
1220c612021Schristos 		(void)fflush(fp);
1238b35abe2Sjtc 		return;
1248b35abe2Sjtc 	}
1258b35abe2Sjtc 
1268b35abe2Sjtc 	/*
1278b35abe2Sjtc 	 * user wants long mode
1288b35abe2Sjtc 	 */
1298b35abe2Sjtc 	sbp = &(arcn->sb);
1308b35abe2Sjtc 	strmode(sbp->st_mode, f_mode);
1318b35abe2Sjtc 
1328b35abe2Sjtc 	/*
133a8e69293Skleink 	 * time format based on age compared to the time pax was started.
1348b35abe2Sjtc 	 */
1355adf1dc2Schristos 	formattime(f_date, sizeof(f_date), arcn->sb.st_mtime);
1368b35abe2Sjtc 	/*
1378b35abe2Sjtc 	 * print file mode, link count, uid, gid and time
1388b35abe2Sjtc 	 */
139a47ed375Sgrant 	user = user_from_uid(sbp->st_uid, 0);
140a47ed375Sgrant 	group = group_from_gid(sbp->st_gid, 0);
1410c612021Schristos 	(void)fprintf(fp, "%s%2lu %-*s %-*s ", f_mode,
1420c612021Schristos 	    (unsigned long)sbp->st_nlink,
143d0e267dcSmycroft 	    UT_NAMESIZE, user ? user : "", UT_GRPSIZE, group ? group : "");
1448b35abe2Sjtc 
1458b35abe2Sjtc 	/*
1468b35abe2Sjtc 	 * print device id's for devices, or sizes for other nodes
1478b35abe2Sjtc 	 */
1488b35abe2Sjtc 	if ((arcn->type == PAX_CHR) || (arcn->type == PAX_BLK))
1490c612021Schristos 		(void)fprintf(fp, "%4lu,%4lu ", (long) MAJOR(sbp->st_rdev),
150f3cd6022Schristos 		    (long) MINOR(sbp->st_rdev));
1518b35abe2Sjtc 	else {
1520c612021Schristos 		(void)fprintf(fp, OFFT_FP("9") " ", (OFFT_T)sbp->st_size);
1538b35abe2Sjtc 	}
1548b35abe2Sjtc 
1558b35abe2Sjtc 	/*
1568b35abe2Sjtc 	 * print name and link info for hard and soft links
1578b35abe2Sjtc 	 */
1580c612021Schristos 	(void)fprintf(fp, "%s %s", f_date, arcn->name);
1598b35abe2Sjtc 	if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))
1600c612021Schristos 		(void)fprintf(fp, " == %s\n", arcn->ln_name);
1618b35abe2Sjtc 	else if (arcn->type == PAX_SLK)
1621c8b4d7bSkleink 		(void)fprintf(fp, " -> %s\n", arcn->ln_name);
1638b35abe2Sjtc 	else
1640c612021Schristos 		(void)fputc('\n', fp);
1650c612021Schristos 	(void)fflush(fp);
1668b35abe2Sjtc }
1678b35abe2Sjtc 
1688b35abe2Sjtc /*
1698b35abe2Sjtc  * tty_ls()
1708b35abe2Sjtc  *	print a short summary of file to tty.
1718b35abe2Sjtc  */
1728b35abe2Sjtc 
1738b35abe2Sjtc void
ls_tty(ARCHD * arcn)17448250187Stls ls_tty(ARCHD *arcn)
1758b35abe2Sjtc {
1768b35abe2Sjtc 	char f_date[DATELEN];
1778b35abe2Sjtc 	char f_mode[MODELEN];
1788b35abe2Sjtc 
1795adf1dc2Schristos 	formattime(f_date, sizeof(f_date), arcn->sb.st_mtime);
1808b35abe2Sjtc 	strmode(arcn->sb.st_mode, f_mode);
1818b35abe2Sjtc 	tty_prnt("%s%s %s\n", f_mode, f_date, arcn->name);
1828b35abe2Sjtc 	return;
1838b35abe2Sjtc }
1848b35abe2Sjtc 
1858b35abe2Sjtc void
safe_print(const char * str,FILE * fp)1860c612021Schristos safe_print(const char *str, FILE *fp)
1878b35abe2Sjtc {
1880c612021Schristos 	char visbuf[5];
1890c612021Schristos 	const char *cp;
1908b35abe2Sjtc 
1918b35abe2Sjtc 	/*
1920c612021Schristos 	 * if printing to a tty, use vis(3) to print special characters.
1938b35abe2Sjtc 	 */
1940c612021Schristos 	if (isatty(fileno(fp))) {
1950c612021Schristos 		for (cp = str; *cp; cp++) {
1960c612021Schristos 			(void)vis(visbuf, cp[0], VIS_CSTYLE, cp[1]);
1970c612021Schristos 			(void)fputs(visbuf, fp);
1980c612021Schristos 		}
1990c612021Schristos 	} else {
2000c612021Schristos 		(void)fputs(str, fp);
2010c612021Schristos 	}
2028b35abe2Sjtc }
2038b35abe2Sjtc 
2048b35abe2Sjtc /*
205d653d57cSchristos  * asc_u32()
206d653d57cSchristos  *	convert hex/octal character string into a uint32_t. We do not have to
2078b35abe2Sjtc  *	check for overflow! (the headers in all supported formats are not large
2088b35abe2Sjtc  *	enough to create an overflow).
2098b35abe2Sjtc  *	NOTE: strings passed to us are NOT TERMINATED.
2108b35abe2Sjtc  * Return:
211d653d57cSchristos  *	uint32_t value
2128b35abe2Sjtc  */
2138b35abe2Sjtc 
214d653d57cSchristos uint32_t
asc_u32(char * str,int len,int base)215d653d57cSchristos asc_u32(char *str, int len, int base)
2168b35abe2Sjtc {
21748250187Stls 	char *stop;
218d653d57cSchristos 	uint32_t tval = 0;
2198b35abe2Sjtc 
2208b35abe2Sjtc 	stop = str + len;
2218b35abe2Sjtc 
2228b35abe2Sjtc 	/*
2238b35abe2Sjtc 	 * skip over leading blanks and zeros
2248b35abe2Sjtc 	 */
2258b35abe2Sjtc 	while ((str < stop) && ((*str == ' ') || (*str == '0')))
2268b35abe2Sjtc 		++str;
2278b35abe2Sjtc 
2288b35abe2Sjtc 	/*
2298b35abe2Sjtc 	 * for each valid digit, shift running value (tval) over to next digit
2308b35abe2Sjtc 	 * and add next digit
2318b35abe2Sjtc 	 */
2328b35abe2Sjtc 	if (base == HEX) {
2338b35abe2Sjtc 		while (str < stop) {
2348b35abe2Sjtc 			if ((*str >= '0') && (*str <= '9'))
2358b35abe2Sjtc 				tval = (tval << 4) + (*str++ - '0');
2368b35abe2Sjtc 			else if ((*str >= 'A') && (*str <= 'F'))
2378b35abe2Sjtc 				tval = (tval << 4) + 10 + (*str++ - 'A');
2388b35abe2Sjtc 			else if ((*str >= 'a') && (*str <= 'f'))
2398b35abe2Sjtc 				tval = (tval << 4) + 10 + (*str++ - 'a');
2408b35abe2Sjtc 			else
2418b35abe2Sjtc 				break;
2428b35abe2Sjtc 		}
2438b35abe2Sjtc 	} else {
2448b35abe2Sjtc 		while ((str < stop) && (*str >= '0') && (*str <= '7'))
2458b35abe2Sjtc 			tval = (tval << 3) + (*str++ - '0');
2468b35abe2Sjtc 	}
247cdec4ac1Sdsl 	return tval;
2488b35abe2Sjtc }
2498b35abe2Sjtc 
2508b35abe2Sjtc /*
251d653d57cSchristos  * u32_asc()
252d653d57cSchristos  *	convert an uintmax_t into an hex/oct ascii string. pads with LEADING
2538b35abe2Sjtc  *	ascii 0's to fill string completely
2548b35abe2Sjtc  *	NOTE: the string created is NOT TERMINATED.
2558b35abe2Sjtc  */
2568b35abe2Sjtc 
2578b35abe2Sjtc int
u32_asc(uintmax_t val,char * str,int len,int base)258d653d57cSchristos u32_asc(uintmax_t val, char *str, int len, int base)
2598b35abe2Sjtc {
26048250187Stls 	char *pt;
261d653d57cSchristos 	uint32_t digit;
262d653d57cSchristos 	uintmax_t p;
263d653d57cSchristos 
264d653d57cSchristos 	p = val & TOP_HALF;
265d653d57cSchristos 	if (p && p != TOP_HALF)
266d653d57cSchristos 		return -1;
267d653d57cSchristos 
268d653d57cSchristos 	val &= BOTTOM_HALF;
2698b35abe2Sjtc 
2708b35abe2Sjtc 	/*
2718b35abe2Sjtc 	 * WARNING str is not '\0' terminated by this routine
2728b35abe2Sjtc 	 */
2738b35abe2Sjtc 	pt = str + len - 1;
2748b35abe2Sjtc 
2758b35abe2Sjtc 	/*
2768b35abe2Sjtc 	 * do a tailwise conversion (start at right most end of string to place
2778b35abe2Sjtc 	 * least significant digit). Keep shifting until conversion value goes
2788b35abe2Sjtc 	 * to zero (all digits were converted)
2798b35abe2Sjtc 	 */
2808b35abe2Sjtc 	if (base == HEX) {
2818b35abe2Sjtc 		while (pt >= str) {
2828b35abe2Sjtc 			if ((digit = (val & 0xf)) < 10)
2838b35abe2Sjtc 				*pt-- = '0' + (char)digit;
2848b35abe2Sjtc 			else
2858b35abe2Sjtc 				*pt-- = 'a' + (char)(digit - 10);
2868b35abe2Sjtc 			if ((val = (val >> 4)) == (u_long)0)
2878b35abe2Sjtc 				break;
2888b35abe2Sjtc 		}
2898b35abe2Sjtc 	} else {
2908b35abe2Sjtc 		while (pt >= str) {
2918b35abe2Sjtc 			*pt-- = '0' + (char)(val & 0x7);
292d653d57cSchristos 			if ((val = (val >> 3)) == 0)
2938b35abe2Sjtc 				break;
2948b35abe2Sjtc 		}
2958b35abe2Sjtc 	}
2968b35abe2Sjtc 
2978b35abe2Sjtc 	/*
2988b35abe2Sjtc 	 * pad with leading ascii ZEROS. We return -1 if we ran out of space.
2998b35abe2Sjtc 	 */
3008b35abe2Sjtc 	while (pt >= str)
3018b35abe2Sjtc 		*pt-- = '0';
302d653d57cSchristos 	if (val != 0)
303cdec4ac1Sdsl 		return -1;
304cdec4ac1Sdsl 	return 0;
3058b35abe2Sjtc }
3068b35abe2Sjtc 
3078b35abe2Sjtc /*
308d653d57cSchristos  * asc_umax()
309*a4c163faSchristos  *	convert hex/octal/base-256 value into a uintmax.
3108b35abe2Sjtc  *	NOTE: strings passed to us are NOT TERMINATED.
3118b35abe2Sjtc  * Return:
312*a4c163faSchristos  *	uintmax_t value; UINTMAX_MAX for overflow/negative
3138b35abe2Sjtc  */
3148b35abe2Sjtc 
315d653d57cSchristos uintmax_t
asc_umax(char * str,int len,int base)316d653d57cSchristos asc_umax(char *str, int len, int base)
3178b35abe2Sjtc {
31848250187Stls 	char *stop;
319d653d57cSchristos 	uintmax_t tval = 0;
3208b35abe2Sjtc 
3218b35abe2Sjtc 	stop = str + len;
3228b35abe2Sjtc 
3238b35abe2Sjtc 	/*
324*a4c163faSchristos 	 * if the highest bit of first byte is set, it's base-256 encoded
325*a4c163faSchristos 	 * (base-256 is basically (n-1)-bit big endian signed
326*a4c163faSchristos 	 */
327*a4c163faSchristos 	if (str < stop && (*str & 0x80)) {
328*a4c163faSchristos 		/*
329*a4c163faSchristos 		 * uintmax_t can't be negative, so fail on negative numbers
330*a4c163faSchristos 		 */
331*a4c163faSchristos 		if (*str & 0x40)
332*a4c163faSchristos 			return UINTMAX_MAX;
333*a4c163faSchristos 
334*a4c163faSchristos 		tval = *str++ & 0x3f;
335*a4c163faSchristos 		while (str < stop) {
336*a4c163faSchristos 			/*
337*a4c163faSchristos 			 * check for overflow
338*a4c163faSchristos 			 */
339*a4c163faSchristos 			if (tval > (UINTMAX_MAX/256))
340*a4c163faSchristos 				return UINTMAX_MAX;
341*a4c163faSchristos 			tval = (tval << 8) | ((*str++) & 0xFF);
342*a4c163faSchristos 		}
343*a4c163faSchristos 
344*a4c163faSchristos 		return tval;
345*a4c163faSchristos 	}
346*a4c163faSchristos 
347*a4c163faSchristos 	/*
3488b35abe2Sjtc 	 * skip over leading blanks and zeros
3498b35abe2Sjtc 	 */
3508b35abe2Sjtc 	while ((str < stop) && ((*str == ' ') || (*str == '0')))
3518b35abe2Sjtc 		++str;
3528b35abe2Sjtc 
3538b35abe2Sjtc 	/*
3548b35abe2Sjtc 	 * for each valid digit, shift running value (tval) over to next digit
3558b35abe2Sjtc 	 * and add next digit
3568b35abe2Sjtc 	 */
3578b35abe2Sjtc 	if (base == HEX) {
3588b35abe2Sjtc 		while (str < stop) {
3598b35abe2Sjtc 			if ((*str >= '0') && (*str <= '9'))
3608b35abe2Sjtc 				tval = (tval << 4) + (*str++ - '0');
3618b35abe2Sjtc 			else if ((*str >= 'A') && (*str <= 'F'))
3628b35abe2Sjtc 				tval = (tval << 4) + 10 + (*str++ - 'A');
3638b35abe2Sjtc 			else if ((*str >= 'a') && (*str <= 'f'))
3648b35abe2Sjtc 				tval = (tval << 4) + 10 + (*str++ - 'a');
3658b35abe2Sjtc 			else
3668b35abe2Sjtc 				break;
3678b35abe2Sjtc 		}
3688b35abe2Sjtc 	} else {
3698b35abe2Sjtc 		while ((str < stop) && (*str >= '0') && (*str <= '7'))
3708b35abe2Sjtc 			tval = (tval << 3) + (*str++ - '0');
3718b35abe2Sjtc 	}
372cdec4ac1Sdsl 	return tval;
3738b35abe2Sjtc }
3748b35abe2Sjtc 
3758b35abe2Sjtc /*
376d653d57cSchristos  * umax_asc()
377d653d57cSchristos  *	convert an uintmax_t into a hex/oct ascii string. pads with
3789ee82d31Slukem  *	LEADING ascii 0's to fill string completely
3798b35abe2Sjtc  *	NOTE: the string created is NOT TERMINATED.
3808b35abe2Sjtc  */
3818b35abe2Sjtc 
3828b35abe2Sjtc int
umax_asc(uintmax_t val,char * str,int len,int base)383d653d57cSchristos umax_asc(uintmax_t val, char *str, int len, int base)
3848b35abe2Sjtc {
38548250187Stls 	char *pt;
386d653d57cSchristos 	uintmax_t digit;
3878b35abe2Sjtc 
3888b35abe2Sjtc 	/*
3898b35abe2Sjtc 	 * WARNING str is not '\0' terminated by this routine
3908b35abe2Sjtc 	 */
3918b35abe2Sjtc 	pt = str + len - 1;
3928b35abe2Sjtc 
3938b35abe2Sjtc 	/*
3948b35abe2Sjtc 	 * do a tailwise conversion (start at right most end of string to place
3958b35abe2Sjtc 	 * least significant digit). Keep shifting until conversion value goes
3968b35abe2Sjtc 	 * to zero (all digits were converted)
3978b35abe2Sjtc 	 */
3988b35abe2Sjtc 	if (base == HEX) {
3998b35abe2Sjtc 		while (pt >= str) {
4008b35abe2Sjtc 			if ((digit = (val & 0xf)) < 10)
4018b35abe2Sjtc 				*pt-- = '0' + (char)digit;
4028b35abe2Sjtc 			else
4038b35abe2Sjtc 				*pt-- = 'a' + (char)(digit - 10);
404d653d57cSchristos 			if ((val = (val >> 4)) == 0)
4058b35abe2Sjtc 				break;
4068b35abe2Sjtc 		}
4078b35abe2Sjtc 	} else {
4088b35abe2Sjtc 		while (pt >= str) {
4098b35abe2Sjtc 			*pt-- = '0' + (char)(val & 0x7);
410d653d57cSchristos 			if ((val = (val >> 3)) == 0)
4118b35abe2Sjtc 				break;
4128b35abe2Sjtc 		}
4138b35abe2Sjtc 	}
4148b35abe2Sjtc 
4158b35abe2Sjtc 	/*
4168b35abe2Sjtc 	 * pad with leading ascii ZEROS. We return -1 if we ran out of space.
4178b35abe2Sjtc 	 */
4188b35abe2Sjtc 	while (pt >= str)
4198b35abe2Sjtc 		*pt-- = '0';
420d653d57cSchristos 	if (val != 0)
421cdec4ac1Sdsl 		return -1;
422cdec4ac1Sdsl 	return 0;
4238b35abe2Sjtc }
4241fbe6b7eStron 
4251fbe6b7eStron int
check_Aflag(void)42627f963a9Smrg check_Aflag(void)
42727f963a9Smrg {
42827f963a9Smrg 
4291fbe6b7eStron 	if (Aflag > 0)
4301fbe6b7eStron 		return 1;
4311fbe6b7eStron 	if (Aflag == 0) {
4321fbe6b7eStron 		Aflag = -1;
433c1bd745cSlukem 		tty_warn(0,
434c1bd745cSlukem 		 "Removing leading / from absolute path names in the archive");
4351fbe6b7eStron 	}
4361fbe6b7eStron 	return 0;
4371fbe6b7eStron }
438