Beispiel #1
0
void run_user_flag(char *name, char *what, NickList *user, NickList *kicker)
{
	char *tmp = NULL;
	char *name_copy, *stuff_copy;
	int sa = 0;
	char buffer[BIG_BUFFER_SIZE*5+1];
	*buffer = 0;
	strmopencat(buffer, BIG_BUFFER_SIZE*5, user->nick, space, user->host, space, user->ip, space, user->userlist?one:zero, space, NULL);
	if (user->userlist)
		strmopencat(buffer, BIG_BUFFER_SIZE*5, user->userlist->nick, space, user->userlist->host, space, user->userlist->channels, space, ltoa(user->userlist->flags), space, NULL);
	if (kicker)
	{
		strmopencat(buffer, BIG_BUFFER_SIZE*5, kicker->nick, space, kicker->host, space, kicker->ip, space, kicker->userlist?one:zero, NULL);
		if (kicker->userlist)
			strmopencat(buffer, BIG_BUFFER_SIZE*5, space, kicker->userlist->nick, space, kicker->userlist->host, space, kicker->userlist->channels, space, ltoa(kicker->userlist->flags), NULL);
	}
	if ((tmp = expand_alias(what, empty_string, &sa, NULL)))
	{
		stuff_copy = alloca(strlen(tmp) + 1);
		name_copy = LOCAL_COPY(name);
		stuff_copy = LOCAL_COPY(tmp);
		will_catch_return_exceptions++;
		parse_line(name_copy, stuff_copy, buffer, 0, 0, 1);
		will_catch_return_exceptions--;
		return_exception = 0;
	}
	new_free(&tmp);
}
Beispiel #2
0
/* 
 * This is an alternative form of put_it which writes three asterisks
 * before actually putting things out.
 */
static void 	vsay (const char *format, va_list args)
{
	if (window_display && format)
	{
		char *str;

		*putbuf = 0;
		if ((str = get_string_var(BANNER_VAR)))
		{
			if (get_int_var(BANNER_EXPAND_VAR))
			{
			    char *foo;

			    foo = expand_alias(str, empty_string);
			    strlcpy(putbuf, foo, sizeof putbuf);
			    new_free(&foo);
			}
			else
			    strlcpy(putbuf, str, sizeof putbuf);

			strlcat(putbuf, " ", sizeof putbuf);
		}

		vsnprintf(putbuf + strlen(putbuf), 
			sizeof(putbuf) - strlen(putbuf) - 1, 
			format, args);

		put_echo(putbuf);
	}
}
Beispiel #3
0
/*
 * add_to_log: add the given line to the log file.  If no log file is open
 * this function does nothing. 
 */
void 	add_to_log (FILE *fp, long winref, const unsigned char *line, int mangler, const char *rewriter)
{
	char	*local_line;
	size_t	size;
	int	must_free = 0;

	if (!fp || inhibit_logging)
		return;

	/*
	 * We need to make a local copy because 'mangle_line' 
	 * diddles around with the source, and so we can't subject
	 * line to that, it is 'const'.
	 *
	 * 'mangle_line' can expand the input string, so it is 
	 * neccesary to allocate more than we need.
	 */
	size = (strlen(line) + 1) * 11;
	local_line = alloca(size + 1);
	strlcpy(local_line, line, size + 1);

	/* Do this first */
	if (mangler == 0)
		mangler = logfile_line_mangler;
	if (mangler)
	   if (mangle_line(local_line, mangler, size) > size)
		(void)0; /* Whimper -- what to do, what to do? */

	if (get_int_var(NO_CONTROL_LOG_VAR))
	{
		char *tmp = alloca(strlen(local_line) + 1);
		strip_control(local_line, tmp);
		strlcpy(local_line, tmp, size);
	}

	if (rewriter == NULL)
		rewriter = get_string_var(LOG_REWRITE_VAR);
	if (rewriter)
	{
		char    *prepend_exp;
		char    argstuff[10240];
		int     args_flag;

		/* First, create the $* list for the expando */
		snprintf(argstuff, 10240, "%ld %s", winref, local_line);

		/* Now expand the expando with the above $* */
		prepend_exp = expand_alias(rewriter, argstuff,
					   &args_flag, NULL);

		local_line = prepend_exp;
		must_free = 1;
	}

	fprintf(fp, "%s\n", local_line);
	fflush(fp);

	if (must_free)
		new_free(&local_line);
}
Beispiel #4
0
/*
 * add_to_log: add the given line to the log file.  If no log file is open
 * this function does nothing. 
 * (Note:  "logref" should be -1 unless we are logging from a /log log, ie,
 * any place that is not inside logfiles.c)
 */
