From 2113c21fdcc57bc8c07a4e514937cd07f7bc8526 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 16 Jun 2016 14:09:09 -0700 Subject: [PATCH] devicemap now works again in OSXEthernetTap --- node/Dictionary.hpp | 49 ++++++++++++++++++++++++++++++++++++++-- osdep/OSXEthernetTap.cpp | 13 ++++++----- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/node/Dictionary.hpp b/node/Dictionary.hpp index ccca00c82..e4c7ff20a 100644 --- a/node/Dictionary.hpp +++ b/node/Dictionary.hpp @@ -182,6 +182,9 @@ public: case '0': dest[j++] = (char)0; break; + case 'e': + dest[j++] = '='; + break; default: dest[j++] = *p; } @@ -261,8 +264,8 @@ public: * Add a new key=value pair * * If the key is already present this will append another, but the first - * will always be returned by get(). There is no erase(). This is designed - * to be generated and shipped, not as an editable data structure. + * will always be returned by get(). This is not checked. If you want to + * ensure a key is not present use erase() first. * * Use the vlen parameter to add binary values. Nulls will be escaped. * @@ -293,6 +296,7 @@ public: case '\n': case '\t': case '\\': + case '=': _d[j++] = '\\'; if (j == ZT_DICTIONARY_MAX_SIZE) { _d[i] = (char)0; @@ -304,6 +308,7 @@ public: case '\n': _d[j++] = 'n'; break; case '\t': _d[j++] = 't'; break; case '\\': _d[j++] = '\\'; break; + case '=': _d[j++] = 'e'; break; } if (j == ZT_DICTIONARY_MAX_SIZE) { _d[i] = (char)0; @@ -375,6 +380,46 @@ public: return (this->get(key,tmp,2) >= 0); } + /** + * Erase a key from this dictionary + * + * Use this before add() to ensure that a key is replaced if it might + * already be present. + * + * @param key Key to erase + * @return True if key was found and erased + */ + inline bool erase(const char *key) + { + char d2[ZT_DICTIONARY_MAX_SIZE]; + char *saveptr = (char *)0; + unsigned int d2ptr = 0; + bool found = false; + for(char *f=Utils::stok(_d,"\r\n",&saveptr);(f);f=Utils::stok((char *)0,"\r\n",&saveptr)) { + if (*f) { + const char *p = f; + const char *k = key; + while ((*k)&&(*p)) { + if (*k != *p) + break; + ++k; + ++p; + } + if (*k) { + p = f; + while (*p) + d2[d2ptr++] = *(p++); + d2[d2ptr++] = '\n'; + } else { + found = true; + } + } + } + d2[d2ptr++] = (char)0; + memcpy(_d,d2,d2ptr); + return found; + } + /** * @return Dictionary data as a 0-terminated C-string */ diff --git a/osdep/OSXEthernetTap.cpp b/osdep/OSXEthernetTap.cpp index 8ffd2bffc..9921049f6 100644 --- a/osdep/OSXEthernetTap.cpp +++ b/osdep/OSXEthernetTap.cpp @@ -356,10 +356,10 @@ OSXEthernetTap::OSXEthernetTap( std::string devmapbuf; Dictionary devmap; if (OSUtils::readFile((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),devmapbuf)) { - devmap.fromString(devmapbuf); - std::string desiredDevice(devmap.get(nwids,"")); - if (desiredDevice.length() > 2) { - Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",desiredDevice.c_str()); + devmap.load(devmapbuf.c_str()); + char desiredDevice[128]; + if (devmap.get(nwids,desiredDevice,sizeof(desiredDevice)) > 0) { + Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",desiredDevice); if (stat(devpath,&stattmp) == 0) { _fd = ::open(devpath,O_RDWR); if (_fd > 0) { @@ -420,8 +420,9 @@ OSXEthernetTap::OSXEthernetTap( ++globalTapsRunning; - devmap[nwids] = _dev; - OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),devmap.toString()); + devmap.erase(nwids); + devmap.add(nwids,_dev.c_str()); + OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),(const void *)devmap.data(),devmap.sizeBytes()); _thread = Thread::start(this); }