diff --git a/ci/run.py b/ci/run.py index 7071784..dc980cc 100755 --- a/ci/run.py +++ b/ci/run.py @@ -28,7 +28,8 @@ TOPDIR = abspath(join(os.getcwd(), '..')) if on_travis(): PREFIX = expanduser('~/opt/local') else: - PREFIX = os.environ.get('SEAFILE_INSTALL_PREFIX', '/usr/local') + #PREFIX = os.environ.get('SEAFILE_INSTALL_PREFIX', '/usr/local') + PREFIX = os.environ.get('SEAFILE_INSTALL_PREFIX', '/home/ly/.pyenv/versions/3.5.3') INSTALLDIR = '/tmp/seafile-tests' @@ -53,7 +54,7 @@ def make_build_env(): _env_add('LDFLAGS', '-L%s' % join(PREFIX, 'lib64'), seperator=' ') _env_add('PATH', join(PREFIX, 'bin')) - _env_add('PYTHONPATH', join(PREFIX, 'lib/python2.7/site-packages')) + _env_add('PYTHONPATH', join(PREFIX, 'lib/python3.7/site-packages')) _env_add('PKG_CONFIG_PATH', join(PREFIX, 'lib', 'pkgconfig')) _env_add('PKG_CONFIG_PATH', join(PREFIX, 'lib64', 'pkgconfig')) _env_add('PKG_CONFIG_PATH', libsearpc_dir) diff --git a/ci/serverctl.py b/ci/serverctl.py index 4121c33..d8e4fda 100755 --- a/ci/serverctl.py +++ b/ci/serverctl.py @@ -152,7 +152,7 @@ connection_charset = utf8 @retry(wait=wait_fixed(1), stop=stop_after_attempt(10)) def wait_ccnet_ready(self): - if not exists(join(self.ccnet_conf_dir, 'ccnet.sock')): + if not exists(join(self.ccnet_conf_dir, 'ccnet-rpc.sock')): raise TryAgain def start(self): @@ -179,13 +179,13 @@ connection_charset = utf8 seafile_sql_path = join(self.sql_dir, 'sqlite', 'seafile.sql') misc_dir = join(self.ccnet_conf_dir, 'misc') - os.mkdir (misc_dir, 0755) + os.mkdir (misc_dir, 0o755) groupmgr_dir = join(self.ccnet_conf_dir, 'GroupMgr') - os.mkdir (groupmgr_dir, 0755) + os.mkdir (groupmgr_dir, 0o755) orgmgr_dir = join(self.ccnet_conf_dir, 'OrgMgr') - os.mkdir (orgmgr_dir, 0755) + os.mkdir (orgmgr_dir, 0o755) usermgr_dir = join(self.ccnet_conf_dir, 'PeerMgr') - os.mkdir (usermgr_dir, 0755) + os.mkdir (usermgr_dir, 0o755) config_db_path = join(misc_dir, 'config.db') groupmgr_db_path = join(groupmgr_dir, 'groupmgr.db') @@ -193,17 +193,17 @@ connection_charset = utf8 usermgr_db_path = join(usermgr_dir, 'usermgr.db') seafile_db_path = join(self.seafile_conf_dir, 'seafile.db') - sql = '.read {}'.format(config_sql_path) + sql = '.read {}'.format(config_sql_path).encode() shell('sqlite3 ' + config_db_path, inputdata=sql, wait=False) - sql = '.read {}'.format(groupmgr_sql_path) + sql = '.read {}'.format(groupmgr_sql_path).encode() shell('sqlite3 ' + groupmgr_db_path, inputdata=sql, wait=False) - sql = '.read {}'.format(org_sql_path) + sql = '.read {}'.format(org_sql_path).encode() shell('sqlite3 ' + orgmgr_db_path, inputdata=sql, wait=False) - sql = '.read {}'.format(user_sql_path) + sql = '.read {}'.format(user_sql_path).encode() shell('sqlite3 ' + usermgr_db_path, inputdata=sql, wait=False) - sql = '.read {}'.format(user_sql_path) + sql = '.read {}'.format(user_sql_path).encode() shell('sqlite3 ' + usermgr_db_path, inputdata=sql, wait=False) - sql = '.read {}'.format(seafile_sql_path) + sql = '.read {}'.format(seafile_sql_path).encode() shell('sqlite3 ' + seafile_db_path, inputdata=sql, wait=False) def start_ccnet(self): diff --git a/ci/utils.py b/ci/utils.py index 0e908c5..3ad2b38 100644 --- a/ci/utils.py +++ b/ci/utils.py @@ -1,4 +1,5 @@ #coding: UTF-8 +from builtins import str import logging import os diff --git a/common/Makefile.am b/common/Makefile.am index 6dfebde..17a5982 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -20,7 +20,6 @@ noinst_HEADERS = \ obj-backend.h \ block-backend.h \ block.h \ - mq-mgr.h \ seaf-db.h \ config-mgr.h \ merge-new.h \ diff --git a/common/branch-mgr.c b/common/branch-mgr.c index 41391e7..c856faa 100644 --- a/common/branch-mgr.c +++ b/common/branch-mgr.c @@ -88,9 +88,8 @@ struct _SeafBranchManagerPriv { #if defined( SEAFILE_SERVER ) && defined( FULL_FEATURE ) -#include "mq-mgr.h" #include -static void publish_repo_update_event (CEvent *event, void *data); +//static void publish_repo_update_event (CEvent *event, void *data); #endif @@ -116,9 +115,11 @@ int seaf_branch_manager_init (SeafBranchManager *mgr) { #if defined( SEAFILE_SERVER ) && defined( FULL_FEATURE ) +/* mgr->priv->cevent_id = cevent_manager_register (seaf->ev_mgr, (cevent_handler)publish_repo_update_event, NULL); +*/ #endif return open_db (mgr); @@ -334,6 +335,7 @@ typedef struct { char *commit_id; } RepoUpdateEventData; +/* static void publish_repo_update_event (CEvent *event, void *data) { @@ -349,6 +351,7 @@ publish_repo_update_event (CEvent *event, void *data) g_free (rdata->commit_id); g_free (rdata); } +*/ static void on_branch_updated (SeafBranchManager *mgr, SeafBranch *branch) diff --git a/common/mq-mgr.c b/common/mq-mgr.c deleted file mode 100644 index dc17f67..0000000 --- a/common/mq-mgr.c +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include - -#include "mq-mgr.h" - -#include "seafile-session.h" -#include "log.h" - -typedef struct _SeafMqManagerPriv SeafMqManagerPriv; - -struct _SeafMqManagerPriv { - CcnetMqclientProc *mqclient_proc; - CcnetTimer *timer; -}; - -SeafMqManager * -seaf_mq_manager_new (SeafileSession *seaf) -{ - CcnetClient *client = seaf->session; - SeafMqManager *mgr; - SeafMqManagerPriv *priv; - - mgr = g_new0 (SeafMqManager, 1); - priv = g_new0 (SeafMqManagerPriv, 1); - - - mgr->seaf = seaf; - mgr->priv = priv; - - priv->mqclient_proc = (CcnetMqclientProc *) - ccnet_proc_factory_create_master_processor (client->proc_factory, - "mq-client"); - - if (!priv->mqclient_proc) { - seaf_warning ("Failed to create mqclient proc.\n"); - g_free (mgr); - g_free(priv); - return NULL; - } - - return mgr; -} - -static int -start_mq_client (CcnetMqclientProc *mqclient) -{ - if (ccnet_processor_startl ((CcnetProcessor *)mqclient, NULL) < 0) { - ccnet_processor_done ((CcnetProcessor *)mqclient, FALSE); - seaf_warning ("Failed to start mqclient proc\n"); - return -1; - } - - seaf_message ("[mq client] mq cilent is started\n"); - - return 0; -} - -int -seaf_mq_manager_init (SeafMqManager *mgr) -{ - SeafMqManagerPriv *priv = mgr->priv; - if (start_mq_client(priv->mqclient_proc) < 0) - return -1; - return 0; -} - -int -seaf_mq_manager_start (SeafMqManager *mgr) -{ - return 0; -} - -static inline CcnetMessage * -create_message (SeafMqManager *mgr, const char *app, const char *body, int flags) -{ - CcnetClient *client = mgr->seaf->session; - CcnetMessage *msg; - - char *from = client->base.id; - char *to = client->base.id; - - msg = ccnet_message_new (from, to, app, body, flags); - return msg; -} - -/* Wrap around ccnet_message_new since all messages we use are local. */ -static inline void -_send_message (SeafMqManager *mgr, CcnetMessage *msg) -{ - CcnetMqclientProc *mqclient_proc = mgr->priv->mqclient_proc; - ccnet_mqclient_proc_put_message (mqclient_proc, msg); -} - -void -seaf_mq_manager_publish_message (SeafMqManager *mgr, - CcnetMessage *msg) -{ - _send_message (mgr, msg); -} - -void -seaf_mq_manager_publish_message_full (SeafMqManager *mgr, - const char *app, - const char *body, - int flags) -{ - CcnetMessage *msg = create_message (mgr, app, body, flags); - _send_message (mgr, msg); - ccnet_message_free (msg); -} - -void -seaf_mq_manager_publish_notification (SeafMqManager *mgr, - const char *type, - const char *content) -{ - static const char *app = "seafile.notification"; - - GString *buf = g_string_new(NULL); - g_string_append_printf (buf, "%s\n%s", type, content); - - CcnetMessage *msg = create_message (mgr, app, buf->str, 0); - _send_message (mgr, msg); - - g_string_free (buf, TRUE); - ccnet_message_free (msg); -} - -void -seaf_mq_manager_publish_event (SeafMqManager *mgr, const char *content) -{ - static const char *app = "seaf_server.event"; - - CcnetMessage *msg = create_message (mgr, app, content, 0); - _send_message (mgr, msg); - - ccnet_message_free (msg); -} - -void -seaf_mq_manager_publish_stats_event (SeafMqManager *mgr, const char *content) -{ - static const char *app = "seaf_server.stats"; - - CcnetMessage *msg = create_message (mgr, app, content, 0); - _send_message (mgr, msg); - - ccnet_message_free (msg); -} diff --git a/common/mq-mgr.h b/common/mq-mgr.h deleted file mode 100644 index ac28861..0000000 --- a/common/mq-mgr.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* - * Mq-manager is responsible for: - * - * - Publishing heartbeat messages every HEARTBEAT_INTERVAL senconds to - * indicate it's alive. If seafile-applet doesn't get the message, it would - * check and try to restart seaf-daemon. - * - * - Provide API for other modules to publish their messages. - * - * Currently we publish these types of messages: - * - * - seafile.heartbeat <> - * - seafile.transfer - * - seafile.repo_sync_done - * - seafile.promt_create_repo - * - seafile.repo_created - * - * And subscribe to no messages. - */ - -#ifndef SEAF_MQ_MANAGER_H -#define SEAF_MQ_MANAGER_H - -struct _CcnetMessage; - -typedef struct _SeafMqManager SeafMqManager; - -struct _SeafMqManager { - struct _SeafileSession *seaf; - struct _SeafMqManagerPriv *priv; -}; - -SeafMqManager *seaf_mq_manager_new (struct _SeafileSession *seaf); - -int seaf_mq_manager_init (SeafMqManager *mgr); - -int seaf_mq_manager_start (SeafMqManager *mgr); - - -void seaf_mq_manager_publish_message (SeafMqManager *mgr, - struct _CcnetMessage *msg); - -void -seaf_mq_manager_publish_message_full (SeafMqManager *mgr, - const char *app, - const char *body, - int flags); - -void -seaf_mq_manager_publish_notification (SeafMqManager *mgr, - const char *type, - const char *content); - -void -seaf_mq_manager_publish_event (SeafMqManager *mgr, const char *content); - -void -seaf_mq_manager_publish_stats_event (SeafMqManager *mgr, const char *content); - -#endif diff --git a/common/rpc-service.c b/common/rpc-service.c index 8d02bc8..df77693 100644 --- a/common/rpc-service.c +++ b/common/rpc-service.c @@ -127,840 +127,6 @@ convert_repo_list (GList *inner_repos) return g_list_reverse (ret); } -/* - * RPC functions only available for clients. - */ - -#ifndef SEAFILE_SERVER - -#include "sync-mgr.h" - -GObject * -seafile_get_session_info (GError **error) -{ - SeafileSessionInfo *info; - - info = seafile_session_info_new (); - g_object_set (info, "datadir", seaf->seaf_dir, NULL); - return (GObject *) info; -} - -int -seafile_set_config (const char *key, const char *value, GError **error) -{ - return seafile_session_config_set_string(seaf, key, value); -} - -char * -seafile_get_config (const char *key, GError **error) -{ - return seafile_session_config_get_string(seaf, key); -} - -int -seafile_set_config_int (const char *key, int value, GError **error) -{ - return seafile_session_config_set_int(seaf, key, value); -} - -int -seafile_get_config_int (const char *key, GError **error) -{ - gboolean exists = TRUE; - - int ret = seafile_session_config_get_int(seaf, key, &exists); - - if (!exists) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Config not exists"); - return -1; - } - - return ret; -} - -int -seafile_set_upload_rate_limit (int limit, GError **error) -{ - if (limit < 0) - limit = 0; - - seaf->sync_mgr->upload_limit = limit; - - return seafile_session_config_set_int (seaf, KEY_UPLOAD_LIMIT, limit); -} - -int -seafile_set_download_rate_limit (int limit, GError **error) -{ - if (limit < 0) - limit = 0; - - seaf->sync_mgr->download_limit = limit; - - return seafile_session_config_set_int (seaf, KEY_DOWNLOAD_LIMIT, limit); -} - -int -seafile_repo_last_modify(const char *repo_id, GError **error) -{ - SeafRepo *repo; - int ctime = 0; - - if (!repo_id) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); - return -1; - } - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "No such repository"); - return -1; - } - - ctime = repo->last_modify; -#ifdef SEAFILE_SERVER - seaf_repo_unref (repo); -#endif - - return ctime; -} - -GObject * -seafile_get_checkout_task (const char *repo_id, GError **error) -{ - if (!repo_id) { - seaf_warning ("Invalid args\n"); - return NULL; - } - - CheckoutTask *task; - task = seaf_repo_manager_get_checkout_task(seaf->repo_mgr, - repo_id); - if (!task) - return NULL; - - SeafileCheckoutTask *c_task = g_object_new - (SEAFILE_TYPE_CHECKOUT_TASK, - "repo_id", task->repo_id, - "worktree", task->worktree, - "total_files", task->total_files, - "finished_files", task->finished_files, - NULL); - - return (GObject *)c_task; -} - -char * -seafile_gen_default_worktree (const char *worktree_parent, - const char *repo_name, - GError **error) -{ - if (!worktree_parent || !repo_name) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Empty args"); - return NULL; - } - - return seaf_clone_manager_gen_default_worktree (seaf->clone_mgr, - worktree_parent, - repo_name); -} - -int -seafile_check_path_for_clone (const char *path, GError **error) -{ - if (!seaf_clone_manager_check_worktree_path(seaf->clone_mgr, path, error)) { - return -1; - } - - return 0; -} - -char * -seafile_clone (const char *repo_id, - int repo_version, - const char *relay_id, - const char *repo_name, - const char *worktree, - const char *token, - const char *passwd, - const char *magic, - const char *peer_addr, - const char *peer_port, - const char *email, - const char *random_key, - int enc_version, - const char *more_info, - GError **error) -{ - if (!repo_id || strlen(repo_id) != 36) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); - return NULL; - } - - if (!relay_id || strlen(relay_id) != 40) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid peer id"); - return NULL; - } - - if (!worktree) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, - "Worktre must be specified"); - return NULL; - } - - if (!token || !peer_addr || !peer_port || !email ) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, - "Argument can't be NULL"); - return NULL; - } - - return seaf_clone_manager_add_task (seaf->clone_mgr, - repo_id, repo_version, - relay_id, - repo_name, token, - passwd, magic, - enc_version, random_key, - worktree, - peer_addr, peer_port, - email, more_info, - error); -} - -char * -seafile_download (const char *repo_id, - int repo_version, - const char *relay_id, - const char *repo_name, - const char *wt_parent, - const char *token, - const char *passwd, - const char *magic, - const char *peer_addr, - const char *peer_port, - const char *email, - const char *random_key, - int enc_version, - const char *more_info, - GError **error) -{ - if (!repo_id || strlen(repo_id) != 36) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); - return NULL; - } - - if (!relay_id || strlen(relay_id) != 40) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid peer id"); - return NULL; - } - - if (!wt_parent) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, - "Worktre must be specified"); - return NULL; - } - - if (!token || !peer_addr || !peer_port || !email ) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, - "Argument can't be NULL"); - return NULL; - } - - return seaf_clone_manager_add_download_task (seaf->clone_mgr, - repo_id, repo_version, - relay_id, - repo_name, token, - passwd, magic, - enc_version, random_key, - wt_parent, - peer_addr, peer_port, - email, more_info, - error); -} - -int -seafile_cancel_clone_task (const char *repo_id, GError **error) -{ - return seaf_clone_manager_cancel_task (seaf->clone_mgr, repo_id); -} - -int -seafile_remove_clone_task (const char *repo_id, GError **error) -{ - return seaf_clone_manager_remove_task (seaf->clone_mgr, repo_id); -} - -GList * -seafile_get_clone_tasks (GError **error) -{ - GList *tasks, *ptr; - GList *ret = NULL; - CloneTask *task; - SeafileCloneTask *t; - - tasks = seaf_clone_manager_get_tasks (seaf->clone_mgr); - for (ptr = tasks; ptr != NULL; ptr = ptr->next) { - task = ptr->data; - t = g_object_new (SEAFILE_TYPE_CLONE_TASK, - "state", clone_task_state_to_str(task->state), - "error_str", clone_task_error_to_str(task->error), - "repo_id", task->repo_id, - "repo_name", task->repo_name, - "worktree", task->worktree, - NULL); - ret = g_list_prepend (ret, t); - } - - g_list_free (tasks); - return ret; -} - -int -seafile_sync (const char *repo_id, const char *peer_id, GError **error) -{ - if (!repo_id) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo ID should not be null"); - return -1; - } - - return seaf_sync_manager_add_sync_task (seaf->sync_mgr, repo_id, error); -} - -static void get_task_size(TransferTask *task, gint64 *rsize, gint64 *dsize) -{ - if (task->runtime_state == TASK_RT_STATE_INIT - || task->runtime_state == TASK_RT_STATE_COMMIT - || task->runtime_state == TASK_RT_STATE_FS - || task->runtime_state == TASK_RT_STATE_FINISHED) { - *rsize = task->rsize; - *dsize = task->dsize; - } - if (task->runtime_state == TASK_RT_STATE_DATA) { - if (task->type == TASK_TYPE_DOWNLOAD) { - *dsize = task->block_list->n_valid_blocks; - *rsize = task->block_list->n_blocks - *dsize; - } else { - *dsize = task->n_uploaded; - *rsize = task->block_list->n_blocks - *dsize; - } - } -} - -static SeafileTask * -convert_task (TransferTask *task) -{ - gint64 rsize = 0, dsize = 0; - SeafileTask *t = seafile_task_new(); - - if (task->protocol_version < 7) - get_task_size (task, &rsize, &dsize); - - g_object_set (t, - "repo_id", task->repo_id, - "state", task_state_to_str(task->state), - "rt_state", task_rt_state_to_str(task->runtime_state), - "error_str", task_error_str(task->error), - NULL); - - if (task->type == TASK_TYPE_DOWNLOAD) { - g_object_set (t, "ttype", "download", NULL); - if (task->runtime_state == TASK_RT_STATE_DATA) { - if (task->protocol_version >= 7) - g_object_set (t, "block_total", task->n_to_download, - "block_done", transfer_task_get_done_blocks (task), - NULL); - else - g_object_set (t, "block_total", task->block_list->n_blocks, - "block_done", transfer_task_get_done_blocks (task), - NULL); - g_object_set (t, "rate", transfer_task_get_rate(task), NULL); - } - } else { - g_object_set (t, "ttype", "upload", NULL); - if (task->runtime_state == TASK_RT_STATE_DATA) { - g_object_set (t, "block_total", task->block_list->n_blocks, - "block_done", transfer_task_get_done_blocks (task), - NULL); - g_object_set (t, "rate", transfer_task_get_rate(task), NULL); - } - } - - return t; -} - -static SeafileTask * -convert_http_task (HttpTxTask *task) -{ - SeafileTask *t = seafile_task_new(); - - g_object_set (t, - "repo_id", task->repo_id, - "state", http_task_state_to_str(task->state), - "rt_state", http_task_rt_state_to_str(task->runtime_state), - "error_str", http_task_error_str(task->error), - NULL); - - if (task->type == HTTP_TASK_TYPE_DOWNLOAD) { - g_object_set (t, "ttype", "download", NULL); - if (task->runtime_state == HTTP_TASK_RT_STATE_BLOCK) { - g_object_set (t, "block_total", task->n_files, - "block_done", task->done_files, - NULL); - g_object_set (t, "rate", http_tx_task_get_rate(task), NULL); - } else if (task->runtime_state == HTTP_TASK_RT_STATE_FS) { - g_object_set (t, "fs_objects_total", task->n_fs_objs, - "fs_objects_done", task->done_fs_objs, - NULL); - } - } else { - g_object_set (t, "ttype", "upload", NULL); - if (task->runtime_state == HTTP_TASK_RT_STATE_BLOCK) { - g_object_set (t, "block_total", task->n_blocks, - "block_done", task->done_blocks, - NULL); - g_object_set (t, "rate", http_tx_task_get_rate(task), NULL); - } - } - - return t; -} - -GObject * -seafile_find_transfer_task (const char *repo_id, GError *error) -{ - TransferTask *task; - HttpTxTask *http_task; - - task = seaf_transfer_manager_find_transfer_by_repo (seaf->transfer_mgr, repo_id); - if (task) - return (GObject *)convert_task (task); - - http_task = http_tx_manager_find_task (seaf->http_tx_mgr, repo_id); - if (http_task) - return (GObject *)convert_http_task (http_task); - - return NULL; -} - -int -seafile_get_upload_rate(GError **error) -{ - return seaf->sync_mgr->last_sent_bytes; -} - -int -seafile_get_download_rate(GError **error) -{ - return seaf->sync_mgr->last_recv_bytes; -} - - -GObject * -seafile_get_repo_sync_info (const char *repo_id, GError **error) -{ - SyncInfo *info; - - info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo_id); - if (!info) - return NULL; - - SeafileSyncInfo *sinfo; - sinfo = g_object_new (SEAFILE_TYPE_SYNC_INFO, - "repo_id", info->repo_id, - "head_commit", info->head_commit, - "deleted_on_relay", info->deleted_on_relay, - "need_fetch", info->need_fetch, - "need_upload", info->need_upload, - "need_merge", info->need_merge, - /* "last_sync_time", info->last_sync_time, */ - NULL); - - return (GObject *)sinfo; -} - - -GObject * -seafile_get_repo_sync_task (const char *repo_id, GError **error) -{ - SeafRepo *repo; - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - - if (!repo) { - return NULL; - } - - SyncInfo *info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo_id); - if (!info || !info->current_task) - return NULL; - - SyncTask *task = info->current_task; - const char *sync_state; - char allzeros[41] = {0}; - - if (!info->in_sync && memcmp(allzeros, info->head_commit, 41) == 0) { - sync_state = "waiting for sync"; - } else { - sync_state = sync_state_to_str(task->state); - if (strcmp(sync_state, "error") == 0 && !info->in_error) - sync_state = "synchronized"; - } - - - SeafileSyncTask *s_task; - s_task = g_object_new (SEAFILE_TYPE_SYNC_TASK, - "force_upload", task->is_manual_sync, - "state", sync_state, - "error", sync_error_to_str(task->error), - "repo_id", info->repo_id, - NULL); - - return (GObject *)s_task; -} - -GList * -seafile_get_sync_task_list (GError **error) -{ - GHashTable *sync_info_tbl = seaf->sync_mgr->sync_infos; - GHashTableIter iter; - SeafileSyncTask *s_task; - GList *task_list = NULL; - gpointer key, value; - - g_hash_table_iter_init (&iter, sync_info_tbl); - while (g_hash_table_iter_next (&iter, &key, &value)) { - SyncInfo *info = value; - if (!info->in_sync) - continue; - SyncTask *task = info->current_task; - if (!task) - continue; - s_task = g_object_new (SEAFILE_TYPE_SYNC_TASK, - "force_upload", task->is_manual_sync, - "state", sync_state_to_str(task->state), - "error", sync_error_to_str(task->error), - "repo_id", info->repo_id, - NULL); - task_list = g_list_prepend (task_list, s_task); - } - - return task_list; -} - - -int -seafile_set_repo_property (const char *repo_id, - const char *key, - const char *value, - GError **error) -{ - int ret; - - if (repo_id == NULL || key == NULL || value == NULL) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); - return -1; - } - - SeafRepo *repo; - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "Can't find Repo %s", repo_id); - return -1; - } - - ret = seaf_repo_manager_set_repo_property (seaf->repo_mgr, - repo->id, key, value); - if (ret < 0) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, - "Failed to set key for repo %s", repo_id); - return -1; - } - - return 0; -} - -gchar * -seafile_get_repo_property (const char *repo_id, - const char *key, - GError **error) -{ - char *value = NULL; - - if (!repo_id || !key) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); - return NULL; - } - - SeafRepo *repo; - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "Can't find Repo %s", repo_id); - return NULL; - } - - value = seaf_repo_manager_get_repo_property (seaf->repo_mgr, repo->id, key); - return value; -} - -char * -seafile_get_repo_relay_address (const char *repo_id, - GError **error) -{ - char *relay_addr = NULL; - - if (!repo_id) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); - return NULL; - } - - seaf_repo_manager_get_repo_relay_info (seaf->repo_mgr, repo_id, - &relay_addr, NULL); - - return relay_addr; -} - -char * -seafile_get_repo_relay_port (const char *repo_id, - GError **error) -{ - char *relay_port = NULL; - - if (!repo_id) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); - return NULL; - } - - seaf_repo_manager_get_repo_relay_info (seaf->repo_mgr, repo_id, - NULL, &relay_port); - - return relay_port; -} - -int -seafile_update_repo_relay_info (const char *repo_id, - const char *new_addr, - const char *new_port, - GError **error) -{ - if (!repo_id || !new_addr || !new_port) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); - return -1; - } - - int port = atoi(new_port); - if (port <= 0 || port > 65535) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid port"); - return -1; - } - - SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - return -1; - } - - CcnetPeer *relay = ccnet_get_peer (seaf->ccnetrpc_client, repo->relay_id); - if (!relay) { - GString *buf = g_string_new(NULL); - g_string_append_printf (buf, "add-relay --id %s --addr %s:%s", - repo->relay_id, new_addr, new_port); - - ccnet_send_command (seaf->session, buf->str, NULL, NULL); - g_string_free (buf, TRUE); - } else { - if (g_strcmp0(relay->public_addr, new_addr) != 0 || - relay->public_port != (uint16_t)port) { - ccnet_update_peer_address (seaf->ccnetrpc_client, repo->relay_id, - new_addr, port); - } - - g_object_unref (relay); - } - - return seaf_repo_manager_update_repo_relay_info (seaf->repo_mgr, repo, - new_addr, new_port); -} - -int -seafile_update_repos_server_host (const char *old_host, - const char *new_host, - const char *new_server_url, - GError **error) -{ - if (!old_host || !new_host || !new_server_url) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); - return -1; - } - - return seaf_repo_manager_update_repos_server_host( - seaf->repo_mgr, old_host, new_host, new_server_url); -} - -int -seafile_calc_dir_size (const char *path, GError **error) -{ - if (!path) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); - return -1; - } - - gint64 size_64 = ccnet_calc_directory_size(path, error); - if (size_64 < 0) { - seaf_warning ("failed to calculate dir size for %s\n", path); - return -1; - } - - /* get the size in MB */ - int size = (int) (size_64 >> 20); - return size; -} - -int -seafile_disable_auto_sync (GError **error) -{ - return seaf_sync_manager_disable_auto_sync (seaf->sync_mgr); -} - -int -seafile_enable_auto_sync (GError **error) -{ - return seaf_sync_manager_enable_auto_sync (seaf->sync_mgr); -} - -int seafile_is_auto_sync_enabled (GError **error) -{ - return seaf_sync_manager_is_auto_sync_enabled (seaf->sync_mgr); -} - -char * -seafile_get_path_sync_status (const char *repo_id, - const char *path, - int is_dir, - GError **error) -{ - char *canon_path = NULL; - int len; - char *status; - - if (!repo_id || !path) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); - return NULL; - } - - /* Empty path means to get status of the worktree folder. */ - if (strcmp (path, "") != 0) { - if (*path == '/') - ++path; - canon_path = g_strdup(path); - len = strlen(canon_path); - if (canon_path[len-1] == '/') - canon_path[len-1] = 0; - } else { - canon_path = g_strdup(path); - } - - status = seaf_sync_manager_get_path_sync_status (seaf->sync_mgr, - repo_id, - canon_path, - is_dir); - g_free (canon_path); - return status; -} - -int -seafile_mark_file_locked (const char *repo_id, const char *path, GError **error) -{ - char *canon_path = NULL; - int len; - int ret; - - if (!repo_id || !path) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); - return -1; - } - - if (*path == '/') - ++path; - - if (path[0] == 0) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path"); - return -1; - } - - canon_path = g_strdup(path); - len = strlen(canon_path); - if (canon_path[len-1] == '/') - canon_path[len-1] = 0; - - ret = seaf_filelock_manager_mark_file_locked (seaf->filelock_mgr, - repo_id, path, FALSE); - - g_free (canon_path); - return ret; -} - -int -seafile_mark_file_unlocked (const char *repo_id, const char *path, GError **error) -{ - char *canon_path = NULL; - int len; - int ret; - - if (!repo_id || !path) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); - return -1; - } - - if (*path == '/') - ++path; - - if (path[0] == 0) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path"); - return -1; - } - - canon_path = g_strdup(path); - len = strlen(canon_path); - if (canon_path[len-1] == '/') - canon_path[len-1] = 0; - - ret = seaf_filelock_manager_mark_file_unlocked (seaf->filelock_mgr, - repo_id, path); - - g_free (canon_path); - return ret; -} - -char * -seafile_get_server_property (const char *server_url, const char *key, GError **error) -{ - if (!server_url || !key) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, - "Argument should not be null"); - return NULL; - } - - return seaf_repo_manager_get_server_property (seaf->repo_mgr, - server_url, - key); -} - -int -seafile_set_server_property (const char *server_url, - const char *key, - const char *value, - GError **error) -{ - if (!server_url || !key || !value) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, - "Argument should not be null"); - return -1; - } - - return seaf_repo_manager_set_server_property (seaf->repo_mgr, - server_url, - key, value); -} - -#endif /* not define SEAFILE_SERVER */ - /* * RPC functions available for both clients and server. */ @@ -2026,79 +1192,6 @@ seafile_list_owned_repos (const char *email, int ret_corrupted, return ret; } -int -seafile_add_chunk_server (const char *server, GError **error) -{ - SeafCSManager *cs_mgr = seaf->cs_mgr; - CcnetPeer *peer; - - peer = ccnet_get_peer_by_idname (seaf->ccnetrpc_client, server); - if (!peer) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid peer id or name %s", server); - return -1; - } - - if (seaf_cs_manager_add_chunk_server (cs_mgr, peer->id) < 0) { - g_object_unref (peer); - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Failed to add chunk server %s", server); - return -1; - } - - g_object_unref (peer); - return 0; -} - -int -seafile_del_chunk_server (const char *server, GError **error) -{ - SeafCSManager *cs_mgr = seaf->cs_mgr; - CcnetPeer *peer; - - peer = ccnet_get_peer_by_idname (seaf->ccnetrpc_client, server); - if (!peer) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid peer id or name %s", server); - return -1; - } - - if (seaf_cs_manager_del_chunk_server (cs_mgr, peer->id) < 0) { - g_object_unref (peer); - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Failed to delete chunk server %s", server); - return -1; - } - - g_object_unref (peer); - return 0; -} - -char * -seafile_list_chunk_servers (GError **error) -{ - SeafCSManager *cs_mgr = seaf->cs_mgr; - GList *servers, *ptr; - char *cs_id; - CcnetPeer *peer; - GString *buf = g_string_new (""); - - servers = seaf_cs_manager_get_chunk_servers (cs_mgr); - ptr = servers; - while (ptr) { - cs_id = ptr->data; - peer = ccnet_get_peer (seaf->ccnetrpc_client, cs_id); - if (!peer) { - g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal error"); - g_string_free (buf, TRUE); - return NULL; - } - g_object_unref (peer); - - g_string_append_printf (buf, "%s\n", cs_id); - ptr = ptr->next; - } - g_list_free (servers); - - return (g_string_free (buf, FALSE)); -} - gint64 seafile_get_user_quota_usage (const char *email, GError **error) { diff --git a/common/seaf-utils.c b/common/seaf-utils.c index ef1c750..b71e704 100644 --- a/common/seaf-utils.c +++ b/common/seaf-utils.c @@ -226,3 +226,21 @@ load_database_config (SeafileSession *session) return ret; } + +SearpcClient * +create_rpc_clients (const char *config_dir) +{ + SearpcNamedPipeClient *rpc_client = NULL; + char *pipe_path = NULL; + + pipe_path = g_strdup_printf ("%s/%s", config_dir, "ccnet-rpc.sock"); + rpc_client = searpc_create_named_pipe_client(pipe_path); + g_free(pipe_path); + + if (searpc_named_pipe_client_connect(rpc_client) < 0) { + seaf_warning ("Named pipe client failed to connect.\n"); + exit (1); + } + + return searpc_client_with_named_pipe_transport (rpc_client, "ccnet-threaded-rpcserver"); +} diff --git a/common/seaf-utils.h b/common/seaf-utils.h index 08e3e4e..4cdd80a 100644 --- a/common/seaf-utils.h +++ b/common/seaf-utils.h @@ -1,6 +1,9 @@ #ifndef SEAF_UTILS_H #define SEAF_UTILS_H +#include +#include + struct _SeafileSession; @@ -12,4 +15,6 @@ seafile_session_get_tmp_file_path (struct _SeafileSession *session, int load_database_config (struct _SeafileSession *session); +SearpcClient * +create_rpc_clients (const char *config_dir); #endif diff --git a/fuse/getattr.c b/fuse/getattr.c index 071ff1a..14406b5 100644 --- a/fuse/getattr.c +++ b/fuse/getattr.c @@ -15,6 +15,7 @@ #include "seaf-fuse.h" #include "seafile-session.h" +#include "seaf-utils.h" static CcnetEmailUser *get_user_from_ccnet (SearpcClient *client, const char *user) { @@ -37,25 +38,19 @@ static int getattr_user(SeafileSession *seaf, const char *user, struct stat *stb SearpcClient *client; CcnetEmailUser *emailuser; - client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-threaded-rpcserver"); - if (!client) { - seaf_warning ("Failed to alloc rpc client.\n"); - return -ENOMEM; - } + client = create_rpc_clients (seaf->config_dir); emailuser = get_user_from_ccnet (client, user); if (!emailuser) { - ccnet_rpc_client_free (client); + searpc_free_client_with_pipe_transport(client); return -ENOENT; } g_object_unref (emailuser); - ccnet_rpc_client_free (client); stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 2; stbuf->st_size = 4096; + searpc_free_client_with_pipe_transport(client); return 0; } diff --git a/fuse/readdir.c b/fuse/readdir.c index c5bfc83..f6e0d83 100644 --- a/fuse/readdir.c +++ b/fuse/readdir.c @@ -15,6 +15,7 @@ #include "seaf-fuse.h" #include "seafile-session.h" +#include "seaf-utils.h" static char *replace_slash (const char *repo_name) { @@ -53,13 +54,7 @@ static int readdir_root(SeafileSession *seaf, GHashTable *user_hash; int dummy; - client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-threaded-rpcserver"); - if (!client) { - seaf_warning ("Failed to alloc rpc client.\n"); - return -ENOMEM; - } + client = create_rpc_clients (seaf->config_dir); user_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); @@ -92,7 +87,8 @@ static int readdir_root(SeafileSession *seaf, g_list_free (users); g_hash_table_destroy (user_hash); - ccnet_rpc_client_free (client); + + searpc_free_client_with_pipe_transport(client); return 0; } @@ -106,25 +102,20 @@ static int readdir_user(SeafileSession *seaf, const char *user, GList *list = NULL, *p; GString *name; - client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-threaded-rpcserver"); - if (!client) { - seaf_warning ("Failed to alloc rpc client.\n"); - return -ENOMEM; - } + client = create_rpc_clients (seaf->config_dir); emailuser = get_user_from_ccnet (client, user); if (!emailuser) { - ccnet_rpc_client_free (client); + searpc_free_client_with_pipe_transport(client); return -ENOENT; } g_object_unref (emailuser); - ccnet_rpc_client_free (client); list = seaf_repo_manager_get_repos_by_owner (seaf->repo_mgr, user); - if (!list) + if (!list) { + searpc_free_client_with_pipe_transport(client); return 0; + } for (p = list; p; p = p->next) { SeafRepo *repo = (SeafRepo *)p->data; @@ -153,6 +144,7 @@ static int readdir_user(SeafileSession *seaf, const char *user, g_list_free (list); + searpc_free_client_with_pipe_transport(client); return 0; } diff --git a/fuse/seaf-fuse.c b/fuse/seaf-fuse.c index 4908402..b5d36e4 100644 --- a/fuse/seaf-fuse.c +++ b/fuse/seaf-fuse.c @@ -18,7 +18,6 @@ #include "seaf-fuse.h" -CcnetClient *ccnet_client = NULL; SeafileSession *seaf = NULL; static char *parse_repo_id (const char *repo_id_name) @@ -324,13 +323,7 @@ int main(int argc, char *argv[]) exit(1); } - ccnet_client = ccnet_client_new(); - if ((ccnet_client_load_confdir(ccnet_client, central_config_dir, config_dir)) < 0) { - seaf_warning("Read config dir error\n"); - exit(1); - } - - seaf = seafile_session_new(central_config_dir, seafile_dir, ccnet_client); + seaf = seafile_session_new(central_config_dir, seafile_dir, config_dir); if (!seaf) { seaf_warning("Failed to create seafile session.\n"); exit(1); @@ -341,12 +334,6 @@ int main(int argc, char *argv[]) exit(1); } - seaf->client_pool = ccnet_client_pool_new(central_config_dir, config_dir); - if (!seaf->client_pool) { - seaf_warning("Failed to creat client pool\n"); - exit(1); - } - set_syslog_config (seaf->config); ret = fuse_main(args.argc, args.argv, &seaf_fuse_ops, NULL); diff --git a/fuse/seafile-session.c b/fuse/seafile-session.c index d560f67..fff3f2a 100644 --- a/fuse/seafile-session.c +++ b/fuse/seafile-session.c @@ -19,19 +19,18 @@ read_excluded_users (SeafileSession *session); SeafileSession * seafile_session_new(const char *central_config_dir, const char *seafile_dir, - CcnetClient *ccnet_session) + const char *config_dir) { char *abs_central_config_dir = NULL; char *abs_seafile_dir; + char *abs_config_dir = NULL; char *tmp_file_dir; char *config_file_path; struct stat st; GKeyFile *config; SeafileSession *session = NULL; - if (!ccnet_session) - return NULL; - + abs_config_dir = ccnet_expand_path (config_dir); abs_seafile_dir = ccnet_expand_path (seafile_dir); tmp_file_dir = g_build_filename(abs_seafile_dir, "tmpfiles", NULL); if (central_config_dir) { @@ -64,8 +63,8 @@ seafile_session_new(const char *central_config_dir, session = g_new0(SeafileSession, 1); session->seaf_dir = abs_seafile_dir; + session->config_dir = abs_config_dir; session->tmp_file_dir = tmp_file_dir; - session->session = ccnet_session; session->config = config; session->excluded_users = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); diff --git a/fuse/seafile-session.h b/fuse/seafile-session.h index bb4a1a9..ed75853 100644 --- a/fuse/seafile-session.h +++ b/fuse/seafile-session.h @@ -12,23 +12,20 @@ #include "commit-mgr.h" #include "repo-mgr.h" -struct _CcnetClient; +#include typedef struct _SeafileSession SeafileSession; -struct CcnetClientPool; - struct _SeafileSession { - struct _CcnetClient *session; + SearpcClient *rpc_client; char *seaf_dir; + char *config_dir; char *tmp_file_dir; /* Config that's only loaded on start */ GKeyFile *config; SeafDB *db; - struct CcnetClientPool *client_pool; - SeafBlockManager *block_mgr; SeafFSManager *fs_mgr; SeafBranchManager *branch_mgr; @@ -45,7 +42,7 @@ extern SeafileSession *seaf; SeafileSession * seafile_session_new(const char *central_config_dir, const char *seafile_dir, - struct _CcnetClient *ccnet_session); + const char *config_dir); int seafile_session_init (SeafileSession *session); diff --git a/python/seafile/__init__.py b/python/seafile/__init__.py index df48bda..116ffec 100644 --- a/python/seafile/__init__.py +++ b/python/seafile/__init__.py @@ -1,9 +1,4 @@ - -from rpcclient import SeafileRpcClient as RpcClient -from rpcclient import SeafileThreadedRpcClient as ThreadedRpcClient -from rpcclient import MonitorRpcClient as MonitorRpcClient -from rpcclient import SeafServerRpcClient as ServerRpcClient -from rpcclient import SeafServerThreadedRpcClient as ServerThreadedRpcClient +from .rpcclient import SeafServerThreadedRpcClient as ServerThreadedRpcClient class TaskType(object): DOWNLOAD = 0 diff --git a/python/seafile/rpcclient.py b/python/seafile/rpcclient.py index 027e48e..8a56ac9 100644 --- a/python/seafile/rpcclient.py +++ b/python/seafile/rpcclient.py @@ -1,327 +1,9 @@ +from pysearpc import searpc_func, SearpcError, NamedPipeClient -import ccnet -from pysearpc import searpc_func, SearpcError +class SeafServerThreadedRpcClient(NamedPipeClient): -class SeafileRpcClient(ccnet.RpcClientBase): - """RPC used in client""" - - def __init__(self, ccnet_client_pool, *args, **kwargs): - ccnet.RpcClientBase.__init__(self, ccnet_client_pool, "seafile-rpcserver", - *args, **kwargs) - - @searpc_func("object", []) - def seafile_get_session_info(): - pass - get_session_info = seafile_get_session_info - - @searpc_func("int", ["string"]) - def seafile_calc_dir_size(path): - pass - calc_dir_size = seafile_calc_dir_size - - @searpc_func("int64", []) - def seafile_get_total_block_size(): - pass - get_total_block_size = seafile_get_total_block_size; - - @searpc_func("string", ["string"]) - def seafile_get_config(key): - pass - get_config = seafile_get_config - - @searpc_func("int", ["string", "string"]) - def seafile_set_config(key, value): - pass - set_config = seafile_set_config - - @searpc_func("int", ["string"]) - def seafile_get_config_int(key): - pass - get_config_int = seafile_get_config_int - - @searpc_func("int", ["string", "int"]) - def seafile_set_config_int(key, value): - pass - set_config_int = seafile_set_config_int - - @searpc_func("int", ["int"]) - def seafile_set_upload_rate_limit(limit): - pass - set_upload_rate_limit = seafile_set_upload_rate_limit - - @searpc_func("int", ["int"]) - def seafile_set_download_rate_limit(limit): - pass - set_download_rate_limit = seafile_set_download_rate_limit - - ### repo - @searpc_func("objlist", ["int", "int"]) - def seafile_get_repo_list(): - pass - get_repo_list = seafile_get_repo_list - - @searpc_func("object", ["string"]) - def seafile_get_repo(): - pass - get_repo = seafile_get_repo - - @searpc_func("string", ["string", "string", "string", "string", "string", "int"]) - def seafile_create_repo(name, desc, passwd, base, relay_id, keep_history): - pass - create_repo = seafile_create_repo - - @searpc_func("int", ["string"]) - def seafile_destroy_repo(repo_id): - pass - remove_repo = seafile_destroy_repo - - @searpc_func("objlist", ["string", "string", "string", "int"]) - def seafile_diff(): - pass - get_diff = seafile_diff - - @searpc_func("object", ["string", "int", "string"]) - def seafile_get_commit(repo_id, version, commit_id): - pass - get_commit = seafile_get_commit - - @searpc_func("objlist", ["string", "int", "int"]) - def seafile_get_commit_list(): - pass - get_commit_list = seafile_get_commit_list - - @searpc_func("objlist", ["string"]) - def seafile_branch_gets(repo_id): - pass - branch_gets = seafile_branch_gets - - @searpc_func("int", ["string", "string"]) - def seafile_branch_add(repo_id, branch): - pass - branch_add = seafile_branch_add - - ##### clone related - @searpc_func("string", ["string", "string"]) - def gen_default_worktree(worktree_parent, repo_name): - pass - - @searpc_func("string", ["string", "int", "string", "string", "string", "string", "string", "string", "string", "string", "string", "int", "string"]) - def seafile_clone(repo_id, repo_version, peer_id, repo_name, worktree, token, password, magic, peer_addr, peer_port, email, random_key, enc_version, more_info): - pass - clone = seafile_clone - - @searpc_func("string", ["string", "int", "string", "string", "string", "string", "string", "string", "string", "string", "string", "int", "string"]) - def seafile_download(repo_id, repo_version, peer_id, repo_name, wt_parent, token, password, magic, peer_addr, peer_port, email, random_key, enc_version, more_info): - pass - download = seafile_download - - @searpc_func("int", ["string"]) - def seafile_cancel_clone_task(repo_id): - pass - cancel_clone_task = seafile_cancel_clone_task - - @searpc_func("int", ["string"]) - def seafile_remove_clone_task(repo_id): - pass - remove_clone_task = seafile_remove_clone_task - - @searpc_func("objlist", []) - def seafile_get_clone_tasks(): - pass - get_clone_tasks = seafile_get_clone_tasks - - @searpc_func("object", ["string"]) - def seafile_find_transfer_task(repo_id): - pass - find_transfer_task = seafile_find_transfer_task - - @searpc_func("object", ["string"]) - def seafile_get_checkout_task(repo_id): - pass - get_checkout_task = seafile_get_checkout_task - - ### sync - @searpc_func("int", ["string", "string"]) - def seafile_sync(repo_id, peer_id): - pass - sync = seafile_sync - - @searpc_func("object", ["string"]) - def seafile_get_repo_sync_task(): - pass - get_repo_sync_task = seafile_get_repo_sync_task - - @searpc_func("object", ["string"]) - def seafile_get_repo_sync_info(): - pass - get_repo_sync_info = seafile_get_repo_sync_info - - @searpc_func("int", []) - def seafile_is_auto_sync_enabled(): - pass - is_auto_sync_enabled = seafile_is_auto_sync_enabled - - ###### Property Management ######### - - @searpc_func("int", ["string", "string"]) - def seafile_set_repo_passwd(repo_id, passwd): - pass - set_repo_passwd = seafile_set_repo_passwd - - @searpc_func("int", ["string", "string", "string"]) - def seafile_set_repo_property(repo_id, key, value): - pass - set_repo_property = seafile_set_repo_property - - @searpc_func("string", ["string", "string"]) - def seafile_get_repo_property(repo_id, key): - pass - get_repo_property = seafile_get_repo_property - - @searpc_func("string", ["string"]) - def seafile_get_repo_relay_address(repo_id): - pass - get_repo_relay_address = seafile_get_repo_relay_address - - @searpc_func("string", ["string"]) - def seafile_get_repo_relay_port(repo_id): - pass - get_repo_relay_port = seafile_get_repo_relay_port - - @searpc_func("int", ["string", "string", "string"]) - def seafile_update_repo_relay_info(repo_id, addr, port): - pass - update_repo_relay_info = seafile_update_repo_relay_info - - @searpc_func("int", ["string", "string"]) - def seafile_set_repo_token(repo_id, token): - pass - set_repo_token = seafile_set_repo_token - - @searpc_func("string", ["string"]) - def seafile_get_repo_token(repo_id): - pass - get_repo_token = seafile_get_repo_token - - @searpc_func("object", ["int", "string", "string"]) - def seafile_generate_magic_and_random_key(enc_version, repo_id, password): - pass - generate_magic_and_random_key = seafile_generate_magic_and_random_key - -class SeafileThreadedRpcClient(ccnet.RpcClientBase): - """RPC used in client that run in a thread""" - - def __init__(self, ccnet_client_pool, *args, **kwargs): - ccnet.RpcClientBase.__init__(self, ccnet_client_pool, - "seafile-threaded-rpcserver", - *args, **kwargs) - - @searpc_func("int", ["string", "string", "string"]) - def seafile_edit_repo(): - pass - edit_repo = seafile_edit_repo - - @searpc_func("int", ["string", "string"]) - def seafile_reset(repo_id, commit_id): - pass - reset = seafile_reset - - @searpc_func("int", ["string", "string"]) - def seafile_revert(repo_id, commit_id): - pass - revert = seafile_revert - - @searpc_func("int", ["string", "string"]) - def seafile_add(repo_id, path): - pass - add = seafile_add - - @searpc_func("int", ["string", "string"]) - def seafile_rm(): - pass - rm = seafile_rm - - @searpc_func("string", ["string", "string"]) - def seafile_commit(repo_id, description): - pass - commit = seafile_commit - - -class MonitorRpcClient(ccnet.RpcClientBase): - - def __init__(self, ccnet_client_pool): - ccnet.RpcClientBase.__init__(self, ccnet_client_pool, "monitor-rpcserver") - - @searpc_func("int", ["string"]) - def monitor_get_repos_size(repo_ids): - pass - get_repos_size = monitor_get_repos_size - - -class SeafServerRpcClient(ccnet.RpcClientBase): - - def __init__(self, ccnet_client_pool, *args, **kwargs): - ccnet.RpcClientBase.__init__(self, ccnet_client_pool, "seafserv-rpcserver", - *args, **kwargs) - - # token for web access to repo - @searpc_func("string", ["string", "string", "string", "string", "int"]) - def seafile_web_get_access_token(repo_id, obj_id, op, username, use_onetime=1): - pass - web_get_access_token = seafile_web_get_access_token - - @searpc_func("object", ["string"]) - def seafile_web_query_access_token(token): - pass - web_query_access_token = seafile_web_query_access_token - - @searpc_func("string", ["string"]) - def seafile_query_zip_progress(token): - pass - query_zip_progress = seafile_query_zip_progress - - @searpc_func("int", ["string"]) - def cancel_zip_task(token): - pass - - ###### GC #################### - @searpc_func("int", []) - def seafile_gc(): - pass - gc = seafile_gc - - @searpc_func("int", []) - def seafile_gc_get_progress(): - pass - gc_get_progress = seafile_gc_get_progress - - # password management - @searpc_func("int", ["string", "string"]) - def seafile_is_passwd_set(repo_id, user): - pass - is_passwd_set = seafile_is_passwd_set - - @searpc_func("object", ["string", "string"]) - def seafile_get_decrypt_key(repo_id, user): - pass - get_decrypt_key = seafile_get_decrypt_key - - # Copy tasks - - @searpc_func("object", ["string"]) - def get_copy_task(task_id): - pass - - @searpc_func("int", ["string"]) - def cancel_copy_task(task_id): - pass - -class SeafServerThreadedRpcClient(ccnet.RpcClientBase): - - def __init__(self, ccnet_client_pool, *args, **kwargs): - ccnet.RpcClientBase.__init__(self, ccnet_client_pool, - "seafserv-threaded-rpcserver", - *args, **kwargs) + def __init__(self, pipe_path): + NamedPipeClient.__init__(self, pipe_path, "seafserv-threaded-rpcserver") # repo manipulation @searpc_func("string", ["string", "string", "string", "string", "int"]) @@ -1055,3 +737,55 @@ class SeafServerThreadedRpcClient(ccnet.RpcClientBase): @searpc_func("int", ["string"]) def get_repo_status(repo_id): pass + + # token for web access to repo + @searpc_func("string", ["string", "string", "string", "string", "int"]) + def seafile_web_get_access_token(repo_id, obj_id, op, username, use_onetime=1): + pass + web_get_access_token = seafile_web_get_access_token + + @searpc_func("object", ["string"]) + def seafile_web_query_access_token(token): + pass + web_query_access_token = seafile_web_query_access_token + + @searpc_func("string", ["string"]) + def seafile_query_zip_progress(token): + pass + query_zip_progress = seafile_query_zip_progress + + @searpc_func("int", ["string"]) + def cancel_zip_task(token): + pass + + ###### GC #################### + @searpc_func("int", []) + def seafile_gc(): + pass + gc = seafile_gc + + @searpc_func("int", []) + def seafile_gc_get_progress(): + pass + gc_get_progress = seafile_gc_get_progress + + # password management + @searpc_func("int", ["string", "string"]) + def seafile_is_passwd_set(repo_id, user): + pass + is_passwd_set = seafile_is_passwd_set + + @searpc_func("object", ["string", "string"]) + def seafile_get_decrypt_key(repo_id, user): + pass + get_decrypt_key = seafile_get_decrypt_key + + # Copy tasks + + @searpc_func("object", ["string"]) + def get_copy_task(task_id): + pass + + @searpc_func("int", ["string"]) + def cancel_copy_task(task_id): + pass diff --git a/python/seaserv/__init__.py b/python/seaserv/__init__.py index 56379a1..376fdd5 100644 --- a/python/seaserv/__init__.py +++ b/python/seaserv/__init__.py @@ -1,19 +1,18 @@ - -import service -from service import ccnet_rpc, seafserv_rpc, seafserv_threaded_rpc, ccnet_threaded_rpc -from service import send_command, check_quota, web_get_access_token, \ +from . import service +from .service import seafserv_threaded_rpc, ccnet_threaded_rpc +from .service import send_command, check_quota, web_get_access_token, \ unset_repo_passwd, get_user_quota_usage, get_user_share_usage, \ get_user_quota -from service import get_emailusers, count_emailusers, get_session_info, \ +from .service import get_emailusers, count_emailusers, \ get_emailuser_with_import -from service import get_org_groups, get_personal_groups_by_user, \ +from .service import get_org_groups, get_personal_groups_by_user, \ get_group_repoids, get_personal_groups, list_share_repos, remove_share, \ check_group_staff, remove_group_user, get_group, get_org_id_by_group, \ get_group_members, get_shared_groups_by_repo, is_group_user, \ get_org_group_repos, get_group_repos, get_org_groups_by_user, is_org_group,\ del_org_group_repo, get_org_groups_by_repo, get_org_group_repoids, \ get_group_repos_by_owner, unshare_group_repo -from service import get_repos, get_repo, get_commits, get_branches, remove_repo, \ +from .service import get_repos, get_repo, get_commits, get_branches, remove_repo, \ get_org_repos, is_repo_owner, create_org_repo, is_inner_pub_repo, \ list_org_inner_pub_repos, get_org_id_by_repo_id, list_org_shared_repos, \ list_personal_shared_repos, is_personal_repo, list_inner_pub_repos, \ @@ -23,21 +22,21 @@ from service import get_repos, get_repo, get_commits, get_branches, remove_repo, get_repo_history_limit, list_inner_pub_repos_by_owner, unset_inner_pub_repo,\ count_inner_pub_repos, edit_repo, list_dir_by_path, create_repo, remove_repo -from service import get_binding_peerids, is_valid_filename, check_permission,\ +from .service import get_binding_peerids, is_valid_filename, check_permission,\ is_passwd_set -from service import create_org, get_orgs_by_user, get_org_by_url_prefix, \ +from .service import create_org, get_orgs_by_user, get_org_by_url_prefix, \ get_user_current_org, add_org_user, remove_org_user, get_org_by_id, \ get_org_id_by_repo_id, is_org_staff, get_org_users_by_url_prefix, \ org_user_exists, list_org_repos_by_owner -from service import get_related_users_by_repo, get_related_users_by_org_repo -from service import post_empty_file, del_file +from .service import get_related_users_by_repo, get_related_users_by_org_repo +from .service import post_empty_file, del_file -from service import CCNET_CONF_PATH, CCNET_SERVER_ADDR, CCNET_SERVER_PORT, \ +from .service import CCNET_CONF_PATH, CCNET_SERVER_ADDR, CCNET_SERVER_PORT, \ MAX_UPLOAD_FILE_SIZE, MAX_DOWNLOAD_DIR_SIZE, FILE_SERVER_ROOT, \ CALC_SHARE_USAGE, SERVICE_URL, FILE_SERVER_PORT, SERVER_ID, \ SEAFILE_CENTRAL_CONF_DIR, LDAP_HOST -from service import send_message +from .service import send_message -from api import seafile_api, ccnet_api +from .api import seafile_api, ccnet_api diff --git a/python/seaserv/api.py b/python/seaserv/api.py index c60ea1d..eff7817 100644 --- a/python/seaserv/api.py +++ b/python/seaserv/api.py @@ -1,5 +1,4 @@ - -from service import seafserv_rpc, seafserv_threaded_rpc, ccnet_threaded_rpc +from .service import seafserv_threaded_rpc, ccnet_threaded_rpc from pysearpc import SearpcError import json @@ -34,8 +33,8 @@ class SeafileAPI(object): Return: the access token in string """ onetime = 1 if bool(use_onetime) else 0 - return seafserv_rpc.web_get_access_token(repo_id, obj_id, op, username, - onetime) + return seafserv_threaded_rpc.web_get_access_token(repo_id, obj_id, op, username, + onetime) def query_fileserver_access_token(self, token): """Get the WebAccess object @@ -44,17 +43,17 @@ class SeafileAPI(object): Return: the WebAccess object (lib/webaccess.vala) """ - return seafserv_rpc.web_query_access_token(token) + return seafserv_threaded_rpc.web_query_access_token(token) def query_zip_progress(self, token): """Query zip progress for download-dir, download-multi token: obtained by get_fileserver_access_token Return: json formated string `{"zipped":, "total":}`, otherwise None. """ - return seafserv_rpc.query_zip_progress(token) + return seafserv_threaded_rpc.query_zip_progress(token) def cancel_zip_task(self, token): - return seafserv_rpc.cancel_zip_task(token) + return seafserv_threaded_rpc.cancel_zip_task(token) # password @@ -62,13 +61,13 @@ class SeafileAPI(object): """ Return non-zero if True, otherwise 0. """ - return seafserv_rpc.is_passwd_set(repo_id, username) + return seafserv_threaded_rpc.is_passwd_set(repo_id, username) def get_decrypt_key(self, repo_id, username): """ Return: a CryptKey object (lib/crypt.vala) """ - return seafserv_rpc.get_decrypt_key(repo_id, username) + return seafserv_threaded_rpc.get_decrypt_key(repo_id, username) def change_repo_passwd(self, repo_id, old_passwd, new_passwd, user): return seafserv_threaded_rpc.change_repo_passwd(repo_id, old_passwd, @@ -311,10 +310,10 @@ class SeafileAPI(object): replace, username, need_progress, synchronous) def get_copy_task(self, task_id): - return seafserv_rpc.get_copy_task(task_id) + return seafserv_threaded_rpc.get_copy_task(task_id) def cancel_copy_task(self, task_id): - return seafserv_rpc.cancel_copy_task(task_id) + return seafserv_threaded_rpc.cancel_copy_task(task_id) def rename_file(self, repo_id, parent_dir, oldname, newname, username): return seafserv_threaded_rpc.rename_file(repo_id, parent_dir, diff --git a/python/seaserv/service.py b/python/seaserv/service.py index e640054..030b289 100644 --- a/python/seaserv/service.py +++ b/python/seaserv/service.py @@ -3,8 +3,8 @@ import json import logging import os import sys -import ConfigParser -from urlparse import urlparse +import configparser +from urllib.parse import urlparse import ccnet import seafile @@ -25,22 +25,25 @@ def _load_path_from_env(key, check=True): raise ImportError("Seaserv cannot be imported, because environment variable %s is undefined." % key) return None if _DEBUG: - print "Loading %s from %s" % (key, v) + print("Loading %s from %s" % (key, v)) return os.path.normpath(os.path.expanduser(v)) CCNET_CONF_PATH = _load_path_from_env('CCNET_CONF_DIR') SEAFILE_CONF_DIR = _load_path_from_env('SEAFILE_CONF_DIR') SEAFILE_CENTRAL_CONF_DIR = _load_path_from_env('SEAFILE_CENTRAL_CONF_DIR', check=False) -pool = ccnet.ClientPool(CCNET_CONF_PATH, central_config_dir=SEAFILE_CENTRAL_CONF_DIR) -ccnet_rpc = ccnet.CcnetRpcClient(pool, req_pool=True) -ccnet_threaded_rpc = ccnet.CcnetThreadedRpcClient(pool, req_pool=True) -seafserv_rpc = seafile.ServerRpcClient(pool, req_pool=True) -seafserv_threaded_rpc = seafile.ServerThreadedRpcClient(pool, req_pool=True) +ccnet_pipe_path = os.path.join (CCNET_CONF_PATH, 'ccnet-rpc.sock') +ccnet_threaded_rpc = ccnet.CcnetThreadedRpcClient(ccnet_pipe_path) + +if SEAFILE_CENTRAL_CONF_DIR: + seafile_pipe_path = os.path.join(SEAFILE_CENTRAL_CONF_DIR, 'seafile.sock') +else: + seafile_pipe_path = os.path.join(SEAFILE_CONF_DIR, 'seafile.sock') +seafserv_threaded_rpc = seafile.ServerThreadedRpcClient(seafile_pipe_path) # load ccnet server addr and port from ccnet.conf. # 'addr:port' is used when downloading a repo -config = ConfigParser.ConfigParser() +config = configparser.ConfigParser() config.read(os.path.join(SEAFILE_CENTRAL_CONF_DIR if SEAFILE_CENTRAL_CONF_DIR else CCNET_CONF_PATH, 'ccnet.conf')) @@ -55,7 +58,7 @@ if config.has_option('General', 'SERVICE_URL'): else: CCNET_SERVER_PORT = 10001 else: - print "Warning: SERVICE_URL not set in ccnet.conf" + print("Warning: SERVICE_URL not set in ccnet.conf") CCNET_SERVER_ADDR = None CCNET_SERVER_PORT = None SERVICE_URL = None @@ -131,9 +134,6 @@ def count_emailusers(): def get_emailuser_with_import(email): return ccnet_threaded_rpc.get_emailuser_with_import(email) -def get_session_info(): - return ccnet_rpc.get_session_info() - # group def get_group(group_id): group_id_int = int(group_id) @@ -171,7 +171,7 @@ def check_group_staff(group_id, username): group_id = int(group_id) try: ret = ccnet_threaded_rpc.check_group_staff(group_id, username) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = 0 @@ -344,7 +344,7 @@ def get_repo(repo_id): def edit_repo(repo_id, name, desc, user): try: ret = seafserv_threaded_rpc.edit_repo(repo_id, name, desc, user) - except SearpcError, e: + except SearpcError as e: ret = -1 return True if ret == 0 else False @@ -354,7 +354,7 @@ def create_repo(name, desc, user, passwd): """ try: ret = seafserv_threaded_rpc.create_repo(name, desc, user, passwd) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = None return ret @@ -365,7 +365,7 @@ def remove_repo(repo_id): """ try: ret = seafserv_threaded_rpc.remove_repo(repo_id) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = -1 return True if ret == 0 else False @@ -784,7 +784,7 @@ def post_empty_file(repo_id, parent_dir, file_name, user): try: ret = seafserv_threaded_rpc.post_empty_file(repo_id, parent_dir, file_name, user) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = -1 return True if ret == 0 else False @@ -796,7 +796,7 @@ def del_file(repo_id, parent_dir, file_name, user): try: ret = seafserv_threaded_rpc.del_file(repo_id, parent_dir, file_name, user) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = -1 return True if ret == 0 else False @@ -816,14 +816,14 @@ def is_valid_filename(file_or_dir): def get_file_size(store_id, version, file_id): try: fs = seafserv_threaded_rpc.get_file_size(store_id, version, file_id) - except SearpcError, e: + except SearpcError as e: fs = 0 return fs def get_file_id_by_path(repo_id, path): try: ret = seafserv_threaded_rpc.get_file_id_by_path(repo_id, path) - except SearpcError, e: + except SearpcError as e: ret = '' return ret @@ -889,7 +889,7 @@ def get_related_users_by_org_repo(org_id, repo_id): def check_quota(repo_id, delta=0): try: ret = seafserv_threaded_rpc.check_quota(repo_id, delta) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = -1 return ret @@ -897,7 +897,7 @@ def check_quota(repo_id, delta=0): def get_user_quota(user): try: ret = seafserv_threaded_rpc.get_user_quota(user) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = 0 return ret @@ -905,7 +905,7 @@ def get_user_quota(user): def get_user_quota_usage(user): try: ret = seafserv_threaded_rpc.get_user_quota_usage(user) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = 0 return ret @@ -913,7 +913,7 @@ def get_user_quota_usage(user): def get_user_share_usage(user): try: ret = seafserv_threaded_rpc.get_user_share_usage(user) - except SearpcError, e: + except SearpcError as e: logger.error(e) ret = 0 return ret @@ -922,7 +922,7 @@ def get_user_share_usage(user): def web_get_access_token(repo_id, obj_id, op, username, use_onetime=1): try: ret = seafserv_rpc.web_get_access_token(repo_id, obj_id, op, username, use_onetime) - except SearpcError, e: + except SearpcError as e: ret = '' return ret @@ -936,14 +936,14 @@ def unset_repo_passwd(repo_id, user): """ try: ret = seafserv_threaded_rpc.unset_passwd(repo_id, user) - except SearpcError, e: + except SearpcError as e: ret = -1 return ret def is_passwd_set(repo_id, user): try: ret = seafserv_rpc.is_passwd_set(repo_id, user) - except SearpcError, e: + except SearpcError as e: ret = -1 return True if ret == 1 else False @@ -951,13 +951,13 @@ def is_passwd_set(repo_id, user): def get_repo_history_limit(repo_id): try: ret = seafserv_threaded_rpc.get_repo_history_limit(repo_id) - except SearpcError, e: + except SearpcError as e: ret = -1 return ret def set_repo_history_limit(repo_id, days): try: ret = seafserv_threaded_rpc.set_repo_history_limit(repo_id, days) - except SearpcError, e: + except SearpcError as e: ret = -1 return ret diff --git a/scripts/build/build-cli.py b/scripts/build/build-cli.py deleted file mode 100755 index 7ccd29e..0000000 --- a/scripts/build/build-cli.py +++ /dev/null @@ -1,696 +0,0 @@ -#!/usr/bin/env python -# coding: UTF-8 - -'''This scirpt builds the seafile command line client (With no gui). - -Some notes: - -''' - -import sys - -#################### -### Requires Python 2.6+ -#################### -if sys.version_info[0] == 3: - print 'Python 3 not supported yet. Quit now.' - sys.exit(1) -if sys.version_info[1] < 6: - print 'Python 2.6 or above is required. Quit now.' - sys.exit(1) - -import os -import commands -import tempfile -import shutil -import re -import subprocess -import optparse -import atexit - -#################### -### Global variables -#################### - -# command line configuartion -conf = {} - -# key names in the conf dictionary. -CONF_VERSION = 'version' -CONF_SEAFILE_VERSION = 'seafile_version' -CONF_LIBSEARPC_VERSION = 'libsearpc_version' -CONF_CCNET_VERSION = 'ccnet_version' -CONF_SRCDIR = 'srcdir' -CONF_KEEP = 'keep' -CONF_BUILDDIR = 'builddir' -CONF_OUTPUTDIR = 'outputdir' -CONF_THIRDPARTDIR = 'thirdpartdir' -CONF_NO_STRIP = 'nostrip' - -#################### -### Common helper functions -#################### -def highlight(content, is_error=False): - '''Add ANSI color to content to get it highlighted on terminal''' - if is_error: - return '\x1b[1;31m%s\x1b[m' % content - else: - return '\x1b[1;32m%s\x1b[m' % content - -def info(msg): - print highlight('[INFO] ') + msg - -def exist_in_path(prog): - '''Test whether prog exists in system path''' - dirs = os.environ['PATH'].split(':') - for d in dirs: - if d == '': - continue - path = os.path.join(d, prog) - if os.path.exists(path): - return True - - return False - -def prepend_env_value(name, value, seperator=':'): - '''append a new value to a list''' - try: - current_value = os.environ[name] - except KeyError: - current_value = '' - - new_value = value - if current_value: - new_value += seperator + current_value - - os.environ[name] = new_value - -def error(msg=None, usage=None): - if msg: - print highlight('[ERROR] ') + msg - if usage: - print usage - sys.exit(1) - -def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Run a program and wait it to finish, and return its exit code. The - standard output of this program is supressed. - - ''' - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(argv, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env) - return proc.wait() - -def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Like run_argv but specify a command line string instead of argv''' - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(cmdline, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env, - shell=True) - return proc.wait() - -def must_mkdir(path): - '''Create a directory, exit on failure''' - try: - os.mkdir(path) - except OSError, e: - error('failed to create directory %s:%s' % (path, e)) - -def must_copy(src, dst): - '''Copy src to dst, exit on failure''' - try: - shutil.copy(src, dst) - except Exception, e: - error('failed to copy %s to %s: %s' % (src, dst, e)) - -class Project(object): - '''Base class for a project''' - # Probject name, i.e. libseaprc/ccnet/seafile/ - name = '' - - # A list of shell commands to configure/build the project - build_commands = [] - - def __init__(self): - # the path to pass to --prefix=/ - self.prefix = os.path.join(conf[CONF_BUILDDIR], 'seafile-cli') - self.version = self.get_version() - self.src_tarball = os.path.join(conf[CONF_SRCDIR], - '%s-%s.tar.gz' % (self.name, self.version)) - # project dir, like /seafile-1.2.2/ - self.projdir = os.path.join(conf[CONF_BUILDDIR], '%s-%s' % (self.name, self.version)) - - def get_version(self): - # libsearpc and ccnet can have different versions from seafile. - raise NotImplementedError - - def get_source_commit_id(self): - '''By convetion, we record the commit id of the source code in the - file "/latest_commit" - - ''' - latest_commit_file = os.path.join(self.projdir, 'latest_commit') - with open(latest_commit_file, 'r') as fp: - commit_id = fp.read().strip('\n\r\t ') - - return commit_id - - def append_cflags(self, macros): - cflags = ' '.join([ '-D%s=%s' % (k, macros[k]) for k in macros ]) - prepend_env_value('CPPFLAGS', - cflags, - seperator=' ') - - def uncompress(self): - '''Uncompress the source from the tarball''' - info('Uncompressing %s' % self.name) - - if run('tar xf %s' % self.src_tarball) < 0: - error('failed to uncompress source of %s' % self.name) - - def before_build(self): - '''Hook method to do project-specific stuff before running build commands''' - pass - - def build(self): - '''Build the source''' - self.before_build() - info('Building %s' % self.name) - for cmd in self.build_commands: - if run(cmd, cwd=self.projdir) != 0: - error('error when running command:\n\t%s\n' % cmd) - -class Libsearpc(Project): - name = 'libsearpc' - - def __init__(self): - Project.__init__(self) - self.build_commands = [ - './configure --prefix=%s --disable-compile-demo' % self.prefix, - 'make', - 'make install' - ] - - def get_version(self): - return conf[CONF_LIBSEARPC_VERSION] - -class Ccnet(Project): - name = 'ccnet' - def __init__(self): - Project.__init__(self) - self.build_commands = [ - './configure --prefix=%s --disable-compile-demo' % self.prefix, - 'make', - 'make install' - ] - - def get_version(self): - return conf[CONF_CCNET_VERSION] - - def before_build(self): - macros = {} - # SET CCNET_SOURCE_COMMIT_ID, so it can be printed in the log - macros['CCNET_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() - - self.append_cflags(macros) - -class Seafile(Project): - name = 'seafile' - def __init__(self): - Project.__init__(self) - self.build_commands = [ - './configure --prefix=%s --disable-gui' % self.prefix, - 'make', - 'make install' - ] - - def get_version(self): - return conf[CONF_SEAFILE_VERSION] - - def update_cli_version(self): - '''Substitute the version number in seaf-cli''' - cli_py = os.path.join(self.projdir, 'app', 'seaf-cli') - with open(cli_py, 'r') as fp: - lines = fp.readlines() - - ret = [] - for line in lines: - old = '''SEAF_CLI_VERSION = ""''' - new = '''SEAF_CLI_VERSION = "%s"''' % conf[CONF_VERSION] - line = line.replace(old, new) - ret.append(line) - - with open(cli_py, 'w') as fp: - fp.writelines(ret) - - def before_build(self): - self.update_cli_version() - macros = {} - # SET SEAFILE_SOURCE_COMMIT_ID, so it can be printed in the log - macros['SEAFILE_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() - self.append_cflags(macros) - -def check_targz_src(proj, version, srcdir): - src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) - if not os.path.exists(src_tarball): - error('%s not exists' % src_tarball) - -def validate_args(usage, options): - required_args = [ - CONF_VERSION, - CONF_LIBSEARPC_VERSION, - CONF_CCNET_VERSION, - CONF_SEAFILE_VERSION, - CONF_SRCDIR, - ] - - # fist check required args - for optname in required_args: - if getattr(options, optname, None) == None: - error('%s must be specified' % optname, usage=usage) - - def get_option(optname): - return getattr(options, optname) - - # [ version ] - def check_project_version(version): - '''A valid version must be like 1.2.2, 1.3''' - if not re.match('^[0-9]+(\.([0-9])+)+$', version): - error('%s is not a valid version' % version, usage=usage) - - version = get_option(CONF_VERSION) - seafile_version = get_option(CONF_SEAFILE_VERSION) - libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) - ccnet_version = get_option(CONF_CCNET_VERSION) - - check_project_version(version) - check_project_version(libsearpc_version) - check_project_version(ccnet_version) - check_project_version(seafile_version) - - # [ srcdir ] - srcdir = get_option(CONF_SRCDIR) - check_targz_src('libsearpc', libsearpc_version, srcdir) - check_targz_src('ccnet', ccnet_version, srcdir) - check_targz_src('seafile', seafile_version, srcdir) - - # [ builddir ] - builddir = get_option(CONF_BUILDDIR) - if not os.path.exists(builddir): - error('%s does not exist' % builddir, usage=usage) - - builddir = os.path.join(builddir, 'seafile-cli-build') - - # [ outputdir ] - outputdir = get_option(CONF_OUTPUTDIR) - if outputdir: - if not os.path.exists(outputdir): - error('outputdir %s does not exist' % outputdir, usage=usage) - else: - outputdir = os.getcwd() - - # [ keep ] - keep = get_option(CONF_KEEP) - - # [ no strip] - nostrip = get_option(CONF_NO_STRIP) - - conf[CONF_VERSION] = version - conf[CONF_LIBSEARPC_VERSION] = libsearpc_version - conf[CONF_SEAFILE_VERSION] = seafile_version - conf[CONF_CCNET_VERSION] = ccnet_version - - conf[CONF_BUILDDIR] = builddir - conf[CONF_SRCDIR] = srcdir - conf[CONF_OUTPUTDIR] = outputdir - conf[CONF_KEEP] = keep - conf[CONF_NO_STRIP] = nostrip - - prepare_builddir(builddir) - show_build_info() - -def show_build_info(): - '''Print all conf information. Confirm before continue.''' - info('------------------------------------------') - info('Seafile command line client %s: BUILD INFO' % conf[CONF_VERSION]) - info('------------------------------------------') - info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) - info('ccnet: %s' % conf[CONF_CCNET_VERSION]) - info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) - info('builddir: %s' % conf[CONF_BUILDDIR]) - info('outputdir: %s' % conf[CONF_OUTPUTDIR]) - info('source dir: %s' % conf[CONF_SRCDIR]) - info('strip symbols: %s' % (not conf[CONF_NO_STRIP])) - info('clean on exit: %s' % (not conf[CONF_KEEP])) - info('------------------------------------------') - info('press any key to continue ') - info('------------------------------------------') - dummy = raw_input() - -def prepare_builddir(builddir): - must_mkdir(builddir) - - if not conf[CONF_KEEP]: - def remove_builddir(): - '''Remove the builddir when exit''' - info('remove builddir before exit') - shutil.rmtree(builddir, ignore_errors=True) - atexit.register(remove_builddir) - - os.chdir(builddir) - - must_mkdir(os.path.join(builddir, 'seafile-cli')) - -def parse_args(): - parser = optparse.OptionParser() - def long_opt(opt): - return '--' + opt - - parser.add_option(long_opt(CONF_VERSION), - dest=CONF_VERSION, - nargs=1, - help='the version to build. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_SEAFILE_VERSION), - dest=CONF_SEAFILE_VERSION, - nargs=1, - help='the version of seafile as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), - dest=CONF_LIBSEARPC_VERSION, - nargs=1, - help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_CCNET_VERSION), - dest=CONF_CCNET_VERSION, - nargs=1, - help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_BUILDDIR), - dest=CONF_BUILDDIR, - nargs=1, - help='the directory to build the source. Defaults to /tmp', - default=tempfile.gettempdir()) - - parser.add_option(long_opt(CONF_OUTPUTDIR), - dest=CONF_OUTPUTDIR, - nargs=1, - help='the output directory to put the generated tarball. Defaults to the current directory.', - default=os.getcwd()) - - parser.add_option(long_opt(CONF_SRCDIR), - dest=CONF_SRCDIR, - nargs=1, - help='''Source tarballs must be placed in this directory.''') - - parser.add_option(long_opt(CONF_KEEP), - dest=CONF_KEEP, - action='store_true', - help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') - - parser.add_option(long_opt(CONF_NO_STRIP), - dest=CONF_NO_STRIP, - action='store_true', - help='''do not strip debug symbols''') - usage = parser.format_help() - options, remain = parser.parse_args() - if remain: - error(usage=usage) - - validate_args(usage, options) - -def setup_build_env(): - '''Setup environment variables, such as export PATH=$BUILDDDIR/bin:$PATH''' - prefix = os.path.join(conf[CONF_BUILDDIR], 'seafile-cli') - - prepend_env_value('CPPFLAGS', - '-I%s' % os.path.join(prefix, 'include'), - seperator=' ') - - prepend_env_value('CPPFLAGS', - '-DSEAFILE_CLIENT_VERSION=\\"%s\\"' % conf[CONF_VERSION], - seperator=' ') - - if conf[CONF_NO_STRIP]: - prepend_env_value('CPPFLAGS', - '-g -O0', - seperator=' ') - - prepend_env_value('LDFLAGS', - '-L%s' % os.path.join(prefix, 'lib'), - seperator=' ') - - prepend_env_value('LDFLAGS', - '-L%s' % os.path.join(prefix, 'lib64'), - seperator=' ') - - prepend_env_value('PATH', os.path.join(prefix, 'bin')) - prepend_env_value('PKG_CONFIG_PATH', os.path.join(prefix, 'lib', 'pkgconfig')) - prepend_env_value('PKG_CONFIG_PATH', os.path.join(prefix, 'lib64', 'pkgconfig')) - -def copy_scripts_and_libs(): - '''Copy scripts and shared libs''' - builddir = conf[CONF_BUILDDIR] - seafile_dir = os.path.join(builddir, Seafile().projdir) - scripts_srcdir = os.path.join(seafile_dir, 'scripts') - doc_dir = os.path.join(seafile_dir, 'doc') - cli_dir = os.path.join(builddir, 'seafile-cli') - - # copy the wrapper shell script for seaf-cli.py - src = os.path.join(scripts_srcdir, 'seaf-cli-wrapper.sh') - dst = os.path.join(cli_dir, 'seaf-cli') - - must_copy(src, dst) - - # copy Readme for cli client - src = os.path.join(doc_dir, 'cli-readme.txt') - dst = os.path.join(cli_dir, 'Readme.txt') - - must_copy(src, dst) - - # rename seaf-cli to seaf-cli.py to avoid confusing users - src = os.path.join(cli_dir, 'bin', 'seaf-cli') - dst = os.path.join(cli_dir, 'bin', 'seaf-cli.py') - - try: - shutil.move(src, dst) - except Exception, e: - error('failed to move %s to %s: %s' % (src, dst, e)) - - # copy shared c libs - copy_shared_libs() - -def get_dependent_libs(executable): - syslibs = ['libsearpc', 'libccnet', 'libseafile', 'libpthread.so', 'libc.so', 'libm.so', 'librt.so', 'libdl.so', 'libselinux.so'] - def is_syslib(lib): - for syslib in syslibs: - if syslib in lib: - return True - return False - - ldd_output = commands.getoutput('ldd %s' % executable) - ret = [] - for line in ldd_output.splitlines(): - tokens = line.split() - if len(tokens) != 4: - continue - if is_syslib(tokens[0]): - continue - - ret.append(tokens[2]) - - return ret - -def copy_shared_libs(): - '''copy shared c libs, such as libevent, glib, libmysqlclient''' - builddir = conf[CONF_BUILDDIR] - - dst_dir = os.path.join(builddir, - 'seafile-cli', - 'lib') - - ccnet_daemon_path = os.path.join(builddir, - 'seafile-cli', - 'bin', - 'ccnet') - - seaf_daemon_path = os.path.join(builddir, - 'seafile-cli', - 'bin', - 'seaf-daemon') - - ccnet_daemon_libs = get_dependent_libs(ccnet_daemon_path) - seaf_daemon_libs = get_dependent_libs(seaf_daemon_path) - - libs = ccnet_daemon_libs - for lib in seaf_daemon_libs: - if lib not in libs: - libs.append(lib) - - for lib in libs: - info('Copying %s' % lib) - shutil.copy(lib, dst_dir) - -def strip_symbols(): - def do_strip(fn): - run('chmod u+w %s' % fn) - info('stripping: %s' % fn) - run('strip "%s"' % fn) - - def remove_static_lib(fn): - info('removing: %s' % fn) - os.remove(fn) - - builddir = conf[CONF_BUILDDIR] - topdir = os.path.join(builddir, 'seafile-cli') - for parent, dnames, fnames in os.walk(topdir): - dummy = dnames # avoid pylint 'unused' warning - for fname in fnames: - fn = os.path.join(parent, fname) - if os.path.isdir(fn): - continue - - if fn.endswith(".a") or fn.endswith(".la"): - remove_static_lib(fn) - continue - - if os.path.islink(fn): - continue - - finfo = commands.getoutput('file "%s"' % fn) - - if 'not stripped' in finfo: - do_strip(fn) - -def create_tarball(tarball_name): - '''call tar command to generate a tarball''' - version = conf[CONF_VERSION] - - cli_dir = 'seafile-cli' - versioned_cli_dir = 'seafile-cli-' + version - - # move seafile-cli to seafile-cli-${version} - try: - shutil.move(cli_dir, versioned_cli_dir) - except Exception, e: - error('failed to move %s to %s: %s' % (cli_dir, versioned_cli_dir, e)) - - ignored_patterns = [ - # common ignored files - '*.pyc', - '*~', - '*#', - - # seafile - os.path.join(versioned_cli_dir, 'share*'), - os.path.join(versioned_cli_dir, 'include*'), - os.path.join(versioned_cli_dir, 'lib', 'pkgconfig*'), - os.path.join(versioned_cli_dir, 'lib64', 'pkgconfig*'), - os.path.join(versioned_cli_dir, 'bin', 'ccnet-demo*'), - os.path.join(versioned_cli_dir, 'bin', 'ccnet-tool'), - os.path.join(versioned_cli_dir, 'bin', 'ccnet-servtool'), - os.path.join(versioned_cli_dir, 'bin', 'searpc-codegen.py'), - os.path.join(versioned_cli_dir, 'bin', 'seafile-admin'), - os.path.join(versioned_cli_dir, 'bin', 'seafile'), - ] - - excludes_list = [ '--exclude=%s' % pattern for pattern in ignored_patterns ] - excludes = ' '.join(excludes_list) - - tar_cmd = 'tar czvf %(tarball_name)s %(versioned_cli_dir)s %(excludes)s' \ - % dict(tarball_name=tarball_name, - versioned_cli_dir=versioned_cli_dir, - excludes=excludes) - - if run(tar_cmd) != 0: - error('failed to generate the tarball') - -def gen_tarball(): - # strip symbols of libraries to reduce size - if not conf[CONF_NO_STRIP]: - try: - strip_symbols() - except Exception, e: - error('failed to strip symbols: %s' % e) - - # determine the output name - # 64-bit: seafile-cli_1.2.2_x86-64.tar.gz - # 32-bit: seafile-cli_1.2.2_i386.tar.gz - version = conf[CONF_VERSION] - arch = os.uname()[-1].replace('_', '-') - if arch != 'x86-64': - arch = 'i386' - - dbg = '' - if conf[CONF_NO_STRIP]: - dbg = '.dbg' - - tarball_name = 'seafile-cli_%(version)s_%(arch)s%(dbg)s.tar.gz' \ - % dict(version=version, arch=arch, dbg=dbg) - dst_tarball = os.path.join(conf[CONF_OUTPUTDIR], tarball_name) - - # generate the tarball - try: - create_tarball(tarball_name) - except Exception, e: - error('failed to generate tarball: %s' % e) - - # move tarball to outputdir - try: - shutil.copy(tarball_name, dst_tarball) - except Exception, e: - error('failed to copy %s to %s: %s' % (tarball_name, dst_tarball, e)) - - print '---------------------------------------------' - print 'The build is successfully. Output is:\t%s' % dst_tarball - print '---------------------------------------------' - -def main(): - parse_args() - setup_build_env() - - libsearpc = Libsearpc() - ccnet = Ccnet() - seafile = Seafile() - - libsearpc.uncompress() - libsearpc.build() - - ccnet.uncompress() - ccnet.build() - - seafile.uncompress() - seafile.build() - - copy_scripts_and_libs() - gen_tarball() - -if __name__ == '__main__': - main() diff --git a/scripts/build/build-deb.py b/scripts/build/build-deb.py deleted file mode 100755 index 710b3ab..0000000 --- a/scripts/build/build-deb.py +++ /dev/null @@ -1,496 +0,0 @@ -#!/usr/bin/env python -# coding: UTF-8 - -'''This scirpt builds the seafile server tarball. - -Some notes: - -1. The working directory is always the 'builddir'. 'os.chdir' is only called -to change to the 'builddir'. We make use of the 'cwd' argument in -'subprocess.Popen' to run a command in a specific directory. - -''' - -import sys - -#################### -### Requires Python 2.6+ -#################### -if sys.version_info[0] == 3: - print 'Python 3 not supported yet. Quit now.' - sys.exit(1) -if sys.version_info[1] < 6: - print 'Python 2.6 or above is required. Quit now.' - sys.exit(1) - -import os -import glob -import tempfile -import shutil -import re -import subprocess -import optparse -import atexit - -#################### -### Global variables -#################### - -# command line configuartion -conf = {} - -# key names in the conf dictionary. -CONF_VERSION = 'version' -CONF_LIBSEARPC_VERSION = 'libsearpc_version' -CONF_CCNET_VERSION = 'ccnet_version' -CONF_SEAFILE_VERSION = 'seafile_version' -CONF_SEAFILE_CLIENT_VERSION = 'seafile_client_version' -CONF_SRCDIR = 'srcdir' -CONF_KEEP = 'keep' -CONF_BUILDDIR = 'builddir' -CONF_OUTPUTDIR = 'outputdir' -CONF_NO_STRIP = 'nostrip' - -#################### -### Common helper functions -#################### -def highlight(content, is_error=False): - '''Add ANSI color to content to get it highlighted on terminal''' - if is_error: - return '\x1b[1;31m%s\x1b[m' % content - else: - return '\x1b[1;32m%s\x1b[m' % content - -def info(msg): - print highlight('[INFO] ') + msg - -def exist_in_path(prog): - '''Test whether prog exists in system path''' - dirs = os.environ['PATH'].split(':') - for d in dirs: - if d == '': - continue - path = os.path.join(d, prog) - if os.path.exists(path): - return True - - return False - -def prepend_env_value(name, value, seperator=':'): - '''append a new value to a list''' - try: - current_value = os.environ[name] - except KeyError: - current_value = '' - - new_value = value - if current_value: - new_value += seperator + current_value - - os.environ[name] = new_value - -def error(msg=None, usage=None): - if msg: - print highlight('[ERROR] ') + msg - if usage: - print usage - sys.exit(1) - -def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Run a program and wait it to finish, and return its exit code. The - standard output of this program is supressed. - - ''' - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(argv, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env) - return proc.wait() - -def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Like run_argv but specify a command line string instead of argv''' - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(cmdline, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env, - shell=True) - return proc.wait() - -def must_mkdir(path): - '''Create a directory, exit on failure''' - try: - os.mkdir(path) - except OSError, e: - error('failed to create directory %s:%s' % (path, e)) - -def must_copy(src, dst): - '''Copy src to dst, exit on failure''' - try: - shutil.copy(src, dst) - except Exception, e: - error('failed to copy %s to %s: %s' % (src, dst, e)) - -class Project(object): - '''Base class for a project''' - # Probject name, i.e. libseaprc/ccnet/seafile/seahub - name = '' - - # A list of shell commands to configure/build the project - build_commands = [] - - def __init__(self): - self.version = self.get_version() - self.src_tarball = os.path.join(conf[CONF_SRCDIR], - '%s-%s.tar.gz' % (self.name, self.version)) - # project dir, like /seafile-1.2.2/ - self.projdir = os.path.join(conf[CONF_BUILDDIR], '%s-%s' % (self.name, self.version)) - - def get_version(self): - # libsearpc and ccnet can have different versions from seafile. - raise NotImplementedError - - def get_source_commit_id(self): - '''By convetion, we record the commit id of the source code in the - file "/latest_commit" - - ''' - latest_commit_file = os.path.join(self.projdir, 'latest_commit') - with open(latest_commit_file, 'r') as fp: - commit_id = fp.read().strip('\n\r\t ') - - return commit_id - - def append_cflags(self, macros): - cflags = ' '.join([ '-D%s=%s' % (k, macros[k]) for k in macros ]) - prepend_env_value('DEB_CPPFLAGS_APPEND', - cflags, - seperator=' ') - - def uncompress(self): - '''Uncompress the source from the tarball''' - info('Uncompressing %s' % self.name) - - if run('tar xf %s' % self.src_tarball) < 0: - error('failed to uncompress source of %s' % self.name) - - def before_build(self): - '''Hook method to do project-specific stuff before running build commands''' - pass - - def build(self): - '''Build the source''' - self.before_build() - info('Building %s' % self.name) - for cmd in self.build_commands: - if run(cmd, cwd=self.projdir) != 0: - error('error when running command:\n\t%s\n' % cmd) - -class Libsearpc(Project): - name = 'libsearpc' - - def get_version(self): - return conf[CONF_LIBSEARPC_VERSION] - -class Ccnet(Project): - name = 'ccnet' - - def get_version(self): - return conf[CONF_CCNET_VERSION] - - def before_build(self): - macros = {} - # SET CCNET_SOURCE_COMMIT_ID, so it can be printed in the log - macros['CCNET_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() - - self.append_cflags(macros) - -class SeafileClient(Project): - name = 'seafile-client' - - def get_version(self): - return conf[CONF_SEAFILE_CLIENT_VERSION] - - def before_build(self): - pass - -class Seafile(Project): - name = 'seafile' - def __init__(self): - Project.__init__(self) - self.build_commands = [ - 'dpkg-buildpackage -B -nc -uc -us', - ] - - def get_version(self): - return conf[CONF_SEAFILE_VERSION] - - def before_build(self): - macros = {} - # SET SEAFILE_SOURCE_COMMIT_ID, so it can be printed in the log - macros['SEAFILE_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() - self.append_cflags(macros) - -def check_targz_src(proj, version, srcdir): - src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) - if not os.path.exists(src_tarball): - error('%s not exists' % src_tarball) - -def validate_args(usage, options): - required_args = [ - CONF_VERSION, - CONF_LIBSEARPC_VERSION, - CONF_CCNET_VERSION, - CONF_SEAFILE_VERSION, - CONF_SEAFILE_CLIENT_VERSION, - CONF_SRCDIR, - ] - - # fist check required args - for optname in required_args: - if getattr(options, optname, None) == None: - error('%s must be specified' % optname, usage=usage) - - def get_option(optname): - return getattr(options, optname) - - # [ version ] - def check_project_version(version): - '''A valid version must be like 1.2.2, 1.3''' - if not re.match('^[0-9]+(\.([0-9])+)+$', version): - error('%s is not a valid version' % version, usage=usage) - - version = get_option(CONF_VERSION) - libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) - ccnet_version = get_option(CONF_CCNET_VERSION) - seafile_version = get_option(CONF_SEAFILE_VERSION) - seafile_client_version = get_option(CONF_SEAFILE_CLIENT_VERSION) - - check_project_version(version) - check_project_version(libsearpc_version) - check_project_version(ccnet_version) - check_project_version(seafile_version) - - # [ srcdir ] - srcdir = get_option(CONF_SRCDIR) - check_targz_src('libsearpc', libsearpc_version, srcdir) - check_targz_src('ccnet', ccnet_version, srcdir) - check_targz_src('seafile', seafile_version, srcdir) - check_targz_src('seafile-client', seafile_client_version, srcdir) - - # [ builddir ] - builddir = get_option(CONF_BUILDDIR) - if not os.path.exists(builddir): - error('%s does not exist' % builddir, usage=usage) - - builddir = os.path.join(builddir, 'seafile-deb-build') - - # [ outputdir ] - outputdir = get_option(CONF_OUTPUTDIR) - if outputdir: - if not os.path.exists(outputdir): - error('outputdir %s does not exist' % outputdir, usage=usage) - else: - outputdir = os.getcwd() - - # [ keep ] - keep = get_option(CONF_KEEP) - - # [ no strip] - nostrip = get_option(CONF_NO_STRIP) - - conf[CONF_VERSION] = version - conf[CONF_LIBSEARPC_VERSION] = libsearpc_version - conf[CONF_CCNET_VERSION] = ccnet_version - conf[CONF_SEAFILE_VERSION] = seafile_version - conf[CONF_SEAFILE_CLIENT_VERSION] = seafile_client_version - - conf[CONF_BUILDDIR] = builddir - conf[CONF_SRCDIR] = srcdir - conf[CONF_OUTPUTDIR] = outputdir - conf[CONF_KEEP] = True - conf[CONF_NO_STRIP] = nostrip - - prepare_builddir(builddir) - show_build_info() - -def show_build_info(): - '''Print all conf information. Confirm before continue.''' - info('------------------------------------------') - info('Seafile debian package: BUILD INFO') - info('------------------------------------------') - info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) - info('seafile-client: %s' % conf[CONF_SEAFILE_CLIENT_VERSION]) - info('ccnet: %s' % conf[CONF_CCNET_VERSION]) - info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) - info('builddir: %s' % conf[CONF_BUILDDIR]) - info('outputdir: %s' % conf[CONF_OUTPUTDIR]) - info('source dir: %s' % conf[CONF_SRCDIR]) - info('strip symbols: %s' % (not conf[CONF_NO_STRIP])) - info('clean on exit: %s' % (not conf[CONF_KEEP])) - info('------------------------------------------') - info('press any key to continue ') - info('------------------------------------------') - dummy = raw_input() - -def prepare_builddir(builddir): - must_mkdir(builddir) - - if not conf[CONF_KEEP]: - def remove_builddir(): - '''Remove the builddir when exit''' - info('remove builddir before exit') - shutil.rmtree(builddir, ignore_errors=True) - atexit.register(remove_builddir) - - os.chdir(builddir) - -def parse_args(): - parser = optparse.OptionParser() - def long_opt(opt): - return '--' + opt - - parser.add_option(long_opt(CONF_VERSION), - dest=CONF_VERSION, - nargs=1, - help='the version to build. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), - dest=CONF_LIBSEARPC_VERSION, - nargs=1, - help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_CCNET_VERSION), - dest=CONF_CCNET_VERSION, - nargs=1, - help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_SEAFILE_VERSION), - dest=CONF_SEAFILE_VERSION, - nargs=1, - help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_SEAFILE_CLIENT_VERSION), - dest=CONF_SEAFILE_CLIENT_VERSION, - nargs=1, - help='the version of seafile-client. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_BUILDDIR), - dest=CONF_BUILDDIR, - nargs=1, - help='the directory to build the source. Defaults to /tmp', - default=tempfile.gettempdir()) - - parser.add_option(long_opt(CONF_OUTPUTDIR), - dest=CONF_OUTPUTDIR, - nargs=1, - help='the output directory to put the generated server tarball. Defaults to the current directory.', - default=os.getcwd()) - - parser.add_option(long_opt(CONF_SRCDIR), - dest=CONF_SRCDIR, - nargs=1, - help='''Source tarballs must be placed in this directory.''') - - parser.add_option(long_opt(CONF_KEEP), - dest=CONF_KEEP, - action='store_true', - help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') - - parser.add_option(long_opt(CONF_NO_STRIP), - dest=CONF_NO_STRIP, - action='store_true', - help='''do not strip debug symbols''') - usage = parser.format_help() - options, remain = parser.parse_args() - if remain: - error(usage=usage) - - validate_args(usage, options) - -def setup_build_env(): - '''Setup environment variables, such as export PATH=$BUILDDDIR/bin:$PATH''' - prefix = os.path.join(Seafile().projdir, 'debian', 'seafile', 'usr') - - prepend_env_value('DEB_CPPFLAGS_APPEND', - '-DSEAFILE_CLIENT_VERSION=\\"%s\\"' % conf[CONF_VERSION], - seperator=' ') - - if conf[CONF_NO_STRIP]: - prepend_env_value('DEB_CPPFLAGS_APPEND', - '-g -O0', - seperator=' ') - os.environ['SEAFILE_NOSTRIP'] = 'true' - os.environ['DEB_CFLAGS_SET'] = '' - os.environ['DEB_CXXFLAGS_SET'] = '' - - prepend_env_value('PATH', os.path.join(prefix, 'bin')) - prepend_env_value('PKG_CONFIG_PATH', os.path.join(prefix, 'lib', 'pkgconfig')) - - os.environ['LIBSEARPC_SOURCE_DIR'] = Libsearpc().projdir - os.environ['CCNET_SOURCE_DIR'] = Ccnet().projdir - os.environ['SEAFILE_CLIENT_SOURCE_DIR'] = SeafileClient().projdir - -def move_deb(): - builddir = conf[CONF_BUILDDIR] - deb_name = glob.glob('*.deb')[0] - - src_deb = os.path.join(builddir, deb_name) - dst_deb = os.path.join(conf[CONF_OUTPUTDIR], deb_name) - - # move deb to outputdir - try: - shutil.move(src_deb, dst_deb) - except Exception, e: - error('failed to copy %s to %s: %s' % (src_deb, dst_deb, e)) - - print '---------------------------------------------' - print 'The build is successfully. Output is:\t%s' % dst_deb - print '---------------------------------------------' - -def main(): - parse_args() - setup_build_env() - - libsearpc = Libsearpc() - ccnet = Ccnet() - seafile = Seafile() - seafile_client = SeafileClient() - - libsearpc.uncompress() - ccnet.uncompress() - seafile.uncompress() - seafile_client.uncompress() - - libsearpc.build() - ccnet.build() - seafile.build() - seafile_client.build() - - move_deb() - -if __name__ == '__main__': - main() diff --git a/scripts/build/build-msi.py b/scripts/build/build-msi.py deleted file mode 100755 index 66d1721..0000000 --- a/scripts/build/build-msi.py +++ /dev/null @@ -1,942 +0,0 @@ -#!/usr/bin/env python -# coding: UTF-8 - -'''This scirpt builds the seafile windows msi installer. - -Some notes: - -1. The working directory is always the 'builddir'. 'os.chdir' is only called -to change to the 'builddir'. We make use of the 'cwd' argument in -'subprocess.Popen' to run a command in a specific directory. - -2. When invoking commands like 'tar', we must convert the path to posix path with the function to_mingw_path. E.g., 'c:\\seafile' should be converted to '/c/seafile'. - -''' - -import sys - -#################### -### Requires Python 2.6+ -#################### -if sys.version_info[0] == 3: - print 'Python 3 not supported yet. Quit now.' - sys.exit(1) -if sys.version_info[1] < 6: - print 'Python 2.6 or above is required. Quit now.' - sys.exit(1) - -import os -import glob -import shutil -import re -import subprocess -import optparse -import atexit -import csv - -error_exit = False -#################### -### Global variables -#################### - -# command line configuartion -conf = {} - -# key names in the conf dictionary. -CONF_VERSION = 'version' -CONF_LIBSEARPC_VERSION = 'libsearpc_version' -CONF_CCNET_VERSION = 'ccnet_version' -CONF_SEAFILE_VERSION = 'seafile_version' -CONF_SEAFILE_CLIENT_VERSION = 'seafile_client_version' -CONF_SRCDIR = 'srcdir' -CONF_KEEP = 'keep' -CONF_BUILDDIR = 'builddir' -CONF_OUTPUTDIR = 'outputdir' -CONF_DEBUG = 'debug' -CONF_ONLY_CHINESE = 'onlychinese' -CONF_QT_ROOT = 'qt_root' -CONF_QT5 = 'qt5' -CONF_WITH_SHIB = 'with_shib' -CONF_BRAND = 'brand' - -#################### -### Common helper functions -#################### -def to_mingw_path(path): - if len(path) < 2 or path[1] != ':' : - return path.replace('\\', '/') - - drive = path[0] - return '/%s%s' % (drive.lower(), path[2:].replace('\\', '/')) - -def to_win_path(path): - if len(path) < 2 or path[1] == ':' : - return path.replace('/', '\\') - - drive = path[1] - return '%s:%s' % (drive.lower(), path[2:].replace('/', '\\')) - -def highlight(content, is_error=False): - '''Add ANSI color to content to get it highlighted on terminal''' - dummy = is_error - return content - # if is_error: - # return '\x1b[1;31m%s\x1b[m' % content - # else: - # return '\x1b[1;32m%s\x1b[m' % content - -def info(msg): - print highlight('[INFO] ') + msg - -def find_in_path(prog): - '''Test whether prog exists in system path''' - dirs = os.environ['PATH'].split(';') - for d in dirs: - if d == '': - continue - path = os.path.join(d, prog) - if os.path.exists(path): - return path - - return None - -def prepend_env_value(name, value, seperator=':'): - '''prepend a new value to a list''' - try: - current_value = os.environ[name] - except KeyError: - current_value = '' - - new_value = value - if current_value: - new_value += seperator + current_value - - os.environ[name] = new_value - -def error(msg=None, usage=None): - if msg: - print highlight('[ERROR] ') + msg - if usage: - print usage - sys.exit(1) - -def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Run a program and wait it to finish, and return its exit code. The - standard output of this program is supressed. - - ''' - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(argv, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env) - return proc.wait() - -def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Like run_argv but specify a command line string instead of argv''' - info('running %s, cwd=%s' % (cmdline, cwd if cwd else os.getcwd())) - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(cmdline, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env, - shell=True) - ret = proc.wait() - if 'depend' not in cmdline and ret != 0: - global error_exit - error_exit = True - return ret - -def must_mkdir(path): - '''Create a directory, exit on failure''' - try: - os.makedirs(path) - except OSError, e: - error('failed to create directory %s:%s' % (path, e)) - -def must_copy(src, dst): - '''Copy src to dst, exit on failure''' - try: - shutil.copy(src, dst) - except Exception, e: - error('failed to copy %s to %s: %s' % (src, dst, e)) - -def must_copytree(src, dst): - '''Copy dir src to dst, exit on failure''' - try: - shutil.copytree(src, dst) - except Exception, e: - error('failed to copy dir %s to %s: %s' % (src, dst, e)) - -def must_move(src, dst): - '''Move src to dst, exit on failure''' - try: - shutil.move(src, dst) - except Exception, e: - error('failed to move %s to %s: %s' % (src, dst, e)) - -class Project(object): - '''Base class for a project''' - # Probject name, i.e. libseaprc/ccnet/seafile/seahub - name = '' - - # A list of shell commands to configure/build the project - build_commands = [] - - def __init__(self): - self.prefix = os.path.join(conf[CONF_BUILDDIR], 'usr') - self.version = self.get_version() - self.src_tarball = os.path.join(conf[CONF_SRCDIR], - '%s-%s.tar.gz' % (self.name, self.version)) - - # project dir, like /seafile-1.2.2/ - self.projdir = os.path.join(conf[CONF_BUILDDIR], '%s-%s' % (self.name, self.version)) - - def get_version(self): - # libsearpc and ccnet can have different versions from seafile. - raise NotImplementedError - - def get_source_commit_id(self): - '''By convetion, we record the commit id of the source code in the - file "/latest_commit" - - ''' - latest_commit_file = os.path.join(self.projdir, 'latest_commit') - with open(latest_commit_file, 'r') as fp: - commit_id = fp.read().strip('\n\r\t ') - - return commit_id - - def append_cflags(self, macros): - cflags = ' '.join([ '-D%s=%s' % (k, macros[k]) for k in macros ]) - prepend_env_value('CPPFLAGS', - cflags, - seperator=' ') - - def uncompress(self): - '''Uncompress the source from the tarball''' - info('Uncompressing %s' % self.name) - - tarball = to_mingw_path(self.src_tarball) - if run('tar xf %s' % tarball) != 0: - error('failed to uncompress source of %s' % self.name) - - def before_build(self): - '''Hook method to do project-specific stuff before running build commands''' - pass - - def build(self): - '''Build the source''' - self.before_build() - info('Building %s' % self.name) - dump_env() - for cmd in self.build_commands: - if run(cmd, cwd=self.projdir) != 0: - error('error when running command:\n\t%s\n' % cmd) - -def get_make_path(): - return find_in_path('make.exe') - -class Libsearpc(Project): - name = 'libsearpc' - - def __init__(self): - Project.__init__(self) - self.build_commands = [ - 'sh ./configure --prefix=%s --disable-compile-demo' % to_mingw_path(self.prefix), - get_make_path(), - '%s install' % get_make_path(), - ] - - def get_version(self): - return conf[CONF_LIBSEARPC_VERSION] - -class Ccnet(Project): - name = 'ccnet' - - def __init__(self): - Project.__init__(self) - self.build_commands = [ - 'sh ./configure --prefix=%s --disable-compile-demo' % to_mingw_path(self.prefix), - get_make_path(), - '%s install' % get_make_path(), - ] - - def get_version(self): - return conf[CONF_CCNET_VERSION] - - def before_build(self): - macros = {} - # SET CCNET_SOURCE_COMMIT_ID, so it can be printed in the log - macros['CCNET_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() - - self.append_cflags(macros) - -class Seafile(Project): - name = 'seafile' - def __init__(self): - Project.__init__(self) - if breakpad_enabled(): - enable_breakpad = '--enable-breakpad' - else: - enable_breakpad = '' - self.build_commands = [ - 'sh ./configure %s --prefix=%s' % (enable_breakpad, to_mingw_path(self.prefix)), - get_make_path(), - '%s install' % get_make_path(), - ] - - def get_version(self): - return conf[CONF_SEAFILE_VERSION] - - def before_build(self): - macros = {} - # SET SEAFILE_SOURCE_COMMIT_ID, so it can be printed in the log - macros['SEAFILE_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() - self.append_cflags(macros) - -class SeafileClient(Project): - name = 'seafile-client' - def __init__(self): - Project.__init__(self) - ninja = find_in_path('ninja.exe') - seafile_prefix = Seafile().prefix - generator = 'Ninja' if ninja else 'MSYS Makefiles' - flags = { - 'USE_QT5': 'ON' if conf[CONF_QT5] else 'OFF', - 'BUILD_SHIBBOLETH_SUPPORT': 'ON' if conf[CONF_WITH_SHIB] else 'OFF', - # ninja invokes cmd.exe which doesn't support msys/mingw path - # change the value but don't override CMAKE_EXE_LINKER_FLAGS, - # which is in use - 'CMAKE_EXE_LINKER_FLAGS_RELEASE': '-L%s' % (os.path.join(seafile_prefix, 'lib') if ninja else to_mingw_path(os.path.join(seafile_prefix, 'lib'))), - } - flags = ' '.join(['-D%s=%s' % (k, v) for k, v in flags.iteritems()]) - make = ninja or get_make_path() - self.build_commands = [ - 'cmake -G "%s" %s -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%s .' % (generator, flags, to_mingw_path(self.prefix)), - make, - '%s install' % make, - "bash extensions/build.sh", - ] - - def get_version(self): - return conf[CONF_SEAFILE_CLIENT_VERSION] - - def before_build(self): - pass - -def check_targz_src(proj, version, srcdir): - src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) - if not os.path.exists(src_tarball): - error('%s not exists' % src_tarball) - -def validate_args(usage, options): - required_args = [ - CONF_VERSION, - CONF_LIBSEARPC_VERSION, - CONF_CCNET_VERSION, - CONF_SEAFILE_VERSION, - CONF_SEAFILE_CLIENT_VERSION, - CONF_SRCDIR, - CONF_QT_ROOT, - ] - - # fist check required args - for optname in required_args: - if getattr(options, optname, None) == None: - error('%s must be specified' % optname, usage=usage) - - def get_option(optname): - return getattr(options, optname) - - # [ version ] - def check_project_version(version): - '''A valid version must be like 1.2.2, 1.3''' - if not re.match('^[0-9]+(\.([0-9])+)+$', version): - error('%s is not a valid version' % version, usage=usage) - - version = get_option(CONF_VERSION) - libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) - ccnet_version = get_option(CONF_CCNET_VERSION) - seafile_version = get_option(CONF_SEAFILE_VERSION) - seafile_client_version = get_option(CONF_SEAFILE_CLIENT_VERSION) - - check_project_version(version) - check_project_version(libsearpc_version) - check_project_version(ccnet_version) - check_project_version(seafile_version) - check_project_version(seafile_client_version) - - # [ srcdir ] - srcdir = to_win_path(get_option(CONF_SRCDIR)) - check_targz_src('libsearpc', libsearpc_version, srcdir) - check_targz_src('ccnet', ccnet_version, srcdir) - check_targz_src('seafile', seafile_version, srcdir) - check_targz_src('seafile-client', seafile_client_version, srcdir) - - # [ builddir ] - builddir = to_win_path(get_option(CONF_BUILDDIR)) - if not os.path.exists(builddir): - error('%s does not exist' % builddir, usage=usage) - - builddir = os.path.join(builddir, 'seafile-msi-build') - - # [ outputdir ] - outputdir = to_win_path(get_option(CONF_OUTPUTDIR)) - if not os.path.exists(outputdir): - error('outputdir %s does not exist' % outputdir, usage=usage) - - # [ keep ] - keep = get_option(CONF_KEEP) - - # [ no strip] - debug = get_option(CONF_DEBUG) - - # [only chinese] - onlychinese = get_option(CONF_ONLY_CHINESE) - - # [ qt root] - qt_root = get_option(CONF_QT_ROOT) - def check_qt_root(qt_root): - if not os.path.exists(os.path.join(qt_root, 'plugins')): - error('%s is not a valid qt root' % qt_root) - check_qt_root(qt_root) - - # [qt5] - qt5 = get_option(CONF_QT5) - with_shib = get_option(CONF_WITH_SHIB) - brand = get_option(CONF_BRAND) - - conf[CONF_VERSION] = version - conf[CONF_LIBSEARPC_VERSION] = libsearpc_version - conf[CONF_CCNET_VERSION] = ccnet_version - conf[CONF_SEAFILE_VERSION] = seafile_version - conf[CONF_SEAFILE_CLIENT_VERSION] = seafile_client_version - - conf[CONF_BUILDDIR] = builddir - conf[CONF_SRCDIR] = srcdir - conf[CONF_OUTPUTDIR] = outputdir - conf[CONF_KEEP] = True - conf[CONF_DEBUG] = debug - conf[CONF_ONLY_CHINESE] = onlychinese - conf[CONF_QT_ROOT] = qt_root - conf[CONF_QT5] = qt5 - conf[CONF_WITH_SHIB] = with_shib - conf[CONF_BRAND] = brand - - prepare_builddir(builddir) - show_build_info() - -def show_build_info(): - '''Print all conf information. Confirm before continue.''' - info('------------------------------------------') - info('Seafile msi installer: BUILD INFO') - info('------------------------------------------') - info('seafile: %s' % conf[CONF_VERSION]) - info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) - info('ccnet: %s' % conf[CONF_CCNET_VERSION]) - info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) - info('seafile-client: %s' % conf[CONF_SEAFILE_CLIENT_VERSION]) - info('qt-root: %s' % conf[CONF_QT_ROOT]) - info('builddir: %s' % conf[CONF_BUILDDIR]) - info('outputdir: %s' % conf[CONF_OUTPUTDIR]) - info('source dir: %s' % conf[CONF_SRCDIR]) - info('debug: %s' % conf[CONF_DEBUG]) - info('build english version: %s' % (not conf[CONF_ONLY_CHINESE])) - info('clean on exit: %s' % (not conf[CONF_KEEP])) - info('------------------------------------------') - info('press any key to continue ') - info('------------------------------------------') - dummy = raw_input() - -def prepare_builddir(builddir): - must_mkdir(builddir) - - if not conf[CONF_KEEP]: - def remove_builddir(): - '''Remove the builddir when exit''' - if not error_exit: - info('remove builddir before exit') - shutil.rmtree(builddir, ignore_errors=True) - atexit.register(remove_builddir) - - os.chdir(builddir) - -def parse_args(): - parser = optparse.OptionParser() - def long_opt(opt): - return '--' + opt - - parser.add_option(long_opt(CONF_VERSION), - dest=CONF_VERSION, - nargs=1, - help='the version to build. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), - dest=CONF_LIBSEARPC_VERSION, - nargs=1, - help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_CCNET_VERSION), - dest=CONF_CCNET_VERSION, - nargs=1, - help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_SEAFILE_VERSION), - dest=CONF_SEAFILE_VERSION, - nargs=1, - help='the version of seafile as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_SEAFILE_CLIENT_VERSION), - dest=CONF_SEAFILE_CLIENT_VERSION, - nargs=1, - help='the version of seafile-client. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_BUILDDIR), - dest=CONF_BUILDDIR, - nargs=1, - help='the directory to build the source. Defaults to /c', - default='c:\\') - - parser.add_option(long_opt(CONF_OUTPUTDIR), - dest=CONF_OUTPUTDIR, - nargs=1, - help='the output directory to put the generated server tarball. Defaults to the current directory.', - default=os.getcwd()) - - parser.add_option(long_opt(CONF_SRCDIR), - dest=CONF_SRCDIR, - nargs=1, - help='''Source tarballs must be placed in this directory.''') - - parser.add_option(long_opt(CONF_QT_ROOT), - dest=CONF_QT_ROOT, - nargs=1, - help='''qt root directory.''') - - parser.add_option(long_opt(CONF_KEEP), - dest=CONF_KEEP, - action='store_true', - help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') - - parser.add_option(long_opt(CONF_DEBUG), - dest=CONF_DEBUG, - action='store_true', - help='''compile in debug mode''') - - parser.add_option(long_opt(CONF_ONLY_CHINESE), - dest=CONF_ONLY_CHINESE, - action='store_true', - help='''only build the Chinese version. By default both Chinese and English versions would be built.''') - - parser.add_option(long_opt(CONF_QT5), - dest=CONF_QT5, - action='store_true', - help='''build seafile client with qt5''') - - parser.add_option(long_opt(CONF_WITH_SHIB), - dest=CONF_WITH_SHIB, - action='store_true', - help='''build seafile client with shibboleth support''') - - parser.add_option(long_opt(CONF_BRAND), - dest=CONF_BRAND, - default='seafile', - help='''brand name of the package''') - - usage = parser.format_help() - options, remain = parser.parse_args() - if remain: - error(usage=usage) - - validate_args(usage, options) - -def setup_build_env(): - '''Setup environment variables, such as export PATH=$BUILDDDIR/bin:$PATH''' - prefix = Seafile().prefix - prepend_env_value('CPPFLAGS', - '-I%s' % to_mingw_path(os.path.join(prefix, 'include')), - seperator=' ') - - prepend_env_value('CPPFLAGS', - '-DSEAFILE_CLIENT_VERSION=\\"%s\\"' % conf[CONF_VERSION], - seperator=' ') - - prepend_env_value('CPPFLAGS', - '-g -fno-omit-frame-pointer', - seperator=' ') - if conf[CONF_DEBUG]: - prepend_env_value('CPPFLAGS', '-O0', seperator=' ') - - prepend_env_value('LDFLAGS', - '-L%s' % to_mingw_path(os.path.join(prefix, 'lib')), - seperator=' ') - - prepend_env_value('PATH', - os.path.join(prefix, 'bin'), - seperator=';') - - prepend_env_value('PKG_CONFIG_PATH', - os.path.join(prefix, 'lib', 'pkgconfig'), - seperator=';') - # to_mingw_path(os.path.join(prefix, 'lib', 'pkgconfig'))) - - # specifiy the directory for wix temporary files - wix_temp_dir = os.path.join(conf[CONF_BUILDDIR], 'wix-temp') - os.environ['WIX_TEMP'] = wix_temp_dir - - must_mkdir(wix_temp_dir) - -def dependency_walk(applet): - output = os.path.join(conf[CONF_BUILDDIR], 'depends.csv') - cmd = 'depends.exe -c -f 1 -oc %s %s' % (output, applet) - - # See the manual of Dependency walker - if run(cmd) > 0x100: - error('failed to run dependency walker for %s' % applet) - - if not os.path.exists(output): - error('failed to run dependency walker for %s' % applet) - - shared_libs = parse_depends_csv(output) - return shared_libs - -def parse_depends_csv(path): - '''parse the output of dependency walker''' - libs = set() - our_libs = ['libsearpc', 'libccnet', 'libseafile'] - def should_ignore_lib(lib): - lib = lib.lower() - if not os.path.exists(lib): - return True - - if lib.startswith('c:\\windows'): - return True - - if lib.endswith('exe'): - return True - - for name in our_libs: - if name in lib: - return True - - return False - - with open(path, 'r') as fp: - reader = csv.reader(fp) - for row in reader: - if len(row) < 2: - continue - lib = row[1] - if not should_ignore_lib(lib): - libs.add(lib) - - return set(libs) - -def copy_shared_libs(exes): - '''Copy shared libs need by seafile-applet.exe, such as libccnet, - libseafile, etc. First we use Dependency walker to analyse - seafile-applet.exe, and get an output file in csv format. Then we parse - the csv file to get the list of shared libs. - - ''' - - shared_libs = set() - for exectuable in exes: - shared_libs.update(dependency_walk(exectuable)) - - pack_bin_dir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin') - for lib in shared_libs: - must_copy(lib, pack_bin_dir) - - ssleay32 = find_in_path('ssleay32.dll') - must_copy(ssleay32, pack_bin_dir) - -def copy_dll_exe(): - prefix = Seafile().prefix - destdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin') - - filelist = [ - os.path.join(prefix, 'bin', 'libsearpc-1.dll'), - os.path.join(prefix, 'bin', 'libccnet-0.dll'), - os.path.join(prefix, 'bin', 'libseafile-0.dll'), - os.path.join(prefix, 'bin', 'ccnet.exe'), - os.path.join(prefix, 'bin', 'seaf-daemon.exe'), - os.path.join(SeafileClient().projdir, 'seafile-applet.exe'), - ] - - for name in filelist: - must_copy(name, destdir) - - extdlls = [ - os.path.join(SeafileClient().projdir, 'extensions', 'lib', 'seafile_shell_ext.dll'), - os.path.join(SeafileClient().projdir, 'extensions', 'lib', 'seafile_shell_ext64.dll'), - ] - - customdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'custom') - for dll in extdlls: - must_copy(dll, customdir) - - copy_shared_libs([ f for f in filelist if f.endswith('.exe') ]) - copy_qt_plugins_imageformats() - copy_qt_plugins_platforms() - copy_qt_translations() - -def copy_qt_plugins_imageformats(): - destdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin', 'imageformats') - must_mkdir(destdir) - - qt_plugins_srcdir = os.path.join(conf[CONF_QT_ROOT], 'plugins', 'imageformats') - - src = os.path.join(qt_plugins_srcdir, 'qico4.dll') - if conf[CONF_QT5]: - src = os.path.join(qt_plugins_srcdir, 'qico.dll') - must_copy(src, destdir) - - src = os.path.join(qt_plugins_srcdir, 'qgif4.dll') - if conf[CONF_QT5]: - src = os.path.join(qt_plugins_srcdir, 'qgif.dll') - must_copy(src, destdir) - -def copy_qt_plugins_platforms(): - if not conf[CONF_QT5]: - return - - destdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin', 'platforms') - must_mkdir(destdir) - - qt_plugins_srcdir = os.path.join(conf[CONF_QT_ROOT], 'plugins', 'platforms') - - src = os.path.join(qt_plugins_srcdir, 'qwindows.dll') - must_copy(src, destdir) - - src = os.path.join(qt_plugins_srcdir, 'qminimal.dll') - must_copy(src, destdir) - -def copy_qt_translations(): - destdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin') - - qt_translation_dir = os.path.join(conf[CONF_QT_ROOT], 'translations') - - i18n_dir = os.path.join(SeafileClient().projdir, 'i18n') - qm_pattern = os.path.join(i18n_dir, 'seafile_*.qm') - - qt_qms = set() - def add_lang(lang): - if not lang: - return - qt_qm = os.path.join(qt_translation_dir, 'qt_%s.qm' % lang) - if os.path.exists(qt_qm): - qt_qms.add(qt_qm) - elif '_' in lang: - add_lang(lang[:lang.index('_')]) - - for fn in glob.glob(qm_pattern): - name = os.path.basename(fn) - m = re.match(r'seafile_(.*)\.qm', name) - lang = m.group(1) - add_lang(lang) - - for src in qt_qms: - must_copy(src, destdir) - -def prepare_msi(): - pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') - - msi_dir = os.path.join(Seafile().projdir, 'msi') - - must_copytree(msi_dir, pack_dir) - must_mkdir(os.path.join(pack_dir, 'bin')) - - if run('make', cwd=os.path.join(pack_dir, 'custom')) != 0: - error('Error when compiling seafile msi custom dlls') - - copy_dll_exe() - -def strip_symbols(): - bin_dir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin') - def do_strip(fn, stripcmd='strip'): - run('%s "%s"' % (stripcmd, fn)) - info('stripping: %s' % fn) - - for dll in glob.glob(os.path.join(bin_dir, '*.dll')): - name = os.path.basename(dll).lower() - if 'qt' in name: - do_strip(dll) - if name == 'seafile_shell_ext.dll': - do_strip(dll) - elif name == 'seafile_shell_ext64.dll': - do_strip(dll, stripcmd='x86_64-w64-mingw32-strip') - -def edit_fragment_wxs(): - '''In the main wxs file(seafile.wxs) we need to reference to the id of - seafile-applet.exe, which is listed in fragment.wxs. Since fragments.wxs is - auto generated, the id is sequentially generated, so we need to change the - id of seafile-applet.exe manually. - - ''' - file_path = os.path.join(conf[CONF_BUILDDIR], 'pack', 'fragment.wxs') - new_lines = [] - with open(file_path, 'r') as fp: - for line in fp: - if 'seafile-applet.exe' in line: - # change the id of 'seafile-applet.exe' to 'seafileapplet.exe' - new_line = re.sub('file_bin_[\d]+', 'seafileapplet.exe', line) - new_lines.append(new_line) - else: - new_lines.append(line) - - content = '\r\n'.join(new_lines) - with open(file_path, 'w') as fp: - fp.write(content) - -def breakpad_enabled(): - return conf[CONF_VERSION] >= '5.0.3' - -def generate_breakpad_symbols(): - seafiledir = Seafile().projdir - script = os.path.join(seafiledir, 'scripts/breakpad.py') - symbol_file = 'seaf-daemon.exe.sym-%s' % conf[CONF_VERSION] - output = os.path.join(seafiledir, symbol_file) - - # generate the breakpad symbols - if run('python %s --output %s' % (script, output)) != 0: - error('Error when generating breakpad symbols') - - # move symbols to output directory - dst_symbol_file = os.path.join(conf[CONF_OUTPUTDIR], symbol_file) - must_copy(output, dst_symbol_file) - -def build_msi(): - prepare_msi() - if breakpad_enabled(): - generate_breakpad_symbols() - strip_symbols() - pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') - if run('make fragment.wxs', cwd=pack_dir) != 0: - error('Error when make fragement.wxs') - - edit_fragment_wxs() - - if run('make', cwd=pack_dir) != 0: - error('Error when make seafile.msi') - -def build_english_msi(): - '''The extra work to build the English msi.''' - pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') - - if run('make en', cwd=pack_dir) != 0: - error('Error when make seafile-en.msi') - -def build_german_msi(): - '''The extra work to build the German msi.''' - pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') - - if run('make de', cwd=pack_dir) != 0: - error('Error when make seafile-de.msi') - -def move_msi(): - pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') - src_msi = os.path.join(pack_dir, 'seafile.msi') - brand = conf[CONF_BRAND] - if not conf[CONF_WITH_SHIB]: - dst_msi = os.path.join(conf[CONF_OUTPUTDIR], '%s-%s.msi' % (brand, conf[CONF_VERSION])) - else: - dst_msi = os.path.join(conf[CONF_OUTPUTDIR], '%s-%s-shibboleth.msi' % (brand, conf[CONF_VERSION])) - - # move msi to outputdir - must_copy(src_msi, dst_msi) - - if not conf[CONF_ONLY_CHINESE]: - src_msi_en = os.path.join(pack_dir, 'seafile-en.msi') - if not conf[CONF_WITH_SHIB]: - dst_msi_en = os.path.join(conf[CONF_OUTPUTDIR], '%s-%s-en.msi' % (brand, conf[CONF_VERSION])) - else: - dst_msi_en = os.path.join(conf[CONF_OUTPUTDIR], '%s-%s-en-shibboleth.msi' % (brand, conf[CONF_VERSION])) - must_copy(src_msi_en, dst_msi_en) - src_msi_de = os.path.join(pack_dir, 'seafile-de.msi') - if not conf[CONF_WITH_SHIB]: - dst_msi_de = os.path.join(conf[CONF_OUTPUTDIR], '%s-%s-de.msi' % (brand, conf[CONF_VERSION])) - else: - dst_msi_de = os.path.join(conf[CONF_OUTPUTDIR], '%s-%s-de-shibboleth.msi' % (brand, conf[CONF_VERSION])) - must_copy(src_msi_de, dst_msi_de) - - print '---------------------------------------------' - print 'The build is successfully. Output is:' - print '>>\t%s' % dst_msi - if not conf[CONF_ONLY_CHINESE]: - print '>>\t%s' % dst_msi_en - print '>>\t%s' % dst_msi_de - print '---------------------------------------------' - -def check_tools(): - tools = [ - 'Paraffin', - 'candle', - 'light', - 'depends', - ] - - for prog in tools: - if not find_in_path(prog + '.exe'): - error('%s not found' % prog) - -def dump_env(): - print 'Dumping environment variables:' - for k, v in os.environ.iteritems(): - print '%s: %s' % (k, v) - -def main(): - dump_env() - parse_args() - setup_build_env() - check_tools() - - libsearpc = Libsearpc() - ccnet = Ccnet() - seafile = Seafile() - seafile_client = SeafileClient() - - libsearpc.uncompress() - libsearpc.build() - - ccnet.uncompress() - ccnet.build() - - seafile.uncompress() - seafile.build() - - seafile_client.uncompress() - seafile_client.build() - - build_msi() - if not conf[CONF_ONLY_CHINESE]: - build_english_msi() - build_german_msi() - - move_msi() - -if __name__ == '__main__': - main() diff --git a/scripts/build/build-server-src.py b/scripts/build/build-server-src.py deleted file mode 100755 index acefa80..0000000 --- a/scripts/build/build-server-src.py +++ /dev/null @@ -1,396 +0,0 @@ -#!/usr/bin/env python -# coding: UTF-8 - -'''This scirpt builds the seafile debian source tarball. In this tarball, -libsearpc and ccnet is also included. - -''' -import sys - -#################### -### Requires Python 2.6+ -#################### -if sys.version_info[0] == 3: - print 'Python 3 not supported yet. Quit now.' - sys.exit(1) -if sys.version_info[1] < 6: - print 'Python 2.6 or above is required. Quit now.' - sys.exit(1) - -import os -import tempfile -import glob -import shutil -import re -import subprocess -import optparse -import atexit - -#################### -### Global variables -#################### - -# command line configuartion -conf = {} - -# key names in the conf dictionary. -CONF_VERSION = 'version' -CONF_LIBSEARPC_VERSION = 'libsearpc_version' -CONF_CCNET_VERSION = 'ccnet_version' -CONF_SEAFILE_VERSION = 'seafile_version' -CONF_SRCDIR = 'srcdir' -CONF_KEEP = 'keep' -CONF_BUILDDIR = 'builddir' -CONF_OUTPUTDIR = 'outputdir' - -#################### -### Common helper functions -#################### -def highlight(content, is_error=False): - '''Add ANSI color to content to get it highlighted on terminal''' - if is_error: - return '\x1b[1;31m%s\x1b[m' % content - else: - return '\x1b[1;32m%s\x1b[m' % content - -def info(msg): - print highlight('[INFO] ') + msg - -def exist_in_path(prog): - '''Test whether prog exists in system path''' - dirs = os.environ['PATH'].split(':') - for d in dirs: - if d == '': - continue - path = os.path.join(d, prog) - if os.path.exists(path): - return True - - return False - -def error(msg=None, usage=None): - if msg: - print highlight('[ERROR] ') + msg - if usage: - print usage - sys.exit(1) - -def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Run a program and wait it to finish, and return its exit code. The - standard output of this program is supressed. - - ''' - - info('running %s, cwd=%s' % (' '.join(argv), cwd if cwd else os.getcwd())) - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(argv, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env) - return proc.wait() - -def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Like run_argv but specify a command line string instead of argv''' - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(cmdline, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env, - shell=True) - return proc.wait() - -def must_mkdir(path): - '''Create a directory, exit on failure''' - try: - os.mkdir(path) - except OSError, e: - error('failed to create directory %s:%s' % (path, e)) - -def must_copy(src, dst): - '''Copy src to dst, exit on failure''' - try: - shutil.copy(src, dst) - except Exception, e: - error('failed to copy %s to %s: %s' % (src, dst, e)) - -def check_targz_src(proj, version, srcdir): - src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) - if not os.path.exists(src_tarball): - error('%s not exists' % src_tarball) - -def remove_unused_files(): - srcdir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION]) - web_sh_files = glob.glob(os.path.join(srcdir, 'web', '*.sh')) - files = [ - os.path.join(srcdir, 'web', 'pygettext.py'), - ] - files.extend(web_sh_files) - - for f in files: - run('rm -f %s' % f) - -def gen_tarball(): - output = os.path.join(conf[CONF_OUTPUTDIR], 'seafile-server-latest.tar.gz') - dirname = 'seafile-%s' % conf[CONF_VERSION] - - ignored_patterns = [ - # windows msvc dlls - os.path.join(dirname, 'msi', 'bin*'), - ] - - excludes_list = [ '--exclude=%s' % pattern for pattern in ignored_patterns ] - argv = [ - 'tar', - 'czvf', - output, - dirname, - ] - - argv.append(*excludes_list) - - if run_argv(argv) != 0: - error('failed to gen %s' % output) - - print '---------------------------------------------' - print 'The build is successfully. Output is:\t%s' % output - print '---------------------------------------------' - -def uncompress_seafile(): - src = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_SEAFILE_VERSION]) - dst = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION]) - - if os.path.exists(src): - error('dir %s already exists' % src) - if os.path.exists(dst): - error('dir %s already exists' % dst) - - tarball = os.path.join(conf[CONF_SRCDIR], 'seafile-%s.tar.gz' % conf[CONF_SEAFILE_VERSION]) - argv = [ 'tar', 'xf', - tarball, - '-C', conf[CONF_BUILDDIR], - ] - - if run_argv(argv) != 0: - error('failed to uncompress seafile') - - if conf[CONF_VERSION] != conf[CONF_SEAFILE_VERSION]: - shutil.move(src, dst) - -def uncompress_libsearpc(): - tarball = os.path.join(conf[CONF_SRCDIR], 'libsearpc-%s.tar.gz' % conf[CONF_LIBSEARPC_VERSION]) - dst_dir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'libsearpc') - must_mkdir(dst_dir) - argv = [ 'tar', 'xf', - tarball, - '--strip-components=1', - '-C', dst_dir, - ] - - if run_argv(argv) != 0: - error('failed to uncompress libsearpc') - -def uncompress_ccnet(): - tarball = os.path.join(conf[CONF_SRCDIR], 'ccnet-%s.tar.gz' % conf[CONF_CCNET_VERSION]) - dst_dir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'ccnet') - must_mkdir(dst_dir) - argv = [ 'tar', 'xf', - tarball, - '--strip-components=1', - '-C', dst_dir, - ] - - if run_argv(argv) != 0: - error('failed to uncompress ccnet') - - -def remove_debian_subdir(): - debian_subdir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'debian') - argv = [ 'rm', '-rf', debian_subdir ] - if run_argv(argv) != 0: - error('failed to uncompress ccnet') - - -def parse_args(): - parser = optparse.OptionParser() - def long_opt(opt): - return '--' + opt - - parser.add_option(long_opt(CONF_VERSION), - dest=CONF_VERSION, - nargs=1, - help='the version of seafile source. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_SEAFILE_VERSION), - dest=CONF_SEAFILE_VERSION, - nargs=1, - help='the version of seafile. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), - dest=CONF_LIBSEARPC_VERSION, - nargs=1, - help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_CCNET_VERSION), - dest=CONF_CCNET_VERSION, - nargs=1, - help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - - parser.add_option(long_opt(CONF_BUILDDIR), - dest=CONF_BUILDDIR, - nargs=1, - help='the directory to build the source. Defaults to /tmp', - default=tempfile.gettempdir()) - - parser.add_option(long_opt(CONF_OUTPUTDIR), - dest=CONF_OUTPUTDIR, - nargs=1, - help='the output directory to put the generated server tarball. Defaults to the current directory.', - default=os.getcwd()) - - parser.add_option(long_opt(CONF_SRCDIR), - dest=CONF_SRCDIR, - nargs=1, - help='''Source tarballs must be placed in this directory.''') - - parser.add_option(long_opt(CONF_KEEP), - dest=CONF_KEEP, - action='store_true', - help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') - - usage = parser.format_help() - options, remain = parser.parse_args() - if remain: - error(usage=usage) - - validate_args(usage, options) - -def validate_args(usage, options): - required_args = [ - CONF_VERSION, - CONF_SEAFILE_VERSION, - CONF_LIBSEARPC_VERSION, - CONF_CCNET_VERSION, - CONF_SRCDIR, - ] - - # fist check required args - for optname in required_args: - if getattr(options, optname, None) == None: - error('%s must be specified' % optname, usage=usage) - - def get_option(optname): - return getattr(options, optname) - - # [ version ] - def check_project_version(version): - '''A valid version must be like 1.2.2, 1.3''' - if not re.match('^[0-9](\.[0-9])+$', version): - error('%s is not a valid version' % version, usage=usage) - - version = get_option(CONF_VERSION) - libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) - ccnet_version = get_option(CONF_CCNET_VERSION) - seafile_version = get_option(CONF_SEAFILE_VERSION) - - check_project_version(version) - check_project_version(libsearpc_version) - check_project_version(ccnet_version) - check_project_version(seafile_version) - - # [ srcdir ] - srcdir = get_option(CONF_SRCDIR) - check_targz_src('libsearpc', libsearpc_version, srcdir) - check_targz_src('ccnet', ccnet_version, srcdir) - check_targz_src('seafile', seafile_version, srcdir) - - # [ builddir ] - builddir = get_option(CONF_BUILDDIR) - if not os.path.exists(builddir): - error('%s does not exist' % builddir, usage=usage) - - builddir = os.path.join(builddir, 'seafile-deb-src') - - # [ outputdir ] - outputdir = get_option(CONF_OUTPUTDIR) - if not os.path.exists(outputdir): - error('outputdir %s does not exist' % outputdir, usage=usage) - - # [ keep ] - keep = get_option(CONF_KEEP) - - conf[CONF_VERSION] = version - conf[CONF_LIBSEARPC_VERSION] = libsearpc_version - conf[CONF_CCNET_VERSION] = ccnet_version - conf[CONF_SEAFILE_VERSION] = seafile_version - - conf[CONF_BUILDDIR] = builddir - conf[CONF_SRCDIR] = srcdir - conf[CONF_OUTPUTDIR] = outputdir - conf[CONF_KEEP] = keep - - prepare_builddir(builddir) - show_build_info() - -def prepare_builddir(builddir): - must_mkdir(builddir) - - if not conf[CONF_KEEP]: - def remove_builddir(): - '''Remove the builddir when exit''' - info('remove builddir before exit') - shutil.rmtree(builddir, ignore_errors=True) - atexit.register(remove_builddir) - - os.chdir(builddir) - -def show_build_info(): - '''Print all conf information. Confirm before continue.''' - info('------------------------------------------') - info('Seafile debian source tarball %s:' % conf[CONF_VERSION]) - info('------------------------------------------') - info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) - info('ccnet: %s' % conf[CONF_CCNET_VERSION]) - info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) - info('builddir: %s' % conf[CONF_BUILDDIR]) - info('outputdir: %s' % conf[CONF_OUTPUTDIR]) - info('source dir: %s' % conf[CONF_SRCDIR]) - info('clean on exit: %s' % (not conf[CONF_KEEP])) - info('------------------------------------------') - info('press any key to continue ') - info('------------------------------------------') - dummy = raw_input() - -def main(): - parse_args() - uncompress_seafile() - uncompress_libsearpc() - uncompress_ccnet() - remove_debian_subdir() - remove_unused_files() - gen_tarball() - -if __name__ == '__main__': - main() diff --git a/scripts/build/build-server.py b/scripts/build/build-server.py index 9fd7208..308c177 100755 --- a/scripts/build/build-server.py +++ b/scripts/build/build-server.py @@ -14,22 +14,27 @@ a directory before running this script. That directory is passed in as the '--thirdpartdir' arguments. ''' +from __future__ import print_function +from future import standard_library +standard_library.install_aliases() +from builtins import input +from builtins import object import sys #################### ### Requires Python 2.6+ #################### if sys.version_info[0] == 3: - print 'Python 3 not supported yet. Quit now.' + print('Python 3 not supported yet. Quit now.') sys.exit(1) if sys.version_info[1] < 6: - print 'Python 2.6 or above is required. Quit now.' + print('Python 2.6 or above is required. Quit now.') sys.exit(1) import os import glob -import commands +import subprocess import tempfile import shutil import re @@ -72,7 +77,7 @@ def highlight(content, is_error=False): return '\x1b[1;32m%s\x1b[m' % content def info(msg): - print highlight('[INFO] ') + msg + print(highlight('[INFO] ') + msg) def find_in_path(prog): '''Find a file in system path''' @@ -88,9 +93,9 @@ def find_in_path(prog): def error(msg=None, usage=None): if msg: - print highlight('[ERROR] ') + msg + print(highlight('[ERROR] ') + msg) if usage: - print usage + print(usage) sys.exit(1) def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): @@ -141,14 +146,14 @@ def must_mkdir(path): '''Create a directory, exit on failure''' try: os.mkdir(path) - except OSError, e: + except OSError as e: error('failed to create directory %s:%s' % (path, e)) def must_copy(src, dst): '''Copy src to dst, exit on failure''' try: shutil.copy(src, dst) - except Exception, e: + except Exception as e: error('failed to copy %s to %s: %s' % (src, dst, e)) class Project(object): @@ -423,7 +428,7 @@ def show_build_info(): info('------------------------------------------') info('press any key to continue ') info('------------------------------------------') - raw_input() + input() def prepare_builddir(builddir): must_mkdir(builddir) @@ -625,7 +630,7 @@ def copy_scripts_and_libs(): dst_update_scriptsdir = os.path.join(serverdir, 'upgrade') try: shutil.copytree(update_scriptsdir, dst_update_scriptsdir) - except Exception, e: + except Exception as e: error('failed to copy upgrade scripts: %s' % e) # copy sql scripts @@ -633,7 +638,7 @@ def copy_scripts_and_libs(): dst_sql_scriptsdir = os.path.join(serverdir, 'sql') try: shutil.copytree(sql_scriptsdir, dst_sql_scriptsdir) - except Exception, e: + except Exception as e: error('failed to copy sql scripts: %s' % e) # copy runtime/seahub.conf @@ -647,7 +652,7 @@ def copy_scripts_and_libs(): dst_seahubdir = os.path.join(serverdir, 'seahub') try: shutil.move(src_seahubdir, dst_seahubdir) - except Exception, e: + except Exception as e: error('failed to move seahub to seafile-server/seahub: %s' % e) # copy seahub thirdpart libs @@ -695,7 +700,7 @@ def get_dependent_libs(executable): return True return False - ldd_output = commands.getoutput('ldd %s' % executable) + ldd_output = subprocess.getoutput('ldd %s' % executable) ret = set() for line in ldd_output.splitlines(): tokens = line.split() @@ -763,7 +768,7 @@ def copy_seahub_thirdpart_libs(seahub_thirdpart): shutil.copytree(src_path, target_path) else: shutil.copy(src_path, target_path) - except Exception, e: + except Exception as e: error('failed to copy seahub thirdpart libs: %s' % e) def strip_symbols(): @@ -790,7 +795,7 @@ def strip_symbols(): if os.path.islink(fn): continue - finfo = commands.getoutput('file "%s"' % fn) + finfo = subprocess.getoutput('file "%s"' % fn) if 'not stripped' in finfo: do_strip(fn) @@ -805,7 +810,7 @@ def create_tarball(tarball_name): # move seafile-server to seafile-server-${version} try: shutil.move(serverdir, versioned_serverdir) - except Exception, e: + except Exception as e: error('failed to move %s to %s: %s' % (serverdir, versioned_serverdir, e)) ignored_patterns = [ @@ -848,7 +853,7 @@ def gen_tarball(): if not conf[CONF_NO_STRIP]: try: strip_symbols() - except Exception, e: + except Exception as e: error('failed to strip symbols: %s' % e) # determine the output name @@ -872,18 +877,18 @@ def gen_tarball(): # generate the tarball try: create_tarball(tarball_name) - except Exception, e: + except Exception as e: error('failed to generate tarball: %s' % e) # move tarball to outputdir try: shutil.copy(tarball_name, dst_tarball) - except Exception, e: + except Exception as e: error('failed to copy %s to %s: %s' % (tarball_name, dst_tarball, e)) - print '---------------------------------------------' - print 'The build is successful. Output is:\t%s' % dst_tarball - print '---------------------------------------------' + print('---------------------------------------------') + print('The build is successful. Output is:\t%s' % dst_tarball) + print('---------------------------------------------') def main(): parse_args() diff --git a/scripts/build/gen-deb-src.py b/scripts/build/gen-deb-src.py deleted file mode 100755 index 2b8aa76..0000000 --- a/scripts/build/gen-deb-src.py +++ /dev/null @@ -1,420 +0,0 @@ -#!/usr/bin/env python -# coding: UTF-8 - -'''This scirpt builds the seafile debian source tarball. In this tarball, -libsearpc and ccnet is also included. - -''' -import sys - -#################### -### Requires Python 2.6+ -#################### -if sys.version_info[0] == 3: - print 'Python 3 not supported yet. Quit now.' - sys.exit(1) -if sys.version_info[1] < 6: - print 'Python 2.6 or above is required. Quit now.' - sys.exit(1) - -import os -import tempfile -import glob -import shutil -import re -import subprocess -import optparse -import atexit - -#################### -### Global variables -#################### - -# command line configuartion -conf = {} - -# key names in the conf dictionary. -CONF_VERSION = 'version' -CONF_LIBSEARPC_VERSION = 'libsearpc_version' -CONF_CCNET_VERSION = 'ccnet_version' -CONF_SEAFILE_VERSION = 'seafile_version' -CONF_SEAFILE_CLIENT_VERSION = 'seafile_client_version' -CONF_SRCDIR = 'srcdir' -CONF_KEEP = 'keep' -CONF_BUILDDIR = 'builddir' -CONF_OUTPUTDIR = 'outputdir' - -#################### -### Common helper functions -#################### -def highlight(content, is_error=False): - '''Add ANSI color to content to get it highlighted on terminal''' - if is_error: - return '\x1b[1;31m%s\x1b[m' % content - else: - return '\x1b[1;32m%s\x1b[m' % content - -def info(msg): - print highlight('[INFO] ') + msg - -def exist_in_path(prog): - '''Test whether prog exists in system path''' - dirs = os.environ['PATH'].split(':') - for d in dirs: - if d == '': - continue - path = os.path.join(d, prog) - if os.path.exists(path): - return True - - return False - -def error(msg=None, usage=None): - if msg: - print highlight('[ERROR] ') + msg - if usage: - print usage - sys.exit(1) - -def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Run a program and wait it to finish, and return its exit code. The - standard output of this program is supressed. - - ''' - - info('running %s, cwd=%s' % (' '.join(argv), cwd if cwd else os.getcwd())) - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(argv, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env) - return proc.wait() - -def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): - '''Like run_argv but specify a command line string instead of argv''' - with open(os.devnull, 'w') as devnull: - if suppress_stdout: - stdout = devnull - else: - stdout = sys.stdout - - if suppress_stderr: - stderr = devnull - else: - stderr = sys.stderr - - proc = subprocess.Popen(cmdline, - cwd=cwd, - stdout=stdout, - stderr=stderr, - env=env, - shell=True) - return proc.wait() - -def must_mkdir(path): - '''Create a directory, exit on failure''' - try: - os.mkdir(path) - except OSError, e: - error('failed to create directory %s:%s' % (path, e)) - -def must_copy(src, dst): - '''Copy src to dst, exit on failure''' - try: - shutil.copy(src, dst) - except Exception, e: - error('failed to copy %s to %s: %s' % (src, dst, e)) - -def check_targz_src(proj, version, srcdir): - src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) - if not os.path.exists(src_tarball): - error('%s not exists' % src_tarball) - -def remove_unused_files(): - srcdir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION]) - web_sh_files = glob.glob(os.path.join(srcdir, 'web', '*.sh')) - files = [ - os.path.join(srcdir, 'web', 'pygettext.py'), - ] - files.extend(web_sh_files) - - for f in files: - run('rm -f %s' % f) - -def gen_tarball(): - output = os.path.join(conf[CONF_OUTPUTDIR], 'seafile-client-latest.tar.gz') - dirname = 'seafile-%s' % conf[CONF_VERSION] - - ignored_patterns = [ - # windows msvc dlls - os.path.join(dirname, 'msi', 'bin*'), - ] - - excludes_list = [ '--exclude=%s' % pattern for pattern in ignored_patterns ] - argv = [ - 'tar', - 'czvf', - output, - dirname, - ] - - argv.append(*excludes_list) - - if run_argv(argv) != 0: - error('failed to gen %s' % output) - - print '---------------------------------------------' - print 'The build is successfully. Output is:\t%s' % output - print '---------------------------------------------' - -def uncompress_seafile(): - src = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_SEAFILE_VERSION]) - dst = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION]) - - if os.path.exists(src): - error('dir %s already exists' % src) - if os.path.exists(dst): - error('dir %s already exists' % dst) - - tarball = os.path.join(conf[CONF_SRCDIR], 'seafile-%s.tar.gz' % conf[CONF_SEAFILE_VERSION]) - argv = [ 'tar', 'xf', - tarball, - '-C', conf[CONF_BUILDDIR], - ] - - if run_argv(argv) != 0: - error('failed to uncompress seafile') - - if conf[CONF_VERSION] != conf[CONF_SEAFILE_VERSION]: - shutil.move(src, dst) - -def uncompress_libsearpc(): - tarball = os.path.join(conf[CONF_SRCDIR], 'libsearpc-%s.tar.gz' % conf[CONF_LIBSEARPC_VERSION]) - dst_dir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'libsearpc') - must_mkdir(dst_dir) - argv = [ 'tar', 'xf', - tarball, - '--strip-components=1', - '-C', dst_dir, - ] - - if run_argv(argv) != 0: - error('failed to uncompress libsearpc') - -def uncompress_ccnet(): - tarball = os.path.join(conf[CONF_SRCDIR], 'ccnet-%s.tar.gz' % conf[CONF_CCNET_VERSION]) - dst_dir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'ccnet') - must_mkdir(dst_dir) - argv = [ 'tar', 'xf', - tarball, - '--strip-components=1', - '-C', dst_dir, - ] - - if run_argv(argv) != 0: - error('failed to uncompress ccnet') - -def uncompress_seafile_client(): - tarball = os.path.join(conf[CONF_SRCDIR], 'seafile-client-%s.tar.gz' % conf[CONF_SEAFILE_CLIENT_VERSION]) - dst_dir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'seafile-client') - must_mkdir(dst_dir) - argv = [ 'tar', 'xf', - tarball, - '--strip-components=1', - '-C', dst_dir, - ] - - if run_argv(argv) != 0: - error('failed to uncompress ccnet') - -def remove_debian_subdir(): - debian_subdir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'debian') - argv = [ 'rm', '-rf', debian_subdir ] - if run_argv(argv) != 0: - error('failed to uncompress ccnet') - - -def parse_args(): - parser = optparse.OptionParser() - def long_opt(opt): - return '--' + opt - - parser.add_option(long_opt(CONF_VERSION), - dest=CONF_VERSION, - nargs=1, - help='the version of seafile source. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_SEAFILE_VERSION), - dest=CONF_SEAFILE_VERSION, - nargs=1, - help='the version of seafile. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), - dest=CONF_LIBSEARPC_VERSION, - nargs=1, - help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_CCNET_VERSION), - dest=CONF_CCNET_VERSION, - nargs=1, - help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_SEAFILE_CLIENT_VERSION), - dest=CONF_SEAFILE_CLIENT_VERSION, - nargs=1, - help='the version of seafile-client. Must be digits delimited by dots, like 1.3.0') - - parser.add_option(long_opt(CONF_BUILDDIR), - dest=CONF_BUILDDIR, - nargs=1, - help='the directory to build the source. Defaults to /tmp', - default=tempfile.gettempdir()) - - parser.add_option(long_opt(CONF_OUTPUTDIR), - dest=CONF_OUTPUTDIR, - nargs=1, - help='the output directory to put the generated server tarball. Defaults to the current directory.', - default=os.getcwd()) - - parser.add_option(long_opt(CONF_SRCDIR), - dest=CONF_SRCDIR, - nargs=1, - help='''Source tarballs must be placed in this directory.''') - - parser.add_option(long_opt(CONF_KEEP), - dest=CONF_KEEP, - action='store_true', - help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') - - usage = parser.format_help() - options, remain = parser.parse_args() - if remain: - error(usage=usage) - - validate_args(usage, options) - -def validate_args(usage, options): - required_args = [ - CONF_VERSION, - CONF_SEAFILE_VERSION, - CONF_LIBSEARPC_VERSION, - CONF_CCNET_VERSION, - CONF_SEAFILE_CLIENT_VERSION, - CONF_SRCDIR, - ] - - # fist check required args - for optname in required_args: - if getattr(options, optname, None) == None: - error('%s must be specified' % optname, usage=usage) - - def get_option(optname): - return getattr(options, optname) - - # [ version ] - def check_project_version(version): - '''A valid version must be like 1.2.2, 1.3''' - if not re.match('^[0-9](\.[0-9])+$', version): - error('%s is not a valid version' % version, usage=usage) - - version = get_option(CONF_VERSION) - libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) - ccnet_version = get_option(CONF_CCNET_VERSION) - seafile_version = get_option(CONF_SEAFILE_VERSION) - seafile_client_version = get_option(CONF_SEAFILE_CLIENT_VERSION) - - check_project_version(version) - check_project_version(libsearpc_version) - check_project_version(ccnet_version) - check_project_version(seafile_version) - check_project_version(seafile_client_version) - - # [ srcdir ] - srcdir = get_option(CONF_SRCDIR) - check_targz_src('libsearpc', libsearpc_version, srcdir) - check_targz_src('ccnet', ccnet_version, srcdir) - check_targz_src('seafile', seafile_version, srcdir) - check_targz_src('seafile-client', seafile_client_version, srcdir) - - # [ builddir ] - builddir = get_option(CONF_BUILDDIR) - if not os.path.exists(builddir): - error('%s does not exist' % builddir, usage=usage) - - builddir = os.path.join(builddir, 'seafile-deb-src') - - # [ outputdir ] - outputdir = get_option(CONF_OUTPUTDIR) - if not os.path.exists(outputdir): - error('outputdir %s does not exist' % outputdir, usage=usage) - - # [ keep ] - keep = get_option(CONF_KEEP) - - conf[CONF_VERSION] = version - conf[CONF_LIBSEARPC_VERSION] = libsearpc_version - conf[CONF_CCNET_VERSION] = ccnet_version - conf[CONF_SEAFILE_VERSION] = seafile_version - conf[CONF_SEAFILE_CLIENT_VERSION] = seafile_client_version - - conf[CONF_BUILDDIR] = builddir - conf[CONF_SRCDIR] = srcdir - conf[CONF_OUTPUTDIR] = outputdir - conf[CONF_KEEP] = keep - - prepare_builddir(builddir) - show_build_info() - -def prepare_builddir(builddir): - must_mkdir(builddir) - - if not conf[CONF_KEEP]: - def remove_builddir(): - '''Remove the builddir when exit''' - info('remove builddir before exit') - shutil.rmtree(builddir, ignore_errors=True) - atexit.register(remove_builddir) - - os.chdir(builddir) - -def show_build_info(): - '''Print all conf information. Confirm before continue.''' - info('------------------------------------------') - info('Seafile debian source tarball %s:' % conf[CONF_VERSION]) - info('------------------------------------------') - info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) - info('seafile-client: %s' % conf[CONF_SEAFILE_CLIENT_VERSION]) - info('ccnet: %s' % conf[CONF_CCNET_VERSION]) - info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) - info('builddir: %s' % conf[CONF_BUILDDIR]) - info('outputdir: %s' % conf[CONF_OUTPUTDIR]) - info('source dir: %s' % conf[CONF_SRCDIR]) - info('clean on exit: %s' % (not conf[CONF_KEEP])) - info('------------------------------------------') - info('press any key to continue ') - info('------------------------------------------') - dummy = raw_input() - -def main(): - parse_args() - uncompress_seafile() - uncompress_libsearpc() - uncompress_ccnet() - uncompress_seafile_client() - remove_debian_subdir() - remove_unused_files() - gen_tarball() - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/scripts/check_init_admin.py b/scripts/check_init_admin.py index 2f5eed6..a3e8cce 100644 --- a/scripts/check_init_admin.py +++ b/scripts/check_init_admin.py @@ -1,7 +1,12 @@ #coding: UTF-8 '''This script would check if there is admin, and prompt the user to create a new one if non exist''' +from __future__ import print_function +from future import standard_library +standard_library.install_aliases() +from builtins import input +from builtins import object import json import sys import os @@ -15,7 +20,7 @@ import getpass import uuid import warnings -from ConfigParser import ConfigParser +from configparser import ConfigParser try: import readline # pylint: disable=W0611 @@ -39,8 +44,8 @@ Make sure you have read seafile server manual at Press ENTER to continue -----------------------------------------------------------------''' % SERVER_MANUAL_HTTP - print welcome_msg - raw_input() + print(welcome_msg) + input() @staticmethod def highlight(content): @@ -49,13 +54,13 @@ Press ENTER to continue @staticmethod def info(msg): - print msg + print(msg) @staticmethod def error(msg): '''Print error and exit''' - print - print 'Error: ' + msg + print() + print('Error: ' + msg) sys.exit(1) @staticmethod @@ -126,7 +131,7 @@ Press ENTER to continue '''Create a directory, exit on failure''' try: os.mkdir(path) - except OSError, e: + except OSError as e: Utils.error('failed to create directory %s:%s' % (path, e)) @staticmethod @@ -134,7 +139,7 @@ Press ENTER to continue '''Copy src to dst, exit on failure''' try: shutil.copy(src, dst) - except Exception, e: + except Exception as e: Utils.error('failed to copy %s to %s: %s' % (src, dst, e)) @staticmethod @@ -212,7 +217,7 @@ Press ENTER to continue ''' assert key or yes_or_no # Format description - print + print() if note: desc += '\n' + note @@ -231,7 +236,7 @@ Press ENTER to continue if password: answer = getpass.getpass(desc).strip() else: - answer = raw_input(desc).strip() + answer = input(desc).strip() # No user input: use default if not answer: @@ -243,7 +248,7 @@ Press ENTER to continue # Have user input: validate answer if yes_or_no: if answer not in ['yes', 'no']: - print Utils.highlight('\nPlease answer yes or no\n') + print(Utils.highlight('\nPlease answer yes or no\n')) continue else: return answer == 'yes' @@ -251,8 +256,8 @@ Press ENTER to continue if validate: try: return validate(answer) - except InvalidAnswer, e: - print Utils.highlight('\n%s\n' % e) + except InvalidAnswer as e: + print(Utils.highlight('\n%s\n' % e)) continue else: return answer @@ -302,17 +307,17 @@ def create_admin(email, passwd): if rpc.create_admin(email, passwd) < 0: raise Exception('failed to create admin') else: - print '\n\n' - print '----------------------------------------' - print 'Successfully created seafile admin' - print '----------------------------------------' - print '\n\n' + print('\n\n') + print('----------------------------------------') + print('Successfully created seafile admin') + print('----------------------------------------') + print('\n\n') def ask_admin_email(): - print - print '----------------------------------------' - print 'It\'s the first time you start the seafile server. Now let\'s create the admin account' - print '----------------------------------------' + print() + print('----------------------------------------') + print('It\'s the first time you start the seafile server. Now let\'s create the admin account') + print('----------------------------------------') def validate(email): # whitespace is not allowed if re.match(r'[\s]', email): @@ -372,11 +377,11 @@ if __name__ == '__main__': try: main() except KeyboardInterrupt: - print '\n\n\n' - print Utils.highlight('Aborted.') - print + print('\n\n\n') + print(Utils.highlight('Aborted.')) + print() sys.exit(1) - except Exception, e: - print - print Utils.highlight('Error happened during creating seafile admin.') - print + except Exception as e: + print() + print(Utils.highlight('Error happened during creating seafile admin.')) + print() diff --git a/scripts/docs-upgrade/db_update_helper.py b/scripts/docs-upgrade/db_update_helper.py index 5b6db7c..08be8df 100644 --- a/scripts/docs-upgrade/db_update_helper.py +++ b/scripts/docs-upgrade/db_update_helper.py @@ -1,8 +1,13 @@ # coding: UTF-8 +from __future__ import print_function +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import object import sys import os -import ConfigParser +import configparser import glob HAS_MYSQLDB = True @@ -41,15 +46,15 @@ class Utils(object): @staticmethod def info(msg): - print Utils.highlight('[INFO] ') + msg + print(Utils.highlight('[INFO] ') + msg) @staticmethod def warning(msg): - print Utils.highlight('[WARNING] ') + msg + print(Utils.highlight('[WARNING] ') + msg) @staticmethod def error(msg): - print Utils.highlight('[ERROR] ') + msg + print(Utils.highlight('[ERROR] ') + msg) sys.exit(1) @staticmethod @@ -57,7 +62,7 @@ class Utils(object): if not os.path.exists(config_path): Utils.error('Config path %s doesn\'t exist, stop db upgrade' % config_path) - cp = ConfigParser.ConfigParser(defaults) + cp = configparser.ConfigParser(defaults) cp.read(config_path) return cp @@ -159,7 +164,7 @@ class DBUpdater(object): password = config.get(db_section, 'PASSWD') db = config.get(db_section, 'DB') unix_socket = config.get(db_section, 'UNIX_SOCKET') - except ConfigParser.NoOptionError, e: + except configparser.NoOptionError as e: Utils.error('Database config in ccnet.conf is invalid: %s' % e) info = MySQLDBInfo(host, port, username, password, db, unix_socket) @@ -192,7 +197,7 @@ class DBUpdater(object): password = config.get(db_section, 'password') db = config.get(db_section, 'db_name') unix_socket = config.get(db_section, 'unix_socket') - except ConfigParser.NoOptionError, e: + except configparser.NoOptionError as e: Utils.error('Database config in seafile.conf is invalid: %s' % e) info = MySQLDBInfo(host, port, username, password, db, unix_socket) @@ -205,7 +210,7 @@ class DBUpdater(object): sys.path.insert(0, env_mgr.central_config_dir) try: import seahub_settings # pylint: disable=F0401 - except ImportError, e: + except ImportError as e: Utils.error('Failed to import seahub_settings.py: %s' % e) if not hasattr(seahub_settings, 'DATABASES'): @@ -331,7 +336,7 @@ class MySQLDBUpdater(DBUpdater): kw['port'] = info.port try: conn = MySQLdb.connect(**kw) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): msg = str(e.args[1]) else: @@ -345,7 +350,7 @@ class MySQLDBUpdater(DBUpdater): try: cursor.execute(sql) conn.commit() - except Exception, e: + except Exception as e: msg = str(e) Utils.warning('Failed to execute sql: %s' % msg) @@ -366,7 +371,7 @@ class MySQLDBUpdater(DBUpdater): def main(): skipdb = os.environ.get('SEAFILE_SKIP_DB_UPGRADE', '').lower() if skipdb in ('1', 'true', 'on'): - print 'Database upgrade skipped because SEAFILE_SKIP_DB_UPGRADE=%s' % skipdb + print('Database upgrade skipped because SEAFILE_SKIP_DB_UPGRADE=%s' % skipdb) sys.exit() version = sys.argv[1] db_updater = DBUpdater.get_instance(version) diff --git a/scripts/seafobj_migrate.py b/scripts/seafobj_migrate.py index 3c1f8df..2b2db58 100755 --- a/scripts/seafobj_migrate.py +++ b/scripts/seafobj_migrate.py @@ -1,11 +1,15 @@ #!/usr/bin/env python #coding: utf-8 +from future import standard_library +standard_library.install_aliases() +from builtins import range +from builtins import object import os import sys import logging from threading import Thread -import Queue +import queue import rados from seafobj.objstore_factory import SeafObjStoreFactory @@ -34,10 +38,10 @@ class ThreadPool(object): def __init__(self, do_work, nworker=20): self.do_work = do_work self.nworker = nworker - self.task_queue = Queue.Queue() + self.task_queue = queue.Queue() def start(self): - for i in xrange(self.nworker): + for i in range(self.nworker): Worker(self.do_work, self.task_queue).start() def put_task(self, task): @@ -46,7 +50,7 @@ class ThreadPool(object): def join(self): self.task_queue.join() # notify all thread to stop - for i in xrange(self.nworker): + for i in range(self.nworker): self.task_queue.put(None) class Task(object): diff --git a/scripts/setup-seafile-mysql.py b/scripts/setup-seafile-mysql.py index 035befd..08bd7f0 100644 --- a/scripts/setup-seafile-mysql.py +++ b/scripts/setup-seafile-mysql.py @@ -1,7 +1,13 @@ #coding: UTF-8 '''This script would guide the seafile admin to setup seafile with MySQL''' +from __future__ import print_function +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import input +from builtins import object import argparse import sys import os @@ -15,7 +21,7 @@ import getpass import uuid import warnings import socket -from ConfigParser import ConfigParser +from configparser import ConfigParser import MySQLdb @@ -42,8 +48,8 @@ Make sure you have read seafile server manual at Press ENTER to continue -----------------------------------------------------------------''' % SERVER_MANUAL_HTTP - print welcome_msg - raw_input() + print(welcome_msg) + input() @staticmethod def highlight(content): @@ -52,13 +58,13 @@ Press ENTER to continue @staticmethod def info(msg): - print msg + print(msg) @staticmethod def error(msg): '''Print error and exit''' - print - print 'Error: ' + msg + print() + print('Error: ' + msg) sys.exit(1) @staticmethod @@ -135,7 +141,7 @@ Press ENTER to continue return try: os.mkdir(path) - except OSError, e: + except OSError as e: Utils.error('failed to create directory %s:%s' % (path, e)) @staticmethod @@ -143,7 +149,7 @@ Press ENTER to continue '''Copy src to dst, exit on failure''' try: shutil.copy(src, dst) - except Exception, e: + except Exception as e: Utils.error('failed to copy %s to %s: %s' % (src, dst, e)) @staticmethod @@ -221,7 +227,7 @@ Press ENTER to continue ''' assert key or yes_or_no # Format description - print + print() if note: desc += '\n' + note @@ -240,7 +246,7 @@ Press ENTER to continue if password: answer = getpass.getpass(desc).strip() else: - answer = raw_input(desc).strip() + answer = input(desc).strip() # No user input: use default if not answer: @@ -252,7 +258,7 @@ Press ENTER to continue # Have user input: validate answer if yes_or_no: if answer not in ['yes', 'no']: - print Utils.highlight('\nPlease answer yes or no\n') + print(Utils.highlight('\nPlease answer yes or no\n')) continue else: return answer == 'yes' @@ -260,8 +266,8 @@ Press ENTER to continue if validate: try: return validate(answer) - except InvalidAnswer, e: - print Utils.highlight('\n%s\n' % e) + except InvalidAnswer as e: + print(Utils.highlight('\n%s\n' % e)) continue else: return answer @@ -470,18 +476,18 @@ Please choose a way to initialize seafile databases: self.ask_mysql_port() def check_mysql_server(self, host, port): - print '\nverifying mysql server running ... ', + print('\nverifying mysql server running ... ', end=' ') try: dummy = MySQLdb.connect(host=host, port=port) except Exception: - print + print() raise InvalidAnswer('Failed to connect to mysql server at "%s:%s"' \ % (host, port)) - print 'done' + print('done') def check_mysql_user(self, user, password, host=None): - print '\nverifying password of user %s ... ' % user, + print('\nverifying password of user %s ... ' % user, end=' ') kwargs = dict(host=host or self.mysql_host, port=self.mysql_port, user=user, @@ -489,7 +495,7 @@ Please choose a way to initialize seafile databases: try: conn = MySQLdb.connect(**kwargs) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): raise InvalidAnswer('Failed to connect to mysql server using user "%s" and password "***": %s' \ % (user, e.args[1])) @@ -497,7 +503,7 @@ Please choose a way to initialize seafile databases: raise InvalidAnswer('Failed to connect to mysql server using user "%s" and password "***": %s' \ % (user, e)) - print 'done' + print('done') return conn def create_seahub_admin(self): @@ -507,7 +513,7 @@ Please choose a way to initialize seafile databases: user=self.seafile_mysql_user, passwd=self.seafile_mysql_password, db=self.ccnet_db_name) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to connect to mysql database %s: %s' % (self.ccnet_db_name, e.args[1])) else: @@ -519,7 +525,7 @@ CREATE TABLE IF NOT EXISTS EmailUser (id INTEGER NOT NULL PRIMARY KEY AUTO_INCRE try: cursor.execute(sql) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to create ccnet user table: %s' % e.args[1]) else: @@ -530,7 +536,7 @@ CREATE TABLE IF NOT EXISTS EmailUser (id INTEGER NOT NULL PRIMARY KEY AUTO_INCRE try: cursor.execute(sql) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to create admin user: %s' % e.args[1]) else: @@ -591,7 +597,7 @@ class NewDBConfigurator(AbstractDBConfigurator): try: cursor.execute(sql) return cursor.fetchall()[0][0] - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to check mysql user %s@%s: %s' % \ (user, self.seafile_mysql_userhost, e.args[1])) @@ -654,7 +660,7 @@ class NewDBConfigurator(AbstractDBConfigurator): try: cursor.execute(sql) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to create mysql user {}@{}: {}'.format(self.seafile_mysql_user, self.seafile_mysql_userhost, e.args[1])) else: @@ -670,7 +676,7 @@ class NewDBConfigurator(AbstractDBConfigurator): try: cursor.execute(sql) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to create database %s: %s' % (db_name, e.args[1])) else: @@ -688,7 +694,7 @@ class NewDBConfigurator(AbstractDBConfigurator): try: cursor.execute(sql) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to grant permission of database %s: %s' % (db_name, e.args[1])) else: @@ -759,7 +765,7 @@ class ExistingDBConfigurator(AbstractDBConfigurator): user = self.seafile_mysql_user password = self.seafile_mysql_password - print '\nverifying user "%s" access to database %s ... ' % (user, db_name), + print('\nverifying user "%s" access to database %s ... ' % (user, db_name), end=' ') try: conn = MySQLdb.connect(host=self.mysql_host, port=self.mysql_port, @@ -770,7 +776,7 @@ class ExistingDBConfigurator(AbstractDBConfigurator): cursor = conn.cursor() cursor.execute('show tables') cursor.close() - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): raise InvalidAnswer('Failed to access database %s using user "%s" and password "***": %s' \ % (db_name, user, e.args[1])) @@ -778,7 +784,7 @@ class ExistingDBConfigurator(AbstractDBConfigurator): raise InvalidAnswer('Failed to access database %s using user "%s" and password "***": %s' \ % (db_name, user, e)) - print 'done' + print('done') return conn @@ -804,7 +810,7 @@ class CcnetConfigurator(AbstractConfigurator): # self.ask_port() def generate(self): - print 'Generating ccnet configuration ...\n' + print('Generating ccnet configuration ...\n') ccnet_init = os.path.join(env_mgr.bin_dir, 'ccnet-init') argv = [ ccnet_init, @@ -882,9 +888,9 @@ class CcnetConfigurator(AbstractConfigurator): validate=validate) def do_syncdb(self): - print '----------------------------------------' - print 'Now creating ccnet database tables ...\n' - print '----------------------------------------' + print('----------------------------------------') + print('Now creating ccnet database tables ...\n') + print('----------------------------------------') try: conn = MySQLdb.connect(host=db_config.mysql_host, @@ -892,7 +898,7 @@ class CcnetConfigurator(AbstractConfigurator): user=db_config.seafile_mysql_user, passwd=db_config.seafile_mysql_password, db=db_config.ccnet_db_name) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to connect to mysql database %s: %s' % (db_config.ccnet_db_name, e.args[1])) else: @@ -908,7 +914,7 @@ class CcnetConfigurator(AbstractConfigurator): for sql in sqls: try: cursor.execute(sql) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to init ccnet database: %s' % e.args[1]) else: @@ -933,7 +939,7 @@ class SeafileConfigurator(AbstractConfigurator): self.ask_fileserver_port() def generate(self): - print 'Generating seafile configuration ...\n' + print('Generating seafile configuration ...\n') seafserv_init = os.path.join(env_mgr.bin_dir, 'seaf-server-init') argv = [ seafserv_init, @@ -948,7 +954,7 @@ class SeafileConfigurator(AbstractConfigurator): time.sleep(1) self.generate_db_conf() self.write_seafile_ini() - print 'done' + print('done') def generate_db_conf(self): config = Utils.read_config(self.seafile_conf) @@ -1019,9 +1025,9 @@ class SeafileConfigurator(AbstractConfigurator): fp.write(self.seafile_dir) def do_syncdb(self): - print '----------------------------------------' - print 'Now creating seafile database tables ...\n' - print '----------------------------------------' + print('----------------------------------------') + print('Now creating seafile database tables ...\n') + print('----------------------------------------') try: conn = MySQLdb.connect(host=db_config.mysql_host, @@ -1029,7 +1035,7 @@ class SeafileConfigurator(AbstractConfigurator): user=db_config.seafile_mysql_user, passwd=db_config.seafile_mysql_password, db=db_config.seafile_db_name) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to connect to mysql database %s: %s' % (db_config.seafile_db_name, e.args[1])) else: @@ -1045,7 +1051,7 @@ class SeafileConfigurator(AbstractConfigurator): for sql in sqls: try: cursor.execute(sql) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to init seafile database: %s' % e.args[1]) else: @@ -1068,7 +1074,7 @@ class SeahubConfigurator(AbstractConfigurator): def generate(self): '''Generating seahub_settings.py''' - print 'Generating seahub configuration ...\n' + print('Generating seahub configuration ...\n') time.sleep(1) with open(self.seahub_settings_py, 'w') as fp: self.write_utf8_comment(fp) @@ -1112,10 +1118,10 @@ class SeahubConfigurator(AbstractConfigurator): fp.write(text) def ask_admin_email(self): - print - print '----------------------------------------' - print 'Now let\'s create the admin account' - print '----------------------------------------' + print() + print('----------------------------------------') + print('Now let\'s create the admin account') + print('----------------------------------------') def validate(email): # whitespace is not allowed if re.match(r'[\s]', email): @@ -1153,9 +1159,9 @@ class SeahubConfigurator(AbstractConfigurator): validate=validate) def do_syncdb(self): - print '----------------------------------------' - print 'Now creating seahub database tables ...\n' - print '----------------------------------------' + print('----------------------------------------') + print('Now creating seahub database tables ...\n') + print('----------------------------------------') try: conn = MySQLdb.connect(host=db_config.mysql_host, @@ -1163,7 +1169,7 @@ class SeahubConfigurator(AbstractConfigurator): user=db_config.seafile_mysql_user, passwd=db_config.seafile_mysql_password, db=db_config.seahub_db_name) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to connect to mysql database %s: %s' % (db_config.seahub_db_name, e.args[1])) else: @@ -1179,7 +1185,7 @@ class SeahubConfigurator(AbstractConfigurator): for sql in sqls: try: cursor.execute(sql) - except Exception, e: + except Exception as e: if isinstance(e, MySQLdb.OperationalError): Utils.error('Failed to init seahub database: %s' % e.args[1]) else: @@ -1213,7 +1219,7 @@ class SeahubConfigurator(AbstractConfigurator): shutil.move(orig_avatar_dir, dest_avatar_dir) os.symlink('../../../seahub-data/avatars', orig_avatar_dir) - except Exception, e: + except Exception as e: Utils.error('Failed to prepare seahub avatars dir: %s' % e) class SeafDavConfigurator(AbstractConfigurator): @@ -1287,11 +1293,11 @@ class UserManualHandler(object): Utils.must_copy(doc, self.library_template_dir) def report_config(): - print - print '---------------------------------' - print 'This is your configuration' - print '---------------------------------' - print + print() + print('---------------------------------') + print('This is your configuration') + print('---------------------------------') + print() template = '''\ server name: %(server_name)s @@ -1324,31 +1330,31 @@ def report_config(): 'db_user': db_config.seafile_mysql_user } - print template % config + print(template % config) if need_pause: - print - print '---------------------------------' - print 'Press ENTER to continue, or Ctrl-C to abort' - print '---------------------------------' + print() + print('---------------------------------') + print('Press ENTER to continue, or Ctrl-C to abort') + print('---------------------------------') - raw_input() + input() def create_seafile_server_symlink(): - print '\ncreating seafile-server-latest symbolic link ... ', + print('\ncreating seafile-server-latest symbolic link ... ', end=' ') seafile_server_symlink = os.path.join(env_mgr.top_dir, 'seafile-server-latest') try: os.symlink(os.path.basename(env_mgr.install_path), seafile_server_symlink) - except Exception, e: - print '\n' + except Exception as e: + print('\n') Utils.error('Failed to create symbolic link %s: %s' % (seafile_server_symlink, e)) else: - print 'done\n\n' + print('done\n\n') def set_file_perm(): - filemode = 0600 - dirmode = 0700 + filemode = 0o600 + dirmode = 0o700 files = [ seahub_config.seahub_settings_py, ] @@ -1500,7 +1506,7 @@ def main(): try: check_params(args) except (InvalidAnswer, InvalidParams) as e: - print Utils.highlight('\n%s\n' % e) + print(Utils.highlight('\n%s\n' % e)) sys.exit(-1) global db_config @@ -1573,14 +1579,14 @@ for information. ''' - print message % dict(fileserver_port=seafile_config.fileserver_port, - server_manual_http=SERVER_MANUAL_HTTP) + print(message % dict(fileserver_port=seafile_config.fileserver_port, + server_manual_http=SERVER_MANUAL_HTTP)) if __name__ == '__main__': try: main() except KeyboardInterrupt: - print - print Utils.highlight('The setup process is aborted') - print + print() + print(Utils.highlight('The setup process is aborted')) + print() diff --git a/scripts/sqlite2mysql.py b/scripts/sqlite2mysql.py index 384cfa2..f87596a 100644 --- a/scripts/sqlite2mysql.py +++ b/scripts/sqlite2mysql.py @@ -11,6 +11,7 @@ Then you can import the .sql file into MySql Note - you need to add foreign key constrains manually since sqlite doesn't actually support them """ +from __future__ import print_function import re import fileinput @@ -80,4 +81,4 @@ for line in fileinput.input(): line = line.replace('"', '`') line = line.replace('AUTOINCREMENT', 'AUTO_INCREMENT') - print line, + print(line, end=' ') diff --git a/server/Makefile.am b/server/Makefile.am index 7af1200..3c16306 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -17,35 +17,12 @@ AM_CFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \ bin_PROGRAMS = seaf-server -proc_headers = $(addprefix processors/, \ - recvfs-proc.h \ - recvbranch-proc.h \ - putcs-proc.h \ - sync-repo-slave-proc.h \ - check-tx-slave-v3-proc.h \ - putfs-proc.h \ - putcommit-v2-proc.h \ - putcommit-v3-proc.h \ - recvcommit-v3-proc.h \ - putcs-v2-proc.h \ - checkbl-proc.h \ - checkff-proc.h \ - putca-proc.h \ - check-protocol-slave-proc.h \ - recvfs-v2-proc.h \ - recvbranch-v2-proc.h \ - putfs-v2-proc.h) - -noinst_HEADERS = web-accesstoken-mgr.h chunkserv-mgr.h seafile-session.h \ +noinst_HEADERS = web-accesstoken-mgr.h seafile-session.h \ repo-mgr.h \ share-mgr.h \ - token-mgr.h \ passwd-mgr.h \ quota-mgr.h \ - listen-mgr.h \ - ../common/mq-mgr.h \ size-sched.h \ - block-tx-server.h \ copy-mgr.h \ http-server.h \ upload-file.h \ @@ -54,19 +31,16 @@ noinst_HEADERS = web-accesstoken-mgr.h chunkserv-mgr.h seafile-session.h \ fileserver-config.h \ http-status-codes.h \ zip-download-mgr.h \ - index-blocks-mgr.h \ - $(proc_headers) + index-blocks-mgr.h seaf_server_SOURCES = \ seaf-server.c \ - web-accesstoken-mgr.c chunkserv-mgr.c seafile-session.c \ + web-accesstoken-mgr.c seafile-session.c \ zip-download-mgr.c \ index-blocks-mgr.c \ share-mgr.c \ - token-mgr.c \ passwd-mgr.c \ quota-mgr.c \ - listen-mgr.c \ repo-op.c \ repo-perm.c \ size-sched.c \ @@ -89,30 +63,11 @@ seaf_server_SOURCES = \ ../common/obj-backend-fs.c \ ../common/seafile-crypt.c \ ../common/diff-simple.c \ - ../common/mq-mgr.c \ ../common/block-mgr.c \ ../common/block-backend.c \ ../common/block-backend-fs.c \ ../common/merge-new.c \ - block-tx-server.c \ - ../common/block-tx-utils.c \ - processors/recvfs-proc.c \ - processors/recvbranch-proc.c \ - processors/putcs-proc.c \ - processors/sync-repo-slave-proc.c \ - processors/check-tx-slave-v3-proc.c \ - processors/putfs-proc.c \ - processors/putcommit-v2-proc.c \ - processors/putcommit-v3-proc.c \ - processors/recvcommit-v3-proc.c \ - processors/putcs-v2-proc.c \ - processors/checkbl-proc.c \ - processors/checkff-proc.c \ - processors/putca-proc.c \ - processors/check-protocol-slave-proc.c \ - processors/recvfs-v2-proc.c \ - processors/recvbranch-v2-proc.c \ - processors/putfs-v2-proc.c + ../common/block-tx-utils.c seaf_server_LDADD = @CCNET_LIBS@ \ $(top_builddir)/lib/libseafile_common.la \ diff --git a/server/block-tx-server.c b/server/block-tx-server.c deleted file mode 100644 index 1b6051a..0000000 --- a/server/block-tx-server.c +++ /dev/null @@ -1,702 +0,0 @@ -#include "common.h" -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include "net.h" - -#ifndef WIN32 -#include -#endif -#include -#include - -#include -#include - -#include "seafile-session.h" -#include "block-tx-server.h" -#include "block-tx-utils.h" -#include "utils.h" - -enum { - RECV_STATE_HANDSHAKE = 0, - RECV_STATE_AUTH, - RECV_STATE_HEADER, - RECV_STATE_CONTENT, -}; - -struct _BlockTxServer { - evutil_socket_t data_fd; - struct evbuffer *recv_buf; - - int recv_state; - int session_key_len; - int command; - char curr_block_id[41]; - - /* Used by put block */ - BlockHandle *block; - - unsigned char key[ENC_KEY_SIZE]; - unsigned char iv[ENC_BLOCK_SIZE]; - - unsigned char key_v2[ENC_KEY_SIZE]; - unsigned char iv_v2[ENC_BLOCK_SIZE]; - - FrameParser parser; - - gboolean break_loop; - - int version; - - char store_id[37]; - int repo_version; -}; - -typedef struct _BlockTxServer BlockTxServer; - -/* Handshake */ - -static int -send_handshake_response (BlockTxServer *server, int status) -{ - HandshakeResponse rsp; - - rsp.status = htonl (status); - rsp.version = htonl (BLOCK_PROTOCOL_VERSION); - - if (sendn (server->data_fd, &rsp, sizeof(rsp)) < 0) { - seaf_warning ("Failed to send handshake response: %s.\n", - evutil_socket_error_to_string(evutil_socket_geterror(server->data_fd))); - return -1; - } - - return 0; -} - -static void -init_frame_parser (BlockTxServer *server) -{ - FrameParser *parser = &server->parser; - - if (server->version == 1) { - memcpy (parser->key, server->key, ENC_BLOCK_SIZE); - memcpy (parser->iv, server->iv, ENC_BLOCK_SIZE); - } else if (server->version == 2) { - memcpy (parser->key_v2, server->key_v2, ENC_KEY_SIZE); - memcpy (parser->iv_v2, server->iv_v2, ENC_BLOCK_SIZE); - } - - parser->version = server->version; - parser->cbarg = server; -} - -static int -process_session_key (BlockTxServer *server, unsigned char *enc_session_key) -{ - char *enc_key_b64 = NULL, *key_b64 = NULL; - unsigned char *session_key = NULL; - gsize len; - SearpcClient *client = NULL; - int ret = 0; - - client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-rpcserver"); - if (!client) { - seaf_warning ("Failed to create rpc client.\n"); - send_handshake_response (server, STATUS_INTERNAL_SERVER_ERROR); - ret = -1; - goto out; - } - - enc_key_b64 = g_base64_encode (enc_session_key, server->session_key_len); - - key_b64 = ccnet_privkey_decrypt (client, enc_key_b64); - if (!key_b64) { - seaf_warning ("Failed to decrypt session key.\n"); - send_handshake_response (server, STATUS_INTERNAL_SERVER_ERROR); - ret = -1; - goto out; - } - - session_key = g_base64_decode (key_b64, &len); - - if (server->version == 1) - blocktx_generate_encrypt_key (session_key, len, server->key, server->iv); - else if (server->version == 2) - blocktx_generate_encrypt_key (session_key, len, server->key_v2, server->iv_v2); - - init_frame_parser (server); - -out: - g_free (enc_key_b64); - g_free (key_b64); - g_free (session_key); - ccnet_rpc_client_free (client); - - return ret; -} - -static int -handle_auth_req_content_cb (char *content, int clen, void *cbarg); - -#define MAX_SESSION_KEY_SIZE 1024 - -static int -handle_handshake_request (BlockTxServer *server) -{ - HandshakeRequest req; - struct evbuffer *input = server->recv_buf; - unsigned char *enc_session_key; - - if (!server->session_key_len) { - if (evbuffer_get_length (input) < sizeof(req)) - return 0; - - evbuffer_remove (input, &req, sizeof(req)); - - req.version = ntohl (req.version); - server->version = MIN (req.version, BLOCK_PROTOCOL_VERSION); - if (server->version != 1 && server->version != 2) { - seaf_warning ("Bad block protocol version %d.\n", server->version); - send_handshake_response (server, STATUS_VERSION_MISMATCH); - return -1; - } - - seaf_debug ("Block protocol version %d.\n", server->version); - - server->session_key_len = ntohl (req.key_len); - if (server->session_key_len > MAX_SESSION_KEY_SIZE) { - seaf_warning ("Encrypted session key is too long: %d.\n", - server->session_key_len); - send_handshake_response (server, STATUS_BAD_REQUEST); - return -1; - } - } - - if (evbuffer_get_length (input) < server->session_key_len) - return 0; - - enc_session_key = g_malloc (server->session_key_len); - - evbuffer_remove (input, enc_session_key, server->session_key_len); - - if (process_session_key (server, enc_session_key) < 0) { - g_free (enc_session_key); - return -1; - } - g_free (enc_session_key); - - if (send_handshake_response (server, STATUS_OK) < 0) - return -1; - - seaf_debug ("recv_state set to AUTH.\n"); - - server->parser.content_cb = handle_auth_req_content_cb; - server->recv_state = RECV_STATE_AUTH; - - return 0; -} - -/* Authentication */ - -static int -send_auth_response (BlockTxServer *server, int status) -{ - AuthResponse rsp; - EVP_CIPHER_CTX *ctx; - int ret = 0; - - rsp.status = htonl (status); - - if (server->version == 1) - blocktx_encrypt_init (&ctx, server->key, server->iv); - else if (server->version == 2) - blocktx_encrypt_init (&ctx, server->key_v2, server->iv_v2); - - if (send_encrypted_data_frame_begin (server->data_fd, sizeof(rsp)) < 0) { - seaf_warning ("Send auth response: failed to begin.\n"); - ret = -1; - goto out; - } - - if (send_encrypted_data (ctx, server->data_fd, &rsp, sizeof(rsp)) < 0) - { - seaf_warning ("Send auth response: failed to send data.\n"); - ret = -1; - goto out; - } - - if (send_encrypted_data_frame_end (ctx, server->data_fd) < 0) { - seaf_warning ("Send auth response: failed to end.\n"); - ret = -1; - goto out; - } - -out: - EVP_CIPHER_CTX_free (ctx); - return ret; -} - -static int -handle_block_header_content_cb (char *content, int clen, void *cbarg); - -static int -handle_auth_req_content_cb (char *content, int clen, void *cbarg) -{ - BlockTxServer *server = cbarg; - char *session_token = content; - SearpcClient *client = NULL; - char repo_id[37]; - SeafRepo *repo; - - if (session_token[clen - 1] != '\0') { - seaf_warning ("Invalid session token format.\n"); - send_auth_response (server, STATUS_BAD_REQUEST); - return -1; - } - - client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-rpcserver"); - if (!client) { - seaf_warning ("Failed to create rpc client.\n"); - send_auth_response (server, STATUS_INTERNAL_SERVER_ERROR); - return -1; - } - - if (seaf_token_manager_verify_token (seaf->token_mgr, client, NULL, - session_token, repo_id) < 0) { - seaf_warning ("Session token check failed.\n"); - send_auth_response (server, STATUS_ACCESS_DENIED); - ccnet_rpc_client_free (client); - return -1; - } - - ccnet_rpc_client_free (client); - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %.8s.\n", repo_id); - return -1; - } - memcpy (server->store_id, repo->store_id, 36); - server->repo_version = repo->version; - seaf_repo_unref (repo); - - if (send_auth_response (server, STATUS_OK) < 0) - return -1; - - seaf_debug ("recv_state set to HEADER.\n"); - - server->parser.content_cb = handle_block_header_content_cb; - server->recv_state = RECV_STATE_HEADER; - - return 0; -} - -static int -handle_auth_request (BlockTxServer *server) -{ - return handle_one_frame (server->recv_buf, &server->parser); -} - -/* Block header */ - -static int -send_block_response_header (BlockTxServer *server, int status) -{ - ResponseHeader header; - EVP_CIPHER_CTX *ctx; - int ret = 0; - - header.status = htonl (status); - - if (server->version == 1) - blocktx_encrypt_init (&ctx, server->key, server->iv); - else if (server->version == 2) - blocktx_encrypt_init (&ctx, server->key_v2, server->iv_v2); - - if (send_encrypted_data_frame_begin (server->data_fd, sizeof(header)) < 0) { - seaf_warning ("Send block response header %s: failed to begin.\n", - server->curr_block_id); - ret = -1; - goto out; - } - - if (send_encrypted_data (ctx, server->data_fd, - &header, sizeof(header)) < 0) - { - seaf_warning ("Send block response header %s: failed to send data.\n", - server->curr_block_id); - ret = -1; - goto out; - } - - if (send_encrypted_data_frame_end (ctx, server->data_fd) < 0) { - seaf_warning ("Send block response header %s: failed to end.\n", - server->curr_block_id); - ret = -1; - goto out; - } - -out: - EVP_CIPHER_CTX_free (ctx); - return ret; -} - -static int -send_block_content (BlockTxServer *server, int block_size); - -static int -save_block_content_cb (char *content, int clen, int end, void *cbarg); - -static int -handle_block_header_content_cb (char *content, int clen, void *cbarg) -{ - BlockTxServer *server = cbarg; - RequestHeader *hdr; - - if (clen != sizeof(RequestHeader)) { - seaf_warning ("Invalid block request header length %d.\n", clen); - send_block_response_header (server, STATUS_BAD_REQUEST); - return -1; - } - - hdr = (RequestHeader *)content; - hdr->command = ntohl (hdr->command); - - if (hdr->command != REQUEST_COMMAND_GET && - hdr->command != REQUEST_COMMAND_PUT) { - seaf_warning ("Unknow command %d.\n", hdr->command); - send_block_response_header (server, STATUS_BAD_REQUEST); - return -1; - } - - server->command = hdr->command; - memcpy (server->curr_block_id, hdr->block_id, 40); - - if (server->command == REQUEST_COMMAND_GET) { - BlockMetadata *md; - int block_size; - - seaf_debug ("Received GET request for block %s.\n", server->curr_block_id); - - md = seaf_block_manager_stat_block (seaf->block_mgr, - server->store_id, - server->repo_version, - server->curr_block_id); - if (!md) { - seaf_warning ("Failed to stat block %s:%s.\n", - server->store_id, server->curr_block_id); - send_block_response_header (server, STATUS_NOT_FOUND); - return -1; - } - block_size = md->size; - g_free (md); - - if (send_block_response_header (server, STATUS_OK) < 0) - return -1; - - if (send_block_content (server, block_size) < 0) - return -1; - - seaf_debug ("recv_state set to HEADER.\n"); - - server->recv_state = RECV_STATE_HEADER; - } else { - seaf_debug ("Received PUT request for block %s.\n", server->curr_block_id); - - server->block = seaf_block_manager_open_block (seaf->block_mgr, - server->store_id, - server->repo_version, - server->curr_block_id, - BLOCK_WRITE); - if (!server->block) { - seaf_warning ("Failed to open block %s:%s for write.\n", - server->store_id, server->curr_block_id); - send_block_response_header (server, STATUS_INTERNAL_SERVER_ERROR); - return -1; - } - - seaf_debug ("recv_state set to CONTENT.\n"); - - server->parser.fragment_cb = save_block_content_cb; - server->recv_state = RECV_STATE_CONTENT; - } - - return 0; -} - -static int -handle_block_header (BlockTxServer *server) -{ - return handle_one_frame (server->recv_buf, &server->parser); -} - -/* Block content */ - -#define SEND_BUFFER_SIZE 4096 - -static int -send_encrypted_block (BlockTxServer *server, - BlockHandle *handle, - const char *block_id, - int size) -{ - int n, remain; - int ret = 0; - EVP_CIPHER_CTX *ctx; - char send_buf[SEND_BUFFER_SIZE]; - - if (server->version == 1) - blocktx_encrypt_init (&ctx, server->key, server->iv); - else if (server->version == 2) - blocktx_encrypt_init (&ctx, server->key_v2, server->iv_v2); - - if (send_encrypted_data_frame_begin (server->data_fd, size) < 0) { - seaf_warning ("Send block %s: failed to begin.\n", block_id); - ret = -1; - goto out; - } - - remain = size; - while (remain > 0) { - n = seaf_block_manager_read_block (seaf->block_mgr, - handle, - send_buf, SEND_BUFFER_SIZE); - if (n < 0) { - seaf_warning ("Failed to read block %s.\n", block_id); - ret = -1; - goto out; - } - - if (send_encrypted_data (ctx, server->data_fd, send_buf, n) < 0) { - seaf_warning ("Send block %s: failed to send data.\n", block_id); - ret = -1; - goto out; - } - - remain -= n; - } - - if (send_encrypted_data_frame_end (ctx, server->data_fd) < 0) { - seaf_warning ("Send block %s: failed to end.\n", block_id); - ret = -1; - goto out; - } - - seaf_debug ("Send block %s done.\n", server->curr_block_id); - -out: - EVP_CIPHER_CTX_free (ctx); - return ret; -} - -static int -send_block_content (BlockTxServer *server, int block_size) -{ - BlockHandle *handle = NULL; - int ret = 0; - - handle = seaf_block_manager_open_block (seaf->block_mgr, - server->store_id, - server->repo_version, - server->curr_block_id, - BLOCK_READ); - if (!handle) { - seaf_warning ("Failed to open block %s:%s.\n", - server->store_id, server->curr_block_id); - return -1; - } - - ret = send_encrypted_block (server, handle, server->curr_block_id, block_size); - - seaf_block_manager_close_block (seaf->block_mgr, handle); - seaf_block_manager_block_handle_free (seaf->block_mgr, handle); - return ret; -} - -static int -save_block_content_cb (char *content, int clen, int end, void *cbarg) -{ - BlockTxServer *server = cbarg; - int n; - - n = seaf_block_manager_write_block (seaf->block_mgr, server->block, - content, clen); - if (n < 0) { - seaf_warning ("Failed to write block %s.\n", server->curr_block_id); - send_block_response_header (server, STATUS_INTERNAL_SERVER_ERROR); - return -1; - } - - if (end) { - if (seaf_block_manager_close_block (seaf->block_mgr, server->block) < 0) { - seaf_warning ("Failed to close block %s.\n", server->curr_block_id); - send_block_response_header (server, STATUS_INTERNAL_SERVER_ERROR); - return -1; - } - - if (seaf_block_manager_commit_block (seaf->block_mgr, server->block) < 0) { - seaf_warning ("Failed to commit block %s.\n", server->curr_block_id); - send_block_response_header (server, STATUS_INTERNAL_SERVER_ERROR); - return -1; - } - - seaf_block_manager_block_handle_free (seaf->block_mgr, server->block); - /* Set this handle to invalid. */ - server->block = NULL; - - send_block_response_header (server, STATUS_OK); - - seaf_debug ("Receive block %s done.\n", server->curr_block_id); - seaf_debug ("recv_state set to HEADER.\n"); - - server->recv_state = RECV_STATE_HEADER; - } - - return 0; -} - -static int -handle_block_content (BlockTxServer *server) -{ - return handle_frame_fragments (server->recv_buf, &server->parser); -} - -static void -recv_data_cb (BlockTxServer *server) -{ - int ret = 0; - - /* Let evbuffer determine how much data can be read. */ - int n = evbuffer_read (server->recv_buf, server->data_fd, -1); - if (n == 0) { - seaf_debug ("Data connection is closed by the client. Transfer done.\n"); - server->break_loop = TRUE; - return; - } else if (n < 0) { - seaf_warning ("Read data connection error: %s.\n", - evutil_socket_error_to_string(evutil_socket_geterror(server->data_fd))); - server->break_loop = TRUE; - return; - } - - switch (server->recv_state) { - case RECV_STATE_HANDSHAKE: - ret = handle_handshake_request (server); - break; - case RECV_STATE_AUTH: - ret = handle_auth_request (server); - break; - case RECV_STATE_HEADER: - ret = handle_block_header (server); - if (ret < 0) - break; - - if (server->recv_state == RECV_STATE_CONTENT && - server->command == REQUEST_COMMAND_PUT) - ret = handle_block_content (server); - - break; - case RECV_STATE_CONTENT: - ret = handle_block_content (server); - break; - } - - if (ret < 0) - server->break_loop = TRUE; -} - -#define BLOCKTX_TIMEOUT 30 - -static void -server_thread_loop (BlockTxServer *server) -{ - fd_set fds; - struct timeval tv = { BLOCKTX_TIMEOUT, 0 }; - int rc; - - while (1) { - FD_ZERO (&fds); - FD_SET (server->data_fd, &fds); - tv.tv_sec = BLOCKTX_TIMEOUT; - tv.tv_usec = 0; - - rc = select (server->data_fd + 1, &fds, NULL, NULL, &tv); - if (rc < 0 && errno == EINTR) { - continue; - } else if (rc < 0) { - seaf_warning ("select error: %s.\n", strerror(errno)); - break; - } - - if (rc == 0) { - seaf_warning ("Recv block timeout.\n"); - break; - } - - if (FD_ISSET (server->data_fd, &fds)) { - recv_data_cb (server); - if (server->break_loop) - break; - } - } -} - -static void * -block_tx_server_thread (void *vdata) -{ - BlockTxServer *server = vdata; - - server->recv_buf = evbuffer_new (); - - server_thread_loop (server); - - if (server->block) { - seaf_block_manager_close_block (seaf->block_mgr, server->block); - seaf_block_manager_block_handle_free (seaf->block_mgr, server->block); - } - - if (server->parser.enc_init) - EVP_CIPHER_CTX_free (server->parser.ctx); - - evbuffer_free (server->recv_buf); - evutil_closesocket (server->data_fd); - - return vdata; -} - -static void -block_tx_server_thread_done (void *vdata) -{ - BlockTxServer *server = vdata; - - g_free (server); -} - -int -block_tx_server_start (evutil_socket_t data_fd) -{ - BlockTxServer *server = g_new0 (BlockTxServer, 1); - int ret = 0; - - int val = 1; - ev_socklen_t optlen = sizeof(int); - setsockopt (data_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, optlen); - - server->data_fd = data_fd; - - ret = ccnet_job_manager_schedule_job (seaf->job_mgr, - block_tx_server_thread, - block_tx_server_thread_done, - server); - if (ret < 0) { - seaf_warning ("Failed to start block tx server thread.\n"); - return -1; - } - - return 0; -} diff --git a/server/block-tx-server.h b/server/block-tx-server.h deleted file mode 100644 index cc9bb4e..0000000 --- a/server/block-tx-server.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef BLOCK_TX_SERVER_H -#define BLOCK_TX_SERVER_H - -#include - -int -block_tx_server_start (evutil_socket_t data_fd); - -#endif diff --git a/server/chunkserv-mgr.c b/server/chunkserv-mgr.c deleted file mode 100644 index 4bd959c..0000000 --- a/server/chunkserv-mgr.c +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include -#include - -#include -#include "seafile-session.h" -#include "chunkserv-mgr.h" -#include "processors/putcs-proc.h" - -#define CHUNKSERVER_DB "chunkserver.db" - -SeafCSManager * -seaf_cs_manager_new (SeafileSession *seaf) -{ - SeafCSManager *mgr = g_new0 (SeafCSManager, 1); - - /* char *db_path = g_build_filename (seaf->seaf_dir, CHUNKSERVER_DB, NULL); */ - /* if (sqlite_open_db (db_path, &mgr->db) < 0) { */ - /* g_critical ("Failed to open chunk server db\n"); */ - /* g_free (db_path); */ - /* g_free (mgr); */ - /* return NULL; */ - /* } */ - - mgr->seaf = seaf; - mgr->chunk_servers = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - return mgr; -} - -static int -load_chunk_servers (SeafCSManager *mgr) -{ - /* char sql[256]; */ - /* sqlite3_stmt *stmt; */ - /* int result; */ - /* char *cs_id; */ - - /* snprintf (sql, 256, "SELECT cs_id FROM chunkservers;"); */ - - /* stmt = sqlite_query_prepare (mgr->db, sql); */ - /* if (!stmt) */ - /* return -1; */ - - /* while ((result = sqlite3_step (stmt)) == SQLITE_ROW) { */ - /* cs_id = (char *) sqlite3_column_text (stmt, 0); */ - /* g_hash_table_insert (mgr->chunk_servers, g_strdup(cs_id), NULL); */ - /* } */ - - /* if (result == SQLITE_ERROR) { */ - /* const gchar *str = sqlite3_errmsg (mgr->db); */ - - /* g_warning ("Couldn't execute query, error: %d->'%s'\n", */ - /* result, str ? str : "no error given"); */ - /* sqlite3_finalize (stmt); */ - - /* return -1; */ - /* } */ - /* sqlite3_finalize (stmt); */ - - /* Add myself as chunk server by default. */ - g_hash_table_insert (mgr->chunk_servers, - g_strdup(mgr->seaf->session->base.id), - NULL); - - return 0; -} - -static void -register_processors (SeafCSManager *mgr) -{ - CcnetClient *client = mgr->seaf->session; - - ccnet_register_service (client, "seafile-putcs", "basic", - SEAFILE_TYPE_PUTCS_PROC, NULL); -} - -int -seaf_cs_manager_start (SeafCSManager *mgr) -{ - /* const char *sql; */ - - register_processors (mgr); - - /* sql = "CREATE TABLE IF NOT EXISTS chunkservers " */ - /* "(id INTEGER PRIMARY KEY, cs_id TEXT);"; */ - /* if (sqlite_query_exec (mgr->db, sql) < 0) */ - /* return -1; */ - - return (load_chunk_servers (mgr)); -} - -int -seaf_cs_manager_add_chunk_server (SeafCSManager *mgr, const char *cs_id) -{ - char sql[256]; - - snprintf (sql, 256, "INSERT INTO chunkservers VALUES (NULL, '%s');", cs_id); - if (sqlite_query_exec (mgr->db, sql) < 0) - return -1; - - g_hash_table_insert (mgr->chunk_servers, g_strdup(cs_id), NULL); - - return 0; -} - -int -seaf_cs_manager_del_chunk_server (SeafCSManager *mgr, const char *cs_id) -{ - char sql[256]; - - snprintf (sql, 256, "DELETE FROM chunkservers WHERE cs_id = '%s';", cs_id); - if (sqlite_query_exec (mgr->db, sql) < 0) - return -1; - - g_hash_table_remove (mgr->chunk_servers, cs_id); - - return 0; -} - -GList* -seaf_cs_manager_get_chunk_servers (SeafCSManager *mgr) -{ - return (g_hash_table_get_keys(mgr->chunk_servers)); -} diff --git a/server/chunkserv-mgr.h b/server/chunkserv-mgr.h deleted file mode 100644 index 6736280..0000000 --- a/server/chunkserv-mgr.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef CHUNKSERV_MGR_H -#define CHUNKSERV_MGR_H - -#include -#include - -struct _SeafileSession; - -struct _SeafCSManager { - struct _SeafileSession *seaf; - GHashTable *chunk_servers; - sqlite3 *db; -}; -typedef struct _SeafCSManager SeafCSManager; - -SeafCSManager* seaf_cs_manager_new (struct _SeafileSession *seaf); -int seaf_cs_manager_start (SeafCSManager *mgr); - -int seaf_cs_manager_add_chunk_server (SeafCSManager *mgr, const char *cs_id); -int seaf_cs_manager_del_chunk_server (SeafCSManager *mgr, const char *cs_id); -GList* seaf_cs_manager_get_chunk_servers (SeafCSManager *mgr); - -#endif diff --git a/server/http-server.c b/server/http-server.c index 424a835..8fcbc6e 100644 --- a/server/http-server.c +++ b/server/http-server.c @@ -497,6 +497,7 @@ typedef struct { char *client_name; } RepoEventData; +/* static void free_repo_event_data (RepoEventData *data) { @@ -555,6 +556,7 @@ publish_stats_event (CEvent *event, void *data) g_string_free (buf, TRUE); free_stats_event_data (rdata); } +*/ static void on_repo_oper (HttpServer *htp_server, const char *etype, @@ -2280,6 +2282,7 @@ seaf_http_server_new (struct _SeafileSession *session) int seaf_http_server_start (HttpServerStruct *server) { +/* server->priv->cevent_id = cevent_manager_register (seaf->ev_mgr, (cevent_handler)publish_repo_event, NULL); @@ -2287,6 +2290,7 @@ seaf_http_server_start (HttpServerStruct *server) server->priv->stats_event_id = cevent_manager_register (seaf->ev_mgr, (cevent_handler)publish_stats_event, NULL); +*/ int ret = pthread_create (&server->priv->thread_id, NULL, http_server_run, server); if (ret != 0) diff --git a/server/listen-mgr.c b/server/listen-mgr.c deleted file mode 100644 index 6cc2e5d..0000000 --- a/server/listen-mgr.c +++ /dev/null @@ -1,275 +0,0 @@ -#include "common.h" - -#include -#include - -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -#include -#include -#include -#endif - - -#include "seafile-session.h" -#include "utils.h" -#include "net.h" -#include "listen-mgr.h" -#include "block-tx-server.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_OTHER -#include "log.h" - - -#define DEFAULT_SERVER_PORT 12001 - -#define TOKEN_LEN 37 /* a uuid */ -#define CHECK_EXPIRE_INTERVAL 1 -#define READ_TOKEN_TIMEOUT 180 /* bufferevent read timeout */ - -struct _SeafListenManagerPriv { - GHashTable *token_hash; - struct evconnlistener *listener; - CcnetTimer *check_timer; -}; - -typedef struct { - int ttl; - ConnAcceptedCB func; - void *user_data; -} CallBackStruct; - -static void accept_connection (struct evconnlistener *listener, - evutil_socket_t connfd, - struct sockaddr *saddr, - int socklen, - void *vmanager); - -static int token_expire_pulse (void * vmanager); -static void read_cb (struct bufferevent *bufev, void *user_data); -static void error_cb (struct bufferevent *bufev, short what, void *user_data); - -static int -get_listen_port (SeafileSession *session) -{ - char *port_str; - int port = 0; - - port_str = g_key_file_get_string (session->config, "network", "port", NULL); - if (port_str) { - port = atoi(port_str); - - if (port <= 0 || port > 65535) - port = DEFAULT_SERVER_PORT; - - g_free(port_str); - } - - return port; -} - - -SeafListenManager * -seaf_listen_manager_new (SeafileSession *session) -{ - SeafListenManager *mgr; - mgr = g_new0 (SeafListenManager, 1); - mgr->port = get_listen_port(session); - - mgr->priv = g_new0 (SeafListenManagerPriv, 1); - mgr->priv->token_hash = g_hash_table_new_full ( - g_str_hash, g_str_equal, g_free, g_free); - - return mgr; -} - -int -seaf_listen_manager_start (SeafListenManager *mgr) -{ - evutil_socket_t listenfd; - unsigned flags; - SeafListenManagerPriv *priv = mgr->priv; - - if (mgr->port == 0) { - return 0; - } - - listenfd = ccnet_net_bind_tcp (mgr->port, 1); - if (listenfd < 0) { - seaf_warning ("[listen mgr] failed to bind port %d\n", mgr->port); - return -1; - } - - flags = LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_EXEC; - - /* start to listen on block transfer port */ - priv->listener = evconnlistener_new (NULL, /* base */ - accept_connection, mgr, /* cb & arg */ - flags, /* flags */ - -1, /* backlog */ - listenfd); /* socket */ - - if (!priv->listener) { - seaf_warning ("[listen mgr] failed to start evlistener\n"); - evutil_closesocket (listenfd); - return -1; - } - - priv->check_timer = ccnet_timer_new (token_expire_pulse, mgr, - CHECK_EXPIRE_INTERVAL * 1000); - - seaf_message ("listen on port %d for block tranfer\n", mgr->port); - return 0; -} - -static void -accept_connection (struct evconnlistener *listener, - evutil_socket_t connfd, - struct sockaddr *saddr, int socklen, - void *vmanager) -{ - struct bufferevent *bufev; - struct timeval tv; - tv.tv_sec = READ_TOKEN_TIMEOUT; - tv.tv_usec = 0; - - bufev = bufferevent_socket_new (NULL, connfd, 0); - bufferevent_setcb (bufev, read_cb, NULL, error_cb, vmanager); - bufferevent_setwatermark (bufev, EV_READ, TOKEN_LEN, TOKEN_LEN); - bufferevent_set_timeouts (bufev, &tv, NULL); - - bufferevent_enable (bufev, EV_READ); - /* no write is needed here*/ - bufferevent_disable (bufev, EV_WRITE); -} - -static void -read_cb (struct bufferevent *bufev, void *user_data) -{ - char *token; - CallBackStruct *cbstruct; - SeafListenManager *mgr = user_data; - size_t len = EVBUFFER_LENGTH(bufev->input); - evutil_socket_t connfd = bufferevent_getfd(bufev); - - /* we set the high & low watermark to TOKEN_LEN, so the received data can - * only be this length. */ - if (len != TOKEN_LEN) { - seaf_warning ("[listen mgr] token with incorrect length received: %d\n", - (int)len); - goto error; - } - - token = (char *)(EVBUFFER_DATA (bufev->input)); - - /* Switch to new block protocol */ - if (strcmp (token, BLOCK_PROTOCOL_SIGNATURE) == 0) { - if (ccnet_net_make_socket_blocking (connfd) < 0) { - seaf_warning ("[listen mgr] Failed to set socket blocking.\n"); - goto error; - } - if (block_tx_server_start (connfd) < 0) { - seaf_warning ("Failed to start block tx server.\n"); - goto error; - } - bufferevent_free (bufev); - return; - } - - cbstruct = g_hash_table_lookup (mgr->priv->token_hash, token); - if (!cbstruct) { - seaf_warning ("[listen mgr] unknown token received: %s\n", token); - goto error; - } - - /* The connfd should be non-blocking for adding to bufferevent. - * But now we want it to be blocking again. - */ - if (ccnet_net_make_socket_blocking (connfd) < 0) { - seaf_warning ("[listen mgr] Failed to set socket blocking.\n"); - goto error; - } - - /* client is now connected, execute the callback function */ - cbstruct->func (connfd, cbstruct->user_data); - - g_hash_table_remove (mgr->priv->token_hash, token); - bufferevent_free (bufev); - return; - -error: - evutil_closesocket(connfd); - bufferevent_free (bufev); -} - -static void -error_cb (struct bufferevent *bufev, short what, void *user_data) -{ - if (what & BEV_EVENT_TIMEOUT) - seaf_warning ("[listen mgr] client timeout\n"); - else - seaf_warning ("[listen mgr] error when reading token\n"); - - /* We don't specify BEV_OPT_CLOSE_ON_FREE, so we need to close the socket - * manually. */ - evutil_closesocket(bufferevent_getfd(bufev)); - bufferevent_free (bufev); -} - - -int -seaf_listen_manager_register_token (SeafListenManager *mgr, - const char *token, - ConnAcceptedCB cb, - void *cb_arg, - int timeout_sec) -{ - CallBackStruct *cbstruct; - if (!token) - return -1; - - if (timeout_sec <= 0) - return -1; - - cbstruct = g_new0(CallBackStruct, 1); - cbstruct->func = cb; - cbstruct->user_data = cb_arg; - cbstruct->ttl = timeout_sec; - - g_hash_table_insert (mgr->priv->token_hash, g_strdup(token), cbstruct); - return 0; -} - -char * -seaf_listen_manager_generate_token (SeafListenManager *mgr) -{ - return gen_uuid(); -} - -static gboolean -is_token_expired (gpointer key, gpointer value, gpointer user_data) -{ - CallBackStruct *cbstruct = value; - - if (cbstruct->ttl == 0) { - /* client doesn't connect before timeout, so token is expired */ - seaf_warning ("[listen mgr] token timeout\n"); - cbstruct->func (-1, cbstruct->user_data); - return TRUE; - } - - --cbstruct->ttl; - - return FALSE; -} - -static int -token_expire_pulse (void * vmanager) -{ - SeafListenManager *mgr = vmanager; - g_hash_table_foreach_remove (mgr->priv->token_hash, - (GHRFunc)is_token_expired, - NULL); - - return TRUE; -} - diff --git a/server/listen-mgr.h b/server/listen-mgr.h deleted file mode 100644 index 7291608..0000000 --- a/server/listen-mgr.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef SEAF_LISTEN_MANAGER_H -#define SEAF_LISTEN_MANAGER_H - -/** - * We always listen on the same tcp port for block tx. - * - * This module listens on the port, and when a new connection comes in, tries - * to read a 37-bit uuid(called a `token'), and deliveres the new socket to - * the corresponding block tx processor by calling the callback it provides - * when the token is registered. - * - * The socket accepted by listen-mgr may be closed by either: - * - * 1. By listen manager: - * - if timeout is reached or error occured when waiting for the token. - * - if a token is received, but no corresponding callback is found for - * this token. - * 2. If a valid token is received, the socket would be passed to the - * processor who registered the token, and the processor is now - * responsible for closing the socket. - */ - -typedef struct _SeafListenManager SeafListenManager; -typedef struct _SeafListenManagerPriv SeafListenManagerPriv; - -struct _SeafListenManager { - int port; - SeafListenManagerPriv *priv; -}; - -struct _SeafListenManager * -seaf_listen_manager_new (struct _SeafileSession *session); - -int -seaf_listen_manager_start (SeafListenManager *mgr); - -typedef void (*ConnAcceptedCB) (evutil_socket_t, void *); - -/** - * Register a token to identify a client when it connects later. - * - * @cb: this callback would be called with the connection socket, or with -1 when timeout - * @cb_arg: user supplied argument - * @timeout_sec: must be a positive number, the token would be expired after - * that many seconds. - */ -int -seaf_listen_manager_register_token (SeafListenManager *mgr, - const char *token, - ConnAcceptedCB cb, - void *cb_arg, - int timeout_sec); - -char * -seaf_listen_manager_generate_token (SeafListenManager *mgr); - -#endif diff --git a/server/processors/check-protocol-slave-proc.c b/server/processors/check-protocol-slave-proc.c deleted file mode 100644 index 9ea0c68..0000000 --- a/server/processors/check-protocol-slave-proc.c +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include "check-protocol-slave-proc.h" - -G_DEFINE_TYPE (SeafileCheckProtocolSlaveProc, seafile_check_protocol_slave_proc, CCNET_TYPE_PROCESSOR) - -static int -check_protocol_slave_start (CcnetProcessor *processor, int argc, char **argv); - -static void -seafile_check_protocol_slave_proc_class_init (SeafileCheckProtocolSlaveProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "seafile-check-protocol-slave-proc"; - proc_class->start = check_protocol_slave_start; -} - -static void -seafile_check_protocol_slave_proc_init (SeafileCheckProtocolSlaveProc *processor) -{ -} - - -static int -check_protocol_slave_start (CcnetProcessor *processor, int argc, char **argv) -{ - int n; - char buf[10]; - n = snprintf (buf, sizeof(buf), "%d", CURRENT_PROTO_VERSION); - ccnet_processor_send_response (processor, SC_OK, SS_OK, buf, n+1); - ccnet_processor_done (processor, TRUE); - - return 0; -} diff --git a/server/processors/check-protocol-slave-proc.h b/server/processors/check-protocol-slave-proc.h deleted file mode 100644 index 8bd77ef..0000000 --- a/server/processors/check-protocol-slave-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_CHECK_PROTOCOL_SLAVE_PROC_H -#define SEAFILE_CHECK_PROTOCOL_SLAVE_PROC_H - -#include -#include - -#define SEAFILE_TYPE_CHECK_PROTOCOL_SLAVE_PROC (seafile_check_protocol_slave_proc_get_type ()) -#define SEAFILE_CHECK_PROTOCOL_SLAVE_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECK_PROTOCOL_SLAVE_PROC, SeafileCheckProtocolSlaveProc)) -#define SEAFILE_IS_CHECK_PROTOCOL_SLAVE_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECK_PROTOCOL_SLAVE_PROC)) -#define SEAFILE_CHECK_PROTOCOL_SLAVE_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECK_PROTOCOL_SLAVE_PROC, SeafileCheckProtocolSlaveProcClass)) -#define IS_SEAFILE_CHECK_PROTOCOL_SLAVE_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECK_PROTOCOL_SLAVE_PROC)) -#define SEAFILE_CHECK_PROTOCOL_SLAVE_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECK_PROTOCOL_SLAVE_PROC, SeafileCheckProtocolSlaveProcClass)) - -typedef struct _SeafileCheckProtocolSlaveProc SeafileCheckProtocolSlaveProc; -typedef struct _SeafileCheckProtocolSlaveProcClass SeafileCheckProtocolSlaveProcClass; - -struct _SeafileCheckProtocolSlaveProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileCheckProtocolSlaveProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_check_protocol_slave_proc_get_type (); - -#endif diff --git a/server/processors/check-quota-common.h b/server/processors/check-quota-common.h deleted file mode 100644 index d32ff57..0000000 --- a/server/processors/check-quota-common.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef CHECK_QUOTA_COMMON_H -#define CHECK_QUOTA_COMMON_H - -#include -#include -#include - -static SearpcClient * -create_sync_ccnetrpc_client (const char *central_config_dir, const char *config_dir, const char *service) -{ - if (!config_dir || !service) - return NULL; - - CcnetClient *sync_client; - SearpcClient *rpc_client; - - sync_client = ccnet_client_new (); - if ((ccnet_client_load_confdir(sync_client, central_config_dir, config_dir)) < 0 ) { - return NULL; - } - - if (ccnet_client_connect_daemon (sync_client, CCNET_CLIENT_SYNC) < 0) - { - g_object_unref ((GObject *)sync_client); - return NULL; - } - - rpc_client = ccnet_create_rpc_client (sync_client, NULL, service); - - return rpc_client; -} - -static void -free_sync_rpc_client (SearpcClient *rpc_client) -{ - CcnetrpcTransportParam *priv = rpc_client->arg; - CcnetClient *client = priv->session; - - /* No need to call ccnet_client_disconnect_daemon. It's called in object - * finalize function of ccnet client class. */ - g_object_unref ((GObject *)client); - ccnet_rpc_client_free (rpc_client); -} - -static int -check_repo_owner_quota (CcnetProcessor *processor, - SearpcClient *rpc_client, - const char *repo_id) -{ - USE_PRIV; - char *user = NULL; - int org_id; - gint64 quota, usage; - int ret = 0; - - /* repo is guranteed to exist before check_repo_owner_quota */ - user = seaf_repo_manager_get_repo_owner (seaf->repo_mgr, repo_id); - if (user != NULL) { - quota = seaf_quota_manager_get_user_quota (seaf->quota_mgr, user); - if (quota <= 0) - quota = seaf->quota_mgr->default_quota; - } else { - org_id = seaf_repo_manager_get_repo_org (seaf->repo_mgr, repo_id); - if (org_id < 0) { - priv->rsp_code = g_strdup (SC_QUOTA_ERROR); - priv->rsp_msg = g_strdup (SS_QUOTA_ERROR); - ret = -1; - goto out; - } - - quota = seaf_quota_manager_get_org_quota (seaf->quota_mgr, org_id); - if (quota <= 0) - quota = seaf->quota_mgr->default_quota; - } - - if (quota == INFINITE_QUOTA) - return ret; - - if (user) - usage = seaf_quota_manager_get_user_usage (seaf->quota_mgr, user); - else - usage = seaf_quota_manager_get_org_usage (seaf->quota_mgr, org_id); - - g_debug ("quota is %"G_GINT64_FORMAT", usage is %"G_GINT64_FORMAT"\n", - quota, usage); - - if (usage < 0) { - priv->rsp_code = g_strdup (SC_QUOTA_ERROR); - priv->rsp_msg = g_strdup (SS_QUOTA_ERROR); - ret = -1; - goto out; - - } else if (usage >= quota) { - priv->rsp_code = g_strdup (SC_QUOTA_FULL); - priv->rsp_msg = g_strdup (SS_QUOTA_FULL); - ret = -1; - goto out; - } - -out: - g_free (user); - - return ret; -} - -#endif diff --git a/server/processors/check-tx-slave-proc.c b/server/processors/check-tx-slave-proc.c deleted file mode 100644 index 4be7a8d..0000000 --- a/server/processors/check-tx-slave-proc.c +++ /dev/null @@ -1,377 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include -#include -#include - -#include -#include -#include - -#include "seafile-session.h" -#include "check-tx-slave-proc.h" - -#include "log.h" - -#define SC_GET_TOKEN "301" -#define SS_GET_TOKEN "Get token" -#define SC_PUT_TOKEN "302" -#define SS_PUT_TOKEN "Put token" -#define SC_GET_VERSION "303" -#define SS_GET_VERSION "Get version" -#define SC_VERSION "304" -#define SS_VERSION "Version" - -#define SC_ACCESS_DENIED "401" -#define SS_ACCESS_DENIED "Access denied" -#define SC_SERVER_ERROR "404" -#define SS_SERVER_ERROR "Internal server error" -#define SC_PROTOCOL_MISMATCH "405" -#define SS_PROTOCOL_MISMATCH "Protocol version mismatch" - -/* Only for upload */ -#define SC_QUOTA_ERROR "402" -#define SS_QUOTA_ERROR "Failed to get quota" -#define SC_QUOTA_FULL "403" -#define SS_QUOTA_FULL "storage for the repo's owner is full" - -/* Only for download */ -#define SC_BAD_REPO "406" -#define SS_BAD_REPO "Repo doesn't exist" -#define SC_NO_BRANCH "407" -#define SS_NO_BRANCH "Branch not found" - -enum { - INIT, - ACCESS_GRANTED, -}; - -enum { - CHECK_TX_TYPE_UPLOAD, - CHECK_TX_TYPE_DOWNLOAD, -}; - -typedef struct { - int type; - - char repo_id[37]; - char *branch_name; - char *email; - - char *rsp_code; - char *rsp_msg; - char head_id[41]; - int has_branch; -} SeafileCheckTxSlaveProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_CHECK_TX_SLAVE_PROC, SeafileCheckTxSlaveProcPriv)) - -#define USE_PRIV \ - SeafileCheckTxSlaveProcPriv *priv = GET_PRIV(processor); - -G_DEFINE_TYPE (SeafileCheckTxSlaveProc, seafile_check_tx_slave_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void thread_done (void *result); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - /* g_free works fine even if ptr is NULL. */ - g_free (priv->email); - g_free (priv->branch_name); - g_free (priv->rsp_code); - g_free (priv->rsp_msg); - - CCNET_PROCESSOR_CLASS (seafile_check_tx_slave_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_check_tx_slave_proc_class_init (SeafileCheckTxSlaveProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "check-tx-slave-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileCheckTxSlaveProcPriv)); -} - -static void -seafile_check_tx_slave_proc_init (SeafileCheckTxSlaveProc *processor) -{ -} - -#include "check-quota-common.h" - -static void -get_branch_head (CcnetProcessor *processor) -{ - SeafBranch *branch; - USE_PRIV; - - branch = seaf_branch_manager_get_branch (seaf->branch_mgr, - priv->repo_id, priv->branch_name); - if (branch != NULL) { - priv->has_branch = 1; - memcpy (priv->head_id, branch->commit_id, 41); - seaf_branch_unref (branch); - - priv->rsp_code = g_strdup(SC_OK); - priv->rsp_msg = g_strdup(SS_OK); - } else if (priv->type == CHECK_TX_TYPE_UPLOAD) { - priv->rsp_code = g_strdup(SC_OK); - priv->rsp_msg = g_strdup(SS_OK); - } else { - priv->rsp_code = g_strdup(SC_NO_BRANCH); - priv->rsp_msg = g_strdup(SS_NO_BRANCH); - } -} - -static gboolean -check_repo_share_permission (SearpcClient *rpc_client, - const char *repo_id, - const char *user_name) -{ - GList *groups, *pgroup; - GList *repos, *prepo; - CcnetGroup *group; - int group_id; - char *shared_repo_id; - gboolean ret = FALSE; - - if (seaf_share_manager_check_permission (seaf->share_mgr, - repo_id, - user_name) != NULL) - return TRUE; - - groups = ccnet_get_groups_by_user (rpc_client, user_name); - for (pgroup = groups; pgroup != NULL; pgroup = pgroup->next) { - group = pgroup->data; - g_object_get (group, "id", &group_id, NULL); - - repos = seaf_repo_manager_get_group_repoids (seaf->repo_mgr, - group_id, NULL); - for (prepo = repos; prepo != NULL; prepo = prepo->next) { - shared_repo_id = prepo->data; - if (strcmp (shared_repo_id, repo_id) == 0) { - ret = TRUE; - break; - } - } - for (prepo = repos; prepo != NULL; prepo = prepo->next) - g_free (prepo->data); - g_list_free (repos); - if (ret) - break; - } - - for (pgroup = groups; pgroup != NULL; pgroup = pgroup->next) - g_object_unref ((GObject *)pgroup->data); - g_list_free (groups); - return ret; -} - -static void * -check_tx (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - char *owner = NULL; - int org_id; - SearpcClient *rpc_client = NULL; - - char *repo_id = priv->repo_id; - - rpc_client = create_sync_ccnetrpc_client - (seaf->session->central_config_dir, seaf->session->config_dir, "ccnet-threaded-rpcserver"); - - if (!rpc_client) { - priv->rsp_code = g_strdup(SC_SERVER_ERROR); - priv->rsp_msg = g_strdup(SS_SERVER_ERROR); - goto out; - } - - if (!seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id)) { - priv->rsp_code = g_strdup(SC_BAD_REPO); - priv->rsp_msg = g_strdup(SS_BAD_REPO); - goto out; - } - - if (priv->type == CHECK_TX_TYPE_UPLOAD && - check_repo_owner_quota (processor, rpc_client, repo_id) < 0) - goto out; - - owner = seaf_repo_manager_get_repo_owner (seaf->repo_mgr, repo_id); - if (owner != NULL) { - /* If the user is not owner, check share permission */ - if (strcmp (owner, priv->email) != 0) { - if(!check_repo_share_permission (rpc_client, repo_id, priv->email)) { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - goto out; - } - } - } else { - /* This should be a repo created in an org. */ - org_id = seaf_repo_manager_get_repo_org (seaf->repo_mgr, repo_id); - if (org_id < 0 || - !ccnet_org_user_exists (rpc_client, org_id, priv->email)) { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - goto out; - } - } - - get_branch_head (processor); - -out: - g_free (owner); - if (rpc_client) - free_sync_rpc_client (rpc_client); - return vprocessor; -} - -static void -thread_done (void *result) -{ - CcnetProcessor *processor = result; - USE_PRIV; - - if (strcmp (priv->rsp_code, SC_OK) == 0) { - if (priv->has_branch) { - ccnet_processor_send_response (processor, - SC_OK, SS_OK, - priv->head_id, 41); - } else - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - processor->state = ACCESS_GRANTED; - } else { - ccnet_processor_send_response (processor, - priv->rsp_code, priv->rsp_msg, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static void -get_email_cb (void *result, void *data, GError *error) -{ - char *email = result; - CcnetProcessor *processor = data; - USE_PRIV; - - if (!email) { - seaf_warning ("[check tx] cannot find email for peer %s.\n", - processor->peer_id); - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - priv->email = g_strdup(email); - - ccnet_processor_thread_create (processor, check_tx, thread_done, processor); -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char *repo_id, *branch_name; - USE_PRIV; - - if (argc < 4) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (strcmp (argv[0], "upload") == 0) { - priv->type = CHECK_TX_TYPE_UPLOAD; - } else if (strcmp (argv[0], "download") == 0) { - priv->type = CHECK_TX_TYPE_DOWNLOAD; - } else { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - repo_id = argv[2]; - branch_name = argv[3]; - - if (strlen(repo_id) != 36) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (priv->type == CHECK_TX_TYPE_UPLOAD && - strcmp (branch_name, "master") != 0) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->repo_id, repo_id, 37); - priv->branch_name = g_strdup(branch_name); - - ccnet_get_binding_email_async (seaf->async_ccnetrpc_client_t, processor->peer_id, - get_email_cb, processor); - - return 0; -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - char *token; - - if (processor->state != ACCESS_GRANTED) { - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - if (strncmp (code, SC_GET_TOKEN, 3) == 0) { - token = seaf_token_manager_generate_token (seaf->token_mgr, - processor->peer_id, - priv->repo_id); - ccnet_processor_send_response (processor, - SC_PUT_TOKEN, SS_PUT_TOKEN, - token, strlen(token) + 1); - g_free (token); - return; - } else if (strncmp (code, SC_GET_VERSION, 3) == 0) { - char buf[16]; - int len; - len = snprintf (buf, sizeof(buf), "%d", CURRENT_PROTO_VERSION); - ccnet_processor_send_response (processor, - SC_VERSION, SS_VERSION, - buf, len + 1); - ccnet_processor_done (processor, TRUE); - return; - } - - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); -} diff --git a/server/processors/check-tx-slave-proc.h b/server/processors/check-tx-slave-proc.h deleted file mode 100644 index 638c401..0000000 --- a/server/processors/check-tx-slave-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_CHECK_TX_SLAVE_PROC_H -#define SEAFILE_CHECK_TX_SLAVE_PROC_H - -#include -#include - -#define SEAFILE_TYPE_CHECK_TX_SLAVE_PROC (seafile_check_tx_slave_proc_get_type ()) -#define SEAFILE_CHECK_TX_SLAVE_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_PROC, SeafileCheckTxSlaveProc)) -#define SEAFILE_IS_CHECK_TX_SLAVE_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_PROC)) -#define SEAFILE_CHECK_TX_SLAVE_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECK_TX_SLAVE_PROC, SeafileCheckTxSlaveProcClass)) -#define IS_SEAFILE_CHECK_TX_SLAVE_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECK_TX_SLAVE_PROC)) -#define SEAFILE_CHECK_TX_SLAVE_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_PROC, SeafileCheckTxSlaveProcClass)) - -typedef struct _SeafileCheckTxSlaveProc SeafileCheckTxSlaveProc; -typedef struct _SeafileCheckTxSlaveProcClass SeafileCheckTxSlaveProcClass; - -struct _SeafileCheckTxSlaveProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileCheckTxSlaveProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_check_tx_slave_proc_get_type (); - -#endif - diff --git a/server/processors/check-tx-slave-v2-proc.c b/server/processors/check-tx-slave-v2-proc.c deleted file mode 100644 index f71e9ab..0000000 --- a/server/processors/check-tx-slave-v2-proc.c +++ /dev/null @@ -1,407 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include -#include -#include - -#include -#include -#include - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include "seafile-session.h" -#include "utils.h" - -#include "check-tx-slave-v2-proc.h" - -#define SC_GET_TOKEN "301" -#define SS_GET_TOKEN "Get token" -#define SC_PUT_TOKEN "302" -#define SS_PUT_TOKEN "Put token" -#define SC_GET_VERSION "303" -#define SS_GET_VERSION "Get version" -#define SC_VERSION "304" -#define SS_VERSION "Version" - -#define SC_ACCESS_DENIED "401" -#define SS_ACCESS_DENIED "Access denied" -#define SC_SERVER_ERROR "404" -#define SS_SERVER_ERROR "Internal server error" -#define SC_PROTOCOL_MISMATCH "405" -#define SS_PROTOCOL_MISMATCH "Protocol version mismatch" - -/* Only for upload */ -#define SC_QUOTA_ERROR "402" -#define SS_QUOTA_ERROR "Failed to get quota" -#define SC_QUOTA_FULL "403" -#define SS_QUOTA_FULL "storage for the repo's owner is full" - -/* Only for download */ -#define SC_BAD_REPO "406" -#define SS_BAD_REPO "Repo doesn't exist" -#define SC_NO_BRANCH "407" -#define SS_NO_BRANCH "Branch not found" - -enum { - INIT, - ACCESS_GRANTED, -}; - -enum { - CHECK_TX_TYPE_UPLOAD, - CHECK_TX_TYPE_DOWNLOAD, -}; - -typedef struct { - int type; - - char repo_id[37]; - char *branch_name; - char *token; - char *session_key; - char *peer_addr; - char *peer_name; - - char *rsp_code; - char *rsp_msg; - char head_id[41]; - int has_branch; -} SeafileCheckTxSlaveV2ProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_CHECK_TX_SLAVE_V2_PROC, SeafileCheckTxSlaveV2ProcPriv)) - -#define USE_PRIV \ - SeafileCheckTxSlaveV2ProcPriv *priv = GET_PRIV(processor); - -G_DEFINE_TYPE (SeafileCheckTxSlaveV2Proc, seafile_check_tx_slave_v2_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void thread_done (void *result); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - /* g_free works fine even if ptr is NULL. */ - g_free (priv->token); - g_free (priv->session_key); - g_free (priv->peer_addr); - g_free (priv->peer_name); - g_free (priv->branch_name); - g_free (priv->rsp_code); - g_free (priv->rsp_msg); - - CCNET_PROCESSOR_CLASS (seafile_check_tx_slave_v2_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_check_tx_slave_v2_proc_class_init (SeafileCheckTxSlaveV2ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "check-tx-slave-v2-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileCheckTxSlaveV2ProcPriv)); -} - -static void -seafile_check_tx_slave_v2_proc_init (SeafileCheckTxSlaveV2Proc *processor) -{ -} - -static void -get_branch_head (CcnetProcessor *processor) -{ - SeafBranch *branch; - USE_PRIV; - - branch = seaf_branch_manager_get_branch (seaf->branch_mgr, - priv->repo_id, priv->branch_name); - if (branch != NULL) { - priv->has_branch = 1; - memcpy (priv->head_id, branch->commit_id, 41); - seaf_branch_unref (branch); - - priv->rsp_code = g_strdup(SC_OK); - priv->rsp_msg = g_strdup(SS_OK); - } else if (priv->type == CHECK_TX_TYPE_UPLOAD) { - priv->rsp_code = g_strdup(SC_OK); - priv->rsp_msg = g_strdup(SS_OK); - } else { - priv->rsp_code = g_strdup(SC_NO_BRANCH); - priv->rsp_msg = g_strdup(SS_NO_BRANCH); - } -} - -static int -decrypt_token (CcnetProcessor *processor) -{ - USE_PRIV; - int hex_len, encrypted_len, token_len; - char *encrypted_token = NULL; - SeafileCrypt *crypt = NULL; - unsigned char key[16], iv[16]; - char *token = NULL; - int ret = 0; - - /* raw data is half the length of hexidecimal */ - hex_len = strlen(priv->token); - if (hex_len % 2 != 0) { - seaf_warning ("[check tx slave v2] invalid length of encrypted token\n"); - ret = -1; - goto out; - } - - token = seaf_repo_manager_get_decrypted_token (seaf->repo_mgr, - priv->token, - priv->session_key); - if (token) - goto found; - - encrypted_len = hex_len / 2; - encrypted_token = g_malloc (encrypted_len); - hex_to_rawdata (priv->token, - (unsigned char *)encrypted_token, - encrypted_len); - - seafile_derive_key (priv->session_key, - strlen(priv->session_key), - 1, NULL, 0, key, iv); - crypt = seafile_crypt_new (1, key, iv); - - if (seafile_decrypt (&token, &token_len, encrypted_token, - encrypted_len, crypt) < 0) { - seaf_warning ("[check tx slave v2] failed to decrypt token\n"); - ret = -1; - goto out; - } - - /* Add to cache. */ - seaf_repo_manager_add_decrypted_token (seaf->repo_mgr, - priv->token, - priv->session_key, - token); - -found: - g_free (priv->token); - /* we can use the decrypted data directly, since the trailing null byte is - * also included when encrypting in the client */ - priv->token = token; - -out: - g_free (crypt); - g_free (encrypted_token); - - return ret; -} - -static void * -check_tx (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - char *user = NULL; - char *repo_id = priv->repo_id; - - if (!seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id)) { - priv->rsp_code = g_strdup(SC_BAD_REPO); - priv->rsp_msg = g_strdup(SS_BAD_REPO); - goto out; - } - - if (decrypt_token (processor) < 0) { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - goto out; - } - - user = seaf_repo_manager_get_email_by_token ( - seaf->repo_mgr, repo_id, priv->token); - - if (!user) { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - goto out; - } - - if (priv->type == CHECK_TX_TYPE_UPLOAD && - seaf_quota_manager_check_quota (seaf->quota_mgr, repo_id) < 0) { - priv->rsp_code = g_strdup(SC_QUOTA_FULL); - priv->rsp_msg = g_strdup(SS_QUOTA_FULL); - goto out; - } - - char *perm = seaf_repo_manager_check_permission (seaf->repo_mgr, - repo_id, user, NULL); - if (!perm || - (strcmp (perm, "r") == 0 && priv->type == CHECK_TX_TYPE_UPLOAD)) - { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - g_free (perm); - goto out; - } - g_free (perm); - - /* Record the (token, email, ) information, may - * include peer_id, peer_ip, peer_name, etc. - */ - if (!seaf_repo_manager_token_peer_info_exists (seaf->repo_mgr, priv->token)) - seaf_repo_manager_add_token_peer_info (seaf->repo_mgr, - priv->token, - processor->peer_id, - priv->peer_addr, - priv->peer_name, - (gint64)time(NULL), NULL); - else - seaf_repo_manager_update_token_peer_info (seaf->repo_mgr, - priv->token, - priv->peer_addr, - (gint64)time(NULL), NULL); - - get_branch_head (processor); - -out: - g_free (user); - return vprocessor; -} - -static void -thread_done (void *result) -{ - CcnetProcessor *processor = result; - USE_PRIV; - - if (strcmp (priv->rsp_code, SC_OK) == 0) { - if (priv->has_branch) { - ccnet_processor_send_response (processor, - SC_OK, SS_OK, - priv->head_id, 41); - } else - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - processor->state = ACCESS_GRANTED; - } else { - ccnet_processor_send_response (processor, - priv->rsp_code, priv->rsp_msg, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char *repo_id, *token; - USE_PRIV; - - if (argc != 5) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (strcmp (argv[0], "upload") == 0) { - priv->type = CHECK_TX_TYPE_UPLOAD; - } else if (strcmp (argv[0], "download") == 0) { - priv->type = CHECK_TX_TYPE_DOWNLOAD; - } else { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - repo_id = argv[2]; - token = argv[4]; - - if (!is_uuid_valid (repo_id)) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->repo_id, repo_id, 37); - priv->branch_name = g_strdup("master"); - - priv->token = g_strdup(token); - - CcnetPeer *peer = ccnet_get_peer (seaf->ccnetrpc_client, processor->peer_id); - if (!peer || !peer->session_key) { - seaf_warning ("[check tx slave v2] session key of peer %.10s is null\n", - processor->peer_id); - ccnet_processor_send_response (processor, SC_BAD_PEER, SS_BAD_PEER, NULL, 0); - ccnet_processor_done (processor, FALSE); - if (peer) - g_object_unref (peer); - return -1; - } - - priv->session_key = g_strdup(peer->session_key); - priv->peer_addr = g_strdup(peer->addr_str); - priv->peer_name = g_strdup(peer->name); - if (!priv->peer_name) - priv->peer_name = g_strdup("Unknown"); - g_object_unref (peer); - - seaf_debug ("[check-tx] %s repo %.8s.\n", argv[0], repo_id); - - ccnet_processor_thread_create (processor, seaf->job_mgr, - check_tx, thread_done, processor); - - return 0; -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - char *token; - - if (processor->state != ACCESS_GRANTED) { - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - if (strncmp (code, SC_GET_TOKEN, 3) == 0) { - token = seaf_token_manager_generate_token (seaf->token_mgr, - processor->peer_id, - priv->repo_id); - ccnet_processor_send_response (processor, - SC_PUT_TOKEN, SS_PUT_TOKEN, - token, strlen(token) + 1); - g_free (token); - return; - } else if (strncmp (code, SC_GET_VERSION, 3) == 0) { - char buf[16]; - int len; - len = snprintf (buf, sizeof(buf), "%d", CURRENT_PROTO_VERSION); - ccnet_processor_send_response (processor, - SC_VERSION, SS_VERSION, - buf, len + 1); - ccnet_processor_done (processor, TRUE); - return; - } - - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); -} diff --git a/server/processors/check-tx-slave-v2-proc.h b/server/processors/check-tx-slave-v2-proc.h deleted file mode 100644 index b24bf66..0000000 --- a/server/processors/check-tx-slave-v2-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_CHECK_TX_SLAVE_V2_PROC_H -#define SEAFILE_CHECK_TX_SLAVE_V2_PROC_H - -#include -#include - -#define SEAFILE_TYPE_CHECK_TX_SLAVE_V2_PROC (seafile_check_tx_slave_v2_proc_get_type ()) -#define SEAFILE_CHECK_TX_SLAVE_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_V2_PROC, SeafileCheckTxSlaveV2Proc)) -#define SEAFILE_IS_CHECK_TX_SLAVE_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_V2_PROC)) -#define SEAFILE_CHECK_TX_SLAVE_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECK_TX_SLAVE_V2_PROC, SeafileCheckTxSlaveV2ProcClass)) -#define IS_SEAFILE_CHECK_TX_SLAVE_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECK_TX_SLAVE_V2_PROC)) -#define SEAFILE_CHECK_TX_SLAVE_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_V2_PROC, SeafileCheckTxSlaveV2ProcClass)) - -typedef struct _SeafileCheckTxSlaveV2Proc SeafileCheckTxSlaveV2Proc; -typedef struct _SeafileCheckTxSlaveV2ProcClass SeafileCheckTxSlaveV2ProcClass; - -struct _SeafileCheckTxSlaveV2Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafileCheckTxSlaveV2ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_check_tx_slave_v2_proc_get_type (); - -#endif diff --git a/server/processors/check-tx-slave-v3-proc.c b/server/processors/check-tx-slave-v3-proc.c deleted file mode 100644 index 04e902c..0000000 --- a/server/processors/check-tx-slave-v3-proc.c +++ /dev/null @@ -1,473 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include "seafile-session.h" -#include "utils.h" - -#include "check-tx-slave-v3-proc.h" - -#define SC_GET_TOKEN "301" -#define SS_GET_TOKEN "Get token" -#define SC_PUT_TOKEN "302" -#define SS_PUT_TOKEN "Put token" -#define SC_GET_VERSION "303" -#define SS_GET_VERSION "Get version" -#define SC_VERSION "304" -#define SS_VERSION "Version" - -#define SC_ACCESS_DENIED "401" -#define SS_ACCESS_DENIED "Access denied" -#define SC_SERVER_ERROR "404" -#define SS_SERVER_ERROR "Internal server error" -#define SC_PROTOCOL_MISMATCH "405" -#define SS_PROTOCOL_MISMATCH "Protocol version mismatch" - -/* Only for upload */ -#define SC_QUOTA_ERROR "402" -#define SS_QUOTA_ERROR "Failed to get quota" -#define SC_QUOTA_FULL "403" -#define SS_QUOTA_FULL "storage for the repo's owner is full" - -/* Only for download */ -#define SC_BAD_REPO "406" -#define SS_BAD_REPO "Repo doesn't exist" -#define SC_NO_BRANCH "407" -#define SS_NO_BRANCH "Branch not found" - -enum { - INIT, - ACCESS_GRANTED, -}; - -enum { - CHECK_TX_TYPE_UPLOAD, - CHECK_TX_TYPE_DOWNLOAD, -}; - -typedef struct { - int type; - - char repo_id[37]; - char *branch_name; - char *token; - char *session_key; - char *peer_addr; - char *peer_name; - int client_version; - - char *rsp_code; - char *rsp_msg; - char head_id[41]; - int has_branch; - - char *user; - char orig_repo_id[37]; - char *orig_path; -} SeafileCheckTxSlaveV3ProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_CHECK_TX_SLAVE_V3_PROC, SeafileCheckTxSlaveV3ProcPriv)) - -#define USE_PRIV \ - SeafileCheckTxSlaveV3ProcPriv *priv = GET_PRIV(processor); - -G_DEFINE_TYPE (SeafileCheckTxSlaveV3Proc, seafile_check_tx_slave_v3_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void thread_done (void *result); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - /* g_free works fine even if ptr is NULL. */ - g_free (priv->token); - g_free (priv->session_key); - g_free (priv->peer_addr); - g_free (priv->peer_name); - g_free (priv->branch_name); - g_free (priv->rsp_code); - g_free (priv->rsp_msg); - g_free (priv->user); - g_free (priv->orig_path); - - CCNET_PROCESSOR_CLASS (seafile_check_tx_slave_v3_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_check_tx_slave_v3_proc_class_init (SeafileCheckTxSlaveV3ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "check-tx-slave-v3-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileCheckTxSlaveV3ProcPriv)); -} - -static void -seafile_check_tx_slave_v3_proc_init (SeafileCheckTxSlaveV3Proc *processor) -{ -} - -static void -get_branch_head (CcnetProcessor *processor) -{ - SeafBranch *branch; - USE_PRIV; - - branch = seaf_branch_manager_get_branch (seaf->branch_mgr, - priv->repo_id, priv->branch_name); - if (branch != NULL) { - priv->has_branch = 1; - memcpy (priv->head_id, branch->commit_id, 41); - seaf_branch_unref (branch); - - priv->rsp_code = g_strdup(SC_OK); - priv->rsp_msg = g_strdup(SS_OK); - } else if (priv->type == CHECK_TX_TYPE_UPLOAD) { - priv->rsp_code = g_strdup(SC_OK); - priv->rsp_msg = g_strdup(SS_OK); - } else { - priv->rsp_code = g_strdup(SC_NO_BRANCH); - priv->rsp_msg = g_strdup(SS_NO_BRANCH); - } -} - -static int -decrypt_token (CcnetProcessor *processor) -{ - USE_PRIV; - int hex_len, encrypted_len, token_len; - char *encrypted_token = NULL; - SeafileCrypt *crypt = NULL; - unsigned char key[16], iv[16]; - char *token = NULL; - int ret = 0; - - /* raw data is half the length of hexidecimal */ - hex_len = strlen(priv->token); - if (hex_len % 2 != 0) { - seaf_warning ("[check tx slave v3] invalid length of encrypted token\n"); - ret = -1; - goto out; - } - - encrypted_len = hex_len / 2; - encrypted_token = g_malloc (encrypted_len); - hex_to_rawdata (priv->token, - (unsigned char *)encrypted_token, - encrypted_len); - - EVP_BytesToKey (EVP_aes_128_cbc(), /* cipher mode */ - EVP_sha1(), /* message digest */ - NULL, /* slat */ - (unsigned char*)priv->session_key, - strlen(priv->session_key), - 1, /* iteration times */ - key, /* the derived key */ - iv); /* IV, initial vector */ - - crypt = seafile_crypt_new (1, key, iv); - - if (seafile_decrypt (&token, &token_len, encrypted_token, - encrypted_len, crypt) < 0) { - seaf_warning ("[check tx slave v3] failed to decrypt token\n"); - ret = -1; - goto out; - } - - g_free (priv->token); - /* we can use the decrypted data directly, since the trailing null byte is - * also included when encrypting in the client */ - priv->token = token; - -out: - g_free (crypt); - g_free (encrypted_token); - - return ret; -} - -static void * -check_tx (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - char *user = NULL; - char *repo_id = priv->repo_id; - SeafRepo *repo = NULL; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - priv->rsp_code = g_strdup(SC_BAD_REPO); - priv->rsp_msg = g_strdup(SS_BAD_REPO); - goto out; - } - - if (repo->repaired) { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - goto out; - } - - if (repo->version > 0 && priv->client_version < 6) { - seaf_warning ("Client protocol version is %d, " - "cannot sync version %d repo %s.\n", - priv->client_version, repo->version, repo_id); - priv->rsp_code = g_strdup(SC_PROTOCOL_MISMATCH); - priv->rsp_msg = g_strdup(SS_PROTOCOL_MISMATCH); - goto out; - } - - if (decrypt_token (processor) < 0) { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - goto out; - } - - user = seaf_repo_manager_get_email_by_token ( - seaf->repo_mgr, repo_id, priv->token); - - if (!user) { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - goto out; - } - - if (priv->type == CHECK_TX_TYPE_UPLOAD && - seaf_quota_manager_check_quota (seaf->quota_mgr, repo_id) < 0) { - priv->rsp_code = g_strdup(SC_QUOTA_FULL); - priv->rsp_msg = g_strdup(SS_QUOTA_FULL); - goto out; - } - - char *perm = seaf_repo_manager_check_permission (seaf->repo_mgr, - repo_id, user, NULL); - if (!perm || - (strcmp (perm, "r") == 0 && priv->type == CHECK_TX_TYPE_UPLOAD)) - { - priv->rsp_code = g_strdup(SC_ACCESS_DENIED); - priv->rsp_msg = g_strdup(SS_ACCESS_DENIED); - g_free (perm); - goto out; - } - g_free (perm); - - /* Record the (token, email, ) information, may - * include peer_id, peer_ip, peer_name, etc. - */ - if (!seaf_repo_manager_token_peer_info_exists (seaf->repo_mgr, priv->token)) - seaf_repo_manager_add_token_peer_info (seaf->repo_mgr, - priv->token, - processor->peer_id, - priv->peer_addr, - priv->peer_name, - (gint64)time(NULL), NULL); - else - seaf_repo_manager_update_token_peer_info (seaf->repo_mgr, - priv->token, - priv->peer_addr, - (gint64)time(NULL), NULL); - - get_branch_head (processor); - - /* Fill information for sending events. */ - priv->user = g_strdup(user); - if (repo->virtual_info) { - memcpy (priv->orig_repo_id, repo->virtual_info->origin_repo_id, 36); - priv->orig_path = g_strdup(repo->virtual_info->path); - } else - memcpy (priv->orig_repo_id, repo_id, 36); - -out: - seaf_repo_unref (repo); - g_free (user); - return vprocessor; -} - -static void -publish_repo_event (CcnetProcessor *processor, const char *etype) -{ - USE_PRIV; - GString *buf; - - if (!priv->user) - return; - - buf = g_string_new (NULL); - g_string_printf (buf, "%s\t%s\t%s\t%s\t%s\t%s", - etype, priv->user, priv->peer_addr, - priv->peer_name, priv->orig_repo_id, - priv->orig_path ? priv->orig_path : "/"); - - seaf_mq_manager_publish_event (seaf->mq_mgr, buf->str); - - g_string_free (buf, TRUE); -} - -static void -thread_done (void *result) -{ - CcnetProcessor *processor = result; - USE_PRIV; - - if (strcmp (priv->rsp_code, SC_OK) == 0) { - if (priv->has_branch) { - ccnet_processor_send_response (processor, - SC_OK, SS_OK, - priv->head_id, 41); - } else - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - processor->state = ACCESS_GRANTED; - - if (priv->type == CHECK_TX_TYPE_DOWNLOAD) - publish_repo_event (processor, "repo-download-sync"); - else if (priv->type == CHECK_TX_TYPE_UPLOAD) - publish_repo_event (processor, "repo-upload-sync"); - } else { - ccnet_processor_send_response (processor, - priv->rsp_code, priv->rsp_msg, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char *repo_id, *token; - USE_PRIV; - - if (argc != 5) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (strcmp (argv[0], "upload") == 0) { - priv->type = CHECK_TX_TYPE_UPLOAD; - } else if (strcmp (argv[0], "download") == 0) { - priv->type = CHECK_TX_TYPE_DOWNLOAD; - } else { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - int client_version = atoi(argv[1]); - if (client_version < 5) { - seaf_debug ("Client protocol version lower than 5, not supported.\n"); - ccnet_processor_send_response (processor, - SC_PROTOCOL_MISMATCH, SS_PROTOCOL_MISMATCH, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - repo_id = argv[2]; - token = argv[4]; - - if (!is_uuid_valid(repo_id)) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->repo_id, repo_id, 37); - priv->branch_name = g_strdup("master"); - - priv->token = g_strdup(token); - priv->client_version = client_version; - - CcnetPeer *peer = ccnet_get_peer (seaf->ccnetrpc_client, processor->peer_id); - if (!peer || !peer->session_key) { - seaf_warning ("[check tx slave v3] session key of peer %.10s is null\n", - processor->peer_id); - ccnet_processor_send_response (processor, SC_BAD_PEER, SS_BAD_PEER, NULL, 0); - ccnet_processor_done (processor, FALSE); - if (peer) - g_object_unref (peer); - return -1; - } - - priv->session_key = g_strdup(peer->session_key); - priv->peer_addr = g_strdup(peer->addr_str); - priv->peer_name = g_strdup(peer->name); - if (!priv->peer_name) - priv->peer_name = g_strdup("Unknown"); - g_object_unref (peer); - - seaf_debug ("[check-tx] %s repo %.8s.\n", argv[0], repo_id); - - ccnet_processor_thread_create (processor, seaf->job_mgr, - check_tx, thread_done, processor); - - return 0; -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - char *token; - - if (processor->state != ACCESS_GRANTED) { - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - if (strncmp (code, SC_GET_TOKEN, 3) == 0) { - token = seaf_token_manager_generate_token (seaf->token_mgr, - processor->peer_id, - priv->repo_id); - ccnet_processor_send_response (processor, - SC_PUT_TOKEN, SS_PUT_TOKEN, - token, strlen(token) + 1); - g_free (token); - return; - } else if (strncmp (code, SC_GET_VERSION, 3) == 0) { - char buf[16]; - int len; - len = snprintf (buf, sizeof(buf), "%d", CURRENT_PROTO_VERSION); - ccnet_processor_send_response (processor, - SC_VERSION, SS_VERSION, - buf, len + 1); - ccnet_processor_done (processor, TRUE); - return; - } - - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); -} - diff --git a/server/processors/check-tx-slave-v3-proc.h b/server/processors/check-tx-slave-v3-proc.h deleted file mode 100644 index add1b31..0000000 --- a/server/processors/check-tx-slave-v3-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_CHECK_TX_SLAVE_V3_PROC_H -#define SEAFILE_CHECK_TX_SLAVE_V3_PROC_H - -#include -#include - -#define SEAFILE_TYPE_CHECK_TX_SLAVE_V3_PROC (seafile_check_tx_slave_v3_proc_get_type ()) -#define SEAFILE_CHECK_TX_SLAVE_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_V3_PROC, SeafileCheckTxSlaveV3Proc)) -#define SEAFILE_IS_CHECK_TX_SLAVE_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_V3_PROC)) -#define SEAFILE_CHECK_TX_SLAVE_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECK_TX_SLAVE_V3_PROC, SeafileCheckTxSlaveV3ProcClass)) -#define IS_SEAFILE_CHECK_TX_SLAVE_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECK_TX_SLAVE_V3_PROC)) -#define SEAFILE_CHECK_TX_SLAVE_V3_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECK_TX_SLAVE_V3_PROC, SeafileCheckTxSlaveV3ProcClass)) - -typedef struct _SeafileCheckTxSlaveV3Proc SeafileCheckTxSlaveV3Proc; -typedef struct _SeafileCheckTxSlaveV3ProcClass SeafileCheckTxSlaveV3ProcClass; - -struct _SeafileCheckTxSlaveV3Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafileCheckTxSlaveV3ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_check_tx_slave_v3_proc_get_type (); - -#endif diff --git a/server/processors/checkbl-proc.c b/server/processors/checkbl-proc.c deleted file mode 100644 index 58ad1c1..0000000 --- a/server/processors/checkbl-proc.c +++ /dev/null @@ -1,245 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "seafile-session.h" -#include "checkbl-proc.h" -#include "log.h" - -#define SC_BLOCK_LIST "301" -#define SS_BLOCK_LIST "Block list" -#define SC_NEED_BLOCKS "302" -#define SS_NEED_BLOCKS "Needed blocks" -#define SC_BLOCK_LIST_END "303" -#define SS_BLOCK_LIST_END "Block list end" - -#define SC_ACCESS_DENIED "401" -#define SS_ACCESS_DENIED "Access denied" - -typedef struct { - gboolean processing; - char *block_list; - int len; - GString *buf; - gboolean success; - - gboolean no_repo_info; - - /* Used for getting repo info */ - char repo_id[37]; - char store_id[37]; - int repo_version; -} SeafileCheckblProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_CHECKBL_PROC, SeafileCheckblProcPriv)) - -#define USE_PRIV \ - SeafileCheckblProcPriv *priv = GET_PRIV(processor); - - -G_DEFINE_TYPE (SeafileCheckblProc, seafile_checkbl_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - g_free (priv->block_list); - if (priv->buf) - g_string_free (priv->buf, TRUE); - - CCNET_PROCESSOR_CLASS (seafile_checkbl_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_checkbl_proc_class_init (SeafileCheckblProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileCheckblProcPriv)); -} - -static void -seafile_checkbl_proc_init (SeafileCheckblProc *processor) -{ -} - -static void * -get_repo_info_thread (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %s.\n", priv->repo_id); - priv->success = FALSE; - return data; - } - - memcpy (priv->store_id, repo->store_id, 36); - priv->repo_version = repo->version; - priv->success = TRUE; - - seaf_repo_unref (repo); - return data; -} - -static void -get_repo_info_done (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (priv->success) { - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - } else { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - - priv->success = FALSE; -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - - if (argc == 0) { - /* To be compatible with older clients (protocol version < 6). - * However older clients can only sync repos with version 0. - * So there is no need to know the repo id. - */ - priv->no_repo_info = TRUE; - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - return 0; - } else { - priv->no_repo_info = FALSE; - - char *session_token = argv[0]; - - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, priv->repo_id) < 0) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - ccnet_processor_thread_create (processor, - seaf->job_mgr, - get_repo_info_thread, - get_repo_info_done, - processor); - } - - return 0; -} - -static void * -check_bl (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - priv->buf = g_string_new (""); - int offset = 0; - char block_id[41]; - while (offset < priv->len) { - memcpy (block_id, &priv->block_list[offset], 40); - block_id[40] = 0; - - if (priv->no_repo_info) { - if (!seaf_block_manager_block_exists(seaf->block_mgr, - NULL, 0, - block_id)) - g_string_append (priv->buf, block_id); - } else { - if (!seaf_block_manager_block_exists(seaf->block_mgr, - priv->store_id, - priv->repo_version, - block_id)) - g_string_append (priv->buf, block_id); - } - - offset += 40; - } - - priv->success = TRUE; - return vprocessor; -} - -static void -check_bl_done (void *result) -{ - CcnetProcessor *processor = result; - USE_PRIV; - - if (priv->success) { - ccnet_processor_send_response (processor, SC_NEED_BLOCKS, SS_NEED_BLOCKS, - priv->buf->str, priv->buf->len); - - priv->processing = FALSE; - g_free (priv->block_list); - priv->block_list = NULL; - g_string_free (priv->buf, TRUE); - priv->buf = NULL; - priv->success = FALSE; - } else { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - - if (memcmp (code, SC_BLOCK_LIST, 3) == 0) { - /* We can't process more than one block list segments at the same time. */ - if (priv->processing) { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - if (clen == 0 || clen % 40 != 0) { - seaf_warning ("Bad block list length %d.\n", priv->len); - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - priv->processing = TRUE; - priv->block_list = g_memdup (content, clen); - priv->len = clen; - ccnet_processor_thread_create (processor, seaf->job_mgr, - check_bl, check_bl_done, processor); - } else if (memcmp (code, SC_BLOCK_LIST_END, 3) == 0) { - ccnet_processor_done (processor, TRUE); - } else { - seaf_warning ("Bad update: %s %s.\n", code, code_msg); - ccnet_processor_done (processor, FALSE); - } -} diff --git a/server/processors/checkbl-proc.h b/server/processors/checkbl-proc.h deleted file mode 100644 index c67c837..0000000 --- a/server/processors/checkbl-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_CHECKBL_PROC_H -#define SEAFILE_CHECKBL_PROC_H - -#include - - -#define SEAFILE_TYPE_CHECKBL_PROC (seafile_checkbl_proc_get_type ()) -#define SEAFILE_CHECKBL_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECKBL_PROC, SeafileCheckblProc)) -#define SEAFILE_IS_CHECKBL_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECKBL_PROC)) -#define SEAFILE_CHECKBL_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECKBL_PROC, SeafileCheckblProcClass)) -#define IS_SEAFILE_CHECKBL_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECKBL_PROC)) -#define SEAFILE_CHECKBL_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECKBL_PROC, SeafileCheckblProcClass)) - -typedef struct _SeafileCheckblProc SeafileCheckblProc; -typedef struct _SeafileCheckblProcClass SeafileCheckblProcClass; - -struct _SeafileCheckblProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileCheckblProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_checkbl_proc_get_type (); - -#endif - diff --git a/server/processors/checkff-proc.c b/server/processors/checkff-proc.c deleted file mode 100644 index f07315e..0000000 --- a/server/processors/checkff-proc.c +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include "seafile-session.h" -#include "checkff-proc.h" -#include "log.h" - -typedef struct { - char repo_id[37]; - char root_id[41]; - int result; -} SeafileCheckffProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_CHECKFF_PROC, SeafileCheckffProcPriv)) - -#define USE_PRIV \ - SeafileCheckffProcPriv *priv = GET_PRIV(processor); - -G_DEFINE_TYPE (SeafileCheckffProc, seafile_checkff_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static void -release_resource(CcnetProcessor *processor) -{ - - CCNET_PROCESSOR_CLASS (seafile_checkff_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_checkff_proc_class_init (SeafileCheckffProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileCheckffProcPriv)); -} - -static void -seafile_checkff_proc_init (SeafileCheckffProc *processor) -{ -} - -typedef struct { - gboolean fast_forward; - char root_id[41]; -} CompareAux; - -static gboolean -compare_root (SeafCommit *commit, void *data, gboolean *stop) -{ - CompareAux *aux = data; - - /* If we've found a match in another branch, stop traversing. */ - if (aux->fast_forward) { - *stop = TRUE; - return TRUE; - } - - if (strcmp (commit->root_id, aux->root_id) == 0) { - aux->fast_forward = TRUE; - *stop = TRUE; - } - - return TRUE; -} - -static gboolean -check_fast_forward (SeafRepo *repo, const char *head_id, const char *root_id) -{ - CompareAux *aux = g_new0 (CompareAux, 1); - gboolean ret; - - memcpy (aux->root_id, root_id, 41); - if (!seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, - repo->id, - repo->version, - head_id, - compare_root, - aux, FALSE)) { - g_free (aux); - return FALSE; - } - - ret = aux->fast_forward; - g_free (aux); - return ret; -} - -static void * -check_fast_forward_thread (void *vdata) -{ - CcnetProcessor *processor = vdata; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Cannot find repo %s.\n", priv->repo_id); - priv->result = 0; - return vdata; - } - - priv->result = check_fast_forward (repo, repo->head->commit_id, priv->root_id); - - seaf_repo_unref (repo); - return vdata; -} - -static void -check_fast_forward_done (void *vdata) -{ - CcnetProcessor *processor = vdata; - USE_PRIV; - char res[10]; - - snprintf (res, sizeof(res), "%d", priv->result); - - seaf_message ("res is %s.\n", res); - - ccnet_processor_send_response (processor, SC_OK, SS_OK, res, strlen(res)+1); - ccnet_processor_done (processor, TRUE); -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - char *repo_id, *root_id; - - if (argc < 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - repo_id = argv[0]; - root_id = argv[1]; - if (strlen(repo_id) != 36 || !is_uuid_valid(repo_id) || strlen(root_id) != 40) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->repo_id, repo_id, 36); - memcpy (priv->root_id, root_id, 40); - - ccnet_processor_thread_create (processor, - seaf->job_mgr, - check_fast_forward_thread, - check_fast_forward_done, - processor); - return 0; -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - -} diff --git a/server/processors/checkff-proc.h b/server/processors/checkff-proc.h deleted file mode 100644 index 0a84bd4..0000000 --- a/server/processors/checkff-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_CHECKFF_PROC_H -#define SEAFILE_CHECKFF_PROC_H - -#include - - -#define SEAFILE_TYPE_CHECKFF_PROC (seafile_checkff_proc_get_type ()) -#define SEAFILE_CHECKFF_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECKFF_PROC, SeafileCheckffProc)) -#define SEAFILE_IS_CHECKFF_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECKFF_PROC)) -#define SEAFILE_CHECKFF_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECKFF_PROC, SeafileCheckffProcClass)) -#define IS_SEAFILE_CHECKFF_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECKFF_PROC)) -#define SEAFILE_CHECKFF_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECKFF_PROC, SeafileCheckffProcClass)) - -typedef struct _SeafileCheckffProc SeafileCheckffProc; -typedef struct _SeafileCheckffProcClass SeafileCheckffProcClass; - -struct _SeafileCheckffProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileCheckffProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_checkff_proc_get_type (); - -#endif - diff --git a/server/processors/heartbeat-proc.c b/server/processors/heartbeat-proc.c deleted file mode 100644 index c9e1cd0..0000000 --- a/server/processors/heartbeat-proc.c +++ /dev/null @@ -1,274 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include -#include "seafile-session.h" -#include "heartbeat-proc.h" - -/* - * Block sizes update algorithm: - * - * 1. When heartbeat starts, it send the list of all current blocks to monitor; - * 2. When a new block is sent to this chunk server, heartbeat will receive - * a signal from block manager. It will add the block metadata into - * priv->block_metadata_new queue. If more than 30 block metadata have been - * queued, heartbeat proc will send the list to monitor. - * 3. On an idle chunk server, it may take long time to queue 30 blocks. - * To keep the monitor up-to-date, a flush timer is scheduled to flush - * block info to monitor every 30 seconds. - */ - -#define FLUSH_INTERVAL_MSEC 30 * 1000 - -#define SC_BLOCK_INFO "301" -#define SS_BLOCK_INFO "Block info" - -/* - Master Slave - - seafile-heartbeat - -----------------------------> - OK - <----------------------------- - - Block Info - -----------------------------> - - Block Info - -----------------------------> - ... - - */ - -typedef struct { - GList *block_metadata_old; - GList *block_metadata_new; - int new_blocks; - CcnetTimer *flush_timer; -} SeafileHeartbeatProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_HEARTBEAT_PROC, SeafileHeartbeatProcPriv)) - -#define USE_PRIV \ - SeafileHeartbeatProcPriv *priv = GET_PRIV(processor); - - -G_DEFINE_TYPE (SeafileHeartbeatProc, seafile_heartbeat_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_response (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static void *collect_block_sizes (void *vprocessor); -static void collect_block_sizes_done (CcnetProcessor *processor, - int status, - char *message); -static void on_block_added (SeafBlockManager *block_mgr, - const char *block_id, - void *vprocessor); -static int flush_block_sizes (void *vprocessor); -static void free_md_list (GList *md_list); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->block_metadata_old) - free_md_list (priv->block_metadata_old); - if (priv->block_metadata_new) - free_md_list (priv->block_metadata_new); - - g_signal_handlers_disconnect_by_func (seaf->block_mgr, on_block_added, processor); - ccnet_timer_free (&priv->flush_timer); - - CCNET_PROCESSOR_CLASS (seafile_heartbeat_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_heartbeat_proc_class_init (SeafileHeartbeatProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "heartbeat-proc"; - proc_class->start = start; - proc_class->handle_response = handle_response; - proc_class->handle_thread_done = collect_block_sizes_done; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileHeartbeatProcPriv)); -} - -static void -seafile_heartbeat_proc_init (SeafileHeartbeatProc *processor) -{ -} - - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char buf[256]; - - snprintf (buf, sizeof(buf), "remote %s seafile-heartbeat", - processor->peer_id); - ccnet_processor_send_request (processor, buf); - - return 0; -} - - -static void -handle_response (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - int rc; - - if (strncmp (code, SC_OK, 3) == 0) { - rc = ccnet_processor_thread_create (processor, - collect_block_sizes, - NULL); - if (rc < 0) { - g_warning ("[heartbeat] failed to create thread.\n"); - ccnet_processor_done (processor, FALSE); - } - - g_signal_connect (seaf->block_mgr, "block-added", - (GCallback)on_block_added, - processor); - - priv->flush_timer = ccnet_timer_new (flush_block_sizes, - processor, - FLUSH_INTERVAL_MSEC); - } else { - g_warning ("[heartbeat] Bad response: %s %s\n", code, code_msg); - ccnet_processor_done (processor, FALSE); - } -} - -static void -send_block_sizes (CcnetProcessor *processor, GList *metadata) -{ - char buf[2048]; - char *ptr = buf; - int count = 0, n; - GList *md_list = metadata; - BlockMetadata *md; - - while (md_list) { - md = md_list->data; - md_list = g_list_delete_link (md_list, md_list); - - n = snprintf (ptr, 60, "%s %u\n", md->id, md->size); - ptr += n; - - if (++count == 30) { - ccnet_processor_send_update (processor, - SC_BLOCK_INFO, SS_BLOCK_INFO, - buf, (ptr - buf) + 1); - count = 0; - ptr = buf; - } - g_free (md); - } - - if (count) { - ccnet_processor_send_update (processor, - SC_BLOCK_INFO, SS_BLOCK_INFO, - buf, (ptr - buf) + 1); - } -} - -static void * -collect_block_sizes (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - GList *metadata_list; - USE_PRIV; - - metadata_list = seaf_block_manager_get_all_block_metadata (seaf->block_mgr); - /* if (!metadata_list) { */ - /* ccnet_processor_thread_done (processor, -1, NULL); */ - /* return NULL; */ - /* } */ - - priv->block_metadata_old = metadata_list; - ccnet_processor_thread_done (processor, 0, NULL); - return NULL; -} - -static void -collect_block_sizes_done (CcnetProcessor *processor, - int status, - char *message) -{ - USE_PRIV; - - if (status == 0) { - g_message ("[hearbeat] collected block sizes on start.\n"); - send_block_sizes (processor, priv->block_metadata_old); - priv->block_metadata_old = NULL; - } else { - g_warning ("Failed to collect block sizes.\n"); - ccnet_processor_done (processor, FALSE); - } -} - -static void -on_block_added (SeafBlockManager *block_mgr, - const char *block_id, - void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - BlockMetadata *md; - USE_PRIV; - - md = seaf_block_manager_stat_block (block_mgr, block_id); - if (!md) { - g_warning ("[heartbeat] Failed to stat block %s\n", block_id); - return; - } - - g_message ("Queue block %s, size is %u\n", block_id, md->size); - - priv->block_metadata_new = g_list_prepend (priv->block_metadata_new, md); - if (++priv->new_blocks == 30) { - send_block_sizes (processor, priv->block_metadata_new); - priv->block_metadata_new = NULL; - priv->new_blocks = 0; - } -} - -static int -flush_block_sizes (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - if (priv->new_blocks != 0) { - g_message ("Flushing %u blocks to monitor.\n", priv->new_blocks); - send_block_sizes (processor, priv->block_metadata_new); - priv->block_metadata_new = NULL; - priv->new_blocks = 0; - } - - return 1; -} - -static void -free_md_list (GList *md_list) -{ - BlockMetadata *md; - - while (md_list) { - md = md_list->data; - md_list = g_list_delete_link (md_list, md_list); - g_free (md); - } -} diff --git a/server/processors/heartbeat-proc.h b/server/processors/heartbeat-proc.h deleted file mode 100644 index f229e78..0000000 --- a/server/processors/heartbeat-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_HEARTBEAT_PROC_H -#define SEAFILE_HEARTBEAT_PROC_H - -#include -#include - -#define SEAFILE_TYPE_HEARTBEAT_PROC (seafile_heartbeat_proc_get_type ()) -#define SEAFILE_HEARTBEAT_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_HEARTBEAT_PROC, SeafileHeartbeatProc)) -#define SEAFILE_IS_HEARTBEAT_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_HEARTBEAT_PROC)) -#define SEAFILE_HEARTBEAT_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_HEARTBEAT_PROC, SeafileHeartbeatProcClass)) -#define IS_SEAFILE_HEARTBEAT_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_HEARTBEAT_PROC)) -#define SEAFILE_HEARTBEAT_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_HEARTBEAT_PROC, SeafileHeartbeatProcClass)) - -typedef struct _SeafileHeartbeatProc SeafileHeartbeatProc; -typedef struct _SeafileHeartbeatProcClass SeafileHeartbeatProcClass; - -struct _SeafileHeartbeatProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileHeartbeatProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_heartbeat_proc_get_type (); - -#endif - diff --git a/server/processors/put-sharedb-proc.c b/server/processors/put-sharedb-proc.c deleted file mode 100644 index 4395b8a..0000000 --- a/server/processors/put-sharedb-proc.c +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include -#include -#include "db.h" -#include "seafile-session.h" -#include "share-info.h" -#include "share-mgr.h" -#include "share-mgr-priv.h" -#include "put-sharedb-proc.h" - -static int put_sharedb_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -typedef struct { - char *share_id; - GList *sinfos; - GList *ptr; -} PutSharedbPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_PUT_SHAREDB_PROC, PutSharedbPriv)) - -#define USE_PRIV \ - PutSharedbPriv *priv = GET_PRIV(processor); - - -G_DEFINE_TYPE (PutSharedbProc, put_sharedb_proc, CCNET_TYPE_PROCESSOR) - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->share_id) - g_free (priv->share_id); - - CCNET_PROCESSOR_CLASS (put_sharedb_proc_parent_class)->release_resource(processor); -} - - -static void -put_sharedb_proc_class_init (PutSharedbProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "put-sharedb-proc"; - proc_class->start = put_sharedb_start; - - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof(PutSharedbPriv)); -} - -static void -put_sharedb_proc_init (PutSharedbProc *processor) -{ -} - -/* return TRUE if more info to send, FALSE otherwise */ -static gboolean -send_share_info (CcnetProcessor *processor) -{ - USE_PRIV; - - if (!priv->ptr) - return FALSE; - - SeafShareInfo *info = priv->ptr->data; - char *s = seaf_share_info_to_json(info); - - ccnet_processor_send_response (processor, "301", "ShareInfo", - s, strlen(s)+1); - priv->ptr = priv->ptr->next; - return TRUE; -} - -static void -prepare_put_share_db (CcnetProcessor *processor) -{ - USE_PRIV; - - priv->sinfos = seaf_share_manager_get_group_share_info ( - seaf->share_mgr, priv->share_id); - priv->ptr = priv->sinfos; -} - -static int -put_sharedb_start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - - if (argc != 1) { - ccnet_processor_send_response (processor, "401", "Bad arguments", - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - priv->share_id = g_strdup(argv[0]); - - prepare_put_share_db (processor); - if (!priv->sinfos) { - /* we do not have any items to send to peer */ - ccnet_processor_send_response (processor, "302", "END", NULL, 0); - ccnet_processor_done (processor, TRUE); - return 0; - } - - send_share_info(processor); - - return 0; -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - - if (memcmp (code, "200", 3) != 0) { - g_warning ("[send-sharedb] received bad respones %s: %s\n", - code, code_msg); - ccnet_processor_done (processor, FALSE); - return; - } - - if (send_share_info(processor) == FALSE) { - ccnet_processor_send_response (processor, "302", "END", NULL, 0); - ccnet_processor_done (processor, TRUE); - } - - return; -} diff --git a/server/processors/put-sharedb-proc.h b/server/processors/put-sharedb-proc.h deleted file mode 100644 index 14fbc6c..0000000 --- a/server/processors/put-sharedb-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef PUT_SHAREDB_PROC_H -#define PUT_SHAREDB_PROC_H - -#include - -#include - -#define SEAFILE_TYPE_PUT_SHAREDB_PROC (put_sharedb_proc_get_type ()) -#define PUT_SHAREDB_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECKIN_PROC, PutSharedbProc)) -#define SEAFILE_IS_CHECKIN_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECKIN_PROC)) -#define PUT_SHAREDB_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECKIN_PROC, PutSharedbProcClass)) -#define IS_PUT_SHAREDB_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECKIN_PROC)) -#define PUT_SHAREDB_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECKIN_PROC, PutSharedbProcClass)) - -typedef struct _PutSharedbProc PutSharedbProc; -typedef struct _PutSharedbProcClass PutSharedbProcClass; - -struct _PutSharedbProc { - CcnetProcessor parent_instance; -}; - -struct _PutSharedbProcClass { - CcnetProcessorClass parent_class; -}; - -GType put_sharedb_proc_get_type (); - -#endif diff --git a/server/processors/putbranch-proc.c b/server/processors/putbranch-proc.c deleted file mode 100644 index 6e954eb..0000000 --- a/server/processors/putbranch-proc.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - - -#include "putbranch-proc.h" - -G_DEFINE_TYPE (SeafilePutbranchProc, seafile_putbranch_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static void -release_resource(CcnetProcessor *processor) -{ - /* FILL IT */ - - CCNET_PROCESSOR_CLASS (seafile_putbranch_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_putbranch_proc_class_init (SeafilePutbranchProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putbranch-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; -} - -static void -seafile_putbranch_proc_init (SeafilePutbranchProc *processor) -{ -} - - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - - - return 0; -} - - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - -} diff --git a/server/processors/putbranch-proc.h b/server/processors/putbranch-proc.h deleted file mode 100644 index 914b7e5..0000000 --- a/server/processors/putbranch-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTBRANCH_PROC_H -#define SEAFILE_PUTBRANCH_PROC_H - -#include - - -#define SEAFILE_TYPE_PUTBRANCH_PROC (seafile_putbranch_proc_get_type ()) -#define SEAFILE_PUTBRANCH_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTBRANCH_PROC, SeafilePutbranchProc)) -#define SEAFILE_IS_PUTBRANCH_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTBRANCH_PROC)) -#define SEAFILE_PUTBRANCH_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTBRANCH_PROC, SeafilePutbranchProcClass)) -#define IS_SEAFILE_PUTBRANCH_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTBRANCH_PROC)) -#define SEAFILE_PUTBRANCH_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTBRANCH_PROC, SeafilePutbranchProcClass)) - -typedef struct _SeafilePutbranchProc SeafilePutbranchProc; -typedef struct _SeafilePutbranchProcClass SeafilePutbranchProcClass; - -struct _SeafilePutbranchProc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutbranchProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putbranch_proc_get_type (); - -#endif - diff --git a/server/processors/putca-proc.c b/server/processors/putca-proc.c deleted file mode 100644 index d8a5755..0000000 --- a/server/processors/putca-proc.c +++ /dev/null @@ -1,269 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include -#include "utils.h" - -#include "seafile-session.h" -#include "putca-proc.h" - -typedef struct { - char repo_id[37]; - char *token; - GHashTable *commit_hash; - - gboolean token_valid; - char ca_id[41]; -} SeafilePutcaProcPriv; - -#define SC_ID_LIST "301" -#define SS_ID_LIST "Commit id list" -#define SC_ID_LIST_END "302" -#define SS_ID_LIST_END "Commit id list end" -#define SC_CA "303" -#define SS_CA "Common ancestor" - -#define SC_ACCESS_DENIED "401" -#define SS_ACCESS_DENIED "Access denied" -#define SC_NO_CA "404" -#define SS_NO_CA "No common ancestor found" - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_PUTCA_PROC, SeafilePutcaProcPriv)) - -#define USE_PRIV \ - SeafilePutcaProcPriv *priv = GET_PRIV(processor); - -static int put_ca_start (CcnetProcessor *processor, int argc, char **argv); -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -G_DEFINE_TYPE (SeafilePutcaProc, seafile_putca_proc, CCNET_TYPE_PROCESSOR) - -static void -release_resource (CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->commit_hash) - g_hash_table_destroy (priv->commit_hash); - if (priv->token) - g_free (priv->token); - - CCNET_PROCESSOR_CLASS (seafile_putca_proc_parent_class)->release_resource (processor); -} - -static void -seafile_putca_proc_class_init (SeafilePutcaProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putca-proc"; - proc_class->start = put_ca_start; - proc_class->release_resource = release_resource; - proc_class->handle_update = handle_update; - - g_type_class_add_private (klass, sizeof (SeafilePutcaProcPriv)); -} - -static void -seafile_putca_proc_init (SeafilePutcaProc *processor) -{ -} - -static void * -check_token_thread (void *vdata) -{ - CcnetProcessor *processor = vdata; - USE_PRIV; - char *user; - - user = seaf_repo_manager_get_email_by_token ( - seaf->repo_mgr, priv->repo_id, priv->token); - if (!user) { - priv->token_valid = FALSE; - return vdata; - } - - g_free (user); - priv->token_valid = TRUE; - return vdata; -} - -static void -check_token_thread_done (void *vdata) -{ - CcnetProcessor *processor = vdata; - USE_PRIV; - - if (!priv->token_valid) { - ccnet_processor_send_response (processor, SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } else { - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - priv->commit_hash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - } -} - -static int -put_ca_start (CcnetProcessor *processor, int argc, char **argv) -{ - char *repo_id, *token; - USE_PRIV; - - if (argc < 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - repo_id = argv[0]; - token = argv[1]; - - if (!is_uuid_valid (repo_id)) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->repo_id, repo_id, 36); - priv->token = g_strdup(token); - - ccnet_processor_thread_create (processor, - seaf->job_mgr, - check_token_thread, - check_token_thread_done, - processor); - - return 0; -} - -static void -process_commit_id_list (CcnetProcessor *processor, char *content, int clen) -{ - USE_PRIV; - int offset; - int size = clen - 1; - int dummy; - - if (size % 40 != 0) { - seaf_warning ("Invalid commid id list size %d.\n", size); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - for (offset = 0; offset < size - 1; offset += 40) - g_hash_table_insert (priv->commit_hash, - g_strndup(&content[offset], 40), &dummy); -} - -static gboolean -find_common_ancestor (SeafCommit *commit, void *data, gboolean *stop) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - /* If common ancestor has been found on other branch, stop traversing down. */ - if (priv->ca_id[0] != 0) { - *stop = TRUE; - return TRUE; - } - - if (g_hash_table_lookup (priv->commit_hash, commit->commit_id)) { - memcpy (priv->ca_id, commit->commit_id, 40); - *stop = TRUE; - return TRUE; - } - - return TRUE; -} - -static void * -compute_common_ancestor_thread (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - SeafRepo *repo = NULL; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to find repo %.8s.\n", priv->repo_id); - return vprocessor; - } - - /* Traverse the commit tree. The first commit whose id is in the commit list - * is the common ancestor. - */ - if (seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, - repo->id, - repo->version, - repo->head->commit_id, - find_common_ancestor, - processor, - FALSE) < 0) { - seaf_warning ("Failed to find common ancestor.\n"); - seaf_repo_unref (repo); - return vprocessor; - } - - seaf_repo_unref (repo); - return vprocessor; -} - -static void -compute_common_ancestor_done (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - if (priv->ca_id[0] != 0) { - ccnet_processor_send_response (processor, SC_CA, SS_CA, priv->ca_id, 41); - ccnet_processor_done (processor, TRUE); - } else { - ccnet_processor_send_response (processor, SC_NO_CA, SS_NO_CA, NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - - if (!priv->token_valid) { - ccnet_processor_send_response (processor, SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - if (strncmp (code, SC_ID_LIST, 3) == 0) { - process_commit_id_list (processor, content, clen); - return; - } else if (strncmp (code, SC_ID_LIST_END, 3) == 0) { - ccnet_processor_thread_create (processor, - seaf->job_mgr, - compute_common_ancestor_thread, - compute_common_ancestor_done, - processor); - return; - } - - seaf_warning ("Bad update: %s %s.\n", code, code_msg); - ccnet_processor_send_response (processor, SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); -} diff --git a/server/processors/putca-proc.h b/server/processors/putca-proc.h deleted file mode 100644 index 293be9f..0000000 --- a/server/processors/putca-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTCA_PROC_H -#define SEAFILE_PUTCA_PROC_H - -#include - - -#define SEAFILE_TYPE_PUTCA_PROC (seafile_putca_proc_get_type ()) -#define SEAFILE_PUTCA_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTCA_PROC, SeafilePutcaProc)) -#define SEAFILE_IS_PUTCA_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTCA_PROC)) -#define SEAFILE_PUTCA_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTCA_PROC, SeafilePutcaProcClass)) -#define IS_SEAFILE_PUTCA_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTCA_PROC)) -#define SEAFILE_PUTCA_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTCA_PROC, SeafilePutcaProcClass)) - -typedef struct _SeafilePutcaProc SeafilePutcaProc; -typedef struct _SeafilePutcaProcClass SeafilePutcaProcClass; - -struct _SeafilePutcaProc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutcaProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putca_proc_get_type (); - -#endif diff --git a/server/processors/putcommit-proc.c b/server/processors/putcommit-proc.c deleted file mode 100644 index 008d868..0000000 --- a/server/processors/putcommit-proc.c +++ /dev/null @@ -1,230 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include -#include -#include -#include -#include -#include - -#include -#include "net.h" -#include "utils.h" - -#include "seafile-session.h" -#include "commit-mgr.h" -#include "putcommit-proc.h" -#include "processors/objecttx-common.h" -#include "object-list.h" -#include "vc-common.h" - -#include "log.h" - -typedef struct { - char commit_id[41]; - char object_path[SEAF_PATH_MAX]; - gboolean transfer_started; - int fd; -} SeafilePutcommitProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_PUTCOMMIT_PROC, SeafilePutcommitProcPriv)) - -#define USE_PRIV \ - SeafilePutcommitProcPriv *priv = GET_PRIV(processor); - -static int put_commit_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static int send_commit_ids (CcnetProcessor *processor, const char *head); - - -G_DEFINE_TYPE (SeafilePutcommitProc, seafile_putcommit_proc, CCNET_TYPE_PROCESSOR) - -static void -seafile_putcommit_proc_class_init (SeafilePutcommitProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putcommit-proc"; - proc_class->start = put_commit_start; - proc_class->handle_update = handle_update; - - g_type_class_add_private (klass, sizeof (SeafilePutcommitProcPriv)); -} - -static void -seafile_putcommit_proc_init (SeafilePutcommitProc *processor) -{ -} - - -static int -put_commit_start (CcnetProcessor *processor, int argc, char **argv) -{ - char *commit_id; - char *session_token; - USE_PRIV; - - if (argc != 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - session_token = argv[1]; - if (seaf_token_manager_verify_token (seaf->token_mgr, - processor->peer_id, - session_token, NULL) < 0) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - commit_id = argv[0]; - - memcpy (priv->commit_id, commit_id, 41); - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - - return send_commit_ids (processor, commit_id); -} - -static gboolean -commit_collector (SeafCommit *commit, void *data, gboolean *stop) -{ - ObjectList *ol = data; - - object_list_insert (ol, commit->commit_id); - - return TRUE; -} - -static int -send_commit_ids (CcnetProcessor *processor, const char *head) -{ - char buf[2048]; - char *ptr = buf; - int i, count = 0; - int ret; - - ObjectList *ol = object_list_new (); - ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, - head, - commit_collector, - ol, FALSE); - if (ret == FALSE) { - object_list_free (ol); - seaf_warning ("[putcommit] Load commits error\n"); - ccnet_processor_send_response ( - processor, SC_NOT_FOUND, SS_NOT_FOUND, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - int ollen = object_list_length(ol); - g_return_val_if_fail (ollen != 0, -1); - - for (i = 0; i < ollen; i++) { - memcpy (ptr, g_ptr_array_index(ol->obj_ids, i), 40); - ptr += 40; - *ptr++ = '\n'; - - if (++count == 48) { - *ptr = '\0'; - ccnet_processor_send_response (processor, SC_COMMIT_IDS, - SS_COMMIT_IDS, buf, 41 * count + 1); - ptr = buf; - count = 0; - } - } - - if (count) { - *ptr = '\0'; - ccnet_processor_send_response (processor, SC_COMMIT_IDS, - SS_COMMIT_IDS, buf, 41 * count + 1); - } - - ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); - - return 0; -} - - -static gboolean -send_commit (CcnetProcessor *processor, char *object_id) -{ - char *data; - int len; - ObjectPack *pack = NULL; - int pack_size; - - if (seaf_obj_store_read_obj (seaf->commit_mgr->obj_store, - object_id, (void**)&data, &len) < 0) { - seaf_warning ("Failed to read commit %s.\n", object_id); - goto fail; - } - - pack_size = sizeof(ObjectPack) + len; - pack = malloc (pack_size); - memcpy (pack->id, object_id, 41); - memcpy (pack->object, data, len); - - ccnet_processor_send_response (processor, SC_OBJECT, SS_OBJECT, - (char *)pack, pack_size); - - g_free (data); - free (pack); - return TRUE; - -fail: - ccnet_processor_send_response (processor, SC_NOT_FOUND, SS_NOT_FOUND, - object_id, 41); - ccnet_processor_done (processor, FALSE); - return FALSE; -} - -static void -send_commits (CcnetProcessor *processor, char *content, int clen) -{ - char *object_id; - int n_objects; - int i; - - if (clen % 41 != 1 || content[clen-1] != '\0') { - seaf_warning ("[putcommit] Bad commit object list.\n"); - ccnet_processor_send_response (processor, SC_BAD_OL, SS_BAD_OL, NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - n_objects = clen/41; - - object_id = content; - for (i = 0; i < n_objects; ++i) { - object_id[40] = '\0'; - if (send_commit (processor, object_id) == FALSE) - return; - - object_id += 41; - } -} - -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - if (strncmp(code, SC_GET_OBJECT, 3) == 0) { - send_commits (processor, content, clen); - } else if (strncmp(code, SC_END, 3) == 0) { - ccnet_processor_done (processor, TRUE); - } else { - seaf_warning ("[putcommit] Bad response: %s %s\n", code, code_msg); - ccnet_processor_done (processor, FALSE); - } -} diff --git a/server/processors/putcommit-proc.h b/server/processors/putcommit-proc.h deleted file mode 100644 index 32bd50c..0000000 --- a/server/processors/putcommit-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTCOMMIT_PROC_H -#define SEAFILE_PUTCOMMIT_PROC_H - -#include - - -#define SEAFILE_TYPE_PUTCOMMIT_PROC (seafile_putcommit_proc_get_type ()) -#define SEAFILE_PUTCOMMIT_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTCOMMIT_PROC, SeafilePutcommitProc)) -#define SEAFILE_IS_PUTCOMMIT_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTCOMMIT_PROC)) -#define SEAFILE_PUTCOMMIT_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTCOMMIT_PROC, SeafilePutcommitProcClass)) -#define IS_SEAFILE_PUTCOMMIT_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTCOMMIT_PROC)) -#define SEAFILE_PUTCOMMIT_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTCOMMIT_PROC, SeafilePutcommitProcClass)) - -typedef struct _SeafilePutcommitProc SeafilePutcommitProc; -typedef struct _SeafilePutcommitProcClass SeafilePutcommitProcClass; - -struct _SeafilePutcommitProc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutcommitProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putcommit_proc_get_type (); - -#endif diff --git a/server/processors/putcommit-v2-proc.c b/server/processors/putcommit-v2-proc.c deleted file mode 100644 index 942078f..0000000 --- a/server/processors/putcommit-v2-proc.c +++ /dev/null @@ -1,379 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include - -#include -#include "net.h" -#include "utils.h" - -#include "seafile-session.h" -#include "putcommit-v2-proc.h" -#include "processors/objecttx-common.h" -#include "vc-common.h" - -typedef struct { - char head_commit_id[41]; - char remote_commit_id[41]; - GList *id_list; - GHashTable *commit_hash; - gboolean fast_forward; - - guint32 reader_id; - gboolean registered; - - char repo_id[37]; - int repo_version; -} SeafilePutcommitProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_PUTCOMMIT_V2_PROC, SeafilePutcommitProcPriv)) - -#define USE_PRIV \ - SeafilePutcommitProcPriv *priv = GET_PRIV(processor); - -static int put_commit_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -G_DEFINE_TYPE (SeafilePutcommitV2Proc, seafile_putcommit_v2_proc, CCNET_TYPE_PROCESSOR) - -static void -release_resource (CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->id_list) - string_list_free (priv->id_list); - if (priv->commit_hash) - g_hash_table_destroy (priv->commit_hash); - if (priv->registered) - seaf_obj_store_unregister_async_read (seaf->commit_mgr->obj_store, - priv->reader_id); - - CCNET_PROCESSOR_CLASS (seafile_putcommit_v2_proc_parent_class)->release_resource (processor); -} - -static void -seafile_putcommit_v2_proc_class_init (SeafilePutcommitV2ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putcommit-v2-proc"; - proc_class->start = put_commit_start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafilePutcommitProcPriv)); -} - -static void -seafile_putcommit_v2_proc_init (SeafilePutcommitV2Proc *processor) -{ -} - -static void -send_commit (CcnetProcessor *processor, - const char *commit_id, - char *data, int len) -{ - ObjectPack *pack = NULL; - int pack_size; - - pack_size = sizeof(ObjectPack) + len; - pack = malloc (pack_size); - memcpy (pack->id, commit_id, 41); - memcpy (pack->object, data, len); - - ccnet_processor_send_response (processor, SC_OBJECT, SS_OBJECT, - (char *)pack, pack_size); - free (pack); -} - -static int -read_and_send_commit (CcnetProcessor *processor) -{ - char *id; - USE_PRIV; - - id = priv->id_list->data; - priv->id_list = g_list_delete_link (priv->id_list, priv->id_list); - - if (seaf_obj_store_async_read (seaf->commit_mgr->obj_store, - priv->reader_id, - id) < 0) { - seaf_warning ("[putcommit] Failed to start read of %s.\n", id); - ccnet_processor_send_response (processor, SC_NOT_FOUND, SS_NOT_FOUND, - NULL, 0); - ccnet_processor_done (processor, FALSE); - g_free (id); - return -1; - } - - g_free (id); - return 0; -} - -static void -read_done_cb (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - USE_PRIV; - - if (!res->success) { - seaf_warning ("[putcommit] Failed to read %s.\n", res->obj_id); - goto bad; - } - - send_commit (processor, res->obj_id, res->data, res->len); - - seaf_debug ("Send commit %.8s.\n", res->obj_id); - - /* Send next commit. */ - if (priv->id_list != NULL) - read_and_send_commit (processor); - else { - ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); - ccnet_processor_done (processor, TRUE); - } - - return; - -bad: - ccnet_processor_send_response (processor, SC_NOT_FOUND, SS_NOT_FOUND, - NULL, 0); - ccnet_processor_done (processor, FALSE); -} - -static gboolean -collect_id_fast_forward (SeafCommit *commit, void *data, gboolean *stop) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (g_strcmp0 (commit->commit_id, priv->remote_commit_id) == 0) { - *stop = TRUE; - return TRUE; - } - - /* In clone remote head is not set but we're alwasy fast-forward. */ - if (priv->remote_commit_id[0] != '\0' && - commit->second_parent_id != NULL) { - *stop = TRUE; - priv->fast_forward = FALSE; - return TRUE; - } - - priv->id_list = g_list_prepend (priv->id_list, g_strdup(commit->commit_id)); - return TRUE; -} - -static gboolean -collect_id_remote (SeafCommit *commit, void *data, gboolean *stop) -{ - CcnetProcessor *processor = data; - USE_PRIV; - char *key; - - if (g_hash_table_lookup (priv->commit_hash, commit->commit_id)) - return TRUE; - - key = g_strdup(commit->commit_id); - g_hash_table_replace (priv->commit_hash, key, key); - return TRUE; -} - -static gboolean -compute_delta (SeafCommit *commit, void *data, gboolean *stop) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (!g_hash_table_lookup (priv->commit_hash, commit->commit_id)) { - priv->id_list = g_list_prepend (priv->id_list, - g_strdup(commit->commit_id)); - } else { - /* Stop traversing down from this commit if it already exists - * in the remote branch. - */ - *stop = TRUE; - } - - return TRUE; -} - -static int -compute_delta_commits (CcnetProcessor *processor, const char *head) -{ - gboolean ret; - USE_PRIV; - - string_list_free (priv->id_list); - priv->id_list = NULL; - - priv->commit_hash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - /* When putting commits, the remote head commit must exists. */ - ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, - priv->repo_id, - priv->repo_version, - priv->remote_commit_id, - collect_id_remote, - processor, - FALSE); - if (!ret) { - seaf_warning ("[putcommit] Failed to traverse remote branch.\n"); - string_list_free (priv->id_list); - priv->id_list = NULL; - return -1; - } - - ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, - priv->repo_id, - priv->repo_version, - head, - compute_delta, - processor, - FALSE); - if (!ret) { - seaf_warning ("[putcommit] Failed to compute delta commits.\n"); - string_list_free (priv->id_list); - priv->id_list = NULL; - return -1; - } - - return 0; -} - -static void * -collect_commit_id_thread (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %s.\n", priv->repo_id); - priv->id_list = NULL; - return vprocessor; - } - priv->repo_version = repo->version; - - priv->fast_forward = TRUE; - if (seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, - repo->id, - repo->version, - priv->head_commit_id, - collect_id_fast_forward, - processor, - FALSE) < 0) { - seaf_warning ("[putcommit] Failed to collect commit id.\n"); - string_list_free (priv->id_list); - priv->id_list = NULL; - goto out; - } - - if (priv->fast_forward) { - seaf_debug ("Send commits after a fast-forward merge.\n"); - goto out; - } - - seaf_debug ("Send commits after a real merge.\n"); - - compute_delta_commits (processor, priv->head_commit_id); - -out: - seaf_repo_unref (repo); - return vprocessor; -} - -static void -collect_commit_id_done (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - if (!priv->id_list) { - ccnet_processor_send_response (processor, SC_NOT_FOUND, SS_NOT_FOUND, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - priv->reader_id = - seaf_obj_store_register_async_read (seaf->commit_mgr->obj_store, - priv->repo_id, - priv->repo_version, - read_done_cb, - processor); - priv->registered = TRUE; - - read_and_send_commit (processor); -} - -static int -put_commit_start (CcnetProcessor *processor, int argc, char **argv) -{ - char *head_id, *remote_id = NULL; - char *session_token; - USE_PRIV; - - if (argc < 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (argc == 2) { - head_id = argv[0]; - session_token = argv[1]; - } else if (argc >= 3) { - head_id = argv[0]; - remote_id = argv[1]; - session_token = argv[2]; - } - - if (strlen(head_id) != 40 || (remote_id && strlen(remote_id) != 40)) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, priv->repo_id) < 0) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->head_commit_id, head_id, 41); - if (remote_id != NULL) - memcpy (priv->remote_commit_id, remote_id, 41); - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - - ccnet_processor_thread_create (processor, - seaf->job_mgr, - collect_commit_id_thread, - collect_commit_id_done, - processor); - - return 0; -} - -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - ccnet_processor_done (processor, FALSE); -} diff --git a/server/processors/putcommit-v2-proc.h b/server/processors/putcommit-v2-proc.h deleted file mode 100644 index 9241d87..0000000 --- a/server/processors/putcommit-v2-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTCOMMIT_V2_PROC_H -#define SEAFILE_PUTCOMMIT_V2_PROC_H - -#include - - -#define SEAFILE_TYPE_PUTCOMMIT_V2_PROC (seafile_putcommit_v2_proc_get_type ()) -#define SEAFILE_PUTCOMMIT_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTCOMMIT_V2_PROC, SeafilePutcommitV2Proc)) -#define SEAFILE_IS_PUTCOMMIT_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTCOMMIT_V2_PROC)) -#define SEAFILE_PUTCOMMIT_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTCOMMIT_V2_PROC, SeafilePutcommitV2ProcClass)) -#define IS_SEAFILE_PUTCOMMIT_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTCOMMIT_V2_PROC)) -#define SEAFILE_PUTCOMMIT_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTCOMMIT_V2_PROC, SeafilePutcommitV2ProcClass)) - -typedef struct _SeafilePutcommitV2Proc SeafilePutcommitV2Proc; -typedef struct _SeafilePutcommitV2ProcClass SeafilePutcommitV2ProcClass; - -struct _SeafilePutcommitV2Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutcommitV2ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putcommit_v2_proc_get_type (); - -#endif diff --git a/server/processors/putcommit-v3-proc.c b/server/processors/putcommit-v3-proc.c deleted file mode 100644 index 6d8b8eb..0000000 --- a/server/processors/putcommit-v3-proc.c +++ /dev/null @@ -1,218 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include - -#include -#include "net.h" -#include "utils.h" - -#include "seafile-session.h" -#include "putcommit-v3-proc.h" -#include "processors/objecttx-common.h" - -typedef struct { - char head_commit_id[41]; - guint32 reader_id; - gboolean registered; - - /* Used for getting repo info */ - char repo_id[37]; - int repo_version; - gboolean success; -} SeafilePutcommitProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_PUTCOMMIT_V3_PROC, SeafilePutcommitProcPriv)) - -#define USE_PRIV \ - SeafilePutcommitProcPriv *priv = GET_PRIV(processor); - -static int put_commit_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -G_DEFINE_TYPE (SeafilePutcommitV3Proc, seafile_putcommit_v3_proc, CCNET_TYPE_PROCESSOR) - -static void -release_resource (CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->registered) - seaf_obj_store_unregister_async_read (seaf->commit_mgr->obj_store, - priv->reader_id); - - CCNET_PROCESSOR_CLASS (seafile_putcommit_v3_proc_parent_class)->release_resource (processor); -} - -static void -seafile_putcommit_v3_proc_class_init (SeafilePutcommitV3ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putcommit-v3-proc"; - proc_class->start = put_commit_start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafilePutcommitProcPriv)); -} - -static void -seafile_putcommit_v3_proc_init (SeafilePutcommitV3Proc *processor) -{ -} - -static void -send_commit (CcnetProcessor *processor, - const char *commit_id, - char *data, int len) -{ - ObjectPack *pack = NULL; - int pack_size; - - pack_size = sizeof(ObjectPack) + len; - pack = malloc (pack_size); - memcpy (pack->id, commit_id, 41); - memcpy (pack->object, data, len); - - ccnet_processor_send_response (processor, SC_OK, SS_OK, - (char *)pack, pack_size); - free (pack); -} - -static int -read_and_send_commit (CcnetProcessor *processor, const char *commit_id) -{ - USE_PRIV; - - if (seaf_obj_store_async_read (seaf->commit_mgr->obj_store, - priv->reader_id, - commit_id) < 0) { - seaf_warning ("[putcommit] Failed to start read of %s.\n", commit_id); - ccnet_processor_send_response (processor, SC_NOT_FOUND, SS_NOT_FOUND, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - return 0; -} - -static void -read_done_cb (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - - if (!res->success) { - seaf_warning ("[putcommit] Failed to read %s.\n", res->obj_id); - ccnet_processor_send_response (processor, SC_NOT_FOUND, SS_NOT_FOUND, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - send_commit (processor, res->obj_id, res->data, res->len); - - seaf_debug ("Send commit %.8s.\n", res->obj_id); -} - -static void * -get_repo_info_thread (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %s.\n", priv->repo_id); - priv->success = FALSE; - return data; - } - - priv->repo_version = repo->version; - priv->success = TRUE; - - seaf_repo_unref (repo); - return data; -} - -static void -get_repo_info_done (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (priv->success) { - priv->reader_id = - seaf_obj_store_register_async_read (seaf->commit_mgr->obj_store, - priv->repo_id, - priv->repo_version, - read_done_cb, - processor); - priv->registered = TRUE; - - read_and_send_commit (processor, priv->head_commit_id); - } else { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static int -put_commit_start (CcnetProcessor *processor, int argc, char **argv) -{ - char *head_id; - char *session_token; - USE_PRIV; - - if (argc < 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - head_id = argv[0]; - session_token = argv[1]; - - if (strlen(head_id) != 40) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, priv->repo_id) < 0) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->head_commit_id, head_id, 40); - ccnet_processor_thread_create (processor, - seaf->job_mgr, - get_repo_info_thread, - get_repo_info_done, - processor); - - return 0; -} - -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - ccnet_processor_done (processor, FALSE); -} diff --git a/server/processors/putcommit-v3-proc.h b/server/processors/putcommit-v3-proc.h deleted file mode 100644 index afe3f50..0000000 --- a/server/processors/putcommit-v3-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTCOMMIT_V3_PROC_H -#define SEAFILE_PUTCOMMIT_V3_PROC_H - -#include - - -#define SEAFILE_TYPE_PUTCOMMIT_V3_PROC (seafile_putcommit_v3_proc_get_type ()) -#define SEAFILE_PUTCOMMIT_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTCOMMIT_V3_PROC, SeafilePutcommitV3Proc)) -#define SEAFILE_IS_PUTCOMMIT_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTCOMMIT_V3_PROC)) -#define SEAFILE_PUTCOMMIT_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTCOMMIT_V3_PROC, SeafilePutcommitV3ProcClass)) -#define IS_SEAFILE_PUTCOMMIT_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTCOMMIT_V3_PROC)) -#define SEAFILE_PUTCOMMIT_V3_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTCOMMIT_V3_PROC, SeafilePutcommitV3ProcClass)) - -typedef struct _SeafilePutcommitV3Proc SeafilePutcommitV3Proc; -typedef struct _SeafilePutcommitV3ProcClass SeafilePutcommitV3ProcClass; - -struct _SeafilePutcommitV3Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutcommitV3ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putcommit_v3_proc_get_type (); - -#endif diff --git a/server/processors/putcs-proc.c b/server/processors/putcs-proc.c deleted file mode 100644 index 84975e1..0000000 --- a/server/processors/putcs-proc.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include -#include "seafile-session.h" -#include "chunkserv-mgr.h" -#include "putcs-proc.h" - -G_DEFINE_TYPE (SeafilePutcsProc, seafile_putcs_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); - -static void -release_resource(CcnetProcessor *processor) -{ - CCNET_PROCESSOR_CLASS (seafile_putcs_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_putcs_proc_class_init (SeafilePutcsProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putcs-proc"; - proc_class->start = start; - proc_class->release_resource = release_resource; -} - -static void -seafile_putcs_proc_init (SeafilePutcsProc *processor) -{ -} - - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - GString *buf = g_string_new(""); - GList *chunk_servers, *cs; - char *cs_id; - - chunk_servers = seaf_cs_manager_get_chunk_servers (seaf->cs_mgr); - cs = chunk_servers; - while (cs) { - cs_id = cs->data; - - /* The public ip of myself is not set. We just send my id to - * clients, they should already have my ip address. - */ - if (strcmp (cs_id, seaf->session->base.id) == 0) { - g_string_append_printf (buf, "%s\n", cs_id); - goto next; - } - - CcnetPeer *peer = ccnet_get_peer (seaf->ccnetrpc_client, cs_id); - if (!peer || !peer->public_addr) { - /* do nothing */ - if (peer) - g_object_unref (peer); - } else { - g_string_append_printf (buf, "%s %s:%d\n", cs_id, - peer->public_addr, - peer->public_port); - g_object_unref (peer); - } - next: - cs = cs->next; - } - g_list_free (chunk_servers); - - ccnet_processor_send_response (processor, SC_OK, SS_OK, buf->str, buf->len+1); - g_string_free (buf, TRUE); - - ccnet_processor_done (processor, TRUE); - - return 0; -} diff --git a/server/processors/putcs-proc.h b/server/processors/putcs-proc.h deleted file mode 100644 index b9bc9dd..0000000 --- a/server/processors/putcs-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTCS_PROC_H -#define SEAFILE_PUTCS_PROC_H - -#include -#include - -#define SEAFILE_TYPE_PUTCS_PROC (seafile_putcs_proc_get_type ()) -#define SEAFILE_PUTCS_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTCS_PROC, SeafilePutcsProc)) -#define SEAFILE_IS_PUTCS_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTCS_PROC)) -#define SEAFILE_PUTCS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTCS_PROC, SeafilePutcsProcClass)) -#define IS_SEAFILE_PUTCS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTCS_PROC)) -#define SEAFILE_PUTCS_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTCS_PROC, SeafilePutcsProcClass)) - -typedef struct _SeafilePutcsProc SeafilePutcsProc; -typedef struct _SeafilePutcsProcClass SeafilePutcsProcClass; - -struct _SeafilePutcsProc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutcsProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putcs_proc_get_type (); - -#endif - diff --git a/server/processors/putcs-v2-proc.c b/server/processors/putcs-v2-proc.c deleted file mode 100644 index be56443..0000000 --- a/server/processors/putcs-v2-proc.c +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include -#include "seafile-session.h" -#include "putcs-v2-proc.h" - -G_DEFINE_TYPE (SeafilePutcsV2Proc, seafile_putcs_v2_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); - -static void -release_resource(CcnetProcessor *processor) -{ - CCNET_PROCESSOR_CLASS (seafile_putcs_v2_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_putcs_v2_proc_class_init (SeafilePutcsV2ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putcs-v2-proc"; - proc_class->start = start; - proc_class->release_resource = release_resource; -} - -static void -seafile_putcs_v2_proc_init (SeafilePutcsV2Proc *processor) -{ -} - -static char * -hostname_from_service_url (const char *service_url) -{ - const char *start, *end; - - start = strstr (service_url, "//"); - if (!start) - start = service_url; - else - start += 2; - - end = strchr (start, ':'); - if (end) - return g_strndup (start, end - start); - - end = strchr (start, '/'); - if (!end) - return g_strdup (start); - else - return g_strndup (start, end - start); -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char *hostname; - GString *buf = g_string_new(""); - - hostname = hostname_from_service_url (seaf->session->base.service_url); - g_string_printf (buf, "%s:%d\n", hostname, seaf->listen_mgr->port); - g_free (hostname); - - ccnet_processor_send_response (processor, SC_OK, SS_OK, buf->str, buf->len+1); - g_string_free (buf, TRUE); - - ccnet_processor_done (processor, TRUE); - - return 0; -} diff --git a/server/processors/putcs-v2-proc.h b/server/processors/putcs-v2-proc.h deleted file mode 100644 index 306791a..0000000 --- a/server/processors/putcs-v2-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTCS_V2_PROC_H -#define SEAFILE_PUTCS_V2_PROC_H - -#include -#include - -#define SEAFILE_TYPE_PUTCS_V2_PROC (seafile_putcs_v2_proc_get_type ()) -#define SEAFILE_PUTCS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTCS_V2_PROC, SeafilePutcsV2Proc)) -#define SEAFILE_IS_PUTCS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTCS_V2_PROC)) -#define SEAFILE_PUTCS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTCS_V2_PROC, SeafilePutcsV2ProcClass)) -#define IS_SEAFILE_PUTCS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTCS_V2_PROC)) -#define SEAFILE_PUTCS_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTCS_V2_PROC, SeafilePutcsV2ProcClass)) - -typedef struct _SeafilePutcsV2Proc SeafilePutcsV2Proc; -typedef struct _SeafilePutcsV2ProcClass SeafilePutcsV2ProcClass; - -struct _SeafilePutcsV2Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutcsV2ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putcs_v2_proc_get_type (); - -#endif - diff --git a/server/processors/putfs-proc.c b/server/processors/putfs-proc.c deleted file mode 100644 index 413f08b..0000000 --- a/server/processors/putfs-proc.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include -#include - -#include -#include "utils.h" - -#include "seafile-session.h" -#include "commit-mgr.h" -#include "fs-mgr.h" -#include "processors/objecttx-common.h" -#include "putfs-proc.h" - -typedef struct { - guint32 reader_id; - gboolean registered; - - /* Used for getting repo info */ - char repo_id[37]; - char store_id[37]; - int repo_version; - gboolean success; -} PutfsProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_PUTFS_PROC, PutfsProcPriv)) - -#define USE_PRIV \ - PutfsProcPriv *priv = GET_PRIV(processor); - -G_DEFINE_TYPE (SeafilePutfsProc, seafile_putfs_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void -read_done_cb (OSAsyncResult *res, void *cb_data); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->registered) - seaf_obj_store_unregister_async_read (seaf->fs_mgr->obj_store, - priv->reader_id); - - CCNET_PROCESSOR_CLASS (seafile_putfs_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_putfs_proc_class_init (SeafilePutfsProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putfs-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (PutfsProcPriv)); -} - -static void -seafile_putfs_proc_init (SeafilePutfsProc *processor) -{ -} - -static void * -get_repo_info_thread (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %s.\n", priv->repo_id); - priv->success = FALSE; - return data; - } - - memcpy (priv->store_id, repo->store_id, 36); - priv->repo_version = repo->version; - priv->success = TRUE; - - seaf_repo_unref (repo); - return data; -} - -static void -get_repo_info_done (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (priv->success) { - priv->registered = TRUE; - priv->reader_id = - seaf_obj_store_register_async_read (seaf->fs_mgr->obj_store, - priv->store_id, - priv->repo_version, - read_done_cb, - processor); - - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - } else { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char *session_token; - char repo_id[37]; - USE_PRIV; - - if (argc != 1) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - session_token = argv[0]; - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, repo_id) < 0) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->repo_id, repo_id, 36); - ccnet_processor_thread_create (processor, - seaf->job_mgr, - get_repo_info_thread, - get_repo_info_done, - processor); - - return 0; -} - -static void -read_done_cb (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - ObjectPack *pack = NULL; - int pack_size; - - if (!res->success) { - seaf_warning ("[putfs] Failed to read %s.\n", res->obj_id); - ccnet_processor_send_response (processor, SC_NOT_FOUND, SS_NOT_FOUND, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - pack_size = sizeof(ObjectPack) + res->len; - pack = malloc (pack_size); - memcpy (pack->id, res->obj_id, 41); - memcpy (pack->object, res->data, res->len); - - if (pack_size <= MAX_OBJ_SEG_SIZE) { - ccnet_processor_send_response (processor, SC_OBJECT, SS_OBJECT, - (char *)pack, pack_size); - } else { - int offset, n; - - offset = 0; - while (offset < pack_size) { - n = MIN(pack_size - offset, MAX_OBJ_SEG_SIZE); - - if (offset + n < pack_size) { - ccnet_processor_send_response (processor, - SC_OBJ_SEG, SS_OBJ_SEG, - (char *)pack + offset, n); - } else { - ccnet_processor_send_response (processor, - SC_OBJ_SEG_END, SS_OBJ_SEG_END, - (char *)pack + offset, n); - } - seaf_debug ("[putfs] Sent object %s segment\n", - res->obj_id, pack_size, offset, n); - offset += n; - } - } - - free (pack); - - seaf_debug ("Send fs object %.8s.\n", res->obj_id); -} - -static gboolean -send_fs_object (CcnetProcessor *processor, char *object_id) -{ - USE_PRIV; - - if (seaf_obj_store_async_read (seaf->fs_mgr->obj_store, - priv->reader_id, - object_id) < 0) { - seaf_warning ("[putfs] Failed to start async read of %s.\n", object_id); - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return FALSE; - } - - return TRUE; -} - -static void -send_fs_objects (CcnetProcessor *processor, char *content, int clen) -{ - char *object_id; - int n_objects; - int i; - - if (clen % 41 != 1 || content[clen-1] != '\0') { - seaf_warning ("[putfs] Bad fs object list.\n"); - ccnet_processor_send_response (processor, SC_BAD_OL, SS_BAD_OL, NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - n_objects = clen/41; - - object_id = content; - for (i = 0; i < n_objects; ++i) { - object_id[40] = '\0'; - if (send_fs_object (processor, object_id) == FALSE) - return; - object_id += 41; - } -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - if (strncmp(code, SC_GET_OBJECT, 3) == 0) { - send_fs_objects (processor, content, clen); - } else if (strncmp(code, SC_END, 3) == 0) { - ccnet_processor_done (processor, TRUE); - } else { - seaf_warning ("[putfs] Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} diff --git a/server/processors/putfs-proc.h b/server/processors/putfs-proc.h deleted file mode 100644 index d8a4634..0000000 --- a/server/processors/putfs-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTFS_PROC_H -#define SEAFILE_PUTFS_PROC_H - -#include - - -#define SEAFILE_TYPE_PUTFS_PROC (seafile_putfs_proc_get_type ()) -#define SEAFILE_PUTFS_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTFS_PROC, SeafilePutfsProc)) -#define SEAFILE_IS_PUTFS_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTFS_PROC)) -#define SEAFILE_PUTFS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTFS_PROC, SeafilePutfsProcClass)) -#define IS_SEAFILE_PUTFS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTFS_PROC)) -#define SEAFILE_PUTFS_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTFS_PROC, SeafilePutfsProcClass)) - -typedef struct _SeafilePutfsProc SeafilePutfsProc; -typedef struct _SeafilePutfsProcClass SeafilePutfsProcClass; - -struct _SeafilePutfsProc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutfsProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putfs_proc_get_type (); - -#endif - diff --git a/server/processors/putfs-v2-proc.c b/server/processors/putfs-v2-proc.c deleted file mode 100644 index 931bbed..0000000 --- a/server/processors/putfs-v2-proc.c +++ /dev/null @@ -1,500 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include -#include - -#include -#include "utils.h" - -#include "seafile-session.h" -#include "commit-mgr.h" -#include "fs-mgr.h" -#include "processors/objecttx-common.h" -#include "putfs-v2-proc.h" - -#include "diff-simple.h" - -enum { - CHECK_OBJECT_LIST = 0, - SEND_OBJECTS, -}; - -typedef struct { - char server_head[41]; - char client_head[41]; - - /* Used for getting repo info */ - char repo_id[37]; - char store_id[37]; - int repo_version; - gboolean success; - - GList *send_obj_list; - - gboolean registered; - guint32 reader_id; - - gboolean calc_success; -} SeafilePutfsProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_PUTFS_V2_PROC, SeafilePutfsProcPriv)) - -#define USE_PRIV \ - SeafilePutfsProcPriv *priv = GET_PRIV(processor); - -G_DEFINE_TYPE (SeafilePutfsV2Proc, seafile_putfs_v2_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static void * -calculate_send_object_list (void *vdata); - -static void -calculate_send_object_list_done (void *vdata); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - string_list_free (priv->send_obj_list); - - seaf_obj_store_unregister_async_read (seaf->fs_mgr->obj_store, - priv->reader_id); - - CCNET_PROCESSOR_CLASS (seafile_putfs_v2_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_putfs_v2_proc_class_init (SeafilePutfsV2ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "putfs-v2-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof(SeafilePutfsProcPriv)); -} - -static void -seafile_putfs_v2_proc_init (SeafilePutfsV2Proc *processor) -{ -} - -static void -fs_object_read_cb (OSAsyncResult *res, void *data); - -static void -register_async_io (CcnetProcessor *processor) -{ - USE_PRIV; - - priv->registered = TRUE; - priv->reader_id = seaf_obj_store_register_async_read (seaf->fs_mgr->obj_store, - priv->store_id, - priv->repo_version, - fs_object_read_cb, - processor); -} - -static void * -get_repo_info_thread (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %s.\n", priv->repo_id); - priv->success = FALSE; - return data; - } - - memcpy (priv->store_id, repo->store_id, 36); - priv->repo_version = repo->version; - priv->success = TRUE; - - seaf_repo_unref (repo); - return data; -} - -static void -get_repo_info_done (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (priv->success) { - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - register_async_io (processor); - - ccnet_processor_thread_create (processor, - seaf->job_mgr, - calculate_send_object_list, - calculate_send_object_list_done, - processor); - } else { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char *session_token; - USE_PRIV; - - if (argc < 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - session_token = argv[0]; - - if (strlen(argv[1]) != 40) { - ccnet_processor_send_response (processor, - SC_BAD_ARGS, SS_BAD_ARGS, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - memcpy (priv->server_head, argv[1], 40); - - if (argc >= 3) { - if (strlen(argv[2]) != 40) { - ccnet_processor_send_response (processor, - SC_BAD_ARGS, SS_BAD_ARGS, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - memcpy (priv->client_head, argv[2], 40); - } - - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, priv->repo_id) == 0) { - ccnet_processor_thread_create (processor, - seaf->job_mgr, - get_repo_info_thread, - get_repo_info_done, - processor); - return 0; - } else { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } -} - -/* Calculate send object list */ - -inline static gboolean -dirent_same (SeafDirent *denta, SeafDirent *dentb) -{ - return (strcmp (dentb->id, denta->id) == 0 && denta->mode == dentb->mode); -} - -static int -collect_file_ids (int n, const char *basedir, SeafDirent *files[], void *data) -{ - SeafDirent *file1 = files[0]; - SeafDirent *file2 = files[1]; - GList **pret = data; - - if (file1 && (!file2 || !dirent_same (file1, file2)) && - strcmp (file1->id, EMPTY_SHA1) != 0) - *pret = g_list_prepend (*pret, g_strdup(file1->id)); - - return 0; -} - -static int -collect_dir_ids (int n, const char *basedir, SeafDirent *dirs[], void *data, - gboolean *recurse) -{ - SeafDirent *dir1 = dirs[0]; - SeafDirent *dir2 = dirs[1]; - GList **pret = data; - - if (dir1 && (!dir2 || !dirent_same (dir1, dir2)) && - strcmp (dir1->id, EMPTY_SHA1) != 0) - *pret = g_list_prepend (*pret, g_strdup(dir1->id)); - - return 0; -} - -static void * -calculate_send_object_list (void *vdata) -{ - CcnetProcessor *processor = vdata; - USE_PRIV; - SeafCommit *remote_head = NULL, *master_head = NULL; - char *remote_head_root; - - master_head = seaf_commit_manager_get_commit (seaf->commit_mgr, - priv->repo_id, priv->repo_version, - priv->server_head); - if (!master_head) { - seaf_warning ("Server head commit %s:%s not found.\n", - priv->repo_id, priv->server_head); - priv->calc_success = FALSE; - goto out; - } - - if (priv->client_head[0] != 0) { - remote_head = seaf_commit_manager_get_commit (seaf->commit_mgr, - priv->repo_id, - priv->repo_version, - priv->client_head); - if (!remote_head) { - seaf_warning ("Remote head commit %s:%s not found.\n", - priv->repo_id, priv->client_head); - priv->calc_success = FALSE; - goto out; - } - remote_head_root = remote_head->root_id; - } else - remote_head_root = EMPTY_SHA1; - - /* Diff won't traverse the root object itself. */ - if (strcmp (remote_head_root, master_head->root_id) != 0 && - strcmp (master_head->root_id, EMPTY_SHA1) != 0) - priv->send_obj_list = g_list_prepend (priv->send_obj_list, - g_strdup(master_head->root_id)); - - DiffOptions opts; - memset (&opts, 0, sizeof(opts)); - memcpy (opts.store_id, priv->store_id, 36); - opts.version = priv->repo_version; - opts.file_cb = collect_file_ids; - opts.dir_cb = collect_dir_ids; - opts.data = &priv->send_obj_list; - - const char *trees[2]; - trees[0] = master_head->root_id; - trees[1] = remote_head_root; - if (diff_trees (2, trees, &opts) < 0) { - seaf_warning ("Failed to diff remote and master head for repo %.8s.\n", - priv->repo_id); - priv->calc_success = FALSE; - } - - priv->calc_success = TRUE; - -out: - seaf_commit_unref (remote_head); - seaf_commit_unref (master_head); - return vdata; -} - -#define OBJECT_LIST_SEGMENT_N 1000 -#define OBJECT_LIST_SEGMENT_LEN 40 * 1000 - -static void -send_object_list_segments (CcnetProcessor *processor) -{ - USE_PRIV; - char buf[OBJECT_LIST_SEGMENT_LEN]; - - int i = 0; - char *p = buf; - char *obj_id; - while (priv->send_obj_list != NULL) { - obj_id = priv->send_obj_list->data; - priv->send_obj_list = g_list_delete_link (priv->send_obj_list, - priv->send_obj_list); - - memcpy (p, obj_id, 40); - p += 40; - g_free (obj_id); - if (++i == OBJECT_LIST_SEGMENT_N) { - seaf_debug ("Send %d object ids.\n", i); - ccnet_processor_send_response (processor, - SC_OBJ_LIST_SEG, SS_OBJ_LIST_SEG, - buf, i * 40); - i = 0; - p = buf; - } - } - - if (i > 0) { - seaf_debug ("Send %d object ids.\n", i); - ccnet_processor_send_response (processor, - SC_OBJ_LIST_SEG, SS_OBJ_LIST_SEG, - buf, i * 40); - } - - ccnet_processor_send_response (processor, - SC_OBJ_LIST_SEG_END, SS_OBJ_LIST_SEG_END, - NULL, 0); -} - -static void -calculate_send_object_list_done (void *vdata) -{ - CcnetProcessor *processor = vdata; - USE_PRIV; - - if (!priv->calc_success) { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - if (priv->send_obj_list == NULL) { - seaf_message ("No fs objects to put. Done.\n"); - ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); - ccnet_processor_done (processor, TRUE); - return; - } - - send_object_list_segments (processor); - - processor->state = SEND_OBJECTS; -} - -/* Send objects */ - -static void -send_fs_object (CcnetProcessor *processor, - const char *object_id, char *data, int len) -{ - ObjectPack *pack = NULL; - int pack_size; - - pack_size = sizeof(ObjectPack) + len; - pack = malloc (pack_size); - memcpy (pack->id, object_id, 41); - memcpy (pack->object, data, len); - - if (pack_size <= MAX_OBJ_SEG_SIZE) { - ccnet_processor_send_response (processor, SC_OBJECT, SS_OBJECT, - (char *)pack, pack_size); - } else { - int offset, n; - - offset = 0; - while (offset < pack_size) { - n = MIN(pack_size - offset, MAX_OBJ_SEG_SIZE); - - if (offset + n < pack_size) { - ccnet_processor_send_response (processor, - SC_OBJ_SEG, SS_OBJ_SEG, - (char *)pack + offset, n); - } else { - ccnet_processor_send_response (processor, - SC_OBJ_SEG_END, SS_OBJ_SEG_END, - (char *)pack + offset, n); - } - - seaf_debug ("Sent object %s segment\n", - object_id, pack_size, offset, n); - - offset += n; - } - } - - seaf_debug ("Send fs object %.8s.\n", object_id); - - free (pack); -} - -static void -fs_object_read_cb (OSAsyncResult *res, void *data) -{ - CcnetProcessor *processor = data; - - if (!res->success) { - seaf_warning ("Failed to read fs object %.8s.\n", res->obj_id); - ccnet_processor_send_response (processor, SC_NOT_FOUND, SS_NOT_FOUND, - res->obj_id, 41); - ccnet_processor_done (processor, FALSE); - return; - } - - send_fs_object (processor, res->obj_id, res->data, res->len); -} - -static void -read_fs_object (CcnetProcessor *processor, const char *obj_id) -{ - USE_PRIV; - - seaf_obj_store_async_read (seaf->fs_mgr->obj_store, - priv->reader_id, - obj_id); -} - -static void -process_object_list_segment (CcnetProcessor *processor, char *content, int clen) -{ - int n, i; - char *p; - - if (clen % 40 != 0) { - seaf_warning ("Invalid object list segment length %d.\n", clen); - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - n = clen/40; - p = content; - - seaf_debug ("%d objects are needed by the client.\n", n); - - char *obj_id; - for (i = 0; i < n; ++i) { - obj_id = g_strndup(p, 40); - read_fs_object (processor, obj_id); - g_free (obj_id); - p += 40; - } -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - switch (processor->state) { - case SEND_OBJECTS: - if (strncmp (code, SC_OBJ_LIST_SEG, 3) == 0) { - process_object_list_segment (processor, content, clen); - return; - } else if (strncmp (code, SC_END, 3) == 0) { - seaf_debug ("All objects received. Done.\n"); - ccnet_processor_done (processor, TRUE); - return; - } - break; - default: - g_return_if_reached (); - } - - seaf_warning ("Bad update: %s %s.\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); -} diff --git a/server/processors/putfs-v2-proc.h b/server/processors/putfs-v2-proc.h deleted file mode 100644 index b17cf81..0000000 --- a/server/processors/putfs-v2-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTFS_V2_PROC_H -#define SEAFILE_PUTFS_V2_PROC_H - -#include - - -#define SEAFILE_TYPE_PUTFS_V2_PROC (seafile_putfs_v2_proc_get_type ()) -#define SEAFILE_PUTFS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTFS_V2_PROC, SeafilePutfsV2Proc)) -#define SEAFILE_IS_PUTFS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTFS_V2_PROC)) -#define SEAFILE_PUTFS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTFS_V2_PROC, SeafilePutfsV2ProcClass)) -#define IS_SEAFILE_PUTFS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTFS_V2_PROC)) -#define SEAFILE_PUTFS_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTFS_V2_PROC, SeafilePutfsV2ProcClass)) - -typedef struct _SeafilePutfsV2Proc SeafilePutfsV2Proc; -typedef struct _SeafilePutfsV2ProcClass SeafilePutfsV2ProcClass; - -struct _SeafilePutfsV2Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutfsV2ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putfs_v2_proc_get_type (); - -#endif - diff --git a/server/processors/putrepoemailtoken-proc.c b/server/processors/putrepoemailtoken-proc.c deleted file mode 100644 index f443295..0000000 --- a/server/processors/putrepoemailtoken-proc.c +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" -#include "ccnet.h" -#include "log.h" -#include "seafile-session.h" -#include "repo-mgr.h" - -#include "putrepoemailtoken-proc.h" - -#define SC_REPO_EMAIL "300" -#define SS_REPO_EMAIL "email" -#define SC_REPO_TOKEN "301" -#define SS_REPO_TOKEN "token" -#define SC_SERVER_ERROR "400" -#define SS_SERVER_ERROR "server error" -#define SC_ACCESS_DENIED "401" -#define SS_ACCESS_DENIED "access denied" -#define SC_NO_REPO "402" -#define SS_NO_REPO "repo does not exist" - -typedef struct { - char *repo_id; - char *email; - char *token; - char *rsp_code; -} SeafilePutrepoemailtokenProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_PUTREPOEMAILTOKEN_PROC, SeafilePutrepoemailtokenProcPriv)) - -#define USE_PRIV \ - SeafilePutrepoemailtokenProcPriv *priv = GET_PRIV(processor); - - -G_DEFINE_TYPE (SeafilePutrepoemailtokenProc, seafile_putrepoemailtoken_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static void get_email_cb (void *result, void *data, GError *error); -static void *get_repo_token (void *vprocessor); -static void get_repo_token_done (void *result); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - g_free (priv->email); - g_free (priv->token); - - CCNET_PROCESSOR_CLASS (seafile_putrepoemailtoken_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_putrepoemailtoken_proc_class_init (SeafilePutrepoemailtokenProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafilePutrepoemailtokenProcPriv)); -} - -static void -seafile_putrepoemailtoken_proc_init (SeafilePutrepoemailtokenProc *processor) -{ -} - - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - - if (argc != 1) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - priv->repo_id = g_strdup(argv[0]); - ccnet_get_binding_email_async (seaf->async_ccnetrpc_client_t, processor->peer_id, - get_email_cb, processor); - - return 0; -} - -static void -get_email_cb (void *result, void *data, GError *error) -{ - char *email = result; - CcnetProcessor *processor = data; - USE_PRIV; - - if (!email) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } else { - priv->email = g_strdup(email); - ccnet_processor_thread_create (processor, - get_repo_token, - get_repo_token_done, - processor); - } -} - -static void * -get_repo_token (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - priv->rsp_code = SC_OK; - if (!seaf_repo_manager_repo_exists (seaf->repo_mgr, priv->repo_id)) { - priv->rsp_code = SC_NO_REPO; - - } else { - priv->token = seaf_repo_manager_get_repo_token_nonnull ( - seaf->repo_mgr, priv->repo_id, priv->email); - - if (!priv->token) - priv->rsp_code = SC_SERVER_ERROR; - } - - return vprocessor; -} - -static void -get_repo_token_done (void *result) -{ - CcnetProcessor *processor = result; - USE_PRIV; - - if (strcmp (priv->rsp_code, SC_NO_REPO) == 0) { - ccnet_processor_send_response (processor, SC_NO_REPO, - SS_NO_REPO, NULL, 0); - ccnet_processor_done (processor, FALSE); - - } else if (strcmp (priv->rsp_code, SC_SERVER_ERROR) == 0) { - ccnet_processor_send_response (processor, SC_SERVER_ERROR, - SS_SERVER_ERROR, NULL, 0); - ccnet_processor_done (processor, FALSE); - } else { - ccnet_processor_send_response (processor, - SC_REPO_EMAIL, SS_REPO_EMAIL, - priv->email, - strlen(priv->email) + 1); - } -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - if (strcmp (code, SC_REPO_TOKEN) == 0) { - ccnet_processor_send_response (processor, - SC_REPO_TOKEN, SS_REPO_TOKEN, - priv->token, - strlen(priv->token) + 1); - ccnet_processor_done (processor, TRUE); - } else { - seaf_warning ("bad update, %s : %s\n", code, code_msg); - ccnet_processor_done (processor, FALSE); - } - -} diff --git a/server/processors/putrepoemailtoken-proc.h b/server/processors/putrepoemailtoken-proc.h deleted file mode 100644 index 77d90d3..0000000 --- a/server/processors/putrepoemailtoken-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_PUTREPOEMAILTOKEN_PROC_H -#define SEAFILE_PUTREPOEMAILTOKEN_PROC_H - -#include - - -#define SEAFILE_TYPE_PUTREPOEMAILTOKEN_PROC (seafile_putrepoemailtoken_proc_get_type ()) -#define SEAFILE_PUTREPOEMAILTOKEN_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_PUTREPOEMAILTOKEN_PROC, SeafilePutrepoemailtokenProc)) -#define SEAFILE_IS_PUTREPOEMAILTOKEN_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_PUTREPOEMAILTOKEN_PROC)) -#define SEAFILE_PUTREPOEMAILTOKEN_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_PUTREPOEMAILTOKEN_PROC, SeafilePutrepoemailtokenProcClass)) -#define IS_SEAFILE_PUTREPOEMAILTOKEN_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_PUTREPOEMAILTOKEN_PROC)) -#define SEAFILE_PUTREPOEMAILTOKEN_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_PUTREPOEMAILTOKEN_PROC, SeafilePutrepoemailtokenProcClass)) - -typedef struct _SeafilePutrepoemailtokenProc SeafilePutrepoemailtokenProc; -typedef struct _SeafilePutrepoemailtokenProcClass SeafilePutrepoemailtokenProcClass; - -struct _SeafilePutrepoemailtokenProc { - CcnetProcessor parent_instance; -}; - -struct _SeafilePutrepoemailtokenProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_putrepoemailtoken_proc_get_type (); - -#endif - diff --git a/server/processors/recvblock-proc.c b/server/processors/recvblock-proc.c deleted file mode 100644 index 282116d..0000000 --- a/server/processors/recvblock-proc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define _GNU_SOURCE -#include -#include -#include -#include -#include - -#include -#include -#include "net.h" -#include "utils.h" - -#include "seafile-session.h" -#include "fs-mgr.h" -#include "block-mgr.h" -#include "recvblock-proc.h" -#include "processors/blocktx-common.h" - -#include "log.h" - -enum { - PREPARE, - READY, -}; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVBLOCK_PROC, BlockProcPriv)) - -#define USE_PRIV \ - BlockProcPriv *priv = GET_PRIV(processor); - -static int block_proc_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void recv_block_cb (CEvent *event, void *vprocessor); -static void release_resource (CcnetProcessor *processor); - -G_DEFINE_TYPE (SeafileRecvblockProc, seafile_recvblock_proc, CCNET_TYPE_PROCESSOR) - -static void -seafile_recvblock_proc_class_init (SeafileRecvblockProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvblock-proc"; - proc_class->start = block_proc_start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (BlockProcPriv)); -} - -static void -seafile_recvblock_proc_init (SeafileRecvblockProc *processor) -{ -} - -static void -recv_block_cb (CEvent *event, void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - BlockResponse *blk_rsp = event->data; - char buf[32]; - int len; - - len = snprintf (buf, 32, "%d", blk_rsp->block_idx); - ccnet_processor_send_response (processor, SC_ACK, SS_ACK, - buf, len + 1); - - g_free (blk_rsp); -} - -#include "processors/blocktx-common-impl.h" - -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - switch (processor->state) { - case PREPARE: - if (memcmp (code, SC_BLOCKLIST, 3) == 0) { - process_block_list (processor, content, clen); - return; - } else if (memcmp (code, SC_GET_PORT, 3) == 0) { - send_port (processor); - return; - } - break; - } - - seaf_warning ("Bad code: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, SC_BAD_UPDATE_CODE, - SS_BAD_UPDATE_CODE, NULL, 0); - ccnet_processor_done (processor, FALSE); -} diff --git a/server/processors/recvblock-proc.h b/server/processors/recvblock-proc.h deleted file mode 100644 index 3786bd2..0000000 --- a/server/processors/recvblock-proc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVBLOCK_PROC_H -#define SEAFILE_RECVBLOCK_PROC_H - -#include - -#define SEAFILE_TYPE_RECVBLOCK_PROC (seafile_recvblock_proc_get_type ()) -#define SEAFILE_RECVBLOCK_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVBLOCK_PROC, SeafileRecvblockProc)) -#define SEAFILE_IS_RECVBLOCK_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVBLOCK_PROC)) -#define SEAFILE_RECVBLOCK_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVBLOCK_PROC, SeafileRecvblockProcClass)) -#define IS_SEAFILE_RECVBLOCK_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVBLOCK_PROC)) -#define SEAFILE_RECVBLOCK_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVBLOCK_PROC, SeafileRecvblockProcClass)) - -typedef struct _SeafileRecvblockProc SeafileRecvblockProc; -typedef struct _SeafileRecvblockProcClass SeafileRecvblockProcClass; - -struct _SeafileRecvblockProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvblockProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvblock_proc_get_type (); - -#endif diff --git a/server/processors/recvblock-v2-proc.c b/server/processors/recvblock-v2-proc.c deleted file mode 100644 index 04d4987..0000000 --- a/server/processors/recvblock-v2-proc.c +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define _GNU_SOURCE -#include -#include -#include -#include -#include - -#include -#include -#include "net.h" -#include "utils.h" - -#include "seafile-session.h" -#include "fs-mgr.h" -#include "block-mgr.h" -#include "recvblock-v2-proc.h" - -#include "log.h" - -enum { - PREPARE, - READY, -}; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVBLOCK_V2_PROC, BlockProcPriv)) - -#define USE_PRIV \ - BlockProcPriv *priv = GET_PRIV(processor); - -static int block_proc_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void recv_block_cb (CEvent *event, void *vprocessor); -static void release_resource (CcnetProcessor *processor); - -G_DEFINE_TYPE (SeafileRecvblockV2Proc, seafile_recvblock_v2_proc, CCNET_TYPE_PROCESSOR) - -#define RECVBLOCK_PROC -#include "processors/blocktx-common-impl-v2.h" - -static void -seafile_recvblock_v2_proc_class_init (SeafileRecvblockV2ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvblock-v2-proc"; - proc_class->start = block_proc_start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (BlockProcPriv)); -} - -static void -seafile_recvblock_v2_proc_init (SeafileRecvblockV2Proc *processor) -{ -} - -static int -block_proc_start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - if (verify_session_token (processor, priv->repo_id, argc, argv) < 0) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - prepare_thread_data(processor, recv_blocks, recv_block_cb, priv->repo_id); - ccnet_processor_send_response (processor, "200", "OK", NULL, 0); - - return 0; -} - -static void -release_resource (CcnetProcessor *processor) -{ - release_thread (processor); - - CCNET_PROCESSOR_CLASS(seafile_recvblock_v2_proc_parent_class)->release_resource (processor); -} - -static void -recv_block_cb (CEvent *event, void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - BlockResponse *blk_rsp = event->data; - char buf[32]; - int len; - - len = snprintf (buf, 32, "%d", blk_rsp->block_idx); - ccnet_processor_send_response (processor, SC_ACK, SS_ACK, - buf, len + 1); - - g_free (blk_rsp); -} - -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - - switch (priv->tdata->state) { - case PREPARE: - if (memcmp (code, SC_BLOCKLIST, 3) == 0) { - process_block_list (processor, content, clen); - return; - } else if (memcmp (code, SC_GET_PORT, 3) == 0) { - send_port (processor); - return; - } - break; - } - - seaf_warning ("Bad code: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, SC_BAD_UPDATE_CODE, - SS_BAD_UPDATE_CODE, NULL, 0); - ccnet_processor_done (processor, FALSE); -} diff --git a/server/processors/recvblock-v2-proc.h b/server/processors/recvblock-v2-proc.h deleted file mode 100644 index 8718c5d..0000000 --- a/server/processors/recvblock-v2-proc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVBLOCK_V2_PROC_H -#define SEAFILE_RECVBLOCK_V2_PROC_H - -#include - -#define SEAFILE_TYPE_RECVBLOCK_V2_PROC (seafile_recvblock_v2_proc_get_type ()) -#define SEAFILE_RECVBLOCK_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVBLOCK_V2_PROC, SeafileRecvblockV2Proc)) -#define SEAFILE_IS_RECVBLOCK_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVBLOCK_V2_PROC)) -#define SEAFILE_RECVBLOCK_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVBLOCK_V2_PROC, SeafileRecvblockV2ProcClass)) -#define IS_SEAFILE_RECVBLOCK_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVBLOCK_V2_PROC)) -#define SEAFILE_RECVBLOCK_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVBLOCK_V2_PROC, SeafileRecvblockV2ProcClass)) - -typedef struct _SeafileRecvblockV2Proc SeafileRecvblockV2Proc; -typedef struct _SeafileRecvblockV2ProcClass SeafileRecvblockV2ProcClass; - -struct _SeafileRecvblockV2Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvblockV2ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvblock_v2_proc_get_type (); - -#endif diff --git a/server/processors/recvbranch-proc.c b/server/processors/recvbranch-proc.c deleted file mode 100644 index 1171b88..0000000 --- a/server/processors/recvbranch-proc.c +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include -#include -#include - -#include "seafile-session.h" -#include "recvbranch-proc.h" -#include "vc-common.h" - -#include "log.h" - -#define SC_BAD_COMMIT "401" -#define SS_BAD_COMMIT "Commit does not exist" -#define SC_NOT_FF "402" -#define SS_NOT_FF "Not fast forward" -#define SC_QUOTA_ERROR "403" -#define SS_QUOTA_ERROR "Failed to get quota" -#define SC_QUOTA_FULL "404" -#define SS_QUOTA_FULL "storage for the repo's owner is full" -#define SC_SERVER_ERROR "405" -#define SS_SERVER_ERROR "Internal server error" -#define SC_BAD_REPO "406" -#define SS_BAD_REPO "Repo does not exist" -#define SC_BAD_BRANCH "407" -#define SS_BAD_BRANCH "Branch does not exist" -#define SC_ACCESS_DENIED "410" -#define SS_ACCESS_DENIED "Access denied" - -typedef struct { - char repo_id[37]; - char *branch_name; - char new_head[41]; - char *email; - - char *rsp_code; - char *rsp_msg; -} SeafileRecvbranchProcPriv; - -G_DEFINE_TYPE (SeafileRecvbranchProc, seafile_recvbranch_proc, CCNET_TYPE_PROCESSOR) - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVBRANCH_PROC, SeafileRecvbranchProcPriv)) - -#define USE_PRIV \ - SeafileRecvbranchProcPriv *priv = GET_PRIV(processor); - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void *update_repo (void *vprocessor); -static void thread_done (void *result); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - g_free (priv->branch_name); - g_free (priv->rsp_code); - g_free (priv->rsp_msg); - - CCNET_PROCESSOR_CLASS (seafile_recvbranch_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_recvbranch_proc_class_init (SeafileRecvbranchProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvbranch-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileRecvbranchProcPriv)); -} - -static void -seafile_recvbranch_proc_init (SeafileRecvbranchProc *processor) -{ -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - char *session_token; - - if (argc != 4) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (!is_uuid_valid(argv[0]) || strlen(argv[2]) != 40) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - memcpy (priv->repo_id, argv[0], 36); - memcpy (priv->new_head, argv[2], 40); - priv->branch_name = g_strdup(argv[1]); - session_token = argv[3]; - - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, NULL) < 0) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - ccnet_processor_thread_create (processor, - seaf->job_mgr, - update_repo, - thread_done, - processor); - - return 0; -} - - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ -} - -static void * -update_repo (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - char *repo_id, *new_head; - SeafRepo *repo = NULL; - SeafBranch *branch = NULL; - SeafCommit *commit = NULL; - char old_commit_id[41]; - - repo_id = priv->repo_id; - new_head = priv->new_head; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - /* repo is deleted on server */ - priv->rsp_code = g_strdup (SC_BAD_REPO); - priv->rsp_msg = g_strdup (SC_BAD_REPO); - goto out; - - } - - /* Since this is the last step of upload procedure, commit should exist. */ - commit = seaf_commit_manager_get_commit (seaf->commit_mgr, - repo->id, repo->version, - new_head); - if (!commit) { - priv->rsp_code = g_strdup (SC_BAD_COMMIT); - priv->rsp_msg = g_strdup (SS_BAD_COMMIT); - goto out; - } - - if (seaf_quota_manager_check_quota (seaf->quota_mgr, repo_id) < 0) { - priv->rsp_code = g_strdup(SC_QUOTA_FULL); - priv->rsp_msg = g_strdup(SS_QUOTA_FULL); - goto out; - } - - branch = seaf_branch_manager_get_branch (seaf->branch_mgr, repo_id, "master"); - if (!branch) { - priv->rsp_code = g_strdup (SC_BAD_BRANCH); - priv->rsp_msg = g_strdup (SS_BAD_BRANCH); - goto out; - } - - /* If branch exists, check fast forward. */ - if (strcmp (new_head, branch->commit_id) != 0 && - !is_fast_forward (repo->id, repo->version, new_head, branch->commit_id)) { - seaf_warning ("Upload is not fast forward. Refusing.\n"); - - seaf_repo_unref (repo); - seaf_commit_unref (commit); - seaf_branch_unref (branch); - - priv->rsp_code = g_strdup (SC_NOT_FF); - priv->rsp_msg = g_strdup (SS_NOT_FF); - return vprocessor; - } - - /* Update branch. In case of concurrent update, we must ensure atomicity. - */ - memcpy (old_commit_id, branch->commit_id, 41); - seaf_branch_set_commit (branch, commit->commit_id); - if (seaf_branch_manager_test_and_update_branch (seaf->branch_mgr, - branch, old_commit_id) < 0) - { - priv->rsp_code = g_strdup (SC_NOT_FF); - priv->rsp_msg = g_strdup (SS_NOT_FF); - goto out; - } - - seaf_repo_manager_merge_virtual_repo (seaf->repo_mgr, repo_id, NULL); - -out: - if (repo) seaf_repo_unref (repo); - if (commit) seaf_commit_unref (commit); - if (branch) seaf_branch_unref (branch); - - if (!priv->rsp_code) { - priv->rsp_code = g_strdup (SC_OK); - priv->rsp_msg = g_strdup (SS_OK); - } - - return vprocessor; -} - -static void -thread_done (void *result) -{ - CcnetProcessor *processor = result; - USE_PRIV; - - if (strcmp (priv->rsp_code, SC_OK) == 0) { - /* Repo is updated, schedule repo size computation. */ - schedule_repo_size_computation (seaf->size_sched, priv->repo_id); - - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - ccnet_processor_done (processor, TRUE); - } else { - ccnet_processor_send_response (processor, - priv->rsp_code, priv->rsp_msg, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - diff --git a/server/processors/recvbranch-proc.h b/server/processors/recvbranch-proc.h deleted file mode 100644 index 42bed43..0000000 --- a/server/processors/recvbranch-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVBRANCH_PROC_H -#define SEAFILE_RECVBRANCH_PROC_H - -#include - - -#define SEAFILE_TYPE_RECVBRANCH_PROC (seafile_recvbranch_proc_get_type ()) -#define SEAFILE_RECVBRANCH_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVBRANCH_PROC, SeafileRecvbranchProc)) -#define SEAFILE_IS_RECVBRANCH_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVBRANCH_PROC)) -#define SEAFILE_RECVBRANCH_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVBRANCH_PROC, SeafileRecvbranchProcClass)) -#define IS_SEAFILE_RECVBRANCH_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVBRANCH_PROC)) -#define SEAFILE_RECVBRANCH_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVBRANCH_PROC, SeafileRecvbranchProcClass)) - -typedef struct _SeafileRecvbranchProc SeafileRecvbranchProc; -typedef struct _SeafileRecvbranchProcClass SeafileRecvbranchProcClass; - -struct _SeafileRecvbranchProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvbranchProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvbranch_proc_get_type (); - -#endif - diff --git a/server/processors/recvbranch-v2-proc.c b/server/processors/recvbranch-v2-proc.c deleted file mode 100644 index d46d1df..0000000 --- a/server/processors/recvbranch-v2-proc.c +++ /dev/null @@ -1,374 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include -#include -#include - -#include "seafile-session.h" -#include "recvbranch-v2-proc.h" -#include "vc-common.h" - -#include "merge-new.h" -#include "diff-simple.h" - -#include "log.h" - -#define SC_BAD_COMMIT "401" -#define SS_BAD_COMMIT "Commit does not exist" -#define SC_NOT_FF "402" -#define SS_NOT_FF "Not fast forward" -#define SC_QUOTA_ERROR "403" -#define SS_QUOTA_ERROR "Failed to get quota" -#define SC_QUOTA_FULL "404" -#define SS_QUOTA_FULL "storage for the repo's owner is full" -#define SC_SERVER_ERROR "405" -#define SS_SERVER_ERROR "Internal server error" -#define SC_BAD_REPO "406" -#define SS_BAD_REPO "Repo does not exist" -#define SC_BAD_BRANCH "407" -#define SS_BAD_BRANCH "Branch does not exist" -#define SC_ACCESS_DENIED "410" -#define SS_ACCESS_DENIED "Access denied" - -typedef struct { - char repo_id[37]; - char *branch_name; - char new_head[41]; - - char *rsp_code; - char *rsp_msg; -} SeafileRecvbranchProcPriv; - -G_DEFINE_TYPE (SeafileRecvbranchV2Proc, seafile_recvbranch_v2_proc, CCNET_TYPE_PROCESSOR) - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVBRANCH_V2_PROC, SeafileRecvbranchProcPriv)) - -#define USE_PRIV \ - SeafileRecvbranchProcPriv *priv = GET_PRIV(processor); - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void *update_repo (void *vprocessor); -static void thread_done (void *result); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - g_free (priv->branch_name); - g_free (priv->rsp_code); - g_free (priv->rsp_msg); - - CCNET_PROCESSOR_CLASS (seafile_recvbranch_v2_proc_parent_class)->release_resource (processor); -} - - -static void -seafile_recvbranch_v2_proc_class_init (SeafileRecvbranchV2ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvbranch-v2-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileRecvbranchProcPriv)); -} - -static void -seafile_recvbranch_v2_proc_init (SeafileRecvbranchV2Proc *processor) -{ -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - char *session_token; - - if (argc != 4) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (!is_uuid_valid(argv[0]) || strlen(argv[2]) != 40) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - memcpy (priv->repo_id, argv[0], 36); - memcpy (priv->new_head, argv[2], 40); - priv->branch_name = g_strdup(argv[1]); - session_token = argv[3]; - - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, NULL) < 0) { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - ccnet_processor_thread_create (processor, - seaf->job_mgr, - update_repo, - thread_done, - processor); - - return 0; -} - - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ -} - -static char * -gen_merge_description (SeafRepo *repo, - const char *merged_root, - const char *p1_root, - const char *p2_root) -{ - GList *p; - GList *results = NULL; - char *desc; - - diff_merge_roots (repo->store_id, repo->version, - merged_root, p1_root, p2_root, &results, TRUE); - - desc = diff_results_to_description (results); - - for (p = results; p; p = p->next) { - DiffEntry *de = p->data; - diff_entry_free (de); - } - g_list_free (results); - - return desc; -} - -static int -fast_forward_or_merge (const char *repo_id, - SeafCommit *base, - SeafCommit *new_commit) -{ -#define MAX_RETRY_COUNT 3 - - SeafRepo *repo = NULL; - SeafCommit *current_head = NULL, *merged_commit = NULL; - int retry_cnt = 0; - int ret = 0; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - seaf_warning ("Repo %s doesn't exist.\n", repo_id); - ret = -1; - goto out; - } - -retry: - current_head = seaf_commit_manager_get_commit (seaf->commit_mgr, - repo->id, repo->version, - repo->head->commit_id); - if (!current_head) { - seaf_warning ("Failed to find head commit of %s:%s.\n", - repo_id, repo->head->commit_id); - ret = -1; - goto out; - } - - /* Merge if base and head are not the same. */ - if (strcmp (base->commit_id, current_head->commit_id) != 0) { - MergeOptions opt; - const char *roots[3]; - char *desc = NULL; - - memset (&opt, 0, sizeof(opt)); - opt.n_ways = 3; - memcpy (opt.remote_repo_id, repo_id, 36); - memcpy (opt.remote_head, new_commit->commit_id, 40); - opt.do_merge = TRUE; - - roots[0] = base->root_id; /* base */ - roots[1] = current_head->root_id; /* head */ - roots[2] = new_commit->root_id; /* remote */ - - if (seaf_merge_trees (repo->store_id, repo->version, 3, roots, &opt) < 0) { - seaf_warning ("Failed to merge.\n"); - ret = -1; - goto out; - } - - if (!opt.conflict) - desc = g_strdup("Auto merge by system"); - else { - desc = gen_merge_description (repo, - opt.merged_tree_root, - current_head->root_id, - new_commit->root_id); - if (!desc) - desc = g_strdup("Auto merge by system"); - } - - merged_commit = seaf_commit_new(NULL, repo->id, opt.merged_tree_root, - new_commit->creator_name, EMPTY_SHA1, - desc, - 0); - g_free (desc); - - merged_commit->parent_id = g_strdup (current_head->commit_id); - merged_commit->second_parent_id = g_strdup (new_commit->commit_id); - merged_commit->new_merge = TRUE; - if (opt.conflict) - merged_commit->conflict = TRUE; - seaf_repo_to_commit (repo, merged_commit); - - if (seaf_commit_manager_add_commit (seaf->commit_mgr, merged_commit) < 0) { - seaf_warning ("Failed to add commit.\n"); - ret = -1; - goto out; - } - } else { - seaf_commit_ref (new_commit); - merged_commit = new_commit; - } - - seaf_branch_set_commit(repo->head, merged_commit->commit_id); - - if (seaf_branch_manager_test_and_update_branch(seaf->branch_mgr, - repo->head, - current_head->commit_id) < 0) - { - seaf_repo_unref (repo); - repo = NULL; - seaf_commit_unref (current_head); - current_head = NULL; - seaf_commit_unref (merged_commit); - merged_commit = NULL; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - seaf_warning ("Repo %s doesn't exist.\n", repo_id); - ret = -1; - goto out; - } - - if (++retry_cnt <= MAX_RETRY_COUNT) { - /* Sleep random time between 100 and 1000 millisecs. */ - usleep (g_random_int_range(1, 11) * 100 * 1000); - goto retry; - } else { - ret = -1; - goto out; - } - } - -out: - seaf_commit_unref (current_head); - seaf_commit_unref (merged_commit); - seaf_repo_unref (repo); - return ret; -} - -static void * -update_repo (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - char *repo_id, *new_head; - SeafRepo *repo = NULL; - SeafCommit *new_commit = NULL, *base = NULL; - - repo_id = priv->repo_id; - new_head = priv->new_head; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); - if (!repo) { - /* repo is deleted on server */ - priv->rsp_code = g_strdup (SC_BAD_REPO); - priv->rsp_msg = g_strdup (SC_BAD_REPO); - goto out; - - } - - /* Since this is the last step of upload procedure, commit should exist. */ - new_commit = seaf_commit_manager_get_commit (seaf->commit_mgr, - repo->id, repo->version, - new_head); - if (!new_commit) { - seaf_warning ("Failed to get commit %s for repo %s.\n", - new_head, repo->id); - priv->rsp_code = g_strdup (SC_BAD_COMMIT); - priv->rsp_msg = g_strdup (SS_BAD_COMMIT); - goto out; - } - - base = seaf_commit_manager_get_commit (seaf->commit_mgr, - repo->id, repo->version, - new_commit->parent_id); - if (!base) { - seaf_warning ("Failed to get commit %s for repo %s.\n", - new_commit->parent_id, repo->id); - priv->rsp_code = g_strdup (SC_BAD_COMMIT); - priv->rsp_msg = g_strdup (SS_BAD_COMMIT); - goto out; - } - - if (seaf_quota_manager_check_quota (seaf->quota_mgr, repo_id) < 0) { - priv->rsp_code = g_strdup(SC_QUOTA_FULL); - priv->rsp_msg = g_strdup(SS_QUOTA_FULL); - goto out; - } - - if (fast_forward_or_merge (repo_id, base, new_commit) < 0) { - priv->rsp_code = g_strdup(SC_SERVER_ERROR); - priv->rsp_msg = g_strdup(SS_SERVER_ERROR); - goto out; - } - - seaf_repo_manager_merge_virtual_repo (seaf->repo_mgr, repo_id, NULL); - -out: - seaf_repo_unref (repo); - seaf_commit_unref (new_commit); - seaf_commit_unref (base); - - if (!priv->rsp_code) { - priv->rsp_code = g_strdup (SC_OK); - priv->rsp_msg = g_strdup (SS_OK); - } - - return vprocessor; -} - -static void -thread_done (void *result) -{ - CcnetProcessor *processor = result; - USE_PRIV; - - if (strcmp (priv->rsp_code, SC_OK) == 0) { - /* Repo is updated, schedule repo size computation. */ - schedule_repo_size_computation (seaf->size_sched, priv->repo_id); - - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - ccnet_processor_done (processor, TRUE); - } else { - ccnet_processor_send_response (processor, - priv->rsp_code, priv->rsp_msg, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - diff --git a/server/processors/recvbranch-v2-proc.h b/server/processors/recvbranch-v2-proc.h deleted file mode 100644 index d740a09..0000000 --- a/server/processors/recvbranch-v2-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVBRANCH_V2_PROC_H -#define SEAFILE_RECVBRANCH_V2_PROC_H - -#include - - -#define SEAFILE_TYPE_RECVBRANCH_V2_PROC (seafile_recvbranch_v2_proc_get_type ()) -#define SEAFILE_RECVBRANCH_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVBRANCH_V2_PROC, SeafileRecvbranchV2Proc)) -#define SEAFILE_IS_RECVBRANCH_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVBRANCH_V2_PROC)) -#define SEAFILE_RECVBRANCH_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVBRANCH_V2_PROC, SeafileRecvbranchV2ProcClass)) -#define IS_SEAFILE_RECVBRANCH_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVBRANCH_V2_PROC)) -#define SEAFILE_RECVBRANCH_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVBRANCH_V2_PROC, SeafileRecvbranchV2ProcClass)) - -typedef struct _SeafileRecvbranchV2Proc SeafileRecvbranchV2Proc; -typedef struct _SeafileRecvbranchV2ProcClass SeafileRecvbranchV2ProcClass; - -struct _SeafileRecvbranchV2Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvbranchV2ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvbranch_v2_proc_get_type (); - -#endif - diff --git a/server/processors/recvcommit-proc.c b/server/processors/recvcommit-proc.c deleted file mode 100644 index e84350e..0000000 --- a/server/processors/recvcommit-proc.c +++ /dev/null @@ -1,245 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include -#include -#include -#include -#include - -#include -#include "net.h" -#include "utils.h" - -#include "seafile-session.h" -#include "commit-mgr.h" -#include "recvcommit-proc.h" -#include "processors/objecttx-common.h" -#include "seaf-utils.h" - -#include "log.h" - -#define CHECK_INTERVAL 100 /* 100ms */ - -enum { - RECV_IDS, - FETCH_OBJECT -}; - -typedef struct { - char object_path[SEAF_PATH_MAX]; - char tmp_object_path[SEAF_PATH_MAX]; - char buf[4096]; - char *bufptr; - int pending_objects; -} SeafileRecvcommitProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVCOMMIT_PROC, SeafileRecvcommitProcPriv)) - -#define USE_PRIV \ - SeafileRecvcommitProcPriv *priv = GET_PRIV(processor); - -static int recv_commit_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - - -G_DEFINE_TYPE (SeafileRecvcommitProc, seafile_recvcommit_proc, CCNET_TYPE_PROCESSOR) - -static void -seafile_recvcommit_proc_class_init (SeafileRecvcommitProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvcommit-proc"; - proc_class->start = recv_commit_start; - proc_class->handle_update = handle_update; - - g_type_class_add_private (klass, sizeof (SeafileRecvcommitProcPriv)); -} - -static void -seafile_recvcommit_proc_init (SeafileRecvcommitProc *processor) -{ -} - -inline static void -request_object_batch_begin (SeafileRecvcommitProcPriv *priv) -{ - priv->bufptr = priv->buf; -} - -inline static void -request_object_batch (SeafileRecvcommitProcPriv *priv, const char *id) -{ - memcpy (priv->bufptr, id, 40); - priv->bufptr += 40; - *priv->bufptr = '\n'; - priv->bufptr++; - - ++priv->pending_objects; -} - -inline static void -request_object_batch_flush (CcnetProcessor *processor, - SeafileRecvcommitProcPriv *priv) -{ - if (priv->bufptr == priv->buf) - return; - *priv->bufptr = '\0'; /* add ending '\0' */ - priv->bufptr++; - ccnet_processor_send_response (processor, SC_GET_OBJECT, SS_GET_OBJECT, - priv->buf, priv->bufptr - priv->buf); -} - -static int -recv_commit_start (CcnetProcessor *processor, int argc, char **argv) -{ - char *session_token; - - if (argc != 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - session_token = argv[1]; - if (seaf_token_manager_verify_token (seaf->token_mgr, - processor->peer_id, - session_token, NULL) == 0) { - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - processor->state = RECV_IDS; - return 0; - } else { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } -} - -static void -check_commit (CcnetProcessor *processor, const char *commit_id) -{ - USE_PRIV; - - if (!seaf_commit_manager_commit_exists (seaf->commit_mgr, commit_id)) { - request_object_batch (priv, commit_id); - } -} - -static int -save_commit (ObjectPack *pack, int len) -{ - return seaf_obj_store_write_obj (seaf->commit_mgr->obj_store, - pack->id, - pack->object, - len - 41); -} - -static void -receive_commit (CcnetProcessor *processor, char *content, int clen) -{ - USE_PRIV; - ObjectPack *pack = (ObjectPack *)content; - - if (clen < sizeof(ObjectPack)) { - seaf_warning ("invalid object id.\n"); - goto bad; - } - - --priv->pending_objects; - - /* TODO: check commit format here. */ - - if (save_commit (pack, clen) < 0) { - goto bad; - } - - if (priv->pending_objects == 0) { - ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); - ccnet_processor_done (processor, TRUE); - } - - return; - -bad: - ccnet_processor_send_response (processor, SC_BAD_OBJECT, - SS_BAD_OBJECT, NULL, 0); - seaf_warning ("Bad commit object received.\n"); - ccnet_processor_done (processor, FALSE); -} - -static void -process_commit_list (CcnetProcessor *processor, char *content, int clen) -{ - USE_PRIV; - char *object_id; - int n_objects; - int i; - - if (clen % 41 != 1 || content[clen-1] != '\0') { - seaf_warning ("Bad commit id list.\n"); - ccnet_processor_send_response (processor, SC_BAD_OL, SS_BAD_OL, NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - n_objects = clen/41; - - request_object_batch_begin(priv); - - object_id = content; - for (i = 0; i < n_objects; ++i) { - object_id[40] = '\0'; - check_commit (processor, object_id); - object_id += 41; - } - - request_object_batch_flush (processor, priv); - - if (priv->pending_objects == 0) { - ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); - ccnet_processor_done (processor, TRUE); - } -} - -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - switch (processor->state) { - case RECV_IDS: - if (strncmp(code, SC_COMMIT_IDS, 3) == 0) { - /* add to inspect queue */ - process_commit_list (processor, content, clen); - } else if (strncmp(code, SC_END, 3) == 0) { - /* change state to FETCH_OBJECT */ - processor->state = FETCH_OBJECT; - } else { - seaf_warning ("Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - break; - case FETCH_OBJECT: - if (strncmp(code, SC_OBJECT, 3) == 0) { - receive_commit (processor, content, clen); - } else { - seaf_warning ("Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - break; - default: - g_return_if_reached (); - } -} diff --git a/server/processors/recvcommit-proc.h b/server/processors/recvcommit-proc.h deleted file mode 100644 index f701677..0000000 --- a/server/processors/recvcommit-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVCOMMIT_PROC_H -#define SEAFILE_RECVCOMMIT_PROC_H - -#include - - -#define SEAFILE_TYPE_RECVCOMMIT_PROC (seafile_recvcommit_proc_get_type ()) -#define SEAFILE_RECVCOMMIT_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVCOMMIT_PROC, SeafileRecvcommitProc)) -#define SEAFILE_IS_RECVCOMMIT_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVCOMMIT_PROC)) -#define SEAFILE_RECVCOMMIT_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVCOMMIT_PROC, SeafileRecvcommitProcClass)) -#define IS_SEAFILE_RECVCOMMIT_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVCOMMIT_PROC)) -#define SEAFILE_RECVCOMMIT_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVCOMMIT_PROC, SeafileRecvcommitProcClass)) - -typedef struct _SeafileRecvcommitProc SeafileRecvcommitProc; -typedef struct _SeafileRecvcommitProcClass SeafileRecvcommitProcClass; - -struct _SeafileRecvcommitProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvcommitProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvcommit_proc_get_type (); - -#endif diff --git a/server/processors/recvcommit-v2-proc.c b/server/processors/recvcommit-v2-proc.c deleted file mode 100644 index 9e243a1..0000000 --- a/server/processors/recvcommit-v2-proc.c +++ /dev/null @@ -1,180 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include - -#include -#include "net.h" -#include "utils.h" - -#include "seafile-session.h" -#include "recvcommit-v2-proc.h" -#include "processors/objecttx-common.h" -#include "seaf-utils.h" - -#include "log.h" - -enum { - INIT, - RECV_OBJECT -}; - -typedef struct { - guint32 writer_id; - gboolean registered; -} RecvcommitPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVCOMMIT_V2_PROC, RecvcommitPriv)) - -#define USE_PRIV \ - RecvcommitPriv *priv = GET_PRIV(processor); - -static int recv_commit_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void -write_done_cb (OSAsyncResult *res, void *cb_data); - - -G_DEFINE_TYPE (SeafileRecvcommitV2Proc, seafile_recvcommit_v2_proc, CCNET_TYPE_PROCESSOR) - -static void -release_resource (CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->registered) - seaf_obj_store_unregister_async_write (seaf->commit_mgr->obj_store, - priv->writer_id); - - CCNET_PROCESSOR_CLASS (seafile_recvcommit_v2_proc_parent_class)->release_resource (processor); -} - -static void -seafile_recvcommit_v2_proc_class_init (SeafileRecvcommitV2ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvcommit-v2-proc"; - proc_class->start = recv_commit_start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (RecvcommitPriv)); -} - -static void -seafile_recvcommit_v2_proc_init (SeafileRecvcommitV2Proc *processor) -{ -} - -static int -recv_commit_start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - char *session_token; - - if (argc != 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - session_token = argv[1]; - if (seaf_token_manager_verify_token (seaf->token_mgr, - processor->peer_id, - session_token, NULL) == 0) { - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - processor->state = RECV_OBJECT; - priv->writer_id = - seaf_obj_store_register_async_write (seaf->commit_mgr->obj_store, - write_done_cb, - processor); - priv->registered = TRUE; - return 0; - } else { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } -} - -static void -write_done_cb (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - - if (!res->success) { - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - seaf_warning ("[recvcommit] Failed to write commit object.\n"); - ccnet_processor_done (processor, FALSE); - } - /* FIXME: need to send ACK if success. */ -} - -static int -save_commit (CcnetProcessor *processor, ObjectPack *pack, int len) -{ - USE_PRIV; - - return seaf_obj_store_async_write (seaf->commit_mgr->obj_store, - priv->writer_id, - pack->id, - pack->object, - len - 41); -} - -static void -receive_commit (CcnetProcessor *processor, char *content, int clen) -{ - ObjectPack *pack = (ObjectPack *)content; - - if (clen < sizeof(ObjectPack)) { - seaf_warning ("[recvcommit] invalid object id.\n"); - goto bad; - } - - g_debug ("[recvcommit] recv commit object %s\n", pack->id); - - if (save_commit (processor, pack, clen) < 0) { - goto bad; - } - - return; - -bad: - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - seaf_warning ("[recvcommit] Failed to write commit object.\n"); - ccnet_processor_done (processor, FALSE); -} - -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - switch (processor->state) { - case RECV_OBJECT: - if (strncmp(code, SC_OBJECT, 3) == 0) { - receive_commit (processor, content, clen); - } else if (strncmp(code, SC_END, 3) == 0) { - g_debug ("[recvcommit] Recv commit end.\n"); - ccnet_processor_done (processor, TRUE); - } else { - seaf_warning ("[recvcommit] Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - break; - default: - g_return_if_reached (); - } -} diff --git a/server/processors/recvcommit-v2-proc.h b/server/processors/recvcommit-v2-proc.h deleted file mode 100644 index bf397f8..0000000 --- a/server/processors/recvcommit-v2-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVCOMMIT_V2_PROC_H -#define SEAFILE_RECVCOMMIT_V2_PROC_H - -#include - - -#define SEAFILE_TYPE_RECVCOMMIT_V2_PROC (seafile_recvcommit_v2_proc_get_type ()) -#define SEAFILE_RECVCOMMIT_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVCOMMIT_V2_PROC, SeafileRecvcommitV2Proc)) -#define SEAFILE_IS_RECVCOMMIT_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVCOMMIT_V2_PROC)) -#define SEAFILE_RECVCOMMIT_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVCOMMIT_V2_PROC, SeafileRecvcommitV2ProcClass)) -#define IS_SEAFILE_RECVCOMMIT_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVCOMMIT_V2_PROC)) -#define SEAFILE_RECVCOMMIT_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVCOMMIT_V2_PROC, SeafileRecvcommitV2ProcClass)) - -typedef struct _SeafileRecvcommitV2Proc SeafileRecvcommitV2Proc; -typedef struct _SeafileRecvcommitV2ProcClass SeafileRecvcommitV2ProcClass; - -struct _SeafileRecvcommitV2Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvcommitV2ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvcommit_v2_proc_get_type (); - -#endif diff --git a/server/processors/recvcommit-v3-proc.c b/server/processors/recvcommit-v3-proc.c deleted file mode 100644 index c5825a4..0000000 --- a/server/processors/recvcommit-v3-proc.c +++ /dev/null @@ -1,231 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include - -#include -#include "net.h" -#include "utils.h" - -#include "seafile-session.h" -#include "recvcommit-v3-proc.h" -#include "processors/objecttx-common.h" -#include "seaf-utils.h" - -enum { - INIT, - RECV_OBJECT -}; - -typedef struct { - guint32 writer_id; - gboolean registered; - - /* Used for getting repo info */ - char repo_id[37]; - int repo_version; - gboolean success; -} RecvcommitPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVCOMMIT_V3_PROC, RecvcommitPriv)) - -#define USE_PRIV \ - RecvcommitPriv *priv = GET_PRIV(processor); - -static int recv_commit_start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); -static void -write_done_cb (OSAsyncResult *res, void *cb_data); - - -G_DEFINE_TYPE (SeafileRecvcommitV3Proc, seafile_recvcommit_v3_proc, CCNET_TYPE_PROCESSOR) - -static void -release_resource (CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->registered) - seaf_obj_store_unregister_async_write (seaf->commit_mgr->obj_store, - priv->writer_id); - - CCNET_PROCESSOR_CLASS (seafile_recvcommit_v3_proc_parent_class)->release_resource (processor); -} - -static void -seafile_recvcommit_v3_proc_class_init (SeafileRecvcommitV3ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvcommit-v3-proc"; - proc_class->start = recv_commit_start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (RecvcommitPriv)); -} - -static void -seafile_recvcommit_v3_proc_init (SeafileRecvcommitV3Proc *processor) -{ -} - -static void * -get_repo_info_thread (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %s.\n", priv->repo_id); - priv->success = FALSE; - return data; - } - - priv->repo_version = repo->version; - priv->success = TRUE; - - seaf_repo_unref (repo); - return data; -} - -static void -get_repo_info_done (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (priv->success) { - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - processor->state = RECV_OBJECT; - priv->writer_id = - seaf_obj_store_register_async_write (seaf->commit_mgr->obj_store, - priv->repo_id, - priv->repo_version, - write_done_cb, - processor); - priv->registered = TRUE; - } else { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static int -recv_commit_start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - char *session_token; - - if (argc != 2) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - session_token = argv[1]; - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, priv->repo_id) == 0) { - ccnet_processor_thread_create (processor, - seaf->job_mgr, - get_repo_info_thread, - get_repo_info_done, - processor); - return 0; - } else { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } -} - -static void -write_done_cb (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - - if (!res->success) { - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - seaf_warning ("[recvcommit] Failed to write commit object.\n"); - ccnet_processor_done (processor, FALSE); - } else { - ccnet_processor_send_response (processor, SC_ACK, SS_ACK, NULL, 0); - } -} - -static int -save_commit (CcnetProcessor *processor, ObjectPack *pack, int len) -{ - USE_PRIV; - - return seaf_obj_store_async_write (seaf->commit_mgr->obj_store, - priv->writer_id, - pack->id, - pack->object, - len - 41, - TRUE); -} - -static void -receive_commit (CcnetProcessor *processor, char *content, int clen) -{ - ObjectPack *pack = (ObjectPack *)content; - - if (clen < sizeof(ObjectPack)) { - seaf_warning ("[recvcommit] invalid object id.\n"); - goto bad; - } - - seaf_debug ("[recvcommit] recv commit object %.8s\n", pack->id); - - if (save_commit (processor, pack, clen) < 0) { - goto bad; - } - - return; - -bad: - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - seaf_warning ("[recvcommit] Failed to write commit object.\n"); - ccnet_processor_done (processor, FALSE); -} - -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - switch (processor->state) { - case RECV_OBJECT: - if (strncmp(code, SC_OBJECT, 3) == 0) { - receive_commit (processor, content, clen); - } else if (strncmp(code, SC_END, 3) == 0) { - seaf_debug ("[recvcommit] Recv commit end.\n"); - ccnet_processor_done (processor, TRUE); - } else { - seaf_warning ("[recvcommit] Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - break; - default: - g_return_if_reached (); - } -} diff --git a/server/processors/recvcommit-v3-proc.h b/server/processors/recvcommit-v3-proc.h deleted file mode 100644 index ebbdadd..0000000 --- a/server/processors/recvcommit-v3-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVCOMMIT_V3_PROC_H -#define SEAFILE_RECVCOMMIT_V3_PROC_H - -#include - - -#define SEAFILE_TYPE_RECVCOMMIT_V3_PROC (seafile_recvcommit_v3_proc_get_type ()) -#define SEAFILE_RECVCOMMIT_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVCOMMIT_V3_PROC, SeafileRecvcommitV3Proc)) -#define SEAFILE_IS_RECVCOMMIT_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVCOMMIT_V3_PROC)) -#define SEAFILE_RECVCOMMIT_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVCOMMIT_V3_PROC, SeafileRecvcommitV3ProcClass)) -#define IS_SEAFILE_RECVCOMMIT_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVCOMMIT_V3_PROC)) -#define SEAFILE_RECVCOMMIT_V3_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVCOMMIT_V3_PROC, SeafileRecvcommitV3ProcClass)) - -typedef struct _SeafileRecvcommitV3Proc SeafileRecvcommitV3Proc; -typedef struct _SeafileRecvcommitV3ProcClass SeafileRecvcommitV3ProcClass; - -struct _SeafileRecvcommitV3Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvcommitV3ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvcommit_v3_proc_get_type (); - -#endif diff --git a/server/processors/recvfs-proc.c b/server/processors/recvfs-proc.c deleted file mode 100644 index 90475ef..0000000 --- a/server/processors/recvfs-proc.c +++ /dev/null @@ -1,630 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include -#include -#include -#include - -#include -#include "utils.h" - -#include "seafile-session.h" -#include "fs-mgr.h" -#include "processors/objecttx-common.h" -#include "recvfs-proc.h" -#include "seaf-utils.h" - -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_NUM_BATCH 64 -#define MAX_CHECKING_DIRS 1000 - -enum { - RECV_ROOT, - FETCH_OBJECT -}; - -typedef struct { - GList *fs_roots; - int n_roots; - - int inspect_objects; - int pending_objects; - char buf[4096]; - char *bufptr; - int n_batch; - - GHashTable *fs_objects; - - int checking_dirs; - GQueue *dir_queue; - - char *obj_seg; - int obj_seg_len; - - gboolean registered; - guint32 reader_id; - guint32 writer_id; - guint32 stat_id; - - /* Used for getting repo info */ - char repo_id[37]; - char store_id[37]; - int repo_version; - gboolean success; -} SeafileRecvfsProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVFS_PROC, SeafileRecvfsProcPriv)) - -#define USE_PRIV \ - SeafileRecvfsProcPriv *priv = GET_PRIV(processor); - - -G_DEFINE_TYPE (SeafileRecvfsProc, seafile_recvfs_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static void -free_dir_id (gpointer data, gpointer user_data) -{ - g_free (data); -} - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - if (priv->fs_objects) - g_hash_table_destroy (priv->fs_objects); - - string_list_free (priv->fs_roots); - - g_queue_foreach (priv->dir_queue, free_dir_id, NULL); - g_queue_free (priv->dir_queue); - - g_free (priv->obj_seg); - - if (priv->registered) { - seaf_obj_store_unregister_async_read (seaf->fs_mgr->obj_store, - priv->reader_id); - seaf_obj_store_unregister_async_write (seaf->fs_mgr->obj_store, - priv->writer_id); - seaf_obj_store_unregister_async_stat (seaf->fs_mgr->obj_store, - priv->stat_id); - } - - CCNET_PROCESSOR_CLASS (seafile_recvfs_proc_parent_class)->release_resource (processor); -} - -static void -seafile_recvfs_proc_class_init (SeafileRecvfsProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvfs-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileRecvfsProcPriv)); -} - -static void -seafile_recvfs_proc_init (SeafileRecvfsProc *processor) -{ -} - -inline static void -request_object_batch_begin (SeafileRecvfsProcPriv *priv) -{ - priv->bufptr = priv->buf; - priv->n_batch = 0; -} - -inline static void -request_object_batch_flush (CcnetProcessor *processor, - SeafileRecvfsProcPriv *priv) -{ - if (priv->bufptr == priv->buf) - return; - *priv->bufptr = '\0'; /* add ending '\0' */ - priv->bufptr++; - ccnet_processor_send_response (processor, SC_GET_OBJECT, SS_GET_OBJECT, - priv->buf, priv->bufptr - priv->buf); - - /* Clean state */ - priv->n_batch = 0; - priv->bufptr = priv->buf; -} - -inline static void -request_object_batch (CcnetProcessor *processor, - SeafileRecvfsProcPriv *priv, const char *id) -{ - memcpy (priv->bufptr, id, 40); - priv->bufptr += 40; - *priv->bufptr = '\n'; - priv->bufptr++; - - /* Flush when too many objects batched. */ - if (++priv->n_batch == MAX_NUM_BATCH) - request_object_batch_flush (processor, priv); - ++priv->pending_objects; -} - -static int -check_seafdir (CcnetProcessor *processor, SeafDir *dir) -{ - USE_PRIV; - GList *ptr; - SeafDirent *dent; - - for (ptr = dir->entries; ptr != NULL; ptr = ptr->next) { - dent = ptr->data; - - if (strcmp (dent->id, EMPTY_SHA1) == 0) - continue; - - /* Don't check objects that have been checked before. */ - if (priv->fs_objects && g_hash_table_lookup (priv->fs_objects, dent->id)) - continue; - - if (S_ISDIR(dent->mode)) { - g_queue_push_tail (priv->dir_queue, g_strdup(dent->id)); - } else { -#ifdef DEBUG - seaf_debug ("[recvfs] Inspect file %s.\n", dent->id); -#endif - - /* For file, we just need to check existence. */ - if (seaf_obj_store_async_stat (seaf->fs_mgr->obj_store, - priv->stat_id, - dent->id) < 0) { - seaf_warning ("[recvfs] Failed to start async stat of %s.\n", - dent->id); - goto bad; - } - ++(priv->inspect_objects); - } - - if (priv->fs_objects) - g_hash_table_insert (priv->fs_objects, g_strdup(dent->id), (gpointer)1); - } - - return 0; - -bad: - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; -} - -static void -on_seafdir_read (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - SeafDir *dir; - USE_PRIV; - - --(priv->inspect_objects); - --(priv->checking_dirs); - - if (!res->success) { - request_object_batch (processor, priv, res->obj_id); - return; - } - -#ifdef DEBUG - seaf_debug ("[recvfs] Read seafdir %s.\n", res->obj_id); -#endif - - dir = seaf_dir_from_data (res->obj_id, res->data, res->len, - (priv->repo_version > 0)); - if (!dir) { - seaf_warning ("[recvfs] Corrupt dir object %s.\n", res->obj_id); - request_object_batch (processor, priv, res->obj_id); - return; - } - - int ret = check_seafdir (processor, dir); - seaf_dir_free (dir); - if (ret < 0) - return; -} - -static void -on_seafile_stat (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - USE_PRIV; - - --(priv->inspect_objects); - -#ifdef DEBUG - seaf_debug ("[recvfs] Stat seafile %s.\n", res->obj_id); -#endif - - if (!res->success) - request_object_batch (processor, priv, res->obj_id); -} - -static void -on_fs_write (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - USE_PRIV; - - if (!res->success) { - seaf_warning ("[recvfs] Failed to write %s.\n", res->obj_id); - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - --priv->pending_objects; - -#ifdef DEBUG - seaf_debug ("[recvfs] Wrote fs object %s.\n", res->obj_id); -#endif -} - -static int -check_end_condition (CcnetProcessor *processor) -{ - USE_PRIV; - - char *dir_id; - while (priv->checking_dirs < MAX_CHECKING_DIRS) { - dir_id = g_queue_pop_head (priv->dir_queue); - if (!dir_id) - break; - -#ifdef DEBUG - seaf_debug ("[recvfs] Inspect dir %s.\n", dir_id); -#endif - - if (seaf_obj_store_async_read (seaf->fs_mgr->obj_store, - priv->reader_id, - dir_id) < 0) { - seaf_warning ("[recvfs] Failed to start async read of %s.\n", dir_id); - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return FALSE; - } - g_free (dir_id); - - ++(priv->inspect_objects); - ++(priv->checking_dirs); - } - - if (priv->checking_dirs > 100) - seaf_debug ("Number of checking dirs: %d.\n", priv->checking_dirs); - if (priv->inspect_objects > 1000) - seaf_debug ("Number of inspect objects: %d.\n", priv->inspect_objects); - - /* Flush periodically. */ - request_object_batch_flush (processor, priv); - - if (priv->pending_objects == 0 && priv->inspect_objects == 0) { - seaf_debug ("Recv fs end.\n"); - ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); - ccnet_processor_done (processor, TRUE); - return FALSE; - } else - return TRUE; -} - -static void -register_async_io (CcnetProcessor *processor) -{ - USE_PRIV; - - priv->registered = TRUE; - priv->reader_id = seaf_obj_store_register_async_read (seaf->fs_mgr->obj_store, - priv->store_id, - priv->repo_version, - on_seafdir_read, - processor); - priv->stat_id = seaf_obj_store_register_async_stat (seaf->fs_mgr->obj_store, - priv->store_id, - priv->repo_version, - on_seafile_stat, - processor); - priv->writer_id = seaf_obj_store_register_async_write (seaf->fs_mgr->obj_store, - priv->store_id, - priv->repo_version, - on_fs_write, - processor); -} - -static void * -get_repo_info_thread (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %s.\n", priv->repo_id); - priv->success = FALSE; - return data; - } - - memcpy (priv->store_id, repo->store_id, 36); - priv->repo_version = repo->version; - priv->success = TRUE; - - seaf_repo_unref (repo); - return data; -} - -static void -get_repo_info_done (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (priv->success) { - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - processor->state = RECV_ROOT; - priv->dir_queue = g_queue_new (); - register_async_io (processor); - } else { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char *session_token; - USE_PRIV; - - if (argc != 1) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - session_token = argv[0]; - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, priv->repo_id) == 0) { - ccnet_processor_thread_create (processor, - seaf->job_mgr, - get_repo_info_thread, - get_repo_info_done, - processor); - return 0; - } else { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } -} - -static int -save_fs_object (CcnetProcessor *processor, ObjectPack *pack, int len) -{ - USE_PRIV; - - return seaf_obj_store_async_write (seaf->fs_mgr->obj_store, - priv->writer_id, - pack->id, - pack->object, - len - 41, - FALSE); -} - -static int -recv_fs_object (CcnetProcessor *processor, char *content, int clen) -{ - USE_PRIV; - ObjectPack *pack = (ObjectPack *)content; - SeafFSObject *fs_obj = NULL; - - if (clen < sizeof(ObjectPack)) { - seaf_warning ("invalid object id.\n"); - goto bad; - } - - seaf_debug ("[recvfs] Recv fs object %.8s.\n", pack->id); - - fs_obj = seaf_fs_object_from_data(pack->id, - pack->object, clen - sizeof(ObjectPack), - (priv->repo_version > 0)); - if (!fs_obj) { - seaf_warning ("Bad fs object %s.\n", pack->id); - goto bad; - } - - if (fs_obj->type == SEAF_METADATA_TYPE_DIR) { - SeafDir *dir = (SeafDir *)fs_obj; - int ret = check_seafdir (processor, dir); - if (ret < 0) - goto bad; - } else if (fs_obj->type == SEAF_METADATA_TYPE_FILE) { - /* TODO: check seafile format. */ -#if 0 - int ret = seafile_check_data_format (pack->object, clen - 41); - if (ret < 0) { - goto bad; - } -#endif - } - - seaf_fs_object_free (fs_obj); - - if (save_fs_object (processor, pack, clen) < 0) { - goto bad; - } - - return 0; - -bad: - ccnet_processor_send_response (processor, SC_BAD_OBJECT, - SS_BAD_OBJECT, NULL, 0); - seaf_warning ("[recvfs] Bad fs object received.\n"); - ccnet_processor_done (processor, FALSE); - - seaf_fs_object_free (fs_obj); - - return -1; -} - -static void -recv_fs_object_seg (CcnetProcessor *processor, char *content, int clen) -{ - USE_PRIV; - - /* Append the received object segment to the end */ - priv->obj_seg = g_realloc (priv->obj_seg, priv->obj_seg_len + clen); - memcpy (priv->obj_seg + priv->obj_seg_len, content, clen); - - seaf_debug ("[recvfs] Get obj seg: \n", - priv->obj_seg, priv->obj_seg_len, clen); - - priv->obj_seg_len += clen; -} - -static void -process_fs_object_seg (CcnetProcessor *processor) -{ - USE_PRIV; - - if (recv_fs_object (processor, priv->obj_seg, priv->obj_seg_len) == 0) { - g_free (priv->obj_seg); - priv->obj_seg = NULL; - priv->obj_seg_len = 0; - } -} - -static void -process_fsroot_list (CcnetProcessor *processor) -{ - GList *ptr; - char *object_id; - USE_PRIV; - - /* When there are more than one fs roots, there may be many - * duplicate fs objects between different commits. - * We remember checked fs objects in a hash table to avoid - * redundant checks. - */ - if (priv->n_roots > 1) - priv->fs_objects = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - request_object_batch_begin (priv); - - for (ptr = priv->fs_roots; ptr != NULL; ptr = ptr->next) { - object_id = ptr->data; - - /* Empty dir or file always exists. */ - if (strcmp (object_id, EMPTY_SHA1) == 0) { - object_id += 41; - continue; - } - -#ifdef DEBUG - seaf_debug ("[recvfs] Inspect object %s.\n", object_id); -#endif - - g_queue_push_tail (priv->dir_queue, g_strdup(object_id)); - - g_free (object_id); - } - - g_list_free (priv->fs_roots); - priv->fs_roots = NULL; -} - -static void -queue_fs_roots (CcnetProcessor *processor, char *content, int clen) -{ - USE_PRIV; - char *object_id; - int n_objects; - int i; - - if (clen % 41 != 0) { - seaf_warning ("Bad fs root list.\n"); - ccnet_processor_send_response (processor, SC_BAD_OL, SS_BAD_OL, NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - n_objects = clen/41; - object_id = content; - for (i = 0; i < n_objects; ++i) { - object_id[40] = '\0'; - priv->fs_roots = g_list_prepend (priv->fs_roots, g_strdup(object_id)); - object_id += 41; - ++(priv->n_roots); - } - - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - switch (processor->state) { - case RECV_ROOT: - if (strncmp(code, SC_ROOT, 3) == 0) { - queue_fs_roots (processor, content, clen); - } else if (strncmp(code, SC_ROOT_END, 3) == 0) { - /* change state to FETCH_OBJECT */ - process_fsroot_list (processor); - processor->timer = ccnet_timer_new ( - (TimerCB)check_end_condition, processor, CHECK_INTERVAL); - processor->state = FETCH_OBJECT; - } else { - seaf_warning ("Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - break; - case FETCH_OBJECT: - if (strncmp(code, SC_OBJ_SEG, 3) == 0) { - recv_fs_object_seg (processor, content, clen); - - } else if (strncmp(code, SC_OBJ_SEG_END, 3) == 0) { - recv_fs_object_seg (processor, content, clen); - process_fs_object_seg (processor); - } else if (strncmp(code, SC_OBJECT, 3) == 0) { - recv_fs_object (processor, content, clen); - } else { - seaf_warning ("Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - break; - default: - g_return_if_reached (); - } -} diff --git a/server/processors/recvfs-proc.h b/server/processors/recvfs-proc.h deleted file mode 100644 index a58f050..0000000 --- a/server/processors/recvfs-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVFS_PROC_H -#define SEAFILE_RECVFS_PROC_H - -#include - - -#define SEAFILE_TYPE_RECVFS_PROC (seafile_recvfs_proc_get_type ()) -#define SEAFILE_RECVFS_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVFS_PROC, SeafileRecvfsProc)) -#define SEAFILE_IS_RECVFS_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVFS_PROC)) -#define SEAFILE_RECVFS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVFS_PROC, SeafileRecvfsProcClass)) -#define IS_SEAFILE_RECVFS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVFS_PROC)) -#define SEAFILE_RECVFS_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVFS_PROC, SeafileRecvfsProcClass)) - -typedef struct _SeafileRecvfsProc SeafileRecvfsProc; -typedef struct _SeafileRecvfsProcClass SeafileRecvfsProcClass; - -struct _SeafileRecvfsProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvfsProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvfs_proc_get_type (); - -#endif - diff --git a/server/processors/recvfs-v2-proc.c b/server/processors/recvfs-v2-proc.c deleted file mode 100644 index ad879da..0000000 --- a/server/processors/recvfs-v2-proc.c +++ /dev/null @@ -1,420 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER -#include "log.h" - -#include -#include -#include -#include - -#include -#include "utils.h" - -#include "seafile-session.h" -#include "fs-mgr.h" -#include "processors/objecttx-common.h" -#include "recvfs-v2-proc.h" -#include "seaf-utils.h" - -enum { - CHECK_OBJECT_LIST = 0, - RECV_OBJECTS, -}; - -typedef struct { - char *obj_seg; - int obj_seg_len; - - gboolean registered; - guint32 writer_id; - - /* Used for getting repo info */ - char repo_id[37]; - char store_id[37]; - int repo_version; - gboolean success; - - /* Used to check object list */ - char *recv_objs; - int recv_len; - GList *needed_objs; - int n_needed; - - int total_needed; - int n_saved; -} SeafileRecvfsProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_RECVFS_V2_PROC, SeafileRecvfsProcPriv)) - -#define USE_PRIV \ - SeafileRecvfsProcPriv *priv = GET_PRIV(processor); - - -G_DEFINE_TYPE (SeafileRecvfsV2Proc, seafile_recvfs_v2_proc, CCNET_TYPE_PROCESSOR) - -static int start (CcnetProcessor *processor, int argc, char **argv); -static void handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - g_free (priv->obj_seg); - - if (priv->registered) { - seaf_obj_store_unregister_async_write (seaf->fs_mgr->obj_store, - priv->writer_id); - } - - g_free (priv->recv_objs); - string_list_free (priv->needed_objs); - - CCNET_PROCESSOR_CLASS (seafile_recvfs_v2_proc_parent_class)->release_resource (processor); -} - -static void -seafile_recvfs_v2_proc_class_init (SeafileRecvfsV2ProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "recvfs-v2-proc"; - proc_class->start = start; - proc_class->handle_update = handle_update; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileRecvfsProcPriv)); -} - -static void -seafile_recvfs_v2_proc_init (SeafileRecvfsV2Proc *processor) -{ -} - -static void -on_fs_write (OSAsyncResult *res, void *cb_data); - -static void -register_async_io (CcnetProcessor *processor) -{ - USE_PRIV; - - priv->registered = TRUE; - priv->writer_id = seaf_obj_store_register_async_write (seaf->fs_mgr->obj_store, - priv->store_id, - priv->repo_version, - on_fs_write, - processor); -} - -static void * -get_repo_info_thread (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - SeafRepo *repo; - - repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); - if (!repo) { - seaf_warning ("Failed to get repo %s.\n", priv->repo_id); - priv->success = FALSE; - return data; - } - - memcpy (priv->store_id, repo->store_id, 36); - priv->repo_version = repo->version; - priv->success = TRUE; - - seaf_repo_unref (repo); - return data; -} - -static void -get_repo_info_done (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (priv->success) { - ccnet_processor_send_response (processor, SC_OK, SS_OK, NULL, 0); - register_async_io (processor); - } else { - ccnet_processor_send_response (processor, SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } -} - -static int -start (CcnetProcessor *processor, int argc, char **argv) -{ - char *session_token; - USE_PRIV; - - if (argc != 1) { - ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - session_token = argv[0]; - if (seaf_token_manager_verify_token (seaf->token_mgr, - NULL, - processor->peer_id, - session_token, priv->repo_id) == 0) { - ccnet_processor_thread_create (processor, - seaf->job_mgr, - get_repo_info_thread, - get_repo_info_done, - processor); - return 0; - } else { - ccnet_processor_send_response (processor, - SC_ACCESS_DENIED, SS_ACCESS_DENIED, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } -} - -static void -on_fs_write (OSAsyncResult *res, void *cb_data) -{ - CcnetProcessor *processor = cb_data; - USE_PRIV; - - if (!res->success) { - seaf_warning ("[recvfs] Failed to write %s.\n", res->obj_id); - ccnet_processor_send_response (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - seaf_debug ("[recvfs] Wrote fs object %s.\n", res->obj_id); - - if (++(priv->n_saved) == priv->total_needed) { - seaf_debug ("All objects saved. Done.\n"); - ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); - ccnet_processor_done (processor, TRUE); - } -} - -static int -save_fs_object (CcnetProcessor *processor, ObjectPack *pack, int len) -{ - USE_PRIV; - - return seaf_obj_store_async_write (seaf->fs_mgr->obj_store, - priv->writer_id, - pack->id, - pack->object, - len - 41, - FALSE); -} - -static int -recv_fs_object (CcnetProcessor *processor, char *content, int clen) -{ - ObjectPack *pack = (ObjectPack *)content; - /* SeafFSObject *fs_obj = NULL; */ - - if (clen < sizeof(ObjectPack)) { - seaf_warning ("invalid object id.\n"); - goto bad; - } - - seaf_debug ("[recvfs] Recv fs object %.8s.\n", pack->id); - - /* Check object integrity by parsing it. */ - /* fs_obj = seaf_fs_object_from_data(pack->id, */ - /* pack->object, clen - sizeof(ObjectPack), */ - /* (priv->repo_version > 0)); */ - /* if (!fs_obj) { */ - /* seaf_warning ("Bad fs object %s.\n", pack->id); */ - /* goto bad; */ - /* } */ - - /* seaf_fs_object_free (fs_obj); */ - - if (save_fs_object (processor, pack, clen) < 0) { - goto bad; - } - - return 0; - -bad: - ccnet_processor_send_response (processor, SC_BAD_OBJECT, - SS_BAD_OBJECT, NULL, 0); - seaf_warning ("[recvfs] Bad fs object received.\n"); - ccnet_processor_done (processor, FALSE); - - /* seaf_fs_object_free (fs_obj); */ - - return -1; -} - -static void -recv_fs_object_seg (CcnetProcessor *processor, char *content, int clen) -{ - USE_PRIV; - - /* Append the received object segment to the end */ - priv->obj_seg = g_realloc (priv->obj_seg, priv->obj_seg_len + clen); - memcpy (priv->obj_seg + priv->obj_seg_len, content, clen); - - seaf_debug ("[recvfs] Get obj seg: \n", - priv->obj_seg, priv->obj_seg_len, clen); - - priv->obj_seg_len += clen; -} - -static void -process_fs_object_seg (CcnetProcessor *processor) -{ - USE_PRIV; - - if (recv_fs_object (processor, priv->obj_seg, priv->obj_seg_len) == 0) { - g_free (priv->obj_seg); - priv->obj_seg = NULL; - priv->obj_seg_len = 0; - } -} - -static void * -process_object_list (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - int n, i; - char *p; - char *obj_id; - - n = priv->recv_len/40; - p = priv->recv_objs; - - for (i = 0; i < n; ++i) { - obj_id = g_strndup (p, 40); - - if (!seaf_obj_store_obj_exists (seaf->fs_mgr->obj_store, - priv->store_id, priv->repo_version, - obj_id)) - { - priv->needed_objs = g_list_prepend (priv->needed_objs, obj_id); - ++(priv->n_needed); - ++(priv->total_needed); - } else - g_free (obj_id); - p += 40; - } - - g_free (priv->recv_objs); - priv->recv_objs = NULL; - - return data; -} - -static void -process_object_list_done (void *data) -{ - CcnetProcessor *processor = data; - USE_PRIV; - - if (priv->n_needed == 0) { - ccnet_processor_send_response (processor, - SC_OBJ_LIST_SEG, SS_OBJ_LIST_SEG, - NULL, 0); - return; - } - - char *buf = g_malloc (priv->n_needed * 40); - char *p; - char *obj_id; - GList *ptr; - - p = buf; - for (ptr = priv->needed_objs; ptr; ptr = ptr->next) { - obj_id = ptr->data; - memcpy (p, obj_id, 40); - p += 40; - } - - ccnet_processor_send_response (processor, - SC_OBJ_LIST_SEG, SS_OBJ_LIST_SEG, - buf, priv->n_needed * 40); - g_free (buf); - string_list_free (priv->needed_objs); - priv->needed_objs = NULL; - priv->n_needed = 0; -} - -static void -handle_update (CcnetProcessor *processor, - char *code, char *code_msg, - char *content, int clen) -{ - USE_PRIV; - - switch (processor->state) { - case CHECK_OBJECT_LIST: - if (strncmp (code, SC_OBJ_LIST_SEG, 3) == 0) { - if (clen % 40 != 0) { - seaf_warning ("Invalid object list segment length %d.\n", clen); - ccnet_processor_send_response (processor, - SC_SHUTDOWN, SS_SHUTDOWN, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return; - } - - priv->recv_objs = g_memdup(content, clen); - priv->recv_len = clen; - ccnet_processor_thread_create (processor, seaf->job_mgr, - process_object_list, - process_object_list_done, - processor); - } else if (strncmp (code, SC_OBJ_LIST_SEG_END, 3) == 0) { - if (priv->total_needed == 0) { - seaf_debug ("No objects are needed. Done.\n"); - ccnet_processor_send_response (processor, SC_END, SS_END, NULL, 0); - ccnet_processor_done (processor, TRUE); - return; - } - processor->state = RECV_OBJECTS; - } else if (strncmp (code, SC_END, 3) == 0) { - /* The client finds nothing to upload. */ - ccnet_processor_done (processor, TRUE); - } else { - seaf_warning ("Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - break; - case RECV_OBJECTS: - if (strncmp(code, SC_OBJ_SEG, 3) == 0) { - recv_fs_object_seg (processor, content, clen); - } else if (strncmp(code, SC_OBJ_SEG_END, 3) == 0) { - recv_fs_object_seg (processor, content, clen); - process_fs_object_seg (processor); - } else if (strncmp(code, SC_OBJECT, 3) == 0) { - recv_fs_object (processor, content, clen); - } else { - seaf_warning ("Bad update: %s %s\n", code, code_msg); - ccnet_processor_send_response (processor, - SC_BAD_UPDATE_CODE, SS_BAD_UPDATE_CODE, - NULL, 0); - ccnet_processor_done (processor, FALSE); - } - break; - default: - g_return_if_reached (); - } -} diff --git a/server/processors/recvfs-v2-proc.h b/server/processors/recvfs-v2-proc.h deleted file mode 100644 index a305511..0000000 --- a/server/processors/recvfs-v2-proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_RECVFS_V2_PROC_H -#define SEAFILE_RECVFS_V2_PROC_H - -#include - - -#define SEAFILE_TYPE_RECVFS_V2_PROC (seafile_recvfs_v2_proc_get_type ()) -#define SEAFILE_RECVFS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_RECVFS_V2_PROC, SeafileRecvfsV2Proc)) -#define SEAFILE_IS_RECVFS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_RECVFS_V2_PROC)) -#define SEAFILE_RECVFS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_RECVFS_V2_PROC, SeafileRecvfsV2ProcClass)) -#define IS_SEAFILE_RECVFS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_RECVFS_V2_PROC)) -#define SEAFILE_RECVFS_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_RECVFS_V2_PROC, SeafileRecvfsV2ProcClass)) - -typedef struct _SeafileRecvfsV2Proc SeafileRecvfsV2Proc; -typedef struct _SeafileRecvfsV2ProcClass SeafileRecvfsV2ProcClass; - -struct _SeafileRecvfsV2Proc { - CcnetProcessor parent_instance; -}; - -struct _SeafileRecvfsV2ProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_recvfs_v2_proc_get_type (); - -#endif - diff --git a/server/processors/sync-repo-slave-proc.c b/server/processors/sync-repo-slave-proc.c deleted file mode 100644 index af19918..0000000 --- a/server/processors/sync-repo-slave-proc.c +++ /dev/null @@ -1,172 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include "common.h" - -#include "seafile-session.h" -#include "repo-mgr.h" -#include "branch-mgr.h" -#include "commit-mgr.h" - -#include "sync-repo-slave-proc.h" -#include "sync-repo-common.h" - -#include "seaf-db.h" -#include "log.h" - -typedef struct { - char repo_id[41]; - char *branch_name; - - char *rsp_code; - char *rsp_msg; - char commit_id[41]; -} SeafileSyncRepoSlaveProcPriv; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_SYNC_REPO_SLAVE_PROC, SeafileSyncRepoSlaveProcPriv)) - -#define USE_PRIV \ - SeafileSyncRepoSlaveProcPriv *priv = GET_PRIV(processor); - -G_DEFINE_TYPE (SeafileSynRepoSlaveProc, seafile_sync_repo_slave_proc, CCNET_TYPE_PROCESSOR) - -static int -sync_repo_slave_start (CcnetProcessor *processor, int argc, char **argv); - -static void * -send_repo_branch_info (void *vprocessor); -static void -thread_done (void *vprocessor); - -static void -release_resource(CcnetProcessor *processor) -{ - USE_PRIV; - - /* g_free works fine even if ptr is NULL. */ - g_free (priv->branch_name); - g_free (priv->rsp_code); - g_free (priv->rsp_msg); - - CCNET_PROCESSOR_CLASS (seafile_sync_repo_slave_proc_parent_class)->release_resource (processor); -} - -static void -seafile_sync_repo_slave_proc_class_init (SeafileSynRepoSlaveProcClass *klass) -{ - CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); - - proc_class->name = "seafile-sync-repo-slave-proc"; - proc_class->start = sync_repo_slave_start; - proc_class->release_resource = release_resource; - - g_type_class_add_private (klass, sizeof (SeafileSyncRepoSlaveProcPriv)); -} - -static void -seafile_sync_repo_slave_proc_init (SeafileSynRepoSlaveProc *processor) -{ -} - - -static int -sync_repo_slave_start (CcnetProcessor *processor, int argc, char **argv) -{ - USE_PRIV; - - if (argc != 2) { - seaf_warning ("[sync-repo-slave] argc(%d) must be 2\n", argc); - ccnet_processor_done (processor, FALSE); - return -1; - } - - if (!is_uuid_valid(argv[0])) { - seaf_warning ("Invalid repo_id %s.\n", argv[0]); - ccnet_processor_done (processor, FALSE); - return -1; - } - - memcpy (priv->repo_id, argv[0], 37); - priv->branch_name = g_strdup (argv[1]); - - /* send the head commit of the branch */ - if (ccnet_processor_thread_create (processor, - seaf->job_mgr, - send_repo_branch_info, - thread_done, - processor) < 0) { - seaf_warning ("[sync repo] failed to start thread.\n"); - ccnet_processor_send_response (processor, - SC_SERVER_ERROR, SS_SERVER_ERROR, - NULL, 0); - ccnet_processor_done (processor, FALSE); - return -1; - } - - return 0; -} - -static gboolean -get_branch (SeafDBRow *row, void *vid) -{ - char *ret = vid; - const char *commit_id; - - commit_id = seaf_db_row_get_column_text (row, 0); - memcpy (ret, commit_id, 41); - - return FALSE; -} - -static void * -send_repo_branch_info (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - char commit_id[41]; - char *sql; - USE_PRIV; - - commit_id[0] = 0; - - sql = "SELECT commit_id FROM Repo r, Branch b " - "WHERE name='master' AND r.repo_id=? AND r.repo_id = b.repo_id"; - if (seaf_db_statement_foreach_row (seaf->db, sql, - get_branch, commit_id, - 1, "string", priv->repo_id) < 0) { - seaf_warning ("DB error when get branch %s.\n", priv->branch_name); - priv->rsp_code = g_strdup (SC_REPO_CORRUPT); - priv->rsp_msg = g_strdup (SS_REPO_CORRUPT); - return vprocessor; - } - - if (commit_id[0] == 0) { - priv->rsp_code = g_strdup (SC_NO_REPO); - priv->rsp_msg = g_strdup (SS_NO_REPO); - return vprocessor; - } - - priv->rsp_code = g_strdup (SC_COMMIT_ID); - priv->rsp_msg = g_strdup (SS_COMMIT_ID); - memcpy (priv->commit_id, commit_id, 41); - - return vprocessor; -} - -static void -thread_done (void *vprocessor) -{ - CcnetProcessor *processor = vprocessor; - USE_PRIV; - - if (strcmp (priv->rsp_code, SC_COMMIT_ID) == 0) { - ccnet_processor_send_response (processor, - priv->rsp_code, priv->rsp_msg, - priv->commit_id, 41); - ccnet_processor_done (processor, TRUE); - } else { - ccnet_processor_send_response (processor, - priv->rsp_code, priv->rsp_msg, - NULL, 0); - ccnet_processor_done (processor, TRUE); - } -} diff --git a/server/processors/sync-repo-slave-proc.h b/server/processors/sync-repo-slave-proc.h deleted file mode 100644 index df4e046..0000000 --- a/server/processors/sync-repo-slave-proc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAFILE_SYNC_REPO_SLAVE_PROC_H -#define SEAFILE_SYNC_REPO_SLAVE_PROC_H - -#include -#include - -#define SEAFILE_TYPE_SYNC_REPO_SLAVE_PROC (seafile_sync_repo_slave_proc_get_type ()) -#define SEAFILE_SYNC_REPO_SLAVE_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SYNC_REPO_SLAVE_PROC, SeafileSynRepoSlaveProc)) -#define SEAFILE_IS_SYNC_REPO_SLAVE_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SYNC_REPO_SLAVE_PROC)) -#define SEAFILE_SYNC_REPO_SLAVE_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SYNC_REPO_SLAVE_PROC, SeafileSynRepoSlaveProcClass)) -#define IS_SEAFILE_SYNC_REPO_SLAVE_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SYNC_REPO_SLAVE_PROC)) -#define SEAFILE_SYNC_REPO_SLAVE_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SYNC_REPO_SLAVE_PROC, SeafileSynRepoSlaveProcClass)) - -typedef struct _SeafileSynRepoSlaveProc SeafileSynRepoSlaveProc; -typedef struct _SeafileSynRepoSlaveProcClass SeafileSynRepoSlaveProcClass; - -struct _SeafileSynRepoSlaveProc { - CcnetProcessor parent_instance; -}; - -struct _SeafileSynRepoSlaveProcClass { - CcnetProcessorClass parent_class; -}; - -GType seafile_sync_repo_slave_proc_get_type (); - -#endif diff --git a/server/quota-mgr.c b/server/quota-mgr.c index 488659c..039c374 100644 --- a/server/quota-mgr.c +++ b/server/quota-mgr.c @@ -375,13 +375,7 @@ get_num_shared_to (const char *user, const char *repo_id) } /* Then groups... */ - client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-threaded-rpcserver"); - if (!client) { - seaf_warning ("Failed to alloc rpc client.\n"); - goto out; - } + client = seaf->rpc_client; groups = seaf_repo_manager_get_groups_by_repo (seaf->repo_mgr, repo_id, NULL); @@ -405,7 +399,6 @@ out: g_hash_table_destroy (user_hash); string_list_free (personal); g_list_free (groups); - ccnet_rpc_client_free (client); return n_shared_to; } diff --git a/server/repo-mgr.c b/server/repo-mgr.c index 95a9bd2..e0ca88b 100644 --- a/server/repo-mgr.c +++ b/server/repo-mgr.c @@ -21,6 +21,7 @@ #include "seafile-crypt.h" #include "seaf-db.h" +#include "seaf-utils.h" #define REAP_TOKEN_INTERVAL 300 /* 5 mins */ #define DECRYPTED_TOKEN_TTL 3600 /* 1 hour */ @@ -4249,15 +4250,11 @@ seaf_get_group_repos_by_user (SeafRepoManager *mgr, GList *groups = NULL, *p, *q; GList *repos = NULL; SeafileRepo *repo = NULL; - SearpcClient *rpc_client; + SearpcClient *rpc_client = NULL; GString *sql = NULL; int group_id = 0; - rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-threaded-rpcserver"); - if (!rpc_client) - return NULL; + rpc_client = create_rpc_clients (seaf->config_dir); /* Get the groups this user belongs to. */ groups = ccnet_get_groups_by_user (rpc_client, user, 1); @@ -4330,10 +4327,10 @@ out: if (sql) g_string_free (sql, TRUE); - ccnet_rpc_client_free (rpc_client); for (p = groups; p != NULL; p = p->next) g_object_unref ((GObject *)p->data); g_list_free (groups); + searpc_free_client_with_pipe_transport(rpc_client); return g_list_reverse (repos); } @@ -4465,11 +4462,7 @@ seaf_repo_manager_convert_repo_path (SeafRepoManager *mgr, if (ret) goto out; - rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-threaded-rpcserver"); - if (!rpc_client) - goto out; + rpc_client = create_rpc_clients (seaf->config_dir); /* Get the groups this user belongs to. */ groups = ccnet_get_groups_by_user (rpc_client, user, 1); @@ -4508,10 +4501,10 @@ out: if (vinfo) seaf_virtual_repo_info_free (vinfo); g_string_free (sql, TRUE); - ccnet_rpc_client_free (rpc_client); for (p1 = groups; p1 != NULL; p1 = p1->next) g_object_unref ((GObject *)p1->data); g_list_free (groups); + searpc_free_client_with_pipe_transport(rpc_client); return ret; } diff --git a/server/repo-perm.c b/server/repo-perm.c index 74ef1e9..5cb515b 100644 --- a/server/repo-perm.c +++ b/server/repo-perm.c @@ -11,7 +11,7 @@ #include "repo-mgr.h" #include "seafile-error.h" - +#include "seaf-utils.h" /* * Permission priority: owner --> personal share --> group share --> public. * Permission with higher priority overwrites those with lower priority. @@ -42,17 +42,13 @@ check_group_permission_by_user (SeafRepoManager *mgr, const char *user_name) { char *permission = NULL; - SearpcClient *rpc_client; + SearpcClient *rpc_client = NULL; GList *groups = NULL, *p1; CcnetGroup *group; int group_id; GString *sql; - rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-threaded-rpcserver"); - if (!rpc_client) - return NULL; + rpc_client = create_rpc_clients (seaf->config_dir); /* Get the groups this user belongs to. */ groups = ccnet_get_groups_by_user (rpc_client, user_name, 1); @@ -81,10 +77,10 @@ check_group_permission_by_user (SeafRepoManager *mgr, g_string_free (sql, TRUE); out: - ccnet_rpc_client_free (rpc_client); for (p1 = groups; p1 != NULL; p1 = p1->next) g_object_unref ((GObject *)p1->data); g_list_free (groups); + searpc_free_client_with_pipe_transport(rpc_client); return permission; } @@ -140,39 +136,35 @@ check_perm_on_parent_repo (const char *origin_repo_id, { GHashTable *user_perms = NULL; GHashTable *group_perms = NULL; - SearpcClient *rpc_client; + SearpcClient *rpc_client = NULL; GList *groups = NULL; GList *iter; char *perm = NULL; - rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, - NULL, - "ccnet-threaded-rpcserver"); - if (!rpc_client) { - return NULL; - } + rpc_client = create_rpc_clients (seaf->config_dir); user_perms = seaf_share_manager_get_shared_dirs_to_user (seaf->share_mgr, origin_repo_id, user); if (!user_perms) { - ccnet_rpc_client_free (rpc_client); + searpc_free_client_with_pipe_transport(rpc_client); return NULL; } + if (g_hash_table_size (user_perms) > 0) { perm = get_dir_perm (user_perms, vpath); if (perm) { g_hash_table_destroy (user_perms); - ccnet_rpc_client_free (rpc_client); return perm; } } g_hash_table_destroy (user_perms); groups = ccnet_get_groups_by_user (rpc_client, user, 1); - ccnet_rpc_client_free (rpc_client); + if (!groups) { + searpc_free_client_with_pipe_transport(rpc_client); return NULL; } @@ -185,6 +177,7 @@ check_perm_on_parent_repo (const char *origin_repo_id, g_list_free (groups); if (!group_perms) { + searpc_free_client_with_pipe_transport(rpc_client); return NULL; } if (g_hash_table_size (group_perms) > 0) { @@ -192,6 +185,7 @@ check_perm_on_parent_repo (const char *origin_repo_id, } g_hash_table_destroy (group_perms); + searpc_free_client_with_pipe_transport(rpc_client); return perm; } diff --git a/server/seaf-server.c b/server/seaf-server.c index d02851d..a5d4773 100644 --- a/server/seaf-server.c +++ b/server/seaf-server.c @@ -23,30 +23,9 @@ #include "log.h" #include "utils.h" -#include "processors/check-tx-slave-v3-proc.h" -#include "processors/recvfs-proc.h" -#include "processors/putfs-proc.h" -#include "processors/recvbranch-proc.h" -#include "processors/sync-repo-slave-proc.h" -#include "processors/putcommit-v2-proc.h" -#include "processors/putcommit-v3-proc.h" -#include "processors/recvcommit-v3-proc.h" -#include "processors/putcs-v2-proc.h" -#include "processors/checkbl-proc.h" -#include "processors/checkff-proc.h" -#include "processors/putca-proc.h" -#include "processors/check-protocol-slave-proc.h" -#include "processors/recvfs-v2-proc.h" -#include "processors/recvbranch-v2-proc.h" -#include "processors/putfs-v2-proc.h" - #include "cdc/cdc.h" SeafileSession *seaf; -SearpcClient *ccnetrpc_client; -SearpcClient *ccnetrpc_client_t; -SearpcClient *async_ccnetrpc_client; -SearpcClient *async_ccnetrpc_client_t; char *pidfile = NULL; @@ -73,57 +52,31 @@ static void usage () fprintf (stderr, "usage: seaf-server [-c config_dir] [-d seafile_dir]\n"); } -static void register_processors (CcnetClient *client) -{ - ccnet_register_service (client, "seafile-check-tx-slave-v3", "basic", - SEAFILE_TYPE_CHECK_TX_SLAVE_V3_PROC, NULL); - ccnet_register_service (client, "seafile-recvfs", "basic", - SEAFILE_TYPE_RECVFS_PROC, NULL); - ccnet_register_service (client, "seafile-putfs", "basic", - SEAFILE_TYPE_PUTFS_PROC, NULL); - ccnet_register_service (client, "seafile-recvbranch", "basic", - SEAFILE_TYPE_RECVBRANCH_PROC, NULL); - ccnet_register_service (client, "seafile-sync-repo-slave", "basic", - SEAFILE_TYPE_SYNC_REPO_SLAVE_PROC, NULL); - ccnet_register_service (client, "seafile-putcommit-v2", "basic", - SEAFILE_TYPE_PUTCOMMIT_V2_PROC, NULL); - ccnet_register_service (client, "seafile-putcommit-v3", "basic", - SEAFILE_TYPE_PUTCOMMIT_V3_PROC, NULL); - ccnet_register_service (client, "seafile-recvcommit-v3", "basic", - SEAFILE_TYPE_RECVCOMMIT_V3_PROC, NULL); - ccnet_register_service (client, "seafile-putcs-v2", "basic", - SEAFILE_TYPE_PUTCS_V2_PROC, NULL); - ccnet_register_service (client, "seafile-checkbl", "basic", - SEAFILE_TYPE_CHECKBL_PROC, NULL); - ccnet_register_service (client, "seafile-checkff", "basic", - SEAFILE_TYPE_CHECKFF_PROC, NULL); - ccnet_register_service (client, "seafile-putca", "basic", - SEAFILE_TYPE_PUTCA_PROC, NULL); - ccnet_register_service (client, "seafile-check-protocol-slave", "basic", - SEAFILE_TYPE_CHECK_PROTOCOL_SLAVE_PROC, NULL); - ccnet_register_service (client, "seafile-recvfs-v2", "basic", - SEAFILE_TYPE_RECVFS_V2_PROC, NULL); - ccnet_register_service (client, "seafile-recvbranch-v2", "basic", - SEAFILE_TYPE_RECVBRANCH_V2_PROC, NULL); - ccnet_register_service (client, "seafile-putfs-v2", "basic", - SEAFILE_TYPE_PUTFS_V2_PROC, NULL); -} - #include #include "searpc-signature.h" #include "searpc-marshal.h" +#include -static void start_rpc_service (CcnetClient *client, int cloud_mode) +static void start_rpc_service (int cloud_mode, char *seafile_dir, char *central_conf_dir) { + seaf_message ("Mydebug %s\n", __FUNCTION__); + SearpcNamedPipeServer *rpc_server = NULL; + char *socket_dir = NULL; + char *pipe_path = NULL; + searpc_server_init (register_marshals); - searpc_create_service ("seafserv-rpcserver"); - ccnet_register_service (client, "seafserv-rpcserver", "rpc-inner", - CCNET_TYPE_RPCSERVER_PROC, NULL); - searpc_create_service ("seafserv-threaded-rpcserver"); - ccnet_register_service (client, "seafserv-threaded-rpcserver", "rpc-inner", - CCNET_TYPE_THREADED_RPCSERVER_PROC, NULL); + + socket_dir = central_conf_dir ? central_conf_dir : seafile_dir; + pipe_path = g_strdup_printf ("%s/%s", socket_dir, "seafile.sock"); + seaf_message ("Mydebug pipe_path = %s\n", pipe_path); + rpc_server = searpc_create_named_pipe_server(pipe_path); + g_free(pipe_path); + if (searpc_named_pipe_server_start(rpc_server) < 0) { + seaf_warning ("Failed to start named pipe server.\n"); + exit (1); + } /* threaded services */ @@ -631,20 +584,6 @@ static void start_rpc_service (CcnetClient *client, int cloud_mode) "cancel_copy_task", searpc_signature_int__string()); - /* chunk server manipulation */ - searpc_server_register_function ("seafserv-rpcserver", - seafile_add_chunk_server, - "seafile_add_chunk_server", - searpc_signature_int__string()); - searpc_server_register_function ("seafserv-rpcserver", - seafile_del_chunk_server, - "seafile_del_chunk_server", - searpc_signature_int__string()); - searpc_server_register_function ("seafserv-rpcserver", - seafile_list_chunk_servers, - "seafile_list_chunk_servers", - searpc_signature_string__void()); - /* password management */ searpc_server_register_function ("seafserv-threaded-rpcserver", seafile_check_passwd, @@ -843,39 +782,6 @@ set_signal_handlers (SeafileSession *session) #endif } -static void -create_sync_rpc_clients (const char *central_config_dir, const char *config_dir) -{ - CcnetClient *sync_client; - - /* sync client and rpc client */ - sync_client = ccnet_client_new (); - if ( (ccnet_client_load_confdir(sync_client, central_config_dir, config_dir)) < 0 ) { - seaf_warning ("Read config dir error\n"); - exit(1); - } - - if (ccnet_client_connect_daemon (sync_client, CCNET_CLIENT_SYNC) < 0) - { - seaf_warning ("Connect to server fail: %s\n", strerror(errno)); - exit(1); - } - - ccnetrpc_client = ccnet_create_rpc_client (sync_client, NULL, "ccnet-rpcserver"); - ccnetrpc_client_t = ccnet_create_rpc_client (sync_client, - NULL, - "ccnet-threaded-rpcserver"); -} - -static void -create_async_rpc_clients (CcnetClient *client) -{ - async_ccnetrpc_client = ccnet_create_async_rpc_client ( - client, NULL, "ccnet-rpcserver"); - async_ccnetrpc_client_t = ccnet_create_async_rpc_client ( - client, NULL, "ccnet-threaded-rpcserver"); -} - static void remove_pidfile (const char *pidfile) { @@ -957,10 +863,10 @@ main (int argc, char **argv) const char *debug_str = NULL; int daemon_mode = 1; int is_master = 0; - CcnetClient *client; char *ccnet_debug_level_str = "info"; char *seafile_debug_level_str = "debug"; int cloud_mode = 0; + SearpcClient *rpc_client = NULL; #ifdef WIN32 argv = get_argv_utf8 (&argc); @@ -1066,29 +972,18 @@ main (int argc, char **argv) exit (1); } - client = ccnet_init (central_config_dir, config_dir); - if (!client) - exit (1); + event_init (); + start_rpc_service (cloud_mode, seafile_dir, central_config_dir); - register_processors (client); - - start_rpc_service (client, cloud_mode); - - create_sync_rpc_clients (central_config_dir, config_dir); - create_async_rpc_clients (client); - - seaf = seafile_session_new (central_config_dir, seafile_dir, client); + seaf = seafile_session_new (central_config_dir, seafile_dir, config_dir); if (!seaf) { seaf_warning ("Failed to create seafile session.\n"); exit (1); } seaf->is_master = is_master; - seaf->ccnetrpc_client = ccnetrpc_client; - seaf->async_ccnetrpc_client = async_ccnetrpc_client; - seaf->ccnetrpc_client_t = ccnetrpc_client_t; - seaf->async_ccnetrpc_client_t = async_ccnetrpc_client_t; - seaf->client_pool = ccnet_client_pool_new (central_config_dir, config_dir); seaf->cloud_mode = cloud_mode; + seaf->rpc_client = rpc_client; + #ifndef WIN32 set_syslog_config (seaf->config); @@ -1123,7 +1018,7 @@ main (int argc, char **argv) /* Create a system default repo to contain the tutorial file. */ schedule_create_system_default_repo (seaf); - ccnet_main (client); + event_dispatch (); return 0; } diff --git a/server/seafile-session.c b/server/seafile-session.c index 8e91133..df42114 100644 --- a/server/seafile-session.c +++ b/server/seafile-session.c @@ -37,18 +37,17 @@ load_thread_pool_config (SeafileSession *session); SeafileSession * seafile_session_new(const char *central_config_dir, const char *seafile_dir, - CcnetClient *ccnet_session) + const char *config_dir) { char *abs_central_config_dir = NULL; char *abs_seafile_dir; + char *abs_config_dir = NULL; char *tmp_file_dir; char *config_file_path; GKeyFile *config; SeafileSession *session = NULL; - if (!ccnet_session) - return NULL; - + abs_config_dir = ccnet_expand_path (config_dir); abs_seafile_dir = ccnet_expand_path (seafile_dir); tmp_file_dir = g_build_filename (abs_seafile_dir, "tmpfiles", NULL); if (central_config_dir) { @@ -82,8 +81,8 @@ seafile_session_new(const char *central_config_dir, session = g_new0(SeafileSession, 1); session->seaf_dir = abs_seafile_dir; + session->config_dir = abs_config_dir; session->tmp_file_dir = tmp_file_dir; - session->session = ccnet_session; session->config = config; if (load_database_config (session) < 0) { @@ -116,10 +115,6 @@ seafile_session_new(const char *central_config_dir, if (!session->branch_mgr) goto onerror; - session->cs_mgr = seaf_cs_manager_new (session); - if (!session->cs_mgr) - goto onerror; - session->share_mgr = seaf_share_manager_new (session); if (!session->share_mgr) goto onerror; @@ -128,10 +123,6 @@ seafile_session_new(const char *central_config_dir, if (!session->web_at_mgr) goto onerror; - session->token_mgr = seaf_token_manager_new (session); - if (!session->token_mgr) - goto onerror; - session->passwd_mgr = seaf_passwd_manager_new (session); if (!session->passwd_mgr) goto onerror; @@ -140,16 +131,11 @@ seafile_session_new(const char *central_config_dir, if (!session->quota_mgr) goto onerror; - session->listen_mgr = seaf_listen_manager_new (session); - if (!session->listen_mgr) - goto onerror; - session->copy_mgr = seaf_copy_manager_new (session); if (!session->copy_mgr) goto onerror; session->job_mgr = ccnet_job_manager_new (session->sync_thread_pool_size); - ccnet_session->job_mgr = ccnet_job_manager_new (session->rpc_thread_pool_size); session->size_sched = size_scheduler_new (session); @@ -157,10 +143,6 @@ seafile_session_new(const char *central_config_dir, if (!session->ev_mgr) goto onerror; - session->mq_mgr = seaf_mq_manager_new (session); - if (!session->mq_mgr) - goto onerror; - session->http_server = seaf_http_server_new (session); if (!session->http_server) goto onerror; @@ -213,8 +195,6 @@ seafile_session_init (SeafileSession *session) return -1; } - seaf_mq_manager_init (session->mq_mgr); - return 0; } @@ -226,11 +206,6 @@ seafile_session_start (SeafileSession *session) return -1; } - if (seaf_cs_manager_start (session->cs_mgr) < 0) { - seaf_warning ("Failed to start chunk server manager.\n"); - return -1; - } - if (seaf_share_manager_start (session->share_mgr) < 0) { seaf_warning ("Failed to start share manager.\n"); return -1; @@ -246,16 +221,6 @@ seafile_session_start (SeafileSession *session) return -1; } - if (seaf_mq_manager_start (session->mq_mgr) < 0) { - seaf_warning ("Failed to start mq manager.\n"); - return -1; - } - - if (seaf_listen_manager_start (session->listen_mgr) < 0) { - seaf_warning ("Failed to start listen manager.\n"); - return -1; - } - if (size_scheduler_start (session->size_sched) < 0) { seaf_warning ("Failed to start size scheduler.\n"); return -1; diff --git a/server/seafile-session.h b/server/seafile-session.h index 59b3c77..ceee10d 100644 --- a/server/seafile-session.h +++ b/server/seafile-session.h @@ -15,19 +15,14 @@ #include "db.h" #include "seaf-db.h" -#include "chunkserv-mgr.h" #include "share-mgr.h" -#include "token-mgr.h" #include "web-accesstoken-mgr.h" #include "passwd-mgr.h" #include "quota-mgr.h" -#include "listen-mgr.h" #include "size-sched.h" #include "copy-mgr.h" #include "config-mgr.h" -#include "mq-mgr.h" - #include "http-server.h" #include "zip-download-mgr.h" #include "index-blocks-mgr.h" @@ -40,19 +35,11 @@ typedef struct _SeafileSession SeafileSession; struct _SeafileSession { - struct _CcnetClient *session; - - SearpcClient *ccnetrpc_client; - SearpcClient *ccnetrpc_client_t; - /* Use async rpc client on server. */ - SearpcClient *async_ccnetrpc_client; - SearpcClient *async_ccnetrpc_client_t; - - /* Used in threads. */ - CcnetClientPool *client_pool; + SearpcClient *rpc_client; char *central_config_dir; char *seaf_dir; + char *config_dir; char *tmp_file_dir; /* Config that's only loaded on start */ GKeyFile *config; @@ -63,19 +50,14 @@ struct _SeafileSession { SeafCommitManager *commit_mgr; SeafBranchManager *branch_mgr; SeafRepoManager *repo_mgr; - SeafCSManager *cs_mgr; SeafShareManager *share_mgr; - SeafTokenManager *token_mgr; SeafPasswdManager *passwd_mgr; SeafQuotaManager *quota_mgr; - SeafListenManager *listen_mgr; SeafCopyManager *copy_mgr; SeafCfgManager *cfg_mgr; SeafWebAccessTokenManager *web_at_mgr; - SeafMqManager *mq_mgr; - CEventManager *ev_mgr; CcnetJobManager *job_mgr; @@ -100,7 +82,7 @@ extern SeafileSession *seaf; SeafileSession * seafile_session_new(const char *central_config_dir, const char *seafile_dir, - struct _CcnetClient *ccnet_session); + const char *config_dir); int seafile_session_init (SeafileSession *session); diff --git a/server/token-mgr.c b/server/token-mgr.c deleted file mode 100644 index 268b14d..0000000 --- a/server/token-mgr.c +++ /dev/null @@ -1,169 +0,0 @@ -#include - -#include "common.h" -#include "seafile-session.h" -#include "utils.h" - -/* - * Token format: - * - * master_id - * client_id - * repo_id - * timestamp - * signature - */ - -#define TOKEN_TIME_TO_EXPIRE 24 * 3600 /* a token is valid in 1 day. */ - -struct TokenManagerPriv { - /* (master, client, repo) --> timestamp */ - GHashTable *token_hash; -}; - -SeafTokenManager * -seaf_token_manager_new (struct _SeafileSession *session) -{ - SeafTokenManager *mgr = g_new0(SeafTokenManager, 1); - struct TokenManagerPriv *priv = g_new0(struct TokenManagerPriv, 1); - - mgr->seaf = session; - mgr->priv = priv; - - /* mgr->priv->token_hash = g_hash_table_new_full (g_str_hash, g_str_equal, */ - /* g_free, g_free); */ - - return mgr; -} - -char * -seaf_token_manager_generate_token (SeafTokenManager *mgr, - const char *client_id, - const char *repo_id) -{ - GString *token = g_string_new (NULL); - char *sig_base64; - - g_string_append_printf (token, "%s\n%s\n%s\n%"G_GUINT64_FORMAT, - seaf->session->base.id, - client_id, - repo_id, - (guint64)time(NULL)); - - /* Create signature with my private key. */ - sig_base64 = ccnet_sign_message (seaf->ccnetrpc_client, token->str); - g_string_append_printf (token, "\n%s", sig_base64); - g_free (sig_base64); - - return g_string_free (token, FALSE); -} - -int -seaf_token_manager_verify_token (SeafTokenManager *mgr, - SearpcClient *rpc_client, - const char *peer_id, - char *token, - char *ret_repo_id) -{ - char **keys; - char *master_id, *client_id, *repo_id, *ts_str, *signature; - guint64 timestamp; - char *sep; - int ret = 0; - - if (token[0] == '\0') - return -1; - - keys = g_strsplit (token, "\n", 5); - if (g_strv_length(keys) != 5) { - ret = -1; - goto out; - } - - master_id = keys[0]; - client_id = keys[1]; - repo_id = keys[2]; - ts_str = keys[3]; - signature = keys[4]; - - if (strlen(master_id) != 40 || - strlen(client_id) != 40 || - strlen(repo_id) != 36) { - ret = -1; - goto out; - } - - sep = strrchr (token, '\n'); - sep[0] = '\0'; - - if (!rpc_client) - rpc_client = seaf->ccnetrpc_client; - - /* Verify signature. - * TODO: we should first check whether master_id is a master server. - */ - if (ccnet_verify_message (rpc_client, - token, signature, master_id) < 0) { - ret = -1; - goto out; - } - - sep[0] = '\n'; - - /* Check whether this token is assigned to the peer. */ - if (peer_id && strcmp (peer_id, client_id) != 0) { - ret = -1; - goto out; - } - - timestamp = strtoul(ts_str, NULL, 10); - - /* The timestamp contained in the token cannot be smaller than - * the last one received, and should not be older than 1 hour. - */ - if (timestamp + TOKEN_TIME_TO_EXPIRE <= (guint64)time(NULL)) { - ret = -1; - goto out; - } - - /* OK, the token is valid. */ - if (ret_repo_id != NULL) - memcpy (ret_repo_id, repo_id, 37); - -out: - g_strfreev (keys); - return ret; -} - -#if 0 -void -seaf_token_manager_invalidate_token (SeafTokenManager *mgr, - char *token) -{ - char **keys; - char *master_id, *client_id, *repo_id, *ts_str; - char hash_key[128]; - guint64 timestamp; - - /* We assume that the token has been verified. */ - - keys = g_strsplit (token, "\n", 5); - - master_id = keys[0]; - client_id = keys[1]; - repo_id = keys[2]; - ts_str = keys[3]; - - snprintf (hash_key, sizeof(hash_key), "%s%s%s", - master_id, client_id, repo_id); - - timestamp = strtoul(ts_str, NULL, 10); - - /* Record the timestamp so that it cannot be reused. */ - guint64 *new_ts = g_new0(guint64, 1); - *new_ts = timestamp; - g_hash_table_insert (mgr->priv->token_hash, g_strdup(hash_key), new_ts); - - g_strfreev (keys); -} -#endif diff --git a/server/token-mgr.h b/server/token-mgr.h deleted file mode 100644 index d510baa..0000000 --- a/server/token-mgr.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifndef SEAF_TOKEN_MGR_H -#define SEAF_TOKEN_MGR_H - -#include - -struct _SeafileSession; -struct TokenManagerPriv; - -struct _SeafTokenManager { - struct _SeafileSession *seaf; - struct TokenManagerPriv *priv; -}; -typedef struct _SeafTokenManager SeafTokenManager; - -SeafTokenManager * -seaf_token_manager_new (struct _SeafileSession *session); - -/* Generate a token, signed by me. - * This is called by a master server. - */ -char * -seaf_token_manager_generate_token (SeafTokenManager *mgr, - const char *client_id, - const char *repo_id); - -/* Verify whether a token is valid. - * - * @peer_id: the peer who presents this token to me. - * If the token is valid, repo id will be stored in @ret_repo_id. - */ -int -seaf_token_manager_verify_token (SeafTokenManager *mgr, - SearpcClient *rpc_client, - const char *peer_id, - char *token, - char *ret_repo_id); - -#if 0 -/* Record a used token so that it cannot be reused. - * This function should only be called after the token has been verified. - */ -void -seaf_token_manager_invalidate_token (SeafTokenManager *mgr, - char *token); -#endif - -#endif diff --git a/server/upload-file.c b/server/upload-file.c index 39b6af1..b09e009 100755 --- a/server/upload-file.c +++ b/server/upload-file.c @@ -164,16 +164,6 @@ send_success_reply (evhtp_request_t *req) evhtp_send_reply (req, EVHTP_RES_OK); } -static void -send_redirect_reply (evhtp_request_t *req) -{ - set_content_length_header (req); - evhtp_headers_add_header ( - req->headers_out, - evhtp_header_new("Content-Type", "text/html; charset=utf-8", 1, 1)); - evhtp_send_reply(req, EVHTP_RES_SEEOTHER); -} - static void send_success_reply_ie8_compatible (evhtp_request_t *req, evhtp_res code) { @@ -192,78 +182,6 @@ send_success_reply_ie8_compatible (evhtp_request_t *req, evhtp_res code) evhtp_send_reply (req, code); } -static void -redirect_to_upload_error (evhtp_request_t *req, - const char *repo_id, - const char *parent_dir, - const char *filename, - int error_code) -{ - char *seahub_url, *escaped_path, *escaped_fn = NULL; - char url[1024]; - - seahub_url = seaf->session->base.service_url; - escaped_path = g_uri_escape_string (parent_dir, NULL, FALSE); - if (filename) { - escaped_fn = g_uri_escape_string (filename, NULL, FALSE); - snprintf(url, 1024, "%s/repo/upload_error/%s?p=%s&fn=%s&err=%d", - seahub_url, repo_id, escaped_path, escaped_fn, error_code); - } else { - snprintf(url, 1024, "%s/repo/upload_error/%s?p=%s&err=%d", - seahub_url, repo_id, escaped_path, error_code); - } - g_free (escaped_path); - g_free (escaped_fn); - - evhtp_headers_add_header(req->headers_out, - evhtp_header_new("Location", - url, 1, 1)); - - send_redirect_reply (req); -} - -static void -redirect_to_update_error (evhtp_request_t *req, - const char *repo_id, - const char *target_file, - int error_code) -{ - char *seahub_url, *escaped_path; - char url[1024]; - - seahub_url = seaf->session->base.service_url; - escaped_path = g_uri_escape_string (target_file, NULL, FALSE); - snprintf(url, 1024, "%s/repo/update_error/%s?p=%s&err=%d", - seahub_url, repo_id, escaped_path, error_code); - g_free (escaped_path); - - evhtp_headers_add_header(req->headers_out, - evhtp_header_new("Location", - url, 1, 1)); - - send_redirect_reply (req); -} - -static void -redirect_to_success_page (evhtp_request_t *req, - const char *repo_id, - const char *parent_dir) -{ - char *seahub_url, *escaped_path; - char url[1024]; - - seahub_url = seaf->session->base.service_url; - escaped_path = g_uri_escape_string (parent_dir, NULL, FALSE); - snprintf(url, 1024, "%s/repo/%s?p=%s", seahub_url, repo_id, escaped_path); - g_free (escaped_path); - - evhtp_headers_add_header(req->headers_out, - evhtp_header_new("Location", - url, 1, 1)); - /* Firefox expects Content-Length header. */ - send_redirect_reply (req); -} - static gboolean check_tmp_file_list (GList *tmp_files, int *error_code) { @@ -419,86 +337,6 @@ create_relative_path (RecvFSM *fsm, char *parent_dir, char *relative_path) return rc; } -static void -upload_cb(evhtp_request_t *req, void *arg) -{ - RecvFSM *fsm = arg; - char *parent_dir; - GError *error = NULL; - int error_code = ERROR_INTERNAL; - char *err_file = NULL; - char *filenames_json, *tmp_files_json; - - /* After upload_headers_cb() returns an error, libevhtp may still - * receive data from the web browser and call into this cb. - * In this case fsm will be NULL. - */ - if (!fsm || fsm->state == RECV_ERROR) - return; - - if (!fsm->files) { - seaf_debug ("[upload] No file uploaded.\n"); - send_error_reply (req, EVHTP_RES_BADREQ, "No file.\n"); - return; - } - - parent_dir = g_hash_table_lookup (fsm->form_kvs, "parent_dir"); - if (!parent_dir) { - seaf_debug ("[upload] No parent dir given.\n"); - send_error_reply (req, EVHTP_RES_BADREQ, "Invalid URL.\n"); - return; - } - - if (!check_parent_dir (req, fsm->repo_id, parent_dir)) - return; - - if (!check_tmp_file_list (fsm->files, &error_code)) - goto error; - - gint64 content_len = get_content_length(req); - if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, - fsm->repo_id, - content_len) != 0) { - error_code = ERROR_QUOTA; - goto error; - } - - filenames_json = file_list_to_json (fsm->filenames); - tmp_files_json = file_list_to_json (fsm->files); - - int rc = seaf_repo_manager_post_multi_files (seaf->repo_mgr, - fsm->repo_id, - parent_dir, - filenames_json, - tmp_files_json, - fsm->user, - 0, - NULL, - NULL, - &error); - g_free (filenames_json); - g_free (tmp_files_json); - if (rc < 0) { - if (error) { - if (error->code == POST_FILE_ERR_FILENAME) { - error_code = ERROR_FILENAME; - err_file = g_strdup(error->message); - } - g_clear_error (&error); - } - goto error; - } - - /* Redirect to repo dir page after upload finishes. */ - redirect_to_success_page (req, fsm->repo_id, parent_dir); - return; - -error: - redirect_to_upload_error (req, fsm->repo_id, parent_dir, - err_file, error_code); - g_free (err_file); -} - static char * file_id_list_from_json (const char *ret_json) { @@ -1388,81 +1226,6 @@ error: } } -static void -update_cb(evhtp_request_t *req, void *arg) -{ - RecvFSM *fsm = arg; - char *target_file, *parent_dir = NULL, *filename = NULL; - const char *head_id = NULL; - GError *error = NULL; - int error_code = ERROR_INTERNAL; - - if (!fsm || fsm->state == RECV_ERROR) - return; - - if (!fsm->files) { - seaf_debug ("[update] No file uploaded.\n"); - send_error_reply (req, EVHTP_RES_BADREQ, "No file.\n"); - return; - } - - target_file = g_hash_table_lookup (fsm->form_kvs, "target_file"); - if (!target_file) { - seaf_debug ("[Update] No target file given.\n"); - send_error_reply (req, EVHTP_RES_BADREQ, "Invalid URL.\n"); - return; - } - - parent_dir = g_path_get_dirname (target_file); - filename = g_path_get_basename (target_file); - - if (!check_parent_dir (req, fsm->repo_id, parent_dir)) - return; - - if (!check_tmp_file_list (fsm->files, &error_code)) - goto error; - - head_id = evhtp_kv_find (req->uri->query, "head"); - - gint64 content_len = get_content_length(req); - if (seaf_quota_manager_check_quota_with_delta (seaf->quota_mgr, - fsm->repo_id, - content_len) != 0) { - error_code = ERROR_QUOTA; - goto error; - } - - int rc = seaf_repo_manager_put_file (seaf->repo_mgr, - fsm->repo_id, - (char *)(fsm->files->data), - parent_dir, - filename, - fsm->user, - head_id, - NULL, - &error); - if (rc < 0) { - if (error) { - if (g_strcmp0 (error->message, "file does not exist") == 0) { - error_code = ERROR_NOT_EXIST; - } - g_clear_error (&error); - } - goto error; - } - - /* Redirect to repo dir page after upload finishes. */ - redirect_to_success_page (req, fsm->repo_id, parent_dir); - g_free (parent_dir); - g_free (filename); - return; - -error: - redirect_to_update_error (req, fsm->repo_id, target_file, error_code); - g_free (parent_dir); - g_free (filename); -} - static void update_api_cb(evhtp_request_t *req, void *arg) { @@ -2888,10 +2651,6 @@ upload_file_init (evhtp_t *htp, const char *http_temp_dir) } g_free (cluster_shared_dir); - cb = evhtp_set_regex_cb (htp, "^/upload/.*", upload_cb, NULL); - /* upload_headers_cb() will be called after evhtp parsed all http headers. */ - evhtp_set_hook(&cb->hooks, evhtp_hook_on_headers, upload_headers_cb, NULL); - cb = evhtp_set_regex_cb (htp, "^/upload-api/.*", upload_api_cb, NULL); evhtp_set_hook(&cb->hooks, evhtp_hook_on_headers, upload_headers_cb, NULL); @@ -2908,9 +2667,6 @@ upload_file_init (evhtp_t *htp, const char *http_temp_dir) cb = evhtp_set_regex_cb (htp, "^/upload-aj/.*", upload_ajax_cb, NULL); evhtp_set_hook(&cb->hooks, evhtp_hook_on_headers, upload_headers_cb, NULL); - cb = evhtp_set_regex_cb (htp, "^/update/.*", update_cb, NULL); - evhtp_set_hook(&cb->hooks, evhtp_hook_on_headers, upload_headers_cb, NULL); - cb = evhtp_set_regex_cb (htp, "^/update-api/.*", update_api_cb, NULL); evhtp_set_hook(&cb->hooks, evhtp_hook_on_headers, upload_headers_cb, NULL); diff --git a/tests/test_file_operation/test_file_operation.py b/tests/test_file_operation/test_file_operation.py index 2d0c153..273edaf 100644 --- a/tests/test_file_operation/test_file_operation.py +++ b/tests/test_file_operation/test_file_operation.py @@ -19,6 +19,7 @@ def create_the_file (): def test_file_operation(): t_repo_version = 1 + print ("Mydebug create repo") t_repo_id1 = api.create_repo('test_file_operation1', '', USER, passwd = None) create_the_file() diff --git a/tests/test_file_property_and_dir_listing/test_file_property_and_dir_listing.py b/tests/test_file_property_and_dir_listing/test_file_property_and_dir_listing.py index b2b24d1..c68a72e 100644 --- a/tests/test_file_property_and_dir_listing/test_file_property_and_dir_listing.py +++ b/tests/test_file_property_and_dir_listing/test_file_property_and_dir_listing.py @@ -65,7 +65,7 @@ def test_file_property_and_dir_listing (): assert t_file_id == t_file_id_tmp #test get_dirent_by_path - std_file_mode = 0100000 | 0644 + std_file_mode = 0o100000 | 0o644 t_dirent_obj = api.get_dirent_by_path(t_repo_id, '/test.txt') assert t_dirent_obj assert t_dirent_obj.obj_id == t_file_id diff --git a/tests/test_share_and_perm/test_shared_repo_perm.py b/tests/test_share_and_perm/test_shared_repo_perm.py index 2bc3e2c..e35a39e 100644 --- a/tests/test_share_and_perm/test_shared_repo_perm.py +++ b/tests/test_share_and_perm/test_shared_repo_perm.py @@ -1,3 +1,4 @@ +from builtins import str import pytest import time from seaserv import seafile_api as api diff --git a/tests/utils.py b/tests/utils.py index bb3350f..423c633 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -12,7 +12,7 @@ def create_and_get_repo(*a, **kw): def randstring(length=12): - return ''.join(random.choice(string.lowercase) for i in range(length)) + return ''.join(random.choice(string.ascii_lowercase) for i in range(length)) def create_and_get_group(*a, **kw): group_id = ccnet_api.create_group(*a, **kw)