16a739773SCodeforEvolution/*
26a739773SCodeforEvolution * Copyright 1998-1999 Be, Inc. All Rights Reserved.
36a739773SCodeforEvolution * Copyright 2003-2019 Haiku, Inc. All rights reserved.
46a739773SCodeforEvolution * Distributed under the terms of the MIT License.
56a739773SCodeforEvolution */
66a739773SCodeforEvolution
76a739773SCodeforEvolution
86a739773SCodeforEvolution#include "SpawningUploadClient.h"
96a739773SCodeforEvolution
10952fdf78SKarsten Heimrich#include <errno.h>
1142b2e5d5SFrançois Revol#include <signal.h>
12e3cfb87eSFrançois Revol#include <stdlib.h>
136a739773SCodeforEvolution#include <unistd.h>
1442b2e5d5SFrançois Revol
156a739773SCodeforEvolution#include <image.h>
1642b2e5d5SFrançois Revol#include <String.h>
1742b2e5d5SFrançois Revol
1842b2e5d5SFrançois Revol
1942b2e5d5SFrançois RevolSpawningUploadClient::SpawningUploadClient()
206a739773SCodeforEvolution	:
216a739773SCodeforEvolution	FileUploadClient(),
226a739773SCodeforEvolution	fCommand(),
236a739773SCodeforEvolution	fCommandPid(-1),
246a739773SCodeforEvolution	fPty(-1)
2542b2e5d5SFrançois Revol{
2642b2e5d5SFrançois Revol}
2742b2e5d5SFrançois Revol
2842b2e5d5SFrançois Revol
2942b2e5d5SFrançois RevolSpawningUploadClient::~SpawningUploadClient()
3042b2e5d5SFrançois Revol{
3142b2e5d5SFrançois Revol	close(fPty);
3242b2e5d5SFrançois Revol	kill(fCommandPid, SIGTERM);
3342b2e5d5SFrançois Revol	kill(fCommandPid, SIGKILL);
346a739773SCodeforEvolution
3542b2e5d5SFrançois Revol	status_t ret;
3642b2e5d5SFrançois Revol	wait_for_thread(fCommandPid, &ret);
3742b2e5d5SFrançois Revol}
3842b2e5d5SFrançois Revol
3942b2e5d5SFrançois Revol
4042b2e5d5SFrançois Revolbool
416a739773SCodeforEvolutionSpawningUploadClient::Connect(const string& server, const string& login,
426a739773SCodeforEvolution	const string& passwd)
4342b2e5d5SFrançois Revol{
4442b2e5d5SFrançois Revol	bool rc = false;
4542b2e5d5SFrançois Revol//	fCommand += " ";
4642b2e5d5SFrançois Revol//	fCommand += server;
4742b2e5d5SFrançois Revol	rc = SpawnCommand();
486a739773SCodeforEvolution
4942b2e5d5SFrançois Revol	return rc;
5042b2e5d5SFrançois Revol}
5142b2e5d5SFrançois Revol
5242b2e5d5SFrançois Revol
5342b2e5d5SFrançois Revolbool
5442b2e5d5SFrançois RevolSpawningUploadClient::SpawnCommand()
5542b2e5d5SFrançois Revol{
56586cf6aeSFrançois Revol	char ptypath[20];
57586cf6aeSFrançois Revol	char ttypath[20];
5842b2e5d5SFrançois Revol	//XXX: should use a system-provided TerminalCommand class
5942b2e5d5SFrançois Revol	BString shellcmd = "exec";
6042b2e5d5SFrançois Revol	const char *args[] = { "/bin/sh", "-c", NULL, NULL };
61dc935a5aSFrançois Revol	fPty = getpty(ptypath, ttypath);
62dc935a5aSFrançois Revol	if (fPty < 0)
63586cf6aeSFrançois Revol		return B_ERROR;
64586cf6aeSFrançois Revol
65586cf6aeSFrançois Revol	shellcmd << " 0<" << ttypath;
66586cf6aeSFrançois Revol	shellcmd << " 1>" << ttypath;
6742b2e5d5SFrançois Revol	shellcmd += " 2>&1";
6842b2e5d5SFrançois Revol	shellcmd << " ; ";
69586cf6aeSFrançois Revol	shellcmd << "export TTY=" << ttypath << "; "; // BeOS hack
7042b2e5d5SFrançois Revol	shellcmd << "export LC_ALL=C; export LANG=C; ";
7142b2e5d5SFrançois Revol	shellcmd << "exec ";
7242b2e5d5SFrançois Revol	shellcmd << fCommand.c_str();
736a739773SCodeforEvolution	printf("spawning: '%s'\n", shellcmd.String());
7442b2e5d5SFrançois Revol	args[2] = shellcmd.String();
756a739773SCodeforEvolution	fCommandPid = load_image(3, args, (const char**)environ);
7642b2e5d5SFrançois Revol	if (fCommandPid < 0)
7742b2e5d5SFrançois Revol		return false;
7842b2e5d5SFrançois Revol	resume_thread(fCommandPid);
796a739773SCodeforEvolution
8042b2e5d5SFrançois Revol	return true;
8142b2e5d5SFrançois Revol}
8242b2e5d5SFrançois Revol
8342b2e5d5SFrançois Revol
8442b2e5d5SFrançois Revolstatus_t
856a739773SCodeforEvolutionSpawningUploadClient::SetCommandLine(const char* command)
8642b2e5d5SFrançois Revol{
8742b2e5d5SFrançois Revol	fCommand = command;
8842b2e5d5SFrançois Revol	return B_OK;
8942b2e5d5SFrançois Revol}
9042b2e5d5SFrançois Revol
9142b2e5d5SFrançois Revol
9242b2e5d5SFrançois Revolssize_t
936a739773SCodeforEvolutionSpawningUploadClient::SendCommand(const char* cmd)
9442b2e5d5SFrançois Revol{
9542b2e5d5SFrançois Revol	return write(InputPipe(), cmd, strlen(cmd));
9642b2e5d5SFrançois Revol}
9742b2e5d5SFrançois Revol
9842b2e5d5SFrançois Revol
9942b2e5d5SFrançois Revolssize_t
1006a739773SCodeforEvolutionSpawningUploadClient::ReadReply(BString* to)
10142b2e5d5SFrançois Revol{
10242b2e5d5SFrançois Revol	char buff[1024];
10342b2e5d5SFrançois Revol	ssize_t len;
1046a739773SCodeforEvolution
10542b2e5d5SFrançois Revol	to->Truncate(0);
10642b2e5d5SFrançois Revol	len = read(OutputPipe(), buff, 1024);
10742b2e5d5SFrançois Revol	if (len < 0)
10842b2e5d5SFrançois Revol		return errno;
10942b2e5d5SFrançois Revol	to->Append(buff, len);
1106a739773SCodeforEvolution
11142b2e5d5SFrançois Revol	return len;
11242b2e5d5SFrançois Revol}
11342b2e5d5SFrançois Revol
11442b2e5d5SFrançois Revol
11542b2e5d5SFrançois Revolstatus_t
11642b2e5d5SFrançois RevolSpawningUploadClient::ParseReply()
11742b2e5d5SFrançois Revol{
11842b2e5d5SFrançois Revol	return B_ERROR;
11942b2e5d5SFrançois Revol}
12042b2e5d5SFrançois Revol
12142b2e5d5SFrançois Revol
122586cf6aeSFrançois Revolint
1236a739773SCodeforEvolutionSpawningUploadClient::getpty(char* pty, char* tty)
124586cf6aeSFrançois Revol{
125586cf6aeSFrançois Revol	static const char major[] = "pqrs";
126586cf6aeSFrançois Revol	static const char minor[] = "0123456789abcdef";
127586cf6aeSFrançois Revol	uint32 i, j;
128586cf6aeSFrançois Revol	int32 fd = -1;
129476fad7fSMatt Madia
130586cf6aeSFrançois Revol	for (i = 0; i < sizeof(major); i++)
131586cf6aeSFrançois Revol	{
132586cf6aeSFrançois Revol		for (j = 0; j < sizeof(minor); j++)
133586cf6aeSFrançois Revol		{
134586cf6aeSFrançois Revol			sprintf(pty, "/dev/pt/%c%c", major[i], minor[j]);
135586cf6aeSFrançois Revol			sprintf(tty, "/dev/tt/%c%c", major[i], minor[j]);
136dc935a5aSFrançois Revol			fd = open(pty, O_RDWR|O_NOCTTY);
137586cf6aeSFrançois Revol			if (fd >= 0)
138586cf6aeSFrançois Revol				return fd;
139586cf6aeSFrançois Revol		}
140586cf6aeSFrançois Revol	}
141476fad7fSMatt Madia
142586cf6aeSFrançois Revol	return fd;
143586cf6aeSFrançois Revol}
144586cf6aeSFrançois Revol
145586cf6aeSFrançois Revol
14642b2e5d5SFrançois Revol/* the rest is empty */
14742b2e5d5SFrançois Revol
14842b2e5d5SFrançois Revol
14942b2e5d5SFrançois Revolbool
15042b2e5d5SFrançois RevolSpawningUploadClient::ChangeDir(const string& dir)
15142b2e5d5SFrançois Revol{
1526a739773SCodeforEvolution	return false;
15342b2e5d5SFrançois Revol}
15442b2e5d5SFrançois Revol
15542b2e5d5SFrançois Revol
15642b2e5d5SFrançois Revolbool
15742b2e5d5SFrançois RevolSpawningUploadClient::ListDirContents(string& listing)
15842b2e5d5SFrançois Revol{
1596a739773SCodeforEvolution	return false;
16042b2e5d5SFrançois Revol}
16142b2e5d5SFrançois Revol
16242b2e5d5SFrançois Revol
16342b2e5d5SFrançois Revolbool
16442b2e5d5SFrançois RevolSpawningUploadClient::PrintWorkingDir(string& dir)
16542b2e5d5SFrançois Revol{
1666a739773SCodeforEvolution	return false;
16742b2e5d5SFrançois Revol}
16842b2e5d5SFrançois Revol
16942b2e5d5SFrançois Revol
17042b2e5d5SFrançois Revolbool
1716a739773SCodeforEvolutionSpawningUploadClient::PutFile(const string& local, const string& remote,
1726a739773SCodeforEvolution	ftp_mode mode)
17342b2e5d5SFrançois Revol{
1746a739773SCodeforEvolution	return false;
17542b2e5d5SFrançois Revol}
17642b2e5d5SFrançois Revol
17742b2e5d5SFrançois Revol
17842b2e5d5SFrançois Revolbool
1796a739773SCodeforEvolutionSpawningUploadClient::GetFile(const string& remote, const string& local,
1806a739773SCodeforEvolution	ftp_mode mode)
18142b2e5d5SFrançois Revol{
1826a739773SCodeforEvolution	return false;
18342b2e5d5SFrançois Revol}
18442b2e5d5SFrançois Revol
18542b2e5d5SFrançois Revol
18642b2e5d5SFrançois Revol// Note: this only works for local remote moves, cross filesystem moves
18742b2e5d5SFrançois Revol// will not work
18842b2e5d5SFrançois Revolbool
18942b2e5d5SFrançois RevolSpawningUploadClient::MoveFile(const string& oldPath, const string& newPath)
19042b2e5d5SFrançois Revol{
1916a739773SCodeforEvolution	return false;
19242b2e5d5SFrançois Revol}
19342b2e5d5SFrançois Revol
19442b2e5d5SFrançois Revol
19542b2e5d5SFrançois Revolbool
19642b2e5d5SFrançois RevolSpawningUploadClient::Chmod(const string& path, const string& mod)
19742b2e5d5SFrançois Revol{
1986a739773SCodeforEvolution	return false;
19942b2e5d5SFrançois Revol}
20042b2e5d5SFrançois Revol
20142b2e5d5SFrançois Revol
20242b2e5d5SFrançois Revolvoid
20342b2e5d5SFrançois RevolSpawningUploadClient::SetPassive(bool on)
20442b2e5d5SFrançois Revol{
20542b2e5d5SFrançois Revol}
206