[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Copyright concerns regarding Seafile

We ask Debian to consider removing and stop distributing Seafile packages [1]  due to copyright concerns. 


Seafile is an open-source dropbox clone created by a team from China. Around 2013 they needed MySQL and PostgreSQL support and started using our open-source database connection pool library, libzdb [2].  

In 2014 a push was made to include Seafile in Debian and a discussion about copyright concerns in Seafile started on GitHub [3]. Libzdb played a role in this discussion and one of the results were that Seafile in 2016 removed the dependency on libzdb and stated that “we completely replaced libzdb with our own code.” [4]  Seafile has since been included in Debian [1].


We later discovered that the code that replaced libzdb is mostly a copy of libzdb's code and structures. This stand in contrast to the statement “we completely replaced libzdb with our own code.”  [4]

Libzdb is licensed under GPLv3. Copying and modifying GPL code is perfectly fine as long as the original copyright notice and license are kept. Unfortunately, this is not what the Seafile team did. Instead they copied code from libzdb, removed the copyright notice, claimed the code as their own and re-license it under another license. 


To do a side by side comparison I’m going to use Seafile’s version of libzdb which they forked on GitHub [6] at version 2.11.1 and based their new code on and claimed as their own [5]. The comparison is going to be against our same version on Bitbucket. 

Libzdb is a database connection pool library which consists of 4 major components: ConnectionPool, Connection, ResultSet and PreparedStatement. Forward declared data structures are used to abstract the concrete database implementation. These components together with their method association are quite unique for a _C_ database connection pool library as far as I know. The Seafile "rewrite" uses the exact same components and method association between components with modest renaming. Mostly by going from camel-case to snake-case.

I’m going to limit the comparison somewhat for brevity, but it should be enough to demonstrate copyright concern. The full comparison can be done by comparing [5] and [7]. 

1. The Connection Pool has two significant methods:

- Get a connection from the pool

a:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/ConnectionPool.c#lines-314

a:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/db-wrapper.c#L180

- And return a connection to the pool

b:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/ConnectionPool.c#lines-345

b:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/db-wrapper.c#L220

Apart from Seafile using glib array and libzdb using its own vector module the above demonstrate copy of code with the same logic, method and variable names. Libzdb’s Connection_setAvailable is equal to their conn->is_available = FALSE; And our LOCK macro is just pthread_mutex_lock. I.e. the same code and logic, just expanded and inlined. 

2. Connection

In libzdb a Connection has three significant  methods, Connection_execute, Connection_executeQuery and Connection_prepareStatement. Seafile has the same methods implemented in the same way

a:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/Connection.c#lines-308

a:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/db-wrapper.c#L258

b:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/Connection.c#lines-323

b:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/db-wrapper.c#L350

Seafile has not copied all methods from libzdb’s Connection, but Connection_ping is is there as well as Connection_beginTransaction, Connection_rollback and Connection_commit

c:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/Connection.c#lines-228

c:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/db-wrapper.c#L241

What is special about our transaction code in libzdb is that we keep a counter called “isInTransaction” which Seafile has as “in_transaction”. 

d:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/Connection.c#lines-252

d:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/db-wrapper.c#L424

3. ResultSet and PreparedStatment are also clearly copied from libzdb. We see ResultSet_next, ResultSet_getString, ResultSet_getInt etc and PreparedStatement_setString, PreparedStatement_setInt etc. Also PreparedStatement_executeQuery is faithfully copied:

a:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/PreparedStatement.c#lines-122

a:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/db-wrapper.c#L392

4. Concrete Database implementations. 

When it comes to the concrete database implementation for SQLite, MySQL and PostgreSQL the same copy of code is repeated. For example, MysqlResultSet_new.

a:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/mysql/MysqlResultSet.c#lines-102

a:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/mysql-db-ops.c#L189

and the special way we ensure column field capacity in MySQL where they very telling even has copied our comment: 

b:libzdb: https://bitbucket.org/tildeslash/libzdb/src/2958e023fcee44f313e6d3f3592b02cc06783e0f/src/db/mysql/MysqlResultSet.c#lines-84

b:seafile: https://github.com/haiwen/seafile-server/blob/9f30eedc467bf5938ff57e24cee3a5b473e72314/common/db-wrapper/mysql-db-ops.c#L277


The evidence above demonstrate that there are reasons to be concerned about the Seafile team's insubstantial dealings in open-source and that the Seafile team for all practical purposes are conducting copyright infringement and violating the GPL terms. It is unclear to me if the Seafile server is part of Debian or if it is downloaded separately or during the install process and that Debian is only distributing the client part of Seafile. If the latter is the case, I still hope that Debian will make a stand and not distribute Seafile packages as long as there are copyright concerns associated with the Seafile Software.

Best regards
Jan-Henrik Haukeland

1. https://packages.debian.org/search?keywords=seafile
2. https://www.tildeslash.com/libzdb/
3. https://github.com/haiwen/seafile/issues/666
4. https://github.com/haiwen/seafile/issues/666#issuecomment-260232869
5. https://github.com/haiwen/seafile-server/tree/master/common/db-wrapper
6. Seafile’s fork of libzdb https://github.com/haiwen/libzdb
7. Our libzdb repository: https://bitbucket.org/tildeslash/libzdb/src/release-2-11-1/

Reply to: