Пример #1
0
static  void WINAPI cygterm_watch_child_process(void* param)
{
	pcmd_backend_data local = param;
	char* errormsg = "Child process exit!";
	DWORD ret = WaitForSingleObject(local->m_hChildProcess, INFINITE );
	from_backend(local->frontend, 0, errormsg, strlen(errormsg));
}
Пример #2
0
static void c_write1(Telnet telnet, int c)
{
    int backlog;
    char cc = (char) c;
    backlog = from_backend(telnet->frontend, 0, &cc, 1);
    sk_set_frozen(telnet->s, backlog > TELNET_MAX_BACKLOG);
}
Пример #3
0
static int serial_gotdata(struct handle *h, void *data, int len)
{
    Serial serial = (Serial)handle_get_privdata(h);
    if (len <= 0) {
	const char *error_msg;

	/*
	 * Currently, len==0 should never happen because we're
	 * ignoring EOFs. However, it seems not totally impossible
	 * that this same back end might be usable to talk to named
	 * pipes or some other non-serial device, in which case EOF
	 * may become meaningful here.
	 */
	if (len == 0)
	    error_msg = "End of file reading from serial device";
	else
	    error_msg = "Error reading from serial device";

	serial_terminate(serial);

	notify_remote_exit(serial->frontend);

	logevent(serial->frontend, error_msg);

	connection_fatal(serial->frontend, "%s", error_msg);

	return 0;		       /* placate optimiser */
    } else {
	return from_backend(serial->frontend, 0, data, len);
    }
}
Пример #4
0
static void c_write(Ldisc ldisc, char *buf, int len)
{
	if( !get_param("PUTTY") && (GetRuTTYFlag()>0) ) {
		from_backend_local(ldisc->frontend, 0, buf, len);
	} else { 
		from_backend(ldisc->frontend, 0, buf, len);
	}
}
Пример #5
0
static DWORD cmd_on_receive_data( pcmd_backend_data local, HANDLE h) 
{
	DWORD nBytesRead;
	char lpszBuffer[256+1];
	char *readBuf = NULL;
	char* sendcmd = NULL;
	int readlen = 0;
	char * descmd = NULL;
	int deslen = 0;
	DWORD total = 0;
	DWORD byteleft = 0;


	if (!ReadFile(h, lpszBuffer, 256,
		&nBytesRead, NULL) || !nBytesRead)
	{
		if (GetLastError() == ERROR_BROKEN_PIPE)
			return ERROR_BROKEN_PIPE;			// pipe done - normal exit path.
	}
	// data on!
	WaitForSingleObject(local->m_hWriteEvent, INFINITE);
	do {
		if (nBytesRead)
		{
			lpszBuffer[nBytesRead] = '\0';
			my_print("[ondata]%x, %d", h, nBytesRead);
			readBuf = lpszBuffer;
			readlen = nBytesRead;
			deslen = readlen*2;
			descmd = smalloc(deslen);
			memset(descmd, 0, deslen);
			cmd_convert_to_cmd_format(readBuf, readlen, descmd, deslen);
			from_backend(local->frontend, 0, descmd, deslen);
			sfree(descmd);
		}

		if( !PeekNamedPipe(h, lpszBuffer, 256, &nBytesRead, &total, &byteleft) )
		{
			if (GetLastError() == ERROR_BROKEN_PIPE)
				return ERROR_BROKEN_PIPE;			// pipe done - normal exit path.
		}
		if( byteleft == 0 )
		{
			SetEvent(local->m_hWriteEvent);
			break;
		}

		if (!ReadFile(h, lpszBuffer, 256,
			&nBytesRead, NULL) || !nBytesRead)
		{
			if (GetLastError() == ERROR_BROKEN_PIPE)
				return ERROR_BROKEN_PIPE;			// pipe done - normal exit path.
		}
	}while(1);

	return ERROR_SUCCESS;
}
Пример #6
0
static void cmd_rollback_until_none(pcmd_backend_data local)
{
	int len = strlen(local->semdcmd);
	for( len; len >0; len --)
	{
		char buf[1];
		buf[0] = 127;
		from_backend(local->frontend, 0, buf, 1);
	}
	local->semdcmd[0] = '\0';
}
Пример #7
0
static int serial_select_result(int fd, int event)
{
    Serial serial;
    char buf[4096];
    int ret;
    int finished = FALSE;

    serial = find234(serial_by_fd, &fd, serial_find_by_fd);

    if (!serial)
	return 1;		       /* spurious event; keep going */

    if (event == 1) {
	ret = read(serial->fd, buf, sizeof(buf));

	if (ret == 0) {
	    /*
	     * Shouldn't happen on a real serial port, but I'm open
	     * to the idea that there might be two-way devices we
	     * can treat _like_ serial ports which can return EOF.
	     */
	    finished = TRUE;
	} else if (ret < 0) {
#ifdef EAGAIN
	    if (errno == EAGAIN)
		return 1;	       /* spurious */
#endif
#ifdef EWOULDBLOCK
	    if (errno == EWOULDBLOCK)
		return 1;	       /* spurious */
#endif
	    perror("read serial port");
	    exit(1);
	} else if (ret > 0) {
	    serial->inbufsize = from_backend(serial->frontend, 0, buf, ret);
	    serial_uxsel_setup(serial); /* might acquire backlog and freeze */
	}
    } else if (event == 2) {
	/*
	 * Attempt to send data down the pty.
	 */
	serial_try_write(serial);
    }

    if (finished) {
	serial_close(serial);

	serial->finished = TRUE;

	notify_remote_exit(serial->frontend);
    }

    return !finished;
}
Пример #8
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;
}
Пример #9
0
void backend_socket_log(void *frontend, int type, SockAddr addr, int port,
                        const char *error_msg, int error_code, Conf *conf,
                        int session_started)
{
    char addrbuf[256], *msg;

    switch (type) {
      case 0:
        sk_getaddr(addr, addrbuf, lenof(addrbuf));
        if (sk_addr_needs_port(addr)) {
            msg = dupprintf("Connecting to %s port %d", addrbuf, port);
        } else {
            msg = dupprintf("Connecting to %s", addrbuf);
        }
        break;
      case 1:
        sk_getaddr(addr, addrbuf, lenof(addrbuf));
        msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
        break;
      case 2:
        /* Proxy-related log messages have their own identifying
         * prefix already, put on by our caller. */
        {
            int len, log_to_term;

            /* Suffix \r\n temporarily, so we can log to the terminal. */
            msg = dupprintf("%s\r\n", error_msg);
            len = (int)strlen(msg);
            assert(len >= 2);

            log_to_term = conf_get_int(conf, CONF_proxy_log_to_term);
            if (log_to_term == AUTO)
                log_to_term = session_started ? FORCE_OFF : FORCE_ON;
            if (log_to_term == FORCE_ON)
                from_backend(frontend, TRUE, msg, len);

            msg[len-2] = '\0';         /* remove the \r\n again */
        }
        break;
      default:
        msg = NULL;  /* shouldn't happen, but placate optimiser */
        break;
    }

    if (msg) {
        logevent(frontend, msg);
        sfree(msg);
    }
}
Пример #10
0
static void c_write(Telnet telnet, char *buf, int len)
{
    int backlog;
    backlog = from_backend(telnet->frontend, 0, buf, len);
    sk_set_frozen(telnet->s, backlog > TELNET_MAX_BACKLOG);
}
Пример #11
0
static void c_write(Ldisc ldisc, char *buf, int len)
{
    from_backend(ldisc->frontend, 0, buf, len);
}
Пример #12
0
static void c_write(Adb adb, char *buf, int len)
{
    int backlog = from_backend(adb->frontend, 0, buf, len);
    sk_set_frozen(adb->s, backlog > ADB_MAX_BACKLOG);
}
Пример #13
0
static int  cmd_send(void *handle, char *buf, int len)
{
	pcmd_backend_data local = handle;
	DWORD writed;
	char *tmp = smalloc(len+1);
	memset(tmp,0,len+1);
	if( !handle || !buf || !len )
		return 0;
	if( strstr(buf, "\r\n") == NULL )
	{
		if( len == 1 && buf[0] == 127 ) //backspace
		{
			int l = strlen(local->semdcmd);
			if( l != 0 )
			{
				from_backend(local->frontend, 0, buf, len);
				l = l-1;
			}
			local->semdcmd[l] = '\0';
			local->bufsize = 1;
		}
		else if( buf[0] == 27 )
		{
			// left || right || up || down
			char c = buf[2];
			if( c == 'A' || c == 'B' ) // up and down
			{
				cmd_rollback_until_none(local);
				if( local->historycount != 0 )
				{
					char* his_buf = (c == 'A') ? cmd_get_previeous_histroy(local) : cmd_get_next_histroy(local);
					strcpy(local->semdcmd, his_buf);
					from_backend(local->frontend, 0, local->semdcmd, strlen(local->semdcmd));
				}
			}
			else
			{
				from_backend(local->frontend, 0, buf+1, 2);
				memcpy(tmp, buf+1, 2);
				strcat(local->semdcmd, tmp);
				local->bufsize = 2;
			}
		}
		else
		{
			from_backend(local->frontend, 0, buf, len);
			memcpy(tmp, buf, len);
			strcat(local->semdcmd, tmp);
			local->bufsize = len;
		}
		
	}
	else
	{

		char sendcmd[MAX_CMD_BUF];
		strcpy(sendcmd, local->semdcmd);
		cmd_rollback_until_none(local);

		WriteFile(local->m_hStdInWrite, sendcmd, strlen(sendcmd), &writed, NULL);
		local->bufsize = writed;
		WriteFile(local->m_hStdInWrite, "\n", 1, &writed, NULL);
		local->bufsize += writed;
		cmd_add_histroy(local, sendcmd);
		local->current_histroy = NULL;
	}

	sfree(tmp);
	return local->bufsize;
}
Пример #14
0
static void logfopen_callback(void *handle, int mode)
{
    struct LogContext *ctx = (struct LogContext *)handle;
    char buf[256], *event;
    struct tm tm;
    const char *fmode;
    int shout = FALSE;

    if (mode == 0) {
	ctx->state = L_ERROR;	       /* disable logging */
    } else {
	fmode = (mode == 1 ? "ab" : "wb");
	ctx->lgfp = f_open(ctx->currlogfilename, fmode, FALSE);
	if (ctx->lgfp) {
	    ctx->state = L_OPEN;
        } else {
	    ctx->state = L_ERROR;
            shout = TRUE;
        }
    }

    if (ctx->state == L_OPEN) {
	/* Write header line into log file. */
	tm = ltime();
	strftime(buf, 24, "%Y.%m.%d %H:%M:%S", &tm);
	logprintf(ctx, "=~=~=~=~=~=~=~=~=~=~=~= PuTTY log %s"
		  " =~=~=~=~=~=~=~=~=~=~=~=\r\n", buf);
    }

    event = dupprintf(MPEXT_BOM "%s session log (%s mode) to file: %s",
		      ctx->state == L_ERROR ?
		      (mode == 0 ? "Disabled writing" : "Error writing") :
		      (mode == 1 ? "Appending" : "Writing new"),
		      (ctx->logtype == LGTYP_ASCII ? "ASCII" :
		       ctx->logtype == LGTYP_DEBUG ? "raw" :
		       ctx->logtype == LGTYP_PACKETS ? "SSH packets" :
		       ctx->logtype == LGTYP_SSHRAW ? "SSH raw data" :
		       "unknown"),
		      filename_to_str(ctx->currlogfilename));
    logevent(ctx->frontend, event);
    if (shout) {
        /*
         * If we failed to open the log file due to filesystem error
         * (as opposed to user action such as clicking Cancel in the
         * askappend box), we should log it more prominently. We do
         * this by sending it to the same place that stderr output
         * from the main session goes (so, either a console tool's
         * actual stderr, or a terminal window).
         *
         * Of course this is one case in which that policy won't cause
         * it to turn up embarrassingly in a log file of real server
         * output, because the whole point is that we haven't managed
         * to open any such log file :-)
         */
        from_backend(ctx->frontend, 1, event, strlen(event));
        from_backend(ctx->frontend, 1, "\r\n", 2);
    }
    sfree(event);

    /*
     * Having either succeeded or failed in opening the log file,
     * we should write any queued data out.
     */
    assert(ctx->state != L_OPENING);   /* make _sure_ it won't be requeued */
    while (bufchain_size(&ctx->queue)) {
	void *data;
	int len;
	bufchain_prefix(&ctx->queue, &data, &len);
	logwrite(ctx, data, len);
	bufchain_consume(&ctx->queue, len);
    }
}
Пример #15
0
static int xyz_Check(Backend *back, void *backhandle, Terminal *term, int outerr)
{
	DWORD exitcode = 0;
	DWORD bread, avail;
	char buf[1024];
	HANDLE h;

	if (!term->xyz_transfering) {
		return 0;
	}

	if (outerr) {
		h = term->xyz_Internals->read_stdout;
	} else {
		h = term->xyz_Internals->read_stderr;
	}

	bread = 0;
	PeekNamedPipe(h,buf,1,&bread,&avail,NULL);
	//check to see if there is any data to read from stdout
	if (bread != 0)
	{
		while (1)
		{
			bread = 0;
		
			PeekNamedPipe(h,buf,1,&bread,&avail,NULL);
			if (bread == 0)
				return 0;

			if (ReadFile(h,buf,sizeof(buf),&bread,NULL))  { //read the stdout pipe
				if (bread) {
#if 0
					char *buffer;
					int len;
					
					buffer = buf;
					len = bread;
					if (0)
					{
						char *debugbuff;
						char *bb, *p;
						int i;
						
						debugbuff = _alloca(len*3+128);
						debugbuff[0] = 0;
						bb = debugbuff;
						p = buffer;
						bb += sprintf(bb, "R: %8d   ", time(NULL));
						for(i=0; i < len; i++) {
							bb += sprintf(bb, "%2x ", *p++);
						}
						bb += sprintf(bb, "\n");
						
						OutputDebugString(debugbuff);
					} else {
						char *debugbuff;
						debugbuff = _alloca(len+128);
						memcpy(debugbuff, buffer, len);
						debugbuff[len] = 0;
						if (outerr) {
							strcat(debugbuff, "<<<<<<<\n");
						} else {
							strcat(debugbuff, "*******\n");
						}
						OutputDebugString(debugbuff);
					}
#endif
					if (outerr) {
						back->send(backhandle, buf, bread);
					} else {
						from_backend(term, 1, buf, bread);
					}
					continue;
				}
			}
			// EOF/ERROR
			xyz_Done(term);
			return 1;
		}
		return 1;
	}
	
	GetExitCodeProcess(term->xyz_Internals->pi.hProcess,&exitcode);
	if (exitcode != STILL_ACTIVE) {
		xyz_Done(term);
		return 1;
	}

	return 0;
}
Пример #16
0
static int loop_send(void *handle, char *buf, int len) {
    struct loop_state *st = handle;

    return from_backend(st->term, 0, buf, len);
}
Пример #17
0
Файл: raw.c Проект: rdebath/sgt
static void c_write(char *buf, int len)
{
    int backlog = from_backend(0, buf, len);
    sk_set_frozen(s, backlog > RAW_MAX_BACKLOG);
}
Пример #18
0
int pty_real_select_result(Pty pty, int event, int status)
{
    char buf[4096];
    int ret;
    int finished = FALSE;

    if (event < 0) {
	/*
	 * We've been called because our child process did
	 * something. `status' tells us what.
	 */
	if ((WIFEXITED(status) || WIFSIGNALED(status))) {
	    /*
	     * The primary child process died. We could keep
	     * the terminal open for remaining subprocesses to
	     * output to, but conventional wisdom seems to feel
	     * that that's the Wrong Thing for an xterm-alike,
	     * so we bail out now (though we don't necessarily
	     * _close_ the window, depending on the state of
	     * Close On Exit). This would be easy enough to
	     * change or make configurable if necessary.
	     */
	    pty->exit_code = status;
	    pty->child_dead = TRUE;
	    del234(ptys_by_pid, pty);
	    finished = TRUE;
	}
    } else {
	if (event == 1) {

	    ret = read(pty->master_fd, buf, sizeof(buf));

	    /*
	     * Clean termination condition is that either ret == 0, or ret
	     * < 0 and errno == EIO. Not sure why the latter, but it seems
	     * to happen. Boo.
	     */
	    if (ret == 0 || (ret < 0 && errno == EIO)) {
		/*
		 * We assume a clean exit if the pty has closed but the
		 * actual child process hasn't. The only way I can
		 * imagine this happening is if it detaches itself from
		 * the pty and goes daemonic - in which case the
		 * expected usage model would precisely _not_ be for
		 * the pterm window to hang around!
		 */
		finished = TRUE;
		if (!pty->child_dead)
		    pty->exit_code = 0;
	    } else if (ret < 0) {
		perror("read pty master");
		exit(1);
	    } else if (ret > 0) {
		from_backend(pty->frontend, 0, buf, ret);
	    }
	} else if (event == 2) {
            /*
             * Attempt to send data down the pty.
             */
            pty_try_write(pty);
        }
    }

    if (finished && !pty->finished) {
	int close_on_exit;

	uxsel_del(pty->master_fd);
	pty_close(pty);
	pty->master_fd = -1;

	pty->finished = TRUE;

	/*
	 * This is a slight layering-violation sort of hack: only
	 * if we're not closing on exit (COE is set to Never, or to
	 * Only On Clean and it wasn't a clean exit) do we output a
	 * `terminated' message.
	 */
	close_on_exit = conf_get_int(pty->conf, CONF_close_on_exit);
	if (close_on_exit == FORCE_OFF ||
	    (close_on_exit == AUTO && pty->exit_code != 0)) {
	    char message[512];
            message[0] = '\0';
	    if (WIFEXITED(pty->exit_code))
		sprintf(message, "\r\n[pterm: process terminated with exit"
			" code %d]\r\n", WEXITSTATUS(pty->exit_code));
	    else if (WIFSIGNALED(pty->exit_code))
#ifdef HAVE_NO_STRSIGNAL
		sprintf(message, "\r\n[pterm: process terminated on signal"
			" %d]\r\n", WTERMSIG(pty->exit_code));
#else
		sprintf(message, "\r\n[pterm: process terminated on signal"
			" %d (%.400s)]\r\n", WTERMSIG(pty->exit_code),
			strsignal(WTERMSIG(pty->exit_code)));
#endif
	    from_backend(pty->frontend, 0, message, strlen(message));
	}

	notify_remote_exit(pty->frontend);
    }

    return !finished;
}
Пример #19
0
static void c_write(Raw raw, char *buf, int len)
{
    int backlog = from_backend(raw->frontend, 0, buf, len);
    sk_set_frozen(raw->s, backlog > RAW_MAX_BACKLOG);
}
Пример #20
0
Файл: pty.c Проект: nohuhu/TuTTY
int pty_select_result(int fd, int event)
{
    char buf[4096];
    int ret;
    int finished = FALSE;

    if (fd == pty_master_fd && event == 1) {

	ret = read(pty_master_fd, buf, sizeof(buf));

	/*
	 * Clean termination condition is that either ret == 0, or ret
	 * < 0 and errno == EIO. Not sure why the latter, but it seems
	 * to happen. Boo.
	 */
	if (ret == 0 || (ret < 0 && errno == EIO)) {
	    /*
	     * We assume a clean exit if the pty has closed but the
	     * actual child process hasn't. The only way I can
	     * imagine this happening is if it detaches itself from
	     * the pty and goes daemonic - in which case the
	     * expected usage model would precisely _not_ be for
	     * the pterm window to hang around!
	     */
	    finished = TRUE;
	    if (!pty_child_dead)
		pty_exit_code = 0;
	} else if (ret < 0) {
	    perror("read pty master");
	    exit(1);
	} else if (ret > 0) {
	    from_backend(pty_frontend, 0, buf, ret);
	}
    } else if (fd == pty_signal_pipe[0]) {
	pid_t pid;
	int status;
	char c[1];

	read(pty_signal_pipe[0], c, 1); /* ignore its value; it'll be `x' */

	do {
	    pid = waitpid(-1, &status, WNOHANG);
	    if (pid == pty_child_pid &&
		(WIFEXITED(status) || WIFSIGNALED(status))) {
		/*
		 * The primary child process died. We could keep
		 * the terminal open for remaining subprocesses to
		 * output to, but conventional wisdom seems to feel
		 * that that's the Wrong Thing for an xterm-alike,
		 * so we bail out now (though we don't necessarily
		 * _close_ the window, depending on the state of
		 * Close On Exit). This would be easy enough to
		 * change or make configurable if necessary.
		 */
		pty_exit_code = status;
		pty_child_dead = TRUE;
		finished = TRUE;
	    }
	} while(pid > 0);
    }

    if (finished && !pty_finished) {
	uxsel_del(pty_master_fd);
	pty_close();
	pty_master_fd = -1;

	pty_finished = TRUE;

	/*
	 * This is a slight layering-violation sort of hack: only
	 * if we're not closing on exit (COE is set to Never, or to
	 * Only On Clean and it wasn't a clean exit) do we output a
	 * `terminated' message.
	 */
	if (pty_cfg.close_on_exit == FORCE_OFF ||
	    (pty_cfg.close_on_exit == AUTO && pty_exit_code != 0)) {
	    char message[512];
	    if (WIFEXITED(pty_exit_code))
		sprintf(message, "\r\n[pterm: process terminated with exit"
			" code %d]\r\n", WEXITSTATUS(pty_exit_code));
	    else if (WIFSIGNALED(pty_exit_code))
#ifdef HAVE_NO_STRSIGNAL
		sprintf(message, "\r\n[pterm: process terminated on signal"
			" %d]\r\n", WTERMSIG(pty_exit_code));
#else
		sprintf(message, "\r\n[pterm: process terminated on signal"
			" %d (%.400s)]\r\n", WTERMSIG(pty_exit_code),
			strsignal(WTERMSIG(pty_exit_code)));
#endif
	    from_backend(pty_frontend, 0, message, strlen(message));
	}
    }
    return !finished;
}
Пример #21
0
static void c_write(Rlogin rlogin, char *buf, int len)
{
    int backlog = from_backend(rlogin->frontend, 0, buf, len);
    sk_set_frozen(rlogin->s, backlog > RLOGIN_MAX_BACKLOG);
}