📄 filkeydb.cpp
字号:
// filkeydb.cpp// code for filkeydb.h#include "filkeydb.h" // this module#include "keyutils.h" // sm_{load,save,test}Key#include "usercfg.h" // userConfigDir#include "sockutil.h" // formatAddress#include "nonport.h" // isDirectory, applyToCwdContents#include <iostream.h> // cout#ifdef WIN32 #define DIRSLASH '\\'#else #define DIRSLASH '/'#endif// slightly reduce redundancy#define DSAPublicKey_str "DSAPublicKey"// name for a given ip addr's keystring keyName(IPAddress addr){ return stringb("keys" << DIRSLASH << formatAddress(addr) << DIRSLASH << DSAPublicKey_str);}bool FileKeyDB::containsKey(IPAddress addr){ return sm_testKey(keyName(addr));}DataBlock FileKeyDB::getKey(IPAddress addr){ return sm_loadKey(keyName(addr));}void FileKeyDB::setKey(IPAddress addr, DataBlock const &key){ sm_saveKey(keyName(addr), key);}// context (i.e. closure) for the getMatchingAddrs fnstruct GetMatchingCtx {public: int count; // # of matching addrs int next; // index of next addr to add IPAddress *addrs; // array into which addrs are added DataBlock const &key; // key to matchpublic: GetMatchingCtx(DataBlock const &k) : count(0), next(0), addrs(NULL), key(k) {}};// when ctx->arr is NULL, we're just counting the # of matching entries// " " is not NULL, we're adding addrs to the arraybool getMatchingAddrsHelper(char const *name, void *extra){ GetMatchingCtx *ctx = (GetMatchingCtx*)extra; if (name[0] != '.') { // don't look at '.' or '..' // get key stored there try { IPAddress addr = resolveHostName(name); // doesn't really do DNS because name is dotted decimal DataBlock stored = sm_loadKey(keyName(addr)); if (stored == ctx->key) { if (ctx->addrs == NULL) { // just counting ctx->count++; } else { // add it to array xassert(ctx->next < ctx->count); // bounds check ctx->addrs[ctx->next] = addr; ctx->next++; } } } catch (...) {} // malformed directory structure; don't care } return true; // continue}IPAddress *FileKeyDB::getMatchingAddrs(int &numMatching, DataBlock const &key){ GetMatchingCtx ctx(key); // count # of matching addrs string dir = stringb(userConfigDir() << DIRSLASH << "keys"); ensurePath(dir, true /*isDirectory*/); applyToDirContents(dir, getMatchingAddrsHelper, &ctx); // check for no matches if (ctx.count == 0) { numMatching = 0; return NULL; } // put matching addrs into an array ctx.addrs = new IPAddress[ctx.count]; applyToDirContents(dir, getMatchingAddrsHelper, &ctx); xassert(ctx.count == ctx.next); // there is a subtle possibility for error here, if the contents of the // directory change between passes.. but we'll assume that that is rare // (worst case is an xassert failure) // return them numMatching = ctx.count; return ctx.addrs;}// ------------------ test code -----------------------------#ifdef TEST_FILKEYDB#include "test.h" // misc.#include "strtokp.h" // StrtokParse#include "syserr.h" // xSysError::xsyserrorvoid entry(){ char buf[80]; DataBlock block; FileKeyDB db; // setup error handling nonportFail = xSysError::xsyserror; for(;;) { cout << "filkeydb> "; cout.flush(); gets(buf); StrtokParse tok(buf, " "); if (tok == 0) { continue; } if (tok==2 && 0==strcmp(tok[0], "contains")) { cout << db.containsKey(resolveHostName(tok[1])) << endl; } else if (tok==2 && 0==strcmp(tok[0], "get")) { block = db.getKey(resolveHostName(tok[1])); block.print(); } else if (tok==3 && 0==strcmp(tok[0], "set")) { block.readFromFile(tok[2]); db.setKey(resolveHostName(tok[1]), block); } else if (tok==2 && 0==strcmp(tok[0], "getMatching")) { block.readFromFile(tok[1]); int count; IPAddress *addrs = db.getMatchingAddrs(count, block); for (int i=0; i<count; i++) { cout << formatAddress(addrs[i]) << endl; } delete[] addrs; } else if (0==strcmp(tok[0], "quit")) { break; } else { cout << "bad command: " << buf << endl; } }}USUAL_MAIN#endif // TEST_FILKEYDB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -