Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package usbredir for openSUSE:Factory 
checked in at 2022-08-10 17:12:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/usbredir (Old)
 and      /work/SRC/openSUSE:Factory/.usbredir.new.1521 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "usbredir"

Wed Aug 10 17:12:46 2022 rev:20 rq:993933 version:0.13.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/usbredir/usbredir.changes        2022-06-09 
14:09:33.280348000 +0200
+++ /work/SRC/openSUSE:Factory/.usbredir.new.1521/usbredir.changes      
2022-08-10 17:13:00.673662768 +0200
@@ -1,0 +2,15 @@
+Tue Aug  9 08:19:29 UTC 2022 - Dominique Leuenberger <[email protected]>
+
+- Update to version 0.13.0:
+  + Fix regression on unserialize data
+  + Removes usbredirserver
+  + Improved header length checks when unserialising data
+  + Fix usage of command line argument in usbredirect
+  + Fix small memory leak on usbredirect
+- Drop 9426fdb1.patch and dffc41c3.patch: fixed upstream.
+- Drop
+  0001-Use-D_FORTIFY_SOURCE-instead-of-Wp-D_FORTIFY_SOURCE.patch:
+  fixed upstream.
+- Add keyring to validate source signature.
+
+-------------------------------------------------------------------
@@ -4 +19 @@
-- Add upstream backported patches:
+- Add upstream backported patches (boo#1199354):

Old:
----
  0001-Use-D_FORTIFY_SOURCE-instead-of-Wp-D_FORTIFY_SOURCE.patch
  9426fdb1.patch
  dffc41c3.patch
  usbredir-0.12.0.tar.xz
  usbredir-0.12.0.tar.xz.sig

New:
----
  usbredir-0.13.0.tar.xz
  usbredir-0.13.0.tar.xz.sig
  usbredir.keyring

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ usbredir.spec ++++++
--- /var/tmp/diff_new_pack.b6tNOB/_old  2022-08-10 17:13:01.773665639 +0200
+++ /var/tmp/diff_new_pack.b6tNOB/_new  2022-08-10 17:13:01.781665660 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           usbredir
-Version:        0.12.0
+Version:        0.13.0
 Release:        0
 Summary:        A protocol for redirecting USB traffic
 License:        GPL-2.0-or-later AND LGPL-2.1-or-later
@@ -26,9 +26,7 @@
 URL:            https://www.spice-space.org/usbredir.html
 Source:         
https://www.spice-space.org/download/usbredir/%{name}-%{version}.tar.xz
 Source1:        
https://www.spice-space.org/download/usbredir/%{name}-%{version}.tar.xz.sig
-Patch0:         
https://gitlab.freedesktop.org/spice/usbredir/-/commit/9426fdb1.patch
-Patch1:         
https://gitlab.freedesktop.org/spice/usbredir/-/commit/dffc41c3.patch
-Patch2:         0001-Use-D_FORTIFY_SOURCE-instead-of-Wp-D_FORTIFY_SOURCE.patch
+Source99:       %{name}.keyring
 BuildRequires:  gcc-c++
 BuildRequires:  glib2-devel >= 2.44
 BuildRequires:  meson >= 0.48
@@ -96,8 +94,6 @@
 %license COPYING
 %{_bindir}/usbredirect
 %{_mandir}/man1/usbredirect.1.gz
-%{_mandir}/man1/usbredirserver.1.gz
-%{_sbindir}/usbredirserver
 
 %files -n libusbredirhost1
 %defattr(-, root, root)

++++++ usbredir-0.12.0.tar.xz -> usbredir-0.13.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/ChangeLog.md 
new/usbredir-0.13.0/ChangeLog.md
--- old/usbredir-0.12.0/ChangeLog.md    2021-11-12 11:45:49.992210900 +0100
+++ new/usbredir-0.13.0/ChangeLog.md    2022-08-02 19:35:49.000000000 +0200
@@ -1,3 +1,11 @@
+# usbredir-0.13.0 - 01 Aug 2022
+
+- !61 Fix regression on unserialize data
+- !59 Removes usbredirserver
+- !58 Improved header length checks when unserialising data
+- !62 Fix usage of command line argument in usbredirect
+- !57 Fix small memory leak on usbredirect
+
 # usbredir-0.12.0 - 12 Nov 2021
 
 - !47 Implement dropping packets from isochronous devices
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/README.md 
new/usbredir-0.13.0/README.md
--- old/usbredir-0.12.0/README.md       2021-11-12 11:45:49.992210900 +0100
+++ new/usbredir-0.13.0/README.md       2022-08-02 19:35:49.000000000 +0200
@@ -22,9 +22,11 @@
 - Provide write and read callbacks for the actual transport of usbredir data
 - Monitor for usbredir and libusb read/write events and call their handlers
 
-## usbredirserver
+## usbredirect
 
-A simple tcp server usb-host, using usbredirhost
+The usbredirect binary is an usbredir client for exporting an USB device either
+as TCP client or server, for use from another (virtual) machine through the
+usbredir protocol.
 
 ## usbredirtestclient
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/docs/how_to_release.md 
new/usbredir-0.13.0/docs/how_to_release.md
--- old/usbredir-0.12.0/docs/how_to_release.md  1970-01-01 01:00:00.000000000 
+0100
+++ new/usbredir-0.13.0/docs/how_to_release.md  2022-08-02 19:35:49.000000000 
+0200
@@ -0,0 +1,48 @@
+How to do a usbredir release
+============================
+
+Some notes to prepare a release, not really strict but better to have in order
+to avoid forgetting something.
+
+Preparing for the release
+-------------------------
+
+* Update the root `meson.build` and also the ones in usbredirparser and
+  usbredirhost directories according to libtool rules.
+* Update `ChangeLog.md` with list of changes done since last release
+* Send a merge request with such changes, handle the review and merge it
+
+Generate source tarball and tags
+--------------------------------
+
+* Tag the merged commit with release version `git tag -s -m "Release $version" 
$version`
+* Be sure to be in a clean environment: `git clean -xfd`
+* Create the source tarball with: `meson . build && meson dist -C build`
+* Sign generated tarball: `cd build/meson-dist && gpg2 -sb 
usbredir-$version.tar.xz`
+* If you have a Fedora account, you can proceed and check if
+  a scratch-build works as expected.
+
+Generate the MSI installer
+--------------------------
+
+* On the usbredir srcdir `mkdir build-win64 && cd build-win64`
+* `mingw64-meson`
+* `DESTDIR=./install-root ninja install`
+* `DESTDIR=./install-root ninja data/usbredirect-x64-$version.msi`
+* The MSI installer is then located at `build-win64/data`
+
+Upload and update Info
+----------------------
+
+* Upload tarball and relative signature to
+  `https://www.spice-space.org/download/usbredir/` and the MSI installer to
+  `https://www.spice-space.org/download/windows/usbredirect/` with sftp
+  `[email protected]:/var/www/www.spice-space.org/download/`
+* Push the tag to Gitlab `git push origin HEAD:main --tags`
+* On Gitlab update tags (https://gitlab.freedesktop.org/spice/usbredir/-/tags)
+  * Add ChangeLog information
+  * Upload tarball with the signature
+  * Upload the MSI installer
+* Update file `download.rst` in
+  https://gitlab.freedesktop.org/spice/spice-space-pages
+* Create a merge request for `spice-space-pages`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/meson.build 
new/usbredir-0.13.0/meson.build
--- old/usbredir-0.12.0/meson.build     2021-11-12 11:45:50.003210800 +0100
+++ new/usbredir-0.13.0/meson.build     2022-08-02 19:35:49.000000000 +0200
@@ -1,5 +1,5 @@
 project('usbredir', 'c',
-    version: '0.12.0',
+    version: '0.13.0',
     license: 'LGPLv2.1+',
     meson_version : '>= 0.53',
     default_options : [
@@ -15,7 +15,7 @@
     '--param=ssp-buffer-size=4',
 ]
 if host_machine.system() != 'windows'
-    cc_flags += [ '-Wp,-D_FORTIFY_SOURCE=2' ]
+    cc_flags += [ '-D_FORTIFY_SOURCE=2' ]
     if not get_option('stack_protector').disabled()
         cc_flags += [ '-fstack-protector' ]
     endif
@@ -103,7 +103,6 @@
     subdir('tools')
 endif
 if host_machine.system() != 'windows'
-    subdir('usbredirserver')
     subdir('usbredirtestclient')
 
     if get_option('fuzzing').enabled()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/tests/meson.build 
new/usbredir-0.13.0/tests/meson.build
--- old/usbredir-0.12.0/tests/meson.build       2021-11-12 11:45:50.006210800 
+0100
+++ new/usbredir-0.13.0/tests/meson.build       2022-08-02 19:35:49.000000000 
+0200
@@ -1,5 +1,6 @@
 tests = [
     'filter',
+    'serializer',
 ]
 
 deps = dependency('glib-2.0')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/tests/serializer.c 
new/usbredir-0.13.0/tests/serializer.c
--- old/usbredir-0.12.0/tests/serializer.c      1970-01-01 01:00:00.000000000 
+0100
+++ new/usbredir-0.13.0/tests/serializer.c      2022-08-02 19:35:49.000000000 
+0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2022 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 <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#define G_LOG_DOMAIN "serializer"
+#define G_LOG_USE_STRUCTURED
+
+#include "usbredirparser.h"
+
+#include <errno.h>
+#include <locale.h>
+#include <glib.h>
+#include <stdlib.h>
+
+
+static void
+log_cb(void *priv, int level, const char *msg)
+{
+    GLogLevelFlags glog_level;
+
+    switch(level) {
+    case usbredirparser_error:
+        glog_level = G_LOG_LEVEL_ERROR;
+        break;
+    case usbredirparser_warning:
+        glog_level = G_LOG_LEVEL_WARNING;
+        break;
+    case usbredirparser_info:
+        glog_level = G_LOG_LEVEL_INFO;
+        break;
+    case usbredirparser_debug:
+    case usbredirparser_debug_data:
+        glog_level = G_LOG_LEVEL_DEBUG;
+        break;
+    default:
+        g_warn_if_reached();
+        return;
+    }
+    g_log_structured(G_LOG_DOMAIN, glog_level, "MESSAGE", msg);
+}
+
+static struct usbredirparser *
+get_usbredirparser(void)
+{
+    struct usbredirparser *parser = usbredirparser_create();
+    g_assert_nonnull(parser);
+
+    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
+    /* Typical caps set by usbredirhost */
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_device_disconnect_ack);
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving);
+#if LIBUSBX_API_VERSION >= 0x01000103
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_streams);
+#endif
+    int parser_flags = usbredirparser_fl_usb_host;
+
+    parser->log_func = log_cb;
+    usbredirparser_init(parser,
+                        PACKAGE_STRING,
+                        caps,
+                        USB_REDIR_CAPS_SIZE,
+                        parser_flags);
+    return parser;
+}
+
+static void
+simple (gconstpointer user_data)
+{
+    uint8_t *state = NULL;
+    int ret, len = -1;
+
+    struct usbredirparser *source = get_usbredirparser();
+    ret = usbredirparser_serialize(source, &state, &len);
+    g_assert_cmpint(ret, ==, 0);
+
+    struct usbredirparser *target = get_usbredirparser();
+    ret = usbredirparser_unserialize(target, state, len);
+    g_assert_cmpint(ret, ==, 0);
+
+    g_clear_pointer(&state, free);
+    usbredirparser_destroy(source);
+    usbredirparser_destroy(target);
+}
+
+int
+main(int argc, char **argv)
+{
+    setlocale(LC_ALL, "");
+    g_test_init(&argc, &argv, NULL);
+
+    g_test_add_data_func("/serializer/serialize-and-unserialize", NULL, 
simple);
+
+    return g_test_run();
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/tools/usbredirect.c 
new/usbredir-0.13.0/tools/usbredirect.c
--- old/usbredir-0.12.0/tools/usbredirect.c     2021-11-12 11:45:50.009210800 
+0100
+++ new/usbredir-0.13.0/tools/usbredirect.c     2022-08-02 19:35:49.000000000 
+0200
@@ -59,6 +59,7 @@
         }
         gint64 bus = g_ascii_strtoll(usbid[0], NULL, 10);
         gint64 addr = g_ascii_strtoll(usbid[1], NULL, 10);
