Changeset View
Changeset View
Standalone View
Standalone View
fish/fish.cpp
Show All 26 Lines | |||||
27 | #include "fish.h" | 27 | #include "fish.h" | ||
28 | 28 | | |||
29 | #include <config-runtime.h> | 29 | #include <config-runtime.h> | ||
30 | #include "config-fish.h" | 30 | #include "config-fish.h" | ||
31 | #include <QFile> | 31 | #include <QFile> | ||
32 | #include <QDateTime> | 32 | #include <QDateTime> | ||
33 | #include <QRegExp> | 33 | #include <QRegExp> | ||
34 | #include <QCoreApplication> | 34 | #include <QCoreApplication> | ||
35 | #include <QDebug> | ||||
36 | #include <QStandardPaths> | ||||
37 | #include <QMimeType> | ||||
38 | #include <QMimeDatabase> | ||||
35 | 39 | | |||
36 | #include <stdlib.h> | 40 | #include <stdlib.h> | ||
41 | #include <sys/resource.h> | ||||
37 | #ifdef HAVE_PTY_H | 42 | #ifdef HAVE_PTY_H | ||
38 | #include <pty.h> | 43 | #include <pty.h> | ||
39 | #endif | 44 | #endif | ||
40 | 45 | | |||
41 | #ifdef HAVE_TERMIOS_H | 46 | #ifdef HAVE_TERMIOS_H | ||
42 | #include <termios.h> | 47 | #include <termios.h> | ||
43 | #endif | 48 | #endif | ||
44 | 49 | | |||
45 | #include <math.h> | | |||
46 | #include <unistd.h> | | |||
47 | #include <signal.h> | | |||
48 | #include <sys/wait.h> | | |||
49 | #include <sys/socket.h> | | |||
50 | #include <netinet/in.h> | | |||
51 | #include <netdb.h> | | |||
52 | #include <sys/types.h> | | |||
53 | | ||||
54 | #ifdef HAVE_SYS_IOCTL_H | 50 | #ifdef HAVE_SYS_IOCTL_H | ||
55 | #include <sys/ioctl.h> | 51 | #include <sys/ioctl.h> | ||
56 | #endif | 52 | #endif | ||
57 | 53 | | |||
58 | #ifdef HAVE_LIBUTIL_H | 54 | #ifdef HAVE_LIBUTIL_H | ||
59 | #include <libutil.h> | 55 | #include <libutil.h> | ||
60 | #endif | 56 | #endif | ||
61 | 57 | | |||
62 | #ifdef HAVE_UTIL_H | 58 | #ifdef HAVE_UTIL_H | ||
63 | #include <util.h> | 59 | #include <util.h> | ||
64 | #endif | 60 | #endif | ||
65 | 61 | | |||
66 | #include <kdebug.h> | | |||
67 | #include <kmessagebox.h> | 62 | #include <kmessagebox.h> | ||
68 | #include <kcomponentdata.h> | 63 | #include <klocalizedstring.h> | ||
69 | #include <kglobal.h> | | |||
70 | #include <kstandarddirs.h> | | |||
71 | #include <klocale.h> | | |||
72 | #include <kremoteencoding.h> | 64 | #include <kremoteencoding.h> | ||
73 | #include <kurl.h> | | |||
74 | #include <stdarg.h> | | |||
75 | #include <time.h> | | |||
76 | #include <sys/stat.h> | | |||
77 | #include <kmimetype.h> | | |||
78 | #include <fcntl.h> | | |||
79 | #include <errno.h> | | |||
80 | #include <sys/resource.h> | | |||
81 | #include <kdefakes.h> | | |||
82 | #include <QStandardPaths> | | |||
83 | 65 | | |||
84 | #include "fishcode.h" | 66 | #include "fishcode.h" | ||
67 | #include "loggingcategory.h" | ||||
85 | 68 | | |||
86 | #ifndef NDEBUG | 69 | #ifndef NDEBUG | ||
87 | #define myDebug(x) kDebug(7127) << __LINE__ << ": " x | 70 | #define myDebug(x) qCDebug(KIO_FISH_DEBUG) << __LINE__ << ": " x | ||
88 | #define connected() do{myDebug( << "_______ emitting connected()" << endl); connected();}while(0) | 71 | #define connected() do{myDebug( << "_______ emitting connected()"); connected();}while(0) | ||
89 | #define dataReq() do{myDebug( << "_______ emitting dataReq()" << endl); dataReq();}while(0) | 72 | #define dataReq() do{myDebug( << "_______ emitting dataReq()"); dataReq();}while(0) | ||
90 | #define needSubURLData() do{myDebug( << "_______ emitting needSubURLData()" << endl); needSubURLData();}while(0) | 73 | #define needSubURLData() do{myDebug( << "_______ emitting needSubURLData()"); needSubURLData();}while(0) | ||
91 | #define slaveStatus(x,y) do{myDebug( << "_______ emitting slaveStatus(" << x << ", " << y << ")" << endl); slaveStatus(x,y);}while(0) | 74 | #define slaveStatus(x,y) do{myDebug( << "_______ emitting slaveStatus(" << x << ", " << y << ")"); slaveStatus(x,y);}while(0) | ||
92 | #define statEntry(x) do{myDebug( << "_______ emitting statEntry("<<x.count()<<")" << endl); statEntry(x);}while(0) | 75 | #define statEntry(x) do{myDebug( << "_______ emitting statEntry("<<x.count()<<")"); statEntry(x);}while(0) | ||
93 | #define listEntries(x) do{myDebug( << "_______ emitting listEntries(...)" << endl); listEntries(x);}while(0) | 76 | #define listEntries(x) do{myDebug( << "_______ emitting listEntries(...)"); listEntries(x);}while(0) | ||
94 | #define canResume(x) do{myDebug( << "_______ emitting canResume("<<(int)x<<")" << endl); canResume(x);}while(0) | 77 | #define canResume(x) do{myDebug( << "_______ emitting canResume("<<(int)x<<")"); canResume(x);}while(0) | ||
95 | #define totalSize(x) do{myDebug( << "_______ emitting totalSize("<<(int)x<<")" << endl); totalSize(x);}while(0) | 78 | #define totalSize(x) do{myDebug( << "_______ emitting totalSize("<<(int)x<<")"); totalSize(x);}while(0) | ||
96 | #define processedSize(x) do{myDebug( << "_______ emitting processedSize("<<x<<")" << endl); processedSize(x);}while(0) | 79 | #define processedSize(x) do{myDebug( << "_______ emitting processedSize("<<x<<")"); processedSize(x);}while(0) | ||
97 | #define speed(x) do{myDebug( << "_______ emitting speed("<<(int)x<<")" << endl); speed(x);}while(0) | 80 | #define speed(x) do{myDebug( << "_______ emitting speed("<<(int)x<<")"); speed(x);}while(0) | ||
98 | #define redirection(x) do{myDebug( << "_______ emitting redirection("<<x<<")" << endl); redirection(x);}while(0) | 81 | #define redirection(x) do{myDebug( << "_______ emitting redirection("<<x<<")"); redirection(x);}while(0) | ||
99 | #define errorPage() do{myDebug( << "_______ emitting errorPage()" << endl); errorPage();}while(0) | 82 | #define errorPage() do{myDebug( << "_______ emitting errorPage()"); errorPage();}while(0) | ||
100 | #define sendmimeType(x) do{myDebug( << "_______ emitting mimeType("<<x<<")" << endl); mimeType(x);}while(0) | 83 | #define sendmimeType(x) do{myDebug( << "_______ emitting mimeType("<<x<<")"); mimeType(x);}while(0) | ||
101 | #define warning(x) do{myDebug( << "_______ emitting warning("<<x<<")" << endl); warning(x);}while(0) | 84 | #define warning(x) do{myDebug( << "_______ emitting warning("<<x<<")"); warning(x);}while(0) | ||
102 | #define infoMessage(x) do{myDebug( << "_______ emitting infoMessage("<<x<<")" << endl); infoMessage(x);}while(0) | 85 | #define infoMessage(x) do{myDebug( << "_______ emitting infoMessage("<<x<<")"); infoMessage(x);}while(0) | ||
103 | #else | 86 | #else | ||
104 | #define myDebug(x) | 87 | #define myDebug(x) | ||
105 | #define sendmimeType(x) mimeType(x) | 88 | #define sendmimeType(x) mimeType(x) | ||
106 | #endif | 89 | #endif | ||
107 | 90 | | |||
108 | #ifdef Q_OS_WIN | 91 | #ifdef Q_OS_WIN | ||
109 | #define ENDLINE "\r\n" | 92 | #define ENDLINE "\r\n" | ||
110 | #else | 93 | #else | ||
Show All 15 Lines | |||||
126 | #define E(x) ((const char*)remoteEncoding()->encode(x).data()) | 109 | #define E(x) ((const char*)remoteEncoding()->encode(x).data()) | ||
127 | 110 | | |||
128 | using namespace KIO; | 111 | using namespace KIO; | ||
129 | extern "C" { | 112 | extern "C" { | ||
130 | 113 | | |||
131 | int Q_DECL_EXPORT kdemain( int argc, char **argv ) | 114 | int Q_DECL_EXPORT kdemain( int argc, char **argv ) | ||
132 | { | 115 | { | ||
133 | QCoreApplication app(argc, argv); | 116 | QCoreApplication app(argc, argv); | ||
134 | KComponentData componentData("fish", "kio_fish"); | 117 | app.setApplicationName("kio_fish"); | ||
135 | 118 | | |||
136 | myDebug( << "*** Starting fish " << endl); | 119 | myDebug( << "*** Starting fish "); | ||
137 | if (argc != 4) { | 120 | if (argc != 4) { | ||
138 | myDebug( << "Usage: fish protocol domain-socket1 domain-socket2" << endl); | 121 | myDebug( << "Usage: kio_fish protocol domain-socket1 domain-socket2"); | ||
139 | exit(-1); | 122 | exit(-1); | ||
140 | } | 123 | } | ||
141 | 124 | | |||
142 | setenv("TZ", "UTC", true); | 125 | setenv("TZ", "UTC", true); | ||
143 | 126 | | |||
144 | fishProtocol slave(argv[2], argv[3]); | 127 | fishProtocol slave(argv[2], argv[3]); | ||
145 | slave.dispatchLoop(); | 128 | slave.dispatchLoop(); | ||
146 | 129 | | |||
147 | myDebug( << "*** fish Done" << endl); | 130 | myDebug( << "*** fish Done"); | ||
148 | return 0; | 131 | return 0; | ||
149 | } | 132 | } | ||
150 | 133 | | |||
151 | } | 134 | } | ||
152 | 135 | | |||
153 | const struct fishProtocol::fish_info fishProtocol::fishInfo[] = { | 136 | const struct fishProtocol::fish_info fishProtocol::fishInfo[] = { | ||
154 | { ("FISH"), 0, | 137 | { ("FISH"), 0, | ||
155 | ("echo; /bin/sh -c start_fish_server > /dev/null 2>/dev/null; perl .fishsrv.pl " CHECKSUM " 2>/dev/null; perl -e '$|=1; print \"### 100 transfer fish server\\n\"; while(<STDIN>) { last if /^__END__/; $code.=$_; } exit(eval($code));' 2>/dev/null;"), | 138 | ("echo; /bin/sh -c start_fish_server > /dev/null 2>/dev/null; perl .fishsrv.pl " CHECKSUM " 2>/dev/null; perl -e '$|=1; print \"### 100 transfer fish server\\n\"; while(<STDIN>) { last if /^__END__/; $code.=$_; } exit(eval($code));' 2>/dev/null;"), | ||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Line(s) | 212 | { ("EXEC"), 2, | |||
230 | ("UMASK=`umask`; umask 077; touch %2; umask $UMASK; eval %1 < /dev/null > %2 2>&1; echo \"###RESULT: $?\" >> %2"), | 213 | ("UMASK=`umask`; umask 077; touch %2; umask $UMASK; eval %1 < /dev/null > %2 2>&1; echo \"###RESULT: $?\" >> %2"), | ||
231 | 0 } | 214 | 0 } | ||
232 | }; | 215 | }; | ||
233 | 216 | | |||
234 | fishProtocol::fishProtocol(const QByteArray &pool_socket, const QByteArray &app_socket) | 217 | fishProtocol::fishProtocol(const QByteArray &pool_socket, const QByteArray &app_socket) | ||
235 | : SlaveBase("fish", pool_socket, app_socket), mimeBuffer(1024, '\0'), | 218 | : SlaveBase("fish", pool_socket, app_socket), mimeBuffer(1024, '\0'), | ||
236 | mimeTypeSent(false) | 219 | mimeTypeSent(false) | ||
237 | { | 220 | { | ||
238 | myDebug( << "fishProtocol::fishProtocol()" << endl); | 221 | myDebug( << "fishProtocol::fishProtocol()"); | ||
239 | if (sshPath == NULL) { | 222 | if (sshPath == NULL) { | ||
240 | // disabled: currently not needed. Didn't work reliably. | 223 | // disabled: currently not needed. Didn't work reliably. | ||
241 | // isOpenSSH = !system("ssh -V 2>&1 | grep OpenSSH > /dev/null"); | 224 | // isOpenSSH = !system("ssh -V 2>&1 | grep OpenSSH > /dev/null"); | ||
242 | #ifdef Q_OS_WIN | 225 | #ifdef Q_OS_WIN | ||
243 | sshPath = strdup(QFile::encodeName(KStandardDirs::findExe("plink"))); | 226 | sshPath = strdup(QFile::encodeName(QStandardPaths::findExecutable("plink"))); | ||
244 | #else | 227 | #else | ||
245 | sshPath = strdup(QFile::encodeName(QStandardPaths::findExecutable("ssh"))); | 228 | sshPath = strdup(QFile::encodeName(QStandardPaths::findExecutable("ssh"))); | ||
246 | #endif | 229 | #endif | ||
247 | } | 230 | } | ||
248 | if (suPath == NULL) { | 231 | if (suPath == NULL) { | ||
249 | suPath = strdup(QFile::encodeName(QStandardPaths::findExecutable("su"))); | 232 | suPath = strdup(QFile::encodeName(QStandardPaths::findExecutable("su"))); | ||
250 | } | 233 | } | ||
251 | childPid = 0; | 234 | childPid = 0; | ||
Show All 22 Lines | |||||
274 | redirectPass = ""; // FIXME: just a workaround for konq deficiencies | 257 | redirectPass = ""; // FIXME: just a workaround for konq deficiencies | ||
275 | fishCodeLen = strlen(fishCode); | 258 | fishCodeLen = strlen(fishCode); | ||
276 | } | 259 | } | ||
277 | /* ---------------------------------------------------------------------------------- */ | 260 | /* ---------------------------------------------------------------------------------- */ | ||
278 | 261 | | |||
279 | 262 | | |||
280 | fishProtocol::~fishProtocol() | 263 | fishProtocol::~fishProtocol() | ||
281 | { | 264 | { | ||
282 | myDebug( << "fishProtocol::~fishProtocol()" << endl); | 265 | myDebug( << "fishProtocol::~fishProtocol()"); | ||
283 | shutdownConnection(true); | 266 | shutdownConnection(true); | ||
284 | } | 267 | } | ||
285 | 268 | | |||
286 | /* --------------------------------------------------------------------------- */ | 269 | /* --------------------------------------------------------------------------- */ | ||
287 | 270 | | |||
288 | /** | 271 | /** | ||
289 | Connects to a server and logs us in via SSH. Then starts FISH protocol. | 272 | Connects to a server and logs us in via SSH. Then starts FISH protocol. | ||
290 | */ | 273 | */ | ||
291 | void fishProtocol::openConnection() { | 274 | void fishProtocol::openConnection() { | ||
292 | if (childPid) return; | 275 | if (childPid) return; | ||
293 | 276 | | |||
294 | if (connectionHost.isEmpty()) | 277 | if (connectionHost.isEmpty()) | ||
295 | { | 278 | { | ||
296 | error( KIO::ERR_UNKNOWN_HOST, QString() ); | 279 | error( KIO::ERR_UNKNOWN_HOST, QString() ); | ||
297 | return; | 280 | return; | ||
298 | } | 281 | } | ||
299 | 282 | | |||
300 | infoMessage(i18n("Connecting...")); | 283 | infoMessage(i18n("Connecting...")); | ||
301 | 284 | | |||
302 | myDebug( << "connecting to: " << connectionUser << "@" << connectionHost << ":" << connectionPort << endl); | 285 | myDebug( << "connecting to: " << connectionUser << "@" << connectionHost << ":" << connectionPort); | ||
303 | sendCommand(FISH_FISH); | 286 | sendCommand(FISH_FISH); | ||
304 | sendCommand(FISH_VER); | 287 | sendCommand(FISH_VER); | ||
305 | if (connectionStart()) { | 288 | if (connectionStart()) { | ||
306 | error(ERR_COULD_NOT_CONNECT,connectionHost); | 289 | error(ERR_COULD_NOT_CONNECT,connectionHost); | ||
307 | shutdownConnection(); | 290 | shutdownConnection(); | ||
308 | return; | 291 | return; | ||
309 | }; | 292 | }; | ||
310 | myDebug( << "subprocess is running" << endl); | 293 | myDebug( << "subprocess is running"); | ||
311 | } | 294 | } | ||
312 | 295 | | |||
313 | // XXX Use KPty! XXX | 296 | // XXX Use KPty! XXX | ||
314 | #ifndef Q_OS_WIN | 297 | #ifndef Q_OS_WIN | ||
315 | static int open_pty_pair(int fd[2]) | 298 | static int open_pty_pair(int fd[2]) | ||
316 | { | 299 | { | ||
317 | #if defined(HAVE_TERMIOS_H) && defined(HAVE_GRANTPT) && !defined(HAVE_OPENPTY) | 300 | #if defined(HAVE_TERMIOS_H) && defined(HAVE_GRANTPT) && !defined(HAVE_OPENPTY) | ||
318 | /** with kind regards to The GNU C Library | 301 | /** with kind regards to The GNU C Library | ||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Line(s) | |||||
384 | bool fishProtocol::connectionStart() { | 367 | bool fishProtocol::connectionStart() { | ||
385 | int fd[2]; | 368 | int fd[2]; | ||
386 | int rc, flags; | 369 | int rc, flags; | ||
387 | thisFn.clear(); | 370 | thisFn.clear(); | ||
388 | 371 | | |||
389 | #ifndef Q_OS_WIN | 372 | #ifndef Q_OS_WIN | ||
390 | rc = open_pty_pair(fd); | 373 | rc = open_pty_pair(fd); | ||
391 | if (rc == -1) { | 374 | if (rc == -1) { | ||
392 | myDebug( << "socketpair failed, error: " << strerror(errno) << endl); | 375 | myDebug( << "socketpair failed, error: " << strerror(errno)); | ||
393 | return true; | 376 | return true; | ||
394 | } | 377 | } | ||
395 | #endif | 378 | #endif | ||
396 | 379 | | |||
397 | if (!requestNetwork()) return true; | 380 | if (!requestNetwork()) return true; | ||
398 | myDebug( << "Exec: " << (local ? suPath : sshPath) << " Port: " << connectionPort << " User: " << connectionUser << endl); | 381 | myDebug( << "Exec: " << (local ? suPath : sshPath) << " Port: " << connectionPort << " User: " << connectionUser); | ||
399 | #ifdef Q_OS_WIN | 382 | #ifdef Q_OS_WIN | ||
400 | childPid = new KProcess(); | 383 | childPid = new KProcess(); | ||
401 | childPid->setOutputChannelMode(KProcess::MergedChannels); | 384 | childPid->setOutputChannelMode(KProcess::MergedChannels); | ||
402 | QStringList common_args; | 385 | QStringList common_args; | ||
403 | common_args << "-l" << connectionUser.toLatin1().constData() << "-x" << connectionHost.toLatin1().constData(); | 386 | common_args << "-l" << connectionUser.toLatin1().constData() << "-x" << connectionHost.toLatin1().constData(); | ||
404 | 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\""; | 387 | 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\""; | ||
405 | 388 | | |||
406 | childPid->setProgram(sshPath, common_args); | 389 | childPid->setProgram(sshPath, common_args); | ||
Show All 22 Lines | 407 | if (childPid->waitForReadyRead(1000)) { | |||
429 | if (noff < 0) return false; | 412 | if (noff < 0) return false; | ||
430 | if (noff > 0) buf = buf.mid(/*offset+*/noff); | 413 | if (noff > 0) buf = buf.mid(/*offset+*/noff); | ||
431 | // offset = noff; | 414 | // offset = noff; | ||
432 | } | 415 | } | ||
433 | } | 416 | } | ||
434 | #else | 417 | #else | ||
435 | childPid = fork(); | 418 | childPid = fork(); | ||
436 | if (childPid == -1) { | 419 | if (childPid == -1) { | ||
437 | myDebug( << "fork failed, error: " << strerror(errno) << endl); | 420 | myDebug( << "fork failed, error: " << strerror(errno)); | ||
438 | ::close(fd[0]); | 421 | ::close(fd[0]); | ||
439 | ::close(fd[1]); | 422 | ::close(fd[1]); | ||
440 | childPid = 0; | 423 | childPid = 0; | ||
441 | dropNetwork(); | 424 | dropNetwork(); | ||
442 | return true; | 425 | return true; | ||
443 | } | 426 | } | ||
444 | if (childPid == 0) { | 427 | if (childPid == 0) { | ||
445 | // taken from konsole, see TEPty.C for details | 428 | // taken from konsole, see TEPty.C for details | ||
Show All 40 Lines | 464 | } else { | |||
486 | // (isOpenSSH?"-C":"+C"), | 469 | // (isOpenSSH?"-C":"+C"), | ||
487 | 470 | | |||
488 | if (connectionPort) | 471 | if (connectionPort) | ||
489 | execl(sshPath, "ssh", "-p", qPrintable(QString::number(connectionPort)), common_args); | 472 | execl(sshPath, "ssh", "-p", qPrintable(QString::number(connectionPort)), common_args); | ||
490 | else | 473 | else | ||
491 | execl(sshPath, "ssh", common_args); | 474 | execl(sshPath, "ssh", common_args); | ||
492 | #undef common_args | 475 | #undef common_args | ||
493 | } | 476 | } | ||
494 | myDebug( << "could not exec! " << strerror(errno) << endl); | 477 | myDebug( << "could not exec! " << strerror(errno)); | ||
495 | ::exit(-1); | 478 | ::exit(-1); | ||
496 | } | 479 | } | ||
497 | ::close(fd[1]); | 480 | ::close(fd[1]); | ||
498 | rc = fcntl(fd[0],F_GETFL,&flags); | 481 | rc = fcntl(fd[0],F_GETFL,&flags); | ||
499 | rc = fcntl(fd[0],F_SETFL,flags|O_NONBLOCK); | 482 | rc = fcntl(fd[0],F_SETFL,flags|O_NONBLOCK); | ||
500 | childFd = fd[0]; | 483 | childFd = fd[0]; | ||
501 | 484 | | |||
502 | fd_set rfds, wfds; | 485 | fd_set rfds, wfds; | ||
503 | FD_ZERO(&rfds); | 486 | FD_ZERO(&rfds); | ||
504 | FD_ZERO(&wfds); | 487 | FD_ZERO(&wfds); | ||
505 | char buf[32768]; | 488 | char buf[32768]; | ||
506 | int offset = 0; | 489 | int offset = 0; | ||
507 | while (!isLoggedIn) { | 490 | while (!isLoggedIn) { | ||
508 | FD_SET(childFd,&rfds); | 491 | FD_SET(childFd,&rfds); | ||
509 | FD_ZERO(&wfds); | 492 | FD_ZERO(&wfds); | ||
510 | if (outBufPos >= 0) FD_SET(childFd,&wfds); | 493 | if (outBufPos >= 0) FD_SET(childFd,&wfds); | ||
511 | struct timeval timeout; | 494 | struct timeval timeout; | ||
512 | timeout.tv_sec = 0; | 495 | timeout.tv_sec = 0; | ||
513 | timeout.tv_usec = 1000; | 496 | timeout.tv_usec = 1000; | ||
514 | rc = select(childFd+1, &rfds, &wfds, NULL, &timeout); | 497 | rc = select(childFd+1, &rfds, &wfds, NULL, &timeout); | ||
515 | if (rc < 0) { | 498 | if (rc < 0) { | ||
516 | if (errno == EINTR) | 499 | if (errno == EINTR) | ||
517 | continue; | 500 | continue; | ||
518 | myDebug( << "select failed, rc: " << rc << ", error: " << strerror(errno) << endl); | 501 | myDebug( << "select failed, rc: " << rc << ", error: " << strerror(errno)); | ||
519 | return true; | 502 | return true; | ||
520 | } | 503 | } | ||
521 | if (FD_ISSET(childFd, &wfds) && outBufPos >= 0) { | 504 | if (FD_ISSET(childFd, &wfds) && outBufPos >= 0) { | ||
522 | if (outBuf) | 505 | if (outBuf) | ||
523 | rc = ::write(childFd, outBuf + outBufPos, outBufLen - outBufPos); | 506 | rc = ::write(childFd, outBuf + outBufPos, outBufLen - outBufPos); | ||
524 | else | 507 | else | ||
525 | rc = 0; | 508 | rc = 0; | ||
526 | 509 | | |||
527 | if (rc >= 0) | 510 | if (rc >= 0) | ||
528 | outBufPos += rc; | 511 | outBufPos += rc; | ||
529 | else { | 512 | else { | ||
530 | if (errno == EINTR) | 513 | if (errno == EINTR) | ||
531 | continue; | 514 | continue; | ||
532 | myDebug( << "write failed, rc: " << rc << ", error: " << strerror(errno) << endl); | 515 | myDebug( << "write failed, rc: " << rc << ", error: " << strerror(errno)); | ||
533 | outBufPos = -1; | 516 | outBufPos = -1; | ||
534 | //return true; | 517 | //return true; | ||
535 | } | 518 | } | ||
536 | if (outBufPos >= outBufLen) { | 519 | if (outBufPos >= outBufLen) { | ||
537 | outBufPos = -1; | 520 | outBufPos = -1; | ||
538 | outBuf = NULL; | 521 | outBuf = NULL; | ||
539 | outBufLen = 0; | 522 | outBufLen = 0; | ||
540 | } | 523 | } | ||
541 | } else if (FD_ISSET(childFd,&rfds)) { | 524 | } else if (FD_ISSET(childFd,&rfds)) { | ||
542 | rc = ::read(childFd, buf + offset, sizeof(buf) - offset); | 525 | rc = ::read(childFd, buf + offset, sizeof(buf) - offset); | ||
543 | if (rc > 0) { | 526 | if (rc > 0) { | ||
544 | int noff = establishConnection(buf, rc + offset); | 527 | int noff = establishConnection(buf, rc + offset); | ||
545 | if (noff < 0) | 528 | if (noff < 0) | ||
546 | return false; | 529 | return false; | ||
547 | if (noff > 0) | 530 | if (noff > 0) | ||
548 | memmove(buf, buf + offset + rc - noff, noff); | 531 | memmove(buf, buf + offset + rc - noff, noff); | ||
549 | offset = noff; | 532 | offset = noff; | ||
550 | } else { | 533 | } else { | ||
551 | if (errno == EINTR) | 534 | if (errno == EINTR) | ||
552 | continue; | 535 | continue; | ||
553 | myDebug( << "read failed, rc: " << rc << ", error: " << strerror(errno) << endl); | 536 | myDebug( << "read failed, rc: " << rc << ", error: " << strerror(errno)); | ||
554 | return true; | 537 | return true; | ||
555 | } | 538 | } | ||
556 | } | 539 | } | ||
557 | } | 540 | } | ||
558 | #endif | 541 | #endif | ||
559 | return false; | 542 | return false; | ||
560 | } | 543 | } | ||
561 | 544 | | |||
562 | /** | 545 | /** | ||
563 | writes one chunk of data to stdin of child process | 546 | writes one chunk of data to stdin of child process | ||
564 | */ | 547 | */ | ||
565 | #ifndef Q_OS_WIN | 548 | #ifndef Q_OS_WIN | ||
566 | void fishProtocol::writeChild(const char *buf, KIO::fileoffset_t len) { | 549 | void fishProtocol::writeChild(const char *buf, KIO::fileoffset_t len) { | ||
567 | if (outBufPos >= 0 && outBuf) { | 550 | if (outBufPos >= 0 && outBuf) { | ||
568 | #else | 551 | #else | ||
569 | void fishProtocol::writeChild(const QByteArray &buf, KIO::fileoffset_t len) { | 552 | void fishProtocol::writeChild(const QByteArray &buf, KIO::fileoffset_t len) { | ||
570 | if (outBufPos >= 0 && outBuf.size()) { | 553 | if (outBufPos >= 0 && outBuf.size()) { | ||
571 | #endif | 554 | #endif | ||
572 | #if 0 | 555 | #if 0 | ||
573 | QString debug = QString::fromLatin1(outBuf,outBufLen); | 556 | QString debug = QString::fromLatin1(outBuf,outBufLen); | ||
574 | if (len > 0) myDebug( << "write request while old one is pending, throwing away input (" << outBufLen << "," << outBufPos << "," << debug.left(10) << "...)" << endl); | 557 | if (len > 0) myDebug( << "write request while old one is pending, throwing away input (" << outBufLen << "," << outBufPos << "," << debug.left(10) << "...)"); | ||
575 | #endif | 558 | #endif | ||
576 | return; | 559 | return; | ||
577 | } | 560 | } | ||
578 | outBuf = buf; | 561 | outBuf = buf; | ||
579 | outBufPos = 0; | 562 | outBufPos = 0; | ||
580 | outBufLen = len; | 563 | outBufLen = len; | ||
581 | } | 564 | } | ||
582 | 565 | | |||
583 | /** | 566 | /** | ||
584 | manages initial communication setup including password queries | 567 | manages initial communication setup including password queries | ||
585 | */ | 568 | */ | ||
586 | #ifndef Q_OS_WIN | 569 | #ifndef Q_OS_WIN | ||
587 | int fishProtocol::establishConnection(char *buffer, KIO::fileoffset_t len) { | 570 | int fishProtocol::establishConnection(char *buffer, KIO::fileoffset_t len) { | ||
588 | QString buf = QString::fromLatin1(buffer,len); | 571 | QString buf = QString::fromLatin1(buffer,len); | ||
589 | #else | 572 | #else | ||
590 | int fishProtocol::establishConnection(const QByteArray &buffer) { | 573 | int fishProtocol::establishConnection(const QByteArray &buffer) { | ||
591 | QString buf = buffer; | 574 | QString buf = buffer; | ||
592 | #endif | 575 | #endif | ||
593 | int pos=0; | 576 | int pos=0; | ||
594 | // Strip trailing whitespace | 577 | // Strip trailing whitespace | ||
595 | while (buf.length() && (buf[buf.length()-1] == ' ')) | 578 | while (buf.length() && (buf[buf.length()-1] == ' ')) | ||
596 | buf.truncate(buf.length()-1); | 579 | buf.truncate(buf.length()-1); | ||
597 | 580 | | |||
598 | myDebug( << "establishing: got " << buf << endl); | 581 | myDebug( << "establishing: got " << buf); | ||
599 | while (childPid && ((pos = buf.indexOf('\n')) >= 0 || | 582 | while (childPid && ((pos = buf.indexOf('\n')) >= 0 || | ||
600 | buf.endsWith(':') || buf.endsWith('?'))) { | 583 | buf.endsWith(':') || buf.endsWith('?'))) { | ||
601 | pos++; | 584 | pos++; | ||
602 | QString str = buf.left(pos); | 585 | QString str = buf.left(pos); | ||
603 | buf = buf.mid(pos); | 586 | buf = buf.mid(pos); | ||
604 | if (str == "\n") | 587 | if (str == "\n") | ||
605 | continue; | 588 | continue; | ||
606 | if (str == "FISH:\n") { | 589 | if (str == "FISH:\n") { | ||
607 | thisFn.clear(); | 590 | thisFn.clear(); | ||
608 | infoMessage(i18n("Initiating protocol...")); | 591 | infoMessage(i18n("Initiating protocol...")); | ||
609 | if (!connectionAuth.password.isEmpty()) { | 592 | if (!connectionAuth.password.isEmpty()) { | ||
610 | connectionAuth.password = connectionAuth.password.left(connectionAuth.password.length()-1); | 593 | connectionAuth.password = connectionAuth.password.left(connectionAuth.password.length()-1); | ||
611 | cacheAuthentication(connectionAuth); | 594 | cacheAuthentication(connectionAuth); | ||
612 | } | 595 | } | ||
613 | isLoggedIn = true; | 596 | isLoggedIn = true; | ||
614 | return 0; | 597 | return 0; | ||
615 | } else if (!str.isEmpty()) { | 598 | } else if (!str.isEmpty()) { | ||
616 | thisFn += str; | 599 | thisFn += str; | ||
617 | } else if (buf.endsWith(':')) { | 600 | } else if (buf.endsWith(':')) { | ||
618 | if (!redirectUser.isEmpty() && connectionUser != redirectUser) { | 601 | if (!redirectUser.isEmpty() && connectionUser != redirectUser) { | ||
619 | KUrl dest = url; | 602 | QUrl dest = url; | ||
620 | dest.setUser(redirectUser); | 603 | dest.setUserName(redirectUser); | ||
621 | dest.setPass(redirectPass); | 604 | dest.setPassword(redirectPass); | ||
622 | redirection(dest); | 605 | redirection(dest); | ||
623 | commandList.clear(); | 606 | commandList.clear(); | ||
624 | commandCodes.clear(); | 607 | commandCodes.clear(); | ||
625 | finished(); | 608 | finished(); | ||
626 | redirectUser = ""; | 609 | redirectUser = ""; | ||
627 | redirectPass = ""; | 610 | redirectPass = ""; | ||
628 | return -1; | 611 | return -1; | ||
629 | } else if (!connectionPassword.isEmpty()) { | 612 | } else if (!connectionPassword.isEmpty()) { | ||
630 | myDebug( << "sending cpass" << endl); | 613 | myDebug( << "sending cpass"); | ||
631 | connectionAuth.password = connectionPassword+ENDLINE; | 614 | connectionAuth.password = connectionPassword+ENDLINE; | ||
632 | connectionPassword.clear(); | 615 | connectionPassword.clear(); | ||
633 | // su does not like receiving a password directly after sending | 616 | // su does not like receiving a password directly after sending | ||
634 | // the password prompt so we wait a while. | 617 | // the password prompt so we wait a while. | ||
635 | if (local) | 618 | if (local) | ||
636 | sleep(1); | 619 | sleep(1); | ||
637 | writeChild(connectionAuth.password.toLatin1(),connectionAuth.password.length()); | 620 | writeChild(connectionAuth.password.toLatin1(),connectionAuth.password.length()); | ||
638 | } else { | 621 | } else { | ||
639 | myDebug( << "sending mpass" << endl); | 622 | myDebug( << "sending mpass"); | ||
640 | connectionAuth.prompt = thisFn+buf; | 623 | connectionAuth.prompt = thisFn+buf; | ||
641 | if (local) | 624 | if (local) | ||
642 | connectionAuth.caption = i18n("Local Login"); | 625 | connectionAuth.caption = i18n("Local Login"); | ||
643 | else | 626 | else | ||
644 | connectionAuth.caption = i18n("SSH Authentication"); | 627 | connectionAuth.caption = i18n("SSH Authentication"); | ||
645 | if ((!firstLogin || !checkCachedAuthentication(connectionAuth))) { | 628 | if ((!firstLogin || !checkCachedAuthentication(connectionAuth))) { | ||
646 | connectionAuth.password.clear(); // don't prefill | 629 | connectionAuth.password.clear(); // don't prefill | ||
647 | if ( !openPasswordDialog(connectionAuth)) { | 630 | int errorCode = openPasswordDialogV2(connectionAuth); | ||
648 | error(ERR_USER_CANCELED,connectionHost); | 631 | if (errorCode != 0) { | ||
632 | error(errorCode, connectionHost); | ||||
649 | shutdownConnection(); | 633 | shutdownConnection(); | ||
650 | return -1; | 634 | return -1; | ||
651 | } | 635 | } | ||
652 | } | 636 | } | ||
653 | firstLogin = false; | 637 | firstLogin = false; | ||
654 | connectionAuth.password += ENDLINE; | 638 | connectionAuth.password += ENDLINE; | ||
655 | if (connectionAuth.username != connectionUser) { | 639 | if (connectionAuth.username != connectionUser) { | ||
656 | KUrl dest = url; | 640 | QUrl dest = url; | ||
657 | dest.setUser(connectionAuth.username); | 641 | dest.setUserName(connectionAuth.username); | ||
658 | dest.setPass(connectionAuth.password); | 642 | dest.setPassword(connectionAuth.password); | ||
659 | redirection(dest); | 643 | redirection(dest); | ||
660 | if (isStat) { // FIXME: just a workaround for konq deficiencies | 644 | if (isStat) { // FIXME: just a workaround for konq deficiencies | ||
661 | redirectUser = connectionAuth.username; | 645 | redirectUser = connectionAuth.username; | ||
662 | redirectPass = connectionAuth.password; | 646 | redirectPass = connectionAuth.password; | ||
663 | } | 647 | } | ||
664 | commandList.clear(); | 648 | commandList.clear(); | ||
665 | commandCodes.clear(); | 649 | commandCodes.clear(); | ||
666 | finished(); | 650 | finished(); | ||
667 | return -1; | 651 | return -1; | ||
668 | } | 652 | } | ||
669 | myDebug( << "sending pass" << endl); | 653 | myDebug( << "sending pass"); | ||
670 | if (local) | 654 | if (local) | ||
671 | sleep(1); | 655 | sleep(1); | ||
672 | writeChild(connectionAuth.password.toLatin1(),connectionAuth.password.length()); | 656 | writeChild(connectionAuth.password.toLatin1(),connectionAuth.password.length()); | ||
673 | } | 657 | } | ||
674 | thisFn.clear(); | 658 | thisFn.clear(); | ||
675 | #ifdef Q_OS_WIN | 659 | #ifdef Q_OS_WIN | ||
676 | return buf.length(); | 660 | return buf.length(); | ||
677 | } | 661 | } | ||
678 | #else | 662 | #else | ||
679 | return 0; | 663 | return 0; | ||
680 | } else if (buf.endsWith('?')) { | 664 | } else if (buf.endsWith('?')) { | ||
681 | int rc = messageBox(QuestionYesNo,thisFn+buf); | 665 | int rc = messageBox(QuestionYesNo,thisFn+buf); | ||
682 | if (rc == KMessageBox::Yes) { | 666 | if (rc == KMessageBox::Yes) { | ||
683 | writeChild("yes\n",4); | 667 | writeChild("yes\n",4); | ||
684 | } else { | 668 | } else { | ||
685 | writeChild("no\n",3); | 669 | writeChild("no\n",3); | ||
686 | } | 670 | } | ||
687 | thisFn.clear(); | 671 | thisFn.clear(); | ||
688 | return 0; | 672 | return 0; | ||
689 | } | 673 | } | ||
690 | #endif | 674 | #endif | ||
691 | else { | 675 | else { | ||
692 | myDebug( << "unmatched case in initial handling! should not happen!" << endl); | 676 | myDebug( << "unmatched case in initial handling! should not happen!"); | ||
693 | } | 677 | } | ||
694 | #ifdef Q_OS_WIN | 678 | #ifdef Q_OS_WIN | ||
695 | if (buf.endsWith(QLatin1String("(y/n)"))) { | 679 | if (buf.endsWith(QLatin1String("(y/n)"))) { | ||
696 | int rc = messageBox(QuestionYesNo,thisFn+buf); | 680 | int rc = messageBox(QuestionYesNo,thisFn+buf); | ||
697 | if (rc == KMessageBox::Yes) { | 681 | if (rc == KMessageBox::Yes) { | ||
698 | writeChild("y\n",2); | 682 | writeChild("y\n",2); | ||
699 | } else { | 683 | } else { | ||
700 | writeChild("n\n",2); | 684 | writeChild("n\n",2); | ||
Show All 19 Lines | |||||
720 | void fishProtocol::setHost(const QString & host, quint16 port, const QString & u, const QString & pass){ | 704 | void fishProtocol::setHost(const QString & host, quint16 port, const QString & u, const QString & pass){ | ||
721 | QString user(u); | 705 | QString user(u); | ||
722 | 706 | | |||
723 | local = (host == "localhost" && port == 0); | 707 | local = (host == "localhost" && port == 0); | ||
724 | if (user.isEmpty()) user = getenv("LOGNAME"); | 708 | if (user.isEmpty()) user = getenv("LOGNAME"); | ||
725 | 709 | | |||
726 | if (host == connectionHost && port == connectionPort && user == connectionUser) | 710 | if (host == connectionHost && port == connectionPort && user == connectionUser) | ||
727 | return; | 711 | return; | ||
728 | myDebug( << "setHost " << u << "@" << host << endl); | 712 | myDebug( << "setHost " << u << "@" << host); | ||
729 | 713 | | |||
730 | if (childPid) shutdownConnection(); | 714 | if (childPid) shutdownConnection(); | ||
731 | 715 | | |||
732 | connectionHost = host; | 716 | connectionHost = host; | ||
733 | connectionAuth.url.setHost(host); | 717 | connectionAuth.url.setHost(host); | ||
734 | 718 | | |||
735 | connectionUser = user; | 719 | connectionUser = user; | ||
736 | connectionAuth.username = user; | 720 | connectionAuth.username = user; | ||
737 | connectionAuth.url.setUserName(user); | 721 | connectionAuth.url.setUserName(user); | ||
738 | 722 | | |||
739 | connectionPort = port; | 723 | connectionPort = port; | ||
740 | connectionPassword = pass; | 724 | connectionPassword = pass; | ||
741 | firstLogin = true; | 725 | firstLogin = true; | ||
742 | } | 726 | } | ||
743 | 727 | | |||
744 | /** | 728 | /** | ||
745 | Forced close of the connection | 729 | Forced close of the connection | ||
746 | 730 | | |||
747 | This function gets called from the application side of the universe, | 731 | This function gets called from the application side of the universe, | ||
748 | it shouldn't send any response. | 732 | it shouldn't send any response. | ||
749 | */ | 733 | */ | ||
750 | void fishProtocol::closeConnection(){ | 734 | void fishProtocol::closeConnection(){ | ||
751 | myDebug( << "closeConnection()" << endl); | 735 | myDebug( << "closeConnection()"); | ||
752 | shutdownConnection(true); | 736 | shutdownConnection(true); | ||
753 | } | 737 | } | ||
754 | 738 | | |||
755 | /** | 739 | /** | ||
756 | Closes the connection | 740 | Closes the connection | ||
757 | */ | 741 | */ | ||
758 | void fishProtocol::shutdownConnection(bool forced){ | 742 | void fishProtocol::shutdownConnection(bool forced){ | ||
759 | if (childPid) { | 743 | if (childPid) { | ||
Show All 28 Lines | 754 | #endif | |||
788 | recvLen = -1; | 772 | recvLen = -1; | ||
789 | sendLen = -1; | 773 | sendLen = -1; | ||
790 | } | 774 | } | ||
791 | /** | 775 | /** | ||
792 | builds each FISH request and sets the error counter | 776 | builds each FISH request and sets the error counter | ||
793 | */ | 777 | */ | ||
794 | bool fishProtocol::sendCommand(fish_command_type cmd, ...) { | 778 | bool fishProtocol::sendCommand(fish_command_type cmd, ...) { | ||
795 | const fish_info &info = fishInfo[cmd]; | 779 | const fish_info &info = fishInfo[cmd]; | ||
796 | myDebug( << "queuing: cmd="<< cmd << "['" << info.command << "'](" << info.params <<"), alt=['" << info.alt << "'], lines=" << info.lines << endl); | 780 | myDebug( << "queuing: cmd="<< cmd << "['" << info.command << "'](" << info.params <<"), alt=['" << info.alt << "'], lines=" << info.lines); | ||
797 | 781 | | |||
798 | va_list list; | 782 | va_list list; | ||
799 | va_start(list, cmd); | 783 | va_start(list, cmd); | ||
800 | QString realCmd = info.command; | 784 | QString realCmd = info.command; | ||
801 | QString realAlt = info.alt; | 785 | QString realAlt = info.alt; | ||
802 | static QRegExp rx("[][\\\\\n $`#!()*?{}~&<>;'\"%^@|\t]"); | 786 | static QRegExp rx("[][\\\\\n $`#!()*?{}~&<>;'\"%^@|\t]"); | ||
803 | for (int i = 0; i < info.params; i++) { | 787 | for (int i = 0; i < info.params; i++) { | ||
804 | QString arg(va_arg(list, const char *)); | 788 | QString arg(va_arg(list, const char *)); | ||
805 | int pos = -2; | 789 | int pos = -2; | ||
806 | while ((pos = rx.indexIn(arg,pos+2)) >= 0) { | 790 | while ((pos = rx.indexIn(arg,pos+2)) >= 0) { | ||
807 | arg.replace(pos,0,QString("\\")); | 791 | arg.replace(pos,0,QString("\\")); | ||
808 | } | 792 | } | ||
809 | //myDebug( << "arg " << i << ": " << arg << endl); | 793 | //myDebug( << "arg " << i << ": " << arg); | ||
810 | realCmd.append(" ").append(arg); | 794 | realCmd.append(" ").append(arg); | ||
811 | realAlt.replace(QRegExp('%'+QString::number(i+1)),arg); | 795 | realAlt.replace(QRegExp('%'+QString::number(i+1)),arg); | ||
812 | } | 796 | } | ||
813 | QString s("#"); | 797 | QString s("#"); | ||
814 | s.append(realCmd).append("\n ").append(realAlt).append(" 2>&1;echo '### 000'\n"); | 798 | s.append(realCmd).append("\n ").append(realAlt).append(" 2>&1;echo '### 000'\n"); | ||
815 | if (realCmd == "FISH") | 799 | if (realCmd == "FISH") | ||
816 | s.prepend(" "); | 800 | s.prepend(" "); | ||
817 | commandList.append(s); | 801 | commandList.append(s); | ||
818 | commandCodes.append(cmd); | 802 | commandCodes.append(cmd); | ||
819 | va_end(list); | 803 | va_end(list); | ||
820 | return true; | 804 | return true; | ||
821 | } | 805 | } | ||
822 | 806 | | |||
823 | /** | 807 | /** | ||
824 | checks response string for result code, converting 000 and 001 appropriately | 808 | checks response string for result code, converting 000 and 001 appropriately | ||
825 | */ | 809 | */ | ||
826 | int fishProtocol::handleResponse(const QString &str){ | 810 | int fishProtocol::handleResponse(const QString &str){ | ||
827 | myDebug( << "handling: " << str << endl); | 811 | myDebug( << "handling: " << str); | ||
828 | if (str.startsWith(QLatin1String("### "))) { | 812 | if (str.startsWith(QLatin1String("### "))) { | ||
829 | bool isOk = false; | 813 | bool isOk = false; | ||
830 | int result = str.mid(4,3).toInt(&isOk); | 814 | int result = str.mid(4,3).toInt(&isOk); | ||
831 | if (!isOk) result = 500; | 815 | if (!isOk) result = 500; | ||
832 | if (result == 0) result = (errorCount != 0?500:200); | 816 | if (result == 0) result = (errorCount != 0?500:200); | ||
833 | if (result == 1) result = (errorCount != 0?500:100); | 817 | if (result == 1) result = (errorCount != 0?500:100); | ||
834 | myDebug( << "result: " << result << ", errorCount: " << errorCount << endl); | 818 | myDebug( << "result: " << result << ", errorCount: " << errorCount); | ||
835 | return result; | 819 | return result; | ||
836 | } else { | 820 | } else { | ||
837 | errorCount++; | 821 | errorCount++; | ||
838 | return 0; | 822 | return 0; | ||
839 | } | 823 | } | ||
840 | } | 824 | } | ||
841 | 825 | | |||
842 | int fishProtocol::makeTimeFromLs(const QString &monthStr, const QString &dayStr, const QString &timeyearStr) | 826 | int fishProtocol::makeTimeFromLs(const QString &monthStr, const QString &dayStr, const QString &timeyearStr) | ||
Show All 18 Lines | 827 | { | |||
861 | if (timeyearStr.length() == 4 && pos == -1) { | 845 | if (timeyearStr.length() == 4 && pos == -1) { | ||
862 | year = timeyearStr.toInt(); | 846 | year = timeyearStr.toInt(); | ||
863 | } else if (pos == -1) { | 847 | } else if (pos == -1) { | ||
864 | return 0; | 848 | return 0; | ||
865 | } else { | 849 | } else { | ||
866 | if (month > currentMonth + 1) year--; | 850 | if (month > currentMonth + 1) year--; | ||
867 | dt.time().setHMS(timeyearStr.left(pos).toInt(),timeyearStr.mid(pos+1).toInt(),0); | 851 | dt.time().setHMS(timeyearStr.left(pos).toInt(),timeyearStr.mid(pos+1).toInt(),0); | ||
868 | } | 852 | } | ||
869 | dt.date().setYMD(year,month,day); | 853 | dt.date().setDate(year,month,day); | ||
870 | 854 | | |||
871 | return dt.toTime_t(); | 855 | return dt.toTime_t(); | ||
872 | } | 856 | } | ||
873 | 857 | | |||
874 | /** | 858 | /** | ||
875 | parses response from server and acts accordingly | 859 | parses response from server and acts accordingly | ||
876 | */ | 860 | */ | ||
877 | void fishProtocol::manageConnection(const QString &l) { | 861 | void fishProtocol::manageConnection(const QString &l) { | ||
Show All 13 Lines | 873 | } else { | |||
891 | shutdownConnection(); | 875 | shutdownConnection(); | ||
892 | } | 876 | } | ||
893 | break; | 877 | break; | ||
894 | case FISH_PWD: | 878 | case FISH_PWD: | ||
895 | url.setPath(line); | 879 | url.setPath(line); | ||
896 | redirection(url); | 880 | redirection(url); | ||
897 | break; | 881 | break; | ||
898 | case FISH_LIST: | 882 | case FISH_LIST: | ||
899 | myDebug( << "listReason: " << static_cast<int>(listReason) << endl); | 883 | myDebug( << "listReason: " << static_cast<int>(listReason)); | ||
900 | /* Fall through */ | 884 | /* Fall through */ | ||
901 | case FISH_STAT: | 885 | case FISH_STAT: | ||
902 | if (line.length() > 0) { | 886 | if (line.length() > 0) { | ||
903 | switch (line[0].cell()) { | 887 | switch (line[0].cell()) { | ||
904 | case '0': | 888 | case '0': | ||
905 | case '1': | 889 | case '1': | ||
906 | case '2': | 890 | case '2': | ||
907 | case '3': | 891 | case '3': | ||
Show All 26 Lines | 917 | } else if (line[1] == 'c') { | |||
934 | udsType = S_IFCHR; | 918 | udsType = S_IFCHR; | ||
935 | } else if (line[1] == 'b') { | 919 | } else if (line[1] == 'b') { | ||
936 | udsType = S_IFBLK; | 920 | udsType = S_IFBLK; | ||
937 | } else if (line[1] == 's') { | 921 | } else if (line[1] == 's') { | ||
938 | udsType = S_IFSOCK; | 922 | udsType = S_IFSOCK; | ||
939 | } else if (line[1] == 'p') { | 923 | } else if (line[1] == 'p') { | ||
940 | udsType = S_IFIFO; | 924 | udsType = S_IFIFO; | ||
941 | } else { | 925 | } else { | ||
942 | myDebug( << "unknown file type: " << line[1].cell() << endl); | 926 | myDebug( << "unknown file type: " << line[1].cell()); | ||
943 | errorCount++; | 927 | errorCount++; | ||
944 | break; | 928 | break; | ||
945 | } | 929 | } | ||
946 | } | 930 | } | ||
947 | //myDebug( << "file type: " << udsType << endl); | 931 | //myDebug( << "file type: " << udsType); | ||
948 | 932 | | |||
949 | long long accessVal = 0; | 933 | long long accessVal = 0; | ||
950 | if (line[2] == 'r') accessVal |= S_IRUSR; | 934 | if (line[2] == 'r') accessVal |= S_IRUSR; | ||
951 | if (line[3] == 'w') accessVal |= S_IWUSR; | 935 | if (line[3] == 'w') accessVal |= S_IWUSR; | ||
952 | if (line[4] == 'x' || line[4] == 's') accessVal |= S_IXUSR; | 936 | if (line[4] == 'x' || line[4] == 's') accessVal |= S_IXUSR; | ||
953 | if (line[4] == 'S' || line[4] == 's') accessVal |= S_ISUID; | 937 | if (line[4] == 'S' || line[4] == 's') accessVal |= S_ISUID; | ||
954 | if (line[5] == 'r') accessVal |= S_IRGRP; | 938 | if (line[5] == 'r') accessVal |= S_IRGRP; | ||
955 | if (line[6] == 'w') accessVal |= S_IWGRP; | 939 | if (line[6] == 'w') accessVal |= S_IWGRP; | ||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Line(s) | 995 | case ':': | |||
1012 | pos = line.lastIndexOf('/'); | 996 | pos = line.lastIndexOf('/'); | ||
1013 | thisFn = line.mid(pos < 0?1:pos+1); | 997 | thisFn = line.mid(pos < 0?1:pos+1); | ||
1014 | if (fishCommand == FISH_LIST) { | 998 | if (fishCommand == FISH_LIST) { | ||
1015 | udsEntry.insert(KIO::UDSEntry::UDS_NAME, thisFn); | 999 | udsEntry.insert(KIO::UDSEntry::UDS_NAME, thisFn); | ||
1016 | } | 1000 | } | ||
1017 | // By default, the mimetype comes from the extension | 1001 | // By default, the mimetype comes from the extension | ||
1018 | // We'll use the file(1) result only as fallback [like the rest of KDE does] | 1002 | // We'll use the file(1) result only as fallback [like the rest of KDE does] | ||
1019 | { | 1003 | { | ||
1020 | KUrl kurl("fish://host/"); | 1004 | QUrl kurl("fish://host/"+thisFn); | ||
1021 | kurl.setFileName(thisFn); // properly encode special chars | 1005 | QMimeDatabase db; | ||
1022 | KMimeType::Ptr mime = KMimeType::findByUrl(kurl, udsType); | 1006 | QMimeType mime = db.mimeTypeForUrl(kurl); | ||
1023 | if ( mime->name() != KMimeType::defaultMimeType() ) | 1007 | if ( !mime.isDefault() ) | ||
1024 | udsMime = mime->name(); | 1008 | udsMime = mime.name(); | ||
1025 | } | 1009 | } | ||
1026 | errorCount--; | 1010 | errorCount--; | ||
1027 | break; | 1011 | break; | ||
1028 | 1012 | | |||
1029 | case 'M': | 1013 | case 'M': | ||
1030 | // This is getting ugly. file(1) makes some uneducated | 1014 | // This is getting ugly. file(1) makes some uneducated | ||
1031 | // guesses, so we must try to ignore them (#51274) | 1015 | // guesses, so we must try to ignore them (#51274) | ||
1032 | if (udsMime.isEmpty() && line.right(8) != "/unknown" && | 1016 | if (udsMime.isEmpty() && line.right(8) != "/unknown" && | ||
Show All 27 Lines | 1032 | } else { | |||
1060 | } else if (listReason == CHECK) checkExist = true; //0 | 1044 | } else if (listReason == CHECK) checkExist = true; //0 | ||
1061 | errorCount--; | 1045 | errorCount--; | ||
1062 | udsEntry.clear(); | 1046 | udsEntry.clear(); | ||
1063 | } | 1047 | } | ||
1064 | break; | 1048 | break; | ||
1065 | 1049 | | |||
1066 | case FISH_RETR: | 1050 | case FISH_RETR: | ||
1067 | if (line.length() == 0) { | 1051 | if (line.length() == 0) { | ||
1068 | error(ERR_IS_DIRECTORY,url.prettyUrl()); | 1052 | error(ERR_IS_DIRECTORY,url.toDisplayString()); | ||
1069 | recvLen = 0; | 1053 | recvLen = 0; | ||
1070 | break; | 1054 | break; | ||
1071 | } | 1055 | } | ||
1072 | recvLen = line.toLongLong(&isOk); | 1056 | recvLen = line.toLongLong(&isOk); | ||
1073 | if (!isOk) { | 1057 | if (!isOk) { | ||
1074 | error(ERR_COULD_NOT_READ,url.prettyUrl()); | 1058 | error(ERR_COULD_NOT_READ,url.toDisplayString()); | ||
1075 | shutdownConnection(); | 1059 | shutdownConnection(); | ||
1076 | break; | 1060 | break; | ||
1077 | } | 1061 | } | ||
1078 | break; | 1062 | break; | ||
1079 | default : break; | 1063 | default : break; | ||
1080 | } | 1064 | } | ||
1081 | 1065 | | |||
1082 | } else if (rc == 100) { | 1066 | } else if (rc == 100) { | ||
1083 | switch (fishCommand) { | 1067 | switch (fishCommand) { | ||
1084 | case FISH_FISH: | 1068 | case FISH_FISH: | ||
1085 | writeChild(fishCode, fishCodeLen); | 1069 | writeChild(fishCode, fishCodeLen); | ||
1086 | break; | 1070 | break; | ||
1087 | case FISH_READ: | 1071 | case FISH_READ: | ||
1088 | recvLen = 1024; | 1072 | recvLen = 1024; | ||
1089 | /* fall through */ | 1073 | /* fall through */ | ||
1090 | case FISH_RETR: | 1074 | case FISH_RETR: | ||
1091 | myDebug( << "reading " << recvLen << endl); | 1075 | myDebug( << "reading " << recvLen); | ||
1092 | if (recvLen == -1) { | 1076 | if (recvLen == -1) { | ||
1093 | error(ERR_COULD_NOT_READ,url.prettyUrl()); | 1077 | error(ERR_COULD_NOT_READ,url.toDisplayString()); | ||
1094 | shutdownConnection(); | 1078 | shutdownConnection(); | ||
1095 | } else { | 1079 | } else { | ||
1096 | rawRead = recvLen; | 1080 | rawRead = recvLen; | ||
1097 | dataRead = 0; | 1081 | dataRead = 0; | ||
1098 | mimeTypeSent = false; | 1082 | mimeTypeSent = false; | ||
1099 | if (recvLen == 0) | 1083 | if (recvLen == 0) | ||
1100 | { | 1084 | { | ||
1101 | mimeType("application/x-zerosize"); | 1085 | mimeType("application/x-zerosize"); | ||
1102 | mimeTypeSent = true; | 1086 | mimeTypeSent = true; | ||
1103 | } | 1087 | } | ||
1104 | } | 1088 | } | ||
1105 | break; | 1089 | break; | ||
1106 | case FISH_STOR: | 1090 | case FISH_STOR: | ||
1107 | case FISH_WRITE: | 1091 | case FISH_WRITE: | ||
1108 | case FISH_APPEND: | 1092 | case FISH_APPEND: | ||
1109 | rawWrite = sendLen; | 1093 | rawWrite = sendLen; | ||
1110 | //myDebug( << "sending " << sendLen << endl); | 1094 | //myDebug( << "sending " << sendLen); | ||
1111 | writeChild(NULL,0); | 1095 | writeChild(NULL,0); | ||
1112 | break; | 1096 | break; | ||
1113 | default : break; | 1097 | default : break; | ||
1114 | } | 1098 | } | ||
1115 | } else if (rc/100 != 2) { | 1099 | } else if (rc/100 != 2) { | ||
1116 | switch (fishCommand) { | 1100 | switch (fishCommand) { | ||
1117 | case FISH_STOR: | 1101 | case FISH_STOR: | ||
1118 | case FISH_WRITE: | 1102 | case FISH_WRITE: | ||
1119 | case FISH_APPEND: | 1103 | case FISH_APPEND: | ||
1120 | error(ERR_COULD_NOT_WRITE,url.prettyUrl()); | 1104 | error(ERR_COULD_NOT_WRITE,url.toDisplayString()); | ||
1121 | shutdownConnection(); | 1105 | shutdownConnection(); | ||
1122 | break; | 1106 | break; | ||
1123 | case FISH_RETR: | 1107 | case FISH_RETR: | ||
1124 | error(ERR_COULD_NOT_READ,url.prettyUrl()); | 1108 | error(ERR_COULD_NOT_READ,url.toDisplayString()); | ||
1125 | shutdownConnection(); | 1109 | shutdownConnection(); | ||
1126 | break; | 1110 | break; | ||
1127 | case FISH_READ: | 1111 | case FISH_READ: | ||
1128 | if ( rc == 501 ) | 1112 | if ( rc == 501 ) | ||
1129 | { | 1113 | { | ||
1130 | mimeType("inode/directory"); | 1114 | mimeType("inode/directory"); | ||
1131 | mimeTypeSent = true; | 1115 | mimeTypeSent = true; | ||
1132 | recvLen = 0; | 1116 | recvLen = 0; | ||
1133 | finished(); | 1117 | finished(); | ||
1134 | } | 1118 | } | ||
1135 | else | 1119 | else | ||
1136 | { | 1120 | { | ||
1137 | error(ERR_COULD_NOT_READ,url.prettyUrl()); | 1121 | error(ERR_COULD_NOT_READ,url.toDisplayString()); | ||
1138 | shutdownConnection(); | 1122 | shutdownConnection(); | ||
1139 | } | 1123 | } | ||
1140 | break; | 1124 | break; | ||
1141 | case FISH_FISH: | 1125 | case FISH_FISH: | ||
1142 | case FISH_VER: | 1126 | case FISH_VER: | ||
1143 | error(ERR_SLAVE_DEFINED,line); | 1127 | error(ERR_SLAVE_DEFINED,line); | ||
1144 | shutdownConnection(); | 1128 | shutdownConnection(); | ||
1145 | break; | 1129 | break; | ||
1146 | case FISH_PWD: | 1130 | case FISH_PWD: | ||
1147 | case FISH_CWD: | 1131 | case FISH_CWD: | ||
1148 | error(ERR_CANNOT_ENTER_DIRECTORY,url.prettyUrl()); | 1132 | error(ERR_CANNOT_ENTER_DIRECTORY,url.toDisplayString()); | ||
1149 | break; | 1133 | break; | ||
1150 | case FISH_LIST: | 1134 | case FISH_LIST: | ||
1151 | myDebug( << "list error. reason: " << static_cast<int>(listReason) << endl); | 1135 | myDebug( << "list error. reason: " << static_cast<int>(listReason)); | ||
1152 | if (listReason == LIST) error(ERR_CANNOT_ENTER_DIRECTORY,url.prettyUrl()); | 1136 | if (listReason == LIST) error(ERR_CANNOT_ENTER_DIRECTORY,url.toDisplayString()); | ||
1153 | else if (listReason == CHECK) { | 1137 | else if (listReason == CHECK) { | ||
1154 | checkExist = false; | 1138 | checkExist = false; | ||
1155 | finished(); | 1139 | finished(); | ||
1156 | } | 1140 | } | ||
1157 | break; | 1141 | break; | ||
1158 | case FISH_STAT: | 1142 | case FISH_STAT: | ||
1159 | error(ERR_DOES_NOT_EXIST,url.prettyUrl()); | 1143 | error(ERR_DOES_NOT_EXIST,url.toDisplayString()); | ||
1160 | udsStatEntry.clear(); | 1144 | udsStatEntry.clear(); | ||
1161 | break; | 1145 | break; | ||
1162 | case FISH_CHMOD: | 1146 | case FISH_CHMOD: | ||
1163 | error(ERR_CANNOT_CHMOD,url.prettyUrl()); | 1147 | error(ERR_CANNOT_CHMOD,url.toDisplayString()); | ||
1164 | break; | 1148 | break; | ||
1165 | case FISH_CHOWN: | 1149 | case FISH_CHOWN: | ||
1166 | case FISH_CHGRP: | 1150 | case FISH_CHGRP: | ||
1167 | error(ERR_ACCESS_DENIED,url.prettyUrl()); | 1151 | error(ERR_ACCESS_DENIED,url.toDisplayString()); | ||
1168 | break; | 1152 | break; | ||
1169 | case FISH_MKD: | 1153 | case FISH_MKD: | ||
1170 | if ( rc == 501 ) | 1154 | if ( rc == 501 ) | ||
1171 | error(ERR_DIR_ALREADY_EXIST,url.prettyUrl()); | 1155 | error(ERR_DIR_ALREADY_EXIST,url.toDisplayString()); | ||
1172 | else | 1156 | else | ||
1173 | error(ERR_COULD_NOT_MKDIR,url.prettyUrl()); | 1157 | error(ERR_COULD_NOT_MKDIR,url.toDisplayString()); | ||
1174 | break; | 1158 | break; | ||
1175 | case FISH_RMD: | 1159 | case FISH_RMD: | ||
1176 | error(ERR_COULD_NOT_RMDIR,url.prettyUrl()); | 1160 | error(ERR_COULD_NOT_RMDIR,url.toDisplayString()); | ||
1177 | break; | 1161 | break; | ||
1178 | case FISH_DELE: | 1162 | case FISH_DELE: | ||
1179 | error(ERR_CANNOT_DELETE,url.prettyUrl()); | 1163 | error(ERR_CANNOT_DELETE,url.toDisplayString()); | ||
1180 | break; | 1164 | break; | ||
1181 | case FISH_RENAME: | 1165 | case FISH_RENAME: | ||
1182 | error(ERR_CANNOT_RENAME,url.prettyUrl()); | 1166 | error(ERR_CANNOT_RENAME,url.toDisplayString()); | ||
1183 | break; | 1167 | break; | ||
1184 | case FISH_COPY: | 1168 | case FISH_COPY: | ||
1185 | case FISH_LINK: | 1169 | case FISH_LINK: | ||
1186 | case FISH_SYMLINK: | 1170 | case FISH_SYMLINK: | ||
1187 | error(ERR_COULD_NOT_WRITE,url.prettyUrl()); | 1171 | error(ERR_COULD_NOT_WRITE,url.toDisplayString()); | ||
1188 | break; | 1172 | break; | ||
1189 | default : break; | 1173 | default : break; | ||
1190 | } | 1174 | } | ||
1191 | } else { | 1175 | } else { | ||
1192 | if (fishCommand == FISH_STOR) fishCommand = (hasAppend?FISH_APPEND:FISH_WRITE); | 1176 | if (fishCommand == FISH_STOR) fishCommand = (hasAppend?FISH_APPEND:FISH_WRITE); | ||
1193 | if (fishCommand == FISH_FISH) { | 1177 | if (fishCommand == FISH_FISH) { | ||
1194 | connected(); | 1178 | connected(); | ||
1195 | } else if (fishCommand == FISH_LIST) { | 1179 | } else if (fishCommand == FISH_LIST) { | ||
1196 | if (listReason == CHECK && !checkOverwrite && checkExist) { | 1180 | if (listReason == CHECK && !checkOverwrite && checkExist) { | ||
1197 | error(ERR_FILE_ALREADY_EXIST,url.prettyUrl()); | 1181 | error(ERR_FILE_ALREADY_EXIST,url.toDisplayString()); | ||
1198 | return; // Don't call finished! | 1182 | return; // Don't call finished! | ||
1199 | } | 1183 | } | ||
1200 | } else if (fishCommand == FISH_STAT) { | 1184 | } else if (fishCommand == FISH_STAT) { | ||
1201 | udsStatEntry.insert( KIO::UDSEntry::UDS_NAME, url.fileName() ); | 1185 | udsStatEntry.insert( KIO::UDSEntry::UDS_NAME, url.fileName() ); | ||
1202 | statEntry(udsStatEntry); | 1186 | statEntry(udsStatEntry); | ||
1203 | } else if (fishCommand == FISH_APPEND) { | 1187 | } else if (fishCommand == FISH_APPEND) { | ||
1204 | dataReq(); | 1188 | dataReq(); | ||
1205 | if (readData(rawData) > 0) sendCommand(FISH_APPEND,E(QString::number(rawData.size())),E(url.path())); | 1189 | if (readData(rawData) > 0) sendCommand(FISH_APPEND,E(QString::number(rawData.size())),E(url.path())); | ||
Show All 13 Lines | |||||
1219 | } | 1203 | } | ||
1220 | 1204 | | |||
1221 | void fishProtocol::writeStdin(const QString &line) | 1205 | void fishProtocol::writeStdin(const QString &line) | ||
1222 | { | 1206 | { | ||
1223 | qlist.append(E(line)); | 1207 | qlist.append(E(line)); | ||
1224 | 1208 | | |||
1225 | if (writeReady) { | 1209 | if (writeReady) { | ||
1226 | writeReady = false; | 1210 | writeReady = false; | ||
1227 | //myDebug( << "Writing: " << qlist.first().mid(0,qlist.first().indexOf('\n')) << endl); | 1211 | //myDebug( << "Writing: " << qlist.first().mid(0,qlist.first().indexOf('\n'))); | ||
1228 | myDebug( << "Writing: " << qlist.first() << endl); | 1212 | myDebug( << "Writing: " << qlist.first()); | ||
1229 | myDebug( << "---------" << endl); | 1213 | myDebug( << "---------"); | ||
1230 | writeChild((const char *)qlist.first(), qlist.first().length()); | 1214 | writeChild((const char *)qlist.first(), qlist.first().length()); | ||
1231 | } | 1215 | } | ||
1232 | } | 1216 | } | ||
1233 | 1217 | | |||
1234 | void fishProtocol::sent() | 1218 | void fishProtocol::sent() | ||
1235 | { | 1219 | { | ||
1236 | if (rawWrite > 0) { | 1220 | if (rawWrite > 0) { | ||
1237 | myDebug( << "writing raw: " << rawData.size() << "/" << rawWrite << endl); | 1221 | myDebug( << "writing raw: " << rawData.size() << "/" << rawWrite); | ||
1238 | writeChild(rawData.data(),(rawWrite > rawData.size()?rawData.size():rawWrite)); | 1222 | writeChild(rawData.data(),(rawWrite > rawData.size()?rawData.size():rawWrite)); | ||
1239 | rawWrite -= rawData.size(); | 1223 | rawWrite -= rawData.size(); | ||
1240 | if (rawWrite > 0) { | 1224 | if (rawWrite > 0) { | ||
1241 | dataReq(); | 1225 | dataReq(); | ||
1242 | if (readData(rawData) <= 0) { | 1226 | if (readData(rawData) <= 0) { | ||
1243 | shutdownConnection(); | 1227 | shutdownConnection(); | ||
1244 | } | 1228 | } | ||
1245 | } | 1229 | } | ||
1246 | return; | 1230 | return; | ||
1247 | } else if (rawWrite == 0) { | 1231 | } else if (rawWrite == 0) { | ||
1248 | // workaround: some dd's insist in reading multiples of | 1232 | // workaround: some dd's insist in reading multiples of | ||
1249 | // 8 bytes, swallowing up to seven bytes. Sending | 1233 | // 8 bytes, swallowing up to seven bytes. Sending | ||
1250 | // newlines is safe even when a sane dd is used | 1234 | // newlines is safe even when a sane dd is used | ||
1251 | writeChild("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",15); | 1235 | writeChild("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",15); | ||
1252 | rawWrite = -1; | 1236 | rawWrite = -1; | ||
1253 | return; | 1237 | return; | ||
1254 | } | 1238 | } | ||
1255 | if (qlist.count() > 0) qlist.erase(qlist.begin()); | 1239 | if (qlist.count() > 0) qlist.erase(qlist.begin()); | ||
1256 | if (qlist.count() == 0) { | 1240 | if (qlist.count() == 0) { | ||
1257 | writeReady = true; | 1241 | writeReady = true; | ||
1258 | } else { | 1242 | } else { | ||
1259 | //myDebug( << "Writing: " << qlist.first().mid(0,qlist.first().indexOf('\n')) << endl); | 1243 | //myDebug( << "Writing: " << qlist.first().mid(0,qlist.first().indexOf('\n'))); | ||
1260 | myDebug( << "Writing: " << qlist.first() << endl); | 1244 | myDebug( << "Writing: " << qlist.first()); | ||
1261 | myDebug( << "---------" << endl); | 1245 | myDebug( << "---------"); | ||
1262 | writeChild((const char *)qlist.first(),qlist.first().length()); | 1246 | writeChild((const char *)qlist.first(),qlist.first().length()); | ||
1263 | } | 1247 | } | ||
1264 | } | 1248 | } | ||
1265 | 1249 | | |||
1266 | int fishProtocol::received(const char *buffer, KIO::fileoffset_t buflen) | 1250 | int fishProtocol::received(const char *buffer, KIO::fileoffset_t buflen) | ||
1267 | { | 1251 | { | ||
1268 | int pos = 0; | 1252 | int pos = 0; | ||
1269 | do { | 1253 | do { | ||
1270 | if (buflen <= 0) break; | 1254 | if (buflen <= 0) break; | ||
1271 | 1255 | | |||
1272 | if (rawRead > 0) { | 1256 | if (rawRead > 0) { | ||
1273 | myDebug( << "processedSize " << dataRead << ", len " << buflen << "/" << rawRead << endl); | 1257 | myDebug( << "processedSize " << dataRead << ", len " << buflen << "/" << rawRead); | ||
1274 | int dataSize = (rawRead > buflen?buflen:rawRead); | 1258 | int dataSize = (rawRead > buflen?buflen:rawRead); | ||
1275 | if (!mimeTypeSent) | 1259 | if (!mimeTypeSent) | ||
1276 | { | 1260 | { | ||
1277 | int mimeSize = qMin(dataSize, (int)(mimeBuffer.size()-dataRead)); | 1261 | int mimeSize = qMin(dataSize, (int)(mimeBuffer.size()-dataRead)); | ||
1278 | memcpy(mimeBuffer.data()+dataRead,buffer,mimeSize); | 1262 | memcpy(mimeBuffer.data()+dataRead,buffer,mimeSize); | ||
1279 | dataRead += mimeSize; | 1263 | dataRead += mimeSize; | ||
1280 | rawRead -= mimeSize; | 1264 | rawRead -= mimeSize; | ||
1281 | buffer += mimeSize; | 1265 | buffer += mimeSize; | ||
1282 | buflen -= mimeSize; | 1266 | buflen -= mimeSize; | ||
1283 | if (rawRead == 0) // End of data | 1267 | if (rawRead == 0) // End of data | ||
1284 | mimeBuffer.resize(dataRead); | 1268 | mimeBuffer.resize(dataRead); | ||
1285 | if (dataRead < (int)mimeBuffer.size()) | 1269 | if (dataRead < (int)mimeBuffer.size()) | ||
1286 | { | 1270 | { | ||
1287 | myDebug( << "wait for more" << endl); | 1271 | myDebug( << "wait for more"); | ||
1288 | break; | 1272 | break; | ||
1289 | } | 1273 | } | ||
1290 | sendmimeType(KMimeType::findByNameAndContent(url.path(), mimeBuffer)->name()); | 1274 | | ||
1275 | QMimeDatabase db; | ||||
1276 | sendmimeType(db.mimeTypeForFileNameAndData(url.path(), mimeBuffer).name()); | ||||
1291 | mimeTypeSent = true; | 1277 | mimeTypeSent = true; | ||
1292 | if (fishCommand != FISH_READ) { | 1278 | if (fishCommand != FISH_READ) { | ||
1293 | totalSize(dataRead + rawRead); | 1279 | totalSize(dataRead + rawRead); | ||
1294 | data(mimeBuffer); | 1280 | data(mimeBuffer); | ||
1295 | processedSize(dataRead); | 1281 | processedSize(dataRead); | ||
1296 | } | 1282 | } | ||
1297 | mimeBuffer.resize(1024); | 1283 | mimeBuffer.resize(1024); | ||
1298 | pos = 0; | 1284 | pos = 0; | ||
Show All 35 Lines | 1310 | { | |||
1334 | while((pos < buflen) && (buffer[pos] != '\n')) | 1320 | while((pos < buflen) && (buffer[pos] != '\n')) | ||
1335 | ++pos; | 1321 | ++pos; | ||
1336 | } | 1322 | } | ||
1337 | } while (childPid && buflen && (rawRead > 0 || pos < buflen)); | 1323 | } while (childPid && buflen && (rawRead > 0 || pos < buflen)); | ||
1338 | return buflen; | 1324 | return buflen; | ||
1339 | } | 1325 | } | ||
1340 | /** get a file */ | 1326 | /** get a file */ | ||
1341 | void fishProtocol::get(const QUrl& u){ | 1327 | void fishProtocol::get(const QUrl& u){ | ||
1342 | myDebug( << "@@@@@@@@@ get " << u << endl); | 1328 | myDebug( << "@@@@@@@@@ get " << u); | ||
1343 | setHostInternal(u); | 1329 | setHostInternal(u); | ||
1344 | url = u; | 1330 | url = u; | ||
1345 | openConnection(); | 1331 | openConnection(); | ||
1346 | if (!isLoggedIn) return; | 1332 | if (!isLoggedIn) return; | ||
1347 | url.cleanPath(); | 1333 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1348 | if (!url.hasPath()) { | 1334 | if (url.path().isEmpty()) { | ||
1349 | sendCommand(FISH_PWD); | 1335 | sendCommand(FISH_PWD); | ||
1350 | } else { | 1336 | } else { | ||
1351 | recvLen = -1; | 1337 | recvLen = -1; | ||
1352 | sendCommand(FISH_RETR,E(url.path())); | 1338 | sendCommand(FISH_RETR,E(url.path())); | ||
1353 | } | 1339 | } | ||
1354 | run(); | 1340 | run(); | ||
1355 | } | 1341 | } | ||
1356 | 1342 | | |||
1357 | /** put a file */ | 1343 | /** put a file */ | ||
1358 | void fishProtocol::put(const QUrl& u, int permissions, KIO::JobFlags flags) { | 1344 | void fishProtocol::put(const QUrl& u, int permissions, KIO::JobFlags flags) { | ||
1359 | myDebug( << "@@@@@@@@@ put " << u << " " << permissions << " " << (flags & KIO::Overwrite) << " " /* << resume */ << endl); | 1345 | myDebug( << "@@@@@@@@@ put " << u << " " << permissions << " " << (flags & KIO::Overwrite) << " " /* << resume */); | ||
1360 | setHostInternal(u); | 1346 | setHostInternal(u); | ||
1361 | 1347 | | |||
1362 | url = u; | 1348 | url = u; | ||
1363 | openConnection(); | 1349 | openConnection(); | ||
1364 | if (!isLoggedIn) return; | 1350 | if (!isLoggedIn) return; | ||
1365 | url.cleanPath(); | 1351 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1366 | if (!url.hasPath()) { | 1352 | if (url.path().isEmpty()) { | ||
1367 | sendCommand(FISH_PWD); | 1353 | sendCommand(FISH_PWD); | ||
1368 | } else { | 1354 | } else { | ||
1369 | putPerm = permissions; | 1355 | putPerm = permissions; | ||
1370 | 1356 | | |||
1371 | checkOverwrite = flags & KIO::Overwrite; | 1357 | checkOverwrite = flags & KIO::Overwrite; | ||
1372 | checkExist = false; | 1358 | checkExist = false; | ||
1373 | putPos = 0; | 1359 | putPos = 0; | ||
1374 | listReason = CHECK; | 1360 | listReason = CHECK; | ||
Show All 18 Lines | 1375 | if (commandList.count() > 0) { | |||
1393 | rawWrite = -1; | 1379 | rawWrite = -1; | ||
1394 | udsEntry.clear(); | 1380 | udsEntry.clear(); | ||
1395 | udsStatEntry.clear(); | 1381 | udsStatEntry.clear(); | ||
1396 | writeStdin(commandList.first()); | 1382 | writeStdin(commandList.first()); | ||
1397 | //if (fishCommand != FISH_APPEND && fishCommand != FISH_WRITE) infoMessage("Sending "+(commandList.first().mid(1,commandList.first().indexOf("\n")-1))+"..."); | 1383 | //if (fishCommand != FISH_APPEND && fishCommand != FISH_WRITE) infoMessage("Sending "+(commandList.first().mid(1,commandList.first().indexOf("\n")-1))+"..."); | ||
1398 | commandList.erase(commandList.begin()); | 1384 | commandList.erase(commandList.begin()); | ||
1399 | commandCodes.erase(commandCodes.begin()); | 1385 | commandCodes.erase(commandCodes.begin()); | ||
1400 | } else { | 1386 | } else { | ||
1401 | myDebug( << "_______ emitting finished()" << endl); | 1387 | myDebug( << "_______ emitting finished()"); | ||
1402 | SlaveBase::finished(); | 1388 | SlaveBase::finished(); | ||
1403 | isRunning = false; | 1389 | isRunning = false; | ||
1404 | } | 1390 | } | ||
1405 | } | 1391 | } | ||
1406 | 1392 | | |||
1407 | /** aborts command sequence and calls error() */ | 1393 | /** aborts command sequence and calls error() */ | ||
1408 | void fishProtocol::error(int type, const QString &detail) { | 1394 | void fishProtocol::error(int type, const QString &detail) { | ||
1409 | commandList.clear(); | 1395 | commandList.clear(); | ||
1410 | commandCodes.clear(); | 1396 | commandCodes.clear(); | ||
1411 | myDebug( << "ERROR: " << type << " - " << detail << endl); | 1397 | myDebug( << "ERROR: " << type << " - " << detail); | ||
1412 | SlaveBase::error(type,detail); | 1398 | SlaveBase::error(type,detail); | ||
1413 | isRunning = false; | 1399 | isRunning = false; | ||
1414 | } | 1400 | } | ||
1415 | 1401 | | |||
1416 | /** executes a chain of commands */ | 1402 | /** executes a chain of commands */ | ||
1417 | void fishProtocol::run() | 1403 | void fishProtocol::run() | ||
1418 | /* This function writes to childFd fish commands (like #STOR 0 /tmp/test ...) that are stored in outBuf | 1404 | /* This function writes to childFd fish commands (like #STOR 0 /tmp/test ...) that are stored in outBuf | ||
1419 | and reads from childFd the remote host's response. ChildFd is the fd to a process that communicates | 1405 | and reads from childFd the remote host's response. ChildFd is the fd to a process that communicates | ||
Show All 16 Lines | 1419 | #ifndef Q_OS_WIN | |||
1436 | if (outBufPos >= 0) FD_SET(childFd,&wfds); | 1422 | if (outBufPos >= 0) FD_SET(childFd,&wfds); | ||
1437 | struct timeval timeout; | 1423 | struct timeval timeout; | ||
1438 | timeout.tv_sec = 0; | 1424 | timeout.tv_sec = 0; | ||
1439 | timeout.tv_usec = 1000; | 1425 | timeout.tv_usec = 1000; | ||
1440 | rc = select(childFd+1, &rfds, &wfds, NULL, &timeout); | 1426 | rc = select(childFd+1, &rfds, &wfds, NULL, &timeout); | ||
1441 | if (rc < 0) { | 1427 | if (rc < 0) { | ||
1442 | if (errno == EINTR) | 1428 | if (errno == EINTR) | ||
1443 | continue; | 1429 | continue; | ||
1444 | myDebug( << "select failed, rc: " << rc << ", error: " << strerror(errno) << endl); | 1430 | myDebug( << "select failed, rc: " << rc << ", error: " << strerror(errno)); | ||
1445 | error(ERR_CONNECTION_BROKEN,connectionHost); | 1431 | error(ERR_CONNECTION_BROKEN,connectionHost); | ||
1446 | shutdownConnection(); | 1432 | shutdownConnection(); | ||
1447 | return; | 1433 | return; | ||
1448 | } | 1434 | } | ||
1449 | // We first write the complete buffer, including all newlines. | 1435 | // We first write the complete buffer, including all newlines. | ||
1450 | // Do: send command and newlines, expect response then | 1436 | // Do: send command and newlines, expect response then | ||
1451 | // Do not: send commands, expect response, send newlines, expect response on newlines | 1437 | // Do not: send commands, expect response, send newlines, expect response on newlines | ||
1452 | // Newlines do not trigger a response. | 1438 | // Newlines do not trigger a response. | ||
Show All 10 Lines | 1448 | else | |||
1463 | rc = 0; | 1449 | rc = 0; | ||
1464 | 1450 | | |||
1465 | if (rc >= 0) | 1451 | if (rc >= 0) | ||
1466 | outBufPos += rc; | 1452 | outBufPos += rc; | ||
1467 | else { | 1453 | else { | ||
1468 | #ifndef Q_OS_WIN | 1454 | #ifndef Q_OS_WIN | ||
1469 | if (errno == EINTR) | 1455 | if (errno == EINTR) | ||
1470 | continue; | 1456 | continue; | ||
1471 | myDebug( << "write failed, rc: " << rc << ", error: " << strerror(errno) << endl); | 1457 | myDebug( << "write failed, rc: " << rc << ", error: " << strerror(errno)); | ||
1472 | #else | 1458 | #else | ||
1473 | myDebug( << "write failed, rc: " << rc); | 1459 | myDebug( << "write failed, rc: " << rc); | ||
1474 | #endif | 1460 | #endif | ||
1475 | error(ERR_CONNECTION_BROKEN,connectionHost); | 1461 | error(ERR_CONNECTION_BROKEN,connectionHost); | ||
1476 | shutdownConnection(); | 1462 | shutdownConnection(); | ||
1477 | return; | 1463 | return; | ||
1478 | } | 1464 | } | ||
1479 | if (outBufPos >= outBufLen) { | 1465 | if (outBufPos >= outBufLen) { | ||
1480 | outBufPos = -1; | 1466 | outBufPos = -1; | ||
1481 | outBuf = NULL; | 1467 | outBuf = NULL; | ||
1482 | sent(); | 1468 | sent(); | ||
1483 | } | 1469 | } | ||
1484 | } | 1470 | } | ||
1485 | #ifndef Q_OS_WIN | 1471 | #ifndef Q_OS_WIN | ||
1486 | else if (FD_ISSET(childFd,&rfds)) { | 1472 | else if (FD_ISSET(childFd,&rfds)) { | ||
1487 | rc = ::read(childFd, buf + offset, sizeof(buf) - offset); | 1473 | rc = ::read(childFd, buf + offset, sizeof(buf) - offset); | ||
1488 | #else | 1474 | #else | ||
1489 | else if (childPid->waitForReadyRead(1000)) { | 1475 | else if (childPid->waitForReadyRead(1000)) { | ||
1490 | rc = childPid->read(buf + offset, sizeof(buf) - offset); | 1476 | rc = childPid->read(buf + offset, sizeof(buf) - offset); | ||
1491 | #endif | 1477 | #endif | ||
1492 | //myDebug( << "read " << rc << " bytes" << endl); | 1478 | //myDebug( << "read " << rc << " bytes"); | ||
1493 | if (rc > 0) { | 1479 | if (rc > 0) { | ||
1494 | int noff = received(buf, rc + offset); | 1480 | int noff = received(buf, rc + offset); | ||
1495 | if (noff > 0) memmove(buf, buf + offset + rc - noff, noff); | 1481 | if (noff > 0) memmove(buf, buf + offset + rc - noff, noff); | ||
1496 | //myDebug( << "left " << noff << " bytes: " << QString::fromLatin1(buf,offset) << endl); | 1482 | //myDebug( << "left " << noff << " bytes: " << QString::fromLatin1(buf,offset)); | ||
1497 | offset = noff; | 1483 | offset = noff; | ||
1498 | } else { | 1484 | } else { | ||
1499 | #ifndef Q_OS_WIN | 1485 | #ifndef Q_OS_WIN | ||
1500 | if (errno == EINTR) | 1486 | if (errno == EINTR) | ||
1501 | continue; | 1487 | continue; | ||
1502 | myDebug( << "read failed, rc: " << rc << ", error: " << strerror(errno) << endl); | 1488 | myDebug( << "read failed, rc: " << rc << ", error: " << strerror(errno)); | ||
1503 | #else | 1489 | #else | ||
1504 | myDebug( << "read failed, rc: " << rc ); | 1490 | myDebug( << "read failed, rc: " << rc ); | ||
1505 | #endif | 1491 | #endif | ||
1506 | error(ERR_CONNECTION_BROKEN,connectionHost); | 1492 | error(ERR_CONNECTION_BROKEN,connectionHost); | ||
1507 | shutdownConnection(); | 1493 | shutdownConnection(); | ||
1508 | return; | 1494 | return; | ||
1509 | } | 1495 | } | ||
1510 | } | 1496 | } | ||
1511 | if (wasKilled()) | 1497 | if (wasKilled()) | ||
1512 | return; | 1498 | return; | ||
1513 | } | 1499 | } | ||
1514 | } | 1500 | } | ||
1515 | } | 1501 | } | ||
1516 | 1502 | | |||
1517 | /** stat a file */ | 1503 | /** stat a file */ | ||
1518 | void fishProtocol::stat(const QUrl& u){ | 1504 | void fishProtocol::stat(const QUrl& u){ | ||
1519 | myDebug( << "@@@@@@@@@ stat " << u << endl); | 1505 | myDebug( << "@@@@@@@@@ stat " << u); | ||
1520 | setHostInternal(u); | 1506 | setHostInternal(u); | ||
1521 | url = u; | 1507 | url = u; | ||
1522 | isStat = true; // FIXME: just a workaround for konq deficiencies | 1508 | isStat = true; // FIXME: just a workaround for konq deficiencies | ||
1523 | openConnection(); | 1509 | openConnection(); | ||
1524 | isStat = false; // FIXME: just a workaround for konq deficiencies | 1510 | isStat = false; // FIXME: just a workaround for konq deficiencies | ||
1525 | if (!isLoggedIn) return; | 1511 | if (!isLoggedIn) return; | ||
1526 | url.cleanPath(); | 1512 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1527 | if (!url.hasPath()) { | 1513 | if (url.path().isEmpty()) { | ||
1528 | sendCommand(FISH_PWD); | 1514 | sendCommand(FISH_PWD); | ||
1529 | } else { | 1515 | } else { | ||
1530 | sendCommand(FISH_STAT,E(url.path(KUrl::RemoveTrailingSlash))); | 1516 | sendCommand(FISH_STAT,E(url.adjusted(QUrl::StripTrailingSlash).path())); | ||
1531 | } | 1517 | } | ||
1532 | run(); | 1518 | run(); | ||
1533 | } | 1519 | } | ||
1534 | /** find mimetype for a file */ | 1520 | /** find mimetype for a file */ | ||
1535 | void fishProtocol::mimetype(const QUrl& u){ | 1521 | void fishProtocol::mimetype(const QUrl& u){ | ||
1536 | myDebug( << "@@@@@@@@@ mimetype " << u << endl); | 1522 | myDebug( << "@@@@@@@@@ mimetype " << u); | ||
1537 | setHostInternal(u); | 1523 | setHostInternal(u); | ||
1538 | url = u; | 1524 | url = u; | ||
1539 | openConnection(); | 1525 | openConnection(); | ||
1540 | if (!isLoggedIn) return; | 1526 | if (!isLoggedIn) return; | ||
1541 | url.cleanPath(); | 1527 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1542 | if (!url.hasPath()) { | 1528 | if (url.path().isEmpty()) { | ||
1543 | sendCommand(FISH_PWD); | 1529 | sendCommand(FISH_PWD); | ||
1544 | } else { | 1530 | } else { | ||
1545 | recvLen = 1024; | 1531 | recvLen = 1024; | ||
1546 | sendCommand(FISH_READ,"0","1024",E(url.path())); | 1532 | sendCommand(FISH_READ,"0","1024",E(url.path())); | ||
1547 | } | 1533 | } | ||
1548 | run(); | 1534 | run(); | ||
1549 | } | 1535 | } | ||
1550 | /** list a directory */ | 1536 | /** list a directory */ | ||
1551 | void fishProtocol::listDir(const QUrl& u){ | 1537 | void fishProtocol::listDir(const QUrl& u){ | ||
1552 | myDebug( << "@@@@@@@@@ listDir " << u << endl); | 1538 | myDebug( << "@@@@@@@@@ listDir " << u); | ||
1553 | setHostInternal(u); | 1539 | setHostInternal(u); | ||
1554 | url = u; | 1540 | url = u; | ||
1555 | openConnection(); | 1541 | openConnection(); | ||
1556 | if (!isLoggedIn) return; | 1542 | if (!isLoggedIn) return; | ||
1557 | url.cleanPath(); | 1543 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1558 | if (!url.hasPath()) { | 1544 | if (url.path().isEmpty()) { | ||
1559 | sendCommand(FISH_PWD); | 1545 | sendCommand(FISH_PWD); | ||
1560 | } else { | 1546 | } else { | ||
1561 | listReason = LIST; | 1547 | listReason = LIST; | ||
1562 | sendCommand(FISH_LIST,E(url.path())); | 1548 | sendCommand(FISH_LIST,E(url.path())); | ||
1563 | } | 1549 | } | ||
1564 | run(); | 1550 | run(); | ||
1565 | } | 1551 | } | ||
1566 | /** create a directory */ | 1552 | /** create a directory */ | ||
1567 | void fishProtocol::mkdir(const QUrl& u, int permissions) { | 1553 | void fishProtocol::mkdir(const QUrl& u, int permissions) { | ||
1568 | myDebug( << "@@@@@@@@@ mkdir " << u << " " << permissions << endl); | 1554 | myDebug( << "@@@@@@@@@ mkdir " << u << " " << permissions); | ||
1569 | setHostInternal(u); | 1555 | setHostInternal(u); | ||
1570 | url = u; | 1556 | url = u; | ||
1571 | openConnection(); | 1557 | openConnection(); | ||
1572 | if (!isLoggedIn) return; | 1558 | if (!isLoggedIn) return; | ||
1573 | url.cleanPath(); | 1559 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1574 | if (!url.hasPath()) { | 1560 | if (url.path().isEmpty()) { | ||
1575 | sendCommand(FISH_PWD); | 1561 | sendCommand(FISH_PWD); | ||
1576 | } else { | 1562 | } else { | ||
1577 | sendCommand(FISH_MKD,E(url.path())); | 1563 | sendCommand(FISH_MKD,E(url.path())); | ||
1578 | if (permissions > -1) sendCommand(FISH_CHMOD,E(QString::number(permissions,8)),E(url.path())); | 1564 | if (permissions > -1) sendCommand(FISH_CHMOD,E(QString::number(permissions,8)),E(url.path())); | ||
1579 | } | 1565 | } | ||
1580 | run(); | 1566 | run(); | ||
1581 | } | 1567 | } | ||
1582 | /** rename a file */ | 1568 | /** rename a file */ | ||
1583 | void fishProtocol::rename(const QUrl& s, const QUrl& d, KIO::JobFlags flags) { | 1569 | void fishProtocol::rename(const QUrl& s, const QUrl& d, KIO::JobFlags flags) { | ||
1584 | myDebug( << "@@@@@@@@@ rename " << s << " " << d << " " << (flags & KIO::Overwrite) << endl); | 1570 | myDebug( << "@@@@@@@@@ rename " << s << " " << d << " " << (flags & KIO::Overwrite)); | ||
1585 | if (s.host() != d.host() || s.port() != d.port() || s.userName() != d.userName()) { | 1571 | if (s.host() != d.host() || s.port() != d.port() || s.userName() != d.userName()) { | ||
1586 | error(ERR_UNSUPPORTED_ACTION,s.toDisplayString()); | 1572 | error(ERR_UNSUPPORTED_ACTION,s.toDisplayString()); | ||
1587 | return; | 1573 | return; | ||
1588 | } | 1574 | } | ||
1589 | setHostInternal(s); | 1575 | setHostInternal(s); | ||
1590 | url = d; | 1576 | url = d; | ||
1591 | openConnection(); | 1577 | openConnection(); | ||
1592 | if (!isLoggedIn) return; | 1578 | if (!isLoggedIn) return; | ||
1593 | KUrl src = s; | 1579 | QUrl src = s; | ||
1594 | url.cleanPath(); | 1580 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1595 | src.cleanPath(); | 1581 | src = src.adjusted(QUrl::NormalizePathSegments); | ||
1596 | if (!url.hasPath()) { | 1582 | if (url.path().isEmpty()) { | ||
1597 | sendCommand(FISH_PWD); | 1583 | sendCommand(FISH_PWD); | ||
1598 | } else { | 1584 | } else { | ||
1599 | if (!(flags & KIO::Overwrite)) { | 1585 | if (!(flags & KIO::Overwrite)) { | ||
1600 | listReason = CHECK; | 1586 | listReason = CHECK; | ||
1601 | checkOverwrite = false; | 1587 | checkOverwrite = false; | ||
1602 | sendCommand(FISH_LIST,E(url.path())); | 1588 | sendCommand(FISH_LIST,E(url.path())); | ||
1603 | } | 1589 | } | ||
1604 | sendCommand(FISH_RENAME,E(src.path()),E(url.path())); | 1590 | sendCommand(FISH_RENAME,E(src.path()),E(url.path())); | ||
1605 | } | 1591 | } | ||
1606 | run(); | 1592 | run(); | ||
1607 | } | 1593 | } | ||
1608 | /** create a symlink */ | 1594 | /** create a symlink */ | ||
1609 | void fishProtocol::symlink(const QString& target, const QUrl& u, KIO::JobFlags flags) { | 1595 | void fishProtocol::symlink(const QString& target, const QUrl& u, KIO::JobFlags flags) { | ||
1610 | myDebug( << "@@@@@@@@@ symlink " << target << " " << u << " " << (flags & KIO::Overwrite) << endl); | 1596 | myDebug( << "@@@@@@@@@ symlink " << target << " " << u << " " << (flags & KIO::Overwrite)); | ||
1611 | setHostInternal(u); | 1597 | setHostInternal(u); | ||
1612 | url = u; | 1598 | url = u; | ||
1613 | openConnection(); | 1599 | openConnection(); | ||
1614 | if (!isLoggedIn) return; | 1600 | if (!isLoggedIn) return; | ||
1615 | url.cleanPath(); | 1601 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1616 | if (!url.hasPath()) { | 1602 | if (url.path().isEmpty()) { | ||
1617 | sendCommand(FISH_PWD); | 1603 | sendCommand(FISH_PWD); | ||
1618 | } else { | 1604 | } else { | ||
1619 | if (!(flags & KIO::Overwrite)) { | 1605 | if (!(flags & KIO::Overwrite)) { | ||
1620 | listReason = CHECK; | 1606 | listReason = CHECK; | ||
1621 | checkOverwrite = false; | 1607 | checkOverwrite = false; | ||
1622 | sendCommand(FISH_LIST,E(url.path())); | 1608 | sendCommand(FISH_LIST,E(url.path())); | ||
1623 | } | 1609 | } | ||
1624 | sendCommand(FISH_SYMLINK,E(target),E(url.path())); | 1610 | sendCommand(FISH_SYMLINK,E(target),E(url.path())); | ||
1625 | } | 1611 | } | ||
1626 | run(); | 1612 | run(); | ||
1627 | } | 1613 | } | ||
1628 | /** change file permissions */ | 1614 | /** change file permissions */ | ||
1629 | void fishProtocol::chmod(const QUrl& u, int permissions){ | 1615 | void fishProtocol::chmod(const QUrl& u, int permissions){ | ||
1630 | myDebug( << "@@@@@@@@@ chmod " << u << " " << permissions << endl); | 1616 | myDebug( << "@@@@@@@@@ chmod " << u << " " << permissions); | ||
1631 | setHostInternal(u); | 1617 | setHostInternal(u); | ||
1632 | url = u; | 1618 | url = u; | ||
1633 | openConnection(); | 1619 | openConnection(); | ||
1634 | if (!isLoggedIn) return; | 1620 | if (!isLoggedIn) return; | ||
1635 | url.cleanPath(); | 1621 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1636 | if (!url.hasPath()) { | 1622 | if (url.path().isEmpty()) { | ||
1637 | sendCommand(FISH_PWD); | 1623 | sendCommand(FISH_PWD); | ||
1638 | } else { | 1624 | } else { | ||
1639 | if (permissions > -1) sendCommand(FISH_CHMOD,E(QString::number(permissions,8)),E(url.path())); | 1625 | if (permissions > -1) sendCommand(FISH_CHMOD,E(QString::number(permissions,8)),E(url.path())); | ||
1640 | } | 1626 | } | ||
1641 | run(); | 1627 | run(); | ||
1642 | } | 1628 | } | ||
1643 | /** copies a file */ | 1629 | /** copies a file */ | ||
1644 | void fishProtocol::copy(const QUrl &s, const QUrl &d, int permissions, KIO::JobFlags flags) { | 1630 | void fishProtocol::copy(const QUrl &s, const QUrl &d, int permissions, KIO::JobFlags flags) { | ||
1645 | myDebug( << "@@@@@@@@@ copy " << s << " " << d << " " << permissions << " " << (flags & KIO::Overwrite) << endl); | 1631 | myDebug( << "@@@@@@@@@ copy " << s << " " << d << " " << permissions << " " << (flags & KIO::Overwrite)); | ||
1646 | if (s.host() != d.host() || s.port() != d.port() || s.userName() != d.userName()) { | 1632 | if (s.host() != d.host() || s.port() != d.port() || s.userName() != d.userName()) { | ||
1647 | error(ERR_UNSUPPORTED_ACTION,s.toDisplayString()); | 1633 | error(ERR_UNSUPPORTED_ACTION,s.toDisplayString()); | ||
1648 | return; | 1634 | return; | ||
1649 | } | 1635 | } | ||
1650 | //myDebug( << s << endl << d << endl); | 1636 | //myDebug( << s << endl << d); | ||
1651 | setHostInternal(s); | 1637 | setHostInternal(s); | ||
1652 | url = d; | 1638 | url = d; | ||
1653 | openConnection(); | 1639 | openConnection(); | ||
1654 | if (!isLoggedIn) return; | 1640 | if (!isLoggedIn) return; | ||
1655 | KUrl src = s; | 1641 | QUrl src = s; | ||
1656 | url.cleanPath(); | 1642 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1657 | src.cleanPath(); | 1643 | src = src.adjusted(QUrl::NormalizePathSegments); | ||
1658 | if (!src.hasPath()) { | 1644 | if (src.path().isEmpty()) { | ||
1659 | sendCommand(FISH_PWD); | 1645 | sendCommand(FISH_PWD); | ||
1660 | } else { | 1646 | } else { | ||
1661 | if (!(flags & KIO::Overwrite)) { | 1647 | if (!(flags & KIO::Overwrite)) { | ||
1662 | listReason = CHECK; | 1648 | listReason = CHECK; | ||
1663 | checkOverwrite = false; | 1649 | checkOverwrite = false; | ||
1664 | sendCommand(FISH_LIST,E(url.path())); | 1650 | sendCommand(FISH_LIST,E(url.path())); | ||
1665 | } | 1651 | } | ||
1666 | sendCommand(FISH_COPY,E(src.path()),E(url.path())); | 1652 | sendCommand(FISH_COPY,E(src.path()),E(url.path())); | ||
1667 | if (permissions > -1) sendCommand(FISH_CHMOD,E(QString::number(permissions,8)),E(url.path())); | 1653 | if (permissions > -1) sendCommand(FISH_CHMOD,E(QString::number(permissions,8)),E(url.path())); | ||
1668 | } | 1654 | } | ||
1669 | run(); | 1655 | run(); | ||
1670 | } | 1656 | } | ||
1671 | /** removes a file or directory */ | 1657 | /** removes a file or directory */ | ||
1672 | void fishProtocol::del(const QUrl &u, bool isFile){ | 1658 | void fishProtocol::del(const QUrl &u, bool isFile){ | ||
1673 | myDebug( << "@@@@@@@@@ del " << u << " " << isFile << endl); | 1659 | myDebug( << "@@@@@@@@@ del " << u << " " << isFile); | ||
1674 | setHostInternal(u); | 1660 | setHostInternal(u); | ||
1675 | url = u; | 1661 | url = u; | ||
1676 | openConnection(); | 1662 | openConnection(); | ||
1677 | if (!isLoggedIn) return; | 1663 | if (!isLoggedIn) return; | ||
1678 | url.cleanPath(); | 1664 | url = url.adjusted(QUrl::NormalizePathSegments); | ||
1679 | if (url.path().isEmpty()) { | 1665 | if (url.path().isEmpty()) { | ||
1680 | sendCommand(FISH_PWD); | 1666 | sendCommand(FISH_PWD); | ||
1681 | } else { | 1667 | } else { | ||
1682 | sendCommand((isFile?FISH_DELE:FISH_RMD),E(url.path())); | 1668 | sendCommand((isFile?FISH_DELE:FISH_RMD),E(url.path())); | ||
1683 | } | 1669 | } | ||
1684 | run(); | 1670 | run(); | ||
1685 | } | 1671 | } | ||
1686 | /** special like background execute */ | 1672 | /** special like background execute */ | ||
1687 | void fishProtocol::special( const QByteArray &data ){ | 1673 | void fishProtocol::special( const QByteArray &data ){ | ||
1688 | int tmp; | 1674 | int tmp; | ||
1689 | 1675 | | |||
1690 | QDataStream stream(data); | 1676 | QDataStream stream(data); | ||
1691 | 1677 | | |||
1692 | stream >> tmp; | 1678 | stream >> tmp; | ||
1693 | switch (tmp) { | 1679 | switch (tmp) { | ||
1694 | case FISH_EXEC_CMD: // SSH EXEC | 1680 | case FISH_EXEC_CMD: // SSH EXEC | ||
1695 | { | 1681 | { | ||
1696 | KUrl u; | 1682 | QUrl u; | ||
1697 | QString command; | 1683 | QString command; | ||
1698 | QString tempfile; | 1684 | QString tempfile; | ||
1699 | stream >> u; | 1685 | stream >> u; | ||
1700 | stream >> command; | 1686 | stream >> command; | ||
1701 | myDebug( << "@@@@@@@@@ exec " << u << " " << command << endl); | 1687 | myDebug( << "@@@@@@@@@ exec " << u << " " << command); | ||
1702 | setHostInternal(u); | 1688 | setHostInternal(u); | ||
1703 | url = u; | 1689 | url = u; | ||
1704 | openConnection(); | 1690 | openConnection(); | ||
1705 | if (!isLoggedIn) return; | 1691 | if (!isLoggedIn) return; | ||
1706 | sendCommand(FISH_EXEC,E(command),E(url.path())); | 1692 | sendCommand(FISH_EXEC,E(command),E(url.path())); | ||
1707 | run(); | 1693 | run(); | ||
1708 | break; | 1694 | break; | ||
1709 | } | 1695 | } | ||
1710 | default: | 1696 | default: | ||
1711 | // Some command we don't understand. | 1697 | // Some command we don't understand. | ||
1712 | error(ERR_UNSUPPORTED_ACTION,QString().setNum(tmp)); | 1698 | error(ERR_UNSUPPORTED_ACTION,QString().setNum(tmp)); | ||
1713 | break; | 1699 | break; | ||
1714 | } | 1700 | } | ||
1715 | } | 1701 | } | ||
1716 | /** report status */ | 1702 | /** report status */ | ||
1717 | void fishProtocol::slave_status() { | 1703 | void fishProtocol::slave_status() { | ||
1718 | myDebug( << "@@@@@@@@@ slave_status" << endl); | 1704 | myDebug( << "@@@@@@@@@ slave_status"); | ||
1719 | if (childPid > 0) | 1705 | if (childPid > 0) | ||
1720 | slaveStatus(connectionHost,isLoggedIn); | 1706 | slaveStatus(connectionHost,isLoggedIn); | ||
1721 | else | 1707 | else | ||
1722 | slaveStatus(QString(),false); | 1708 | slaveStatus(QString(),false); | ||
1723 | } | 1709 | } |