mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
6079e3e674
commit
bb7f8e681e
17
ChangeLog
17
ChangeLog
@ -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>
|
2005-11-22 Christian Stimming <stimming@tuhh.de>
|
||||||
|
|
||||||
* po/nb.po: Updated Norwegian (bokmaal) translation by Tor Harald
|
* po/nb.po: Updated Norwegian (bokmaal) translation by Tor Harald
|
||||||
|
50
configure.in
50
configure.in
@ -388,7 +388,7 @@ dnl *************************************
|
|||||||
dnl QOF
|
dnl QOF
|
||||||
dnl *************************************
|
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
|
QOF_REQUIRED=0.6.0
|
||||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
||||||
if test pkg-config = no; then
|
if test pkg-config = no; then
|
||||||
@ -580,7 +580,7 @@ AC_ARG_ENABLE( profile,
|
|||||||
LDFLAGS="${LDFLAGS} -pg")
|
LDFLAGS="${LDFLAGS} -pg")
|
||||||
|
|
||||||
AC_ARG_ENABLE( ref-counts-dumps,
|
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,1,Enable reference count dumps),
|
||||||
AC_DEFINE(DEBUG_REFERENCE_COUNTING,0,Enable reference count dumps) )
|
AC_DEFINE(DEBUG_REFERENCE_COUNTING,0,Enable reference count dumps) )
|
||||||
|
|
||||||
@ -674,21 +674,7 @@ AC_SUBST(SQL_DIR)
|
|||||||
|
|
||||||
|
|
||||||
### --------------------------------------------------------------------------
|
### --------------------------------------------------------------------------
|
||||||
### RPC
|
### RPC has been removed in gnucash 1.9.0
|
||||||
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)
|
|
||||||
|
|
||||||
### --------------------------------------------------------------------------
|
### --------------------------------------------------------------------------
|
||||||
### OFX
|
### OFX
|
||||||
@ -828,7 +814,7 @@ AC_SUBST(HBCI_DIR)
|
|||||||
### i18n
|
### i18n
|
||||||
|
|
||||||
AC_ARG_WITH( locale-dir,
|
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="$with_locale_dir",
|
||||||
LOCALE_DIR="\${prefix}/share/locale")
|
LOCALE_DIR="\${prefix}/share/locale")
|
||||||
|
|
||||||
@ -847,7 +833,7 @@ AC_ARG_ENABLE( locale-specific-tax,
|
|||||||
|
|
||||||
# Used to initialize doc-path.
|
# Used to initialize doc-path.
|
||||||
AC_ARG_WITH( help-prefix,
|
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="$with_help_prefix",
|
||||||
GNC_HELPDIR="\${datadir}")
|
GNC_HELPDIR="\${datadir}")
|
||||||
|
|
||||||
@ -891,7 +877,7 @@ AM_CONDITIONAL(GNC_CTAGS_FILE, test x${GNC_CTAGS_FILE} = xtags)
|
|||||||
|
|
||||||
# Check for perl, force version 5
|
# Check for perl, force version 5
|
||||||
AC_ARG_WITH(perl,
|
AC_ARG_WITH(perl,
|
||||||
[ --with-perl=FILE which perl executable to use ],
|
[ --with-perl=FILE which perl executable to use ],
|
||||||
PERL="${with_perl}")
|
PERL="${with_perl}")
|
||||||
|
|
||||||
# If the user didn't specify a perl, then go fetch.
|
# 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"}'`
|
PERLINCL=`$PERL -MConfig -e 'print $Config{"archlibexp"}'`
|
||||||
AC_ARG_WITH( perl-includes,
|
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" )
|
PERLINCL="$with_perl_includes" )
|
||||||
AC_SUBST(PERLINCL)
|
AC_SUBST(PERLINCL)
|
||||||
|
|
||||||
@ -929,10 +915,10 @@ AC_SUBST(PERLINCL)
|
|||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
AC_DEFUN([BB_ENABLE_DOXYGEN],
|
AC_DEFUN([BB_ENABLE_DOXYGEN],
|
||||||
[
|
[
|
||||||
AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (auto)])
|
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(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(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(latex-docs, [ --enable-latex-docs enable LaTeX documentation generation with doxygen (no)], [], [ enable_latex_docs=no])
|
||||||
if test "x$enable_doxygen" = xno; then
|
if test "x$enable_doxygen" = xno; then
|
||||||
enable_doc=no
|
enable_doc=no
|
||||||
else
|
else
|
||||||
@ -1081,7 +1067,7 @@ esac
|
|||||||
### ----------------------------------------------------------------------
|
### ----------------------------------------------------------------------
|
||||||
### XIM
|
### XIM
|
||||||
AC_ARG_ENABLE(xim,
|
AC_ARG_ENABLE(xim,
|
||||||
[ --enable-xim support XIM [default=yes]],
|
[ --enable-xim support XIM [default=yes]],
|
||||||
, enable_xim="yes")
|
, enable_xim="yes")
|
||||||
|
|
||||||
if test "x$enable_xim" = "xyes"; then
|
if test "x$enable_xim" = "xyes"; then
|
||||||
@ -1296,14 +1282,12 @@ AC_CONFIG_FILES(po/Makefile.in
|
|||||||
src/app-utils/Makefile
|
src/app-utils/Makefile
|
||||||
src/app-utils/test/Makefile
|
src/app-utils/test/Makefile
|
||||||
src/backend/Makefile
|
src/backend/Makefile
|
||||||
src/backend/net/Makefile
|
|
||||||
src/backend/file/Makefile
|
src/backend/file/Makefile
|
||||||
src/backend/file/test/Makefile
|
src/backend/file/test/Makefile
|
||||||
src/backend/file/test/test-files/Makefile
|
src/backend/file/test/test-files/Makefile
|
||||||
src/backend/file/test/test-files/xml2/Makefile
|
src/backend/file/test/test-files/xml2/Makefile
|
||||||
src/backend/postgres/Makefile
|
src/backend/postgres/Makefile
|
||||||
src/backend/postgres/test/Makefile
|
src/backend/postgres/test/Makefile
|
||||||
src/backend/rpc/Makefile
|
|
||||||
src/bin/Makefile
|
src/bin/Makefile
|
||||||
src/bin/overrides/Makefile
|
src/bin/overrides/Makefile
|
||||||
src/bin/test/Makefile
|
src/bin/test/Makefile
|
||||||
@ -1409,16 +1393,6 @@ AC_CONFIG_FILES(po/Makefile.in
|
|||||||
)
|
)
|
||||||
AC_OUTPUT
|
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([
|
AC_MSG_RESULT([
|
||||||
Options detected/selected
|
Options detected/selected
|
||||||
-------------------------
|
-------------------------
|
||||||
|
@ -47,7 +47,6 @@ src/backend/file/sixtp-dom-parsers.c
|
|||||||
src/backend/file/sixtp-stack.c
|
src/backend/file/sixtp-stack.c
|
||||||
src/backend/file/sixtp-to-dom-parser.c
|
src/backend/file/sixtp-to-dom-parser.c
|
||||||
src/backend/file/sixtp-utils.c
|
src/backend/file/sixtp-utils.c
|
||||||
src/backend/net/NetIO.c
|
|
||||||
src/backend/postgres/account.c
|
src/backend/postgres/account.c
|
||||||
src/backend/postgres/book.c
|
src/backend/postgres/book.c
|
||||||
src/backend/postgres/builder.c
|
src/backend/postgres/builder.c
|
||||||
@ -63,18 +62,6 @@ src/backend/postgres/putil.c
|
|||||||
src/backend/postgres/txn.c
|
src/backend/postgres/txn.c
|
||||||
src/backend/postgres/txnmass.c
|
src/backend/postgres/txnmass.c
|
||||||
src/backend/postgres/upgrade.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/businessmod-core.c
|
||||||
src/business/business-core/file/gnc-address-xml-v2.c
|
src/business/business-core/file/gnc-address-xml-v2.c
|
||||||
src/business/business-core/file/gnc-bill-term-xml-v2.c
|
src/business/business-core/file/gnc-bill-term-xml-v2.c
|
||||||
|
@ -24,7 +24,6 @@ engine The engine module, without any backends
|
|||||||
|
|
||||||
backend/file Binary and XML (v1 and v2) backends
|
backend/file Binary and XML (v1 and v2) backends
|
||||||
backend/postgres Postgres backend
|
backend/postgres Postgres backend
|
||||||
backend/rpc RPC backend
|
|
||||||
|
|
||||||
register/ledger-core The xacc SplitLedger and MultiLedger parts formerly
|
register/ledger-core The xacc SplitLedger and MultiLedger parts formerly
|
||||||
in src/
|
in src/
|
||||||
@ -57,3 +56,6 @@ gnome-utils Extensions and utilities for using Gnome/Gtk
|
|||||||
network-utils Utils for network communication.
|
network-utils Utils for network communication.
|
||||||
|
|
||||||
tax/us US tax information
|
tax/us US tax information
|
||||||
|
|
||||||
|
(RPC was removed in v.1.9.0, subversion release: 12018)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
SUBDIRS = file ${SQL_DIR} ${RPC_DIR}
|
SUBDIRS = file ${SQL_DIR} ${RPC_DIR}
|
||||||
DIST_SUBDIRS = file net postgres rpc
|
DIST_SUBDIRS = file postgres
|
||||||
|
|
||||||
noinst_HEADERS = gnc-backend-api.h
|
noinst_HEADERS = gnc-backend-api.h
|
||||||
|
@ -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
|
|
@ -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 ======================== */
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
@ -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 */
|
|
@ -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;
|
|
||||||
}
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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);
|
|
||||||
}
|
|
@ -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
@ -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 */
|
|
@ -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);
|
|
||||||
}
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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... */
|
|
||||||
};
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
|
@ -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));
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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();
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -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 */
|
|
@ -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);
|
|
||||||
}
|
|
@ -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 */
|
|
@ -190,39 +190,3 @@ qof_session_export (QofSession *tmp_session,
|
|||||||
return TRUE;
|
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? */
|
|
||||||
}
|
|
||||||
|
@ -250,7 +250,6 @@ qof_session_export (QofSession *tmp_session,
|
|||||||
QofSession *real_session,
|
QofSession *real_session,
|
||||||
QofPercentageFunc percentage_func);
|
QofPercentageFunc percentage_func);
|
||||||
|
|
||||||
void gnc_run_rpc_server(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -292,8 +292,7 @@ xaccResolveURL (const char * pathfrag)
|
|||||||
|
|
||||||
if (!g_ascii_strncasecmp (pathfrag, "http://", 7) ||
|
if (!g_ascii_strncasecmp (pathfrag, "http://", 7) ||
|
||||||
!g_ascii_strncasecmp (pathfrag, "https://", 8) ||
|
!g_ascii_strncasecmp (pathfrag, "https://", 8) ||
|
||||||
!g_ascii_strncasecmp (pathfrag, "postgres://", 11) ||
|
!g_ascii_strncasecmp (pathfrag, "postgres://", 11))
|
||||||
!g_ascii_strncasecmp (pathfrag, "rpc://", 6))
|
|
||||||
{
|
{
|
||||||
return g_strdup(pathfrag);
|
return g_strdup(pathfrag);
|
||||||
}
|
}
|
||||||
|
@ -240,13 +240,6 @@
|
|||||||
|
|
||||||
;; (gw:enum-add-value! we "ERR_SQL_MISSING_DATA" 'sql-missing-data)
|
;; (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)
|
#t)
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -2415,14 +2408,6 @@ of having a parent transaction with which one is working...")
|
|||||||
'((<gnc:numeric> arg))
|
'((<gnc:numeric> arg))
|
||||||
"Convert gnc_numeric to a printable string")
|
"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
|
;; gnc-date.h
|
||||||
|
|
||||||
(gw:wrap-function
|
(gw:wrap-function
|
||||||
|
Loading…
Reference in New Issue
Block a user