[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdebase/runtime/kioslave
From: Carlo Segato <brandon.ml () gmail ! com>
Date: 2008-12-03 8:56:18
Message-ID: 1228294578.264409.31687.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 891899 by segato:
port fish kioslave to windows
M +1 -5 CMakeLists.txt
M +11 -5 fish/CMakeLists.txt
M +118 -4 fish/fish.cpp
M +13 -0 fish/fish.h
A fish/generate_fishcode.py
--- trunk/KDE/kdebase/runtime/kioslave/CMakeLists.txt #891898:891899
@@ -17,12 +17,8 @@
add_subdirectory( remote )
add_subdirectory( desktop )
add_subdirectory( sftp )
+add_subdirectory( fish )
-# need kdesu
-if(UNIX)
- add_subdirectory( fish )
-endif(UNIX)
-
if(NOT WIN32)
add_subdirectory( floppy )
add_subdirectory( finger )
--- trunk/KDE/kdebase/runtime/kioslave/fish/CMakeLists.txt #891898:891899
@@ -14,20 +14,26 @@
configure_file(config-fish.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-fish.h)
########### next target ###############
-
+if(NOT WIN32)
# on Linux there is md5sum, on FreeBSD there is md5
find_program(MD5SUM_EXECUTABLE NAMES md5sum md5 )
+endif(NOT WIN32)
+
+if (MD5SUM_EXECUTABLE OR WIN32)
-if (MD5SUM_EXECUTABLE)
-
if ("${MD5SUM_EXECUTABLE}" MATCHES "md5sum")
set(CUT_ARG "-f 1") # for md5sum the sum is in the \
1st column else ("${MD5SUM_EXECUTABLE}" MATCHES "md5sum")
set(CUT_ARG "-f 4") # for md5 the sum is in the 4th \
column endif ("${MD5SUM_EXECUTABLE}" MATCHES "md5sum")
+ if (WIN32)
+ set(FISH_GENERATOR "generate_fishcode.py")
+ else (WIN32)
+ set(FISH_GENERATOR "generate_fishcode.sh")
+ endif (WIN32)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/fishcode.h
- COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/generate_fishcode.sh ARGS \
${CMAKE_CURRENT_SOURCE_DIR}/fish.pl ${MD5SUM_EXECUTABLE} \
${CMAKE_CURRENT_BINARY_DIR}/fishcode.h "${CUT_ARG}" + COMMAND \
${CMAKE_CURRENT_SOURCE_DIR}/${FISH_GENERATOR} ARGS \
${CMAKE_CURRENT_SOURCE_DIR}/fish.pl ${MD5SUM_EXECUTABLE} \
${CMAKE_CURRENT_BINARY_DIR}/fishcode.h "${CUT_ARG}" DEPENDS \
${CMAKE_CURRENT_SOURCE_DIR}/fish.pl )
set(kio_fish_PART_SRCS fish.cpp ${CMAKE_CURRENT_BINARY_DIR}/fishcode.h)
@@ -47,4 +53,4 @@
install( FILES fish.protocol DESTINATION ${SERVICES_INSTALL_DIR} )
-endif (MD5SUM_EXECUTABLE)
+endif (MD5SUM_EXECUTABLE OR WIN32)
--- trunk/KDE/kdebase/runtime/kioslave/fish/fish.cpp #891898:891899
@@ -108,13 +108,23 @@
#define sendmimeType(x) mimeType(x)
#endif
+#ifdef Q_WS_WIN
+#define ENDLINE "\r\n"
+#else
+#define ENDLINE '\n'
+#endif
+
static char *sshPath = NULL;
static char *suPath = NULL;
// disabled: currently not needed. Didn't work reliably.
// static int isOpenSSH = 0;
/** the SSH process used to communicate with the remote end */
+#ifndef Q_WS_WIN
static pid_t childPid;
+#else
+static KProcess *childPid = 0;
+#endif
#define E(x) ((const char*)remoteEncoding()->encode(x).data())
@@ -231,7 +241,11 @@
if (sshPath == NULL) {
// disabled: currently not needed. Didn't work reliably.
// isOpenSSH = !system("ssh -V 2>&1 | grep OpenSSH > /dev/null");
+#ifdef Q_WS_WIN
+ sshPath = strdup(QFile::encodeName(KStandardDirs::findExe("plink")));
+#else
sshPath = strdup(QFile::encodeName(KStandardDirs::findExe("ssh")));
+#endif
}
if (suPath == NULL) {
suPath = strdup(QFile::encodeName(KStandardDirs::findExe("su")));
@@ -299,6 +313,7 @@
}
// XXX Use KPty! XXX
+#ifndef Q_WS_WIN
static int open_pty_pair(int fd[2])
{
#if defined(HAVE_TERMIOS_H) && defined(HAVE_GRANTPT) && !defined(HAVE_OPENPTY)
@@ -364,6 +379,7 @@
#endif
#endif
}
+#endif
/**
creates the subprocess
*/
@@ -372,14 +388,52 @@
int rc, flags;
thisFn.clear();
+#ifndef Q_WS_WIN
rc = open_pty_pair(fd);
if (rc == -1) {
myDebug( << "socketpair failed, error: " << strerror(errno) << endl);
return true;
}
+#endif
if (!requestNetwork()) return true;
myDebug( << "Exec: " << (local ? suPath : sshPath) << " Port: " << \
connectionPort << " User: " << connectionUser << endl); +#ifdef Q_WS_WIN
+ childPid = new KProcess();
+ childPid->setOutputChannelMode(KProcess::MergedChannels);
+ QStringList common_args;
+ common_args << "-l" << connectionUser.toLatin1().constData() << "-x" << \
connectionHost.toLatin1().constData(); + common_args << "echo;echo FISH:;exec \
/bin/sh -c \"if env true 2>/dev/null; then env PS1= PS2= TZ=UTC LANG=C LC_ALL=C \
LOCALE=C /bin/sh; else PS1= PS2= TZ=UTC LANG=C LC_ALL=C LOCALE=C /bin/sh; fi\""; +
+ childPid->setProgram(sshPath, common_args);
+ childPid->start();
+
+ QByteArray buf;
+ int offset = 0;
+ while (!isLoggedIn) {
+ if (outBuf.size()) {
+ rc = childPid->write(outBuf);
+ outBuf.clear();
+ }
+ else rc = 0;
+
+ if(rc < 0) {
+ myDebug( << "write failed, rc: " << rc);
+ outBufPos = -1;
+ //return true;
+ }
+
+ if (childPid->waitForReadyRead(1000)) {
+ QByteArray buf2 = childPid->readAll();
+ buf += buf2;
+
+ int noff = establishConnection(buf);
+ if (noff < 0) return false;
+ if (noff > 0) buf = buf.mid(/*offset+*/noff);
+// offset = noff;
+ }
+ }
+#else
childPid = fork();
if (childPid == -1) {
myDebug( << "fork failed, error: " << strerror(errno) << endl);
@@ -498,14 +552,20 @@
}
}
}
+#endif
return false;
}
/**
writes one chunk of data to stdin of child process
*/
+#ifndef Q_WS_WIN
void fishProtocol::writeChild(const char *buf, KIO::fileoffset_t len) {
if (outBufPos >= 0 && outBuf) {
+#else
+void fishProtocol::writeChild(const QByteArray &buf, KIO::fileoffset_t len) {
+ if (outBufPos >= 0 && outBuf.size()) {
+#endif
#if 0
QString debug;
debug.setLatin1(outBuf,outBufLen);
@@ -521,8 +581,13 @@
/**
manages initial communication setup including password queries
*/
+#ifndef Q_WS_WIN
int fishProtocol::establishConnection(char *buffer, KIO::fileoffset_t len) {
QString buf = QString::fromLatin1(buffer,len);
+#else
+int fishProtocol::establishConnection(const QByteArray &buffer) {
+ QString buf = buffer;
+#endif
int pos=0;
// Strip trailing whitespace
while (buf.length() && (buf[buf.length()-1] == ' '))
@@ -561,7 +626,7 @@
return -1;
} else if (!connectionPassword.isEmpty()) {
myDebug( << "sending cpass" << endl);
- connectionAuth.password = connectionPassword+'\n';
+ connectionAuth.password = connectionPassword+ENDLINE;
connectionPassword.clear();
// su does not like receiving a password directly after sending
// the password prompt so we wait a while.
@@ -584,7 +649,7 @@
}
}
firstLogin = false;
- connectionAuth.password += '\n';
+ connectionAuth.password += ENDLINE;
if (connectionAuth.username != connectionUser) {
KUrl dest = url;
dest.setUser(connectionAuth.username);
@@ -605,6 +670,10 @@
writeChild(connectionAuth.password.toLatin1(),connectionAuth.password.length());
}
thisFn.clear();
+#ifdef Q_WS_WIN
+ return buf.length();
+ }
+#else
return 0;
} else if (buf.endsWith('?')) {
int rc = messageBox(QuestionYesNo,thisFn+buf);
@@ -615,9 +684,23 @@
}
thisFn.clear();
return 0;
- } else {
+ }
+#endif
+ else {
myDebug( << "unmatched case in initial handling! should not happen!" << \
endl);
- }
+ }
+#ifdef Q_WS_WIN
+ if (buf.endsWith("(y/n)")) {
+ int rc = messageBox(QuestionYesNo,thisFn+buf);
+ if (rc == KMessageBox::Yes) {
+ writeChild("y\n",2);
+ } else {
+ writeChild("n\n",2);
+ }
+ thisFn.clear();
+ return 0;
+ }
+#endif
}
return buf.length();
}
@@ -672,11 +755,17 @@
*/
void fishProtocol::shutdownConnection(bool forced){
if (childPid) {
+#ifdef Q_WS_WIN
+ childPid->terminate();
+#else
int killStatus = kill(childPid,SIGTERM); // We may not have permission...
if (killStatus == 0) waitpid(childPid, 0, 0);
+#endif
childPid = 0;
+#ifndef Q_WS_WIN
::close(childFd); // ...in which case this should do the trick
childFd = -1;
+#endif
if (!forced)
{
dropNetwork();
@@ -1330,11 +1419,14 @@
int rc;
isRunning = true;
finished();
+#ifndef Q_WS_WIN
fd_set rfds, wfds;
FD_ZERO(&rfds);
+#endif
char buf[32768];
int offset = 0;
while (isRunning) {
+#ifndef Q_WS_WIN
FD_SET(childFd,&rfds);
FD_ZERO(&wfds);
if (outBufPos >= 0) FD_SET(childFd,&wfds);
@@ -1351,18 +1443,31 @@
return;
}
if (FD_ISSET(childFd,&wfds) && outBufPos >= 0) {
+#else
+ if (outBufPos >= 0) {
+#endif
#if 0
QString debug;
debug.setLatin1(outBuf+outBufPos,outBufLen-outBufPos);
myDebug( << "now writing " << (outBufLen-outBufPos) << " " << \
debug.left(40) << "..." << endl); #endif
+#ifndef Q_WS_WIN
if (outBufLen-outBufPos > 0) rc = \
::write(childFd,outBuf+outBufPos,outBufLen-outBufPos); +#else
+ if (outBufLen-outBufPos > 0) {
+ rc = childPid->write(outBuf);
+ }
+#endif
else rc = 0;
if (rc >= 0) outBufPos += rc;
else {
+#ifndef Q_WS_WIN
if (errno == EINTR)
continue;
myDebug( << "write failed, rc: " << rc << ", error: " << \
strerror(errno) << endl); +#else
+ myDebug( << "write failed, rc: " << rc);
+#endif
error(ERR_CONNECTION_BROKEN,connectionHost);
shutdownConnection();
return;
@@ -1373,8 +1478,13 @@
sent();
}
}
+#ifndef Q_WS_WIN
if (FD_ISSET(childFd,&rfds)) {
rc = ::read(childFd,buf+offset,32768-offset);
+#else
+ if (childPid->waitForReadyRead(1000)) {
+ rc = childPid->read(buf+offset,32768-offset);
+#endif
//myDebug( << "read " << rc << " bytes" << endl);
if (rc > 0) {
int noff = received(buf,rc+offset);
@@ -1382,9 +1492,13 @@
//myDebug( << "left " << noff << " bytes: " << \
QString::fromLatin1(buf,offset) << endl); offset = noff;
} else {
+#ifndef Q_WS_WIN
if (errno == EINTR)
continue;
myDebug( << "read failed, rc: " << rc << ", error: " << \
strerror(errno) << endl); +#else
+ myDebug( << "read failed, rc: " << rc );
+#endif
error(ERR_CONNECTION_BROKEN,connectionHost);
shutdownConnection();
return;
--- trunk/KDE/kdebase/runtime/kioslave/fish/fish.h #891898:891899
@@ -19,6 +19,7 @@
#include <kurl.h>
#include <kio/global.h>
#include <kio/slavebase.h>
+#include <kprocess.h>
#include <kio/authinfo.h>
#include <time.h>
@@ -81,7 +82,11 @@
/** fd for reading and writing to the process */
int childFd;
/** buffer for data to be written */
+#ifndef Q_WS_WIN
const char *outBuf;
+#else
+ QByteArray outBuf;
+#endif
/** current write position in buffer */
KIO::fileoffset_t outBufPos;
/** length of buffer */
@@ -179,7 +184,11 @@
int fishCodeLen;
protected: // Protected methods
/** manages initial communication setup including password queries */
+#ifndef Q_WS_WIN
int establishConnection(char *buffer, KIO::fileoffset_t buflen);
+#else
+ int establishConnection(const QByteArray &buffer);
+#endif
int received(const char *buffer, KIO::fileoffset_t buflen);
void sent();
/** builds each FISH request and sets the error counter */
@@ -193,7 +202,11 @@
/** creates the subprocess */
bool connectionStart();
/** writes one chunk of data to stdin of child process */
+#ifndef Q_WS_WIN
void writeChild(const char *buf, KIO::fileoffset_t len);
+#else
+ void writeChild(const QByteArray &buf, KIO::fileoffset_t len);
+#endif
/** parses response from server and acts accordingly */
void manageConnection(const QString &line);
/** writes to process */
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic