/* * Convert an expression of the following forms to an off_t * 1) A positive decimal number. * 2) A positive decimal number followed by a b (mult by 512). * 3) A positive decimal number followed by a k (mult by 1024). * 4) A positive decimal number followed by a m (mult by 1048576). * 5) A positive decimal number followed by a w (mult by sizeof int) * 6) Two or more positive decimal numbers (with/without k,b or w). * separated by x (also * for backwards compatibility), specifying * the product of the indicated values. */ static off_t get_off(char *val) { off_t num, t; char *expr; num = strtoq(val, &expr, 0); if (num == QUAD_MAX) /* Overflow. */ err(1, "%s", oper); if (expr == val) /* No digits. */ errx(1, "%s: illegal numeric value", oper); switch(*expr) { case 'b': t = num; num *= 512; if (t > num) goto erange; ++expr; break; case 'k': case 'K': t = num; num *= 1024; if (t > num) goto erange; ++expr; break; case 'm': case 'M': t = num; num *= 1048576; if (t > num) goto erange; ++expr; break; case 'w': t = num; num *= sizeof(int); if (t > num) goto erange; ++expr; break; } switch(*expr) { case '\0': break; case '*': /* Backward compatible. */ case 'x': t = num; num *= get_off(expr + 1); if (t > num) erange: errx(1, "%s: %s", oper, strerror(ERANGE)); break; default: errx(1, "%s: illegal numeric value", oper); } return (num); }
static long dehumanize(const char *value) { char *vtp; long iv; if (value == NULL) return (0); iv = strtoq(value, &vtp, 0); if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) { return (0); } switch (vtp[0]) { case 't': case 'T': iv *= 1024; case 'g': case 'G': iv *= 1024; case 'm': case 'M': iv *= 1024; case 'k': case 'K': iv *= 1024; case '\0': break; default: return (0); } return (iv); }
/* * Read the offsets written by writeoffsets(). */ void readoffsets(struct disk *disks, const char *save_file) { FILE *fp; struct disk *dp; char *space, buf[1024]; if ((fp = fopen(save_file, "r")) == NULL) { if (debug > 1 && errno == ENOENT) fprintf(stderr, "open %s failed: %s [continuing]\n", save_file, strerror(errno)); if (errno != ENOENT) syslog(LOG_NOTICE, "open %s failed: %m", save_file); return; } while (fgets(buf, sizeof buf, fp) != NULL) { if ((space = strchr(buf, ' ')) == NULL) continue; *space = '\0'; for (dp = disks; dp->device != NULL && strcmp(dp->device, buf) != 0; dp++) ; /* nothing */ if (dp->device != NULL) { if (debug) fprintf(stderr, "%s: seek %s", buf, space + 1); dseek(dp, (off_t)strtoq(space + 1, NULL, 0), SEEK_SET); } } fclose(fp); if (debug) fprintf(stderr, "readoffsets: done\n"); }
static Q_INT64 read_int_ascii( QDataStream *s ) { register int n = 0; char buf[40]; for ( ;; ) { buf[n] = s->device()->getch(); if ( buf[n] == '\n' || n > 38 ) // $-terminator break; n++; } buf[n] = '\0'; #if defined(__LP64__) || defined(Q_OS_OSF) // sizeof(long) == 8 return strtol(buf, (char **)0, 10); #else # if defined(Q_OS_TEMP) return strtol( buf, (char**)0, 10 ); # elif defined(Q_OS_WIN) return _atoi64( buf ); # elif defined(Q_OS_HPUX) return __strtoll( buf, (char**)0, 10 ); # elif defined(Q_OS_MACX) && defined(QT_MACOSX_VERSION) && QT_MACOSX_VERSION < 0x1020 return strtoq( buf, (char**)0, 10 ); # else return strtoll( buf, (char**)0, 10 ); // C99 function # endif #endif }
/* * Return a quad_t value from an environment variable. */ int getenv_quad(const char *name, quad_t *data) { char *value; char *vtp; quad_t iv; value = getenv(name); if (value == NULL) return (0); iv = strtoq(value, &vtp, 0); if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) { freeenv(value); return (0); } switch (vtp[0]) { case 't': case 'T': iv *= 1024; case 'g': case 'G': iv *= 1024; case 'm': case 'M': iv *= 1024; case 'k': case 'K': iv *= 1024; case '\0': break; default: freeenv(value); return (0); } *data = iv; freeenv(value); return (1); }
static off_t str_offt(char *val) { char *expr; off_t num, t; num = strtoq(val, &expr, 0); if ((num == QUAD_MAX) || (num <= 0) || (expr == val)) return(0); switch(*expr) { case 'b': t = num; num *= 512; if (t > num) return(0); ++expr; break; case 'k': t = num; num *= 1024; if (t > num) return(0); ++expr; break; case 'm': t = num; num *= 1048576; if (t > num) return(0); ++expr; break; case 'w': t = num; num *= sizeof(int); if (t > num) return(0); ++expr; break; } switch(*expr) { case '\0': break; case '*': case 'x': t = num; num *= str_offt(expr + 1); if (t > num) return(0); break; default: return(0); } return(num); }
/** * eva_strtoll: * @str: the string to parse a longlong integer (gint64) from. * @endp: optional place to store the character right past * the number in @str. If *endp == @str, then you may assume an error * occurred. * @base: the assumed base for the number to parse. eg "2" to * parse a binary, "8" for octal, "10" for decimal, "16" for hexidecimal. * Also, "0" is autodetects the C-style base. * * Like strtol, but for 64-bit integers. * * returns: the parsed integer. */ gint64 eva_strtoll (const char *str, char **endp, int base) { #if HAVE_STRTOQ return strtoq (str, endp, base); #elif HAVE_STRTOLL return strtoll (str, endp, base); #else return strtol (str, endp, base); #endif }
/* * Return an integer value from an environment variable. */ int getenv_int(char *name, int *data) { char *value, *vtp; quad_t iv; if ((value = getenv(name)) == NULL) return(0); iv = strtoq(value, &vtp, 0); if ((vtp == value) || (*vtp != 0)) return(0); *data = (int)iv; return(1); }
/* * Convert an expression of the following forms to an off_t. This is the * same as get_num(), but it uses signed numbers. * * The major problem here is that an off_t may not necessarily be a intmax_t. */ static off_t get_off_t(const char *val) { intmax_t num, mult, prevnum; char *expr; errno = 0; num = strtoq(val, &expr, 0); if (errno != 0) /* Overflow or underflow. */ err(1, "%s", oper); if (expr == val) /* No valid digits. */ errx(1, "%s: illegal numeric value", oper); mult = postfix_to_mult(*expr); if (mult != 0) { prevnum = num; num *= mult; /* Check for overflow. */ if ((prevnum > 0) != (num > 0) || num / mult != prevnum) goto erange; expr++; } switch (*expr) { case '\0': break; case '*': /* Backward compatible. */ case 'X': case 'x': mult = (intmax_t)get_off_t(expr + 1); prevnum = num; num *= mult; if ((prevnum > 0) == (num > 0) && num / mult == prevnum) break; erange: errx(1, "%s: %s", oper, strerror(ERANGE)); default: errx(1, "%s: illegal numeric value", oper); } return (num); }
Bool StrUtil_StrToInt64(int64 *out, // OUT: The output value const char *str) // IN : String to parse { char *ptr; ASSERT(out); ASSERT(str); errno = 0; #if defined(_WIN32) *out = _strtoi64(str, &ptr, 0); #elif defined(__FreeBSD__) *out = strtoq(str, &ptr, 0); #else *out = strtoll(str, &ptr, 0); #endif return ptr[0] == '\0' && errno != ERANGE; }
int main(int argc, char *argv[]) { struct stat sb1, sb2; off_t skip1, skip2; int ch, fd1, fd2, special; char *file1, *file2; setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, "ls")) != -1) switch (ch) { case 'l': /* print all differences */ lflag = 1; break; case 's': /* silent run */ sflag = 1; break; case '?': default: usage(); } argv += optind; argc -= optind; if (lflag && sflag) errx(ERR_EXIT, "only one of -l and -s may be specified"); if (argc < 2 || argc > 4) usage(); /* Backward compatibility -- handle "-" meaning stdin. */ special = 0; if (strcmp(file1 = argv[0], "-") == 0) { special = 1; fd1 = 0; file1 = "stdin"; } else if ((fd1 = open(file1, O_RDONLY, 0)) < 0) { if (sflag) exit(ERR_EXIT); else err(ERR_EXIT, "%s", file1); } if (strcmp(file2 = argv[1], "-") == 0) { if (special) { if (sflag) exit(ERR_EXIT); else errx(ERR_EXIT, "standard input may only be specified once"); } special = 1; fd2 = 0; file2 = "stdin"; } else if ((fd2 = open(file2, O_RDONLY, 0)) < 0) { if (sflag) exit(ERR_EXIT); else err(ERR_EXIT, "%s", file2); } skip1 = argc > 2 ? strtoq(argv[2], NULL, 0) : 0; skip2 = argc == 4 ? strtoq(argv[3], NULL, 0) : 0; if (!special) { if (fstat(fd1, &sb1)) { if (sflag) exit(ERR_EXIT); else err(ERR_EXIT, "%s", file1); } if (!S_ISREG(sb1.st_mode)) special = 1; else { if (fstat(fd2, &sb2)) { if (sflag) exit(ERR_EXIT); else err(ERR_EXIT, "%s", file2); } if (!S_ISREG(sb2.st_mode)) special = 1; } } if (special) c_special(fd1, file1, skip1, fd2, file2, skip2); else c_regular(fd1, file1, skip1, sb1.st_size, fd2, file2, skip2, sb2.st_size); return 0; }
static int luaA_sysctl_set(lua_State *L) { int i; int len; int intval; int mib[CTL_MAXNAME]; unsigned int uintval; u_int kind; long longval; unsigned long ulongval; size_t s; size_t newsize = 0; #if __FreeBSD_version < 900000 quad_t quadval; #else int64_t i64val; uint64_t u64val; intmax_t intmaxval; uintmax_t uintmaxval; #endif char fmt[BUFSIZ]; char oid[BUFSIZ]; char nvalbuf[BUFSIZ]; char *endptr; void *newval = NULL; /* get first argument from lua */ s = strlcpy(oid, luaL_checkstring(L, 1), sizeof(oid)); if (s >= sizeof(oid)) return (luaL_error(L, "oid too long: '%s'", oid)); /* get second argument from lua */ s = strlcpy(nvalbuf, luaL_checkstring(L, 2), sizeof(nvalbuf)); if (s >= sizeof(nvalbuf)) return (luaL_error(L, "new value too long")); newval = nvalbuf; newsize = s; len = name2oid(oid, mib); if (len < 0) return (luaL_error(L, "unknown iod '%s'", oid)); if (oidfmt(mib, len, fmt, sizeof(fmt), &kind) != 0) return (luaL_error(L, "couldn't find format of oid '%s'", oid)); if ((kind & CTLTYPE) == CTLTYPE_NODE) return (luaL_error(L, "oid '%s' isn't a leaf node", oid)); if (!(kind & CTLFLAG_WR)) { if (kind & CTLFLAG_TUN) return (luaL_error(L, "oid '%s' is a read only tunable. " "Tunable values are set in /boot/loader.conf", oid)); else return (luaL_error(L, "oid '%s' is read only", oid)); } if ((kind & CTLTYPE) == CTLTYPE_INT || (kind & CTLTYPE) == CTLTYPE_UINT || (kind & CTLTYPE) == CTLTYPE_LONG || (kind & CTLTYPE) == CTLTYPE_ULONG || #if __FreeBSD_version < 900000 (kind & CTLTYPE) == CTLTYPE_QUAD #else (kind & CTLTYPE) == CTLTYPE_S64 || (kind & CTLTYPE) == CTLTYPE_U64 #endif ) { if (strlen(newval) == 0) return (luaL_error(L, "empty numeric value")); } switch (kind & CTLTYPE) { case CTLTYPE_INT: if (strcmp(fmt, "IK") == 0) { if (!set_IK(newval, &intval)) return (luaL_error(L, "invalid value '%s'", (char *)newval)); } else { longval = strtol(newval, &endptr, 0); if (endptr == newval || *endptr != '\0' || longval > INT_MAX || longval < INT_MIN) { return (luaL_error(L, "invalid integer: '%s'", (char *)newval)); } intval = (int)longval; } newval = &intval; newsize = sizeof(intval); break; case CTLTYPE_UINT: ulongval = strtoul(newval, &endptr, 0); if (endptr == newval || *endptr != '\0' || ulongval > UINT_MAX) { return (luaL_error(L, "invalid unsigned integer: '%s'", (char *)newval)); } uintval = (unsigned int)ulongval; newval = &uintval; newsize = sizeof(uintval); break; case CTLTYPE_LONG: longval = strtol(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { return (luaL_error(L, "invalid long integer: '%s'", (char *)newval)); } newval = &longval; newsize = sizeof(longval); break; case CTLTYPE_ULONG: ulongval = strtoul(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { return (luaL_error(L, "invalid unsigned long integer: '%s'", (char *)newval)); } newval = &ulongval; newsize = sizeof(ulongval); break; case CTLTYPE_STRING: break; #if __FreeBSD_version < 900000 case CTLTYPE_QUAD: quadval = strtoq(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { return (luaL_error(L, "invalid quad_t: '%s'", (char *)newval)); } newval = &quadval; newsize = sizeof(quadval); break; #else case CTLTYPE_S64: intmaxval = strtoimax(newval, &endptr, 0); if (endptr == newval || *endptr != '\0' || intmaxval > INT64_MAX || intmaxval < INT64_MIN) { return (luaL_error(L, "invalid int64_t integer: '%s'", (char *)newval)); } i64val = (int64_t)intmaxval; newval = &i64val; newsize = sizeof(i64val); break; case CTLTYPE_U64: uintmaxval = strtoumax(newval, &endptr, 0); if (endptr == newval || *endptr != '\0' || uintmaxval > UINT64_MAX) { return (luaL_error(L, "invalid int64_t integer: '%s'", (char *)newval)); } u64val = (uint64_t)uintmaxval; newval = &u64val; newsize = sizeof(u64val); break; #endif case CTLTYPE_OPAQUE: if (strcmp(fmt, "T,dev_t") == 0) { set_T_dev_t(L, newval, &newval, &newsize); break; } /* FALLTHROUGH */ default: return (luaL_error(L, "oid '%s' is type %d, cannot set that", oid, kind & CTLTYPE)); } if (sysctl(mib, len, NULL, NULL, newval, newsize) == -1) { switch (errno) { case EOPNOTSUPP: return (luaL_error(L, "%s: value is not available", oid)); case ENOTDIR: return (luaL_error(L, "%s: specification is incomplete", oid)); case ENOMEM: /* really? with ENOMEM !?! */ return (luaL_error(L, "%s: type is unknown to this program", oid)); default: i = strerror_r(errno, nvalbuf, sizeof(nvalbuf)); if (i != 0) return (luaL_error(L, "strerror_r failed")); else return (luaL_error(L, "%s: %s", oid, nvalbuf)); } /* NOTREACHED */ } return (0); }
int vsscanf(const char *inp, char const *fmt0, va_list ap) { int inr; const u_char *fmt = (const u_char *)fmt0; int c; /* character from format, or conversion */ size_t width; /* field width, or 0 */ char *p; /* points into all kinds of strings */ int n; /* handy integer */ int flags; /* flags as defined above */ char *p0; /* saves original value of p when necessary */ int nassigned; /* number of fields assigned */ int nconversions; /* number of conversions */ int nread; /* number of characters consumed from fp */ int base; /* base argument to conversion function */ char ccltab[256]; /* character class table for %[...] */ char buf[BUF]; /* buffer for numeric conversions */ /* `basefix' is used to avoid `if' tests in the integer scanner */ static short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; inr = strlen(inp); nassigned = 0; nconversions = 0; nread = 0; base = 0; /* XXX just to keep gcc happy */ for (;;) { c = *fmt++; if (c == 0) return (nassigned); if (isspace(c)) { while (inr > 0 && isspace(*inp)) nread++, inr--, inp++; continue; } if (c != '%') goto literal; width = 0; flags = 0; /* * switch on the format. continue if done; * break once format type is derived. */ again: c = *fmt++; switch (c) { case '%': literal: if (inr <= 0) goto input_failure; if (*inp != c) goto match_failure; inr--, inp++; nread++; continue; case '*': flags |= SUPPRESS; goto again; case 'l': if (flags & LONG) { flags &= ~LONG; flags |= LONGLONG; } else flags |= LONG; goto again; case 'q': flags |= LONGLONG; /* not quite */ goto again; case 'h': if (flags & SHORT) { flags &= ~SHORT; flags |= SHORTSHORT; } else flags |= SHORT; goto again; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': width = width * 10 + c - '0'; goto again; /* * Conversions. */ case 'd': c = CT_INT; base = 10; break; case 'i': c = CT_INT; base = 0; break; case 'o': c = CT_INT; flags |= UNSIGNED; base = 8; break; case 'u': c = CT_INT; flags |= UNSIGNED; base = 10; break; case 'X': case 'x': flags |= PFXOK; /* enable 0x prefixing */ c = CT_INT; flags |= UNSIGNED; base = 16; break; case 's': c = CT_STRING; break; case '[': fmt = __sccl(ccltab, fmt); flags |= NOSKIP; c = CT_CCL; break; case 'c': flags |= NOSKIP; c = CT_CHAR; break; case 'p': /* pointer format is like hex */ flags |= POINTER | PFXOK; c = CT_INT; flags |= UNSIGNED; base = 16; break; case 'n': nconversions++; if (flags & SUPPRESS) /* ??? */ continue; if (flags & SHORTSHORT) *va_arg(ap, char *) = nread; else if (flags & SHORT) *va_arg(ap, short *) = nread; else if (flags & LONG) *va_arg(ap, long *) = nread; else if (flags & LONGLONG) *va_arg(ap, long long *) = nread; else *va_arg(ap, int *) = nread; continue; } /* * We have a conversion that requires input. */ if (inr <= 0) goto input_failure; /* * Consume leading white space, except for formats * that suppress this. */ if ((flags & NOSKIP) == 0) { while (isspace(*inp)) { nread++; if (--inr > 0) inp++; else goto input_failure; } /* * Note that there is at least one character in * the buffer, so conversions that do not set NOSKIP * can no longer result in an input failure. */ } /* * Do the conversion. */ switch (c) { case CT_CHAR: /* scan arbitrary characters (sets NOSKIP) */ if (width == 0) width = 1; if (flags & SUPPRESS) { size_t sum = 0; for (;;) { if ((n = inr) < (int)width) { sum += n; width -= n; inp += n; if (sum == 0) goto input_failure; break; } else { sum += width; inr -= width; inp += width; break; } } nread += sum; } else { bcopy(inp, va_arg(ap, char *), width); inr -= width; inp += width; nread += width; nassigned++; } nconversions++; break; case CT_CCL: /* scan a (nonempty) character class (sets NOSKIP) */ if (width == 0) width = (size_t)~0; /* `infinity' */ /* take only those things in the class */ if (flags & SUPPRESS) { n = 0; while (ccltab[(unsigned char)*inp]) { n++, inr--, inp++; if (--width == 0) break; if (inr <= 0) { if (n == 0) goto input_failure; break; } } if (n == 0) goto match_failure; } else { p0 = p = va_arg(ap, char *); while (ccltab[(unsigned char)*inp]) { inr--; *p++ = *inp++; if (--width == 0) break; if (inr <= 0) { if (p == p0) goto input_failure; break; } } n = p - p0; if (n == 0) goto match_failure; *p = 0; nassigned++; } nread += n; nconversions++; break; case CT_STRING: /* like CCL, but zero-length string OK, & no NOSKIP */ if (width == 0) width = (size_t)~0; if (flags & SUPPRESS) { n = 0; while (!isspace(*inp)) { n++, inr--, inp++; if (--width == 0) break; if (inr <= 0) break; } nread += n; } else { p0 = p = va_arg(ap, char *); while (!isspace(*inp)) { inr--; *p++ = *inp++; if (--width == 0) break; if (inr <= 0) break; } *p = 0; nread += p - p0; nassigned++; } nconversions++; continue; case CT_INT: /* scan an integer as if by the conversion function */ #ifdef hardway if (width == 0 || width > sizeof(buf) - 1) width = sizeof(buf) - 1; #else /* size_t is unsigned, hence this optimisation */ if (--width > sizeof(buf) - 2) width = sizeof(buf) - 2; width++; #endif flags |= SIGNOK | NDIGITS | NZDIGITS; for (p = buf; width; width--) { c = *inp; /* * Switch on the character; `goto ok' * if we accept it as a part of number. */ switch (c) { /* * The digit 0 is always legal, but is * special. For %i conversions, if no * digits (zero or nonzero) have been * scanned (only signs), we will have * base==0. In that case, we should set * it to 8 and enable 0x prefixing. * Also, if we have not scanned zero digits * before this, do not turn off prefixing * (someone else will turn it off if we * have scanned any nonzero digits). */ case '0': if (base == 0) { base = 8; flags |= PFXOK; } if (flags & NZDIGITS) flags &= ~(SIGNOK|NZDIGITS|NDIGITS); else flags &= ~(SIGNOK|PFXOK|NDIGITS); goto ok; /* 1 through 7 always legal */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': base = basefix[base]; flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* digits 8 and 9 ok iff decimal or hex */ case '8': case '9': base = basefix[base]; if (base <= 8) break; /* not legal here */ flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* letters ok iff hex */ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': /* no need to fix base here */ if (base <= 10) break; /* not legal here */ flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* sign ok only as first character */ case '+': case '-': if (flags & SIGNOK) { flags &= ~SIGNOK; goto ok; } break; /* x ok iff flag still set & 2nd char */ case 'x': case 'X': if (flags & PFXOK && p == buf + 1) { base = 16; /* if %i */ flags &= ~PFXOK; goto ok; } break; } /* * If we got here, c is not a legal character * for a number. Stop accumulating digits. */ break; ok: /* * c is legal: store it and look at the next. */ *p++ = c; if (--inr > 0) inp++; else break; /* end of input */ } /* * If we had only a sign, it is no good; push * back the sign. If the number ends in `x', * it was [sign] '0' 'x', so push back the x * and treat it as [sign] '0'. */ if (flags & NDIGITS) { if (p > buf) { inp--; inr++; } goto match_failure; } c = ((u_char *)p)[-1]; if (c == 'x' || c == 'X') { --p; inp--; inr++; } if ((flags & SUPPRESS) == 0) { u_quad_t res; *p = 0; if ((flags & UNSIGNED) == 0) res = strtoq(buf, (char **)NULL, base); else res = strtouq(buf, (char **)NULL, base); if (flags & POINTER) *va_arg(ap, void **) = (void *)(uintptr_t)res; else if (flags & SHORTSHORT) *va_arg(ap, char *) = res; else if (flags & SHORT) *va_arg(ap, short *) = res; else if (flags & LONG) *va_arg(ap, long *) = res; else if (flags & LONGLONG) *va_arg(ap, long long *) = res; else *va_arg(ap, int *) = res; nassigned++; } nread += p - buf; nconversions++; break; } } input_failure: return (nconversions != 0 ? nassigned : -1); match_failure: return (nassigned); }
/* * Parse a name into a MIB entry. * Lookup and print out the MIB entry if it exists. * Set a new value if requested. */ static void parse(const char *string) { size_t len; int i, j; void *newval = NULL; int intval; unsigned int uintval; long longval; unsigned long ulongval; size_t newsize = 0; quad_t quadval; u_quad_t uquadval; int mib[CTL_MAXNAME]; char *cp, fmt[BUFSIZ]; const char *name; char *name_allocated = NULL; u_int kind; if ((cp = strchr(string, '=')) != NULL) { if ((name_allocated = malloc(cp - string + 1)) == NULL) err(1, "malloc failed"); strlcpy(name_allocated, string, cp - string + 1); name = name_allocated; while (isspace(*++cp)) ; newval = cp; newsize = strlen(cp); } else { name = string; } len = CTL_MAXNAME; if (sysctlnametomib(name, mib, &len) < 0) { if (errno == ENOENT) { errx(1, "unknown oid '%s'", name); } else { err(1, "sysctlnametomib(\"%s\")", name); } } if (oidfmt(mib, len, fmt, &kind)) err(1, "couldn't find format of oid '%s'", name); if (newval == NULL) { if ((kind & CTLTYPE) == CTLTYPE_NODE) { sysctl_all(mib, len); } else { i = show_var(mib, len); if (!i && !bflag) putchar('\n'); } } else { if ((kind & CTLTYPE) == CTLTYPE_NODE) errx(1, "oid '%s' isn't a leaf node", name); if (!(kind&CTLFLAG_WR)) errx(1, "oid '%s' is read only", name); switch (kind & CTLTYPE) { case CTLTYPE_INT: if (!(strcmp(fmt, "IK") == 0)) { if (!set_IK(newval, &intval)) errx(1, "invalid value '%s'", (char *)newval); } else intval = (int) strtol(newval, NULL, 0); newval = &intval; newsize = sizeof(intval); break; case CTLTYPE_UINT: uintval = (int) strtoul(newval, NULL, 0); newval = &uintval; newsize = sizeof uintval; break; case CTLTYPE_LONG: longval = strtol(newval, NULL, 0); newval = &longval; newsize = sizeof longval; break; case CTLTYPE_ULONG: ulongval = strtoul(newval, NULL, 0); newval = &ulongval; newsize = sizeof ulongval; break; case CTLTYPE_STRING: break; case CTLTYPE_QUAD: quadval = strtoq(newval, NULL, 0); newval = &quadval; newsize = sizeof(quadval); break; case CTLTYPE_UQUAD: uquadval = strtouq(newval, NULL, 0); newval = &uquadval; newsize = sizeof(uquadval); break; case CTLTYPE_OPAQUE: if (strcmp(fmt, "T,dev_t") == 0 || strcmp(fmt, "T,udev_t") == 0 ) { set_T_dev_t((char*)newval, &newval, &newsize); break; } /* FALLTHROUGH */ default: errx(1, "oid '%s' is type %d," " cannot set that", name, kind & CTLTYPE); } i = show_var(mib, len); if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { if (!i && !bflag) putchar('\n'); switch (errno) { case EOPNOTSUPP: errx(1, "%s: value is not available", string); case ENOTDIR: errx(1, "%s: specification is incomplete", string); case ENOMEM: errx(1, "%s: type is unknown to this program", string); default: warn("%s", string); return; } } if (!bflag) printf(" -> "); i = nflag; nflag = 1; j = show_var(mib, len); if (!j && !bflag) putchar('\n'); nflag = i; } if (name_allocated != NULL) free(name_allocated); }
/* assmble a litteral fix num */ void asm_lit_fixnum(buffer_type *buf, yyscan_t *scanner) { vm_int i = 0; i = strtoq(get_text(scanner), 0, 0); EMIT_LIT_FIXNUM(buf, i); }
static void set(char *t, NODE *ip) { int type; char *kw, *val = NULL; struct group *gr; struct passwd *pw; mode_t *m; int value; char *ep; for (; (kw = strtok(t, "= \t\n")); t = NULL) { ip->flags |= type = parsekey(kw, &value); if (value && (val = strtok(NULL, " \t\n")) == NULL) errx(1, "line %d: missing value", lineno); switch(type) { case F_CKSUM: ip->cksum = strtoul(val, &ep, 10); if (*ep) errx(1, "line %d: invalid checksum %s", lineno, val); break; case F_MD5: ip->md5digest = strdup(val); if(!ip->md5digest) { errx(1, "strdup"); } break; case F_SHA1: ip->sha1digest = strdup(val); if(!ip->sha1digest) { errx(1, "strdup"); } break; case F_RMD160: ip->rmd160digest = strdup(val); if(!ip->rmd160digest) { errx(1, "strdup"); } break; case F_FLAGS: if (strcmp("none", val) == 0) ip->st_flags = 0; else if (strtofflags(&val, &ip->st_flags, NULL) != 0) errx(1, "line %d: invalid flag %s",lineno, val); break; case F_GID: ip->st_gid = strtoul(val, &ep, 10); if (*ep) errx(1, "line %d: invalid gid %s", lineno, val); break; case F_GNAME: if ((gr = getgrnam(val)) == NULL) errx(1, "line %d: unknown group %s", lineno, val); ip->st_gid = gr->gr_gid; break; case F_IGN: /* just set flag bit */ break; case F_MODE: if ((m = setmode(val)) == NULL) errx(1, "line %d: invalid file mode %s", lineno, val); ip->st_mode = getmode(m, 0); free(m); break; case F_NLINK: ip->st_nlink = strtoul(val, &ep, 10); if (*ep) errx(1, "line %d: invalid link count %s", lineno, val); break; case F_SIZE: ip->st_size = strtoq(val, &ep, 10); if (*ep) errx(1, "line %d: invalid size %s", lineno, val); break; case F_SLINK: if ((ip->slink = strdup(val)) == NULL) errx(1, "strdup"); break; case F_TIME: ip->st_mtimespec.tv_sec = strtoul(val, &ep, 10); if (*ep != '.') errx(1, "line %d: invalid time %s", lineno, val); val = ep + 1; ip->st_mtimespec.tv_nsec = strtoul(val, &ep, 10); if (*ep) errx(1, "line %d: invalid time %s", lineno, val); break; case F_TYPE: switch(*val) { case 'b': if (!strcmp(val, "block")) ip->type = F_BLOCK; break; case 'c': if (!strcmp(val, "char")) ip->type = F_CHAR; break; case 'd': if (!strcmp(val, "dir")) ip->type = F_DIR; break; case 'f': if (!strcmp(val, "file")) ip->type = F_FILE; if (!strcmp(val, "fifo")) ip->type = F_FIFO; break; case 'l': if (!strcmp(val, "link")) ip->type = F_LINK; break; case 's': if (!strcmp(val, "socket")) ip->type = F_SOCK; break; default: errx(1, "line %d: unknown file type %s", lineno, val); } break; case F_UID: ip->st_uid = strtoul(val, &ep, 10); if (*ep) errx(1, "line %d: invalid uid %s", lineno, val); break; case F_UNAME: if ((pw = getpwnam(val)) == NULL) errx(1, "line %d: unknown user %s", lineno, val); ip->st_uid = pw->pw_uid; break; } } }
static int UnDosLine( char *const line, const char *const curdir, size_t curdirlen, char *fname, size_t fnamesize, int *ftype, longest_int *fsize, time_t *ftime) { char *cp; int hour, year; char *filestart; char *sizestart; struct tm ftm; /* * 0123456789012345678901234567890123456789012345678901234567890123456789 04-27-99 10:32PM 270158 Game booklet.pdf 03-11-99 10:03PM <DIR> Get A3d Banner We also try to parse the format from CMD.EXE, which is similar: 03/22/2001 06:23p 62,325 cls.pdf * */ cp = line; if ( isdigit((int) cp[0]) && isdigit((int) cp[1]) && ispunct((int) cp[2]) && isdigit((int) cp[3]) && isdigit((int) cp[4]) && ispunct((int) cp[5]) && isdigit((int) cp[6]) && isdigit((int) cp[7]) ) { (void) memset(&ftm, 0, sizeof(struct tm)); ftm.tm_isdst = -1; cp[2] = '\0'; ftm.tm_mon = atoi(cp + 0); if (ftm.tm_mon > 0) ftm.tm_mon -= 1; cp[5] = '\0'; ftm.tm_mday = atoi(cp + 3); if ((isdigit((int) cp[8])) && (isdigit((int) cp[9]))) { /* Four-digit year */ cp[10] = '\0'; year = atoi(cp + 6); if (year > 1900) year -= 1900; ftm.tm_year = year; /* years since 1900 */ cp += 11; } else { /* Two-digit year */ cp[8] = '\0'; year = atoi(cp + 6); if (year < 98) year += 100; ftm.tm_year = year; /* years since 1900 */ cp += 9; } for (;;) { if (*cp == '\0') return (-1); if (isdigit((int) *cp)) break; cp++; } cp[2] = '\0'; hour = atoi(cp); if (((cp[5] == 'P') || (cp[5] == 'p')) && (hour < 12)) hour += 12; else if (((cp[5] == 'A') || (cp[5] == 'a')) && (hour == 12)) hour -= 12; ftm.tm_hour = hour; cp[5] = '\0'; ftm.tm_min = atoi(cp + 3); *ftime = mktime(&ftm); if (*ftype == (time_t) -1) return (-1); cp += 6; *ftype = '-'; for (;;) { if (*cp == '\0') return (-1); if ((*cp == '<') && (cp[1] == 'D')) { /* found <DIR> */ *ftype = 'd'; cp += 5; break; /* size field will end up being empty string */ } else if ((*cp == '<') && (cp[1] == 'J')) { /* found <JUNCTION> * * Will we ever really see this? * IIS from Win2000sp1 sends <DIR> * for FTP, but CMD.EXE prints * <JUNCTION>. */ *ftype = 'd'; cp += 10; break; } else if (isdigit((int) *cp)) { break; } else { cp++; } } sizestart = cp; for (;;) { if (*cp == '\0') return (-1); #ifdef HAVE_MEMMOVE if (*cp == ',') { /* Yuck -- US Locale dependency */ memmove(cp, cp + 1, strlen(cp + 1) + 1); } #endif if (!isdigit((int) *cp)) { *cp++ = '\0'; break; } cp++; } if (fsize != NULL) { #if defined(HAVE_LONG_LONG) && defined(SCANF_LONG_LONG) if (*ftype == 'd') *fsize = 0; else (void) sscanf(sizestart, SCANF_LONG_LONG, fsize); #elif defined(HAVE_LONG_LONG) && defined(HAVE_STRTOQ) if (*ftype == 'd') *fsize = 0; else *fsize = (longest_int) strtoq(sizestart, NULL, 0); #else *fsize = (longest_int) 0; if (*ftype != 'd') { long fsize2 = 0L; (void) sscanf(sizestart, "%ld", &fsize2); *fsize = (longest_int) fsize2; } #endif } for (;;) { if (*cp == '\0') return (-1); if (!isspace((int) *cp)) { break; } cp++; } filestart = cp; if (curdirlen == 0) { (void) Strncpy(fname, filestart, fnamesize); } else { (void) Strncpy(fname, curdir, fnamesize); (void) Strncat(fname, filestart, fnamesize); } return (0); } return (-1); } /* UnDosLine */
int main(int argc, char *argv[]) { struct timezone tz; int ch, rflag; int jflag, nflag; const char *format; char buf[1024]; char *endptr, *fmt; char *tmp; int set_timezone; struct vary *v; const struct vary *badv; struct tm lt; v = NULL; fmt = NULL; (void) setlocale(LC_TIME, ""); tz.tz_dsttime = tz.tz_minuteswest = 0; rflag = 0; jflag = nflag = 0; set_timezone = 0; while ((ch = getopt(argc, argv, "d:f:jnr:t:uv:")) != -1) switch((char)ch) { case 'd': /* daylight savings time */ tz.tz_dsttime = strtol(optarg, &endptr, 10) ? 1 : 0; if (endptr == optarg || *endptr != '\0') usage(); set_timezone = 1; break; case 'f': fmt = optarg; break; case 'j': jflag = 1; /* don't set time */ break; case 'n': /* don't set network */ nflag = 1; break; case 'r': /* user specified seconds */ rflag = 1; tval = strtoq(optarg, &tmp, 0); if (*tmp != 0) usage(); break; case 't': /* minutes west of UTC */ /* error check; don't allow "PST" */ tz.tz_minuteswest = strtol(optarg, &endptr, 10); if (endptr == optarg || *endptr != '\0') usage(); set_timezone = 1; break; case 'u': /* do everything in UTC */ (void)setenv("TZ", "UTC0", 1); break; case 'v': v = vary_append(v, optarg); break; default: usage(); } argc -= optind; argv += optind; /* * If -d or -t, set the timezone or daylight savings time; this * doesn't belong here; the kernel should not know about either. */ if (set_timezone && settimeofday((struct timeval *)NULL, &tz)) err(1, "settimeofday (timezone)"); if (!rflag && time(&tval) == -1) err(1, "time"); format = "%+"; /* allow the operands in any order */ if (*argv && **argv == '+') { format = *argv + 1; ++argv; } if (*argv) { setthetime(fmt, *argv, jflag, nflag); ++argv; } else if (fmt != NULL) usage(); if (*argv && **argv == '+') format = *argv + 1; lt = *localtime(&tval); badv = vary_apply(v, <); if (badv) { fprintf(stderr, "%s: Cannot apply date adjustment\n", badv->arg); vary_destroy(v); usage(); } vary_destroy(v); (void)strftime(buf, sizeof(buf), format, <); (void)printf("%s\n", buf); if (fflush(stdout)) err(1, "stdout"); exit(retval); }
int UnMlsT(const FTPCIPtr UNUSED(cip), const char *const line0, const MLstItemPtr mlip) { char *cp, *val, *fact; int ec; size_t len; char line[1024]; LIBNCFTP_USE_VAR(cip); memset(mlip, 0, sizeof(MLstItem)); mlip->mode = -1; mlip->fsize = kSizeUnknown; mlip->ftype = '-'; mlip->ftime = kModTimeUnknown; len = strlen(line0); if (len > (sizeof(line) - 1)) return (-1); /* Line too long, sorry. */ /* This should be re-coded so does not need to make a * copy of the buffer; it could be done in place. */ memcpy(line, line0, len + 1); /* Skip leading whitespace. */ for (cp = line; *cp != '\0'; cp++) { if (! isspace((int) *cp)) break; } while (*cp != '\0') { for (fact = cp; ; cp++) { if ((*cp == '\0') || (*cp == ' ')) { /* protocol violation */ return (-1); } if (*cp == '=') { /* End of fact name. */ *cp++ = '\0'; break; } } for (val = cp; ; cp++) { if (*cp == '\0') { /* protocol violation */ return (-1); } if (*cp == ' ') { ec = ' '; *cp++ = '\0'; break; } else if (*cp == ';') { if (cp[1] == ' ') { ec = ' '; *cp++ = '\0'; *cp++ = '\0'; } else { ec = ';'; *cp++ = '\0'; } break; } } if (ISTRNEQ(fact, "OS.", 3)) fact += 3; if (ISTREQ(fact, "type")) { if (ISTREQ(val, "file")) { mlip->ftype = '-'; } else if (ISTREQ(val, "dir")) { mlip->ftype = 'd'; } else if (ISTREQ(val, "cdir")) { /* not supported: current directory */ return (-2); } else if (ISTREQ(val, "pdir")) { /* not supported: parent directory */ return (-2); } else { /* ? */ return (-1); } } else if (ISTREQ(fact, "UNIX.mode")) { if (val[0] == '0') sscanf(val, "%o", &mlip->mode); else sscanf(val, "%i", &mlip->mode); if (mlip->mode != (-1)) mlip->mode &= 00777; } else if (ISTREQ(fact, "perm")) { STRNCPY(mlip->perm, val); } else if (ISTREQ(fact, "size")) { #if defined(HAVE_LONG_LONG) && defined(SCANF_LONG_LONG) (void) sscanf(val, SCANF_LONG_LONG, &mlip->fsize); #elif defined(HAVE_LONG_LONG) && defined(HAVE_STRTOQ) mlip->fsize = (longest_int) strtoq(val, NULL, 0); #else { long fsize2 = 0L; (void) sscanf(val, "%ld", &fsize2); mlip->fsize = (longest_int) fsize2; } #endif } else if (ISTREQ(fact, "modify")) { mlip->ftime = UnMDTMDate(val); } else if (ISTREQ(fact, "UNIX.owner")) { STRNCPY(mlip->owner, val); } else if (ISTREQ(fact, "UNIX.group")) { STRNCPY(mlip->group, val); } else if (ISTREQ(fact, "UNIX.uid")) { mlip->uid = atoi(val); } else if (ISTREQ(fact, "UNIX.gid")) { mlip->gid = atoi(val); } else if (ISTREQ(fact, "perm")) { STRNCPY(mlip->perm, val); } /* End of facts? */ if (ec == ' ') break; } len = strlen(cp); if (len > (sizeof(mlip->fname) - 1)) { /* Filename too long */ return (-1); } memcpy(mlip->fname, cp, len); /* also set linkto here if used */ return (0); } /* UnMlsT */
static int UnLslRLine( char *const line, const char *const curdir, size_t curdirlen, char *fname, size_t fnamesize, char *linkto, size_t linktosize, int *ftype, longest_int *fsize, time_t *ftime, time_t now, int thisyear, int *plugend) { char *cp; int mon = 0, day = 0, hr = 0, min = 0, year = 0, sec = 0; int haveIsoHHMMSS = -1; char *monstart, *daystart, *hrstart, *minstart, *yearstart, *secstart = NULL; char *linktostart, *filestart = NULL; char *sizestart; char *pe; struct tm ftm; *plugend = 0; *ftype = 0; if (ftime != NULL) *ftime = (time_t) -1; if (fsize != NULL) *fsize = (longest_int) -1; /* * Look for the digit just before the space * before the month name. * -rw-rw---- 1 gleason sysdev 33404 Mar 24 01:29 RCmd.o -rw-rw-r-- 1 gleason sysdevzz 1829 Jul 7 1996 README -rw-rw-r-- 1 gleason sysdevzz 1829 Jul 7 1996 README -rw-rw-r-- 1 gleason sysdevzz 1829 Jul 7 1996 README -rw-rw-r-- 1 gleason sysdevzz 1829 Jul 7 1996 README drwxrwxrwx 1 pvr pvr 45056 Jan 1 2000 DataFiles * *------------------------------^ * 0123456789012345 *------plugend--------^ * 9876543210 * */ for (cp = line; *cp != '\0'; cp++) { if ( (isdigit((int) *cp)) && (isspace((int) cp[1])) && (isupper((int) cp[2])) && (islower((int) cp[3])) /* && (islower((int) cp[4])) */ && (isspace((int) cp[5])) && ( ((isdigit((int) cp[6])) && (isdigit((int) cp[7]))) || ((isdigit((int) cp[6])) && (isspace((int) cp[7]))) || ((isspace((int) cp[6])) && (isdigit((int) cp[7]))) ) && (isspace((int) cp[8])) ) { monstart = cp + 2; daystart = cp + 6; if ( ((isspace((int) cp[9])) || (isdigit((int) cp[9]))) && (isdigit((int) cp[10])) && (isdigit((int) cp[11])) && (isdigit((int) cp[12])) && ((isdigit((int) cp[13])) || (isspace((int) cp[13]))) ) { /* "Mon DD YYYY" form */ yearstart = cp + 9; if (isspace((int) *yearstart)) yearstart++; hrstart = NULL; minstart = NULL; filestart = cp + 15; cp[1] = '\0'; /* end size */ cp[5] = '\0'; /* end mon */ cp[8] = '\0'; /* end day */ if (! isspace((int) filestart[-1])) { if (isspace((int) filestart[-2])) { filestart--; } } filestart[-1] = '\0'; /* end year */ mon = LsMonthNameToNum(monstart); day = atoi(daystart); hr = 23; min = 59; sec = 59; year = atoi(yearstart); pe = cp; while (isdigit((int) *pe)) pe--; while (isspace((int) *pe)) pe--; *plugend = (int) (pe - line) + 1; break; } else if ( /* * Windows NT does not 0 pad. (isdigit((int) cp[9])) && */ (isdigit((int) cp[10])) && (cp[11] == ':') && (isdigit((int) cp[12])) && (isdigit((int) cp[13])) ) { /* "Mon DD HH:MM" form */ yearstart = NULL; hrstart = cp + 9; minstart = cp + 12; filestart = cp + 15; cp[1] = '\0'; /* end size */ cp[5] = '\0'; /* end mon */ cp[8] = '\0'; /* end day */ cp[11] = '\0'; /* end hr */ cp[14] = '\0'; /* end min */ mon = LsMonthNameToNum(monstart); day = atoi(daystart); hr = atoi(hrstart); min = atoi(minstart); sec = 0; year = 0; pe = cp; while (isdigit((int) *pe)) pe--; while (isspace((int) *pe)) pe--; *plugend = (int) (pe - line) + 1; break; } } else if ( (isdigit((int) *cp)) && (isspace((int) cp[1])) && (isdigit((int) cp[2])) && (isdigit((int) cp[3])) && (isdigit((int) cp[4])) && (isdigit((int) cp[5])) && (cp[6] == '-') && (isdigit((int) cp[7])) && (isdigit((int) cp[8])) && (cp[9] == '-') && (isdigit((int) cp[10])) && (isdigit((int) cp[11])) && (isspace((int) cp[12])) && (isdigit((int) cp[13])) && (isdigit((int) cp[14])) && (cp[15] == ':') && (isdigit((int) cp[16])) && (isdigit((int) cp[17])) && ( ((haveIsoHHMMSS = isspace((int) cp[18]))) || ( (isdigit((int) cp[19])) && (isdigit((int) cp[20])) && (isspace((int) cp[21])) && ((haveIsoHHMMSS = (int) cp[18]) == ':') ) ) ) { /* "YYYY-mm-dd HH:MM" or "YYYY-mm-dd HH:MM:SS" form */ /* drwxr-xr-x 4 ftpuser ftpusers 136 2008-03-12 23:38 beta 0123456789012345678901234567890123456789 */ yearstart = cp + 2; cp[6] = '\0'; /* end year */ monstart = cp + 7; cp[9] = '\0'; /* end month */ daystart = cp + 10; cp[12] = '\0'; /* end day */ hrstart = cp + 13; cp[15] = '\0'; /* end hr */ minstart = cp + 16; cp[18] = '\0'; /* end min */ if (haveIsoHHMMSS == ':') { secstart = cp + 19; cp[21] = '\0'; /* end sec */ sec = atoi(secstart); filestart = cp + 22; } else { filestart = cp + 19; sec = 0; } mon = atoi(monstart) - 1; day = atoi(daystart); hr = atoi(hrstart); min = atoi(minstart); year = atoi(yearstart); pe = cp; while (isdigit((int) *pe)) pe--; while (isspace((int) *pe)) pe--; *plugend = (int) (pe - line) + 1; break; } } if (*cp == '\0') return (-1); linktostart = strstr(filestart, " -> "); if (linktostart != NULL) { *linktostart = '\0'; linktostart += 4; (void) Strncpy(linkto, linktostart, linktosize); } else { *linkto = '\0'; } if (curdirlen == 0) { (void) Strncpy(fname, filestart, fnamesize); } else { (void) Strncpy(fname, curdir, fnamesize); (void) Strncat(fname, filestart, fnamesize); } if (ftime != NULL) { (void) memset(&ftm, 0, sizeof(struct tm)); ftm.tm_mon = mon; ftm.tm_mday = day; ftm.tm_hour = hr; ftm.tm_min = min; ftm.tm_sec = sec; ftm.tm_isdst = -1; if (year == 0) { /* We guess the year, based on what the * current year is. * * UNIX ls would always print the year * if the file was older than 6 months, * but many non-UNIX based servers do * not honor that convention, so we * now assume that if the year was not * given it implies the current year, * unless the file is up to two days * into the future. */ ftm.tm_year = thisyear - 1900; *ftime = mktime(&ftm); if (*ftime == (time_t) -1) { /* panic */ } else if (*ftime > (now + (2 * 86400L))) { --ftm.tm_year; *ftime = mktime(&ftm); } } else { ftm.tm_year = year - 1900; *ftime = mktime(&ftm); } } if (fsize != NULL) { while ((cp > line) && (isdigit((int) *cp))) --cp; sizestart = cp + 1; #if defined(HAVE_LONG_LONG) && defined(SCANF_LONG_LONG) (void) sscanf(sizestart, SCANF_LONG_LONG, fsize); #elif defined(HAVE_LONG_LONG) && defined(HAVE_STRTOQ) *fsize = (longest_int) strtoq(sizestart, NULL, 0); #else { long fsize2 = 0L; (void) sscanf(sizestart, "%ld", &fsize2); *fsize = (longest_int) fsize2; } #endif } switch (line[0]) { case 'd': case 'l': *ftype = (int) line[0]; break; case 'b': case 'c': case 's': *ftype = (int) line[0]; return (-1); default: *ftype = '-'; } return (0); } /* UnLslRLine */
static rlim_t resource_num(int which, int ch, const char *str) { rlim_t res = RLIM_INFINITY; if (str != NULL && !(strcasecmp(str, "inf") == 0 || strcasecmp(str, "infinity") == 0 || strcasecmp(str, "unlimit") == 0 || strcasecmp(str, "unlimited") == 0)) { const char * s = str; char *e; switch (which) { case RLIMIT_CPU: /* time values */ errno = 0; res = 0; while (*s) { rlim_t tim = strtoq(s, &e, 0); if (e == NULL || e == s || errno) break; switch (*e++) { case 0: /* end of string */ e--; default: case 's': case 'S': /* seconds */ break; case 'm': case 'M': /* minutes */ tim *= 60L; break; case 'h': case 'H': /* hours */ tim *= (60L * 60L); break; case 'd': case 'D': /* days */ tim *= (60L * 60L * 24L); break; case 'w': case 'W': /* weeks */ tim *= (60L * 60L * 24L * 7L); case 'y': case 'Y': /* Years */ tim *= (60L * 60L * 24L * 365L); } s = e; res += tim; } break; case RLIMIT_FSIZE: /* Size values */ case RLIMIT_DATA: case RLIMIT_STACK: case RLIMIT_CORE: case RLIMIT_RSS: case RLIMIT_MEMLOCK: case RLIMIT_SBSIZE: case RLIMIT_VMEM: case RLIMIT_SWAP: errno = 0; res = 0; while (*s) { rlim_t mult, tim = strtoq(s, &e, 0); if (e == NULL || e == s || errno) break; switch (*e++) { case 0: /* end of string */ e--; default: mult = 1; break; case 'b': case 'B': /* 512-byte blocks */ mult = 512; break; case 'k': case 'K': /* 1024-byte Kilobytes */ mult = 1024; break; case 'm': case 'M': /* 1024-k kbytes */ mult = 1024 * 1024; break; case 'g': case 'G': /* 1Gbyte */ mult = 1024 * 1024 * 1024; break; case 't': case 'T': /* 1TBte */ mult = 1024LL * 1024LL * 1024LL * 1024LL; break; } s = e; res += (tim * mult); } break; case RLIMIT_NPROC: case RLIMIT_NOFILE: case RLIMIT_NPTS: case RLIMIT_KQUEUES: case RLIMIT_UMTXP: res = strtoq(s, &e, 0); s = e; break; } if (*s) { warnx("invalid value -%c `%s'", ch, str); usage(); } } return res; }
/* * Report a read error, logging how many bytes were trying to be read, which * sector they were being read from, and try to also find out what that sector * is used for. */ void logreaderror(struct disk *dp, int nbytes) { quad_t secno; off_t saved_offset; char newdev[512]; #ifdef DIOCGDINFO int fd, slice, part; struct dos_partition *dos; struct disklabel label; char buf[512]; #else /* DIOCGDINFO */ static size_t geomSize = 0; static char * geomConf = NULL; char * cp; static size_t partLen = 31; static char *part = NULL; quad_t relsec = -1; char *typefld = NULL; #endif /* DIOCGDINFO */ saved_offset = dseek(dp, 0, SEEK_CUR); secno = (quad_t)saved_offset / dp->secsize; dp->errors++; syslog(LOG_NOTICE, "error reading %d bytes from sector " QD " on %s", nbytes, secno, dp->device); #ifdef DIOCGDINFO /* * First, find out which slice it's in. To do this, we seek to the * start of the disk, read the first sector, and go through the DOS * slice table. */ if (dseek(dp, 0, SEEK_SET) == -1) { syslog(LOG_NOTICE, "could not seek to start of disk: %m"); exit(EXIT_FAILURE); } if (read(dp->fd, buf, sizeof buf) != sizeof buf) { dseek(dp, saved_offset, SEEK_SET); return; } /* seek back to where we were */ if (dseek(dp, saved_offset, SEEK_SET) == -1) { syslog(LOG_NOTICE, "could not seek to previous position" "after reading first sector: %m"); exit(EXIT_FAILURE); } // TODO: should validate DOS partition table (vs GPT or dedicated) dos = (struct dos_partition *)&buf[DOSPARTOFF]; for (slice = 0; slice < NDOSPART; slice++) if (dos[slice].dp_start <= secno && secno < dos[slice].dp_start + dos[slice].dp_size) break; if (slice == NDOSPART) { syslog(LOG_NOTICE, "sector " QD " on %s doesn't appear " "to be within any DOS slice", secno, dp->device); return; } /* Make secno relative to this slice */ secno -= dos[slice].dp_start; snprintf(newdev, sizeof newdev, "%ss%d", dp->device, slice + 1); syslog(LOG_DEBUG, "bad sector seems to be within %s", newdev); /* Check the type of that partition. */ if (dos[slice].dp_typ != DOSPTYP_386BSD) { /* If not a BSD slice, we can't do much more. */ syslog(LOG_NOTICE, "last bad sector is sector " QD " on device %s, type %02x", secno, newdev, dos[slice].dp_typ); return; } if ((fd = open(newdev, O_RDONLY)) < 0) { syslog(LOG_NOTICE, "open %s failure: %m", newdev); return; } /* Try to read the disklabel from that device. */ if (ioctl(fd, DIOCGDINFO, &label) < 0) { syslog(LOG_NOTICE, "DIOCGDINFO on %s failed: %m", newdev); return; } /* Check which partition this sector is in. */ for (part = 0; part < MAXPARTITIONS; part++) if (part != 2 && /* skip 'c' partition */ label.d_partitions[part].p_offset <= secno && secno < label.d_partitions[part].p_offset + label.d_partitions[part].p_size) break; if (part == MAXPARTITIONS) { syslog(LOG_NOTICE, "sector " QD " on %s doesn't appear " "to be within any BSD partition", secno, newdev); return; } secno -= label.d_partitions[part].p_offset; snprintf(newdev, sizeof newdev, "%ss%d%c", dp->device, slice + 1, 'a' + part); syslog(LOG_DEBUG, "bad sector seems to be within %s", newdev); if (label.d_partitions[part].p_fstype != FS_BSDFFS) { /* Again, if not a BSD partition, can't do much. */ syslog(LOG_NOTICE, "last bad sector is sector " QD " on device %s, type %s", secno, newdev, fstypename(label.d_partitions[part].p_fstype)); return; } #else /* DIOCGDINFO */ if (geomSize == 0) { sysctlbyname("kern.geom.conftxt", NULL, &geomSize, NULL, 0); if (geomSize <= 0) { printf("sysctlbyname() returned size = %d\n", geomSize); geomSize = 0; exit(EXIT_FAILURE); } geomConf = malloc(geomSize); if (geomConf == NULL) { printf("malloc(%d) returned NULL\n", geomSize); geomSize = 0; exit(EXIT_FAILURE); } if (sysctlbyname("kern.geom.conftxt", geomConf, &geomSize, NULL, 0) != 0) { perror("sysctlbyname()"); geomSize = 0; free(geomConf); geomConf = NULL; exit(EXIT_FAILURE); } } if (part == NULL) part = malloc(partLen + 1); for ( cp = geomConf ; *cp ; ++cp ) { // find line "0 DISK " matching current disk, using // strncmp because where cp points is not null-terminated // (All DISK lines, and only DISK lines, are at level 0.) // Magic numbers: 7 == strlen("0 DISK "); 5 == strlen("/dev/") if (strncmp(cp, "0 DISK ", 7) == 0 && strncmp(&cp[7], &dp->device[5], strlen(dp->device) - 5) == 0 && cp[7 + strlen(dp->device) - 5] == ' ') { for (;;) { // scan to end of line while (cp[1] && *cp != '\n') ++cp; ++cp; // start of next line // Find PART line containing the failed sector; // must be on same disk => stop upon finding // another DISK line. If more than one matching // PART -- due to nested geoms -- use the last // (innermost). if (*cp == '\0' || *cp == '0') break; // end of current DISK's entries // scan to end of level number while (cp[1] && *cp != ' ') ++cp; if (strncmp(cp, " PART ", 6) == 0) { char *pp = &cp[6]; int pl = strchr(pp, ' ') - pp; quad_t mediasize, offset; long secsize; cp = pp + pl; // cp -> mediasize mediasize = strtoq(cp, &cp, 10); secsize = strtol(cp, &cp, 10); mediasize /= secsize; cp = strchr(cp, 'o') + 1; offset = strtoq(cp, &cp, 10) / secsize; if (secno >= offset && (secno - offset) < mediasize) { if (pl > partLen) { part = realloc(part, pl+1); partLen = pl; } strncpy(part, pp, pl); part[pl] = '\0'; relsec = secno - offset; typefld = cp + 1; } } } } // scan to end of line while (cp[1] && *cp != '\n') ++cp; } //// printf("part %s, relsec %qd, typefld %p: %.27s\n", //// part, relsec, typefld, typefld); secno = relsec; strncpy(newdev, part, sizeof(newdev) - 1); newdev[sizeof(newdev) - 1] = '\0'; // paranoia #endif /* DIOCGDINFO */ syslog(LOG_NOTICE, "last bad sector is sector " QD " on 4.2BSD filesystem %s", secno, newdev); /* * XXX: todo: find out which file on the BSD filesystem uses this * sector... */ }
void http_got_header(struct connection *c, struct read_buffer *rb) { int cf; int state = c->state != S_PROC ? S_GETH : S_PROC; unsigned char *head; unsigned char *cookie, *ch; int a, h, version; unsigned char *d; struct cache_entry *e; struct http_connection_info *info; unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url); set_timeout(c); info = c->info; if (rb->close == 2) { unsigned char *h; if (!c->tries && (h = get_host_name(host))) { if (info->bl_flags & BL_NO_CHARSET) { del_blacklist_entry(h, BL_NO_CHARSET); } else { add_blacklist_entry(h, BL_NO_CHARSET); c->tries = -1; } mem_free(h); } setcstate(c, S_CANT_READ); retry_connection(c); return; } rb->close = 0; again: if ((a = get_header(rb)) == -1) { setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if (!a) { read_from_socket(c, c->sock1, rb, http_got_header); setcstate(c, state); return; } if (a != -2) { head = mem_alloc(a + 1); memcpy(head, rb->data, a); head[a] = 0; kill_buffer_data(rb, a); } else { head = stracpy("HTTP/0.9 200 OK\r\nContent-Type: text/html\r\n\r\n"); } if (get_http_code(head, &h, &version) || h == 101) { mem_free(head); setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if (check_http_server_bugs(host, c->info, head) && is_connection_restartable(c)) { mem_free(head); setcstate(c, S_RESTART); retry_connection(c); return; } ch = head; while ((cookie = parse_http_header(ch, "Set-Cookie", &ch))) { unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url); set_cookie(NULL, host, cookie); mem_free(cookie); } if (h == 100) { mem_free(head); state = S_PROC; goto again; } if (h < 200) { mem_free(head); setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if (h == 204) { mem_free(head); setcstate(c, S_HTTP_204); http_end_request(c, 0); return; } if (h == 304) { mem_free(head); setcstate(c, S_OK); http_end_request(c, 1); return; } if ((h == 500 || h == 502 || h == 503 || h == 504) && http_bugs.retry_internal_errors && is_connection_restartable(c)) { /* !!! FIXME: wait some time ... */ mem_free(head); setcstate(c, S_RESTART); retry_connection(c); return; } if (!c->cache && get_cache_entry(c->url, &c->cache)) { mem_free(head); setcstate(c, S_OUT_OF_MEM); abort_connection(c); return; } e = c->cache; e->http_code = h; if (e->head) mem_free(e->head); e->head = head; if ((d = parse_http_header(head, "Expires", NULL))) { time_t t = parse_http_date(d); if (t && e->expire_time != 1) e->expire_time = t; mem_free(d); } if ((d = parse_http_header(head, "Pragma", NULL))) { if (!casecmp(d, "no-cache", 8)) e->expire_time = 1; mem_free(d); } if ((d = parse_http_header(head, "Cache-Control", NULL))) { char *f = d; while (1) { while (*f && (*f == ' ' || *f == ',')) f++; if (!*f) break; if (!casecmp(f, "no-cache", 8) || !casecmp(f, "must-revalidate", 15)) { e->expire_time = 1; } if (!casecmp(f, "max-age=", 8)) { if (e->expire_time != 1) e->expire_time = time(NULL) + atoi(f + 8); } while (*f && *f != ',') f++; } mem_free(d); } #ifdef HAVE_SSL if (c->ssl) { int l = 0; if (e->ssl_info) mem_free(e->ssl_info); e->ssl_info = init_str(); add_num_to_str(&e->ssl_info, &l, SSL_get_cipher_bits(c->ssl, NULL)); add_to_str(&e->ssl_info, &l, "-bit "); add_to_str(&e->ssl_info, &l, SSL_get_cipher_version(c->ssl)); add_to_str(&e->ssl_info, &l, " "); add_to_str(&e->ssl_info, &l, (unsigned char *)SSL_get_cipher_name(c->ssl)); } #endif if (e->redirect) mem_free(e->redirect), e->redirect = NULL; if (h == 301 || h == 302 || h == 303 || h == 307) { if ((h == 302 || h == 307) && !e->expire_time) e->expire_time = 1; if ((d = parse_http_header(e->head, "Location", NULL))) { unsigned char *user, *ins; unsigned char *newuser, *newpassword; if (!parse_url(d, NULL, &user, NULL, NULL, NULL, &ins, NULL, NULL, NULL, NULL, NULL, NULL) && !user && ins && (newuser = get_user_name(host))) { if (*newuser) { int ins_off = ins - d; newpassword = get_pass(host); if (!newpassword) newpassword = stracpy(""); add_to_strn(&newuser, ":"); add_to_strn(&newuser, newpassword); add_to_strn(&newuser, "@"); extend_str(&d, strlen(newuser)); ins = d + ins_off; memmove(ins + strlen(newuser), ins, strlen(ins) + 1); memcpy(ins, newuser, strlen(newuser)); mem_free(newpassword); } mem_free(newuser); } if (e->redirect) mem_free(e->redirect); e->redirect = d; e->redirect_get = h == 303; } } if (!e->expire_time && strchr(c->url, POST_CHAR)) e->expire_time = 1; info->close = 0; info->length = -1; info->version = version; if ((d = parse_http_header(e->head, "Connection", NULL)) || (d = parse_http_header(e->head, "Proxy-Connection", NULL))) { if (!strcasecmp(d, "close")) info->close = 1; mem_free(d); } else if (version < 11) info->close = 1; cf = c->from; c->from = 0; if ((d = parse_http_header(e->head, "Content-Range", NULL))) { if (strlen(d) > 6) { d[5] = 0; if (!(strcasecmp(d, "bytes")) && d[6] >= '0' && d[6] <= '9') { #if defined(HAVE_STRTOLL) long long f = strtoll(d + 6, NULL, 10); #elif defined(HAVE_STRTOQ) longlong f = strtoq(d + 6, NULL, 10); #else long f = strtol(d + 6, NULL, 10); if (f == MAXLONG) f = -1; #endif if (f >= 0 && (off_t)f >= 0 && (off_t)f == f) c->from = f; } } mem_free(d); } if (cf && !c->from && !c->unrestartable) c->unrestartable = 1; if (c->from > cf || c->from < 0) { setcstate(c, S_HTTP_ERROR); abort_connection(c); return; } if ((d = parse_http_header(e->head, "Content-Length", NULL))) { unsigned char *ep; #if defined(HAVE_STRTOLL) long long l = strtoll(d, (char **)(void *)&ep, 10); #elif defined(HAVE_STRTOQ) longlong l = strtoq(d, (char **)(void *)&ep, 10); #else long l = strtol(d, (char **)(void *)&ep, 10); if (l == MAXLONG) l = -1; #endif if (!*ep && l >= 0 && (off_t)l >= 0 && (off_t)l == l) { if (!info->close || version >= 11) info->length = l; if (c->from + l >= 0) c->est_length = c->from + l; } mem_free(d); } if ((d = parse_http_header(e->head, "Accept-Ranges", NULL))) { if (!strcasecmp(d, "none") && !c->unrestartable) c->unrestartable = 1; mem_free(d); } else { if (!c->unrestartable && !c->from) c->unrestartable = 1; } if (info->bl_flags & BL_NO_RANGE && !c->unrestartable) c->unrestartable = 1; if ((d = parse_http_header(e->head, "Transfer-Encoding", NULL))) { if (!strcasecmp(d, "chunked")) { info->length = -2; info->chunk_remaining = -1; } mem_free(d); } if (!info->close && info->length == -1) info->close = 1; if ((d = parse_http_header(e->head, "Last-Modified", NULL))) { if (e->last_modified && strcasecmp(e->last_modified, d)) { delete_entry_content(e); if (c->from) { c->from = 0; mem_free(d); setcstate(c, S_MODIFIED); retry_connection(c); return; } } if (!e->last_modified) e->last_modified = d; else mem_free(d); } if (!e->last_modified && (d = parse_http_header(e->head, "Date", NULL))) e->last_modified = d; if (info->length == -1 || (version < 11 && info->close)) rb->close = 1; read_http_data(c, rb); }