Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package seafile for openSUSE:Factory checked 
in at 2026-09-02 16:59:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/seafile (Old)
 and      /work/SRC/openSUSE:Factory/.seafile.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "seafile"

Wed Sep  2 16:59:12 2026 rev:24 rq:1375124 version:9.0.21

Changes:
--------
--- /work/SRC/openSUSE:Factory/seafile/seafile.changes  2026-06-30 
15:13:51.004887866 +0200
+++ /work/SRC/openSUSE:Factory/.seafile.new.1265/seafile.changes        
2026-09-02 16:59:15.263075647 +0200
@@ -1,0 +2,8 @@
+Tue Sep  1 12:13:57 UTC 2026 - Paolo Stivanin <[email protected]>
+
+- Update to 9.0.21 (no changelog).
+- Add fix-lws-socks5.patch: guard the new SOCKS5 proxy support in
+  the notification manager with LWS_WITH_SOCKS5, since
+  libwebsockets is not built with -DLWS_WITH_SOCKS5=ON.
+
+-------------------------------------------------------------------

Old:
----
  v9.0.20.tar.gz

New:
----
  fix-lws-socks5.patch
  v9.0.21.tar.gz

----------(New B)----------
  New:- Update to 9.0.21 (no changelog).
- Add fix-lws-socks5.patch: guard the new SOCKS5 proxy support in
  the notification manager with LWS_WITH_SOCKS5, since
----------(New E)----------

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

Other differences:
------------------
++++++ seafile.spec ++++++
--- /var/tmp/diff_new_pack.sboTfG/_old  2026-09-02 16:59:16.011101651 +0200
+++ /var/tmp/diff_new_pack.sboTfG/_new  2026-09-02 16:59:16.013101721 +0200
@@ -17,13 +17,14 @@
 
 
 Name:           seafile
-Version:        9.0.20
+Version:        9.0.21
 Release:        0
 Summary:        Cloud storage client
 License:        GPL-2.0-only
 URL:            https://github.com/haiwen/seafile/
 Source0:        https://github.com/haiwen/seafile/archive/v%{version}.tar.gz
 Patch0:         fix-issues.patch
+Patch1:         fix-lws-socks5.patch
 BuildRequires:  argon2-devel
 BuildRequires:  autoconf
 BuildRequires:  automake

++++++ fix-lws-socks5.patch ++++++
Guard the SOCKS5 proxy setup for the notification server with LWS_WITH_SOCKS5.

socks_proxy_address / socks_proxy_port only exist in struct
lws_context_creation_info when libwebsockets is built with
-DLWS_WITH_SOCKS5=ON, which is not the case for the distro package.

Index: seafile-9.0.21/daemon/notif-mgr.c
===================================================================
--- seafile-9.0.21.orig/daemon/notif-mgr.c
+++ seafile-9.0.21/daemon/notif-mgr.c
@@ -836,12 +836,17 @@
             info.http_proxy_port = has_auth ? 0 :
                                    (seaf->http_proxy_port > 0 ? 
seaf->http_proxy_port : 80);
         } else if (g_strcmp0 (seaf->http_proxy_type, PROXY_TYPE_SOCKS) == 0) {
+#if defined(LWS_WITH_SOCKS5)
             if (seaf->http_proxy_port >= 0) {
                 socks_proxy_addr = has_auth ? build_proxy_address (1080) : 
g_strdup (seaf->http_proxy_addr);
                 info.socks_proxy_address = socks_proxy_addr;
                 info.socks_proxy_port = has_auth ? 0 :
                                     (seaf->http_proxy_port > 0 ? 
seaf->http_proxy_port : 1080);
             }
+#else
+            seaf_warning ("libwebsockets was built without SOCKS5 support, "
+                          "not using the SOCKS proxy for the notification 
server.\n");
+#endif
         }
     }
 

++++++ v9.0.20.tar.gz -> v9.0.21.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/app/seaf-cli 
new/seafile-9.0.21/app/seaf-cli
--- old/seafile-9.0.20/app/seaf-cli     2026-06-29 11:19:16.000000000 +0200
+++ new/seafile-9.0.21/app/seaf-cli     2026-08-07 08:17:18.000000000 +0200
@@ -811,6 +811,17 @@
     conf_dir = _conf_dir(args)
 
     seafile_rpc = get_rpc_client(conf_dir)
+    recent_sync_errors = seafile_rpc.get_file_sync_errors(0, 
args.sync_error_count)
+
+    def format_timestamp(timestamp):
+        return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp))
+
+    def format_sync_error(sync_error):
+        repo_name = sync_error.repo_name or ''
+        path = sync_error.path or '/'
+        err = seafile_rpc.sync_error_id_to_str(sync_error.err_id)
+        time_str = format_timestamp(sync_error.timestamp)
+        return repo_name, path, err, time_str
 
     if args.json:
         entries = []
@@ -871,7 +882,22 @@
             else:
                 entries.append({'id': repo.id, 'name': repo.name, 'state': 
task.state})
 
-        print(json.dumps(entries, ensure_ascii=False))
+        sync_errors = []
+        for sync_error in recent_sync_errors:
+            repo_name, path, err, time_str = format_sync_error(sync_error)
+            sync_errors.append({
+                'repo_id': sync_error.repo_id,
+                'repo_name': repo_name,
+                'path': path,
+                'error': err,
+                'timestamp': sync_error.timestamp,
+                'time': time_str,
+            })
+
+        print(json.dumps({
+            'repos': entries,
+            'sync_errors': sync_errors,
+        }, ensure_ascii=False))
     else:
         tasks = seafile_rpc.get_clone_tasks()
         print('# {:<50s}\t{:<20s}\t{:<20s}'.format('Name', 'Status', 
'Progress'))
@@ -928,6 +954,14 @@
             else:
                 print('{:<50s}\t{:<20s}'.format(repo.name, task.state))
 
