Blame src/gtk-helpers/desktop-utils.c

Packit Service 779887
/*
Packit Service 779887
    Copyright (C) ABRT Team
Packit Service 779887
    Copyright (C) RedHat inc.
Packit Service 779887
Packit Service 779887
    This program is free software; you can redistribute it and/or modify
Packit Service 779887
    it under the terms of the GNU General Public License as published by
Packit Service 779887
    the Free Software Foundation; either version 2 of the License, or
Packit Service 779887
    (at your option) any later version.
Packit Service 779887
Packit Service 779887
    This program is distributed in the hope that it will be useful,
Packit Service 779887
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 779887
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 779887
    GNU General Public License for more details.
Packit Service 779887
Packit Service 779887
    You should have received a copy of the GNU General Public License along
Packit Service 779887
    with this program; if not, write to the Free Software Foundation, Inc.,
Packit Service 779887
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit Service 779887
*/
Packit Service 779887
Packit Service 779887
#include <gio/gdesktopappinfo.h>
Packit Service 779887
#include <string.h>
Packit Service 779887
#include <stdlib.h>
Packit Service 779887
#include "problem_utils.h"
Packit Service 779887
Packit Service 779887
char *
Packit Service 779887
problem_get_argv0 (const char *cmdline)
Packit Service 779887
{
Packit Service 779887
    char *ret;
Packit Service 779887
    char **items;
Packit Service 779887
Packit Service 779887
    items = g_strsplit (cmdline, " ", -1);
Packit Service 779887
    ret = g_strdup (items[0]);
Packit Service 779887
    g_strfreev (items);
Packit Service 779887
    return ret;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
static void
Packit Service 779887
remove_quotes (char **args)
Packit Service 779887
{
Packit Service 779887
    guint i;
Packit Service 779887
Packit Service 779887
    for (i = 0; args[i] != NULL; i++)
Packit Service 779887
    {
Packit Service 779887
        char **items;
Packit Service 779887
        char *str;
Packit Service 779887
Packit Service 779887
        items = g_strsplit (args[i], "\"", -1);
Packit Service 779887
        str = g_strjoinv (NULL, items);
Packit Service 779887
        g_strfreev (items);
Packit Service 779887
Packit Service 779887
        g_free (args[i]);
Packit Service 779887
        args[i] = str;
Packit Service 779887
    }
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
static gboolean
Packit Service 779887
_is_it_file_arg (const char *s)
Packit Service 779887
{
Packit Service 779887
    if (s == NULL)
Packit Service 779887
        return FALSE;
Packit Service 779887
    if (*s == '-')
Packit Service 779887
        return FALSE;
Packit Service 779887
    return TRUE;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
static gboolean
Packit Service 779887
_is_it_url (const char *s)
Packit Service 779887
{
Packit Service 779887
    if (s == NULL)
Packit Service 779887
        return FALSE;
Packit Service 779887
    if (strstr (s, "://"))
Packit Service 779887
        return TRUE;
Packit Service 779887
    return FALSE;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
static gboolean
Packit Service 779887
compare_args (char **cmdargs,
Packit Service 779887
          char **dcmdargs)
Packit Service 779887
{
Packit Service 779887
    guint cargi, dargi;
Packit Service 779887
    gboolean ret;
Packit Service 779887
Packit Service 779887
    /* Start at 1, as we already compared the binaries */
Packit Service 779887
    cargi = dargi = 1;
Packit Service 779887
    while (dargi < g_strv_length(dcmdargs))
Packit Service 779887
    {
Packit Service 779887
        if (g_str_equal (dcmdargs[dargi], "%f"))
Packit Service 779887
        {
Packit Service 779887
            if (cargi >= g_strv_length(cmdargs) || _is_it_file_arg(cmdargs[cargi]))
Packit Service 779887
            {
Packit Service 779887
                return FALSE;
Packit Service 779887
            } else {
Packit Service 779887
                dargi++;
Packit Service 779887
                cargi++;
Packit Service 779887
            }
Packit Service 779887
        }
Packit Service 779887
        else if (g_str_equal (dcmdargs[dargi], "%F"))
Packit Service 779887
        {
Packit Service 779887
            if (cargi >= g_strv_length(cmdargs) || _is_it_file_arg(cmdargs[cargi]))
Packit Service 779887
                dargi++;
Packit Service 779887
            else
Packit Service 779887
                cargi++;
Packit Service 779887
        }
Packit Service 779887
        else if (g_str_equal (dcmdargs[dargi], "%u"))
Packit Service 779887
        {
Packit Service 779887
            if (cargi >= g_strv_length(cmdargs) ||
Packit Service 779887
                (!_is_it_url(cmdargs[cargi]) && !_is_it_file_arg(cmdargs[cargi])))
Packit Service 779887
            {
Packit Service 779887
                return FALSE;
Packit Service 779887
            }
Packit Service 779887
            else
Packit Service 779887
            {
Packit Service 779887
                cargi++;
Packit Service 779887
                dargi++;
Packit Service 779887
            }
Packit Service 779887
        }
Packit Service 779887
        else if (g_str_equal (dcmdargs[dargi], "%U"))
Packit Service 779887
        {
Packit Service 779887
            if (cargi >= g_strv_length(cmdargs) ||
Packit Service 779887
                (!_is_it_url(cmdargs[cargi]) && !_is_it_file_arg(cmdargs[cargi])))
Packit Service 779887
            {
Packit Service 779887
                dargi++;
Packit Service 779887
            }
Packit Service 779887
            else
Packit Service 779887
            {
Packit Service 779887
                cargi++;
Packit Service 779887
            }
Packit Service 779887
        }
Packit Service 779887
        else if (g_str_equal (dcmdargs[dargi], "%i"))
Packit Service 779887
        {
Packit Service 779887
            //logging.debug("Unsupported Exec key %i");
Packit Service 779887
            dargi++;
Packit Service 779887
            cargi += 2;
Packit Service 779887
        }
Packit Service 779887
        else if (g_str_equal (dcmdargs[dargi], "%c") ||
Packit Service 779887
                 g_str_equal (dcmdargs[dargi], "%k"))
Packit Service 779887
        {
Packit Service 779887
            //logging.debug("Unsupported Exec key %s", dcmdargs[dargi]);
Packit Service 779887
            dargi++;
Packit Service 779887
            cargi++;
Packit Service 779887
        }
Packit Service 779887
        else
Packit Service 779887
        {
Packit Service 779887
            if (cargi >= g_strv_length(cmdargs) || !g_str_equal (dcmdargs[dargi], cmdargs[cargi]))
Packit Service 779887
                return FALSE;
Packit Service 779887
            dargi++;
Packit Service 779887
            cargi++;
Packit Service 779887
        }
Packit Service 779887
    }
Packit Service 779887
Packit Service 779887
    ret = (cargi == g_strv_length(cmdargs) && dargi == g_strv_length(dcmdargs));
Packit Service 779887
Packit Service 779887
    return ret;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
static gboolean
Packit Service 779887
compare_binaries (char *cmd,
Packit Service 779887
          const char *dcmd)
Packit Service 779887
{
Packit Service 779887
    char *basename, *dbasename;
Packit Service 779887
    gboolean ret = FALSE;
Packit Service 779887
Packit Service 779887
    if (g_strcmp0 (cmd, dcmd) == 0)
Packit Service 779887
        return TRUE;
Packit Service 779887
Packit Service 779887
    basename = g_path_get_basename (cmd);
Packit Service 779887
    dbasename = g_path_get_basename (dcmd);
Packit Service 779887
Packit Service 779887
    if (g_strcmp0 (basename, dbasename) == 0)
Packit Service 779887
        ret = TRUE;
Packit Service 779887
Packit Service 779887
    g_free (basename);
Packit Service 779887
    g_free (dbasename);
Packit Service 779887
Packit Service 779887
    return ret;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
GAppInfo *
Packit Service 779887
problem_create_app_from_cmdline (const char *cmdline)
Packit Service 779887
{
Packit Service 779887
    GAppInfo *app;
Packit Service 779887
    GList *apps, *l;
Packit Service 779887
    GList *shortlist;
Packit Service 779887
    char *binary;
Packit Service 779887
    char **cmdargs;
Packit Service 779887
Packit Service 779887
    binary = problem_get_argv0(cmdline);
Packit Service 779887
Packit Service 779887
    apps = g_app_info_get_all ();
Packit Service 779887
    shortlist = NULL;
Packit Service 779887
    app = NULL;
Packit Service 779887
    for (l = apps; l != NULL; l = l->next)
Packit Service 779887
    {
Packit Service 779887
        GAppInfo *a = l->data;
Packit Service 779887
Packit Service 779887
        if (!g_app_info_should_show(a))
Packit Service 779887
            continue;
Packit Service 779887
Packit Service 779887
        if (!compare_binaries (binary, g_app_info_get_executable (a)))
Packit Service 779887
            continue;
Packit Service 779887
Packit Service 779887
        shortlist = g_list_prepend (shortlist, a);
Packit Service 779887
    }
Packit Service 779887
Packit Service 779887
    if (shortlist == NULL)
Packit Service 779887
    {
Packit Service 779887
        g_list_free_full (apps, g_object_unref);
Packit Service 779887
        return NULL;
Packit Service 779887
    }
Packit Service 779887
Packit Service 779887
    cmdargs = g_strsplit (cmdline, " ", -1);
Packit Service 779887
    remove_quotes (cmdargs);
Packit Service 779887
Packit Service 779887
    for (l = shortlist; l != NULL; l = l->next)
Packit Service 779887
    {
Packit Service 779887
        GAppInfo *a = l->data;
Packit Service 779887
        char **dcmdargs;
Packit Service 779887
Packit Service 779887
        const char *commandline = g_app_info_get_commandline (a);
Packit Service 779887
        if (commandline == NULL)
Packit Service 779887
            continue;
Packit Service 779887
Packit Service 779887
        dcmdargs = g_strsplit (commandline, " ", -1);
Packit Service 779887
        remove_quotes (dcmdargs);
Packit Service 779887
Packit Service 779887
        if (compare_args (cmdargs, dcmdargs))
Packit Service 779887
            app = g_object_ref (a);
Packit Service 779887
Packit Service 779887
        g_strfreev (dcmdargs);
Packit Service 779887
        if (app != NULL)
Packit Service 779887
            break;
Packit Service 779887
    }
Packit Service 779887
Packit Service 779887
    g_list_free (shortlist);
Packit Service 779887
    g_list_free_full (apps, g_object_unref);
Packit Service 779887
    return app;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
#define GIO_LAUNCHED_DESKTOP_FILE_PREFIX     "GIO_LAUNCHED_DESKTOP_FILE="
Packit Service 779887
#define GIO_LAUNCHED_DESKTOP_FILE_PID_PREFIX "GIO_LAUNCHED_DESKTOP_FILE_PID="
Packit Service 779887
Packit Service 779887
GAppInfo *
Packit Service 779887
problem_create_app_from_env (const char **envp,
Packit Service 779887
			     pid_t        pid)
Packit Service 779887
{
Packit Service 779887
    GDesktopAppInfo *app;
Packit Service 779887
    guint i;
Packit Service 779887
    const char *desktop, *epid;
Packit Service 779887
Packit Service 779887
    if (envp == NULL)
Packit Service 779887
        return NULL;
Packit Service 779887
    if (pid < 0)
Packit Service 779887
        return NULL;
Packit Service 779887
Packit Service 779887
    desktop = epid = NULL;
Packit Service 779887
    for (i = 0; envp[i] != NULL; i++)
Packit Service 779887
    {
Packit Service 779887
        if (g_str_has_prefix (envp[i], GIO_LAUNCHED_DESKTOP_FILE_PREFIX))
Packit Service 779887
            desktop = envp[i] + strlen (GIO_LAUNCHED_DESKTOP_FILE_PREFIX);
Packit Service 779887
        else if (g_str_has_prefix (envp[i], GIO_LAUNCHED_DESKTOP_FILE_PID_PREFIX))
Packit Service 779887
            epid = envp[i] + strlen (GIO_LAUNCHED_DESKTOP_FILE_PID_PREFIX);
Packit Service 779887
Packit Service 779887
        if (desktop && epid)
Packit Service 779887
            break;
Packit Service 779887
    }
Packit Service 779887
Packit Service 779887
    if (!desktop || !epid)
Packit Service 779887
        return NULL;
Packit Service 779887
Packit Service 779887
    /* Verify PID */
Packit Service 779887
    if (atoi (epid) != pid)
Packit Service 779887
        return NULL;
Packit Service 779887
Packit Service 779887
    if (*desktop == '/')
Packit Service 779887
        app = g_desktop_app_info_new_from_filename (desktop);
Packit Service 779887
    else
Packit Service 779887
        app = g_desktop_app_info_new (desktop);
Packit Service 779887
Packit Service 779887
    return (GAppInfo *) app;
Packit Service 779887
}
Packit Service 779887