void 	add_to_log (int logref, FILE *fp, long winref, const unsigned char *line, int mangler, const char *rewriter)
{
	char	*local_line = NULL;
	int	old_logref;
static	int	recursive = 0;

	/*
	 * I added "recursive" because this function should not
	 * generate any output.  But it might generate output if
	 * the string expand was bogus below.  I chose to "fix" this
	 * by refusing to log anything recursively.  The downside
	 * is any errors won't get logged, which may or may not be
	 * a problem, I haven't decided yet.
	 */
	if (recursive > 0)
		return;
	
	if (!fp || inhibit_logging)
		return;

	recursive++;
	old_logref = current_log_refnum;
	current_log_refnum = logref;

	/* Do this first */
	/* Either do mangling or /set no_control_log, but never both! */
	if (mangler == 0)
		mangler = logfile_line_mangler;
	else if (get_int_var(NO_CONTROL_LOG_VAR))
		mangler |= STRIP_UNPRINTABLE;
	if (mangler)
		local_line = new_normalize_string(line, 1, mangler);
	else
		local_line = malloc_strdup(line);

	if (rewriter == NULL)
		rewriter = get_string_var(LOG_REWRITE_VAR);
	if (rewriter)
	{
		char    *prepend_exp;
		char    argstuff[10240];

		/* First, create the $* list for the expando */
		snprintf(argstuff, 10240, "%ld %s", winref, local_line);
		new_free(&local_line);

		/* Now expand the expando with the above $* */
		prepend_exp = expand_alias(rewriter, argstuff);
		local_line = prepend_exp;
	}

	fprintf(fp, "%s\n", local_line);
	fflush(fp);

	new_free(&local_line);
	current_log_refnum = old_logref;
	recursive--;
}
Beispiel #5
0
void
fec(u_char *command, u_char *args, u_char *subargs)
{
	u_char	*pointer;
	u_char	*list = NULL;
	u_char	*var = NULL;
	u_char	stuff[2];
	int	args_flag = 0;
	unsigned display;
	u_char	*sa, *todo;

	list = next_expr(&args, '(');		/* ) */
	if (list == NULL)
	{
		yell ("FEC: Missing List for /FEC");
		return;
	}

	sa = subargs ? subargs : empty_string();
	list = expand_alias(NULL, list, sa, &args_flag, NULL);
	pointer = list;

	var = next_arg(args, &args);
	args = my_index(args, '{');		/* } */

	if ((todo = next_expr(&args, '{')) == NULL)
	{
		yell ("FE: Missing }");
		return;
	}

	stuff[1] = '\0';

	while (*pointer)
	{
		display = set_display_off();
		stuff[0] = *pointer++;
		add_alias(VAR_ALIAS, var, stuff);
		set_display(display);
		parse_line(NULL, todo, 
		    subargs ? subargs : empty_string(), 0, 0, 0);
	}
	display = set_display_off();
	delete_alias(VAR_ALIAS, var);
	set_display(display);

	new_free(&list);
}
Beispiel #6
0
static void	for_fe_cmd (int argc, char **argv, const char *subargs)
{
	char 	*var, *list, *cmds;
	char	*next, *real_list, *x;

	if (!subargs)
		subargs = empty_string;

	if ((my_stricmp(argv[1], "in")) || (argc != 4)) {
		my_error("Usage: /FOR var IN (list) {commands}");
		return;
	}

	var = argv[0];
	list = argv[2];
	cmds = argv[3];

	if (*cmds == '{')
		cmds++;
	if (*list == '(')
		list++;
	x = real_list = expand_alias(list, subargs);
	will_catch_break_exceptions++;
	will_catch_continue_exceptions++;
	while (real_list && *real_list)
	{
		next = next_func_arg(real_list, &real_list);
		add_local_alias(var, next, 0);
		runcmds(cmds, subargs);

		if (break_exception) {
			break_exception = 0;
			break;
		}
		if (continue_exception)
			continue_exception = 0;	/* Dont continue here! */
		if (return_exception)
			break;
		if (system_exception)
			break;
	}
	will_catch_break_exceptions--;
	will_catch_continue_exceptions--;
	new_free(&x);
}
Beispiel #7
0
/*
 * syserr is exactly like say, except that if the error occured while
 * you were loading a script, it tells you where it happened.
 */