+        g_strfreev(usbid);
 
         libusb_device **list = NULL;
         ssize_t i, n;
@@ -566,7 +567,12 @@
         GSocketService *socket_service;
 
         socket_service = g_socket_service_new ();
-        GInetAddress *iaddr = 
g_inet_address_new_loopback(G_SOCKET_FAMILY_IPV4);
+        GInetAddress *iaddr = g_inet_address_new_from_string(self->addr);
+        if (iaddr == NULL) {
+            g_warning("Failed to parse IP: %s", self->addr);
+            goto end;
+        }
+
         GSocketAddress *saddr = g_inet_socket_address_new(iaddr, self->port);
         g_object_unref(iaddr);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/usbredirparser/meson.build 
new/usbredir-0.13.0/usbredirparser/meson.build
--- old/usbredir-0.12.0/usbredirparser/meson.build      2021-11-12 
11:45:50.013210800 +0100
+++ new/usbredir-0.13.0/usbredirparser/meson.build      2022-08-02 
19:35:49.000000000 +0200
@@ -1,7 +1,7 @@
 # so verison, see:
 # 
http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
 usbredir_parser_current = 3
-usbredir_parser_revision = 0
+usbredir_parser_revision = 1
 usbredir_parser_age = 2
 usbredir_parser_so_version = '@0@.@1@.@2@'.format(
     usbredir_parser_current - usbredir_parser_age,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/usbredirparser/usbredirparser.c 
new/usbredir-0.13.0/usbredirparser/usbredirparser.c
--- old/usbredir-0.12.0/usbredirparser/usbredirparser.c 2021-11-12 
11:45:50.017210700 +0100
+++ new/usbredir-0.13.0/usbredirparser/usbredirparser.c 2022-08-02 
19:35:49.000000000 +0200
@@ -1816,15 +1816,28 @@
         return -1;
     }
 
