diff -Nru phodav-2.3/avahi-common.c phodav-2.4/avahi-common.c
--- phodav-2.3/avahi-common.c 1970-01-01 00:00:00.000000000 +0000
+++ phodav-2.4/avahi-common.c 2020-03-05 11:15:02.000000000 +0000
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library 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.1 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 .
+ */
+
+#include "config.h"
+#include "avahi-common.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+static GaClient *mdns_client;
+static GaEntryGroup *mdns_group;
+
+static const gchar *s_name;
+static guint s_port;
+static gboolean s_local;
+
+static gboolean
+ifaddr_is_loopback (struct ifaddrs *ifa)
+{
+ union {
+ struct sockaddr_in *in;
+ struct sockaddr_in6 *in6;
+ } sa;
+
+ if (!(ifa->ifa_flags & IFF_LOOPBACK))
+ return FALSE;
+
+ if (!ifa->ifa_addr)
+ return FALSE;
+
+ switch (ifa->ifa_addr->sa_family)
+ {
+ case AF_INET:
+ sa.in = (struct sockaddr_in *)(ifa->ifa_addr);
+ return sa.in->sin_addr.s_addr == g_htonl (0x7f000001); // 127.0.0.1
+ case AF_INET6:
+ sa.in6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
+ return IN6_IS_ADDR_LOOPBACK (&sa.in6->sin6_addr);
+ }
+ return FALSE;
+}
+
+static guint
+get_loopback_if_id ()
+{
+ struct ifaddrs *ifaddr, *ifa;
+ guint id = AVAHI_IF_UNSPEC;
+
+ if (getifaddrs (&ifaddr) == -1)
+ {
+ g_warning ("getifaddrs failed, using AVAHI_IF_UNSPEC: %s", g_strerror(errno));
+ return id;
+ }
+
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
+ {
+ if (ifaddr_is_loopback (ifa))
+ {
+ id = if_nametoindex (ifa->ifa_name);
+ break;
+ }
+ }
+
+ freeifaddrs (ifaddr);
+ return id;
+}
+
+static void
+mdns_register_service (void)
+{
+ GaEntryGroupService *mdns_service;
+ GError *error = NULL;
+
+ if (!mdns_group)
+ {
+ mdns_group = ga_entry_group_new ();
+
+ if (!ga_entry_group_attach (mdns_group, mdns_client, &error))
+ {
+ g_warning ("Could not attach MDNS group to client: %s", error->message);
+ g_clear_error (&error);
+ return;
+ }
+ }
+
+ mdns_service =
+ ga_entry_group_add_service_full (mdns_group,
+ s_local ? get_loopback_if_id () : AVAHI_IF_UNSPEC,
+ AVAHI_PROTO_UNSPEC,
+ 0,
+ s_name, "_webdav._tcp",
+ NULL, NULL,
+ s_port, &error,
+ NULL);
+ if (!mdns_service)
+ {
+ g_warning ("Could not create service: %s", error->message);
+ g_clear_error (&error);
+ return;
+ }
+
+ ga_entry_group_service_freeze (mdns_service);
+ if (!ga_entry_group_service_set (mdns_service, "u", "", &error) ||
+ !ga_entry_group_service_set (mdns_service, "p", "", &error) ||
+ !ga_entry_group_service_set (mdns_service, "path", "/", &error) ||
+ !ga_entry_group_service_thaw (mdns_service, &error))
+ {
+ g_warning ("Could not update TXT: %s", error->message);
+ g_clear_error (&error);
+ }
+
+ if (!ga_entry_group_commit (mdns_group, &error))
+ {
+ g_warning ("Could not announce MDNS service: %s", error->message);
+ g_clear_error (&error);
+ }
+}
+
+static void
+mdns_unregister_service (void)
+{
+ GError *error = NULL;
+
+ if (mdns_group)
+ {
+ if (!ga_entry_group_reset (mdns_group, &error))
+ {
+ g_warning ("Could not disconnect MDNS service: %s", error->message);
+ g_clear_error (&error);
+ }
+ g_debug ("MDNS client disconected");
+ }
+}
+
+static void
+mdns_state_changed (GaClient *client, GaClientState state, gpointer user_data)
+{
+ switch (state)
+ {
+ case GA_CLIENT_STATE_FAILURE:
+ g_warning ("MDNS client state failure");
+ break;
+
+ case GA_CLIENT_STATE_S_RUNNING:
+ g_debug ("MDNS client found server running");
+ mdns_register_service ();
+ break;
+
+ case GA_CLIENT_STATE_S_COLLISION:
+ case GA_CLIENT_STATE_S_REGISTERING:
+ g_message ("MDNS collision");
+ mdns_unregister_service ();
+ break;
+
+ default:
+ // Do nothing
+ break;
+ }
+}
+
+gboolean
+avahi_client_start (const gchar *name, guint port, gboolean local, GError **error)
+{
+ g_return_val_if_fail (mdns_client == NULL, FALSE);
+
+ mdns_client = ga_client_new (GA_CLIENT_FLAG_NO_FLAGS);
+ s_name = name;
+ s_port = port;
+ s_local = local;
+
+ g_signal_connect (mdns_client, "state-changed", G_CALLBACK (mdns_state_changed), NULL);
+ return ga_client_start (mdns_client, error);
+}
+
+void
+avahi_client_stop ()
+{
+ mdns_unregister_service ();
+ g_clear_object (&mdns_group);
+ g_clear_object (&mdns_client);
+}
diff -Nru phodav-2.3/avahi-common.h phodav-2.4/avahi-common.h
--- phodav-2.3/avahi-common.h 1970-01-01 00:00:00.000000000 +0000
+++ phodav-2.4/avahi-common.h 2020-03-05 11:15:02.000000000 +0000
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library 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.1 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 .
+ */
+
+#include
+
+gboolean avahi_client_start (const gchar *name, guint port, gboolean local, GError **error);
+void avahi_client_stop ();
diff -Nru phodav-2.3/debian/changelog phodav-2.4/debian/changelog
--- phodav-2.3/debian/changelog 2019-09-15 01:01:04.000000000 +0000
+++ phodav-2.4/debian/changelog 2020-03-15 10:38:05.000000000 +0000
@@ -1,3 +1,14 @@
+phodav (2.4-1) unstable; urgency=medium
+
+ * New upstream release
+ * debian/control.in: Bump Standards-Version to 4.5.0 (no further changes)
+ * debian/control.in: Set Rules-Requires-Root: no
+ * debian/control.in: Add libglib2.0-doc and libsoup2.4-doc to the build-deps
+ * Only require systemd and udev on linux architectures and adjust installed
+ files on non-linux ones
+
+ -- Laurent Bigonville Sun, 15 Mar 2020 11:38:05 +0100
+
phodav (2.3-2) unstable; urgency=medium
* Build-Depend on debhelper-compat 12 and drop debian/compat
diff -Nru phodav-2.3/debian/control phodav-2.4/debian/control
--- phodav-2.3/debian/control 2019-09-15 01:01:04.000000000 +0000
+++ phodav-2.4/debian/control 2020-03-15 10:38:05.000000000 +0000
@@ -15,13 +15,16 @@
libavahi-client-dev,
libavahi-gobject-dev,
libglib2.0-dev (>= 2.51),
+ libglib2.0-doc,
libsoup2.4-dev (>= 2.48.0),
+ libsoup2.4-doc,
libxml2-dev,
meson (>= 0.49),
- systemd,
- udev,
+ systemd [linux-any],
+ udev [linux-any],
xmlto
-Standards-Version: 4.4.0
+Standards-Version: 4.5.0
+Rules-Requires-Root: no
Vcs-Browser: https://salsa.debian.org/gnome-team/phodav
Vcs-Git: https://salsa.debian.org/gnome-team/phodav.git
Homepage: https://wiki.gnome.org/phodav
diff -Nru phodav-2.3/debian/control.in phodav-2.4/debian/control.in
--- phodav-2.3/debian/control.in 2019-09-15 01:01:04.000000000 +0000
+++ phodav-2.4/debian/control.in 2020-03-15 10:38:05.000000000 +0000
@@ -11,13 +11,16 @@
libavahi-client-dev,
libavahi-gobject-dev,
libglib2.0-dev (>= 2.51),
+ libglib2.0-doc,
libsoup2.4-dev (>= 2.48.0),
+ libsoup2.4-doc,
libxml2-dev,
meson (>= 0.49),
- systemd,
- udev,
+ systemd [linux-any],
+ udev [linux-any],
xmlto
-Standards-Version: 4.4.0
+Standards-Version: 4.5.0
+Rules-Requires-Root: no
Vcs-Browser: https://salsa.debian.org/gnome-team/phodav
Vcs-Git: https://salsa.debian.org/gnome-team/phodav.git
Homepage: https://wiki.gnome.org/phodav
diff -Nru phodav-2.3/debian/rules phodav-2.4/debian/rules
--- phodav-2.3/debian/rules 2019-09-15 01:01:04.000000000 +0000
+++ phodav-2.4/debian/rules 2020-03-15 10:38:05.000000000 +0000
@@ -3,14 +3,28 @@
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 -Wl,-z,defs -Wl,--as-needed
+ifneq ($(DEB_HOST_ARCH_OS),linux)
+ DISABLE_SYSTEMD=-Dsystemd=disabled -Dudev=disabled
+endif
+
%:
dh $@
override_dh_auto_configure:
- dh_auto_configure -- -Dauto_features=enabled
+ dh_auto_configure -- -Dauto_features=enabled $(DISABLE_SYSTEMD)
override_dh_makeshlibs:
dh_makeshlibs -- -c4
override_dh_missing:
dh_missing --fail-missing
+
+override_dh_install:
+ grep -E -v 'lib/systemd|lib/udev' debian/spice-webdavd.install > debian/spice-webdavd.install.kfreebsd
+ grep -E -v 'lib/systemd|lib/udev' debian/spice-webdavd.install > debian/spice-webdavd.install.hurd
+ dh_install
+
+override_dh_clean:
+ rm -f debian/spice-webdavd.install.kfreebsd
+ rm -f debian/spice-webdavd.install.hurd
+ dh_clean
diff -Nru phodav-2.3/libphodav/chezdav.c phodav-2.4/libphodav/chezdav.c
--- phodav-2.3/libphodav/chezdav.c 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/libphodav/chezdav.c 2020-03-05 11:15:02.000000000 +0000
@@ -27,12 +27,7 @@
#endif
#ifdef WITH_AVAHI
-#include
-#include
-
-static GaClient *mdns_client;
-static GaEntryGroup *mdns_group;
-static GaEntryGroupService *mdns_service;
+#include "avahi-common.h"
#endif
#include "libphodav/phodav.h"
@@ -77,88 +72,6 @@
return g_strdup_printf ("%s\'s public share", g_get_user_name ());
}
-#ifdef WITH_AVAHI
-static void
-mdns_register_service (void)
-{
- GError *error = NULL;
- gchar *name = NULL;
-
- if (!mdns_group)
- {
- mdns_group = ga_entry_group_new ();
-
- if (!ga_entry_group_attach (mdns_group, mdns_client, &error))
- {
- g_warning ("Could not attach MDNS group to client: %s", error->message);
- g_clear_error (&error);
- return;
- }
- }
-
- name = get_realm ();
- mdns_service = ga_entry_group_add_service (mdns_group,
- name, "_webdav._tcp",
- port, &error,
- NULL);
- if (!mdns_service)
- {
- g_warning ("Could not create service: %s", error->message);
- g_clear_error (&error);
- goto end;
- }
-
- ga_entry_group_service_freeze (mdns_service);
- if (!ga_entry_group_service_set (mdns_service, "u", "", &error) ||
- !ga_entry_group_service_set (mdns_service, "p", "", &error) ||
- !ga_entry_group_service_set (mdns_service, "path", "/", &error) ||
- !ga_entry_group_service_thaw (mdns_service, &error))
- {
- g_warning ("Could not update TXT: %s", error->message);
- g_clear_error (&error);
- }
-
- if (!ga_entry_group_commit (mdns_group, &error))
- {
- g_warning ("Could not announce MDNS service: %s", error->message);
- g_clear_error (&error);
- }
-
-end:
- g_free (name);
-}
-
-static void
-mdns_state_changed (GaClient *client, GaClientState state, gpointer user_data)
-{
- switch (state)
- {
- case GA_CLIENT_STATE_FAILURE:
- g_warning ("MDNS client state failure");
- break;
-
- case GA_CLIENT_STATE_S_RUNNING:
- g_debug ("MDNS client found server running");
- mdns_register_service ();
- break;
-
- case GA_CLIENT_STATE_S_COLLISION:
- case GA_CLIENT_STATE_S_REGISTERING:
- g_message ("MDNS collision");
- if (mdns_group)
- {
- ga_entry_group_reset (mdns_group, NULL);
- mdns_service = 0;
- }
- break;
-
- default:
- // Do nothing
- break;
- }
-}
-#endif // WITH_AVAHI
-
gchar *htdigest = NULL;
static gchar *
@@ -216,9 +129,6 @@
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-#if !GLIB_CHECK_VERSION (2, 35, 1)
- g_type_init ();
-#endif
g_set_prgname ("chezdav");
context = g_option_context_new (_ ("- simple WebDAV server"));
@@ -282,9 +192,8 @@
#ifdef WITH_AVAHI
- mdns_client = ga_client_new (GA_CLIENT_FLAG_NO_FLAGS);
- g_signal_connect (mdns_client, "state-changed", G_CALLBACK (mdns_state_changed), NULL);
- if (!ga_client_start (mdns_client, &error))
+ gchar *name = get_realm ();
+ if (!avahi_client_start (name, port, local, &error))
my_error (_ ("mDNS failed: %s\n"), error->message);
#endif
@@ -306,7 +215,8 @@
g_main_loop_unref (mainloop);
#ifdef WITH_AVAHI
- g_object_unref (mdns_client);
+ avahi_client_stop ();
+ g_free (name);
#endif
g_object_unref (dav);
diff -Nru phodav-2.3/libphodav/meson.build phodav-2.4/libphodav/meson.build
--- phodav-2.3/libphodav/meson.build 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/libphodav/meson.build 2020-03-05 11:15:02.000000000 +0000
@@ -53,7 +53,7 @@
executable(
'chezdav',
- [ 'chezdav.c' ],
+ [ 'chezdav.c' ] + avahi_common,
include_directories : incdir,
dependencies : avahi_deps + deps,
link_with : [ libphodav ],
diff -Nru phodav-2.3/libphodav/phodav-method-propfind.c phodav-2.4/libphodav/phodav-method-propfind.c
--- phodav-2.3/libphodav/phodav-method-propfind.c 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/libphodav/phodav-method-propfind.c 2020-03-05 11:15:02.000000000 +0000
@@ -327,6 +327,7 @@
prop_quota_available (PathHandler *handler, PropFind *pf,
const gchar *path, GFileInfo *_info, xmlNsPtr ns)
{
+ GFile *file;
GFileInfo *info = NULL;
gint status = SOUP_STATUS_OK;
xmlNodePtr node = xmlNewNode (ns, BAD_CAST "quota-available-bytes");
@@ -338,8 +339,11 @@
if (pf->type == PROPFIND_PROPNAME)
goto end;
- info = g_file_query_filesystem_info (handler_get_file (handler), "filesystem::*",
+ file = g_file_get_child (handler_get_file (handler), path + 1);
+ info = g_file_query_filesystem_info (file, "filesystem::*",
cancellable, &error);
+ g_object_unref (file);
+
if (error)
{
g_warning ("Filesystem info error: %s", error->message);
@@ -361,11 +365,11 @@
return node;
}
-#if GLIB_CHECK_VERSION (2, 38, 0)
static xmlNodePtr
prop_quota_used (PathHandler *handler, PropFind *pf,
const gchar *path, GFileInfo *info, xmlNsPtr ns)
{
+ GFile *file = NULL;
gint status = SOUP_STATUS_OK;
GCancellable *cancellable = handler_get_cancellable(handler);
xmlNodePtr node = xmlNewNode (ns, BAD_CAST "quota-used-bytes");
@@ -376,7 +380,8 @@
if (pf->type == PROPFIND_PROPNAME)
goto end;
- if (!g_file_measure_disk_usage (handler_get_file (handler),
+ file = g_file_get_child (handler_get_file (handler), path + 1);
+ if (!g_file_measure_disk_usage (file,
G_FILE_MEASURE_NONE,
cancellable,
NULL, NULL,
@@ -392,11 +397,11 @@
xmlAddChild (node, xmlNewText (BAD_CAST tmp));
end:
+ g_clear_object (&file);
g_free (tmp);
PROP_SET_STATUS (node, status);
return node;
}
-#endif
static gint
node_compare_int (xmlNodePtr a,
@@ -431,9 +436,7 @@
PROP (supportedlock, 0),
PROP (lockdiscovery, 0),
{ "quota-available-bytes", prop_quota_available, },
-#if GLIB_CHECK_VERSION (2, 38, 0)
{ "quota-used-bytes", prop_quota_used, FALSE, TRUE, }
-#endif
};
static xmlNodePtr
diff -Nru phodav-2.3/meson.build phodav-2.4/meson.build
--- phodav-2.3/meson.build 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/meson.build 2020-03-05 11:15:02.000000000 +0000
@@ -6,7 +6,7 @@
check : true
).stdout().strip(),
license : 'LGPLv2.1',
- meson_version : '>= 0.49',
+ meson_version : '>= 0.50',
)
meson.add_dist_script('sh', '-c', 'echo @0@>"$MESON_DIST_ROOT/.tarball-version"'.format(meson.project_version()))
@@ -29,9 +29,9 @@
deps = []
if host_machine.system() == 'windows'
- deps += dependency('gio-windows-2.0')
+ deps += dependency('gio-windows-2.0', version : '>= 2.44')
else
- deps += dependency('gio-unix-2.0')
+ deps += dependency('gio-unix-2.0', version : '>= 2.44')
endif
deps += dependency('libsoup-2.4', version : '>= 2.48.0')
@@ -40,8 +40,10 @@
d1 = dependency('avahi-gobject', required : get_option('avahi'))
d2 = dependency('avahi-client', required : get_option('avahi'))
avahi_deps = []
+avahi_common = []
if d1.found() and d2.found()
avahi_deps += [ d1, d2 ]
+ avahi_common += [ '../avahi-common.c', ]
conf.set('WITH_AVAHI', 1)
endif
@@ -53,7 +55,7 @@
)
endif
-udev = dependency('udev', required : get_option('systemd'))
+udev = dependency('udev', required : get_option('udev'))
if udev.found()
install_data(
'data/70-spice-webdavd.rules',
diff -Nru phodav-2.3/meson_options.txt phodav-2.4/meson_options.txt
--- phodav-2.3/meson_options.txt 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/meson_options.txt 2020-03-05 11:15:02.000000000 +0000
@@ -10,6 +10,10 @@
type : 'feature',
description : 'Install systemd units/configuration')
+option('udev',
+ type : 'feature',
+ description : 'Install udev rules')
+
option('build-id',
type : 'integer',
value : 0,
diff -Nru phodav-2.3/NEWS phodav-2.4/NEWS
--- phodav-2.3/NEWS 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/NEWS 2020-03-05 11:15:02.000000000 +0000
@@ -1,3 +1,20 @@
+v2.4
+====
+
+- Requires GIO >= 2.44
+- !2 - Added udev option to meson
+- spice-webdavd:
+ - !3 : several improvements and fixes including some leaks
+ - !4 : disconnect the client gracefully
+ - !5 : code refcatory to improve performance and error handling
+ - !6 : avahi fixes on registering and unregistering service
+ - !7 : Fixes DAV:quota-used-bytes in resource is not in root fs
+
+- Translations
+ - Added Basque
+ - Added Dutch
+ - Added Finnish
+
v2.3
====
diff -Nru phodav-2.3/po/eu.po phodav-2.4/po/eu.po
--- phodav-2.3/po/eu.po 1970-01-01 00:00:00.000000000 +0000
+++ phodav-2.4/po/eu.po 2020-03-05 11:15:02.000000000 +0000
@@ -0,0 +1,90 @@
+# Basque translation for phodav.
+# Copyright (C) 2019 phodav's COPYRIGHT HOLDER
+# This file is distributed under the same license as the phodav package.
+# Asier Sarasua Garmendia , 2019.
+#
+msgid ""
+msgstr "Project-Id-Version: phodav master\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/phodav/issues\n"
+"POT-Creation-Date: 2019-08-22 15:18+0000\n"
+"PO-Revision-Date: 2019-10-18 10:00+0100\n"
+"Last-Translator: Asier Sarasua Garmendia \n"
+"Language-Team: Basque \n"
+"Language: eu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: libphodav/chezdav.c:203
+msgid "Print program version"
+msgstr "Erakutsi programaren bertsioa"
+
+#: libphodav/chezdav.c:204
+msgid "Be verbose"
+msgstr "Eman xehetasunak"
+
+#: libphodav/chezdav.c:205
+msgid "Port to listen to"
+msgstr "Entzungo den ataka"
+
+#: libphodav/chezdav.c:206
+msgid "Listen on loopback only"
+msgstr "Entzun atzera-begiztan soilik"
+
+#: libphodav/chezdav.c:207
+msgid "Listen on all interfaces"
+msgstr "Entzun interfaze guztietan"
+
+#: libphodav/chezdav.c:208
+msgid "Path to export"
+msgstr "Esportaziorako bide-izena"
+
+#: libphodav/chezdav.c:209
+msgid "Path to htdigest file"
+msgstr "htdigest fitxategiaren bide-izena"
+
+#: libphodav/chezdav.c:210
+msgid "Read-only access"
+msgstr "Irakurtzeko soilik den sarbidea"
+
+#: libphodav/chezdav.c:221
+msgid "- simple WebDAV server"
+msgstr "- WebDAV zerbitzari sinplea"
+
+#: libphodav/chezdav.c:222
+#, c-format
+msgid "Report bugs to <%s>"
+msgstr "Bidali erroreei buruzko informazioa hona: <%s>"
+
+#: libphodav/chezdav.c:229
+#, c-format
+msgid "Option parsing failed: %s\n"
+msgstr "Huts egin du aukera aztertzean: %s\n"
+
+#: libphodav/chezdav.c:233
+#, c-format
+msgid "Unsupported extra arguments: %s ...\n"
+msgstr "Onartzen ez diren argumentu gehigarriak: %s …\n"
+
+#: libphodav/chezdav.c:242
+msgid "--local and --public are mutually exclusive\n"
+msgstr "--local and --public elkarrekiko esklusiboak dira\n"
+
+#: libphodav/chezdav.c:266
+#, c-format
+msgid "Failed to open htdigest: %s\n"
+msgstr "Huts egin du htdigest irekitzeak: %s\n"
+
+#: libphodav/chezdav.c:285
+#, c-format
+msgid "mDNS failed: %s\n"
+msgstr "mDNS-k huts egin du: %s\n"
+
+#: libphodav/chezdav.c:296
+msgid "Internal error, should not happen\n"
+msgstr "Barneko errorea, ez litzateke gertatu beharko\n"
+
+#: libphodav/chezdav.c:299
+#, c-format
+msgid "Listen failed: %s\n"
+msgstr "Entzuteak huts egin du: %s\n"
diff -Nru phodav-2.3/po/fi.po phodav-2.4/po/fi.po
--- phodav-2.3/po/fi.po 1970-01-01 00:00:00.000000000 +0000
+++ phodav-2.4/po/fi.po 2020-03-05 11:15:02.000000000 +0000
@@ -0,0 +1,93 @@
+# Finnish translation for phodav.
+# Copyright (C) 2019 phodav's COPYRIGHT HOLDER
+# This file is distributed under the same license as the phodav package.
+# Jiri Grönroos , 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: phodav master\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/phodav/issues\n"
+"POT-Creation-Date: 2019-11-30 10:34+0000\n"
+"PO-Revision-Date: 2020-02-23 14:59+0200\n"
+"Last-Translator: Jiri Grönroos \n"
+"Language-Team: Finnish \n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.3\n"
+
+#: libphodav/chezdav.c:203
+msgid "Print program version"
+msgstr "Tulosta ohjelman versio"
+
+#: libphodav/chezdav.c:204
+msgid "Be verbose"
+msgstr "Ole runsassanainen"
+
+#: libphodav/chezdav.c:205
+msgid "Port to listen to"
+msgstr "Kuunneltava portti"
+
+#: libphodav/chezdav.c:206
+msgid "Listen on loopback only"
+msgstr "Kuuntele vain loopback-osoitetta"
+
+#: libphodav/chezdav.c:207
+msgid "Listen on all interfaces"
+msgstr "Kuuntele kaikissa liitännöissä"
+
+#: libphodav/chezdav.c:208
+msgid "Path to export"
+msgstr "Tuotava polku"
+
+#: libphodav/chezdav.c:209
+msgid "Path to htdigest file"
+msgstr "Polku htdigest-tiedostoon"
+
+#: libphodav/chezdav.c:210
+msgid "Read-only access"
+msgstr "Vain lukuoikeus"
+
+#: libphodav/chezdav.c:221
+msgid "- simple WebDAV server"
+msgstr "- yksinkertainen WebDAV-palvelin"
+
+#: libphodav/chezdav.c:222
+#, c-format
+msgid "Report bugs to <%s>"
+msgstr "Ilmoita bugeista <%s>"
+
+#: libphodav/chezdav.c:229
+#, c-format
+msgid "Option parsing failed: %s\n"
+msgstr "Valinnan jäsentäminen epäonnistui: %s\n"
+
+#: libphodav/chezdav.c:233
+#, c-format
+msgid "Unsupported extra arguments: %s ...\n"
+msgstr "Ei-tuetut lisäargumentit: %s ...\n"
+
+#: libphodav/chezdav.c:242
+msgid "--local and --public are mutually exclusive\n"
+msgstr "--local ja --public eivät ole samanaikaisesti käytettävissä\n"
+
+#: libphodav/chezdav.c:266
+#, c-format
+msgid "Failed to open htdigest: %s\n"
+msgstr "Htdigestin avaaminen epäonnistui: %s\n"
+
+#: libphodav/chezdav.c:285
+#, c-format
+msgid "mDNS failed: %s\n"
+msgstr "mDNS epäonnistui: %s\n"
+
+#: libphodav/chezdav.c:296
+msgid "Internal error, should not happen\n"
+msgstr "Sisäinen virhe, ei pitäisi tapahtua\n"
+
+#: libphodav/chezdav.c:299
+#, c-format
+msgid "Listen failed: %s\n"
+msgstr "Kuuntelu epäonnistui: %s\n"
diff -Nru phodav-2.3/po/LINGUAS phodav-2.4/po/LINGUAS
--- phodav-2.3/po/LINGUAS 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/po/LINGUAS 2020-03-05 11:15:02.000000000 +0000
@@ -5,10 +5,13 @@
de
el
es
+eu
+fi
fur
hr
hu
id
+nl
pl
pt
pt_BR
diff -Nru phodav-2.3/po/nl.po phodav-2.4/po/nl.po
--- phodav-2.3/po/nl.po 1970-01-01 00:00:00.000000000 +0000
+++ phodav-2.4/po/nl.po 2020-03-05 11:15:02.000000000 +0000
@@ -0,0 +1,93 @@
+# Dutch translation for phodav.
+# Copyright (C) 2019 phodav's COPYRIGHT HOLDER
+# This file is distributed under the same license as the phodav package.
+# Nathan Follens , 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: phodav master\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/phodav/issues\n"
+"POT-Creation-Date: 2019-02-27 16:59+0000\n"
+"PO-Revision-Date: 2019-03-04 16:20+0100\n"
+"Language-Team: Dutch \n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Last-Translator: Nathan Follens \n"
+"X-Generator: Poedit 2.2.1\n"
+
+#: libphodav/chezdav.c:203
+msgid "Print program version"
+msgstr "Programmaversie tonen"
+
+#: libphodav/chezdav.c:204
+msgid "Be verbose"
+msgstr "Uitgebreide uitvoer"
+
+#: libphodav/chezdav.c:205
+msgid "Port to listen to"
+msgstr "Poort om op te luisteren"
+
+#: libphodav/chezdav.c:206
+msgid "Listen on loopback only"
+msgstr "Enkel op loopback luisteren"
+
+#: libphodav/chezdav.c:207
+msgid "Listen on all interfaces"
+msgstr "Op alle interfaces luisteren"
+
+#: libphodav/chezdav.c:208
+msgid "Path to export"
+msgstr "Pad naar export"
+
+#: libphodav/chezdav.c:209
+msgid "Path to htdigest file"
+msgstr "Pad naar htdigest-bestand"
+
+#: libphodav/chezdav.c:210
+msgid "Read-only access"
+msgstr "Alleen-lezen-toegang"
+
+#: libphodav/chezdav.c:224
+msgid "- simple WebDAV server"
+msgstr "- eenvoudige WebDAV-server"
+
+#: libphodav/chezdav.c:225
+#, c-format
+msgid "Report bugs to <%s>"
+msgstr "Rapporteer fouten aan <%s>"
+
+#: libphodav/chezdav.c:232
+#, c-format
+msgid "Option parsing failed: %s\n"
+msgstr "Ontleden van optie mislukt: %s\n"
+
+#: libphodav/chezdav.c:236
+#, c-format
+msgid "Unsupported extra arguments: %s ...\n"
+msgstr "Niet-ondersteunde extra parameters: %s …\n"
+
+#: libphodav/chezdav.c:245
+msgid "--local and --public are mutually exclusive\n"
+msgstr "--local en --public sluiten elkaar onderling uit\n"
+
+#: libphodav/chezdav.c:269
+#, c-format
+msgid "Failed to open htdigest: %s\n"
+msgstr "Openen van htdigest mislukt: %s\n"
+
+#: libphodav/chezdav.c:288
+#, c-format
+msgid "mDNS failed: %s\n"
+msgstr "mDNS mislukt: %s\n"
+
+#: libphodav/chezdav.c:299
+msgid "Internal error, should not happen\n"
+msgstr "Interne fout, dit zou niet mogen gebeuren\n"
+
+#: libphodav/chezdav.c:302
+#, c-format
+msgid "Listen failed: %s\n"
+msgstr "Luisteren mislukt: %s\n"
diff -Nru phodav-2.3/README phodav-2.4/README
--- phodav-2.3/README 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/README 1970-01-01 00:00:00.000000000 +0000
@@ -1,31 +0,0 @@
-phởdav
-======
-
-= About
-
-phởdav is a WebDav server implementation using libsoup (RFC 4918).
-
- Releases: http://ftp.gnome.org/pub/GNOME/sources/phodav/
-
-= Tools
-
- chezdav, allows to share a particual directory (with optional
- digest authentication)
-
-= Notes
-
-phởdav was initially developped as a filesharing mechanism for Spice,
-but it is generic enough to be reused in other projects, in particular
-in the GNOME desktop. Further integration work would be a welcome
-contribution!
-
-= Contributing
-
- git clone git://git.gnome.org/phodav
-
- http://lists.freedesktop.org/mailman/listinfo/spice-devel
-
-Please report bug there:
-https://bugzilla.gnome.org/enter_bug.cgi?product=phodav
-
-Forking and sending github pull requests is also welcome.
\ No newline at end of file
diff -Nru phodav-2.3/README.md phodav-2.4/README.md
--- phodav-2.3/README.md 1970-01-01 00:00:00.000000000 +0000
+++ phodav-2.4/README.md 2020-03-05 11:15:02.000000000 +0000
@@ -0,0 +1,31 @@
+# phởdav
+
+## About
+
+phởdav is a WebDav server implementation using libsoup (RFC 4918).
+
+Releases: http://ftp.gnome.org/pub/GNOME/sources/phodav/
+
+## Tools
+
+* chezdav, allows to share a particual directory (with optional
+ digest authentication)
+
+## Notes
+
+phởdav was initially developped as a filesharing mechanism for Spice,
+but it is generic enough to be reused in other projects, in particular
+in the GNOME desktop. Further integration work would be a welcome
+contribution!
+
+## Contributing
+
+ git clone https://gitlab.gnome.org/GNOME/phodav.git
+
+Mailing list:
+http://lists.freedesktop.org/mailman/listinfo/spice-devel
+
+Please report bugs on gitlab:
+https://gitlab.gnome.org/GNOME/phodav/issues
+
+Forking on gitlab and making pull requests is recommended, as it runs CI test.
\ No newline at end of file
diff -Nru phodav-2.3/spice/meson.build phodav-2.4/spice/meson.build
--- phodav-2.3/spice/meson.build 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/spice/meson.build 2020-03-05 11:15:02.000000000 +0000
@@ -4,9 +4,15 @@
win32_deps += compiler.find_library('mpr')
endif
+sources = [
+ 'spice-webdavd.c',
+ 'output-queue.c',
+ 'output-queue.h'
+]
+
executable(
'spice-webdavd',
- [ 'spice-webdavd.c' ],
+ sources + avahi_common,
install_dir : sbindir,
include_directories : incdir,
dependencies : win32_deps + avahi_deps + deps,
diff -Nru phodav-2.3/spice/output-queue.c phodav-2.4/spice/output-queue.c
--- phodav-2.3/spice/output-queue.c 1970-01-01 00:00:00.000000000 +0000
+++ phodav-2.4/spice/output-queue.c 2020-03-05 11:15:02.000000000 +0000
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library 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.1 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 .
+ */
+#include
+
+#include "output-queue.h"
+
+typedef struct _OutputQueueElem
+{
+ const guint8 *buf;
+ gsize size;
+ PushedCb cb;
+ gpointer user_data;
+} OutputQueueElem;
+
+struct _OutputQueue
+{
+ GObject parent_instance;
+ GOutputStream *output;
+ gboolean writing;
+ GQueue *queue;
+ GCancellable *cancel;
+};
+
+G_DEFINE_TYPE (OutputQueue, output_queue, G_TYPE_OBJECT);
+
+static void output_queue_kick (OutputQueue *q);
+
+static void output_queue_init (OutputQueue *self)
+{
+ self->queue = g_queue_new ();
+}
+
+static void output_queue_finalize (GObject *obj)
+{
+ OutputQueue *self = OUTPUT_QUEUE (obj);
+
+ g_queue_free_full (self->queue, g_free);
+ g_object_unref (self->output);
+ g_object_unref (self->cancel);
+
+ G_OBJECT_CLASS (output_queue_parent_class)->finalize (obj);
+}
+
+static void output_queue_class_init (OutputQueueClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = output_queue_finalize;
+}
+
+OutputQueue* output_queue_new (GOutputStream *output, GCancellable *cancel)
+{
+ OutputQueue *self = g_object_new (OUTPUT_TYPE_QUEUE, NULL);
+ self->output = g_object_ref (output);
+ self->cancel = g_object_ref (cancel);
+ return self;
+}
+
+static void
+write_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ OutputQueue *q = user_data;
+ OutputQueueElem *e;
+ GError *err = NULL;
+
+ e = g_queue_pop_head (q->queue);
+ g_output_stream_write_all_finish (G_OUTPUT_STREAM (source_object), res, NULL, &err);
+
+ if (e->cb)
+ e->cb (q, e->user_data, err);
+
+ g_free (e);
+ q->writing = FALSE;
+ if (!err)
+ output_queue_kick (q);
+ g_clear_error (&err);
+ g_object_unref (q);
+}
+
+static void
+output_queue_kick (OutputQueue *q)
+{
+ OutputQueueElem *e;
+
+ if (!q || q->writing || g_queue_is_empty (q->queue))
+ return;
+
+ e = g_queue_peek_head (q->queue);
+ q->writing = TRUE;
+ g_output_stream_write_all_async (q->output, e->buf, e->size,
+ G_PRIORITY_DEFAULT, q->cancel, write_cb, g_object_ref (q));
+}
+
+void
+output_queue_push (OutputQueue *q, const guint8 *buf, gsize size,
+ PushedCb pushed_cb, gpointer user_data)
+{
+ OutputQueueElem *e;
+
+ g_return_if_fail (q != NULL);
+
+ e = g_new (OutputQueueElem, 1);
+ e->buf = buf;
+ e->size = size;
+ e->cb = pushed_cb;
+ e->user_data = user_data;
+ g_queue_push_tail (q->queue, e);
+
+ output_queue_kick (q);
+}
diff -Nru phodav-2.3/spice/output-queue.h phodav-2.4/spice/output-queue.h
--- phodav-2.3/spice/output-queue.h 1970-01-01 00:00:00.000000000 +0000
+++ phodav-2.4/spice/output-queue.h 2020-03-05 11:15:02.000000000 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library 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.1 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 .
+ */
+
+#ifndef __OUTPUT_QUEUE_H
+#define __OUTPUT_QUEUE_H
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define OUTPUT_TYPE_QUEUE output_queue_get_type ()
+G_DECLARE_FINAL_TYPE (OutputQueue, output_queue, OUTPUT, QUEUE, GObject);
+
+OutputQueue* output_queue_new (GOutputStream *output, GCancellable *cancel);
+
+typedef void (*PushedCb) (OutputQueue *q, gpointer user_data, GError *error);
+
+void output_queue_push (OutputQueue *q, const guint8 *buf, gsize size,
+ PushedCb pushed_cb, gpointer user_data);
+
+G_END_DECLS
+
+#endif
diff -Nru phodav-2.3/spice/spice-webdavd.c phodav-2.4/spice/spice-webdavd.c
--- phodav-2.3/spice/spice-webdavd.c 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/spice/spice-webdavd.c 2020-03-05 11:15:02.000000000 +0000
@@ -24,38 +24,22 @@
#include
#include
#include
+#include
+#include
#endif
#ifdef G_OS_WIN32
#include
#include
#include
+#define SERVICE_NAME "spice-webdavd"
#endif
#ifdef WITH_AVAHI
-#include
-#include
+#include "avahi-common.h"
#endif
-typedef struct _OutputQueue
-{
- guint refs;
- GOutputStream *output;
- gboolean flushing;
- guint idle_id;
- GQueue *queue;
-} OutputQueue;
-
-typedef void (*PushedCb) (OutputQueue *q, gpointer user_data, GError *error);
-
-typedef struct _OutputQueueElem
-{
- OutputQueue *queue;
- const guint8 *buf;
- gsize size;
- PushedCb cb;
- gpointer user_data;
-} OutputQueueElem;
+#include "output-queue.h"
typedef struct _ServiceData
{
@@ -67,139 +51,6 @@
static GCancellable *cancel;
-static OutputQueue*
-output_queue_new (GOutputStream *output)
-{
- OutputQueue *queue = g_new0 (OutputQueue, 1);
-
- queue->output = g_object_ref (output);
- queue->queue = g_queue_new ();
- queue->refs = 1;
-
- return queue;
-}
-
-static
-void
-output_queue_free (OutputQueue *queue)
-{
- g_warn_if_fail (g_queue_get_length (queue->queue) == 0);
- g_warn_if_fail (!queue->flushing);
- g_warn_if_fail (!queue->idle_id);
-
- g_queue_free_full (queue->queue, g_free);
- g_clear_object (&queue->output);
- g_free (queue);
-}
-
-static OutputQueue*
-output_queue_ref (OutputQueue *q)
-{
- q->refs++;
- return q;
-}
-
-static void
-output_queue_unref (OutputQueue *q)
-{
- g_return_if_fail (q != NULL);
-
- q->refs--;
- if (q->refs == 0)
- output_queue_free (q);
-}
-
-static gboolean output_queue_idle (gpointer user_data);
-
-static void
-output_queue_flush_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GError *error = NULL;
- OutputQueueElem *e = user_data;
- OutputQueue *q = e->queue;
-
- g_debug ("flushed");
- q->flushing = FALSE;
- g_output_stream_flush_finish (G_OUTPUT_STREAM (source_object),
- res, &error);
- if (error)
- g_warning ("error: %s", error->message);
-
- g_clear_error (&error);
-
- if (!q->idle_id)
- q->idle_id = g_idle_add (output_queue_idle, output_queue_ref (q));
-
- g_free (e);
- output_queue_unref (q);
-}
-
-static gboolean
-output_queue_idle (gpointer user_data)
-{
- OutputQueue *q = user_data;
- OutputQueueElem *e = NULL;
- GError *error = NULL;
-
- if (q->flushing)
- {
- g_debug ("already flushing");
- goto end;
- }
-
- e = g_queue_pop_head (q->queue);
- if (!e)
- {
- g_debug ("No more data to flush");
- goto end;
- }
-
- g_debug ("flushing %" G_GSIZE_FORMAT, e->size);
- g_output_stream_write_all (q->output, e->buf, e->size, NULL, cancel, &error);
- if (e->cb)
- e->cb (q, e->user_data, error);
-
- if (error)
- goto end;
-
- q->flushing = TRUE;
- g_output_stream_flush_async (q->output, G_PRIORITY_DEFAULT, cancel, output_queue_flush_cb, e);
-
- q->idle_id = 0;
- return FALSE;
-
-end:
- g_clear_error (&error);
- q->idle_id = 0;
- g_free (e);
- output_queue_unref (q);
-
- return FALSE;
-}
-
-static void
-output_queue_push (OutputQueue *q, const guint8 *buf, gsize size,
- PushedCb pushed_cb, gpointer user_data)
-{
- OutputQueueElem *e;
-
- g_return_if_fail (q != NULL);
-
- e = g_new (OutputQueueElem, 1);
- e->buf = buf;
- e->size = size;
- e->cb = pushed_cb;
- e->user_data = user_data;
- e->queue = q;
- g_queue_push_tail (q->queue, e);
-
- if (!q->idle_id && !q->flushing)
- q->idle_id = g_idle_add (output_queue_idle, output_queue_ref (q));
-}
-
-
static struct _DemuxData
{
gint64 client;
@@ -209,14 +60,17 @@
typedef struct _Client
{
- gint64 id;
- guint8 buf[G_MAXUINT16];
- guint16 size;
+ guint ref_count;
+ struct
+ {
+ gint64 id;
+ guint16 size;
+ guint8 buf[G_MAXUINT16];
+ } mux;
GSocketConnection *client_connection;
- OutputQueue *queue;
} Client;
-static gboolean quit_service;
+static volatile gboolean quit_service;
static GMainLoop *loop;
static GInputStream *mux_istream;
static GOutputStream *mux_ostream;
@@ -230,9 +84,6 @@
#endif
static void start_mux_read (GInputStream *istream);
-#ifdef WITH_AVAHI
-static void mdns_unregister_service (void);
-#endif
static void
quit (int sig)
@@ -242,144 +93,80 @@
if (sig == SIGINT || sig == SIGTERM)
quit_service = TRUE;
- g_main_loop_quit (loop);
+ if (loop)
+ g_main_loop_quit (loop);
}
+#ifdef G_OS_UNIX
+static gboolean
+signal_handler (gpointer user_data)
+{
+ quit(SIGINT);
+ return G_SOURCE_REMOVE;
+}
+#endif
+
static Client *
add_client (GSocketConnection *client_connection)
{
- GIOStream *iostream = G_IO_STREAM (client_connection);
- GOutputStream *ostream = g_io_stream_get_output_stream (iostream);
- GOutputStream *bostream;
Client *client;
-
- bostream = g_buffered_output_stream_new (ostream);
- g_buffered_output_stream_set_auto_grow (G_BUFFERED_OUTPUT_STREAM (bostream), TRUE);
-
client = g_new0 (Client, 1);
+ client->ref_count = 1;
client->client_connection = g_object_ref (client_connection);
// TODO: check if usage of this idiom is portable, or if we need to check collisions
- client->id = GPOINTER_TO_INT (client_connection);
- client->queue = output_queue_new (bostream);
- g_object_unref (bostream);
-
- g_hash_table_insert (clients, &client->id, client);
- g_warn_if_fail (g_hash_table_lookup (clients, &client->id));
+ client->mux.id = GPOINTER_TO_INT (client_connection);
+ g_hash_table_insert (clients, &client->mux.id, client);
+ g_warn_if_fail (g_hash_table_lookup (clients, &client->mux.id));
return client;
}
+static Client *
+client_ref (Client *c)
+{
+ c->ref_count++;
+ return c;
+}
+
static void
-client_free (Client *c)
+client_unref (gpointer user_data)
{
- g_debug ("Free client %p", c);
+ Client *c = user_data;
+ if (--c->ref_count > 0)
+ return;
+
+ g_debug ("Free client %" G_GINT64_FORMAT, c->mux.id);
g_io_stream_close (G_IO_STREAM (c->client_connection), NULL, NULL);
g_object_unref (c->client_connection);
- output_queue_unref (c->queue);
g_free (c);
}
static void
remove_client (Client *client)
{
- g_debug ("remove client %p", client);
+ g_debug ("remove client %" G_GINT64_FORMAT, client->mux.id);
- g_hash_table_remove (clients, &client->id);
+ g_hash_table_remove (clients, &client->mux.id);
}
-typedef struct ReadData
-{
- void *buffer;
- gsize count;
-} ReadData;
-
static void
-read_thread (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
+mux_pushed_client_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
+ Client *client = user_data;
GError *error = NULL;
- GInputStream *stream = G_INPUT_STREAM (source_object);
- ReadData *data;
- gsize bread;
-
- data = g_task_get_task_data (task);
-
- g_debug ("my read %" G_GSIZE_FORMAT, data->count);
- g_input_stream_read_all (stream,
- data->buffer, data->count, &bread,
- cancellable, &error);
- g_debug ("my read result %" G_GSIZE_FORMAT, bread);
+ g_output_stream_write_all_finish (G_OUTPUT_STREAM (source_object), res, NULL, &error);
if (error)
{
- g_debug ("error: %s", error->message);
- g_task_return_error (task, error);
- }
- if (bread != data->count)
- {
- g_task_return_int (task, -1);
- }
- else
- {
- g_task_return_int (task, bread);
+ g_warning ("error pushing to client %" G_GINT64_FORMAT ": %s",
+ client->mux.id, error->message);
+ g_error_free (error);
+ remove_client (client);
}
-}
-
-static void
-my_input_stream_read_async (GInputStream *stream,
- void *buffer,
- gsize count,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GTask *task;
- ReadData *data = g_new (ReadData, 1);
-
- data->buffer = buffer;
- data->count = count;
-
- task = g_task_new (stream, cancellable, callback, user_data);
- g_task_set_task_data (task, data, g_free);
- g_task_run_in_thread (task, read_thread);
-
- g_object_unref (task);
-}
-
-static gssize
-my_input_stream_read_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_task_is_valid (result, stream), -1);
-
- return g_task_propagate_int (G_TASK (result), error);
-}
-
-static void
-handle_push_error (OutputQueue *q, gpointer user_data, GError *error)
-{
- Client *client = user_data;
-
- if (!error)
- return;
-
- g_warning ("push error: %s", error->message);
- remove_client (client);
- return;
-}
-
-static void
-mux_pushed_client_cb (OutputQueue *q, gpointer user_data, GError *error)
-{
- if (error) {
- handle_push_error (q, user_data, error);
- return;
- }
+ client_unref (client);
start_mux_read (mux_istream);
}
@@ -390,25 +177,31 @@
gpointer user_data)
{
GError *error = NULL;
- gssize size;
+ gsize size;
- size = my_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
- g_return_if_fail (size == demux.size);
+ g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &size, &error);
+ g_debug ("read %" G_GSIZE_FORMAT " bytes from mux", size);
if (error)
{
- g_warning ("error: %s", error->message);
+ g_warning ("%s: error: %s", __FUNCTION__, error->message);
g_clear_error (&error);
+ }
+ if (size != demux.size)
+ {
quit (-1);
return;
}
Client *c = g_hash_table_lookup (clients, &demux.client);
- g_debug ("looked up client: %p", c);
- g_warn_if_fail(c != NULL);
+ g_debug ("looked up client %" G_GINT64_FORMAT ": %p", demux.client, c);
if (c)
- output_queue_push (c->queue, (guint8 *) demux.buf, demux.size,
- mux_pushed_client_cb, c);
+ {
+ GOutputStream *out;
+ out = g_io_stream_get_output_stream (G_IO_STREAM (c->client_connection));
+ g_output_stream_write_all_async (out, demux.buf, demux.size,
+ G_PRIORITY_DEFAULT, cancel, mux_pushed_client_cb, client_ref (c));
+ }
else
start_mux_read (mux_istream);
}
@@ -420,21 +213,21 @@
{
GInputStream *istream = G_INPUT_STREAM (source_object);
GError *error = NULL;
- gssize size;
+ gsize size;
- size = my_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
+ g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &size, &error);
if (error || size != sizeof (guint16))
goto end;
- my_input_stream_read_async (istream,
- &demux.buf, demux.size, G_PRIORITY_DEFAULT,
- cancel, mux_data_read_cb, NULL);
+ g_input_stream_read_all_async (istream,
+ &demux.buf, demux.size, G_PRIORITY_DEFAULT,
+ cancel, mux_data_read_cb, NULL);
return;
end:
if (error)
{
- g_warning ("error: %s", error->message);
+ g_warning ("%s: error: %s", __FUNCTION__, error->message);
g_clear_error (&error);
}
@@ -448,36 +241,33 @@
{
GInputStream *istream = G_INPUT_STREAM (source_object);
GError *error = NULL;
- gssize size;
+ gsize size;
- size = my_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
- g_debug ("read %" G_GSSIZE_FORMAT, size);
+ g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &size, &error);
if (error || size != sizeof (gint64))
goto end;
- my_input_stream_read_async (istream,
- &demux.size, sizeof (guint16), G_PRIORITY_DEFAULT,
- cancel, mux_size_read_cb, NULL);
+ g_input_stream_read_all_async (istream,
+ &demux.size, sizeof (guint16), G_PRIORITY_DEFAULT,
+ cancel, mux_size_read_cb, NULL);
return;
end:
if (error)
{
- g_warning ("error: %s", error->message);
+ g_warning ("%s: error: %s", __FUNCTION__, error->message);
g_clear_error (&error);
}
-#ifdef WITH_AVAHI
- mdns_unregister_service ();
-#endif
quit (-3);
}
static void
start_mux_read (GInputStream *istream)
{
- my_input_stream_read_async (istream,
- &demux.client, sizeof (gint64), G_PRIORITY_DEFAULT,
- cancel, mux_client_read_cb, NULL);
+ g_debug ("start reading mux");
+ g_input_stream_read_all_async (istream,
+ &demux.client, sizeof (gint64), G_PRIORITY_DEFAULT,
+ cancel, mux_client_read_cb, NULL);
}
static void client_start_read (Client *client);
@@ -487,18 +277,23 @@
{
Client *client = user_data;
- if (error) {
- handle_push_error (q, client, error);
- return;
- }
+ if (error)
+ {
+ g_warning ("error pushing to mux from client %" G_GINT64_FORMAT ": %s",
+ client->mux.id, error->message);
+ remove_client (client);
+ goto end;
+ }
- if (client->size == 0)
+ if (client->mux.size == 0)
{
remove_client (client);
- return;
+ goto end;
}
client_start_read (client);
+end:
+ client_unref (client);
}
static void
@@ -511,24 +306,23 @@
gssize size;
size = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
- g_debug ("end read %" G_GSSIZE_FORMAT, size);
+ g_debug ("read %" G_GSSIZE_FORMAT " bytes from client %" G_GINT64_FORMAT, size, client->mux.id);
if (error)
{
- g_warning ("error: %s", error->message);
+ g_warning ("%s: error for client %" G_GINT64_FORMAT ": %s",
+ __FUNCTION__, client->mux.id, error->message);
g_clear_error (&error);
remove_client (client);
+ client_unref (client);
return;
}
g_return_if_fail (size <= G_MAXUINT16);
g_return_if_fail (size >= 0);
- client->size = size;
-
- output_queue_push (mux_queue, (guint8 *) &client->id, sizeof (gint64), handle_push_error, client);
- output_queue_push (mux_queue, (guint8 *) &client->size, sizeof (guint16), handle_push_error, client);
- output_queue_push (mux_queue, (guint8 *) client->buf, size, mux_pushed_cb, client);
+ client->mux.size = size;
- return;
+ output_queue_push (mux_queue, (guint8 *) &client->mux,
+ sizeof (gint64) + sizeof (guint16) + size, mux_pushed_cb, client);
}
static void
@@ -537,10 +331,10 @@
GIOStream *iostream = G_IO_STREAM (client->client_connection);
GInputStream *istream = g_io_stream_get_input_stream (iostream);
- g_debug ("start read client %p", client);
+ g_debug ("start read client %" G_GINT64_FORMAT, client->mux.id);
g_input_stream_read_async (istream,
- client->buf, G_MAXUINT16, G_PRIORITY_DEFAULT,
- NULL, client_read_cb, client);
+ client->mux.buf, G_MAXUINT16, G_PRIORITY_DEFAULT,
+ cancel, client_read_cb, client_ref (client));
}
static gboolean
@@ -551,8 +345,8 @@
{
Client *client;
- g_debug ("new client!");
client = add_client (client_connection);
+ g_debug ("new client %" G_GINT64_FORMAT, client->mux.id);
client_start_read (client);
return FALSE;
@@ -564,114 +358,6 @@
static gboolean no_service;
#endif
-#ifdef WITH_AVAHI
-static GaClient *mdns_client;
-static GaEntryGroup *mdns_group;
-static GaEntryGroupService *mdns_service;
-
-static void
-mdns_register_service (void)
-{
- GError *error = NULL;
- gchar *name = NULL;
-
- if (!mdns_group)
- {
- mdns_group = ga_entry_group_new ();
-
- if (!ga_entry_group_attach (mdns_group, mdns_client, &error))
- {
- g_warning ("Could not attach MDNS group to client: %s", error->message);
- g_clear_error (&error);
- goto end;
- }
- }
-
- name = g_strdup_printf ("Spice client folder");
- mdns_service = ga_entry_group_add_service (mdns_group,
- name, "_webdav._tcp",
- port, &error,
- NULL);
- if (!mdns_service)
- {
- g_warning ("Could not create service: %s", error->message);
- g_clear_error (&error);
- goto end;
-
- }
-
- ga_entry_group_service_freeze (mdns_service);
- if (!ga_entry_group_service_set (mdns_service, "u", "", &error) ||
- !ga_entry_group_service_set (mdns_service, "p", "", &error) ||
- !ga_entry_group_service_set (mdns_service, "path", "/", &error) ||
- !ga_entry_group_service_thaw (mdns_service, &error))
- {
- g_warning ("Could not update TXT: %s", error->message);
- g_clear_error (&error);
- }
-
- if (!ga_entry_group_commit (mdns_group, &error))
- {
- g_warning ("Could not announce MDNS service: %s", error->message);
- g_clear_error (&error);
- }
-
-end:
- g_free (name);
-}
-
-static void
-mdns_unregister_service (void)
-{
- GError *error = NULL;
-
- if (mdns_group)
- {
- if (!ga_entry_group_reset (mdns_group, &error))
- {
- g_warning ("Could not disconnect MDNS service: %s", error->message);
- g_clear_error (&error);
- }
-
- mdns_service = 0;
- g_debug ("MDNS client disconected");
- }
-}
-
-static void
-mdns_state_changed (GaClient *client, GaClientState state, gpointer user_data)
-{
- switch (state)
- {
- case GA_CLIENT_STATE_FAILURE:
- g_warning ("MDNS client state failure");
- break;
-
- case GA_CLIENT_STATE_S_RUNNING:
- g_debug ("MDNS client found server running");
- mdns_register_service ();
- break;
-
- case GA_CLIENT_STATE_S_COLLISION:
- case GA_CLIENT_STATE_S_REGISTERING:
- g_message ("MDNS collision");
- mdns_unregister_service ();
- break;
-
- default:
- // Do nothing
- break;
- }
-}
-#endif
-
-#ifndef G_SOURCE_REMOVE
-#define G_SOURCE_REMOVE FALSE
-#endif
-#ifndef G_SOURCE_CONTINUE
-#define G_SOURCE_CONTINUE TRUE
-#endif
-
#ifdef G_OS_UNIX
static void
wait_for_virtio_host (gint fd)
@@ -708,8 +394,12 @@
g_debug ("Open %s", path);
#ifdef G_OS_UNIX
port_fd = g_open (path, O_RDWR);
+ gint errsv = errno;
if (port_fd == -1)
+ {
+ g_printerr("Failed to open %s: %s\n", path, g_strerror(errsv));
exit (1);
+ }
wait_for_virtio_host (port_fd);
@@ -731,18 +421,12 @@
mux_istream = G_INPUT_STREAM (g_win32_input_stream_new (port_handle, TRUE));
#endif
- mux_queue = output_queue_new (G_OUTPUT_STREAM (mux_ostream));
+ mux_queue = output_queue_new (G_OUTPUT_STREAM (mux_ostream), cancel);
}
#ifdef G_OS_WIN32
#define MAX_SHARED_FOLDER_NAME_SIZE 64
#define MAX_DRIVE_LETTER_SIZE 3
-typedef enum _MapDriveEnum
-{
- MAP_DRIVE_OK,
- MAP_DRIVE_TRY_AGAIN,
- MAP_DRIVE_ERROR
-} MapDriveEnum;
typedef struct _MapDriveData
{
@@ -827,7 +511,7 @@
g_free(net_resource->lpRemoteName);
}
-static MapDriveEnum
+static guint32
map_drive(const gchar drive_letter)
{
NETRESOURCE net_resource;
@@ -840,16 +524,17 @@
if (errn == NO_ERROR)
{
g_debug ("Shared folder mapped to %c succesfully", drive_letter);
- return MAP_DRIVE_OK;
}
else if (errn == ERROR_ALREADY_ASSIGNED)
{
g_debug ("Drive letter %c is already assigned", drive_letter);
- return MAP_DRIVE_TRY_AGAIN;
+ }
+ else
+ {
+ g_warning ("map_drive error %d", errn);
}
- g_warning ("map_drive error %d", errn);
- return MAP_DRIVE_ERROR;
+ return errn;
}
static void
@@ -876,7 +561,6 @@
}
g_mutex_unlock(&service_data->mutex);
- return;
}
static void
@@ -914,14 +598,20 @@
break;
}
- if (map_drive (drive_letter) != MAP_DRIVE_TRY_AGAIN)
+ ret = map_drive (drive_letter);
+ if (ret == ERROR_ALREADY_ASSIGNED)
{
- break;
+ /* try again with another letter */
+ continue;
}
+ if (ret != NO_ERROR)
+ {
+ drive_letter = 0;
+ }
+ break;
//TODO: After mapping, rename network drive from \\localhost@PORT\DavWWWRoot
// to something like SPICE Shared Folder
}
-
g_mutex_lock(&map_drive_data->service_data->mutex);
map_drive_data->service_data->drive_letter = drive_letter;
g_mutex_unlock(&map_drive_data->service_data->mutex);
@@ -929,11 +619,15 @@
#endif
-static void
+/* returns FALSE if the service should quit */
+static gboolean
run_service (ServiceData *service_data)
{
g_debug ("Run service");
+ if (quit_service)
+ return FALSE;
+
#ifdef G_OS_WIN32
MapDriveData map_drive_data;
map_drive_data.cancel_map = g_cancellable_new ();
@@ -957,7 +651,7 @@
cancel = g_cancellable_new ();
clients = g_hash_table_new_full (g_int64_hash, g_int64_equal,
- NULL, (GDestroyNotify) client_free);
+ NULL, client_unref);
loop = g_main_loop_new (NULL, TRUE);
#ifdef G_OS_UNIX
@@ -972,10 +666,7 @@
#ifdef WITH_AVAHI
GError *error = NULL;
-
- mdns_client = ga_client_new (GA_CLIENT_FLAG_NO_FLAGS);
- g_signal_connect (mdns_client, "state-changed", G_CALLBACK (mdns_state_changed), NULL);
- if (!ga_client_start (mdns_client, &error))
+ if (!avahi_client_start ("Spice client folder", port, TRUE, &error))
{
g_printerr ("%s\n", error->message);
exit (1);
@@ -984,7 +675,7 @@
start_mux_read (mux_istream);
g_main_loop_run (loop);
- g_main_loop_unref (loop);
+ g_clear_pointer (&loop, g_main_loop_unref);
#ifdef G_OS_WIN32
g_cancellable_cancel (map_drive_data.cancel_map);
@@ -996,12 +687,14 @@
g_clear_object (&mux_istream);
g_clear_object (&mux_ostream);
- output_queue_unref (mux_queue);
+ g_clear_object (&mux_queue);
g_hash_table_unref (clients);
+#ifdef WITH_AVAHI
+ avahi_client_stop ();
+#endif
g_socket_service_stop (socket_service);
- mux_queue = NULL;
g_clear_object (&cancel);
#ifdef G_OS_WIN32
@@ -1009,6 +702,7 @@
#else
close (port_fd);
#endif
+ return !quit_service;
}
#ifdef G_OS_WIN32
@@ -1057,7 +751,7 @@
g_mutex_init(&service_data.mutex);
service_status_handle =
- RegisterServiceCtrlHandlerEx ("spice-webdavd", service_ctrl_handler, &service_data);
+ RegisterServiceCtrlHandlerEx (SERVICE_NAME, service_ctrl_handler, &service_data);
g_return_if_fail (service_status_handle != 0);
@@ -1070,9 +764,8 @@
service_status.dwWaitHint = 0;
SetServiceStatus (service_status_handle, &service_status);
- while (!quit_service) {
- run_service (&service_data);
- g_usleep (G_USEC_PER_SEC);
+ while (run_service(&service_data)) {
+ g_usleep(G_USEC_PER_SEC);
}
service_status.dwCurrentState = SERVICE_STOPPED;
@@ -1116,7 +809,11 @@
}
g_option_context_free (opts);
+#ifdef G_OS_UNIX
+ g_unix_signal_add (SIGINT, signal_handler, NULL);
+#else
signal (SIGINT, quit);
+#endif
/* run socket service once at beginning, there seems to be a bug on
windows, and it can't accept new connections if cleanup and
@@ -1133,6 +830,7 @@
NULL,
NULL,
&error);
+ g_object_unref (saddr);
if (error)
{
g_printerr ("%s\n", error->message);
@@ -1149,7 +847,7 @@
SERVICE_TABLE_ENTRY service_table[] =
{
- { (char *)"spice-webdavd", service_main }, { NULL, NULL }
+ { SERVICE_NAME, service_main }, { NULL, NULL }
};
if (!no_service && !getenv("DEBUG"))
{
@@ -1160,8 +858,7 @@
}
} else
#endif
- while (!quit_service) {
- run_service (&service_data);
+ while (run_service(&service_data)) {
g_usleep (G_USEC_PER_SEC);
}
diff -Nru phodav-2.3/.tarball-version phodav-2.4/.tarball-version
--- phodav-2.3/.tarball-version 2019-02-26 18:12:17.000000000 +0000
+++ phodav-2.4/.tarball-version 2020-03-05 11:15:02.000000000 +0000
@@ -1 +1 @@
-2.3
+2.4