mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-16 22:19:47 -04:00
When we've listened to all sockets we write to the fd, and when the other end of the fd is closed we exit. This can be used to limit the lifetime of the proxy to the container.
219 lines
5.0 KiB
C
219 lines
5.0 KiB
C
/*
|
|
* Copyright © 2015 Red Hat, Inc
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Authors:
|
|
* Alexander Larsson <alexl@redhat.com>
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "libglnx/libglnx.h"
|
|
|
|
#include "xdg-app-proxy.h"
|
|
|
|
GList *proxies;
|
|
int sync_fd = -1;
|
|
|
|
int
|
|
parse_generic_args (int n_args, const char *args[])
|
|
{
|
|
if (g_str_has_prefix (args[0], "--fd="))
|
|
{
|
|
const char *fd_s = args[0] + strlen("--fd=");
|
|
char *endptr;
|
|
int fd;
|
|
|
|
fd = strtol (fd_s, &endptr, 10);
|
|
if (fd < 0 || endptr == fd_s || *endptr != 0)
|
|
{
|
|
g_printerr ("Invalid fd %s\n", fd_s);
|
|
return -1;
|
|
}
|
|
sync_fd = fd;
|
|
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
g_printerr ("Unknown argument %s\n", args[0]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int
|
|
start_proxy (int n_args, const char *args[])
|
|
{
|
|
g_autoptr(XdgAppProxy) proxy = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
const char *bus_address, *socket_path;
|
|
int n;
|
|
|
|
n = 0;
|
|
if (n_args < n+1 || args[n][0] == '-')
|
|
{
|
|
g_printerr ("No bus address given\n");
|
|
return -1;
|
|
}
|
|
bus_address = args[n++];
|
|
|
|
if (n_args < n+1 || args[n][0] == '-')
|
|
{
|
|
g_printerr ("No socket path given\n");
|
|
return -1;
|
|
}
|
|
socket_path = args[n++];
|
|
|
|
proxy = xdg_app_proxy_new (bus_address, socket_path);
|
|
|
|
while (n < n_args)
|
|
{
|
|
if (args[n][0] != '-')
|
|
break;
|
|
|
|
if (g_str_has_prefix (args[n], "--see=") ||
|
|
g_str_has_prefix (args[n], "--talk=") ||
|
|
g_str_has_prefix (args[n], "--own="))
|
|
{
|
|
XdgAppPolicy policy = XDG_APP_POLICY_SEE;
|
|
g_autofree char *name = NULL;
|
|
gboolean wildcard = FALSE;
|
|
|
|
if (args[n][2] == 't')
|
|
policy = XDG_APP_POLICY_TALK;
|
|
else if (args[n][2] == 'o')
|
|
policy = XDG_APP_POLICY_OWN;
|
|
|
|
name = g_strdup (strchr (args[n], '=') + 1);
|
|
if (g_str_has_suffix (name, ".*"))
|
|
{
|
|
name[strlen (name) - 2] = 0;
|
|
wildcard = TRUE;
|
|
}
|
|
|
|
if (name[0] == ':' || !g_dbus_is_name (name))
|
|
{
|
|
g_printerr ("'%s' is not a valid dbus name\n", name);
|
|
return -1;
|
|
}
|
|
|
|
if (wildcard)
|
|
xdg_app_proxy_add_wildcarded_policy (proxy, name, policy);
|
|
else
|
|
xdg_app_proxy_add_policy (proxy, name, policy);
|
|
}
|
|
else if (g_str_equal (args[n], "--log"))
|
|
{
|
|
xdg_app_proxy_set_log_messages (proxy, TRUE);
|
|
}
|
|
else if (g_str_equal (args[n], "--filter"))
|
|
{
|
|
xdg_app_proxy_set_filter (proxy, TRUE);
|
|
}
|
|
else
|
|
{
|
|
int res = parse_generic_args (n_args - n, &args[n]);
|
|
if (res == -1)
|
|
return -1;
|
|
|
|
n += res - 1; /* res - 1, because we ++ below */
|
|
}
|
|
|
|
n++;
|
|
}
|
|
|
|
if (!xdg_app_proxy_start (proxy, &error))
|
|
{
|
|
g_printerr ("Failed to start proxy for %s: %s\n", bus_address, error->message);
|
|
return -1;
|
|
}
|
|
|
|
proxies = g_list_prepend (proxies, g_object_ref (proxy));
|
|
|
|
return n;
|
|
}
|
|
|
|
static gboolean
|
|
sync_closed_cb (GIOChannel *source,
|
|
GIOCondition condition,
|
|
gpointer data)
|
|
{
|
|
exit (0);
|
|
return TRUE;
|
|
}
|
|
|
|
int
|
|
main (int argc, const char *argv[])
|
|
{
|
|
GMainLoop *service_loop;
|
|
int n_args, res;
|
|
const char **args;
|
|
|
|
n_args = argc - 1;
|
|
args = &argv[1];
|
|
|
|
while (n_args > 0)
|
|
{
|
|
if (args[0][0] == '-')
|
|
{
|
|
res = parse_generic_args (n_args, &args[0]);
|
|
if (res == -1)
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
res = start_proxy (n_args, args);
|
|
if (res == -1)
|
|
return 1;
|
|
}
|
|
|
|
g_assert (res > 0);
|
|
n_args -= res;
|
|
args += res;
|
|
}
|
|
|
|
if (proxies == NULL)
|
|
{
|
|
g_printerr ("No proxies specied\n");
|
|
return 1;
|
|
}
|
|
|
|
if (sync_fd >= 0)
|
|
{
|
|
ssize_t written;
|
|
GIOChannel *sync_channel;
|
|
written = write (sync_fd, "x", 1);
|
|
if (written != 1)
|
|
g_warning ("Can't write to sync socket");
|
|
|
|
sync_channel = g_io_channel_unix_new (sync_fd);
|
|
g_io_add_watch (sync_channel, G_IO_ERR | G_IO_HUP,
|
|
sync_closed_cb, NULL);
|
|
}
|
|
|
|
service_loop = g_main_loop_new (NULL, FALSE);
|
|
g_main_loop_run (service_loop);
|
|
|
|
g_main_loop_unref (service_loop);
|
|
|
|
return 0;
|
|
}
|