/*************************************************************************** * By Théophile Bastian, 2017 * M1 Network course project at ENS Cachan, Juliusz Chroboczek. * License: WTFPL v2 **************************************************************************/ #include "configFile.h" #include #include #include using namespace std; ConfigFile::ConfigFile() : curDataSum(0) { selfId = randId(); } bool ConfigFile::read(const char* path) { ifstream handle(path); if(!handle.is_open()) return false; while(handle.good()) { string attr; handle >> attr; if(attr == "id") { handle >> hex >> selfId >> dec; } else if(attr == "bootstrap") { u16 port; u64 id; SockAddr addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; string addrStr; handle >> hex >> id >> dec; handle >> addrStr; handle >> port; addr.sin6_port = htons(port); if(inet_pton(AF_INET6, addrStr.c_str(), &(addr.sin6_addr)) != 1) { fprintf(stderr, "Could not convert '%s' to IPv6 address\n", addrStr.c_str()); continue; } bootstrapNodes.push_back(Neighbour(id, addr)); } else if(attr == "data") { string dataStr; getline(handle, dataStr); size_t nonWSPos = 0; for(; nonWSPos < dataStr.size(); nonWSPos++) if(dataStr[nonWSPos] != ' ' && dataStr[nonWSPos] != '\t') break; if(nonWSPos == dataStr.size()) continue; std::string realDat = dataStr.substr(nonWSPos); if(curDataSum + realDat.size() + 12 + 2 > 0xff) { fprintf(stderr, "Too much data, won't fit. Discarding `%s`\n", realDat.c_str()); continue; } curDataSum += realDat.size() + 2; data.push_back(realDat); } else if(attr.empty()) continue; else { fprintf(stderr, "Unknown configuration item: '%s'\n", attr.c_str()); continue; } } handle.close(); return true; } bool ConfigFile::write(const char* path) { ofstream handle(path, ofstream::out | ofstream::trunc); if(!handle.is_open()) return false; handle << "id " << hex << selfId << dec << '\n'; for(Neighbour nei : bootstrapNodes) { char addr[54]; if(inet_ntop(AF_INET6, &nei.addr.sin6_addr, addr, 54) == NULL) { perror("Could not convert IPv6 back to string"); continue; } handle << "bootstrap " << hex << nei.id << dec << ' ' << addr << ' ' << ntohs(nei.addr.sin6_port) << '\n'; } for(auto dat : data) { handle << "data " << dat << '\n'; } handle.close(); return true; } u64 ConfigFile::randId() const { u64 out=0; for(int i=0; i < 8; i++) { out <<= 8; out += rand() % 0xFF; } return out; }