"Fossies" - the Fresh Open Source Software Archive 
Member "xombrero-1.6.4/linux/linux.c" (17 Feb 2015, 21039 Bytes) of package /linux/www/old/xombrero-1.6.4.tgz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "linux.c" see the
Fossies "Dox" file reference documentation.
1 #include <sys/types.h>
2 #include <sys/cdefs.h>
3 #include <sys/socket.h>
4
5 #include <errno.h>
6 #include <errno.h>
7 #include <limits.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "util.h"
13
14 /*
15 * All the workarounds for glibc stupidity are piled into this file...
16 */
17
18 /* --------------------------------------------------------------------------- */
19 /* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
20
21 /*
22 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
23 *
24 * Permission to use, copy, modify, and distribute this software for any
25 * purpose with or without fee is hereby granted, provided that the above
26 * copyright notice and this permission notice appear in all copies.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
29 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
30 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
31 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
32 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
33 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
34 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35 */
36
37 /*
38 * Copy src to string dst of size siz. At most siz-1 characters
39 * will be copied. Always NUL terminates (unless siz == 0).
40 * Returns strlen(src); if retval >= siz, truncation occurred.
41 */
42 size_t
43 strlcpy(char *dst, const char *src, size_t siz)
44 {
45 char *d = dst;
46 const char *s = src;
47 size_t n = siz;
48
49 /* Copy as many bytes as will fit */
50 if (n != 0 && --n != 0) {
51 do {
52 if ((*d++ = *s++) == 0)
53 break;
54 } while (--n != 0);
55 }
56
57 /* Not enough room in dst, add NUL and traverse rest of src */
58 if (n == 0) {
59 if (siz != 0)
60 *d = '\0'; /* NUL-terminate dst */
61 while (*s++)
62 ;
63 }
64
65 return(s - src - 1); /* count does not include NUL */
66 }
67
68 /* --------------------------------------------------------------------------- */
69 /* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
70
71 /*
72 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
73 *
74 * Permission to use, copy, modify, and distribute this software for any
75 * purpose with or without fee is hereby granted, provided that the above
76 * copyright notice and this permission notice appear in all copies.
77 *
78 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
79 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
80 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
81 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
82 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
83 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
84 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
85 */
86
87 /*
88 * Appends src to string dst of size siz (unlike strncat, siz is the
89 * full size of dst, not space left). At most siz-1 characters
90 * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
91 * Returns strlen(src) + MIN(siz, strlen(initial dst)).
92 * If retval >= siz, truncation occurred.
93 */
94 size_t
95 strlcat(char *dst, const char *src, size_t siz)
96 {
97 char *d = dst;
98 const char *s = src;
99 size_t n = siz;
100 size_t dlen;
101
102 /* Find the end of dst and adjust bytes left but don't go past end */
103 while (n-- != 0 && *d != '\0')
104 d++;
105 dlen = d - dst;
106 n = siz - dlen;
107
108 if (n == 0)
109 return(dlen + strlen(s));
110 while (*s != '\0') {
111 if (n != 1) {
112 *d++ = *s;
113 n--;
114 }
115 s++;
116 }
117 *d = '\0';
118
119 return(dlen + (s - src)); /* count does not include NUL */
120 }
121
122 /* --------------------------------------------------------------------------- */
123 /* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */
124
125 /*-
126 * Copyright (c) 1998 The NetBSD Foundation, Inc.
127 * All rights reserved.
128 *
129 * This code is derived from software contributed to The NetBSD Foundation
130 * by Christos Zoulas.
131 *
132 * Redistribution and use in source and binary forms, with or without
133 * modification, are permitted provided that the following conditions
134 * are met:
135 * 1. Redistributions of source code must retain the above copyright
136 * notice, this list of conditions and the following disclaimer.
137 * 2. Redistributions in binary form must reproduce the above copyright
138 * notice, this list of conditions and the following disclaimer in the
139 * documentation and/or other materials provided with the distribution.
140 * 3. Neither the name of The NetBSD Foundation nor the names of its
141 * contributors may be used to endorse or promote products derived
142 * from this software without specific prior written permission.
143 *
144 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
145 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
146 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
147 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
148 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
149 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
150 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
151 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
152 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
153 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
154 * POSSIBILITY OF SUCH DAMAGE.
155 */
156
157 char *
158 fgetln(fp, len)
159 FILE *fp;
160 size_t *len;
161 {
162 static char *buf = NULL;
163 static size_t bufsiz = 0;
164 char *ptr;
165
166
167 if (buf == NULL) {
168 bufsiz = BUFSIZ;
169 if ((buf = malloc(bufsiz)) == NULL)
170 return NULL;
171 }
172
173 if (fgets(buf, bufsiz, fp) == NULL)
174 return NULL;
175
176 *len = 0;
177 while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
178 size_t nbufsiz = bufsiz + BUFSIZ;
179 char *nbuf = realloc(buf, nbufsiz);
180
181 if (nbuf == NULL) {
182 int oerrno = errno;
183 free(buf);
184 errno = oerrno;
185 buf = NULL;
186 return NULL;
187 } else
188 buf = nbuf;
189
190 *len = bufsiz;
191 if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
192 return buf;
193
194 bufsiz = nbufsiz;
195 }
196
197 *len = (ptr - buf) + 1;
198 return buf;
199 }
200
201 /* --------------------------------------------------------------------------- */
202 /* $OpenBSD: fparseln.c,v 1.6 2005/08/02 21:46:23 espie Exp $ */
203 /* $NetBSD: fparseln.c,v 1.7 1999/07/02 15:49:12 simonb Exp $ */
204
205 /*
206 * Copyright (c) 1997 Christos Zoulas. All rights reserved.
207 *
208 * Redistribution and use in source and binary forms, with or without
209 * modification, are permitted provided that the following conditions
210 * are met:
211 * 1. Redistributions of source code must retain the above copyright
212 * notice, this list of conditions and the following disclaimer.
213 * 2. Redistributions in binary form must reproduce the above copyright
214 * notice, this list of conditions and the following disclaimer in the
215 * documentation and/or other materials provided with the distribution.
216 * 3. All advertising materials mentioning features or use of this software
217 * must display the following acknowledgement:
218 * This product includes software developed by Christos Zoulas.
219 * 4. The name of the author may not be used to endorse or promote products
220 * derived from this software without specific prior written permission.
221 *
222 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
223 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
224 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
225 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
226 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
227 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
228 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
229 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
230 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
231 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
232 */
233
234 #define FPARSELN_UNESCESC 0x01
235 #define FPARSELN_UNESCCONT 0x02
236 #define FPARSELN_UNESCCOMM 0x04
237 #define FPARSELN_UNESCREST 0x08
238 #define FPARSELN_UNESCALL 0x0f
239
240 static int isescaped(const char *, const char *, int);
241
242 /* isescaped():
243 * Return true if the character in *p that belongs to a string
244 * that starts in *sp, is escaped by the escape character esc.
245 */
246 static int
247 isescaped(const char *sp, const char *p, int esc)
248 {
249 const char *cp;
250 size_t ne;
251
252 /* No escape character */
253 if (esc == '\0')
254 return 1;
255
256 /* Count the number of escape characters that precede ours */
257 for (ne = 0, cp = p; --cp >= sp && *cp == esc; ne++)
258 continue;
259
260 /* Return true if odd number of escape characters */
261 return (ne & 1) != 0;
262 }
263
264
265 /* fparseln():
266 * Read a line from a file parsing continuations ending in \
267 * and eliminating trailing newlines, or comments starting with
268 * the comment char.
269 */
270 char *
271 fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3],
272 int flags)
273 {
274 static const char dstr[3] = { '\\', '\\', '#' };
275 char *buf = NULL, *ptr, *cp, esc, con, nl, com;
276 size_t s, len = 0;
277 int cnt = 1;
278
279 if (str == NULL)
280 str = dstr;
281
282 esc = str[0];
283 con = str[1];
284 com = str[2];
285
286 /*
287 * XXX: it would be cool to be able to specify the newline character,
288 * but unfortunately, fgetln does not let us
289 */
290 nl = '\n';
291
292 while (cnt) {
293 cnt = 0;
294
295 if (lineno)
296 (*lineno)++;
297
298 if ((ptr = fgetln(fp, &s)) == NULL)
299 break;
300
301 if (s && com) { /* Check and eliminate comments */
302 for (cp = ptr; cp < ptr + s; cp++)
303 if (*cp == com && !isescaped(ptr, cp, esc)) {
304 s = cp - ptr;
305 cnt = s == 0 && buf == NULL;
306 break;
307 }
308 }
309
310 if (s && nl) { /* Check and eliminate newlines */
311 cp = &ptr[s - 1];
312
313 if (*cp == nl)
314 s--; /* forget newline */
315 }
316
317 if (s && con) { /* Check and eliminate continuations */
318 cp = &ptr[s - 1];
319
320 if (*cp == con && !isescaped(ptr, cp, esc)) {
321 s--; /* forget escape */
322 cnt = 1;
323 }
324 }
325
326 if (s == 0 && buf != NULL)
327 continue;
328
329 if ((cp = realloc(buf, len + s + 1)) == NULL) {
330 free(buf);
331 return NULL;
332 }
333 buf = cp;
334
335 (void) memcpy(buf + len, ptr, s);
336 len += s;
337 buf[len] = '\0';
338 }
339
340 if ((flags & FPARSELN_UNESCALL) != 0 && esc && buf != NULL &&
341 strchr(buf, esc) != NULL) {
342 ptr = cp = buf;
343 while (cp[0] != '\0') {
344 int skipesc;
345
346 while (cp[0] != '\0' && cp[0] != esc)
347 *ptr++ = *cp++;
348 if (cp[0] == '\0' || cp[1] == '\0')
349 break;
350
351 skipesc = 0;
352 if (cp[1] == com)
353 skipesc += (flags & FPARSELN_UNESCCOMM);
354 if (cp[1] == con)
355 skipesc += (flags & FPARSELN_UNESCCONT);
356 if (cp[1] == esc)
357 skipesc += (flags & FPARSELN_UNESCESC);
358 if (cp[1] != com && cp[1] != con && cp[1] != esc)
359 skipesc = (flags & FPARSELN_UNESCREST);
360
361 if (skipesc)
362 cp++;
363 else
364 *ptr++ = *cp++;
365 *ptr++ = *cp++;
366 }
367 *ptr = '\0';
368 len = strlen(buf);
369 }
370
371 if (size)
372 *size = len;
373 return buf;
374 }
375
376 /* --------------------------------------------------------------------------- */
377 /* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
378
379 /*
380 * Copyright (c) 2004 Ted Unangst and Todd Miller
381 * All rights reserved.
382 *
383 * Permission to use, copy, modify, and distribute this software for any
384 * purpose with or without fee is hereby granted, provided that the above
385 * copyright notice and this permission notice appear in all copies.
386 *
387 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
388 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
389 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
390 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
391 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
392 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
393 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
394 */
395
396 #define INVALID 1
397 #define TOOSMALL 2
398 #define TOOLARGE 3
399
400 long long
401 strtonum(const char *numstr, long long minval, long long maxval,
402 const char **errstrp)
403 {
404 long long ll = 0;
405 char *ep;
406 int error = 0;
407 struct errval {
408 const char *errstr;
409 int err;
410 } ev[4] = {
411 { NULL, 0 },
412 { "invalid", EINVAL },
413 { "too small", ERANGE },
414 { "too large", ERANGE },
415 };
416
417 ev[0].err = errno;
418 errno = 0;
419 if (minval > maxval)
420 error = INVALID;
421 else {
422 ll = strtoll(numstr, &ep, 10);
423 if (numstr == ep || *ep != '\0')
424 error = INVALID;
425 else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
426 error = TOOSMALL;
427 else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
428 error = TOOLARGE;
429 }
430 if (errstrp != NULL)
431 *errstrp = ev[error].errstr;
432 errno = ev[error].err;
433 if (error)
434 ll = 0;
435
436 return (ll);
437 }
438
439 /* $OpenBSD: fmt_scaled.c,v 1.10 2009/06/20 15:00:04 martynas Exp $ */
440
441 /*
442 * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved.
443 *
444 * Redistribution and use in source and binary forms, with or without
445 * modification, are permitted provided that the following conditions
446 * are met:
447 * 1. Redistributions of source code must retain the above copyright
448 * notice, this list of conditions and the following disclaimer.
449 * 2. Redistributions in binary form must reproduce the above copyright
450 * notice, this list of conditions and the following disclaimer in the
451 * documentation and/or other materials provided with the distribution.
452 * 3. The name of the author may not be used to endorse or promote products
453 * derived from this software without specific prior written permission.
454 *
455 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
456 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
457 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
458 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
459 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
460 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
461 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
462 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
463 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
464 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
465 */
466
467 /*
468 * fmt_scaled: Format numbers scaled for human comprehension
469 * scan_scaled: Scan numbers in this format.
470 *
471 * "Human-readable" output uses 4 digits max, and puts a unit suffix at
472 * the end. Makes output compact and easy-to-read esp. on huge disks.
473 * Formatting code was originally in OpenBSD "df", converted to library routine.
474 * Scanning code written for OpenBSD libutil.
475 */
476
477 #include <stdio.h>
478 #include <stdlib.h>
479 #include <errno.h>
480 #include <string.h>
481 #include <ctype.h>
482 #include <limits.h>
483
484 #include "util.h"
485
486 typedef enum {
487 NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6
488 } unit_type;
489
490 /* These three arrays MUST be in sync! XXX make a struct */
491 static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA };
492 static char scale_chars[] = "BKMGTPE";
493 static long long scale_factors[] = {
494 1LL,
495 1024LL,
496 1024LL*1024,
497 1024LL*1024*1024,
498 1024LL*1024*1024*1024,
499 1024LL*1024*1024*1024*1024,
500 1024LL*1024*1024*1024*1024*1024,
501 };
502 #define SCALE_LENGTH (sizeof(units)/sizeof(units[0]))
503
504 #define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */
505
506 /* Convert the given input string "scaled" into numeric in "result".
507 * Return 0 on success, -1 and errno set on error.
508 */
509 int
510 scan_scaled(char *scaled, long long *result)
511 {
512 char *p = scaled;
513 int sign = 0;
514 unsigned int i, ndigits = 0, fract_digits = 0;
515 long long scale_fact = 1, whole = 0, fpart = 0;
516
517 /* Skip leading whitespace */
518 while (isascii(*p) && isspace(*p))
519 ++p;
520
521 /* Then at most one leading + or - */
522 while (*p == '-' || *p == '+') {
523 if (*p == '-') {
524 if (sign) {
525 errno = EINVAL;
526 return -1;
527 }
528 sign = -1;
529 ++p;
530 } else if (*p == '+') {
531 if (sign) {
532 errno = EINVAL;
533 return -1;
534 }
535 sign = +1;
536 ++p;
537 }
538 }
539
540 /* Main loop: Scan digits, find decimal point, if present.
541 * We don't allow exponentials, so no scientific notation
542 * (but note that E for Exa might look like e to some!).
543 * Advance 'p' to end, to get scale factor.
544 */
545 for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) {
546 if (*p == '.') {
547 if (fract_digits > 0) { /* oops, more than one '.' */
548 errno = EINVAL;
549 return -1;
550 }
551 fract_digits = 1;
552 continue;
553 }
554
555 i = (*p) - '0'; /* whew! finally a digit we can use */
556 if (fract_digits > 0) {
557 if (fract_digits >= MAX_DIGITS-1)
558 /* ignore extra fractional digits */
559 continue;
560 fract_digits++; /* for later scaling */
561 fpart *= 10;
562 fpart += i;
563 } else { /* normal digit */
564 if (++ndigits >= MAX_DIGITS) {
565 errno = ERANGE;
566 return -1;
567 }
568 whole *= 10;
569 whole += i;
570 }
571 }
572
573 if (sign) {
574 whole *= sign;
575 fpart *= sign;
576 }
577
578 /* If no scale factor given, we're done. fraction is discarded. */
579 if (!*p) {
580 *result = whole;
581 return 0;
582 }
583
584 /* Validate scale factor, and scale whole and fraction by it. */
585 for (i = 0; i < SCALE_LENGTH; i++) {
586
587 /* Are we there yet? */
588 if (*p == scale_chars[i] ||
589 *p == tolower(scale_chars[i])) {
590
591 /* If it ends with alphanumerics after the scale char, bad. */
592 if (isalnum(*(p+1))) {
593 errno = EINVAL;
594 return -1;
595 }
596 scale_fact = scale_factors[i];
597
598 /* scale whole part */
599 whole *= scale_fact;
600
601 /* truncate fpart so it does't overflow.
602 * then scale fractional part.
603 */
604 while (fpart >= LLONG_MAX / scale_fact) {
605 fpart /= 10;
606 fract_digits--;
607 }
608 fpart *= scale_fact;
609 if (fract_digits > 0) {
610 for (i = 0; i < fract_digits -1; i++)
611 fpart /= 10;
612 }
613 whole += fpart;
614 *result = whole;
615 return 0;
616 }
617 }
618 errno = ERANGE;
619 return -1;
620 }
621
622 /* Format the given "number" into human-readable form in "result".
623 * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE.
624 * Return 0 on success, -1 and errno set if error.
625 */
626 int
627 fmt_scaled(long long number, char *result)
628 {
629 long long abval, fract = 0;
630 unsigned int i;
631 unit_type unit = NONE;
632
633 abval = llabs(number);
634
635 /* Not every negative long long has a positive representation.
636 * Also check for numbers that are just too darned big to format
637 */
638 if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) {
639 errno = ERANGE;
640 return -1;
641 }
642
643 /* scale whole part; get unscaled fraction */
644 for (i = 0; i < SCALE_LENGTH; i++) {
645 if (abval/1024 < scale_factors[i]) {
646 unit = units[i];
647 fract = (i == 0) ? 0 : abval % scale_factors[i];
648 number /= scale_factors[i];
649 if (i > 0)
650 fract /= scale_factors[i - 1];
651 break;
652 }
653 }
654
655 fract = (10 * fract + 512) / 1024;
656 /* if the result would be >= 10, round main number */
657 if (fract == 10) {
658 if (number >= 0)
659 number++;
660 else
661 number--;
662 fract = 0;
663 }
664
665 if (number == 0)
666 strlcpy(result, "0B", FMT_SCALED_STRSIZE);
667 else if (unit == NONE || number >= 100 || number <= -100) {
668 if (fract >= 5) {
669 if (number >= 0)
670 number++;
671 else
672 number--;
673 }
674 (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c",
675 number, scale_chars[unit]);
676 } else
677 (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c",
678 number, fract, scale_chars[unit]);
679
680 return 0;
681 }
682
683 /* --------------------------------------------------------------------------- */
684
685 /*
686 * Copyright (c) 2002,2004 Damien Miller <djm@mindrot.org>
687 *
688 * Permission to use, copy, modify, and distribute this software for any
689 * purpose with or without fee is hereby granted, provided that the above
690 * copyright notice and this permission notice appear in all copies.
691 *
692 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
693 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
694 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
695 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
696 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
697 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
698 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
699 */
700
701 /* Get effective user and group identification of locally-connected
702 * peer.
703 */
704 int
705 getpeereid(int s, uid_t *euid, gid_t *gid)
706 {
707 struct ucred cred;
708 socklen_t len = sizeof(cred);
709
710 if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0)
711 return (-1);
712 *euid = cred.uid;
713 *gid = cred.gid;
714
715 return (0);
716 }
717
718 #ifdef MAIN
719 /*
720 * This is the original version of the program in the man page.
721 * Copy-and-paste whatever you need from it.
722 */
723 int
724 main(int argc, char **argv)
725 {
726 char *cinput = "1.5K", buf[FMT_SCALED_STRSIZE];
727 long long ninput = 10483892, result;
728
729 if (scan_scaled(cinput, &result) == 0)
730 printf("\"%s\" -> %lld\n", cinput, result);
731 else
732 perror(cinput);
733
734 if (fmt_scaled(ninput, buf) == 0)
735 printf("%lld -> \"%s\"\n", ninput, buf);
736 else
737 fprintf(stderr, "%lld invalid (%s)\n", ninput, strerror(errno));
738
739 return 0;
740 }
741 #endif