nrelease - fix/improve livecd
[dragonfly.git] / lib / libc / nameser / 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 ISC DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  *
17  * $Id: ns_ttl.c,v 1.4 2005/07/28 06:51:49 marka Exp $
18  */
19
20 /* Import. */
21
22 #include "port_before.h"
23
24 #include <arpa/nameser.h>
25
26 #include <ctype.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "port_after.h"
32
33 #ifdef SPRINTF_CHAR
34 # define SPRINTF(x) strlen(sprintf/**/x)
35 #else
36 # define SPRINTF(x) ((size_t)sprintf x)
37 #endif
38
39 /* Forward. */
40
41 static int      fmt1(int t, char s, char **buf, size_t *buflen);
42
43 /* Macros. */
44
45 #define T(x) if ((x) < 0) return (-1); else (void)NULL
46
47 /* Public. */
48
49 int
50 ns_format_ttl(u_long src, char *dst, size_t dstlen) {
51         char *odst = dst;
52         int secs, mins, hours, days, weeks, x;
53         char *p;
54
55         secs = src % 60;   src /= 60;
56         mins = src % 60;   src /= 60;
57         hours = src % 24;  src /= 24;
58         days = src % 7;    src /= 7;
59         weeks = src;       src = 0;
60
61         x = 0;
62         if (weeks) {
63                 T(fmt1(weeks, 'W', &dst, &dstlen));
64                 x++;
65         }
66         if (days) {
67                 T(fmt1(days, 'D', &dst, &dstlen));
68                 x++;
69         }
70         if (hours) {
71                 T(fmt1(hours, 'H', &dst, &dstlen));
72                 x++;
73         }
74         if (mins) {
75                 T(fmt1(mins, 'M', &dst, &dstlen));
76                 x++;
77         }
78         if (secs || !(weeks || days || hours || mins)) {
79                 T(fmt1(secs, 'S', &dst, &dstlen));
80                 x++;
81         }
82
83         if (x > 1) {
84                 int ch;
85
86                 for (p = odst; (ch = *p) != '\0'; p++)
87                         if (isascii(ch) && isupper(ch))
88                                 *p = tolower(ch);
89         }
90
91         return (dst - odst);
92 }
93
94 int
95 ns_parse_ttl(const char *src, u_long *dst) {
96         u_long ttl, tmp;
97         int ch, digits, dirty;
98
99         ttl = 0;
100         tmp = 0;
101         digits = 0;
102         dirty = 0;
103         while ((ch = *src++) != '\0') {
104                 if (!isascii(ch) || !isprint(ch))
105                         goto einval;
106                 if (isdigit(ch)) {
107                         tmp *= 10;
108                         tmp += (ch - '0');
109                         digits++;
110                         continue;
111                 }
112                 if (digits == 0)
113                         goto einval;
114                 if (islower(ch))
115                         ch = toupper(ch);
116                 switch (ch) {
117                 case 'W':  tmp *= 7;
118                 case 'D':  tmp *= 24;
119                 case 'H':  tmp *= 60;
120                 case 'M':  tmp *= 60;
121                 case 'S':  break;
122                 default:   goto einval;
123                 }
124                 ttl += tmp;
125                 tmp = 0;
126                 digits = 0;
127                 dirty = 1;
128         }
129         if (digits > 0) {
130                 if (dirty)
131                         goto einval;
132                 else
133                         ttl += tmp;
134         } else if (!dirty)
135                 goto einval;
136         *dst = ttl;
137         return (0);
138
139  einval:
140         errno = EINVAL;
141         return (-1);
142 }
143
144 /* Private. */
145
146 static int
147 fmt1(int t, char s, char **buf, size_t *buflen) {
148         char tmp[50];
149         size_t len;
150
151         len = SPRINTF((tmp, "%d%c", t, s));
152         if (len + 1 > *buflen)
153                 return (-1);
154         strcpy(*buf, tmp);
155         *buf += len;
156         *buflen -= len;
157         return (0);
158 }
159
160 /*! \file */