Пример #1
0
/* Set default format keys for a window pane. */
void
format_window_pane(struct format_tree *ft, struct window_pane *wp)
{
	struct grid		*gd = wp->base.grid;
	struct grid_line	*gl;
	unsigned long long	 size;
	u_int			 i;
	u_int			 idx;

	size = 0;
	for (i = 0; i < gd->hsize; i++) {
		gl = &gd->linedata[i];
		size += gl->cellsize * sizeof *gl->celldata;
		size += gl->utf8size * sizeof *gl->utf8data;
	}
	size += gd->hsize * sizeof *gd->linedata;

	if (window_pane_index(wp, &idx) != 0)
		fatalx("index not found");

	format_add(ft, "pane_width", "%u", wp->sx);
	format_add(ft, "pane_height", "%u", wp->sy);
	format_add(ft, "pane_title", "%s", wp->base.title);
	format_add(ft, "pane_index", "%u", idx);
	format_add(ft, "history_size", "%u", gd->hsize);
	format_add(ft, "history_limit", "%u", gd->hlimit);
	format_add(ft, "history_bytes", "%llu", size);
	format_add(ft, "pane_id", "%%%u", wp->id);
	format_add(ft, "pane_active", "%d", wp == wp->window->active);
	format_add(ft, "pane_dead", "%d", wp->fd == -1);
	if (wp->cmd != NULL)
		format_add(ft, "pane_start_command", "%s", wp->cmd);
	if (wp->cwd != NULL)
		format_add(ft, "pane_start_path", "%s", wp->cwd);
	format_add(ft, "pane_current_path", "%s", get_proc_cwd(wp->pid));
	format_add(ft, "pane_pid", "%ld", (long) wp->pid);
	format_add(ft, "pane_tty", "%s", wp->tty);
}
void gfire_process_list_update(gfire_process_list *p_list)
{
	if(!p_list)
		return;

#ifdef DEBUG_VERBOSE
	purple_debug_info("gfire", "gfire_process_list_update: TRACE\n");
#endif // DEBUG_VERBOSE

	gfire_process_list_clear(p_list);

	DIR *proc = opendir("/proc");
	struct dirent *proc_dirent;

	if(!proc)
	{
		purple_debug_error("gfire", "gfire_process_list_update: opendir() failed\n");
		return;
	}

	while((proc_dirent = readdir(proc)))
	{
#ifdef DEBUG_VERBOSE
		purple_debug_info("gfire", "gfire_process_list_update: checking: \"%s\"\n", proc_dirent->d_name);
#endif // DEBUG_VERBOSE

		// Check if we got a valid process dir
		gboolean dir_valid = TRUE;
		int i = 0;
		for(; i < strlen(proc_dirent->d_name); i++)
		{
			if(!g_ascii_isdigit(proc_dirent->d_name[i]))
			{
				dir_valid = FALSE;
				break;
			}
		}
		if(!dir_valid)
		{
#ifdef DEBUG_VERBOSE
			purple_debug_error("gfire", "gfire_process_list_update: \"%s\" is no valid process directory\n",
							   proc_dirent->d_name);
#endif // DEBUG_VERBOSE
			continue;
		}

		gchar *proc_path = g_strdup_printf("/proc/%s", proc_dirent->d_name);

		// Check if it is a directory and owned by the current user
		struct stat process_stat;
		if(stat(proc_path, &process_stat) == -1)
		{
#ifdef DEBUG
			purple_debug_error("gfire", "gfire_process_list_update: stat(\"%s\") failed\n", proc_path);
#endif // DEBUG
			g_free(proc_path);
			continue;
		}

		// Don't check current process if not owned
		if(geteuid() != process_stat.st_uid || !S_ISDIR(process_stat.st_mode))
		{
#ifdef DEBUG_VERBOSE
			purple_debug_error("gfire", "gfire_process_list_update: \"%s\" is not owned by current user\n",
							   proc_dirent->d_name);
#endif // DEBUG_VERBOSE
			g_free(proc_path);
			continue;
		}

		// Get process id
		guint32 process_id;
		sscanf(proc_dirent->d_name, "%u", &process_id);

		// Get process exe
		const gchar *process_exe = get_proc_exe(proc_path);
		if(!process_exe)
		{
			g_free(proc_path);
			continue;
		}

		// Get process' command line
		gchar *process_cmd = NULL;
		gchar *process_args = NULL;
		get_proc_cmdline(&process_cmd, &process_args, proc_path);

		gchar *process_real_exe = NULL;
		// Different behaviour for Wine processes
		if(strstr(process_exe, "wine-preloader"))
		{
#ifdef DEBUG_VERBOSE
			purple_debug_misc("gfire", "gfire_process_list_update: WINE game! Starting WINE based detection...\n");
#endif // DEBUG_VERBOSE

			// Get Wine prefix for winepath
			GHashTable *environ = get_environ(proc_path);
			const gchar *prefix = NULL;
			if(environ)
				prefix = g_hash_table_lookup(environ, "WINEPREFIX");

#ifdef DEBUG_VERBOSE
			if(prefix)
				purple_debug_misc("gfire", "gfire_process_list_update: WINEPREFIX=\"%s\"\n", prefix);
			else
				purple_debug_misc("gfire", "gfire_process_list_update: no WINEPREFIX set\n");
#endif // DEBUG_VERBOSE

			// Get process name using winepath
			const gchar *real_path = get_winepath(prefix, process_cmd);

			// Some error occured
			if(!real_path)
			{
				g_hash_table_destroy(environ);
				g_free(process_cmd);
				g_free(process_args);
				g_free(proc_path);
				continue;
			}

#ifdef DEBUG_VERBOSE
			purple_debug_misc("gfire", "gfire_process_list_update: Canonicalizing path: \"%s\"\n", real_path);
#endif // DEBUG_VERBOSE

			// Get the physical path
#ifdef GF_OS_BSD
			gchar phys_path_buf[PATH_MAX];
			gchar *phys_path = realpath(real_path, phys_path_buf);
#else
			gchar *phys_path = canonicalize_file_name(real_path);
#endif // GF_OS_BSD

			// We might have only the executables name, try with adding the CWD
			if(!phys_path)
			{
#ifdef DEBUG_VERBOSE
				purple_debug_misc("gfire", "gfire_process_list_update: No such file :'( Trying to prepend the CWD...\n");
#endif // DEBUG_VERBOSE
				const gchar *cwd = get_proc_cwd(environ, proc_path);
				// Okay, we really can't do anything about it
				if(!cwd)
				{
					g_hash_table_destroy(environ);
					g_free(process_cmd);
					g_free(process_args);
					g_free(proc_path);
					continue;
				}

				gchar *full_cmd = g_strdup_printf("%s/%s", cwd, process_cmd);
				g_free(process_cmd);

#ifdef DEBUG_VERBOSE
				purple_debug_misc("gfire", "gfire_process_list_update: Trying the following path: \"%s\"\n", full_cmd);
#endif // DEBUG_VERBOSE

				real_path = get_winepath(prefix, full_cmd);
				g_free(full_cmd);
				g_hash_table_destroy(environ);

				// Again some error :'(
				if(!real_path)
				{
					g_free(process_args);
					g_free(proc_path);
					continue;
				}

#ifdef DEBUG_VERBOSE
			purple_debug_misc("gfire", "gfire_process_list_update: Canonicalizing path: \"%s\"\n", real_path);
#endif // DEBUG_VERBOSE

				// Try again
#ifdef GF_OS_BSD
				phys_path = realpath(real_path, phys_path_buf);
#else
				phys_path = canonicalize_file_name(real_path);
#endif // GF_OS_BSD

				// Okay...we lost
				if(!phys_path)
				{
#ifdef DEBUG_VERBOSE
					purple_debug_error("gfire", "gfire_process_list_update: No such file, we give up...\n");
#endif // DEBUG_VERBOSE
					g_free(process_args);
					g_free(proc_path);
					continue;
				}
			}
			else
			{
				g_hash_table_destroy(environ);
				g_free(process_cmd);
			}

			process_real_exe = phys_path;
		}
		else
		{
			g_free(process_cmd);
			process_real_exe = g_strdup(process_exe);
		}

		// Add process to list
		process_info *info = gfire_process_info_new(process_real_exe, process_id, process_args);
#ifdef DEBUG_VERBOSE
		purple_debug_info("gfire", "gfire_process_list_update: added process: pid=%u exe=\"%s\" args=\"%s\"\n",
						  process_id, process_real_exe, process_args);
#endif // DEBUG_VERBOSE
		p_list->processes = g_list_append(p_list->processes, info);

#ifndef GF_OS_BSD
		g_free(process_real_exe);
#endif // !GF_OS_BSD
		g_free(process_args);
		g_free(proc_path);
	}

	closedir(proc);
}