• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
kextsock.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2000-2004 Thiago Macieira <thiago.macieira@kdemail.net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  **/
20 
21 #include <config.h>
22 
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <sys/times.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
28 #include <sys/un.h>
29 
30 #include <stdio.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 
34 #include <netdb.h>
35 
36 #include <stdlib.h>
37 #include <unistd.h>
38 
39 #include <tqglobal.h>
40 #include <tqstring.h>
41 #include <tqiodevice.h>
42 #include <tqsocketnotifier.h>
43 #include <tqguardedptr.h>
44 
45 #include "kresolver.h"
46 
47 #include "kdebug.h"
48 #include "kextsock.h"
49 #include "ksockaddr.h"
50 #include "ksocks.h"
51 
52 #ifdef __CYGWIN__
53 #include "netsupp.h"
54 #endif
55 
56 using namespace KNetwork;
57 
58 //
59 // Internal class definitions
60 //
61 
62 class KExtendedSocketPrivate
63 {
64 public:
65  int flags; // socket flags
66  int status; // status
67  int syserror; // the system error value
68 
69  timeval timeout; // connection/acception timeout
70 
71  KResolver resRemote; // the resolved addresses
72  KResolver resLocal; // binding resolution
73  unsigned current; // used by the asynchronous connection
74 
75  ::TDESocketAddress *local; // local socket address
76  ::TDESocketAddress *peer; // peer socket address
77 
78  TQSocketNotifier *qsnIn, *qsnOut;
79  int inMaxSize, outMaxSize;
80  bool emitRead : 1, emitWrite : 1;
81  mutable bool addressReusable : 1, ipv6only : 1;
82 
83  KExtendedSocketPrivate() :
84  flags(0), status(0), syserror(0),
85  current(0), local(0), peer(0),
86  qsnIn(0), qsnOut(0), inMaxSize(-1), outMaxSize(-1), emitRead(false), emitWrite(false),
87  addressReusable(false), ipv6only(false)
88  {
89  timeout.tv_sec = timeout.tv_usec = 0;
90  }
91 };
92 
93 // translate KExtendedSocket flags into KResolver ones
94 static bool process_flags(int flags, int& socktype, int& familyMask, int& outflags)
95 {
96  switch (flags & (KExtendedSocket::streamSocket | KExtendedSocket::datagramSocket | KExtendedSocket::rawSocket))
97  {
98  case 0:
99  /* No flags given, use default */
100 
101  case KExtendedSocket::streamSocket:
102  /* streaming socket requested */
103  socktype = SOCK_STREAM;
104  break;
105 
106  case KExtendedSocket::datagramSocket:
107  /* datagram packet socket requested */
108  socktype = SOCK_DGRAM;
109  break;
110 
111  case KExtendedSocket::rawSocket:
112  /* raw socket requested. I wouldn't do this if I were you... */
113  socktype = SOCK_RAW;
114  break;
115 
116  default:
117  /* the flags were used in an invalid manner */
118  return false;
119  }
120 
121  if (flags & KExtendedSocket::knownSocket)
122  {
123  familyMask = 0;
124  if ((flags & KExtendedSocket::unixSocket) == KExtendedSocket::unixSocket)
125  familyMask |= KResolver::UnixFamily;
126 
127  switch ((flags & (KExtendedSocket::ipv6Socket|KExtendedSocket::ipv4Socket)))
128  {
129  case KExtendedSocket::ipv4Socket:
130  familyMask |= KResolver::IPv4Family;
131  break;
132  case KExtendedSocket::ipv6Socket:
133  familyMask |= KResolver::IPv6Family;
134  break;
135  case KExtendedSocket::inetSocket:
136  familyMask |= KResolver::InternetFamily;
137  break;
138  }
139 
140  // those are all the families we know about
141  }
142  else
143  familyMask = KResolver::KnownFamily;
144 
145  /* check other flags */
146  outflags = (flags & KExtendedSocket::passiveSocket ? KResolver::Passive : 0) |
147  (flags & KExtendedSocket::canonName ? KResolver::CanonName : 0) |
148  (flags & KExtendedSocket::noResolve ? KResolver::NoResolve : 0);
149 
150  if (getenv("TDE_NO_IPV6"))
151  familyMask &= ~KResolver::IPv6Family;
152 
153  return true;
154 }
155 
156 // "skips" at most len bytes from file descriptor fd
157 // that is, we will try and read that much data and discard
158 // it. We will stop when we have read those or when the read
159 // function returns error
160 static int skipData(int fd, unsigned len)
161 {
162  char buf[1024];
163  unsigned skipped = 0;
164  while (len)
165  {
166  int count = sizeof(buf);
167  if ((unsigned)count > len)
168  count = len;
169  count = KSocks::self()->read(fd, buf, count);
170  if (count == -1)
171  return -1;
172  else
173  {
174  len -= count;
175  skipped += count;
176  }
177  }
178  return skipped;
179 }
180 
181 /*
182  * class KExtendedSocket
183  */
184 
185 // default constructor
186 KExtendedSocket::KExtendedSocket() :
187  sockfd(-1), d(new KExtendedSocketPrivate)
188 {
189 }
190 
191 // constructor with hostname
192 KExtendedSocket::KExtendedSocket(const TQString& host, int port, int flags) :
193  sockfd(-1), d(new KExtendedSocketPrivate)
194 {
195  setAddress(host, port);
196  setSocketFlags(flags);
197 }
198 
199 // same
200 KExtendedSocket::KExtendedSocket(const TQString& host, const TQString& service, int flags) :
201  sockfd(-1), d(new KExtendedSocketPrivate)
202 {
203  setAddress(host, service);
204  setSocketFlags(flags);
205 }
206 
207 // destroy the class
208 KExtendedSocket::~KExtendedSocket()
209 {
210  closeNow();
211 
212  if (d->local != NULL)
213  delete d->local;
214  if (d->peer != NULL)
215  delete d->peer;
216 
217  if (d->qsnIn != NULL)
218  delete d->qsnIn;
219  if (d->qsnOut != NULL)
220  delete d->qsnOut;
221 
222  delete d;
223 }
224 
225 #ifdef USE_QT3
226 void KExtendedSocket::reset()
227 #endif // USE_QT3
228 #ifdef USE_QT4
229 bool KExtendedSocket::reset()
230 #endif // USE_QT4
231 {
232  closeNow();
233  release();
234  d->current = 0;
235  d->status = nothing;
236  d->syserror = 0;
237 }
238 
239 int KExtendedSocket::socketStatus() const
240 {
241  return d->status;
242 }
243 
244 void KExtendedSocket::setSocketStatus(int newstatus)
245 {
246  d->status = newstatus;
247 }
248 
249 void KExtendedSocket::setError(int errorcode, int syserror)
250 {
251  setStatus(errorcode);
252  d->syserror = syserror;
253 }
254 
255 int KExtendedSocket::systemError() const
256 {
257  return d->syserror;
258 }
259 
260 /*
261  * Sets socket flags
262  * This is only allowed if we are in nothing state
263  */
264 int KExtendedSocket::setSocketFlags(int flags)
265 {
266  if (d->status > nothing)
267  return -1; // error!
268 
269  return d->flags = flags;
270 }
271 
272 int KExtendedSocket::socketFlags() const
273 {
274  return d->flags;
275 }
276 
277 /*
278  * Sets socket target hostname
279  * This is only allowed if we are in nothing state
280  */
281 bool KExtendedSocket::setHost(const TQString& host)
282 {
283  if (d->status > nothing)
284  return false; // error!
285 
286  d->resRemote.setNodeName(host);
287  return true;
288 }
289 
290 /*
291  * returns the hostname
292  */
293 TQString KExtendedSocket::host() const
294 {
295  return d->resRemote.nodeName();
296 }
297 
298 /*
299  * Sets the socket target port/service
300  * Same thing: only state 'nothing'
301  */
302 bool KExtendedSocket::setPort(int port)
303 {
304  return setPort(TQString::number(port));
305 }
306 
307 bool KExtendedSocket::setPort(const TQString& service)
308 {
309  if (d->status > nothing)
310  return false; // error
311 
312  d->resRemote.setServiceName(service);
313  return true;
314 }
315 
316 /*
317  * returns the service port number
318  */
319 TQString KExtendedSocket::port() const
320 {
321  return d->resRemote.serviceName();
322 }
323 
324 /*
325  * sets the address
326  */
327 bool KExtendedSocket::setAddress(const TQString& host, int port)
328 {
329  return setHost(host) && setPort(port);
330 }
331 
332 /*
333  * the same
334  */
335 bool KExtendedSocket::setAddress(const TQString& host, const TQString& serv)
336 {
337  return setHost(host) && setPort(serv);
338 }
339 
340 /*
341  * Sets the bind hostname
342  * This is only valid in the 'nothing' state and if this is not a
343  * passiveSocket socket
344  */
345 bool KExtendedSocket::setBindHost(const TQString& host)
346 {
347  if (d->status > nothing || d->flags & passiveSocket)
348  return false; // error
349 
350  d->resLocal.setServiceName(host);
351  return true;
352 }
353 
354 /*
355  * Unsets the bind hostname
356  * same thing
357  */
358 bool KExtendedSocket::unsetBindHost()
359 {
360  return setBindHost(TQString::null);
361 }
362 
363 /*
364  * returns the binding host
365  */
366 TQString KExtendedSocket::bindHost() const
367 {
368  return d->resLocal.serviceName();
369 }
370 
371 /*
372  * Sets the bind port
373  * Same condition as setBindHost
374  */
375 bool KExtendedSocket::setBindPort(int port)
376 {
377  return setBindPort(TQString::number(port));
378 }
379 
380 bool KExtendedSocket::setBindPort(const TQString& service)
381 {
382  if (d->status > nothing || d->flags & passiveSocket)
383  return false; // error
384 
385  d->resLocal.setServiceName(service);
386  return true;
387 }
388 
389 /*
390  * unsets the bind port
391  */
392 bool KExtendedSocket::unsetBindPort()
393 {
394  return setBindPort(TQString::null);
395 }
396 
397 /*
398  * returns the binding port
399  */
400 TQString KExtendedSocket::bindPort() const
401 {
402  return d->resLocal.serviceName();
403 }
404 
405 /*
406  * sets the binding address
407  */
408 bool KExtendedSocket::setBindAddress(const TQString& host, int port)
409 {
410  return setBindHost(host) && setBindPort(port);
411 }
412 
413 /*
414  * same
415  */
416 bool KExtendedSocket::setBindAddress(const TQString& host, const TQString& service)
417 {
418  return setBindHost(host) && setBindPort(service);
419 }
420 
421 /*
422  * unsets binding address
423  */
424 bool KExtendedSocket::unsetBindAddress()
425 {
426  return unsetBindHost() && unsetBindPort();
427 }
428 
429 /*
430  * sets the timeout for the connection
431  */
432 bool KExtendedSocket::setTimeout(int secs, int usecs)
433 {
434  if (d->status >= connected) // closed?
435  return false;
436 
437  d->timeout.tv_sec = secs;
438  d->timeout.tv_usec = usecs;
439  return true;
440 }
441 
442 /*
443  * returns the timeout
444  */
445 timeval KExtendedSocket::timeout() const
446 {
447  return d->timeout;
448 }
449 
450 /*
451  * Sets the blocking mode on this socket
452  */
453 bool KExtendedSocket::setBlockingMode(bool enable)
454 {
455  cleanError();
456  if (d->status < created)
457  return false;
458 
459  if (sockfd == -1)
460  return false; // error!
461 
462  int fdflags = fcntl(sockfd, F_GETFL, 0);
463  if (fdflags == -1)
464  return false; // error!
465 
466  if (!enable)
467  fdflags |= O_NONBLOCK;
468  else
469  fdflags &= ~O_NONBLOCK;
470 
471  if (fcntl(sockfd, F_SETFL, fdflags) == -1)
472  {
473  setError(IO_UnspecifiedError, errno);
474  return false;
475  }
476  return true;
477 }
478 
479 /*
480  * Returns the blocking mode on the socket
481  */
482 bool KExtendedSocket::blockingMode()
483 {
484  cleanError();
485  if (d->status < created)
486  return false; // sockets not created are in blocking mode
487 
488  if (sockfd == -1)
489  return false; // error
490 
491  int fdflags = fcntl(sockfd, F_GETFL, 0);
492  if (fdflags == -1)
493  {
494  setError(IO_UnspecifiedError, errno);
495  return false;
496  }
497  return (fdflags & O_NONBLOCK) == 0; // non-blocking == false
498 }
499 
500 /*
501  * Sets the reusability flag for this socket in the OS
502  */
503 bool KExtendedSocket::setAddressReusable(bool enable)
504 {
505  cleanError();
506  d->addressReusable = enable;
507  if (d->status < created)
508  return true;
509 
510  if (sockfd == -1)
511  return true;
512 
513  if (!setAddressReusable(sockfd, enable))
514  {
515  setError(IO_UnspecifiedError, errno);
516  return false;
517  }
518  return true;
519 }
520 
521 bool KExtendedSocket::setAddressReusable(int fd, bool enable)
522 {
523  if (fd == -1)
524  return false;
525 
526  int on = enable; // just to be on the safe side
527 
528  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1)
529  return false;
530  return true;
531 }
532 
533 /*
534  * Retrieves the reusability flag for this socket
535  */
536 bool KExtendedSocket::addressReusable()
537 {
538  cleanError();
539  if (d->status < created)
540  return d->addressReusable;
541 
542  if (sockfd == -1)
543  return d->addressReusable;
544 
545  int on;
546  socklen_t onsiz = sizeof(on);
547  if (getsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, &onsiz) == -1)
548  {
549  setError(IO_UnspecifiedError, errno);
550  return false;
551  }
552 
553  return on != 0;
554 }
555 
556 /*
557  * Set the IPV6_V6ONLY flag
558  */
559 bool KExtendedSocket::setIPv6Only(bool enable)
560 {
561 #ifdef IPV6_V6ONLY
562  cleanError();
563 
564  d->ipv6only = enable;
565  if (sockfd == -1)
566  return true; // can't set on a non-existing socket
567 
568  int on = enable;
569 
570  if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
571  (char *)&on, sizeof(on)) == -1)
572  {
573  setError(IO_UnspecifiedError, errno);
574  return false;
575  }
576  else
577  return true;
578 
579 #else
580  // we don't have the IPV6_V6ONLY constant in this system
581  d->ipv6only = enable;
582 
583  setError(IO_UnspecifiedError, ENOSYS);
584  return false; // can't set if we don't know about this flag
585 #endif
586 }
587 
588 /*
589  * retrieve the IPV6_V6ONLY flag
590  */
591 bool KExtendedSocket::isIPv6Only()
592 {
593 #ifdef IPV6_V6ONLY
594  cleanError();
595 
596  if (d->status < created || sockfd == -1)
597  return d->ipv6only;
598 
599  int on;
600  socklen_t onsiz = sizeof(on);
601  if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
602  (char *)&on, &onsiz) == -1)
603  {
604  setError(IO_UnspecifiedError, errno);
605  return false;
606  }
607 
608  return d->ipv6only = on;
609 
610 #else
611  // we don't have the constant
612  setError(IO_UnspecifiedError, ENOSYS);
613  return false;
614 #endif
615 }
616 
617 /*
618  * Sets the buffer sizes in this socket
619  * Also, we create or delete the socket notifiers
620  */
621 bool KExtendedSocket::setBufferSize(int rsize, int wsize)
622 {
623  cleanError();
624  if (d->status < created)
625  return false;
626 
627  if (sockfd == -1)
628  return false;
629 
630  if (d->flags & passiveSocket)
631  return false; // no I/O on passive sockets
632 
633  if (rsize < -2)
634  return false;
635 
636  if (wsize < -2)
637  return false;
638 
639  // LOCK BUFFER MUTEX
640 
641  // The input socket notifier is always enabled
642  // That happens because we want to be notified of when the socket gets
643  // closed
644  if (d->qsnIn == NULL)
645  {
646  d->qsnIn = new TQSocketNotifier(sockfd, TQSocketNotifier::Read);
647  TQObject::connect(d->qsnIn, TQT_SIGNAL(activated(int)), this, TQT_SLOT(socketActivityRead()));
648  d->qsnIn->setEnabled(true);
649  }
650 
651  if (rsize == 0 && d->flags & inputBufferedSocket)
652  {
653  // user wants to disable input buffering
654  d->flags &= ~inputBufferedSocket;
655 
656  consumeReadBuffer(readBufferSize(), NULL, true);
657  d->inMaxSize = 0;
658  }
659  else if (rsize != -2)
660  {
661  // enabling input buffering
662  if (rsize)
663  d->flags |= inputBufferedSocket;
664  d->inMaxSize = rsize;
665 
666  if (rsize > 0 && (unsigned)rsize < readBufferSize())
667  // input buffer has more data than the new size; discard
668  consumeReadBuffer(readBufferSize() - rsize, NULL, true);
669 
670  }
671 
672  if (wsize == 0 && d->flags & outputBufferedSocket)
673  {
674  // disabling output buffering
675  d->flags &= ~outputBufferedSocket;
676  if (d->qsnOut && !d->emitWrite)
677  d->qsnOut->setEnabled(false);
678  consumeWriteBuffer(writeBufferSize());
679  d->outMaxSize = 0;
680  }
681  else if (wsize != -2)
682  {
683  // enabling input buffering
684  if (wsize)
685  d->flags |= outputBufferedSocket;
686  d->outMaxSize = wsize;
687 
688  if (wsize > 0 && (unsigned)wsize < writeBufferSize())
689  // output buffer is bigger than it is to become; shrink
690  consumeWriteBuffer(writeBufferSize() - wsize);
691 
692  if (d->qsnOut == NULL)
693  {
694  d->qsnOut = new TQSocketNotifier(sockfd, TQSocketNotifier::Write);
695  TQObject::connect(d->qsnOut, TQT_SIGNAL(activated(int)), this, TQT_SLOT(socketActivityWrite()));
696  // if the class is being created now, there's nothing to write yet
697  // so socketActivityWrite() will get called once and disable
698  // the notifier
699  }
700  }
701 
702  // UNLOCK BUFFER MUTEX
703 
704  setFlags((mode() & ~IO_Raw) | ((d->flags & bufferedSocket) ? 0 : IO_Raw));
705 
706  // check we didn't turn something off we shouldn't
707  if (d->emitWrite && d->qsnOut == NULL)
708  {
709  d->qsnOut = new TQSocketNotifier(sockfd, TQSocketNotifier::Write);
710  TQObject::connect(d->qsnOut, TQT_SIGNAL(activated(int)), this, TQT_SLOT(socketActivityWrite()));
711  }
712 
713  return true;
714 }
715 
716 /*
717  * Finds the local address for this socket
718  * if we have done this already, we return it. Otherwise, we'll have
719  * to find the socket name
720  */
721 const ::TDESocketAddress *KExtendedSocket::localAddress()
722 {
723  if (d->local != NULL)
724  return d->local;
725  if (d->status < bound)
726  return NULL;
727 
728  return d->local = localAddress(sockfd);
729 }
730 
731 /*
732  * Same thing, but for peer address. Which means this does not work on
733  * passiveSocket and that we require to be connected already. Also note that
734  * the behavior on connectionless sockets is not defined here.
735  */
736 const ::TDESocketAddress* KExtendedSocket::peerAddress()
737 {
738  if (d->peer != NULL)
739  return d->peer;
740  if (d->flags & passiveSocket || d->status < connected)
741  return NULL;
742 
743  return d->peer = peerAddress(sockfd);
744 }
745 
746 /*
747  * Perform the lookup on the addresses given
748  */
749 int KExtendedSocket::lookup()
750 {
751  if (startAsyncLookup() != 0)
752  return -1;
753 
754  if (!d->resRemote.wait() || !d->resLocal.wait())
755  {
756  d->status = nothing;
757  return -1;
758  }
759 
760  d->status = lookupDone;
761  if (d->resRemote.error() != KResolver::NoError)
762  return d->resRemote.error();
763  if (d->resLocal.error() != KResolver::NoError)
764  return d->resLocal.error();
765  return 0;
766 }
767 
768 /*
769  * Performs an asynchronous lookup on the given address(es)
770  */
771 int KExtendedSocket::startAsyncLookup()
772 {
773  cleanError();
774  if (d->status > lookupInProgress)
775  return -1;
776  if (d->status == lookupInProgress)
777  // already in progress
778  return 0;
779 
780  /* check socket type flags */
781  int socktype, familyMask, flags;
782  if (!process_flags(d->flags, socktype, familyMask, flags))
783  return -2;
784 
785  // perform the global lookup before
786  if (!d->resRemote.isRunning())
787  {
788  d->resRemote.setFlags(flags);
789  d->resRemote.setFamily(familyMask);
790  d->resRemote.setSocketType(socktype);
791  TQObject::connect(&d->resRemote, TQT_SIGNAL(finished(KResolverResults)),
792  this, TQT_SLOT(dnsResultsReady()));
793 
794  if (!d->resRemote.start())
795  {
796  setError(IO_LookupError, d->resRemote.error());
797  return d->resRemote.error();
798  }
799  }
800 
801  if ((d->flags & passiveSocket) == 0 && !d->resLocal.isRunning())
802  {
803  /* keep flags, but make this passive */
804  flags |= KResolver::Passive;
805  d->resLocal.setFlags(flags);
806  d->resLocal.setFamily(familyMask);
807  d->resLocal.setSocketType(socktype);
808  TQObject::connect(&d->resLocal, TQT_SIGNAL(finished(KResolverResults)),
809  this, TQT_SLOT(dnsResultsReady()));
810 
811  if (!d->resLocal.start())
812  {
813  setError(IO_LookupError, d->resLocal.error());
814  return d->resLocal.error();
815  }
816  }
817 
818  // if we are here, there were no errors
819  if (d->resRemote.isRunning() || d->resLocal.isRunning())
820  d->status = lookupInProgress; // only if there actually is a running lookup
821  else
822  {
823  d->status = lookupDone;
824  emit lookupFinished(d->resRemote.results().count() +
825  d->resLocal.results().count());
826  }
827  return 0;
828 }
829 
830 void KExtendedSocket::cancelAsyncLookup()
831 {
832  cleanError();
833  if (d->status != lookupInProgress)
834  return; // what's to cancel?
835 
836  d->status = nothing;
837  d->resLocal.cancel(false);
838  d->resRemote.cancel(false);
839 }
840 
841 int KExtendedSocket::listen(int N)
842 {
843  cleanError();
844  if ((d->flags & passiveSocket) == 0 || d->status >= listening)
845  return -2;
846  if (d->status < lookupDone)
847  if (lookup() != 0)
848  return -2; // error!
849  if (d->resRemote.error())
850  return -2;
851 
852  // doing the loop:
853  KResolverResults::const_iterator it;
854  KResolverResults res = d->resRemote.results();
855  for (it = res.begin(); it != res.end(); ++it)
856  {
857  //kdDebug(170) << "Trying to listen on " << (*it).address().toString() << endl;
858  sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
859  if (sockfd == -1)
860  {
861  // socket failed creating
862  //kdDebug(170) << "Failed to create: " << perror << endl;
863  continue;
864  }
865 
866  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
867 
868  if (d->addressReusable)
869  setAddressReusable(sockfd, true);
870  setIPv6Only(d->ipv6only);
871  cleanError();
872  if (KSocks::self()->bind(sockfd, (*it).address().address(), (*it).length()) == -1)
873  {
874  //kdDebug(170) << "Failed to bind: " << perror << endl;
875  ::close(sockfd);
876  sockfd = -1;
877  continue;
878  }
879 
880  // ok, socket has bound
881  // kdDebug(170) << "Socket bound: " << sockfd << endl;
882 
883  d->status = bound;
884  break;
885  }
886 
887  if (sockfd == -1)
888  {
889  setError(IO_ListenError, errno);
890  //kdDebug(170) << "Listen error - sockfd is -1 " << endl;
891  return -1;
892  }
893 
894  d->status = bound;
895  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
896 
897  int retval = KSocks::self()->listen(sockfd, N);
898  if (retval == -1)
899  setError(IO_ListenError, errno);
900  else
901  {
902  d->status = listening;
903  d->qsnIn = new TQSocketNotifier(sockfd, TQSocketNotifier::Read);
904  TQObject::connect(d->qsnIn, TQT_SIGNAL(activated(int)), this, TQT_SLOT(socketActivityRead()));
905  }
906  return retval == -1 ? -1 : 0;
907 }
908 
909 int KExtendedSocket::accept(KExtendedSocket *&sock)
910 {
911  cleanError();
912  sock = NULL;
913  if ((d->flags & passiveSocket) == 0 || d->status >= accepting)
914  return -2;
915  if (d->status < listening)
916  if (listen() < 0)
917  return -2; // error!
918 
919  // let's see
920  // if we have a timeout in place, we have to place this socket in non-blocking
921  // mode
922  bool block = blockingMode();
923  struct sockaddr sa;
924  ksocklen_t len = sizeof(sa);
925  sock = NULL;
926 
927  if (d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0)
928  {
929  fd_set set;
930 
931  setBlockingMode(false); // turn on non-blocking
932  FD_ZERO(&set);
933  FD_SET(sockfd, &set);
934 
935  //kdDebug(170).form("Accepting on %d with %d.%06d second timeout\n",
936  // sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
937  // check if there is anything to accept now
938  int retval = KSocks::self()->select(sockfd + 1, &set, NULL, NULL, &d->timeout);
939  if (retval == -1)
940  {
941  setError(IO_UnspecifiedError, errno);
942  return -1; // system error
943  }
944  else if (retval == 0 || !FD_ISSET(sockfd, &set))
945  {
946  setError(IO_TimeOutError, 0);
947  return -3; // timeout
948  }
949  }
950 
951  // it's common stuff here
952  int newfd = KSocks::self()->accept(sockfd, &sa, &len);
953 
954  if (newfd == -1)
955  {
956  setError(IO_AcceptError, errno);
957  kdWarning(170) << "Error accepting on socket " << sockfd << ":"
958  << perror << endl;
959  return -1;
960  }
961 
962  fcntl(newfd, F_SETFD, FD_CLOEXEC);
963 
964  //kdDebug(170).form("Socket %d accepted socket %d\n", sockfd, newfd);
965 
966  setBlockingMode(block); // restore blocking mode
967 
968  sock = new KExtendedSocket;
969  sock->d->status = connected;
970  sock->sockfd = newfd;
971  sock->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
972  sock->setBufferSize(0, 0); // always unbuffered here. User can change that later
973 
974  return 0;
975 }
976 
977 /*
978  * tries to connect
979  *
980  * FIXME!
981  * This function is critical path. It has to be cleaned up and made faster
982  */
983 int KExtendedSocket::connect()
984 {
985  cleanError();
986  if (d->flags & passiveSocket || d->status >= connected)
987  return -2;
988  if (d->status < lookupDone)
989  if (lookup() != 0)
990  return -2;
991 
992  timeval end, now;
993  timeval timeout_copy = d->timeout;
994  // Ok, things are a little tricky here
995  // Let me explain
996  // getaddrinfo() will return several different families of sockets
997  // When we have to bind before we connect, we have to make sure we're binding
998  // and connecting to the same family, or things won't work
999 
1000  KResolverResults remote = d->resRemote.results(),
1001  local = d->resLocal.results();
1002  KResolverResults::const_iterator it, it2;
1003  //kdDebug(170) << "Starting connect to " << host() << '|' << port()
1004  // << ": have " << local.count() << " local entries and "
1005  // << remote.count() << " remote" << endl;
1006 
1007  int ret = -1;
1008  for (it = remote.begin(), it2 = local.begin(); it != remote.end(); ++it)
1009  {
1010  bool doingtimeout = d->timeout.tv_sec > 0 || d->timeout.tv_usec > 0;
1011  if (doingtimeout)
1012  {
1013  gettimeofday(&end, NULL);
1014  end.tv_usec += d->timeout.tv_usec;
1015  end.tv_sec += d->timeout.tv_sec;
1016  if (end.tv_usec > 1000*1000)
1017  {
1018  end.tv_usec -= 1000*1000;
1019  end.tv_sec++;
1020  }
1021  //kdDebug(170).form("Connection with timeout of %d.%06d seconds (ends in %d.%06d)\n",
1022  // d->timeout.tv_sec, d->timeout.tv_usec, end.tv_sec, end.tv_usec);
1023  }
1024 
1025  //kdDebug(170) << "Trying to connect to " << (*it).address().toString() << endl;
1026  if (it2 != local.end())
1027  {
1028 // //kdDebug(170) << "Searching bind socket for family " << p->ai_family << endl;
1029  if ((*it).family() != (*it2).family())
1030  // differing families, scan local for a matching family
1031  for (it2 = local.begin(); it2 != local.end(); ++it2)
1032  if ((*it).family() == (*it2).family())
1033  break;
1034 
1035  if ((*it).family() != (*it2).family())
1036  {
1037  // no matching families for this
1038  //kdDebug(170) << "No matching family for bind socket\n";
1039  it2 = local.begin();
1040  continue;
1041  }
1042 
1043  //kdDebug(170) << "Binding on " << (*it2).address().toString() << " before connect" << endl;
1044  errno = 0;
1045  sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
1046  setError(IO_ConnectError, errno);
1047  if (sockfd == -1)
1048  continue; // cannot create this socket
1049  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1050  if (d->addressReusable)
1051  setAddressReusable(sockfd, true);
1052  setIPv6Only(d->ipv6only);
1053  cleanError();
1054  if (KSocks::self()->bind(sockfd, (*it2).address(), (*it2).length()))
1055  {
1056  //kdDebug(170) << "Bind failed: " << perror << endl;
1057  ::close(sockfd);
1058  sockfd = -1;
1059  continue;
1060  }
1061  }
1062  else
1063  {
1064  // no need to bind, just create
1065  sockfd = ::socket((*it).family(), (*it).socketType(), (*it).protocol());
1066  if (sockfd == -1)
1067  {
1068  setError(IO_ConnectError, errno);
1069  continue;
1070  }
1071  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1072  if (d->addressReusable)
1073  setAddressReusable(sockfd, true);
1074  setIPv6Only(d->ipv6only);
1075  cleanError();
1076  }
1077 
1078 // kdDebug(170) << "Socket " << sockfd << " created" << endl;
1079  d->status = created;
1080 
1081  // check if we have to do timeout
1082  if (doingtimeout && KSocks::self()->hasWorkingAsyncConnect())
1083  {
1084  fd_set rd, wr;
1085 
1086  setBlockingMode(false);
1087 
1088  // now try and connect
1089  if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
1090  {
1091  // this could be EWOULDBLOCK
1092  if (errno != EWOULDBLOCK && errno != EINPROGRESS)
1093  {
1094  //kdDebug(170) << "Socket " << sockfd << " did not connect: " << perror << endl;
1095  setError(IO_ConnectError, errno);
1096  ::close(sockfd);
1097  sockfd = -1;
1098  continue; // nope, another error
1099  }
1100 
1101  FD_ZERO(&rd);
1102  FD_ZERO(&wr);
1103  FD_SET(sockfd, &rd);
1104  FD_SET(sockfd, &wr);
1105 
1106  int retval = KSocks::self()->select(sockfd + 1, &rd, &wr, NULL, &d->timeout);
1107  if (retval == -1)
1108  {
1109  setError(IO_FatalError, errno);
1110  continue; // system error
1111  }
1112  else if (retval == 0)
1113  {
1114  ::close(sockfd);
1115  sockfd = -1;
1116 // kdDebug(170) << "Time out while trying to connect to " <<
1117 // (*it).address().toString() << endl;
1118  setError(IO_TimeOutError, 0);
1119  ret = -3; // time out
1120 
1121  d->timeout.tv_usec += timeout_copy.tv_usec;
1122  d->timeout.tv_sec += timeout_copy.tv_sec;
1123  if (d->timeout.tv_usec < 0)
1124  {
1125  d->timeout.tv_usec += 1000*1000;
1126  d->timeout.tv_sec--;
1127  }
1128 
1129  continue;
1130  }
1131 
1132  // adjust remaining time
1133  gettimeofday(&now, NULL);
1134  d->timeout.tv_sec = end.tv_sec - now.tv_sec;
1135  d->timeout.tv_usec = end.tv_usec - now.tv_usec;
1136  if (d->timeout.tv_usec < 0)
1137  {
1138  d->timeout.tv_usec += 1000*1000;
1139  d->timeout.tv_sec--;
1140  }
1141 // kdDebug(170).form("Socket %d activity; %d.%06d seconds remaining\n",
1142 // sockfd, d->timeout.tv_sec, d->timeout.tv_usec);
1143 
1144  // this means that an event occurred in the socket
1145  int errcode;
1146  socklen_t len = sizeof(errcode);
1147  retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode,
1148  &len);
1149  if (retval == -1 || errcode != 0)
1150  {
1151  // socket did not connect
1152  //kdDebug(170) << "Socket " << sockfd << " did not connect: "
1153  // << strerror(errcode) << endl;
1154  ::close(sockfd);
1155  sockfd = -1;
1156 
1157  // this is HIGHLY UNLIKELY
1158  if (d->timeout.tv_sec == 0 && d->timeout.tv_usec == 0)
1159  {
1160  d->status = lookupDone;
1161  setError(IO_TimeOutError, 0);
1162  return -3; // time out
1163  }
1164 
1165  setError(IO_ConnectError, errcode);
1166  continue;
1167  }
1168  }
1169 
1170  // getting here means it connected
1171  // setBufferSize() takes care of creating the socket notifiers
1172  setBlockingMode(true);
1173  d->status = connected;
1174  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
1175  setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
1176  d->flags & outputBufferedSocket ? -1 : 0);
1177  emit connectionSuccess();
1178 // kdDebug(170) << "Socket " << sockfd << " connected\n";
1179  return 0;
1180  }
1181  else
1182  {
1183  // without timeouts
1184  if (KSocks::self()->connect(sockfd, (*it).address(), (*it).length()) == -1)
1185  {
1186  //kdDebug(170) << "Socket " << sockfd << " to " << (*it).address().toString()
1187  // << " did not connect: " << perror << endl;
1188  setError(IO_ConnectError, errno);
1189  ::close(sockfd);
1190  sockfd = -1;
1191  continue;
1192  }
1193 
1194  d->status = connected;
1195  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
1196  setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
1197  d->flags & outputBufferedSocket ? -1 : 0);
1198  emit connectionSuccess();
1199 // kdDebug(170) << "Socket " << sockfd << " connected\n";
1200  return 0; // it connected
1201  }
1202  }
1203 
1204  // getting here means no socket connected or stuff like that
1205  emit connectionFailed(d->syserror);
1206  //kdDebug(170) << "Failed to connect\n";
1207  return ret;
1208 }
1209 
1210 int KExtendedSocket::startAsyncConnect()
1211 {
1212  cleanError();
1213  // check status
1214  if (d->status >= connected || d->flags & passiveSocket)
1215  return -2;
1216 
1217  if (d->status == connecting)
1218  // already on async connect
1219  return 0;
1220 
1221  // check if we have to do lookup
1222  // if we do, then we'll use asynchronous lookup and use
1223  // signal lookupFinished to do connection
1224  if (d->status < lookupDone)
1225  {
1226  TQObject::connect(this, TQT_SIGNAL(lookupFinished(int)), this, TQT_SLOT(startAsyncConnectSlot()));
1227  if (d->status < lookupInProgress)
1228  return startAsyncLookup();
1229  else
1230  return 0; // we still have to wait
1231  }
1232 
1233  // here we have d->status >= lookupDone and <= connecting
1234  // we can do our connection
1235  d->status = connecting;
1236  TQGuardedPtr<TQObject> p = TQT_TQOBJECT(this);
1237  connectionEvent();
1238  if (!p)
1239  return -1; // We have been deleted.
1240  if (d->status < connecting)
1241  return -1;
1242  return 0;
1243 }
1244 
1245 void KExtendedSocket::cancelAsyncConnect()
1246 {
1247  if (d->status != connecting)
1248  return;
1249 
1250  if (sockfd != -1)
1251  {
1252  // we have a waiting connection
1253  if (d->qsnIn)
1254  delete d->qsnIn;
1255  if (d->qsnOut)
1256  delete d->qsnOut;
1257  d->qsnIn = d->qsnOut = NULL;
1258 
1259  ::close(sockfd);
1260  sockfd = -1;
1261  }
1262  d->status = lookupDone;
1263 }
1264 
1265 bool KExtendedSocket::open(TQ_OpenMode mode)
1266 {
1267  if (mode != IO_Raw | IO_ReadWrite)
1268  return false; // invalid open mode
1269 
1270  if (d->flags & passiveSocket)
1271  return listen() == 0;
1272  else if (d->status < connecting)
1273  return connect() == 0;
1274  else
1275  return false;
1276 }
1277 
1278 void KExtendedSocket::close()
1279 {
1280  if (sockfd == -1 || d->status >= closing)
1281  return; // nothing to close
1282 
1283  // LOCK BUFFER MUTEX
1284  if (d->flags & outputBufferedSocket && writeBufferSize() > 0)
1285  {
1286  // write buffer not empty, go into closing state
1287  d->status = closing;
1288  if (d->qsnIn)
1289  delete d->qsnIn;
1290  d->qsnIn = NULL;
1291  // we keep the outgoing socket notifier because we want
1292  // to send data, but not receive
1293  }
1294  else
1295  {
1296  // nope, write buffer is empty
1297  // we can close now
1298  if (d->qsnIn)
1299  delete d->qsnIn;
1300  if (d->qsnOut)
1301  delete d->qsnOut;
1302  d->qsnIn = d->qsnOut = NULL;
1303 
1304  ::close(sockfd);
1305  d->status = done;
1306  emit closed(readBufferSize() != 0 ? availRead : 0);
1307  }
1308  // UNLOCK BUFFER MUTEX
1309 }
1310 
1311 
1312 void KExtendedSocket::closeNow()
1313 {
1314  if (d->status >= done)
1315  return; // nothing to close
1316 
1317  // close the socket
1318  delete d->qsnIn;
1319  delete d->qsnOut;
1320  d->qsnIn = d->qsnOut = NULL;
1321 
1322  if (d->status > connecting && sockfd != -1)
1323  {
1324  ::close(sockfd);
1325  sockfd = -1;
1326  }
1327  else if (d->status == connecting)
1328  cancelAsyncConnect();
1329  else if (d->status == lookupInProgress)
1330  cancelAsyncLookup();
1331 
1332  d->status = done;
1333 
1334  emit closed(closedNow |
1335  (readBufferSize() != 0 ? availRead : 0) |
1336  (writeBufferSize() != 0 ? dirtyWrite : 0));
1337 }
1338 
1339 void KExtendedSocket::release()
1340 {
1341  // release our hold on the socket
1342  sockfd = -1;
1343  d->status = done;
1344 
1345  d->resRemote.cancel(false);
1346  d->resLocal.cancel(false);
1347 
1348  if (d->local != NULL)
1349  delete d->local;
1350  if (d->peer != NULL)
1351  delete d->peer;
1352 
1353  d->peer = d->local = NULL;
1354 
1355  if (d->qsnIn != NULL)
1356  delete d->qsnIn;
1357  if (d->qsnOut != NULL)
1358  delete d->qsnOut;
1359 
1360  d->qsnIn = d->qsnOut = NULL;
1361 
1362  // now that the socket notificators are done with, we can flush out the buffers
1363  consumeReadBuffer(readBufferSize(), NULL, true);
1364  consumeWriteBuffer(writeBufferSize());
1365 
1366  // don't delete d
1367  // leave that for the destructor
1368 }
1369 
1370 void KExtendedSocket::flush()
1371 {
1372  cleanError();
1373  if (d->status < connected || d->status >= done || d->flags & passiveSocket)
1374  return;
1375 
1376  if (sockfd == -1)
1377  return;
1378 
1379  if ((d->flags & outputBufferedSocket) == 0)
1380  return; // nothing to do
1381 
1382  // LOCK MUTEX
1383 
1384  unsigned written = 0;
1385  unsigned offset = outBufIndex; // this happens only for the first
1386  while (writeBufferSize() - written > 0)
1387  {
1388  // we have to write each output buffer in outBuf
1389  // but since we can have several very small buffers, we can make things
1390  // better by concatenating a few of them into a big buffer
1391  // question is: how big should that buffer be? 16 kB should be enough
1392 
1393  TQByteArray buf(16384);
1394  TQByteArray *a = outBuf.first();
1395  unsigned count = 0;
1396 
1397  while (a && count + (a->size() - offset) <= buf.size())
1398  {
1399  memcpy(buf.data() + count, a->data() + offset, a->size() - offset);
1400  count += a->size() - offset;
1401  offset = 0;
1402  a = outBuf.next();
1403  }
1404 
1405  // see if we can still fit more
1406  if (a && count < buf.size())
1407  {
1408  // getting here means this buffer (a) is larger than
1409  // (buf.size() - count) (even for count == 0).
1410  memcpy(buf.data() + count, a->data() + offset, buf.size() - count);
1411  offset += buf.size() - count;
1412  count = buf.size();
1413  }
1414 
1415  // now try to write those bytes
1416  int wrote = KSocks::self()->write(sockfd, buf, count);
1417 
1418  if (wrote == -1)
1419  {
1420  // could be EAGAIN (EWOULDBLOCK)
1421  setError(IO_WriteError, errno);
1422  break;
1423  }
1424  written += wrote;
1425 
1426  if ((unsigned)wrote != count)
1427  break;
1428  }
1429  if (written)
1430  {
1431  consumeWriteBuffer(written);
1432  emit bytesWritten(written);
1433  }
1434 
1435  // UNLOCK MUTEX
1436 }
1437 
1438 
1439 TQT_TQIO_LONG KExtendedSocket::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
1440 {
1441  cleanError();
1442  if (d->status < connected || d->flags & passiveSocket)
1443  return -2;
1444 
1445  int retval;
1446 
1447  if ((d->flags & inputBufferedSocket) == 0)
1448  {
1449  // we aren't buffering this socket, so just pass along
1450  // the call to the real read method
1451 
1452  if (sockfd == -1)
1453  return -2;
1454  if (data)
1455  retval = KSocks::self()->read(sockfd, data, maxlen);
1456  else
1457  retval = skipData(sockfd, maxlen);
1458  if (retval == -1)
1459  setError(IO_ReadError, errno);
1460  }
1461  else
1462  {
1463  // this socket is being buffered. So read from the buffer
1464 
1465  // LOCK BUFFER MUTEX
1466 
1467  retval = consumeReadBuffer(maxlen, data);
1468  if (retval == 0)
1469  {
1470  // consumeReadBuffer returns 0 only if the buffer is
1471  // empty
1472  if (sockfd == -1)
1473  return 0; // buffer is clear now, indicate EOF
1474  setError(IO_ReadError, EWOULDBLOCK);
1475  retval = -1;
1476  }
1477 
1478  // UNLOCK BUFFER MUTEX
1479 
1480  }
1481  return retval;
1482 }
1483 
1484 TQT_TQIO_LONG KExtendedSocket::tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
1485 {
1486  cleanError();
1487  if (d->status < connected || d->status >= closing || d->flags & passiveSocket)
1488  return -2;
1489  if (sockfd == -1)
1490  return -2;
1491 
1492  if (len == 0)
1493  return 0; // what's to write?
1494 
1495  int retval;
1496 
1497  if ((d->flags & outputBufferedSocket) == 0)
1498  {
1499  // socket not buffered. Just call write
1500  retval = KSocks::self()->write(sockfd, data, len);
1501  if (retval == -1)
1502  setError(IO_WriteError, errno);
1503  else
1504  emit bytesWritten(retval);
1505  }
1506  else
1507  {
1508  // socket is buffered. Feed the write buffer
1509 
1510  // LOCK BUFFER MUTEX
1511 
1512  unsigned wsize = writeBufferSize();
1513  if (d->outMaxSize == (int)wsize) // (int) to get rid of annoying warning
1514  {
1515  // buffer is full!
1516  setError(IO_WriteError, EWOULDBLOCK);
1517  retval = -1;
1518  }
1519  else
1520  {
1521  if (d->outMaxSize != -1 && wsize + len > (unsigned)d->outMaxSize)
1522  // we cannot write all data. Write just as much as to fill the buffer
1523  len = d->outMaxSize - wsize;
1524 
1525  // len > 0 here
1526  retval = feedWriteBuffer(len, data);
1527  if (wsize == 0 || d->emitWrite)
1528  // buffer was empty, which means that the notifier is probably disabled
1529  d->qsnOut->setEnabled(true);
1530  }
1531 
1532  // UNLOCK BUFFER MUTEX
1533  }
1534 
1535  return retval;
1536 }
1537 
1538 int KExtendedSocket::peekBlock(char *data, uint maxlen)
1539 {
1540  if (d->status < connected || d->flags & passiveSocket)
1541  return -2;
1542  if (sockfd == -1)
1543  return -2;
1544 
1545  // need to LOCK MUTEX around this call...
1546 
1547  if (d->flags & inputBufferedSocket)
1548  return consumeReadBuffer(maxlen, data, false);
1549 
1550  return 0;
1551 }
1552 
1553 int KExtendedSocket::unreadBlock(const char *, uint)
1554 {
1555  // Always return -1, indicating this is not supported
1556  setError(IO_ReadError, ENOSYS);
1557  return -1;
1558 }
1559 
1560 #ifdef USE_QT3
1561 int KExtendedSocket::bytesAvailable() const
1562 #endif // USE_QT3
1563 #ifdef USE_QT4
1564 qint64 KExtendedSocket::bytesAvailable() const
1565 #endif // USE_QT4
1566 {
1567  if (d->status < connected || d->flags & passiveSocket)
1568  return -2;
1569 
1570  // as of now, we don't do any extra processing
1571  // we only work in input-buffered sockets
1572  if (d->flags & inputBufferedSocket)
1573  return TDEBufferedIO::bytesAvailable();
1574 
1575  return 0; // TODO: FIONREAD ioctl
1576 }
1577 
1578 int KExtendedSocket::waitForMore(int msecs)
1579 {
1580  cleanError();
1581  if (d->flags & passiveSocket || d->status < connected || d->status >= closing)
1582  return -2;
1583  if (sockfd == -1)
1584  return -2;
1585 
1586  fd_set rd;
1587  FD_ZERO(&rd);
1588  FD_SET(sockfd, &rd);
1589  timeval tv;
1590  tv.tv_sec = msecs / 1000;
1591  tv.tv_usec = (msecs % 1000) * 1000;
1592 
1593  int retval = KSocks::self()->select(sockfd + 1, &rd, NULL, NULL, &tv);
1594  if (retval == -1)
1595  {
1596  setError(IO_FatalError, errno);
1597  return -1;
1598  }
1599  else if (retval != 0)
1600  socketActivityRead(); // do read processing
1601 
1602  return bytesAvailable();
1603 }
1604 
1605 int KExtendedSocket::getch()
1606 {
1607  unsigned char c;
1608  int retval;
1609  retval = tqreadBlock((char*)&c, sizeof(c));
1610 
1611  if (retval < 0)
1612  return retval;
1613  return c;
1614 }
1615 
1616 int KExtendedSocket::putch(int ch)
1617 {
1618  unsigned char c = (char)ch;
1619  return tqwriteBlock((char*)&c, sizeof(c));
1620 }
1621 
1622 // sets the emission of the readyRead signal
1623 void KExtendedSocket::enableRead(bool enable)
1624 {
1625  // check if we can disable the socket notifier
1626  // saves us a few cycles
1627  // this is so because in buffering mode, we rely on these signals
1628  // being emitted to do our I/O. We couldn't disable them here
1629  if (!enable && (d->flags & inputBufferedSocket) == 0 && d->qsnIn)
1630  d->qsnIn->setEnabled(false);
1631  else if (enable && d->qsnIn)
1632  // we can enable it always
1633  d->qsnIn->setEnabled(true);
1634  d->emitRead = enable;
1635 }
1636 
1637 // sets the emission of the readyWrite signal
1638 void KExtendedSocket::enableWrite(bool enable)
1639 {
1640  // same thing as above
1641  if (!enable && (d->flags & outputBufferedSocket) == 0 && d->qsnOut)
1642  d->qsnOut->setEnabled(false);
1643  else if (enable && d->qsnOut)
1644  // we can enable it always
1645  d->qsnOut->setEnabled(true);
1646  d->emitWrite = enable;
1647 }
1648 
1649 // protected slot
1650 // this is connected to d->qsnIn::activated(int)
1651 void KExtendedSocket::socketActivityRead()
1652 {
1653  if (d->flags & passiveSocket)
1654  {
1655  emit readyAccept();
1656  return;
1657  }
1658  if (d->status == connecting)
1659  {
1660  connectionEvent();
1661  return;
1662  }
1663  if (d->status != connected)
1664  return;
1665 
1666  // do we need to do I/O here?
1667  if (d->flags & inputBufferedSocket)
1668  {
1669  // aye. Do read from the socket and feed our buffer
1670  TQByteArray a;
1671  char buf[1024];
1672  int len, totalread = 0;
1673 
1674  // LOCK MUTEX
1675 
1676  unsigned cursize = readBufferSize();
1677 
1678  if (d->inMaxSize == -1 || cursize < (unsigned)d->inMaxSize)
1679  {
1680  do
1681  {
1682  // check that we can read that many bytes
1683  if (d->inMaxSize != -1 && d->inMaxSize - (cursize + totalread) < sizeof(buf))
1684  // no, that would overrun the buffer
1685  // note that this will also make us exit the loop
1686  len = d->inMaxSize - (cursize + totalread);
1687  else
1688  len = sizeof(buf);
1689 
1690  len = KSocks::self()->read(sockfd, buf, len);
1691  if (len > 0)
1692  {
1693  // normal read operation
1694  a.resize(a.size() + len);
1695  memcpy(a.data() + totalread, buf, len);
1696  totalread += len; // totalread == a.size() now
1697  }
1698  else if (len == 0)
1699  {
1700  // EOF condition here
1701  ::close(sockfd);
1702  sockfd = -1; // we're closed
1703  d->qsnIn->deleteLater();
1704  delete d->qsnOut;
1705  d->qsnIn = d->qsnOut = NULL;
1706  d->status = done;
1707  emit closed(involuntary |
1708  (readBufferSize() ? availRead : 0) |
1709  (writeBufferSize() ? dirtyWrite : 0));
1710  return;
1711  }
1712  else
1713  {
1714  // error!
1715  setError(IO_ReadError, errno);
1716  return;
1717  }
1718  // will loop only for normal read operations
1719  }
1720  while (len == sizeof(buf));
1721 
1722  feedReadBuffer(a.size(), a.data());
1723  }
1724 
1725  // UNLOCK MUTEX
1726  }
1727  else
1728  {
1729  // No input buffering, but the notifier fired
1730  // That means that either there is data to be read or that the
1731  // socket closed.
1732 
1733  // try to read one byte. If we can't, then the socket got closed
1734 
1735  char c;
1736  int len = KSocks::self()->recv(sockfd, &c, sizeof(c), MSG_PEEK);
1737  if (len == 0)
1738  {
1739  // yes, it's an EOF condition
1740  d->qsnIn->setEnabled(false);
1741  ::close(sockfd);
1742  sockfd = -1;
1743  d->status = done;
1744  emit closed(involuntary);
1745  return;
1746  }
1747  }
1748 
1749  if (d->emitRead)
1750  emit readyRead();
1751 }
1752 
1753 void KExtendedSocket::socketActivityWrite()
1754 {
1755  if (d->flags & passiveSocket)
1756  return;
1757  if (d->status == connecting)
1758  {
1759  connectionEvent();
1760  return;
1761  }
1762  if (d->status != connected && d->status != closing)
1763  return;
1764 
1765  flush();
1766 
1767  bool empty = writeBufferSize() == 0;
1768 
1769  if (d->emitWrite && empty)
1770  emit readyWrite();
1771  else if (!d->emitWrite)
1772  {
1773  // check if we can disable the notifier
1774  d->qsnOut->setEnabled(!empty); // leave it enabled only if we have more data to send
1775  }
1776  if (d->status == closing && empty)
1777  {
1778  // done sending the missing data!
1779  d->status = done;
1780 
1781  delete d->qsnOut;
1782  ::close(sockfd);
1783 
1784  d->qsnOut = NULL;
1785  sockfd = -1;
1786  emit closed(delayed | (readBufferSize() ? availRead : 0));
1787  }
1788 }
1789 
1790 // this function is called whenever we have a "connection event"
1791 // that is, whenever our asynchronously connecting socket throws
1792 // an event
1793 void KExtendedSocket::connectionEvent()
1794 {
1795  if (d->status != connecting)
1796  return; // move along. There's nothing to see here
1797 
1798  KResolverResults remote = d->resRemote.results();
1799  if (remote.count() == 0)
1800  {
1801  // We have a problem! Abort?
1802  kdError(170) << "KExtendedSocket::connectionEvent() called but no data available!\n";
1803  return;
1804  }
1805 
1806  int errcode = 0;
1807 
1808  if (sockfd != -1)
1809  {
1810  // our socket has activity
1811  // find out what it was
1812  int retval;
1813  socklen_t len = sizeof(errcode);
1814  retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
1815 
1816  if (retval == -1 || errcode != 0)
1817  {
1818  // socket activity and there was error?
1819  // that means the socket probably did not connect
1820  if (d->qsnIn)
1821  delete d->qsnIn;
1822  if (d->qsnOut)
1823  delete d->qsnOut;
1824  ::close(sockfd);
1825 
1826  sockfd = -1;
1827  d->qsnIn = d->qsnOut = NULL;
1828  d->current++;
1829  setError(IO_ConnectError, errcode);
1830  }
1831  else
1832  {
1833  // hmm, socket activity and there was no error?
1834  // that means it connected
1835  // YAY!
1836  cleanError();
1837  d->status = connected;
1838  setBlockingMode(true);
1839  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
1840  setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
1841  d->flags & outputBufferedSocket ? -1 : 0);
1842  emit connectionSuccess();
1843  return;
1844  }
1845  }
1846 
1847  // ok, we have to try something here
1848  // and sockfd == -1
1849  KResolverResults local = d->resLocal.results();
1850  unsigned localidx = 0;
1851  for ( ; d->current < remote.count(); d->current++)
1852  {
1853  // same code as in connect()
1854  if (local.count() != 0)
1855  {
1856  // scan bindres for a local resuls family
1857  for (localidx = 0; localidx < local.count(); localidx++)
1858  if (remote[d->current].family() == local[localidx].family())
1859  break;
1860 
1861  if (remote[d->current].family() != local[localidx].family())
1862  {
1863  // no matching families for this
1864  continue;
1865  }
1866 
1867  errno = 0;
1868  sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
1869  remote[d->current].protocol());
1870  setError(IO_ConnectError, errno);
1871  errcode = errno;
1872  if (sockfd == -1)
1873  continue; // cannot create this socket
1874  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1875  if (d->addressReusable)
1876  setAddressReusable(sockfd, true);
1877  setIPv6Only(d->ipv6only);
1878  cleanError();
1879  if (KSocks::self()->bind(sockfd, local[localidx].address(),
1880  local[localidx].length()) == -1)
1881  {
1882  ::close(sockfd);
1883  sockfd = -1;
1884  continue;
1885  }
1886  }
1887  else
1888  {
1889  // no need to bind, just create
1890  sockfd = ::socket(remote[d->current].family(), remote[d->current].socketType(),
1891  remote[d->current].protocol());
1892  if (sockfd == -1)
1893  {
1894  setError(IO_ConnectError, errno);
1895  errcode = errno;
1896  continue;
1897  }
1898  fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1899  if (d->addressReusable)
1900  setAddressReusable(sockfd, true);
1901  setIPv6Only(d->ipv6only);
1902  cleanError();
1903  }
1904 
1905  if (KSocks::self()->hasWorkingAsyncConnect())
1906  setBlockingMode(false);
1907  if (KSocks::self()->connect(sockfd, remote[d->current].address(),
1908  remote[d->current].length()) == -1)
1909  {
1910  if (errno != EWOULDBLOCK && errno != EINPROGRESS)
1911  {
1912  setError(IO_ConnectError, errno);
1913  ::close(sockfd);
1914  sockfd = -1;
1915  errcode = errno;
1916  continue;
1917  }
1918 
1919  // error here is either EWOULDBLOCK or EINPROGRESS
1920  // so, it is a good condition
1921  d->qsnIn = new TQSocketNotifier(sockfd, TQSocketNotifier::Read);
1922  TQObject::connect(d->qsnIn, TQT_SIGNAL(activated(int)), this, TQT_SLOT(socketActivityRead()));
1923  d->qsnOut = new TQSocketNotifier(sockfd, TQSocketNotifier::Write);
1924  TQObject::connect(d->qsnOut, TQT_SIGNAL(activated(int)), this, TQT_SLOT(socketActivityWrite()));
1925 
1926  // ok, let the Qt event loop do the selecting for us
1927  return;
1928  }
1929 
1930  // eh, what?
1931  // the non-blocking socket returned valid connection?
1932  // already?
1933  // I suppose that could happen...
1934  cleanError();
1935  d->status = connected;
1936  setBlockingMode(true);
1937  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
1938  setBufferSize(d->flags & inputBufferedSocket ? -1 : 0,
1939  d->flags & outputBufferedSocket ? -1 : 0);
1940  emit connectionSuccess();
1941  return;
1942  }
1943 
1944  // if we got here, it means that there are no more options to connect
1945  d->status = lookupDone; // go back
1946  emit connectionFailed(errcode);
1947 }
1948 
1949 void KExtendedSocket::dnsResultsReady()
1950 {
1951  // check that this function was called in a valid state
1952  if (d->status != lookupInProgress)
1953  return;
1954 
1955  // valid state. Are results fully ready?
1956  if (d->resRemote.isRunning() || d->resLocal.isRunning())
1957  // no, still waiting for answer in one of the lookups
1958  return;
1959 
1960  // ok, we have all results
1961  // count how many results we have
1962  int n = d->resRemote.results().count() + d->resLocal.results().count();
1963 
1964  if (n)
1965  {
1966  d->status = lookupDone;
1967  cleanError();
1968  }
1969  else
1970  {
1971  d->status = nothing;
1972  setError(IO_LookupError, KResolver::NoName);
1973  }
1974 
1975  emit lookupFinished(n);
1976 
1977  return;
1978 }
1979 
1980 void KExtendedSocket::startAsyncConnectSlot()
1981 {
1982  TQObject::disconnect(this, TQT_SIGNAL(lookupFinished(int)), this, TQT_SLOT(startAsyncConnectSlot()));
1983 
1984  if (d->status == lookupDone)
1985  startAsyncConnect();
1986 }
1987 
1988 int KExtendedSocket::resolve(sockaddr *sock, ksocklen_t len, TQString &host,
1989  TQString &port, int flags)
1990 {
1991  kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
1992 
1993  int err;
1994  char h[NI_MAXHOST], s[NI_MAXSERV];
1995 
1996  h[0] = s[0] = '\0';
1997 
1998  err = getnameinfo(sock, len, h, sizeof(h) - 1, s, sizeof(s) - 1, flags);
1999  host = TQString::fromUtf8(h);
2000  port = TQString::fromUtf8(s);
2001 
2002  return err;
2003 }
2004 
2005 int KExtendedSocket::resolve(::TDESocketAddress *sock, TQString &host, TQString &port,
2006  int flags)
2007 {
2008  return resolve(sock->data, sock->datasize, host, port, flags);
2009 }
2010 
2011 TQPtrList<KAddressInfo> KExtendedSocket::lookup(const TQString& host, const TQString& port,
2012  int userflags, int *error)
2013 {
2014  kdDebug(170) << "Deprecated function called:" << k_funcinfo << endl;
2015 
2016  int socktype, familyMask, flags;
2017  unsigned i;
2018  TQPtrList<KAddressInfo> l;
2019 
2020  /* check socket type flags */
2021  if (!process_flags(userflags, socktype, familyMask, flags))
2022  return l;
2023 
2024 // kdDebug(170) << "Performing lookup on " << host << "|" << port << endl;
2025  KResolverResults res = KResolver::resolve(host, port, flags, familyMask);
2026  if (res.error())
2027  {
2028  if (error)
2029  *error = res.error();
2030  return l;
2031  }
2032 
2033  for (i = 0; i < res.count(); i++)
2034  {
2035  KAddressInfo *ai = new KAddressInfo();
2036 
2037  // I should have known that using addrinfo was going to come
2038  // and bite me back some day...
2039  ai->ai = (addrinfo *) malloc(sizeof(addrinfo));
2040  memset(ai->ai, 0, sizeof(addrinfo));
2041 
2042  ai->ai->ai_family = res[i].family();
2043  ai->ai->ai_socktype = res[i].socketType();
2044  ai->ai->ai_protocol = res[i].protocol();
2045  TQString canon = res[i].canonicalName();
2046  if (!canon.isEmpty())
2047  {
2048  ai->ai->ai_canonname = (char *) malloc(canon.length()+1);
2049  strcpy(ai->ai->ai_canonname, canon.ascii()); // ASCII here is intentional
2050  }
2051  if ((ai->ai->ai_addrlen = res[i].length()))
2052  {
2053  ai->ai->ai_addr = (struct sockaddr *) malloc(res[i].length());
2054  memcpy(ai->ai->ai_addr, res[i].address().address(), res[i].length());
2055  }
2056  else
2057  {
2058  ai->ai->ai_addr = 0;
2059  }
2060 
2061  ai->addr = ::TDESocketAddress::newAddress(ai->ai->ai_addr, ai->ai->ai_addrlen);
2062 
2063  l.append(ai);
2064  }
2065 
2066  if ( error )
2067  *error = 0; // all is fine!
2068 
2069  return l;
2070 }
2071 
2072 ::TDESocketAddress *KExtendedSocket::localAddress(int fd)
2073 {
2074  ::TDESocketAddress *local;
2075  struct sockaddr static_sa, *sa = &static_sa;
2076  ksocklen_t len = sizeof(static_sa);
2077 
2078  /* find out the socket length, in advance
2079  * we use a sockaddr allocated on the heap just not to pass down
2080  * a NULL pointer to the first call. Some systems are reported to
2081  * set len to 0 if we pass NULL as the sockaddr */
2082  if (KSocks::self()->getsockname(fd, sa, &len) == -1)
2083  return NULL; // error!
2084 
2085  /* was it enough? */
2086  if (len > sizeof(static_sa)
2087 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2088  || sa->sa_len > sizeof(static_sa)
2089 #endif
2090  )
2091  {
2092  /* nope, malloc a new socket with the proper size */
2093 
2094 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2095  if (sa->sa_len != len)
2096  len = sa->sa_len;
2097 #endif
2098 
2099  sa = (sockaddr*)malloc(len);
2100  if (sa == NULL)
2101  return NULL; // out of memory
2102 
2103  if (KSocks::self()->getsockname(fd, sa, &len) == -1)
2104  {
2105  free(sa);
2106  return NULL;
2107  }
2108 
2109  local = ::TDESocketAddress::newAddress(sa, len);
2110  free(sa);
2111  }
2112  else
2113  local = ::TDESocketAddress::newAddress(sa, len);
2114 
2115  return local;
2116 }
2117 
2118 /* This is exactly the same code as localAddress, except
2119  * we call getpeername here */
2120 ::TDESocketAddress *KExtendedSocket::peerAddress(int fd)
2121 {
2122  ::TDESocketAddress *peer;
2123  struct sockaddr static_sa, *sa = &static_sa;
2124  ksocklen_t len = sizeof(static_sa);
2125 
2126  /* find out the socket length, in advance
2127  * we use a sockaddr allocated on the heap just not to pass down
2128  * a NULL pointer to the first call. Some systems are reported to
2129  * set len to 0 if we pass NULL as the sockaddr */
2130  if (KSocks::self()->getpeername(fd, sa, &len) == -1)
2131  return NULL; // error!
2132 
2133  /* was it enough? */
2134  if (len > sizeof(static_sa)
2135 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2136  || sa->sa_len > sizeof(static_sa)
2137 #endif
2138  )
2139  {
2140  /* nope, malloc a new socket with the proper size */
2141 
2142 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2143  if (sa->sa_len != len)
2144  len = sa->sa_len;
2145 #endif
2146 
2147  sa = (sockaddr*)malloc(len);
2148  if (sa == NULL)
2149  return NULL; // out of memory
2150 
2151  if (KSocks::self()->getpeername(fd, sa, &len) == -1)
2152  {
2153  free(sa);
2154  return NULL;
2155  }
2156 
2157  peer = ::TDESocketAddress::newAddress(sa, len);
2158  free(sa);
2159  }
2160  else
2161  peer = ::TDESocketAddress::newAddress(sa, len);
2162 
2163  return peer;
2164 }
2165 
2166 TQString KExtendedSocket::strError(int code, int syserr)
2167 {
2168  const char * msg;
2169  if (code == IO_LookupError)
2170  msg = gai_strerror(syserr);
2171  else
2172  msg = strerror(syserr);
2173 
2174  return TQString::fromLocal8Bit(msg);
2175 }
2176 
2177 
2178 TQSocketNotifier *KExtendedSocket::readNotifier() { return d->qsnIn; }
2179 TQSocketNotifier *KExtendedSocket::writeNotifier() { return d->qsnOut; }
2180 
2181 /*
2182  * class KAddressInfo
2183  */
2184 
2185 #if 0
2186 KAddressInfo::KAddressInfo(addrinfo *p)
2187 {
2188  ai = (addrinfo *) malloc(sizeof(addrinfo));
2189  memcpy(ai, p, sizeof(addrinfo));
2190  ai->ai_next = NULL;
2191  if (p->ai_canonname)
2192  {
2193  ai->ai_canonname = (char *) malloc(strlen(p->ai_canonname)+1);
2194  strcpy(ai->ai_canonname, p->ai_canonname);
2195  }
2196  if (p->ai_addr && p->ai_addrlen)
2197  {
2198  ai->ai_addr = (struct sockaddr *) malloc(p->ai_addrlen);
2199  memcpy(ai->ai_addr, p->ai_addr, p->ai_addrlen);
2200  }
2201  else
2202  {
2203  ai->ai_addr = 0;
2204  ai->ai_addrlen = 0;
2205  }
2206 
2207  addr = ::TDESocketAddress::newAddress(ai->ai_addr, ai->ai_addrlen);
2208 }
2209 #endif
2210 KAddressInfo::~KAddressInfo()
2211 {
2212  if (ai && ai->ai_canonname)
2213  free(ai->ai_canonname);
2214 
2215  if (ai && ai->ai_addr)
2216  free(ai->ai_addr);
2217 
2218  if (ai)
2219  free(ai);
2220  delete addr;
2221 }
2222 
2223 int KAddressInfo::flags() const
2224 {
2225  return ai->ai_flags;
2226 }
2227 
2228 int KAddressInfo::family() const
2229 {
2230  return ai->ai_family;
2231 }
2232 
2233 int KAddressInfo::socktype() const
2234 {
2235  return ai->ai_socktype;
2236 }
2237 
2238 int KAddressInfo::protocol() const
2239 {
2240  return ai->ai_protocol;
2241 }
2242 
2243 const char* KAddressInfo::canonname() const
2244 {
2245  return ai->ai_canonname;
2246 }
2247 
2248 void KExtendedSocket::virtual_hook( int id, void* data )
2249 { TDEBufferedIO::virtual_hook( id, data ); }
2250 
2251 #include "kextsock.moc"
KExtendedSocket::unsetBindAddress
bool unsetBindAddress()
Unsets the bind address for the socket.
Definition: kextsock.cpp:424
KExtendedSocket::setSocketFlags
int setSocketFlags(int flags)
Sets the given flags.
Definition: kextsock.cpp:264
KSocks::listen
int listen(int s, int backlog)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:580
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:423
KAsyncIO::readyWrite
void readyWrite()
This signal gets sent when the device is ready for writing.
TDESocketAddress::newAddress
static TDESocketAddress * newAddress(const struct sockaddr *sa, ksocklen_t size)
Creates a new TDESocketAddress or descendant class from given raw socket address. ...
Definition: ksockaddr.cpp:123
KExtendedSocket::enableRead
virtual void enableRead(bool enable)
Toggles the emission of the readyRead signal.
Definition: kextsock.cpp:1623
KExtendedSocket::release
virtual void release()
Releases the socket and anything we have holding on it.
Definition: kextsock.cpp:1339
TDEBufferedIO::readBufferSize
virtual unsigned readBufferSize() const
Returns the number of bytes in the read buffer.
Definition: kbufferedio.cpp:280
KExtendedSocket::strError
static TQString strError(int code, int syserr)
Returns the representing text of this error code.
Definition: kextsock.cpp:2166
KExtendedSocket::unreadBlock
virtual int unreadBlock(const char *data, uint len)
Reimplementation of unreadBlock() method.
Definition: kextsock.cpp:1553
KExtendedSocket::closeNow
virtual void closeNow()
Closes the socket now, discarding the contents of the write buffer, if any.
Definition: kextsock.cpp:1312
KNetwork::KResolver
Name and service resolution class.
Definition: kresolver.h:295
KExtendedSocket::lookupFinished
void lookupFinished(int count)
This signal is emitted whenever an asynchronous lookup process is done.
KAddressInfo::socktype
int socktype() const KDE_DEPRECATED
Returns the socket type of the address info (see getaddrinfo(3)).
Definition: kextsock.cpp:2233
KExtendedSocket::open
virtual bool open(TQ_OpenMode mode=(TQ_OpenMode)(IO_Raw|IO_ReadWrite))
Implementation of TQIODevice::open() pure virtual function.
Definition: kextsock.cpp:1265
KExtendedSocket::flush
virtual void flush()
Flushes the socket buffer.
Definition: kextsock.cpp:1370
KExtendedSocket::unsetBindPort
bool unsetBindPort()
Unsets the bind port/service.
Definition: kextsock.cpp:392
KNetwork::KResolverResults
Name and service resolution results.
Definition: kresolver.h:197
KExtendedSocket::setBlockingMode
bool setBlockingMode(bool enable)
Sets/unsets blocking mode for the socket.
Definition: kextsock.cpp:453
TDEBufferedIO::outBuf
TQPtrList< TQByteArray > outBuf
For an explanation on how this buffer work, please refer to the comments at the top of kbufferedio...
Definition: kbufferedio.h:229
TDEBufferedIO::feedReadBuffer
virtual unsigned feedReadBuffer(unsigned nbytes, const char *buffer, bool atBeginning=false)
Feeds data into the input buffer.
Definition: kbufferedio.cpp:253
KSocks::self
static KSocks * self()
Return an instance of class KSocks *.
Definition: ksocks.cpp:212
KExtendedSocket::connectionFailed
void connectionFailed(int error)
This signal is emitted whenever our asynchronous connection attempt failed to all hosts listed...
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36
KExtendedSocket::setBindPort
bool setBindPort(int port)
Sets the port/service to which we will bind before connecting.
Definition: kextsock.cpp:375
KExtendedSocket::setIPv6Only
bool setIPv6Only(bool enable)
Sets/unsets the v6-only flag for IPv6 sockets.
Definition: kextsock.cpp:559
KExtendedSocket::setBufferSize
virtual bool setBufferSize(int rsize, int wsize=-2)
Sets the buffer sizes for this socket.
Definition: kextsock.cpp:621
KExtendedSocket::unsetBindHost
bool unsetBindHost()
Unsets the bind hostname.
Definition: kextsock.cpp:358
KExtendedSocket::timeout
timeval timeout() const
Returns the timeout value for the connection.
Definition: kextsock.cpp:445
KAddressInfo
Definition: kextsock.h:1042
KExtendedSocket::accept
virtual int accept(KExtendedSocket *&sock)
Accepts an incoming connection from the socket.
Definition: kextsock.cpp:909
KAddressInfo::protocol
int protocol() const KDE_DEPRECATED
Returns the protocol of the address info (see getaddrinfo(3)).
Definition: kextsock.cpp:2238
KExtendedSocket::setPort
bool setPort(int port)
Sets the port/service.
Definition: kextsock.cpp:302
KExtendedSocket::waitForMore
virtual int waitForMore(int msec)
Returns the number of available bytes yet to be read via readBlock and family of functions.
Definition: kextsock.cpp:1578
KExtendedSocket::tqreadBlock
virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
Reads a block of data from the socket.
Definition: kextsock.cpp:1439
KExtendedSocket::connect
virtual int connect()
Attempts to connect to the remote host.
Definition: kextsock.cpp:983
KExtendedSocket::cancelAsyncConnect
virtual void cancelAsyncConnect()
Cancels any on-going asynchronous connection attempt.
Definition: kextsock.cpp:1245
KExtendedSocket::systemError
int systemError() const
Returns the related system error code Except for IO_LookupError errors, these are codes found in errn...
Definition: kextsock.cpp:255
KExtendedSocket::peekBlock
virtual int peekBlock(char *data, uint maxlen)
Peeks at a block of data from the socket.
Definition: kextsock.cpp:1538
KExtendedSocket::KExtendedSocket
KExtendedSocket()
Creates an empty KExtendedSocket.
Definition: kextsock.cpp:186
KExtendedSocket::resolve
static int resolve(sockaddr *sock, ksocklen_t len, TQString &host, TQString &port, int flags=0) KDE_DEPRECATED
Performs resolution on the given socket address.
Definition: kextsock.cpp:1988
TDEBufferedIO::writeBufferSize
virtual unsigned writeBufferSize() const
Returns the number of bytes in the write buffer.
Definition: kbufferedio.cpp:293
KExtendedSocket::putch
virtual int putch(int ch)
Writes a single character (unsigned char) to the stream.
Definition: kextsock.cpp:1616
KSocks::accept
int accept(int s, sockaddr *addr, ksocklen_t *addrlen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:560
KAddressInfo::family
int family() const KDE_DEPRECATED
Returns the family of the address info (see getaddrinfo(3)).
Definition: kextsock.cpp:2228
KSocks::getsockname
int getsockname(int s, sockaddr *name, ksocklen_t *namelen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:536
KExtendedSocket::lookup
virtual int lookup()
Performs lookup on the addresses we were given before.
Definition: kextsock.cpp:749
KExtendedSocket::bindHost
TQString bindHost() const
Returns the hostname to which the socket will be/is bound.
Definition: kextsock.cpp:366
KExtendedSocket::isIPv6Only
bool isIPv6Only()
Returns the status of the v6-only flag for IPv6 sockets.
Definition: kextsock.cpp:591
KExtendedSocket::tqwriteBlock
virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
Writes a block of data to the socket.
Definition: kextsock.cpp:1484
TDEBufferedIO::bytesWritten
void bytesWritten(int nbytes)
This signal gets sent whenever bytes are written from the buffer.
KExtendedSocket::setHost
bool setHost(const TQString &host)
Sets the hostname to the given value.
Definition: kextsock.cpp:281
KExtendedSocket::port
TQString port() const
Returns the port/service.
Definition: kextsock.cpp:319
KExtendedSocket::setBindHost
bool setBindHost(const TQString &host)
Sets the hostname to which we will bind locally before connecting.
Definition: kextsock.cpp:345
TDEBufferedIO::closed
void closed(int state)
This signal gets sent when the stream is closed.
KExtendedSocket::enableWrite
virtual void enableWrite(bool enable)
Toggles the emission of the readyWrite signal.
Definition: kextsock.cpp:1638
KExtendedSocket::peerAddress
const ::TDESocketAddress * peerAddress()
Returns the peer socket address.
Definition: kextsock.cpp:736
KSocks::select
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:572
KExtendedSocket::setTimeout
bool setTimeout(int secs, int usecs=0)
Sets the timeout value for the connection (if this is not passiveSocket) or acception (if it is)...
Definition: kextsock.cpp:432
KExtendedSocket::bindPort
TQString bindPort() const
Returns the service to which the socket will be/is bound.
Definition: kextsock.cpp:400
KExtendedSocket::addressReusable
bool addressReusable()
Returns whether this socket's address can be reused.
Definition: kextsock.cpp:536
KExtendedSocket::socketFlags
int socketFlags() const
Returns the current flags.
Definition: kextsock.cpp:272
KExtendedSocket::close
virtual void close()
Closes the socket.
Definition: kextsock.cpp:1278
KAsyncIO::readyRead
void readyRead()
This signal gets sent when the device is ready for reading.
KExtendedSocket::startAsyncConnect
virtual int startAsyncConnect()
Starts an asynchronous connect.
Definition: kextsock.cpp:1210
KExtendedSocket::localAddress
const ::TDESocketAddress * localAddress()
Returns the local socket address.
Definition: kextsock.cpp:721
TDEBufferedIO::outBufIndex
unsigned outBufIndex
Offset into first output buffer.
Definition: kbufferedio.h:231
KExtendedSocket::setAddress
bool setAddress(const TQString &host, int port)
Sets the address where we will connect to.
Definition: kextsock.cpp:327
KSocks::getpeername
int getpeername(int s, sockaddr *name, ksocklen_t *namelen)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:548
KExtendedSocket::blockingMode
bool blockingMode()
Returns the current blocking mode for this socket.
Definition: kextsock.cpp:482
KExtendedSocket::cancelAsyncLookup
virtual void cancelAsyncLookup()
Cancels any on-going asynchronous lookups.
Definition: kextsock.cpp:830
TDEBufferedIO::consumeWriteBuffer
virtual void consumeWriteBuffer(unsigned nbytes)
Consumes data from the output buffer.
Definition: kbufferedio.cpp:224
KExtendedSocket
The extended socket class.
Definition: kextsock.h:95
KExtendedSocket::socketStatus
int socketStatus() const
Resets the socket, disconnecting if still connected and freeing any related resources still being kep...
Definition: kextsock.cpp:239
KExtendedSocket::setError
void setError(int errorkind, int error)
Sets the error code.
Definition: kextsock.cpp:249
KSocks::read
signed long int read(int fd, void *buf, unsigned long int count)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:487
TDEBufferedIO::consumeReadBuffer
virtual unsigned consumeReadBuffer(unsigned nbytes, char *destbuffer, bool discard=true)
Consumes data from the input buffer.
Definition: kbufferedio.cpp:174
KExtendedSocket::setAddressReusable
bool setAddressReusable(bool enable)
Sets/unsets address reusing flag for this socket.
Definition: kextsock.cpp:503
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583
KAddressInfo::flags
int flags() const KDE_DEPRECATED
Returns the flags of the address info (see getaddrinfo(3)).
Definition: kextsock.cpp:2223
KExtendedSocket::listen
virtual int listen(int N=5)
Place the socket in listen mode.
Definition: kextsock.cpp:841
KExtendedSocket::getch
virtual int getch()
Gets a single character (unsigned char) from the stream.
Definition: kextsock.cpp:1605
KExtendedSocket::connectionSuccess
void connectionSuccess()
This signal is emitted whenever we connected asynchronously to a host.
KExtendedSocket::setSocketStatus
void setSocketStatus(int status)
Sets the socket status.
Definition: kextsock.cpp:244
KNetwork::KResolverResults::error
int error() const
Retrieves the error code associated with this resolution.
Definition: kresolver.cpp:247
KAddressInfo::canonname
const char * canonname() const KDE_DEPRECATED
Returns the official name of the host (see getaddrinfo(3)).
Definition: kextsock.cpp:2243
KExtendedSocket::host
TQString host() const
Returns the hostname.
Definition: kextsock.cpp:293
KSocks::write
signed long int write(int fd, const void *buf, unsigned long int count)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:494
KSocks::recv
int recv(int s, void *buf, unsigned long int len, int flags)
This is the re-implementation of libc's function of the same name.
Definition: ksocks.cpp:522
TDEBufferedIO::feedWriteBuffer
virtual unsigned feedWriteBuffer(unsigned nbytes, const char *buffer)
Feeds data into the output buffer.
Definition: kbufferedio.cpp:269
KExtendedSocket::setBindAddress
bool setBindAddress(const TQString &host, int port)
Sets both host and port to which we will bind the socket.
Definition: kextsock.cpp:408
KExtendedSocket::readyAccept
void readyAccept()
This signal is emitted whenever this socket is ready to accept another socket.
KExtendedSocket::~KExtendedSocket
virtual ~KExtendedSocket()
Destroys the socket, disconnecting if still connected and freeing any related resources still being k...
Definition: kextsock.cpp:208
KExtendedSocket::startAsyncLookup
virtual int startAsyncLookup()
Starts an asynchronous lookup for the addresses given.
Definition: kextsock.cpp:771

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.8
This website is maintained by Timothy Pearson.