(root)/
glibc-2.38/
resolv/
ns_ttl.c
       1  /*
       2   * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
       3   * Copyright (c) 1996,1999 by Internet Software Consortium.
       4   *
       5   * Permission to use, copy, modify, and distribute this software for any
       6   * purpose with or without fee is hereby granted, provided that the above
       7   * copyright notice and this permission notice appear in all copies.
       8   *
       9   * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
      10   * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
      11   * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
      12   * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
      13   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
      14   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
      15   * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
      16   * SOFTWARE.
      17   */
      18  
      19  /* Import. */
      20  
      21  #include <arpa/nameser.h>
      22  
      23  #include <ctype.h>
      24  #include <errno.h>
      25  #include <stdio.h>
      26  #include <string.h>
      27  
      28  #ifdef SPRINTF_CHAR
      29  # define SPRINTF(x) strlen(sprintf/**/x)
      30  #else
      31  # define SPRINTF(x) ((size_t)sprintf x)
      32  #endif
      33  
      34  /* Forward. */
      35  
      36  static int	fmt1(int t, char s, char **buf, size_t *buflen);
      37  
      38  /* Macros. */
      39  
      40  #define T(x) if ((x) < 0) return (-1); else (void)NULL
      41  
      42  /* Public. */
      43  
      44  int
      45  ns_format_ttl(u_long src, char *dst, size_t dstlen) {
      46  	char *odst = dst;
      47  	int secs, mins, hours, days, weeks, x;
      48  	char *p;
      49  
      50  	secs = src % 60;   src /= 60;
      51  	mins = src % 60;   src /= 60;
      52  	hours = src % 24;  src /= 24;
      53  	days = src % 7;    src /= 7;
      54  	weeks = src;       src = 0;
      55  
      56  	x = 0;
      57  	if (weeks) {
      58  		T(fmt1(weeks, 'W', &dst, &dstlen));
      59  		x++;
      60  	}
      61  	if (days) {
      62  		T(fmt1(days, 'D', &dst, &dstlen));
      63  		x++;
      64  	}
      65  	if (hours) {
      66  		T(fmt1(hours, 'H', &dst, &dstlen));
      67  		x++;
      68  	}
      69  	if (mins) {
      70  		T(fmt1(mins, 'M', &dst, &dstlen));
      71  		x++;
      72  	}
      73  	if (secs || !(weeks || days || hours || mins)) {
      74  		T(fmt1(secs, 'S', &dst, &dstlen));
      75  		x++;
      76  	}
      77  
      78  	if (x > 1) {
      79  		int ch;
      80  
      81  		for (p = odst; (ch = *p) != '\0'; p++)
      82  			if (isascii(ch) && isupper(ch))
      83  				*p = tolower(ch);
      84  	}
      85  
      86  	return (dst - odst);
      87  }
      88  libresolv_hidden_def (ns_format_ttl)
      89  
      90  // Seems not to be needed.  It's not exported from the DSO.  Some libresolv.a
      91  // might depend on it so we let it in.
      92  int
      93  ns_parse_ttl(const char *src, u_long *dst) {
      94  	u_long ttl, tmp;
      95  	int ch, digits, dirty;
      96  
      97  	ttl = 0;
      98  	tmp = 0;
      99  	digits = 0;
     100  	dirty = 0;
     101  	while ((ch = *src++) != '\0') {
     102  		if (!isascii(ch) || !isprint(ch))
     103  			goto einval;
     104  		if (isdigit(ch)) {
     105  			tmp *= 10;
     106  			tmp += (ch - '0');
     107  			digits++;
     108  			continue;
     109  		}
     110  		if (digits == 0)
     111  			goto einval;
     112  		if (islower(ch))
     113  			ch = toupper(ch);
     114  		switch (ch) {
     115  		case 'W':  tmp *= 7;
     116  		  /* Fall through.  */
     117  		case 'D':  tmp *= 24;
     118  		  /* Fall through.  */
     119  		case 'H':  tmp *= 60;
     120  		  /* Fall through.  */
     121  		case 'M':  tmp *= 60;
     122  		  /* Fall through.  */
     123  		case 'S':  break;
     124  		default:   goto einval;
     125  		}
     126  		ttl += tmp;
     127  		tmp = 0;
     128  		digits = 0;
     129  		dirty = 1;
     130  	}
     131  	if (digits > 0) {
     132  		if (dirty)
     133  			goto einval;
     134  		else
     135  			ttl += tmp;
     136  	} else if (!dirty)
     137  		goto einval;
     138  	*dst = ttl;
     139  	return (0);
     140  
     141   einval:
     142  	__set_errno (EINVAL);
     143  	return (-1);
     144  }
     145  
     146  /* Private. */
     147  
     148  static int
     149  fmt1(int t, char s, char **buf, size_t *buflen) {
     150  	char tmp[50];
     151  	size_t len;
     152  
     153  	len = SPRINTF((tmp, "%d%c", t, s));
     154  	if (len + 1 > *buflen)
     155  		return (-1);
     156  	strcpy(*buf, tmp);
     157  	*buf += len;
     158  	*buflen -= len;
     159  	return (0);
     160  }
     161  
     162  /*! \file */