1/* 2 * Copyright 1998-1999 Be, Inc. All Rights Reserved. 3 * Copyright 2003-2019 Haiku, Inc. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8#include "SpawningUploadClient.h" 9 10#include <errno.h> 11#include <signal.h> 12#include <stdlib.h> 13#include <unistd.h> 14 15#include <image.h> 16#include <String.h> 17 18 19SpawningUploadClient::SpawningUploadClient() 20 : 21 FileUploadClient(), 22 fCommand(), 23 fCommandPid(-1), 24 fPty(-1) 25{ 26} 27 28 29SpawningUploadClient::~SpawningUploadClient() 30{ 31 close(fPty); 32 kill(fCommandPid, SIGTERM); 33 kill(fCommandPid, SIGKILL); 34 35 status_t ret; 36 wait_for_thread(fCommandPid, &ret); 37} 38 39 40bool 41SpawningUploadClient::Connect(const string& server, const string& login, 42 const string& passwd) 43{ 44 bool rc = false; 45// fCommand += " "; 46// fCommand += server; 47 rc = SpawnCommand(); 48 49 return rc; 50} 51 52 53bool 54SpawningUploadClient::SpawnCommand() 55{ 56 char ptypath[20]; 57 char ttypath[20]; 58 //XXX: should use a system-provided TerminalCommand class 59 BString shellcmd = "exec"; 60 const char *args[] = { "/bin/sh", "-c", NULL, NULL }; 61 fPty = getpty(ptypath, ttypath); 62 if (fPty < 0) 63 return B_ERROR; 64 65 shellcmd << " 0<" << ttypath; 66 shellcmd << " 1>" << ttypath; 67 shellcmd += " 2>&1"; 68 shellcmd << " ; "; 69 shellcmd << "export TTY=" << ttypath << "; "; // BeOS hack 70 shellcmd << "export LC_ALL=C; export LANG=C; "; 71 shellcmd << "exec "; 72 shellcmd << fCommand.c_str(); 73 printf("spawning: '%s'\n", shellcmd.String()); 74 args[2] = shellcmd.String(); 75 fCommandPid = load_image(3, args, (const char**)environ); 76 if (fCommandPid < 0) 77 return false; 78 resume_thread(fCommandPid); 79 80 return true; 81} 82 83 84status_t 85SpawningUploadClient::SetCommandLine(const char* command) 86{ 87 fCommand = command; 88 return B_OK; 89} 90 91 92ssize_t 93SpawningUploadClient::SendCommand(const char* cmd) 94{ 95 return write(InputPipe(), cmd, strlen(cmd)); 96} 97 98 99ssize_t 100SpawningUploadClient::ReadReply(BString* to) 101{ 102 char buff[1024]; 103 ssize_t len; 104 105 to->Truncate(0); 106 len = read(OutputPipe(), buff, 1024); 107 if (len < 0) 108 return errno; 109 to->Append(buff, len); 110 111 return len; 112} 113 114 115status_t 116SpawningUploadClient::ParseReply() 117{ 118 return B_ERROR; 119} 120 121 122int 123SpawningUploadClient::getpty(char* pty, char* tty) 124{ 125 static const char major[] = "pqrs"; 126 static const char minor[] = "0123456789abcdef"; 127 uint32 i, j; 128 int32 fd = -1; 129 130 for (i = 0; i < sizeof(major); i++) 131 { 132 for (j = 0; j < sizeof(minor); j++) 133 { 134 sprintf(pty, "/dev/pt/%c%c", major[i], minor[j]); 135 sprintf(tty, "/dev/tt/%c%c", major[i], minor[j]); 136 fd = open(pty, O_RDWR|O_NOCTTY); 137 if (fd >= 0) 138 return fd; 139 } 140 } 141 142 return fd; 143} 144 145 146/* the rest is empty */ 147 148 149bool 150SpawningUploadClient::ChangeDir(const string& dir) 151{ 152 return false; 153} 154 155 156bool 157SpawningUploadClient::ListDirContents(string& listing) 158{ 159 return false; 160} 161 162 163bool 164SpawningUploadClient::PrintWorkingDir(string& dir) 165{ 166 return false; 167} 168 169 170bool 171SpawningUploadClient::PutFile(const string& local, const string& remote, 172 ftp_mode mode) 173{ 174 return false; 175} 176 177 178bool 179SpawningUploadClient::GetFile(const string& remote, const string& local, 180 ftp_mode mode) 181{ 182 return false; 183} 184 185 186// Note: this only works for local remote moves, cross filesystem moves 187// will not work 188bool 189SpawningUploadClient::MoveFile(const string& oldPath, const string& newPath) 190{ 191 return false; 192} 193 194 195bool 196SpawningUploadClient::Chmod(const string& path, const string& mod) 197{ 198 return false; 199} 200 201 202void 203SpawningUploadClient::SetPassive(bool on) 204{ 205} 206