void inotifysocket::watch(const ibrcommon::File &path, int opts) throw (ibrcommon::socket_exception)
		{
#ifdef HAVE_SYS_INOTIFY_H
			int wd = inotify_add_watch(this->fd(), path.getPath().c_str(), opts);
			_watch_map[wd] = path;
#endif
		}
		void SecurityKeyManager::createRSA(const dtn::data::EID &ref, const int bits)
		{
			const ibrcommon::File privkey = getKeyFile(ref, SecurityKey::KEY_PRIVATE);
			const ibrcommon::File pubkey = getKeyFile(ref, SecurityKey::KEY_PUBLIC);
			RSA* rsa = RSA_new();
			BIGNUM* e = BN_new();

			BN_set_word(e, 65537);

			RSA_generate_key_ex(rsa, bits, e, NULL);

			BN_free(e);
			e = NULL;

			// write private key
			int fd = ::open(privkey.getPath().c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0600);

			FILE * rsa_privkey_file = fdopen(fd, "w");
			if (!rsa_privkey_file) {
				IBRCOMMON_LOGGER_TAG(SecurityKeyManager::TAG, error) << "Failed to open " << privkey.getPath() << IBRCOMMON_LOGGER_ENDL;
				RSA_free(rsa);
				return;
			}
			PEM_write_RSAPrivateKey(rsa_privkey_file, rsa, NULL, NULL, 0, NULL, NULL);
			fclose(rsa_privkey_file);

			// write public key
			FILE * rsa_pubkey_file = fopen(pubkey.getPath().c_str(), "w+");
			if (!rsa_pubkey_file) {
				IBRCOMMON_LOGGER_TAG(SecurityKeyManager::TAG, error) << "Failed to open " << privkey.getPath() << IBRCOMMON_LOGGER_ENDL;
				RSA_free(rsa);
				return;
			}
			PEM_write_RSA_PUBKEY(rsa_pubkey_file, rsa);
			fclose(rsa_pubkey_file);

			RSA_free(rsa);

			// set trust-level to high
			SecurityKey key = get(ref, SecurityKey::KEY_PUBLIC);
			key.trustlevel = SecurityKey::HIGH;
			store(key);
		}
		void FileMonitor::adopt(const ibrcommon::File &path)
		{
			// look for ".dtndrive" file
			const ibrcommon::File drivefile = path.get(".dtndrive");
			if (drivefile.exists())
			{
				ibrcommon::ConfigFile cf(drivefile.getPath());

				try {
					const dtn::data::EID eid( cf.read<std::string>("EID") );

					dtn::core::Node n(eid);
					const std::string uri = "file://" + path.getPath() + "/" + cf.read<std::string>("PATH");

					n.add(dtn::core::Node::URI(dtn::core::Node::NODE_DISCOVERED, dtn::core::Node::CONN_FILE, uri, 0, 10));
					dtn::core::BundleCore::getInstance().getConnectionManager().add(n);

					_active_paths[path] = n;

					IBRCOMMON_LOGGER_DEBUG_TAG("FileMonitor", 5) << "Node on drive found: " << n.getEID().getString() << IBRCOMMON_LOGGER_ENDL;

				} catch (const ibrcommon::ConfigFile::key_not_found&) {};
			}
		}
		void FileMonitor::watch(const ibrcommon::File &watch)
		{
			IBRCOMMON_LOGGER_DEBUG_TAG("FileMonitor", 5) << "watch on: " << watch.getPath() << IBRCOMMON_LOGGER_ENDL;

			if (!watch.isDirectory())
				throw ibrcommon::Exception("can not watch files, please specify a directory");

			ibrcommon::socketset socks = _socket.getAll();
			if (socks.size() == 0) return;
			inotifysocket &sock = dynamic_cast<inotifysocket&>(**socks.begin());

#ifdef HAVE_SYS_INOTIFY_H
			sock.watch(watch, IN_CREATE | IN_DELETE);
#endif
			_watchset.insert(watch);
		}
	FATFile FATFile::getParent() const
	{
		const ibrcommon::File parent = ibrcommon::File::getParent();
		return FATFile(_reader, parent.getPath());
	}
	FATFile FATFile::get(const std::string &filename) const
	{
		const ibrcommon::File child = ibrcommon::File::get(filename);
		return FATFile(_reader, child.getPath());
	}