• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdeio
 

tdeio/tdeio

  • tdeio
  • tdeio
tdeprotocolmanager.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 1999 Torben Weis <weis@kde.org>
3  Copyright (C) 2000- Waldo Bastain <bastain@kde.org>
4  Copyright (C) 2000- Dawit Alemayehu <adawit@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License version 2 as published by the Free Software Foundation.
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 <string.h>
22 #include <sys/utsname.h>
23 
24 #include <dcopref.h>
25 #include <kdebug.h>
26 #include <tdeglobal.h>
27 #include <tdelocale.h>
28 #include <tdeconfig.h>
29 #include <tdeversion.h>
30 #include <tdestandarddirs.h>
31 #include <klibloader.h>
32 #include <kstringhandler.h>
33 #include <kstaticdeleter.h>
34 #include <tdeio/slaveconfig.h>
35 #include <tdeio/ioslave_defaults.h>
36 #include <tdeio/http_slave_defaults.h>
37 
38 #include "tdeprotocolmanager.h"
39 
40 class
41 KProtocolManagerPrivate
42 {
43 public:
44  KProtocolManagerPrivate();
45 
46  ~KProtocolManagerPrivate();
47 
48  TDEConfig *config;
49  TDEConfig *http_config;
50  bool init_busy;
51  KURL url;
52  TQString protocol;
53  TQString proxy;
54  TQString modifiers;
55  TQString useragent;
56 };
57 
58 static KProtocolManagerPrivate* d = 0;
59 static KStaticDeleter<KProtocolManagerPrivate> kpmpksd;
60 
61 KProtocolManagerPrivate::KProtocolManagerPrivate()
62  :config(0), http_config(0), init_busy(false)
63 {
64  kpmpksd.setObject(d, this);
65 }
66 
67 KProtocolManagerPrivate::~KProtocolManagerPrivate()
68 {
69  delete config;
70  delete http_config;
71 }
72 
73 
74 // DEFAULT USERAGENT STRING
75 #define CFG_DEFAULT_UAGENT(X) \
76 TQString("Mozilla/5.0 (compatible; Konqueror/%1.%2%3) KHTML/TDEHTML/%4.%5.%6 (like Gecko)") \
77  .arg(TDE_VERSION_MAJOR).arg(TDE_VERSION_MINOR).arg(X).arg(TDE_VERSION_MAJOR).arg(TDE_VERSION_MINOR).arg(TDE_VERSION_RELEASE)
78 
79 void KProtocolManager::reparseConfiguration()
80 {
81  kpmpksd.destructObject();
82 
83  // Force the slave config to re-read its config...
84  TDEIO::SlaveConfig::self()->reset ();
85 }
86 
87 TDEConfig *KProtocolManager::config()
88 {
89  if (!d)
90  d = new KProtocolManagerPrivate;
91 
92  if (!d->config)
93  {
94  d->config = new TDEConfig("tdeioslaverc", true, false);
95  }
96  return d->config;
97 }
98 
99 TDEConfig *KProtocolManager::http_config()
100 {
101  if (!d)
102  d = new KProtocolManagerPrivate;
103 
104  if (!d->http_config)
105  {
106  d->http_config = new TDEConfig("tdeio_httprc", false, false);
107  }
108  return d->http_config;
109 }
110 
111 /*=============================== TIMEOUT SETTINGS ==========================*/
112 
113 int KProtocolManager::readTimeout()
114 {
115  TDEConfig *cfg = config();
116  cfg->setGroup( TQString::null );
117  int val = cfg->readNumEntry( "ReadTimeout", DEFAULT_READ_TIMEOUT );
118  return TQMAX(MIN_TIMEOUT_VALUE, val);
119 }
120 
121 int KProtocolManager::connectTimeout()
122 {
123  TDEConfig *cfg = config();
124  cfg->setGroup( TQString::null );
125  int val = cfg->readNumEntry( "ConnectTimeout", DEFAULT_CONNECT_TIMEOUT );
126  return TQMAX(MIN_TIMEOUT_VALUE, val);
127 }
128 
129 int KProtocolManager::proxyConnectTimeout()
130 {
131  TDEConfig *cfg = config();
132  cfg->setGroup( TQString::null );
133  int val = cfg->readNumEntry( "ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT );
134  return TQMAX(MIN_TIMEOUT_VALUE, val);
135 }
136 
137 int KProtocolManager::responseTimeout()
138 {
139  TDEConfig *cfg = config();
140  cfg->setGroup( TQString::null );
141  int val = cfg->readNumEntry( "ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT );
142  return TQMAX(MIN_TIMEOUT_VALUE, val);
143 }
144 
145 /*========================== PROXY SETTINGS =================================*/
146 
147 bool KProtocolManager::useProxy()
148 {
149  return proxyType() != NoProxy;
150 }
151 
152 bool KProtocolManager::useReverseProxy()
153 {
154  TDEConfig *cfg = config();
155  cfg->setGroup( "Proxy Settings" );
156  return cfg->readBoolEntry("ReversedException", false);
157 }
158 
159 KProtocolManager::ProxyType KProtocolManager::proxyType()
160 {
161  TDEConfig *cfg = config();
162  cfg->setGroup( "Proxy Settings" );
163  return static_cast<ProxyType>(cfg->readNumEntry( "ProxyType" ));
164 }
165 
166 KProtocolManager::ProxyAuthMode KProtocolManager::proxyAuthMode()
167 {
168  TDEConfig *cfg = config();
169  cfg->setGroup( "Proxy Settings" );
170  return static_cast<ProxyAuthMode>(cfg->readNumEntry( "AuthMode" ));
171 }
172 
173 /*========================== CACHING =====================================*/
174 
175 bool KProtocolManager::useCache()
176 {
177  TDEConfig *cfg = http_config();
178  return cfg->readBoolEntry( "UseCache", true );
179 }
180 
181 TDEIO::CacheControl KProtocolManager::cacheControl()
182 {
183  TDEConfig *cfg = http_config();
184  TQString tmp = cfg->readEntry("cache");
185  if (tmp.isEmpty())
186  return DEFAULT_CACHE_CONTROL;
187  return TDEIO::parseCacheControl(tmp);
188 }
189 
190 TQString KProtocolManager::cacheDir()
191 {
192  TDEConfig *cfg = http_config();
193  return cfg->readPathEntry("CacheDir", TDEGlobal::dirs()->saveLocation("cache","http"));
194 }
195 
196 int KProtocolManager::maxCacheAge()
197 {
198  TDEConfig *cfg = http_config();
199  return cfg->readNumEntry( "MaxCacheAge", DEFAULT_MAX_CACHE_AGE ); // 14 days
200 }
201 
202 int KProtocolManager::maxCacheSize()
203 {
204  TDEConfig *cfg = http_config();
205  return cfg->readNumEntry( "MaxCacheSize", DEFAULT_MAX_CACHE_SIZE ); // 5 MB
206 }
207 
208 TQString KProtocolManager::noProxyForRaw()
209 {
210  TDEConfig *cfg = config();
211  cfg->setGroup( "Proxy Settings" );
212 
213  return cfg->readEntry( "NoProxyFor" );
214 }
215 
216 TQString KProtocolManager::noProxyFor()
217 {
218  TQString noProxy = noProxyForRaw();
219  if (proxyType() == EnvVarProxy)
220  noProxy = TQString::fromLocal8Bit(getenv(noProxy.local8Bit()));
221 
222  return noProxy;
223 }
224 
225 TQString KProtocolManager::proxyFor( const TQString& protocol )
226 {
227  TQString scheme = protocol.lower();
228 
229  if (scheme == "webdav")
230  scheme = "http";
231  else if (scheme == "webdavs")
232  scheme = "https";
233 
234  TDEConfig *cfg = config();
235  cfg->setGroup( "Proxy Settings" );
236  return cfg->readEntry( scheme + "Proxy" );
237 }
238 
239 TQString KProtocolManager::proxyForURL( const KURL &url )
240 {
241  TQString proxy;
242  ProxyType pt = proxyType();
243 
244  switch (pt)
245  {
246  case PACProxy:
247  case WPADProxy:
248  if (!url.host().isEmpty())
249  {
250  KURL u (url);
251  TQString p = u.protocol().lower();
252 
253  // webdav is a KDE specific protocol. Look up proxy
254  // information using HTTP instead...
255  if ( p == "webdav" )
256  {
257  p = "http";
258  u.setProtocol( p );
259  }
260  else if ( p == "webdavs" )
261  {
262  p = "https";
263  u.setProtocol( p );
264  }
265 
266  if ( p.startsWith("http") || p == "ftp" || p == "gopher" )
267  DCOPRef( "kded", "proxyscout" ).call( "proxyForURL", u ).get( proxy );
268  }
269  break;
270  case EnvVarProxy:
271  proxy = TQString(TQString::fromLocal8Bit(getenv(proxyFor(url.protocol()).local8Bit()))).stripWhiteSpace();
272  break;
273  case ManualProxy:
274  proxy = proxyFor( url.protocol() );
275  break;
276  case NoProxy:
277  default:
278  break;
279  }
280 
281  return (proxy.isEmpty() ? TQString::fromLatin1("DIRECT") : proxy);
282 }
283 
284 void KProtocolManager::badProxy( const TQString &proxy )
285 {
286  DCOPRef( "kded", "proxyscout" ).send( "blackListProxy", proxy );
287 }
288 
289 /*
290  Domain suffix match. E.g. return true if host is "cuzco.inka.de" and
291  nplist is "inka.de,hadiko.de" or if host is "localhost" and nplist is
292  "localhost".
293 */
294 static bool revmatch(const char *host, const char *nplist)
295 {
296  if (host == 0)
297  return false;
298 
299  const char *hptr = host + strlen( host ) - 1;
300  const char *nptr = nplist + strlen( nplist ) - 1;
301  const char *shptr = hptr;
302 
303  while ( nptr >= nplist )
304  {
305  if ( *hptr != *nptr )
306  {
307  hptr = shptr;
308 
309  // Try to find another domain or host in the list
310  while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ;
311 
312  // Strip out multiple spaces and commas
313  while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ;
314  }
315  else
316  {
317  if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ')
318  return true;
319  if ( hptr == host ) // e.g. revmatch("bugs.kde.org","mybugs.kde.org")
320  return false;
321 
322  hptr--;
323  nptr--;
324  }
325  }
326 
327  return false;
328 }
329 
330 TQString KProtocolManager::slaveProtocol(const KURL &url, TQString &proxy)
331 {
332  if (url.hasSubURL()) // We don't want the suburl's protocol
333  {
334  KURL::List list = KURL::split(url);
335  KURL::List::Iterator it = list.fromLast();
336  return slaveProtocol(*it, proxy);
337  }
338 
339  if (!d)
340  d = new KProtocolManagerPrivate;
341 
342  if (d->url == url)
343  {
344  proxy = d->proxy;
345  return d->protocol;
346  }
347 
348  if (useProxy())
349  {
350  proxy = proxyForURL(url);
351  if ((proxy != "DIRECT") && (!proxy.isEmpty()))
352  {
353  bool isRevMatch = false;
354  KProtocolManager::ProxyType type = proxyType();
355  bool useRevProxy = ((type == ManualProxy) && useReverseProxy());
356 
357  TQString noProxy;
358  // Check no proxy information iff the proxy type is either
359  // ManualProxy or EnvVarProxy
360  if ( (type == ManualProxy) || (type == EnvVarProxy) )
361  noProxy = noProxyFor();
362 
363  if (!noProxy.isEmpty())
364  {
365  TQString qhost = url.host().lower();
366  const char *host = qhost.latin1();
367  TQString qno_proxy = noProxy.stripWhiteSpace().lower();
368  const char *no_proxy = qno_proxy.latin1();
369  isRevMatch = revmatch(host, no_proxy);
370 
371  // If no match is found and the request url has a port
372  // number, try the combination of "host:port". This allows
373  // users to enter host:port in the No-proxy-For list.
374  if (!isRevMatch && url.port() > 0)
375  {
376  qhost += ':' + TQString::number (url.port());
377  host = qhost.latin1();
378  isRevMatch = revmatch (host, no_proxy);
379  }
380 
381  // If the hostname does not contain a dot, check if
382  // <local> is part of noProxy.
383  if (!isRevMatch && host && (strchr(host, '.') == NULL))
384  isRevMatch = revmatch("<local>", no_proxy);
385  }
386 
387  if ( (!useRevProxy && !isRevMatch) || (useRevProxy && isRevMatch) )
388  {
389  d->url = proxy;
390  if ( d->url.isValid() )
391  {
392  // The idea behind slave protocols is not applicable to http
393  // and webdav protocols.
394  TQString protocol = url.protocol().lower();
395  if (protocol.startsWith("http") || protocol.startsWith("webdav"))
396  d->protocol = protocol;
397  else
398  {
399  d->protocol = d->url.protocol();
400  kdDebug () << "slaveProtocol: " << d->protocol << endl;
401  }
402 
403  d->url = url;
404  d->proxy = proxy;
405  return d->protocol;
406  }
407  }
408  }
409  }
410 
411  d->url = url;
412  d->proxy = proxy = TQString::null;
413  d->protocol = url.protocol();
414  return d->protocol;
415 }
416 
417 /*================================= USER-AGENT SETTINGS =====================*/
418 
419 TQString KProtocolManager::userAgentForHost( const TQString& hostname )
420 {
421  TQString sendUserAgent = TDEIO::SlaveConfig::self()->configData("http", hostname.lower(), "SendUserAgent").lower();
422  if (sendUserAgent == "false")
423  return TQString::null;
424 
425  TQString useragent = TDEIO::SlaveConfig::self()->configData("http", hostname.lower(), "UserAgent");
426 
427  // Return the default user-agent if none is specified
428  // for the requested host.
429  if (useragent.isEmpty())
430  return defaultUserAgent();
431 
432  return useragent;
433 }
434 
435 TQString KProtocolManager::defaultUserAgent( )
436 {
437  TQString modifiers = TDEIO::SlaveConfig::self()->configData("http", TQString::null, "UserAgentKeys");
438  return defaultUserAgent(modifiers);
439 }
440 
441 TQString KProtocolManager::defaultUserAgent( const TQString &_modifiers )
442 {
443  if (!d)
444  d = new KProtocolManagerPrivate;
445 
446  TQString modifiers = _modifiers.lower();
447  if (modifiers.isEmpty())
448  modifiers = DEFAULT_USER_AGENT_KEYS;
449 
450  if (d->modifiers == modifiers)
451  return d->useragent;
452 
453  TQString supp;
454  struct utsname nam;
455  if( uname(&nam) >= 0 )
456  {
457  if( modifiers.contains('o') )
458  {
459  supp += TQString("; %1").arg(nam.sysname);
460  if ( modifiers.contains('v') )
461  supp += TQString(" %1").arg(nam.release);
462  }
463  if( modifiers.contains('p') )
464  {
465  // TODO: determine this value instead of hardcoding it...
466  supp += TQString::fromLatin1("; X11");
467  }
468  if( modifiers.contains('m') )
469  {
470  supp += TQString("; %1").arg(nam.machine);
471  }
472  if( modifiers.contains('l') )
473  {
474  TQStringList languageList = TDEGlobal::locale()->languageList();
475  TQStringList::Iterator it = languageList.find( TQString::fromLatin1("C") );
476  if( it != languageList.end() )
477  {
478  if( languageList.contains( TQString::fromLatin1("en") ) > 0 )
479  languageList.remove( it );
480  else
481  (*it) = TQString::fromLatin1("en");
482  }
483  if( languageList.count() )
484  supp += TQString("; %1").arg(languageList.join(", "));
485  }
486  }
487  d->modifiers = modifiers;
488  d->useragent = CFG_DEFAULT_UAGENT(supp);
489  return d->useragent;
490 }
491 
492 /*==================================== OTHERS ===============================*/
493 
494 bool KProtocolManager::markPartial()
495 {
496  TDEConfig *cfg = config();
497  cfg->setGroup( TQString::null );
498  return cfg->readBoolEntry( "MarkPartial", true );
499 }
500 
501 int KProtocolManager::minimumKeepSize()
502 {
503  TDEConfig *cfg = config();
504  cfg->setGroup( TQString::null );
505  return cfg->readNumEntry( "MinimumKeepSize",
506  DEFAULT_MINIMUM_KEEP_SIZE ); // 5000 byte
507 }
508 
509 bool KProtocolManager::autoResume()
510 {
511  TDEConfig *cfg = config();
512  cfg->setGroup( TQString::null );
513  return cfg->readBoolEntry( "AutoResume", false );
514 }
515 
516 bool KProtocolManager::persistentConnections()
517 {
518  TDEConfig *cfg = config();
519  cfg->setGroup( TQString::null );
520  return cfg->readBoolEntry( "PersistentConnections", true );
521 }
522 
523 bool KProtocolManager::persistentProxyConnection()
524 {
525  TDEConfig *cfg = config();
526  cfg->setGroup( TQString::null );
527  return cfg->readBoolEntry( "PersistentProxyConnection", false );
528 }
529 
530 TQString KProtocolManager::proxyConfigScript()
531 {
532  TDEConfig *cfg = config();
533  cfg->setGroup( "Proxy Settings" );
534  return cfg->readEntry( "Proxy Config Script" );
535 }
KProtocolManager::badProxy
static void badProxy(const TQString &proxy)
Marks this proxy as bad (down).
Definition: tdeprotocolmanager.cpp:284
KProtocolManager::ProxyAuthMode
ProxyAuthMode
Proxy authorization modes.
Definition: tdeprotocolmanager.h:195
KProtocolManager::useCache
static bool useCache()
Returns true/false to indicate whether a cache should be used.
Definition: tdeprotocolmanager.cpp:175
KProtocolManager::useReverseProxy
static bool useReverseProxy()
Returns true if the proxy settings should apply to the list returned by noProxyFor.
Definition: tdeprotocolmanager.cpp:152
KProtocolManager::proxyConnectTimeout
static int proxyConnectTimeout()
Returns the preferred timeout value for proxy connections in seconds.
Definition: tdeprotocolmanager.cpp:129
KProtocolManager::defaultUserAgent
static TQString defaultUserAgent()
Returns the default user-agent string.
Definition: tdeprotocolmanager.cpp:435
KProtocolManager::noProxyFor
static TQString noProxyFor()
Returns a comma-separated list of hostnames or partial host-names that should bypass any proxy settin...
Definition: tdeprotocolmanager.cpp:216
KProtocolManager::proxyConfigScript
static TQString proxyConfigScript()
Returns the URL of the script for automatic proxy configuration.
Definition: tdeprotocolmanager.cpp:530
KProtocolManager::slaveProtocol
static TQString slaveProtocol(const KURL &url, TQString &proxy)
Return the protocol to use in order to handle the given url It's usually the same,...
Definition: tdeprotocolmanager.cpp:330
KProtocolManager::userAgentForHost
static TQString userAgentForHost(const TQString &hostname)
Returns the userAgent string configured for the specified host.
Definition: tdeprotocolmanager.cpp:419
KProtocolManager::persistentProxyConnection
static bool persistentProxyConnection()
Returns true if proxy connections should be persistent.
Definition: tdeprotocolmanager.cpp:523
KProtocolManager::ProxyType
ProxyType
Types of proxy configuration.
Definition: tdeprotocolmanager.h:167
KProtocolManager::persistentConnections
static bool persistentConnections()
Returns true if connections should be persistent.
Definition: tdeprotocolmanager.cpp:516
KProtocolManager::useProxy
static bool useProxy()
Returns true if the user specified a proxy server to make connections.
Definition: tdeprotocolmanager.cpp:147
KProtocolManager::proxyAuthMode
static ProxyAuthMode proxyAuthMode()
Returns the way proxy authorization should be handled.
Definition: tdeprotocolmanager.cpp:166
KProtocolManager::cacheDir
static TQString cacheDir()
The directory which contains the cache files.
Definition: tdeprotocolmanager.cpp:190
KProtocolManager::maxCacheSize
static int maxCacheSize()
Returns the maximum size that can be used for caching.
Definition: tdeprotocolmanager.cpp:202
KProtocolManager::connectTimeout
static int connectTimeout()
Returns the preferred timeout value for remote connections in seconds.
Definition: tdeprotocolmanager.cpp:121
KProtocolManager::autoResume
static bool autoResume()
Returns true if partial downloads should be automatically resumed.
Definition: tdeprotocolmanager.cpp:509
KProtocolManager::markPartial
static bool markPartial()
Returns true if partial downloads should be marked with a ".part" extension.
Definition: tdeprotocolmanager.cpp:494
KProtocolManager::proxyFor
static TQString proxyFor(const TQString &protocol)
Returns the proxy server address for a given protocol.
Definition: tdeprotocolmanager.cpp:225
KProtocolManager::proxyForURL
static TQString proxyForURL(const KURL &url)
Returns the proxy server address for a given URL.
Definition: tdeprotocolmanager.cpp:239
KProtocolManager::noProxyForRaw
static TQString noProxyForRaw()
Same as above except the environment variable name is returned instead of the variable value when pro...
Definition: tdeprotocolmanager.cpp:208
KProtocolManager::minimumKeepSize
static int minimumKeepSize()
Returns the minimum file size for keeping aborted downloads.
Definition: tdeprotocolmanager.cpp:501
KProtocolManager::reparseConfiguration
static void reparseConfiguration()
Force a reload of the general config file of io-slaves ( tdeioslaverc).
Definition: tdeprotocolmanager.cpp:79
KProtocolManager::cacheControl
static TDEIO::CacheControl cacheControl()
Returns the Cache control directive to be used.
Definition: tdeprotocolmanager.cpp:181
KProtocolManager::maxCacheAge
static int maxCacheAge()
Returns the maximum age in seconds cached files should be kept before they are deleted as necessary.
Definition: tdeprotocolmanager.cpp:196
KProtocolManager::responseTimeout
static int responseTimeout()
Returns the preferred response timeout value for remote connecting in seconds.
Definition: tdeprotocolmanager.cpp:137
KProtocolManager::readTimeout
static int readTimeout()
Returns the preferred timeout value for reading from remote connections in seconds.
Definition: tdeprotocolmanager.cpp:113
KProtocolManager::proxyType
static ProxyType proxyType()
Returns the type of proxy configuration that is used.
Definition: tdeprotocolmanager.cpp:159
TDEIO::SlaveConfig::configData
MetaData configData(const TQString &protocol, const TQString &host)
Query slave configuration for slaves of type protocol when dealing with host.
Definition: slaveconfig.cpp:192
TDEIO::SlaveConfig::reset
void reset()
Undo any changes made by calls to setConfigData.
Definition: slaveconfig.cpp:216
TDEIO::parseCacheControl
TDEIO_EXPORT TDEIO::CacheControl parseCacheControl(const TQString &cacheControl)
Parses the string representation of the cache control option.
Definition: global.cpp:2002
TDEIO::CacheControl
CacheControl
Specifies how to use the cache.
Definition: global.h:388

tdeio/tdeio

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

tdeio/tdeio

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