static int load_locale_sub(int category, const char *locname, int isspecial) { char name[PATH_MAX]; /* check for the default locales */ if (!strcmp(new_categories[category], "C") || !strcmp(new_categories[category], "POSIX")) { revert_to_default(category); return(0); } /* check whether special symbol */ if (isspecial && _bcs_strcasecmp(locname, _LOCALE_SYM_FORCE) == 0) return(force_locale_enable(category)); /* sanity check */ if (strchr(locname, '/') != NULL) return(-1); snprintf(name, sizeof(name), "%s/%s/%s", _PathLocale, locname, categories[category].name); if (category > 0 && category < (int)__arysize(categories) && categories[category].load_function != NULL) return(categories[category].load_function(locname)); return(0); }
static char * loadlocale(int category) { char aliaspath[PATH_MAX], loccat[PATH_MAX], buf[PATH_MAX]; const char *alias; _DIAGASSERT(0 < category && category < __arysize(categories)); if (strcmp(new_categories[category], current_categories[category]) == 0) return(current_categories[category]); /* (1) non-aliased file */ if (!load_locale_sub(category, new_categories[category], 0)) goto success; /* (2) lookup locname/catname type alias */ snprintf(aliaspath, sizeof(aliaspath), "%s/" _LOCALE_ALIAS_NAME, _PathLocale); snprintf(loccat, sizeof(loccat), "%s/%s", new_categories[category], categories[category].name); alias = _lookup_alias(aliaspath, loccat, buf, sizeof(buf), _LOOKUP_CASE_SENSITIVE); if (!load_locale_sub(category, alias, 1)) goto success; /* (3) lookup locname type alias */ alias = _lookup_alias(aliaspath, new_categories[category], buf, sizeof(buf), _LOOKUP_CASE_SENSITIVE); if (!load_locale_sub(category, alias, 1)) goto success; return(NULL); success: strlcpy(current_categories[category], new_categories[category], sizeof(current_categories[category])); return(current_categories[category]); }
char * setlocale(int category, const char *locale) { int i, loadlocale_success; size_t len; const char *env, *r; __mb_len_max_runtime = 32; if (issetugid() || (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE")))) _PathLocale = _PATH_LOCALE; if (category < 0 || category >= (int)__arysize(categories)) return(NULL); if (locale == NULL) return(category ? current_categories[category] : currentlocale()); /* * Default to the current locale for everything. */ for (i = 1; i < _LC_LAST; ++i) strlcpy(new_categories[i], current_categories[i], sizeof(new_categories[i])); /* * Now go fill up new_categories from the locale argument */ if (*locale == '\0') { if (category == LC_ALL) { for (i = 1; i < _LC_LAST; ++i) { env = __get_locale_env(i); strlcpy(new_categories[i], env, sizeof(new_categories[i])); } } else { env = __get_locale_env(category); strlcpy(new_categories[category], env, sizeof(new_categories[category])); } } else if (category) { strlcpy(new_categories[category], locale, sizeof(new_categories[category])); } else { if ((r = strchr(locale, '/')) == 0) { for (i = 1; i < _LC_LAST; ++i) { strlcpy(new_categories[i], locale, sizeof(new_categories[i])); } } else { for (i = 1;;) { _DIAGASSERT(*r == '/' || *r == 0); _DIAGASSERT(*locale != 0); if (*locale == '/') return(NULL); /* invalid format. */ len = r - locale; if (len + 1 > sizeof(new_categories[i])) return(NULL); /* too long */ memcpy(new_categories[i], locale, len); new_categories[i][len] = '\0'; if (*r == 0) break; _DIAGASSERT(*r == '/'); if (*(locale = ++r) == 0) /* slash followed by NUL */ return(NULL); /* skip until NUL or '/' */ while (*r && *r != '/') r++; if (++i == _LC_LAST) return(NULL); /* too many slashes. */ } if (i + 1 != _LC_LAST) return(NULL); /* too few slashes. */ } } if (category) return(loadlocale(category)); loadlocale_success = 0; for (i = 1; i < _LC_LAST; ++i) { if (loadlocale(i) != NULL) loadlocale_success = 1; } /* * If all categories failed, return NULL; we don't need to back * changes off, since none happened. */ if (!loadlocale_success) return(NULL); return(currentlocale()); }
int main(int argc, char **argv) { int c, todo; u_int interval; /* milliseconds */ int reps; char *memf, *nlistf; char errbuf[_POSIX2_LINE_MAX]; memf = nlistf = NULL; interval = reps = todo = 0; maxshowdevs = 2; while ((c = getopt(argc, argv, "c:fiM:mN:n:p:stvw:z")) != -1) { switch (c) { case 'c': reps = atoi(optarg); break; case 'f': #ifdef notyet todo |= FORKSTAT; #else errx(EX_USAGE, "sorry, -f is not (re)implemented yet"); #endif break; case 'i': todo |= INTRSTAT; break; case 'M': memf = optarg; break; case 'm': todo |= MEMSTAT; break; case 'N': nlistf = optarg; break; case 'n': nflag = 1; maxshowdevs = atoi(optarg); if (maxshowdevs < 0) errx(1, "number of devices %d is < 0", maxshowdevs); break; case 'p': if (buildmatch(optarg, &matches, &num_matches) != 0) errx(1, "%s", devstat_errbuf); break; case 's': todo |= SUMSTAT; break; case 't': #ifdef notyet todo |= TIMESTAT; #else errx(EX_USAGE, "sorry, -t is not (re)implemented yet"); #endif break; case 'v': ++verbose; break; case 'w': interval = (u_int)(strtod(optarg, NULL) * 1000.0); break; case 'z': todo |= ZMEMSTAT; break; default: usage(); } } argc -= optind; argv += optind; if (todo == 0) todo = VMSTAT; /* * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. */ if (nlistf != NULL || memf != NULL) setgid(getgid()); kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); if (kd == NULL) errx(1, "kvm_openfiles: %s", errbuf); if ((c = kvm_nlist(kd, namelist)) != 0) { if (c > 0) { warnx("undefined symbols:"); for (c = 0; c < (int)__arysize(namelist); c++) if (namelist[c].n_type == 0) fprintf(stderr, " %s", namelist[c].n_name); fputc('\n', stderr); } else warnx("kvm_nlist: %s", kvm_geterr(kd)); exit(1); } if (todo & VMSTAT) { struct winsize winsize; /* * Make sure that the userland devstat version matches the * kernel devstat version. If not, exit and print a * message informing the user of his mistake. */ if (checkversion() < 0) errx(1, "%s", devstat_errbuf); argv = getdrivedata(argv); winsize.ws_row = 0; ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&winsize); if (winsize.ws_row > 0) winlines = winsize.ws_row; } #define BACKWARD_COMPATIBILITY #ifdef BACKWARD_COMPATIBILITY if (*argv) { interval = (u_int)(strtod(*argv, NULL) * 1000.0); if (*++argv) reps = atoi(*argv); } #endif if (interval) { if (!reps) reps = -1; } else if (reps) { interval = 1000; } #ifdef notyet if (todo & FORKSTAT) doforkst(); #endif if (todo & MEMSTAT) domem(); if (todo & ZMEMSTAT) dozmem(); if (todo & SUMSTAT) dosum(); #ifdef notyet if (todo & TIMESTAT) dotimes(); #endif if (todo & INTRSTAT) dointr(); if (todo & VMSTAT) dovmstat(interval, reps); exit(0); }