Remove RPC and net backends.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@12018 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Neil Williams 2005-11-22 22:54:04 +00:00
parent 6079e3e674
commit bb7f8e681e
45 changed files with 34 additions and 7954 deletions

View File

@ -1,3 +1,20 @@
2005-11-22 Neil Williams <linux@codehelp.co.uk>
* configure.in : Remove net and RPC backends,
Tidy up --with and --enable output to --help
* po/POTFILES.in : Remove RPC and net related files.
* src/backend/Makefile.am : Remove net and RPPC
* src/backend/net : Removed all files.
* src/backend/qsf : Removed stub.
* src/backend/rpc : Removed all files.
* src/engine/gnc-engine.c : Remove gnc_run_rpc_server
function.
* src/engine/gnc-engine.h : Remove -gnc_run_rpc_server
definition.
* src/engine/gnc-filepath-utils.c : Remove rpc://
* src/engine/gw-engine-spec.scm : Remove g-wrapper
* src/README.modules : Document removal of RPC.
2005-11-22 Christian Stimming <stimming@tuhh.de>
* po/nb.po: Updated Norwegian (bokmaal) translation by Tor Harald

View File

@ -388,7 +388,7 @@ dnl *************************************
dnl QOF
dnl *************************************
AC_ARG_WITH(qof, [ --with-qof=path prefix for Query Object Framework - QOF (auto)])
AC_ARG_WITH(qof, [ --with-qof=path prefix for Query Object Framework - QOF (auto)])
QOF_REQUIRED=0.6.0
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
if test pkg-config = no; then
@ -580,7 +580,7 @@ AC_ARG_ENABLE( profile,
LDFLAGS="${LDFLAGS} -pg")
AC_ARG_ENABLE( ref-counts-dumps,
[ --enable-ref-counts-dumps compile with ref count dumps],
[ --enable-ref-counts-dumps compile with ref count dumps],
AC_DEFINE(DEBUG_REFERENCE_COUNTING,1,Enable reference count dumps),
AC_DEFINE(DEBUG_REFERENCE_COUNTING,0,Enable reference count dumps) )
@ -674,21 +674,7 @@ AC_SUBST(SQL_DIR)
### --------------------------------------------------------------------------
### RPC
AC_ARG_ENABLE( rpc,
[ --enable-rpc compile with rpc support],
[
AC_MSG_WARN([
The RPC Backend is depricated. You should not use it.
It may go away in the future. If you need it, please
contact gnucash-devel@gnucash.org and let the developers
know.
])
RPC_DIR=rpc
])
AC_SUBST(RPC_DIR)
### RPC has been removed in gnucash 1.9.0
### --------------------------------------------------------------------------
### OFX
@ -828,7 +814,7 @@ AC_SUBST(HBCI_DIR)
### i18n
AC_ARG_WITH( locale-dir,
[ --with-locale-dir=PATH specify where to look for locale-specific information],
[ --with-locale-dir=PATH specify where to look for locale-specific information],
LOCALE_DIR="$with_locale_dir",
LOCALE_DIR="\${prefix}/share/locale")
@ -847,7 +833,7 @@ AC_ARG_ENABLE( locale-specific-tax,
# Used to initialize doc-path.
AC_ARG_WITH( help-prefix,
[ --with-help-prefix=PATH specify where to store the help files],
[ --with-help-prefix=PATH specify where to store the help files],
GNC_HELPDIR="$with_help_prefix",
GNC_HELPDIR="\${datadir}")
@ -891,7 +877,7 @@ AM_CONDITIONAL(GNC_CTAGS_FILE, test x${GNC_CTAGS_FILE} = xtags)
# Check for perl, force version 5
AC_ARG_WITH(perl,
[ --with-perl=FILE which perl executable to use ],
[ --with-perl=FILE which perl executable to use ],
PERL="${with_perl}")
# If the user didn't specify a perl, then go fetch.
@ -921,7 +907,7 @@ AC_SUBST(PERL)
#
PERLINCL=`$PERL -MConfig -e 'print $Config{"archlibexp"}'`
AC_ARG_WITH( perl-includes,
[ --with-perl-includes=DIR specify where to look for perl includes],
[ --with-perl-includes=DIR specify where to look for perl includes],
PERLINCL="$with_perl_includes" )
AC_SUBST(PERLINCL)
@ -929,10 +915,10 @@ AC_SUBST(PERLINCL)
# ----------------------------------------------------------------------------
AC_DEFUN([BB_ENABLE_DOXYGEN],
[
AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (auto)])
AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)])
AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes])
AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX documentation generation with doxygen (no)], [], [ enable_latex_docs=no])
AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (auto)])
AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)])
AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes])
AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX documentation generation with doxygen (no)], [], [ enable_latex_docs=no])
if test "x$enable_doxygen" = xno; then
enable_doc=no
else
@ -1081,7 +1067,7 @@ esac
### ----------------------------------------------------------------------
### XIM
AC_ARG_ENABLE(xim,
[ --enable-xim support XIM [default=yes]],
[ --enable-xim support XIM [default=yes]],
, enable_xim="yes")
if test "x$enable_xim" = "xyes"; then
@ -1296,14 +1282,12 @@ AC_CONFIG_FILES(po/Makefile.in
src/app-utils/Makefile
src/app-utils/test/Makefile
src/backend/Makefile
src/backend/net/Makefile
src/backend/file/Makefile
src/backend/file/test/Makefile
src/backend/file/test/test-files/Makefile
src/backend/file/test/test-files/xml2/Makefile
src/backend/postgres/Makefile
src/backend/postgres/test/Makefile
src/backend/rpc/Makefile
src/bin/Makefile
src/bin/overrides/Makefile
src/bin/test/Makefile
@ -1409,16 +1393,6 @@ AC_CONFIG_FILES(po/Makefile.in
)
AC_OUTPUT
if test x$RPC_DIR = xrpc ; then
AC_MSG_WARN([
The RPC Backend is deprecated. You should not use it.
It may go away in the future. If you need it, please
contact gnucash-devel@gnucash.org and let the developers
know.
])
fi
AC_MSG_RESULT([
Options detected/selected
-------------------------

View File

@ -47,7 +47,6 @@ src/backend/file/sixtp-dom-parsers.c
src/backend/file/sixtp-stack.c
src/backend/file/sixtp-to-dom-parser.c
src/backend/file/sixtp-utils.c
src/backend/net/NetIO.c
src/backend/postgres/account.c
src/backend/postgres/book.c
src/backend/postgres/builder.c
@ -63,18 +62,6 @@ src/backend/postgres/putil.c
src/backend/postgres/txn.c
src/backend/postgres/txnmass.c
src/backend/postgres/upgrade.c
src/backend/rpc/clnt_thrd.c
src/backend/rpc/gncmod-backend-rpc.c
src/backend/rpc/gncRpc_clnt.c
src/backend/rpc/gncRpc_server.c
src/backend/rpc/gncRpc_server_stubs.c
src/backend/rpc/gncRpc_svc.c
src/backend/rpc/RpcBackend.c
src/backend/rpc/RpcServer.c
src/backend/rpc/RpcSock.c
src/backend/rpc/RpcUtils.c
src/backend/rpc/svc_thrd.c
src/backend/rpc/xprt_thrd.c
src/business/business-core/businessmod-core.c
src/business/business-core/file/gnc-address-xml-v2.c
src/business/business-core/file/gnc-bill-term-xml-v2.c

View File

@ -24,7 +24,6 @@ engine The engine module, without any backends
backend/file Binary and XML (v1 and v2) backends
backend/postgres Postgres backend
backend/rpc RPC backend
register/ledger-core The xacc SplitLedger and MultiLedger parts formerly
in src/
@ -57,3 +56,6 @@ gnome-utils Extensions and utilities for using Gnome/Gtk
network-utils Utils for network communication.
tax/us US tax information
(RPC was removed in v.1.9.0, subversion release: 12018)

View File

@ -1,5 +1,5 @@
SUBDIRS = file ${SQL_DIR} ${RPC_DIR}
DIST_SUBDIRS = file net postgres rpc
DIST_SUBDIRS = file postgres
noinst_HEADERS = gnc-backend-api.h

View File

@ -1,21 +0,0 @@
SUBDIRS = .
pkglib_LTLIBRARIES = libgncmod-backend-net.la
AM_CFLAGS = \
-I.. -I../.. \
-I../../engine -I${srcdir}/../../engine \
-I../file -I${srcdir}/../file \
-I../../gnc-module \
${GLIB_CFLAGS}
libgncmod_backend_net_la_SOURCES = \
NetIO.c
noinst_HEADERS = \
NetIO.h
libgncmod_backend_net_la_LDFLAGS = -module
libgncmod_backend_net_la_LIBADD = \
${GLIB_LIBS} \
${top_builddir}/src/engine/libgncmod-engine.la

View File

@ -1,335 +0,0 @@
/********************************************************************\
* NetIO.c -- read and write network IO *
* Copyright (C) 2001 Linas Vepstas <linas@linas.org> *
* *
* This program 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 program 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, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
* Boston, MA 02110-1301, USA gnu@gnu.org *
* *
\********************************************************************/
/********************************************************************\
* 2003-03-11 TomF changes for Gnome-2 branch, 6th batch *
* src/backend/net/NetIO.c: Remove include ghttp.h *
* to bypass missing ghttp. The functions were already disabled. *
\********************************************************************/
/*
* Rudimentary implmentation right now; good enough for a demo,
* but that's all.
*
* HACK ALERT -- this should be moved into its own subdirectory
* Mostly so that the engine build doesn't require libghttp
* as a dependency. In general, backends should be dynamically
* loaded ...
*/
#include "config.h"
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BackendP.h"
#include "NetIO.h"
#include "gnc-book.h"
#include "qof.h"
#include "io-gncxml.h"
static QofLogModule log_module = MOD_BACKEND;
typedef struct _xmlend XMLBackend;
struct _xmlend {
Backend be;
ghttp_request *request;
char * query_url;
char * auth_cookie;
};
Backend *xmlendNew (void);
#if 0
/* ==================================================================== */
/* Perform various validty checks on the reply:
* -- was the content type text/gnc-xml ?
* -- was there a reply body, of positive length?
* -- did the body appear to contain gnc xml data?
*
* Also, if the reply contained a set-cookie command, process that.
*/
static int
check_response (XMLBackend *be)
{
ghttp_request *request;
const char *bufp;
int len;
request = be->request;
/* get the content type out of the header */
bufp = ghttp_get_header(request, "Content-Type");
PINFO ("Content-Type: %s", bufp ? bufp : "(null)");
/* in principle, we should reject content that isn't
* labelled as text/gnc-xml. But for now, we'll be soft ...
*/
if (strncmp (bufp, "text/gnc-xml", 12))
{
PWARN ("content type is incorrectly labelled as %s", bufp);
be->be.last_err = ERR_NETIO_WRONG_CONTENT_TYPE;
// return 0;
}
len = ghttp_get_body_len(request);
PINFO ("reply length=%d\n", len);
/* body length must be postive */
if (0 >= len)
{
const char * errstr = ghttp_get_error (request);
const char * reason = ghttp_reason_phrase (request);
PERR ("connection failed: %s %s\n",
errstr ? errstr : "",
reason ? reason : "");
be->be.last_err = ERR_NETIO_SHORT_READ;
return len;
}
bufp = ghttp_get_body(request);
g_return_val_if_fail (bufp, 0);
DEBUG ("%s\n", bufp);
/* skip paste whitespace */
bufp += strspn (bufp, " \t\f\n\r\v\b");
/* see if this really appears to be gnc-xml content ... */
if (strncmp (bufp, "<?xml version", 13))
{
PERR ("bogus file content, file was:\n%s", bufp);
be->be.last_err = ERR_NETIO_NOT_GNCXML;
return 0;
}
/* if we got to here, the response looks good.
* if there is a cookie in the header, obey it
*/
bufp = ghttp_get_header(request, "Set-Cookie");
if (bufp)
{
if (be->auth_cookie) g_free (be->auth_cookie);
be->auth_cookie = g_strdup (bufp);
}
/* must be good */
return len;
}
/* ==================================================================== */
static void
setup_request (XMLBackend *be)
{
ghttp_request *request = be->request;
/* clean is needed to clear out old request bodies, headers, etc. */
ghttp_clean (request);
ghttp_set_header (be->request, http_hdr_Connection, "close");
ghttp_set_header (be->request, http_hdr_User_Agent,
PACKAGE "/" VERSION
" (Financial Browser for Linux; http://gnucash.org)");
ghttp_set_sync (be->request, ghttp_sync);
if (be->auth_cookie) {
ghttp_set_header (request, "Cookie", be->auth_cookie);
}
}
/* ==================================================================== */
/* Initialize the connection ... ?? */
/* validate the URL for syntactic correctness ?? */
/* maybe check to see if the server is reachable? */
static void
xmlbeBookBegin (GNCBook *book, const char *url)
{
XMLBackend *be;
if (!book || !url) return;
ENTER ("url is %s", url);
be = (XMLBackend *) xaccGNCBookGetBackend (book);
/* hack alert -- we store this first url as the url for inital
* contact & * for sending queries to
* this should be made customizable, I suppose ???? */
be->query_url = g_strdup (url);
LEAVE(" ");
}
/* ==================================================================== */
/* Load a set of accounts and currencies from the indicated URL. */
static AccountGroup *
xmlbeBookLoad (Backend *bend)
{
XMLBackend *be = (XMLBackend *) bend;
AccountGroup *grp;
ghttp_request *request;
const char *bufp;
int len;
if (!be) return NULL;
/* build up a request for the URL */
setup_request (be);
request = be->request;
ghttp_set_uri (request, be->query_url);
ghttp_set_type (request, ghttp_type_get);
ghttp_prepare (request);
ghttp_process (request);
/* perform various error and validity checking on the response */
len = check_response (be);
if (0 >= len) return NULL;
bufp = ghttp_get_body(request);
grp = gnc_book_load_from_buf ((char *)bufp, len);
LEAVE(" ");
return grp;
}
/* ==================================================================== */
static gpointer
xmlbeCompileQuery (Backend *b, Query *q)
{
return q;
}
static void
xmlbeRunQuery (Backend *b, gpointer q_p)
{
Query *q = (Query*) q_p;
XMLBackend *be = (XMLBackend *) b;
AccountGroup *grp, *reply_grp;
ghttp_request *request;
char *bufp;
int len;
if (!be || !q) return;
ENTER ("be=%p q=%p", b, q);
/* set up a new http request, of type POST */
setup_request (be);
request = be->request;
ghttp_set_uri (request, be->query_url);
ghttp_set_type (request, ghttp_type_post);
/* convert the query to XML */
gncxml_write_query_to_buf (q, &bufp, &len);
/* put the XML into the request body */
ghttp_set_body (request, bufp, len);
/* send it off the the webserver, wait for the reply */
ghttp_prepare (request);
ghttp_process (request);
/* free the query xml */
free (bufp);
/* perform various error and validity checking on the response */
len = check_response (be);
if (0 >= len) return;
/* we get back a list of splits */
bufp = ghttp_get_body(request);
reply_grp = gncxml_read_from_buf (bufp, len);
/* merge the splits into our local cache */
grp = xaccQueryGetGroup (q);
xaccGroupConcatGroup (grp, reply_grp);
xaccGroupMergeAccounts (grp);
xaccFreeAccountGroup (reply_grp);
LEAVE(" ");
return;
}
/* ==================================================================== */
static void
xmlbeBookEnd (Backend *b)
{
XMLBackend *be = (XMLBackend *) b;
ghttp_request_destroy (be->request);
g_free (be->query_url);
}
/* ==================================================================== */
#endif
Backend *
xmlendNew (void)
{
#if 0
XMLBackend *be;
be = (XMLBackend *) malloc (sizeof (XMLBackend));
/* generic backend handlers */
be->be.book_begin = NULL;
be->be.book_end = xmlbeBookEnd;
be->be.load = xmlbeBookLoad;
be->be.begin = NULL;
be->be.commit = NULL;
be->be.rollback = NULL;
be->be.compile_query = xmlbeCompileQuery;
be->be.free_query = NULL;
be->be.run_query = xmlbeRunQuery;
be->be.price_lookup = NULL;
be->be.sync = NULL;
be->be.events_pending = NULL;
be->be.process_events = NULL;
be->be.last_err = ERR_BACKEND_NO_ERR;
be->request = ghttp_request_new();
be->auth_cookie = NULL;
be->query_url = NULL;
return (Backend *) be;
#endif
return NULL;
}
/* ============================== END OF FILE ======================== */

View File

@ -1,32 +0,0 @@
/********************************************************************\
* NetIO.h -- read and write network IO *
* Copyright (C) 2001 Linas Vepstas <linas@linas.org> *
* *
* This program 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 program 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, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
* Boston, MA 02110-1301, USA gnu@gnu.org *
* *
\********************************************************************/
#ifndef XACC_NET_IO_H
#define XACC_NET_IO_H
#include "BackendP.h"
Backend * xmlendNew (void);
#endif /* XACC_NET_IO_H */

View File

@ -1,81 +0,0 @@
# RPC library Makefile.am file.
# Created By: Derek Atkins <warlord@MIT.EDU>
# The GNC RPC Backend
pkglib_LTLIBRARIES = libgncmod-backend-rpc.la
libgncmod_backend_rpc_la_SOURCES = \
gncmod-backend-rpc.c \
RpcBackend.c \
RpcServer.c \
RpcSock.c \
RpcUtils.c \
gncRpc_xdr.c \
gncRpc_clnt.c \
gncRpc_svc.c \
gncRpc_server.c \
clnt_thrd.c \
svc_thrd.c \
xprt_thrd.c
libgncmod_backend_rpc_la_LDFLAGS = -version-info 0:0:0
noinst_HEADERS = \
RpcBackend.h \
RpcServer.h \
RpcServerP.h \
RpcSock.h \
RpcUtils.h \
gncRpc.h \
clnt_thrd.h \
svc_thrd.h \
xprt_thrd.h
RPCGEN_FILES = \
gncRpc.h \
gncRpc_xdr.c \
gncRpc_clnt.c \
gncRpc_svc.c
EXTRA_DIST = \
README \
gncRpc_server_stubs.c \
$(RPCGEN_SRCS)
LDADD = -lpthread
AM_CFLAGS = \
-I.. -I${srcdir}/.. \
-I../../engine -I${srcdir}/../../engine \
-I../../gnc-module -I${srcdir}/../../gnc-module \
${GLIB_CFLAGS} -DGNCACCT_COMMODITY
#RPCGEN=rpcgen -M
RPCGEN=rpcgen -DGNCACCT_COMMODITY
RPCGEN_SRCS = gncAccount.x gncCommodity.x gncKVP.x gncGUID.x \
gncPrice.x gncQuery.x gncRpc.x gncSplit.x gncTxn.x
#gncRpc.h: $(RPCGEN_SRCS)
# $(RM) $@
# $(RPCGEN) -h -o $@ gncRpc.x
gncRpc_xdr.c: $(RPCGEN_SRCS)
$(RM) $@
$(RPCGEN) -c -o $@ ${srcdir}/gncRpc.x
#gncRpc_clnt.c: $(RPCGEN_SRCS)
# $(RM) $@
# $(RPCGEN) -l -o $@ gncRpc.x
#gncRpc_svc.c: $(RPCGEN_SRCS)
# $(RM) $@
# $(RPCGEN) -m -o $@ gncRpc.x
#gncRpc_server_stubs.c: $(RPCGEN_SRCS)
# $(RPCGEN) -Ss -o $@ gncRpc.x
rpcgen: $(RPCGEN_FILES)
# Make sure the system knows to run rpcgen first
$(libgncmod_backend_rpc_la_SOURCES): gncRpc.h

View File

@ -1,78 +0,0 @@
NOTE: the RPC backend doesn't build at the moment. It's pretty close
but needs a bit of sprucing up to make it work with the
currency-in-transaction changes.
Bill Gribble (2001-08-01)
-----------------------------------------------------------------------
This directory contains code for RPC support. The RPC Backend is a
part of the client and connects to an RPC Server sitting elsewhere.
The RPC support in Gnucash is considered experimental, and you should
use it only at your own risk. In addition, the RPC Client and Server
must match, meaning that they must be using the same version of the
RPC protocol. The client does attempt to check the version of the
server and will complain if it does not match.
Version 1, 2001-03-17
GnuCash Build Instructions
--------------------------
Build the same as usual, but you must specify the flag '--enable-rpc'
to the configure (or autogen.sh), and then run 'make' as usual.
How to use GnuCash RPC
----------------------
GnuCash RPC has two parts, an RPC Server and an RPC Client. First,
choose your server machine and run the GnuCash RPC Server:
gnucash --rpc-server
Next, start the RPC Client on your workstation. You activate the RPC
Client by supplying a URL of the form rpc://hostname[:port]/<URL> to
your client. This will connect to the RPC Server on the specified
host and open the Gnucash file <URL> on the server. The <URL> must be
a complete Gnucash URL.
Example RPC URLs include:
rpc://localhost//path/to/gnucash-file.xac
rpc://serverhost:12345/file:/path/to/file.xac
rpc://host/postgres:/...
Things to do:
-------------
- Implement Security (encryption) on the RPC connection
- Better version checking in the RPC Protocol (allow client/server to
try to find a 'matching' protocol version?) This might require
more integration of the version number into RpcUtils
- username/password or other authentication methods
- better server integration with e.g. postgres (allow RPC Server to
authenticate to postgres on behalf of client, instead of in-band
authentication in the postgres URL)
- better error messages
- Support for pricedb
- cope with new accounts/transactions in begin_edit()
- grab the book_error more often for the result/error returns in the server
- better handling when the server connection is lost
provide a way to reconnect?
- better way to kill the server (currently can only 'kill' it or ^C it)
- test whether rpcgen supports '-M'.. For now, supply the stubs as a
part of the release and let anyone who changes the .x files also
change the stubs and header. Only the xdr routines are built on the
build host, because that doesn't depend on the -M flag at all.
Derek Atkins <warlord@MIT.EDU>

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
/*
* FILE:
* RpcBackend.h
*
* FUNCTION:
* Implements the callbacks for the RPC (client) backend.
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef RPC_BACKEND_H
#define RPC_BACKEND_H
#include "BackendP.h"
typedef struct _rpcend RPCBackend;
/*
* rpcendNew() creates a new RPC Backend
*/
Backend * rpcendNew (void);
#endif /* __RPC_BACKEND_H */

View File

@ -1,132 +0,0 @@
/*
* FILE:
* RpcServer.c
*
* FUNCTION:
* Implements the Gnucash RPC server.
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#define _GNU_SOURCE
#include "config.h"
#include "qof"
#include "RpcServer.h"
#include "RpcServerP.h"
#include "RpcSock.h"
#include "gncRpc.h"
#include "xprt_thrd.h"
extern void gncrpc_prog_1(struct svc_req *, register SVCXPRT *);
static short module = MOD_BACKEND;
static void myClose (void *arg)
{
GncRpcSvc *cl = (GncRpcSvc *)arg;
if (!cl)
return;
TXPRT_DESTROY (cl->xprt);
if (cl->clnt)
CLNT_DESTROY (cl->clnt);
if (cl->book)
gnc_book_destroy (cl->book);
PINFO ("Client Disconnected: %p", cl);
/* Remove myself from the Client List */
cl->clist->clist = g_list_remove (cl->clist->clist, cl);
g_free (cl);
}
int rpc_server_run (unsigned short port)
{
RPCSock *master;
int ret;
int run = 1;
GncRPCClist clist;
ENTER ("port=%d", port);
if (!port)
port = RPCEND_PORT;
if ((ret = RpcCreateListener (htons(port), &master)) != 0) {
LEAVE ("listener failed");
return ret;
}
fprintf (stderr, "RPC Server Running...\n");
while (run) {
GncRpcSvc *new = g_malloc (sizeof (*new));
if (!new) {
LEAVE ("g_malloc failed");
return -1;
}
memset (new, 0, sizeof (*new));
new->book = gnc_book_new ();
if (!new->book) {
g_free (new);
LEAVE ("gnc_book_new() failed");
return -2;
}
new->clist = &clist;
/* Setup to listen */
RpcListen (master, 3);
/* Grab the next client */
if ((ret = RpcAccept (master, &(new->sock))) != 0) {
run = 0;
LEAVE ("Accept failed (%d)", ret);
break;
}
/* XXX Authenticate? */
/* Build the RPC Transport */
if ((ret = RpcTransport (new->sock, myClose, (void *)new, &(new->xprt)))
!= 0) {
RpcClose (new->sock);
run = 0;
LEAVE ("Transport failed (%d)", ret);
break;
}
/* Add this client to the clist */
clist.clist = g_list_prepend (clist.clist, new);
/* Register the service */
TXPRT_REG_CALLOUT (new->xprt, GNCRPC_PROG, GNCRPC_VERS, gncrpc_prog_1);
PINFO ("New Client connected: %p", new);
}
return ret;
}

View File

@ -1,37 +0,0 @@
/*
* FILE:
* RpcServer.h
*
* FUNCTION:
* Implements the Gnucash RPC server.
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef RPC_SERVER_H
#define RPC_SERVER_H
typedef struct _gncrpc_svc GncRpcSvc;
int rpc_server_run (unsigned short port);
#endif /* __RPC_SERVER_H */

View File

@ -1,54 +0,0 @@
/*
* FILE:
* RpcServerP.h
*
* FUNCTION:
* Gnucash RPC Server Private Header
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef RPC_SERVERP_H
#define RPC_SERVERP_H
#include "xprt_thrd.h"
#include "RpcServer.h"
#include "RpcSock.h"
#include "gncRpc.h"
#include "gnc-book.h"
typedef struct _gncrpc_clist {
GList *clist;
} GncRPCClist;
struct _gncrpc_svc {
TXPRT * xprt; /* Transport */
RPCSock * sock; /* Socket */
GNCBook * book; /* My Client's Book */
CLIENT * clnt; /* Client's Callback Object */
GncRPCClist * clist; /* Client List */
};
#endif /* __RPC_SERVERP_H */

View File

@ -1,272 +0,0 @@
/*
* FILE:
* RpcSock.c
*
* FUNCTION:
* Implements the RPC Socket connection
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#include <netdb.h>
#include <unistd.h>
#include <sys/socket.h>
#include "xprt_thrd.h"
#include "RpcBackend.h"
#include "RpcSock.h"
struct _rpcend_sock {
int sock; /* socket */
TXPRT * xprt; /* Transport */
void * cb_arg; /* Callback Argument */
void (*close)(void *cb); /* Close callback */
gboolean listener; /* Is this a master listener? */
struct sockaddr_in peer; /* Peer Address */
};
static int
myread (caddr_t sockp, char *buf, int len)
{
RPCSock *sock = (RPCSock *)sockp;
if (len == 0)
return 0;
switch (len = read (sock->sock, buf, len))
{
case 0:
/* premature eof */
/* ECONNRESET, RPC_CANTRECV */
len = -1; /* it's really an error */
break;
case -1:
/* RPC_CANTRECV */
break;
}
return len;
}
static int
mywrite (caddr_t sockp, char *buf, int len)
{
RPCSock *sock = (RPCSock *)sockp;
int i, cnt;
for (cnt = len; cnt > 0; cnt -= i, buf += i)
{
if ((i = write (sock->sock, buf, cnt)) == -1)
{
/* RPC_CANTSEND */
return -1;
}
}
return len;
}
static int
myselect (caddr_t sockp)
{
RPCSock *sock = (RPCSock *)sockp;
struct timeval timeout;
fd_set fds;
timeout.tv_sec = 2;
timeout.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(sock->sock, &fds);
return select (sock->sock+1, &fds, 0, 0, &timeout);
}
static void
myclose (caddr_t sockp)
{
RPCSock *sock = (RPCSock *)sockp;
/* Close callback */
if (sock->close)
(*sock->close)(sock->cb_arg);
close (sock->sock);
g_free (sock);
}
int RpcConnect (char *hostname, unsigned short port, RPCSock **sock)
{
RPCSock *new;
int s;
struct hostent *hp;
struct sockaddr_in sin;
if (hostname == NULL || *hostname == '\0' || port == 0)
return ERR_BACKEND_BAD_URL;
if (sock == NULL)
return ERR_BACKEND_MISC;
if ((hp = gethostbyname (hostname)) == NULL)
return ERR_RPC_HOST_UNK;
sin.sin_family = hp->h_addrtype;
sin.sin_port = port;
memcpy (&sin.sin_addr, hp->h_addr, MIN(sizeof(sin.sin_addr),hp->h_length));
if ((s = socket (sin.sin_family, SOCK_STREAM, 0)) < 0)
return ERR_BACKEND_ALLOC;
if (connect (s, (struct sockaddr *) &sin, sizeof(sin)) != 0)
return ERR_BACKEND_CANT_CONNECT;
new = g_malloc (sizeof (*new));
if (new == NULL) {
close (s);
return ERR_BACKEND_ALLOC;
}
memset (new, 0, sizeof (*new));
new->sock = s;
*sock = new;
return 0;
}
int RpcClose (RPCSock *sock)
{
if (sock == NULL)
return ERR_BACKEND_MISC;
myclose ((caddr_t) sock);
return 0;
}
int RpcTransport (RPCSock *sock, void (*myClose)(void *arg), void *arg,
TXPRT **xprt)
{
TXPRT *x;
if (sock == NULL || xprt == NULL || myClose == NULL || sock->xprt != NULL)
return ERR_BACKEND_MISC;
x = xprt_thrd_create ((caddr_t)sock, myread, mywrite, myclose, myselect,
0, 0);
if (x == NULL)
return ERR_BACKEND_ALLOC;
sock->close = myClose;
sock->cb_arg = arg;
sock->xprt = *xprt = x;
return 0;
}
int RpcCreateListener (unsigned short port, RPCSock **sock)
{
int s;
int on = 1;
struct sockaddr_in sin;
RPCSock *new;
if (!sock)
return ERR_BACKEND_MISC;
/* Create socket */
if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
return ERR_BACKEND_ALLOC;
/* Set socket options */
if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))
< 0) {
close (s);
return ERR_BACKEND_MISC;
}
/* Bind to the address */
sin.sin_family = AF_INET;
sin.sin_port = port;
sin.sin_addr.s_addr = INADDR_ANY;
if (bind (s, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
close (s);
return ERR_RPC_CANT_BIND;
}
/* Build RPCSock */
new = g_malloc (sizeof (*new));
if (new == NULL) {
close (s);
return ERR_BACKEND_ALLOC;
}
memset (new, 0, sizeof (*new));
new->sock = s;
new->listener = TRUE;
*sock = new;
return 0;
}
int RpcListen (RPCSock *sock, int val)
{
if (!sock)
return -1;
if (!sock->listener)
return -2;
return (listen (sock->sock, val));
}
int RpcAccept (RPCSock *master, RPCSock **client)
{
int s;
socklen_t len;
RPCSock *new;
if (!master || !client)
return ERR_BACKEND_MISC;
if (!master->listener)
return ERR_BACKEND_MISC;
new = g_malloc (sizeof (*new));
if (!new)
return ERR_BACKEND_ALLOC;
memset (new, 0, sizeof (*new));
len = sizeof (new->peer);
if ((new->sock = accept (master->sock,
(struct sockaddr *) &(new->peer), &len)) < 0) {
g_free (new);
return ERR_RPC_CANT_ACCEPT;
}
*client = new;
return 0;
}
void * RpcGetData (RPCSock *sock)
{
if (!sock)
return NULL;
return (sock->cb_arg);
}

