xref: /original-bsd/bin/pax/gen_subs.c (revision 3631e65b)
14f1449c6Smuller /*-
24f1449c6Smuller  * Copyright (c) 1992 Keith Muller.
3*3631e65bSbostic  * Copyright (c) 1992, 1993
4*3631e65bSbostic  *	The Regents of the University of California.  All rights reserved.
54f1449c6Smuller  *
64f1449c6Smuller  * This code is derived from software contributed to Berkeley by
74f1449c6Smuller  * Keith Muller of the University of California, San Diego.
84f1449c6Smuller  *
94f1449c6Smuller  * %sccs.include.redist.c%
104f1449c6Smuller  */
114f1449c6Smuller 
124f1449c6Smuller #ifndef lint
13*3631e65bSbostic static char sccsid[] = "@(#)gen_subs.c	8.1 (Berkeley) 05/31/93";
144f1449c6Smuller #endif /* not lint */
154f1449c6Smuller 
164f1449c6Smuller #include <sys/types.h>
174f1449c6Smuller #include <sys/time.h>
184f1449c6Smuller #include <sys/stat.h>
194f1449c6Smuller #include <sys/param.h>
204f1449c6Smuller #include <stdio.h>
214f1449c6Smuller #include <ctype.h>
224f1449c6Smuller #include <tzfile.h>
234f1449c6Smuller #include <utmp.h>
244f1449c6Smuller #include <unistd.h>
254f1449c6Smuller #include <stdlib.h>
264f1449c6Smuller #include <string.h>
274f1449c6Smuller #include "pax.h"
284f1449c6Smuller #include "extern.h"
294f1449c6Smuller 
304f1449c6Smuller /*
314f1449c6Smuller  * a collection of general purpose subroutines used by pax
324f1449c6Smuller  */
334f1449c6Smuller 
344f1449c6Smuller /*
354f1449c6Smuller  * constants used by ls_list() when printing out archive members
364f1449c6Smuller  */
374f1449c6Smuller #define MODELEN 20
384f1449c6Smuller #define DATELEN 64
394f1449c6Smuller #define SIXMONTHS	 ((DAYSPERNYEAR / 2) * SECSPERDAY)
404f1449c6Smuller #define CURFRMT		"%b %e %H:%M"
414f1449c6Smuller #define OLDFRMT		"%b %e  %Y"
424f1449c6Smuller #ifndef UT_NAMESIZE
434f1449c6Smuller #define UT_NAMESIZE	8
444f1449c6Smuller #endif
454f1449c6Smuller #define UT_GRPSIZE	6
464f1449c6Smuller 
474f1449c6Smuller /*
484f1449c6Smuller  * ls_list()
494f1449c6Smuller  *	list the members of an archive in ls format
504f1449c6Smuller  */
514f1449c6Smuller 
524f1449c6Smuller #if __STDC__
534f1449c6Smuller void
ls_list(register ARCHD * arcn,time_t now)544f1449c6Smuller ls_list(register ARCHD *arcn, time_t now)
554f1449c6Smuller #else
564f1449c6Smuller void
574f1449c6Smuller ls_list(arcn, now)
584f1449c6Smuller 	register ARCHD *arcn;
594f1449c6Smuller 	time_t now;
604f1449c6Smuller #endif
614f1449c6Smuller {
624f1449c6Smuller 	register struct stat *sbp;
634f1449c6Smuller 	char f_mode[MODELEN];
644f1449c6Smuller 	char f_date[DATELEN];
654f1449c6Smuller 	char *timefrmt;
664f1449c6Smuller 
674f1449c6Smuller 	/*
684f1449c6Smuller 	 * if not verbose, just print the file name
694f1449c6Smuller 	 */
704f1449c6Smuller 	if (!vflag) {
714f1449c6Smuller 		(void)printf("%s\n", arcn->name);
724f1449c6Smuller 		(void)fflush(stdout);
734f1449c6Smuller 		return;
744f1449c6Smuller 	}
754f1449c6Smuller 
764f1449c6Smuller 	/*
774f1449c6Smuller 	 * user wants long mode
784f1449c6Smuller 	 */
794f1449c6Smuller 	sbp = &(arcn->sb);
804f1449c6Smuller 	strmode(sbp->st_mode, f_mode);
814f1449c6Smuller 
824f1449c6Smuller 	if (ltmfrmt == NULL) {
834f1449c6Smuller 		/*
844f1449c6Smuller 		 * no locale specified format. time format based on age
854f1449c6Smuller 		 * compared to the time pax was started.
864f1449c6Smuller 		 */
874f1449c6Smuller 		if ((sbp->st_mtime + SIXMONTHS) <= now)
884f1449c6Smuller 			timefrmt = OLDFRMT;
894f1449c6Smuller 		else
904f1449c6Smuller 			timefrmt = CURFRMT;
914f1449c6Smuller 	} else
924f1449c6Smuller 		timefrmt = ltmfrmt;
934f1449c6Smuller 
944f1449c6Smuller 	/*
954f1449c6Smuller 	 * print file mode, link count, uid, gid and time
964f1449c6Smuller 	 */
974f1449c6Smuller 	if (strftime(f_date,DATELEN,timefrmt,localtime(&(sbp->st_mtime))) == 0)
984f1449c6Smuller 		f_date[0] = '\0';
994f1449c6Smuller 	(void)printf("%s%2u %-*s %-*s ", f_mode, sbp->st_nlink, UT_NAMESIZE,
1004f1449c6Smuller 		name_uid(sbp->st_uid, 1), UT_GRPSIZE,
1014f1449c6Smuller 		name_gid(sbp->st_gid, 1));
1024f1449c6Smuller 
1034f1449c6Smuller 	/*
1044f1449c6Smuller 	 * print device id's for devices, or sizes for other nodes
1054f1449c6Smuller 	 */
1064f1449c6Smuller 	if ((arcn->type == PAX_CHR) || (arcn->type == PAX_BLK))
1074f1449c6Smuller #		ifdef NET2_STAT
1084f1449c6Smuller 		(void)printf("%4u,%4u ", MAJOR(sbp->st_rdev),
1094f1449c6Smuller #		else
1104f1449c6Smuller 		(void)printf("%4lu,%4lu ", MAJOR(sbp->st_rdev),
1114f1449c6Smuller #		endif
1124f1449c6Smuller 		    MINOR(sbp->st_rdev));
1134f1449c6Smuller 	else {
1144f1449c6Smuller #		ifdef NET2_STAT
1154f1449c6Smuller 		(void)printf("%9lu ", sbp->st_size);
1164f1449c6Smuller #		else
1174f1449c6Smuller 		(void)printf("%9qu ", sbp->st_size);
1184f1449c6Smuller #		endif
1194f1449c6Smuller 	}
1204f1449c6Smuller 
1214f1449c6Smuller 	/*
1224f1449c6Smuller 	 * print name and link info for hard and soft links
1234f1449c6Smuller 	 */
1244f1449c6Smuller 	(void)printf("%s %s", f_date, arcn->name);
1254f1449c6Smuller 	if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))
1264f1449c6Smuller 		(void)printf(" == %s\n", arcn->ln_name);
1274f1449c6Smuller 	else if (arcn->type == PAX_SLK)
1284f1449c6Smuller 		(void)printf(" => %s\n", arcn->ln_name);
1294f1449c6Smuller 	else
1304f1449c6Smuller 		(void)putchar('\n');
1314f1449c6Smuller 	(void)fflush(stdout);
1324f1449c6Smuller 	return;
1334f1449c6Smuller }
1344f1449c6Smuller 
1354f1449c6Smuller /*
1364f1449c6Smuller  * tty_ls()
1374f1449c6Smuller  * 	print a short summary of file to tty.
1384f1449c6Smuller  */
1394f1449c6Smuller 
1404f1449c6Smuller #if __STDC__
1414f1449c6Smuller void
ls_tty(register ARCHD * arcn)1424f1449c6Smuller ls_tty(register ARCHD *arcn)
1434f1449c6Smuller #else
1444f1449c6Smuller void
1454f1449c6Smuller ls_tty(arcn)
1464f1449c6Smuller 	register ARCHD *arcn;
1474f1449c6Smuller #endif
1484f1449c6Smuller {
1494f1449c6Smuller 	char f_date[DATELEN];
1504f1449c6Smuller 	char f_mode[MODELEN];
1514f1449c6Smuller 	char *timefrmt;
1524f1449c6Smuller 
1534f1449c6Smuller 	if (ltmfrmt == NULL) {
1544f1449c6Smuller 		/*
1554f1449c6Smuller 		 * no locale specified format
1564f1449c6Smuller 		 */
1574f1449c6Smuller 		if ((arcn->sb.st_mtime + SIXMONTHS) <= time((time_t *)NULL))
1584f1449c6Smuller 			timefrmt = OLDFRMT;
1594f1449c6Smuller 		else
1604f1449c6Smuller 			timefrmt = CURFRMT;
1614f1449c6Smuller 	} else
1624f1449c6Smuller 		timefrmt = ltmfrmt;
1634f1449c6Smuller 
1644f1449c6Smuller 	/*
1654f1449c6Smuller 	 * convert time to string, and print
1664f1449c6Smuller 	 */
1674f1449c6Smuller 	if (strftime(f_date, DATELEN, timefrmt,
1684f1449c6Smuller 	    localtime(&(arcn->sb.st_mtime))) == 0)
1694f1449c6Smuller 		f_date[0] = '\0';
1704f1449c6Smuller 	strmode(arcn->sb.st_mode, f_mode);
1714f1449c6Smuller 	tty_prnt("%s%s %s\n", f_mode, f_date, arcn->name);
1724f1449c6Smuller 	return;
1734f1449c6Smuller }
1744f1449c6Smuller 
1754f1449c6Smuller /*
1764f1449c6Smuller  * zf_strncpy()
1774f1449c6Smuller  *	copy src to dest up to len chars (stopping at first '\0'), when src is
1784f1449c6Smuller  *	shorter than len, pads to len with '\0'. big performance win (and
1794f1449c6Smuller  *	a lot easier to code) over strncpy(), then a strlen() then a
1804f1449c6Smuller  *	bzero(). (or doing the bzero() first).
1814f1449c6Smuller  */
1824f1449c6Smuller 
1834f1449c6Smuller #if __STDC__
1844f1449c6Smuller void
zf_strncpy(register char * dest,register char * src,int len)1854f1449c6Smuller zf_strncpy(register char *dest, register char *src, int len)
1864f1449c6Smuller #else
1874f1449c6Smuller void
1884f1449c6Smuller zf_strncpy(dest, src, len)
1894f1449c6Smuller 	register char *dest;
1904f1449c6Smuller 	register char *src;
1914f1449c6Smuller 	int len;
1924f1449c6Smuller #endif
1934f1449c6Smuller {
1944f1449c6Smuller 	register char *stop;
1954f1449c6Smuller 
1964f1449c6Smuller 	stop = dest + len;
1974f1449c6Smuller 	while ((dest < stop) && (*src != '\0'))
1984f1449c6Smuller 		*dest++ = *src++;
1994f1449c6Smuller 	while (dest < stop)
2004f1449c6Smuller 		*dest++ = '\0';
2014f1449c6Smuller 	return;
2024f1449c6Smuller }
2034f1449c6Smuller 
2044f1449c6Smuller /*
2054f1449c6Smuller  * l_strncpy()
2064f1449c6Smuller  *	copy src to dest up to len chars (stopping at first '\0')
2074f1449c6Smuller  * Return:
2084f1449c6Smuller  *	number of chars copied. (Note this is a real performance win over
2094f1449c6Smuller  *	doing a strncpy() then a strlen()
2104f1449c6Smuller  */
2114f1449c6Smuller 
2124f1449c6Smuller #if __STDC__
2134f1449c6Smuller int
l_strncpy(register char * dest,register char * src,int len)2144f1449c6Smuller l_strncpy(register char *dest, register char *src, int len)
2154f1449c6Smuller #else
2164f1449c6Smuller int
2174f1449c6Smuller l_strncpy(dest, src, len)
2184f1449c6Smuller 	register char *dest;
2194f1449c6Smuller 	register char *src;
2204f1449c6Smuller 	int len;
2214f1449c6Smuller #endif
2224f1449c6Smuller {
2234f1449c6Smuller 	register char *stop;
2244f1449c6Smuller 	register char *start;
2254f1449c6Smuller 
2264f1449c6Smuller 	stop = dest + len;
2274f1449c6Smuller 	start = dest;
2284f1449c6Smuller 	while ((dest < stop) && (*src != '\0'))
2294f1449c6Smuller 		*dest++ = *src++;
2304f1449c6Smuller 	if (dest < stop)
2314f1449c6Smuller 		*dest = '\0';
2324f1449c6Smuller 	return(dest - start);
2334f1449c6Smuller }
2344f1449c6Smuller 
2354f1449c6Smuller /*
2364f1449c6Smuller  * asc_ul()
2374f1449c6Smuller  *	convert hex/octal character string into a u_long. We do not have to
2384f1449c6Smuller  *	check for overflow! (the headers in all supported formats are not large
2394f1449c6Smuller  *	enough to create an overflow).
2404f1449c6Smuller  *	NOTE: strings passed to us are NOT TERMINATED.
2414f1449c6Smuller  * Return:
2424f1449c6Smuller  *	unsigned long value
2434f1449c6Smuller  */
2444f1449c6Smuller 
2454f1449c6Smuller #if __STDC__
2464f1449c6Smuller u_long
asc_ul(register char * str,int len,register int base)2474f1449c6Smuller asc_ul(register char *str, int len, register int base)
2484f1449c6Smuller #else
2494f1449c6Smuller u_long
2504f1449c6Smuller asc_ul(str, len, base)
2514f1449c6Smuller 	register char *str;
2524f1449c6Smuller 	int len;
2534f1449c6Smuller 	register int base;
2544f1449c6Smuller #endif
2554f1449c6Smuller {
2564f1449c6Smuller 	register char *stop;
2574f1449c6Smuller 	u_long tval = 0;
2584f1449c6Smuller 
2594f1449c6Smuller 	stop = str + len;
2604f1449c6Smuller 
2614f1449c6Smuller 	/*
2624f1449c6Smuller 	 * skip over leading blanks and zeros
2634f1449c6Smuller 	 */
2644f1449c6Smuller 	while ((str < stop) && ((*str == ' ') || (*str == '0')))
2654f1449c6Smuller 		++str;
2664f1449c6Smuller 
2674f1449c6Smuller 	/*
2684f1449c6Smuller 	 * for each valid digit, shift running value (tval) over to next digit
2694f1449c6Smuller 	 * and add next digit
2704f1449c6Smuller 	 */
2714f1449c6Smuller 	if (base == HEX) {
2724f1449c6Smuller 		while (str < stop) {
2734f1449c6Smuller 			if ((*str >= '0') && (*str <= '9'))
2744f1449c6Smuller 				tval = (tval << 4) + (*str++ - '0');
2754f1449c6Smuller 			else if ((*str >= 'A') && (*str <= 'F'))
2764f1449c6Smuller 				tval = (tval << 4) + 10 + (*str++ - 'A');
2774f1449c6Smuller 			else if ((*str >= 'a') && (*str <= 'f'))
2784f1449c6Smuller 				tval = (tval << 4) + 10 + (*str++ - 'a');
2794f1449c6Smuller 			else
2804f1449c6Smuller 				break;
2814f1449c6Smuller 		}
2824f1449c6Smuller 	} else {
2834f1449c6Smuller  		while ((str < stop) && (*str >= '0') && (*str <= '7'))
2844f1449c6Smuller 			tval = (tval << 3) + (*str++ - '0');
2854f1449c6Smuller 	}
2864f1449c6Smuller 	return(tval);
2874f1449c6Smuller }
2884f1449c6Smuller 
2894f1449c6Smuller /*
2904f1449c6Smuller  * ul_asc()
2914f1449c6Smuller  *	convert an unsigned long into an hex/oct ascii string. pads with LEADING
2924f1449c6Smuller  *	ascii 0's to fill string completely
2934f1449c6Smuller  *	NOTE: the string created is NOT TERMINATED.
2944f1449c6Smuller  */
2954f1449c6Smuller 
2964f1449c6Smuller #if __STDC__
2974f1449c6Smuller int
ul_asc(u_long val,register char * str,register int len,register int base)2984f1449c6Smuller ul_asc(u_long val, register char *str, register int len, register int base)
2994f1449c6Smuller #else
3004f1449c6Smuller int
3014f1449c6Smuller ul_asc(val, str, len, base)
3024f1449c6Smuller 	u_long val;
3034f1449c6Smuller 	register char *str;
3044f1449c6Smuller 	register int len;
3054f1449c6Smuller 	register int base;
3064f1449c6Smuller #endif
3074f1449c6Smuller {
3084f1449c6Smuller 	register char *pt;
3094f1449c6Smuller 	u_long digit;
3104f1449c6Smuller 
3114f1449c6Smuller 	/*
3124f1449c6Smuller 	 * WARNING str is not '\0' terminated by this routine
3134f1449c6Smuller 	 */
3144f1449c6Smuller 	pt = str + len - 1;
3154f1449c6Smuller 
3164f1449c6Smuller 	/*
3174f1449c6Smuller 	 * do a tailwise conversion (start at right most end of string to place
3184f1449c6Smuller 	 * least significant digit). Keep shifting until conversion value goes
3194f1449c6Smuller 	 * to zero (all digits were converted)
3204f1449c6Smuller 	 */
3214f1449c6Smuller 	if (base == HEX) {
3224f1449c6Smuller 		while (pt >= str) {
3234f1449c6Smuller 			if ((digit = (val & 0xf)) < 10)
3244f1449c6Smuller 				*pt-- = '0' + (char)digit;
3254f1449c6Smuller 			else
3264f1449c6Smuller 				*pt-- = 'a' + (char)(digit - 10);
3274f1449c6Smuller 			if ((val = (val >> 4)) == (u_long)0)
3284f1449c6Smuller 				break;
3294f1449c6Smuller 		}
3304f1449c6Smuller 	} else {
3314f1449c6Smuller 		while (pt >= str) {
3324f1449c6Smuller 			*pt-- = '0' + (char)(val & 0x7);
3334f1449c6Smuller 			if ((val = (val >> 3)) == (u_long)0)
3344f1449c6Smuller 				break;
3354f1449c6Smuller 		}
3364f1449c6Smuller 	}
3374f1449c6Smuller 
3384f1449c6Smuller 	/*
3394f1449c6Smuller 	 * pad with leading ascii ZEROS. We return -1 if we ran out of space.
3404f1449c6Smuller 	 */
3414f1449c6Smuller 	while (pt >= str)
3424f1449c6Smuller 		*pt-- = '0';
3434f1449c6Smuller 	if (val != (u_long)0)
3444f1449c6Smuller 		return(-1);
3454f1449c6Smuller 	return(0);
3464f1449c6Smuller }
3474f1449c6Smuller 
3484f1449c6Smuller #ifndef NET2_STAT
3494f1449c6Smuller /*
3504f1449c6Smuller  * asc_uqd()
3514f1449c6Smuller  *	convert hex/octal character string into a u_quad_t. We do not have to
3524f1449c6Smuller  *	check for overflow! (the headers in all supported formats are not large
3534f1449c6Smuller  *	enough to create an overflow).
3544f1449c6Smuller  *	NOTE: strings passed to us are NOT TERMINATED.
3554f1449c6Smuller  * Return:
3564f1449c6Smuller  *	u_quad_t value
3574f1449c6Smuller  */
3584f1449c6Smuller 
3594f1449c6Smuller #if __STDC__
3604f1449c6Smuller u_quad_t
asc_uqd(register char * str,int len,register int base)3614f1449c6Smuller asc_uqd(register char *str, int len, register int base)
3624f1449c6Smuller #else
3634f1449c6Smuller u_quad_t
3644f1449c6Smuller asc_uqd(str, len, base)
3654f1449c6Smuller 	register char *str;
3664f1449c6Smuller 	int len;
3674f1449c6Smuller 	register int base;
3684f1449c6Smuller #endif
3694f1449c6Smuller {
3704f1449c6Smuller 	register char *stop;
3714f1449c6Smuller 	u_quad_t tval = 0;
3724f1449c6Smuller 
3734f1449c6Smuller 	stop = str + len;
3744f1449c6Smuller 
3754f1449c6Smuller 	/*
3764f1449c6Smuller 	 * skip over leading blanks and zeros
3774f1449c6Smuller 	 */
3784f1449c6Smuller 	while ((str < stop) && ((*str == ' ') || (*str == '0')))
3794f1449c6Smuller 		++str;
3804f1449c6Smuller 
3814f1449c6Smuller 	/*
3824f1449c6Smuller 	 * for each valid digit, shift running value (tval) over to next digit
3834f1449c6Smuller 	 * and add next digit
3844f1449c6Smuller 	 */
3854f1449c6Smuller 	if (base == HEX) {
3864f1449c6Smuller 		while (str < stop) {
3874f1449c6Smuller 			if ((*str >= '0') && (*str <= '9'))
3884f1449c6Smuller 				tval = (tval << 4) + (*str++ - '0');
3894f1449c6Smuller 			else if ((*str >= 'A') && (*str <= 'F'))
3904f1449c6Smuller 				tval = (tval << 4) + 10 + (*str++ - 'A');
3914f1449c6Smuller 			else if ((*str >= 'a') && (*str <= 'f'))
3924f1449c6Smuller 				tval = (tval << 4) + 10 + (*str++ - 'a');
3934f1449c6Smuller 			else
3944f1449c6Smuller 				break;
3954f1449c6Smuller 		}
3964f1449c6Smuller 	} else {
3974f1449c6Smuller  		while ((str < stop) && (*str >= '0') && (*str <= '7'))
3984f1449c6Smuller 			tval = (tval << 3) + (*str++ - '0');
3994f1449c6Smuller 	}
4004f1449c6Smuller 	return(tval);
4014f1449c6Smuller }
4024f1449c6Smuller 
4034f1449c6Smuller /*
4044f1449c6Smuller  * uqd_asc()
4054f1449c6Smuller  *	convert an u_quad_t into a hex/oct ascii string. pads with LEADING
4064f1449c6Smuller  *	ascii 0's to fill string completely
4074f1449c6Smuller  *	NOTE: the string created is NOT TERMINATED.
4084f1449c6Smuller  */
4094f1449c6Smuller 
4104f1449c6Smuller #if __STDC__
4114f1449c6Smuller int
uqd_asc(u_quad_t val,register char * str,register int len,register int base)4124f1449c6Smuller uqd_asc(u_quad_t val, register char *str, register int len, register int base)
4134f1449c6Smuller #else
4144f1449c6Smuller int
4154f1449c6Smuller uqd_asc(val, str, len, base)
4164f1449c6Smuller 	u_quad_t val;
4174f1449c6Smuller 	register char *str;
4184f1449c6Smuller 	register int len;
4194f1449c6Smuller 	register int base;
4204f1449c6Smuller #endif
4214f1449c6Smuller {
4224f1449c6Smuller 	register char *pt;
4234f1449c6Smuller 	u_quad_t digit;
4244f1449c6Smuller 
4254f1449c6Smuller 	/*
4264f1449c6Smuller 	 * WARNING str is not '\0' terminated by this routine
4274f1449c6Smuller 	 */
4284f1449c6Smuller 	pt = str + len - 1;
4294f1449c6Smuller 
4304f1449c6Smuller 	/*
4314f1449c6Smuller 	 * do a tailwise conversion (start at right most end of string to place
4324f1449c6Smuller 	 * least significant digit). Keep shifting until conversion value goes
4334f1449c6Smuller 	 * to zero (all digits were converted)
4344f1449c6Smuller 	 */
4354f1449c6Smuller 	if (base == HEX) {
4364f1449c6Smuller 		while (pt >= str) {
4374f1449c6Smuller 			if ((digit = (val & 0xf)) < 10)
4384f1449c6Smuller 				*pt-- = '0' + (char)digit;
4394f1449c6Smuller 			else
4404f1449c6Smuller 				*pt-- = 'a' + (char)(digit - 10);
4414f1449c6Smuller 			if ((val = (val >> 4)) == (u_quad_t)0)
4424f1449c6Smuller 				break;
4434f1449c6Smuller 		}
4444f1449c6Smuller 	} else {
4454f1449c6Smuller 		while (pt >= str) {
4464f1449c6Smuller 			*pt-- = '0' + (char)(val & 0x7);
4474f1449c6Smuller 			if ((val = (val >> 3)) == (u_quad_t)0)
4484f1449c6Smuller 				break;
4494f1449c6Smuller 		}
4504f1449c6Smuller 	}
4514f1449c6Smuller 
4524f1449c6Smuller 	/*
4534f1449c6Smuller 	 * pad with leading ascii ZEROS. We return -1 if we ran out of space.
4544f1449c6Smuller 	 */
4554f1449c6Smuller 	while (pt >= str)
4564f1449c6Smuller 		*pt-- = '0';
4574f1449c6Smuller 	if (val != (u_quad_t)0)
4584f1449c6Smuller 		return(-1);
4594f1449c6Smuller 	return(0);
4604f1449c6Smuller }
4614f1449c6Smuller #endif
462