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