Beispiel #1
0
struct session *activate_session(struct session *ses)
{
	check_all_events(gtd->ses, SUB_ARG|SUB_SEC, 0, 1, "SESSION DEACTIVATED", gtd->ses->name);

	gtd->ses = ses;

	display_printf(ses, "#SESSION '%s' ACTIVATED.", ses->name);

	check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "SESSION ACTIVATED", ses->name);

	return ses;
}
Beispiel #2
0
void process_mud_output(struct session *ses, char *linebuf, int prompt) {
  char line[STRING_SIZE];

  ses->check_output = 0;

  strip_vt102_codes(linebuf, line);

  check_all_events(ses, SUB_ARG | SUB_SEC, 0, 2, "RECEIVED LINE", linebuf, line);

  if (prompt) {
    check_all_events(ses, SUB_ARG | SUB_SEC, 0, 2, "RECEIVED PROMPT", linebuf, line);
  }

  if (HAS_BIT(ses->flags, SES_FLAG_COLORPATCH)) {
    sprintf(line, "%s%s", ses->color, linebuf);

    get_color_codes(ses->color, linebuf, ses->color);

    linebuf = line;
  }

  do_one_line(linebuf, ses);    /* changes linebuf */

  /*
     Take care of gags, vt102 support still goes
   */

  if (HAS_BIT(ses->flags, SES_FLAG_GAG)) {
    strip_non_vt102_codes(linebuf, ses->more_output);

    printf("%s", ses->more_output);

    ses->more_output[0] = 0;

    DEL_BIT(ses->flags, SES_FLAG_GAG);

    return;
  }

  add_line_buffer(ses, linebuf, prompt);

  if (ses == gtd->ses) {
    printline(ses, linebuf, prompt);
  } else if (HAS_BIT(ses->flags, SES_FLAG_SNOOP)) {
    strip_vt102_codes_non_graph(linebuf, linebuf);

    tintin_printf2(gtd->ses, "[%s] %s", ses->name, linebuf);
  }
}
Beispiel #3
0
void process_input(void)
{
	if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_SGA) && !HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO))
	{
		read_key();
	}
	else
	{
		read_line();
	}

	if (!HAS_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT))
	{
		return;
	}

	DEL_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT);

	if (gtd->chat && gtd->chat->paste_time)
	{
		chat_paste(gtd->input_buf, NULL);

		return;
	}

	if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO))
	{
		add_line_history(gtd->ses, gtd->input_buf);
	}

	if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO))
	{
		echo_command(gtd->ses, gtd->input_buf);
	}
	else
	{
		echo_command(gtd->ses, "");
	}

	if (gtd->ses->scroll_line != -1)
	{
		buffer_end(gtd->ses, "");
	}

	check_all_events(gtd->ses, SUB_ARG|SUB_SEC, 0, 1, "RECEIVED INPUT", gtd->input_buf);

	gtd->ses = script_driver(gtd->ses, LIST_COMMAND, gtd->input_buf);

	if (IS_SPLIT(gtd->ses))
	{
		erase_toeol();
	}

	gtd->input_buf[0] = 0;
}
Beispiel #4
0
struct session *connect_session(struct session *ses)
{
	int sock;

	push_call("connection_session(%p)",ses);

	ses->connect_retry = utime() + gts->connect_retry;

	reconnect:

	sock = connect_mud(ses, ses->host, ses->port);

	if (sock == -1)
	{
		cleanup_session(ses);

		pop_call();
		return NULL;
	}

	if (sock)
	{
		gtd->ses    = ses;
		ses->socket = sock;

		ses->connect_retry = 0;

		SET_BIT(ses->flags, SES_FLAG_CONNECTED);

		tintin_printf2(ses, "");

		tintin_printf(ses, "#SESSION '%s' CONNECTED TO '%s' PORT '%s'", ses->name, ses->host, ses->port);

		check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "SESSION CONNECTED", ses->name, ses->host, ses->ip, ses->port);

