File indexing completed on 2024-12-08 08:12:52
0001 // This license reflects the original Adept code: 0002 // -*- C++ -*- (c) 2008 Petr Rockai <me@mornfall.net> 0003 // (c) 2011 Modestas Vainius <modax@debian.org> 0004 // Redistribution and use in source and binary forms, with or without 0005 // modification, are permitted provided that the following conditions are 0006 // met: 0007 // 0008 // * Redistributions of source code must retain the above copyright 0009 // notice, this list of conditions and the following disclaimer. 0010 // 0011 // * Redistributions in binary form must reproduce the above 0012 // copyright notice, this list of conditions and the following 0013 // disclaimer in the documentation and/or other materials provided 0014 // with the distribution. 0015 // 0016 // * Neither the name of [original copyright holder] nor the names of 0017 // its contributors may be used to endorse or promote products 0018 // derived from this software without specific prior written 0019 // permission. 0020 // 0021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0032 /* 0033 * All the modifications below are licensed under this license 0034 * Copyright (C) 2010 Daniel Nicoletti <dantti12@gmail.com> 0035 * 0036 * This library is free software; you can redistribute it and/or 0037 * modify it under the terms of the GNU Library General Public 0038 * License as published by the Free Software Foundation; either 0039 * version 2 of the License, or (at your option) any later version. 0040 * 0041 * This library is distributed in the hope that it will be useful, 0042 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0043 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0044 * Library General Public License for more details. 0045 * 0046 * You should have received a copy of the GNU Library General Public License 0047 * along with this library; see the file COPYING.LIB. If not, write to 0048 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0049 * Boston, MA 02110-1301, USA. 0050 */ 0051 0052 #ifndef DEBCONF_H 0053 #define DEBCONF_H 0054 0055 #include <QtCore/QHash> 0056 #include <QtCore/QStringList> 0057 #include <QtCore/QMetaEnum> 0058 #include <QtCore/QMetaObject> 0059 #include <QtCore/QFile> 0060 #include <QtNetwork/QLocalSocket> 0061 #include <QtNetwork/QLocalServer> 0062 0063 class QSocketNotifier; 0064 0065 namespace DebconfKde { 0066 0067 /** 0068 * An abstract class which talks Debconf Passthrough frontend protocol. It 0069 * does not implement underlying I/O method specifics. 0070 */ 0071 class DebconfFrontend : public QObject { 0072 Q_OBJECT 0073 Q_ENUMS(PropertyKey) 0074 Q_ENUMS(TypeKey) 0075 public: 0076 typedef enum { 0077 Choices, 0078 Description, 0079 ExtendedDescription, 0080 Type, 0081 UnknownPropertyKey = -1 0082 } PropertyKey; 0083 0084 typedef enum { 0085 String, 0086 Password, 0087 Progress, 0088 Boolean, 0089 Select, 0090 Multiselect, 0091 Note, 0092 Error, 0093 Title, 0094 Text, 0095 UnknownTypeKey = -1 0096 } TypeKey; 0097 0098 explicit DebconfFrontend(QObject *parent = 0); 0099 virtual ~DebconfFrontend(); 0100 0101 QString value(const QString &key) const; 0102 void setValue(const QString &key, const QString &value); 0103 0104 QString property(const QString &key, PropertyKey p) const; 0105 0106 TypeKey type(const QString &string) const; 0107 0108 /** 0109 * Send \p string to Debconf over established connection 0110 */ 0111 void say(const QString &string); 0112 0113 /** 0114 * Goes to the next question 0115 */ 0116 void next(); 0117 /** 0118 * Goes back one question (if backup(true) was emitted) 0119 */ 0120 void back(); 0121 /** 0122 * Closes the current connection, canceling all questions 0123 */ 0124 virtual void cancel(); 0125 0126 Q_SIGNALS: 0127 void go(const QString &title, const QStringList &input); 0128 void progress(const QString ¶m); 0129 /** 0130 * Emitted when connection with Debconf is terminated. 0131 */ 0132 void finished(); 0133 void backup(bool capable); 0134 0135 protected Q_SLOTS: 0136 /** 0137 * This slot should be called when there is new data available. 0138 */ 0139 virtual bool process(); 0140 0141 /** 0142 * This slot should be called when connection with Debconf is terminated. 0143 */ 0144 virtual void disconnected(); 0145 0146 protected: 0147 /** 0148 * This method must be overridden by the derivative class and return 0149 * current QIODevice which should be used to read data from Debconf. 0150 */ 0151 virtual QIODevice* getReadDevice() const = 0; 0152 /** 0153 * This method must be overridden by the derivative class and return 0154 * current QIODevice which should be used to write data to Debconf. 0155 */ 0156 virtual QIODevice* getWriteDevice() const = 0; 0157 /** 0158 * This is called to clean up internal data once connection with 0159 * Debconf is terminated. 0160 */ 0161 virtual void reset(); 0162 0163 private: 0164 void cmd_capb(const QString &caps); 0165 void cmd_set(const QString ¶m); 0166 void cmd_get(const QString ¶m); 0167 void cmd_input(const QString ¶m); 0168 void cmd_go(const QString &); 0169 void cmd_title(const QString ¶m); 0170 void cmd_data(const QString ¶m); 0171 void cmd_subst(const QString ¶m); 0172 void cmd_progress(const QString ¶m); 0173 void cmd_x_ping(const QString ¶m); 0174 void cmd_version(const QString ¶m); 0175 void cmd_x_loadtemplatefile(const QString ¶m); 0176 void cmd_info(const QString ¶m); 0177 void cmd_fget(const QString ¶m); 0178 void cmd_fset(const QString ¶m); 0179 void cmd_beginblock(const QString ¶m); 0180 void cmd_endblock(const QString ¶m); 0181 void cmd_stop(const QString ¶m); 0182 struct Cmd { 0183 const char *cmd; 0184 void (DebconfFrontend::*run)(const QString &); 0185 }; 0186 static const Cmd commands[]; 0187 0188 // TODO this is apparently very much untested 0189 QString substitute(const QString &key, const QString &rest) const; 0190 /** 0191 * Transforms the string camel cased and return it's enum given the enum name 0192 */ 0193 template<class T> static int enumFromString(const QString &str, const char *enumName); 0194 PropertyKey propertyKeyFromString(const QString &string); 0195 0196 typedef QHash<PropertyKey, QString> Properties; 0197 typedef QHash<QString, QString> Substitutions; 0198 typedef QHash<QString, bool> Flags; 0199 0200 QHash<QString, Properties> m_data; 0201 QHash<QString, Substitutions> m_subst; 0202 QHash<QString, QString> m_values; 0203 QHash<QString, Flags> m_flags; 0204 QString m_title; 0205 QStringList m_input; 0206 }; 0207 0208 /** 0209 * DebconfFrontend which communicates with Debconf over UNIX socket. Even when 0210 * finished signal is emitted, DeconfFrontend will reset and continue to 0211 * listen for new connections on the socket. 0212 */ 0213 class DebconfFrontendSocket : public DebconfFrontend { 0214 Q_OBJECT 0215 0216 public: 0217 /** 0218 * Instantiates the class and starts listening for new connections on the 0219 * socket at \p socketName path. Please note that any file at \p socketName 0220 * will be removed if it exists prior to the call of this constructor. 0221 */ 0222 explicit DebconfFrontendSocket(const QString &socketName, QObject *parent = 0); 0223 0224 /** 0225 * Removes socket when the object is destroyed. 0226 */ 0227 virtual ~DebconfFrontendSocket(); 0228 0229 /** 0230 * Overridden to trigger termination of the current connection. 0231 */ 0232 void cancel() override; 0233 0234 protected: 0235 inline QIODevice* getReadDevice() const override { return m_socket; } 0236 inline QIODevice* getWriteDevice() const override { return m_socket; } 0237 void reset() override; 0238 0239 private Q_SLOTS: 0240 /** 0241 * Called when a new connection is received on the socket 0242 * If we are already handlyng a connection we refuse the others 0243 */ 0244 void newConnection(); 0245 0246 private: 0247 QLocalServer *m_server; 0248 QLocalSocket *m_socket; 0249 }; 0250 0251 /** 0252 * DebconfFrontend which communicates with Debconf over FIFO pipes. Once 0253 * finished signal is emitted, the frontend is no longer usable as pipes 0254 * have been been closed by then. 0255 */ 0256 class DebconfFrontendFifo : public DebconfFrontend { 0257 0258 public: 0259 /** 0260 * Instantiates the class and prepares for communication with Debconf over 0261 * \p readfd (read) and \p writefd (write) FIFO file descriptors. 0262 */ 0263 explicit DebconfFrontendFifo(int readfd, int writefd, QObject *parent = 0); 0264 0265 /** 0266 * Overridden to trigger full disconnection 0267 */ 0268 void cancel() override; 0269 0270 protected: 0271 QIODevice* getReadDevice() const override { return m_readf; } 0272 QIODevice* getWriteDevice() const override { return m_writef; } 0273 void reset() override; 0274 bool process() override; 0275 0276 private: 0277 QFile *m_readf; 0278 QFile *m_writef; 0279 QSocketNotifier *m_readnotifier; 0280 }; 0281 0282 } 0283 0284 #endif