File indexing completed on 2024-04-14 15:05:28
0001 /*************************************************************************** 0002 These are the private helper classes of the Smb4KGlobal namespace. 0003 ------------------- 0004 begin : Di Jul 24 2007 0005 copyright : (C) 2007-2019 by Alexander Reinholdt 0006 email : alexander.reinholdt@kdemail.net 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * This program is free software; you can redistribute it and/or modify * 0011 * it under the terms of the GNU General Public License as published by * 0012 * the Free Software Foundation; either version 2 of the License, or * 0013 * (at your option) any later version. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, but * 0016 * WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 0018 * General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program; if not, write to the * 0022 * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston,* 0023 * MA 02110-1335, USA * 0024 ***************************************************************************/ 0025 0026 #ifdef HAVE_CONFIG_H 0027 #include <config.h> 0028 #endif 0029 0030 // application specific includes 0031 #include "smb4kglobal_p.h" 0032 #include "smb4knotification.h" 0033 #include "smb4ksettings.h" 0034 0035 // Qt includes 0036 #include <QDir> 0037 #include <QTextStream> 0038 #include <QTextCodec> 0039 #include <QFile> 0040 #include <QCoreApplication> 0041 #include <QHostAddress> 0042 #include <QAbstractSocket> 0043 #include <QHostInfo> 0044 #include <QDirIterator> 0045 0046 0047 Smb4KGlobalPrivate::Smb4KGlobalPrivate() 0048 { 0049 onlyForeignShares = false; 0050 coreInitialized = false; 0051 m_sambaConfigMissing = false; 0052 0053 #ifdef Q_OS_LINUX 0054 whitelistedMountArguments << "dynperm"; 0055 whitelistedMountArguments << "rwpidforward"; 0056 whitelistedMountArguments << "hard"; 0057 whitelistedMountArguments << "soft"; 0058 whitelistedMountArguments << "noacl"; 0059 whitelistedMountArguments << "cifsacl"; 0060 whitelistedMountArguments << "backupuid"; 0061 whitelistedMountArguments << "backupgid"; 0062 whitelistedMountArguments << "ignorecase"; 0063 whitelistedMountArguments << "nocase"; 0064 whitelistedMountArguments << "nobrl"; 0065 whitelistedMountArguments << "sfu"; 0066 whitelistedMountArguments << "nounix"; 0067 whitelistedMountArguments << "nouser_xattr"; 0068 whitelistedMountArguments << "fsc"; 0069 whitelistedMountArguments << "multiuser"; 0070 whitelistedMountArguments << "actimeo"; 0071 whitelistedMountArguments << "noposixpaths"; 0072 whitelistedMountArguments << "posixpaths"; 0073 #endif 0074 0075 // 0076 // File system watcher for smb.conf file 0077 // 0078 m_watcher = new QFileSystemWatcher(this); 0079 0080 // 0081 // Connections 0082 // 0083 connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(slotAboutToQuit())); 0084 connect(m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(slotSmbConfModified(QString))); 0085 } 0086 0087 0088 Smb4KGlobalPrivate::~Smb4KGlobalPrivate() 0089 { 0090 // Clear the workgroup list. 0091 while (!workgroupsList.isEmpty()) 0092 { 0093 workgroupsList.takeFirst().clear(); 0094 } 0095 0096 // Clear the host list. 0097 while (!hostsList.isEmpty()) 0098 { 0099 hostsList.takeFirst().clear(); 0100 } 0101 0102 // Clear the list of mounted shares. 0103 while (!mountedSharesList.isEmpty()) 0104 { 0105 mountedSharesList.takeFirst().clear(); 0106 } 0107 0108 // Clear the list of shares. 0109 while (!sharesList.isEmpty()) 0110 { 0111 sharesList.takeFirst().clear(); 0112 } 0113 } 0114 0115 0116 const QMap<QString,QString> &Smb4KGlobalPrivate::globalSambaOptions(bool read) 0117 { 0118 if ((!m_sambaConfigMissing && m_sambaOptions.isEmpty()) || read) 0119 { 0120 // 0121 // Clear the options. 0122 // 0123 m_sambaOptions.clear(); 0124 0125 // 0126 // Now search the smb.conf file. 0127 // 0128 // With the introduction of Samba 4, the smb.conf file might also 0129 // be named smb4.conf. Thus we need to search for two filenames. 0130 // 0131 QStringList paths; 0132 paths << "/etc"; 0133 paths << "/usr/local/etc"; 0134 paths << "/usr/pkg/etc"; 0135 0136 QStringList files; 0137 files << "smb.conf"; 0138 files << "smb4.conf"; 0139 0140 QString result; 0141 0142 for (const QString &path : paths) 0143 { 0144 QDirIterator it(path, files, QDir::Files, QDirIterator::Subdirectories); 0145 0146 while (it.hasNext()) 0147 { 0148 result = it.next(); 0149 } 0150 0151 if (!result.isEmpty()) 0152 { 0153 break; 0154 } 0155 } 0156 0157 // 0158 // Check if we found the file and read it. Otherwise show an error 0159 // message to the user. 0160 // 0161 QStringList contents; 0162 0163 if (!result.isEmpty()) 0164 { 0165 QFile smbConf(result); 0166 0167 if (smbConf.open(QIODevice::ReadOnly | QIODevice::Text)) 0168 { 0169 QTextStream ts(&smbConf); 0170 0171 while (!ts.atEnd()) 0172 { 0173 contents << ts.readLine(0); 0174 } 0175 0176 smbConf.close(); 0177 } 0178 else 0179 { 0180 Smb4KNotification::openingFileFailed(smbConf); 0181 return m_sambaOptions; 0182 } 0183 0184 // 0185 // Add the file to the file system watcher 0186 // 0187 m_watcher->addPath(result); 0188 0189 // 0190 // Tell the program that the config file was found 0191 // 0192 m_sambaConfigMissing = false; 0193 } 0194 else 0195 { 0196 if (!m_sambaConfigMissing) 0197 { 0198 Smb4KNotification::sambaConfigFileMissing(); 0199 m_sambaConfigMissing = true; 0200 return m_sambaOptions; 0201 } 0202 } 0203 0204 // 0205 // Process the contents of the smb.conf file 0206 // 0207 if (!contents.isEmpty()) 0208 { 0209 // 0210 // Jump to the [global] section and get the listed parameters 0211 // 0212 for (int i = contents.indexOf("[global]", 0); i < contents.size(); ++i) 0213 { 0214 if (i == -1) 0215 { 0216 // 0217 // No [global] section found. Stop. 0218 // 0219 break; 0220 } 0221 else if (contents.at(i).trimmed().startsWith('#') || contents.at(i).trimmed().startsWith(';') || contents.at(i).trimmed().isEmpty()) 0222 { 0223 // 0224 // This is either a comment or an empty line. We do not want it. 0225 // 0226 continue; 0227 } 0228 else if (contents.at(i).trimmed().startsWith(QLatin1String("include"))) 0229 { 0230 // 0231 // This is an include file. Get its contents and insert it into the 0232 // global Samba options map 0233 // 0234 QFile includeFile(contents.at(i).section('=', 1, 1).trimmed()); 0235 0236 if (includeFile.exists()) 0237 { 0238 if (includeFile.open(QIODevice::ReadOnly | QIODevice::Text)) 0239 { 0240 QTextStream ts(&includeFile); 0241 0242 QString buffer; 0243 0244 while(!ts.atEnd()) 0245 { 0246 buffer = ts.readLine(0).trimmed(); 0247 0248 if (buffer.startsWith('#') || buffer.startsWith(';')) 0249 { 0250 // 0251 // This is either a comment or an empty line. We do not want it. 0252 // 0253 continue; 0254 } 0255 else 0256 { 0257 // 0258 // This is an option. Put it into the global Samba options map 0259 // 0260 QString key = contents.at(i).section('=', 0, 0).trimmed().toLower(); 0261 QString value = contents.at(i).section('=', 1, 1).trimmed().toUpper(); 0262 0263 m_sambaOptions.insert(key, value); 0264 } 0265 } 0266 } 0267 else 0268 { 0269 Smb4KNotification::openingFileFailed(includeFile); 0270 continue; 0271 } 0272 } 0273 } 0274 else if (contents.at(i).trimmed().startsWith('[') && !contents.at(i).contains("[global]", Qt::CaseSensitive)) 0275 { 0276 // 0277 // A new section begins. Stop. 0278 // 0279 break; 0280 } 0281 else 0282 { 0283 // 0284 // This is an option. Put it into the global Samba options map 0285 // 0286 QString key = contents.at(i).section('=', 0, 0).trimmed().toLower(); 0287 QString value = contents.at(i).section('=', 1, 1).trimmed().toUpper(); 0288 0289 m_sambaOptions.insert(key, value); 0290 } 0291 } 0292 } 0293 } 0294 0295 return m_sambaOptions; 0296 } 0297 0298 0299 void Smb4KGlobalPrivate::slotAboutToQuit() 0300 { 0301 Smb4KSettings::self()->save(); 0302 } 0303 0304 0305 void Smb4KGlobalPrivate::slotSmbConfModified(const QString &/*file*/) 0306 { 0307 globalSambaOptions(true); 0308 } 0309