summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2018-08-26 00:18:56 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2018-08-26 00:18:56 +0900
commita18f9fcc94b6982fecb8b75ccb5c21b213e78706 (patch)
treedb1e3d87eaba2952829717f25a51e9b7a5c18d8c /src
parent3eaf665507fb178a718ef9f57f2bb9ec908d5ac8 (diff)
downloadtdeio-gopher-a18f9fcc94b6982fecb8b75ccb5c21b213e78706.tar.gz
tdeio-gopher-a18f9fcc94b6982fecb8b75ccb5c21b213e78706.zip
Adapted to TDE and TQt3. Build and work fine. No helpbook or
translation are built yet. Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt40
-rw-r--r--src/gopher.protocol9
-rw-r--r--src/tdeio_gopher.cpp345
-rw-r--r--src/tdeio_gopher.h36
4 files changed, 430 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..65045d6
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,40 @@
+
+
+
+#set(tdeio_man_PART_SRCS tdeio_gopher.cpp)
+
+#kde4_add_plugin(tdeio_gopher ${tdeio_man_PART_SRCS})
+
+
+#find_package(Msgfmt REQUIRED)
+#find_package(Gettext REQUIRED)
+#add_subdirectory( po )
+#add_subdirectory( doc-translations )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+#####add_subdirectory(doc)
+
+##### other data ################################
+
+install( FILES gopher.protocol DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+##### tdeio_gopher (module) #######################
+
+set( target tdeio_gopher )
+
+tde_add_kpart( ${target} AUTOMOC
+ SOURCES tdeio_gopher.cpp
+ LINK tdeio-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/src/gopher.protocol b/src/gopher.protocol
new file mode 100644
index 0000000..e0f5ffc
--- /dev/null
+++ b/src/gopher.protocol
@@ -0,0 +1,9 @@
+[Protocol]
+exec=tdeio_gopher
+protocol=gopher
+input=none
+output=filesystem
+reading=true
+defaultMimetype=application/octet-stream
+determineMimetypeFromExtension=false
+X-DocPath=tdeioslave/gopher/index.html
diff --git a/src/tdeio_gopher.cpp b/src/tdeio_gopher.cpp
new file mode 100644
index 0000000..cbfdd33
--- /dev/null
+++ b/src/tdeio_gopher.cpp
@@ -0,0 +1,345 @@
+/****************************************************************************
+ * Copyright (C) 2003-2008 by Albert Astals Cid *
+ * aacid@kde.org *
+ * *
+ * 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 "tdeio_gopher.h"
+
+#include <stdlib.h>
+#include <kurl.h>
+#include <kdebug.h>
+#include <kmdcodec.h>
+#include <kinstance.h>
+#include <kdebug.h>
+#include <tdelocale.h>
+#include <kmimetype.h>
+
+#include <ntqbuffer.h>
+#include <ntqfile.h>
+
+using namespace TDEIO;
+
+extern "C"
+{
+ int KDE_EXPORT kdemain( int argc, char **argv )
+ {
+ TDEInstance instance( "tdeio_gopher" );
+
+ if (argc != 4)
+ {
+ fprintf(stderr, "Usage: tdeio_gopher protocol domain-socket1 domain-socket2\n");
+ exit(-1);
+ }
+
+ GopherProtocol slave(argv[2], argv[3]);
+ slave.dispatchLoop();
+ return 0;
+ }
+}
+
+
+/* gopher */
+
+GopherProtocol::GopherProtocol(const TQCString &pool_socket, const TQCString &app_socket)
+ : TCPSlaveBase(70, "gopher", pool_socket, app_socket)
+{
+}
+
+void GopherProtocol::get(const KURL& url )
+{
+ // gopher urls are
+ // gopher://<host>:<port>/<gopher-path>
+ //
+ // where <gopher-path> is one of
+ //
+ // <gophertype><selector>
+ // <gophertype><selector>%09<search>
+ // <gophertype><selector>%09<search>%09<gopher+_string>
+ int port;
+ TQChar type;
+ TQString path(url.path());
+ TQString query(url.query());
+
+ // determine the type
+ if (path != "/" && path != "") type = path[1];
+ else type = '1';
+
+ // determine the port
+ if (url.port() > 0) port = url.port();
+ else port = 70;
+
+ setBlockConnection(true);
+
+ // connect to the host
+ if (!connectToHost(url.host(), port)) return;
+
+ if (type == '7' && query.isNull())
+ {
+ closeDescriptor();
+ handleSearch(url.host(), path, port);
+ }
+ else
+ {
+ int i, bytes;
+ char aux[10240];
+ TQBuffer received;
+ received.open(IO_WriteOnly);
+
+ infoMessage(i18n("Connecting to %1...").arg(url.host()));
+ infoMessage(i18n("%1 contacted. Retrieving data...").arg(url.host()));
+ bytes = 0;
+
+ // send the selector
+ path.remove(0, 2);
+ write(path.latin1(), path.length());
+ write(query.latin1(), query.length());
+ write("\r\n", 2);
+
+ // read the data
+ while((i = read(aux, 10240)) > 0)
+ {
+ bytes += i;
+ received.writeBlock(aux, i);
+ processedSize(bytes);
+ infoMessage(i18n("Retrieved %1 bytes from %2...").arg(bytes).arg(url.host()));
+ }
+
+ if (type == '1' || type =='7')
+ {
+ processDirectory(received.buffer().data(), url.host(), url.path());
+ }
+ else
+ {
+ KMimeType::Ptr result = KMimeType::findByContent(received.buffer());
+ mimeType(result->name());
+ data(received.buffer());
+ }
+ closeDescriptor();
+ }
+ finished();
+}
+
+void GopherProtocol::processDirectory(const TQString &received_str, const TQString &host, const TQString &path)
+{
+ TQString received(received_str);
+ TQString pathToShow;
+ if (path == "/" || path == "/1")
+ {
+ pathToShow = "";
+ }
+ else
+ {
+ pathToShow = path;
+ }
+ mimeType("text/html");
+ TQString info;
+ TQString show("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\t<head>\n\t\t<title>");
+ show += host.utf8();
+ show += pathToShow.utf8();
+ show += TQString("</title>\n\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
+ "\t\t<style type=\"text/css\">\n\t\t\t.info{ font-size : small; display : block; font-family : monospace; "
+ "white-space : pre; margin-left : 18px; }\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<h1>");
+ show += host.utf8();
+ show += pathToShow.utf8();
+ show += "</h1>\n";
+ int i, remove;
+ findLine(received, &i, &remove);
+ while(i != -1)
+ {
+ processDirectoryLine(received.left(i), show, info);
+ received.remove(0, i + remove);
+ findLine(received, &i, &remove);
+ }
+ show += "\t</body>\n</html>\n";
+ TQByteArray showdata;
+ showdata.duplicate(show.utf8(), show.length());
+ data(showdata);
+}
+
+void GopherProtocol::processDirectoryLine(const TQString &d, TQString &show, TQString &info)
+{
+ // gopher <type><display><tab><selector><tab><server><tab><port><\r><\n>
+ // gopher+ <type><display><tab><selector><tab><server><tab><port><tab><things><\r><\n>
+ int i;
+ TQString data(d);
+
+ TQString type = data.left(1);
+ data.remove(0, 1);
+
+ i = data.find("\t");
+ TQString name = data.left(i);
+ data.remove(0, i + 1);
+
+ i = data.find("\t");
+ TQString url = data.left(i);
+ data.remove(0, i + 1);
+
+ i = data.find("\t");
+ TQString server = data.left(i);
+ data.remove(0, i + 1);
+
+ TQString port = parsePort(data);
+
+ if (type == "i")
+ {
+ if (!info.isEmpty())
+ info.append("\n");
+ info.append(name);
+ }
+ else
+ {
+ if (!info.isEmpty())
+ {
+ show.append("\t\t<div class=\"info\">");
+ show.append(info);
+ show.append("</div>\n");
+ info = "";
+ }
+ // it's the final line, ignore it
+ if (type == ".") return;
+ // those are the standard gopher types defined in the rfc
+ // 0 Item is a file
+ // 1 Item is a directory
+ // 2 Item is a CSO phone-book server
+ // 3 Error
+ // 4 Item is a BinHexed Macintosh file.
+ // 5 Item is DOS binary archive of some sort. Client must read until the TCP connection closes. Beware.
+ // 6 Item is a UNIX uuencoded file.
+ // 7 Item is an Index-Search server.
+ // 8 Item points to a text-based telnet session.
+ // 9 Item is a binary file! Client must read until the TCP connection closes. Beware.
+ // + Item is a redundant server
+ // T Item points to a text-based tn3270 session.
+ // g Item is a GIF format graphics file.
+ // I Item is some kind of image file. Client decides how to display.
+ show.append("\t\t\t<div>");
+ // support the non-standard extension for URL to external sites
+ // in this case, url begins with 'URL:'
+ TQString finalUrl;
+ TQString iconUrl;
+ if (url.startsWith("URL:"))
+ {
+ finalUrl = url.mid(4);
+ iconUrl = finalUrl;
+ }
+ else
+ {
+ finalUrl = "gopher://" + server;
+ if (port != "70")
+ {
+ finalUrl.append(":");
+ finalUrl.append(port);
+ }
+ finalUrl.append('/' + type + url);
+ iconUrl = url;
+ }
+ show.append("\t\t\t\t<a href=\"");
+ show.append(finalUrl);
+ show.append("\">");
+ addIcon(type, iconUrl, show);
+ show.append(name);
+ show.append("</a><br />\n");
+ show.append("\t\t\t</div>");
+ }
+}
+
+TQString GopherProtocol::parsePort(TQString &received)
+{
+ uint i = 0;
+ TQString port;
+ bool found = false;
+ TQChar c;
+ while (!found && i < received.length())
+ {
+ c = received[i];
+ if (c.isDigit())
+ i++;
+ else
+ found = true;
+ }
+ port = received.left(i);
+ received.remove(0, i);
+ return port;
+}
+
+void GopherProtocol::findLine(const TQString &received, int *i, int *remove)
+{
+ // it's not in the rfc but most servers don't follow the spec
+ // find lines ending only in \n and in \r\n
+ int aux, aux2;
+ aux = received.find("\r\n");
+ aux2 = received.find("\n");
+
+ if (aux == -1)
+ {
+ *i = aux2;
+ *remove = 1;
+ }
+ else
+ {
+ if (aux2 < aux)
+ {
+ *remove = 1;
+ *i = aux2;
+ }
+ else
+ {
+ *remove = 2;
+ *i = aux;
+ }
+ }
+}
+
+void GopherProtocol::handleSearch(const TQString &host, const TQString &path, int port)
+{
+ TQString sPort;
+ if (port != 70) sPort = ':' + TQString::number(port);
+ mimeType("text/html");
+ TQString show("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\t<head>\n\t\t<title>");
+ show += host.utf8();
+ show += path.utf8();
+ show += "</title>\n\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
+ "\t\t<script type=\"text/javascript\">\n\t\t\tfunction search()\n\t\t\t{\n\t\t\t\tdocument.location = 'gopher://";
+ show += host.utf8();
+ show += sPort.utf8();
+ show += path.utf8();
+ show += "?' + document.getElementById('what').value;\n\t\t\t}\n\t\t</script>\n\t</head>\n\t<body>\n\t\t<h1>";
+ show.append(host.utf8());
+ show.append(path.utf8());
+ show += "</h1>\n\t\t";
+ show += i18n("Enter a search term:").utf8();
+ show += "<br />\n\t\t<input id=\"what\" type=\"text\">\n\t\t<input type=\"button\" value=\"";
+ show += i18n("Text on a search button, like at a search engine", "Search").utf8();
+ show += "\" onClick=\"search()\">\n\t</body>\n</html>\n";
+ TQByteArray showdata;
+ showdata.duplicate(show.utf8(), show.length());
+ data(showdata);
+}
+
+void GopherProtocol::addIcon(const TQString &type, const TQString &url, TQString &show)
+{
+ TQString icon;
+ if (type == "1") icon = "inode-directory.png";
+ else if (type == "3") icon = "dialog-error.png";
+ else if (type == "7") icon = "system-search.png";
+ else if (type == "g") icon = "image-gif.png";
+ else if (type == "I") icon = "image-x-generic.png";
+ else
+ {
+ KMimeType::Ptr mime = KMimeType::findByURL(KURL(url), 0, false, true);
+ icon = mime->icon(TQString::null, false);
+ }
+ TQFile file(m_iconLoader.iconPath(icon, -16));
+ file.open(IO_ReadOnly);
+ TQByteArray ba = file.readAll();
+ show.append("<img width=\"16\" height=\"16\" src=\"data:image/png;base64,");
+ show.append(KCodecs::base64Encode(ba));
+ show.append("\" /> ");
+}
diff --git a/src/tdeio_gopher.h b/src/tdeio_gopher.h
new file mode 100644
index 0000000..f0f7151
--- /dev/null
+++ b/src/tdeio_gopher.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * Copyright (C) 2003-2008 by Albert Astals Cid *
+ * aacid@kde.org *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef __tdeio_gopher_h__
+#define __tdeio_gopher_h__
+
+#include <tdeio/tcpslavebase.h>
+#include <kiconloader.h>
+
+class GopherProtocol : public TDEIO::TCPSlaveBase
+{
+ public:
+ GopherProtocol(const TQCString &pool_socket, const TQCString &app_socket);
+
+ void get(const KURL& url);
+
+ private:
+ void processDirectory(const TQString &received_str, const TQString &host, const TQString &path);
+ void processDirectoryLine(const TQString &data, TQString &show, TQString &info);
+ TQString parsePort(TQString &received);
+ void findLine(const TQString &received, int *i, int *remove);
+ void handleSearch(const TQString &host, const TQString &path, int port);
+ void addIcon(const TQString &type, const TQString &url, TQString &show);
+
+ TDEIconLoader m_iconLoader;
+};
+
+#endif
+