		pop_call();
		return ses;
	}

	if (ses->connect_retry > utime())
	{
		goto reconnect;
	}

	if (ses->connect_error)
	{
		tintin_printf(ses, "#SESSION '%s' FAILED TO CONNECT.", ses->name);
	}

	cleanup_session(ses);

	pop_call();
	return NULL;
}
Beispiel #5
0
void cleanup_session(struct session *ses)
{
	push_call("cleanup_session(%p)",ses);

	if (ses == gtd->update)
	{
		gtd->update = ses->next;
	}

	UNLINK(ses, gts->next, gts->prev);

	if (ses->socket)
	{
		if (close(ses->socket) == -1)
		{
			syserr("close in cleanup");
		}

		if (HAS_BIT(ses->flags, SES_FLAG_RUN))
		{
			kill(ses->pid, SIGKILL);
		}

		DEL_BIT(ses->flags, SES_FLAG_CONNECTED);
	}

	check_all_events(ses, SUB_ARG|SUB_SEC, 0, 3, "SESSION DISCONNECTED", ses->name, ses->command, ntos(ses->pid));

	display_printf(gtd->ses, "#SESSION '%s' DIED.", ses->name);

	if (ses == gtd->ses)
	{
		gtd->ses = newactive_session();
	}

	if (ses->logfile)
	{
		fclose(ses->logfile);
	}

	if (ses->logline)
	{
		fclose(ses->logline);
	}

	LINK(ses, gtd->dispose_next, gtd->dispose_prev);

	pop_call();
	return;
}
Beispiel #6
0
void write_line_mud(struct session *ses, char *line, int size)
{
	static int retry;

	push_call("write_line_mud(%p,%p)",line,ses);

	if (ses == gts)
	{
		tintin_printf2(ses, "#NO SESSION ACTIVE. USE: %csession {name} {host} {port} TO START ONE.", gtd->tintin_char);

		pop_call();
		return;
	}

	if (!HAS_BIT(ses->flags, SES_FLAG_CONNECTED))
	{
		tintin_printf2(ses, "#THIS SESSION IS NOT CONNECTED.");

		pop_call();
		return;
	}

	if (write(ses->socket, line, size) == -1)
	{
		if (retry++ < 10)
		{
			usleep(100000);

			write_line_mud(ses, line, size);

			pop_call();
			return;
		}
		perror("write in write_line_mud");

		cleanup_session(ses);

		pop_call();
		return;
	}

	retry = 0;

	check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "SEND OUTPUT", line);

	pop_call();
	return;
}
Beispiel #7
0
void quitmsg(char *message)
{
	struct session *ses;

	SET_BIT(gtd->flags, TINTIN_FLAG_TERMINATE);

	while ((ses = gts->next) != NULL)
	{
		cleanup_session(ses);
	}

	if (gtd->chat)
	{
		close(gtd->chat->fd);
	}

	check_all_events(gts, SUB_ARG|SUB_SEC, 0, 0, "PROGRAM TERMINATION");

/*
	if (gtd->history_size)
	{
		char filename[BUFFER_SIZE];

		sprintf(filename, "%s/%s", getenv("HOME"), HISTORY_FILE);

		history_write(gts, filename);
	}
*/
	restore_terminal();

	clean_screen(gts);

	if (message)
	{
		printf("\n%s\n", message);
	}

	printf("\nGoodbye from TinTin++\n\n");

	fflush(NULL);

	exit(0);
}
Beispiel #8
0
void init_screen_size(struct session *ses)
{
	int top, bot;
	struct winsize screen;

	top = ses->top_row == 0 ? 1 : ses->top_row;
	bot = ses->bot_row == 0 ? 0 : ses->rows - ses->bot_row;

	if (ses == gts)
	{
		if (ioctl(0, TIOCGWINSZ, &screen) == -1)
		{
			ses->rows = SCREEN_HEIGHT;
			ses->cols = SCREEN_WIDTH;
		}
		else
		{
			ses->rows = screen.ws_row;
			ses->cols = screen.ws_col;
		}
		SET_BIT(gtd->flags, TINTIN_FLAG_RESETBUFFER);
	}
	else
	{
		ses->rows = gts->rows;
		ses->cols = gts->cols;
	}

	ses->top_row = top;
	ses->bot_row = ses->rows - bot;

	if (HAS_BIT(ses->flags, SES_FLAG_SPLIT))
	{
		init_split(ses, ses->top_row, ses->bot_row);
	}
	check_all_events(ses, SUB_ARG|SUB_SEC, 0, 2, "SCREEN RESIZE", ntos(ses->cols), ntos(ses->rows));
}
Beispiel #9
0
void cleanup_session(struct session *ses)
{
	push_call("cleanup_session(%p)",ses);

	if (HAS_BIT(ses->flags, SES_FLAG_CLOSED))
	{
		tintin_printf2(NULL, "\n#SESSION '%s' IS ALREADY CLOSED.", ses->name);
		dump_stack();

		pop_call();
		return;
	}

	if (ses == gtd->update)
	{
		gtd->update = ses->next;
	}

	UNLINK(ses, gts->next, gts->prev);

	if (ses->socket)
	{
		if (close(ses->socket) == -1)
		{
			syserr("close in cleanup");
		}

		// the PID is stored in the session's port.

		if (HAS_BIT(ses->flags, SES_FLAG_RUN))
		{
			kill(atoi(ses->port), SIGKILL);
		}

	}

	SET_BIT(ses->flags, SES_FLAG_CLOSED);

	if (HAS_BIT(ses->flags, SES_FLAG_CONNECTED))
	{
		check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "SESSION DISCONNECTED", ses->name, ses->host, ses->ip, ses->port);

		tintin_printf(gtd->ses, "#SESSION '%s' DIED.", ses->name);
	}
	else
	{
		check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "SESSION TIMED OUT", ses->name, ses->host, ses->ip, ses->port);

		tintin_printf(gtd->ses, "#SESSION '%s' TIMED OUT.", ses->name);
	}

	if (ses == gtd->ses)
	{
		gtd->ses = newactive_session();
	}

	if (ses->logfile)
	{
		fclose(ses->logfile);
	}

	if (ses->logline)
	{
		fclose(ses->logline);
	}

	LINK(ses, gtd->dispose_next, gtd->dispose_prev);

	pop_call();
	return;
}
Beispiel #10
0
void readmud(struct session *ses)
{
	char *line, *next_line;
	char linebuf[STRING_SIZE];

	push_call("readmud(%p)", ses);

	if (gtd->mud_output_len < BUFFER_SIZE)
	{
		check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "RECEIVED OUTPUT", gtd->mud_output_buf);
	}

	gtd->mud_output_len = 0;

	/* separate into lines and print away */

	if (HAS_BIT(gtd->ses->flags, SES_FLAG_SPLIT))
	{
		save_pos(gtd->ses);
		goto_rowcol(gtd->ses, gtd->ses->bot_row, 1);
	}

	SET_BIT(gtd->ses->flags, SES_FLAG_READMUD);

	for (line = gtd->mud_output_buf ; line && *line ; line = next_line)
	{
		next_line = strchr(line, '\n');

		if (next_line)
		{
			*next_line = 0;
			next_line++;
		}
		else if (*line == 0)
		{
			break;
		}

		if (next_line == NULL && strlen(ses->more_output) < BUFFER_SIZE / 2)
		{
			if (!HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_PROMPT))
			{
				if (gts->check_output)
				{
					strcat(ses->more_output, line);
					ses->check_output = utime() + gts->check_output;
					break;
				}
			}
		}

		if (ses->more_output[0])
		{
			if (ses->check_output)
			{
				sprintf(linebuf, "%s%s", ses->more_output, line);

				ses->more_output[0] = 0;
			}
			else
			{
				strcpy(linebuf, line);
			}
		}
		else
		{
			strcpy(linebuf, line);
		}

		process_mud_output(ses, linebuf, next_line == NULL);
	}
	DEL_BIT(gtd->ses->flags, SES_FLAG_READMUD);

	if (HAS_BIT(gtd->ses->flags, SES_FLAG_SPLIT))
	{
		restore_pos(gtd->ses);
	}

	pop_call();
	return;
}
Beispiel #11
0
int main(int argc, char **argv)
{
	int greeting = TRUE;

	#ifdef SOCKS
		SOCKSinit(argv[0]);
	#endif

	if (signal(SIGTERM, trap_handler) == BADSIG)
	{
		syserr("signal SIGTERM");
	}

	if (signal(SIGSEGV, trap_handler) == BADSIG)
	{
		syserr("signal SIGSEGV");
	}

	if (signal(SIGHUP, trap_handler) == BADSIG)
	{
		syserr("signal SIGHUP");
	}

	if (signal(SIGABRT, abort_handler) == BADSIG)
	{
		syserr("signal SIGTERM");
	}

	if (signal(SIGINT, abort_handler) == BADSIG)
	{
		syserr("signal SIGINT");
	}

	if (signal(SIGTSTP, suspend_handler) == BADSIG)
	{
		syserr("signal SIGSTOP");
	}

	if (signal(SIGPIPE, pipe_handler) == BADSIG)
	{
		syserr("signal SIGPIPE");
	}

	if (signal(SIGWINCH, winch_handler) == BADSIG)
	{
		syserr("signal SIGWINCH");
	}

/*
	if (getenv("HOME") != NULL)
	{
		char filename[256];

		sprintf(filename, "%s/%s", getenv("HOME"), HISTORY_FILE);

		read_history(gts, filename);
	}
*/

	srand(time(NULL));

	if (argc > 1)
	{
		int c;

		while ((c = getopt(argc, argv, "e: G h r: s: t: v")) != EOF)
		{
			if (c == 'G')
			{
				greeting = FALSE;
			}
		}

		optind = 1;
	}

	init_tintin(greeting);

	if (argc > 1)
	{
		int c;

		optind = 1;

		while ((c = getopt(argc, argv, "e: G h r: s: t: v")) != EOF)
		{
			switch (c)
			{
				case 'e':
					gtd->ses = script_driver(gtd->ses, -1, optarg);
					break;

				case 'G':
					break;

				case 'h':
					tintin_printf(NULL, "Usage: %s [OPTION]... [FILE]...", argv[0]);
					tintin_printf(NULL, "");
					tintin_printf(NULL, "  -e  Execute given command.");
					tintin_printf(NULL, "  -G  Don't show the greeting screen.");
					tintin_printf(NULL, "  -h  This help section.");
					tintin_printf(NULL, "  -r  Read given file.");
					tintin_printf(NULL, "  -t  Set given title.");
					tintin_printf(NULL, "  -v  Enable verbose mode.");

					restore_terminal();
					exit(1);
					break;

				case 'r':
					gtd->ses = do_read(gtd->ses, optarg);
					break;

				case 't':
					printf("\033]0;%s\007", optarg);
					break;

				case 's':
					srand((unsigned int) atoll(optarg));
					break;

				case 'v':
					do_configure(gtd->ses, "{VERBOSE} {ON}");
					break;

				default:
					tintin_printf(NULL, "Unknown option '%c'.", c);
					break;
			}
		}

		if (argv[optind] != NULL)
		{
			gtd->ses = do_read(gtd->ses, argv[optind]);
		}
	}
	check_all_events(gts, SUB_ARG|SUB_SEC, 0, 2, "PROGRAM START", CLIENT_NAME, CLIENT_VERSION);
	check_all_events(gts, SUB_ARG|SUB_SEC, 0, 2, "SCREEN RESIZE", ntos(gts->cols), ntos(gts->rows));

	mainloop();

	return 0;
}
Beispiel #12
0
struct session *new_session(struct session *ses, char *name, char *command, int pid, int socket)
{
	int cnt = 0;
	struct session *newsession;