-    if (!(parser->write_buf_count == 0 && parser->write_buf == NULL &&
-          parser->write_buf_total_size == 0 &&
-          parser->data == NULL && parser->header_read == 0 &&
+    if (!(parser->data == NULL && parser->header_read == 0 &&
           parser->type_header_read == 0 && parser->data_read == 0)) {
         ERROR("unserialization must use a pristine parser");
         usbredirparser_assert_invariants(parser);
         return -1;
     }
 
+    {
+        /* We need to reset parser's state to receive unserialized
+         * data. */
+        struct usbredirparser_buf *wbuf = parser->write_buf;
+        while (wbuf) {
+            struct usbredirparser_buf *next_wbuf = wbuf->next;
+            free(wbuf->buf);
+            free(wbuf);
+            wbuf = next_wbuf;
+        }
+        parser->write_buf = NULL;
+        parser->write_buf_count = 0;
+        parser->write_buf_total_size = 0;
+    }
+
     if (unserialize_int(parser, &state, &remain, &i, "length")) {
         usbredirparser_assert_invariants(parser);
         return -1;
@@ -1881,21 +1894,22 @@
     header_len = usbredirparser_get_header_len(parser_pub);
     data = (uint8_t *)&parser->header;
     i = header_len;
+    memset(&parser->header, 0, sizeof(parser->header));
     if (unserialize_data(parser, &state, &remain, &data, &i, "header")) {
         usbredirparser_assert_invariants(parser);
         return -1;
     }
+    if (parser->header.length > MAX_PACKET_SIZE) {
+        ERROR("packet length of %d larger than permitted %d bytes",
+              parser->header.length, MAX_PACKET_SIZE);
+        usbredirparser_assert_invariants(parser);
+        return -1;
+    }
     parser->header_read = i;
     parser->type_header_len = 0;
 
     /* Set various length field from the header (if any) */
     if (parser->header_read == header_len) {
-        if (parser->header.length > MAX_PACKET_SIZE) {
-            ERROR("packet length of %d larger than permitted %d bytes",
-                  parser->header.length, MAX_PACKET_SIZE);
-            return -1;
-        }
-
         int type_header_len =
             usbredirparser_get_type_header_len(parser_pub,
                                                parser->header.type, 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/usbredirserver/meson.build 
new/usbredir-0.13.0/usbredirserver/meson.build
--- old/usbredir-0.12.0/usbredirserver/meson.build      2021-11-12 
11:45:50.021210700 +0100
+++ new/usbredir-0.13.0/usbredirserver/meson.build      1970-01-01 
01:00:00.000000000 +0100
@@ -1,12 +0,0 @@
-usbredirserver_sources = [
-    'usbredirserver.c',
-]
-
-executable('usbredirserver',
-    sources : usbredirserver_sources,
-    c_args : '-Wno-deprecated-declarations',
-    install : true,
-    install_dir: get_option('sbindir'),
-    dependencies : usbredir_host_lib_dep)
-
-install_man('usbredirserver.1')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/usbredirserver/usbredirserver.1 
new/usbredir-0.13.0/usbredirserver/usbredirserver.1
--- old/usbredir-0.12.0/usbredirserver/usbredirserver.1 2021-11-12 
11:45:50.021210700 +0100
+++ new/usbredir-0.13.0/usbredirserver/usbredirserver.1 1970-01-01 
01:00:00.000000000 +0100
@@ -1,41 +0,0 @@
-.TH USBREDIRSERVER "1" "April 2012" "usbredirserver" "User Commands"
-.SH NAME
-usbredirserver \- exporting an USB device for use from another (virtual) 
machine
-.SH SYNOPSIS
-.B usbredirserver
-[\fI-p|--port <port>\fR] [\fI-v|--verbose <0-5>\fR] [\fI-4 <ipv4_addr|I-6 
<ipv6_addr>]
-\fI<busnum-devnum|vendorid:prodid>\fR
-.SH DESCRIPTION
-usbredirserver is a small standalone server for exporting an USB device for
-use from another (virtual) machine through the usbredir protocol.
-.PP
-You can specify the USB device to export either by USB id in the form of
-\fI<vendorid>:<prodid>\fR, or by USB bus number and device address in the form
-of \fI<usbbus>-<usbaddr>\fR.
-.PP
-Notice that an instance of usbredirserver can only be used to export a
-single USB device. If you want to export multiple devices you can start
-multiple instances listening on different TCP ports.
-.SH OPTIONS
-.TP
-\fB\-p\fR, \fB\-\-port\fR=\fIPORT\fR
-Set the TCP port to listen on to \fIPORT\fR
-.TP
-\fB\-v\fR, \fB\-\-verbose\fR=\fIVERBOSE\fR
-Set usbredirserver's verbosity level to \fIVERBOSE\fR, this mostly affects USB
-redirection related messages. Valid values are 0-5:
-.br
-0:Silent 1:Errors 2:Warnings 3:Info 4:Debug 5:Debug++
-.SH AUTHOR
-Written by Hans de Goede <[email protected]>
-.SH REPORTING BUGS
-You can report bugs to the spice-devel mailinglist:
-http://lists.freedesktop.org/mailman/listinfo/spice-devel
-or filing an issue at:
-https://gitlab.freedesktop.org/spice/usbredir/issues/new
-.SH COPYRIGHT
-Copyright 2010-2012 Red Hat, Inc.
-License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.
-.br
-This is free software: you are free to change and redistribute it.
-There is NO WARRANTY, to the extent permitted by law.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/usbredir-0.12.0/usbredirserver/usbredirserver.c 
new/usbredir-0.13.0/usbredirserver/usbredirserver.c
--- old/usbredir-0.12.0/usbredirserver/usbredirserver.c 2021-11-12 
11:45:50.021210700 +0100
+++ new/usbredir-0.13.0/usbredirserver/usbredirserver.c 1970-01-01 
01:00:00.000000000 +0100
@@ -1,474 +0,0 @@
-/* usbredirserver.c simple usb network redirection tcp/ip server (host).
-
-   Copyright 2010-2011 Red Hat, Inc.
-
-   Red Hat Authors:
-   Hans de Goede <[email protected]>
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-
-   This program 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
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <errno.h>
-#include <poll.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include "usbredirhost.h"
-
-
-#define SERVER_VERSION "usbredirserver " PACKAGE_VERSION
-
-#if !defined(SOL_TCP) && defined(IPPROTO_TCP)
-#define SOL_TCP IPPROTO_TCP
-#endif
-#if !defined(TCP_KEEPIDLE) && defined(TCP_KEEPALIVE) && defined(__APPLE__)
-#define TCP_KEEPIDLE TCP_KEEPALIVE
-#endif
-
-static int verbose = usbredirparser_info;
-static int client_fd, running = 1;
-static libusb_context *ctx;
-static struct usbredirhost *host;
-
-static const struct option longopts[] = {
-    { "port", required_argument, NULL, 'p' },
-    { "verbose", required_argument, NULL, 'v' },
-    { "ipv4", required_argument, NULL, '4' },
-    { "ipv6", required_argument, NULL, '6' },
-    { "keepalive", required_argument, NULL, 'k' },
-    { "help", no_argument, NULL, 'h' },
-    { NULL, 0, NULL, 0 }
-};
-
-static void usbredirserver_log(void *priv, int level, const char *msg)
-{
-    if (level <= verbose)
-        fprintf(stderr, "%s\n", msg);
-}
-
-static int usbredirserver_read(void *priv, uint8_t *data, int count)
-{
-    int r = read(client_fd, data, count);
-    if (r < 0) {
-        if (errno == EAGAIN)
-            return 0;
-        return -1;
-    }
-    if (r == 0) { /* Client disconnected */
-        close(client_fd);
-        client_fd = -1;
-    }
-    return r;
-}
-
-static int usbredirserver_write(void *priv, uint8_t *data, int count)
-{
-    int r = write(client_fd, data, count);
-    if (r < 0) {
-        if (errno == EAGAIN)
-            return 0;
-        if (errno == EPIPE) { /* Client disconnected */
-            close(client_fd);
-            client_fd = -1;
-            return 0;
-        }
-        return -1;
-    }
-    return r;
-}
-
-static void usage(int exit_code, char *argv0)
-{
-    fprintf(exit_code? stderr:stdout,
-        "Usage: %s [-p|--port <port>] [-v|--verbose <0-5>] "
-        "[[-4|--ipv4 ipaddr]|[-6|--ipv6 ipaddr]] "
-        "[-k|--keepalive seconds] "
-        "<busnum-devnum|vendorid:prodid>\n",
-        argv0);
-    exit(exit_code);
-}
-
-static void invalid_usb_device_id(char *usb_device_id, char *argv0)
-{
-    fprintf(stderr, "Invalid usb device identifier: %s\n", usb_device_id);
-    usage(1, argv0);
-}
-
-static void run_main_loop(void)
-{
-    const struct libusb_pollfd **pollfds = NULL;
-    fd_set readfds, writefds;
-    int i, n, nfds;
-    struct timeval timeout, *timeout_p;
-
-    while (running && client_fd != -1) {
-        FD_ZERO(&readfds);
-        FD_ZERO(&writefds);
-
-        FD_SET(client_fd, &readfds);
-        if (usbredirhost_has_data_to_write(host)) {
-            FD_SET(client_fd, &writefds);
-        }
-        nfds = client_fd + 1;
-
-        free(pollfds);
-        pollfds = libusb_get_pollfds(ctx);
-        for (i = 0; pollfds && pollfds[i]; i++) {
-            if (pollfds[i]->events & POLLIN) {
-                FD_SET(pollfds[i]->fd, &readfds);
-            }
-            if (pollfds[i]->events & POLLOUT) {
-                FD_SET(pollfds[i]->fd, &writefds);
-            }
-            if (pollfds[i]->fd >= nfds)
-                nfds = pollfds[i]->fd + 1;
-        }
-
-        if (libusb_get_next_timeout(ctx, &timeout) == 1) {
-            timeout_p = &timeout;
-        } else {
-            timeout_p = NULL;
-        }
-        n = select(nfds, &readfds, &writefds, NULL, timeout_p);
-        if (n == -1) {
-            if (errno == EINTR) {
-                continue;
-            }
-            perror("select");
-            break;
-        }
-        memset(&timeout, 0, sizeof(timeout));
-        if (n == 0) {
-            libusb_handle_events_timeout(ctx, &timeout);
-            continue;
-        }
-
-        if (FD_ISSET(client_fd, &readfds)) {
-            if (usbredirhost_read_guest_data(host)) {
-                break;
-            }
-        }
-        /* usbredirhost_read_guest_data may have detected client disconnect */
-        if (client_fd == -1)
-            break;
-
-        if (FD_ISSET(client_fd, &writefds)) {
-            if (usbredirhost_write_guest_data(host)) {
-                break;
-            }
-        }
-
-        for (i = 0; pollfds && pollfds[i]; i++) {
-            if (FD_ISSET(pollfds[i]->fd, &readfds) ||
-                FD_ISSET(pollfds[i]->fd, &writefds)) {
-                libusb_handle_events_timeout(ctx, &timeout);
-                break;
-            }
-        }
-    }
-    if (client_fd != -1) { /* Broken out of the loop because of an error ? */
-        close(client_fd);
-        client_fd = -1;
-    }
-    free(pollfds);
-}
-
-static void quit_handler(int sig)
-{
-    running = 0;
-}
-
-int main(int argc, char *argv[])
-{
-    int o, flags, server_fd = -1;
-    char *endptr, *delim;
-    int port       = 4000;
-    int usbbus     = -1;
-    int usbaddr    = -1;
-    int usbvendor  = -1;
-    int usbproduct = -1;
-    int on = 1;
-    int keepalive  = -1;
-    char *ipv4_addr = NULL, *ipv6_addr = NULL;
-    union {
-        struct sockaddr_in v4;
-        struct sockaddr_in6 v6;
-    } serveraddr;
-    struct sigaction act;
-    libusb_device_handle *handle = NULL;
-
-    while ((o = getopt_long(argc, argv, "hp:v:4:6:k:", longopts, NULL)) != -1) 
{
-        switch (o) {
-        case 'p':
-            port = strtol(optarg, &endptr, 10);
-            if (*endptr != '\0') {
-                fprintf(stderr, "Invalid value for --port: '%s'\n", optarg);
-                usage(1, argv[0]);
-            }
-            break;
-        case 'v':
-            verbose = strtol(optarg, &endptr, 10);
-            if (*endptr != '\0') {
-                fprintf(stderr, "Invalid value for --verbose: '%s'\n", optarg);
-                usage(1, argv[0]);
-            }
-            break;
-        case '4':
-            ipv4_addr = optarg;
-            break;
-        case '6':
-            ipv6_addr = optarg;
-            break;
-        case 'k':
-            keepalive = strtol(optarg, &endptr, 10);
-            if (*endptr != '\0') {
-                fprintf(stderr, "Invalid value for -k: '%s'\n", optarg);
-                usage(1, argv[0]);
-            }
-            break;
-        case '?':
-        case 'h':
-            usage(o == '?', argv[0]);
-            break;
-        }
-    }
-    if (optind == argc) {
-        fprintf(stderr, "Missing usb device identifier argument\n");
-        usage(1, argv[0]);
-    }
-    delim = strchr(argv[optind], '-');
-    if (delim && delim[1]) {
-        usbbus = strtol(argv[optind], &endptr, 10);
-        if (*endptr != '-') {
-            invalid_usb_device_id(argv[optind], argv[0]);
-        }
-        usbaddr = strtol(delim + 1, &endptr, 10);
-        if (*endptr != '\0') {
-            invalid_usb_device_id(argv[optind], argv[0]);
-        }
-    } else {
-        delim = strchr(argv[optind], ':');
-        if (!delim || !delim[1]) {
-            invalid_usb_device_id(argv[optind], argv[0]);
-        }
-        usbvendor = strtol(argv[optind], &endptr, 16);
-        if (*endptr != ':' || usbvendor <= 0 || usbvendor > 0xffff) {
-            invalid_usb_device_id(argv[optind], argv[0]);
-        }
-        usbproduct = strtol(delim + 1, &endptr, 16);
-        /* Product ID 0000 is valid */
-        if (*endptr != '\0' || usbproduct < 0 || usbproduct > 0xffff) {
-            invalid_usb_device_id(argv[optind], argv[0]);
-        }
-    }
-    optind++;
-    if (optind != argc) {
-        fprintf(stderr, "Excess non option arguments\n");
-        usage(1, argv[0]);
-    }
-
-    memset(&act, 0, sizeof(act));
-    act.sa_handler = quit_handler;
-    sigaction(SIGINT, &act, NULL);
-    sigaction(SIGHUP, &act, NULL);
-    sigaction(SIGTERM, &act, NULL);
-    sigaction(SIGQUIT, &act, NULL);
-
-    if (libusb_init(&ctx)) {
-        fprintf(stderr, "Could not init libusb\n");
-        exit(1);
-    }
-
-#if LIBUSB_API_VERSION >= 0x01000106
-    libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, verbose);
-#else
-    libusb_set_debug(ctx, verbose);
-#endif
-
-    if (ipv4_addr) {
-        server_fd = socket(AF_INET, SOCK_STREAM, 0);
-    } else {
-        server_fd = socket(AF_INET6, SOCK_STREAM, 0);
-    }
-    if (server_fd == -1) {
-        perror("Error creating ip socket");
-        exit(1);
-    }
-
-    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
-        perror("Error setsockopt(SO_REUSEADDR) failed");
-        exit(1);
-    }
-
-    memset(&serveraddr, 0, sizeof(serveraddr));
-
-    if (ipv4_addr) {
-        serveraddr.v4.sin_family = AF_INET;
-        serveraddr.v4.sin_port   = htons(port);
-        if ((inet_pton(AF_INET, ipv4_addr,
-                       &serveraddr.v4.sin_addr)) != 1) {
-            perror("Error convert ipv4 address");
-            exit(1);
-        }
-    } else {
-        serveraddr.v6.sin6_family = AF_INET6;
-        serveraddr.v6.sin6_port   = htons(port);
-        if (ipv6_addr) {
-            if ((inet_pton(AF_INET6, ipv6_addr,
-                           &serveraddr.v6.sin6_addr)) != 1) {
-                perror("Error convert ipv6 address");
-                exit(1);
-            }
-        } else {
-            serveraddr.v6.sin6_addr   = in6addr_any;
-        }
-    }
-
-    if (bind(server_fd, (struct sockaddr *)&serveraddr,
-             sizeof(serveraddr))) {
-        perror("Error bind");
-        exit(1);
-    }
-
-    if (listen(server_fd, 1)) {
-        perror("Error listening");
-        exit(1);
-    }
-
-    while (running) {
-        client_fd = accept(server_fd, NULL, 0);
-        if (client_fd == -1) {
-            if (errno == EINTR) {
-                continue;
-            }
-            perror("accept");
-            break;
-        }
-
-        if (keepalive > 0) {
-            int optval = 1;
-            socklen_t optlen = sizeof(optval);
-            if (setsockopt(client_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, 
optlen) == -1) {
-                if (errno != ENOTSUP) {
-                    perror("setsockopt SO_KEEPALIVE error.");
-                    break;
-                }
-            }
-            optval = keepalive;        /* set default TCP_KEEPIDLE time from 
cmdline */
-            if (setsockopt(client_fd, SOL_TCP, TCP_KEEPIDLE, &optval, optlen) 
== -1) {
-                if (errno != ENOTSUP) {
-                    perror("setsockopt TCP_KEEPIDLE error.");
-                    break;
-                }
-            }
-            optval = 10;       /* set default TCP_KEEPINTVL time as 10s */
-            if (setsockopt(client_fd, SOL_TCP, TCP_KEEPINTVL, &optval, optlen) 
== -1) {
-                if (errno != ENOTSUP) {
-                    perror("setsockopt TCP_KEEPINTVL error.");
-                    break;
-                }
-            }
-            optval = 3;        /* set default TCP_KEEPCNT as 3 */
-            if (setsockopt(client_fd, SOL_TCP, TCP_KEEPCNT, &optval, optlen) 
== -1) {
-                if (errno != ENOTSUP) {
-                    perror("setsockopt TCP_KEEPCNT error.");
-                    break;
-                }
-            }
-        }
-
-        flags = fcntl(client_fd, F_GETFL);
-        if (flags == -1) {
-            perror("fcntl F_GETFL");
-            break;
-        }
-        flags = fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
-        if (flags == -1) {
-            perror("fcntl F_SETFL O_NONBLOCK");
-            break;
-        }
-
-        /* Try to find the specified usb device */
-        if (usbvendor != -1) {
-            handle = libusb_open_device_with_vid_pid(ctx, usbvendor,
-                                                     usbproduct);
-            if (!handle) {
-                fprintf(stderr,
-                    "Could not open an usb-device with vid:pid %04x:%04x\n",
-                    usbvendor, usbproduct);
-            } else if (verbose >= usbredirparser_info) {
-                libusb_device *dev;
-                dev = libusb_get_device(handle);
-                fprintf(stderr, "Open a usb-device with vid:pid %04x:%04x on "
-                        "bus %03x device %03x\n",
-                        usbvendor, usbproduct,
-                        libusb_get_bus_number(dev),
-                        libusb_get_device_address(dev));
-            }
-        } else {
-            libusb_device **list = NULL;
-            ssize_t i, n;
-
-            n = libusb_get_device_list(ctx, &list);
-            for (i = 0; i < n; i++) {
-                if (libusb_get_bus_number(list[i]) == usbbus &&
-                        libusb_get_device_address(list[i]) == usbaddr)
-                    break;
-            }
-            if (i < n) {
-                if (libusb_open(list[i], &handle) != 0) {
-                    fprintf(stderr,
-                        "Could not open usb-device at busnum-devnum %d-%d\n",
-                        usbbus, usbaddr);
-                }
-            } else {
-                fprintf(stderr,
-                    "Could not find an usb-device at busnum-devnum %d-%d\n",
-                    usbbus, usbaddr);
-            }
-            libusb_free_device_list(list, 1);
-        }
-        if (!handle) {
-            close(client_fd);
-            continue;
-        }
-
-        host = usbredirhost_open(ctx, handle, usbredirserver_log,
-                                 usbredirserver_read, usbredirserver_write,
-                                 NULL, SERVER_VERSION, verbose, 0);
-        if (!host)
-            exit(1);
-        run_main_loop();
-        usbredirhost_close(host);
-        handle = NULL;
-    }
-
-    close(server_fd);
-    libusb_exit(ctx);
-    exit(0);
-}

Reply via email to