diff options
Diffstat (limited to 'osdep/OSUtils.cpp')
-rw-r--r-- | osdep/OSUtils.cpp | 222 |
1 files changed, 187 insertions, 35 deletions
diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp index c652e272..6b95258c 100644 --- a/osdep/OSUtils.cpp +++ b/osdep/OSUtils.cpp @@ -23,6 +23,7 @@ #include <sys/stat.h> #include "../node/Constants.hpp" +#include "../node/Utils.hpp" #ifdef __UNIX_LIKE__ #include <unistd.h> @@ -107,17 +108,18 @@ std::vector<std::string> OSUtils::listDirectory(const char *path) return r; } -std::vector<std::string> OSUtils::listSubdirectories(const char *path) +std::map<std::string,char> OSUtils::listDirectoryFull(const char *path) { - std::vector<std::string> r; + std::map<std::string,char> r; #ifdef __WINDOWS__ HANDLE hFind; WIN32_FIND_DATAA ffd; if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) { do { - if ((strcmp(ffd.cFileName,"."))&&(strcmp(ffd.cFileName,".."))&&((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) - r.push_back(std::string(ffd.cFileName)); + if ((strcmp(ffd.cFileName,"."))&&(strcmp(ffd.cFileName,".."))) { + r[ffd.cFileName] = ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) ? 'd' : 'f'; + } } while (FindNextFileA(hFind,&ffd)); FindClose(hFind); } @@ -132,8 +134,9 @@ std::vector<std::string> OSUtils::listSubdirectories(const char *path) if (readdir_r(d,&de,&dptr)) break; if (dptr) { - if ((strcmp(dptr->d_name,"."))&&(strcmp(dptr->d_name,".."))&&(dptr->d_type == DT_DIR)) - r.push_back(std::string(dptr->d_name)); + if ((strcmp(dptr->d_name,"."))&&(strcmp(dptr->d_name,".."))) { + r[dptr->d_name] = (dptr->d_type == DT_DIR) ? 'd' : 'f'; + } } else break; } closedir(d); @@ -142,6 +145,64 @@ std::vector<std::string> OSUtils::listSubdirectories(const char *path) return r; } +long OSUtils::cleanDirectory(const char *path,const uint64_t olderThan) +{ + long cleaned = 0; + +#ifdef __WINDOWS__ + HANDLE hFind; + WIN32_FIND_DATAA ffd; + LARGE_INTEGER date,adjust; + adjust.QuadPart = 11644473600000 * 10000; + char tmp[4096]; + if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) { + do { + if ((strcmp(ffd.cFileName,"."))&&(strcmp(ffd.cFileName,".."))&&((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) { + date.HighPart = ffd.ftLastWriteTime.dwHighDateTime; + date.LowPart = ffd.ftLastWriteTime.dwLowDateTime; + if (date.QuadPart > 0) { + date.QuadPart -= adjust.QuadPart; + if (((date.QuadPart / 10000000) * 1000) < olderThan) { + Utils::snprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName); + if (DeleteFileA(tmp)) + ++cleaned; + } + } + } + } while (FindNextFileA(hFind,&ffd)); + FindClose(hFind); + } +#else + struct dirent de; + struct dirent *dptr; + struct stat st; + char tmp[4096]; + DIR *d = opendir(path); + if (!d) + return -1; + dptr = (struct dirent *)0; + for(;;) { + if (readdir_r(d,&de,&dptr)) + break; + if (dptr) { + if ((strcmp(dptr->d_name,"."))&&(strcmp(dptr->d_name,".."))&&(dptr->d_type == DT_REG)) { + Utils::snprintf(tmp,sizeof(tmp),"%s/%s",path,dptr->d_name); + if (stat(tmp,&st) == 0) { + uint64_t mt = (uint64_t)(st.st_mtime); + if ((mt > 0)&&((mt * 1000) < olderThan)) { + if (unlink(tmp) == 0) + ++cleaned; + } + } + } + } else break; + } + closedir(d); +#endif + + return cleaned; +} + bool OSUtils::rmDashRf(const char *path) { #ifdef __WINDOWS__ @@ -178,7 +239,7 @@ bool OSUtils::rmDashRf(const char *path) std::string p(path); p.push_back(ZT_PATH_SEPARATOR); p.append(dptr->d_name); - if (unlink(p.c_str()) != 0) { + if (unlink(p.c_str()) != 0) { // unlink first will remove symlinks instead of recursing them if (!rmDashRf(p.c_str())) return false; } @@ -253,34 +314,6 @@ int64_t OSUtils::getFileSize(const char *path) return -1; } -std::vector<InetAddress> OSUtils::resolve(const char *name) -{ - std::vector<InetAddress> r; - std::vector<InetAddress>::iterator i; - InetAddress tmp; - struct addrinfo *ai = (struct addrinfo *)0,*p; - if (!getaddrinfo(name,(const char *)0,(const struct addrinfo *)0,&ai)) { - try { - p = ai; - while (p) { - if ((p->ai_addr)&&((p->ai_addr->sa_family == AF_INET)||(p->ai_addr->sa_family == AF_INET6))) { - tmp = *(p->ai_addr); - for(i=r.begin();i!=r.end();++i) { - if (i->ipsEqual(tmp)) - goto skip_add_inetaddr; - } - r.push_back(tmp); - } -skip_add_inetaddr: - p = p->ai_next; - } - } catch ( ... ) {} - freeaddrinfo(ai); - } - std::sort(r.begin(),r.end()); - return r; -} - bool OSUtils::readFile(const char *path,std::string &buf) { char tmp[1024]; @@ -313,6 +346,50 @@ bool OSUtils::writeFile(const char *path,const void *buf,unsigned int len) return false; } +std::vector<std::string> OSUtils::split(const char *s,const char *const sep,const char *esc,const char *quot) +{ + std::vector<std::string> fields; + std::string buf; + + if (!esc) + esc = ""; + if (!quot) + quot = ""; + + bool escapeState = false; + char quoteState = 0; + while (*s) { + if (escapeState) { + escapeState = false; + buf.push_back(*s); + } else if (quoteState) { + if (*s == quoteState) { + quoteState = 0; + fields.push_back(buf); + buf.clear(); + } else buf.push_back(*s); + } else { + const char *quotTmp; + if (strchr(esc,*s)) + escapeState = true; + else if ((buf.size() <= 0)&&((quotTmp = strchr(quot,*s)))) + quoteState = *quotTmp; + else if (strchr(sep,*s)) { + if (buf.size() > 0) { + fields.push_back(buf); + buf.clear(); + } // else skip runs of seperators + } else buf.push_back(*s); + } + ++s; + } + + if (buf.size()) + fields.push_back(buf); + + return fields; +} + std::string OSUtils::platformDefaultHomePath() { #ifdef __UNIX_LIKE__ @@ -349,6 +426,81 @@ std::string OSUtils::platformDefaultHomePath() #endif // __UNIX_LIKE__ or not... } +// Inline these massive JSON operations in one place only to reduce binary footprint and compile time +nlohmann::json OSUtils::jsonParse(const std::string &buf) { return nlohmann::json::parse(buf.c_str()); } +std::string OSUtils::jsonDump(const nlohmann::json &j) { return j.dump(1); } + +uint64_t OSUtils::jsonInt(const nlohmann::json &jv,const uint64_t dfl) +{ + try { + if (jv.is_number()) { + return (uint64_t)jv; + } else if (jv.is_string()) { + std::string s = jv; + return Utils::strToU64(s.c_str()); + } else if (jv.is_boolean()) { + return ((bool)jv ? 1ULL : 0ULL); + } + } catch ( ... ) {} + return dfl; +} + +bool OSUtils::jsonBool(const nlohmann::json &jv,const bool dfl) +{ + try { + if (jv.is_boolean()) { + return (bool)jv; + } else if (jv.is_number()) { + return ((uint64_t)jv > 0ULL); + } else if (jv.is_string()) { + std::string s = jv; + if (s.length() > 0) { + switch(s[0]) { + case 't': + case 'T': + case '1': + return true; + } + } + return false; + } + } catch ( ... ) {} + return dfl; +} + +std::string OSUtils::jsonString(const nlohmann::json &jv,const char *dfl) +{ + try { + if (jv.is_string()) { + return jv; + } else if (jv.is_number()) { + char tmp[64]; + Utils::snprintf(tmp,sizeof(tmp),"%llu",(uint64_t)jv); + return tmp; + } else if (jv.is_boolean()) { + return ((bool)jv ? std::string("1") : std::string("0")); + } + } catch ( ... ) {} + return std::string((dfl) ? dfl : ""); +} + +std::string OSUtils::jsonBinFromHex(const nlohmann::json &jv) +{ + std::string s(jsonString(jv,"")); + if (s.length() > 0) { + char *buf = new char[(s.length() / 2) + 1]; + try { + unsigned int l = Utils::unhex(s,buf,(unsigned int)s.length()); + std::string b(buf,l); + delete [] buf; + return b; + } catch ( ... ) { + delete [] buf; + } + } + return std::string(); +} + // Used to convert HTTP header names to ASCII lower case const unsigned char OSUtils::TOLOWER_TABLE[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; |