This commit is contained in:
Adam Ierymenko 2020-01-21 13:12:07 -08:00
parent d7b31fe014
commit e6273b3300
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
2 changed files with 37 additions and 138 deletions

View file

@ -11,36 +11,19 @@
*/ */
/****/ /****/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdarg>
#include <sys/stat.h>
#include "../node/Constants.hpp" #include "../node/Constants.hpp"
#include "../node/Utils.hpp" #include "../node/Utils.hpp"
#include "OSUtils.hpp"
#ifdef __UNIX_LIKE__
#include <unistd.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <dirent.h>
#endif
#ifdef __GCC__
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef __WINDOWS__ #ifdef __WINDOWS__
#include <windows.h> #include <WinSock2.h>
#include <wincrypt.h> #include <Windows.h>
#include <ShlObj.h> #include <Shlwapi.h>
#include <netioapi.h> #else
#include <iphlpapi.h> #include <dirent.h>
#include <fcntl.h>
#endif #endif
#include "OSUtils.hpp"
namespace ZeroTier { namespace ZeroTier {
unsigned int OSUtils::ztsnprintf(char *buf,unsigned int len,const char *fmt,...) unsigned int OSUtils::ztsnprintf(char *buf,unsigned int len,const char *fmt,...)
@ -62,13 +45,12 @@ unsigned int OSUtils::ztsnprintf(char *buf,unsigned int len,const char *fmt,...)
#ifdef __UNIX_LIKE__ #ifdef __UNIX_LIKE__
bool OSUtils::redirectUnixOutputs(const char *stdoutPath,const char *stderrPath) bool OSUtils::redirectUnixOutputs(const char *stdoutPath,const char *stderrPath)
throw()
{ {
int fdout = ::open(stdoutPath,O_WRONLY|O_CREAT,0600); int fdout = open(stdoutPath,O_WRONLY|O_CREAT,0600);
if (fdout > 0) { if (fdout > 0) {
int fderr; int fderr;
if (stderrPath) { if (stderrPath) {
fderr = ::open(stderrPath,O_WRONLY|O_CREAT,0600); fderr = open(stderrPath,O_WRONLY|O_CREAT,0600);
if (fderr <= 0) { if (fderr <= 0) {
::close(fdout); ::close(fdout);
return false; return false;
@ -99,8 +81,8 @@ std::vector<std::string> OSUtils::listDirectory(const char *path,bool includeDir
FindClose(hFind); FindClose(hFind);
} }
#else #else
struct dirent de; dirent de;
struct dirent *dptr; dirent *dptr;
DIR *d = opendir(path); DIR *d = opendir(path);
if (!d) if (!d)
return r; return r;
@ -109,7 +91,7 @@ std::vector<std::string> OSUtils::listDirectory(const char *path,bool includeDir
if (readdir_r(d,&de,&dptr)) if (readdir_r(d,&de,&dptr))
break; break;
if (dptr) { if (dptr) {
if ((strcmp(dptr->d_name,"."))&&(strcmp(dptr->d_name,".."))&&((dptr->d_type != DT_DIR)||(includeDirectories))) if ((strcmp(dptr->d_name,".") != 0)&&(strcmp(dptr->d_name,"..") != 0)&&((dptr->d_type != DT_DIR)||(includeDirectories)))
r.push_back(std::string(dptr->d_name)); r.push_back(std::string(dptr->d_name));
} else break; } else break;
} }
@ -140,8 +122,8 @@ bool OSUtils::rmDashRf(const char *path)
} }
return (RemoveDirectoryA(path) != FALSE); return (RemoveDirectoryA(path) != FALSE);
#else #else
struct dirent de; dirent de;
struct dirent *dptr; dirent *dptr;
DIR *d = opendir(path); DIR *d = opendir(path);
if (!d) if (!d)
return true; return true;
@ -198,14 +180,6 @@ void OSUtils::lockDownFile(const char *path,bool isDir)
#endif #endif
} }
uint64_t OSUtils::getLastModified(const char *path)
{
struct stat s;
if (stat(path,&s))
return 0;
return (((uint64_t)s.st_mtime) * 1000ULL);
}
bool OSUtils::fileExists(const char *path,bool followLinks) bool OSUtils::fileExists(const char *path,bool followLinks)
{ {
struct stat s; struct stat s;
@ -216,20 +190,6 @@ bool OSUtils::fileExists(const char *path,bool followLinks)
return (stat(path,&s) == 0); return (stat(path,&s) == 0);
} }
int64_t OSUtils::getFileSize(const char *path)
{
struct stat s;
if (stat(path,&s))
return -1;
#ifdef __WINDOWS__
return s.st_size;
#else
if (S_ISREG(s.st_mode))
return s.st_size;
#endif
return -1;
}
bool OSUtils::readFile(const char *path,std::string &buf) bool OSUtils::readFile(const char *path,std::string &buf)
{ {
char tmp[16384]; char tmp[16384];
@ -376,6 +336,7 @@ std::string OSUtils::platformDefaultHomePath()
} }
#ifndef OMIT_JSON_SUPPORT #ifndef OMIT_JSON_SUPPORT
// Inline these massive JSON operations in one place only to reduce binary footprint and compile time // 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()); } nlohmann::json OSUtils::jsonParse(const std::string &buf) { return nlohmann::json::parse(buf.c_str()); }
std::string OSUtils::jsonDump(const nlohmann::json &j,int indentation) { return j.dump(indentation); } std::string OSUtils::jsonDump(const nlohmann::json &j,int indentation) { return j.dump(indentation); }
@ -451,7 +412,4 @@ std::string OSUtils::jsonString(const nlohmann::json &jv,const char *dfl)
#endif // OMIT_JSON_SUPPORT #endif // OMIT_JSON_SUPPORT
// 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 };
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -14,32 +14,22 @@
#ifndef ZT_OSUTILS_HPP #ifndef ZT_OSUTILS_HPP
#define ZT_OSUTILS_HPP #define ZT_OSUTILS_HPP
#include <stdio.h> #include "../node/Constants.hpp"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <cstdarg>
#include <ctime>
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
#include <map> #include <map>
#include "../node/Constants.hpp" #ifndef __WINDOWS__
#include "../node/InetAddress.hpp"
#ifdef __WINDOWS__
#include <WinSock2.h>
#include <Windows.h>
#include <Shlwapi.h>
#else
#include <unistd.h>
#include <errno.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <arpa/inet.h> #include <unistd.h>
#ifdef __LINUX__
#include <sys/syscall.h>
#endif
#endif #endif
#ifndef OMIT_JSON_SUPPORT #ifndef OMIT_JSON_SUPPORT
@ -79,8 +69,7 @@ public:
* @param stderrPath Path to file to use for stderr, or NULL for same as stdout (default) * @param stderrPath Path to file to use for stderr, or NULL for same as stdout (default)
* @return True on success * @return True on success
*/ */
static bool redirectUnixOutputs(const char *stdoutPath,const char *stderrPath = (const char *)0) static bool redirectUnixOutputs(const char *stdoutPath,const char *stderrPath = nullptr);
throw();
#endif // __UNIX_LIKE__ #endif // __UNIX_LIKE__
/** /**
@ -89,7 +78,7 @@ public:
* @param path Path to delete * @param path Path to delete
* @return True if delete was successful * @return True if delete was successful
*/ */
static inline bool rm(const char *path) static ZT_ALWAYS_INLINE bool rm(const char *path)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return (DeleteFileA(path) != FALSE); return (DeleteFileA(path) != FALSE);
@ -97,9 +86,9 @@ public:
return (unlink(path) == 0); return (unlink(path) == 0);
#endif #endif
} }
static inline bool rm(const std::string &path) { return rm(path.c_str()); } static ZT_ALWAYS_INLINE bool rm(const std::string &path) { return rm(path.c_str()); }
static inline bool mkdir(const char *path) static ZT_ALWAYS_INLINE bool mkdir(const char *path)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
if (::PathIsDirectoryA(path)) if (::PathIsDirectoryA(path))
@ -111,9 +100,9 @@ public:
return true; return true;
#endif #endif
} }
static inline bool mkdir(const std::string &path) { return OSUtils::mkdir(path.c_str()); } static ZT_ALWAYS_INLINE bool mkdir(const std::string &path) { return OSUtils::mkdir(path.c_str()); }
static inline bool rename(const char *o,const char *n) static ZT_ALWAYS_INLINE bool rename(const char *o,const char *n)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
DeleteFileA(n); DeleteFileA(n);
@ -151,17 +140,6 @@ public:
*/ */
static void lockDownFile(const char *path,bool isDir); static void lockDownFile(const char *path,bool isDir);
/**
* Get file last modification time
*
* Resolution is often only second, not millisecond, but the return is
* always in ms for comparison against now().
*
* @param path Path to file to get time
* @return Last modification time in ms since epoch or 0 if not found
*/
static uint64_t getLastModified(const char *path);
/** /**
* @param path Path to check * @param path Path to check
* @param followLinks Follow links (on platforms with that concept) * @param followLinks Follow links (on platforms with that concept)
@ -169,16 +147,10 @@ public:
*/ */
static bool fileExists(const char *path,bool followLinks = true); static bool fileExists(const char *path,bool followLinks = true);
/**
* @param path Path to file
* @return File size or -1 if nonexistent or other failure
*/
static int64_t getFileSize(const char *path);
/** /**
* @return Current time in milliseconds since epoch * @return Current time in milliseconds since epoch
*/ */
static inline int64_t now() static ZT_ALWAYS_INLINE int64_t now()
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
FILETIME ft; FILETIME ft;
@ -190,12 +162,12 @@ public:
tmp.HighPart = ft.dwHighDateTime; tmp.HighPart = ft.dwHighDateTime;
return (int64_t)( ((tmp.QuadPart - 116444736000000000LL) / 10000L) + st.wMilliseconds ); return (int64_t)( ((tmp.QuadPart - 116444736000000000LL) / 10000L) + st.wMilliseconds );
#else #else
struct timeval tv; timeval tv;
#ifdef __LINUX__ // #ifdef __LINUX__
syscall(SYS_gettimeofday,&tv,0); /* fix for musl libc broken gettimeofday bug */ // syscall(SYS_gettimeofday,&tv,0); /* fix for musl libc broken gettimeofday bug */
#else // #else
gettimeofday(&tv,(struct timezone *)0); gettimeofday(&tv,(struct timezone *)0);
#endif // #endif
return ( (1000LL * (int64_t)tv.tv_sec) + (int64_t)(tv.tv_usec / 1000) ); return ( (1000LL * (int64_t)tv.tv_sec) + (int64_t)(tv.tv_usec / 1000) );
#endif #endif
}; };
@ -233,28 +205,6 @@ public:
*/ */
static std::vector<std::string> split(const char *s,const char *const sep,const char *esc,const char *quot); static std::vector<std::string> split(const char *s,const char *const sep,const char *esc,const char *quot);
/**
* Trim whitespace from beginning and end of string
*/
static inline std::string trimString(const std::string &s)
{
unsigned long end = (unsigned long)s.length();
while (end) {
char c = s[end - 1];
if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t'))
--end;
else break;
}
unsigned long start = 0;
while (start < end) {
char c = s[start];
if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t'))
++start;
else break;
}
return s.substr(start,end - start);
}
/** /**
* Write a block of data to disk, replacing any current file contents * Write a block of data to disk, replacing any current file contents
* *
@ -262,13 +212,7 @@ public:
* @param s Data to write * @param s Data to write
* @return True if entire file was successfully written * @return True if entire file was successfully written
*/ */
static inline bool writeFile(const char *path,const std::string &s) { return writeFile(path,s.data(),(unsigned int)s.length()); } static ZT_ALWAYS_INLINE bool writeFile(const char *path,const std::string &s) { return writeFile(path,s.data(),(unsigned int)s.length()); }
/**
* @param c ASCII character to convert
* @return Lower case ASCII character or unchanged if not a letter
*/
static inline char toLower(char c) throw() { return (char)OSUtils::TOLOWER_TABLE[(unsigned long)c]; }
/** /**
* @return Platform default ZeroTier One home path * @return Platform default ZeroTier One home path
@ -283,9 +227,6 @@ public:
static bool jsonBool(const nlohmann::json &jv,const bool dfl); static bool jsonBool(const nlohmann::json &jv,const bool dfl);
static std::string jsonString(const nlohmann::json &jv,const char *dfl); static std::string jsonString(const nlohmann::json &jv,const char *dfl);
#endif // OMIT_JSON_SUPPORT #endif // OMIT_JSON_SUPPORT
private:
static const unsigned char TOLOWER_TABLE[256];
}; };
} // namespace ZeroTier } // namespace ZeroTier