summaryrefslogtreecommitdiffstats
path: root/kdecore/network/ksocketdevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdecore/network/ksocketdevice.cpp')
-rw-r--r--kdecore/network/ksocketdevice.cpp891
1 files changed, 0 insertions, 891 deletions
diff --git a/kdecore/network/ksocketdevice.cpp b/kdecore/network/ksocketdevice.cpp
deleted file mode 100644
index 68651b8e2..000000000
--- a/kdecore/network/ksocketdevice.cpp
+++ /dev/null
@@ -1,891 +0,0 @@
-/* -*- C++ -*-
- * Copyright (C) 2003,2005 Thiago Macieira <thiago.macieira@kdemail.net>
- *
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <config.h>
-
-#include <tqmap.h>
-
-#ifdef USE_SOLARIS
-# include <sys/filio.h>
-#endif
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <unistd.h>
-
-#ifdef HAVE_POLL
-# include <sys/poll.h>
-#else
-# ifdef HAVE_SYS_SELECT
-# include <sys/select.h>
-# endif
-#endif
-
-// Include syssocket before our local includes
-#include "syssocket.h"
-
-#include <tqmutex.h>
-#include <tqsocketnotifier.h>
-
-#include "kresolver.h"
-#include "ksocketaddress.h"
-#include "ksocketbase.h"
-#include "ksocketdevice.h"
-#include "ksockssocketdevice.h"
-
-using namespace KNetwork;
-
-class KNetwork::KSocketDevicePrivate
-{
-public:
- mutable TQSocketNotifier *input, *output, *exception;
- KSocketAddress local, peer;
- int af;
-
- inline KSocketDevicePrivate()
- {
- input = output = exception = 0L;
- af = 0;
- }
-};
-
-
-KSocketDevice::KSocketDevice(const KSocketBase* parent)
- : m_sockfd(-1), d(new KSocketDevicePrivate)
-{
- setSocketDevice(this);
- if (parent)
- setSocketOptions(parent->socketOptions());
-}
-
-KSocketDevice::KSocketDevice(int fd)
- : m_sockfd(fd), d(new KSocketDevicePrivate)
-{
- setState(IO_Open);
- setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
- setSocketDevice(this);
- d->af = localAddress().family();
-}
-
-KSocketDevice::KSocketDevice(bool, const KSocketBase* parent)
- : m_sockfd(-1), d(new KSocketDevicePrivate)
-{
- // do not set parent
- if (parent)
- setSocketOptions(parent->socketOptions());
-}
-
-KSocketDevice::~KSocketDevice()
-{
- close(); // deletes the notifiers
- unsetSocketDevice(); // prevent double deletion
- delete d;
-}
-
-bool KSocketDevice::setSocketOptions(int opts)
-{
- // must call parent
- TQMutexLocker locker(mutex());
- KSocketBase::setSocketOptions(opts);
-
- if (m_sockfd == -1)
- return true; // flags are stored
-
- {
- int fdflags = fcntl(m_sockfd, F_GETFL, 0);
- if (fdflags == -1)
- {
- setError(IO_UnspecifiedError, UnknownError);
- return false; // error
- }
-
- if (opts & Blocking)
- fdflags &= ~O_NONBLOCK;
- else
- fdflags |= O_NONBLOCK;
-
- if (fcntl(m_sockfd, F_SETFL, fdflags) == -1)
- {
- setError(IO_UnspecifiedError, UnknownError);
- return false; // error
- }
- }
-
- {
- int on = opts & AddressReuseable ? 1 : 0;
- if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1)
- {
- setError(IO_UnspecifiedError, UnknownError);
- return false; // error
- }
- }
-
-#if defined(IPV6_V6ONLY) && defined(AF_INET6)
- if (d->af == AF_INET6)
- {
- // don't try this on non-IPv6 sockets, or we'll get an error
-
- int on = opts & IPv6Only ? 1 : 0;
- if (setsockopt(m_sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on, sizeof(on)) == -1)
- {
- setError(IO_UnspecifiedError, UnknownError);
- return false; // error
- }
- }
-#endif
-
- {
- int on = opts & Broadcast ? 1 : 0;
- if (setsockopt(m_sockfd, SOL_SOCKET, SO_BROADCAST, (char*)&on, sizeof(on)) == -1)
- {
- setError(IO_UnspecifiedError, UnknownError);
- return false; // error
- }
- }
-
- return true; // all went well
-}
-
-bool KSocketDevice::open(TQ_OpenMode)
-{
- resetError();
- return false;
-}
-
-void KSocketDevice::close()
-{
- resetError();
- if (m_sockfd != -1)
- {
- delete d->input;
- delete d->output;
- delete d->exception;
-
- d->input = d->output = d->exception = 0L;
-
- d->local.setFamily(AF_UNSPEC);
- d->peer.setFamily(AF_UNSPEC);
-
- ::close(m_sockfd);
- }
- setState(0);
-
- m_sockfd = -1;
-}
-
-bool KSocketDevice::create(int family, int type, int protocol)
-{
- resetError();
-
- if (m_sockfd != -1)
- {
- // it's already created!
- setError(IO_SocketCreateError, AlreadyCreated);
- return false;
- }
-
- // no socket yet; we have to create it
- m_sockfd = kde_socket(family, type, protocol);
-
- if (m_sockfd == -1)
- {
- setError(IO_SocketCreateError, NotSupported);
- return false;
- }
-
- d->af = family;
- setSocketOptions(socketOptions());
- setState(IO_Open);
- return true; // successfully created
-}
-
-bool KSocketDevice::create(const KResolverEntry& address)
-{
- return create(address.family(), address.socketType(), address.protocol());
-}
-
-bool KSocketDevice::bind(const KResolverEntry& address)
-{
- resetError();
-
- if (m_sockfd == -1 && !create(address))
- return false; // failed creating
-
- // we have a socket, so try and bind
- if (kde_bind(m_sockfd, address.address(), address.length()) == -1)
- {
- if (errno == EADDRINUSE)
- setError(IO_BindError, AddressInUse);
- else if (errno == EINVAL)
- setError(IO_BindError, AlreadyBound);
- else
- // assume the address is the cause
- setError(IO_BindError, NotSupported);
- return false;
- }
-
- return true;
-}
-
-bool KSocketDevice::listen(int backlog)
-{
- if (m_sockfd != -1)
- {
- if (kde_listen(m_sockfd, backlog) == -1)
- {
- setError(IO_ListenError, NotSupported);
- return false;
- }
-
- resetError();
- setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
- return true;
- }
-
- // we don't have a socket
- // can't listen
- setError(IO_ListenError, NotCreated);
- return false;
-}
-
-bool KSocketDevice::connect(const KResolverEntry& address)
-{
- resetError();
-
- if (m_sockfd == -1 && !create(address))
- return false; // failed creating!
-
- if (kde_connect(m_sockfd, address.address(), address.length()) == -1)
- {
- if (errno == EISCONN)
- return true; // we're already connected
- else if (errno == EALREADY || errno == EINPROGRESS)
- {
- setError(IO_ConnectError, InProgress);
- return true;
- }
- else if (errno == ECONNREFUSED)
- setError(IO_ConnectError, ConnectionRefused);
- else if (errno == ENETDOWN || errno == ENETUNREACH ||
- errno == ENETRESET || errno == ECONNABORTED ||
- errno == ECONNRESET || errno == EHOSTDOWN ||
- errno == EHOSTUNREACH)
- setError(IO_ConnectError, NetFailure);
- else
- setError(IO_ConnectError, NotSupported);
-
- return false;
- }
-
- setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
- return true; // all is well
-}
-
-KSocketDevice* KSocketDevice::accept()
-{
- if (m_sockfd == -1)
- {
- // can't accept without a socket
- setError(IO_AcceptError, NotCreated);
- return 0L;
- }
-
- struct sockaddr sa;
- socklen_t len = sizeof(sa);
- int newfd = kde_accept(m_sockfd, &sa, &len);
- if (newfd == -1)
- {
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- setError(IO_AcceptError, WouldBlock);
- else
- setError(IO_AcceptError, UnknownError);
- return NULL;
- }
-
- return new KSocketDevice(newfd);
-}
-
-bool KSocketDevice::disconnect()
-{
- resetError();
-
- if (m_sockfd == -1)
- return false; // can't create
-
- KSocketAddress address;
- address.setFamily(AF_UNSPEC);
- if (kde_connect(m_sockfd, address.address(), address.length()) == -1)
- {
- if (errno == EALREADY || errno == EINPROGRESS)
- {
- setError(IO_ConnectError, InProgress);
- return false;
- }
- else if (errno == ECONNREFUSED)
- setError(IO_ConnectError, ConnectionRefused);
- else if (errno == ENETDOWN || errno == ENETUNREACH ||
- errno == ENETRESET || errno == ECONNABORTED ||
- errno == ECONNRESET || errno == EHOSTDOWN ||
- errno == EHOSTUNREACH)
- setError(IO_ConnectError, NetFailure);
- else
- setError(IO_ConnectError, NotSupported);
-
- return false;
- }
-
- setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
- setState(IO_Open);
- return true; // all is well
-}
-
-#ifdef USE_QT3
-TQ_LONG KSocketDevice::bytesAvailable() const
-#endif
-#ifdef USE_QT4
-qint64 KSocketDevice::bytesAvailable() const
-#endif
-{
- if (m_sockfd == -1)
- return -1; // there's nothing to read in a closed socket
-
- int nchars;
- if (ioctl(m_sockfd, FIONREAD, &nchars) == -1)
- return -1; // error!
-
- return nchars;
-}
-
-TQ_LONG KSocketDevice::waitForMore(int msecs, bool *timeout)
-{
- if (m_sockfd == -1)
- return -1; // there won't ever be anything to read...
-
- bool input;
- if (!poll(&input, 0, 0, msecs, timeout))
- return -1; // failed polling
-
- return bytesAvailable();
-}
-
-static int do_read_common(int sockfd, char *data, TQ_ULONG maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false)
-{
- socklen_t len;
- if (from)
- {
- from->setLength(len = 128); // arbitrary length
- retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len);
- }
- else
- retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
-
- if (retval == -1)
- {
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- return KSocketDevice::WouldBlock;
- else
- return KSocketDevice::UnknownError;
- }
- if (retval == 0)
- return KSocketDevice::RemotelyDisconnected;
-
- if (from)
- from->setLength(len);
- return 0;
-}
-
-TQT_TQIO_LONG KSocketDevice::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
-{
- resetError();
- if (m_sockfd == -1)
- return -1;
-
- if (maxlen == 0 || data == 0L)
- return 0; // can't read
-
- ssize_t retval;
- int err = do_read_common(m_sockfd, data, maxlen, 0L, retval);
-
- if (err)
- {
- setError(IO_ReadError, static_cast<SocketError>(err));
- return -1;
- }
-
- return retval;
-}
-
-TQT_TQIO_LONG KSocketDevice::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, KSocketAddress &from)
-{
- resetError();
- if (m_sockfd == -1)
- return -1; // nothing to do here
-
- if (data == 0L || maxlen == 0)
- return 0; // user doesn't want to read
-
- ssize_t retval;
- int err = do_read_common(m_sockfd, data, maxlen, &from, retval);
-
- if (err)
- {
- setError(IO_ReadError, static_cast<SocketError>(err));
- return -1;
- }
-
- return retval;
-}
-
-TQ_LONG KSocketDevice::peekBlock(char *data, TQ_ULONG maxlen)
-{
- resetError();
- if (m_sockfd == -1)
- return -1;
-
- if (maxlen == 0 || data == 0L)
- return 0; // can't read
-
- ssize_t retval;
- int err = do_read_common(m_sockfd, data, maxlen, 0L, retval, true);
-
- if (err)
- {
- setError(IO_ReadError, static_cast<SocketError>(err));
- return -1;
- }
-
- return retval;
-}
-
-TQ_LONG KSocketDevice::peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from)
-{
- resetError();
- if (m_sockfd == -1)
- return -1; // nothing to do here
-
- if (data == 0L || maxlen == 0)
- return 0; // user doesn't want to read
-
- ssize_t retval;
- int err = do_read_common(m_sockfd, data, maxlen, &from, retval, true);
-
- if (err)
- {
- setError(IO_ReadError, static_cast<SocketError>(err));
- return -1;
- }
-
- return retval;
-}
-
-TQT_TQIO_LONG KSocketDevice::tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
-{
- return tqwriteBlock(data, len, KSocketAddress());
-}
-
-TQT_TQIO_LONG KSocketDevice::tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const KSocketAddress& to)
-{
- resetError();
- if (m_sockfd == -1)
- return -1; // can't write to unopen socket
-
- if (data == 0L || len == 0)
- return 0; // nothing to be written
-
- ssize_t retval = ::sendto(m_sockfd, data, len, 0, to.address(), to.length());
- if (retval == -1)
- {
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- setError(IO_WriteError, WouldBlock);
- else
- setError(IO_WriteError, UnknownError);
- return -1; // nothing written
- }
- else if (retval == 0)
- setError(IO_WriteError, RemotelyDisconnected);
-
- return retval;
-}
-
-KSocketAddress KSocketDevice::localAddress() const
-{
- if (m_sockfd == -1)
- return KSocketAddress(); // not open, empty value
-
- if (d->local.family() != AF_UNSPEC)
- return d->local;
-
- socklen_t len;
- KSocketAddress localAddress;
- localAddress.setLength(len = 32); // arbitrary value
- if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
- // error!
- return d->local = KSocketAddress();
-
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- len = localAddress.address()->sa_len;
-#endif
-
- if (len <= localAddress.length())
- {
- // it has fit already
- localAddress.setLength(len);
- return d->local = localAddress;
- }
-
- // no, the socket address is actually larger than we had anticipated
- // call again
- localAddress.setLength(len);
- if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
- // error!
- return d->local = KSocketAddress();
-
- return d->local = localAddress;
-}
-
-KSocketAddress KSocketDevice::peerAddress() const
-{
- if (m_sockfd == -1)
- return KSocketAddress(); // not open, empty value
-
- if (d->peer.family() != AF_UNSPEC)
- return d->peer;
-
- socklen_t len;
- KSocketAddress peerAddress;
- peerAddress.setLength(len = 32); // arbitrary value
- if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
- // error!
- return d->peer = KSocketAddress();
-
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- len = peerAddress.address()->sa_len;
-#endif
-
- if (len <= peerAddress.length())
- {
- // it has fit already
- peerAddress.setLength(len);
- return d->peer = peerAddress;
- }
-
- // no, the socket address is actually larger than we had anticipated
- // call again
- peerAddress.setLength(len);
- if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
- // error!
- return d->peer = KSocketAddress();
-
- return d->peer = peerAddress;
-}
-
-KSocketAddress KSocketDevice::externalAddress() const
-{
- // for normal sockets, the externally visible address is the same
- // as the local address
- return localAddress();
-}
-
-TQSocketNotifier* KSocketDevice::readNotifier() const
-{
- if (d->input)
- return d->input;
-
- TQMutexLocker locker(mutex());
- if (d->input)
- return d->input;
-
- if (m_sockfd == -1)
- {
- // socket doesn't exist; can't create notifier
- return 0L;
- }
-
- return d->input = createNotifier(TQSocketNotifier::Read);
-}
-
-TQSocketNotifier* KSocketDevice::writeNotifier() const
-{
- if (d->output)
- return d->output;
-
- TQMutexLocker locker(mutex());
- if (d->output)
- return d->output;
-
- if (m_sockfd == -1)
- {
- // socket doesn't exist; can't create notifier
- return 0L;
- }
-
- return d->output = createNotifier(TQSocketNotifier::Write);
-}
-
-TQSocketNotifier* KSocketDevice::exceptionNotifier() const
-{
- if (d->exception)
- return d->exception;
-
- TQMutexLocker locker(mutex());
- if (d->exception)
- return d->exception;
-
- if (m_sockfd == -1)
- {
- // socket doesn't exist; can't create notifier
- return 0L;
- }
-
- return d->exception = createNotifier(TQSocketNotifier::Exception);
-}
-
-bool KSocketDevice::poll(bool *input, bool *output, bool *exception,
- int timeout, bool* timedout)
-{
- if (m_sockfd == -1)
- {
- setError(IO_UnspecifiedError, NotCreated);
- return false;
- }
-
- resetError();
-#ifdef HAVE_POLL
- struct pollfd fds;
- fds.fd = m_sockfd;
- fds.events = 0;
-
- if (input)
- {
- fds.events |= POLLIN;
- *input = false;
- }
- if (output)
- {
- fds.events |= POLLOUT;
- *output = false;
- }
- if (exception)
- {
- fds.events |= POLLPRI;
- *exception = false;
- }
-
- int retval = ::poll(&fds, 1, timeout);
- if (retval == -1)
- {
- setError(IO_UnspecifiedError, UnknownError);
- return false;
- }
- if (retval == 0)
- {
- // timeout
- if (timedout)
- *timedout = true;
- return true;
- }
-
- if (input && fds.revents & POLLIN)
- *input = true;
- if (output && fds.revents & POLLOUT)
- *output = true;
- if (exception && fds.revents & POLLPRI)
- *exception = true;
- if (timedout)
- *timedout = false;
-
- return true;
-#else
- /*
- * We don't have poll(2). We'll have to make do with select(2).
- */
-
- fd_set readfds, writefds, exceptfds;
- fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
-
- if (input)
- {
- preadfds = &readfds;
- FD_ZERO(preadfds);
- FD_SET(m_sockfd, preadfds);
- *input = false;
- }
- if (output)
- {
- pwritefds = &writefds;
- FD_ZERO(pwritefds);
- FD_SET(m_sockfd, pwritefds);
- *output = false;
- }
- if (exception)
- {
- pexceptfds = &exceptfds;
- FD_ZERO(pexceptfds);
- FD_SET(m_sockfd, pexceptfds);
- *exception = false;
- }
-
- int retval;
- if (timeout < 0)
- retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
- else
- {
- // convert the milliseconds to timeval
- struct timeval tv;
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = timeout % 1000 * 1000;
-
- retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
- }
-
- if (retval == -1)
- {
- setError(IO_UnspecifiedError, UnknownError);
- return false;
- }
- if (retval == 0)
- {
- // timeout
- if (timedout)
- *timedout = true;
- return true;
- }
-
- if (input && FD_ISSET(m_sockfd, preadfds))
- *input = true;
- if (output && FD_ISSET(m_sockfd, pwritefds))
- *output = true;
- if (exception && FD_ISSET(m_sockfd, pexceptfds))
- *exception = true;
-
- return true;
-#endif
-}
-
-bool KSocketDevice::poll(int timeout, bool *timedout)
-{
- bool input, output, exception;
- return poll(&input, &output, &exception, timeout, timedout);
-}
-
-TQSocketNotifier* KSocketDevice::createNotifier(TQSocketNotifier::Type type) const
-{
- if (m_sockfd == -1)
- return 0L;
-
- return new TQSocketNotifier(m_sockfd, type);
-}
-
-namespace
-{
- // simple class to avoid pointer stuff
- template<class T> class ptr
- {
- typedef T type;
- type* obj;
- public:
- ptr() : obj(0)
- { }
-
- ptr(const ptr<T>& other) : obj(other.obj)
- { }
-
- ptr(type* _obj) : obj(_obj)
- { }
-
- ~ptr()
- { }
-
- ptr<T>& operator=(const ptr<T>& other)
- { obj = other.obj; return *this; }
-
- ptr<T>& operator=(T* _obj)
- { obj = _obj; return *this; }
-
- type* operator->() const { return obj; }
-
- operator T*() const { return obj; }
-
- bool isNull() const
- { return obj == 0; }
- };
-}
-
-static KSocketDeviceFactoryBase* defaultImplFactory;
-static TQMutex defaultImplFactoryMutex;
-typedef TQMap<int, KSocketDeviceFactoryBase* > factoryMap;
-static factoryMap factories;
-
-KSocketDevice* KSocketDevice::createDefault(KSocketBase* parent)
-{
- KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
- if (device != 0L)
- return device;
-
- KSocksSocketDevice::initSocks();
-
- if (defaultImplFactory)
- return defaultImplFactory->create(parent);
-
- // the really default
- return new KSocketDevice(parent);
-}
-
-KSocketDevice* KSocketDevice::createDefault(KSocketBase* parent, int capabilities)
-{
- KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
- if (device != 0L)
- return device;
-
- TQMutexLocker locker(&defaultImplFactoryMutex);
- factoryMap::ConstIterator it = factories.constBegin();
- for ( ; it != factories.constEnd(); ++it)
- if ((it.key() & capabilities) == capabilities)
- // found a match
- return it.data()->create(parent);
-
- return 0L; // no default
-}
-
-KSocketDeviceFactoryBase*
-KSocketDevice::setDefaultImpl(KSocketDeviceFactoryBase* factory)
-{
- TQMutexLocker locker(&defaultImplFactoryMutex);
- KSocketDeviceFactoryBase* old = defaultImplFactory;
- defaultImplFactory = factory;
- return old;
-}
-
-void KSocketDevice::addNewImpl(KSocketDeviceFactoryBase* factory, int capabilities)
-{
- TQMutexLocker locker(&defaultImplFactoryMutex);
- if (factories.contains(capabilities))
- delete factories[capabilities];
- factories.insert(capabilities, factory);
-}
-