static void     vsyserr (int server, const char *format, va_list args)
{
	char *  str;
	int     l, old_from_server = from_server;
	int	i_set_from_server = 0;

        if (!window_display || !format)
		return;

	*putbuf = 0;
	if ((str = get_string_var(BANNER_VAR)))
	{
		if (get_int_var(BANNER_EXPAND_VAR))
		{
		    char *foo;

		    foo = expand_alias(str, empty_string);
		    strlcpy(putbuf, foo, sizeof putbuf);
		    new_free(&foo);
		}
		else
		    strlcpy(putbuf, str, sizeof putbuf);

		strlcat(putbuf, " INFO -- ", sizeof putbuf);
	}

	vsnprintf(putbuf + strlen(putbuf),
		sizeof(putbuf) - strlen(putbuf) - 1,
		format, args);

	if (is_server_valid(server))
	{
		old_from_server = from_server;
		from_server = server;
		i_set_from_server = 1;
	}

	l = message_from(NULL, LEVEL_SYSERR);
	if (do_hook(YELL_LIST, "%s", putbuf))
		put_echo(putbuf);
	pop_message_from(l);

	if (i_set_from_server)
		from_server = old_from_server;
}
Beispiel #8
0
/*
 * banner: This returns in a static string of either "xxx" where
 * xxx is the current numeric, or "***" if SHOW_NUMBERS is OFF 
 */
const char *	banner (void)
{
	static	char	thing[80];
	char *str;

	if (current_numeric > 0 && get_int_var(SHOW_NUMERICS_VAR))
		snprintf(thing, sizeof thing, "%3.3u", current_numeric);
	else if ((str = get_string_var(BANNER_VAR)))
	{
		if (get_int_var(BANNER_EXPAND_VAR))
		{
			char *foo = expand_alias(str, empty_string);
			strlcpy(thing, foo, sizeof thing);
			new_free(&foo);
		}
		else
			strlcpy(thing, str, sizeof thing);
	}
	else
		*thing = 0;

	return (thing);
}
Beispiel #9
0
static char
input_do_check_prompt(int update)
{
	ScreenInputData *inputdata = screen_get_inputdata(get_current_screen());
	u_char	*prompt;
	u_char	*ptr;
	char	changed = 0;
	int	free_it = 1;
	unsigned len;
	int	args_used;	/* unused */

	if (update == NO_UPDATE)
		return changed;

	prompt = prompt_current_prompt();
	if (!prompt)
		prompt = input_prompt ? input_prompt : empty_string();

	if (is_process(get_target_by_refnum(0)))
	{
		ptr = get_prompt_by_refnum(0);
		free_it = 0;
	}
	else
		ptr = expand_alias(NULL, prompt, empty_string(), &args_used, NULL);

	len = my_strlen(ptr);
	if (my_strncmp(ptr, inputdata->buffer.buf, len) || !len)
	{
		input_do_replace_prompt(ptr);
		changed = 1;
	}
	if (free_it)
		new_free(&ptr);
	return changed;
}
Beispiel #10
0
/*
 * update_input: does varying amount of updating on the input line depending
 * upon the position of the cursor and the update flag.  If the cursor has
 * move toward one of the edge boundaries on the screen, update_cursor()
 * flips the input line to the next (previous) line of text. The update flag
 * may be: 
 *
 * NO_UPDATE - only do the above bounds checking. 
 *
 * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should
 * be. 
 *
 * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from
 * the cursor to the right edge of the screen is current (by redrawing it). 
 *
 * UPDATE_ALL - redraws the entire line 
 */
