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