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