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