📄 nonport.cpp
字号:
// nonport.cpp// code for nonport.h// copyright SafeTP Development Group, Inc., 2000 Terms of use are as specified in license.txt#include <stdio.h> // printf#include <stdlib.h> // abort#include <string.h> // strncpy#include <assert.h>#ifdef __WIN32__# ifdef USE_MINWIN_H# include "minwin.h" // api# else# include <windows.h> // api# endif# include <strstrea.h> // ostrstream# include <conio.h> // getch or _getch# include <dos.h> // sleep# include <io.h> // chmod# ifdef __BORLANDC__# include <dir.h> // mkdir, chdir# include <dirent.h> // opendir# pragma warn -par // warning: parameter not used# else // MSVC# include <errno.h> // ENOENT# include <direct.h> // _mkdir, _chdir# define getch _getch# define mkdir _mkdir // why must VC be such an oddball?# define chdir _chdir# define chmod _chmod void sleep(unsigned sec) { Sleep(sec * 1000); return; }# endif# define DIRSLASH '\\'# define DIRSLASHES "\\/"#else // unix# include <sys/time.h> // struct timeval, gettimeofday# include <sys/types.h> // mkdir constants, DIR, struct dirent# include <fcntl.h> // mkdir constants# include <unistd.h> // mkdir, sleep, chdir, geteuid# include <errno.h> // errno# include <pwd.h> // getpwuid, struct passwd# include <dirent.h> // opendir# define DIRSLASH '/'# define DIRSLASHES "/"#endif#include <sys/stat.h> // chmod, mode macros#include <time.h> // tzset, localtime, time#include <iostream.h> // cout#include "nonport.h" // this module// thread safety: assumed to only change during global initNonportFailFunc nonportFail = defaultNonportFail;void defaultNonportFail(char const *, char const *){}// convenienceinline void fail(char const *call, char const *ctx=NULL){ nonportFail(call, ctx);}void setRawMode(bool raw){#ifdef __WIN32__ DWORD mode;# ifdef ALLOW_CONSOLE_REDIRECT // allows input to be redirected from a file // probably a bad thing because we use this function to read passwords, etc HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); if (hConsole == INVALID_HANDLE_VALUE) fail("GetStdHandle", "setRawMode");# else HANDLE hConsole = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hConsole == INVALID_HANDLE_VALUE) fail("CreateFile", "setRawMode");# endif if (raw) { // first, flush out any garbage that may be sitting in the input buffer already fflush(stdin); if (!FlushConsoleInputBuffer(hConsole)) fail("FlushConsoleInputBuffer", "setRawMode"); if (!GetConsoleMode(hConsole, &mode)) fail("GetConsoleMode", "setRawMode"); mode = mode & ~((DWORD)(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT)); if (!SetConsoleMode(hConsole, mode)) fail("SetConsoleMode", "setRawMode"); } else { if (!GetConsoleMode(hConsole, &mode)) fail("GetConsoleMode", "setRawMode"); mode = mode | ((DWORD)(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT)); if (!SetConsoleMode(hConsole, mode)) fail("SetConsoleMode", "setRawMode"); } CloseHandle(hConsole);#else // UNIX int res; if (raw) { // turn off UNIX term output, put in raw mode res = system("stty -echo raw"); } else { // back to normal mode res = system("stty echo -raw"); } if (res != 0) { //fail("system", "setRawMode"); }#endif}// get the next character typed, without any intervening interpretation// or bufferingchar getConsoleChar(){#ifdef __WIN32__# ifdef ALLOW_CONSOLE_REDIRECT // allows input to be redirected from a file // probably a bad thing because we use this function to read passwords, etc HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); if (hConsole == INVALID_HANDLE_VALUE) fail("GetStdHandle", "setRawMode");# else HANDLE hConsole = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hConsole == INVALID_HANDLE_VALUE) fail("CreateFile", "setRawMode");# endif char ch = '\0'; DWORD numread; if (!ReadFile(hConsole, &ch, 1, &numread, NULL)) fail("ReadFile", "getConsoleChar"); if (numread == 0) fail("ReadFile", "getConsoleChar"); // EOF CloseHandle(hConsole); return ch;#else // UNIX // relies on raw mode for console int ch = getchar(); if (ch == EOF) { fail("getchar", "getConsoleChar"); } return ch;#endif}// return the # of milliseconds since some unspecified, but// constant for the life of the program, eventlong getMilliseconds(){# ifdef __WIN32__ // # of milliseconds since program started return GetTickCount();# else // some unspecified millisecond count (unspecified // because tv.tv_sec * 1000 will overflow a 32-bit // long, for typical values) struct timeval tv; gettimeofday(&tv, NULL); // according to HPUX man page, this always returns 0 and does // not have any errors defined //printf("tv.tv_sec = %d, tv.tv_usec = %d\n", // tv.tv_sec, tv.tv_usec); return tv.tv_sec * 1000 + tv.tv_usec / 1000;# endif}bool limitFileAccess(char const *fname){ // read/write for user, nothing for group or others if (chmod(fname, 0600) != 0) { fail("chmod", fname); return false; } else { return true; }}bool createDirectory(char const *dirname){ int res;# ifdef __WIN32__ // no 'mode' argument res = mkdir(dirname);# else // unix // read/write/execute permission for user, no one else res = mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR);# endif if (res != 0) { fail("mkdir", dirname); return false; } else { return true; }}bool changeDirectory(char const *dirname){ if (0!=chdir(dirname)) { fail("chdir", dirname); return false; } else { return true; }}bool getCurrentDirectory(char *dirname, int len){ bool ok = getcwd(dirname, len) != NULL; if (!ok) { fail("getcwd"); } return ok;}bool removeFile(char const *fname){ bool ok = unlink(fname) == 0; if (!ok) { fail("unlink", fname); } return ok;}// this may in fact use a portable subset of the standard// C library.. but I'm not holding my breath, so that's why// this routine is in the 'nonport' modulevoid getCurrentDate(int &month, int &day, int &year){ // tzset is apparently required (recommended?) before // calling localtime() tzset(); // retrieve standard UNIX time time_t unixTime; time(&unixTime); // convert to month/day/year struct tm *t = localtime(&unixTime); // write into return variables month = t->tm_mon + 1; day = t->tm_mday; year = t->tm_year + 1900; // this is not a y2k bug!}// same game for the timevoid getCurrentTime(int &hour, int &minute, int &second){ // retrieve standard UNIX time tzset(); time_t unixTime; time(&unixTime); // convert to hours/mins/secs struct tm *t = localtime(&unixTime); // write into return variables hour = t->tm_hour; minute = t->tm_min; second = t->tm_sec; // tm_sec is actually allowed to be as large as 61 for leap second // reasons. I'm not interested in exposing that, so I'm simply going // to truncate my returns to stay within 0 .. 59 if (second > 59) { second = 59; }}void portableSleep(unsigned seconds){ // with proper headers included (above), "sleep" works sleep(seconds);}void getCurrentUsername(char *buf, int buflen){ #ifdef __WIN32__ DWORD len = buflen; if (!GetUserName(buf, &len)) { fail("GetUserName"); strncpy(buf, "(unknown)", buflen); } #else // unix (SunOS only? we'll see..) #if 0 // old.. linux man page insists 'cuserid' is a bad fn to call char temp[L_cuserid]; cuserid(temp); // fail return? #endif // 0 char const *temp; struct passwd *pw = getpwuid(geteuid()); if (!pw) { fail("getpwuid(geteuid())"); temp = "(unknown)"; } else { temp = pw->pw_name; } strncpy(buf, temp, buflen); #endif}// loop reading characters, return when finishedstatic void nonechoLoop(char *buf, int len){ int cursor = 0; for(;;) { char ch = getConsoleChar(); switch (ch) { case '\r': // carriage return case '\n': // newline (apparently helps piping user/pass) buf[cursor] = 0; return; case '\b': // backspace if (cursor > 0) { cursor--; } break; case 3: // control-c setRawMode(false); // make sure it gets reset cout << "Aborting due to ^C press.\n"; exit(2); // perhaps questionable response... default: buf[cursor++] = ch; if (cursor >= len-1) { // end of buffer buf[len-1] = 0; return; } break; } }}void readNonechoString(char *buf, int len, char const *prompt){ cout << prompt; cout.flush(); setRawMode(true); try { nonechoLoop(buf, len); } catch (...) { setRawMode(false); // make sure it gets reset throw; } setRawMode(false); cout << "\n"; cout.flush();}void applyToCwdContents(PerFileFunc func, void *extra){ applyToDirContents(".", func, extra);}void applyToDirContents(char const *dirName, PerFileFunc func, void *extra){ // SM: we had find{first,next} code here for win32, but // my Borland has opendir & friends, so let's see if // that works everywhere.. (old code is below, in // trash section) // DOB: VC doesn't have opendir- // I think this is the only way to do it in the Win32 API #if defined(WIN32) && !defined(__BORLANDC__) struct _finddata_t fb; char* buf = new char[strlen(dirName)+5]; strcpy(buf, dirName); if (buf[strlen(buf)-1] != '\\') strcat(buf, "\\"); strcat(buf, "*"); long handle = _findfirst(buf, &fb); delete buf; int done = (handle == -1); if (handle == -1 && errno != ENOENT) // ENOENT = no matching entries fail("_findfirst", dirName); while (!done) { if (!func(fb.name, extra)) { break; } done = _findnext(handle, &fb); } if (handle != -1) { if (_findclose(handle)) fail("_findclose", dirName); } #else // unix and borland DIR *dir = opendir(dirName); if (!dir) { fail("opendir", dirName); return; } for(;;) { // grab next directory entry struct dirent *ent = readdir(dir); if (!ent) { break; // end of listing } if (!func(ent->d_name, extra)) { break; // user wants to stop listing } } if (closedir(dir) != 0) { fail("closedir", dirName); } #endif}bool isDirectory(char const *path){ struct stat st; if (0!=stat(path, &st)) { fail("stat", path); return false; } #if defined(WIN32) && !defined(__BORLANDC__) return !!(st.st_mode & _S_IFDIR); // this is how it works for VC #else return S_ISDIR(st.st_mode); #endif}bool fileOrDirectoryExists(char const *path){ struct stat st; if (0!=stat(path, &st)) { return false; // assume error is because of nonexistence } else { return true; }}// adapted from Dan's keyutils.cpp (and indentation style// ruthlessly changed! :) )bool ensurePath(char const *filename, bool isDirectory){ // make a temporary buffer so we can modify it safely int len = strlen(filename); char *temp = new char[len+1]; strcpy(temp, filename);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -