summaryrefslogtreecommitdiffstats
path: root/src/apt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/apt.cpp')
-rw-r--r--src/apt.cpp946
1 files changed, 946 insertions, 0 deletions
diff --git a/src/apt.cpp b/src/apt.cpp
new file mode 100644
index 0000000..9a68991
--- /dev/null
+++ b/src/apt.cpp
@@ -0,0 +1,946 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Sylvain Joyeux *
+ * The forms are by Willy De la Court <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "apt.h"
+#include "regexps.h"
+
+#include "dpkg.h"
+
+#include "parsers/parsers.h"
+
+#include <qcstring.h>
+
+#include <kapplication.h>
+#include <kinstance.h>
+#include <kglobal.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kio/slavebase.h>
+#include <kmessagebox.h>
+
+#include <kdebug.h>
+
+#include <qregexp.h>
+
+#include <stdlib.h>
+
+#include <config.h>
+
+using namespace KIO;
+
+/*************************************************************************
+* Common definitions of HTML fragments
+*/
+
+static const QString
+ html_preamble("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Strict//EN\"\n"
+ "\t\"http://www.w3.org/TR/html4/strict.dtd\">\n"
+ "<html>\n");
+static const QString
+ html_redirect(html_preamble +
+ QString("<head>\n"
+ "\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"
+ "\t<meta http-equiv=\"Refresh\" content=\"0 ; URL=%1\">\n"
+ "</head>\n"
+ "\n<body></body>\n"
+ "</html>"));
+
+static const QString
+ html_head(html_preamble +
+ QString("<head>\n"
+ "\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
+ "\t<link rel=\"stylesheet\" href=\"file:%1\">\n"
+ "\t<title>%2</title>\n"
+ "</head>\n\n"
+ "<body>\n"));
+
+static QString close_html_head();
+static QString open_html_head(const QString& title, bool links, AptProtocol const& config)
+{
+
+ static const QString
+ html_head_table(
+ "<table class=\"header\" style=\"background-image: url(file:%1);\"\n"
+ "\t\tcellspacing=\"0\" cellpadding=\"0\">\n"
+ "<tr>\n"
+ "\t<td class=\"logo\" %2><img src=\"file:%3\" alt=\"%4\" style=\"border: 0px\" /></td>\n"
+ "\t<td class=\"header-title\">%4</td>\n");
+
+ QString rowspan;
+ if (links) rowspan = "rowspan=\"2\"";
+ QString ret =
+ html_head
+ .arg(config.stylesheet())
+ .arg(title)
+ + html_head_table
+ .arg(config.header_background())
+ .arg(rowspan)
+ .arg(config.logo())
+ .arg(config.logo_alt())
+ .arg(title);
+
+ if (links)
+ {
+ return ret +
+ "</tr>\n"
+ "<tr>\n"
+ "\t<td class=\"links\">\n"
+ "\t<table class=\"links\" cellspacing=\"0\" cellpadding=\"0\">\n"
+ "\t<tr>\n";
+ }
+ else
+ {
+ return ret + "</tr>\n</table>\n\n";
+ }
+}
+static QString add_html_head_link(const QString& url, const QString& name, const QString& long_desc)
+{
+ static const QString format("\t\t<td><a href=\"%1\" title=\"%2\">%3</a></td>\n");
+ return format.arg(url).arg(long_desc).arg(name);
+}
+static QString close_html_head()
+{
+ return "\t</tr>\n"
+ "\t</table>\n"
+ "\t</td>\n"
+ "</tr>"
+ "</table>";
+}
+
+static const QString
+ html_tail("<div class=\"footer\">%1</div>\n"
+ "</body>\n"
+ "</html>");
+
+
+QString AptProtocol::make_html_tail(const QString& note, bool with_form)
+{
+ with_form = m_search && with_form;
+
+ QString ret;
+ if (with_form)
+ ret = "<hr>\n" + make_html_form();
+
+ if (!note.isEmpty())
+ ret += html_tail.arg(note + ". " + i18n("Page generated by kio_apt."));
+ else ret += html_tail.arg(i18n("Page generated by kio_apt."));
+
+ return ret;
+}
+
+/**********************************************************************************
+ * Search form
+ */
+
+static const QString
+ html_form_begin("\n<form action=\"apt:/\" method=\"GET\">\n"
+ "<table class=\"query\">\n");
+static const QString
+ html_form_end("<tr>\n"
+ "\t<td class=\"button\" colspan=\"2\"><input type=\"submit\" value=\"%1\"></td>\n"
+ "</tr>\n"
+ "</table>\n"
+ "</form>\n");
+
+static const QString
+ html_form_line("<tr>\n"
+ "\t<td><label for=\"%1\">%2</label></td>\n"
+ "\t<td><input type=\"text\" name=\"%3\" id=\"%4\"></td>\n"
+ "</tr>\n");
+
+static QString make_html_form_line(const QString& type, const QString& label)
+{ return html_form_line.arg(type).arg(label).arg(type).arg(type); }
+
+
+static QString make_extform_cmd(bool ext_form, const KURL& query)
+{
+ QString cmd = ext_form ? "0" : "1";
+ QString msg = ext_form ? i18n("Hide extended form") : i18n("Show extended form");
+
+ KURL url(query);
+ url.addQueryItem("extended_form", cmd);
+ url.setRef("extformcmd");
+
+ return
+ "<div class=\"command\" id=\"extformcmd\">\n"
+ "\t<a href=\"" + url.htmlURL() + "\">[" + msg + "]</a>\n"
+ "</div>\n";
+}
+
+/** Prints the HTML code for the query form */
+QString AptProtocol::make_html_form() const
+{
+ bool can_fsearch = false;
+ bool ext_form = KGlobal::config() -> readBoolEntry("extended_form", true);
+ // Only in config-file. Needed for some dpkg-based distros that are not Debian
+ can_fsearch = can_searchfile(true);
+
+ bool online = false;
+ bool online_form = KGlobal::config() -> readBoolEntry("online_form", true);
+ if (m_adept_batch)
+ online = online_form && (!m_internal) && ext_form && m_adept_batch -> capabilities(PackageManager::ONLINE);
+
+ QString ret;
+ QTextOStream stream(&ret);
+ stream << make_extform_cmd(ext_form, m_query);
+
+ if (online)
+ stream << "<table class=\"queryform\"><tr><td>\n";
+
+ stream << html_form_begin;
+ stream << "<tr><td colspan=\"2\" class=\"title\">" + i18n("Offline search") + "</td></tr>" << endl;
+ stream << make_html_form_line("search", i18n("Package search"));
+ if (ext_form)
+ {
+ if (can_fsearch)
+ stream << make_html_form_line("fsearch", i18n("File search"));
+ stream << make_html_form_line("show", i18n("Package info"));
+ }
+ stream << html_form_end.arg( i18n("Search") );
+
+ if (online)
+ {
+ stream << "\n</td><td>\n";
+ stream << m_adept_batch -> getOnlineForm();
+ stream << "\n</td></tr>\n</table>";
+ }
+
+ return ret;
+}
+
+/****************************************************************************************/
+
+AptProtocol::AptProtocol( const QCString &pool_socket, const QCString &app_socket )
+ : SlaveBase( "kio_apt", pool_socket, app_socket ),
+ m_adept_batch(0), m_parser(0)
+
+{
+ KStandardDirs* dirs = KGlobal::dirs();
+ m_stylesheet = dirs->findResource( "data", "kio_apt/kio_apt.css" );
+
+ m_logo = dirs->findResource( "data", "kio_apt/"
+ + KGlobal::config() -> readEntryUntranslated("logo", "kdedeb_logo.png" ) );
+
+ m_header_background = dirs->findResource( "data", "kio_apt/"
+ + KGlobal::config() -> readEntryUntranslated("background", "headerbg.png" ) );
+
+ m_logo_alt = KGlobal::config() -> readEntryUntranslated("alt_tag", i18n("KDE on Debian") );
+
+ connect(&m_process, SIGNAL(token(const QString&, const QString&)),
+ this, SLOT(token_dispatch(const QString&, const QString&)));
+
+ m_adept_batch = new Dpkg(this);
+
+ if (m_adept_batch)
+ {
+ connect(m_adept_batch, SIGNAL(token(const QString&, const QString&)),
+ this, SLOT(token_dispatch(const QString&, const QString&)));
+ }
+}
+
+AptProtocol::~AptProtocol() {}
+
+QString AptProtocol::stylesheet() const { return m_stylesheet; }
+QString AptProtocol::logo() const { return m_logo; }
+QString AptProtocol::logo_alt() const { return m_logo_alt; }
+QString AptProtocol::header_background() const { return m_header_background; }
+
+void AptProtocol::token_dispatch(const QString& name, const QString& val)
+{
+ if (m_parser.get())
+ (*m_parser)(this, name, val);
+}
+
+void AptProtocol::data(const QCString& string)
+{
+ using namespace Parsers;
+ (*this) << string;
+}
+
+void AptProtocol::data(const QString& string)
+{
+ using namespace Parsers;
+ (*this) << string;
+}
+
+void AptProtocol::data(const char* string)
+{
+ using namespace Parsers;
+ (*this) << string;
+}
+
+void AptProtocol::data(const QByteArray& array)
+{ SlaveBase::data(array); }
+
+void AptProtocol::mimetype( const KURL & /*url*/ )
+{
+ mimeType( "text/html" );
+ finished();
+}
+
+bool AptProtocol::check_validpackage(const QString& query)
+{
+ static QRegExp rx_pkgname(rxs_pkgname);
+ if (!rx_pkgname.exactMatch(query))
+ {
+ error( ERR_SLAVE_DEFINED, i18n("\"%1\" is not a valid package name").arg(query) );
+ return false;
+ }
+ return true;
+}
+
+
+/********************************************************************
+ * Main entry point
+ */
+
+static QString read_option(QMap<QString, QString>& map, const QString& name, const QString& def)
+{
+ if (!map.contains(name)) return def;
+ QString ret = map[name];
+ map.remove(name);
+ return ret;
+}
+
+void AptProtocol::get ( const KURL& url )
+{
+ /* The queries have two possible formats :
+
+ - clean way to call a command
+ apt:/command?query&option=value&option=value&...
+ - needed to simplify forms
+ apt:/?command=query&command2=&command3=&option=value&option=value&...
+ - calls only the query form page
+ apt:/
+ */
+
+ typedef void (AptProtocol::*Command)(const QString&, const QueryOptions&);
+ static const QString commands[] =
+ { "search", "show", "policy",
+ "fsearch", "list", "online",
+ "get", QString::null };
+ static const Command methods[] =
+ { &AptProtocol::search, &AptProtocol::show, &AptProtocol::policy,
+ &AptProtocol::searchfile, &AptProtocol::listfiles, &AptProtocol::online,
+ &AptProtocol::adept_batch };
+
+ QString command, query;
+ Command method = 0;
+ QueryOptions options = url.queryItems(KURL::CaseInsensitiveKeys);
+
+ // canonize the part before ? : remove the first /
+ QString path = url.path();
+ QString host = url.host();
+
+ if ( path.isEmpty() && !host.isEmpty() )
+ {
+ path = host;
+ }
+
+ if (path [0] == '/')
+ path = path.right(path.length() - 1);
+
+ for (int cmd_idx = 0; !commands[cmd_idx].isNull(); ++cmd_idx)
+ {
+ const QString cmd_it = commands[cmd_idx];
+
+ // Look if the command is in the path part
+ if (command.isEmpty() && cmd_it == path)
+ {
+ command = cmd_it;
+ method = methods[cmd_idx];
+ }
+ if (options.contains(cmd_it))
+ {
+
+ if (options[cmd_it].isEmpty() && !options[cmd_it].isNull())
+ { // we have a &command=& format, we remove it
+ options.remove(cmd_it);
+ }
+ else if (command.isEmpty() && !options[cmd_it].isEmpty())
+ { // the command is set in the options map
+ command = cmd_it;
+ method = methods[cmd_idx];
+ query = options[cmd_it];
+ options.remove(cmd_it);
+ }
+ }
+ }
+
+ // Well, we have no query for now, let's find it
+ if (query.isEmpty())
+ {
+ for (QueryOptions::Iterator i = options.begin(); i != options.end(); ++i)
+ {
+ if ((*i).isNull())
+ {
+ query = KURL::decode_string(i.key());
+ options.remove(i);
+ break;
+ }
+ }
+ }
+
+ // Interpret the ioslave config options
+ // and remove them from the options map
+ QString opt = read_option(options, "extended_form", QString::null);
+ if (!opt.isNull())
+ {
+ bool ext_form = (opt != "0");
+ KGlobal::config() -> writeEntry("extended_form", ext_form);
+ }
+
+ // Enable install/remove/upgrade/...
+ opt = read_option(options, "enable_actions", "1");
+ m_act = (opt != "0");
+
+ opt = read_option(options, "enable_search", "1");
+ m_search = (opt != "0");
+
+ // Allow links outside of apt:/ hierarchy
+ opt = read_option(options, "stay_internal", "0");
+ m_internal = (opt == "1");
+
+ // Sync the config (must use kcfg sometime :p)
+ KGlobal::config() -> sync();
+
+ if (command.isEmpty() || query.isEmpty())
+ {
+ //If path isn't empty, then a package is to be installed via an apt:/ link
+ if ( !path.isEmpty())
+ {
+ query = "install";
+ options["package"] = path;
+ options["weblinkinstall"] = 1;
+ adept_batch(query, options);
+ return;
+ }
+
+ // No query or no command, we go in help mode
+ m_query = buildURL(KURL("apt:/"));
+ help();
+ }
+ else
+ {
+ m_query = buildURL(command, query);
+ m_query.setHTMLRef(url.htmlRef());
+ for (QueryOptions::ConstIterator i = options.begin(); i != options.end(); ++i)
+ m_query.addQueryItem(i.key(), i.data());
+
+ kdDebug() << "Old url " << url << ", new url " << m_query << endl;
+
+ if (m_query != url)
+ {
+ redirection(m_query);
+ data(QByteArray());
+ finished();
+ return;
+ }
+
+ (this->*method)(query, options);
+ }
+}
+
+
+/***********************************************************************************
+*
+* form
+*
+*/
+
+void AptProtocol::help()
+{
+ mimeType("text/html");
+
+ QString buffer;
+ QTextOStream stream(&buffer);
+ stream
+ << open_html_head(i18n("Search Form"), false, *this)
+ << make_html_form()
+ << make_html_tail(QString::null, false);
+ data(buffer);
+ data(QByteArray());
+ finished();
+}
+
+
+
+
+
+
+
+/***********************************************************************************
+ * apt-cache search
+ */
+
+void AptProtocol::search( const QString& query, const QueryOptions& /*options*/ )
+{
+ mimeType("text/html");
+
+ data(open_html_head(i18n("Package search result for \"%1\"").arg(query), false, *this));
+
+ m_parser.reset(new Parsers::Search);
+ (*m_parser)(this, "begin", query);
+ if (!m_process.search( query ))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("Error launching the search").arg(query));
+ return;
+ }
+ (*m_parser)(this, "end", QString::null);
+
+ data(make_html_tail( i18n("%1 results").arg(m_parser -> result_count())) );
+ data(QByteArray());
+ finished();
+}
+
+
+
+
+
+
+/***********************************************************************************
+ * apt-cache show
+ */
+
+static QString filelist_cmd(bool show_filelist, const KURL& query)
+{
+ QString value = show_filelist ? "0" : "1";
+ QString msg = show_filelist ? i18n("Hide file list") : i18n("Show file list");
+
+ KURL url(query);
+ url.addQueryItem("show_filelist", value);
+ url.setRef("filelistcmd");
+
+ return
+ "<div class=\"command\" id=\"filelistcmd\">\n"
+ "\t<a href=\"" + url.htmlURL() + "\">"
+ "[" + msg + "]"
+ "</a>\n"
+ "</div>";
+}
+
+void AptProtocol::show(const QString& package, const QueryOptions& options)
+{
+ if (!check_validpackage(package)) return;
+
+ if (options.contains("show_filelist"))
+ {
+ KGlobal::config() -> writeEntry("show_filelist", options["show_filelist"] != "0");
+ KGlobal::config() -> sync();
+ }
+
+ mimeType("text/html");
+
+ QString installed_version;
+
+ /** First, we parse policy
+ * We use here the fact that HTML is generated
+ * during the call of (*policy)(...,"end",...),
+ * since the header changes when the package
+ * is installed or not */
+ Parsers::Policy* policy = new Parsers::Policy(package, m_act);
+ m_parser.reset(policy);
+ (*m_parser)(this, "begin", QString::null);
+ {
+ if (!m_process.policy( package ))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("Can't launch \"apt-cache policy %1\"").arg(package));
+ return;
+ }
+
+ installed_version = policy->getInstalled();
+ bool can_list = can_listfiles(!installed_version.isEmpty());
+ QString buffer;
+ QTextOStream s(&buffer);
+ if (can_list)
+ {
+ KURL url = buildURL("list", package);
+ s << open_html_head(i18n("Package description for \"%1\"").arg(package), true, *this)
+ << add_html_head_link(url.htmlURL(), i18n("List package files"), "")
+ << close_html_head();
+ }
+ else
+ {
+ s << open_html_head(i18n("Package description for \"%1\"").arg(package), false, *this);
+ }
+ data(buffer);
+ }
+ (*m_parser)(this, "end", QString::null);
+
+
+ /** Add package description section */
+ m_parser.reset(new Parsers::Show(package, installed_version, m_act));
+ (*m_parser)(this, "begin", QString::null);
+ {
+ if (!m_process.show(package))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("Can't launch \"apt-cache show %1\"").arg(package));
+ return;
+ }
+ if (!m_parser -> result_count())
+ {
+ data("<div class=\"error\">" + i18n("No package found named \"%1\"").arg(package) + "</div>\n");
+ data(make_html_tail());
+ data(QByteArray());
+ finished();
+ return;
+ }
+ }
+ (*m_parser)(this, "end", QString::null);
+
+
+
+ /** Add file list (if enabled) */
+ bool show_filelist = KGlobal::config() -> readBoolEntry("show_filelist", false);
+ if ( show_filelist )
+ {
+ if (can_listfiles(!installed_version.isEmpty()))
+ {
+ data(
+ "<hr>\n"
+ + filelist_cmd(show_filelist, m_query)
+ + "<div class=\"filelist\">\n");
+
+ m_parser.reset(new Parsers::List(!m_internal));
+ (*m_parser)(this, "begin", QString::null);
+ if (!m_adept_batch -> list(package))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("Error listing files of %1").arg(package));
+ return;
+ }
+ (*m_parser)(this, "end", QString::null);
+
+ data("\n</div>\n");
+ }
+ else // cannot list files
+ {
+ data(
+ "<hr>\n"
+ + filelist_cmd(show_filelist, m_query)
+ + "<div class=\"error\">" + i18n("Cannot list files for non-installed packages") + "</div>\n");
+ }
+ }
+ else
+ {
+ data("<hr>\n" + filelist_cmd(show_filelist, m_query));
+ }
+
+
+ data(make_html_tail());
+ data(QByteArray());
+ finished();
+}
+
+
+
+
+/***********************************************************************************
+ * apt-cache policy
+ */
+
+void AptProtocol::policy( const QString& query, const QueryOptions& /*options*/ )
+{
+ if (!check_validpackage(query)) return;
+
+ mimeType("text/html");
+
+ data( open_html_head(i18n("Apt policy for \"%1\"").arg(query), false, *this) );
+
+ m_parser.reset(new Parsers::Policy(query, m_act));
+ (*m_parser)(this, "begin", QString::null);
+ if (!m_process.policy( query ))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("Can't launch the policy for %1").arg(query));
+ return;
+ }
+ (*m_parser)(this, "end", QString::null);
+
+ data(make_html_tail());
+ data(QByteArray());
+ finished();
+}
+
+
+
+/***********************************************************************************
+* Search the package which contains a specific file
+*/
+
+static const QString
+ html_dpkgs_begin("\n\n<table>\n"),
+ html_dpkgs_end("\n\n</table>\n");
+
+
+bool AptProtocol::can_searchfile(bool is_installed) const
+{
+ if (!m_adept_batch) return false;
+ int caps = m_adept_batch -> capabilities(PackageManager::SEARCH_FILE | PackageManager::OFFLINE);
+ if (!caps) return false;
+ return is_installed || !(caps & PackageManager::INSTALLED_ONLY);
+}
+void AptProtocol::searchfile(const QString& query, const QueryOptions& /*options*/)
+{
+ if (!can_searchfile(true)) return;
+
+ mimeType("text/html");
+ data( open_html_head(i18n("File search for \"%1\"").arg(query), false, *this) + html_dpkgs_begin );
+
+ m_parser.reset(new Parsers::FileSearch);
+ (*m_parser)(this, "begin", QString::null);
+ if (!m_adept_batch -> search( query ))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("Can't launch the package manager").arg(query));
+ return;
+ }
+ (*m_parser)(this, "end", QString::null);
+
+ data( html_dpkgs_end + make_html_tail(i18n("%1 files found").arg(m_parser -> result_count())) );
+ data(QByteArray());
+ finished();
+}
+
+
+
+
+/***********************************************************************************
+* List the files of a package
+*/
+
+bool AptProtocol::can_listfiles(bool is_installed) const
+{
+ if (!m_adept_batch) return false;
+ int caps = m_adept_batch -> capabilities(PackageManager::LIST_FILES | PackageManager::OFFLINE);
+ if (!caps) return false;
+ return is_installed || !(caps & PackageManager::INSTALLED_ONLY);
+}
+
+void AptProtocol::listfiles(const QString& query, const QueryOptions& /*options*/)
+{
+ if (!can_listfiles(true)) return;
+ if (!check_validpackage(query)) return;
+
+ mimeType("text/html");
+
+ KURL ret_url = buildURL("show", query);
+
+ QString buffer;
+ QTextOStream stream(&buffer);
+ stream
+ << open_html_head(i18n("Files in \"%1\"").arg(query), true, *this)
+ << add_html_head_link(ret_url.htmlURL(), i18n("Show package info"), "")
+ << close_html_head()
+ << endl;
+ data(buffer);
+
+ m_parser.reset(new Parsers::List(!m_internal));
+ (*m_parser)(this, "begin", QString::null);
+ if (!m_adept_batch -> list( query ))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("Can't launch the package manager").arg(query));
+ return;
+ }
+ (*m_parser)(this, "end", QString::null);
+
+ data(make_html_tail());
+ data(QByteArray());
+ finished();
+}
+
+
+
+
+/***********************************************************************************
+ * Go use online search services (like packages.debian.org for instance)
+ */
+
+//bool AptProtocol::can_online(int mode) const
+//{
+//// if (!m_adept_batch) return false;
+//// return m_adept_batch -> capabilities(PackageManager::ONLINE | mode);
+// return false;
+//}
+
+void AptProtocol::online(const QString& query, const QueryOptions& options)
+{
+ QString url = m_adept_batch -> getOnlineURL(query, options);
+ redirection(url);
+ finished();
+ return;
+}
+
+/***********************************************************************************
+ * Send commands for adept_batch
+ */
+void AptProtocol::adept_batch(const QString& query, const QueryOptions& options)
+{
+ p=NULL;
+
+ QString command;
+ QString url;
+ QStringList plist;
+ QStringList puninst;
+ QStringList pinst;
+ int pcount;
+ int ip;
+
+ if (query == "install" || query.isEmpty()) {
+ command = "kdesu adept_batch install ";
+ } else if (query == "remove") {
+ command = "kdesu adept_batch remove ";
+ }
+
+ if (command.isEmpty())
+ {
+ error(ERR_SLAVE_DEFINED, i18n("No package manager command specified"));
+ return;
+ }
+
+ if (!options.contains("package"))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("No package specified"));
+ return;
+ }
+
+ plist = QStringList::split(", ", options["package"], false);
+ pcount = plist.count();
+ command += plist.join(" ");
+
+ if (pcount == 1)
+ {
+ if (query == "install")
+ ip = SlaveBase::messageBox(QuestionYesNo, i18n("Do you want to install %1 ?").arg(plist[0]), i18n("Package Installation"));
+ else
+ ip = SlaveBase::messageBox(QuestionYesNo, i18n("Do you want to remove %1 ?").arg(plist[0]), i18n("Package Removal"));
+ }
+ else
+ {
+ if (query == "install")
+ ip = SlaveBase::messageBox(QuestionYesNo,i18n("Do you want to install the following %1 packages ?\n%2").arg(pcount).arg(options["package"]));
+ else
+ ip = SlaveBase::messageBox(QuestionYesNo,i18n("Do you want to remove the following %1 packages ?\n").arg(pcount).arg(options["package"]));
+ }
+
+ kdDebug(DEBUG_ZONE) << command << endl;
+
+ if (ip == KMessageBox::Yes)
+ {
+ p = new KShellProcess;
+ p->clearArguments();
+ *p << command;
+ p->start( KProcess::Block, KProcess::All );
+
+ for(int i = 0; i != pcount; ++i)
+ {
+ QString installed_version;
+
+ Parsers::Policy* policy = new Parsers::Policy(plist[i], m_act);
+ m_parser.reset(policy);
+ (*m_parser)(this, "begin", QString::null);
+ {
+ if (!m_process.policy( plist[i] ))
+ {
+ error(ERR_SLAVE_DEFINED, i18n("Can't launch \"apt-cache policy %1\"").arg(plist[i]));
+ return;
+ }
+
+ installed_version = policy->getInstalled();
+ if (installed_version.isEmpty())
+ {
+ puninst += plist[i];
+ }
+ else
+ {
+ pinst += plist[i];
+ }
+ }
+ }
+
+ if (options.contains("weblinkinstall"))
+ {
+ if (puninst.count() == 0)
+ {
+ messageBox(Information,i18n("Installation successfull."));
+ }
+ else
+ {
+ QString toto = puninst.join(" ");
+ messageBox(Information,i18n("There was a problem installing %1.").arg(toto));
+ }
+ return;
+ }
+ else
+ {
+ url = "apt:/show?";
+ // Outside of a weblink, only one package can be installed at time
+ url += plist[0];
+ redirection(url);
+ data(QByteArray());
+ finished();
+ return;
+ }
+ }
+ else
+ {
+ return;
+ }
+}
+
+KURL AptProtocol::buildURL( const QString & command, const QString & query ) const
+{
+ KURL url;
+ url.setProtocol("apt");
+ if (!command.startsWith("/"))
+ url.setPath("/" + command);
+ else
+ url.setPath(command);
+ url.setQuery(query);
+ return buildURL(url);
+}
+
+KURL AptProtocol::buildURL( const KURL& query ) const
+{
+ KURL url(query);
+
+ if (!m_act)
+ url.addQueryItem("enable_actions", "0");
+ if (!m_search)
+ url.addQueryItem("enable_search", "0");
+ if (m_internal)
+ url.addQueryItem("stay_internal", "1");
+
+ return url;
+}
+
+/***********************************************************************************
+*
+* kdemain
+*
+*/
+
+extern "C" {
+ int kdemain( int argc, char **argv ) {
+ KInstance instance( "kio_apt" );
+
+ if ( argc != 4 ) {
+ kdDebug( DEBUG_ZONE ) << "Usage: kio_apt protocol domain-socket1 domain-socket2" << endl;
+ exit ( -1 );
+ }
+
+ AptProtocol slave( argv[ 2 ], argv[ 3 ] );
+ slave.dispatchLoop();
+
+ return 0;
+ }
+}
+
+#include "apt.moc"