	push_call("new_session(%p,%p,%p,%d,%d)",ses,name,command,pid,socket);

	for (newsession = gts ; newsession ; newsession = newsession->next)
	{
		if (!strcmp(newsession->name, name))
		{
			display_puts(ses, "THERE'S A SESSION WITH THAT NAME ALREADY.");

			if (close(socket) == -1)
			{
				syserr("close in new_session");
			}

			kill(pid, SIGKILL);

			pop_call();
			return ses;
		}
	}

	newsession                = (struct session *) calloc(1, sizeof(struct session));

	newsession->name          = strdup(name);
	newsession->command       = strdup(command);
	newsession->pid           = pid;

	newsession->group         = strdup(gts->group);
	newsession->flags         = gts->flags;

	LINK(newsession, gts->next, gts->prev);

	for (cnt = 0 ; cnt < LIST_MAX ; cnt++)
	{
		newsession->list[cnt] = copy_list(newsession, gts->list[cnt], cnt);
	}

	newsession->rows          = gts->rows;
	newsession->cols          = gts->cols;

	display_printf(ses, "#TRYING TO LAUNCH '%s' RUNNING '%s'.", newsession->name, newsession->command);

	gtd->ses = newsession;

	SET_BIT(newsession->flags, SES_FLAG_CONNECTED|SES_FLAG_RUN);

	DEL_BIT(newsession->flags, SES_FLAG_LOCALECHO);

	gtd->ses = newsession;

	gtd->ses->socket = socket;

	check_all_events(ses, SUB_ARG|SUB_SEC, 0, 3, "SESSION CONNECTED", ses->name, ses->command, ntos(ses->pid));

	pop_call();
	return gtd->ses;
}