+        if recent_sync_errors:
+            print('')
+            print('File sync errors:')
+            print('# {:<19s}\t{:<24s}\t{:<36s}\t{:<20s}'.format('Time', 
'Library', 'Path', 'Error'))
+            for sync_error in recent_sync_errors:
+                repo_name, path, err, time_str = format_sync_error(sync_error)
+                print('{:<19s}\t{:<24s}\t{:<36s}\t{:<20s}'.format(time_str, 
repo_name, path, err))
+
 def create_repo(url, token, args):
     headers = { 'Authorization': 'Token %s' % token }
     data = {
@@ -1026,6 +1060,7 @@
     parser_status.set_defaults(func=seaf_status)
     parser_status.add_argument('-c', '--confdir', help='the config directory', 
type=str, required=confdir_required)
     parser_status.add_argument('--json', help='output json format result', 
action='store_true')
+    parser_status.add_argument('--sync-error-count', help='number of file sync 
errors to show', type=int, default=10)
 
     # download
     parser_download = subparsers.add_parser('download',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/configure.ac 
new/seafile-9.0.21/configure.ac
--- old/seafile-9.0.20/configure.ac     2026-06-29 11:19:16.000000000 +0200
+++ new/seafile-9.0.21/configure.ac     2026-08-07 08:17:18.000000000 +0200
@@ -2,7 +2,7 @@
 
 
 AC_PREREQ(2.61)
-AC_INIT([seafile], [9.0.20], [[email protected]])
+AC_INIT([seafile], [9.0.21], [[email protected]])
 AC_CONFIG_HEADER([config.h])
 
 AC_CONFIG_MACRO_DIR([m4])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/daemon/http-tx-mgr.c 
new/seafile-9.0.21/daemon/http-tx-mgr.c
--- old/seafile-9.0.20/daemon/http-tx-mgr.c     2026-06-29 11:19:16.000000000 
+0200
+++ new/seafile-9.0.21/daemon/http-tx-mgr.c     2026-08-07 08:17:18.000000000 
+0200
@@ -1551,6 +1551,13 @@
             json_decref (object);
             return -1;
         }
+        if (strlen(head_commit) != 40) {
+            seaf_warning ("Check head commit for repo %s failed. "
+                          "Response contains invalid head commit id.\n",
+                          data->repo_id);
+            json_decref (object);
+            return -1;
+        }
         memcpy (data->head_commit, head_commit, 40);
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/daemon/notif-mgr.c 
new/seafile-9.0.21/daemon/notif-mgr.c
--- old/seafile-9.0.20/daemon/notif-mgr.c       2026-06-29 11:19:16.000000000 
+0200
+++ new/seafile-9.0.21/daemon/notif-mgr.c       2026-08-07 08:17:18.000000000 
+0200
@@ -6,6 +6,7 @@
 #include <glib.h>
 
 #include "seafile-session.h"
+#include "seafile-config.h"
 #include "notif-mgr.h"
 #include "sync-mgr.h"
 
@@ -19,7 +20,6 @@
 #define STATUS_DISCONNECTED 0
 #define STATUS_CONNECTED    1
 #define STATUS_ERROR        2
-#define STATUS_CANCELLED    3
 
 typedef struct NotifServer {
     struct lws_context *context;
@@ -28,8 +28,7 @@
 
     // status of the notification server.
     int      status;
-    // whether to close the connection to the server.
-    gboolean close;
+    gboolean reconnect;
 
     GHashTable *subscriptions;
     pthread_mutex_t sub_lock;
@@ -158,13 +157,62 @@
 notif_server_ref (NotifServer *server);
 
 static struct lws_context *
-lws_context_new (int port);
+lws_context_new (gboolean use_ssl);
+
+static void
+init_client_connect_info (NotifServer *server);
+
+static gboolean
+proxy_has_auth (void)
+{
+    return seaf->http_proxy_username && seaf->http_proxy_password &&
+           seaf->http_proxy_username[0] != '\0' &&
+           seaf->http_proxy_password[0] != '\0';
+}
+
+static char *
+build_proxy_address (int default_port)
+{
+    char *escaped_user = NULL;
+    char *escaped_pass = NULL;
+    char *proxy = NULL;
+    int port = seaf->http_proxy_port > 0 ? seaf->http_proxy_port : 
default_port;
+
+    escaped_user = g_uri_escape_string (seaf->http_proxy_username, NULL, 
FALSE);
+    escaped_pass = g_uri_escape_string (seaf->http_proxy_password, NULL, 
FALSE);
+    proxy = g_strdup_printf ("%s:%s@%s:%d",
+                             escaped_user,
+                             escaped_pass,
+                             seaf->http_proxy_addr,
+                             port);
+    g_free (escaped_user);
+    g_free (escaped_pass);
+
+    return proxy;
+}
+
+static int
+reset_lws_context (NotifServer *server)
+{
+    if (server->context) {
+        lws_context_destroy (server->context);
+        server->context = NULL;
+    }
+
+    server->wsi = NULL;
+
+    server->context = lws_context_new (server->use_ssl);
+    if (!server->context)
+        return -1;
+
+    init_client_connect_info (server);
+    return 0;
+}
 
 static NotifServer*
 notif_new_server (const char *server_url, gboolean use_notif_server_port)
 {
     NotifServer *server = NULL;
-    static struct lws_context *context;
     URI *uri = NULL;
     int port = NOTIF_PORT;
     gboolean use_ssl = FALSE;
@@ -186,20 +234,8 @@
     }
     
 
-    context = lws_context_new (use_ssl);
-    if (!context) {
-        g_free (uri->scheme);
-        g_free (uri->host);
-        g_free (uri);
-        seaf_warning ("failed to create libwebsockets context\n");
-        return NULL;
-    }
-
     server = g_new0 (NotifServer, 1);
-
     server->messages = g_async_queue_new ();
-
-    server->context = context;
     server->server_url = g_strdup (server_url);
     server->addr = g_strdup (uri->host);
     server->use_ssl = use_ssl;
@@ -281,9 +317,6 @@
         notif_server_free (server);
 }
 
-static void
-init_client_connect_info (NotifServer *server);
-
 static void *
 notification_worker (void *vdata);
 
@@ -310,8 +343,6 @@
         return;
     }
 
-    init_client_connect_info (server);
-
     rc = pthread_create (&tid, NULL, notification_worker, server);
     if (rc != 0) {
         seaf_warning ("Failed to create event notification new thread: %s.\n", 
strerror(rc));
@@ -326,12 +357,30 @@
     return;
 }
 
-static void
-disconnect_server (NotifServer *server)
+void
+seaf_notif_manager_reconnect_servers (SeafNotifManager *mgr)
 {
-    // lws_cancel_service will produce a cancel event to break out of 
lws_service loop.
-    lws_cancel_service (server->context);
-    server->close = TRUE;
+    GHashTableIter iter;
+    gpointer key, value;
+
+    if (!mgr->priv)
+        return;
+
+    pthread_mutex_lock (&mgr->priv->server_lock);
+    g_hash_table_iter_init (&iter, mgr->priv->servers);
+    while (g_hash_table_iter_next (&iter, &key, &value)) {
+        NotifServer *server = value;
+
+        if (!server || !server->context)
+            continue;
+
+        server->reconnect = TRUE;
+
+        // Call lws_cancel_service() to wake up lws_service() and make it 
process events immediately.
+        if (server->context)
+            lws_cancel_service (server->context);
+    }
+    pthread_mutex_unlock (&mgr->priv->server_lock);
 }
 
 // This policy will send a ping packet to the server per second.
@@ -378,6 +427,7 @@
     Message *msg = NULL;
     int m;
     int ret = 0;
+
     if (!server) {
         return ret;
     }
@@ -387,6 +437,7 @@
     switch (reason) {
     case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER:
     {
+        // this callback happens when a client handshake is being compiled.
         unsigned char **p = (unsigned char **)in, *end = (*p) + len;
 
         if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_USER_AGENT,
@@ -395,15 +446,24 @@
         break;
     }
     case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
+        // the request client connection has been unable to complete a 
handshake with the remote server.
         server->status = STATUS_ERROR;
         seaf_debug ("websocket connection error: %s\n",
             in ? (char *)in : "(null)");
         ret = -1;
         break;
     case LWS_CALLBACK_CLIENT_RECEIVE:
+        // data has appeared from the server for the client connection.
         handle_messages (in, len);
         break;
     case LWS_CALLBACK_CLIENT_WRITEABLE:
+        // If it already was able to take another packet without blocking,
+        // you'll get this callback at the next call to the service loop 
function.
+
+        // Return -1 to close the current connection and exit lws_service loop.
+        if (server->reconnect) {
+            return -1;
+        }
         msg = g_async_queue_try_pop (server->messages);
         if (!msg) {
             break;
@@ -422,22 +482,21 @@
         notif_message_free (msg);
         break;
     case LWS_CALLBACK_CLIENT_ESTABLISHED:
+        // after your client connection completed the websocket upgrade 
handshake with the remote server.
         seaf_sync_manager_check_locks_and_folder_perms (seaf->sync_mgr, 
server->server_url);
         server->status = STATUS_CONNECTED;
-        seaf_debug ("Successfully connected to the server: %s\n", 
server->server_url);
+        seaf_message ("Successfully connected to notification server: %s\n", 
server->server_url);
         break;
     case LWS_CALLBACK_CLIENT_CLOSED:
+        // when a client websocket session ends.
         ret = -1;
         server->status = STATUS_ERROR;
+        server->wsi = NULL;
         // When the client is closed, cancel the context to prevent the socket 
from blocking in poll after the operating system wakes from sleep.
         // After calling lws_cancel_service, a 
LWS_CALLBACK_EVENT_WAIT_CANCELLED callback is sent to every protocol on every 
vhost,
-        // notification_worker will exit loop.
+        // lws_service() will return.
         lws_cancel_service (server->context);
         break;
-    case LWS_CALLBACK_EVENT_WAIT_CANCELLED:
-        ret = -1;
-        server->status = STATUS_CANCELLED;
-        break;
     default:
         break;
     }
@@ -757,6 +816,9 @@
 {
     struct lws_context_creation_info info;
     struct lws_context *context = NULL;
+    char *http_proxy_addr = NULL;
+    char *socks_proxy_addr = NULL;
+    gboolean has_auth = proxy_has_auth ();
 
     memset(&info, 0, sizeof info);
     info.port = CONTEXT_PORT_NO_LISTEN;
@@ -766,6 +828,23 @@
     // have to use the default allocations for fd tables up to ulimit -n.
     // It will just allocate for 1 internal and 1 (+ 1 http2 nwsi) that we 
will use.
     info.fd_limit_per_thread = 1 + 1 + 1;
+
+    if (seaf->use_http_proxy && seaf->http_proxy_type && 
seaf->http_proxy_addr) {
+        if (g_strcmp0 (seaf->http_proxy_type, PROXY_TYPE_HTTP) == 0) {
+            http_proxy_addr = has_auth ? build_proxy_address (80) : g_strdup 
(seaf->http_proxy_addr);
+            info.http_proxy_address = http_proxy_addr;
+            info.http_proxy_port = has_auth ? 0 :
+                                   (seaf->http_proxy_port > 0 ? 
seaf->http_proxy_port : 80);
+        } else if (g_strcmp0 (seaf->http_proxy_type, PROXY_TYPE_SOCKS) == 0) {
+            if (seaf->http_proxy_port >= 0) {
+                socks_proxy_addr = has_auth ? build_proxy_address (1080) : 
g_strdup (seaf->http_proxy_addr);
+                info.socks_proxy_address = socks_proxy_addr;
+                info.socks_proxy_port = has_auth ? 0 :
+                                    (seaf->http_proxy_port > 0 ? 
seaf->http_proxy_port : 1080);
+            }
+        }
+    }
+
     char *ca_path = g_build_filename (seaf->seaf_dir, "ca-bundle.pem", NULL);
     if (use_ssl) {
          info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
@@ -774,11 +853,15 @@
 
     context = lws_create_context(&info);
     if (!context) {
+        g_free (http_proxy_addr);
+        g_free (socks_proxy_addr);
         g_free (ca_path);
         seaf_warning ("failed to create libwebsockets context\n");
         return NULL;
     }
 
+    g_free (http_proxy_addr);
+    g_free (socks_proxy_addr);
     g_free (ca_path);
     return context;
 }
@@ -831,21 +914,31 @@
     struct lws_client_connect_info *i = &server->i;
     int n = 0;
 
-    while (!server->close) {
+    while (1) {
+        if (reset_lws_context (server) < 0) {
+            g_usleep (RECONNECT_INTERVAL * G_USEC_PER_SEC);
+            server->status = STATUS_DISCONNECTED;
+            continue;
+        }
+
         // We don't need to check the return value of this function, the 
connection will be processed in the event loop.
         lws_client_connect_via_info(i);
 
-        while (n >= 0 && !server->close &&
-               server->status != STATUS_ERROR &&
-               server->status != STATUS_CANCELLED) {
-            n = lws_service(server->context, 0);
+        while (n >= 0 && server->status != STATUS_ERROR) {
+            // Wait for events for up to 1000 ms, lws_service() will return 
when the timeout expires.
+            n = lws_service(server->context, 1000);
         }
 
         delete_subscribed_repos (server);
         delete_unsent_messages (server);
 
-        if (server->status == STATUS_CANCELLED)
-            break;
+        if (server->reconnect) {
+            server->reconnect = FALSE;
+            n = 0;
+            server->status = STATUS_DISCONNECTED;
+            seaf_message ("Reconnecting to the notification server: %s.\n", 
server->server_url);
+            continue;
+        }
 
         // Wait a minute to reconnect to the notification server.
         g_usleep (RECONNECT_INTERVAL * G_USEC_PER_SEC);
@@ -853,12 +946,6 @@
         server->status = STATUS_DISCONNECTED;
     }
 
-    seaf_message ("Notification worker for server %s exiting.\n", 
server->server_url);
-    pthread_mutex_lock (&seaf->notif_mgr->priv->server_lock);
-    g_hash_table_remove (seaf->notif_mgr->priv->servers, server->server_url);
-    pthread_mutex_unlock (&seaf->notif_mgr->priv->server_lock);
-    notif_server_unref (server);
-
     return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/daemon/notif-mgr.h 
new/seafile-9.0.21/daemon/notif-mgr.h
--- old/seafile-9.0.20/daemon/notif-mgr.h       2026-06-29 11:19:16.000000000 
+0200
+++ new/seafile-9.0.21/daemon/notif-mgr.h       2026-08-07 08:17:18.000000000 
+0200
@@ -21,6 +21,9 @@
                                    gboolean use_notif_server_port);
 
 void
+seaf_notif_manager_reconnect_servers (SeafNotifManager *mgr);
+
+void
 seaf_notif_manager_subscribe_repo (SeafNotifManager *mgr, SeafRepo *repo);
 
 void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/daemon/repo-mgr.c 
new/seafile-9.0.21/daemon/repo-mgr.c
--- old/seafile-9.0.20/daemon/repo-mgr.c        2026-06-29 11:19:16.000000000 
+0200
+++ new/seafile-9.0.21/daemon/repo-mgr.c        2026-08-07 08:17:18.000000000 
+0200
@@ -4241,6 +4241,17 @@
     g_async_queue_push (queue, job);
 }
 
+#define IGNORE_FILE "seafile-ignore.txt"
+static gboolean
+is_ignore_file_path (const char *path)
+{
+    if (!path) {
+        return FALSE;
+    }
+
+    return g_strcmp0 (path, IGNORE_FILE) == 0;
+}
+
 static int
 apply_worktree_changes_to_index (SeafRepo *repo, struct index_state *istate,
                                  SeafileCrypt *crypt, GList *ignore_list,
@@ -4334,6 +4345,14 @@
                 strcmp (next_event->path, event->path) == 0)
                 break;
 
+            if (is_ignore_file_path (event->path)) {
+                if (seaf_wt_monitor_refresh_repo (seaf->wt_monitor, repo->id) 
< 0) {
+                    seaf_warning ("Failed to refresh watch for repo %s.\n", 
repo->id);
+                    send_file_sync_error_notification (repo->id, repo->name, 
"/",
+                                                       
SYNC_ERROR_ID_WATCH_FAILED);
+                }
+            }
+
             /* CREATE_OR_UPDATE event tells us the exact path of changed 
file/dir.
              * If the event path is not writable, we don't need to check the 
paths
              * under the event path.
@@ -4387,6 +4406,14 @@
 
             break;
         case WT_EVENT_DELETE:
+            if (is_ignore_file_path (event->path)) {
+                if (seaf_wt_monitor_refresh_repo (seaf->wt_monitor, repo->id) 
< 0) {
+                    seaf_warning ("Failed to refresh watch for repo %s.\n", 
repo->id);
+                    send_file_sync_error_notification (repo->id, repo->name, 
"/",
+                                                       
SYNC_ERROR_ID_WATCH_FAILED);
+                }
+            }
+
             seaf_sync_manager_delete_active_path (seaf->sync_mgr,
                                                   repo->id,
                                                   event->path);
@@ -4438,6 +4465,14 @@
             }
             break;
         case WT_EVENT_RENAME:
+            if (is_ignore_file_path (event->path) || is_ignore_file_path 
(event->new_path)) {
+                if (seaf_wt_monitor_refresh_repo (seaf->wt_monitor, repo->id) 
< 0) {
+                    seaf_warning ("Failed to refresh watch for repo %s.\n", 
repo->id);
+                    send_file_sync_error_notification (repo->id, repo->name, 
"/",
+                                                       
SYNC_ERROR_ID_WATCH_FAILED);
+                }
+            }
+
             handle_rename (repo, istate, crypt, ignore_list, fset, event, 
&scanned_del_dirs, &total_size);
             break;
         case WT_EVENT_ATTRIB:
@@ -4452,6 +4487,13 @@
             seaf_warning ("Kernel event queue overflowed, fall back to 
scan.\n");
             scan_worktree_for_changes (istate, repo, crypt, ignore_list, fset);
             break;
+        case WT_EVENT_WATCH_ERROR:
+            seaf_warning ("Worktree watch failed for repo %s at %s.\n",
+                          repo->id, event->path ? event->path : "");
+            send_file_sync_error_notification (repo->id, repo->name, 
event->path,
+                                               SYNC_ERROR_ID_WATCH_FAILED);
+            wt_event_free (event);
+            goto out;
         }
 
         if (event == last_event) {
@@ -4619,6 +4661,9 @@
         case WT_EVENT_OVERFLOW:
             name = "overflow";
             break;
+        case WT_EVENT_WATCH_ERROR:
+            name = "watch error";
+            break;
         default:
             name = "unknown";
         }
@@ -4942,6 +4987,7 @@
     char *repo_id;
     char *content;
     int size;
+    size_t capacity;
     void *user_data;
 };
 typedef struct _UpdateAux UpdateAux;
@@ -5028,6 +5074,8 @@
     UpdateAux *aux = userp;
     HttpTxTask *task = aux->user_data;
     int ret = realsize;
+    size_t old_capacity;
+    char *new_content = NULL;
 
     if (task) {
         if (task->state == HTTP_TASK_STATE_CANCELED || task->all_stop) {
@@ -5035,11 +5083,27 @@
         }
     }
 
-    aux->content = g_realloc (aux->content, aux->size + realsize);
-    if (!aux->content) {
-        seaf_warning ("Not enough memory.\n");
-        return 0;
+    old_capacity = aux->capacity;
+
+    if (aux->capacity == 0) {
+        aux->capacity = 8 * 1024;
+    }
+
+    // Double the buffer capacity until it can hold the new data.
+    // This avoids frequent calls to g_realloc(), which may introduce 
unnecessary overhead and latency.
+    while (aux->capacity < aux->size + realsize) {
+        aux->capacity *= 2;
     }
+
+    if (aux->capacity != old_capacity) {
+        new_content = g_realloc (aux->content, aux->capacity);
+        if (!new_content) {
+            seaf_warning ("Not enough memory.\n");
+            return 0;
+        }
+        aux->content = new_content;
+    }
+
     memcpy (aux->content + aux->size, contents, realsize);
     aux->size += realsize;
 
@@ -6780,7 +6844,6 @@
             de->status == DIFF_STATUS_DIR_RENAMED) {
             seaf_debug ("Rename %s to %s.\n", de->name, de->new_name);
 
-#ifdef WIN32
             IgnoreReason reason;
             if (should_ignore_on_checkout (de->new_name, &reason)) {
                 seaf_message ("Path %s is invalid on Windows, skip rename.\n", 
de->new_name);
@@ -6804,7 +6867,6 @@
                                             de, &results);
                 continue;
             }
-#endif
 
             if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr,
                                                       repo_id, de->name))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/daemon/seafile-config.c 
new/seafile-9.0.21/daemon/seafile-config.c
--- old/seafile-9.0.20/daemon/seafile-config.c  2026-06-29 11:19:16.000000000 
+0200
+++ new/seafile-9.0.21/daemon/seafile-config.c  2026-08-07 08:17:18.000000000 
+0200
@@ -113,8 +113,13 @@
     if (g_strcmp0(key, KEY_USE_PROXY) == 0) {
         if (g_strcmp0(value, "true") == 0)
             session->use_http_proxy = TRUE;
-        else
+        else {
             session->use_http_proxy = FALSE;
+            // Disabling proxy completes with KEY_USE_PROXY=false,
+            // so reconnect notification server here to drop the old proxied 
connection.
+            if (session->notif_mgr)
+                seaf_notif_manager_reconnect_servers (session->notif_mgr);
+        }
     }
 
     if (g_strcmp0(key, KEY_PROXY_TYPE) == 0) {
@@ -132,6 +137,10 @@
 
     if (g_strcmp0(key, KEY_PROXY_PASSWORD) == 0) {
         session->http_proxy_password = g_strdup(value);
+        // The RPC caller updates proxy settings key by key and writes 
KEY_PROXY_PASSWORD last when proxy is enabled,
+        // so reconnect notifications here to pick up the complete new proxy 
settings.
+        if (session->notif_mgr)
+            seaf_notif_manager_reconnect_servers (session->notif_mgr);
     }
 
     if (g_strcmp0(key, KEY_HIDE_WINDOWS_INCOMPATIBLE_PATH_NOTIFICATION) == 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/daemon/seafile-error.c 
new/seafile-9.0.21/daemon/seafile-error.c
--- old/seafile-9.0.20/daemon/seafile-error.c   2026-06-29 11:19:16.000000000 
+0200
+++ new/seafile-9.0.21/daemon/seafile-error.c   2026-08-07 08:17:18.000000000 
+0200
@@ -209,6 +209,11 @@
         SYNC_ERROR_LEVEL_REPO,
         "Encryption key is corrupted. Please create a new library and upload 
files again"
     },
+    {
+        SYNC_ERROR_ID_WATCH_FAILED,
+        SYNC_ERROR_LEVEL_FILE,
+        "Failed to monitor local folder changes. Please check Linux inotify 
limits or ignore rules"
+    },
 };
 
 const char *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/daemon/wt-monitor-linux.c 
new/seafile-9.0.21/daemon/wt-monitor-linux.c
--- old/seafile-9.0.20/daemon/wt-monitor-linux.c        2026-06-29 
11:19:16.000000000 +0200
+++ new/seafile-9.0.21/daemon/wt-monitor-linux.c        2026-08-07 
08:17:18.000000000 +0200
@@ -12,6 +12,7 @@
 
 #include "job-mgr.h"
 #include "seafile-session.h"
+#include "seafile-error.h"
 #include "utils.h"
 #include "wt-monitor.h"
 #define DEBUG_FLAG SEAFILE_DEBUG_WATCH
@@ -39,6 +40,8 @@
     WatchPathMapping *mapping;
     RenameInfo *rename_info;
     EventInfo last_event;
+    GList *ignore_list;
+    gboolean watch_error_reported;
     char *worktree;
 } RepoWatchInfo;
 
@@ -56,6 +59,14 @@
 
 static void handle_watch_command (SeafWTMonitor *monitor, WatchCommand *cmd);
 
+static int handle_refresh_repo (SeafWTMonitor *monitor, const char *repo_id);
+
+static void
+add_event_to_queue (WTStatus *status,
+                    int type,
+                    const char *path,
+                    const char *new_path);
+
 static int
 add_watch_recursive (RepoWatchInfo *info, int in_fd,
                      const char *worktree, const char *path,
@@ -132,6 +143,7 @@
     info->status = status;
     info->mapping = mapping;
     info->rename_info = rename_info;
+    info->ignore_list = seaf_repo_load_ignore_files (worktree);
     info->worktree = g_strdup(worktree);
 
     return info;
@@ -143,11 +155,22 @@
     wt_status_unref (info->status);
     free_mapping (info->mapping);
     free_rename_info (info->rename_info);
+    seaf_repo_free_ignore_files (info->ignore_list);
     g_free (info->worktree);
     g_free (info);
 }
 
 static void
+add_watch_error_event (RepoWatchInfo *info, const char *path)
+{
+    if (info->watch_error_reported)
+        return;
+
+    info->watch_error_reported = TRUE;
+    add_event_to_queue (info->status, WT_EVENT_WATCH_ERROR, path, NULL);
+}
+
+static void
 add_event_to_queue (WTStatus *status,
                     int type, const char *path, const char *new_path)
 {
@@ -173,6 +196,9 @@
     case WT_EVENT_ATTRIB:
         name = "attribute change";
         break;
+    case WT_EVENT_WATCH_ERROR:
+        name = "watch error";
+        break;
     default:
         name = "unknown";
     }
@@ -398,8 +424,9 @@
 }
 
 static gboolean
-process_events (SeafWTMonitorPriv *priv, const char *repo_id, int in_fd)
+process_events (SeafWTMonitor *monitor, const char *repo_id, int in_fd)
 {
+    SeafWTMonitorPriv *priv = monitor->priv;
     char *event_buf = NULL;
     unsigned int buf_size;
     struct inotify_event *event;
@@ -496,7 +523,7 @@
             repo_id = key;
             inotify_fd = (int)(long)value;
             if (FD_ISSET (inotify_fd, &fds))
-                process_events (priv, repo_id, inotify_fd);
+                process_events (monitor, repo_id, inotify_fd);
         }
     }
 
@@ -530,6 +557,12 @@
         goto out;
     }
 
+    if (path[0] != 0 && S_ISDIR(st.st_mode) &&
+        seaf_repo_check_ignore_file (info->ignore_list, full_path)) {
+        seaf_debug ("[wt mon] skip ignored dir %s.\n", full_path);
+        goto out;
+    }
+
     if (add_events && path[0] != 0)
         add_event_to_queue (info->status, WT_EVENT_CREATE_OR_UPDATE,
                             path, NULL);
@@ -541,6 +574,7 @@
         if (wd < 0) {
             seaf_warning ("[wt mon] fail to add watch to %s: %s.\n",
                           full_path, strerror(errno));
+            add_watch_error_event (info, path);
             goto out;
         }
 
@@ -673,9 +707,31 @@
     return 0;
 }
 
-static int handle_refresh_repo (SeafWTMonitorPriv *priv, const char *repo_id)
+static int
+handle_refresh_repo (SeafWTMonitor *monitor, const char *repo_id)
 {
-    return 0;
+    SeafWTMonitorPriv *priv = monitor->priv;
+    gpointer key, value;
+    RepoWatchInfo *info;
+    char *worktree;
+    int ret;
+
+    if (!g_hash_table_lookup_extended (priv->handle_hash, repo_id, &key, 
&value))
+        return 0;
+
+    info = g_hash_table_lookup (priv->info_hash, value);
+    if (!info)
+        return -1;
+
+    // Copy worktree before calling handle_rm_repo, since handle_rm_repo frees 
info.
+    worktree = g_strdup (info->worktree);
+    info->watch_error_reported = FALSE;
+
+    handle_rm_repo (monitor, repo_id, value);
+    ret = handle_add_repo (priv, repo_id, worktree);
+
+    g_free (worktree);
+    return ret;
 }
 
 static void
@@ -703,6 +759,8 @@
         if (handle_add_repo(priv, cmd->repo_id, cmd->worktree) < 0) {
             seaf_warning ("[wt mon] failed to watch worktree of repo %s.\n",
                           cmd->repo_id);
+            send_file_sync_error_notification (cmd->repo_id, NULL, "/",
+                                               SYNC_ERROR_ID_WATCH_FAILED);
             reply_watch_command (monitor, -1);
             return;
         }
@@ -720,7 +778,7 @@
         handle_rm_repo (monitor, cmd->repo_id, value);
         reply_watch_command (monitor, 0);
     } else if (cmd->type ==  CMD_REFRESH_WATCH) {
-        if (handle_refresh_repo (priv, cmd->repo_id) < 0) {
+        if (handle_refresh_repo (monitor, cmd->repo_id) < 0) {
             seaf_warning ("[wt mon] failed to refresh watch of repo %s.\n",
                           cmd->repo_id);
             reply_watch_command (monitor, -1);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/daemon/wt-monitor-structs.h 
new/seafile-9.0.21/daemon/wt-monitor-structs.h
--- old/seafile-9.0.20/daemon/wt-monitor-structs.h      2026-06-29 
11:19:16.000000000 +0200
+++ new/seafile-9.0.21/daemon/wt-monitor-structs.h      2026-08-07 
08:17:18.000000000 +0200
@@ -11,6 +11,7 @@
     WT_EVENT_ATTRIB,
     WT_EVENT_OVERFLOW,
     WT_EVENT_SCAN_DIR,
+    WT_EVENT_WATCH_ERROR,
 };
 
 typedef struct WTEvent {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/debian/changelog 
new/seafile-9.0.21/debian/changelog
--- old/seafile-9.0.20/debian/changelog 2026-06-29 11:19:16.000000000 +0200
+++ new/seafile-9.0.21/debian/changelog 2026-08-07 08:17:18.000000000 +0200
@@ -1,3 +1,8 @@
+seafile-daemon (9.0.21) unstable; urgency=low
+
+  * new upstream release
+
+ -- Jonathan Xu <[email protected]>  Fri, 07 Aug 2026 14:15:21 +0800
 seafile-daemon (9.0.20) unstable; urgency=low
 
   * new upstream release
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/include/seafile-error.h 
new/seafile-9.0.21/include/seafile-error.h
--- old/seafile-9.0.20/include/seafile-error.h  2026-06-29 11:19:16.000000000 
+0200
+++ new/seafile-9.0.21/include/seafile-error.h  2026-08-07 08:17:18.000000000 
+0200
@@ -69,6 +69,7 @@
 #define SYNC_ERROR_ID_CASE_CONFLICT             37
 #define SYNC_ERROR_ID_STOPPED_BY_LOGOUT         38
 #define SYNC_ERROR_ID_CORRUPTED_ENC_KEY         39
-#define N_SYNC_ERROR_ID                         40
+#define SYNC_ERROR_ID_WATCH_FAILED              40
+#define N_SYNC_ERROR_ID                         41
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/msi/Includes.wxi 
new/seafile-9.0.21/msi/Includes.wxi
--- old/seafile-9.0.20/msi/Includes.wxi 2026-06-29 11:19:16.000000000 +0200
+++ new/seafile-9.0.21/msi/Includes.wxi 2026-08-07 08:17:18.000000000 +0200
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Include Id="SeafileInclude">
-  <?define CurrentSeafileVersion="9.0.20" ?>
+  <?define CurrentSeafileVersion="9.0.21" ?>
 
   <!-- Update Guid 不能变 -->
   <?define CurrentUpdateGuid="65DED1C8-A5F1-4C49-8E7E-B0A8A5A6535C" ?>
@@ -173,7 +173,8 @@
   <!-- <?define ProductGuid="F9FBBFAF-7E4B-4DD0-BB55-2CC22A91DF6C" ?> (9.0.16) 
-->
   <!-- <?define ProductGuid="340A1B15-1F3C-4EB7-91D5-6B210299B7D8" ?> (9.0.18) 
-->
   <!-- <?define ProductGuid="F7B60716-0AE3-4E15-BBBF-489D9FE36FDD" ?> (9.0.19) 
-->
-  <?define ProductGuid="6D8AA65E-1A89-4E5A-9313-767322FDA996" ?>
+  <!-- <?define ProductGuid="6D8AA65E-1A89-4E5A-9313-767322FDA996" ?> (9.0.20) 
-->
+  <?define ProductGuid="812B8682-0C2A-4D5D-9EC6-97E3FC222955" ?>
 
   <?define GuidOfCustomComponent="AD201805-3CBD-4834-9097-5D934F7E0000" ?>
   <?define GuidOfAutoStartComponent="AD201805-3CBD-4834-9097-5D934F7E0001" ?>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/seafile-9.0.20/seafile-ports/libwebsockets/export-include-path.patch 
new/seafile-9.0.21/seafile-ports/libwebsockets/export-include-path.patch
--- old/seafile-9.0.20/seafile-ports/libwebsockets/export-include-path.patch    
1970-01-01 01:00:00.000000000 +0100
+++ new/seafile-9.0.21/seafile-ports/libwebsockets/export-include-path.patch    
2026-08-07 08:17:18.000000000 +0200
@@ -0,0 +1,35 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt   (revision b0a749c8e7a8294b68581ce4feac0e55045eb00b)
++++ b/CMakeLists.txt   (date 1669850632899)
+@@ -1071,8 +1071,8 @@
+     "${LWS_ABSOLUTE_INSTALL_CMAKE_DIR}"
+     "${LWS_ABSOLUTE_INSTALL_INCLUDE_DIR}") # Calculate the relative directory 
from the cmake dir.
+ 
+-if (DEFINED REL_INCLUDE_DIR)
+-    set(LWS__INCLUDE_DIRS "\${LWS_CMAKE_DIR}/${REL_INCLUDE_DIR}")
++if (1)
++      set(LWS__INCLUDE_DIRS "\${CMAKE_CURRENT_LIST_DIR}/../include")
+ endif()
+ if (DEFINED OPENSSL_INCLUDE_DIRS)
+       set(LWS__INCLUDE_DIRS "${LWS__INCLUDE_DIRS};${OPENSSL_INCLUDE_DIRS}")
+diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
+--- a/lib/CMakeLists.txt       (revision 
b0a749c8e7a8294b68581ce4feac0e55045eb00b)
++++ b/lib/CMakeLists.txt       (date 1669850782017)
+@@ -174,7 +174,7 @@
+               $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
+               $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include>
+       )
+-      target_include_directories(websockets PRIVATE 
${LWS_LIB_BUILD_INC_PATHS})
++      target_include_directories(websockets PRIVATE 
$<BUILD_INTERFACE:${LWS_LIB_BUILD_INC_PATHS}> PUBLIC 
$<INSTALL_INTERFACE:include>)
+       target_compile_definitions(websockets PRIVATE LWS_BUILDING_STATIC)
+       target_include_directories(websockets PUBLIC ${LWS_PUBLIC_INCLUDES})
+       set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
+@@ -202,7 +202,7 @@
+               $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
+               $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include>
+       )
+-      target_include_directories(websockets_shared PRIVATE 
${LWS_LIB_BUILD_INC_PATHS})
++      target_include_directories(websockets_shared PRIVATE 
$<BUILD_INTERFACE:${LWS_LIB_BUILD_INC_PATHS}> PUBLIC 
$<INSTALL_INTERFACE:include>)
+       target_compile_definitions(websockets_shared PRIVATE 
LWS_BUILDING_SHARED)
+       target_include_directories(websockets_shared PUBLIC 
${LWS_PUBLIC_INCLUDES})
+       set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/seafile-9.0.20/seafile-ports/libwebsockets/fix-build-error.patch 
new/seafile-9.0.21/seafile-ports/libwebsockets/fix-build-error.patch
--- old/seafile-9.0.20/seafile-ports/libwebsockets/fix-build-error.patch        
1970-01-01 01:00:00.000000000 +0100
+++ new/seafile-9.0.21/seafile-ports/libwebsockets/fix-build-error.patch        
2026-08-07 08:17:18.000000000 +0200
@@ -0,0 +1,24 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt   (revision b0a749c8e7a8294b68581ce4feac0e55045eb00b)
++++ b/CMakeLists.txt   (date 1669850509296)
+@@ -494,6 +494,11 @@
+ set(LWS_EXT_PTHREAD_INCLUDE_DIR CACHE PATH "Path to an external pthreads 
include directory")
+ set(LWS_EXT_PTHREAD_LIBRARIES CACHE PATH "Path to an external pthreads 
library")
+ 
++if(WIN32)
++    find_package(pthreads_windows REQUIRED)
++    set(LWS_EXT_PTHREAD_INCLUDE_DIR ${PThreads4W_INCLUDE_DIR})
++    set(LWS_EXT_PTHREAD_LIBRARIES ${PThreads4W_LIBRARY})
++endif()
+ 
+ if (LWS_WITH_HTTP_STREAM_COMPRESSION)
+       set(LWS_WITH_ZLIB 1)
+@@ -850,7 +855,7 @@
+       # Turn off pointless microsoft security warnings.
+       add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
+       # Fail the build if any warnings
+-      add_compile_options(/W3 /WX)
++      add_compile_options(/W3 /WX /wd4142 /wd4267 /wd4996)
+       # Unbreak MSVC broken preprocessor __VA_ARGS__ behaviour
+       if (MSVC_VERSION GREATER 1925)
+               add_compile_options(/Zc:preprocessor /wd5105)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/seafile-9.0.20/seafile-ports/libwebsockets/fix-dependency-libuv.patch 
new/seafile-9.0.21/seafile-ports/libwebsockets/fix-dependency-libuv.patch
--- old/seafile-9.0.20/seafile-ports/libwebsockets/fix-dependency-libuv.patch   
1970-01-01 01:00:00.000000000 +0100
+++ new/seafile-9.0.21/seafile-ports/libwebsockets/fix-dependency-libuv.patch   
2026-08-07 08:17:18.000000000 +0200
@@ -0,0 +1,13 @@
+diff --git a/lib/event-libs/libuv/CMakeLists.txt 
b/lib/event-libs/libuv/CMakeLists.txt
+index fb810a8..2258ade 100644
+--- a/lib/event-libs/libuv/CMakeLists.txt
++++ b/lib/event-libs/libuv/CMakeLists.txt
+@@ -36,7 +36,7 @@ set(LWS_LIBUV_INCLUDE_DIRS CACHE PATH "Path to the libuv 
include directory")
+ if ("${LWS_LIBUV_LIBRARIES}" STREQUAL "" OR "${LWS_LIBUV_INCLUDE_DIRS}" 
STREQUAL "")
+       if (NOT LIBUV_FOUND)
+               find_path(LIBUV_INCLUDE_DIRS NAMES uv.h)
+-              find_library(LIBUV_LIBRARIES NAMES uv)
++              find_library(LIBUV_LIBRARIES NAMES uv libuv)
+       endif()
+ else()
+       set(LIBUV_LIBRARIES ${LWS_LIBUV_LIBRARIES})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/seafile-9.0.20/seafile-ports/libwebsockets/fix-find-openssl.patch 
new/seafile-9.0.21/seafile-ports/libwebsockets/fix-find-openssl.patch
--- old/seafile-9.0.20/seafile-ports/libwebsockets/fix-find-openssl.patch       
1970-01-01 01:00:00.000000000 +0100
+++ new/seafile-9.0.21/seafile-ports/libwebsockets/fix-find-openssl.patch       
2026-08-07 08:17:18.000000000 +0200
@@ -0,0 +1,11 @@
+diff --git a/lib/tls/CMakeLists.txt b/lib/tls/CMakeLists.txt
+--- a/lib/tls/CMakeLists.txt   (revision 
a5aae049b2a386712e1be3b417915c0d44c7e675)
++++ b/lib/tls/CMakeLists.txt   (date 1642427956730)
+@@ -257,7 +257,6 @@
+                               find_package(PkgConfig QUIET)
+                               pkg_check_modules(PC_OPENSSL openssl QUIET)
+                               find_package(OpenSSL REQUIRED)
+-                              list(APPEND OPENSSL_LIBRARIES 
${PC_OPENSSL_LIBRARIES})
+                               set(OPENSSL_LIBRARIES ${OPENSSL_LIBRARIES} 
PARENT_SCOPE)
+                       endif()
+                       set(OPENSSL_INCLUDE_DIRS "${OPENSSL_INCLUDE_DIR}")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/seafile-9.0.20/seafile-ports/libwebsockets/portfile.cmake 
new/seafile-9.0.21/seafile-ports/libwebsockets/portfile.cmake
--- old/seafile-9.0.20/seafile-ports/libwebsockets/portfile.cmake       
1970-01-01 01:00:00.000000000 +0100
+++ new/seafile-9.0.21/seafile-ports/libwebsockets/portfile.cmake       
2026-08-07 08:17:18.000000000 +0200
@@ -0,0 +1,192 @@
+vcpkg_from_github(
+    OUT_SOURCE_PATH SOURCE_PATH
+    REPO warmcat/libwebsockets
+    REF b0a749c8e7a8294b68581ce4feac0e55045eb00b # v4.3.2
+    SHA512 
48c1d59cfdbe6cc043a51e950a614273bd2f9bbfd0ab8436e4ba30bf119cfdbc3e691c02608e8c169356ec79ca96472340d98d17659b66ee60bb998f3695d3c4
+    HEAD_REF master
+    PATCHES
+        fix-dependency-libuv.patch
+        fix-build-error.patch
+        export-include-path.patch
+        fix-find-openssl.patch
+)
+
+string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" LWS_WITH_STATIC)
+string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" LWS_WITH_SHARED)
+
+## All LWS options could be possible features:
+# #
+# # Major individual features
+# #
+# option(LWS_WITH_NETWORK "Compile with network-related code" ON)
+# option(LWS_ROLE_H1 "Compile with support for http/1 (needed for ws)" ON)
+# option(LWS_ROLE_WS "Compile with support for websockets" ON)
+# option(LWS_ROLE_DBUS "Compile with support for DBUS" OFF)
+# option(LWS_ROLE_RAW_PROXY "Raw packet proxy" OFF)
+# option(LWS_WITH_HTTP2 "Compile with server support for HTTP/2" ON)
+# option(LWS_WITH_LWSWS "Libwebsockets Webserver" OFF)
+# option(LWS_WITH_CGI "Include CGI (spawn process with network-connected 
stdin/out/err) APIs" OFF)
+# option(LWS_IPV6 "Compile with support for ipv6" OFF)
+# option(LWS_UNIX_SOCK "Compile with support for UNIX domain socket" OFF)
+# option(LWS_WITH_PLUGINS "Support plugins for protocols and extensions" OFF)
+# option(LWS_WITH_HTTP_PROXY "Support for HTTP proxying" OFF)
+# option(LWS_WITH_ZIP_FOPS "Support serving pre-zipped files" OFF)
+# option(LWS_WITH_SOCKS5 "Allow use of SOCKS5 proxy on client connections" OFF)
+# option(LWS_WITH_GENERIC_SESSIONS "With the Generic Sessions plugin" OFF)
+# option(LWS_WITH_PEER_LIMITS "Track peers and restrict resources a single 
peer can allocate" OFF)
+# option(LWS_WITH_ACCESS_LOG "Support generating Apache-compatible access 
logs" OFF)
+# option(LWS_WITH_RANGES "Support http ranges (RFC7233)" OFF)
+# option(LWS_WITH_SERVER_STATUS "Support json + jscript server monitoring" OFF)
+# option(LWS_WITH_THREADPOOL "Managed worker thread pool support (relies on 
pthreads)" OFF)
+# option(LWS_WITH_HTTP_STREAM_COMPRESSION "Support HTTP stream compression" 
OFF)
+# option(LWS_WITH_HTTP_BROTLI "Also offer brotli http stream compression 
(requires LWS_WITH_HTTP_STREAM_COMPRESSION)" OFF)
+# option(LWS_WITH_ACME "Enable support for ACME automatic cert acquisition + 
maintenance (letsencrypt etc)" OFF)
+# option(LWS_WITH_HUBBUB "Enable libhubbub rewriting support" OFF)
+# option(LWS_WITH_FTS "Full Text Search support" OFF)
+# #
+# # TLS library options... all except mbedTLS are basically OpenSSL variants.
+# #
+# option(LWS_WITH_SSL "Include SSL support (defaults to OpenSSL or similar, 
mbedTLS if LWS_WITH_MBEDTLS is set)" ON)
+# option(LWS_WITH_MBEDTLS "Use mbedTLS (>=2.0) replacement for OpenSSL. When 
setting this, you also may need to specify LWS_MBEDTLS_LIBRARIES and 
LWS_MBEDTLS_INCLUDE_DIRS" OFF)
+# option(LWS_WITH_BORINGSSL "Use BoringSSL replacement for OpenSSL" OFF)
+# option(LWS_WITH_CYASSL "Use CyaSSL replacement for OpenSSL. When setting 
this, you also need to specify LWS_CYASSL_LIBRARIES and 
LWS_CYASSL_INCLUDE_DIRS" OFF)
+# option(LWS_WITH_WOLFSSL "Use wolfSSL replacement for OpenSSL. When setting 
this, you also need to specify LWS_WOLFSSL_LIBRARIES and 
LWS_WOLFSSL_INCLUDE_DIRS" OFF)
+# option(LWS_SSL_CLIENT_USE_OS_CA_CERTS "SSL support should make use of the 
OS-installed CA root certs" ON)
+# #
+# # Event library options (may select multiple, or none for default poll()
+# #
+# option(LWS_WITH_LIBEV "Compile with support for libev" OFF)
+# option(LWS_WITH_LIBUV "Compile with support for libuv" OFF)
+# option(LWS_WITH_LIBEVENT "Compile with support for libevent" OFF)
+# #
+# # Static / Dynamic build options
+# #
+# option(LWS_WITH_STATIC "Build the static version of the library" ON)
+# option(LWS_WITH_SHARED "Build the shared version of the library" ON)
+# option(LWS_LINK_TESTAPPS_DYNAMIC "Link the test apps to the shared version 
of the library. Default is to link statically" OFF)
+# option(LWS_STATIC_PIC "Build the static version of the library with 
position-independent code" OFF)
+# #
+# # Specific platforms
+# #
+# option(LWS_WITH_ESP32 "Build for ESP32" OFF)
+# option(LWS_WITH_ESP32_HELPER "Build ESP32 helper" OFF)
+# option(LWS_PLAT_OPTEE "Build for OPTEE" OFF)
+# #
+# # Client / Server / Test Apps build control
+# #
+# option(LWS_WITHOUT_CLIENT "Don't build the client part of the library" OFF)
+# option(LWS_WITHOUT_SERVER "Don't build the server part of the library" OFF)
+# option(LWS_WITHOUT_TESTAPPS "Don't build the libwebsocket-test-apps" OFF)
+# option(LWS_WITHOUT_TEST_SERVER "Don't build the test server" OFF)
+# option(LWS_WITHOUT_TEST_SERVER_EXTPOLL "Don't build the test server version 
that uses external poll" OFF)
+# option(LWS_WITHOUT_TEST_PING "Don't build the ping test application" OFF)
+# option(LWS_WITHOUT_TEST_CLIENT "Don't build the client test application" OFF)
+# #
+# # Extensions (permessage-deflate)
+# #
+# option(LWS_WITHOUT_EXTENSIONS "Don't compile with extensions" ON)
+# #
+# # Helpers + misc
+# #
+# option(LWS_WITHOUT_BUILTIN_GETIFADDRS "Don't use the BSD getifaddrs 
implementation from libwebsockets if it is missing (this will result in a 
compilation error) ... The default is to assume that your libc provides it. On 
some systems such as uclibc it doesn't exist." OFF)
+# option(LWS_FALLBACK_GETHOSTBYNAME "Also try to do dns resolution using 
gethostbyname if getaddrinfo fails" OFF)
+# option(LWS_WITHOUT_BUILTIN_SHA1 "Don't build the lws sha-1 (eg, because 
openssl will provide it" OFF)
+# option(LWS_WITH_LATENCY "Build latency measuring code into the library" OFF)
+# option(LWS_WITHOUT_DAEMONIZE "Don't build the daemonization api" ON)
+# option(LWS_SSL_SERVER_WITH_ECDH_CERT "Include SSL server use ECDH 
certificate" OFF)
+# option(LWS_WITH_LEJP "With the Lightweight JSON Parser" ON)
+# option(LWS_WITH_SQLITE3 "Require SQLITE3 support" OFF)
+# option(LWS_WITH_STRUCT_JSON "Generic struct serialization to and from JSON" 
ON)
+# option(LWS_WITH_STRUCT_SQLITE3 "Generic struct serialization to and from 
SQLITE3" OFF)
+# option(LWS_WITH_SMTP "Provide SMTP support" OFF)
+# if (WIN32 OR LWS_WITH_ESP32)
+# option(LWS_WITH_DIR "Directory scanning api support" OFF)
+# option(LWS_WITH_LEJP_CONF "With LEJP configuration parser as used by lwsws" 
OFF)
+# else()
+# option(LWS_WITH_DIR "Directory scanning api support" ON)
+# option(LWS_WITH_LEJP_CONF "With LEJP configuration parser as used by lwsws" 
ON)
+# endif()
+# option(LWS_WITH_NO_LOGS "Disable all logging from being compiled in" OFF)
+# option(LWS_AVOID_SIGPIPE_IGN "Android 7+ reportedly needs this" OFF)
+# option(LWS_WITH_STATS "Keep statistics of lws internal operations" OFF)
+# option(LWS_WITH_JOSE "JSON Web Signature / Encryption / Keys (RFC7515/6/) 
API" OFF)
+# option(LWS_WITH_GENCRYPTO "Enable support for Generic Crypto apis 
independent of TLS backend" OFF)
+# option(LWS_WITH_SELFTESTS "Selftests run at context creation" OFF)
+# option(LWS_WITH_GCOV "Build with gcc gcov coverage instrumentation" OFF)
+# option(LWS_WITH_EXPORT_LWSTARGETS "Export libwebsockets CMake targets.  
Disable if they conflict with an outer cmake project." ON)
+# option(LWS_REPRODUCIBLE "Build libwebsockets reproducible. It removes the 
build user and hostname from the build" ON)
+# option(LWS_WITH_MINIMAL_EXAMPLES "Also build the normally standalone minimal 
examples, for QA" OFF)
+# option(LWS_WITH_LWSAC "lwsac Chunk Allocation api" ON)
+# option(LWS_WITH_CUSTOM_HEADERS "Store and allow querying custom HTTP headers 
(H1 only)" ON)
+# option(LWS_WITH_DISKCACHE "Hashed cache directory with lazy LRU deletion to 
size limit" OFF)
+# option(LWS_WITH_ASAN "Build with gcc runtime sanitizer options enabled 
(needs libasan)" OFF)
+# option(LWS_WITH_DIR "Directory scanning api support" OFF)
+# option(LWS_WITH_LEJP_CONF "With LEJP configuration parser as used by lwsws" 
OFF)
+# option(LWS_WITH_ZLIB "Include zlib support (required for extensions)" OFF)
+# option(LWS_WITH_BUNDLED_ZLIB "Use bundled zlib version (Windows only)" 
${LWS_WITH_BUNDLED_ZLIB_DEFAULT})
+# option(LWS_WITH_MINIZ "Use miniz instead of zlib" OFF)
+# option(LWS_WITH_DEPRECATED_LWS_DLL "Migrate to lws_dll2 instead ASAP" OFF)
+# option(LWS_WITH_SEQUENCER "lws_seq_t support" ON)
+# option(LWS_WITH_EXTERNAL_POLL "Support external POLL integration using 
callback messages (not recommended)" OFF)
+# option(LWS_WITH_LWS_DSH "Support lws_dsh_t Disordered Shared Heap" OFF)
+##
+
+set(EXTRA_ARGS)
+if(NOT VCPKG_TARGET_ARCHITECTURE STREQUAL "wasm32")
+    set(EXTRA_ARGS "-DLWS_WITH_LIBUV=ON")
+endif()
+
+vcpkg_cmake_configure(
+    SOURCE_PATH "${SOURCE_PATH}"
+    OPTIONS
+        ${EXTRA_ARGS}
+        -DLWS_WITH_STATIC=${LWS_WITH_STATIC}
+        -DLWS_WITH_SHARED=${LWS_WITH_SHARED}
+        -DLWS_WITH_GENCRYPTO=ON
+        -DLWS_WITH_TLS=ON
+        -DLWS_WITH_BUNDLED_ZLIB=OFF
+        -DLWS_WITHOUT_TESTAPPS=ON
+        -DLWS_IPV6=ON
+        -DLWS_WITH_HTTP2=ON
+        -DLWS_WITH_HTTP_STREAM_COMPRESSION=ON # Since zlib is already a 
dependency
+        -DLWS_WITH_EXTERNAL_POLL=ON
+       -DLWS_WITH_SOCKS5=ON
+    # OPTIONS_RELEASE -DOPTIMIZE=1
+    # OPTIONS_DEBUG -DDEBUGGABLE=1
+)
+
+vcpkg_cmake_install()
+
+if (VCPKG_TARGET_IS_WINDOWS)
+    vcpkg_cmake_config_fixup(CONFIG_PATH cmake)
+else()
+    vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/libwebsockets)
+endif()
+
+file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
+file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share")
+file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/share/libwebsockets-test-server")
+file(READ 
"${CURRENT_PACKAGES_DIR}/share/libwebsockets/libwebsockets-config.cmake" 
LIBWEBSOCKETSCONFIG_CMAKE)
+string(REPLACE "/../include" "/../../include" LIBWEBSOCKETSCONFIG_CMAKE 
"${LIBWEBSOCKETSCONFIG_CMAKE}")
+file(WRITE 
"${CURRENT_PACKAGES_DIR}/share/libwebsockets/libwebsockets-config.cmake" 
"${LIBWEBSOCKETSCONFIG_CMAKE}")
+
+if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
+    vcpkg_replace_string( 
"${CURRENT_PACKAGES_DIR}/share/libwebsockets/LibwebsocketsTargets-debug.cmake" 
"websockets_static.lib" "websockets.lib")
+endif()
+
+if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
+    vcpkg_replace_string( 
"${CURRENT_PACKAGES_DIR}/share/libwebsockets/LibwebsocketsTargets-release.cmake"
 "websockets_static.lib" "websockets.lib")
+endif()
+
+if (VCPKG_LIBRARY_LINKAGE STREQUAL static)
+    if (VCPKG_TARGET_IS_WINDOWS)
+        file(RENAME "${CURRENT_PACKAGES_DIR}/debug/lib/websockets_static.lib" 
"${CURRENT_PACKAGES_DIR}/debug/lib/websockets.lib")
+        file(RENAME "${CURRENT_PACKAGES_DIR}/lib/websockets_static.lib" 
"${CURRENT_PACKAGES_DIR}/lib/websockets.lib")
+    endif()
+endif ()
+
+vcpkg_copy_pdbs()
+vcpkg_fixup_pkgconfig()
+vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/lws_config.h" 
"${CURRENT_PACKAGES_DIR}" "")
+
+file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION 
"${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/seafile-9.0.20/seafile-ports/libwebsockets/vcpkg.json 
new/seafile-9.0.21/seafile-ports/libwebsockets/vcpkg.json
--- old/seafile-9.0.20/seafile-ports/libwebsockets/vcpkg.json   1970-01-01 
01:00:00.000000000 +0100
+++ new/seafile-9.0.21/seafile-ports/libwebsockets/vcpkg.json   2026-08-07 
08:17:18.000000000 +0200
@@ -0,0 +1,24 @@
+{
+  "name": "libwebsockets",
+  "version-semver": "4.3.2",
+  "description": "Libwebsockets is a lightweight pure C library built to use 
minimal CPU and memory resources, and provide fast throughput in both 
directions as client or server.",
+  "homepage": "https://github.com/warmcat/libwebsockets";,
+  "supports": "!uwp",
+  "dependencies": [
+    {
+      "name": "libuv",
+      "platform": "!emscripten"
+    },
+    "openssl",
+    "pthreads",
+    {
+      "name": "vcpkg-cmake",
+      "host": true
+    },
+    {
+      "name": "vcpkg-cmake-config",
+      "host": true
+    },
+    "zlib"
+  ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/seafile.vcxproj 
new/seafile-9.0.21/seafile.vcxproj
--- old/seafile-9.0.20/seafile.vcxproj  2026-06-29 11:19:16.000000000 +0200
+++ new/seafile-9.0.21/seafile.vcxproj  2026-08-07 08:17:18.000000000 +0200
@@ -95,7 +95,7 @@
       <WarningLevel>Level3</WarningLevel>
       <SDLCheck>
       </SDLCheck>
-      
<PreprocessorDefinitions>WIN32;UNICODE;WIN32_LEAN_AND_MEAN;SEAFILE_CLIENT;PACKAGE_VERSION="9.0.20";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      
<PreprocessorDefinitions>WIN32;UNICODE;WIN32_LEAN_AND_MEAN;SEAFILE_CLIENT;PACKAGE_VERSION="9.0.21";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>false</ConformanceMode>
       <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
       
<AdditionalIncludeDirectories>$(ProjectDir)..\libsearpc\lib;$(ProjectDir)common;$(ProjectDir)lib;$(ProjectDir)include;$(ProjectDir)daemon;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -113,7 +113,7 @@
       <WarningLevel>Level1</WarningLevel>
       <SDLCheck>
       </SDLCheck>
-      
<PreprocessorDefinitions>WIN32;UNICODE;WIN32_LEAN_AND_MEAN;SEAFILE_CLIENT;PACKAGE_VERSION="9.0.20";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      
<PreprocessorDefinitions>WIN32;UNICODE;WIN32_LEAN_AND_MEAN;SEAFILE_CLIENT;PACKAGE_VERSION="9.0.21";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>false</ConformanceMode>
       <LanguageStandard>stdcpp17</LanguageStandard>
       
<AdditionalIncludeDirectories>$(ProjectDir)vcpkg_installed\x64-windows\x64-windows\include\glib-2.0;$(ProjectDir)vcpkg_installed\x64-windows\x64-windows\lib\glib-2.0\include;$(ProjectDir)..\libsearpc\lib;$(ProjectDir)common;$(ProjectDir)include;$(ProjectDir)daemon;$(ProjectDir)lib;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -134,7 +134,7 @@
       <IntrinsicFunctions>false</IntrinsicFunctions>
       <SDLCheck>
       </SDLCheck>
-      
<PreprocessorDefinitions>WIN32;PACKAGE_VERSION="9.0.20";WIN32_LEAN_AND_MEAN;UNICODE;SEAFILE_CLIENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      
<PreprocessorDefinitions>WIN32;PACKAGE_VERSION="9.0.21";WIN32_LEAN_AND_MEAN;UNICODE;SEAFILE_CLIENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>false</ConformanceMode>
       <LanguageStandard>stdcpp17</LanguageStandard>
       
<AdditionalIncludeDirectories>$(ProjectDir)..\libsearpc\lib;$(ProjectDir);$(ProjectDir)daemon;$(ProjectDir)include;$(ProjectDir)lib;$(ProjectDir)common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -161,7 +161,7 @@
       <IntrinsicFunctions>false</IntrinsicFunctions>
       <SDLCheck>
       </SDLCheck>
-      
<PreprocessorDefinitions>WIN32;PACKAGE_VERSION="9.0.20";WIN32_LEAN_AND_MEAN;UNICODE;SEAFILE_CLIENT;ENABLE_BREAKPAD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      
<PreprocessorDefinitions>WIN32;PACKAGE_VERSION="9.0.21";WIN32_LEAN_AND_MEAN;UNICODE;SEAFILE_CLIENT;ENABLE_BREAKPAD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>false</ConformanceMode>
       <LanguageStandard>stdcpp17</LanguageStandard>
       
<AdditionalIncludeDirectories>$(ProjectDir)vcpkg_installed\x64-windows\x64-windows\include\glib-2.0;$(ProjectDir)vcpkg_installed\x64-windows\x64-windows\lib\glib-2.0\include;$(ProjectDir)..\libsearpc\lib;$(ProjectDir);$(ProjectDir)common;$(ProjectDir)lib;$(ProjectDir)include;$(ProjectDir)daemon;$(ProjectDir)..\breakpad\src;$(ProjectDir)..\libwebsockets\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/seafile-9.0.20/vcpkg-configuration.json 
new/seafile-9.0.21/vcpkg-configuration.json
--- old/seafile-9.0.20/vcpkg-configuration.json 1970-01-01 01:00:00.000000000 
+0100
+++ new/seafile-9.0.21/vcpkg-configuration.json 2026-08-07 08:17:18.000000000 
+0200
@@ -0,0 +1,9 @@
+{
+  "default-registry": {
+    "kind": "builtin",
+    "baseline": "e1dfb369fc1c6e58d5850cf67c224caa955309e5"
+  },
+  "overlay-ports": [
+    "./seafile-ports"
+  ]
+}

Reply via email to