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
11SpawningUploadClient::SpawningUploadClient()
12	: FileUploadClient()
13	, fCommand()
14	, fCommandPid(-1)
15	, fPty(-1)
16{
17}
18
19
20SpawningUploadClient::~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
30bool
31SpawningUploadClient::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
41bool
42SpawningUploadClient::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();
61printf("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
71status_t
72SpawningUploadClient::SetCommandLine(const char *command)
73{
74	fCommand = command;
75	return B_OK;
76}
77
78
79ssize_t
80SpawningUploadClient::SendCommand(const char *cmd)
81{
82	return write(InputPipe(), cmd, strlen(cmd));
83}
84
85
86ssize_t
87SpawningUploadClient::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
100status_t
101SpawningUploadClient::ParseReply()
102{
103	return B_ERROR;
104}
105
106
107int
108SpawningUploadClient::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
136bool
137SpawningUploadClient::ChangeDir(const string& dir)
138{
139	bool rc = false;
140	return rc;
141}
142
143
144bool
145SpawningUploadClient::ListDirContents(string& listing)
146{
147	bool rc = false;
148	return rc;
149}
150
151
152bool
153SpawningUploadClient::PrintWorkingDir(string& dir)
154{
155	bool rc = false;
156	return rc;
157}
158
159
160bool
161SpawningUploadClient::PutFile(const string& local, const string& remote, ftp_mode mode)
162{
163	bool rc = false;
164	return rc;
165}
166
167
168bool
169SpawningUploadClient::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
178bool
179SpawningUploadClient::MoveFile(const string& oldPath, const string& newPath)
180{
181	bool rc = false;
182	return rc;
183}
184
185
186bool
187SpawningUploadClient::Chmod(const string& path, const string& mod)
188{
189	bool rc = false;
190	return rc;
191}
192
193
194void
195SpawningUploadClient::SetPassive(bool on)
196{
197}
198
199
200