KIO

slaveconfig.cpp
1 // -*- c++ -*-
2 /*
3  This file is part of the KDE libraries
4  SPDX-FileCopyrightText: 2001 Waldo Bastian <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-only
7 */
8 
9 #include "slaveconfig.h"
10 
11 #include <QHash>
12 #include <QThreadStorage>
13 
14 #include <KConfig>
15 #include <KSharedConfig>
16 #include <kprotocolinfo.h>
17 #include <kprotocolmanager.h>
18 
19 using namespace KIO;
20 
21 namespace KIO
22 {
23 class SlaveConfigProtocol
24 {
25 public:
26  SlaveConfigProtocol()
27  {
28  }
29  ~SlaveConfigProtocol()
30  {
31  delete configFile;
32  }
33 
34  SlaveConfigProtocol(const SlaveConfigProtocol &) = delete;
35  SlaveConfigProtocol &operator=(const SlaveConfigProtocol &) = delete;
36 
37 public:
38  MetaData global;
40  KConfig *configFile;
41 };
42 
43 static void readConfig(KConfig *config, const QString &group, MetaData *metaData)
44 {
45  *metaData += config->entryMap(group);
46 }
47 
48 class SlaveConfigPrivate
49 {
50 public:
51  void readGlobalConfig();
52  SlaveConfigProtocol *readProtocolConfig(const QString &_protocol);
53  SlaveConfigProtocol *findProtocolConfig(const QString &_protocol);
54  void readConfigProtocolHost(const QString &_protocol, SlaveConfigProtocol *scp, const QString &host);
55 
56 public:
57  MetaData global;
59 };
60 
61 void SlaveConfigPrivate::readGlobalConfig()
62 {
63  global.clear();
64  // Read stuff...
65  readConfig(KSharedConfig::openConfig().data(), QStringLiteral("Socks"), &global); // Socks settings.
66  global += KProtocolManager::entryMap(QStringLiteral("<default>"));
67 }
68 
69 SlaveConfigProtocol *SlaveConfigPrivate::readProtocolConfig(const QString &_protocol)
70 {
71  SlaveConfigProtocol *scp = protocol.value(_protocol, nullptr);
72  if (!scp) {
73  QString filename = KProtocolInfo::config(_protocol);
74  scp = new SlaveConfigProtocol;
75  scp->configFile = new KConfig(filename, KConfig::NoGlobals);
76  protocol.insert(_protocol, scp);
77  }
78  // Read global stuff...
79  readConfig(scp->configFile, QStringLiteral("<default>"), &(scp->global));
80  return scp;
81 }
82 
83 SlaveConfigProtocol *SlaveConfigPrivate::findProtocolConfig(const QString &_protocol)
84 {
85  SlaveConfigProtocol *scp = protocol.value(_protocol, nullptr);
86  if (!scp) {
87  scp = readProtocolConfig(_protocol);
88  }
89  return scp;
90 }
91 
92 void SlaveConfigPrivate::readConfigProtocolHost(const QString &, SlaveConfigProtocol *scp, const QString &host)
93 {
94  MetaData metaData;
95  scp->host.insert(host, metaData);
96 
97  // Read stuff
98  // Break host into domains
99  QString domain = host;
100 
101  if (!domain.contains(QLatin1Char('.'))) {
102  // Host without domain.
103  if (scp->configFile->hasGroup("<local>")) {
104  readConfig(scp->configFile, QStringLiteral("<local>"), &metaData);
105  scp->host.insert(host, metaData);
106  }
107  }
108 
109  int pos = 0;
110  do {
111  pos = host.lastIndexOf(QLatin1Char('.'), pos - 1);
112 
113  if (pos < 0) {
114  domain = host;
115  } else {
116  domain = host.mid(pos + 1);
117  }
118 
119  if (scp->configFile->hasGroup(domain)) {
120  readConfig(scp->configFile, domain.toLower(), &metaData);
121  scp->host.insert(host, metaData);
122  }
123  } while (pos > 0);
124 }
125 
126 class SlaveConfigSingleton
127 {
128 public:
129  SlaveConfig instance;
130 };
131 
132 template<typename T>
133 T *perThreadGlobalStatic()
134 {
135  static QThreadStorage<T *> s_storage;
136  if (!s_storage.hasLocalData()) {
137  s_storage.setLocalData(new T);
138  }
139  return s_storage.localData();
140 }
141 // Q_GLOBAL_STATIC(SlaveConfigSingleton, _self)
142 SlaveConfigSingleton *_self()
143 {
144  return perThreadGlobalStatic<SlaveConfigSingleton>();
145 }
146 
147 SlaveConfig *SlaveConfig::self()
148 {
149  return &_self()->instance;
150 }
151 
152 SlaveConfig::SlaveConfig()
153  : d(new SlaveConfigPrivate)
154 {
155  d->readGlobalConfig();
156 }
157 
158 SlaveConfig::~SlaveConfig()
159 {
160  qDeleteAll(d->protocol);
161  delete d;
162 }
163 
164 void SlaveConfig::setConfigData(const QString &protocol, const QString &host, const QString &key, const QString &value)
165 {
167  config.insert(key, value);
168  setConfigData(protocol, host, config);
169 }
170 
171 void SlaveConfig::setConfigData(const QString &protocol, const QString &host, const MetaData &config)
172 {
173  if (protocol.isEmpty()) {
174  d->global += config;
175  } else {
176  SlaveConfigProtocol *scp = d->findProtocolConfig(protocol);
177  if (host.isEmpty()) {
178  scp->global += config;
179  } else {
180  if (!scp->host.contains(host)) {
181  d->readConfigProtocolHost(protocol, scp, host);
182  }
183 
184  MetaData hostConfig = scp->host.value(host);
185  hostConfig += config;
186  scp->host.insert(host, hostConfig);
187  }
188  }
189 }
190 
191 MetaData SlaveConfig::configData(const QString &protocol, const QString &host)
192 {
193  MetaData config = d->global;
194  SlaveConfigProtocol *scp = d->findProtocolConfig(protocol);
195  config += scp->global;
196  if (host.isEmpty()) {
197  return config;
198  }
199 
200  if (!scp->host.contains(host)) {
201  d->readConfigProtocolHost(protocol, scp, host);
202  Q_EMIT configNeeded(protocol, host);
203  }
204  MetaData hostConfig = scp->host.value(host);
205  config += hostConfig;
206 
207  return config;
208 }
209 
210 QString SlaveConfig::configData(const QString &protocol, const QString &host, const QString &key)
211 {
212  return configData(protocol, host).value(key);
213 }
214 
216 {
217  qDeleteAll(d->protocol);
218  d->protocol.clear();
219  d->readGlobalConfig();
220 }
221 
222 }
MetaData configData(const QString &protocol, const QString &host)
Query slave configuration for slaves of type protocol when dealing with host.
A namespace for KIO globals.
static QString config(const QString &protocol)
Returns the name of the config file associated with the specified protocol.
void setConfigData(const QString &protocol, const QString &host, const QString &key, const QString &value)
Configure slaves of type protocol by setting key to value.
MetaData is a simple map of key/value strings.
Definition: metadata.h:22
void reset()
Undo any changes made by calls to setConfigData.
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
QMap< QString, QString > entryMap(const QString &aGroup=QString()) const
void setLocalData(T data)
bool hasLocalData() const const
KConfigGroup * config()
Returns a configuration object to query config/meta-data information from.
Definition: slavebase.cpp:438
bool isEmpty() const const
void clear()
QString toLower() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
void readConfig()
QString mid(int position, int n) const const
SlaveConfig.
Definition: slaveconfig.h:38
QMap::iterator insert(const Key &key, const T &value)
const T value(const Key &key, const T &defaultValue) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Apr 18 2021 23:00:56 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.