/** Is filename an executable file? An executable file: 1) exists 2) is a file, not a directory 3) has a name ending with ".efi" 4) Only has a single '.' in the name. If basename(filename) does not contain a '.', append ".efi" to filename If filename ends in ".efi", it is executable, else it isn't. This routine is used to when searching for the file named by argv[0]. As such, there is no need to search for extensions other than ".efi". @param[in] filename The name of the file to test. It may, or may not, have an extension. @retval 0 filename already has a path other than ".efi", or it doesn't exist, or is a directory. @retval 1 filename refers to an executable file. **/ static int isxfile(char *filename) { struct stat buf; char *bn; char *newbn; int bnlen; bn = basename(filename); // Separate off the file name component reduce(filename); // and isolate the path component bnlen = strlen(bn); newbn = strrchr(bn, '.'); // Does basename contain a period? if(newbn == NULL) { // Does NOT contain a period. newbn = &bn[bnlen]; strncpyX(newbn, ".efi", MAXPATHLEN - bnlen); // append ".efi" to basename bnlen += 4; } else if(strcmp(newbn, ".efi") != 0) { return 0; // File can not be executable. } joinpath(filename, bn); // Stitch path and file name back together if (stat(filename, &buf) != 0) { // Now, verify that file exists return 0; } if(S_ISDIR(buf.st_mode)) { // And it is not a directory. return 0; } return 1; }
/** Extract the volume name from a path. @param[out] Dest Pointer to location in which to store the extracted volume name. @param[in] path Pointer to the path to extract the volume name from. **/ static void set_volume(char *Dest, char *path) { size_t VolLen; if(is_absolute(path)) { VolLen = strcspn(path, "/\\:"); if((VolLen != 0) && (path[VolLen] == ':')) { (void) strncpyX(Dest, path, VolLen + 1); } } }
/* const char * * inet_ntop4(src, dst, size) * format an IPv4 address, more or less like inet_ntoa() * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a u_char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(const u_char *src, char *dst, socklen_t size) { char tmp[sizeof "255.255.255.255"]; int l; _DIAGASSERT(src != NULL); _DIAGASSERT(dst != NULL); l = snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u", src[0], src[1], src[2], src[3]); if (l <= 0 || (socklen_t) l >= size) { errno = ENOSPC; return (NULL); } //strlcpy(dst, tmp, size); strncpyX(dst, tmp, (size_t)size); return (dst); }
static char * currentlocale() { int i; (void)strncpyX(current_locale_string, current_categories[1], sizeof(current_locale_string)); for (i = 2; i < _LC_LAST; ++i) if (strcmp(current_categories[1], current_categories[i])) { (void)snprintf(current_locale_string, sizeof(current_locale_string), "%s/%s/%s/%s/%s/%s", current_categories[1], current_categories[2], current_categories[3], current_categories[4], current_categories[5], current_categories[6]); break; } return (current_locale_string); }
static char * loadlocale(int category) { //char aliaspath[PATH_MAX], loccat[PATH_MAX], buf[PATH_MAX]; //const char *alias; _DIAGASSERT(0 < category && category < _LC_LAST); 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 */ //(void)snprintf(aliaspath, sizeof(aliaspath), // "%s/" _LOCALE_ALIAS_NAME, _PathLocale); //(void)snprintf(loccat, sizeof(loccat), "%s/%s", // new_categories[category], categories[category]); //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: (void)strncpyX(current_categories[category], new_categories[category], sizeof(current_categories[category])); return current_categories[category]; }
/* const char * * inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ static const char * inet_ntop6(const u_char *src, char *dst, socklen_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; char *tp, *ep; struct { int base, len; } best, cur; unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; int advance; _DIAGASSERT(src != NULL); _DIAGASSERT(dst != NULL); /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); for (i = 0; i < NS_IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; best.len = 0; cur.base = -1; cur.len = 0; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; ep = tmp + sizeof(tmp); for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) { if (tp + 1 >= ep) return (NULL); *tp++ = ':'; } /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 7 && words[7] != 0x0001) || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, (socklen_t)(ep - tp))) return (NULL); tp += strlen(tp); break; } advance = snprintf(tp, (size_t)(ep - tp), "%x", words[i]); if (advance <= 0 || advance >= ep - tp) return (NULL); tp += advance; } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) { if (tp + 1 >= ep) return (NULL); *tp++ = ':'; } if (tp + 1 >= ep) return (NULL); *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } //strlcpy(dst, tmp, size); strncpyX(dst, tmp, (size_t)size); return (dst); }
char * __setlocale(int category, const char *locale) { int i, loadlocale_success; size_t len; const char *env, *r; //if (issetugid() || // (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE")))) // _PathLocale = _PATH_LOCALE; if (category < 0 || category >= _LC_LAST) return (NULL); if (!locale) return (category ? current_categories[category] : currentlocale()); /* * Default to the current locale for everything. */ for (i = 1; i < _LC_LAST; ++i) (void)strncpyX(new_categories[i], current_categories[i], sizeof(new_categories[i])); /* * Now go fill up new_categories from the locale argument */ if (!*locale) { if (category == LC_ALL) { for (i = 1; i < _LC_LAST; ++i) { env = __get_locale_env(i); (void)strncpyX(new_categories[i], env, sizeof(new_categories[i])); } } else { env = __get_locale_env(category); (void)strncpyX(new_categories[category], env, sizeof(new_categories[category])); } } else if (category) { (void)strncpyX(new_categories[category], locale, sizeof(new_categories[category])); } else { if ((r = strchr(locale, '/')) == 0) { for (i = 1; i < _LC_LAST; ++i) { (void)strncpyX(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 */ (void)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()); }