"Fossies" - the Fresh Open Source Software Archive

Member "host-20070128/misc.c" (4 Apr 2003, 14322 Bytes) of archive /linux/misc/host-20070128.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format (assuming markdown format). Alternatively you can here view or download the uninterpreted source code file. A member file download can also be achieved by clicking within a package contents listing on the according byte size field.

/ * Copyright © 1985, 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that: (1) source distributions retain this entire copyright * notice and comment, and (2) distributions including binaries display * the following acknowledgement: “This product includes software * developed by the University of California, Berkeley and its contributors” * in the documentation or other materials provided with the distribution * and in all advertising materials mentioning features or use of this * software. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED “AS IS” AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. /

ident “@(#)host:HOST-20070128:misc.c,v 1.8 2003/04/04 04:00:10 woods Exp”

if 0

static char Version[] = “@(#)misc.c e07@nikhef.nl (Eric Wassenaar) 991529”;

endif

include “host.h”

include “glob.h”

/ XALLOC – Allocate or reallocate additional memory ————————————————– Returns: Pointer to (re)allocated buffer space. Aborts if the requested memory could not be obtained. /

ptr_t * xalloc(buf, size) register ptr_t buf; / current start of buffer space / input size_t size; / number of bytes to allocate */ { if (buf == NULL) buf = malloc(size); else buf = realloc(buf, size);

if (buf == NULL) {
    errmsg("Out of memory");
    exit(EX_OSERR);
}

return (buf);

}

/ DTOA – Convert value to decimal integer ascii string —————————————————– Returns: ** Pointer to string. /

char * dtoa(n) input int n; / value to convert / { static char buf[30]; / sufficient for 64-bit values /

(void) sprintf(buf, "%d", n);

return (buf);

}

/ UTOA – Convert value to unsigned decimal ascii string —————————————————— Returns: ** Pointer to string. /

char * utoa(n) input int n; / value to convert / { static char buf[30]; / sufficient for 64-bit values /

(void) sprintf(buf, "%u", (unsigned)n);

return (buf);

}

/ XTOA – Convert value to hexadecimal ascii string ————————————————- Returns: ** Pointer to string. /

char * xtoa(n) input int n; / value to convert / { static char buf[17]; / sufficient for 64-bit values /

(void) sprintf(buf, "%X", (unsigned)n);

return (buf);

}

/ STOA – Extract partial ascii string, escape if necessary ——————————————————— Returns: ** Pointer to string. /

char * stoa(cp, size, escape) input u_char cp; / current position in answer buf / input int size; / number of bytes to extract / input bool_t escape; / escape special characters if set / { static char buf[(2 * MAXDLEN) + 1]; / allow one backslash per char, plus NUL / register char p; register char c; register int i;

if (size > MAXDLEN)
    size = MAXDLEN;

ifdef obsolete

if (size > 0)
    (void) sprintf(buf, "%.*s", size, (char *) cp);
else
    (void) sprintf(buf, "%s", "");

endif

for (p = buf, i = 0; i < size; i++) {
    c = *cp++;
    if (escape && (c == '\n' || c == '\\' || c == '"'))
        *p++ = '\\';
    *p++ = c;
}
*p = '\0';

return (buf);

}

/ BASE_NTOA – Convert binary data to base64 ascii ———————————————— Returns: Pointer to string. This routine is used to convert encoded keys, signatures, and certificates in T_KEY, T_SIG, and T_CERT resource records. /

char b64tab[] = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”;

char * base_ntoa(cp, size) input u_char cp; / current position in answer buf / input int size; / number of bytes to extract / { static char buf[MAXB64SIZE+1]; register char p; int c1, c2, c3, c4;

if (size > MAXMD5SIZE)
    size = MAXMD5SIZE;

for (p = buf; size > 2; cp += 3, size -= 3) {
    c1 = (((u_int) cp[0] >> 2) & 0x3f);
    c2 = (((u_int) cp[0] & 0x03) << 4) + (((u_int) cp[1] >> 4) & 0x0f);
    c3 = (((u_int) cp[1] & 0x0f) << 2) + (((u_int) cp[2] >> 6) & 0x03);
    c4 =  ((u_int) cp[2] & 0x3f);

    *p++ = b64tab[c1];
    *p++ = b64tab[c2];
    *p++ = b64tab[c3];
    *p++ = b64tab[c4];
}

if (size == 2) {
    c1 = (((u_int) cp[0] >> 2) & 0x3f);
    c2 = (((u_int) cp[0] & 0x03) << 4) + (((u_int) cp[1] >> 4) & 0x0f);
    c3 = (((u_int) cp[1] & 0x0f) << 2);

    *p++ = b64tab[c1];
    *p++ = b64tab[c2];
    *p++ = b64tab[c3];
    *p++ = '=';
} else if (size == 1) {
    c1 = (((u_int) cp[0] >> 2) & 0x3f);
    c2 = (((u_int) cp[0] & 0x03) << 4);

    *p++ = b64tab[c1];
    *p++ = b64tab[c2];
    *p++ = '=';
    *p++ = '=';
}
*p = '\0';

return (buf);

}

/ NSAP_NTOA – Convert binary nsap address to ascii ————————————————- Returns: Pointer to string. As per RFC 1637 an nsap address is encoded in binary form in the resource record. It was unclear from RFC 1348 how the encoding should be. RFC 1629 defines an upper bound of 20 bytes to the size of a binary nsap address. /

char * nsap_ntoa(cp, size) input u_char cp; / current position in answer buf / input int size; / number of bytes to extract / { static char buf[3MAXNSAP+1]; register char *p; register int c; register int i;

if (size > MAXNSAP)
    size = MAXNSAP;

for (p = buf, i = 0; i < size; i++, cp++) {
    c = ((u_int) (*cp) >> 4) & 0x0f;
    *p++ = hexdigit(c);
    c = ((u_int) (*cp) >> 0) & 0x0f;
    *p++ = hexdigit(c);

    /* add dots for readability */
    if ((i % 2) == 0 && (i + 1) < size)
        *p++ = '.';
}
*p = '\0';

return (buf);

}

/ IPNG_NTOA – Convert binary ip v6 address to ascii ————————————————– Returns: Pointer to string. As per RFC 1886 an ip v6 address is encoded in binary form in the resource record. The size is fixed. /

char * ipng_ntoa(cp) input u_char cp; / current position in answer buf / { static char buf[5(IPNGSIZE/2)+1]; register char *p; register int n; register int i;

for (p = buf, i = 0; i < IPNGSIZE/2; i++) {
    n = ns_get16(cp);
    cp += INT16SZ;

    (void) sprintf(p, ":%X", n);
    p += strlength(p);
}
*p = '\0';

return (buf + 1);

}

/ PR_DATE – Produce printable version of a clock value —————————————————– Returns: Pointer to string. ** The value is a standard absolute clock value. /

char * pr_date(value) input int value; / the clock value to be converted / { static char buf[sizeof(“YYYYMMDDHHMMSS”)+1]; time_t clocktime = value; struct tm *t;

t = gmtime(&clocktime);
t->tm_year += 1900;
t->tm_mon += 1;

(void) sprintf(buf, "%04d%02d%02d%02d%02d%02d",
           t->tm_year, t->tm_mon, t->tm_mday,
           t->tm_hour, t->tm_min, t->tm_sec);

return (buf);

}

/ PR_TIME – Produce printable version of a time interval ——————————————————- Returns: Pointer to a string version of interval. ** The value is a time interval expressed in seconds. /

char * pr_time(value, brief) input int value; / the interval to be converted / input bool_t brief; / use brief format if set / { static char buf[256]; register char *p = buf; int week = 0; int days, hour, mins, secs;

/* special cases */
if (value < 0)
    return ("negative");

if ((value == 0) && !brief)
    return ("zero seconds");

/*
 * Decode the components.
 */
secs = value % 60; value /= 60;
mins = value % 60; value /= 60;
hour = value % 24; value /= 24;
days = value;

if (!brief) {
    days = value % 7; value /= 7;
    week = value;
}

/*
 * Now turn it into a sexy form.
 */
if (brief) {
    if (days > 0) {
        (void) sprintf(p, "%d+", days);
        p += strlength(p);
    }

    (void) sprintf(p, "%02d:%02d:%02d", hour, mins, secs);
    return (buf);
}
if (week > 0) {
    (void) sprintf(p, ", %d week%s", week, plural(week));
    p += strlength(p);
}
if (days > 0) {
    (void) sprintf(p, ", %d day%s", days, plural(days));
    p += strlength(p);
}
if (hour > 0) {
    (void) sprintf(p, ", %d hour%s", hour, plural(hour));
    p += strlength(p);
}
if (mins > 0) {
    (void) sprintf(p, ", %d minute%s", mins, plural(mins));
    p += strlength(p);
}
if (secs > 0) {
    (void) sprintf(p, ", %d second%s", secs, plural(secs));
    /* p += strlength(p); */
}

return (buf + 2);

}

/ PR_SPHERICAL – Produce printable version of a spherical location —————————————————————– Returns: Pointer to a string version of location. The value is a spherical location (latitude or longitude) expressed in thousandths of a second of arc. ** The value 231 represents zero (equator or prime meridian). /

char * pr_spherical(value, pos, neg) input int value; / the location to be converted / input char pos; / suffix if value positive / input char neg; / suffix if value negative / { static char buf[256]; register char p = buf; char direction; int degrees, minutes, seconds, fracsec;

/*
 * Normalize.
 */
value -= (int) ((u_int) 1 << 31);

direction = pos;
if (value < 0) {
    direction = neg;
    value = -value;
}

/*
 * Decode the components.
 */
fracsec = value % 1000; value /= 1000;
seconds = value % 60;   value /= 60;
minutes = value % 60;   value /= 60;
degrees = value;

/*
 * Construct output string.
 */
(void) sprintf(p, "%d", degrees);
p += strlength(p);

if (minutes > 0 || seconds > 0 || fracsec > 0) {
    (void) sprintf(p, " %02d", minutes);
    p += strlength(p);
}

if (seconds > 0 || fracsec > 0) {
    (void) sprintf(p, " %02d", seconds);
    p += strlength(p);
}

if (fracsec > 0) {
    (void) sprintf(p, ".%03d", fracsec);
    p += strlength(p);
}

(void) sprintf(p, " %s", direction);

ifdef obsolete

(void) sprintf(buf, "%d %02d %02d.%03d %s",
           degrees, minutes, seconds, fracsec, direction);

endif

return (buf);

}

/ PR_VERTICAL – Produce printable version of a vertical location ————————————————————— Returns: Pointer to a string version of location. The value is an altitude expressed in centimeters, starting from a base 100000 meters below the GPS reference spheroid. ** This allows for the actual range [-10000000 .. 4293967296]. /

char * pr_vertical(value, pos, neg) input int value; / the location to be converted / input char pos; / prefix if value positive / input char neg; / prefix if value negative / { static char buf[256]; register char p = buf; char direction; int meters, centimeters; unsigned int altitude; unsigned int reference;

/*
 * Normalize.
 */
altitude = value;
reference = 100000*100;

if (altitude < reference) {
    direction = neg;
    altitude = reference - altitude;
} else {
    direction = pos;
    altitude = altitude - reference;
}

/*
 * Decode the components.
 */
centimeters = altitude % 100; altitude /= 100;
meters = altitude;

/*
 * Construct output string.
 */
(void) sprintf(p, "%s%d", direction, meters);
p += strlength(p);

if (centimeters > 0)
    (void) sprintf(p, ".%02d", centimeters);

ifdef obsolete

(void) sprintf(buf, "%s%d.%02d", direction, meters, centimeters);

endif

return (buf);

}

/ PR_PRECISION – Produce printable version of a location precision —————————————————————– Returns: Pointer to a string version of precision. The value is a precision expressed in centimeters, encoded as 4-bit mantissa and 4-bit power of 10 (each ranging 0-9). /

unsigned int poweroften[10] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 };

char * pr_precision(value) input unsigned int value; / the precision to be converted / { static char buf[256]; register char *p = buf; int meters, centimeters; unsigned int precision; register int mantissa; register int exponent;

/*
 * Normalize.
 */
mantissa = (((u_int) value >> 4) & 0x0f) % 10;
exponent = (((u_int) value >> 0) & 0x0f) % 10;
precision = mantissa * poweroften[exponent];

/*
 * Decode the components.
 */
centimeters = precision % 100; precision /= 100;
meters = precision;

/*
 * Construct output string.
 */
(void) sprintf(p, "%d", meters);
p += strlength(p);

if (centimeters > 0)
    (void) sprintf(p, ".%02d", centimeters);

ifdef obsolete

(void) sprintf(buf, "%d.%02d", meters, centimeters);

endif

return (buf);

}

/ CONVTIME – Decode a time period from input string ————————————————– Returns: Non-negative numeric value of time period (in seconds). -1 in case of invalid time specification. Only rudimentary syntax errors are checked. It is easy to fool this routine to yield bizarre results. If the result is negative, it should not be trusted. /

int convtime(string, defunits) input char string; / time specification in ascii / input int defunits; / default units if none specified / { int period = 0; / overall result value / register int value; / intermediate value of component / register char units; register char p = string;

while (*p) {
    /* must start with numeric value */
    if (!is_digit((int) *p))
        return (-1);

    /* assemble numeric value */
    for (value = 0; is_digit((int) *p); p++)
        value = (value * 10) + (*p - '0');

    /* fetch units -- use default when omitted */
    if (*p != '\0')
        units = *p++;
    else
        units = defunits;

    switch (lowercase((int) units)) {
    case 'w':       /* weeks */
        value *= 7;
        /*FALLTHROUGH*/

    case 'd':       /* days */
        value *= 24;
        /*FALLTHROUGH*/

    case 'h':       /* hours */
        value *= 60;
        /*FALLTHROUGH*/

    case 'm':       /* minutes */
        value *= 60;
        /*FALLTHROUGH*/

    case 's':       /* seconds */
        break;

    default:        /* unknown */
        value = -1;
        break;
    }

    /* must be reasonable */
    if (value < 0)
        return (-1);

    /* accumulate total */
    period += value;
}

return (period);

}