Compare commits
80 Commits
libApp_0-3
...
master
Author | SHA1 | Date | |
---|---|---|---|
9ee3344c46 | |||
c489093b0e | |||
fdf6d51887 | |||
5465283ff4 | |||
3856cc9748 | |||
031887ebf2 | |||
7195117804 | |||
10513104f0 | |||
092937a5d0 | |||
d0e1dbd2e3 | |||
8d2424ed40 | |||
e455db85fd | |||
314ea122b8 | |||
91a6f38dc8 | |||
f63438e736 | |||
fa419377f5 | |||
386fc440fd | |||
1fd59a5f41 | |||
41e364ecef | |||
45d6dc6774 | |||
e8e65fe2c0 | |||
deaae04315 | |||
04e8f21cd2 | |||
a984ce1452 | |||
8120944d5a | |||
c19142336c | |||
87c629e9c9 | |||
462136fbd8 | |||
5ade15bd7b | |||
eb05528c7f | |||
f062054e9f | |||
8a7456eed0 | |||
6643a3e217 | |||
83a1bf0b71 | |||
dca219b7b6 | |||
95d45851b5 | |||
6968cfd261 | |||
b922ec51fb | |||
aa76254a1c | |||
57ae51b11b | |||
892b8100da | |||
147f025360 | |||
06e16fbad6 | |||
cbc93775d5 | |||
d0ec7a589f | |||
3d6a6705c3 | |||
874d7a8fee | |||
c4e1784816 | |||
eb3fe28e7c | |||
36e95e95d4 | |||
5dced389d5 | |||
8795cceaf0 | |||
1132c45143 | |||
06e33a406f | |||
54d57b441f | |||
7f4451b9a0 | |||
688d40c1ad | |||
607c9b00f3 | |||
04b3177051 | |||
cae0ac9453 | |||
3473d9c713 | |||
6fbfc9b274 | |||
37d3714060 | |||
91c2a0aadf | |||
b4cd799664 | |||
6ea20eb1c5 | |||
985268a76a | |||
2f45a85464 | |||
47f6049119 | |||
56fb20d8fd | |||
8b815c58bf | |||
07e00a809a | |||
cd01e8468e | |||
c1d0cf8e3f | |||
ad55e78919 | |||
74e061a9a7 | |||
b20c1301fc | |||
f3dcfaf146 | |||
87c85bd38c | |||
ae5235b7a7 |
29
.github/workflows/deforaos-c-ci_ubuntu-latest.yml
vendored
Normal file
29
.github/workflows/deforaos-c-ci_ubuntu-latest.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
name: DeforaOS C CI (ubuntu-latest)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: bootstrap libSystem
|
||||
run: git clone https://github.com/DeforaOS/libSystem.git libSystem && for dir in include data src tools; do (cd libSystem/$dir && make PREFIX="$HOME/opt/DeforaOS" install); done
|
||||
- name: bootstrap configure
|
||||
run: git clone https://github.com/DeforaOS/configure.git configure && for dir in data src; do (cd configure/$dir && PKG_CONFIG_PATH="$HOME/opt/DeforaOS/lib/pkgconfig" make PREFIX="$HOME/opt/DeforaOS" install); done
|
||||
- name: bootstrap libMarshall
|
||||
run: git clone https://github.com/DeforaOS/libMarshall.git libMarshall && $HOME/opt/DeforaOS/bin/configure -p "$HOME/opt/DeforaOS" libMarshall && for dir in include data src tools; do (cd libMarshall/$dir && PKG_CONFIG_PATH="$HOME/opt/DeforaOS/lib/pkgconfig" make install); done
|
||||
- name: configure
|
||||
run: $HOME/opt/DeforaOS/bin/configure -p "$HOME/opt/DeforaOS"
|
||||
- name: make
|
||||
run: PKG_CONFIG_PATH="$HOME/opt/DeforaOS/lib/pkgconfig" make CCSHARED="cc -shared"
|
||||
- name: make tests
|
||||
run: PKG_CONFIG_PATH="$HOME/opt/DeforaOS/lib/pkgconfig" make CCSHARED="cc -shared" tests
|
||||
- name: make distcheck
|
||||
run: PKG_CONFIG_PATH="$HOME/opt/DeforaOS/lib/pkgconfig" make CCSHARED="cc -shared" distcheck
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,5 +6,6 @@ Makefile
|
||||
*.o
|
||||
*.so
|
||||
*.so.*
|
||||
/config.ent
|
||||
/config.h
|
||||
/config.sh
|
||||
|
11
README.md
11
README.md
@ -17,15 +17,14 @@ Dependencies for libApp
|
||||
libApp depends on the following software components to build:
|
||||
- pkg-config from the freedesktop software collection, as found in most
|
||||
software distributions already; otherwise at
|
||||
<http://www.freedesktop.org/wiki/Software/pkg-config/>
|
||||
<https://www.freedesktop.org/wiki/Software/pkg-config/> (or a compatible
|
||||
replacement)
|
||||
- libSystem from the DeforaOS Project, as found at
|
||||
<http://www.defora.org/os/project/27/libSystem> if not packaged for your
|
||||
system.
|
||||
<https://www.defora.org/os/project/27/libSystem>
|
||||
- libMarshall from the DeforaOS Project, as found at
|
||||
<http://www.defora.org/os/project/4400/libMarshall> if not packaged for your
|
||||
system.
|
||||
<https://www.defora.org/os/project/4400/libMarshall>
|
||||
- configure from the DeforaOS Project, likewise found at
|
||||
<http://www.defora.org/os/project/16/configure>
|
||||
<https://www.defora.org/os/project/16/configure>
|
||||
|
||||
|
||||
Configuring libApp
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2011-2019 Pierre Pronchery <khorben@defora.org>
|
||||
#Copyright (c) 2011-2022 Pierre Pronchery <khorben@defora.org>
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
@ -27,18 +27,114 @@
|
||||
#variables
|
||||
CONFIGSH="${0%/pkgconfig.sh}/../config.sh"
|
||||
PREFIX="/usr/local"
|
||||
DEBUG="_debug"
|
||||
DEVNULL="/dev/null"
|
||||
PROGNAME="pkgconfig.sh"
|
||||
#executables
|
||||
INSTALL="install -m 0644"
|
||||
DEBUG="_debug"
|
||||
INSTALL="install"
|
||||
MKDIR="mkdir -m 0755 -p"
|
||||
RM="rm -f"
|
||||
SED="sed"
|
||||
|
||||
[ -f "$CONFIGSH" ] && . "$CONFIGSH"
|
||||
|
||||
|
||||
#functions
|
||||
#pkgconfig
|
||||
_pkgconfig()
|
||||
{
|
||||
#check the variables
|
||||
if [ -z "$PACKAGE" ]; then
|
||||
_error "The PACKAGE variable needs to be set"
|
||||
return $?
|
||||
fi
|
||||
if [ -z "$VERSION" ]; then
|
||||
_error "The VERSION variable needs to be set"
|
||||
return $?
|
||||
fi
|
||||
[ -z "$BINDIR" ] && BINDIR="$PREFIX/bin"
|
||||
[ -z "$DATADIR" ] && DATADIR="$PREFIX/share"
|
||||
[ -z "$INCLUDEDIR" ] && INCLUDEDIR="$PREFIX/include"
|
||||
[ -z "$LIBDIR" ] && LIBDIR="$PREFIX/lib"
|
||||
[ -z "$LIBEXECDIR" ] && LIBEXECDIR="$PREFIX/libexec"
|
||||
[ -z "$MANDIR" ] && MANDIR="$DATADIR/man"
|
||||
[ -z "$SBINDIR" ] && SBINDIR="$PREFIX/sbin"
|
||||
if [ -z "$SYSCONFDIR" ]; then
|
||||
SYSCONFDIR="$PREFIX/etc"
|
||||
[ "$PREFIX" = "/usr" ] && SYSCONFDIR="/etc"
|
||||
fi
|
||||
PKGCONFIG="$PREFIX/lib/pkgconfig"
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
target="$1"
|
||||
shift
|
||||
|
||||
#clean
|
||||
[ "$clean" -ne 0 ] && continue
|
||||
|
||||
#uninstall
|
||||
if [ "$uninstall" -eq 1 ]; then
|
||||
$DEBUG $RM -- "$PKGCONFIG/$target" || return 2
|
||||
continue
|
||||
fi
|
||||
|
||||
#install
|
||||
if [ "$install" -eq 1 ]; then
|
||||
source="${target#$OBJDIR}"
|
||||
$DEBUG $MKDIR -- "$PKGCONFIG" || return 2
|
||||
mode="-m 0644"
|
||||
basename="$source"
|
||||
if [ "${source##*/}" != "$source" ]; then
|
||||
basename="${source##*/}"
|
||||
fi
|
||||
$DEBUG $INSTALL $mode "$target" "$PKGCONFIG/$basename" \
|
||||
|| return 2
|
||||
continue
|
||||
fi
|
||||
|
||||
#portability
|
||||
RPATH=
|
||||
if [ "$PREFIX" != "/usr" ]; then
|
||||
RPATH="-Wl,-rpath-link,\${libdir} -Wl,-rpath,\${libdir}"
|
||||
case $(uname -s) in
|
||||
"Darwin")
|
||||
RPATH="-Wl,-rpath,\${libdir}"
|
||||
;;
|
||||
"SunOS")
|
||||
RPATH="-Wl,-R\${libdir}"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#create
|
||||
source="${target#$OBJDIR}"
|
||||
source="${source}.in"
|
||||
([ -z "$OBJDIR" ] || $DEBUG $MKDIR -- "${target%/*}") \
|
||||
|| return 2
|
||||
$DEBUG $SED -e "s;@VENDOR@;$VENDOR;g" \
|
||||
-e "s;@PACKAGE@;$PACKAGE;g" \
|
||||
-e "s;@VERSION@;$VERSION;g" \
|
||||
-e "s;@PREFIX@;$PREFIX;g" \
|
||||
-e "s;@BINDIR@;$BINDIR;g" \
|
||||
-e "s;@DATADIR@;$DATADIR;g" \
|
||||
-e "s;@INCLUDEDIR@;$INCLUDEDIR;g" \
|
||||
-e "s;@LIBDIR@;$LIBDIR;g" \
|
||||
-e "s;@LIBEXECDIR@;$LIBEXECDIR;g" \
|
||||
-e "s;@MANDIR@;$MANDIR;g" \
|
||||
-e "s;@PWD@;$PWD;g" \
|
||||
-e "s;@RPATH@;$RPATH;g" \
|
||||
-e "s;@SBINDIR@;$SBINDIR;g" \
|
||||
-e "s;@SYSCONFDIR@;$SYSCONFDIR;g" \
|
||||
-- "$source" > "$target"
|
||||
if [ $? -ne 0 ]; then
|
||||
$RM -- "$target" 2> "$DEVNULL"
|
||||
return 2
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#debug
|
||||
_debug()
|
||||
{
|
||||
@ -93,91 +189,10 @@ while getopts "ciuO:P:" name; do
|
||||
esac
|
||||
done
|
||||
shift $(($OPTIND - 1))
|
||||
if [ $# -lt 0 ]; then
|
||||
if [ $# -lt 1 ]; then
|
||||
_usage
|
||||
exit $?
|
||||
fi
|
||||
|
||||
#check the variables
|
||||
if [ -z "$PACKAGE" ]; then
|
||||
_error "The PACKAGE variable needs to be set"
|
||||
exit $?
|
||||
fi
|
||||
if [ -z "$VERSION" ]; then
|
||||
_error "The VERSION variable needs to be set"
|
||||
exit $?
|
||||
fi
|
||||
[ -z "$BINDIR" ] && BINDIR="$PREFIX/bin"
|
||||
[ -z "$DATADIR" ] && DATADIR="$PREFIX/share"
|
||||
[ -z "$INCLUDEDIR" ] && INCLUDEDIR="$PREFIX/include"
|
||||
[ -z "$LIBDIR" ] && LIBDIR="$PREFIX/lib"
|
||||
[ -z "$LIBEXECDIR" ] && LIBEXECDIR="$PREFIX/libexec"
|
||||
[ -z "$MANDIR" ] && MANDIR="$DATADIR/man"
|
||||
if [ -z "$SYSCONFDIR" ]; then
|
||||
SYSCONFDIR="$PREFIX/etc"
|
||||
[ "$PREFIX" = "/usr" ] && SYSCONFDIR="/etc"
|
||||
fi
|
||||
|
||||
PKGCONFIG="$PREFIX/lib/pkgconfig"
|
||||
exec 3>&1
|
||||
while [ $# -gt 0 ]; do
|
||||
target="$1"
|
||||
shift
|
||||
|
||||
#clean
|
||||
[ "$clean" -ne 0 ] && continue
|
||||
|
||||
#uninstall
|
||||
if [ "$uninstall" -eq 1 ]; then
|
||||
$DEBUG $RM -- "$PKGCONFIG/$target" || exit 2
|
||||
continue
|
||||
fi
|
||||
|
||||
#install
|
||||
if [ "$install" -eq 1 ]; then
|
||||
source="${target#$OBJDIR}"
|
||||
$DEBUG $MKDIR -- "$PKGCONFIG" || exit 2
|
||||
basename="$source"
|
||||
if [ "${source##*/}" != "$source" ]; then
|
||||
basename="${source##*/}"
|
||||
fi
|
||||
$DEBUG $INSTALL "$target" "$PKGCONFIG/$basename"|| exit 2
|
||||
continue
|
||||
fi
|
||||
|
||||
#portability
|
||||
RPATH=
|
||||
if [ "$PREFIX" != "/usr" ]; then
|
||||
RPATH="-Wl,-rpath-link,\${libdir} -Wl,-rpath,\${libdir}"
|
||||
case $(uname -s) in
|
||||
"Darwin")
|
||||
RPATH="-Wl,-rpath,\${libdir}"
|
||||
;;
|
||||
"SunOS")
|
||||
RPATH="-Wl,-R\${libdir}"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#create
|
||||
source="${target#$OBJDIR}"
|
||||
source="${source}.in"
|
||||
([ -z "$OBJDIR" ] || $DEBUG $MKDIR -- "${target%/*}") || exit 2
|
||||
$DEBUG $SED -e "s;@PACKAGE@;$PACKAGE;g" \
|
||||
-e "s;@VERSION@;$VERSION;g" \
|
||||
-e "s;@PREFIX@;$PREFIX;g" \
|
||||
-e "s;@BINDIR@;$BINDIR;g" \
|
||||
-e "s;@DATADIR@;$DATADIR;g" \
|
||||
-e "s;@INCLUDEDIR@;$INCLUDEDIR;g" \
|
||||
-e "s;@LIBDIR@;$LIBDIR;g" \
|
||||
-e "s;@LIBEXECDIR@;$LIBEXECDIR;g" \
|
||||
-e "s;@MANDIR@;$MANDIR;g" \
|
||||
-e "s;@PWD@;$PWD;g" \
|
||||
-e "s;@RPATH@;$RPATH;g" \
|
||||
-e "s;@SYSCONFDIR@;$SYSCONFDIR;g" \
|
||||
-- "$source" > "$target"
|
||||
if [ $? -ne 0 ]; then
|
||||
$DEBUG $RM -- "$target"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
_pkgconfig "$@"
|
||||
|
5
doc/.gitignore
vendored
5
doc/.gitignore
vendored
@ -2,3 +2,8 @@
|
||||
/AppBroker.html
|
||||
/AppClient.1
|
||||
/AppClient.html
|
||||
/gtkdoc/html
|
||||
/gtkdoc/html.stamp
|
||||
/gtkdoc/libApp.types
|
||||
/gtkdoc/tmpl.stamp
|
||||
/gtkdoc/xml.stamp
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2012-2017 Pierre Pronchery <khorben@defora.org>
|
||||
#Copyright (c) 2012-2024 Pierre Pronchery <khorben@defora.org>
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
@ -25,17 +25,22 @@
|
||||
|
||||
|
||||
#variables
|
||||
CONFIGSH="${0%/docbook.sh}/../config.sh"
|
||||
PREFIX="/usr/local"
|
||||
[ -f "../config.sh" ] && . "../config.sh"
|
||||
PROGNAME="docbook.sh"
|
||||
XSL_HTML="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"
|
||||
XSL_MAN="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"
|
||||
XSL_PDF="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"
|
||||
#executables
|
||||
DEBUG="_debug"
|
||||
FOP="fop"
|
||||
INSTALL="install -m 0644"
|
||||
MKDIR="mkdir -m 0755 -p"
|
||||
RM="rm -f"
|
||||
XMLLINT="xmllint"
|
||||
XSLTPROC="xsltproc --nonet --xinclude"
|
||||
XMLLINT="xmllint --noent --nonet --xinclude --path ${PWD}"
|
||||
XSLTPROC="xsltproc --nonet --xinclude --path ${PWD}"
|
||||
|
||||
[ -f "$CONFIGSH" ] && . "$CONFIGSH"
|
||||
|
||||
|
||||
#functions
|
||||
@ -58,18 +63,20 @@ _docbook()
|
||||
ext="${ext##.}"
|
||||
case "$ext" in
|
||||
html)
|
||||
XSL="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"
|
||||
XSL="$XSL_HTML"
|
||||
[ -f "${source%.*}.xsl" ] && XSL="${source%.*}.xsl"
|
||||
[ -f "${target%.*}.xsl" ] && XSL="${target%.*}.xsl"
|
||||
if [ -f "${target%.*}.css.xml" ]; then
|
||||
XSLTPROC="$XSLTPROC --param custom.css.source \"${target%.*}.css.xml\" --param generate.css.header 1"
|
||||
XSLTPROC_PARAMS="--param custom.css.source \"${target%.*}.css.xml\" --param generate.css.header 1"
|
||||
elif [ -f "${source%.*}.css.xml" ]; then
|
||||
XSLTPROC="$XSLTPROC --param custom.css.source \"${source%.*}.css.xml\" --param generate.css.header 1"
|
||||
XSLTPROC_PARAMS="--param custom.css.source \"${source%.*}.css.xml\" --param generate.css.header 1"
|
||||
else
|
||||
XSLTPROC_PARAMS=
|
||||
fi
|
||||
$DEBUG $XSLTPROC -o "$target" "$XSL" "$source"
|
||||
$DEBUG $XSLTPROC $XSLTPROC_PARAMS -o "$target" "$XSL" "$source"
|
||||
;;
|
||||
pdf)
|
||||
XSL="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"
|
||||
XSL="$XSL_PDF"
|
||||
[ -f "${source%.*}.xsl" ] && XSL="${source%.*}.xsl"
|
||||
[ -f "${target%.*}.xsl" ] && XSL="${target%.*}.xsl"
|
||||
$DEBUG $XSLTPROC -o "${target%.*}.fo" "$XSL" "$source" &&
|
||||
@ -77,7 +84,7 @@ _docbook()
|
||||
$RM -- "${target%.*}.fo"
|
||||
;;
|
||||
1|2|3|4|5|6|7|8|9)
|
||||
XSL="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"
|
||||
XSL="$XSL_MAN"
|
||||
$DEBUG $XSLTPROC -o "$target" "$XSL" "$source"
|
||||
;;
|
||||
*)
|
||||
@ -168,7 +175,7 @@ while [ $# -gt 0 ]; do
|
||||
source="${target#$OBJDIR}"
|
||||
source="${source%.*}.xml"
|
||||
xpath="string(/refentry/refmeta/manvolnum)"
|
||||
section=$($XMLLINT --xpath "$xpath" "$source")
|
||||
section=$($DEBUG $XMLLINT --xpath "$xpath" "$source")
|
||||
if [ $? -eq 0 -a -n "$section" ]; then
|
||||
instdir="$MANDIR/html$section"
|
||||
fi
|
||||
|
147
doc/gtkdoc.sh
147
doc/gtkdoc.sh
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2012-2017 Pierre Pronchery <khorben@defora.org>
|
||||
#Copyright (c) 2012-2020 Pierre Pronchery <khorben@defora.org>
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
|
||||
#variables
|
||||
CONFIGSH="${0%/gtkdoc.sh}/../config.sh"
|
||||
PREFIX="/usr/local"
|
||||
PROGNAME="gtkdoc.sh"
|
||||
#executables
|
||||
@ -38,9 +39,10 @@ GTKDOC_SCAN="gtkdoc-scan"
|
||||
INSTALL="install -m 0644"
|
||||
MKDIR="mkdir -m 0755 -p"
|
||||
RM="rm -f"
|
||||
RMDIR="rmdir"
|
||||
TOUCH="touch"
|
||||
|
||||
[ -f "../config.sh" ] && . "../config.sh"
|
||||
[ -f "$CONFIGSH" ] && . "$CONFIGSH"
|
||||
|
||||
|
||||
#functions
|
||||
@ -60,6 +62,77 @@ _error()
|
||||
}
|
||||
|
||||
|
||||
#gtkdoc_fixxref
|
||||
_gtkdoc_fixxref()
|
||||
{
|
||||
module="$1"
|
||||
moduledir="$2"
|
||||
htmldir="$3"
|
||||
outputdir="$4"
|
||||
|
||||
(cd "$outputdir" &&
|
||||
$DEBUG $GTKDOC_FIXXREF \
|
||||
--module="$module" \
|
||||
--module-dir="$moduledir" \
|
||||
--html-dir="$htmldir") || exit 2
|
||||
}
|
||||
|
||||
|
||||
#gtkdoc_mkdb
|
||||
_gtkdoc_mkdb()
|
||||
{
|
||||
module="$1"
|
||||
sourcedir="$2"
|
||||
outputdir="$3"
|
||||
|
||||
(cd "$sourcedir" &&
|
||||
$DEBUG $GTKDOC_MKDB --module="$module" \
|
||||
--output-dir="$outputdir" \
|
||||
--output-format="xml" --tmpl-dir="tmpl")
|
||||
}
|
||||
|
||||
|
||||
#gtkdoc_mkhtml
|
||||
_gtkdoc_mkhtml()
|
||||
{
|
||||
module="$1"
|
||||
path="$2"
|
||||
driver="$3"
|
||||
outputdir="$4"
|
||||
|
||||
(cd "$outputdir" &&
|
||||
$DEBUG $GTKDOC_MKHTML --path "$path" "$module" "$driver")
|
||||
}
|
||||
|
||||
|
||||
#gtkdoc_mktmpl
|
||||
_gtkdoc_mktmpl()
|
||||
{
|
||||
module="$1"
|
||||
sourcedir="$2"
|
||||
outputdir="$3"
|
||||
|
||||
(cd "$sourcedir" &&
|
||||
$DEBUG $GTKDOC_MKTMPL --module="$module" \
|
||||
--output-dir="$outputdir")
|
||||
}
|
||||
|
||||
|
||||
#gtkdoc_scan
|
||||
_gtkdoc_scan()
|
||||
{
|
||||
module="$1"
|
||||
sourcedir="$2"
|
||||
outputdir="$3"
|
||||
|
||||
(cd ".." &&
|
||||
$DEBUG $GTKDOC_SCAN --module="$module" \
|
||||
--source-dir="$sourcedir" \
|
||||
--output-dir="$outputdir")
|
||||
# --rebuild-types
|
||||
}
|
||||
|
||||
|
||||
#usage
|
||||
_usage()
|
||||
{
|
||||
@ -129,23 +202,28 @@ while [ $# -gt 0 ]; do
|
||||
file="${i##*/}"
|
||||
$DEBUG $RM -- "$instdir/$MODULE/$file" || exit 2
|
||||
done
|
||||
if [ -d "$instdir/$MODULE" ]; then
|
||||
$DEBUG $RMDIR -- "$instdir/$MODULE" || exit 2
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
#create
|
||||
case "$target" in
|
||||
gtkdoc/html.stamp)
|
||||
driver="../$MODULE-docs.xml"
|
||||
if [ -n "$OBJDIR" ]; then
|
||||
driver="gtkdoc/$MODULE-docs.xml"
|
||||
$DEBUG $CP -- "$driver" "${OBJDIR}gtkdoc" \
|
||||
|| exit 2
|
||||
fi
|
||||
output="${OBJDIR}gtkdoc/html"
|
||||
$DEBUG $MKDIR -- "$output" || exit 2
|
||||
(cd "$output" &&
|
||||
$DEBUG $GTKDOC_MKHTML "$MODULE" \
|
||||
"${OBJDIR}$driver")
|
||||
driver="$MODULE-docs.xml"
|
||||
oldpath="$PWD"
|
||||
[ -n "$OBJDIR" ] && for file in \
|
||||
"gtkdoc/$driver" \
|
||||
"gtkdoc/xml/gtkdocentities.ent"; do
|
||||
[ -f "$file" ] || continue
|
||||
$DEBUG $CP -- "$file" \
|
||||
"${OBJDIR}$file" || exit 2
|
||||
done
|
||||
_gtkdoc_mkhtml "$MODULE" "${oldpath%/*}" "../$driver" \
|
||||
"$output"
|
||||
#detect when gtk-doc is not available
|
||||
res=$?
|
||||
if [ $res -eq 127 ]; then
|
||||
@ -156,24 +234,7 @@ while [ $# -gt 0 ]; do
|
||||
exit 2
|
||||
fi
|
||||
output="${OBJDIR}gtkdoc"
|
||||
(cd "$output" &&
|
||||
$DEBUG $GTKDOC_FIXXREF \
|
||||
--module="$MODULE" \
|
||||
--module-dir="html" \
|
||||
--html-dir="$instdir") || exit 2
|
||||
;;
|
||||
gtkdoc/sgml.stamp)
|
||||
output="xml"
|
||||
if [ -n "$OBJDIR" ]; then
|
||||
output="${OBJDIR}gtkdoc/xml"
|
||||
$DEBUG $MKDIR -- "$output" || exit 2
|
||||
fi
|
||||
(cd "${OBJDIR}gtkdoc" &&
|
||||
$DEBUG $GTKDOC_MKDB \
|
||||
--module="$MODULE" \
|
||||
--output-dir="$output" \
|
||||
--output-format="xml" \
|
||||
--tmpl-dir="tmpl")
|
||||
_gtkdoc_fixxref "$MODULE" "html" "$instdir" "$output"
|
||||
;;
|
||||
gtkdoc/tmpl.stamp)
|
||||
output="tmpl"
|
||||
@ -181,22 +242,28 @@ while [ $# -gt 0 ]; do
|
||||
output="${OBJDIR}gtkdoc/tmpl"
|
||||
$DEBUG $MKDIR -- "$output" || exit 2
|
||||
fi
|
||||
(cd "${OBJDIR}gtkdoc" &&
|
||||
$DEBUG $GTKDOC_MKTMPL \
|
||||
--module="$MODULE" \
|
||||
--output-dir="$output")
|
||||
_gtkdoc_mktmpl "$MODULE" "${OBJDIR}gtkdoc" "$output"
|
||||
;;
|
||||
gtkdoc/xml.stamp)
|
||||
output="xml"
|
||||
if [ -n "$OBJDIR" ]; then
|
||||
output="${OBJDIR}gtkdoc"
|
||||
sections="gtkdoc/$MODULE-sections.txt"
|
||||
$DEBUG $MKDIR -- "$output/xml" || exit 2
|
||||
$DEBUG $CP -- "$sections" "$output" \
|
||||
|| exit 2
|
||||
_gtkdoc_scan "$MODULE" "include" "$output"
|
||||
output="${OBJDIR}gtkdoc/xml"
|
||||
fi
|
||||
_gtkdoc_mkdb "$MODULE" "${OBJDIR}gtkdoc" "$output"
|
||||
;;
|
||||
gtkdoc/*.types)
|
||||
output="doc/gtkdoc" || exit 2
|
||||
output="$PWD/gtkdoc" || exit 2
|
||||
if [ -n "$OBJDIR" ]; then
|
||||
output="${OBJDIR}gtkdoc"
|
||||
$DEBUG $MKDIR -- "$output" || exit 2
|
||||
fi
|
||||
(cd ".." &&
|
||||
$DEBUG $GTKDOC_SCAN \
|
||||
--module="$MODULE" \
|
||||
--source-dir="include" \
|
||||
--output-dir="$output")
|
||||
_gtkdoc_scan "$MODULE" "include" "$output"
|
||||
;;
|
||||
*)
|
||||
_error "$target: Unknown type"
|
||||
@ -208,7 +275,7 @@ while [ $# -gt 0 ]; do
|
||||
_error "$target: Could not create documentation"
|
||||
install=0
|
||||
fi
|
||||
$TOUCH "$target"
|
||||
$TOUCH "${OBJDIR}$target"
|
||||
|
||||
#install
|
||||
if [ "$install" -eq 1 ]; then
|
||||
|
@ -3,28 +3,35 @@
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||
[
|
||||
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||
<!ENTITY server "www.defora.org/doc/gtk-doc/html">
|
||||
<!ENTITY title "DeforaOS libApp">
|
||||
<!ENTITY version "0.1.5">
|
||||
<!ENTITY % gtkdocentities SYSTEM "xml/gtkdocentities.ent">
|
||||
%gtkdocentities;
|
||||
<!ENTITY % configentities SYSTEM "config.ent">
|
||||
%configentities;
|
||||
]>
|
||||
<book id="index">
|
||||
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
|
||||
<bookinfo>
|
||||
<title>libApp Reference Manual</title>
|
||||
<title>&vendor; &package; &title;</title>
|
||||
<releaseinfo>
|
||||
for libApp &version;.
|
||||
for &vendor; &package; &version;.
|
||||
The latest version of this documentation can be found on-line at
|
||||
<ulink role="online-location" url="http://&server;/libApp/index.html">http://&server;/libApp/</ulink>.
|
||||
<ulink role="online-location" url="https://&server;/&package;/">https://&server;/&package;/</ulink>.
|
||||
</releaseinfo>
|
||||
</bookinfo>
|
||||
|
||||
<chapter>
|
||||
<title>&title;</title>
|
||||
<title>&vendor; &package;</title>
|
||||
<xi:include href="xml/app.xml"/>
|
||||
<xi:include href="xml/appclient.xml"/>
|
||||
<xi:include href="xml/appmessage.xml"/>
|
||||
<xi:include href="xml/appserver.xml"/>
|
||||
<xi:include href="xml/apptransport.xml"/>
|
||||
|
||||
</chapter>
|
||||
<!-- enable this when you use gobject types
|
||||
<chapter id="object-tree">
|
||||
<title>Object Hierarchy</title>
|
||||
<xi:include href="xml/tree_index.sgml"/>
|
||||
</chapter>
|
||||
-->
|
||||
<index id="api-index-full">
|
||||
<title>API Index</title>
|
||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||
@ -33,6 +40,7 @@
|
||||
<title>Index of deprecated API</title>
|
||||
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
||||
</index>
|
||||
|
||||
<!-- enable this when you use gobject introspection annotations
|
||||
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
|
||||
-->
|
||||
</book>
|
||||
|
56
doc/gtkdoc/libApp-sections.txt
Normal file
56
doc/gtkdoc/libApp-sections.txt
Normal file
@ -0,0 +1,56 @@
|
||||
<SECTION>
|
||||
<FILE>App</FILE>
|
||||
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>app</FILE>
|
||||
AppMessage
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>appclient</FILE>
|
||||
AppClient
|
||||
appclient_call
|
||||
appclient_delete
|
||||
appclient_new
|
||||
appclient_new_event
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>appmessage</FILE>
|
||||
AppMessageType
|
||||
appmessage_delete
|
||||
appmessage_get_method
|
||||
appmessage_get_type
|
||||
appmessage_new_call
|
||||
appmessage_new_deserialize
|
||||
appmessage_serialize
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>appserver</FILE>
|
||||
APPSERVER_MAX_ARGUMENTS
|
||||
AppServer
|
||||
AppServerOptions
|
||||
appserver_delete
|
||||
appserver_get_client_id
|
||||
appserver_loop
|
||||
appserver_new
|
||||
appserver_new_event
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>apptransport</FILE>
|
||||
AppTransport
|
||||
AppTransportClient
|
||||
AppTransportMode
|
||||
AppTransportPlugin
|
||||
AppTransportPluginDefinition
|
||||
AppTransportStatus
|
||||
client_delete
|
||||
client_new
|
||||
client_receive
|
||||
status
|
||||
</SECTION>
|
||||
|
@ -1 +1 @@
|
||||
dist=Makefile,libApp-docs.xml
|
||||
dist=Makefile,libApp-docs.xml,libApp-sections.txt,xml/gtkdocentities.ent
|
||||
|
2
doc/gtkdoc/xml/gtkdocentities.ent
Normal file
2
doc/gtkdoc/xml/gtkdocentities.ent
Normal file
@ -0,0 +1,2 @@
|
||||
<!ENTITY server "www.defora.org/doc/gtk-doc/html">
|
||||
<!ENTITY title "Reference Manual">
|
@ -1,7 +1,8 @@
|
||||
subdirs=gtkdoc
|
||||
targets=AppBroker.1,AppBroker.html,AppClient.1,AppClient.html,gtkdoc/libApp.types,gtkdoc/tmpl.stamp,gtkdoc/sgml.stamp,gtkdoc/html.stamp
|
||||
targets=AppBroker.1,AppBroker.html,AppClient.1,AppClient.html,gtkdoc/html.stamp,gtkdoc/libApp.types,gtkdoc/tmpl.stamp,gtkdoc/xml.stamp
|
||||
dist=Makefile,AppBroker.css.xml,AppBroker.xml,AppClient.css.xml,AppClient.xml,docbook.sh,gtkdoc.sh,manual.css.xml
|
||||
|
||||
#targets
|
||||
[AppBroker.1]
|
||||
type=script
|
||||
script=./docbook.sh
|
||||
@ -26,22 +27,23 @@ script=./docbook.sh
|
||||
depends=AppClient.css.xml,AppClient.xml,manual.css.xml
|
||||
#install=
|
||||
|
||||
[gtkdoc/html.stamp]
|
||||
type=script
|
||||
script=./gtkdoc.sh
|
||||
depends=gtkdoc.sh,gtkdoc/libApp-docs.xml,$(OBJDIR)gtkdoc/xml.stamp,gtkdoc/xml/gtkdocentities.ent,../config.ent
|
||||
install=
|
||||
|
||||
[gtkdoc/libApp.types]
|
||||
type=script
|
||||
script=./gtkdoc.sh
|
||||
depends=gtkdoc.sh
|
||||
|
||||
[gtkdoc/tmpl.stamp]
|
||||
type=script
|
||||
script=./gtkdoc.sh
|
||||
depends=$(OBJDIR)gtkdoc/libApp.types
|
||||
depends=gtkdoc.sh,$(OBJDIR)gtkdoc/libApp.types
|
||||
|
||||
[gtkdoc/sgml.stamp]
|
||||
[gtkdoc/xml.stamp]
|
||||
type=script
|
||||
script=./gtkdoc.sh
|
||||
depends=$(OBJDIR)gtkdoc/tmpl.stamp
|
||||
|
||||
[gtkdoc/html.stamp]
|
||||
type=script
|
||||
script=./gtkdoc.sh
|
||||
depends=gtkdoc/libApp-docs.xml,$(OBJDIR)gtkdoc/sgml.stamp,$(OBJDIR)gtkdoc/tmpl.stamp
|
||||
install=
|
||||
depends=gtkdoc.sh,$(OBJDIR)gtkdoc/tmpl.stamp
|
||||
|
1
include/App/.gitignore
vendored
Normal file
1
include/App/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/app.h
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -25,4 +25,8 @@ typedef struct _App App;
|
||||
|
||||
typedef struct _AppMessage AppMessage;
|
||||
|
||||
|
||||
/* constants */
|
||||
# define APP_PATH "@LIBDIR@/App"
|
||||
|
||||
#endif /* !LIBAPP_APP_APP_H */
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2011-2015 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2011-2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -18,6 +18,7 @@
|
||||
#ifndef LIBAPP_APP_APPCLIENT_H
|
||||
# define LIBAPP_APP_APPCLIENT_H
|
||||
|
||||
# include <stdarg.h>
|
||||
# include <stdint.h>
|
||||
# include <System/event.h>
|
||||
# include <System/variable.h>
|
||||
@ -42,7 +43,13 @@ AppStatus * appclient_get_status(AppClient * appclient);
|
||||
/* useful */
|
||||
int appclient_call(AppClient * appclient,
|
||||
void ** result, char const * method, ...);
|
||||
int appclient_callv(AppClient * appclient,
|
||||
void ** result, char const * method, va_list args);
|
||||
int appclient_call_variable(AppClient * appclient,
|
||||
Variable * result, char const * method, ...);
|
||||
int appclient_call_variables(AppClient * appclient,
|
||||
Variable * result, char const * method, Variable ** args);
|
||||
int appclient_call_variablev(AppClient * appclient,
|
||||
Variable * result, char const * method, va_list args);
|
||||
|
||||
#endif /* !LIBAPP_APP_APPCLIENT_H */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012-2015 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -41,7 +41,7 @@ typedef uint32_t AppMessageID;
|
||||
/* calls */
|
||||
typedef enum _AppMessageCallDirection
|
||||
{
|
||||
AMCD_IN = 0,
|
||||
AMCD_IN = 1,
|
||||
AMCD_OUT,
|
||||
AMCD_IN_OUT
|
||||
} AppMessageCallDirection;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012-2014 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -84,4 +84,8 @@ struct _AppTransportPluginDefinition
|
||||
AppTransportClient * client, AppMessage * message);
|
||||
};
|
||||
|
||||
|
||||
/* constants */
|
||||
# define APP_TRANSPORT_PATH APP_PATH "/transport"
|
||||
|
||||
#endif /* !LIBAPP_APP_APPTRANSPORT_H */
|
||||
|
@ -1,9 +1,8 @@
|
||||
includes=app.h,appclient.h,appmessage.h,appserver.h,appstatus.h,apptransport.h
|
||||
dist=Makefile
|
||||
|
||||
[app.h]
|
||||
install=$(INCLUDEDIR)/System/App
|
||||
includes=appclient.h,appmessage.h,appserver.h,appstatus.h,apptransport.h
|
||||
targets=app.h
|
||||
dist=Makefile,app.h.in
|
||||
|
||||
#includes
|
||||
[appclient.h]
|
||||
install=$(INCLUDEDIR)/System/App
|
||||
|
||||
@ -18,3 +17,10 @@ install=$(INCLUDEDIR)/System/App
|
||||
|
||||
[apptransport.h]
|
||||
install=$(INCLUDEDIR)/System/App
|
||||
|
||||
#targets
|
||||
[app.h]
|
||||
type=script
|
||||
script=../../tools/subst.sh
|
||||
install=$(INCLUDEDIR)/System/App
|
||||
depends=app.h.in,../../config.sh
|
||||
|
12
project.conf
12
project.conf
@ -1,7 +1,7 @@
|
||||
package=libApp
|
||||
version=0.3.1
|
||||
config=h,sh
|
||||
dist=Makefile,COPYING,README.md,config.h,config.sh
|
||||
version=0.3.2
|
||||
config=ent,h,sh
|
||||
dist=Makefile,COPYING,README.md,config.ent,config.h,config.sh
|
||||
|
||||
subdirs=data,doc,include,src,src/transport,tools,tests
|
||||
targets=tests
|
||||
@ -9,7 +9,11 @@ targets=tests
|
||||
#targets
|
||||
[tests]
|
||||
type=command
|
||||
command=cd tests && (if [ -n "$(OBJDIR)" ]; then $(MAKE) OBJDIR="$(OBJDIR)tests/" "$(OBJDIR)tests/fixme.log"; else $(MAKE) fixme.log; fi)
|
||||
command=cd tests && (if [ -n "$(OBJDIR)" ]; then $(MAKE) OBJDIR="$(OBJDIR)tests/" "$(OBJDIR)tests/fixme.log" "$(OBJDIR)tests/pkgconfig.log" "$(OBJDIR)tests/shlint.log" "$(OBJDIR)tests/tests.log"; else $(MAKE) fixme.log pkgconfig.log shlint.log tests.log; fi)
|
||||
depends=all
|
||||
enabled=0
|
||||
phony=1
|
||||
|
||||
#dist
|
||||
[README.md]
|
||||
install=$(PREFIX)/share/doc/$(PACKAGE)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2011-2014 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2011-2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -79,10 +79,14 @@ AppClient * appclient_new_event(App * self, char const * app,
|
||||
appclient->transport = apptransport_new_app(ATM_CLIENT,
|
||||
&appclient->helper, app, name, appclient->event);
|
||||
/* check for errors */
|
||||
if(appclient->interface == NULL || appclient->transport == NULL
|
||||
if(appclient->interface == NULL
|
||||
|| appclient->transport == NULL
|
||||
|| appclient->event == NULL)
|
||||
{
|
||||
appclient_delete(appclient);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s() => NULL\n", __func__);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
@ -131,34 +135,73 @@ int appclient_call(AppClient * appclient,
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, method);
|
||||
ret = appinterface_callv(appclient->interface, appclient->app, result,
|
||||
method, ap);
|
||||
ret = appclient_callv(appclient, result, method, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* appclient_callv */
|
||||
int appclient_callv(AppClient * appclient,
|
||||
void ** result, char const * method, va_list ap)
|
||||
{
|
||||
int ret;
|
||||
AppMessage * message;
|
||||
|
||||
if((message = appinterface_messagev(appclient->interface, method, ap))
|
||||
== NULL)
|
||||
return -1;
|
||||
/* FIXME obtain the answer (AICD_{,IN}OUT) */
|
||||
ret = apptransport_client_send(appclient->transport, message, 1);
|
||||
appmessage_delete(message);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* appclient_call_variable */
|
||||
int appclient_call_variable(AppClient * appclient,
|
||||
Variable * result, char const * method, ...)
|
||||
{
|
||||
int ret;
|
||||
size_t cnt;
|
||||
size_t i;
|
||||
va_list ap;
|
||||
Variable ** argv;
|
||||
|
||||
if(appinterface_get_args_count(appclient->interface, &cnt, method) != 0)
|
||||
return -1;
|
||||
if((argv = malloc(sizeof(*argv) * cnt)) == NULL)
|
||||
return error_set_code(-errno, "%s", strerror(errno));
|
||||
va_start(ap, method);
|
||||
for(i = 0; i < cnt; i++)
|
||||
argv[i] = va_arg(ap, Variable *);
|
||||
ret = appclient_call_variablev(appclient, result, method, ap);
|
||||
va_end(ap);
|
||||
ret = appinterface_call_variablev(appclient->interface, appclient->app,
|
||||
result, method, cnt, argv);
|
||||
free(argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* appclient_call_variables */
|
||||
int appclient_call_variables(AppClient * appclient,
|
||||
Variable * result, char const * method, Variable ** args)
|
||||
{
|
||||
int ret;
|
||||
AppMessage * message;
|
||||
|
||||
if((message = appinterface_message_variables(appclient->interface,
|
||||
method, args)) == NULL)
|
||||
return -1;
|
||||
/* FIXME obtain the answer (AICD_{,IN}OUT) */
|
||||
ret = apptransport_client_send(appclient->transport, message, 1);
|
||||
appmessage_delete(message);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* appclient_call_variablev */
|
||||
int appclient_call_variablev(AppClient * appclient,
|
||||
Variable * result, char const * method, va_list args)
|
||||
{
|
||||
int ret;
|
||||
AppMessage * message;
|
||||
|
||||
if((message = appinterface_message_variablev(appclient->interface,
|
||||
method, args)) == NULL)
|
||||
return -1;
|
||||
/* FIXME obtain the answer (AICD_{,IN}OUT) */
|
||||
ret = apptransport_client_send(appclient->transport, message, 1);
|
||||
appmessage_delete(message);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -201,7 +244,7 @@ static int _helper_message_call(AppClient * appclient, AppTransport * transport,
|
||||
/* XXX report errors */
|
||||
return -1;
|
||||
ret = appinterface_call_variablev(appclient->interface, appclient->app,
|
||||
result, method, 0, NULL);
|
||||
NULL, result, method, 0, NULL);
|
||||
if(result != NULL)
|
||||
variable_delete(result);
|
||||
return ret;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2011-2016 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2011-2022 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -26,6 +26,7 @@
|
||||
#include <errno.h>
|
||||
#include <System.h>
|
||||
#include <System/Marshall.h>
|
||||
#include "App/appmessage.h"
|
||||
#include "App/appserver.h"
|
||||
#include "appstatus.h"
|
||||
#include "appinterface.h"
|
||||
@ -43,7 +44,6 @@
|
||||
/* private */
|
||||
/* types */
|
||||
/* XXX get rid of this */
|
||||
#define VT_LAST VT_STRING
|
||||
#define VT_COUNT (VT_LAST + 1)
|
||||
#define AICT_MASK 077
|
||||
|
||||
@ -51,7 +51,8 @@
|
||||
static const String * AICTString[VT_COUNT] =
|
||||
{
|
||||
"void", "bool", "int8", "uint8", "int16", "uint16", "int32", "uint32",
|
||||
"int64", "uint64", "String", "Buffer", "float", "double"
|
||||
"int64", "uint64", "float", "double", "Buffer", "String", "Array",
|
||||
"Compound"
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -76,7 +77,7 @@ typedef struct _AppInterfaceCall
|
||||
AppInterfaceCallArg type;
|
||||
AppInterfaceCallArg * args;
|
||||
size_t args_cnt;
|
||||
MarshallCallback func;
|
||||
MarshallCall call;
|
||||
} AppInterfaceCall;
|
||||
|
||||
struct _AppInterface
|
||||
@ -88,6 +89,9 @@ struct _AppInterface
|
||||
AppStatus * status;
|
||||
AppInterfaceCall * calls;
|
||||
size_t calls_cnt;
|
||||
AppInterfaceCall * callbacks;
|
||||
size_t callbacks_cnt;
|
||||
/* XXX for hash_foreach() in _new_interface_do() */
|
||||
int error;
|
||||
};
|
||||
|
||||
@ -161,8 +165,14 @@ static AppInterfaceCall * _appinterface_get_call(AppInterface * appinterface,
|
||||
char const * method);
|
||||
|
||||
/* useful */
|
||||
static int _appinterface_call(App * app, Variable * result,
|
||||
AppInterfaceCall * call, size_t argc, Variable ** argv);
|
||||
static Variable ** _appinterface_argv_new(AppInterfaceCall * call,
|
||||
va_list ap);
|
||||
static void _appinterface_argv_free(Variable ** argv, size_t argc);
|
||||
static int _appinterface_call(App * app, AppServerClient * asc,
|
||||
Variable * result, AppInterfaceCall * call,
|
||||
size_t argc, Variable ** argv);
|
||||
static AppMessage * _appinterface_message(AppInterfaceCall * call,
|
||||
size_t argc, Variable ** argv);
|
||||
|
||||
|
||||
/* functions */
|
||||
@ -220,51 +230,38 @@ static String * _new_interface(String const * app)
|
||||
|
||||
|
||||
/* appinterface_new_interface */
|
||||
static int _new_interface_append(AppInterface * ai, VariableType type,
|
||||
char const * method);
|
||||
static int _new_interface_append_arg(AppInterface * ai, char const * arg);
|
||||
static AppInterfaceCall * _new_interface_append_call(AppInterface * ai,
|
||||
VariableType type, char const * method);
|
||||
static AppInterfaceCall * _new_interface_append_callback(AppInterface * ai,
|
||||
VariableType type, char const * method);
|
||||
static int _new_interface_append_arg(AppInterfaceCall * call, char const * arg);
|
||||
AppInterface * _new_interface_do(AppTransportMode mode, String const * app,
|
||||
String const * pathname);
|
||||
static int _new_interface_do_appstatus(AppInterface * appinterface);
|
||||
static int _new_interface_foreach(char const * key, Hash * value,
|
||||
static int _new_interface_foreach_calls(char const * key, Hash * value,
|
||||
AppInterface * appinterface);
|
||||
static int _new_interface_foreach_callbacks(char const * key, Hash * value,
|
||||
AppInterface * appinterface);
|
||||
static AppInterface * _new_interface_mode_client(AppTransportMode mode,
|
||||
String const * app, String const * pathname);
|
||||
static AppInterface * _new_interface_mode_server(AppTransportMode mode,
|
||||
String const * app, String const * pathname);
|
||||
|
||||
AppInterface * appinterface_new_interface(AppTransportMode mode,
|
||||
String const * app, String const * pathname)
|
||||
{
|
||||
AppInterface * ai;
|
||||
Plugin * handle;
|
||||
size_t i;
|
||||
String * name;
|
||||
|
||||
if((handle = plugin_new_self()) == NULL)
|
||||
return NULL;
|
||||
if((ai = _new_interface_do(mode, app, pathname)) == NULL)
|
||||
return NULL;
|
||||
for(i = 0; i < ai->calls_cnt; i++)
|
||||
switch(mode)
|
||||
{
|
||||
if((name = string_new_append(ai->name, "_", ai->calls[i].name,
|
||||
NULL)) == NULL)
|
||||
{
|
||||
appinterface_delete(ai);
|
||||
ai = NULL;
|
||||
break;
|
||||
}
|
||||
ai->calls[i].func = plugin_lookup(handle, name);
|
||||
string_delete(name);
|
||||
if(ai->calls[i].func == NULL)
|
||||
{
|
||||
appinterface_delete(ai);
|
||||
ai = NULL;
|
||||
break;
|
||||
}
|
||||
case ATM_CLIENT:
|
||||
return _new_interface_mode_client(mode, app, pathname);
|
||||
case ATM_SERVER:
|
||||
return _new_interface_mode_server(mode, app, pathname);
|
||||
}
|
||||
plugin_delete(handle);
|
||||
return ai;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _new_interface_append(AppInterface * ai, VariableType type,
|
||||
char const * method)
|
||||
static AppInterfaceCall * _new_interface_append_call(AppInterface * ai,
|
||||
VariableType type, char const * method)
|
||||
{
|
||||
AppInterfaceCall * p;
|
||||
|
||||
@ -272,25 +269,47 @@ static int _new_interface_append(AppInterface * ai, VariableType type,
|
||||
fprintf(stderr, "DEBUG: %s(%d, \"%s\")\n", __func__, type, method);
|
||||
#endif
|
||||
if((p = realloc(ai->calls, sizeof(*p) * (ai->calls_cnt + 1))) == NULL)
|
||||
return -1;
|
||||
return NULL;
|
||||
ai->calls = p;
|
||||
p = &ai->calls[ai->calls_cnt];
|
||||
if((p->name = string_new(method)) == NULL)
|
||||
return -1;
|
||||
return NULL;
|
||||
p->type.type = type & AICT_MASK;
|
||||
p->type.direction = type & AICD_MASK;
|
||||
p->args = NULL;
|
||||
p->args_cnt = 0;
|
||||
ai->calls_cnt++;
|
||||
return 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
static int _new_interface_append_arg(AppInterface * ai, char const * arg)
|
||||
static AppInterfaceCall * _new_interface_append_callback(AppInterface * ai,
|
||||
VariableType type, char const * method)
|
||||
{
|
||||
AppInterfaceCall * p;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%d, \"%s\")\n", __func__, type, method);
|
||||
#endif
|
||||
if((p = realloc(ai->callbacks, sizeof(*p) * (ai->callbacks_cnt + 1)))
|
||||
== NULL)
|
||||
return NULL;
|
||||
ai->callbacks = p;
|
||||
p = &ai->callbacks[ai->callbacks_cnt];
|
||||
if((p->name = string_new(method)) == NULL)
|
||||
return NULL;
|
||||
p->type.type = type & AICT_MASK;
|
||||
p->type.direction = type & AICD_MASK;
|
||||
p->args = NULL;
|
||||
p->args_cnt = 0;
|
||||
ai->callbacks_cnt++;
|
||||
return p;
|
||||
}
|
||||
|
||||
static int _new_interface_append_arg(AppInterfaceCall * call, char const * arg)
|
||||
{
|
||||
char buf[16];
|
||||
char * p;
|
||||
int type;
|
||||
AppInterfaceCall * q;
|
||||
AppInterfaceCallArg * r;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -301,11 +320,10 @@ static int _new_interface_append_arg(AppInterface * ai, char const * arg)
|
||||
*p = '\0';
|
||||
if((type = _string_enum(buf, _string_type)) < 0)
|
||||
return -1;
|
||||
q = &ai->calls[ai->calls_cnt - 1];
|
||||
if((r = realloc(q->args, sizeof(*r) * (q->args_cnt + 1))) == NULL)
|
||||
if((r = realloc(call->args, sizeof(*r) * (call->args_cnt + 1))) == NULL)
|
||||
return error_set_code(-errno, "%s", strerror(errno));
|
||||
q->args = r;
|
||||
r = &q->args[q->args_cnt++];
|
||||
call->args = r;
|
||||
r = &call->args[call->args_cnt++];
|
||||
r->type = type & AICT_MASK;
|
||||
r->direction = type & AICD_MASK;
|
||||
#ifdef DEBUG
|
||||
@ -330,6 +348,8 @@ AppInterface * _new_interface_do(AppTransportMode mode, String const * app,
|
||||
appinterface->status = NULL;
|
||||
appinterface->calls = NULL;
|
||||
appinterface->calls_cnt = 0;
|
||||
appinterface->callbacks = NULL;
|
||||
appinterface->callbacks_cnt = 0;
|
||||
appinterface->error = 0;
|
||||
if(appinterface->name == NULL
|
||||
|| appinterface->config == NULL
|
||||
@ -340,7 +360,11 @@ AppInterface * _new_interface_do(AppTransportMode mode, String const * app,
|
||||
return NULL;
|
||||
}
|
||||
appinterface->error = 0;
|
||||
hash_foreach(appinterface->config, (HashForeach)_new_interface_foreach,
|
||||
hash_foreach(appinterface->config,
|
||||
(HashForeach)_new_interface_foreach_calls,
|
||||
appinterface);
|
||||
hash_foreach(appinterface->config,
|
||||
(HashForeach)_new_interface_foreach_callbacks,
|
||||
appinterface);
|
||||
if(appinterface->error != 0)
|
||||
{
|
||||
@ -359,29 +383,28 @@ static int _new_interface_do_appstatus(AppInterface * appinterface)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _new_interface_foreach(char const * key, Hash * value,
|
||||
static int _new_interface_foreach_callbacks(char const * key, Hash * value,
|
||||
AppInterface * appinterface)
|
||||
{
|
||||
String const * prefix = (appinterface->mode == ATM_SERVER)
|
||||
? APPINTERFACE_CALL_PREFIX : APPINTERFACE_CALLBACK_PREFIX;
|
||||
String const * prefix = APPINTERFACE_CALLBACK_PREFIX;
|
||||
unsigned int i;
|
||||
char buf[8];
|
||||
int type = VT_NULL;
|
||||
char const * p;
|
||||
AppInterfaceCall * callback;
|
||||
|
||||
if(key == NULL || strncmp(prefix, key, string_length(prefix)) != 0)
|
||||
if(key == NULL || strncmp(prefix, key, string_get_length(prefix)) != 0)
|
||||
return 0;
|
||||
key += string_length(prefix);
|
||||
key += string_get_length(prefix);
|
||||
if((p = hash_get(value, "ret")) != NULL
|
||||
&& (type = _string_enum(p, _string_type)) < 0)
|
||||
{
|
||||
appinterface->error = error_set_code(1, "%s: %s%s", p,
|
||||
"Invalid return type for ",
|
||||
(appinterface->mode == ATM_SERVER)
|
||||
? "call" : "callback");
|
||||
appinterface->error = error_set_code(1, "%s: %s", p,
|
||||
"Invalid return type for callback");
|
||||
return -appinterface->error;
|
||||
}
|
||||
if(_new_interface_append(appinterface, type, key) != 0)
|
||||
if((callback = _new_interface_append_callback(appinterface, type, key))
|
||||
== NULL)
|
||||
{
|
||||
appinterface->error = 1;
|
||||
return -appinterface->error;
|
||||
@ -391,7 +414,7 @@ static int _new_interface_foreach(char const * key, Hash * value,
|
||||
snprintf(buf, sizeof(buf), "arg%u", i + 1);
|
||||
if((p = hash_get(value, buf)) == NULL)
|
||||
break;
|
||||
if(_new_interface_append_arg(appinterface, p) != 0)
|
||||
if(_new_interface_append_arg(callback, p) != 0)
|
||||
{
|
||||
/* FIXME may crash here? */
|
||||
appinterface->error = 1;
|
||||
@ -401,6 +424,123 @@ static int _new_interface_foreach(char const * key, Hash * value,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _new_interface_foreach_calls(char const * key, Hash * value,
|
||||
AppInterface * appinterface)
|
||||
{
|
||||
String const * prefix = APPINTERFACE_CALL_PREFIX;
|
||||
unsigned int i;
|
||||
char buf[8];
|
||||
int type = VT_NULL;
|
||||
char const * p;
|
||||
AppInterfaceCall * call;
|
||||
|
||||
if(key == NULL || strncmp(prefix, key, string_get_length(prefix)) != 0)
|
||||
return 0;
|
||||
key += string_get_length(prefix);
|
||||
if((p = hash_get(value, "ret")) != NULL
|
||||
&& (type = _string_enum(p, _string_type)) < 0)
|
||||
{
|
||||
appinterface->error = error_set_code(1, "%s: %s", p,
|
||||
"Invalid return type for call");
|
||||
return -appinterface->error;
|
||||
}
|
||||
if((call = _new_interface_append_call(appinterface, type, key)) == NULL)
|
||||
{
|
||||
appinterface->error = 1;
|
||||
return -appinterface->error;
|
||||
}
|
||||
for(i = 0; i < APPSERVER_MAX_ARGUMENTS; i++)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "arg%u", i + 1);
|
||||
if((p = hash_get(value, buf)) == NULL)
|
||||
break;
|
||||
if(_new_interface_append_arg(call, p) != 0)
|
||||
{
|
||||
/* FIXME may crash here? */
|
||||
appinterface->error = 1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
AppInterface * _new_interface_mode_client(AppTransportMode mode,
|
||||
String const * app, String const * pathname)
|
||||
{
|
||||
AppInterface * ai;
|
||||
Plugin * plugin;
|
||||
size_t i;
|
||||
String * name;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%u, \"%s\", \"%s\")\n", __func__, mode, app,
|
||||
pathname);
|
||||
#endif
|
||||
if((plugin = plugin_new_self()) == NULL)
|
||||
return NULL;
|
||||
if((ai = _new_interface_do(mode, app, pathname)) == NULL)
|
||||
{
|
||||
plugin_delete(plugin);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < ai->callbacks_cnt; i++)
|
||||
{
|
||||
if((name = string_new_append(ai->name, "_",
|
||||
ai->callbacks[i].name, NULL))
|
||||
== NULL)
|
||||
break;
|
||||
ai->callbacks[i].call = plugin_lookup(plugin, name);
|
||||
string_delete(name);
|
||||
if(ai->callbacks[i].call == NULL)
|
||||
break;
|
||||
}
|
||||
plugin_delete(plugin);
|
||||
if(i != ai->callbacks_cnt)
|
||||
{
|
||||
appinterface_delete(ai);
|
||||
return NULL;
|
||||
}
|
||||
return ai;
|
||||
}
|
||||
|
||||
AppInterface * _new_interface_mode_server(AppTransportMode mode,
|
||||
String const * app, String const * pathname)
|
||||
{
|
||||
AppInterface * ai;
|
||||
Plugin * plugin;
|
||||
size_t i;
|
||||
String * name;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%u, \"%s\", \"%s\")\n", __func__, mode, app,
|
||||
pathname);
|
||||
#endif
|
||||
if((plugin = plugin_new_self()) == NULL)
|
||||
return NULL;
|
||||
if((ai = _new_interface_do(mode, app, pathname)) == NULL)
|
||||
{
|
||||
plugin_delete(plugin);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < ai->calls_cnt; i++)
|
||||
{
|
||||
if((name = string_new_append(ai->name, "_", ai->calls[i].name,
|
||||
NULL)) == NULL)
|
||||
break;
|
||||
ai->calls[i].call = plugin_lookup(plugin, name);
|
||||
string_delete(name);
|
||||
if(ai->calls[i].call == NULL)
|
||||
break;
|
||||
}
|
||||
plugin_delete(plugin);
|
||||
if(i != ai->calls_cnt)
|
||||
{
|
||||
appinterface_delete(ai);
|
||||
return NULL;
|
||||
}
|
||||
return ai;
|
||||
}
|
||||
|
||||
|
||||
/* appinterface_delete */
|
||||
void appinterface_delete(AppInterface * appinterface)
|
||||
@ -507,31 +647,14 @@ AppStatus * appinterface_get_status(AppInterface * appinterface)
|
||||
|
||||
/* useful */
|
||||
/* appinterface_callv */
|
||||
int appinterface_callv(AppInterface * appinterface, App * app, void ** result,
|
||||
int appinterface_callv(AppInterface * appinterface, App * app,
|
||||
AppServerClient * asc, void ** result,
|
||||
String const * method, va_list args)
|
||||
{
|
||||
int ret = 0;
|
||||
AppInterfaceCall * call;
|
||||
Variable * r;
|
||||
size_t argc;
|
||||
Variable ** argv;
|
||||
union
|
||||
{
|
||||
bool b;
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
int16_t i16;
|
||||
uint16_t u16;
|
||||
int32_t i32;
|
||||
uint32_t u32;
|
||||
int64_t i64;
|
||||
uint64_t u64;
|
||||
char * str;
|
||||
Buffer * buf;
|
||||
float f;
|
||||
double d;
|
||||
} u;
|
||||
void * p;
|
||||
|
||||
if((call = _appinterface_get_call(appinterface, method)) == NULL)
|
||||
return -1;
|
||||
@ -539,100 +662,93 @@ int appinterface_callv(AppInterface * appinterface, App * app, void ** result,
|
||||
r = NULL;
|
||||
else if((r = variable_new(call->type.type, NULL)) == NULL)
|
||||
return -1;
|
||||
if((argv = malloc(sizeof(*argv) * (call->args_cnt))) == NULL)
|
||||
if((argv = _appinterface_argv_new(call, args)) == NULL)
|
||||
{
|
||||
if(r != NULL)
|
||||
variable_delete(r);
|
||||
return -1;
|
||||
}
|
||||
for(argc = 0; argc < call->args_cnt; argc++)
|
||||
{
|
||||
/* FIXME also implement AICD_{,IN}OUT */
|
||||
switch(call->args[argc].type)
|
||||
{
|
||||
case VT_BOOL:
|
||||
u.b = va_arg(args, unsigned int);
|
||||
p = &u.b;
|
||||
break;
|
||||
case VT_INT8:
|
||||
u.i8 = va_arg(args, int);
|
||||
p = &u.i8;
|
||||
break;
|
||||
case VT_UINT8:
|
||||
u.u8 = va_arg(args, unsigned int);
|
||||
p = &u.u8;
|
||||
break;
|
||||
case VT_INT16:
|
||||
u.i16 = va_arg(args, int);
|
||||
p = &u.i16;
|
||||
break;
|
||||
case VT_UINT16:
|
||||
u.u16 = va_arg(args, unsigned int);
|
||||
p = &u.u16;
|
||||
break;
|
||||
case VT_INT32:
|
||||
u.i32 = va_arg(args, int32_t);
|
||||
p = &u.i32;
|
||||
break;
|
||||
case VT_UINT32:
|
||||
u.u32 = va_arg(args, uint32_t);
|
||||
p = &u.u32;
|
||||
break;
|
||||
case VT_INT64:
|
||||
u.i64 = va_arg(args, int64_t);
|
||||
p = &u.i64;
|
||||
break;
|
||||
case VT_UINT64:
|
||||
u.u64 = va_arg(args, uint64_t);
|
||||
p = &u.u64;
|
||||
break;
|
||||
case VT_STRING:
|
||||
u.str = va_arg(args, char *);
|
||||
p = u.str;
|
||||
break;
|
||||
case VT_BUFFER:
|
||||
u.buf = va_arg(args, Buffer *);
|
||||
p = u.buf;
|
||||
break;
|
||||
case VT_FLOAT:
|
||||
u.f = va_arg(args, double);
|
||||
p = &u.f;
|
||||
break;
|
||||
case VT_DOUBLE:
|
||||
u.d = va_arg(args, double);
|
||||
p = &u.d;
|
||||
break;
|
||||
case VT_NULL:
|
||||
default:
|
||||
p = NULL;
|
||||
break;
|
||||
}
|
||||
argv[argc] = (p != NULL)
|
||||
? variable_new(call->args[argc].type, p) : NULL;
|
||||
if(p == NULL || argv[argc] == NULL)
|
||||
ret = -1;
|
||||
}
|
||||
if(ret == 0)
|
||||
ret = _appinterface_call(app, r, call, argc, argv);
|
||||
if(ret == 0 && result != NULL)
|
||||
/* XXX return 0 anyway? */
|
||||
ret = variable_get_as(r, call->type.type, *result);
|
||||
ret = _appinterface_call(app, asc, r, call,
|
||||
call->args_cnt, argv);
|
||||
if(r != NULL)
|
||||
{
|
||||
if(ret == 0 && result != NULL)
|
||||
/* XXX return 0 anyway? */
|
||||
ret = variable_get_as(r, call->type.type, *result,
|
||||
NULL);
|
||||
variable_delete(r);
|
||||
}
|
||||
/* FIXME also implement AICD_{,IN}OUT */
|
||||
_appinterface_argv_free(argv, call->args_cnt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* appinterface_call_variablev */
|
||||
int appinterface_call_variablev(AppInterface * appinterface, App * app,
|
||||
Variable * result, char const * method,
|
||||
AppServerClient * asc, Variable * result, char const * method,
|
||||
size_t argc, Variable ** argv)
|
||||
{
|
||||
AppInterfaceCall * call;
|
||||
|
||||
if((call = _appinterface_get_call(appinterface, method)) == NULL)
|
||||
return -1;
|
||||
return _appinterface_call(app, result, call, argc, argv);
|
||||
return _appinterface_call(app, asc, result, call, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
/* appinterface_messagev */
|
||||
AppMessage * appinterface_messagev(AppInterface * appinterface,
|
||||
char const * method, va_list ap)
|
||||
{
|
||||
AppInterfaceCall * call;
|
||||
Variable ** argv;
|
||||
AppMessage * message;
|
||||
|
||||
if((call = _appinterface_get_call(appinterface, method)) == NULL)
|
||||
return NULL;
|
||||
if((argv = _appinterface_argv_new(call, ap)) == NULL)
|
||||
return NULL;
|
||||
message = _appinterface_message(call, call->args_cnt, argv);
|
||||
_appinterface_argv_free(argv, call->args_cnt);
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
/* appinterface_message_variables */
|
||||
AppMessage * appinterface_message_variables(AppInterface * appinterface,
|
||||
char const * method, Variable ** args)
|
||||
{
|
||||
AppInterfaceCall * call;
|
||||
|
||||
if((call = _appinterface_get_call(appinterface, method)) == NULL)
|
||||
return NULL;
|
||||
return _appinterface_message(call, call->args_cnt, args);
|
||||
}
|
||||
|
||||
|
||||
/* appinterface_message_variablev */
|
||||
AppMessage * appinterface_message_variablev(AppInterface * appinterface,
|
||||
char const * method, va_list ap)
|
||||
{
|
||||
AppInterfaceCall * call;
|
||||
Variable ** argv;
|
||||
size_t i;
|
||||
AppMessage * message;
|
||||
|
||||
if((call = _appinterface_get_call(appinterface, method)) == NULL)
|
||||
return NULL;
|
||||
if(call->args_cnt == 0)
|
||||
argv = NULL;
|
||||
else if((argv = malloc(sizeof(*argv) * call->args_cnt)) == NULL)
|
||||
/* XXX report error */
|
||||
return NULL;
|
||||
for(i = 0; i < call->args_cnt; i++)
|
||||
argv[i] = va_arg(ap, Variable *);
|
||||
message = _appinterface_message(call, call->args_cnt, argv);
|
||||
free(argv);
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
@ -654,28 +770,281 @@ static AppInterfaceCall * _appinterface_get_call(AppInterface * appinterface,
|
||||
|
||||
|
||||
/* useful */
|
||||
/* appinterface_argv */
|
||||
static Variable * _argv_new_in(VariableType type, va_list ap);
|
||||
static Variable * _argv_new_in_out(VariableType type, va_list ap);
|
||||
static Variable * _argv_new_out(VariableType type, va_list ap);
|
||||
|
||||
static Variable ** _appinterface_argv_new(AppInterfaceCall * call, va_list ap)
|
||||
{
|
||||
Variable ** argv;
|
||||
size_t i;
|
||||
|
||||
if((argv = object_new(sizeof(*argv) * (call->args_cnt))) == NULL)
|
||||
return NULL;
|
||||
for(i = 0; i < call->args_cnt; i++)
|
||||
{
|
||||
switch(call->args[i].direction)
|
||||
{
|
||||
case AICD_IN:
|
||||
argv[i] = _argv_new_in(call->args[i].type, ap);
|
||||
break;
|
||||
case AICD_IN_OUT:
|
||||
argv[i] = _argv_new_in_out(call->args[i].type,
|
||||
ap);
|
||||
break;
|
||||
case AICD_OUT:
|
||||
argv[i] = _argv_new_out(call->args[i].type,
|
||||
ap);
|
||||
break;
|
||||
default:
|
||||
/* XXX report the error */
|
||||
argv[i] = NULL;
|
||||
break;
|
||||
}
|
||||
if(argv[i] == NULL)
|
||||
{
|
||||
_appinterface_argv_free(argv, i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return argv;
|
||||
}
|
||||
|
||||
static Variable * _argv_new_in(VariableType type, va_list ap)
|
||||
{
|
||||
return variable_newv(type, ap);
|
||||
}
|
||||
|
||||
static Variable * _argv_new_in_out(VariableType type, va_list ap)
|
||||
{
|
||||
union
|
||||
{
|
||||
bool * bp;
|
||||
int8_t * i8p;
|
||||
uint8_t * u8p;
|
||||
int16_t * i16p;
|
||||
uint16_t * u16p;
|
||||
int32_t * i32p;
|
||||
uint32_t * u32p;
|
||||
int64_t * i64p;
|
||||
uint64_t * u64p;
|
||||
char ** strp;
|
||||
Buffer * buf;
|
||||
float * fp;
|
||||
double * dp;
|
||||
} u;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%u)\n", __func__, type);
|
||||
#endif
|
||||
switch(type)
|
||||
{
|
||||
case VT_NULL:
|
||||
return variable_new(type);
|
||||
case VT_BOOL:
|
||||
u.bp = va_arg(ap, bool *);
|
||||
return variable_new(type, *u.bp);
|
||||
case VT_INT8:
|
||||
u.i8p = va_arg(ap, int8_t *);
|
||||
return variable_new(type, *u.i8p);
|
||||
case VT_UINT8:
|
||||
u.u8p = va_arg(ap, uint8_t *);
|
||||
return variable_new(type, *u.u8p);
|
||||
case VT_INT16:
|
||||
u.i16p = va_arg(ap, int16_t *);
|
||||
return variable_new(type, *u.i16p);
|
||||
case VT_UINT16:
|
||||
u.u16p = va_arg(ap, uint16_t *);
|
||||
return variable_new(type, *u.u16p);
|
||||
case VT_INT32:
|
||||
u.i32p = va_arg(ap, int32_t *);
|
||||
return variable_new(type, *u.i32p);
|
||||
case VT_UINT32:
|
||||
u.u32p = va_arg(ap, uint32_t *);
|
||||
return variable_new(type, *u.u32p);
|
||||
case VT_INT64:
|
||||
u.i64p = va_arg(ap, int64_t *);
|
||||
return variable_new(type, *u.i64p);
|
||||
case VT_UINT64:
|
||||
u.u64p = va_arg(ap, uint64_t *);
|
||||
return variable_new(type, *u.u64p);
|
||||
case VT_FLOAT:
|
||||
u.fp = va_arg(ap, float *);
|
||||
return variable_new(type, *u.fp);
|
||||
case VT_DOUBLE:
|
||||
u.dp = va_arg(ap, double *);
|
||||
return variable_new(type, *u.dp);
|
||||
case VT_STRING:
|
||||
u.strp = va_arg(ap, char **);
|
||||
return variable_new(type, *u.strp);
|
||||
case VT_BUFFER:
|
||||
u.buf = va_arg(ap, Buffer *);
|
||||
return variable_new(type, u.buf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Variable * _argv_new_out(VariableType type, va_list ap)
|
||||
{
|
||||
union
|
||||
{
|
||||
bool * bp;
|
||||
int8_t * i8p;
|
||||
uint8_t * u8p;
|
||||
int16_t * i16p;
|
||||
uint16_t * u16p;
|
||||
int32_t * i32p;
|
||||
uint32_t * u32p;
|
||||
int64_t * i64p;
|
||||
uint64_t * u64p;
|
||||
char ** strp;
|
||||
Buffer * buf;
|
||||
float * fp;
|
||||
double * dp;
|
||||
} u;
|
||||
void * p;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%u)\n", __func__, type);
|
||||
#endif
|
||||
switch(type)
|
||||
{
|
||||
case VT_BOOL:
|
||||
u.bp = va_arg(ap, bool *);
|
||||
p = u.bp;
|
||||
break;
|
||||
case VT_INT8:
|
||||
u.i8p = va_arg(ap, int8_t *);
|
||||
p = u.i8p;
|
||||
break;
|
||||
case VT_UINT8:
|
||||
u.u8p = va_arg(ap, uint8_t *);
|
||||
p = u.u8p;
|
||||
break;
|
||||
case VT_INT16:
|
||||
u.i16p = va_arg(ap, int16_t *);
|
||||
p = u.i16p;
|
||||
break;
|
||||
case VT_UINT16:
|
||||
u.u16p = va_arg(ap, uint16_t *);
|
||||
p = u.u16p;
|
||||
break;
|
||||
case VT_INT32:
|
||||
u.i32p = va_arg(ap, int32_t *);
|
||||
p = u.i32p;
|
||||
break;
|
||||
case VT_UINT32:
|
||||
u.u32p = va_arg(ap, uint32_t *);
|
||||
p = u.u32p;
|
||||
break;
|
||||
case VT_INT64:
|
||||
u.i64p = va_arg(ap, int64_t *);
|
||||
p = u.i64p;
|
||||
break;
|
||||
case VT_UINT64:
|
||||
u.u64p = va_arg(ap, uint64_t *);
|
||||
p = u.u64p;
|
||||
break;
|
||||
case VT_STRING:
|
||||
u.strp = va_arg(ap, char **);
|
||||
p = u.strp;
|
||||
break;
|
||||
case VT_BUFFER:
|
||||
u.buf = va_arg(ap, Buffer *);
|
||||
p = u.buf;
|
||||
break;
|
||||
case VT_FLOAT:
|
||||
u.fp = va_arg(ap, float *);
|
||||
p = u.fp;
|
||||
break;
|
||||
case VT_DOUBLE:
|
||||
u.dp = va_arg(ap, double *);
|
||||
p = u.dp;
|
||||
break;
|
||||
case VT_NULL:
|
||||
default:
|
||||
p = NULL;
|
||||
break;
|
||||
}
|
||||
if(p == NULL)
|
||||
return NULL;
|
||||
return variable_new(type, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* appinterface_argv_free */
|
||||
static void _appinterface_argv_free(Variable ** argv, size_t argc)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < argc; i++)
|
||||
variable_delete(argv[i]);
|
||||
object_delete(argv);
|
||||
}
|
||||
|
||||
|
||||
/* appinterface_call */
|
||||
static int _appinterface_call(App * app, Variable * result,
|
||||
AppInterfaceCall * call, size_t argc, Variable ** argv)
|
||||
static int _appinterface_call(App * app, AppServerClient * asc,
|
||||
Variable * result, AppInterfaceCall * call,
|
||||
size_t argc, Variable ** argv)
|
||||
{
|
||||
int ret;
|
||||
Variable ** p;
|
||||
size_t i;
|
||||
|
||||
if(argc != call->args_cnt)
|
||||
/* XXX set the error */
|
||||
return -1;
|
||||
if((p = malloc(sizeof(*p) * (argc + 1))) == NULL)
|
||||
if((p = object_new(sizeof(*p) * (argc + 2))) == NULL)
|
||||
return -1;
|
||||
/* XXX really is a VT_POINTER (void *) */
|
||||
if((p[0] = variable_new(VT_BUFFER, app)) == NULL)
|
||||
p[0] = variable_new(VT_POINTER, app);
|
||||
p[1] = variable_new(VT_POINTER, asc);
|
||||
if(p[0] == NULL || p[1] == NULL)
|
||||
{
|
||||
free(p);
|
||||
if(p[0] != NULL)
|
||||
variable_delete(p[0]);
|
||||
if(p[1] != NULL)
|
||||
variable_delete(p[1]);
|
||||
object_delete(p);
|
||||
return -1;
|
||||
}
|
||||
for(i = 0; i < argc; i++)
|
||||
p[i + 1] = argv[i];
|
||||
ret = marshall_call(result, call->func, argc, argv);
|
||||
p[i + 2] = argv[i];
|
||||
ret = marshall_callp(result, call->call, argc + 2, p);
|
||||
variable_delete(p[1]);
|
||||
variable_delete(p[0]);
|
||||
free(p);
|
||||
object_delete(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* appinterface_message */
|
||||
static AppMessage * _appinterface_message(AppInterfaceCall * call,
|
||||
size_t argc, Variable ** argv)
|
||||
{
|
||||
AppMessage * message;
|
||||
AppMessageCallArgument * args;
|
||||
size_t i;
|
||||
|
||||
if(argc != call->args_cnt)
|
||||
{
|
||||
error_set_code(1, "%s: %s%zu%s%zu%s", call->name,
|
||||
"Invalid number of arguments (", argc,
|
||||
", expected: ", call->args_cnt, ")");
|
||||
return NULL;
|
||||
}
|
||||
if(argc == 0)
|
||||
args = NULL;
|
||||
else if((args = object_new(sizeof(*args) * argc)) == NULL)
|
||||
return NULL;
|
||||
else
|
||||
for(i = 0; i < argc; i++)
|
||||
{
|
||||
args[i].direction = call->args[i].direction;
|
||||
args[i].arg = argv[i];
|
||||
}
|
||||
message = appmessage_new_call(call->name, args, argc);
|
||||
object_delete(args);
|
||||
return message;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2011-2015 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2011-2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
# include <stdarg.h>
|
||||
# include <System/variable.h>
|
||||
# include "App/appserver.h"
|
||||
# include "App/appstatus.h"
|
||||
# include "App/apptransport.h"
|
||||
|
||||
@ -45,10 +46,18 @@ int appinterface_get_args_count(AppInterface * appinterface, size_t * count,
|
||||
AppStatus * appinterface_get_status(AppInterface * appinterface);
|
||||
|
||||
/* useful */
|
||||
int appinterface_callv(AppInterface * appinterface, App * app, void ** result,
|
||||
int appinterface_callv(AppInterface * appinterface, App * app,
|
||||
AppServerClient * asc, void ** result,
|
||||
char const * method, va_list args);
|
||||
int appinterface_call_variablev(AppInterface * appinterface, App * app,
|
||||
Variable * result, char const * method,
|
||||
AppServerClient * asc, Variable * result, char const * method,
|
||||
size_t argc, Variable ** argv);
|
||||
|
||||
AppMessage * appinterface_messagev(AppInterface * appinterface,
|
||||
char const * method, va_list args);
|
||||
AppMessage * appinterface_message_variables(AppInterface * appinterface,
|
||||
char const * method, Variable ** args);
|
||||
AppMessage * appinterface_message_variablev(AppInterface * appinterface,
|
||||
char const * method, va_list args);
|
||||
|
||||
#endif /* !LIBAPP_APPINTERFACE_H */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012-2016 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2022 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -21,6 +21,8 @@
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <System.h>
|
||||
#include "appmessage.h"
|
||||
|
||||
@ -78,18 +80,26 @@ AppMessage * appmessage_new_call(char const * method,
|
||||
message->type = AMT_CALL;
|
||||
message->id = 0;
|
||||
message->t.call.method = string_new(method);
|
||||
message->t.call.args = malloc(sizeof(*args) * args_cnt);
|
||||
message->t.call.args_cnt = args_cnt;
|
||||
if(message->t.call.args == NULL)
|
||||
if((message->t.call.args = object_new(sizeof(*args) * args_cnt))
|
||||
== NULL)
|
||||
{
|
||||
message->t.call.args_cnt = 0;
|
||||
appmessage_delete(message);
|
||||
return NULL;
|
||||
}
|
||||
for(i = 0; i < args_cnt; i++)
|
||||
{
|
||||
/* FIXME check for errors */
|
||||
message->t.call.args[i].direction = args[i].direction;
|
||||
message->t.call.args[i].arg = variable_new_copy(args[i].arg);
|
||||
if((message->t.call.args[i].arg = variable_new_copy(
|
||||
args[i].arg)) == NULL)
|
||||
break;
|
||||
}
|
||||
message->t.call.args_cnt = i;
|
||||
/* check for errors */
|
||||
if(i != args_cnt)
|
||||
{
|
||||
appmessage_delete(message);
|
||||
return NULL;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
@ -125,6 +135,7 @@ AppMessage * appmessage_new_callv(char const * method, ...)
|
||||
if((p = realloc(message->t.call.args, sizeof(*p) * (i + 1)))
|
||||
== NULL)
|
||||
{
|
||||
error_set_code(-errno, "%s", strerror(errno));
|
||||
appmessage_delete(message);
|
||||
message = NULL;
|
||||
break;
|
||||
@ -173,7 +184,12 @@ AppMessage * appmessage_new_callv_variables(char const * method, ...)
|
||||
{
|
||||
if((p = realloc(message->t.call.args, sizeof(*p) * (i + 1)))
|
||||
== NULL)
|
||||
{
|
||||
error_set_code(-errno, "%s", strerror(errno));
|
||||
appmessage_delete(message);
|
||||
message = NULL;
|
||||
break;
|
||||
}
|
||||
message->t.call.args = p;
|
||||
if((v = variable_new_copy(v)) == NULL)
|
||||
{
|
||||
@ -181,7 +197,7 @@ AppMessage * appmessage_new_callv_variables(char const * method, ...)
|
||||
message = NULL;
|
||||
break;
|
||||
}
|
||||
message->t.call.args[i].direction = AMCD_IN; /* XXX */
|
||||
message->t.call.args[i].direction = AMCD_IN; /* FIXME */
|
||||
message->t.call.args[i].arg = v;
|
||||
message->t.call.args_cnt = i + 1;
|
||||
}
|
||||
@ -223,7 +239,7 @@ AppMessage * appmessage_new_deserialize(Buffer * buffer)
|
||||
pos += s;
|
||||
size -= s;
|
||||
/* XXX may fail */
|
||||
variable_get_as(v, VT_UINT8, &u8);
|
||||
variable_get_as(v, VT_UINT8, &u8, NULL);
|
||||
variable_delete(v);
|
||||
switch((message->type = u8))
|
||||
{
|
||||
@ -276,7 +292,7 @@ static AppMessage * _new_deserialize_call(AppMessage * message,
|
||||
}
|
||||
pos += s;
|
||||
/* XXX may fail */
|
||||
variable_get_as(v, VT_STRING, &message->t.call.method);
|
||||
variable_get_as(v, VT_STRING, &message->t.call.method, NULL);
|
||||
variable_delete(v);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__,
|
||||
@ -291,6 +307,7 @@ static AppMessage * _new_deserialize_call(AppMessage * message,
|
||||
if((p = realloc(message->t.call.args, sizeof(*p) * (i + 1)))
|
||||
== NULL)
|
||||
{
|
||||
error_set_code(-errno, "%s", strerror(errno));
|
||||
appmessage_delete(message);
|
||||
return NULL;
|
||||
}
|
||||
@ -330,7 +347,7 @@ static AppMessage * _new_deserialize_id(AppMessage * message, char const * data,
|
||||
appmessage_delete(message);
|
||||
return NULL;
|
||||
}
|
||||
ret = variable_get_as(v, VT_UINT32, &message->id);
|
||||
ret = variable_get_as(v, VT_UINT32, &message->id, NULL);
|
||||
variable_delete(v);
|
||||
if(ret != 0)
|
||||
{
|
||||
@ -360,6 +377,11 @@ void appmessage_delete(AppMessage * message)
|
||||
|
||||
static void _delete_call(AppMessage * message)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < message->t.call.args_cnt; i++)
|
||||
variable_delete(message->t.call.args[i].arg);
|
||||
free(message->t.call.args);
|
||||
string_delete(message->t.call.method);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2011-2015 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2011-2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -183,8 +183,9 @@ static int _helper_message_call(AppServer * appserver, AppTransport * transport,
|
||||
if(!appinterface_can_call(appserver->interface, method, name))
|
||||
/* XXX report errors */
|
||||
return -1;
|
||||
/* FIXME provide the actual AppServerClient */
|
||||
ret = appinterface_call_variablev(appserver->interface, appserver->app,
|
||||
result, method, 0, NULL);
|
||||
NULL, result, method, 0, NULL);
|
||||
if(result != NULL)
|
||||
variable_delete(result);
|
||||
return ret;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2015 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2015-2024 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -32,7 +32,8 @@ struct _AppStatus
|
||||
/* public */
|
||||
/* methods */
|
||||
/* appstatus_new */
|
||||
static void _new_config_foreach_section(String const * variable,
|
||||
static void _new_config_foreach_section(Config const * config,
|
||||
String const * section, String const * variable,
|
||||
String const * value, void * data);
|
||||
|
||||
AppStatus * appstatus_new_config(Config * config, String const * section)
|
||||
@ -41,8 +42,8 @@ AppStatus * appstatus_new_config(Config * config, String const * section)
|
||||
struct
|
||||
{
|
||||
size_t members;
|
||||
VariableType * types;
|
||||
void ** values;
|
||||
String const ** names;
|
||||
Variable ** variables;
|
||||
} data;
|
||||
|
||||
if((appstatus = object_new(sizeof(*appstatus))) == NULL)
|
||||
@ -52,9 +53,9 @@ AppStatus * appstatus_new_config(Config * config, String const * section)
|
||||
NULL);
|
||||
if(data.members == 0)
|
||||
appstatus->variable = NULL;
|
||||
else if((appstatus->variable = variable_new_compoundv(NULL,
|
||||
data.members, data.types, data.values))
|
||||
== NULL)
|
||||
else if((appstatus->variable = variable_new_compound_variables(NULL,
|
||||
data.members, data.names,
|
||||
data.variables)) == NULL)
|
||||
{
|
||||
appstatus_delete(appstatus);
|
||||
return NULL;
|
||||
@ -62,14 +63,15 @@ AppStatus * appstatus_new_config(Config * config, String const * section)
|
||||
return appstatus;
|
||||
}
|
||||
|
||||
static void _new_config_foreach_section(String const * variable,
|
||||
static void _new_config_foreach_section(Config const * config,
|
||||
String const * section, String const * variable,
|
||||
String const * value, void * data)
|
||||
{
|
||||
struct
|
||||
{
|
||||
size_t members;
|
||||
VariableType * types;
|
||||
void ** values;
|
||||
String const ** names;
|
||||
Variable ** variables;
|
||||
} * d = data;
|
||||
|
||||
/* FIXME implement */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012-2015 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -408,7 +408,16 @@ static AppTransportClient * _apptransport_helper_client_new(
|
||||
if((client = object_new(sizeof(*client))) == NULL)
|
||||
return NULL;
|
||||
client->transport = transport;
|
||||
client->name = (name != NULL) ? string_new(name) : NULL;
|
||||
if(name != NULL)
|
||||
{
|
||||
if((client->name = string_new(name)) == NULL)
|
||||
{
|
||||
object_delete(client);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
client->name = NULL;
|
||||
return client;
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,19 @@
|
||||
targets=libApp
|
||||
cppflags_force=-I ../include
|
||||
cppflags_force=-I ../include -I ${OBJDIR}../include/App
|
||||
cflags_force=-fPIC `pkg-config --cflags libSystem libMarshall`
|
||||
cflags=-W -Wall -g -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-all
|
||||
cflags=-W -Wall -g -O2 -D_FORTIFY_SOURCE=2 -fstack-protector
|
||||
ldflags_force=`pkg-config --libs libSystem libMarshall`
|
||||
ldflags=-Wl,-z,relro -Wl,-z,now
|
||||
dist=Makefile,appinterface.h,appmessage.h,appstatus.h,apptransport.h
|
||||
|
||||
#targets
|
||||
[libApp]
|
||||
type=library
|
||||
sources=appclient.c,appinterface.c,appmessage.c,appserver.c,appstatus.c,apptransport.c
|
||||
ldflags=-lsocket -lws2_32
|
||||
install=$(LIBDIR)
|
||||
|
||||
#sources
|
||||
[appclient.c]
|
||||
depends=appinterface.h,../include/App/appclient.h
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
targets=self,tcp,tcp4,tcp6,template,udp,udp4,udp6
|
||||
cppflags_force=-I ../../include
|
||||
cppflags_force=-I ../../include -I ${OBJDIR}../../include/App
|
||||
cppflags=
|
||||
cflags_force=-fPIC `pkg-config --cflags libSystem`
|
||||
cflags=-W -Wall -g -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-all
|
||||
cflags=-W -Wall -g -O2 -D_FORTIFY_SOURCE=2 -fstack-protector
|
||||
ldflags_force=`pkg-config --libs libSystem` -L$(OBJDIR).. -lApp
|
||||
ldflags=-Wl,-z,relro -Wl,-z,now
|
||||
dist=Makefile,common.h,common.c
|
||||
|
||||
#targets
|
||||
[self]
|
||||
type=plugin
|
||||
sources=self.c
|
||||
@ -19,27 +20,18 @@ sources=tcp.c
|
||||
ldflags=-lsocket
|
||||
install=$(LIBDIR)/App/transport
|
||||
|
||||
[tcp.c]
|
||||
depends=common.h,common.c
|
||||
|
||||
[tcp4]
|
||||
type=plugin
|
||||
sources=tcp4.c
|
||||
ldflags=-lsocket
|
||||
install=$(LIBDIR)/App/transport
|
||||
|
||||
[tcp4.c]
|
||||
depends=tcp.c,common.h,common.c
|
||||
|
||||
[tcp6]
|
||||
type=plugin
|
||||
sources=tcp6.c
|
||||
ldflags=-lsocket
|
||||
install=$(LIBDIR)/App/transport
|
||||
|
||||
[tcp6.c]
|
||||
depends=tcp.c,common.h,common.c
|
||||
|
||||
[template]
|
||||
type=plugin
|
||||
sources=template.c
|
||||
@ -50,23 +42,33 @@ sources=udp.c
|
||||
ldflags=-lsocket
|
||||
install=$(LIBDIR)/App/transport
|
||||
|
||||
[udp.c]
|
||||
depends=common.h,common.c
|
||||
|
||||
[udp4]
|
||||
type=plugin
|
||||
sources=udp4.c
|
||||
ldflags=-lsocket
|
||||
install=$(LIBDIR)/App/transport
|
||||
|
||||
[udp4.c]
|
||||
depends=udp.c,common.h,common.c
|
||||
|
||||
[udp6]
|
||||
type=plugin
|
||||
sources=udp6.c
|
||||
ldflags=-lsocket
|
||||
install=$(LIBDIR)/App/transport
|
||||
|
||||
#sources
|
||||
[tcp.c]
|
||||
depends=common.h,common.c
|
||||
|
||||
[tcp4.c]
|
||||
depends=tcp.c,common.h,common.c
|
||||
|
||||
[tcp6.c]
|
||||
depends=tcp.c,common.h,common.c
|
||||
|
||||
[udp.c]
|
||||
depends=common.h,common.c
|
||||
|
||||
[udp4.c]
|
||||
depends=udp.c,common.h,common.c
|
||||
|
||||
[udp6.c]
|
||||
depends=udp.c,common.h,common.c
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012-2016 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2022 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -77,7 +77,7 @@ struct _AppTransportPlugin
|
||||
AppTransportMode mode;
|
||||
|
||||
struct addrinfo * ai;
|
||||
socklen_t ai_addrlen;
|
||||
struct addrinfo * aip;
|
||||
|
||||
union
|
||||
{
|
||||
@ -109,9 +109,9 @@ static TCP * _tcp_init(AppTransportPluginHelper * helper, AppTransportMode mode,
|
||||
char const * name);
|
||||
static void _tcp_destroy(TCP * tcp);
|
||||
|
||||
static int _tcp_client_send(TCP * tcp, AppTransportClient * client,
|
||||
static int _tcp_client_send(TCP * tcp, AppMessage * message);
|
||||
static int _tcp_server_send(TCP * tcp, AppTransportClient * client,
|
||||
AppMessage * message);
|
||||
static int _tcp_send(TCP * tcp, AppMessage * message);
|
||||
|
||||
/* useful */
|
||||
static int _tcp_error(char const * message);
|
||||
@ -120,7 +120,8 @@ static int _tcp_error(char const * message);
|
||||
static int _tcp_server_add_client(TCP * tcp, TCPSocket * client);
|
||||
|
||||
/* sockets */
|
||||
static int _tcp_socket_init(TCPSocket * tcpsocket, int domain, TCP * tcp);
|
||||
static int _tcp_socket_init(TCPSocket * tcpsocket, int domain, int flags,
|
||||
TCP * tcp);
|
||||
static void _tcp_socket_init_fd(TCPSocket * tcpsocket, TCP * tcp, int fd,
|
||||
struct sockaddr * sa, socklen_t sa_len);
|
||||
static TCPSocket * _tcp_socket_new_fd(TCP * tcp, int fd, struct sockaddr * sa,
|
||||
@ -143,11 +144,14 @@ static int _tcp_socket_callback_write(int fd, TCPSocket * tcpsocket);
|
||||
AppTransportPluginDefinition transport =
|
||||
{
|
||||
"TCP",
|
||||
NULL,
|
||||
#ifndef TRANSPORT_DESCRIPTION
|
||||
# define TRANSPORT_DESCRIPTION "Plain TCP/IP"
|
||||
#endif
|
||||
TRANSPORT_DESCRIPTION,
|
||||
_tcp_init,
|
||||
_tcp_destroy,
|
||||
_tcp_send,
|
||||
_tcp_client_send
|
||||
_tcp_client_send,
|
||||
_tcp_server_send
|
||||
};
|
||||
|
||||
|
||||
@ -199,7 +203,6 @@ static TCP * _tcp_init(AppTransportPluginHelper * helper, AppTransportMode mode,
|
||||
|
||||
static int _init_client(TCP * tcp, char const * name, int domain)
|
||||
{
|
||||
struct addrinfo * aip;
|
||||
#ifdef DEBUG
|
||||
struct sockaddr_in * sa;
|
||||
#endif
|
||||
@ -210,26 +213,27 @@ static int _init_client(TCP * tcp, char const * name, int domain)
|
||||
if((tcp->ai = _init_address(name, domain, 0)) == NULL)
|
||||
return -1;
|
||||
/* connect to the remote host */
|
||||
for(aip = tcp->ai; aip != NULL; aip = aip->ai_next)
|
||||
for(tcp->aip = tcp->ai; tcp->aip != NULL; tcp->aip = tcp->aip->ai_next)
|
||||
{
|
||||
tcp->u.client.fd = -1;
|
||||
/* initialize the client socket */
|
||||
if(_tcp_socket_init(&tcp->u.client, aip->ai_family, tcp) != 0)
|
||||
if(_tcp_socket_init(&tcp->u.client, tcp->aip->ai_family,
|
||||
O_NONBLOCK, tcp) != 0)
|
||||
continue;
|
||||
#ifdef DEBUG
|
||||
if(aip->ai_family == AF_INET)
|
||||
if(tcp->aip->ai_family == AF_INET)
|
||||
{
|
||||
sa = (struct sockaddr_in *)aip->ai_addr;
|
||||
fprintf(stderr, "DEBUG: %s() %s (%s:%u)\n", __func__,
|
||||
"connect()", inet_ntoa(sa->sin_addr),
|
||||
sa = (struct sockaddr_in *)tcp->aip->ai_addr;
|
||||
fprintf(stderr, "DEBUG: %s() connect(%s:%u)\n", __func__,
|
||||
inet_ntoa(sa->sin_addr),
|
||||
ntohs(sa->sin_port));
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "DEBUG: %s() %s %d\n", __func__,
|
||||
"connect()", aip->ai_family);
|
||||
fprintf(stderr, "DEBUG: %s() connect(%d)\n", __func__,
|
||||
tcp->aip->ai_family);
|
||||
#endif
|
||||
if(connect(tcp->u.client.fd, aip->ai_addr, aip->ai_addrlen)
|
||||
!= 0)
|
||||
if(connect(tcp->u.client.fd, tcp->aip->ai_addr,
|
||||
tcp->aip->ai_addrlen) != 0)
|
||||
{
|
||||
if(errno != EINPROGRESS)
|
||||
{
|
||||
@ -242,24 +246,33 @@ static int _init_client(TCP * tcp, char const * name, int domain)
|
||||
tcp->u.client.fd,
|
||||
(EventIOFunc)_tcp_callback_connect,
|
||||
tcp);
|
||||
event_loop(tcp->helper->event);
|
||||
}
|
||||
else
|
||||
/* listen for any incoming message */
|
||||
event_register_io_read(tcp->helper->event,
|
||||
tcp->u.client.fd,
|
||||
(EventIOFunc)_tcp_socket_callback_read,
|
||||
&tcp->u.client);
|
||||
tcp->ai_addrlen = aip->ai_addrlen;
|
||||
break;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s() connect() => %d\n", __func__,
|
||||
tcp->u.client.fd);
|
||||
#endif
|
||||
if(tcp->u.client.fd >= 0)
|
||||
break;
|
||||
}
|
||||
freeaddrinfo(tcp->ai);
|
||||
tcp->ai = NULL;
|
||||
return (aip != NULL) ? 0 : -1;
|
||||
if(tcp->aip == NULL)
|
||||
return -1;
|
||||
/* listen for any incoming message */
|
||||
event_register_io_read(tcp->helper->event, tcp->u.client.fd,
|
||||
(EventIOFunc)_tcp_socket_callback_read, &tcp->u.client);
|
||||
/* write pending messages if any */
|
||||
if(tcp->u.client.bufout_cnt > 0)
|
||||
{
|
||||
event_register_io_write(tcp->helper->event, tcp->u.client.fd,
|
||||
(EventIOFunc)_tcp_socket_callback_write,
|
||||
&tcp->u.client);
|
||||
event_loop(tcp->helper->event);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _init_server(TCP * tcp, char const * name, int domain)
|
||||
{
|
||||
struct addrinfo * aip;
|
||||
TCPSocket tcpsocket;
|
||||
#ifdef DEBUG
|
||||
struct sockaddr_in * sa;
|
||||
@ -269,27 +282,29 @@ static int _init_server(TCP * tcp, char const * name, int domain)
|
||||
/* obtain the local address */
|
||||
if((tcp->ai = _init_address(name, domain, AI_PASSIVE)) == NULL)
|
||||
return -1;
|
||||
for(aip = tcp->ai; aip != NULL; aip = aip->ai_next)
|
||||
for(tcp->aip = tcp->ai; tcp->aip != NULL; tcp->aip = tcp->aip->ai_next)
|
||||
{
|
||||
/* create the socket */
|
||||
if(_tcp_socket_init(&tcpsocket, aip->ai_family, tcp) != 0)
|
||||
if(_tcp_socket_init(&tcpsocket, tcp->aip->ai_family, O_NONBLOCK,
|
||||
tcp) != 0)
|
||||
continue;
|
||||
/* XXX ugly */
|
||||
tcp->u.server.fd = tcpsocket.fd;
|
||||
/* accept incoming connections */
|
||||
#ifdef DEBUG
|
||||
if(aip->ai_family == AF_INET)
|
||||
if(tcp->aip->ai_family == AF_INET)
|
||||
{
|
||||
sa = (struct sockaddr_in *)aip->ai_addr;
|
||||
sa = (struct sockaddr_in *)tcp->aip->ai_addr;
|
||||
fprintf(stderr, "DEBUG: %s() %s (%s:%u)\n", __func__,
|
||||
"bind()", inet_ntoa(sa->sin_addr),
|
||||
ntohs(sa->sin_port));
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "DEBUG: %s() %s %d\n", __func__,
|
||||
"bind()", aip->ai_family);
|
||||
"bind()", tcp->aip->ai_family);
|
||||
#endif
|
||||
if(bind(tcp->u.server.fd, aip->ai_addr, aip->ai_addrlen) != 0)
|
||||
if(bind(tcp->u.server.fd, tcp->aip->ai_addr,
|
||||
tcp->aip->ai_addrlen) != 0)
|
||||
{
|
||||
_tcp_error("bind");
|
||||
close(tcp->u.server.fd);
|
||||
@ -306,14 +321,11 @@ static int _init_server(TCP * tcp, char const * name, int domain)
|
||||
tcp->u.server.fd = -1;
|
||||
continue;
|
||||
}
|
||||
tcp->ai_addrlen = aip->ai_addrlen;
|
||||
event_register_io_read(tcp->helper->event, tcp->u.server.fd,
|
||||
(EventIOFunc)_tcp_callback_accept, tcp);
|
||||
break;
|
||||
}
|
||||
freeaddrinfo(tcp->ai);
|
||||
tcp->ai = NULL;
|
||||
return (aip != NULL) ? 0 : -1;
|
||||
return (tcp->aip != NULL) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
@ -358,7 +370,26 @@ static void _destroy_server(TCP * tcp)
|
||||
|
||||
|
||||
/* tcp_client_send */
|
||||
static int _tcp_client_send(TCP * tcp, AppTransportClient * client,
|
||||
static int _tcp_client_send(TCP * tcp, AppMessage * message)
|
||||
{
|
||||
int ret;
|
||||
Buffer * buffer;
|
||||
|
||||
if(tcp->mode != ATM_CLIENT)
|
||||
return -error_set_code(1, "%s", "Not a client");
|
||||
/* send the message */
|
||||
if((buffer = buffer_new(0, NULL)) == NULL)
|
||||
return -1;
|
||||
if((ret = appmessage_serialize(message, buffer)) == 0
|
||||
&& (ret = _tcp_socket_queue(&tcp->u.client, buffer)) == 0)
|
||||
event_loop(tcp->helper->event);
|
||||
buffer_delete(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* tcp_server_send */
|
||||
static int _tcp_server_send(TCP * tcp, AppTransportClient * client,
|
||||
AppMessage * message)
|
||||
{
|
||||
size_t i;
|
||||
@ -389,27 +420,6 @@ static int _tcp_client_send(TCP * tcp, AppTransportClient * client,
|
||||
}
|
||||
|
||||
|
||||
/* tcp_send */
|
||||
static int _tcp_send(TCP * tcp, AppMessage * message)
|
||||
{
|
||||
Buffer * buffer;
|
||||
|
||||
if(tcp->mode != ATM_CLIENT)
|
||||
return -error_set_code(1, "%s", "Not a client");
|
||||
/* send the message */
|
||||
if((buffer = buffer_new(0, NULL)) == NULL)
|
||||
return -1;
|
||||
if(appmessage_serialize(message, buffer) != 0
|
||||
|| _tcp_socket_queue(&tcp->u.client, buffer) != 0)
|
||||
{
|
||||
buffer_delete(buffer);
|
||||
return -1;
|
||||
}
|
||||
buffer_delete(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* useful */
|
||||
/* tcp_error */
|
||||
static int _tcp_error(char const * message)
|
||||
@ -457,23 +467,27 @@ static int _tcp_server_add_client(TCP * tcp, TCPSocket * client)
|
||||
|
||||
/* sockets */
|
||||
/* tcp_socket_init */
|
||||
static int _tcp_socket_init(TCPSocket * tcpsocket, int domain, TCP * tcp)
|
||||
static int _tcp_socket_init(TCPSocket * tcpsocket, int domain, int flags,
|
||||
TCP * tcp)
|
||||
{
|
||||
int flags;
|
||||
int f;
|
||||
|
||||
if((tcpsocket->fd = socket(domain, SOCK_STREAM, 0)) < 0)
|
||||
return -_tcp_error("socket");
|
||||
_tcp_socket_init_fd(tcpsocket, tcp, tcpsocket->fd, NULL, 0);
|
||||
/* set the socket as non-blocking */
|
||||
if((flags = fcntl(tcpsocket->fd, F_GETFL)) == -1)
|
||||
return -_tcp_error("fcntl");
|
||||
if((flags & O_NONBLOCK) == 0)
|
||||
if(fcntl(tcpsocket->fd, F_SETFL, flags | O_NONBLOCK) == -1)
|
||||
/* set the socket flags */
|
||||
if(flags != 0)
|
||||
{
|
||||
if((f = fcntl(tcpsocket->fd, F_GETFL)) == -1)
|
||||
return -_tcp_error("fcntl");
|
||||
if((f & flags) != flags)
|
||||
if(fcntl(tcpsocket->fd, F_SETFL, f | flags) == -1)
|
||||
return -_tcp_error("fcntl");
|
||||
}
|
||||
#ifdef TCP_NODELAY
|
||||
/* do not wait before sending any traffic */
|
||||
flags = 1;
|
||||
setsockopt(fd, SOL_SOCKET, TCP_NODELAY, &flags, sizeof(flags));
|
||||
f = 1;
|
||||
setsockopt(fd, SOL_SOCKET, TCP_NODELAY, &f, sizeof(f));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -593,7 +607,7 @@ static int _accept_client(TCP * tcp, int fd, struct sockaddr * sa,
|
||||
static int _tcp_callback_accept(int fd, TCP * tcp)
|
||||
{
|
||||
struct sockaddr * sa;
|
||||
socklen_t sa_len = tcp->ai_addrlen;
|
||||
socklen_t sa_len = tcp->aip->ai_addrlen;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%d)\n", __func__, fd);
|
||||
@ -652,8 +666,8 @@ static int _accept_client(TCP * tcp, int fd, struct sockaddr * sa,
|
||||
/* tcp_callback_connect */
|
||||
static int _tcp_callback_connect(int fd, TCP * tcp)
|
||||
{
|
||||
int res;
|
||||
socklen_t s = sizeof(res);
|
||||
int ret;
|
||||
socklen_t s = sizeof(ret);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%d)\n", __func__, fd);
|
||||
@ -662,7 +676,7 @@ static int _tcp_callback_connect(int fd, TCP * tcp)
|
||||
if(tcp->u.client.fd != fd)
|
||||
return -1;
|
||||
/* obtain the connection status */
|
||||
if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &res, &s) != 0)
|
||||
if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &s) != 0)
|
||||
{
|
||||
error_set_code(-errno, "%s: %s", "getsockopt", strerror(errno));
|
||||
close(fd);
|
||||
@ -671,33 +685,29 @@ static int _tcp_callback_connect(int fd, TCP * tcp)
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s() %s\n", __func__, strerror(errno));
|
||||
#endif
|
||||
return -1;
|
||||
ret = -1;
|
||||
}
|
||||
if(res != 0)
|
||||
else if(ret != 0)
|
||||
{
|
||||
/* the connection failed */
|
||||
error_set_code(-res, "%s: %s", "connect", strerror(res));
|
||||
error_set_code(-ret, "%s: %s", "connect", strerror(ret));
|
||||
close(fd);
|
||||
tcp->u.client.fd = -1;
|
||||
/* FIXME report error */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s() %s\n", __func__, strerror(res));
|
||||
fprintf(stderr, "DEBUG: %s() %s\n", __func__, strerror(ret));
|
||||
#endif
|
||||
return -1;
|
||||
ret = -1;
|
||||
}
|
||||
/* listen for any incoming message */
|
||||
event_register_io_read(tcp->helper->event, fd,
|
||||
(EventIOFunc)_tcp_socket_callback_read,
|
||||
&tcp->u.client);
|
||||
/* write pending messages if any */
|
||||
if(tcp->u.client.bufout_cnt > 0)
|
||||
{
|
||||
event_register_io_write(tcp->helper->event, fd,
|
||||
(EventIOFunc)_tcp_socket_callback_write,
|
||||
&tcp->u.client);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
else
|
||||
/* deregister this callback */
|
||||
ret = 1;
|
||||
if(tcp->mode == ATM_CLIENT)
|
||||
event_loop_quit(tcp->helper->event);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s() => %d\n", __func__, ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -755,7 +765,7 @@ static AppMessage * _socket_callback_message(TCPSocket * tcpsocket)
|
||||
tcpsocket->bufin_cnt -= size;
|
||||
memmove(tcpsocket->bufin, &tcpsocket->bufin[size],
|
||||
tcpsocket->bufin_cnt);
|
||||
if((variable_get_as(variable, VT_BUFFER, &buffer)) == 0)
|
||||
if((variable_get_as(variable, VT_BUFFER, &buffer, NULL)) == 0)
|
||||
{
|
||||
message = appmessage_new_deserialize(buffer);
|
||||
buffer_delete(buffer);
|
||||
@ -850,6 +860,10 @@ static int _tcp_socket_callback_write(int fd, TCPSocket * tcpsocket)
|
||||
tcpsocket->bufout_cnt -= ssize;
|
||||
/* unregister the callback if there is nothing left to write */
|
||||
if(tcpsocket->bufout_cnt == 0)
|
||||
{
|
||||
if(tcpsocket->tcp->mode == ATM_CLIENT)
|
||||
event_loop_quit(tcpsocket->tcp->helper->event);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012-2013 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -15,5 +15,6 @@
|
||||
|
||||
|
||||
|
||||
#define TCP_DOMAIN AF_INET
|
||||
#define TCP_DOMAIN AF_INET
|
||||
#define TRANSPORT_DESCRIPTION "Plain TCP/IP (IPv4 only)"
|
||||
#include "tcp.c"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012-2013 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -16,4 +16,5 @@
|
||||
|
||||
|
||||
#define TCP_DOMAIN AF_INET6
|
||||
#define TRANSPORT_DESCRIPTION "Plain TCP/IP (IPv6 only)"
|
||||
#include "tcp.c"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -89,13 +89,13 @@ static Template * _template_init(AppTransportPluginHelper * helper,
|
||||
|
||||
static int _init_client(Template * template, char const * name)
|
||||
{
|
||||
/* FIXME really implement */
|
||||
/* TODO implement */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _init_server(Template * template, char const * name)
|
||||
{
|
||||
/* FIXME really implement */
|
||||
/* TODO implement */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -103,6 +103,6 @@ static int _init_server(Template * template, char const * name)
|
||||
/* template_destroy */
|
||||
static void _template_destroy(Template * template)
|
||||
{
|
||||
/* FIXME really implement */
|
||||
/* TODO implement */
|
||||
object_delete(template);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012-2016 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -126,7 +126,10 @@ static int _udp_callback_read(int fd, UDP * udp);
|
||||
AppTransportPluginDefinition transport =
|
||||
{
|
||||
"UDP",
|
||||
NULL,
|
||||
#ifndef TRANSPORT_DESCRIPTION
|
||||
# define TRANSPORT_DESCRIPTION "Plain UDP"
|
||||
#endif
|
||||
TRANSPORT_DESCRIPTION,
|
||||
_udp_init,
|
||||
_udp_destroy,
|
||||
_udp_send,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -16,4 +16,5 @@
|
||||
|
||||
|
||||
#define UDP_DOMAIN AF_INET
|
||||
#define TRANSPORT_DESCRIPTION "Plain UDP (IPv4 only)"
|
||||
#include "udp.c"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2012 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2012-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -16,4 +16,5 @@
|
||||
|
||||
|
||||
#define UDP_DOMAIN AF_INET6
|
||||
#define TRANSPORT_DESCRIPTION "Plain UDP (IPv6 only)"
|
||||
#include "udp.c"
|
||||
|
4
tests/.gitignore
vendored
4
tests/.gitignore
vendored
@ -1,4 +1,6 @@
|
||||
/AppBroker
|
||||
/Dummy.h
|
||||
/Test.h
|
||||
/appclient
|
||||
/appinterface
|
||||
/appmessage
|
||||
@ -6,5 +8,7 @@
|
||||
/fixme.log
|
||||
/includes
|
||||
/lookup
|
||||
/pkgconfig.log
|
||||
/shlint.log
|
||||
/tests.log
|
||||
/transport
|
||||
|
18
tests/appbroker.c
Normal file
18
tests/appbroker.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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, version 3 of the License.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
|
||||
#include "../tools/appbroker.c"
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2011-2019 Pierre Pronchery <khorben@defora.org>
|
||||
#Copyright (c) 2011-2020 Pierre Pronchery <khorben@defora.org>
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
@ -27,7 +27,7 @@
|
||||
#variables
|
||||
PROGNAME="appbroker.sh"
|
||||
#executables
|
||||
APPBROKER="AppBroker"
|
||||
APPBROKER=
|
||||
DEBUG="_debug"
|
||||
|
||||
|
||||
@ -85,6 +85,17 @@ fi
|
||||
|
||||
[ "$clean" -ne 0 ] && exit 0
|
||||
|
||||
if [ -z "$APPBROKER" ]; then
|
||||
if [ -n "$PKG_CONFIG_SYSROOT_DIR" ]; then
|
||||
#XXX cross-compiling (requires AppBroker(1) installed)
|
||||
APPBROKER="AppBroker$EXEEXT"
|
||||
elif [ -n "$OBJDIR" ]; then
|
||||
APPBROKER="${OBJDIR}AppBroker$EXEEXT"
|
||||
else
|
||||
APPBROKER="./AppBroker$EXEEXT"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec 3>&1
|
||||
while [ $# -gt 0 ]; do
|
||||
target="$1"
|
||||
@ -92,6 +103,8 @@ while [ $# -gt 0 ]; do
|
||||
|
||||
source="${target#$OBJDIR}"
|
||||
appinterface="${source##*/}"
|
||||
appinterface="${appinterface%%.h}.interface"
|
||||
appinterface="${appinterface%.h}.interface"
|
||||
#XXX also look in ../data
|
||||
[ ! -f "$appinterface" ] && appinterface="../data/$appinterface"
|
||||
_appbroker "$target" "$appinterface" || exit 2
|
||||
done
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2014 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2014-2020 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -19,7 +19,6 @@
|
||||
#include <stdio.h>
|
||||
#include <System/error.h>
|
||||
#include "App/appserver.h"
|
||||
/* FIXME does not survive OBJDIR */
|
||||
#include "Dummy.h"
|
||||
|
||||
|
||||
|
130
tests/fixme.sh
130
tests/fixme.sh
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2017-2019 Pierre Pronchery <khorben@defora.org>
|
||||
#Copyright (c) 2017-2022 Pierre Pronchery <khorben@defora.org>
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
@ -25,23 +25,30 @@
|
||||
|
||||
|
||||
#variables
|
||||
CONFIGSH="${0%/fixme.sh}/../config.sh"
|
||||
PROGNAME="fixme.sh"
|
||||
PROJECTCONF="../project.conf"
|
||||
REGEXP_ERROR="FIXME"
|
||||
REGEXP_WARNING="\\(TODO\|XXX\\)"
|
||||
#executables
|
||||
DATE="date"
|
||||
DEBUG="_debug"
|
||||
FIND="find"
|
||||
GREP="grep"
|
||||
HEAD="head"
|
||||
MKDIR="mkdir -p"
|
||||
SORT="sort -n"
|
||||
TR="tr"
|
||||
|
||||
[ -f "$CONFIGSH" ] && . "$CONFIGSH"
|
||||
|
||||
|
||||
#functions
|
||||
#fixme
|
||||
_fixme()
|
||||
{
|
||||
res=0
|
||||
subdirs=
|
||||
|
||||
$DATE
|
||||
echo
|
||||
@ -56,27 +63,14 @@ _fixme()
|
||||
;;
|
||||
esac
|
||||
done < "$PROJECTCONF"
|
||||
if [ ! -n "$subdirs" ]; then
|
||||
_error "Could not locate directories to analyze"
|
||||
return $?
|
||||
fi
|
||||
for subdir in $subdirs; do
|
||||
[ -d "../$subdir" ] || continue
|
||||
for filename in $($FIND "../$subdir" -type f | $SORT); do
|
||||
callback=
|
||||
ext=${filename##*/}
|
||||
ext=${ext%.in}
|
||||
ext=${ext##*.}
|
||||
case "$ext" in
|
||||
asm|S)
|
||||
callback="_fixme_asm"
|
||||
;;
|
||||
c|cc|cpp|cxx|h|js)
|
||||
callback="_fixme_c"
|
||||
;;
|
||||
conf|sh)
|
||||
callback="_fixme_sh"
|
||||
;;
|
||||
htm|html|xml)
|
||||
callback="_fixme_xml"
|
||||
;;
|
||||
esac
|
||||
callback=$(_fixme_callback "$filename")
|
||||
[ -n "$callback" ] || continue
|
||||
($callback "$filename") 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
@ -88,54 +82,114 @@ _fixme()
|
||||
return $res
|
||||
}
|
||||
|
||||
_fixme_asm()
|
||||
_fixme_callback()
|
||||
{
|
||||
filename="$1"
|
||||
ext=${filename##*/}
|
||||
ext=${ext%.in}
|
||||
ext=${ext##*.}
|
||||
callback=
|
||||
|
||||
case "$ext" in
|
||||
asm|S)
|
||||
echo "_fixme_callback_asm"
|
||||
return 0
|
||||
;;
|
||||
c|cc|cpp|cxx|go|h|js|v)
|
||||
echo "_fixme_callback_c"
|
||||
return 0
|
||||
;;
|
||||
conf|sh)
|
||||
echo "_fixme_callback_sh"
|
||||
return 0
|
||||
;;
|
||||
py)
|
||||
echo "_fixme_callback_python"
|
||||
return 0
|
||||
;;
|
||||
htm|html|xml|xsl)
|
||||
echo "_fixme_callback_xml"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
case $($HEAD -n 1 "$filename") in
|
||||
"#!/bin/sh"*|"#! /bin/sh"*|\
|
||||
"#!/usr/bin/env bash"*|"#! /usr/bin/env bash"*)
|
||||
echo "_fixme_callback_sh"
|
||||
return 0
|
||||
;;
|
||||
"#!/usr/bin/env python"*|"#! /usr/bin/env python"*)
|
||||
echo "_fixme_callback_python"
|
||||
return 0
|
||||
;;
|
||||
"<!DOCTYPE"*|"<!doctype"*|"<HTML"*|"<html"*|"<?xml"*)
|
||||
echo "_fixme_callback_xml"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
return 2
|
||||
}
|
||||
|
||||
_fixme_callback_asm()
|
||||
{
|
||||
res=0
|
||||
filename="$1"
|
||||
|
||||
#warnings
|
||||
$GREP -nH '/\*.*\(TODO\|XXX\)' "$filename"
|
||||
$GREP -nH "/\\*.*$REGEXP_WARNING" "$filename"
|
||||
#failures
|
||||
$GREP -nH '/\*.*FIXME' "$filename" && res=2
|
||||
$GREP -nH "/\\*.*$REGEXP_ERROR" "$filename" && res=2
|
||||
return $res
|
||||
}
|
||||
|
||||
_fixme_c()
|
||||
_fixme_callback_c()
|
||||
{
|
||||
res=0
|
||||
filename="$1"
|
||||
|
||||
#warnings
|
||||
$GREP -nH '/\(/\|\*\).*\(TODO\|XXX\)' "$filename"
|
||||
$GREP -nH "/\\(/\\|\\*\\).*$REGEXP_WARNING" "$filename"
|
||||
#failures
|
||||
$GREP -nH '/\(/\|\*\).*FIXME' "$filename" && res=2
|
||||
$GREP -nH "/\\(/\\|\\*\\).*$REGEXP_ERROR" "$filename" && res=2
|
||||
return $res
|
||||
}
|
||||
|
||||
_fixme_sh()
|
||||
_fixme_callback_python()
|
||||
{
|
||||
res=0
|
||||
filename="$1"
|
||||
#XXX avoid matching the regexp
|
||||
comment="#"
|
||||
|
||||
#warnings
|
||||
$GREP -nH "$comment.*\\(TODO\\|XXX\\)" "$filename"
|
||||
$GREP -nH "$comment.*$REGEXP_WARNING" "$filename"
|
||||
#failures
|
||||
$GREP -nH "$comment.*FIXME" "$filename" && res=2
|
||||
$GREP -nH "$comment.*$REGEXP_ERROR" "$filename" && res=2
|
||||
return $res
|
||||
}
|
||||
|
||||
_fixme_xml()
|
||||
_fixme_callback_sh()
|
||||
{
|
||||
res=0
|
||||
filename="$1"
|
||||
comment="#"
|
||||
|
||||
#warnings
|
||||
$GREP -nH "$comment.*$REGEXP_WARNING" "$filename"
|
||||
#failures
|
||||
$GREP -nH "$comment.*$REGEXP_ERROR" "$filename" && res=2
|
||||
return $res
|
||||
}
|
||||
|
||||
_fixme_callback_xml()
|
||||
{
|
||||
res=0
|
||||
filename="$1"
|
||||
|
||||
#XXX limited to a single line
|
||||
#warnings
|
||||
$GREP -nH '<!--.*\(TODO\|XXX\)' "$filename"
|
||||
$GREP -nH "<!--.*$REGEXP_WARNING" "$filename"
|
||||
#failures
|
||||
$GREP -nH '<!--.*FIXME' "$filename" && res=2
|
||||
$GREP -nH "<!--.*$REGEXP_ERROR" "$filename" && res=2
|
||||
return $res
|
||||
}
|
||||
|
||||
@ -145,10 +199,14 @@ _debug()
|
||||
{
|
||||
echo "$@" 1>&3
|
||||
"$@"
|
||||
res=$?
|
||||
#ignore errors when the command is not available
|
||||
[ $res -eq 127 ] && return 0
|
||||
return $res
|
||||
}
|
||||
|
||||
|
||||
#error
|
||||
_error()
|
||||
{
|
||||
echo "$PROGNAME: $@" 1>&2
|
||||
return 2
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2016 Pierre Pronchery <khorben@defora.org>
|
||||
#Copyright (c) 2016-2025 Pierre Pronchery <khorben@defora.org>
|
||||
#This file is part of DeforaOS Desktop libDesktop
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
@ -23,35 +23,94 @@
|
||||
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
|
||||
#variables
|
||||
PACKAGE="libApp"
|
||||
CONFIGSH="${0%/pkgconfig.sh}/../config.sh"
|
||||
PKG_CONFIG_PATH="$OBJDIR../data:$PKG_CONFIG_PATH"
|
||||
PKG_CONFIG_PATH="${PKG_CONFIG_PATH%:}"
|
||||
PROGNAME="pkgconfig.sh"
|
||||
#executables
|
||||
ECHO="echo"
|
||||
PKGCONFIG="pkg-config"
|
||||
UNAME="uname"
|
||||
[ "$($UNAME -s)" != "Darwin" ] || ECHO="/bin/echo"
|
||||
|
||||
[ -f "$CONFIGSH" ] && . "$CONFIGSH"
|
||||
|
||||
|
||||
#functions
|
||||
#pkgconfig
|
||||
_pkgconfig()
|
||||
{
|
||||
{(
|
||||
ret=0
|
||||
|
||||
_pkgconfig_do "EXISTS:" --exists "$PACKAGE" || return 2
|
||||
|
||||
_pkgconfig_do "VERSION:" --modversion "$PACKAGE" || ret=3
|
||||
_pkgconfig_do "CFLAGS: " --cflags "$PACKAGE" || ret=4
|
||||
_pkgconfig_do "LIBS: " --libs "$PACKAGE" || ret=5
|
||||
_pkgconfig_do "PROVIDES:" --print-provides "$PACKAGE" || ret=6
|
||||
_pkgconfig_do "REQUIRES:" --print-requires "$PACKAGE" || ret=7
|
||||
return $ret
|
||||
)}
|
||||
|
||||
_pkgconfig_do()
|
||||
{
|
||||
caption="$1"
|
||||
options="$2"
|
||||
packages="$3"
|
||||
|
||||
echo -n "$caption"
|
||||
output=$($PKGCONFIG $options "$packages")
|
||||
ret=$?
|
||||
echo "$output"
|
||||
return $ret
|
||||
$ECHO -n "$caption"
|
||||
PKG_CONFIG_PATH="$PKG_CONFIG_PATH" $PKGCONFIG $options "$packages"
|
||||
}
|
||||
|
||||
_pkgconfig "EXISTS:" --exists "$PACKAGE" || exit 2
|
||||
|
||||
#usage
|
||||
_usage()
|
||||
{
|
||||
echo "Usage: $PROGNAME [-c] target..." 1>&2
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
#main
|
||||
clean=0
|
||||
while getopts "cO:P:" name; do
|
||||
case "$name" in
|
||||
c)
|
||||
clean=1
|
||||
;;
|
||||
O)
|
||||
export "${OPTARG%%=*}"="${OPTARG#*=}"
|
||||
;;
|
||||
P)
|
||||
#XXX ignored for compatibility
|
||||
;;
|
||||
?)
|
||||
_usage
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
if [ $# -lt 1 ]; then
|
||||
_usage
|
||||
exit $?
|
||||
fi
|
||||
|
||||
#clean
|
||||
[ $clean -ne 0 ] && exit 0
|
||||
|
||||
exec 3>&1
|
||||
ret=0
|
||||
while [ $# -gt 0 ]; do
|
||||
target="$1"
|
||||
dirname="${target%/*}"
|
||||
shift
|
||||
|
||||
_pkgconfig "VERSION:" --modversion "$PACKAGE" || ret=3
|
||||
_pkgconfig "CFLAGS: " --cflags "$PACKAGE" || ret=4
|
||||
_pkgconfig "LIBS: " --libs "$PACKAGE" || ret=5
|
||||
_pkgconfig "PROVIDES:" --print-provides "$PACKAGE" || ret=6
|
||||
_pkgconfig "REQUIRES:" --print-requires "$PACKAGE" || ret=7
|
||||
|
||||
if [ -n "$dirname" -a "$dirname" != "$target" ]; then
|
||||
$MKDIR -- "$dirname" || ret=$?
|
||||
fi
|
||||
_pkgconfig > "$target" || ret=$?
|
||||
done
|
||||
exit $ret
|
||||
|
@ -1,49 +1,43 @@
|
||||
targets=Dummy.h,appclient,appinterface,appmessage,appserver,fixme.log,includes,lookup,shlint.log,tests.log,transport
|
||||
cppflags_force=-I../include -I$(OBJDIR).
|
||||
targets=AppBroker,Dummy.h,appclient,appinterface,appmessage,appserver,fixme.log,includes,lookup,pkgconfig.log,shlint.log,tests.log,transport
|
||||
cppflags_force=-I../include -I. -I$(OBJDIR).
|
||||
cflags_force=`pkg-config --cflags libSystem`
|
||||
cflags=-W -Wall -g -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector-all
|
||||
cflags=-W -Wall -g -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector
|
||||
ldflags_force=`pkg-config --libs libSystem` -L$(OBJDIR)../src -Wl,-rpath,$(OBJDIR)../src -lApp
|
||||
ldflags=-pie -Wl,-z,relro -Wl,-z,now -rdynamic
|
||||
dist=System/App.h,appbroker.sh,fixme.sh,Makefile,Test.expected,Test.interface,pkgconfig.sh,shlint.sh,tests.sh
|
||||
|
||||
#targets
|
||||
[AppBroker]
|
||||
type=binary
|
||||
sources=appbroker.c
|
||||
depends=$(OBJDIR)../src/libApp.a
|
||||
ldflags=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[Dummy.h]
|
||||
type=script
|
||||
script=../tools/appbroker.sh
|
||||
flags=-O APPBROKER=$(OBJDIR)../tools/AppBroker$(EXEEXT)
|
||||
depends=../data/Dummy.interface,../tools/appbroker.sh
|
||||
script=./appbroker.sh
|
||||
depends=../data/Dummy.interface,appbroker.sh
|
||||
|
||||
[appclient]
|
||||
type=binary
|
||||
sources=appclient.c
|
||||
ldflags=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appclient.c]
|
||||
depends=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appinterface]
|
||||
type=binary
|
||||
sources=appinterface.c
|
||||
ldflags=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appinterface.c]
|
||||
depends=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appmessage]
|
||||
type=binary
|
||||
sources=appmessage.c
|
||||
ldflags=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appmessage.c]
|
||||
depends=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appserver]
|
||||
type=binary
|
||||
sources=appserver.c
|
||||
ldflags=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appserver.c]
|
||||
depends=$(OBJDIR)../src/libApp.a,$(OBJDIR)Dummy.h
|
||||
|
||||
[fixme.log]
|
||||
type=script
|
||||
script=./fixme.sh
|
||||
@ -58,22 +52,46 @@ sources=includes.c
|
||||
type=binary
|
||||
sources=lookup.c
|
||||
|
||||
[lookup.c]
|
||||
depends=../src/apptransport.h
|
||||
[pkgconfig.log]
|
||||
type=script
|
||||
script=./pkgconfig.sh
|
||||
depends=$(OBJDIR)../data/libApp.pc,pkgconfig.sh
|
||||
enabled=0
|
||||
|
||||
[shlint.log]
|
||||
type=script
|
||||
script=./shlint.sh
|
||||
depends=$(OBJDIR)../src/libApp.a,shlint.sh
|
||||
enabled=0
|
||||
|
||||
[tests.log]
|
||||
type=script
|
||||
script=./tests.sh
|
||||
depends=Test.expected,Test.interface,$(OBJDIR)../tools/AppBroker$(EXEEXT),appbroker.sh,$(OBJDIR)appclient$(EXEEXT),$(OBJDIR)appmessage$(EXEEXT),$(OBJDIR)appserver$(EXEEXT),$(OBJDIR)includes$(EXEEXT),$(OBJDIR)lookup$(EXEEXT),pkgconfig.sh,tests.sh,$(OBJDIR)transport$(EXEEXT),../src/transport/tcp.c,../src/transport/udp.c
|
||||
depends=Test.expected,Test.interface,$(OBJDIR)AppBroker$(EXEEXT),appbroker.sh,$(OBJDIR)appclient$(EXEEXT),$(OBJDIR)appmessage$(EXEEXT),$(OBJDIR)appserver$(EXEEXT),$(OBJDIR)includes$(EXEEXT),$(OBJDIR)lookup$(EXEEXT),tests.sh,$(OBJDIR)transport$(EXEEXT),../src/transport/tcp.c,../src/transport/udp.c
|
||||
enabled=0
|
||||
|
||||
[transport]
|
||||
type=binary
|
||||
sources=transport.c
|
||||
|
||||
#sources
|
||||
[appbroker.c]
|
||||
depends=../tools/appbroker.c
|
||||
|
||||
[appclient.c]
|
||||
depends=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appinterface.c]
|
||||
depends=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appmessage.c]
|
||||
depends=$(OBJDIR)../src/libApp.a
|
||||
|
||||
[appserver.c]
|
||||
depends=$(OBJDIR)../src/libApp.a,$(OBJDIR)Dummy.h
|
||||
|
||||
[lookup.c]
|
||||
depends=../src/apptransport.h
|
||||
|
||||
[transport.c]
|
||||
depends=$(OBJDIR)../src/libApp.a
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2014-2017 Pierre Pronchery <khorben@defora.org>
|
||||
#Copyright (c) 2014-2021 Pierre Pronchery <khorben@defora.org>
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
@ -25,26 +25,30 @@
|
||||
|
||||
|
||||
#variables
|
||||
CONFIGSH="${0%/shlint.sh}/../config.sh"
|
||||
PROGNAME="shlint.sh"
|
||||
PROJECTCONF="../project.conf"
|
||||
#executables
|
||||
DATE="date"
|
||||
DEBUG="_debug"
|
||||
ECHO="/bin/echo"
|
||||
FIND="find"
|
||||
MKDIR="mkdir -p"
|
||||
SHLINT="sh -n"
|
||||
SORT="sort -n"
|
||||
TR="tr"
|
||||
|
||||
[ -f "$CONFIGSH" ] && . "$CONFIGSH"
|
||||
|
||||
|
||||
#functions
|
||||
#shlint
|
||||
_shlint()
|
||||
{
|
||||
ret=0
|
||||
subdirs="data doc src tests tools"
|
||||
res=0
|
||||
subdirs=
|
||||
|
||||
$DATE
|
||||
echo
|
||||
while read line; do
|
||||
case "$line" in
|
||||
"["*)
|
||||
@ -56,19 +60,30 @@ _shlint()
|
||||
;;
|
||||
esac
|
||||
done < "$PROJECTCONF"
|
||||
if [ ! -n "$subdirs" ]; then
|
||||
_error "Could not locate directories to analyze"
|
||||
return $?
|
||||
fi
|
||||
for subdir in $subdirs; do
|
||||
[ -d "../$subdir" ] || continue
|
||||
for filename in $($FIND "../$subdir" -type f -a -name '*.sh' | $SORT); do
|
||||
while read filename; do
|
||||
[ -n "$filename" ] || continue
|
||||
echo
|
||||
$ECHO -n "$filename:"
|
||||
_shlint_file "$filename"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "$filename:"
|
||||
echo " OK"
|
||||
echo "$PROGNAME: $filename: OK" 1>&2
|
||||
else
|
||||
echo "FAIL"
|
||||
echo "$PROGNAME: $filename: FAIL" 1>&2
|
||||
ret=2
|
||||
res=2
|
||||
fi
|
||||
done
|
||||
done << EOF
|
||||
$($FIND "../$subdir" -type f -a -iname '*.sh' | $SORT)
|
||||
EOF
|
||||
done
|
||||
return $ret
|
||||
return $res
|
||||
}
|
||||
|
||||
_shlint_file()
|
||||
@ -88,7 +103,7 @@ _shlint_file()
|
||||
esac
|
||||
done < "$filename"
|
||||
if [ $warn -ne 0 ]; then
|
||||
_warning "$filename: return instead of exit in the global scope"
|
||||
_error "$filename: return instead of exit in the global scope"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@ -99,10 +114,14 @@ _debug()
|
||||
{
|
||||
echo "$@" 1>&3
|
||||
"$@"
|
||||
res=$?
|
||||
#ignore errors when the command is not available
|
||||
[ $res -eq 127 ] && return 0
|
||||
return $res
|
||||
}
|
||||
|
||||
|
||||
#error
|
||||
_error()
|
||||
{
|
||||
echo "$PROGNAME: $@" 1>&2
|
||||
return 2
|
||||
}
|
||||
|
||||
|
||||
@ -114,14 +133,6 @@ _usage()
|
||||
}
|
||||
|
||||
|
||||
#warning
|
||||
_warning()
|
||||
{
|
||||
echo "$PROGNAME: $@" 1>&2
|
||||
return 2
|
||||
}
|
||||
|
||||
|
||||
#main
|
||||
clean=0
|
||||
while getopts "cO:P:" name; do
|
||||
@ -151,9 +162,15 @@ fi
|
||||
[ $clean -ne 0 ] && exit 0
|
||||
|
||||
exec 3>&1
|
||||
ret=0
|
||||
while [ $# -gt 0 ]; do
|
||||
target="$1"
|
||||
dirname="${target%/*}"
|
||||
shift
|
||||
|
||||
_shlint > "$target" || exit 2
|
||||
if [ -n "$dirname" -a "$dirname" != "$target" ]; then
|
||||
$MKDIR -- "$dirname" || ret=$?
|
||||
fi
|
||||
_shlint > "$target" || ret=$?
|
||||
done
|
||||
exit $ret
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2012-2019 Pierre Pronchery <khorben@defora.org>
|
||||
#Copyright (c) 2012-2025 Pierre Pronchery <khorben@defora.org>
|
||||
#This file is part of DeforaOS System libApp
|
||||
#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
|
||||
@ -20,6 +20,9 @@ PROGNAME="tests.sh"
|
||||
#executables
|
||||
DATE="date"
|
||||
DEBUG="_debug"
|
||||
ECHO="echo"
|
||||
UNAME="uname"
|
||||
[ "$($UNAME -s)" != "Darwin" ] || ECHO="/bin/echo"
|
||||
|
||||
|
||||
#functions
|
||||
@ -67,7 +70,7 @@ _run()
|
||||
|
||||
shift
|
||||
shift
|
||||
echo -n "$test:" 1>&2
|
||||
$ECHO -n "$test:" 1>&2
|
||||
(echo
|
||||
echo "Testing: $test $name ($OBJDIR)"
|
||||
[ -n "$OBJDIR" ] || OBJDIR="./"
|
||||
@ -159,7 +162,6 @@ while [ $# -ne 0 ]; do
|
||||
-n "tcp4:localhost:4242"
|
||||
APPSERVER_Session="tcp:localhost:4242" _test "lookup" \
|
||||
"lookup Session" -a "Session"
|
||||
_test "pkgconfig.sh" "pkg-config"
|
||||
_test "transport" "tcp4 127.0.0.1:4242" -p tcp4 127.0.0.1:4242
|
||||
_test "transport" "tcp4 localhost:4242" -p tcp4 localhost:4242
|
||||
_test "transport" "tcp6 ::1.4242" -p tcp6 ::1.4242
|
||||
|
1
tools/.gitignore
vendored
1
tools/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/AppBroker
|
||||
/AppClient
|
||||
/AppTransport
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2011-2016 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2011-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -20,9 +20,12 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <System.h>
|
||||
#include "App.h"
|
||||
#include "App/appserver.h"
|
||||
#include "App/apptransport.h"
|
||||
|
||||
#define PROGNAME_APPBROKER "AppBroker"
|
||||
#ifndef PROGNAME_APPBROKER
|
||||
# define PROGNAME_APPBROKER "AppBroker"
|
||||
#endif
|
||||
|
||||
|
||||
/* AppBroker */
|
||||
@ -325,7 +328,7 @@ static int _appbroker_foreach_call_arg(AppBroker * appbroker, char const * sep,
|
||||
}
|
||||
if(appbroker->fp != NULL)
|
||||
fprintf(appbroker->fp, "%s%s%s%s", sep, ctype,
|
||||
(p != NULL && string_length(p + 1)) ? " " : "",
|
||||
(p != NULL && string_get_length(p + 1)) ? " " : "",
|
||||
(p != NULL) ? p + 1 : "");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,106 +0,0 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2011-2016 Pierre Pronchery <khorben@defora.org>
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
#IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
#FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
#DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
#SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
#OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
|
||||
#variables
|
||||
PROGNAME="appbroker.sh"
|
||||
#executables
|
||||
APPBROKER=
|
||||
DEBUG="_debug"
|
||||
|
||||
|
||||
#functions
|
||||
#appbroker
|
||||
_appbroker()
|
||||
{
|
||||
target="$1"
|
||||
appinterface="$2"
|
||||
|
||||
$DEBUG $APPBROKER -o "$target" "$appinterface"
|
||||
}
|
||||
|
||||
|
||||
#debug
|
||||
_debug()
|
||||
{
|
||||
echo "$@" 1>&3
|
||||
"$@"
|
||||
}
|
||||
|
||||
|
||||
#usage
|
||||
_usage()
|
||||
{
|
||||
echo "Usage: $PROGNAME [-c] target..." 1>&2
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
#main
|
||||
clean=0
|
||||
while getopts "cO:P:" name; do
|
||||
case "$name" in
|
||||
c)
|
||||
clean=1
|
||||
;;
|
||||
O)
|
||||
export "${OPTARG%%=*}"="${OPTARG#*=}"
|
||||
;;
|
||||
P)
|
||||
#XXX ignored for compatibility
|
||||
;;
|
||||
?)
|
||||
_usage
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
if [ $# -eq 0 ]; then
|
||||
_usage
|
||||
exit $?
|
||||
fi
|
||||
|
||||
[ "$clean" -ne 0 ] && exit 0
|
||||
|
||||
if [ -n "$PKG_CONFIG_SYSROOT_DIR" ]; then
|
||||
#XXX cross-compiling (requires AppBroker(1) installed)
|
||||
APPBROKER="AppBroker$EXEEXT"
|
||||
elif [ -z "$APPBROKER" ]; then
|
||||
APPBROKER="$OBJDIR../tools/AppBroker$EXEEXT"
|
||||
#XXX ugly workaround
|
||||
export LD_LIBRARY_PATH="$OBJDIR../src"
|
||||
fi
|
||||
|
||||
exec 3>&1
|
||||
while [ $# -gt 0 ]; do
|
||||
target="$1"
|
||||
shift
|
||||
|
||||
source="${target#$OBJDIR}"
|
||||
appinterface="${source##*/}"
|
||||
appinterface="../data/${appinterface%%.h}.interface"
|
||||
_appbroker "$target" "$appinterface" || exit 2
|
||||
done
|
@ -1,5 +1,5 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2011-2016 Pierre Pronchery <khorben@defora.org> */
|
||||
/* Copyright (c) 2011-2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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
|
||||
@ -15,16 +15,17 @@
|
||||
|
||||
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <System.h>
|
||||
#include "App.h"
|
||||
#include "App/appclient.h"
|
||||
|
||||
#ifndef PROGNAME
|
||||
# define PROGNAME "AppClient"
|
||||
#ifndef PROGNAME_APPCLIENT
|
||||
# define PROGNAME_APPCLIENT "AppClient"
|
||||
#endif
|
||||
|
||||
|
||||
@ -75,13 +76,13 @@ static int _appclient(int verbose, char const * app, char const * name,
|
||||
app, name, (void *)calls, calls_cnt);
|
||||
#endif
|
||||
if((ac = appclient_new(NULL, app, name)) == NULL)
|
||||
return _error(PROGNAME, 1);
|
||||
return _error(PROGNAME_APPCLIENT, 1);
|
||||
if(verbose != 0)
|
||||
puts("Connected.");
|
||||
for(i = 0; i < calls_cnt; i++)
|
||||
if(_appclient_call(verbose, ac, &calls[i]) != 0)
|
||||
{
|
||||
ret |= _error(PROGNAME, 1);
|
||||
ret |= _error(PROGNAME_APPCLIENT, 1);
|
||||
break;
|
||||
}
|
||||
if(verbose != 0)
|
||||
@ -95,9 +96,10 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
|
||||
int ret = 0;
|
||||
Variable * v;
|
||||
VariableType type;
|
||||
int64_t res;
|
||||
double dres;
|
||||
int64_t ires;
|
||||
String * sres;
|
||||
uint64_t ures;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||
@ -206,23 +208,35 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
|
||||
{
|
||||
case VT_BOOL:
|
||||
case VT_INT8:
|
||||
case VT_UINT8:
|
||||
case VT_INT16:
|
||||
case VT_UINT16:
|
||||
case VT_INT32:
|
||||
case VT_UINT32:
|
||||
case VT_INT64:
|
||||
if(variable_get_as(v, VT_INT64, &ires, NULL)
|
||||
== 0)
|
||||
printf("\"%s\"%s%" PRId64 "\n",
|
||||
call->name,
|
||||
" returned ", ires);
|
||||
else
|
||||
printf("\"%s\"%s\n", call->name,
|
||||
" returned");
|
||||
break;
|
||||
case VT_UINT8:
|
||||
case VT_UINT16:
|
||||
case VT_UINT32:
|
||||
case VT_UINT64:
|
||||
if(variable_get_as(v, VT_INT64, &res) == 0)
|
||||
printf("\"%s\"%s%ld\n", call->name,
|
||||
" returned ", res);
|
||||
if(variable_get_as(v, VT_UINT64, &ures, NULL)
|
||||
== 0)
|
||||
printf("\"%s\"%s%" PRIu64 "\n",
|
||||
call->name,
|
||||
" returned ", ures);
|
||||
else
|
||||
printf("\"%s\"%s\n", call->name,
|
||||
" returned");
|
||||
break;
|
||||
case VT_FLOAT:
|
||||
case VT_DOUBLE:
|
||||
if(variable_get_as(v, VT_DOUBLE, &dres) == 0)
|
||||
if(variable_get_as(v, VT_DOUBLE, &dres, NULL)
|
||||
== 0)
|
||||
printf("\"%s\"%s%f\n", call->name,
|
||||
" returned ", dres);
|
||||
else
|
||||
@ -231,7 +245,8 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
|
||||
break;
|
||||
case VT_STRING:
|
||||
sres = NULL;
|
||||
if(variable_get_as(v, VT_STRING, &sres) == 0)
|
||||
if(variable_get_as(v, VT_STRING, &sres, NULL)
|
||||
== 0)
|
||||
printf("\"%s\"%s\"%s\"\n", call->name,
|
||||
" returned ", sres);
|
||||
else
|
||||
@ -261,7 +276,7 @@ static int _error(char const * message, int ret)
|
||||
/* usage */
|
||||
static int _usage(void)
|
||||
{
|
||||
fputs("Usage: " PROGNAME " [-v][-H hostname] -S service"
|
||||
fputs("Usage: " PROGNAME_APPCLIENT " [-v][-H hostname] -S service"
|
||||
" [-C call [-d double|-f float|-i integer|-s string]...]...\n"
|
||||
" -v Be more verbose\n"
|
||||
" -H Hostname to connect to\n"
|
||||
@ -328,7 +343,7 @@ int main(int argc, char * argv[])
|
||||
return _usage();
|
||||
}
|
||||
if(res != 0)
|
||||
return _error(PROGNAME, 2);
|
||||
return _error(PROGNAME_APPCLIENT, 2);
|
||||
}
|
||||
if(app == NULL)
|
||||
return _usage();
|
||||
|
132
tools/apptransport.c
Normal file
132
tools/apptransport.c
Normal file
@ -0,0 +1,132 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2025 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS System libApp */
|
||||
/* 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, version 3 of the License.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <System/error.h>
|
||||
#include <System/plugin.h>
|
||||
#include "App/apptransport.h"
|
||||
#include "../config.h"
|
||||
|
||||
#ifndef PROGNAME_APPTRANSPORT
|
||||
# define PROGNAME_APPTRANSPORT "AppTransport"
|
||||
#endif
|
||||
|
||||
|
||||
/* AppTransport */
|
||||
/* private */
|
||||
/* prototypes */
|
||||
static int _apptransport_list(void);
|
||||
|
||||
static int _error(char const * message, int ret);
|
||||
static int _usage(void);
|
||||
|
||||
|
||||
/* functions */
|
||||
/* apptransport_list */
|
||||
static int _apptransport_list(void)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
char const soext[] = ".dylib";
|
||||
#elif defined(__WIN32__)
|
||||
char const soext[] = ".dll";
|
||||
#else
|
||||
char const soext[] = ".so";
|
||||
#endif
|
||||
DIR * dir;
|
||||
struct dirent * de;
|
||||
size_t len;
|
||||
String * path;
|
||||
Plugin * plugin;
|
||||
AppTransportPluginDefinition * transport;
|
||||
|
||||
if((dir = opendir(APP_TRANSPORT_PATH)) == NULL)
|
||||
return _error(APP_TRANSPORT_PATH, -1);
|
||||
while((de = readdir(dir)) != NULL)
|
||||
{
|
||||
if((len = strlen(de->d_name)) < sizeof(soext))
|
||||
continue;
|
||||
if(strcmp(&de->d_name[len - sizeof(soext) + 1], soext) != 0)
|
||||
continue;
|
||||
if((path = string_new_append(APP_TRANSPORT_PATH "/", de->d_name,
|
||||
NULL)) == NULL)
|
||||
{
|
||||
_error(PROGNAME_APPTRANSPORT, -1);
|
||||
continue;
|
||||
}
|
||||
plugin = plugin_new_path(path);
|
||||
string_delete(path);
|
||||
if(plugin == NULL)
|
||||
{
|
||||
_error(PROGNAME_APPTRANSPORT, -1);
|
||||
continue;
|
||||
}
|
||||
if((transport = plugin_lookup(plugin, "transport")) == NULL)
|
||||
{
|
||||
_error(PROGNAME_APPTRANSPORT, -1);
|
||||
plugin_delete(plugin);
|
||||
continue;
|
||||
}
|
||||
de->d_name[len - sizeof(soext) + 1] = '\0';
|
||||
printf("%s (%s): %s\n", de->d_name, transport->name,
|
||||
transport->description);
|
||||
plugin_delete(plugin);
|
||||
}
|
||||
closedir(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* error */
|
||||
static int _error(char const * message, int ret)
|
||||
{
|
||||
error_print(message);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* usage */
|
||||
static int _usage(void)
|
||||
{
|
||||
fputs("Usage: " PROGNAME_APPTRANSPORT " -l\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* public */
|
||||
/* functions */
|
||||
/* main */
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
int o;
|
||||
int list = 0;
|
||||
|
||||
while((o = getopt(argc, argv, "l")) != -1)
|
||||
switch(o)
|
||||
{
|
||||
case 'l':
|
||||
list = 1;
|
||||
break;
|
||||
default:
|
||||
return _usage();
|
||||
}
|
||||
if(optind != argc || list == 0)
|
||||
return _usage();
|
||||
return (_apptransport_list() == 0) ? 0 : 2;
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
targets=AppBroker,AppClient
|
||||
cppflags_force=-I ../include
|
||||
targets=AppBroker,AppClient,AppTransport
|
||||
cppflags_force=-I ../include -I $(OBJDIR)../include/App
|
||||
cppflags=
|
||||
cflags_force=`pkg-config --cflags libSystem libMarshall`
|
||||
cflags=-W -Wall -g -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector-all
|
||||
cflags=-W -Wall -g -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector
|
||||
ldflags_force=-L$(OBJDIR)../src `pkg-config --libs libSystem libMarshall` -lApp
|
||||
ldflags=-pie -Wl,-z,relro -Wl,-z,now
|
||||
dist=Makefile,appbroker.sh
|
||||
dist=Makefile,tools.sh
|
||||
|
||||
#targets
|
||||
[AppBroker]
|
||||
type=binary
|
||||
sources=appbroker.c
|
||||
@ -16,3 +17,18 @@ install=$(BINDIR)
|
||||
type=binary
|
||||
sources=appclient.c
|
||||
#install=$(BINDIR)
|
||||
|
||||
[AppTransport]
|
||||
type=binary
|
||||
sources=apptransport.c
|
||||
install=$(BINDIR)
|
||||
|
||||
#sources
|
||||
[appbroker.c]
|
||||
depends=../include/App/appserver.h,../include/App/apptransport.h
|
||||
|
||||
[appclient.c]
|
||||
depends=../include/App/appclient.h
|
||||
|
||||
[apptransport.c]
|
||||
depends=$(OBJDIR)../include/App/app.h,../include/App/apptransport.h
|
||||
|
213
tools/subst.sh
Executable file
213
tools/subst.sh
Executable file
@ -0,0 +1,213 @@
|
||||
#!/bin/sh
|
||||
#$Id$
|
||||
#Copyright (c) 2012-2022 Pierre Pronchery <khorben@defora.org>
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
#IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
#FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
#DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
#SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
#OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
|
||||
#variables
|
||||
CONFIGSH="${0%/subst.sh}/../config.sh"
|
||||
PREFIX="/usr/local"
|
||||
BINDIR=
|
||||
DATADIR=
|
||||
DEVNULL="/dev/null"
|
||||
INCLUDEDIR=
|
||||
LDSO=
|
||||
LIBDIR=
|
||||
LIBEXECDIR=
|
||||
MANDIR=
|
||||
PROGNAME="subst.sh"
|
||||
SBINDIR=
|
||||
SYSCONFDIR=
|
||||
#executables
|
||||
CHMOD="chmod"
|
||||
DATE="date"
|
||||
DEBUG="_debug"
|
||||
INSTALL="install"
|
||||
MKDIR="mkdir -m 0755 -p"
|
||||
RM="rm -f"
|
||||
SED="sed"
|
||||
|
||||
[ -f "$CONFIGSH" ] && . "$CONFIGSH"
|
||||
|
||||
|
||||
#functions
|
||||
#subst
|
||||
_subst()
|
||||
{
|
||||
#check the variables
|
||||
if [ -z "$PACKAGE" ]; then
|
||||
_error "The PACKAGE variable needs to be set"
|
||||
return $?
|
||||
fi
|
||||
if [ -z "$VERSION" ]; then
|
||||
_error "The VERSION variable needs to be set"
|
||||
return $?
|
||||
fi
|
||||
[ -z "$BINDIR" ] && BINDIR="$PREFIX/bin"
|
||||
[ -z "$DATADIR" ] && DATADIR="$PREFIX/share"
|
||||
[ -z "$INCLUDEDIR" ] && INCLUDEDIR="$PREFIX/include"
|
||||
if [ -z "$LDSO" ]; then
|
||||
case "$(uname -s)" in
|
||||
FreeBSD)
|
||||
LDSO="/libexec/ld-elf.so.1"
|
||||
;;
|
||||
Linux)
|
||||
LDSO="/lib/ld-linux-$(uname -m | tr _ -).so.2"
|
||||
;;
|
||||
*)
|
||||
LDSO="/libexec/ld.elf_so"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
[ -z "$LIBDIR" ] && LIBDIR="$PREFIX/lib"
|
||||
[ -z "$LIBEXECDIR" ] && LIBEXECDIR="$PREFIX/libexec"
|
||||
[ -z "$MANDIR" ] && MANDIR="$DATADIR/man"
|
||||
if [ -z "$SYSCONFDIR" ]; then
|
||||
SYSCONFDIR="$PREFIX/etc"
|
||||
[ "$PREFIX" = "/usr" ] && SYSCONFDIR="/etc"
|
||||
fi
|
||||
[ -z "$SBINDIR" ] && SBINDIR="$PREFIX/sbin"
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
target="$1"
|
||||
shift
|
||||
|
||||
#clean
|
||||
[ "$clean" -ne 0 ] && continue
|
||||
|
||||
#uninstall
|
||||
if [ "$uninstall" -eq 1 ]; then
|
||||
$DEBUG $RM -- "$PREFIX/$target" || return 2
|
||||
continue
|
||||
fi
|
||||
|
||||
#install
|
||||
if [ "$install" -eq 1 ]; then
|
||||
source="${target#$OBJDIR}"
|
||||
$DEBUG $MKDIR -- "$PREFIX" || return 2
|
||||
mode="-m 0644"
|
||||
[ -x "${source}.in" ] && mode="-m 0755"
|
||||
$DEBUG $INSTALL $mode "$target" "$PREFIX/$source" \
|
||||
|| return 2
|
||||
continue
|
||||
fi
|
||||
|
||||
#create
|
||||
source="${target#$OBJDIR}"
|
||||
source="${source}.in"
|
||||
([ -z "$OBJDIR" ] || $DEBUG $MKDIR -- "${target%/*}") \
|
||||
|| return 2
|
||||
$DEBUG $SED -e "s;@VENDOR@;$VENDOR;g" \
|
||||
-e "s;@PACKAGE@;$PACKAGE;g" \
|
||||
-e "s;@VERSION@;$VERSION;g" \
|
||||
-e "s;@PREFIX@;$PREFIX;g" \
|
||||
-e "s;@BINDIR@;$BINDIR;g" \
|
||||
-e "s;@DATADIR@;$DATADIR;g" \
|
||||
-e "s;@DATE@;$DATE;g" \
|
||||
-e "s;@INCLUDEDIR@;$INCLUDEDIR;g" \
|
||||
-e "s;@LDSO@;$LDSO;g" \
|
||||
-e "s;@LIBDIR@;$LIBDIR;g" \
|
||||
-e "s;@LIBEXECDIR@;$LIBEXECDIR;g" \
|
||||
-e "s;@MANDIR@;$MANDIR;g" \
|
||||
-e "s;@PWD@;$PWD;g" \
|
||||
-e "s;@SBINDIR@;$SBINDIR;g" \
|
||||
-e "s;@SYSCONFDIR@;$SYSCONFDIR;g" \
|
||||
-- "$source" > "$target"
|
||||
if [ $? -ne 0 ]; then
|
||||
$RM -- "$target" 2> "$DEVNULL"
|
||||
return 2
|
||||
elif [ -x "$source" ]; then
|
||||
$DEBUG $CHMOD -- 0755 "$target"
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#debug
|
||||
_debug()
|
||||
{
|
||||
echo "$@" 1>&3
|
||||
"$@"
|
||||
}
|
||||
|
||||
|
||||
#error
|
||||
_error()
|
||||
{
|
||||
echo "$PROGNAME: $@" 1>&2
|
||||
return 2
|
||||
}
|
||||
|
||||
|
||||
#usage
|
||||
_usage()
|
||||
{
|
||||
echo "Usage: $PROGNAME [-c|-i|-u][-P prefix] target..." 1>&2
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
#main
|
||||
clean=0
|
||||
install=0
|
||||
uninstall=0
|
||||
while getopts "ciuO:P:" name; do
|
||||
case $name in
|
||||
c)
|
||||
clean=1
|
||||
;;
|
||||
i)
|
||||
uninstall=0
|
||||
install=1
|
||||
;;
|
||||
u)
|
||||
install=0
|
||||
uninstall=1
|
||||
;;
|
||||
O)
|
||||
export "${OPTARG%%=*}"="${OPTARG#*=}"
|
||||
;;
|
||||
P)
|
||||
PREFIX="$OPTARG"
|
||||
;;
|
||||
?)
|
||||
_usage
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $(($OPTIND - 1))
|
||||
if [ $# -lt 1 ]; then
|
||||
_usage
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ -n "$SOURCE_DATE_EPOCH" ]; then
|
||||
DATE="$($DATE -d "@$SOURCE_DATE_EPOCH" '+%B %d, %Y')"
|
||||
else
|
||||
DATE="$($DATE '+%B %d, %Y')"
|
||||
fi
|
||||
|
||||
exec 3>&1
|
||||
_subst "$@"
|
Loading…
Reference in New Issue
Block a user