void	update_input (int update)
{
	int	old_zone;
	char	*ptr, *ptr_free;
	int	len,
		free_it = 0,
		max;
	char	*prompt;
	int	do_echo = 1;
	Screen	*os = last_input_screen;
	Screen	*ns;
	Window	*saved_current_window = current_window;

	/*
	 * No input line in dumb or bg mode.
	 */
	if (dumb_mode || !foreground)
		return;

  for (ns = screen_list; ns; ns = ns->next)
  {
	if (!ns->alive)
		continue;	/* It's dead, Jim! */

	last_input_screen = ns;
	current_window = ns->current_window;

	/*
	 * Make sure the client thinks the cursor is on the input line.
	 */
	cursor_to_input();

	/*
	 * See if we're in a add_wait_prompt() call.  If we are, grab that
	 * current prompt, otherwise use the default input prompt.
	 */
	if (last_input_screen->promptlist)
		prompt = last_input_screen->promptlist->prompt;
	else
		prompt = input_prompt;

	/*
	 *
	 * GET THE INPUT PROMPT
	 *
	 */

	/*
	 * If we have a prompt, and we're supposed to update the input
	 * prompt, then we do need to expand the prompt.
	 */
	if (prompt && update != NO_UPDATE)
	{
		int	af;

		/*
		 * If the current window is query'ing an exec'd process,
		 * then we just get the current prompt for that process.
		 * Note that it is not malloced.
		 */
		if (is_valid_process(get_target_by_refnum(0)) != -1)
			ptr = get_prompt_by_refnum(0);

		/*
		 * Otherwise, we just expand the prompt as normal.
		 */
		else
		{
			ptr = expand_alias(prompt, empty_string, &af, NULL);
			free_it = 1;
		}

		/*
		 * If we're in an add_wait_prompt(), we see whether or not
		 * this is an "invisible" prompt.  If it is, we turn off the
		 * echo so what the user types doesnt show up.
		 */
		if (last_input_screen->promptlist)
			term_echo(last_input_screen->promptlist->echo);

		/*
		 * Mangle out any ansi chars or so forth.
		 */
		ptr_free = ptr;
		ptr = normalize_string(ptr, 0);	/* This should be ok */
		if (free_it)
			new_free(&ptr_free);
		free_it = 1;

		/*
		 * If the prompt has changed, or if there is no prompt...
		 */
		if (	(ptr && !INPUT_PROMPT) ||
			(!ptr && INPUT_PROMPT) ||
			strcmp(ptr, INPUT_PROMPT)	)
		{
			if (last_input_screen->input_prompt_malloc)
				new_free(&INPUT_PROMPT);

			last_input_screen->input_prompt_malloc = free_it;
			INPUT_PROMPT = ptr;
			INPUT_PROMPT_LEN = output_with_count(INPUT_PROMPT, 0, 0);
			update = UPDATE_ALL;
		}
		/*
		 * Prompt didnt change, so clean up our mess
		 */
		else
		{
			if (free_it)
				new_free(&ptr);
		}
	}


	/*
	 * 
	 * HAS THE SCREEN CHANGED SIZE SINCE THE LAST TIME?
	 *
	 */

	/*
	 * If the screen has resized, then we need to re-compute the
	 * side-to-side scrolling effect.
	 */
	if ((last_input_screen->li != last_input_screen->old_li) || 
	    (last_input_screen->co != last_input_screen->old_co))
	{
		/*
		 * The input line is always the bottom line
		 */
		INPUT_LINE = last_input_screen->li - 1;

		/*
		 * The "zone" is the range in which when you type, the
		 * input line does not scroll.  It is WIDTH chars in from
		 * either side of the display.
		 */
		ZONE = last_input_screen->co - (WIDTH * 2);
		if (ZONE < 10)
			ZONE = 10;		/* Take that! */
		START_ZONE = WIDTH;
		END_ZONE = last_input_screen->co - WIDTH;

		last_input_screen->old_co = last_input_screen->co;
		last_input_screen->old_li = last_input_screen->li;
	}

	/*
	 * About zones:
	 * The input line is divided into "zones".  A "zone" is set above,
	 * and is the width of the screen minus 20 (by default).  The input
	 * line, as displayed, is therefore composed of the current "zone",
	 * plus 10 characters from the previous zone, plus 10 characters 
	 * from the next zone.  When the cursor moves to an adjacent zone,
	 * (by going into column 9 from the right or left of the edge), the
	 * input line is redrawn.  There is one catch.  The first "zone"
	 * includes the first ten characters of the input line.
	 */
	old_zone = START_ZONE;

	/*
	 * The BEGINNING of the current "zone" is a calculated value:
	 *	The number of characters since the origin of the input buffer
	 *	is the number of printable chars in the input prompt plus the
	 *	current position in the input buffer.  We subtract from that
	 * 	the WIDTH delta to take off the first delta, which doesnt
	 *	count towards the width of the zone.  Then we divide that by
	 * 	the size of the zone, to get an integer, then we multiply it
	 * 	back.  This gives us the first character on the screen.  We
	 *	add WIDTH to the result in order to get the start of the zone
	 *	itself.
	 * The END of the current "zone" is just the beginning plus the width.
	 * If we have moved to an different "zone" since last time, we want to
	 * 	completely redraw the input line.
	 */
	START_ZONE = ((INPUT_PROMPT_LEN + THIS_POS - WIDTH) / ZONE) * ZONE + WIDTH;
	END_ZONE = START_ZONE + ZONE;

	if (old_zone != START_ZONE)
		update = UPDATE_ALL;

	/*
	 * Now that we know where the "zone" is in the input buffer, we can
	 * easily calculate where where we want to start displaying stuff
	 * from the INPUT_BUFFER.  If we're in the first "zone", then we will
	 * output from the beginning of the buffer.  If we're not in the first
	 * "zone", then we will begin to output from 10 characters to the
	 * left of the zone, after adjusting for the length of the prompt.
	 */
	if (START_ZONE == WIDTH)
	    INPUT_ONSCREEN = 0;
	else {
	    if ((INPUT_ONSCREEN = START_ZONE - WIDTH - INPUT_PROMPT_LEN) < 0)
		INPUT_ONSCREEN = 0;
	}

	/*
	 * And the cursor is simply how many characters away THIS_POS is
	 * from the first column on the screen.
	 */
	if (INPUT_ONSCREEN == 0)
		INPUT_CURSOR = INPUT_PROMPT_LEN + THIS_POS;
	else
		INPUT_CURSOR = THIS_POS - INPUT_ONSCREEN;

	/*
	 * If the cursor moved, or if we're supposed to do a full update,
	 * then redraw the entire input line.
	 */
	if (update == UPDATE_ALL)
	{
		/*
		 * Move the cursor to the start of the input line
		 */
		term_move_cursor(0, INPUT_LINE);

		/*
		 * If the input line is NOT empty, and we're starting the
		 * display at the beginning of the input buffer, then we
		 * output the prompt first.
		 */
		if (INPUT_ONSCREEN == 0 && INPUT_PROMPT && *INPUT_PROMPT)
		{
			/*
			 * Forcibly turn on echo.
			 */
			do_echo = term_echo(1);

			/*
			 * Crop back the input prompt so it does not extend
			 * past the end of the zone.
			 */
			if (INPUT_PROMPT_LEN > (last_input_screen->co - WIDTH))
				INPUT_PROMPT_LEN = last_input_screen->co - WIDTH - 1;

			/*
			 * Output the prompt.
			 */
			output_with_count(INPUT_PROMPT, 0, 1);

			/*
			 * Turn the echo back to what it was before,
			 * and output the rest of the input buffer.
			 */
			term_echo(do_echo);
			safe_puts(INPUT_BUFFER, last_input_screen->co - INPUT_PROMPT_LEN, do_echo);
		}

		/*
		 * Otherwise we just output whatever we have.
		 */
		else if (do_echo)
			safe_puts(&(INPUT_VISIBLE), last_input_screen->co, do_echo);

		/*
		 * Clear the rest of the input line and reset the cursor
		 * to the current input position.
		 */
		term_clear_to_eol();
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * If we're just supposed to refresh whats to the right of the
	 * current logical position...
	 */
	else if (update == UPDATE_FROM_CURSOR)
	{
		/*
		 * Move the cursor to where its supposed to be,
		 * Figure out how much we can output from here,
		 * and then output it.
		 */
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		max = last_input_screen->co - (THIS_POS - INPUT_ONSCREEN);
		if (INPUT_ONSCREEN == 0 && INPUT_PROMPT && *INPUT_PROMPT)
			max -= INPUT_PROMPT_LEN;

		if ((len = strlen(&(THIS_CHAR))) > max)
			len = max;
		safe_puts(&(THIS_CHAR), len, do_echo);
		term_clear_to_eol();
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * If we're just supposed to move the cursor back to the input
	 * line, then go ahead and do that.
	 */
	else if (update == UPDATE_JUST_CURSOR)
	{
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * Turn the terminal echo back on, and flush all of the output
	 * we may have done here.
	 */
	term_echo(1);
	term_flush();
    }
    last_input_screen = os;
    current_window = saved_current_window;
}
Beispiel #11
0
void
fe(u_char *command, u_char *args, u_char *subargs)
{
	u_char	*list = NULL,
		*templist = NULL,
		*placeholder,
		*oldlist = NULL,
		*sa,
		*vars,
		*var[255],
		*word = NULL,
		*todo = NULL;
	int	ind, x, y, count, args_flag;
	unsigned display;

	for (x = 0; x < 255; var[x++] = NULL)
		;

	list = next_expr(&args, '(');	/* ) */
	if (!list)
	{
		yell ("FE: Missing List for /FE");
		return;
	}

	sa = subargs ? subargs : (u_char *) " ";
	malloc_strcpy(&templist, list);
	do 
	{
		malloc_strcpy(&oldlist, templist);
		new_free(&templist);
		templist = expand_alias(NULL, oldlist, sa, &args_flag, NULL);
	} while (my_strcmp(templist, oldlist));

	new_free(&oldlist);

	if (*templist == '\0')
	{
		new_free(&templist);
		return;
	}

	vars = args;
	if (!(args = my_index(args, '{')))		/* } */
	{
		yell ("FE: Missing commands");
		new_free(&templist);
		return;
	}
	*(args-1) = '\0';
	ind = 0;
	while ((var[ind++] = next_arg(vars, &vars)))
	{
		if (ind == 255)
		{
			yell ("FE: Too many variables");
			new_free(&templist);
			return;
		}
	}
	ind = ind ? ind - 1: 0;

	if (!(todo = next_expr(&args, '{')))		/* } { */
	{
		yell ("FE: Missing }");		
		new_free(&templist);
		return;
	}

	count = word_count(templist);
	display = get_display();
	placeholder = templist;
	for (x = 0; x < count;)
	{
		set_display_off();
		for (y = 0; y < ind; y++)
		{
			word = ((x + y) < count)
			    ? next_arg(templist, &templist)
			    : NULL;
			add_alias(VAR_ALIAS, var[y], word);
		}
		set_display(display);
		x += ind;
		parse_line(NULL, todo, 
		    subargs ? subargs : empty_string(), 0, 0, 0);
	}
	set_display_off();
	for (y = 0; y < ind; y++)  {
		delete_alias(VAR_ALIAS, var[y]);
	}
	set_display(display);
	new_free(&placeholder);
}
Beispiel #12
0
/*
 * update_input: does varying amount of updating on the input line depending
 * upon the position of the cursor and the update flag.  If the cursor has
 * move toward one of the edge boundaries on the screen, update_cursor()
 * flips the input line to the next (previous) line of text. The update flag
 * may be: 
 *
 * NO_UPDATE - only do the above bounds checking. 
 *
 * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should
 * be. 
 *
 * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from
 * the cursor to the right edge of the screen is current (by redrawing it). 
 *
 * UPDATE_ALL - redraws the entire line 
 */
void update_input(int update)
{
    int old_start;
    static int co = 0, li = 0;
    char *ptr;
    int len, free_it = 1, cnt, ansi_count, max;

    char *prompt;

    cursor_to_input();

    if (current_screen->promptlist)
	prompt = current_screen->promptlist->prompt;
    else
	prompt = input_prompt;
    if (prompt) {
	if (update != NO_UPDATE) {
	    char *inp_ptr = NULL;
	    int args_used;

	    if (is_process(get_target_by_refnum(0))) {
		ptr = (char *) get_prompt_by_refnum(0);
		free_it = 0;
	    } else if (!get_int_var(DISPLAY_ANSI_VAR))
		ptr = expand_alias(stripansicodes(prompt), empty_str, &args_used, NULL);
	    else
		ptr = expand_alias(prompt, empty_str, &args_used, NULL);
	    if (*ptr && ((my_strnicmp(ptr, "Password:"******"Operator Password:"******"Server Password:", 16) == 0)))
		term_echo(0);
	    else
		term_echo(1);
	    len = strlen(ptr);
	    if (strncmp(ptr, current_screen->input_buffer, len) || !len) {
		malloc_strcpy(&inp_ptr, INPUT_BUFFER + MIN_POS);
		strmcpy(INPUT_BUFFER, ptr, INPUT_BUFFER_SIZE);
		THIS_POS += (len - MIN_POS);
		MIN_POS = strlen(ptr);
		ADD_TO_INPUT(inp_ptr);
		new_free(&inp_ptr);
		update = UPDATE_ALL;
	    }

	    if (free_it)
		new_free(&ptr);
	}
    } else
	term_echo(1);

    if ((li != term_rows) || (co != term_cols)) {
	/* resized? Keep it simple and reset everything */
	input_line = term_rows - 1;
	zone = term_cols - (WIDTH * 2) + 4;
	lower_mark = WIDTH;
	upper_mark = term_cols - WIDTH;
	cursor = current_screen->buffer_min_pos;
	current_screen->buffer_pos = current_screen->buffer_min_pos;
	str_start = 0;
	li = term_rows;
	co = term_cols;
    }
    old_start = str_start;
    ansi_count = count_ansi(current_screen->input_buffer, zone);
    if (old_ansi != ansi_count || current_screen->buffer_pos - ansi_count > zone) {
	lower_mark = WIDTH;
	upper_mark = term_cols - WIDTH;
	str_start = 0;
    }
    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);

    while ((current_screen->buffer_pos - ansi_count < lower_mark) && lower_mark > WIDTH) {
	upper_mark = lower_mark - ansi_count;
	lower_mark -= (zone + ansi_count);
	str_start -= (zone + ansi_count);
	if (str_start < zone) {
	    str_start = 0;
	    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);
	    lower_mark -= ansi_count;
	    upper_mark -= ansi_count;
	}
    }
    while (current_screen->buffer_pos - ansi_count >= upper_mark) {
	lower_mark = upper_mark + ansi_count;
	upper_mark += zone + ansi_count;
	str_start += zone + ansi_count;
	if (ansi_count)
	    ansi_count = 0;
    }

    /* we need to count ansi characters again, this time in the part of the string we are gonna display in a few moments */
    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);
    old_ansi = count_ansi(current_screen->input_buffer, zone);
    /* we need to substract number of ansi characters from cursor position since those are not visible, otherwise we'd display cursor
     * in wrong place */
    cursor = current_screen->buffer_pos - str_start - ansi_count;
    if ((old_start != str_start) || (update == UPDATE_ALL)) {
	term_move_cursor(0, input_line);
	if ((str_start == 0) && (MIN_POS > 0)) {
	    int echo;

	    echo = term_echo(1);
	    if (MIN_POS > (term_cols - WIDTH))
		len = term_cols - WIDTH - 1 /* + ansi_count */ ;
	    else
		len = MIN_POS;
	    cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), len);
	    term_echo(echo);
	    cnt += /* term_puts */ safe_puts(&(current_screen->input_buffer[
									       str_start + len]), term_cols - len + ansi_count);
	} else
	    cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), term_cols);
	term_clear_to_eol();
	term_move_cursor(cursor, input_line);
    } else if (update == UPDATE_FROM_CURSOR) {
	term_move_cursor(cursor, input_line);
	cnt = cursor;
	max = term_cols - (current_screen->buffer_pos - str_start) + ansi_count;
	if ((len = strlen(&(THIS_CHAR))) > max)
	    len = max;
	cnt += /* term_puts */ safe_puts(&(THIS_CHAR), len);
	term_clear_to_eol();
	term_move_cursor(cursor, input_line);
    } else if (update == UPDATE_JUST_CURSOR)
	term_move_cursor(cursor, input_line);
    term_flush();
}
Beispiel #13
0
/*
 * This just sucked beyond words.  I was always planning on rewriting this,
 * but the crecendo of complaints with regards to this just got to be too 
 * irritating, so i fixed it early.
 */
