Introduction
Introduction Statistics Contact Development Disclaimer Help
util.c - frontends - front-ends for some sites (experiment)
Log
Files
Refs
README
LICENSE
---
util.c (4633B)
---
1 #include <sys/socket.h>
2 #include <sys/types.h>
3
4 #include <ctype.h>
5 #include <errno.h>
6 #include <netdb.h>
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <unistd.h>
13 #include <wchar.h>
14
15 int
16 uriencode(const char *s, char *buf, size_t bufsiz)
17 {
18 static char hex[] = "0123456789ABCDEF";
19 char *d = buf, *e = buf + bufsiz;
20 unsigned char c;
21
22 if (!bufsiz)
23 return 0;
24
25 for (; *s; ++s) {
26 c = (unsigned char)*s;
27 if (d + 4 >= e)
28 return 0;
29 if (c == ' ' || c == '#' || c == '%' || c == '?' || c ==…
30 c == '&' || c == '<' || c <= 0x1f || c >= 0x7f) {
31 *d++ = '%';
32 *d++ = hex[c >> 4];
33 *d++ = hex[c & 0x0f];
34 } else {
35 *d++ = *s;
36 }
37 }
38 *d = '\0';
39
40 return 1;
41 }
42
43 int
44 hexdigit(int c)
45 {
46 if (c >= '0' && c <= '9')
47 return c - '0';
48 else if (c >= 'A' && c <= 'F')
49 return c - 'A' + 10;
50 else if (c >= 'a' && c <= 'f')
51 return c - 'a' + 10;
52
53 return 0;
54 }
55
56 /* decode until NUL separator or end of "key". */
57 int
58 decodeparam(char *buf, size_t bufsiz, const char *s)
59 {
60 size_t i;
61
62 if (!bufsiz)
63 return -1;
64
65 for (i = 0; *s && *s != '&'; s++) {
66 switch (*s) {
67 case '%':
68 if (i + 3 >= bufsiz)
69 return -1;
70 if (!isxdigit((unsigned char)*(s+1)) ||
71 !isxdigit((unsigned char)*(s+2)))
72 return -1;
73 buf[i++] = hexdigit(*(s+1)) * 16 + hexdigit(*(s+…
74 s += 2;
75 break;
76 case '+':
77 if (i + 1 >= bufsiz)
78 return -1;
79 buf[i++] = ' ';
80 break;
81 default:
82 if (i + 1 >= bufsiz)
83 return -1;
84 buf[i++] = *s;
85 break;
86 }
87 }
88 buf[i] = '\0';
89
90 return i;
91 }
92
93 char *
94 getparam(const char *query, const char *s)
95 {
96 const char *p, *last = NULL;
97 size_t len;
98
99 len = strlen(s);
100 for (p = query; (p = strstr(p, s)); p += len) {
101 if (p[len] == '=' && (p == query || p[-1] == '&' || p[-1…
102 last = p + len + 1;
103 }
104
105 return (char *)last;
106 }
107
108 int
109 friendlytime(time_t now, time_t t)
110 {
111 long long d = now - t;
112
113 if (d < 60) {
114 printf("just now");
115 } else if (d < 3600) {
116 printf("%lld minutes ago", d / 60);
117 } else if (d <= 24*3600) {
118 printf("%lld hours ago", d / 3600);
119 } else {
120 return 0;
121 }
122 return 1;
123 }
124
125 /* Escape characters below as HTML 2.0 / XML 1.0. */
126 void
127 xmlencode(const char *s)
128 {
129 for (; *s; s++) {
130 switch(*s) {
131 case '<': fputs("&lt;", stdout); break;
132 case '>': fputs("&gt;", stdout); break;
133 case '\'': fputs("&#39;", stdout); break;
134 case '&': fputs("&amp;", stdout); break;
135 case '"': fputs("&quot;", stdout); break;
136 default: putchar(*s);
137 }
138 }
139 }
140
141 /* format `len' columns of characters. If string is shorter pad the rest
142 * with characters `pad`. */
143 int
144 utf8pad(char *buf, size_t bufsiz, const char *s, size_t len, int pad)
145 {
146 wchar_t wc;
147 size_t col = 0, i, slen, siz = 0;
148 int rl, w;
149
150 if (!len)
151 return -1;
152
153 slen = strlen(s);
154 for (i = 0; i < slen; i += rl) {
155 if ((rl = mbtowc(&wc, &s[i], slen - i < 4 ? slen - i : 4…
156 break;
157 if ((w = wcwidth(wc)) == -1)
158 continue;
159 if (col + w > len || (col + w == len && s[i + rl])) {
160 if (siz + 4 >= bufsiz)
161 return -1;
162 memcpy(&buf[siz], "\xe2\x80\xa6", 3);
163 siz += 3;
164 if (col + w == len && w > 1)
165 buf[siz++] = pad;
166 buf[siz] = '\0';
167 return 0;
168 }
169 if (siz + rl + 1 >= bufsiz)
170 return -1;
171 memcpy(&buf[siz], &s[i], rl);
172 col += w;
173 siz += rl;
174 buf[siz] = '\0';
175 }
176
177 len -= col;
178 if (siz + len + 1 >= bufsiz)
179 return -1;
180 memset(&buf[siz], pad, len);
181 siz += len;
182 buf[siz] = '\0';
183
184 return 0;
185 }
186
187 /* Escape characters in gopher, CR and LF are ignored */
188 void
189 gophertext(FILE *fp, const char *s, size_t len)
190 {
191 size_t i;
192
193 for (i = 0; *s && i < len; s++, i++) {
194 switch (*s) {
195 case '\r': /* ignore CR */
196 case '\n': /* ignore LF */
197 break;
198 case '\t':
199 fputs(" ", fp);
200 break;
201 default:
202 fputc(*s, fp);
203 break;
204 }
205 }
206 }
207
208 /* seconds to duration string: "%H:%M:%S" or "%H:%M:%S" */
209 int
210 durationstr(long secs, char *buf, size_t bufsiz)
211 {
212 int h, m, s, r;
213
214 h = secs / 3600;
215 m = secs / 60;
216 s = secs;
217 if (h <= 0)
218 r = snprintf(buf, bufsiz, "%02d:%02d", m % 60, s % 60);
219 else
220 r = snprintf(buf, bufsiz, "%d:%02d:%02d", h, m % 60, s %…
221
222 return r;
223 }
224
225 /* print views with thousand separators, returns printed characters */
226 size_t
227 printnumsep(const char *s)
228 {
229 const char *p;
230 size_t n = 0, ndigits = 0;
231
232 /* first count all digits */
233 for (p = s; *p; p++)
234 if (*p >= '0' && *p <= '9')
235 ndigits++;
236
237 for (p = s; *p; p++) {
238 if (!(*p >= '0' && *p <= '9'))
239 continue;
240
241 putchar(*p);
242 n++;
243 ndigits--;
244
245 /* show separator on every 3 digits and when there are
246 digits remaining */
247 if ((ndigits % 3) == 0 && ndigits > 0) {
248 putchar(',');
249 n++;
250 }
251 }
252
253 return n;
254 }
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.