Ejemplo n.º 1
0
static int
cygterm_accepting(Plug plug, OSSocket sock)
{
	Local local = (Local)plug;
	cygterm_debug("top");
	local->s = sk_register(sock, plug);
	sk_set_frozen(local->s, 0);
	/* Reset terminal size */
	cygterm_size(local, conf_get_int(local->conf, CONF_width), conf_get_int(local->conf, CONF_height));
	cygterm_debug("OK");
	return 0;
}
Ejemplo n.º 2
0
static int
cygterm_receive(Plug plug, int urgent, char *data, int len)
{
	Local local = (Local)plug;
	int backlog;
	cygterm_debug("backend -> display %u", len);
//	dmemdump(data, len);
	backlog = from_backend(local->frontend, 0, data, len);
//	dmemdumpl(data, len);
	sk_set_frozen(local->s, backlog > CYGTERM_MAX_BACKLOG);
	cygterm_debug("OK");
	return 1;
}
Ejemplo n.º 3
0
static void
cygterm_free(void *handle)
{
	Local local = handle;
	cygterm_debug("top");
	sfree(local);
}
Ejemplo n.º 4
0
static void
cygterm_reconfig(void *handle, Conf *conf)
{
	Local local = handle;
	cygterm_debug("top");
	local->conf = conf;
}
Ejemplo n.º 5
0
static int
cygterm_connected(void *handle)
{
	Local local = handle;
	cygterm_debug("top");
	return local->s != NULL;
}
Ejemplo n.º 6
0
static int
cygterm_sendbuffer(void *handle)
{
	Local local = handle;
	cygterm_debug("top");
	return local->bufsize;
}
Ejemplo n.º 7
0
static void
cygterm_reconfig(void *handle, Config *cfg)
{
	Local local = handle;
	cygterm_debug("top");
	local->cfg = *cfg;
}
Ejemplo n.º 8
0
static void
cygterm_unthrottle(void *handle, int backlog)
{
	Local local = handle;
	cygterm_debug("top");
	sk_set_frozen(local->s, backlog > CYGTERM_MAX_BACKLOG);
}
Ejemplo n.º 9
0
static int
cygterm_exitcode(void *handle)
{
	Local local = handle;
	cygterm_debug("top");
	return local->exitcode;
}
Ejemplo n.º 10
0
static int
cygterm_closing(Plug plug, const char *error_msg, int error_code, int calling_back)
{
	Local local = (Local)plug;
	cygterm_debug("top");
	if (local->s) {
		sk_close(local->s);
		local->s = NULL;
	}
	/* check for errors from cthelper */
	CloseHandle(local->ctl);
	/* wait for cthelper */
	if (local->pi.hProcess != INVALID_HANDLE_VALUE) {
		if (WAIT_OBJECT_0 == WaitForSingleObject(local->pi.hProcess, 2000)) {
			DWORD status;
			GetExitCodeProcess(local->pi.hProcess, &status);
			switch (status) {
			case CthelperSuccess:
				break;
			case CthelperInvalidUsage:
			case CthelperInvalidPort:
			case CthelperConnectFailed:
				local->exitcode = INT_MAX;
				error_msg = "Internal error";
				break;
			case CthelperPtyforkFailure:
				local->exitcode = INT_MAX;
				error_msg = "Failed to allocate pseudoterminal";
				break;
			case CthelperExecFailure:
				local->exitcode = INT_MAX;
				error_msg = "Failed to execute command";
				break;
			}
		}
	}
	/* this calls cygterm_exitcode() */
	notify_remote_exit(local->frontend);
	if (error_msg) {
		cygterm_debug("error_msg: %s", error_msg);
		connection_fatal(local->frontend, "%s", error_msg);
	}
	return 0;
}
Ejemplo n.º 11
0
static void
cygterm_size(void *handle, int width, int height)
{
	Local local = handle;
	cygterm_debug("top");
	cygterm_debug("size=%d,%d (last=%d,%d)",
	              width, height, conf_get_int(local->conf, CONF_width), conf_get_int(local->conf, CONF_height));
	conf_set_int(local->conf, CONF_width, width);
	conf_set_int(local->conf, CONF_height, height);
	if (local->s) {
		DWORD n;
		Message m;
		m.size = MESSAGE_MIN + sizeof(m.msg);
		m.type = MSG_RESIZE;
		m.msg.resize.width = width;
		m.msg.resize.height = height;
		cygterm_debug("WriteFile %p %p:%u", local->ctl, &m, m.size);
		WriteFile(local->ctl, (const char *)&m, m.size, &n, 0);
		cygterm_debug("WriteFile returns %d");
	}
}
Ejemplo n.º 12
0
static int
cygterm_ldisc(void *handle, int option)
{
	Local local = handle;
	cygterm_debug("cygterm_ldisc: %d", option);
	switch (option) {
	case LD_EDIT:
		return local->editing;
	case LD_ECHO:
		return local->echoing;
	}
	return 0;
}
Ejemplo n.º 13
0
static int
cygterm_send(void *handle, char *buf, int len)
{
	Local local = handle;
	cygterm_debug("frontend -> pty %u", len);
//	dmemdump(buf, len);
#if 0
	/* HACK */
	{
		int i;
		for (i = 0; i < len - 1; i++)
			if (buf[i] == 033 && !(buf[i+1]&0x80)) {
				memmove(buf + i, buf + i + 1, --len - i);
				buf[i] |= 0x80;
			}
	}
#endif
	if (local->s != 0)
		local->bufsize = sk_write(local->s, buf, len);
	cygterm_debug("OK");
	return local->bufsize;
}
Ejemplo n.º 14
0
static void
appendPath(const char *append)
{
	char *path;
	char *newPath;

	cygterm_debug("getting PATH");
	if (!(path = getenv("PATH"))) {
		cygterm_debug("hmm.. PATH not set");
		path = "";
	}
	cygterm_debug("alloc newPath");
	newPath = smalloc(5 + strlen(append) + 1 + strlen(path) + 1);
	cygterm_debug("init newPath");
	sprintf(newPath, "PATH=%s;%s", path, append);
	cygterm_debug("set newPath");
	putenv(newPath);
	cygterm_debug("free newPath");
	sfree(newPath);
}
Ejemplo n.º 15
0
static void
cygterm_provide_logctx(void *handle, void *logctx)
{
	cygterm_debug("top");
}
Ejemplo n.º 16
0
static void
cygterm_provide_ldisc(void *handle, void *ldisc)
{
	cygterm_debug("top");
}
Ejemplo n.º 17
0
static int
cygterm_sendok(void *handle)
{
	cygterm_debug("top");
	return 1;
}
Ejemplo n.º 18
0
static const char *
cygterm_init(void *frontend_handle, void **backend_handle,
             Conf *conf,
             char *unused_host, int unused_port,
             char **realhost, int nodelay, int keepalive)
{
	/* XXX: I'm not sure if it is OK to overload Plug like this.
	 * cygterm_accepting should only be used for the listening socket
	 * (local->a) while the cygterm_closing, cygterm_receive, and cygterm_sent
	 * should be used only for the actual connection (local->s).
	 */
	static const struct plug_function_table fn_table = {
		cygterm_log,
		cygterm_closing,
		cygterm_receive,
		cygterm_sent,
		cygterm_accepting
	};
	Local local;
	const char *command;
	char cmdline[2 * MAX_PATH];
	int cport;
	const char *err;
	int cmdlinelen;

	cygterm_debug("top");

	local = snew(struct cygterm_backend_data);
	local->fn = &fn_table;
	local->a = NULL;
	local->s = NULL;
	local->conf = conf;
	local->editing = 0;
	local->echoing = 0;
	local->exitcode = 0;
	*backend_handle = local;

	local->frontend = frontend_handle;

	/* set up listen socket for communication with child */
	cygterm_debug("setupCygTerm");

	/* let sk use INADDR_LOOPBACK and let WinSock choose a port */
	local->a = sk_newlistener(0, 0, (Plug)local, 1, ADDRTYPE_IPV4);
	if ((err = sk_socket_error(local->a)) != NULL)
		goto fail_free;

	/* now, get the port that WinSock chose */
	/* XXX: Is there another function in PuTTY to do this? */
	cygterm_debug("getting port");
	cport = sk_getport(local->a);
	if (cport == -1) {
		err = "Failed to get port number for cthelper";
		goto fail_close;
	}

	if (strchr(conf_get_str(local->conf, CONF_termtype), ' ')) {
		err = "term type contains spaces";
		goto fail_close;
	}

	/*  Build cthelper command line */
	if(conf_get_int(conf, CONF_cygterm64)) {
		cmdlinelen = sprintf(cmdline, CTHELPER64" %u %s ", cport, conf_get_str(local->conf, CONF_termtype));
	}
	else {
		cmdlinelen = sprintf(cmdline, CTHELPER" %u %s ", cport, conf_get_str(local->conf, CONF_termtype));
	}
	cmdlinelen += makeAttributes(cmdline + cmdlinelen, conf);

	command = conf_get_str(conf, CONF_cygcmd);
	cygterm_debug("command is :%s:", command);
	/*  A command of  "."  or  "-"  tells us to pass no command arguments to
	 *  cthelper which will then run the user's shell under Cygwin.  */
	if ((command[0]=='-'||command[0]=='.') && command[1]=='\0')
		;
	else if (cmdlinelen + strlen(command) + 2 > sizeof cmdline) {
		err = "command is too long";
		goto fail_close;
	}
	else {
		cmdlinelen += sprintf(cmdline + cmdlinelen, " %s", command);
	}

	/* Add the Cygwin /bin path to the PATH. */
	if (conf_get_int(conf, CONF_cygautopath)) {
		char *cygwinBinPath = getCygwinBin(conf_get_int(conf, CONF_cygterm64));
		if (!cygwinBinPath) {
			/* we'll try anyway */
			cygterm_debug("cygwin bin directory not found");
		}
		else {
			cygterm_debug("found cygwin directory: %s", cygwinBinPath);
			appendPath(cygwinBinPath);
			sfree(cygwinBinPath);
		}
	}

	cygterm_debug("starting cthelper: %s", cmdline);
	if ((err = spawnChild(cmdline, &local->pi, &local->ctl)))
		goto fail_close;

	/*  This should be set to the local hostname, Apparently, realhost is used
	 *  only to set the window title.
	 */
	strcpy(*realhost = smalloc(sizeof CYGTERM_NAME), CYGTERM_NAME);
	cygterm_debug("OK");
	return 0;

fail_close:
	sk_close(local->a);
fail_free:
	sfree(local);
	return err;
}
Ejemplo n.º 19
0
static const struct telnet_special *
cygterm_get_specials(void *handle)
{
	cygterm_debug("top");
	return NULL;
}
Ejemplo n.º 20
0
static void
cygterm_special(void *handle, Telnet_Special code)
{
	cygterm_debug("top");
}