View File

@ -1,51 +0,0 @@
/*
* FILE:
* RpcSock.h
*
* FUNCTION:
* Implements the RPC Socket connection
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef RPC_SOCK_H
#define RPC_SOCK_H
#include "xprt_thrd.h"
#include "RpcBackend.h"
#define RPCEND_PORT 11207
typedef struct _rpcend_sock RPCSock;
int RpcConnect (char *hostname, unsigned short port, RPCSock **sock);
int RpcClose (RPCSock *sock);
int RpcCreateListener (unsigned short port, RPCSock **sock);
int RpcListen (RPCSock *sock, int val);
int RpcAccept (RPCSock *master, RPCSock **client);
int RpcTransport (RPCSock *sock, void (*myClose)(void *arg), void *cb_arg,
TXPRT **xprt);
void * RpcGetData (RPCSock *sock);
#endif /* __RPC_SOCK_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +0,0 @@
/*
* FILE:
* RpcUtils.h
*
* FUNCTION:
* Implements some utility functions for the RPC (client) backend.
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef RPC_UTILS_H
#define RPC_UTILS_H
#include "gncRpc.h"
#include "Account.h"
#include "RpcBackend.h"
/*
* This number should be increased every time the RPC protocol
* changes. This means every time any of the .x file change, this
* number should be increased.
*/
#define GNCRPC_PROTOCOL_VERSION 1
gnc_kvp_frame *rpcend_build_gnckvp (kvp_frame *frame);
void rpcend_free_gnckvp (gnc_kvp_frame *frame);
kvp_frame * rpcend_parse_gnckvp (gnc_kvp_frame *data);
void rpcend_build_gnctxn (gncTransaction *gnctxn, Transaction *txn);
void rpcend_free_gnctxn (gncTransaction *gnctxn, gboolean freetxn);
void rpcend_build_gncacct (gncAccount *gncacct, Account *acc);
void rpcend_free_gncacct (gncAccount *acc, gboolean freeacct);
gnc_txnlist * rpcend_build_gnctxnlist_list (AccountGroup *ag,
gnc_vers_list *txnlist);
void rpcend_free_gnctxnlist (gnc_txnlist *txnlist);
gnc_acctlist * rpcend_build_gncacctlist_list (AccountGroup *ag,
gnc_vers_list *acctlist);
gnc_acctlist * rpcend_build_gncacctlist (AccountGroup *ag);
void rpcend_free_gncacctlist (gnc_acctlist *acctlist);
gnc_vers_list * rpcend_build_gncacct_verslist (AccountGroup *ag,
gboolean copyguid);
gnc_vers_list * rpcend_build_gnctxn_verslist (AccountGroup *ag,
gboolean copyguid);
gnc_vers_list * rpcend_build_gncverslist_txn (GList *txnlist,
gboolean copyguid);
void rpcend_free_verslist (gnc_vers_list *vlist, gboolean freeguid);
gnc_commoditylist * rpcend_build_gnccommoditylist (gnc_commodity_table *ct,
gboolean copycom);
void rpcend_free_gnccommoditylist (gnc_commoditylist *clist, gboolean freecom);
void rpcend_load_gnccommodity (gnc_commodity_table *ct, gncCommodity *com);
void rpcend_load_commoditylist (gnc_commodity_table *ct,
gnc_commoditylist *clist);
int rpcend_do_add_acct (AccountGroup *ag, gncAccount * acct,
gnc_commodity_table *ct);
int rpcend_do_add_txn (gncTransaction * txn, gnc_commodity_table *ct);
void rpcend_build_gncquery (gncQuery *gq, Query *q);
void rpcend_parse_gncquery (gncQuery *gq, Query *q);
void rpcend_free_gncquery (gncQuery *gq);
void rpcend_free_query (Query *q);
#endif /* __RPC_UTILS_H */

View File

