mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
Sync from OpenBSD.
This commit is contained in:
		
							
								
								
									
										7
									
								
								cfg.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								cfg.c
									
									
									
									
									
								
							| @@ -36,7 +36,8 @@ void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); | |||||||
|  |  | ||||||
| char			*cfg_cause; | char			*cfg_cause; | ||||||
| int			 cfg_finished; | int			 cfg_finished; | ||||||
| struct causelist	cfg_causes = ARRAY_INITIALIZER; | int	 		 cfg_references; | ||||||
|  | struct causelist	 cfg_causes; | ||||||
|  |  | ||||||
| /* ARGSUSED */ | /* ARGSUSED */ | ||||||
| void printflike2 | void printflike2 | ||||||
| @@ -89,6 +90,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) | |||||||
| 	} | 	} | ||||||
| 	n = 0; | 	n = 0; | ||||||
|  |  | ||||||
|  | 	cfg_references++; | ||||||
|  |  | ||||||
| 	line = NULL; | 	line = NULL; | ||||||
| 	retval = CMD_RETURN_NORMAL; | 	retval = CMD_RETURN_NORMAL; | ||||||
| 	while ((buf = fgetln(f, &len))) { | 	while ((buf = fgetln(f, &len))) { | ||||||
| @@ -171,6 +174,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) | |||||||
| 	} | 	} | ||||||
| 	fclose(f); | 	fclose(f); | ||||||
|  |  | ||||||
|  | 	cfg_references--; | ||||||
|  |  | ||||||
| 	return (retval); | 	return (retval); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,13 +30,15 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| enum cmd_retval	 cmd_run_shell_exec(struct cmd *, struct cmd_ctx *); | enum cmd_retval	 cmd_run_shell_exec(struct cmd *, struct cmd_ctx *); | ||||||
|  |  | ||||||
| void	cmd_run_shell_callback(struct job *); | void	cmd_run_shell_callback(struct job *); | ||||||
| void	cmd_run_shell_free(void *); | void	cmd_run_shell_free(void *); | ||||||
|  | void	cmd_run_shell_print(struct job *, const char *); | ||||||
|  |  | ||||||
| const struct cmd_entry cmd_run_shell_entry = { | const struct cmd_entry cmd_run_shell_entry = { | ||||||
| 	"run-shell", "run", | 	"run-shell", "run", | ||||||
| 	"", 1, 1, | 	"t:", 1, 1, | ||||||
| 	"command", | 	CMD_TARGET_PANE_USAGE " command", | ||||||
| 	0, | 	0, | ||||||
| 	NULL, | 	NULL, | ||||||
| 	NULL, | 	NULL, | ||||||
| @@ -46,17 +48,42 @@ const struct cmd_entry cmd_run_shell_entry = { | |||||||
| struct cmd_run_shell_data { | struct cmd_run_shell_data { | ||||||
| 	char		*cmd; | 	char		*cmd; | ||||||
| 	struct cmd_ctx	 ctx; | 	struct cmd_ctx	 ctx; | ||||||
|  | 	u_int		 wp_id; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | void | ||||||
|  | cmd_run_shell_print(struct job *job, const char *msg) | ||||||
|  | { | ||||||
|  | 	struct cmd_run_shell_data	*cdata = job->data; | ||||||
|  | 	struct cmd_ctx			*ctx = &cdata->ctx; | ||||||
|  | 	struct window_pane		*wp; | ||||||
|  |  | ||||||
|  | 	wp = window_pane_find_by_id(cdata->wp_id); | ||||||
|  | 	if (wp == NULL) { | ||||||
|  | 		ctx->print(ctx, "%s", msg); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (window_pane_set_mode(wp, &window_copy_mode) == 0) | ||||||
|  | 		window_copy_init_for_output(wp); | ||||||
|  | 	if (wp->mode == &window_copy_mode) | ||||||
|  | 		window_copy_add(wp, "%s", msg); | ||||||
|  | } | ||||||
|  |  | ||||||
| enum cmd_retval | enum cmd_retval | ||||||
| cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx) | cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||||
| { | { | ||||||
| 	struct args			*args = self->args; | 	struct args			*args = self->args; | ||||||
| 	struct cmd_run_shell_data	*cdata; | 	struct cmd_run_shell_data	*cdata; | ||||||
| 	const char			*shellcmd = args->argv[0]; | 	const char			*shellcmd = args->argv[0]; | ||||||
|  | 	struct window_pane		*wp; | ||||||
|  |  | ||||||
|  | 	if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) | ||||||
|  | 		return (CMD_RETURN_ERROR); | ||||||
|  |  | ||||||
| 	cdata = xmalloc(sizeof *cdata); | 	cdata = xmalloc(sizeof *cdata); | ||||||
| 	cdata->cmd = xstrdup(args->argv[0]); | 	cdata->cmd = xstrdup(args->argv[0]); | ||||||
|  | 	cdata->wp_id = wp->id; | ||||||
| 	memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); | 	memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); | ||||||
|  |  | ||||||
| 	if (ctx->cmdclient != NULL) | 	if (ctx->cmdclient != NULL) | ||||||
| @@ -87,7 +114,7 @@ cmd_run_shell_callback(struct job *job) | |||||||
| 	lines = 0; | 	lines = 0; | ||||||
| 	do { | 	do { | ||||||
| 		if ((line = evbuffer_readline(job->event->input)) != NULL) { | 		if ((line = evbuffer_readline(job->event->input)) != NULL) { | ||||||
| 			ctx->print(ctx, "%s", line); | 			cmd_run_shell_print (job, line); | ||||||
| 			lines++; | 			lines++; | ||||||
| 		} | 		} | ||||||
| 	} while (line != NULL); | 	} while (line != NULL); | ||||||
| @@ -98,7 +125,7 @@ cmd_run_shell_callback(struct job *job) | |||||||
| 		memcpy(line, EVBUFFER_DATA(job->event->input), size); | 		memcpy(line, EVBUFFER_DATA(job->event->input), size); | ||||||
| 		line[size] = '\0'; | 		line[size] = '\0'; | ||||||
|  |  | ||||||
| 		ctx->print(ctx, "%s", line); | 		cmd_run_shell_print(job, line); | ||||||
| 		lines++; | 		lines++; | ||||||
|  |  | ||||||
| 		free(line); | 		free(line); | ||||||
| @@ -115,10 +142,10 @@ cmd_run_shell_callback(struct job *job) | |||||||
| 		xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); | 		xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); | ||||||
| 	} | 	} | ||||||
| 	if (msg != NULL) { | 	if (msg != NULL) { | ||||||
| 		if (lines != 0) | 		if (lines == 0) | ||||||
| 			ctx->print(ctx, "%s", msg); |  | ||||||
| 		else |  | ||||||
| 			ctx->info(ctx, "%s", msg); | 			ctx->info(ctx, "%s", msg); | ||||||
|  | 		else | ||||||
|  | 			cmd_run_shell_print(job, msg); | ||||||
| 		free(msg); | 		free(msg); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -42,35 +42,32 @@ enum cmd_retval | |||||||
| cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx) | cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||||
| { | { | ||||||
| 	struct args		*args = self->args; | 	struct args		*args = self->args; | ||||||
| 	struct causelist	 causes; |  | ||||||
| 	char			*cause; |  | ||||||
| 	struct window_pane	*wp; |  | ||||||
| 	int			 retval; | 	int			 retval; | ||||||
| 	u_int			 i; | 	u_int			 i; | ||||||
|  | 	char			*cause; | ||||||
|  |  | ||||||
| 	ARRAY_INIT(&causes); | 	retval = load_cfg(args->argv[0], ctx, &cfg_causes); | ||||||
|  |  | ||||||
| 	retval = load_cfg(args->argv[0], ctx, &causes); | 	/* | ||||||
| 	if (ARRAY_EMPTY(&causes)) | 	 * If the context for the cmdclient came from tmux's configuration | ||||||
|  | 	 * file, then return the status of this command now, regardless of the | ||||||
|  | 	 * error condition. Any errors from parsing a configuration file at | ||||||
|  | 	 * startup will be handled for us by the server. | ||||||
|  | 	 */ | ||||||
|  | 	if (cfg_references > 0 || | ||||||
|  | 	    (ctx->curclient == NULL && ctx->cmdclient == NULL)) | ||||||
| 		return (retval); | 		return (retval); | ||||||
|  |  | ||||||
| 	if (retval == 1 && !RB_EMPTY(&sessions) && ctx->cmdclient != NULL) { | 	/* | ||||||
| 		wp = RB_MIN(sessions, &sessions)->curw->window->active; | 	 * We were called from the command-line in which case print the errors | ||||||
| 		window_pane_set_mode(wp, &window_copy_mode); | 	 * gathered here directly. | ||||||
| 		window_copy_init_for_output(wp); | 	 */ | ||||||
| 		for (i = 0; i < ARRAY_LENGTH(&causes); i++) { | 	for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) { | ||||||
| 			cause = ARRAY_ITEM(&causes, i); | 		cause = ARRAY_ITEM(&cfg_causes, i); | ||||||
| 			window_copy_add(wp, "%s", cause); |  | ||||||
| 			free(cause); |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		for (i = 0; i < ARRAY_LENGTH(&causes); i++) { |  | ||||||
| 			cause = ARRAY_ITEM(&causes, i); |  | ||||||
| 		ctx->print(ctx, "%s", cause); | 		ctx->print(ctx, "%s", cause); | ||||||
| 		free(cause); | 		free(cause); | ||||||
| 	} | 	} | ||||||
| 	} | 	ARRAY_FREE(&cfg_causes); | ||||||
| 	ARRAY_FREE(&causes); |  | ||||||
|  |  | ||||||
| 	return (retval); | 	return (retval); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								cmd.c
									
									
									
									
									
								
							| @@ -115,6 +115,7 @@ const struct cmd_entry *cmd_table[] = { | |||||||
| 	NULL | 	NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | int		 cmd_session_better(struct session *, struct session *, int); | ||||||
| struct session	*cmd_choose_session_list(struct sessionslist *); | struct session	*cmd_choose_session_list(struct sessionslist *); | ||||||
| struct session	*cmd_choose_session(int); | struct session	*cmd_choose_session(int); | ||||||
| struct client	*cmd_choose_client(struct clients *); | struct client	*cmd_choose_client(struct clients *); | ||||||
| @@ -370,6 +371,24 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached) | |||||||
| 	return (cmd_choose_session(prefer_unattached)); | 	return (cmd_choose_session(prefer_unattached)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Is this session better? */ | ||||||
|  | int | ||||||
|  | cmd_session_better(struct session *s, struct session *best, | ||||||
|  |     int prefer_unattached) | ||||||
|  | { | ||||||
|  | 	if (best == NULL) | ||||||
|  | 		return 1; | ||||||
|  | 	if (prefer_unattached) { | ||||||
|  | 		if (!(best->flags & SESSION_UNATTACHED) && | ||||||
|  | 		    (s->flags & SESSION_UNATTACHED)) | ||||||
|  | 			return 1; | ||||||
|  | 		else if ((best->flags & SESSION_UNATTACHED) && | ||||||
|  | 		    !(s->flags & SESSION_UNATTACHED)) | ||||||
|  | 			return 0; | ||||||
|  | 	} | ||||||
|  | 	return (timercmp(&s->activity_time, &best->activity_time, >)); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Find the most recently used session, preferring unattached if the flag is |  * Find the most recently used session, preferring unattached if the flag is | ||||||
|  * set. |  * set. | ||||||
| @@ -377,21 +396,14 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached) | |||||||
| struct session * | struct session * | ||||||
| cmd_choose_session(int prefer_unattached) | cmd_choose_session(int prefer_unattached) | ||||||
| { | { | ||||||
| 	struct session	*s, *sbest; | 	struct session	*s, *best; | ||||||
| 	struct timeval	*tv = NULL; |  | ||||||
|  |  | ||||||
| 	sbest = NULL; | 	best = NULL; | ||||||
| 	RB_FOREACH(s, sessions, &sessions) { | 	RB_FOREACH(s, sessions, &sessions) { | ||||||
| 		if (tv == NULL || timercmp(&s->activity_time, tv, >) || | 		if (cmd_session_better(s, best, prefer_unattached)) | ||||||
| 		    (prefer_unattached && | 			best = s; | ||||||
| 		    !(sbest->flags & SESSION_UNATTACHED) && |  | ||||||
| 		    (s->flags & SESSION_UNATTACHED))) { |  | ||||||
| 			sbest = s; |  | ||||||
| 			tv = &s->activity_time; |  | ||||||
| 	} | 	} | ||||||
| 	} | 	return (best); | ||||||
|  |  | ||||||
| 	return (sbest); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Find the most recently used session from a list. */ | /* Find the most recently used session from a list. */ | ||||||
|   | |||||||
| @@ -685,6 +685,21 @@ const struct options_table_entry window_options_table[] = { | |||||||
| 	  .default_str = "#I:#W#F" | 	  .default_str = "#I:#W#F" | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|  | 	{ .name = "window-status-last-attr", | ||||||
|  | 	  .type = OPTIONS_TABLE_ATTRIBUTES, | ||||||
|  | 	  .default_num = 0 | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	{ .name = "window-status-last-bg", | ||||||
|  | 	  .type = OPTIONS_TABLE_COLOUR, | ||||||
|  | 	  .default_num = 8 | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	{ .name = "window-status-last-fg", | ||||||
|  | 	  .type = OPTIONS_TABLE_COLOUR, | ||||||
|  | 	  .default_num = 8 | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	{ .name = "window-status-fg", | 	{ .name = "window-status-fg", | ||||||
| 	  .type = OPTIONS_TABLE_COLOUR, | 	  .type = OPTIONS_TABLE_COLOUR, | ||||||
| 	  .default_num = 8 | 	  .default_num = 8 | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								status.c
									
									
									
									
									
								
							| @@ -705,6 +705,17 @@ status_print( | |||||||
| 			gc->attr = attr; | 			gc->attr = attr; | ||||||
| 		fmt = options_get_string(oo, "window-status-current-format"); | 		fmt = options_get_string(oo, "window-status-current-format"); | ||||||
| 	} | 	} | ||||||
|  | 	if (wl == TAILQ_FIRST(&s->lastw)) { | ||||||
|  | 		fg = options_get_number(oo, "window-status-last-fg"); | ||||||
|  | 		if (fg != 8) | ||||||
|  | 			colour_set_fg(gc, fg); | ||||||
|  | 		bg = options_get_number(oo, "window-status-last-bg"); | ||||||
|  | 		if (bg != 8) | ||||||
|  | 			colour_set_bg(gc, bg); | ||||||
|  | 		attr = options_get_number(oo, "window-status-last-attr"); | ||||||
|  | 		if (attr != 0) | ||||||
|  | 			gc->attr = attr; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (wl->flags & WINLINK_BELL) { | 	if (wl->flags & WINLINK_BELL) { | ||||||
| 		fg = options_get_number(oo, "window-status-bell-fg"); | 		fg = options_get_number(oo, "window-status-bell-fg"); | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -2827,6 +2827,15 @@ Like | |||||||
| .Ar window-status-format , | .Ar window-status-format , | ||||||
| but is the format used when the window is the current window. | but is the format used when the window is the current window. | ||||||
| .Pp | .Pp | ||||||
|  | .It Ic window-status-last-attr Ar attributes | ||||||
|  | Set status line attributes for the last active window. | ||||||
|  | .Pp | ||||||
|  | .It Ic window-status-last-bg Ar colour | ||||||
|  | Set status line background colour for the last active window. | ||||||
|  | .Pp | ||||||
|  | .It Ic window-status-last-fg Ar colour | ||||||
|  | Set status line foreground colour for the last active window. | ||||||
|  | .Pp | ||||||
| .It Ic window-status-fg Ar colour | .It Ic window-status-fg Ar colour | ||||||
| Set status line foreground colour for a single window. | Set status line foreground colour for a single window. | ||||||
| .Pp | .Pp | ||||||
| @@ -3389,12 +3398,18 @@ otherwise. | |||||||
| Lock each client individually by running the command specified by the | Lock each client individually by running the command specified by the | ||||||
| .Ic lock-command | .Ic lock-command | ||||||
| option. | option. | ||||||
| .It Ic run-shell Ar shell-command | .It Xo Ic run-shell | ||||||
|  | .Op Fl t Ar target-pane | ||||||
|  | .Ar shell-command | ||||||
|  | .Xc | ||||||
| .D1 (alias: Ic run ) | .D1 (alias: Ic run ) | ||||||
| Execute | Execute | ||||||
| .Ar shell-command | .Ar shell-command | ||||||
| in the background without creating a window. | in the background without creating a window. | ||||||
| After it finishes, any output to stdout is displayed in copy mode. | After it finishes, any output to stdout is displayed in copy mode (in the pane | ||||||
|  | specified by | ||||||
|  | .Fl t | ||||||
|  | or the current pane if omitted). | ||||||
| If the command doesn't return success, the exit status is also displayed. | If the command doesn't return success, the exit status is also displayed. | ||||||
| .It Ic server-info | .It Ic server-info | ||||||
| .D1 (alias: Ic info ) | .D1 (alias: Ic info ) | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								tmux.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								tmux.c
									
									
									
									
									
								
							| @@ -162,7 +162,7 @@ parseenvironment(void) | |||||||
| char * | char * | ||||||
| makesocketpath(const char *label) | makesocketpath(const char *label) | ||||||
| { | { | ||||||
| 	char		base[MAXPATHLEN], *path, *s; | 	char		base[MAXPATHLEN], realbase[MAXPATHLEN], *path, *s; | ||||||
| 	struct stat	sb; | 	struct stat	sb; | ||||||
| 	u_int		uid; | 	u_int		uid; | ||||||
|  |  | ||||||
| @@ -186,7 +186,10 @@ makesocketpath(const char *label) | |||||||
| 		return (NULL); | 		return (NULL); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	xasprintf(&path, "%s/%s", base, label); | 	if (realpath(base, realbase) == NULL) | ||||||
|  | 		strlcpy(realbase, base, sizeof realbase); | ||||||
|  |  | ||||||
|  | 	xasprintf(&path, "%s/%s", realbase, label); | ||||||
| 	return (path); | 	return (path); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -333,6 +336,8 @@ main(int argc, char **argv) | |||||||
| 	options_init(&global_w_options, NULL); | 	options_init(&global_w_options, NULL); | ||||||
| 	options_table_populate_tree(window_options_table, &global_w_options); | 	options_table_populate_tree(window_options_table, &global_w_options); | ||||||
|  |  | ||||||
|  | 	ARRAY_INIT(&cfg_causes); | ||||||
|  |  | ||||||
| 	/* Enable UTF-8 if the first client is on UTF-8 terminal. */ | 	/* Enable UTF-8 if the first client is on UTF-8 terminal. */ | ||||||
| 	if (flags & IDENTIFY_UTF8) { | 	if (flags & IDENTIFY_UTF8) { | ||||||
| 		options_set_number(&global_s_options, "status-utf8", 1); | 		options_set_number(&global_s_options, "status-utf8", 1); | ||||||
| @@ -390,7 +395,6 @@ main(int argc, char **argv) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	free(label); | 	free(label); | ||||||
| 	if (realpath(path, socket_path) == NULL) |  | ||||||
| 	strlcpy(socket_path, path, sizeof socket_path); | 	strlcpy(socket_path, path, sizeof socket_path); | ||||||
| 	free(path); | 	free(path); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -1513,6 +1513,7 @@ __dead void	 shell_exec(const char *, const char *); | |||||||
|  |  | ||||||
| /* cfg.c */ | /* cfg.c */ | ||||||
| extern int       cfg_finished; | extern int       cfg_finished; | ||||||
|  | extern int       cfg_references; | ||||||
| extern struct causelist cfg_causes; | extern struct causelist cfg_causes; | ||||||
| void printflike2 cfg_add_cause(struct causelist *, const char *, ...); | void printflike2 cfg_add_cause(struct causelist *, const char *, ...); | ||||||
| int		 load_cfg(const char *, struct cmd_ctx *, struct causelist *); | int		 load_cfg(const char *, struct cmd_ctx *, struct causelist *); | ||||||
|   | |||||||
| @@ -832,10 +832,10 @@ window_copy_mouse( | |||||||
| 	if (m->event == MOUSE_EVENT_WHEEL) { | 	if (m->event == MOUSE_EVENT_WHEEL) { | ||||||
| 		if (m->wheel == MOUSE_WHEEL_UP) { | 		if (m->wheel == MOUSE_WHEEL_UP) { | ||||||
| 			for (i = 0; i < 5; i++) | 			for (i = 0; i < 5; i++) | ||||||
| 				window_copy_cursor_up(wp, 0); | 				window_copy_cursor_up(wp, 1); | ||||||
| 		} else if (m->wheel == MOUSE_WHEEL_DOWN) { | 		} else if (m->wheel == MOUSE_WHEEL_DOWN) { | ||||||
| 			for (i = 0; i < 5; i++) | 			for (i = 0; i < 5; i++) | ||||||
| 				window_copy_cursor_down(wp, 0); | 				window_copy_cursor_down(wp, 1); | ||||||
| 			if (data->oy == 0) | 			if (data->oy == 0) | ||||||
| 				goto reset_mode; | 				goto reset_mode; | ||||||
| 		} | 		} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Thomas Adam
					Thomas Adam