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