14b88c807SRodney W. Grimes /*- 24b88c807SRodney W. Grimes * Copyright (c) 1992 Keith Muller. 34b88c807SRodney W. Grimes * Copyright (c) 1992, 1993 44b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 54b88c807SRodney W. Grimes * 64b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 74b88c807SRodney W. Grimes * Keith Muller of the University of California, San Diego. 84b88c807SRodney W. Grimes * 94b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 104b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 114b88c807SRodney W. Grimes * are met: 124b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 134b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 144b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 154b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 164b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 174b88c807SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 184b88c807SRodney W. Grimes * must display the following acknowledgement: 194b88c807SRodney W. Grimes * This product includes software developed by the University of 204b88c807SRodney W. Grimes * California, Berkeley and its contributors. 214b88c807SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 224b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 234b88c807SRodney W. Grimes * without specific prior written permission. 244b88c807SRodney W. Grimes * 254b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 264b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 274b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 284b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 294b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 304b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 314b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 324b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 334b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 344b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 354b88c807SRodney W. Grimes * SUCH DAMAGE. 364b88c807SRodney W. Grimes */ 374b88c807SRodney W. Grimes 384b88c807SRodney W. Grimes #ifndef lint 39c9a8d1f4SPhilippe Charnier #if 0 40c9a8d1f4SPhilippe Charnier static char sccsid[] = "@(#)gen_subs.c 8.1 (Berkeley) 5/31/93"; 41c9a8d1f4SPhilippe Charnier #endif 42c9a8d1f4SPhilippe Charnier static const char rcsid[] = 432a456239SPeter Wemm "$FreeBSD$"; 444b88c807SRodney W. Grimes #endif /* not lint */ 454b88c807SRodney W. Grimes 464b88c807SRodney W. Grimes #include <sys/types.h> 474b88c807SRodney W. Grimes #include <sys/time.h> 484b88c807SRodney W. Grimes #include <sys/stat.h> 495f94e68dSAndrey A. Chernov #include <langinfo.h> 504b88c807SRodney W. Grimes #include <stdio.h> 514b88c807SRodney W. Grimes #include <utmp.h> 524b88c807SRodney W. Grimes #include <unistd.h> 534b88c807SRodney W. Grimes #include <stdlib.h> 544b88c807SRodney W. Grimes #include <string.h> 554b88c807SRodney W. Grimes #include "pax.h" 564b88c807SRodney W. Grimes #include "extern.h" 574b88c807SRodney W. Grimes 584b88c807SRodney W. Grimes /* 594b88c807SRodney W. Grimes * a collection of general purpose subroutines used by pax 604b88c807SRodney W. Grimes */ 614b88c807SRodney W. Grimes 624b88c807SRodney W. Grimes /* 634b88c807SRodney W. Grimes * constants used by ls_list() when printing out archive members 644b88c807SRodney W. Grimes */ 654b88c807SRodney W. Grimes #define MODELEN 20 664b88c807SRodney W. Grimes #define DATELEN 64 67656dcd43SGarrett Wollman #define SIXMONTHS ((365 / 2) * 86400) 685f94e68dSAndrey A. Chernov #define CURFRMTM "%b %e %H:%M" 695f94e68dSAndrey A. Chernov #define OLDFRMTM "%b %e %Y" 705f94e68dSAndrey A. Chernov #define CURFRMTD "%e %b %H:%M" 715f94e68dSAndrey A. Chernov #define OLDFRMTD "%e %b %Y" 724b88c807SRodney W. Grimes #ifndef UT_NAMESIZE 734b88c807SRodney W. Grimes #define UT_NAMESIZE 8 744b88c807SRodney W. Grimes #endif 754b88c807SRodney W. Grimes #define UT_GRPSIZE 6 764b88c807SRodney W. Grimes 775f94e68dSAndrey A. Chernov static int d_first = -1; 785f94e68dSAndrey A. Chernov 794b88c807SRodney W. Grimes /* 804b88c807SRodney W. Grimes * ls_list() 814b88c807SRodney W. Grimes * list the members of an archive in ls format 824b88c807SRodney W. Grimes */ 834b88c807SRodney W. Grimes 84778766feSKris Kennaway #ifdef __STDC__ 854b88c807SRodney W. Grimes void 864b88c807SRodney W. Grimes ls_list(register ARCHD *arcn, time_t now) 874b88c807SRodney W. Grimes #else 884b88c807SRodney W. Grimes void 894b88c807SRodney W. Grimes ls_list(arcn, now) 904b88c807SRodney W. Grimes register ARCHD *arcn; 914b88c807SRodney W. Grimes time_t now; 924b88c807SRodney W. Grimes #endif 934b88c807SRodney W. Grimes { 944b88c807SRodney W. Grimes register struct stat *sbp; 954b88c807SRodney W. Grimes char f_mode[MODELEN]; 964b88c807SRodney W. Grimes char f_date[DATELEN]; 974b88c807SRodney W. Grimes char *timefrmt; 984b88c807SRodney W. Grimes 994b88c807SRodney W. Grimes /* 1004b88c807SRodney W. Grimes * if not verbose, just print the file name 1014b88c807SRodney W. Grimes */ 1024b88c807SRodney W. Grimes if (!vflag) { 1034b88c807SRodney W. Grimes (void)printf("%s\n", arcn->name); 1044b88c807SRodney W. Grimes (void)fflush(stdout); 1054b88c807SRodney W. Grimes return; 1064b88c807SRodney W. Grimes } 1074b88c807SRodney W. Grimes 1085f94e68dSAndrey A. Chernov if (d_first < 0) 1095f94e68dSAndrey A. Chernov d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); 1104b88c807SRodney W. Grimes /* 1114b88c807SRodney W. Grimes * user wants long mode 1124b88c807SRodney W. Grimes */ 1134b88c807SRodney W. Grimes sbp = &(arcn->sb); 1144b88c807SRodney W. Grimes strmode(sbp->st_mode, f_mode); 1154b88c807SRodney W. Grimes 1164b88c807SRodney W. Grimes /* 1177a6be913SRuslan Ermilov * time format based on age compared to the time pax was started. 1184b88c807SRodney W. Grimes */ 1194b88c807SRodney W. Grimes if ((sbp->st_mtime + SIXMONTHS) <= now) 1205f94e68dSAndrey A. Chernov timefrmt = d_first ? OLDFRMTD : OLDFRMTM; 1214b88c807SRodney W. Grimes else 1225f94e68dSAndrey A. Chernov timefrmt = d_first ? CURFRMTD : CURFRMTM; 1234b88c807SRodney W. Grimes 1244b88c807SRodney W. Grimes /* 1254b88c807SRodney W. Grimes * print file mode, link count, uid, gid and time 1264b88c807SRodney W. Grimes */ 1274b88c807SRodney W. Grimes if (strftime(f_date,DATELEN,timefrmt,localtime(&(sbp->st_mtime))) == 0) 1284b88c807SRodney W. Grimes f_date[0] = '\0'; 1294b88c807SRodney W. Grimes (void)printf("%s%2u %-*s %-*s ", f_mode, sbp->st_nlink, UT_NAMESIZE, 1304b88c807SRodney W. Grimes name_uid(sbp->st_uid, 1), UT_GRPSIZE, 1314b88c807SRodney W. Grimes name_gid(sbp->st_gid, 1)); 1324b88c807SRodney W. Grimes 1334b88c807SRodney W. Grimes /* 1344b88c807SRodney W. Grimes * print device id's for devices, or sizes for other nodes 1354b88c807SRodney W. Grimes */ 1364b88c807SRodney W. Grimes if ((arcn->type == PAX_CHR) || (arcn->type == PAX_BLK)) 1374b88c807SRodney W. Grimes # ifdef NET2_STAT 1384b88c807SRodney W. Grimes (void)printf("%4u,%4u ", MAJOR(sbp->st_rdev), 13978b09ffeSSteve Price MINOR(sbp->st_rdev)); 1404b88c807SRodney W. Grimes # else 1410fd510b7SJoerg Wunsch (void)printf("%4lu,%4lu ", (unsigned long)MAJOR(sbp->st_rdev), 14278b09ffeSSteve Price (unsigned long)MINOR(sbp->st_rdev)); 1434b88c807SRodney W. Grimes # endif 1444b88c807SRodney W. Grimes else { 1454b88c807SRodney W. Grimes # ifdef NET2_STAT 1464b88c807SRodney W. Grimes (void)printf("%9lu ", sbp->st_size); 1474b88c807SRodney W. Grimes # else 1484b88c807SRodney W. Grimes (void)printf("%9qu ", sbp->st_size); 1494b88c807SRodney W. Grimes # endif 1504b88c807SRodney W. Grimes } 1514b88c807SRodney W. Grimes 1524b88c807SRodney W. Grimes /* 1534b88c807SRodney W. Grimes * print name and link info for hard and soft links 1544b88c807SRodney W. Grimes */ 1554b88c807SRodney W. Grimes (void)printf("%s %s", f_date, arcn->name); 1564b88c807SRodney W. Grimes if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) 1574b88c807SRodney W. Grimes (void)printf(" == %s\n", arcn->ln_name); 1584b88c807SRodney W. Grimes else if (arcn->type == PAX_SLK) 1594b88c807SRodney W. Grimes (void)printf(" => %s\n", arcn->ln_name); 1604b88c807SRodney W. Grimes else 1614b88c807SRodney W. Grimes (void)putchar('\n'); 1624b88c807SRodney W. Grimes (void)fflush(stdout); 1634b88c807SRodney W. Grimes return; 1644b88c807SRodney W. Grimes } 1654b88c807SRodney W. Grimes 1664b88c807SRodney W. Grimes /* 1674b88c807SRodney W. Grimes * tty_ls() 1684b88c807SRodney W. Grimes * print a short summary of file to tty. 1694b88c807SRodney W. Grimes */ 1704b88c807SRodney W. Grimes 171778766feSKris Kennaway #ifdef __STDC__ 1724b88c807SRodney W. Grimes void 1734b88c807SRodney W. Grimes ls_tty(register ARCHD *arcn) 1744b88c807SRodney W. Grimes #else 1754b88c807SRodney W. Grimes void 1764b88c807SRodney W. Grimes ls_tty(arcn) 1774b88c807SRodney W. Grimes register ARCHD *arcn; 1784b88c807SRodney W. Grimes #endif 1794b88c807SRodney W. Grimes { 1804b88c807SRodney W. Grimes char f_date[DATELEN]; 1814b88c807SRodney W. Grimes char f_mode[MODELEN]; 1824b88c807SRodney W. Grimes char *timefrmt; 1834b88c807SRodney W. Grimes 1845f94e68dSAndrey A. Chernov if (d_first < 0) 1855f94e68dSAndrey A. Chernov d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); 1865f94e68dSAndrey A. Chernov 187778766feSKris Kennaway if ((arcn->sb.st_mtime + SIXMONTHS) <= time(NULL)) 1885f94e68dSAndrey A. Chernov timefrmt = d_first ? OLDFRMTD : OLDFRMTM; 1894b88c807SRodney W. Grimes else 1905f94e68dSAndrey A. Chernov timefrmt = d_first ? CURFRMTD : CURFRMTM; 1914b88c807SRodney W. Grimes 1924b88c807SRodney W. Grimes /* 1934b88c807SRodney W. Grimes * convert time to string, and print 1944b88c807SRodney W. Grimes */ 1954b88c807SRodney W. Grimes if (strftime(f_date, DATELEN, timefrmt, 1964b88c807SRodney W. Grimes localtime(&(arcn->sb.st_mtime))) == 0) 1974b88c807SRodney W. Grimes f_date[0] = '\0'; 1984b88c807SRodney W. Grimes strmode(arcn->sb.st_mode, f_mode); 1994b88c807SRodney W. Grimes tty_prnt("%s%s %s\n", f_mode, f_date, arcn->name); 2004b88c807SRodney W. Grimes return; 2014b88c807SRodney W. Grimes } 2024b88c807SRodney W. Grimes 2034b88c807SRodney W. Grimes /* 2044b88c807SRodney W. Grimes * zf_strncpy() 2054b88c807SRodney W. Grimes * copy src to dest up to len chars (stopping at first '\0'), when src is 2064b88c807SRodney W. Grimes * shorter than len, pads to len with '\0'. big performance win (and 2074b88c807SRodney W. Grimes * a lot easier to code) over strncpy(), then a strlen() then a 208778766feSKris Kennaway * memset(). (or doing the memset() first). 2094b88c807SRodney W. Grimes */ 2104b88c807SRodney W. Grimes 211778766feSKris Kennaway #ifdef __STDC__ 2124b88c807SRodney W. Grimes void 2134b88c807SRodney W. Grimes zf_strncpy(register char *dest, register char *src, int len) 2144b88c807SRodney W. Grimes #else 2154b88c807SRodney W. Grimes void 2164b88c807SRodney W. Grimes zf_strncpy(dest, src, len) 2174b88c807SRodney W. Grimes register char *dest; 2184b88c807SRodney W. Grimes register char *src; 2194b88c807SRodney W. Grimes int len; 2204b88c807SRodney W. Grimes #endif 2214b88c807SRodney W. Grimes { 2224b88c807SRodney W. Grimes register char *stop; 2234b88c807SRodney W. Grimes 2244b88c807SRodney W. Grimes stop = dest + len; 2254b88c807SRodney W. Grimes while ((dest < stop) && (*src != '\0')) 2264b88c807SRodney W. Grimes *dest++ = *src++; 2274b88c807SRodney W. Grimes while (dest < stop) 2284b88c807SRodney W. Grimes *dest++ = '\0'; 2294b88c807SRodney W. Grimes return; 2304b88c807SRodney W. Grimes } 2314b88c807SRodney W. Grimes 2324b88c807SRodney W. Grimes /* 2334b88c807SRodney W. Grimes * l_strncpy() 2344b88c807SRodney W. Grimes * copy src to dest up to len chars (stopping at first '\0') 2354b88c807SRodney W. Grimes * Return: 2364b88c807SRodney W. Grimes * number of chars copied. (Note this is a real performance win over 2374b88c807SRodney W. Grimes * doing a strncpy() then a strlen() 2384b88c807SRodney W. Grimes */ 2394b88c807SRodney W. Grimes 240778766feSKris Kennaway #ifdef __STDC__ 2414b88c807SRodney W. Grimes int 2424b88c807SRodney W. Grimes l_strncpy(register char *dest, register char *src, int len) 2434b88c807SRodney W. Grimes #else 2444b88c807SRodney W. Grimes int 2454b88c807SRodney W. Grimes l_strncpy(dest, src, len) 2464b88c807SRodney W. Grimes register char *dest; 2474b88c807SRodney W. Grimes register char *src; 2484b88c807SRodney W. Grimes int len; 2494b88c807SRodney W. Grimes #endif 2504b88c807SRodney W. Grimes { 2514b88c807SRodney W. Grimes register char *stop; 2524b88c807SRodney W. Grimes register char *start; 2534b88c807SRodney W. Grimes 2544b88c807SRodney W. Grimes stop = dest + len; 2554b88c807SRodney W. Grimes start = dest; 2564b88c807SRodney W. Grimes while ((dest < stop) && (*src != '\0')) 2574b88c807SRodney W. Grimes *dest++ = *src++; 2584b88c807SRodney W. Grimes if (dest < stop) 2594b88c807SRodney W. Grimes *dest = '\0'; 2604b88c807SRodney W. Grimes return(dest - start); 2614b88c807SRodney W. Grimes } 2624b88c807SRodney W. Grimes 2634b88c807SRodney W. Grimes /* 2644b88c807SRodney W. Grimes * asc_ul() 2654b88c807SRodney W. Grimes * convert hex/octal character string into a u_long. We do not have to 2664b88c807SRodney W. Grimes * check for overflow! (the headers in all supported formats are not large 2674b88c807SRodney W. Grimes * enough to create an overflow). 2684b88c807SRodney W. Grimes * NOTE: strings passed to us are NOT TERMINATED. 2694b88c807SRodney W. Grimes * Return: 2704b88c807SRodney W. Grimes * unsigned long value 2714b88c807SRodney W. Grimes */ 2724b88c807SRodney W. Grimes 273778766feSKris Kennaway #ifdef __STDC__ 2744b88c807SRodney W. Grimes u_long 2754b88c807SRodney W. Grimes asc_ul(register char *str, int len, register int base) 2764b88c807SRodney W. Grimes #else 2774b88c807SRodney W. Grimes u_long 2784b88c807SRodney W. Grimes asc_ul(str, len, base) 2794b88c807SRodney W. Grimes register char *str; 2804b88c807SRodney W. Grimes int len; 2814b88c807SRodney W. Grimes register int base; 2824b88c807SRodney W. Grimes #endif 2834b88c807SRodney W. Grimes { 2844b88c807SRodney W. Grimes register char *stop; 2854b88c807SRodney W. Grimes u_long tval = 0; 2864b88c807SRodney W. Grimes 2874b88c807SRodney W. Grimes stop = str + len; 2884b88c807SRodney W. Grimes 2894b88c807SRodney W. Grimes /* 2904b88c807SRodney W. Grimes * skip over leading blanks and zeros 2914b88c807SRodney W. Grimes */ 2924b88c807SRodney W. Grimes while ((str < stop) && ((*str == ' ') || (*str == '0'))) 2934b88c807SRodney W. Grimes ++str; 2944b88c807SRodney W. Grimes 2954b88c807SRodney W. Grimes /* 2964b88c807SRodney W. Grimes * for each valid digit, shift running value (tval) over to next digit 2974b88c807SRodney W. Grimes * and add next digit 2984b88c807SRodney W. Grimes */ 2994b88c807SRodney W. Grimes if (base == HEX) { 3004b88c807SRodney W. Grimes while (str < stop) { 3014b88c807SRodney W. Grimes if ((*str >= '0') && (*str <= '9')) 3024b88c807SRodney W. Grimes tval = (tval << 4) + (*str++ - '0'); 3034b88c807SRodney W. Grimes else if ((*str >= 'A') && (*str <= 'F')) 3044b88c807SRodney W. Grimes tval = (tval << 4) + 10 + (*str++ - 'A'); 3054b88c807SRodney W. Grimes else if ((*str >= 'a') && (*str <= 'f')) 3064b88c807SRodney W. Grimes tval = (tval << 4) + 10 + (*str++ - 'a'); 3074b88c807SRodney W. Grimes else 3084b88c807SRodney W. Grimes break; 3094b88c807SRodney W. Grimes } 3104b88c807SRodney W. Grimes } else { 3114b88c807SRodney W. Grimes while ((str < stop) && (*str >= '0') && (*str <= '7')) 3124b88c807SRodney W. Grimes tval = (tval << 3) + (*str++ - '0'); 3134b88c807SRodney W. Grimes } 3144b88c807SRodney W. Grimes return(tval); 3154b88c807SRodney W. Grimes } 3164b88c807SRodney W. Grimes 3174b88c807SRodney W. Grimes /* 3184b88c807SRodney W. Grimes * ul_asc() 3194b88c807SRodney W. Grimes * convert an unsigned long into an hex/oct ascii string. pads with LEADING 3204b88c807SRodney W. Grimes * ascii 0's to fill string completely 3214b88c807SRodney W. Grimes * NOTE: the string created is NOT TERMINATED. 3224b88c807SRodney W. Grimes */ 3234b88c807SRodney W. Grimes 324778766feSKris Kennaway #ifdef __STDC__ 3254b88c807SRodney W. Grimes int 3264b88c807SRodney W. Grimes ul_asc(u_long val, register char *str, register int len, register int base) 3274b88c807SRodney W. Grimes #else 3284b88c807SRodney W. Grimes int 3294b88c807SRodney W. Grimes ul_asc(val, str, len, base) 3304b88c807SRodney W. Grimes u_long val; 3314b88c807SRodney W. Grimes register char *str; 3324b88c807SRodney W. Grimes register int len; 3334b88c807SRodney W. Grimes register int base; 3344b88c807SRodney W. Grimes #endif 3354b88c807SRodney W. Grimes { 3364b88c807SRodney W. Grimes register char *pt; 3374b88c807SRodney W. Grimes u_long digit; 3384b88c807SRodney W. Grimes 3394b88c807SRodney W. Grimes /* 3404b88c807SRodney W. Grimes * WARNING str is not '\0' terminated by this routine 3414b88c807SRodney W. Grimes */ 3424b88c807SRodney W. Grimes pt = str + len - 1; 3434b88c807SRodney W. Grimes 3444b88c807SRodney W. Grimes /* 3454b88c807SRodney W. Grimes * do a tailwise conversion (start at right most end of string to place 3464b88c807SRodney W. Grimes * least significant digit). Keep shifting until conversion value goes 3474b88c807SRodney W. Grimes * to zero (all digits were converted) 3484b88c807SRodney W. Grimes */ 3494b88c807SRodney W. Grimes if (base == HEX) { 3504b88c807SRodney W. Grimes while (pt >= str) { 3514b88c807SRodney W. Grimes if ((digit = (val & 0xf)) < 10) 3524b88c807SRodney W. Grimes *pt-- = '0' + (char)digit; 3534b88c807SRodney W. Grimes else 3544b88c807SRodney W. Grimes *pt-- = 'a' + (char)(digit - 10); 3554b88c807SRodney W. Grimes if ((val = (val >> 4)) == (u_long)0) 3564b88c807SRodney W. Grimes break; 3574b88c807SRodney W. Grimes } 3584b88c807SRodney W. Grimes } else { 3594b88c807SRodney W. Grimes while (pt >= str) { 3604b88c807SRodney W. Grimes *pt-- = '0' + (char)(val & 0x7); 3614b88c807SRodney W. Grimes if ((val = (val >> 3)) == (u_long)0) 3624b88c807SRodney W. Grimes break; 3634b88c807SRodney W. Grimes } 3644b88c807SRodney W. Grimes } 3654b88c807SRodney W. Grimes 3664b88c807SRodney W. Grimes /* 3674b88c807SRodney W. Grimes * pad with leading ascii ZEROS. We return -1 if we ran out of space. 3684b88c807SRodney W. Grimes */ 3694b88c807SRodney W. Grimes while (pt >= str) 3704b88c807SRodney W. Grimes *pt-- = '0'; 3714b88c807SRodney W. Grimes if (val != (u_long)0) 3724b88c807SRodney W. Grimes return(-1); 3734b88c807SRodney W. Grimes return(0); 3744b88c807SRodney W. Grimes } 3754b88c807SRodney W. Grimes 3764b88c807SRodney W. Grimes #ifndef NET2_STAT 3774b88c807SRodney W. Grimes /* 3784b88c807SRodney W. Grimes * asc_uqd() 3794b88c807SRodney W. Grimes * convert hex/octal character string into a u_quad_t. We do not have to 3804b88c807SRodney W. Grimes * check for overflow! (the headers in all supported formats are not large 3814b88c807SRodney W. Grimes * enough to create an overflow). 3824b88c807SRodney W. Grimes * NOTE: strings passed to us are NOT TERMINATED. 3834b88c807SRodney W. Grimes * Return: 3844b88c807SRodney W. Grimes * u_quad_t value 3854b88c807SRodney W. Grimes */ 3864b88c807SRodney W. Grimes 387778766feSKris Kennaway #ifdef __STDC__ 3884b88c807SRodney W. Grimes u_quad_t 3894b88c807SRodney W. Grimes asc_uqd(register char *str, int len, register int base) 3904b88c807SRodney W. Grimes #else 3914b88c807SRodney W. Grimes u_quad_t 3924b88c807SRodney W. Grimes asc_uqd(str, len, base) 3934b88c807SRodney W. Grimes register char *str; 3944b88c807SRodney W. Grimes int len; 3954b88c807SRodney W. Grimes register int base; 3964b88c807SRodney W. Grimes #endif 3974b88c807SRodney W. Grimes { 3984b88c807SRodney W. Grimes register char *stop; 3994b88c807SRodney W. Grimes u_quad_t tval = 0; 4004b88c807SRodney W. Grimes 4014b88c807SRodney W. Grimes stop = str + len; 4024b88c807SRodney W. Grimes 4034b88c807SRodney W. Grimes /* 4044b88c807SRodney W. Grimes * skip over leading blanks and zeros 4054b88c807SRodney W. Grimes */ 4064b88c807SRodney W. Grimes while ((str < stop) && ((*str == ' ') || (*str == '0'))) 4074b88c807SRodney W. Grimes ++str; 4084b88c807SRodney W. Grimes 4094b88c807SRodney W. Grimes /* 4104b88c807SRodney W. Grimes * for each valid digit, shift running value (tval) over to next digit 4114b88c807SRodney W. Grimes * and add next digit 4124b88c807SRodney W. Grimes */ 4134b88c807SRodney W. Grimes if (base == HEX) { 4144b88c807SRodney W. Grimes while (str < stop) { 4154b88c807SRodney W. Grimes if ((*str >= '0') && (*str <= '9')) 4164b88c807SRodney W. Grimes tval = (tval << 4) + (*str++ - '0'); 4174b88c807SRodney W. Grimes else if ((*str >= 'A') && (*str <= 'F')) 4184b88c807SRodney W. Grimes tval = (tval << 4) + 10 + (*str++ - 'A'); 4194b88c807SRodney W. Grimes else if ((*str >= 'a') && (*str <= 'f')) 4204b88c807SRodney W. Grimes tval = (tval << 4) + 10 + (*str++ - 'a'); 4214b88c807SRodney W. Grimes else 4224b88c807SRodney W. Grimes break; 4234b88c807SRodney W. Grimes } 4244b88c807SRodney W. Grimes } else { 4254b88c807SRodney W. Grimes while ((str < stop) && (*str >= '0') && (*str <= '7')) 4264b88c807SRodney W. Grimes tval = (tval << 3) + (*str++ - '0'); 4274b88c807SRodney W. Grimes } 4284b88c807SRodney W. Grimes return(tval); 4294b88c807SRodney W. Grimes } 4304b88c807SRodney W. Grimes 4314b88c807SRodney W. Grimes /* 4324b88c807SRodney W. Grimes * uqd_asc() 4334b88c807SRodney W. Grimes * convert an u_quad_t into a hex/oct ascii string. pads with LEADING 4344b88c807SRodney W. Grimes * ascii 0's to fill string completely 4354b88c807SRodney W. Grimes * NOTE: the string created is NOT TERMINATED. 4364b88c807SRodney W. Grimes */ 4374b88c807SRodney W. Grimes 438778766feSKris Kennaway #ifdef __STDC__ 4394b88c807SRodney W. Grimes int 4404b88c807SRodney W. Grimes uqd_asc(u_quad_t val, register char *str, register int len, register int base) 4414b88c807SRodney W. Grimes #else 4424b88c807SRodney W. Grimes int 4434b88c807SRodney W. Grimes uqd_asc(val, str, len, base) 4444b88c807SRodney W. Grimes u_quad_t val; 4454b88c807SRodney W. Grimes register char *str; 4464b88c807SRodney W. Grimes register int len; 4474b88c807SRodney W. Grimes register int base; 4484b88c807SRodney W. Grimes #endif 4494b88c807SRodney W. Grimes { 4504b88c807SRodney W. Grimes register char *pt; 4514b88c807SRodney W. Grimes u_quad_t digit; 4524b88c807SRodney W. Grimes 4534b88c807SRodney W. Grimes /* 4544b88c807SRodney W. Grimes * WARNING str is not '\0' terminated by this routine 4554b88c807SRodney W. Grimes */ 4564b88c807SRodney W. Grimes pt = str + len - 1; 4574b88c807SRodney W. Grimes 4584b88c807SRodney W. Grimes /* 4594b88c807SRodney W. Grimes * do a tailwise conversion (start at right most end of string to place 4604b88c807SRodney W. Grimes * least significant digit). Keep shifting until conversion value goes 4614b88c807SRodney W. Grimes * to zero (all digits were converted) 4624b88c807SRodney W. Grimes */ 4634b88c807SRodney W. Grimes if (base == HEX) { 4644b88c807SRodney W. Grimes while (pt >= str) { 4654b88c807SRodney W. Grimes if ((digit = (val & 0xf)) < 10) 4664b88c807SRodney W. Grimes *pt-- = '0' + (char)digit; 4674b88c807SRodney W. Grimes else 4684b88c807SRodney W. Grimes *pt-- = 'a' + (char)(digit - 10); 4694b88c807SRodney W. Grimes if ((val = (val >> 4)) == (u_quad_t)0) 4704b88c807SRodney W. Grimes break; 4714b88c807SRodney W. Grimes } 4724b88c807SRodney W. Grimes } else { 4734b88c807SRodney W. Grimes while (pt >= str) { 4744b88c807SRodney W. Grimes *pt-- = '0' + (char)(val & 0x7); 4754b88c807SRodney W. Grimes if ((val = (val >> 3)) == (u_quad_t)0) 4764b88c807SRodney W. Grimes break; 4774b88c807SRodney W. Grimes } 4784b88c807SRodney W. Grimes } 4794b88c807SRodney W. Grimes 4804b88c807SRodney W. Grimes /* 4814b88c807SRodney W. Grimes * pad with leading ascii ZEROS. We return -1 if we ran out of space. 4824b88c807SRodney W. Grimes */ 4834b88c807SRodney W. Grimes while (pt >= str) 4844b88c807SRodney W. Grimes *pt-- = '0'; 4854b88c807SRodney W. Grimes if (val != (u_quad_t)0) 4864b88c807SRodney W. Grimes return(-1); 4874b88c807SRodney W. Grimes return(0); 4884b88c807SRodney W. Grimes } 4894b88c807SRodney W. Grimes #endif 490