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" + ] +}
