⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nonport.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  if (isDirectory) {    len++;    // also consider final '\0' (strchr returns ptr to it)  }  // start at 1 (and not 0) because if the path starts with a slash,  // then starting at 0 will cause us to try mkdir("")  for (int i=1; i < len; i++) {    if (strchr(DIRSLASHES, temp[i])) {      // wherever there is a slash (or '\0'), truncate and test      temp[i] = '\0';      if (!fileOrDirectoryExists(temp)) {        // make directory if necessary; automatically limits file access        if (!createDirectory(temp)) {          delete[] temp;          return false;        }      }      temp[i] = DIRSLASH;      // may kill final '\0', doesn't matter    }  }  // was leaking this.. found the leak with the feudal-C instrumentor!  delete[] temp;  return true;}#ifdef USE_DEV_SRANDOM  #define DEV_RANDOM "/dev/srandom"    // for OpenBSD#else  #define DEV_RANDOM "/dev/random"     // linux, etc.#endif// underlying testbool hsrcHelper(){  // I don't use FreeBSD's /dev/random because:  //   - there are comments in the source for /dev/random (at least  //     in some 5.x versions) suggest it isn't cryptographically  //     secure; if so, I don't think /dev/random should appear in  //     the filesystem by default  //   - it doesn't block when the entropy pool is empty, and I don't  //     want to busy-wait for more entropy to arrive  //   - the default configuration won't yield any data at all, because  //     no IRQs are set up to gather entropy (see rndcontrol(8))  #if defined(__UNIX__) && !defined(__FREEBSD__)    // if this takes more than three seconds, something is wrong;    // after 3 seconds we'll get a SIGALRM which will kill the process    alarm(3);    // see if /dev/random exists and is readable    int fd = open(DEV_RANDOM, O_RDONLY);    if (fd < 0) {      return false;    }    // I considered trying to grab 32 bits of entropy to test it,    // but since this is run on every process run, that might be    // a bit wasteful of entropy    // looks ok!    if (close(fd) < 0) {      perror("close");      return false;      // seems unlikely, but..    }    // ok, disable the alarm now    alarm(0);    return true;  #else    // windows    return false;  #endif}// thread safety: worst case is multiple calls to hsrcHelper, since// the boolean only changes monotonically, so it's safebool hasSystemCryptoRandom(){  #ifdef NO_DEV_RANDOM    return false;      #else    static bool cached = false;    static bool cachedAnswer;    if (!cached) {      cachedAnswer = hsrcHelper();      cached = true;    }    return cachedAnswer;  #endif}// assume we are only called if the above fn returned true;// for this fn, any failure is considered fatal because we// don't have a way to communicate it, and the possibility of// returning nonrandom values is not tolerable (if something// I haven't thought of is causing failure, add it to the list// of things hasSystemCryptoRandom checks)unsigned getSystemCryptoRandom(){  #ifdef __UNIX__    // if this takes more than three seconds, something is wrong;    // after 3 seconds we'll get a SIGALRM which will kill the process    alarm(3);    // open /dev/random    int fd = open(DEV_RANDOM, O_RDONLY);    if (!fd) {      perror("open");      exit(2);    }    // grab 4 bytes    union {      unsigned ret;      char c[4];    };    int got = 0;    while (got < 4) {      int ct = read(fd, c+got, 4-got);      if (ct < 0) {       	perror("read");       	exit(2);      }      if (ct == 0) {        // this actually happens under FreeBSD, and is part of        // why I don't use FreeBSD's /dev/random        fprintf(stderr, "got 0 bytes from %s.. it's supposed to block!!\n",                        DEV_RANDOM);        exit(2);      }      got += ct;    }    if (close(fd) < 0) {      perror("close");      exit(2);    }    // ok, disable the alarm now    alarm(0);    return ret;  #else     // windows    fprintf(stderr, "no system crypto random function available!\n");    exit(2);    return 0;   // silence warning  #endif}int getProcessId(){  #ifdef __UNIX__    return getpid();  #else // windows    return GetCurrentProcessId();  #endif}#ifdef WIN32static class _critsec_class {  private:    CRITICAL_SECTION critsec;    // these are _not_ necessary (CRITICAL_SECTION gives us everything we need)    // but they're useful for preventing bad behavior which has undefined results    // (e.g. calling leave() when you don't own the lock, which WIN32 API says causes undefined behavior )    DWORD currentOwner;    bool noOwner;    DWORD lockCount;    void init() {      static bool initcomplete = false;      if (initcomplete) return;      InitializeCriticalSection(&critsec);      currentOwner = 0;      noOwner = true;      lockCount = 0;      initcomplete = true;    }  public:    _critsec_class() { // gets called automatically at program startup by startup thread      init();    }    ~_critsec_class() {      // DeleteCriticalSection(&critsec);         // we just leak this critical section, because otherwise there's no way to handle locks called        // from static destructors     }    void enter() {      init();  // necessary to enforce initialization when called from another static initializer               // (note in this case there is always exactly one thread in the process, i.e. the startup thread)      EnterCriticalSection(&critsec); // block until available      // do some checking to ensure sanity      DWORD myid = GetCurrentThreadId();      assert((noOwner && lockCount == 0) || (currentOwner == myid && lockCount > 0));      currentOwner = myid;      noOwner = false;      lockCount++;    }    void leave() {      // do some checking to ensure sanity      DWORD myid = GetCurrentThreadId();      assert(currentOwner == myid && lockCount > 0);      lockCount--;      if (lockCount == 0) { currentOwner = 0; noOwner = true; }      LeaveCriticalSection(&critsec); // leave the critical section    }} myCritSec;#endif// enter a critical section - blocks until section is free// used for synchronizing across threads in a single process// note there is only one critical section object here // a single thread may call this multiple times without being blocked// but must call portableUnlock() the same number of timesvoid portableLock() {  #ifdef _MT // defined automatically on MSVC for multi-threaded code    #ifdef WIN32      myCritSec.enter();    #else      abort(); // make sure we never claim to provide mutual exclusion if we really don't    #endif  #endif  }// leave a critical section // this thread must have previously successfully executed a portableLock() callvoid portableUnlock() {  #ifdef _MT // defined automatically on MSVC for multi-threaded code    #ifdef WIN32      myCritSec.leave();    #else      abort(); // make sure we never claim to provide mutual exclusion if we really don't    #endif  #endif  }// ----------------- test code --------------------#ifdef TEST_NONPORT#include <stdio.h>       // printf// helper for testing applyToCwdFilesbool printFirst10(char const *name, void *extra){  int &count = *((int*)extra);  count++;  if (count <= 10) {    printf("  %s\n", name);    return true;    // continue  }  else {    return false;   // stop  }}bool printIt(char const *name, void*){  printf("%s\n", name);  return true;    // continue}void testingFail(char const *call, char const *ctx){  printf("FAIL: call=%s, ctx=%s, errno=%d\n",         call, (ctx? ctx : "(null)"), errno);}int main(int argc, char **argv){  nonportFail = testingFail;       if (argc > 1) {    // -ls: list directory    if (0==strcmp(argv[1], "-ls")) {      applyToCwdContents(printIt);      return 0;    }    // -hasRandom: test whether /dev/random exists and is usable    if (0==strcmp(argv[1], "-hasRandom")) {      if (hasSystemCryptoRandom()) {        getSystemCryptoRandom();        getSystemCryptoRandom();        return 0;     // yes      }      else {        return 2;     // no      }    }        printf("unknown argument: %s\n", argv[1]);    return 2;  }  // trying to figure out why backspace sometimes gives ^? crap  // (turns out Konsole sometimes sends ^? in response to BS,  // even when the option looks unchecked)  //char buf[80];  //printf("type stuff and try backspace: ");  //gets(buf);  //printf("%s (%d chars)\n", buf, strlen(buf));  //return 0;  #if 0    // annoying during 'make check'    long startTime = getMilliseconds();    printf("Type some characters; you should see each\n"           "character echoed once as you type it (q to stop):\n");    setRawMode(true);    char ch;    do {      ch = getConsoleChar();      printf("%c", ch);    } while (ch != 'q');    setRawMode(false);    printf("\n\nYou typed for %ld milliseconds\n",           getMilliseconds() - startTime);  #endif // 0  limitFileAccess("chmod.test");  printf("if the current dir contains a file called "         "chmod.test, I just attempted to limit\n"         "its access to just the owner\n");  createDirectory("test.dir");  // test chdir, which also implicitly tests mkdir  bool didFirst=false;  if (!changeDirectory("test.dir") || (didFirst=true, false) ||      !changeDirectory("..")) {    printf("failed while trying to chdir to %s\n",           (didFirst? ".." : "test.dir"));  }  // more straightforward  if (!fileOrDirectoryExists("test.dir")) {    printf("test.dir didn't get created?\n");  }  printf("what's more, I just tried to mkdir & chdir test.dir\n");  // test ensurePath  if (!ensurePath("test.dir/a/b/c/d", false /*isDirectory*/)) {    printf("ensurePath test.dir/a/b/c/d failed\n");  }  // try to list partial directory contents  printf("listing of first 10 files in this directory:\n");  {    int count = 0;    applyToCwdContents(printFirst10, &count);  }  // test date function  {    int m, d, y;    getCurrentDate(m, d, y);    printf("I think the date is (m/d/yyyy): %d/%d/%d\n", m, d, y);  }  // and time  {    int h, m, s;    getCurrentTime(h, m, s);    printf("and the time is (hh:mm:ss): %02d:%02d:%02d\n", h, m, s);  }  // test sleep (mostly just to make sure it doesn't segfault)  printf("sleeping for 1 second...\n");  portableSleep(1);  // test user name  char buf[80];  getCurrentUsername(buf, 80);  printf("current user name is: %s\n", buf);  #if 0    // annoying during 'make check'    // test nonecho reading    printf("Type something and press Enter; it won't be echoed (yet):\n");    readNonechoString(buf, 80, "  > ");    printf("You typed: %s\n", buf);  #endif // 0  // test random stuff  printf("Testing %s; if this dies with an \"Alarm clock\"\n"         "message, then something is wrong with %s.\n",         DEV_RANDOM, DEV_RANDOM);  printf("hasSystemCryptoRandom: ");  if (!hasSystemCryptoRandom()) {    printf("no\n");  }  else {    printf("yes\n");    printf("three random numbers: %u %u %u\n",           getSystemCryptoRandom(),           getSystemCryptoRandom(),           getSystemCryptoRandom());  }  // and process id  printf("my process id is %d\n", getProcessId());  return 0;}#endif // TEST_NONPORT// -------------- trash ----------------#if 0void limitFileAccess(char const *fname){  // we'll decide whether this is possible by whether  // or not the necessary macros are defined#ifndef S_IRGRP     // assume rest are if this is    // probably can't do anything    return;#else  // modify file permissions (to simplify things,  // we'll just set permissions, rather than  // read-modify-write); don't bother testing for  // error condition since there isn't much we  // can do about it anyway  chmod(fname, S_IRUSR | S_IWUSR);# endif}# ifdef __WIN32__     // findfirst, findnext#   ifdef __BORLANDC__      struct ffblk fb;      int done = findfirst("*", &fb, 0);      while (!done) {        if (!func(fb.ff_name, extra)) {          break;        }        done = findnext(&fb);      }#   else  // DOB: VC has a totally diff interface for this      struct _finddata_t fb;      long handle = _findfirst("*", &fb);      int done = (handle == -1);      while (!done) {        if (!func(fb.name, extra)) {          break;        }        done = _findnext(handle, &fb);      }      if (handle != -1) _findclose(handle);#   endif# else    // unix     // {open,read,close}dir, stat# endif#endif // 0    (trash)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -