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 19 SpawningUploadClient::SpawningUploadClient() 20 : 21 FileUploadClient(), 22 fCommand(), 23 fCommandPid(-1), 24 fPty(-1) 25 { 26 } 27 28 29 SpawningUploadClient::~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 40 bool 41 SpawningUploadClient::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 53 bool 54 SpawningUploadClient::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 84 status_t 85 SpawningUploadClient::SetCommandLine(const char* command) 86 { 87 fCommand = command; 88 return B_OK; 89 } 90 91 92 ssize_t 93 SpawningUploadClient::SendCommand(const char* cmd) 94 { 95 return write(InputPipe(), cmd, strlen(cmd)); 96 } 97 98 99 ssize_t 100 SpawningUploadClient::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 115 status_t 116 SpawningUploadClient::ParseReply() 117 { 118 return B_ERROR; 119 } 120 121 122 int 123 SpawningUploadClient::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 149 bool 150 SpawningUploadClient::ChangeDir(const string& dir) 151 { 152 return false; 153 } 154 155 156 bool 157 SpawningUploadClient::ListDirContents(string& listing) 158 { 159 return false; 160 } 161 162 163 bool 164 SpawningUploadClient::PrintWorkingDir(string& dir) 165 { 166 return false; 167 } 168 169 170 bool 171 SpawningUploadClient::PutFile(const string& local, const string& remote, 172 ftp_mode mode) 173 { 174 return false; 175 } 176 177 178 bool 179 SpawningUploadClient::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 188 bool 189 SpawningUploadClient::MoveFile(const string& oldPath, const string& newPath) 190 { 191 return false; 192 } 193 194 195 bool 196 SpawningUploadClient::Chmod(const string& path, const string& mod) 197 { 198 return false; 199 } 200 201 202 void 203 SpawningUploadClient::SetPassive(bool on) 204 { 205 } 206