@ -1,418 +0,0 @@
/* @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
#endif
/*
* clnt_thrd.c, Implements a Threaded, TCP/IP based, client side RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* TCP based RPC supports 'batched calls'.
* A sequence of calls may be batched-up in a send buffer. The rpc call
* return immediately to the client even though the call was not necessarily
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
* the rpc timeout value is zero (see clnt.h, rpc).
*
* Clients should NOT casually batch calls that in fact return results; that is,
* the server side should be aware that a call is batched and not produce any
* return message. Batched calls that produce many result messages can
* deadlock (netlock) the client and the server....
*
* Now go hang yourself.
*/
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <rpc/pmap_clnt.h>
#include "xprt_thrd.h"
#include "clnt_thrd.h"
#define MCALL_MSG_SIZE 24
struct ct_data
{
bool_t ct_waitset; /* wait set by clnt_control? */
struct timeval ct_wait;
struct rpc_err ct_error;
char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg header */
u_int ct_mpos; /* length of marshalled header */
u_long ct_prog; /* Program number */
u_long ct_vers; /* Version Number */
TXPRT_WAIT *ct_repl; /* A reply wait object */
TXPRT *ct_xprt; /* Transport Object */
};
static enum clnt_stat clntthrd_call (CLIENT *, u_long, xdrproc_t, caddr_t,
xdrproc_t, caddr_t, struct timeval);
static void clntthrd_abort (void);
static void clntthrd_geterr (CLIENT *, struct rpc_err *);
static bool_t clntthrd_freeres (CLIENT *, xdrproc_t, caddr_t);
static bool_t clntthrd_control (CLIENT *, int, char *);
static void clntthrd_destroy (CLIENT *);
static struct clnt_ops thrd_ops =
{
clntthrd_call,
clntthrd_abort,
clntthrd_geterr,
clntthrd_freeres,
clntthrd_destroy,
clntthrd_control
};
/*
* Create a client handle for a threaded tcp/ip connection.
* transport is the Threaded Transport we wish to attach this client to.
* NB: It is the client's responsibility to open and close the transport
* NB: The rpch->cl_auth is set null authentication. Caller may wish to set
* this to something more useful.
*/
CLIENT *
clntthrd_create (TXPRT *transport, u_long prog, u_long vers)
{
CLIENT *h = NULL;
struct ct_data *ct = NULL;
struct rpc_msg call_msg;
struct timeval now;
XDR xdr;
if (transport == NULL)
return (CLIENT *)NULL;
h = (CLIENT *) malloc (sizeof (*h));
if (h == NULL)
{
(void) fprintf (stderr, "clntthrd_create: out of memory\n");
goto fooy;
}
ct = (struct ct_data *) malloc (sizeof (*ct));
if (ct == NULL)
{
(void) fprintf (stderr, "clntthrd_create: out of memory\n");
goto fooy;
}
memset (ct, 0, sizeof (*ct));
memset (h, 0, sizeof (*h));
/*
* Set up private data structure
*/
ct->ct_repl = xprt_thrd_new_wait ();
if (ct->ct_repl == NULL)
{
(void) fprintf (stderr, "clntthrd_create: out of memory\n");
goto fooy;
}
ct->ct_wait.tv_usec = 0;
ct->ct_waitset = FALSE;
ct->ct_xprt = transport;
/*
* Initialize call message
*/
gettimeofday (&now, NULL);
srand48 (now.tv_sec ^ now.tv_usec);
call_msg.rm_xid = lrand48();
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
ct->ct_prog = call_msg.rm_call.cb_prog = prog;
ct->ct_vers = call_msg.rm_call.cb_vers = vers;
/*
* pre-serialize the static part of the call msg and stash it away
*/
xdrmem_create (&xdr, ct->ct_mcall, MCALL_MSG_SIZE, XDR_ENCODE);
if (!xdr_callhdr (&xdr, &call_msg))
{
goto fooy;
}
ct->ct_mpos = XDR_GETPOS (&xdr);
XDR_DESTROY (&xdr);
/*
* Build the CLIENT structure
*/
h->cl_auth = authnone_create ();
h->cl_ops = &thrd_ops;
h->cl_private = (caddr_t) ct;
return h;
fooy:
/*
* Something goofed, free stuff and barf
*/
if (ct != NULL) {
if (ct->ct_repl != NULL)
xprt_destroy_wait (ct->ct_repl);
free ((caddr_t) ct);
}
if (h != NULL) free ((caddr_t) h);
return ((CLIENT *) NULL);
}
static enum clnt_stat
clntthrd_call (h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
CLIENT *h;
u_long proc;
xdrproc_t xdr_args;
caddr_t args_ptr;
xdrproc_t xdr_results;
caddr_t results_ptr;
struct timeval timeout;
{
struct ct_data *ct = (struct ct_data *) h->cl_private;
XDR *xdrs;
struct rpc_msg reply_msg;
u_long x_id;
u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall); /* yuk */
bool_t shipnow;
int refreshes = 2;
if (!ct->ct_waitset)
{
ct->ct_wait = timeout;
}
shipnow =
(xdr_results == (xdrproc_t) 0 && timeout.tv_sec == 0
&& timeout.tv_usec == 0) ? FALSE : TRUE;
/* Obtain and lock XDR object */
xdrs = TXPRT_GET_XDR (ct->ct_xprt);
call_again:
xdrs->x_op = XDR_ENCODE;
ct->ct_error.re_status = RPC_SUCCESS;
x_id = ntohl (--(*msg_x_id));
if ((!XDR_PUTBYTES (xdrs, ct->ct_mcall, ct->ct_mpos)) ||
(!XDR_PUTLONG (xdrs, (long *) &proc)) ||
(!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
(!(*xdr_args) (xdrs, args_ptr)))
{
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTENCODEARGS;
(void) xdrrec_endofrecord (xdrs, TRUE);
TXPRT_REL_XDR (ct->ct_xprt);
return (ct->ct_error.re_status);
}
if (!xdrrec_endofrecord (xdrs, shipnow)) {
TXPRT_REL_XDR (ct->ct_xprt);
return ct->ct_error.re_status = RPC_CANTSEND;
}
if (!shipnow) {
TXPRT_REL_XDR (ct->ct_xprt);
return RPC_SUCCESS;
}
/*
* Hack to provide rpc-based message passing
*/
if (timeout.tv_sec == 0 && timeout.tv_usec == 0)
{
TXPRT_REL_XDR (ct->ct_xprt);
return ct->ct_error.re_status = RPC_TIMEDOUT;
}
/* Setup reply-state for Transport callback */
ct->ct_repl->tw_x_id = x_id;
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = NULL;
reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
/* Now register the callback and wait for our reply message */
TXPRT_WAIT_REPLY (ct->ct_xprt, &reply_msg, &xdrs, ct->ct_repl, timeout);
/*
* Ok, we're back. That means that our reply has come in. We expect
* that reply_msg and xdrs have been filled in for us, and the XDR
* Object is locked. That means we don't have to look for the response
* on our own, nor lock XDR on our own, so....
*/
/*
* process header
*/
_seterr_reply (&reply_msg, &(ct->ct_error));
if (ct->ct_error.re_status == RPC_SUCCESS)
{
if (!AUTH_VALIDATE (h->cl_auth, &reply_msg.acpted_rply.ar_verf))
{
ct->ct_error.re_status = RPC_AUTHERROR;
ct->ct_error.re_why = AUTH_INVALIDRESP;
}
else if (!(*xdr_results) (xdrs, results_ptr))
{
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTDECODERES;
}
/* free verifier ... */
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
{
xdrs->x_op = XDR_FREE;
(void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf));
}
} /* end successful completion */
else
{
/* maybe our credentials need to be refreshed ... */
if (refreshes-- && AUTH_REFRESH (h->cl_auth))
/* We still have the XDR lock */
goto call_again;
} /* end of unsuccessful completion */
TXPRT_REL_XDR (ct->ct_xprt);
return ct->ct_error.re_status;
}
static void
clntthrd_geterr (h, errp)
CLIENT *h;
struct rpc_err *errp;
{
struct ct_data *ct =
(struct ct_data *) h->cl_private;
*errp = ct->ct_error;
}
static bool_t
clntthrd_freeres (cl, xdr_res, res_ptr)
CLIENT *cl;
xdrproc_t xdr_res;
caddr_t res_ptr;
{
bool_t res;
struct ct_data *ct = (struct ct_data *) cl->cl_private;
XDR *xdrs = TXPRT_GET_XDR (ct->ct_xprt);
xdrs->x_op = XDR_FREE;
res = (*xdr_res) (xdrs, res_ptr);
TXPRT_REL_XDR (ct->ct_xprt);
return res;
}
static void
clntthrd_abort ()
{
}
static bool_t
clntthrd_control (CLIENT *cl, int request, char *info)
{
struct ct_data *ct = (struct ct_data *) cl->cl_private;
switch (request)
{
case CLSET_TIMEOUT:
ct->ct_wait = *(struct timeval *) info;
ct->ct_waitset = TRUE;
break;
case CLGET_TIMEOUT:
*(struct timeval *) info = ct->ct_wait;
break;
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure *.
* This will get the xid of the PREVIOUS call
*/
*(u_long *)info = ntohl (*(u_long *)ct->ct_mcall);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
*(u_long *)ct->ct_mcall = htonl (*(u_long *)info - 1);
/* decrement by 1 as clntthrd_call() increments once */
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(u_long *)info = ntohl (*(u_long *)(ct->ct_mcall +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
*(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
= htonl (*(u_long *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
*(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
/* We don't support these, yet */
case CLSET_FD_CLOSE:
case CLSET_FD_NCLOSE:
case CLGET_SERVER_ADDR:
case CLGET_FD:
return FALSE;
/* The following are only possible with TI-RPC */
case CLGET_RETRY_TIMEOUT:
case CLSET_RETRY_TIMEOUT:
case CLGET_SVC_ADDR:
case CLSET_SVC_ADDR:
case CLSET_PUSH_TIMOD:
case CLSET_POP_TIMOD:
default:
return FALSE;
}
return TRUE;
}
static void
clntthrd_destroy (CLIENT *h)
{
struct ct_data *ct = (struct ct_data *) h->cl_private;
xprt_destroy_wait (ct->ct_repl);
free ((caddr_t) ct);
free ((caddr_t) h);
}

View File

@ -1,16 +0,0 @@
/*
* clnt_thrd.h -- Threaded, Multiplexed, RPC/TCP Client
*
* Written By: Derek Atkins <warlord@MIT.EDU>
*
*/
#ifndef RPC_CLNT_THRD_H
#define RPC_CLNT_THRD_H
#include <rpc/clnt.h>
#include "xprt_thrd.h"
CLIENT *clntthrd_create (TXPRT *transport, u_long prog, u_long vers);
#endif /* RPC_CLNT_THRD_H */

View File

@ -1,79 +0,0 @@
/*
* FILE:
* gncAccount.x
*
* FUNCTION:
* The RPC definition for a Gnucash Account
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_ACCOUNT_X
#define __GNC_ACCOUNT_X
#include "gncKVP.x"
#include "gncGUID.x"
#include "gncCommodity.x"
#ifdef RPC_HDR
%#include "Account.h"
#endif
struct gncAccount {
gncGUID guid;
string name<>;
string code<>;
string desc<>;
gnc_kvp_frame * kvp_data;
enum_t type; /* GNCAccountType */
/* This really sucks -- why do I need to send both a currency and a
* security? Well, the engine seems to want it that way. Ouch.
*/
#ifdef GNCACCT_COMMODITY
gncCommodityPtr commodity;
#else
gncCommodityPtr currency;
gncCommodityPtr security;
#endif
gncGUID * parent;
int vers;
gncNumeric balance;
gncNumeric cleared_balance;
gncNumeric reconciled_balance;
gncNumeric share_balance;
gncNumeric share_cleared_balance;
gncNumeric share_reconciled_balance;
bool core_dirty;
bool do_free;
};
struct gnc_acctlist {
gncAccount * acct;
gnc_acctlist * next;
};
#endif /* __GNC_ACCOUNT_X */

View File

@ -1,60 +0,0 @@
/*
* FILE:
* gncCommodity.x
*
* FUNCTION:
* The RPC definition for a Gnucash Commodity
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_COMMODITY_X
#define __GNC_COMMODITY_X
/* This is an actual commodity entry; unique_name is generated */
struct gncCommodity {
string fullname<>;
string namespace<>;
string mnemonic<>;
string printname<>;
string exchange_code<>;
int fraction;
};
/* List of commodities */
struct gnc_commoditylist {
gncCommodity * commodity;
gnc_commoditylist * next;
};
/* This is sufficient information to find a commodity in the commodity
* table using gnc_commodity_table_lookup(), although while it does
* save on network transfer space, it makes it harder on the sender
* to actually package up an account. So let's keep it here but not
* use it.
*/
struct gncCommodityPtr {
string namespace<>;
string mnemonic<>;
};
#endif /* __GNC_COMMODITY_X */

View File

@ -1,51 +0,0 @@
/*
* FILE:
* gncQuery.x
*
* FUNCTION:
* The RPC definition for a Gnucash Query
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_GUID_X
#define __GNC_GUID_X
typedef opaque gncGUID[16];
struct gnc_guidlist {
gncGUID * guid;
gnc_guidlist * next;
};
struct gnc_vers_list {
gncGUID * guid;
int vers;
gnc_vers_list * next;
};
struct gncTimespec {
int64_t tv_sec;
int tv_nsec;
};
#endif /* __GNC_GUID_X */

View File

@ -1,78 +0,0 @@
/*
* FILE:
* gncKVP.x
*
* FUNCTION:
* The RPC definition for a Gnucash kvp_frame
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_KVP_X
#define __GNC_KVP_X
#include "gncGUID.x"
#ifdef RPC_HDR
%#include "kvp_frame.h"
#endif
struct gncNumeric {
int64_t num;
int64_t denom;
};
struct gnc_kvp_valuelist {
struct gnc_kvp_value * val;
gnc_kvp_valuelist * next;
};
union gnc_kvp_value switch (enum_t type) { /* kvp_value_t */
case KVP_TYPE_GINT64:
int64_t int64;
case KVP_TYPE_DOUBLE:
double dbl;
case KVP_TYPE_NUMERIC:
gncNumeric numeric;
case KVP_TYPE_STRING:
string str<>;
case KVP_TYPE_GUID:
gncGUID guid;
case KVP_TYPE_BINARY:
opaque binary<>;
case KVP_TYPE_GLIST:
gnc_kvp_valuelist * glist;
case KVP_TYPE_FRAME:
struct gnc_kvp_frame * frame;
};
struct gnc_kvp {
string key<>;
gnc_kvp_value * value;
};
struct gnc_kvp_frame {
gnc_kvp * data;
gnc_kvp_frame * next;
};
#endif /* __GNC_KVP_X */

View File

@ -1,35 +0,0 @@
/*
* FILE:
* gncPrice.x
*
* FUNCTION:
* The RPC protocol definition for Gnucash PriceDB
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_PRICE_X
#define __GNC_PRICE_X
#endif /* __GNC_PRICE_X */

View File

@ -1,90 +0,0 @@
module Query {
enum SortBy { STANDARD, DATE, DATEENTERED, DATERECONCILED, NUM,
AMOUNT, MEMO, DESC, RECONCILE, NONE };
enum QueryOp { AND, OR, NAND, NOR, XOR };
enum pdtypet { DATE, AMOUNT, ACCOUNT, STRING, CLEARED, MISC };
enum acctmatcht { ACCT_MATCH_ALL, ACCT_MATCH_ANY, ACCT_MATCH_NONE }
enum amtmatcht { AMT_MATCH_ATLEAST, AMT_MATCH_ATMOST,
AMT_MATCH_EXACTLY } ;
enum amtmatchsgnt { AMT_SGN_MATCH_EITHER, AMT_SGN_MATCH_CREDIT,
AMT_SGN_MATCH_DEBIT } ;
enum clearing { CLEARED_NO, CLEARED_CLEARED, CLEARED_RECONCILED,
CLEARED_FROZEN };
enum strmatching { STRING_MATCH_CASE, STRING_MATCH_REGEXP,
STRING_MATCH_INSENSITIVE };
struct DatePredicateData {
long usestart;
Timespec start;
long useend;
Timespec end;
}
struct AmountPredicateData {
amtmatcht how;
amtmatchsgnt amt_sgn;
double amount;
};
struct AccountPredicateData {
acctmatcht how;
Accounts::AccountList accounts;
// Note that this references a type from
// module "Accounts"
}
struct StringPredicateData {
strmatching behavior; /* what kind of search? */
string matchstring;
// regex_t compiled; // Compilation isn't part of the interface
} StringPredicateData;
struct MiscPredicateData {
long how; /* Shouldn't this use one of the enums? */
long data; /* What is this? */
};
struct ClearedPredicateData {
long how;
};
union PredicateData switch (pdtypet) {
case DATE:
DatePredicateData date;
case AMOUNT:
AmountPredicateData amount;
case ACCOUNT:
AccountPredicateData acct;
case STRING:
StringPredicateData str;
case CLEARED:
ClearedPredicateData cleared;
case MISC:
MiscPredicateData misc;
}
struct QueryTerm {
Predicate p; /* What is this type supposed to be? */
PredicateData data;
long sense;
};
/* Something is wrong with the following; I am somehow not correctly
understanding what the Predicate type is... I'll punt and
pretend that a Query consists of a binary tree of QueryTerm
elements... */
struct Query {
QueryTerm qt;
QueryOp combinethus;
Query subquery;
};
// Locally, there would be the whole host of "Query Construction"
// functions to build up a complex query.
void InvokeQuery (in query q,
out Transactions::TransactionList txns);
/* Note that this references, from the "Transactions" module, the
"TransactionList" typedef, which would reflect a sequence of
transactions... */
};

View File

@ -1,151 +0,0 @@
/*
* FILE:
* gncQuery.x
*
* FUNCTION:
* The RPC definition for a Gnucash Query
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_QUERY_X
#define __GNC_QUERY_X
#include "gncAccount.x"
#include "gncGUID.x"
#ifdef RPC_HDR
%#include "Query.h"
#endif
struct gncDatePredicateData {
enum_t term_type; /* pr_type_t */
int sense;
int usestart;
gncTimespec start;
int useend;
gncTimespec end;
};
struct gncAmountPredicateData {
enum_t term_type; /* pr_type_t */
int sense;
enum_t how; /* amt_match_t */
enum_t amt_sgn; /* amt_match_sgn_t */
double amount;
};
struct gncAccountPredicateData {
enum_t term_type; /* pr_type_t */
int sense;
enum_t how; /* acct_match_t */
/* Leave out Accts; we can recreate on the server side */
gnc_guidlist * acct_guids;
};
struct gncStringPredicateData {
enum_t term_type; /* pr_type_t */
int sense;
int case_sens;
int use_regexp;
string matchstring<>;
/* XXX: How do I transfer a regex_t? */
};
struct gncClearedPredicateData {
enum_t term_type; /* pr_type_t */
int sense;
enum_t how; /* cleared_match_t */
};
struct gncBalancePredicateData {
enum_t term_type; /* pr_type_t */
int sense;
enum_t how; /* balance_match_t */
};
struct gncMiscPredicateData {
enum_t term_type; /* pr_type_t */
int sense;
int how;
int data;
};
union gncPredicateData switch (enum_t type) { /* pd_type_t */
case PD_DATE:
gncDatePredicateData date;
case PD_AMOUNT:
gncAmountPredicateData amount;
case PD_ACCOUNT:
gncAccountPredicateData acct;
case PD_STRING:
gncStringPredicateData str;
case PD_CLEARED:
gncClearedPredicateData cleared;
case PD_BALANCE:
gncBalancePredicateData balance;
case PD_MISC:
gncMiscPredicateData misc;
};
struct gncQueryTerm {
gncPredicateData data;
int * p; /* This 'predicate' is just for compatibility
* with Query.h. We should really check if
* it's non-NULL, because we cannot easily
* transfer a function-pointer!
*/
};
/* A list of QueryTerms */
struct gncQTList {
gncQueryTerm * qt;
gncQTList * next;
};
/* A list of QueryTerm Lists */
struct gncQTOrlist {
gncQTList * andlist;
gncQTOrlist * next;
};
/* See Query.c for the description */
struct gncQuery {
gncQTOrlist * terms;
enum_t primary_sort; /* sort_type_t */
enum_t secondary_sort; /* sort_type_t */
enum_t tertiary_sort; /* sort_type_t */
bool primary_increasing;
bool secondary_increasing;
bool tertiary_increasing;
int max_splits;
/* Results cache */
int changed;
enum_t last_run_type; /* query_run_t */
int * acct_group; /* AccountGroup * */
int * split_list; /* GList * */
int * xtn_list; /* GList * */
};
#endif /* __GNC_QUERY_X */

View File

@ -1,573 +0,0 @@
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#ifndef _GNCRPC_H_RPCGEN
#define _GNCRPC_H_RPCGEN
#include <rpc/rpc.h>
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef char gncGUID[16];
struct gnc_guidlist {
gncGUID *guid;
struct gnc_guidlist *next;
};
typedef struct gnc_guidlist gnc_guidlist;
struct gnc_vers_list {
gncGUID *guid;
int vers;
struct gnc_vers_list *next;
};
typedef struct gnc_vers_list gnc_vers_list;
struct gncTimespec {
int64_t tv_sec;
int tv_nsec;
};
typedef struct gncTimespec gncTimespec;
#include "qof.h"
struct gncNumeric {
int64_t num;
int64_t denom;
};
typedef struct gncNumeric gncNumeric;
struct gnc_kvp_valuelist {
struct gnc_kvp_value *val;
struct gnc_kvp_valuelist *next;
};
typedef struct gnc_kvp_valuelist gnc_kvp_valuelist;
struct gnc_kvp_value {
enum_t type;
union {
int64_t int64;
double dbl;
gncNumeric numeric;
char *str;
gncGUID guid;
struct {
u_int binary_len;
char *binary_val;
} binary;
gnc_kvp_valuelist *glist;
struct gnc_kvp_frame *frame;
} gnc_kvp_value_u;
};
typedef struct gnc_kvp_value gnc_kvp_value;
struct gnc_kvp {
char *key;
gnc_kvp_value *value;
};
typedef struct gnc_kvp gnc_kvp;
struct gnc_kvp_frame {
gnc_kvp *data;
struct gnc_kvp_frame *next;
};
typedef struct gnc_kvp_frame gnc_kvp_frame;
struct gncCommodity {
char *fullname;
char *namespace;
char *mnemonic;
char *printname;
char *exchange_code;
int fraction;
};
typedef struct gncCommodity gncCommodity;
struct gnc_commoditylist {
gncCommodity *commodity;
struct gnc_commoditylist *next;
};
typedef struct gnc_commoditylist gnc_commoditylist;
struct gncCommodityPtr {
char *namespace;
char *mnemonic;
};
typedef struct gncCommodityPtr gncCommodityPtr;
#include "Account.h"
struct gncAccount {
gncGUID guid;
char *name;
char *code;
char *desc;
gnc_kvp_frame *kvp_data;
enum_t type;
gncCommodityPtr currency;
gncCommodityPtr security;
gncGUID *parent;
int vers;
gncNumeric balance;
gncNumeric cleared_balance;
gncNumeric reconciled_balance;
gncNumeric share_balance;
gncNumeric share_cleared_balance;
gncNumeric share_reconciled_balance;
bool_t core_dirty;
bool_t do_free;
};
typedef struct gncAccount gncAccount;
struct gnc_acctlist {
gncAccount *acct;
struct gnc_acctlist *next;
};
typedef struct gnc_acctlist gnc_acctlist;
#include "Query.h"
struct gncDatePredicateData {
enum_t term_type;
int sense;
int usestart;
gncTimespec start;
int useend;
gncTimespec end;
};
typedef struct gncDatePredicateData gncDatePredicateData;
struct gncAmountPredicateData {
enum_t term_type;
int sense;
enum_t how;
enum_t amt_sgn;
double amount;
};
typedef struct gncAmountPredicateData gncAmountPredicateData;
struct gncAccountPredicateData {
enum_t term_type;
int sense;
enum_t how;
gnc_guidlist *acct_guids;
};
typedef struct gncAccountPredicateData gncAccountPredicateData;
struct gncStringPredicateData {
enum_t term_type;
int sense;
int case_sens;
int use_regexp;
char *matchstring;
};
typedef struct gncStringPredicateData gncStringPredicateData;
struct gncClearedPredicateData {
enum_t term_type;
int sense;
enum_t how;
};
typedef struct gncClearedPredicateData gncClearedPredicateData;
struct gncBalancePredicateData {
enum_t term_type;
int sense;
enum_t how;
};
typedef struct gncBalancePredicateData gncBalancePredicateData;
struct gncMiscPredicateData {
enum_t term_type;
int sense;
int how;
int data;
};
typedef struct gncMiscPredicateData gncMiscPredicateData;
struct gncPredicateData {
enum_t type;
union {
gncDatePredicateData date;
gncAmountPredicateData amount;
gncAccountPredicateData acct;
gncStringPredicateData str;
gncClearedPredicateData cleared;
gncBalancePredicateData balance;
gncMiscPredicateData misc;
} gncPredicateData_u;
};
typedef struct gncPredicateData gncPredicateData;
struct gncQueryTerm {
gncPredicateData data;
int *p;
};
typedef struct gncQueryTerm gncQueryTerm;
struct gncQTList {
gncQueryTerm *qt;
struct gncQTList *next;
};
typedef struct gncQTList gncQTList;
struct gncQTOrlist {
gncQTList *andlist;
struct gncQTOrlist *next;
};
typedef struct gncQTOrlist gncQTOrlist;
struct gncQuery {
gncQTOrlist *terms;
enum_t primary_sort;
enum_t secondary_sort;
enum_t tertiary_sort;
bool_t primary_increasing;
bool_t secondary_increasing;
bool_t tertiary_increasing;
int max_splits;
int changed;
enum_t last_run_type;
int *acct_group;
int *split_list;
int *xtn_list;
};
typedef struct gncQuery gncQuery;
struct gncSplit {
gncGUID guid;
gncGUID acct_guid;
gncGUID txn_guid;
char *memo;
char *action;
gnc_kvp_frame *kvp_data;
char reconciled;
gncTimespec date_reconciled;
gncNumeric value;
gncNumeric damount;
};
typedef struct gncSplit gncSplit;
struct gnc_splitlist {
gncSplit *split;
struct gnc_splitlist *next;
};
typedef struct gnc_splitlist gnc_splitlist;
struct gncTransaction {
gncGUID guid;
gncTimespec date_entered;
gncTimespec date_posted;
char *num;
char *desc;
gnc_kvp_frame *kvp_data;
gncCommodityPtr common_currency;
int vers;
gnc_splitlist *splits;
bool_t do_free;
};
typedef struct gncTransaction gncTransaction;
struct gnc_txnlist {
gncTransaction *txn;
struct gnc_txnlist *next;
};
typedef struct gnc_txnlist gnc_txnlist;
typedef char gncrpc_ptr[8];
struct gncrpc_book_begin_args {
gncrpc_ptr book;
gncrpc_ptr backend;
char *book_id;
bool_t ignore_lock;
bool_t create;
};
typedef struct gncrpc_book_begin_args gncrpc_book_begin_args;
struct gncrpc_book_load_ret {
int error;
gnc_commoditylist *commodities;
gnc_acctlist *acctlist;
};
typedef struct gncrpc_book_load_ret gncrpc_book_load_ret;
struct gncrpc_backend_guid {
gncrpc_ptr backend;
gncGUID guid;
};
typedef struct gncrpc_backend_guid gncrpc_backend_guid;
struct gncrpc_backend_txn {
gncrpc_ptr backend;
gncTransaction txn;
};
typedef struct gncrpc_backend_txn gncrpc_backend_txn;
struct gncrpc_commit_acct_args {
gncrpc_ptr backend;
gncAccount acct;
#ifdef GNCACCT_COMMODITY
gncCommodity *commodity;
#else
gncCommodity *currency;
gncCommodity *security;
#endif
};
typedef struct gncrpc_commit_acct_args gncrpc_commit_acct_args;
struct gncrpc_commit_txn_args {
gncrpc_ptr backend;
gncTransaction new;
};
typedef struct gncrpc_commit_txn_args gncrpc_commit_txn_args;
struct gncrpc_sync1_args {
gncrpc_ptr backend;
gnc_commoditylist *commodities;
gnc_vers_list *acctlist;
gnc_vers_list *txnlist;
};
typedef struct gncrpc_sync1_args gncrpc_sync1_args;
struct gncrpc_sync1_ret {
int error;
gnc_vers_list *send_acctlist;
gnc_vers_list *send_txnlist;
gnc_acctlist *acctlist;
gnc_txnlist *txnlist;
gnc_commoditylist *commodities;
};
typedef struct gncrpc_sync1_ret gncrpc_sync1_ret;
struct gncrpc_sync2_args {
gncrpc_ptr backend;
gnc_acctlist *acctlist;
gnc_txnlist *txnlist;
};
typedef struct gncrpc_sync2_args gncrpc_sync2_args;
struct gncrpc_query_args {
gncrpc_ptr backend;
gncGUID *group_parent_guid;
gncQuery *query;
};
typedef struct gncrpc_query_args gncrpc_query_args;
struct gncrpc_query_ret {
int error;
gnc_vers_list *txnlist;
};
typedef struct gncrpc_query_ret gncrpc_query_ret;
struct gncrpc_get_txns_args {
gncrpc_ptr backend;
gnc_vers_list *guids;
};
typedef struct gncrpc_get_txns_args gncrpc_get_txns_args;
struct gncrpc_get_txns_ret {
int error;
gnc_txnlist *txnlist;
};
typedef struct gncrpc_get_txns_ret gncrpc_get_txns_ret;
#define GNCRPC_PROG 729284
#define GNCRPC_VERS 1
#if defined(__STDC__) || defined(__cplusplus)
#define gncrpc_version 0
extern enum clnt_stat gncrpc_version_1(void *, int *, CLIENT *);
extern bool_t gncrpc_version_1_svc(void *, int *, struct svc_req *);
#define gncrpc_book_begin 1
extern enum clnt_stat gncrpc_book_begin_1(gncrpc_book_begin_args *, int *, CLIENT *);
extern bool_t gncrpc_book_begin_1_svc(gncrpc_book_begin_args *, int *, struct svc_req *);
#define gncrpc_book_load 2
extern enum clnt_stat gncrpc_book_load_1(char *, gncrpc_book_load_ret *, CLIENT *);
extern bool_t gncrpc_book_load_1_svc(char *, gncrpc_book_load_ret *, struct svc_req *);
#define gncrpc_book_end 3
extern enum clnt_stat gncrpc_book_end_1(char *, int *, CLIENT *);
extern bool_t gncrpc_book_end_1_svc(char *, int *, struct svc_req *);
#define gncrpc_account_begin_edit 4
extern enum clnt_stat gncrpc_account_begin_edit_1(gncrpc_backend_guid *, int *, CLIENT *);
extern bool_t gncrpc_account_begin_edit_1_svc(gncrpc_backend_guid *, int *, struct svc_req *);
#define gncrpc_account_commit_edit 5
extern enum clnt_stat gncrpc_account_commit_edit_1(gncrpc_commit_acct_args *, int *, CLIENT *);
extern bool_t gncrpc_account_commit_edit_1_svc(gncrpc_commit_acct_args *, int *, struct svc_req *);
#define gncrpc_account_rollback_edit 6
extern enum clnt_stat gncrpc_account_rollback_edit_1(gncrpc_backend_guid *, int *, CLIENT *);
extern bool_t gncrpc_account_rollback_edit_1_svc(gncrpc_backend_guid *, int *, struct svc_req *);
#define gncrpc_txn_begin_edit 7
extern enum clnt_stat gncrpc_txn_begin_edit_1(gncrpc_backend_guid *, int *, CLIENT *);
extern bool_t gncrpc_txn_begin_edit_1_svc(gncrpc_backend_guid *, int *, struct svc_req *);
#define gncrpc_txn_commit_edit 8
extern enum clnt_stat gncrpc_txn_commit_edit_1(gncrpc_commit_txn_args *, int *, CLIENT *);
extern bool_t gncrpc_txn_commit_edit_1_svc(gncrpc_commit_txn_args *, int *, struct svc_req *);
#define gncrpc_txn_rollback_edit 9
extern enum clnt_stat gncrpc_txn_rollback_edit_1(gncrpc_backend_guid *, int *, CLIENT *);
extern bool_t gncrpc_txn_rollback_edit_1_svc(gncrpc_backend_guid *, int *, struct svc_req *);
#define gncrpc_run_query 10
extern enum clnt_stat gncrpc_run_query_1(gncrpc_query_args *, gncrpc_query_ret *, CLIENT *);
extern bool_t gncrpc_run_query_1_svc(gncrpc_query_args *, gncrpc_query_ret *, struct svc_req *);
#define gncrpc_sync1 11
extern enum clnt_stat gncrpc_sync1_1(gncrpc_sync1_args *, gncrpc_sync1_ret *, CLIENT *);
extern bool_t gncrpc_sync1_1_svc(gncrpc_sync1_args *, gncrpc_sync1_ret *, struct svc_req *);
#define gncrpc_sync2 12
extern enum clnt_stat gncrpc_sync2_1(gncrpc_sync2_args *, int *, CLIENT *);
extern bool_t gncrpc_sync2_1_svc(gncrpc_sync2_args *, int *, struct svc_req *);
#define gncrpc_get_txns 13
extern enum clnt_stat gncrpc_get_txns_1(gncrpc_get_txns_args *, gncrpc_get_txns_ret *, CLIENT *);
extern bool_t gncrpc_get_txns_1_svc(gncrpc_get_txns_args *, gncrpc_get_txns_ret *, struct svc_req *);
extern int gncrpc_prog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#else /* K&R C */
#define gncrpc_version 0
extern enum clnt_stat gncrpc_version_1();
extern bool_t gncrpc_version_1_svc();
#define gncrpc_book_begin 1
extern enum clnt_stat gncrpc_book_begin_1();
extern bool_t gncrpc_book_begin_1_svc();
#define gncrpc_book_load 2
extern enum clnt_stat gncrpc_book_load_1();
extern bool_t gncrpc_book_load_1_svc();
#define gncrpc_book_end 3
extern enum clnt_stat gncrpc_book_end_1();
extern bool_t gncrpc_book_end_1_svc();
#define gncrpc_account_begin_edit 4
extern enum clnt_stat gncrpc_account_begin_edit_1();
extern bool_t gncrpc_account_begin_edit_1_svc();
#define gncrpc_account_commit_edit 5
extern enum clnt_stat gncrpc_account_commit_edit_1();
extern bool_t gncrpc_account_commit_edit_1_svc();
#define gncrpc_account_rollback_edit 6
extern enum clnt_stat gncrpc_account_rollback_edit_1();
extern bool_t gncrpc_account_rollback_edit_1_svc();
#define gncrpc_txn_begin_edit 7
extern enum clnt_stat gncrpc_txn_begin_edit_1();
extern bool_t gncrpc_txn_begin_edit_1_svc();
#define gncrpc_txn_commit_edit 8
extern enum clnt_stat gncrpc_txn_commit_edit_1();
extern bool_t gncrpc_txn_commit_edit_1_svc();
#define gncrpc_txn_rollback_edit 9
extern enum clnt_stat gncrpc_txn_rollback_edit_1();
extern bool_t gncrpc_txn_rollback_edit_1_svc();
#define gncrpc_run_query 10
extern enum clnt_stat gncrpc_run_query_1();
extern bool_t gncrpc_run_query_1_svc();
#define gncrpc_sync1 11
extern enum clnt_stat gncrpc_sync1_1();
extern bool_t gncrpc_sync1_1_svc();
#define gncrpc_sync2 12
extern enum clnt_stat gncrpc_sync2_1();
extern bool_t gncrpc_sync2_1_svc();
#define gncrpc_get_txns 13
extern enum clnt_stat gncrpc_get_txns_1();
extern bool_t gncrpc_get_txns_1_svc();
extern int gncrpc_prog_1_freeresult ();
#endif /* K&R C */
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_gncGUID (XDR *, gncGUID);
extern bool_t xdr_gnc_guidlist (XDR *, gnc_guidlist*);
extern bool_t xdr_gnc_vers_list (XDR *, gnc_vers_list*);
extern bool_t xdr_gncTimespec (XDR *, gncTimespec*);
extern bool_t xdr_gncNumeric (XDR *, gncNumeric*);
extern bool_t xdr_gnc_kvp_valuelist (XDR *, gnc_kvp_valuelist*);
extern bool_t xdr_gnc_kvp_value (XDR *, gnc_kvp_value*);
extern bool_t xdr_gnc_kvp (XDR *, gnc_kvp*);
extern bool_t xdr_gnc_kvp_frame (XDR *, gnc_kvp_frame*);
extern bool_t xdr_gncCommodity (XDR *, gncCommodity*);
extern bool_t xdr_gnc_commoditylist (XDR *, gnc_commoditylist*);
extern bool_t xdr_gncCommodityPtr (XDR *, gncCommodityPtr*);
extern bool_t xdr_gncAccount (XDR *, gncAccount*);
extern bool_t xdr_gnc_acctlist (XDR *, gnc_acctlist*);
extern bool_t xdr_gncDatePredicateData (XDR *, gncDatePredicateData*);
extern bool_t xdr_gncAmountPredicateData (XDR *, gncAmountPredicateData*);
extern bool_t xdr_gncAccountPredicateData (XDR *, gncAccountPredicateData*);
extern bool_t xdr_gncStringPredicateData (XDR *, gncStringPredicateData*);
extern bool_t xdr_gncClearedPredicateData (XDR *, gncClearedPredicateData*);
extern bool_t xdr_gncBalancePredicateData (XDR *, gncBalancePredicateData*);
extern bool_t xdr_gncMiscPredicateData (XDR *, gncMiscPredicateData*);
extern bool_t xdr_gncPredicateData (XDR *, gncPredicateData*);
extern bool_t xdr_gncQueryTerm (XDR *, gncQueryTerm*);
extern bool_t xdr_gncQTList (XDR *, gncQTList*);
extern bool_t xdr_gncQTOrlist (XDR *, gncQTOrlist*);
extern bool_t xdr_gncQuery (XDR *, gncQuery*);
extern bool_t xdr_gncSplit (XDR *, gncSplit*);
extern bool_t xdr_gnc_splitlist (XDR *, gnc_splitlist*);
extern bool_t xdr_gncTransaction (XDR *, gncTransaction*);
extern bool_t xdr_gnc_txnlist (XDR *, gnc_txnlist*);
extern bool_t xdr_gncrpc_ptr (XDR *, gncrpc_ptr);
extern bool_t xdr_gncrpc_book_begin_args (XDR *, gncrpc_book_begin_args*);
extern bool_t xdr_gncrpc_book_load_ret (XDR *, gncrpc_book_load_ret*);
extern bool_t xdr_gncrpc_backend_guid (XDR *, gncrpc_backend_guid*);
extern bool_t xdr_gncrpc_backend_txn (XDR *, gncrpc_backend_txn*);
extern bool_t xdr_gncrpc_commit_acct_args (XDR *, gncrpc_commit_acct_args*);
extern bool_t xdr_gncrpc_commit_txn_args (XDR *, gncrpc_commit_txn_args*);
extern bool_t xdr_gncrpc_sync1_args (XDR *, gncrpc_sync1_args*);
extern bool_t xdr_gncrpc_sync1_ret (XDR *, gncrpc_sync1_ret*);
extern bool_t xdr_gncrpc_sync2_args (XDR *, gncrpc_sync2_args*);
extern bool_t xdr_gncrpc_query_args (XDR *, gncrpc_query_args*);
extern bool_t xdr_gncrpc_query_ret (XDR *, gncrpc_query_ret*);
extern bool_t xdr_gncrpc_get_txns_args (XDR *, gncrpc_get_txns_args*);
extern bool_t xdr_gncrpc_get_txns_ret (XDR *, gncrpc_get_txns_ret*);
#else /* K&R C */
extern bool_t xdr_gncGUID ();
extern bool_t xdr_gnc_guidlist ();
extern bool_t xdr_gnc_vers_list ();
extern bool_t xdr_gncTimespec ();
extern bool_t xdr_gncNumeric ();
extern bool_t xdr_gnc_kvp_valuelist ();
extern bool_t xdr_gnc_kvp_value ();
extern bool_t xdr_gnc_kvp ();
extern bool_t xdr_gnc_kvp_frame ();
extern bool_t xdr_gncCommodity ();
extern bool_t xdr_gnc_commoditylist ();
extern bool_t xdr_gncCommodityPtr ();
extern bool_t xdr_gncAccount ();
extern bool_t xdr_gnc_acctlist ();
extern bool_t xdr_gncDatePredicateData ();
extern bool_t xdr_gncAmountPredicateData ();
extern bool_t xdr_gncAccountPredicateData ();
extern bool_t xdr_gncStringPredicateData ();
extern bool_t xdr_gncClearedPredicateData ();
extern bool_t xdr_gncBalancePredicateData ();
extern bool_t xdr_gncMiscPredicateData ();
extern bool_t xdr_gncPredicateData ();
extern bool_t xdr_gncQueryTerm ();
extern bool_t xdr_gncQTList ();
extern bool_t xdr_gncQTOrlist ();
extern bool_t xdr_gncQuery ();
extern bool_t xdr_gncSplit ();
extern bool_t xdr_gnc_splitlist ();
extern bool_t xdr_gncTransaction ();
extern bool_t xdr_gnc_txnlist ();
extern bool_t xdr_gncrpc_ptr ();
extern bool_t xdr_gncrpc_book_begin_args ();
extern bool_t xdr_gncrpc_book_load_ret ();
extern bool_t xdr_gncrpc_backend_guid ();
extern bool_t xdr_gncrpc_backend_txn ();
extern bool_t xdr_gncrpc_commit_acct_args ();
extern bool_t xdr_gncrpc_commit_txn_args ();
extern bool_t xdr_gncrpc_sync1_args ();
extern bool_t xdr_gncrpc_sync1_ret ();
extern bool_t xdr_gncrpc_sync2_args ();
extern bool_t xdr_gncrpc_query_args ();
extern bool_t xdr_gncrpc_query_ret ();
extern bool_t xdr_gncrpc_get_txns_args ();
extern bool_t xdr_gncrpc_get_txns_ret ();
#endif /* K&R C */
#ifdef __cplusplus
}
#endif
#endif /* !_GNCRPC_H_RPCGEN */

View File

@ -1,157 +0,0 @@
/*
* FILE:
* gncRpc.x
*
* FUNCTION:
* The RPC protocol definition for Gnucash
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifdef RPC_XDR
%#ifndef xdr_enum_t
%#define xdr_enum_t xdr_enum
%#endif
#endif
#include "gncQuery.x"
#include "gncAccount.x"
#include "gncTxn.x"
typedef opaque gncrpc_ptr[8];
/***************************************************************/
struct gncrpc_book_begin_args {
gncrpc_ptr book;
gncrpc_ptr backend;
string book_id<>;
bool ignore_lock;
bool create;
};
struct gncrpc_book_load_ret {
int error;
gnc_commoditylist * commodities; /* List of commodities */
gnc_acctlist * acctlist; /* Full Account tree */
};
struct gncrpc_backend_guid {
gncrpc_ptr backend;
gncGUID guid;
};
struct gncrpc_backend_txn {
gncrpc_ptr backend;
gncTransaction txn;
};
struct gncrpc_commit_acct_args {
gncrpc_ptr backend;
gncAccount acct;
#ifdef GNCACCT_COMMODITY
gncCommodity * commodity;
#else
gncCommodity * currency;
gncCommodity * security;
#endif
};
struct gncrpc_commit_txn_args {
gncrpc_ptr backend;
gncTransaction new;
};
struct gncrpc_sync1_args {
gncrpc_ptr backend;
gnc_commoditylist * commodities; /* all commodities */
gnc_vers_list * acctlist; /* list of all account guid+versions */
gnc_vers_list * txnlist; /* list of all txn guid+versions */
};
struct gncrpc_sync1_ret {
int error;
gnc_vers_list * send_acctlist; /* accts to send to server */
gnc_vers_list * send_txnlist; /* txns to send to server */
gnc_acctlist * acctlist; /* new or changed accounts from server */
gnc_txnlist * txnlist; /* new or changed txns from server */
gnc_commoditylist * commodities; /* new commodities from server */
};
struct gncrpc_sync2_args {
gncrpc_ptr backend;
gnc_acctlist * acctlist; /* new or changed accounts in client */
gnc_txnlist * txnlist; /* new or changed txns in client */
};
struct gncrpc_query_args {
gncrpc_ptr backend;
gncGUID * group_parent_guid;
gncQuery * query;
};
struct gncrpc_query_ret {
int error;
gnc_vers_list * txnlist;
};
struct gncrpc_get_txns_args {
gncrpc_ptr backend;
gnc_vers_list * guids;
};
struct gncrpc_get_txns_ret {
int error;
gnc_txnlist * txnlist;
};
/***************************************************************/
program GNCRPC_PROG {
version GNCRPC_VERS {
/*
* int gncrpc_version ()
* send the min/max version and get back a suggested version number
*/
int gncrpc_version () = 0;
/* Backend functions */
int gncrpc_book_begin (gncrpc_book_begin_args args) = 1;
gncrpc_book_load_ret gncrpc_book_load (gncrpc_ptr backend) = 2;
int gncrpc_book_end (gncrpc_ptr backend) = 3;
int gncrpc_account_begin_edit (gncrpc_backend_guid) = 4;
int gncrpc_account_commit_edit (gncrpc_commit_acct_args) = 5;
int gncrpc_account_rollback_edit (gncrpc_backend_guid) = 6;
int gncrpc_txn_begin_edit (gncrpc_backend_guid) = 7;
int gncrpc_txn_commit_edit (gncrpc_commit_txn_args) = 8;
int gncrpc_txn_rollback_edit (gncrpc_backend_guid) = 9;
gncrpc_query_ret gncrpc_run_query (gncrpc_query_args) = 10;
gncrpc_sync1_ret gncrpc_sync1 (gncrpc_sync1_args) = 11;
int gncrpc_sync2 (gncrpc_sync2_args) = 12;
/* Helper functions */
gncrpc_get_txns_ret gncrpc_get_txns (gncrpc_get_txns_args) = 13;
} = 1;
} = 729284;

View File

@ -1,136 +0,0 @@
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include <memory.h> /* for memset */
#include "gncRpc.h"
/* Default timeout can be changed using clnt_control() */
static struct timeval TIMEOUT = { 25, 0 };
enum clnt_stat
gncrpc_version_1(void *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_version,
(xdrproc_t) xdr_void, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_book_begin_1(gncrpc_book_begin_args *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_book_begin,
(xdrproc_t) xdr_gncrpc_book_begin_args, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_book_load_1(char *argp, gncrpc_book_load_ret *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_book_load,
(xdrproc_t) xdr_gncrpc_ptr, (caddr_t) argp,
(xdrproc_t) xdr_gncrpc_book_load_ret, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_book_end_1(char *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_book_end,
(xdrproc_t) xdr_gncrpc_ptr, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_account_begin_edit_1(gncrpc_backend_guid *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_account_begin_edit,
(xdrproc_t) xdr_gncrpc_backend_guid, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_account_commit_edit_1(gncrpc_commit_acct_args *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_account_commit_edit,
(xdrproc_t) xdr_gncrpc_commit_acct_args, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_account_rollback_edit_1(gncrpc_backend_guid *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_account_rollback_edit,
(xdrproc_t) xdr_gncrpc_backend_guid, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_txn_begin_edit_1(gncrpc_backend_guid *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_txn_begin_edit,
(xdrproc_t) xdr_gncrpc_backend_guid, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_txn_commit_edit_1(gncrpc_commit_txn_args *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_txn_commit_edit,
(xdrproc_t) xdr_gncrpc_commit_txn_args, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_txn_rollback_edit_1(gncrpc_backend_guid *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_txn_rollback_edit,
(xdrproc_t) xdr_gncrpc_backend_guid, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_run_query_1(gncrpc_query_args *argp, gncrpc_query_ret *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_run_query,
(xdrproc_t) xdr_gncrpc_query_args, (caddr_t) argp,
(xdrproc_t) xdr_gncrpc_query_ret, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_sync1_1(gncrpc_sync1_args *argp, gncrpc_sync1_ret *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_sync1,
(xdrproc_t) xdr_gncrpc_sync1_args, (caddr_t) argp,
(xdrproc_t) xdr_gncrpc_sync1_ret, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_sync2_1(gncrpc_sync2_args *argp, int *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_sync2,
(xdrproc_t) xdr_gncrpc_sync2_args, (caddr_t) argp,
(xdrproc_t) xdr_int, (caddr_t) clnt_res,
TIMEOUT));
}
enum clnt_stat
gncrpc_get_txns_1(gncrpc_get_txns_args *argp, gncrpc_get_txns_ret *clnt_res, CLIENT *clnt)
{
return (clnt_call(clnt, gncrpc_get_txns,
(xdrproc_t) xdr_gncrpc_get_txns_args, (caddr_t) argp,
(xdrproc_t) xdr_gncrpc_get_txns_ret, (caddr_t) clnt_res,
TIMEOUT));
}

View File

@ -1,585 +0,0 @@
/*
* FILE:
* gncRpc_server.c
*
* FUNCTION:
* Implements the Gnucash RPC server stubs, as generated by rpcgen.
* Note: The function prototypes here must match those created by
* rpcgen -- if any function prototypes in gncRpc.x are changed, this
* file must change as well.
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#include "gncRpc.h"
#include "RpcServerP.h"
#include "RpcUtils.h"
#include "TransactionP.h"
#include "AccountP.h"
#include "qof.h"
static QofLogModule log_module = MOD_BACKEND;
static bool_t gncrpc_get_state (struct svc_req *req, TXPRT **xprt,
GncRpcSvc **cl)
{
TXPRT *x;
bool_t retval;
retval = svc_getargs (req->rq_xprt, (xdrproc_t) xprt_thrd_getargs_hook,
(caddr_t) &x);
if (!retval)
return !retval;
if (xprt)
*xprt = x;
if (cl) {
RPCSock *s = (RPCSock *) TXPRT_GETSOCK (x);
*cl = (GncRpcSvc *) RpcGetData (s);
}
return retval;
}
bool_t
gncrpc_version_1_svc(void *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
*result = GNCRPC_PROTOCOL_VERSION;
return retval;
}
bool_t
gncrpc_book_begin_1_svc(gncrpc_book_begin_args *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
GncRpcSvc *cl;
int res = ERR_BACKEND_SERVER_ERR;
ENTER ("id=\"%s\"", argp->book_id ? argp->book_id : "");
do {
gboolean ret;
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval)
break;
ret = gnc_book_begin (cl->book, argp->book_id, argp->ignore_lock,
argp->create);
PINFO ("ret == %s", (ret == TRUE ? "true" : "false"));
res = gnc_book_pop_error (cl->book);
} while (0);
*result = res;
LEAVE ("done %d", res);
return retval;
}
bool_t
gncrpc_book_load_1_svc(char *argp, gncrpc_book_load_ret *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
GncRpcSvc *cl;
gboolean ret;
ENTER ("ok");
memset (result, 0, sizeof (*result));
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
result->error = ERR_BACKEND_SERVER_ERR;
LEAVE ("bad state");
return retval;
}
ret = gnc_book_load (cl->book);
if (!ret) {
result->error = gnc_book_pop_error (cl->book);
} else {
result->commodities =
rpcend_build_gnccommoditylist (gnc_book_get_commodity_table
(cl->book),
TRUE);
result->acctlist =
rpcend_build_gncacctlist (gnc_book_get_group (cl->book));
}
LEAVE ("res = %d", result->error);
return retval;
}
bool_t
gncrpc_book_end_1_svc(char *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
GncRpcSvc *cl;
ENTER ("ok");
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
*result = ERR_BACKEND_SERVER_ERR;
LEAVE ("bad state");
return retval;
}
gnc_book_end (cl->book);
*result = gnc_book_pop_error (cl->book);
LEAVE ("res = %d", *result);
return retval;
}
bool_t
gncrpc_account_begin_edit_1_svc(gncrpc_backend_guid *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
Account *acc;
GUID *guid = (GUID *) &(argp->guid);
ENTER ("ok");
acc = xaccAccountLookup (guid);
if (!acc) {
*result = -1; /* XXX Deal with new accounts */
LEAVE ("no acc");
return retval;
}
xaccAccountBeginEdit (acc);
*result = 0; /* XXX book_error */
LEAVE ("acct=%p (%s)", acc, acc ? acc->accountName : "");
return retval;
}
bool_t
gncrpc_account_commit_edit_1_svc(gncrpc_commit_acct_args *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
Account *acc;
AccountGroup *ag;
gnc_commodity_table *ct;
GUID *guid = (GUID *) &(argp->acct.guid);
GncRpcSvc *cl;
int added;
ENTER ("vers=%d", argp->acct.vers);
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
*result = ERR_BACKEND_SERVER_ERR;
LEAVE ("bad state");
return retval;
}
ag = gnc_book_get_group (cl->book);
ct = gnc_book_get_commodity_table (cl->book);
/* Load the commodity, in case it changed */
#ifdef GNCACCT_COMMODITY
rpcend_load_gnccommodity (ct, argp->commodity);
#else
rpcend_load_gnccommodity (ct, argp->currency);
rpcend_load_gnccommodity (ct, argp->security);
#endif
/* Now add the account */
added = rpcend_do_add_acct (ag, &(argp->acct), ct);
acc = xaccAccountLookup (guid);
if (!acc) {
*result = gnc_book_pop_error (cl->book);
if (*result == 0)
*result = ERR_RPC_FAILED;
LEAVE ("no acc");
return retval;
}
PINFO ("commiting acct..");
xaccAccountCommitEdit (acc);
LEAVE ("vers=%d, added=%d (%s)", acc->version, added,
acc ? acc->accountName : "");
*result = added < 0 ? 0 : ERR_RPC_NOT_ADDED; /* XXX book error? */
return retval;
}
bool_t
gncrpc_account_rollback_edit_1_svc(gncrpc_backend_guid *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
Account *acc;
GUID *guid = (GUID *) &(argp->guid);
GncRpcSvc *cl;
ENTER ("ok");
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
*result = ERR_BACKEND_SERVER_ERR;
LEAVE ("bad state");
return retval;
}
acc = xaccAccountLookup (guid);
if (!acc) {
*result = ERR_RPC_FAILED;
LEAVE ("no acc");
return retval;
}
/* XXX There is no account rollback. Just commit it without
* any changes */
xaccAccountCommitEdit (acc);
*result = gnc_book_pop_error (cl->book);
LEAVE ("acc=%p (%s)", acc, acc ? acc->accountName : "");
return retval;
}
bool_t
gncrpc_txn_begin_edit_1_svc(gncrpc_backend_guid *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
Transaction *txn;
GUID *guid = (GUID *) &(argp->guid);
ENTER ("ok");
txn = xaccTransLookup (guid);
if (!txn) {
*result = -1; /* XXX: deal with 'new' transaction */
LEAVE ("no txn");
return retval;
}
xaccTransBeginEdit (txn);
*result = 0; /* XXX: book error */
LEAVE ("ok");
return retval;
}
bool_t
gncrpc_txn_commit_edit_1_svc(gncrpc_commit_txn_args *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
Transaction *txn;
gnc_commodity_table *ct;
GUID *guid = (GUID *) &(argp->new.guid);
GncRpcSvc *cl;
int added;
ENTER ("vers=%d", argp->new.vers);
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
*result = ERR_BACKEND_SERVER_ERR;
LEAVE ("bad state");
return retval;
}
ct = gnc_book_get_commodity_table (cl->book);
added = rpcend_do_add_txn (&(argp->new), ct);
txn = xaccTransLookup (guid);
if (!txn) {
*result = ERR_RPC_FAILED;
LEAVE ("no txn!");
return retval;
}
PINFO ("Committing txn..");
xaccTransCommitEdit (txn);
LEAVE ("ok, added=%d, vers=%d", added, txn->version);
*result = added < 0 ? 0 : ERR_RPC_NOT_ADDED; /* XXX book error? */
return retval;
}
bool_t
gncrpc_txn_rollback_edit_1_svc(gncrpc_backend_guid *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
Transaction *txn;
GUID *guid = (GUID *) &(argp->guid);
ENTER ("ok");
txn = xaccTransLookup (guid);
if (!txn) {
*result = ERR_RPC_FAILED;
LEAVE ("no txn");
return retval;
}
xaccTransRollbackEdit (txn);
*result = 0; /* XXX book error? */
LEAVE ("ok");
return retval;
}
bool_t
gncrpc_run_query_1_svc(gncrpc_query_args *argp, gncrpc_query_ret *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
gncQuery thisq;
Query *q = (Query *)&thisq;
GList *txnlist;
GncRpcSvc *cl;
AccountGroup *ag = NULL;
ENTER ("parent=%p, q=%p", argp->group_parent_guid, argp->query);
memset (result, 0, sizeof (*result));
/* Find state */
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
result->error = ERR_BACKEND_SERVER_ERR;
LEAVE ("Bad state");
return retval;
}
/* Figure out the query account group */
if (argp->group_parent_guid) {
Account *acc = xaccAccountLookup ((GUID *)argp->group_parent_guid);
if (acc)
ag = xaccAccountGetChildren (acc);
}
if (!ag)
ag = gnc_book_get_group (cl->book);
/* Setup query */
argp->query->acct_group = (int *)ag;
rpcend_parse_gncquery (argp->query, q);
argp->query->acct_group = NULL;
/* Run Query */
txnlist = xaccQueryGetTransactions (q, QUERY_MATCH_ANY);
/* Setup return value */
result->txnlist = rpcend_build_gncverslist_txn (txnlist, TRUE);
/* Free the txnlist */
g_list_free (txnlist);
/* Reset argument/query structure */
g_list_free ((GList *)(((gncQuery *)q)->split_list));
rpcend_free_query (q);
LEAVE ("query done");
return retval;
}
bool_t
gncrpc_sync1_1_svc(gncrpc_sync1_args *argp, gncrpc_sync1_ret *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
GncRpcSvc *cl;
AccountGroup *ag = NULL;
gnc_commodity_table *ct;
gnc_vers_list *this, *next, *new, **endnew, *old, **endold;
gnc_acctlist *acctlist = NULL;
gnc_txnlist *txnlist = NULL;
ENTER ("ok");
memset (result, 0, sizeof (*result));
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
result->error = ERR_BACKEND_SERVER_ERR;
LEAVE ("bad state");
return retval;
}
ct = gnc_book_get_commodity_table (cl->book);
ag = gnc_book_get_group (cl->book);
rpcend_load_commoditylist (ct, argp->commodities);
/* Just send back the whole commodity list. It wont be too
* big, right???? Otherwise, I can implement an N^2 algorithm
* to figure out which commodities we need to send back...
*/
result->commodities = rpcend_build_gnccommoditylist (ct, TRUE);
/* Walk the acctlist and txnlist; for each one, if the client
* is newer, ask them to send it; if the server is newer, grab
* the new version
*/
new = NULL;
endnew = &new;
old = NULL;
endold = &old;
for (this = argp->acctlist; this; this = next) {
GUID *guid = (GUID *)(this->guid);
Account *acc = xaccAccountLookup (guid);
next = this->next;
if (!acc || acc->version < this->vers) {
/* Tell the client to send this account */
*endnew = this;
endnew = &(this->next);
} else {
/* Maybe send this account? */
if (acc->version < this->vers) {
gnc_acctlist *newaccl = malloc (sizeof (*newaccl));
gncAccount *newacc = malloc (sizeof (*newacc));
rpcend_build_gncacct (newacc, acc);
newaccl->acct = newacc;
newaccl->next = acctlist;
acctlist = newaccl;
}
*endold = this;
endold = &(this->next);
}
} /* for */
/* XXX Should we figure out if there are new accounts and send
* them?
*/
/* Be sure to NULL-terminate these lists! */
*endold = NULL;
*endnew = NULL;
/* Reset the args and set the reply */
result->send_acctlist = new;
result->acctlist = acctlist;
argp->acctlist = old;
/* Do a similar thing for transactions */
new = NULL;
endnew = &new;
old = NULL;
endold = &old;
for (this = argp->txnlist; this; this = next) {
GUID *guid = (GUID *)(this->guid);
Transaction *txn = xaccTransLookup (guid);
next = this->next;
if (!txn || txn->version < this->vers) {
/* Tell the client to send this account */
*endnew = this;
endnew = &(this->next);
} else {
/* Maybe send this txn? */
if (txn->version < this->vers) {
gnc_txnlist *newtxnl = malloc (sizeof (*newtxnl));
gncTransaction *newtxn = malloc (sizeof (*newtxn));
rpcend_build_gnctxn (newtxn, txn);
newtxnl->txn = newtxn;
newtxnl->next = txnlist;
txnlist = newtxnl;
}
*endold = this;
endold = &(this->next);
}
} /* for */
/* Be sure to NULL-terminate these lists! */
*endold = NULL;
*endnew = NULL;
/* Reset the args and set the reply */
result->send_txnlist = new;
result->txnlist = txnlist;
argp->txnlist = old;
LEAVE ("ok");
return retval;
}
bool_t
gncrpc_sync2_1_svc(gncrpc_sync2_args *argp, int *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
GncRpcSvc *cl;
AccountGroup *ag = NULL;
gnc_acctlist *acctlist = NULL;
gnc_txnlist *txnlist = NULL;
gnc_commodity_table *ct;
ENTER ("ok");
*result = 0;
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
*result = ERR_BACKEND_SERVER_ERR;
LEAVE ("bad state");
return retval;
}
ag = gnc_book_get_group (cl->book);
ct = gnc_book_get_commodity_table (cl->book);
for (acctlist = argp->acctlist; acctlist; acctlist = acctlist->next) {
rpcend_do_add_acct (ag, acctlist->acct, ct);
}
for (txnlist = argp->txnlist; txnlist; txnlist = txnlist->next) {
rpcend_do_add_txn (txnlist->txn, ct);
}
gnc_book_save (cl->book);
*result = gnc_book_pop_error (cl->book);
/* XXX: clear results if error! */
LEAVE ("ok");
return retval;
}
bool_t
gncrpc_get_txns_1_svc(gncrpc_get_txns_args *argp, gncrpc_get_txns_ret *result, struct svc_req *rqstp)
{
bool_t retval = TRUE;
GncRpcSvc *cl;
AccountGroup *ag;
ENTER ("get txns");
memset (result, 0, sizeof (*result));
retval = gncrpc_get_state (rqstp, NULL, &cl);
if (!retval) {
result->error = ERR_BACKEND_SERVER_ERR;
LEAVE ("Bad state");
return retval;
}
ag = gnc_book_get_group (cl->book);
result->txnlist = rpcend_build_gnctxnlist_list (ag, argp->guids);
LEAVE ("ok");
return retval;
}
int
gncrpc_prog_1_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
{
xdr_free (xdr_result, result);
/*
* Insert additional freeing code here, if needed
*/
return 1;
}

View File

@ -1,175 +0,0 @@
/*
* This is sample code generated by rpcgen.
* These are only templates and you can use them
* as a guideline for developing your own functions.
*/
#include "gncRpc.h"
bool_t
gncrpc_version_1_svc(void *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_book_begin_1_svc(gncrpc_book_begin_args *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_book_load_1_svc(char *argp, gncrpc_book_load_ret *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_book_end_1_svc(char *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_account_begin_edit_1_svc(gncrpc_backend_guid *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_account_commit_edit_1_svc(gncrpc_commit_acct_args *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_txn_begin_edit_1_svc(gncrpc_backend_guid *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_txn_commit_edit_1_svc(gncrpc_commit_txn_args *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_txn_rollback_edit_1_svc(gncrpc_backend_guid *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_run_query_1_svc(gncrpc_query_args *argp, gncrpc_query_ret *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_sync1_1_svc(gncrpc_sync1_args *argp, gncrpc_sync1_ret *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_sync2_1_svc(gncrpc_sync2_args *argp, int *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
bool_t
gncrpc_get_txns_1_svc(gncrpc_get_txns_args *argp, gncrpc_get_txns_ret *result, struct svc_req *rqstp)
{
bool_t retval;
/*
* insert server code here
*/
return retval;
}
int
gncrpc_prog_1_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
{
xdr_free (xdr_result, result);
/*
* Insert additional freeing code here, if needed
*/
return 1;
}

View File

@ -1,163 +0,0 @@
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "gncRpc.h"
#include <stdio.h>
#include <stdlib.h>
#include <rpc/pmap_clnt.h>
#include <string.h>
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifndef SIG_PF
#define SIG_PF void(*)(int)
#endif
void
gncrpc_prog_1(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
gncrpc_book_begin_args gncrpc_book_begin_1_arg;
gncrpc_ptr gncrpc_book_load_1_arg;
gncrpc_ptr gncrpc_book_end_1_arg;
gncrpc_backend_guid gncrpc_account_begin_edit_1_arg;
gncrpc_commit_acct_args gncrpc_account_commit_edit_1_arg;
gncrpc_backend_guid gncrpc_account_rollback_edit_1_arg;
gncrpc_backend_guid gncrpc_txn_begin_edit_1_arg;
gncrpc_commit_txn_args gncrpc_txn_commit_edit_1_arg;
gncrpc_backend_guid gncrpc_txn_rollback_edit_1_arg;
gncrpc_query_args gncrpc_run_query_1_arg;
gncrpc_sync1_args gncrpc_sync1_1_arg;
gncrpc_sync2_args gncrpc_sync2_1_arg;
gncrpc_get_txns_args gncrpc_get_txns_1_arg;
} argument;
union {
int gncrpc_version_1_res;
int gncrpc_book_begin_1_res;
gncrpc_book_load_ret gncrpc_book_load_1_res;
int gncrpc_book_end_1_res;
int gncrpc_account_begin_edit_1_res;
int gncrpc_account_commit_edit_1_res;
int gncrpc_account_rollback_edit_1_res;
int gncrpc_txn_begin_edit_1_res;
int gncrpc_txn_commit_edit_1_res;
int gncrpc_txn_rollback_edit_1_res;
gncrpc_query_ret gncrpc_run_query_1_res;
gncrpc_sync1_ret gncrpc_sync1_1_res;
int gncrpc_sync2_1_res;
gncrpc_get_txns_ret gncrpc_get_txns_1_res;
} result;
bool_t retval;
xdrproc_t _xdr_argument, _xdr_result;
bool_t (*local)(char *, void *, struct svc_req *);
switch (rqstp->rq_proc) {
case gncrpc_version:
_xdr_argument = (xdrproc_t) xdr_void;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_version_1_svc;
break;
case gncrpc_book_begin:
_xdr_argument = (xdrproc_t) xdr_gncrpc_book_begin_args;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_book_begin_1_svc;
break;
case gncrpc_book_load:
_xdr_argument = (xdrproc_t) xdr_gncrpc_ptr;
_xdr_result = (xdrproc_t) xdr_gncrpc_book_load_ret;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_book_load_1_svc;
break;
case gncrpc_book_end:
_xdr_argument = (xdrproc_t) xdr_gncrpc_ptr;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_book_end_1_svc;
break;
case gncrpc_account_begin_edit:
_xdr_argument = (xdrproc_t) xdr_gncrpc_backend_guid;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_account_begin_edit_1_svc;
break;
case gncrpc_account_commit_edit:
_xdr_argument = (xdrproc_t) xdr_gncrpc_commit_acct_args;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_account_commit_edit_1_svc;
break;
case gncrpc_account_rollback_edit:
_xdr_argument = (xdrproc_t) xdr_gncrpc_backend_guid;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_account_rollback_edit_1_svc;
break;
case gncrpc_txn_begin_edit:
_xdr_argument = (xdrproc_t) xdr_gncrpc_backend_guid;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_txn_begin_edit_1_svc;
break;
case gncrpc_txn_commit_edit:
_xdr_argument = (xdrproc_t) xdr_gncrpc_commit_txn_args;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_txn_commit_edit_1_svc;
break;
case gncrpc_txn_rollback_edit:
_xdr_argument = (xdrproc_t) xdr_gncrpc_backend_guid;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_txn_rollback_edit_1_svc;
break;
case gncrpc_run_query:
_xdr_argument = (xdrproc_t) xdr_gncrpc_query_args;
_xdr_result = (xdrproc_t) xdr_gncrpc_query_ret;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_run_query_1_svc;
break;
case gncrpc_sync1:
_xdr_argument = (xdrproc_t) xdr_gncrpc_sync1_args;
_xdr_result = (xdrproc_t) xdr_gncrpc_sync1_ret;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_sync1_1_svc;
break;
case gncrpc_sync2:
_xdr_argument = (xdrproc_t) xdr_gncrpc_sync2_args;
_xdr_result = (xdrproc_t) xdr_int;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_sync2_1_svc;
break;
case gncrpc_get_txns:
_xdr_argument = (xdrproc_t) xdr_gncrpc_get_txns_args;
_xdr_result = (xdrproc_t) xdr_gncrpc_get_txns_ret;
local = (bool_t (*) (char *, void *, struct svc_req *))gncrpc_get_txns_1_svc;
break;
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp);
if (retval > 0 && !svc_sendreply(transp, _xdr_result, (char *)&result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "unable to free arguments");
exit (1);
}
if (!gncrpc_prog_1_freeresult (transp, _xdr_result, (caddr_t) &result))
fprintf (stderr, "unable to free results");
return;
}

View File

@ -1,58 +0,0 @@
/*
* FILE:
* gncSplit.x
*
* FUNCTION:
* The RPC protocol definition for Gnucash Splits
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_SPLIT_X
#define __GNC_SPLIT_X
#include "gncGUID.x"
#include "gncKVP.x"
struct gncSplit {
gncGUID guid;
/* Different from Gnucash Split */
gncGUID acct_guid; /* Account GUID for this split */
gncGUID txn_guid; /* Parent transaction GUID */
string memo<>;
string action<>;
gnc_kvp_frame * kvp_data;
char reconciled;
gncTimespec date_reconciled;
gncNumeric value;
gncNumeric damount;
};
struct gnc_splitlist {
gncSplit * split;
gnc_splitlist * next;
};
#endif /* __GNC_SPLIT_X */

View File

@ -1,57 +0,0 @@
/*
* FILE:
* gncTxn.x
*
* FUNCTION:
* The RPC protocol definition for Gnucash Transactions
*
* HISTORY:
* Created By: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001, Derek Atkins
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef __GNC_TXN_X
#define __GNC_TXN_X
#include "gncCommodity.x"
#include "gncGUID.x"
#include "gncKVP.x"
#include "gncSplit.x"
struct gncTransaction {
gncGUID guid;
gncTimespec date_entered;
gncTimespec date_posted;
string num<>;
string desc<>;
gnc_kvp_frame* kvp_data;
gncCommodityPtr common_currency;
int vers;
/* Different from here */
gnc_splitlist * splits;
bool do_free;
};
struct gnc_txnlist {
gncTransaction * txn;
gnc_txnlist * next;
};
#endif /* __GNC_TXN_X */

View File

@ -1,82 +0,0 @@
/*********************************************************************
* gncmod-backend-rpc.c
* module definition/initialization for the rpc backend module
*
* Copyright (c) 2001 Linux Developers Group, Inc.
*********************************************************************/
#include <stdio.h>
#include <glib.h>
#include "Backend.h"
#include "RpcBackend.h"
#include "gnc-backend-api.h"
#include "gnc-module.h"
#include "gnc-module-api.h"
/* version of the gnc module system interface we require */
int libgncmod_backend_rpc_LTX_gnc_module_system_interface = 0;
/* module versioning uses libtool semantics. */
int libgncmod_backend_rpc_LTX_gnc_module_current = 0;
int libgncmod_backend_rpc_LTX_gnc_module_revision = 0;
int libgncmod_backend_rpc_LTX_gnc_module_age = 0;
GNCModule engine;
/* forward references */
char *libgncmod_backend_rpc_LTX_gnc_module_path(void);
char *libgncmod_backend_rpc_LTX_gnc_module_description(void);
int libgncmod_backend_rpc_LTX_gnc_module_init(int refcount);
int libgncmod_backend_rpc_LTX_gnc_module_end(int refcount);
Backend * libgncmod_backend_rpc_LTX_gnc_backend_new(void);
char *
libgncmod_backend_rpc_LTX_gnc_module_path(void)
{
return g_strdup("gnucash/backend/postgres");
}
char *
libgncmod_backend_rpc_LTX_gnc_module_description(void)
{
return g_strdup("The Postgres backend for Gnucash");
}
int
libgncmod_backend_rpc_LTX_gnc_module_init(int refcount)
{
engine = gnc_module_load("gnucash/engine", 0);
if(!engine) return FALSE;
return TRUE;
}
int
libgncmod_backend_rpc_LTX_gnc_module_end(int refcount)
{
int unload = TRUE;
if (engine)
unload = gnc_module_unload(engine);
if (refcount == 0)
engine = NULL;
return unload;
}
/****************************************************************
* gnc_backend_new
* this is the init function that must be defined by every dynamically
* loadable backend. the rpc backend doesn't follow backend
* loader naming conventions yet so we wrap its initializer function
* temporarily
****************************************************************/
Backend *
libgncmod_backend_rpc_LTX_gnc_backend_new(void) {
return rpcendNew();
}

View File

@ -1,219 +0,0 @@
/* @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
#endif
/*
* svc_thrd.c, Server side for Threaded TCP/IP based RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <errno.h>
#include <stdlib.h>
#include "xprt_thrd.h"
#include "svc_thrd.h"
#ifdef DEBUG_RPC
#define dfprintf(a) fprintf a
#else
#define dfprintf(a)
#endif
#ifdef USE_IN_LIBIO
# include <libio/iolibio.h>
# define fputs(s, f) _IO_fputs (s, f)
#endif
/*
* Ops vector for TCP/IP based rpc service handle
*/
static bool_t svcthrd_recv (SVCXPRT *, struct rpc_msg *);
static enum xprt_stat svcthrd_stat (SVCXPRT *);
static bool_t svcthrd_getargs (SVCXPRT *, xdrproc_t, caddr_t);
static bool_t svcthrd_reply (SVCXPRT *, struct rpc_msg *);
static bool_t svcthrd_freeargs (SVCXPRT *, xdrproc_t, caddr_t);
static void svcthrd_destroy (SVCXPRT *);
static const struct xp_ops svcthrd_op =
{
svcthrd_recv,
svcthrd_stat,
svcthrd_getargs,
svcthrd_reply,
svcthrd_freeargs,
svcthrd_destroy
};
struct tcp_conn
{ /* kept in xprt->xp_p1 */
u_long x_id;
TXPRT *xprt;
char verf_body[MAX_AUTH_BYTES];
};
/*
* Usage:
* xprt = svcthrd_create(transport);
*
* Creates and returns a (rpc) tcp based transporter.
* This routine returns a NULL if a problem occurred.
*
* NOTE: This assumes that a lock is held on the XDR Object whenever
* the methods herein are called. A word to the wise.... (The tranport
* object will hold this lock when it calls the dispatch routine for a call)
*/
SVCXPRT *
svcthrd_create (TXPRT *transport)
{
SVCXPRT *xprt;
struct tcp_conn *cd;
xprt = (SVCXPRT *) malloc (sizeof (SVCXPRT));
if (xprt == (SVCXPRT *) NULL)
{
(void) fputs ("svcthrd_create: out of memory\n", stderr);
goto done;
}
cd = (struct tcp_conn *) malloc (sizeof (struct tcp_conn));
if (cd == (struct tcp_conn *) NULL)
{
(void) fputs ("svcthrd_create: out of memory\n", stderr);
free ((char *) xprt);
xprt = (SVCXPRT *) NULL;
goto done;
}
memset (xprt, 0, sizeof (*xprt));
memset (cd, 0, sizeof (*cd));
cd->xprt = transport;
xprt->xp_p2 = NULL;
xprt->xp_p1 = (caddr_t) cd;
xprt->xp_verf.oa_base = cd->verf_body;
xprt->xp_addrlen = 0;
xprt->xp_ops = &svcthrd_op; /* truly deals with calls */
xprt->xp_port = 0; /* this is a connection, not a rendezvouser */
xprt->xp_sock = -1;
done:
return xprt;
}
static enum xprt_stat
svcthrd_stat (SVCXPRT *xprt)
{
return XPRT_IDLE;
}
static bool_t
svcthrd_recv (SVCXPRT *xprt, struct rpc_msg *msg)
{
struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1);
dfprintf ((stderr, "svcthrd_recv: set xid: %lx\n", msg->rm_xid));
cd->x_id = msg->rm_xid;
return TRUE;
}
/*
* NB: This method assumes that readlock is held, and it will release
* the locks on exit.
*
* This implies that the "caller" must already have the lock, and
* must only call this function once. NOTE that calling with
* xprt_thrd_getargs_hook will NOT touch the XDR object.
*/
static bool_t
svcthrd_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
{
struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1);
XDR *xdr;
bool_t res;
if (xdr_args == (xdrproc_t) xprt_thrd_getargs_hook) {
if (args_ptr != NULL)
*((TXPRT **) args_ptr) = cd->xprt;
return TRUE;
}
xdr = TXPRT_GET_XDR (cd->xprt);
xdr->x_op = XDR_DECODE;
res = ((*xdr_args) (xdr, args_ptr));
TXPRT_REL_XDR (cd->xprt);
return res;
}
static bool_t
svcthrd_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
{
struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1);
XDR *xdrs = TXPRT_GET_XDR (cd->xprt);
bool_t res;
xdrs->x_op = XDR_FREE;
res = ((*xdr_args) (xdrs, args_ptr));
TXPRT_REL_XDR (cd->xprt);
return res;
}
static bool_t
svcthrd_reply (SVCXPRT *xprt, struct rpc_msg *msg)
{
struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1);
XDR *xdrs = TXPRT_GET_XDR (cd->xprt);
bool_t stat;
dfprintf ((stderr, "svcthrd_reply: xid=%lx (msg says %lx)\n", cd->x_id,
msg->rm_xid));
xdrs->x_op = XDR_ENCODE;
msg->rm_xid = cd->x_id;
stat = xdr_replymsg (xdrs, msg);
(void) xdrrec_endofrecord (xdrs, TRUE);
TXPRT_REL_XDR (cd->xprt);
return stat;
}
static void
svcthrd_destroy (SVCXPRT *xprt)
{
struct tcp_conn *cd = (struct tcp_conn *) xprt->xp_p1;
free ((caddr_t) cd);
free ((caddr_t) xprt);
}

View File

@ -1,16 +0,0 @@
/*
* svc_thrd.h -- Threaded, Multiplexed, RPC/TCP Service
*
* Written By: Derek Atkins <warlord@MIT.EDU>
*
*/
#ifndef RPC_SVC_THRD_H
#define RPC_SVC_THRD_H
#include <rpc/svc.h>
#include "xprt_thrd.h"
extern SVCXPRT *svcthrd_create (TXPRT *transport);
#endif /* RPC_SVC_THRD_H */

View File

@ -1,886 +0,0 @@
/*
* Threaded TCP Transport scheme for RPC; allow a client and a service
* to share a single (TCP) stream. A single reader/writer thread
* exists to handle to I/O. Writers obtain a write-lock before
* writing to the stream, and 'readers' setup a callback with the I/O
* thread which wakes them up when a particular request (or reply) is
* received.
*
* Created by: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include "xprt_thrd.h"
#include "clnt_thrd.h"
#include "svc_thrd.h"
#ifdef DEBUG_RPC
#define dfprintf(a) fprintf a
#else
#define dfprintf(a)
#endif
#define RQCRED_SIZE 400 /* this size is excessive */
/* Internal Service Request */
struct my_svc_req {
char cred[2 * MAX_AUTH_BYTES + RQCRED_SIZE];
struct svc_req r;
struct rpc_msg m;
void (*dispatch) (struct svc_req *r, SVCXPRT *x);
TXPRT * xprt;
};
/* Transport Wait Object private storage */
struct tw_priv {
pthread_cond_t cond;
struct rpc_msg *repl;
TXPRT_WAIT *next;
};
/* Dispatch service */
struct xt_svc {
u_long prog;
u_long vers;
void (*dispatch) (struct svc_req *r, SVCXPRT *x);
struct xt_svc *next;
};
/*
* A stream object private storage
*/
struct xt_priv {
pthread_mutex_t xdrlock;
pthread_mutex_t waitlock;
pthread_mutex_t readlock;
bool_t readlock_is_locked;
pthread_t readlock_by;
int svccnt;
pthread_mutex_t svccntlock;
pthread_attr_t pattr;
int sock;
struct rpc_err err;
XDR xdr;
SVCXPRT *svc;
struct xt_svc *callout;
TXPRT_WAIT *waitlist;
/* For select loop */
pthread_t select_thread;
bool_t stop;
caddr_t selectarg;
int (*select)(caddr_t arg);
void (*close)(caddr_t arg);
};
static int readtcp (caddr_t, char *, int);
static int writetcp (caddr_t, char *, int);
static void closetcp (caddr_t);
static int selecttcp (caddr_t);
static void xprt_thrd_run (TXPRT *xprt);
static SVCXPRT *xprt_get_svcxprt (TXPRT *xprt);
static struct xt_svc *svc_find (struct xt_priv *xtp, u_long prog, u_long vers,
bool_t *found, u_long *low, u_long *high);
/* threadsafe Waitlist handling */
static TXPRT_WAIT *find_wait (struct xt_priv *xtp, u_long x_id);
static void add_wait (struct xt_priv *xtp, TXPRT_WAIT *wait);
static void rem_wait (struct xt_priv *xtp, TXPRT_WAIT *wait);
/* We need to re-implement some of the low-level RPC functions */
static bool_t read_reply (XDR *xdrs, struct rpc_msg *rmsg);
static bool_t read_call (XDR *xdrs, struct rpc_msg *cmsg);
/* Ops vector for Threaded Transport */
static CLIENT * xprt_thrd_new_client (TXPRT *xprt, u_long proc, u_long vers);
static XDR * xprt_thrd_get_xdr (TXPRT *xprt);
static void xprt_thrd_rel_xdr (TXPRT *xprt);
static void xprt_thrd_wait_rep (TXPRT *xprt, struct rpc_msg *reply_msg,
XDR **xdrs, TXPRT_WAIT *wait,
struct timeval timeout);
static bool_t xprt_thrd_reg_call (TXPRT *xprt, u_long prog, u_long vers,
void (*dispatch) (struct svc_req *,
SVCXPRT *));
static caddr_t xprt_thrd_getsock (TXPRT *xprt);
static void xprt_thrd_destroy (TXPRT *xprt);
static void xprt_thrd_readlock (TXPRT *xprt);
static bool_t xprt_thrd_doread (TXPRT *xprt);
static const struct txprt_ops xprtthrd_ops =
{
xprt_thrd_new_client,
xprt_thrd_reg_call,
xprt_thrd_getsock,
xprt_thrd_destroy,
xprt_thrd_readlock,
xprt_thrd_doread,
xprt_thrd_get_xdr,
xprt_thrd_rel_xdr,
xprt_thrd_wait_rep
};
/*
* Create a baseline threaded transport
*/
TXPRT *
xprt_thrd_create (caddr_t sock,
int (*read)(caddr_t, char *, int),
int (*write)(caddr_t, char *, int),
void (*close)(caddr_t),
int (*select)(caddr_t),
u_int sendsz, u_int recvsz)
{
TXPRT *xprt;
struct xt_priv *xtp;
if ((read == NULL && write != NULL) ||
(read != NULL && write == NULL))
return NULL;
/* If read/write are supplied, must supply select and close */
if (read != NULL &&
(select == NULL || close == NULL))
return NULL;
xprt = (TXPRT *) malloc (sizeof (*xprt));
if (xprt == NULL) {
fprintf (stderr, ("xprt_thrd_create: out of memory\n"));
goto done;
}
xtp = (struct xt_priv *) malloc (sizeof (*xtp));
if (xtp == NULL) {
fprintf (stderr, ("xprt_thrd__create: out of memory\n"));
free ((char *) xprt);
xprt = (TXPRT *) NULL;
goto done;
}
memset (xprt, 0, sizeof (*xprt));
memset (xtp, 0, sizeof (*xtp));
/* Initialized Private context */
pthread_mutex_init (&(xtp->xdrlock), NULL);
pthread_mutex_init (&(xtp->waitlock), NULL);
pthread_mutex_init (&(xtp->readlock), NULL);
pthread_mutex_init (&(xtp->svccntlock), NULL);
pthread_attr_init (&(xtp->pattr));
pthread_attr_setdetachstate (&(xtp->pattr), PTHREAD_CREATE_DETACHED);
if (read == NULL) {
xtp->sock = (int) sock;
read = readtcp;
write = writetcp;
close = closetcp;
select = selecttcp;
sock = (caddr_t) xtp;
}
xdrrec_create (&(xtp->xdr), sendsz, recvsz, sock, read, write);
xtp->close = close;
xtp->select = select;
xtp->selectarg = sock;
/* Setup Transport Object */
xprt->txp_private = (caddr_t) xtp;
xprt->txp_ops = &xprtthrd_ops;
/* Start it running */
xprt_thrd_run (xprt);
done:
return xprt;
}
static CLIENT *
xprt_thrd_new_client (TXPRT *xprt, u_long proc, u_long vers)
{
return clntthrd_create (xprt, proc, vers);
}
static caddr_t
xprt_thrd_getsock (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
return (xtp->selectarg);
}
static XDR *
xprt_thrd_get_xdr (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
pthread_mutex_lock (&(xtp->xdrlock));
return &(xtp->xdr);
}
static void
xprt_thrd_readlock (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
pthread_mutex_lock (&(xtp->readlock));
xtp->readlock_is_locked = TRUE;
xtp->readlock_by = pthread_self ();
}
static void
unlock_readlock (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
xtp->readlock_is_locked = FALSE;
pthread_mutex_unlock (&(xtp->readlock));
}
static void
xprt_thrd_unlock_xdr (struct xt_priv *xtp)
{
pthread_mutex_unlock (&(xtp->xdrlock));
}
static void
xprt_thrd_rel_xdr (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
/* Release the read lock if we're decoding */
if (xtp->xdr.x_op == XDR_DECODE && xtp->readlock_is_locked) {
unlock_readlock (xprt);
}
/* Then release the XDR lock */
xprt_thrd_unlock_xdr (xtp);
}
static void
xprt_thrd_wait_rep (TXPRT *xprt, struct rpc_msg *reply_msg,
XDR **xdrs, TXPRT_WAIT *wait, struct timeval timeout)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
struct tw_priv *twp = (struct tw_priv *)wait->tw_priv;
/* Add wait to waitlist */
twp->repl = reply_msg;
add_wait (xtp, wait);
dfprintf ((stderr, "xprt_thrd_wait_rep: waiting for xid %lx\n", wait->tw_x_id));
/* wait for reply */
pthread_cond_wait (&twp->cond, &xtp->xdrlock);
/* Ok, we're awake, and we should have xdrlock held now */
/* Remove the wait from the waitlist */
rem_wait (xtp, wait);
/* And fill in the rest.. */
*xdrs = &(xtp->xdr);
(*xdrs)->x_op = XDR_DECODE;
return;
}
static bool_t
xprt_thrd_reg_call (TXPRT *xprt, u_long prog, u_long vers,
void (*dispatch) (struct svc_req *,
SVCXPRT *))
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
struct xt_svc *new;
if ((new = svc_find (xtp, prog, vers, NULL, NULL, NULL)) != NULL) {
/* re-registering???? Can't do that. */
return FALSE;
}
new = (struct xt_svc *) malloc (sizeof (*new));
if (new == NULL)
return FALSE;
new->prog = prog;
new->vers = vers;
new->dispatch = dispatch;
new->next = xtp->callout;
xtp->callout = new;
return TRUE;
}
static void
xprt_thrd_destroy (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
struct xt_svc *t, *s;
TXPRT_WAIT *wait, *tempwait;
/*
* First, wait for the select thread to exit. If we're in the
* select thread (which can happen if the close() callback destroys
* the transport), then just continue -- we know we'll exit when
* control is returned.
*/
xtp->stop = TRUE;
if (xtp->select)
pthread_join (xtp->select_thread, NULL);
/* Clear out registered callouts */
for (s = xtp->callout; s != NULL; s = t) {
t = s->next;
free (s);
}
/* Wakeup waiting threads */
if (xtp->waitlist != NULL) {
/* Obtain the locks */
xprt_thrd_readlock (xprt);
xprt_thrd_get_xdr (xprt);
while ((wait = xtp->waitlist) != NULL) {
struct tw_priv *twp = (struct tw_priv *)wait->tw_priv;
XDR *xdr;
pthread_cond_signal (&twp->cond);
xprt_thrd_unlock_xdr (xtp);
/* We don't have to do anything here; we'll block waiting for readlock */
xprt_thrd_readlock (xprt);
xprt_thrd_get_xdr (xprt);
}
/*
* At this point we should have the locks held and all threads
* should be dead. So let's clear the locks and go home.
*/
xtp->xdr.x_op = XDR_DECODE;
xprt_thrd_rel_xdr (xprt);
}
/* Make sure all service calls have returned */
while (xtp->svccnt > 0);
/* Then clear my memory */
pthread_mutex_destroy (&(xtp->xdrlock));
pthread_mutex_destroy (&(xtp->waitlock));
pthread_mutex_destroy (&(xtp->readlock));
pthread_mutex_destroy (&(xtp->svccntlock));
pthread_attr_destroy (&(xtp->pattr));
XDR_DESTROY (&(xtp->xdr));
if (xtp->svc) svc_destroy(xtp->svc);
free (xtp);
free (xprt);
}
static void
xprt_thrd_destroy_wait (TXPRT_WAIT *wait)
{
struct tw_priv *twp = (struct tw_priv *)wait->tw_priv;
pthread_cond_destroy (&twp->cond);
free (twp);
free (wait);
}
TXPRT_WAIT *
xprt_thrd_new_wait (void)
{
TXPRT_WAIT *wait;
struct tw_priv *twp;
wait = (TXPRT_WAIT *)malloc (sizeof (*wait));
if (wait != NULL) {
twp = (struct tw_priv *) malloc (sizeof (*twp));
if (twp == NULL) {
free (wait);
return NULL;
}
memset (wait, 0, sizeof (*wait));
pthread_cond_init (&twp->cond, NULL);
twp->next = NULL;
wait->tw_priv = (caddr_t) twp;
wait->tw_destroy = xprt_thrd_destroy_wait;
}
return wait;
}
static SVCXPRT *
xprt_get_svcxprt (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
if (xtp->svc == NULL) {
xtp->svc = svcthrd_create (xprt);
}
return xtp->svc;
}
/*
* Interface between xdr serializer and tcp connection.
* Behaves like the system calls, read & write, but keeps some error state
* around for the rpc level.
*/
static int
readtcp (char *ptr, char *buf, int len)
{
struct xt_priv *xt = (struct xt_priv *)ptr;
struct pollfd fd;
int milliseconds = 30000; /* XXX */
/* (ct->ct_wait.tv_sec * 1000) + (ct->ct_wait.tv_usec / 1000); */
if (len == 0)
return 0;
fd.fd = xt->sock;
fd.events = POLLIN;
while (TRUE)
{
switch (poll(&fd, 1, milliseconds))
{
case 0:
xt->err.re_status = RPC_TIMEDOUT;
return -1;
case -1:
if (errno == EINTR)
continue;
xt->err.re_status = RPC_CANTRECV;
xt->err.re_errno = errno;
return -1;
}
break;
}
switch (len = read (xt->sock, buf, len))
{
case 0:
/* premature eof */
xt->err.re_errno = ECONNRESET;
xt->err.re_status = RPC_CANTRECV;
len = -1; /* it's really an error */
break;
case -1:
xt->err.re_errno = errno;
xt->err.re_status = RPC_CANTRECV;
break;
}
return len;
}
static int
writetcp (caddr_t ptr, char *buf, int len)
{
int i, cnt;
struct xt_priv *xt = (struct xt_priv*)ptr;
for (cnt = len; cnt > 0; cnt -= i, buf += i)
{
if ((i = write (xt->sock, buf, cnt)) == -1)
{
xt->err.re_errno = errno;
xt->err.re_status = RPC_CANTSEND;
return -1;
}
}
return len;
}
static void
closetcp (caddr_t sock)
{
/* Do we close or not? */
}
static int
selecttcp (caddr_t sockp)
{
TXPRT *xprt = (TXPRT *)sockp;
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
int sock = xtp->sock;
struct timeval timeout;
fd_set fds;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(sock, &fds);
return select (sock+1, &fds, 0, 0, &timeout);
}
static struct xt_svc *
svc_find (struct xt_priv *xtp, u_long prog, u_long vers,
bool_t *found, u_long *low, u_long *high)
{
struct xt_svc *s = xtp->callout;
while (s != NULL) {
if (s->prog == prog) {
if (s->vers == vers) {
goto done;
}
if (found) *found = TRUE;
if (low && high) {
if (s->vers < *low)
*low = s->vers;
if (s->vers > *high)
*high = s->vers;
}
} /* s->prog != prog */
s = s->next;
}
done:
return s;
}
static TXPRT_WAIT *
find_wait (struct xt_priv *xtp, u_long x_id)
{
TXPRT_WAIT *wait;
struct tw_priv *twp;
pthread_mutex_lock (&xtp->waitlock);
wait = xtp->waitlist;
while (wait != NULL) {
if (wait->tw_x_id == x_id)
break;
twp = (struct tw_priv *)wait->tw_priv;
wait = twp->next;
}
pthread_mutex_unlock (&xtp->waitlock);
return wait;
}
static void
add_wait (struct xt_priv *xtp, TXPRT_WAIT *wait)
{
struct tw_priv *twp = (struct tw_priv *)wait->tw_priv;
pthread_mutex_lock (&xtp->waitlock);
twp->next = xtp->waitlist;
xtp->waitlist = wait;
pthread_mutex_unlock (&xtp->waitlock);
}
static void
rem_wait (struct xt_priv *xtp, TXPRT_WAIT *wait)
{
TXPRT_WAIT **oldwait;
pthread_mutex_lock (&xtp->waitlock);
oldwait = &(xtp->waitlist);
while (*oldwait != NULL) {
struct tw_priv *twp = (struct tw_priv *)(*oldwait)->tw_priv;
if (*oldwait == wait) {
*oldwait = twp->next;
break;
}
oldwait = &(twp->next);
}
pthread_mutex_unlock (&xtp->waitlock);
return;
}
bool_t
xprt_thrd_getargs_hook (XDR *x, void *v)
{
return FALSE;
}
static bool_t
read_call (XDR *xdrs, struct rpc_msg *cmsg)
{
if (
xdr_u_long (xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
(cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
xdr_u_long (xdrs, &(cmsg->rm_call.cb_prog)) &&
xdr_u_long (xdrs, &(cmsg->rm_call.cb_vers)) &&
xdr_u_long (xdrs, &(cmsg->rm_call.cb_proc)) &&
xdr_opaque_auth (xdrs, &(cmsg->rm_call.cb_cred)))
return xdr_opaque_auth (xdrs, &(cmsg->rm_call.cb_verf));
return FALSE;
}
/* declarations from the SunRPC library */
extern bool_t xdr_accepted_reply (XDR*, void*);
extern bool_t xdr_rejected_reply (XDR*, void*);
static const struct xdr_discrim reply_dscrm[3] =
{
{(int) MSG_ACCEPTED, (xdrproc_t) xdr_accepted_reply},
{(int) MSG_DENIED, (xdrproc_t) xdr_rejected_reply},
{__dontcare__, NULL_xdrproc_t}};
static bool_t
read_reply (XDR *xdrs, struct rpc_msg *rmsg)
{
return xdr_union (xdrs, (enum_t *) & (rmsg->rm_reply.rp_stat),
(caddr_t) & (rmsg->rm_reply.ru), reply_dscrm,
NULL_xdrproc_t);
}
static void
svc_up (struct xt_priv *xtp)
{
pthread_mutex_lock (&(xtp->svccntlock));
xtp->svccnt++;
pthread_mutex_unlock (&(xtp->svccntlock));
}
static void
svc_down (struct xt_priv *xtp)
{
pthread_mutex_lock (&(xtp->svccntlock));
xtp->svccnt--;
pthread_mutex_unlock (&(xtp->svccntlock));
}
static void *
do_callsvc (void *rqst)
{
struct my_svc_req *mr = (struct my_svc_req *) rqst;
struct xt_priv *xtp = (struct xt_priv *)mr->xprt->txp_private;
/* Let the transport know we exist */
svc_up (xtp);
/* Usurp the readlock */
xtp->readlock_by = pthread_self ();
dfprintf ((stderr, "do_callsvc: xid=%lx\n", mr->m.rm_xid));
/* Call the dispatch */
(*(mr->dispatch))(&(mr->r), mr->r.rq_xprt);
dfprintf ((stderr, "do_callsvc return: xid=%lx\n", mr->m.rm_xid));
/* Now figure out if we need to unlock the readlock */
if (xtp->readlock_is_locked && pthread_equal (xtp->readlock_by,
pthread_self ()))
unlock_readlock (mr->xprt);
/* Clean up and exit */
free (mr);
svc_down (xtp);
return NULL;
}
/*
* The Magic reader. When this function is called we KNOW we have
* input but we don't know to whom the message is intended. It may be
* either a request or a response; if it is a request, we need to call
* out to the service. If it is a response, we need to wakeup the
* calling thread.
*
* NB: Assumes readlock is already held.
* NB: Assumes xdrlock is NOT held.
* Will release lock(s) as necessary on return
*/
static bool_t
xprt_thrd_doread (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
struct rpc_msg msg;
XDR *xdr = xprt_thrd_get_xdr (xprt); /* Grab and Lock XDR! */
xdr->x_op = XDR_DECODE;
/* First, we need to make sure we're at the beginning of the record */
if (!xdrrec_skiprecord (xdr)) {
xprt_thrd_rel_xdr (xprt);
dfprintf ((stderr, "xprt_thrd_doread: skiprecord failed\n"));
return FALSE;
}
if (xdr_u_long (xdr, &(msg.rm_xid)) &&
xdr_enum (xdr, (enum_t *) &(msg.rm_direction))) {
/* Ok, we've got our x_id and direction... */
dfprintf ((stderr, "xprt_thrd_doread: %s for %lx\n",
(msg.rm_direction == CALL ? "call" :
(msg.rm_direction == REPLY ? "reply" : "(unk)")),
msg.rm_xid));
if (msg.rm_direction == CALL) {
struct my_svc_req *mr = (struct my_svc_req *) malloc (sizeof (*mr));
if (mr == NULL) {
xprt_thrd_rel_xdr (xprt);
fprintf (stderr, "xprt_thrd_doread: malloc failed\n");
return FALSE;
}
memset (mr, 0, sizeof (*mr));
mr->xprt = xprt;
mr->m.rm_xid = msg.rm_xid;
mr->m.rm_direction = msg.rm_direction;
mr->m.rm_call.cb_cred.oa_base = mr->cred;
mr->m.rm_call.cb_verf.oa_base = &(mr->cred[MAX_AUTH_BYTES]);
mr->r.rq_clntcred = &(mr->cred[2 * MAX_AUTH_BYTES]);
if (read_call (xdr, &(mr->m))) {
struct xt_svc *s;
enum auth_stat why;
bool_t found = FALSE;
u_long low = 0, high = 0;
mr->r.rq_prog = mr->m.rm_call.cb_prog;
mr->r.rq_vers = mr->m.rm_call.cb_vers;
mr->r.rq_proc = mr->m.rm_call.cb_proc;
mr->r.rq_cred = mr->m.rm_call.cb_cred;
mr->r.rq_xprt = xprt_get_svcxprt (xprt);
/* Setup for reply */
SVC_RECV (mr->r.rq_xprt, &(mr->m));
if ((why = _authenticate (&(mr->r), &(mr->m))) != AUTH_OK)
{
xprt_thrd_rel_xdr (xprt);
svcerr_auth (mr->r.rq_xprt, why);
goto call_done;
}
/* now match message with a registered service */
s = svc_find (xtp, mr->r.rq_prog, mr->r.rq_vers, &found, &low, &high);
if (s != NULL) {
pthread_t thr;
mr->dispatch = s->dispatch;
xprt_thrd_unlock_xdr (xtp);
dfprintf ((stderr, "xprt_thrd_doread: calling proc for xid %lx\n",
msg.rm_xid));
pthread_create (&thr, &(xtp->pattr), do_callsvc, mr);
mr = NULL;
goto call_done;
} else {
/* Or unlock XDR for to respond in error */
xprt_thrd_rel_xdr (xprt);
}
/*
* if we got here, the program or version
* is not served ...
*/
/* First we clear the locks */
if (found)
svcerr_progvers (mr->r.rq_xprt, low, high);
else
svcerr_noprog (mr->r.rq_xprt);
/* Fall through to ... */
call_done:
/* If we're here, then we had a "successful" call */
if (mr != NULL)
free (mr);
return TRUE;
} /* !read_call() */
if (mr != NULL)
free (mr);
dfprintf ((stderr, "xprt_thrd_doread: read_call failed, %lx\n",
msg.rm_xid));
} else if (msg.rm_direction == REPLY) {
/* Find the requestor thread.. */
TXPRT_WAIT *wait = find_wait(xtp, msg.rm_xid);
if (wait != NULL) {
struct tw_priv *twp = (struct tw_priv *) wait->tw_priv;
twp->repl->rm_xid = msg.rm_xid;
twp->repl->rm_direction = msg.rm_direction;
if (read_reply (xdr, twp->repl)) {
pthread_cond_signal (&twp->cond);
/* Now unlock the lock to let the other thread pick it up.
Note, keep the readlock locked! */
xprt_thrd_unlock_xdr (xtp);
return TRUE;
}
/* If we got here, then the reply didn't read correctly */
dfprintf ((stderr, "Reply didn't read correctly\n"));
}
/* If we got here, then either the reply didn't read or there is
no matching xid */
dfprintf ((stderr, "bad reply or no matching xid, %lx\n", msg.rm_xid));
}
/*
* If we got here, either the direction is bogus or the message
* didn't parse correctly
*/
dfprintf ((stderr, "bad message or bad direction\n"));
}
/* If we got here, then we've got a bad message */
xprt_thrd_rel_xdr (xprt);
dfprintf ((stderr, "xprt_thrd_doread: bad message\n"));
return FALSE;
}
static void *
do_select_loop (void *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)((TXPRT *)xprt)->txp_private;
int (*select)(caddr_t) = xtp->select;
caddr_t arg = xtp->selectarg;
/* Get the readlock */
xprt_thrd_readlock (xprt);
while (1) {
if (xtp->stop) {
unlock_readlock (xprt);
return NULL;
}
/* now see if there is anything to read */
switch ((*select)(arg)) {
case -1:
/* error */
if (errno == EINTR)
break;
perror ("xprt_thrd: xprt_do_select_loop: select failed");
unlock_readlock (xprt);
return NULL;
case 0:
/* timeout */
continue;
default:
/* Go read the data */
if (!xprt_thrd_doread (xprt)) {
/* We Died */
xtp->stop = 1;
if (xtp->close)
xtp->close (xtp->selectarg);
return NULL;
}
/* Then wait until the reading is done */
xprt_thrd_readlock (xprt);
} /* select */
} /* while */
}
static void
xprt_thrd_run (TXPRT *xprt)
{
struct xt_priv *xtp = (struct xt_priv *)xprt->txp_private;
xtp->stop = FALSE;
/* start thread */
pthread_create (&(xtp->select_thread), NULL, do_select_loop, xprt);
}

View File

@ -1,208 +0,0 @@
/*
* xprt_thrd.h
*
* Threaded TCP Transport scheme for RPC; allow a client and a service
* to share a single (TCP) stream. A single reader/writer thread
* exists to handle to I/O. Writers obtain a write-lock before
* writing to the stream, and 'readers' setup a callback with the I/O
* thread which wakes them up when a particular request (or reply) is
* received.
*
* Created by: Derek Atkins <warlord@MIT.EDU>
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program 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 program 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
#ifndef RPC_XPRT_THRD_H
#define RPC_XPRT_THRD_H
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/clnt.h>
#include <rpc/svc.h>
#include <rpc/rpc_msg.h>
typedef struct TXPRT_WAIT TXPRT_WAIT;
typedef struct TXPRT TXPRT;
struct TXPRT {
const struct txprt_ops {
/*
* PUBLIC interfaces
*/
CLIENT * (*txp_new_clnt) (TXPRT *xprt, u_long prog, u_long vers);
/* build and return a new CLIENT object on this transport */
bool_t (*txp_reg_call) (TXPRT *xprt, u_long prog, u_long vers,
void (*dispatch) (struct svc_req *,
SVCXPRT *));
/* register a callout to a service/dispatch */
caddr_t (*txp_get_sock) (TXPRT *xprt);
/* Return the socket pointer for a transport */
void (*txp_destroy) (TXPRT *xprt);
/* destroy a threaded transport (does NOT destroy CLIENTs nor does
it call close() */
/*
* Semi-Private interfaces
* (for use in writing your own select loop)
*/
void (*txp_readlock) (TXPRT *xptr);
/* Obtain the read lock on the underlying transport */
bool_t (*txp_doread) (TXPRT *xptr);
/* When the read-lock is held and data exists on this transport, read it */
/*
* PRIVATE interfaces
*/
XDR * (*txp_get_xdr) (TXPRT *xprt);
/* get and lock the XDR object (blocks until lock can be obtained) */
void (*txp_rel_xdr) (TXPRT *xprt);
/* release/unlock the XDR object */
void (*txp_wait_rep) (TXPRT *xprt, struct rpc_msg *reply_msg,
XDR **xdrs, TXPRT_WAIT *wait,
struct timeval timeout);
/* wait for a reply to the call, return with reply_msg filled
* and xdrs filled and locked */
} *txp_ops;
caddr_t txp_private; /* Private Stuff */
};
/*
* operations on a Threaded Transport handle:
*
* TXPRT *xprt
* u_long prog, vers
* void (*)(struct svc_req *, SVCSPRT *) disp
*/
/*
* PUBLIC Interfaces
*/
#define TXPRT_NEW_CLIENT(xprt,prog,vers) \
(*(xprt)->txp_ops->txp_new_clnt)((xprt),(prog),(vers))
#define txprt_new_client(xprt,prog,vers) \
(*(xprt)->txp_ops->txp_new_clnt)((xprt),(prog),(vers))
#define TXPRT_REG_CALLOUT(xprt,prog,vers,disp) \
(*(xprt)->txp_ops->txp_reg_call)((xprt),(prog),(vers),(disp))
#define txprt_reg_callout(xprt,prog,vers,disp) \
(*(xprt)->txp_ops->txp_reg_call)((xprt),(prog),(vers),(disp))
#define TXPRT_DESTROY(xprt) (*(xprt)->txp_ops->txp_destroy)(xprt)
#define txprt_destroy(xprt) (*(xprt)->txp_ops->txp_destroy)(xprt)
#define TXPRT_GETSOCK(xprt) (*(xprt)->txp_ops->txp_get_sock)(xprt)
#define txprt_getsock(xprt) (*(xprt)->txp_ops->txp_get_sock)(xprt)
/*
* Semi-Private interfaces
* (for use in writing your own select loop)
*
* NOTE: you must lock readlock and then call doread with the lock held;
* doread will unlock the readlock when it is done.
*/
#define TXPRT_READLOCK(xprt) (*(xprt)->txp_ops->txp_readlock)(xprt)
#define txprt_readlock(xprt) (*(xprt)->txp_ops->txp_readlock)(xprt)
#define TXPRT_DOREAD(xprt) (*(xprt)->txp_ops->txp_doread)(xprt)
#define txprt_doread(xprt) (*(xprt)->txp_ops->txp_doread)(xprt)
/*
* Transport Creation/Destruction
*/
extern TXPRT * xprt_thrd_create (caddr_t sock,
int (*read)(caddr_t, char *, int),
int (*write)(caddr_t, char *, int),
void (*close)(caddr_t),
int (*select)(caddr_t),
u_int sendsz, u_int recvsz);
/*
* This is an xdrproc_t function that, when passed into a threaded
* SVCXPRT will obtain the TXPRT * from the service. It should be
* used by service routines if they want to obtain the TXPRT * to
* e.g. build a CLIENT for a callback from a request. It should be
* used like this:
*
* SVCXPRT *svc
* TXPRT *xprt
* bool_t res
*
* res = svc_getargs(svc, (xdrproc_t) xprt_thrd_getargs_hook,
* (caddr_t) &xprt);
*
* If res == TRUE, then xprt is a valid pointer. If res == FALSE,
* then svc is not a threaded transport service (and xprt is invalid)
*/
extern bool_t xprt_thrd_getargs_hook (XDR *, void *);
/*
* PRIVATE Interfaces
*/
struct TXPRT_WAIT {
u_long tw_x_id;
void (*tw_destroy)(TXPRT_WAIT *);
caddr_t tw_priv;
};
/*
* operations on a Threaded Transport handle:
*
* TXPRT *xprt
* XDR **xdrp
* struct rpc_msg *rmsg
* TXPRT_WAIT *wait (with tw_x_id filled in with the request ID)
*/
/* Returns and locks XDR */
#define TXPRT_GET_XDR(xprt) (*(xprt)->txp_ops->txp_get_xdr)(xprt)
#define txprt_get_xdr(xprt) (*(xprt)->txp_ops->txp_get_xdr)(xprt)
/* Unlocks XDR (and potentially the ReadLock if x_op == XDR_DECODE */
#define TXPRT_REL_XDR(xprt) (*(xprt)->txp_ops->txp_rel_xdr)(xprt)
#define txprt_rel_xdr(xprt) (*(xprt)->txp_ops->txp_rel_xdr)(xprt)
/* Wait for a reply -- blocks until we get a response for wait->tw_x_id */
#define TXPRT_WAIT_REPLY(xprt,rmsg,xdrp,wait,time) \
(*(xprt)->txp_ops->txp_wait_rep)((xprt),(rmsg),(xdrp),(wait),(time))
#define txprt_wait_reply(xprt,rmsg,xdrp,wait,time) \
(*(xprt)->txp_ops->txp_wait_rep)((xprt),(rmsg),(xdrp),(wait),(time))
/* create a wait object (for use in the client) */
extern TXPRT_WAIT * xprt_thrd_new_wait (void);
/* Destroy a wait object */
#define XPRT_DESTROY_WAIT(wait) (*(wait)->tw_destroy)(wait)
#define xprt_destroy_wait(wait) (*(wait)->tw_destroy)(wait)
#endif /* RPC_XPRT_THRD_H */

View File

@ -190,39 +190,3 @@ qof_session_export (QofSession *tmp_session,
return TRUE;
}
void
gnc_run_rpc_server (void)
{
const char * dll_err;
void * dll_handle;
int (*rpc_run)(short);
int ret;
/* open and resolve all symbols now (we don't want mystery
* failure later) */
#ifndef RTLD_NOW
# ifdef RTLD_LAZY
# define RTLD_NOW RTLD_LAZY
# endif
#endif
dll_handle = dlopen ("libgnc_rpc.so", RTLD_NOW);
if (! dll_handle)
{
dll_err = dlerror();
PWARN (" can't load library: %s\n", dll_err ? dll_err : "");
return;
}
rpc_run = dlsym (dll_handle, "rpc_server_run");
dll_err = dlerror();
if (dll_err)
{
dll_err = dlerror();
PWARN (" can't find symbol: %s\n", dll_err ? dll_err : "");
return;
}
ret = (*rpc_run)(0);
/* XXX How do we force an exit? */
}

View File

@ -250,7 +250,6 @@ qof_session_export (QofSession *tmp_session,
QofSession *real_session,
QofPercentageFunc percentage_func);
void gnc_run_rpc_server(void);
#endif
/** @} */

View File

@ -292,8 +292,7 @@ xaccResolveURL (const char * pathfrag)
if (!g_ascii_strncasecmp (pathfrag, "http://", 7) ||
!g_ascii_strncasecmp (pathfrag, "https://", 8) ||
!g_ascii_strncasecmp (pathfrag, "postgres://", 11) ||
!g_ascii_strncasecmp (pathfrag, "rpc://", 6))
!g_ascii_strncasecmp (pathfrag, "postgres://", 11))
{
return g_strdup(pathfrag);
}

View File

@ -240,13 +240,6 @@
;; (gw:enum-add-value! we "ERR_SQL_MISSING_DATA" 'sql-missing-data)
;; (gw:enum-add-value! we "ERR_RPC_HOST_UNK" 'rpc_host_unk)
;; (gw:enum-add-value! we "ERR_RPC_CANT_BIND" 'rpc_cant_bind)
;; (gw:enum-add-value! we "ERR_RPC_CANT_ACCEPT" 'rpc_cant_accept)
;; (gw:enum-add-value! we "ERR_RPC_NO_CONNECTION" 'rpc_no_connection)
;; (gw:enum-add-value! we "ERR_RPC_BAD_VERSION" 'rpc_bad_version)
;; (gw:enum-add-value! we "ERR_RPC_FAILED" 'rpc_failed)
;; (gw:enum-add-value! we "ERR_RPC_NOT_ADDED" 'rpc_not_added)
#t)
;
@ -2415,14 +2408,6 @@ of having a parent transaction with which one is working...")
'((<gnc:numeric> arg))
"Convert gnc_numeric to a printable string")
(gw:wrap-function
ws
'gnc:run-rpc-server
'<gw:void>
"gnc_run_rpc_server"
'()
"Run the RPC Server")
;; gnc-date.h
(gw:wrap-function