~mterry/content-hub/ual-parse

« back to all changes in this revision

Viewing changes to src/helper/exec-tool.c

New upstream version to reflect addition of the out of process
peer picker

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2014 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3, as published
 
6
 * by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License along
 
14
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authors:
 
17
 *   Ted Gould <ted.gould@canonical.com>
 
18
 */
 
19
 
 
20
#include <glib.h>
 
21
#include <click.h>
 
22
#include <ubuntu-app-launch.h>
 
23
 
 
24
gchar *
 
25
build_exec (const gchar * appid, const gchar * directory)
 
26
{
 
27
        gchar * appid_desktop = g_strdup_printf("%s.desktop", appid);
 
28
        gchar * desktopfilepath = g_build_filename(directory, appid_desktop, NULL);
 
29
        g_free(appid_desktop);
 
30
 
 
31
        g_warning("content-hub desktop file '%s'", desktopfilepath);
 
32
        if (!g_file_test(desktopfilepath, G_FILE_TEST_EXISTS)) {
 
33
                g_warning("Unable to find content-hub desktop file '%s'", desktopfilepath);
 
34
                g_free(desktopfilepath);
 
35
                return NULL;
 
36
        }
 
37
 
 
38
        GError * error = NULL;
 
39
        GKeyFile * keyfile = g_key_file_new();
 
40
        g_key_file_load_from_file(keyfile, desktopfilepath, G_KEY_FILE_NONE, &error);
 
41
 
 
42
        if (error != NULL) {
 
43
                g_error("Unable to read content-hub desktop file '%s': %s", desktopfilepath, error->message);
 
44
                g_free(desktopfilepath);
 
45
                g_key_file_free(keyfile);
 
46
                g_error_free(error);
 
47
                return NULL;
 
48
        }
 
49
 
 
50
        g_free(desktopfilepath);
 
51
 
 
52
        if (!g_key_file_has_key(keyfile, "Desktop Entry", "Exec", NULL)) {
 
53
                g_error("Desktop file for '%s' in '%s' does not have 'Exec' key", appid, directory);
 
54
                g_key_file_free(keyfile);
 
55
                return NULL;
 
56
        }
 
57
 
 
58
        gchar * exec = g_key_file_get_string(keyfile, "Desktop Entry", "Exec", NULL);
 
59
        g_key_file_free(keyfile);
 
60
        g_warning("content-hub exec: '%s'", exec);
 
61
 
 
62
        return exec;
 
63
}
 
64
 
 
65
gchar *
 
66
build_dir (const gchar * appid)
 
67
{
 
68
        GError * error = NULL;
 
69
        gchar * package = NULL;
 
70
 
 
71
        /* 'Parse' the App ID */
 
72
        if (!ubuntu_app_launch_app_id_parse(appid, &package, NULL, NULL)) {
 
73
                g_warning("Unable to parse App ID: '%s'", appid);
 
74
                return NULL;
 
75
        }
 
76
 
 
77
        /* Check click to find out where the files are */
 
78
        ClickDB * db = click_db_new();
 
79
 
 
80
        /* If TEST_CLICK_DB is unset, this reads the system database. */
 
81
        click_db_read(db, g_getenv("TEST_CLICK_DB"), &error);
 
82
        if (error != NULL) {
 
83
                g_warning("Unable to read Click database: %s", error->message);
 
84
                g_error_free(error);
 
85
                g_free(package);
 
86
                return NULL;
 
87
        }
 
88
 
 
89
        /* If TEST_CLICK_USER is unset, this uses the current user name. */
 
90
        ClickUser * user = click_user_new_for_user(db, g_getenv("TEST_CLICK_USER"), &error);
 
91
        if (error != NULL) {
 
92
                g_warning("Unable to read Click database: %s", error->message);
 
93
                g_error_free(error);
 
94
                g_free(package);
 
95
                g_object_unref(db);
 
96
                return NULL;
 
97
        }
 
98
 
 
99
        gchar * pkgdir = click_user_get_path(user, package, &error);
 
100
 
 
101
        g_object_unref(user);
 
102
        g_object_unref(db);
 
103
        g_free(package);
 
104
 
 
105
        if (error != NULL) {
 
106
                g_warning("Unable to get the Click package directory for %s: %s", package, error->message);
 
107
                g_error_free(error);
 
108
                return NULL;
 
109
        }
 
110
 
 
111
        return pkgdir;
 
112
}
 
113
 
 
114
int
 
115
main (int argc, char * argv[])
 
116
{
 
117
        g_warning("argc: %d", argc);
 
118
        g_warning("argv0: %s", g_shell_quote(argv[0]));
 
119
 
 
120
        /* Build up our exec */
 
121
        const gchar * appid = g_getenv("APP_ID");
 
122
        if (appid == NULL) {
 
123
                return -1;
 
124
        }
 
125
 
 
126
        gchar * exec = NULL;
 
127
 
 
128
        /* Allow for environment override */
 
129
        const gchar * envdir = g_getenv("URL_DISPATCHER_OVERLAY_DIR");
 
130
        if (G_UNLIKELY(envdir != NULL)) { /* Mostly for testing */
 
131
                exec = build_exec(appid, envdir);
 
132
        }
 
133
 
 
134
        /* Try the system directory */
 
135
        if (exec == NULL) {
 
136
                exec = build_exec(appid, SYSTEM_DIRECTORY);
 
137
        }
 
138
 
 
139
        /* If not there look to the user directory (click) */
 
140
        if (exec == NULL) {
 
141
                gchar * userdir = g_build_filename(g_get_user_cache_dir(), "ubuntu-app-launch", "desktop", NULL);
 
142
                exec = build_exec(appid, userdir);
 
143
                g_free(userdir);
 
144
        }
 
145
 
 
146
        if (exec == NULL) {
 
147
                const gchar * props[3] = {
 
148
                        "AppID",
 
149
                        appid,
 
150
                        NULL
 
151
                };
 
152
 
 
153
                return -1;
 
154
        }
 
155
 
 
156
        gchar * dir = build_dir(appid);
 
157
        /* NOTE: Dir will be NULL for system apps */
 
158
 
 
159
        GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
 
160
        g_return_val_if_fail(bus != NULL, -1);
 
161
 
 
162
        g_warning("content-hub main exec: '%s'", exec);
 
163
        g_warning("content-hub main dir: '%s'", dir);
 
164
 
 
165
        gboolean sended = ubuntu_app_launch_helper_set_exec(exec, dir);
 
166
        g_free(exec);
 
167
        g_free(dir);
 
168
 
 
169
        /* Ensuring the messages get on the bus before we quit */
 
170
        g_dbus_connection_flush_sync(bus, NULL, NULL);
 
171
        g_clear_object(&bus);
 
172
 
 
173
        if (sended) {
 
174
                return 0;
 
175
        } else {
 
176
                g_critical("Unable to send exec to Upstart");
 
177
                return -1;
 
178
        }
 
179
}