clean up
parent
9c7aec8d5c
commit
f12bb01571
@ -1,12 +0,0 @@
|
||||
Package: libsntl-dev
|
||||
Source: libsntl
|
||||
Version: 0.1.0
|
||||
Architecture: amd64
|
||||
Maintainer: Alexander Vdolainen <vdo@askele.com>
|
||||
Installed-Size: 94
|
||||
Depends: libsntl (= 0.1.0), libsexpr-dev, libssl1.0.0-dev, libtdata-dev, uuid-dev
|
||||
Section: libdevel
|
||||
Priority: extra
|
||||
Homepage: http://askele.com/software
|
||||
Description: Development files for libsntl
|
||||
Development files for sntl library
|
@ -1,9 +0,0 @@
|
||||
a308bdc1ae862fbc6d6a17ed75e33bfa usr/include/sntl/connection.h
|
||||
57ab61abf79d35bcc7cf5f186b55cf76 usr/include/sntl/pth_queue.h
|
||||
29d522606ca36fcb6113762477f32ea5 usr/lib/libsntl.a
|
||||
e6cfd12c5a6771aac0251ba14bdc5a6c usr/lib/pkgconfig/libsntl.pc
|
||||
71871531899aaf89ff3e0c7d659ff820 usr/share/doc/libsntl-dev/NEWS.gz
|
||||
f93d2d6c0d313ad0266f6f88cf4d3d2a usr/share/doc/libsntl-dev/README
|
||||
c3f0efcfa0458a2eaab242c388b28bda usr/share/doc/libsntl-dev/README.Debian
|
||||
87736146030b265e3f3c8b577726c44b usr/share/doc/libsntl-dev/changelog.gz
|
||||
7f3520d22e4f7e2bbbb8bf0b1b104a9e usr/share/doc/libsntl-dev/copyright
|
@ -1,320 +0,0 @@
|
||||
/*
|
||||
* File: connection.h
|
||||
* Author: vdo
|
||||
*
|
||||
* Created on September 24, 2014, 2:36 AM
|
||||
*/
|
||||
|
||||
#ifndef __ESXC_CONNECTION_H_
|
||||
#define __ESXC_CONNECTION_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include <tdata/usrtc.h>
|
||||
#include <tdata/idx_allocator.h>
|
||||
#include <sexpr/sexp.h>
|
||||
#include <sexpr/faststack.h>
|
||||
|
||||
#include <sntl/pth_queue.h>
|
||||
|
||||
/* error codes */
|
||||
#define ESXOREPLYREQ 44 /* protocol require reply with expression,
|
||||
* or expression return for the request */
|
||||
#define ESXOTIMEDOUT 45 /* timedout */
|
||||
#define ESXRCBADPROT 46 /* invalid protocol */
|
||||
#define ESXNOCONNECT 47 /* connection is lost */
|
||||
#define ESXNOCHANSUP 48
|
||||
#define ESXRAPIDREPLY 49
|
||||
|
||||
/* sexp helpers */
|
||||
#define SEXP_IS_LIST(sx) \
|
||||
((sx)->ty == SEXP_LIST) ? 1 : 0
|
||||
|
||||
#define SEXP_IS_TYPE(sx,type) \
|
||||
((sx)->ty == SEXP_VALUE && (sx)->aty == (type)) ? 1 : 0
|
||||
|
||||
#define SEXP_ITERATE_LIST(lst, iter, ind) \
|
||||
for((ind) = 0, (iter) = (lst)->list; (ind) < sexp_list_length(lst); \
|
||||
(ind)++, (iter) = (iter)->next)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int sexp_list_cdr(sexp_t *expr, sexp_t **sx);
|
||||
int sexp_list_car(sexp_t *expr, sexp_t **sx);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define VERIFY_DEPTH 1 /* FIXME: */
|
||||
|
||||
#define MAX_CONNECTIONS 32768
|
||||
#define MAX_CHANNELS 4096
|
||||
#define MAX_RPC_LIST 2048
|
||||
#define MAX_MULTI 12
|
||||
#define MAX_PENDINGMSG 16384
|
||||
#define MAX_MSGINDEX ((MAX_PENDINGMSG) * (MAX_MULTI))
|
||||
|
||||
typedef struct __perm_context_type {
|
||||
char *login;
|
||||
char *passwd;
|
||||
ulong_t certid;
|
||||
ulong_t uid;
|
||||
ulong_t gid;
|
||||
ulong_t *gids;
|
||||
int n_gids;
|
||||
int p_attr;
|
||||
struct in_addr *addr;
|
||||
void *priv;
|
||||
} perm_ctx_t;
|
||||
|
||||
#define CXCONN_MASTER (1 << 1)
|
||||
#define CXCONN_SLAVE (1 << 2)
|
||||
#define CXCONN_ESTABL (1 << 3)
|
||||
#define CXCONN_BROKEN (1 << 4)
|
||||
|
||||
/*
|
||||
* älä jätä kommentteja omalla kielellä! yksinkertaisia englanti sijaan!
|
||||
* i found somebody who write comments and messages in non-english,
|
||||
* itäs a fucking practice - forget it.
|
||||
*/
|
||||
typedef struct __connection_t {
|
||||
char *uuid; /** < uuid of the connection */
|
||||
idx_allocator_t *idx_ch; /** < index allocation for channels */
|
||||
usrtc_t *chnl_tree; /** < search tree of all channels */
|
||||
usrtc_t *rpc_list; /** < search tree of possible RPC typed lists */
|
||||
SSL_CTX *ctx; /** < SSL context */
|
||||
SSL *ssl; /** < SSL connection */
|
||||
int ssl_data_index; /** < SSL index for the custom data */
|
||||
perm_ctx_t *pctx; /** < higher layer authentification context */
|
||||
pthread_t cthread; /** < thread for listening the connection socket */
|
||||
pthread_t rmsgthread; /** < thread for message queue (1) */
|
||||
pthread_t msgthread; /** < thread for message queue (2) */
|
||||
pth_queue_t *mqueue; /** < message queue (2) */
|
||||
pth_queue_t *rqueue; /** < message queue (1) */
|
||||
pth_dqtpoll_t *tpoll; /** < thread poll for rpc requests */
|
||||
pthread_mutex_t oplock; /** < mutex used to sync operations on connection */
|
||||
pthread_rwlock_t chnl_lock; /** < rwlock used to sync ops with channels */
|
||||
int flags; /** < flags of the connection */
|
||||
usrtc_node_t csnode; /** < node to store the connection within list */
|
||||
} conn_t;
|
||||
|
||||
struct __connection_rpc_list_type;
|
||||
struct __message_t;
|
||||
|
||||
#define ESXCHAN_PENDING (1 << 1)
|
||||
#define ESXCHAN_CLOSURE (1 << 2)
|
||||
|
||||
typedef struct __channel_t {
|
||||
ulong_t cid; /** < ID of the channel */
|
||||
char *uuid; /** < UUID of the channel, used in advanced implementation
|
||||
* of the complex distributed systems */
|
||||
conn_t *connection; /** < pointer to the parent connection */
|
||||
idx_allocator_t *idx_msg; /** < index allocation for messages */
|
||||
usrtc_t *msgs_tree; /** < search tree of the existing messages */
|
||||
struct __message_t *sysmsg; /** < system message used to operate with channel */
|
||||
struct __connection_rpc_list_type *rpc_list; /** < rpc functions list */
|
||||
pthread_mutex_t oplock; /** < operation ops lock */
|
||||
pthread_rwlock_t msglock; /** < rwlock used to operate with messages */
|
||||
usrtc_node_t node; /** < node for connection search tree */
|
||||
int use_count; /** < use count */
|
||||
int flags; /** < flags of the channel */
|
||||
} chnl_t;
|
||||
|
||||
typedef struct __sexp_payload_t {
|
||||
char *cstr;
|
||||
sexp_t *sx;
|
||||
} sxpayload_t;
|
||||
|
||||
#define ESX_SYSMSG_SIZE 512
|
||||
|
||||
#define ESXMSG_SYS (1 << 1)
|
||||
#define ESXMSG_USR (1 << 2)
|
||||
#define ESXMSG_PENDING (1 << 3)
|
||||
#define ESXMSG_NOWAY (1 << 4)
|
||||
#define ESXMSG_TIMEDOUT (1 << 5)
|
||||
#define ESXMSG_PULSE (1 << 6)
|
||||
#define ESXMSG_NOWAIT (1 << 7)
|
||||
#define ESXMSG_ISREPLY (1 << 8)
|
||||
#define ESXMSG_CLOSURE (1 << 9)
|
||||
#define ESXMSG_RMONRETR (1 << 10)
|
||||
#define ESXMSG_KILLTHRD (1 << 11)
|
||||
#define ESXMSG_ISRAPID (1 << 12)
|
||||
|
||||
/**
|
||||
* \brief Message used in sntl message passing
|
||||
*
|
||||
* This structure used to manage a message within a channel
|
||||
* of the sntl structure stack.
|
||||
*/
|
||||
typedef struct __message_t {
|
||||
chnl_t *pch; /** < channel of the message(if applicable) */
|
||||
ulong_t mid; /** < unique ID within connection context */
|
||||
char *uuid; /** < UUID of the message, used for special messages */
|
||||
usrtc_node_t pendingq_node; /** < node for the pending queue */
|
||||
pthread_mutex_t wait; /** < special wait mutex, used for sync */
|
||||
void *payload; /** < payload */
|
||||
sexp_t *initial_sx;
|
||||
int opcode; /** < opcode for system and pulse messages */
|
||||
int flags; /** < flags of the message (type, state etc ...)*/
|
||||
int use_count; /** < use count */
|
||||
} sxmsg_t;
|
||||
|
||||
typedef struct __connection_rpc_entry_type {
|
||||
char *name;
|
||||
int (*rpcf)(void *, sexp_t *);
|
||||
usrtc_node_t node;
|
||||
} cx_rpc_t;
|
||||
|
||||
typedef struct __connection_rpc_list_type {
|
||||
usrtc_t *rpc_tree; /** < search tree for the rpc lookup */
|
||||
char *opt_version; /** < reserved for future implementations */
|
||||
} cx_rpc_list_t;
|
||||
|
||||
/**
|
||||
* \brief Connection subsystem structure.
|
||||
*
|
||||
* This structure used for management and control a set of a
|
||||
* determined connections with the same RPC lists and the same
|
||||
* mode (server, client).
|
||||
*
|
||||
*/
|
||||
typedef struct __connections_subsys_type {
|
||||
int ex_ssldata_index; /** < index used to work with additional data
|
||||
* provided to the special call during SSL handshake */
|
||||
usrtc_t *connections;
|
||||
pth_queue_t *ioq; /** < general messages queue */
|
||||
pth_queue_t *ioqueue; /** < system messages queue */
|
||||
/* system threads */
|
||||
pthread_t iog_thread; /** < general io queue */
|
||||
pthread_t ios_thread; /** < system io queue */
|
||||
pthread_rwlock_t rwlock;
|
||||
char *rootca, *certpem, *certkey; /* path name to the certificates */
|
||||
cx_rpc_list_t *system_rpc;
|
||||
/* special functions pointers */
|
||||
int (*validate_sslpem)(conn_t *); /** < this function used to validate SSL certificate while SSL handshake */
|
||||
int (*secure_check)(conn_t *); /** < this function authorize user to login,
|
||||
* and also should check SSL cert and user, and already made sessions */
|
||||
usrtc_t* (*get_rpc_typed_list_tree)(conn_t *); /** < this function is used to set RPC list of the functions */
|
||||
int (*set_typed_list_callback)(conn_t *, int, char *); /** < this function is a callback
|
||||
* during setting up a typed channel */
|
||||
void (*on_destroy)(conn_t *); /** < callback on connection destroy */
|
||||
void *priv;
|
||||
} conn_sys_t;
|
||||
|
||||
typedef struct __rpc_typed_list_type {
|
||||
int type_id;
|
||||
char *description;
|
||||
cx_rpc_list_t *rpc_list;
|
||||
usrtc_node_t lnode;
|
||||
} rpc_typed_list_t;
|
||||
|
||||
extern conn_sys_t *conn_sys;
|
||||
|
||||
/* General API */
|
||||
/* subsystem */
|
||||
|
||||
extern conn_sys_t *conn_sys;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int connections_subsystem_init(void);
|
||||
|
||||
int connections_subsystem_setsslserts(const char *rootca, const char *certpem,
|
||||
const char *certkey);
|
||||
|
||||
int connections_subsystem_setrpclist_function(usrtc_t* (*get_rpc_typed_list_tree)(conn_t *));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define connections_subsystem_set_securecheck(c, fuu) (c)->secure_check = fuu
|
||||
#define connections_subsystem_set_sslvalidator(c, fuu) (c)->validate_sslpem = fuu
|
||||
#define connections_subsystem_set_rpctlist_call(c, fuu) (c)->set_typed_list_callback = fuu
|
||||
#define connections_subsystem_set_on_destroy(c, fuu) (c)->on_destroy = fuu
|
||||
|
||||
/* connection */
|
||||
#define connection_create(c, s) connection_create_fapi((c), (s), NULL)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int connection_initiate (conn_t *co, const char *host, int port,
|
||||
const char *SSL_cert, perm_ctx_t *pctx);
|
||||
|
||||
int connection_create_fapi(conn_t *co, int sck, struct in_addr *addr);
|
||||
|
||||
int connection_close(conn_t *co);
|
||||
|
||||
/* FIXME: for the next versions */
|
||||
int connection_reinit(conn_t *co);
|
||||
|
||||
/* channels */
|
||||
int channel_open(conn_t *co, chnl_t **ch, int type);
|
||||
|
||||
int channel_close(chnl_t *chnl);
|
||||
|
||||
/* message passing */
|
||||
int msg_send(chnl_t *ch, sexp_t *sx, sxmsg_t **msg);
|
||||
|
||||
int msg_send_timed(chnl_t *ch, sexp_t *sx, sxmsg_t **msg, struct timespec *tio);
|
||||
|
||||
int msg_return(sxmsg_t *msg, int opcode);
|
||||
|
||||
int msg_reply(sxmsg_t *msg, sexp_t *sx);
|
||||
|
||||
int msg_reply_timed(sxmsg_t *msg, sexp_t *sx, struct timespec *tio);
|
||||
|
||||
/* reply with S expression without confirmation of delivery and applying */
|
||||
int msg_reply_rapid(sxmsg_t *msg, sexp_t *sx);
|
||||
|
||||
/* this is required to clean the message in case if it's a rapid message */
|
||||
int msg_rapid_clean(sxmsg_t *msg);
|
||||
|
||||
int msg_send_pulse(chnl_t *ch, sexp_t *sx);
|
||||
|
||||
int msg_send_pulse_timed(chnl_t *ch, sexp_t *sx, struct timespec *tio);
|
||||
|
||||
int msg_send_pulse_nowait(chnl_t *ch, sexp_t *sx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* additional functions */
|
||||
#define sntl_msg_get_secctx(m) (m)->pch->connection->pctx
|
||||
|
||||
/* RPC List API */
|
||||
#define SNTL_FILTER_INC 0xa
|
||||
#define SNTL_FILTER_EXC 0xb
|
||||
#define SNTL_FILTER_END -1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int sntl_rpclist_init(usrtc_t *tree);
|
||||
|
||||
int sntl_rpclist_add(usrtc_t *tree, int type, const char *description,
|
||||
const char *version);
|
||||
|
||||
int sntl_rpclist_add_function(usrtc_t *tree, int type, const char *fu_name,
|
||||
int (*rpcf)(void *, sexp_t *));
|
||||
|
||||
int sntl_rpclist_filter(usrtc_t *source, usrtc_t **dest, int flag, int *filter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* for DEBUG purposes */
|
||||
#define __DBGLINE fprintf(stderr, "%s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__)
|
||||
|
||||
#endif /* __ESXC_CONNECTION_H_ */
|
||||
|
@ -1,117 +0,0 @@
|
||||
/*
|
||||
* This is a proprietary software. See COPYING for further details.
|
||||
*
|
||||
* (c) 2013 Copyright Askele, inc. <http://askele.com>
|
||||
* (c) 2013 Copyright Askele Ingria, inc. <http://askele-ingria.com>
|
||||
* (c) 2014 Copyright Confident, inc. (granted permission to use in commercial software)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file pth_queue.h
|
||||
* @author Alexander Vdolainen
|
||||
* @date 4 Nov 2013, 20 Dec 2014 (dynamic polls)
|
||||
* @brief queue implementation for threads intercommunication
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PTH_QUEUE_H__
|
||||
#define __PTH_QUEUE_H__
|
||||
|
||||
#include <pthread.h>
|
||||
#include <tdata/idx_allocator.h>
|
||||
|
||||
/* possible message types, ones with POLL_ prefix valid on for pth_dqtpoll_* */
|
||||
#define SYS_MSG 0x0f0affee
|
||||
#define USR_MSG 0x0afeeffe
|
||||
#define POLL_DECREASE 0x0afafafe
|
||||
#define POLL_INCREASE 0x0afaffff
|
||||
#define NIL_MSG 0x0
|
||||
#define END_MSG 0xdead0000
|
||||
|
||||
/* max amount of threads within the poll */
|
||||
#define MAX_POLL_VALUE 32
|
||||
|
||||
typedef struct pth_msg_s {
|
||||
void *data; /** < message payload */
|
||||
unsigned int msgtype; /** < message type ID */
|
||||
unsigned int qlength; /** < current queue length (actual on add moment),
|
||||
* it makes no sense with few readers */
|
||||
usrtc_node_t node;
|
||||
} pth_msg_t;
|
||||
|
||||
typedef struct pth_queue_s {
|
||||
unsigned int length;
|
||||
/* sync */
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
/* queue data */
|
||||
usrtc_t qtree;
|
||||
/* cache */
|
||||
usrtc_t msgcache;
|
||||
} pth_queue_t;
|
||||
|
||||
int pth_queue_init(pth_queue_t *queue);
|
||||
|
||||
int pth_queue_add(pth_queue_t *queue, void *data, unsigned int msgtype);
|
||||
|
||||
int pth_queue_get(pth_queue_t *queue, const struct timespec *timeout,
|
||||
pth_msg_t *msg);
|
||||
|
||||
unsigned int pth_queue_length(pth_queue_t *queue);
|
||||
|
||||
int pth_queue_destroy(pth_queue_t *queue, int freedata,
|
||||
void (*free_msg)(void *));
|
||||
|
||||
/* dynamic queue thread poll ... bbrrr .... ok, ok with beer
|
||||
* Dynamic queue thread poll is a queue like pth_queue,
|
||||
* but also it has itäs own mamagement for threads - that's
|
||||
* why dynamic.
|
||||
* Ideally, the model is trying to achieve the following:
|
||||
* 1. one thread in queue while no or very small amount of jobs in the queue
|
||||
* 2. grow until max threads is reached while too many requests
|
||||
* 3. gently slide down volume of threads after job heat
|
||||
* 4. minimal additional drawbacks (i hate something periodically running,
|
||||
* it's bad practice)
|
||||
* The model is quite simple, we should make spurious wakeups equal to zero,
|
||||
* if no - decrease poll value, and, if we don't have thread available -
|
||||
* create it.
|
||||
*/
|
||||
typedef struct pth_dqtpoll_s {
|
||||
pth_queue_t *queue; /** < Job queue */
|
||||
pthread_t *poll; /** < Thread descriptors */
|
||||
int (*jobdata_callback)(void *); /** < Callback to have a deal with data */
|
||||
int flags; /** < Flags */
|
||||
idx_allocator_t *idx; /** < index allocator for the poll threads */
|
||||
pthread_rwlock_t stats_lock; /** < rwlock for stats data */
|
||||
unsigned long spurious_wakeups; /** < amount of spurios wakeups */
|
||||
int poll_value; /** < value of the poll (totally) */
|
||||
struct timeval sched_time;
|
||||
int msgop;
|
||||
} pth_dqtpoll_t;
|
||||
|
||||
/* flags for poll */
|
||||
#define DQTPOLL_RUNNING (1 << 1) /* poll is running */
|
||||
#define DQTPOLL_DEADSTAGE (1 << 2) /* poll in the stage of destroy */
|
||||
|
||||
/* keep it stupid */
|
||||
#define DQTPOLL_DELTAMS 500000
|
||||
#define DQTPOLL_DELTASE 0
|
||||
|
||||
/* init poll, structure must be allocated */
|
||||
int pth_dqtpoll_init(pth_dqtpoll_t*, int (*jobdata_callback)(void *));
|
||||
|
||||
/* run poll: poll */
|
||||
int pth_dqtpoll_run(pth_dqtpoll_t*);
|
||||
|
||||
/* add the job to the queue: poll, job data, message type */
|
||||
int pth_dqtpoll_add(pth_dqtpoll_t*, void*, unsigned int);
|
||||
|
||||
/* destroy the poll: poll, force flag
|
||||
* if force flag is set (!= 0), give up
|
||||
* about jobs, if no, do the job, but don't
|
||||
* accept the new ones, and destroy all poll
|
||||
* with last thread.
|
||||
*/
|
||||
int pth_dqtpoll_destroy(pth_dqtpoll_t*, int);
|
||||
|
||||
#endif /* __PTH_QUEUE_H__ */
|
@ -1 +0,0 @@
|
||||
libsntl.so.0.0.0
|
@ -1,13 +0,0 @@
|
||||
prefix=/usr
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
datarootdir=${prefix}/share
|
||||
datadir=${datarootdir}
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libsntl
|
||||
Description: Secure Network Transport Layer library implementation
|
||||
Version: 0.1.0
|
||||
Requires:
|
||||
Libs: -L${libdir} -lsntl
|
||||
Cflags: -I${includedir}
|
Binary file not shown.
@ -1 +0,0 @@
|
||||
1. Build the Debian package: debuild -i -us -uc -b
|
@ -1,6 +0,0 @@
|
||||
libsntl for Debian
|
||||
-------------------
|
||||
|
||||
<possible notes regarding this package - if none, delete this file>
|
||||
|
||||
-- Alexander Vdolainen <vdo@daze> Mon, 24 Nov 2014 11:52:48 +0200
|
Binary file not shown.
@ -1,38 +0,0 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: libsntl
|
||||
Source: <url://example.com>
|
||||
|
||||
Files: *
|
||||
Copyright: <years> <put author's name and email here>
|
||||
<years> <likewise for another author>
|
||||
License: <special license>
|
||||
<Put the license of the package here indented by 1 space>
|
||||
<This follows the format of Description: lines in control file>
|
||||
.
|
||||
<Including paragraphs>
|
||||
|
||||
# If you want to use GPL v2 or later for the /debian/* files use
|
||||
# the following clauses, or change it to suit. Delete these two lines
|
||||
Files: debian/*
|
||||
Copyright: 2014 Alexander Vdolainen <vdo@daze>
|
||||
License: GPL-2+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
# Please also look if there are files or directories which have a
|
||||
# different copyright/license attached and list them here.
|
||||
# Please avoid to pick license terms that are more restrictive than the
|
||||
# packaged work, as it may make Debian's contributions unacceptable upstream.
|
Loading…
Reference in New Issue