int	make_status (Window *window, int must_redraw)
{
	int	status_line;
	u_char	buffer	    [BIG_BUFFER_SIZE + 1];
	u_char	lhs_buffer  [BIG_BUFFER_SIZE + 1];
	u_char	rhs_buffer  [BIG_BUFFER_SIZE + 1];
	Char	*func_value [MAX_FUNCTIONS];
	u_char	*ptr;
	size_t	save_size;

	/* We do NOT redraw status bars for hidden windows */
	if (!window->screen || !status_updates_permitted)
		return -1;

	for (status_line = 0; status_line < window->status.double_status + 1; status_line++)
	{
		u_char	lhs_fillchar[6],
			rhs_fillchar[6],
			*fillchar = lhs_fillchar,
			*lhp = lhs_buffer,
			*rhp = rhs_buffer,
			*cp,
			*start_rhs = 0,
			*str;
		int	in_rhs = 0,
			pr_lhs = 0,
			pr_rhs = 0,
			line,
			*prc = &pr_lhs, 
			i;

		fillchar[0] = fillchar[1] = 0;

		/*
		 * If status line gets to one, then that means that
		 * window->double_status is not zero.  That means that
		 * the status line we're working on is STATUS2.
		 */
		if (status_line)
			line = 2;

		/*
		 * If status_line is zero, and window->double_status is
		 * not zero (double status line is on) then we're working
		 * on STATUS1.
		 */
		else if (window->status.double_status)
			line = 1;

		/*
		 * So status_line is zero and window->double_status is zero.
		 * So we're working on STATUS (0).
		 */
		else
			line = 0;


		/*
		 * Sanity check:  If the status format doesnt exist, dont do
		 * anything for it.
		 */
		if (!window->status.line[line].format)
			continue;

		/*
		 * Run each of the status-generating functions from the the
		 * status list.  Note that the retval of the functions is no
		 * longer malloc()ed.  This saves 40-some odd malloc/free sets
		 * each time the status bar is updated, which is non-trivial.
		 */
		for (i = 0; i < MAX_FUNCTIONS; i++)
		{
			if (window->screen == NULL)
				return -1;

			if (window->status.line[line].func[i] == NULL)
				panic("status callback null.  Window [%d], line [%d], function [%d]", window->refnum, line, i);
			func_value[i] = window->status.line[line].func[i]
				(window, window->status.line[line].map[i],
				 window->status.line[line].key[i]);
		}

		/*
		 * If the REVERSE_STATUS_LINE var is on, then put a reverse
		 * character in the first position (itll get translated to
		 * the tcap code in the output code.
		 */
		if (get_int_var(REVERSE_STATUS_LINE_VAR))
			*buffer = REV_TOG , str = buffer + 1;
		else
			str = buffer;

		/*
		 * Now press the status line into "buffer".  The magic about
		 * setting status_format is handled elsewhere.
		 */
		snprintf(str, BIG_BUFFER_SIZE - 1, window->status.line[line].format,
		    func_value[0], func_value[1], func_value[2], 
		    func_value[3], func_value[4], func_value[5],
		    func_value[6], func_value[7], func_value[8], func_value[9],
		    func_value[10], func_value[11], func_value[12],
		    func_value[13], func_value[14], func_value[15],
		    func_value[16], func_value[17], func_value[18],
		    func_value[19], func_value[20], func_value[21],
		    func_value[22], func_value[23], func_value[24],
		    func_value[25], func_value[26], func_value[27],
		    func_value[28], func_value[29], func_value[30],
		    func_value[31], func_value[32], func_value[33],
		    func_value[34], func_value[35], func_value[36], 
		    func_value[37], func_value[38], func_value[39]); 

		/*
		 * If the user wants us to, pass the status bar through the
		 * expander to pick any variables/function calls.
		 * This is horribly expensive, but what do i care if you
		 * want to waste cpu cycles? ;-)
		 */
		if (get_int_var(STATUS_DOES_EXPANDOS_VAR))
		{
			int  af = 0;
			int  old_fs = from_server;
			Window *old = current_window;
			int	owd = window_display;

			current_window = window;
			from_server = current_window->server;
			window_display = 0;
			str = expand_alias(buffer, empty_string, &af, NULL);
			window_display = owd;
			from_server = old_fs;
			current_window = old;
			strlcpy(buffer, str, sizeof buffer);
			new_free(&str);
		}


		/*
		 * This converts away any ansi codes in the status line
		 * in accordance with the currenet settings.  This leaves us
		 * with nothing but logical characters, which are then easy
		 * to count. :-)
		 */
		str = normalize_string(buffer, 3);

		/*
		 * Count out the characters.
		 * Walk the entire string, looking for nonprintable
		 * characters.  We count all the printable characters
		 * on both sides of the %> tag.
		 */
		ptr = str;
		cp = lhp;
		lhs_buffer[0] = rhs_buffer[0] = 0;

		while (*ptr)
		{
			/*
			 * The FIRST such %> tag is used.
			 * Using multiple %>s is bogus.
			 */
			if (*ptr == '\f' && start_rhs == NULL)
			{
				ptr++;
				start_rhs = ptr;
				fillchar = rhs_fillchar;
				in_rhs = 1;
				*cp = 0;
				cp = rhp;
				prc = &pr_rhs;
			}

                        /*
                         * Skip over attribute changes, not useful.
                         */
                        else if (*ptr == '\006')
                        {
                                /* Copy the next 5 values */
                                *cp++ = *ptr++;
                                *cp++ = *ptr++;
                                *cp++ = *ptr++;
                                *cp++ = *ptr++;
                                *cp++ = *ptr++;
                        }

			/*
			 * XXXXX This is a bletcherous hack.
			 * If i knew what was good for me id not do this.
			 */
			else if (*ptr == 9)	/* TAB */
			{
				fillchar[0] = ' ';
				fillchar[1] = 0;
				do
					*cp++ = ' ';
				while (++(*prc) % 8);
				ptr++;
			}

			/*
			 * So it is a printable character.
			 */
			else
			{
				*prc += 1;
				fillchar[0] = *cp++ = *ptr++;
				fillchar[1] = 0;
			}

			/*
			 * Dont allow more than CO printable characters
			 */
			if (pr_lhs + pr_rhs >= window->screen->co)
			{
				*cp = 0;
				break;
			}
		}
		*cp = 0;

		/* What will we be filling with? */
		if (get_int_var(STATUS_NO_REPEAT_VAR))
		{
			lhs_fillchar[0] = ' ';
			lhs_fillchar[1] = 0;
			rhs_fillchar[0] = ' ';
			rhs_fillchar[1] = 0;
		}

		/*
		 * Now if we have a rhs, then we have to adjust it.
		 */
		if (start_rhs)
		{
			int numf = 0;

			numf = window->screen->co - pr_lhs - pr_rhs -1;
			while (numf-- >= 0)
				strlcat(lhs_buffer, lhs_fillchar, 
						sizeof lhs_buffer);
		}

		/*
		 * No rhs?  If the user wants us to pad it out, do so.
		 */
		else if (get_int_var(FULL_STATUS_LINE_VAR))
		{
			int chars = window->screen->co - pr_lhs - 1;

			while (chars-- >= 0)
				strlcat(lhs_buffer, lhs_fillchar, 
						sizeof lhs_buffer);
		}

		save_size = strlen(all_off());
		strlcpy(buffer, lhs_buffer, sizeof buffer - save_size);
		strlcat(buffer, rhs_buffer, sizeof buffer - save_size);
		strlcat(buffer, all_off(), sizeof buffer);
		new_free(&str);

		/*
		 * Ends up that BitchX always throws this hook and
		 * people seem to like having this thrown in standard
		 * mode, so i'll go along with that.
		 */
		do_hook(STATUS_UPDATE_LIST, "%d %d %s", 
			window->refnum, 
			status_line, 
			buffer);

		if (dumb_mode || !foreground)
			continue;

		/*
		 * Update the status line on the screen.
		 * First check to see if it has changed
		 * Remember this is only done in full screen mode.
		 */
		if (must_redraw || !window->status.line[status_line].result ||
			strcmp(buffer, window->status.line[status_line].result))
		{
			/*
			 * Roll the new back onto the old
			 */
			malloc_strcpy(&window->status.line[status_line].result,
					buffer);

			/*
			 * Output the status line to the screen
			 */
			output_screen = window->screen;
			term_move_cursor(0, window->bottom + status_line);
			output_with_count(buffer, 1, 1);
			cursor_in_display(window);
		}
	}

	cursor_to_input();
	return 0;
}