List of commits:
Subject Hash Author Date (UTC)
Lots of changes 8c803765a4dd6d79e7f61927c47a5f1a19e3db31 Catalin(ux) M. BOIE 2023-03-13 05:51:28
Record full path of the cert for openssl 66e89d4e0eaf638859b39c791d82d233e2d0c2c2 Catalin(ux) M. BOIE 2023-03-03 18:41:57
Improve presentation 0600fd3c6e5fcb0dd152d0e680ea85a8ae89bd86 Catalin(ux) M. BOIE 2022-12-09 17:46:09
More curl tracing info 04013af7a216e6cf7f363b3895ffcebe78859a65 Catalin(ux) M. BOIE 2022-12-09 17:45:46
Added curl support c374ad15d2d5548d168084c0e8506929803e9bf0 Catalin(ux) M. BOIE 2022-11-30 11:28:48
More Latex modules were missing ff5bec2cfba2cf77e0115f89124cdeb83dfbc73d Catalin(ux) M. BOIE 2022-11-24 16:52:48
Forgot to add beamer 1080ddc6497af77b66fd57eb7b9da0abaf75cb2a Catalin(ux) M. BOIE 2022-11-24 16:39:30
Mispelled docs 463d312e5ddc8b237e03a4d9b4cfb33524393fb0 Catalin(ux) M. BOIE 2022-11-24 16:11:45
More docs updated 83876ce8fcf9ae03c189e4fc7f354bf67f328916 Catalin(ux) M. BOIE 2022-11-24 15:59:05
Record bytes read/written on fds 428c3905bb135725ac3bd2ecfe5949e434b179b5 Catalin(ux) M. BOIE 2022-11-24 15:58:25
A lot of small fixes 9a5841916f3f0870ca091f457102c7512b21808a Catalin(ux) M. BOIE 2022-11-23 07:28:06
Added pthread_join + small fixes a5206c335f8c858d791f114da7361190196ad4a4 Catalin(ux) M. BOIE 2022-11-21 14:05:31
Lots of updates 5583e8dbd607b684a14ced92b4d2ffdacbcf57e1 Catalin(ux) M. BOIE 2022-11-18 05:40:05
mysql, sqlite3, depth d9d83cafbd372d1055fa2e51cdf3deb2396f5d08 Catalin(ux) M. BOIE 2022-11-07 05:58:04
More spec fixes 3867b17137b5397c3eeabdcbbc232417ad212a27 Catalin(ux) M. BOIE 2022-10-25 19:04:28
More spec fixes 68abc4ce485fbbcc18a232e57b956f9e2b016d72 Catalin(ux) M. BOIE 2022-10-25 18:48:22
Fixed installation paths in Makefiles c98920bd55f7cd2ebcec7083e2360009d8c16b29 Catalin(ux) M. BOIE 2022-10-25 18:19:49
Debian support added, create correctly the paths for install 512c13ca06dda005504cdeab831431c943dde74a Catalin(ux) M. BOIE 2022-10-25 06:19:50
Bump version to 0.6 for a stupid reason (mass with dupdump) c4d10510ddf944965a80d9a3e5f4ac62b84a103e Catalin(ux) M. BOIE 2022-10-25 06:04:33
History update c83cd94af87636bc67bf9526ca0a65734ce96fac Catalin(ux) M. BOIE 2022-10-22 10:34:01
Commit 8c803765a4dd6d79e7f61927c47a5f1a19e3db31 - Lots of changes
Author: Catalin(ux) M. BOIE
Author date (UTC): 2023-03-13 05:51
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2023-03-13 05:51
Parent(s): 66e89d4e0eaf638859b39c791d82d233e2d0c2c2
Signer:
Signing key:
Signing status: N
Tree: 03ffb0d57e5e8f764485b152be1282c9a538684b
File Lines added Lines deleted
.gitignore 2 0
Makefile.common.in 29 0
Makefile.in 18 30
TODO 15 0
agent/Makefile 40 12
agent/c/TODO 11 0
agent/c/oci.c 369 0
agent/c/oci.h 27 0
agent/ctools.c 1 1
agent/ctools.h 7 0
agent/curl.c 10 8
agent/java/agent/Makefile 7 3
agent/java/agent/MyInstrumentationAgent.java 142 30
agent/java/agent/QueryTransformer.java 360 80
agent/java/agent/ninedogs.java 138 31
agent/ninedogs.TODO 7 0
agent/ninedogs.c 728 424
agent/ninedogs.h 1 1
agent/php-core.c 335 0
agent/php-core.h 184 0
agent/php-curl.c 178 0
agent/php-curl.h 4 0
agent/php-mysql.c 759 0
agent/php-mysql.h 4 0
agent/php-oci.c 283 0
agent/php-oci.h 4 0
agent/php-pg.c 565 0
agent/php-pg.h 4 0
agent/php.TODO 1 0
agent/php.c 12 1907
agent/php.h 6 0
agent/php/gd.c 186 0
agent/php/gd.h 9 0
agent/process_core.c 22 25
agent/process_db.c 145 91
agent/process_db.h 43 53
agent/process_ssl.c 6 6
agent/process_url.c 16 16
agent/python.c 31 32
agent/text2process.c 245 11
agent/text2process.h 1 1
agent/trace_encode.c 184 0
agent/trace_encode.h 24 0
common/Makefile 12 6
common/bin2json.c 89 0
common/bin2json.h 5 0
common/bin2struct.c 148 0
common/bin2struct.h 42 0
common/decode_text.c 295 0
common/decode_text.h 12 0
common/ids.h 15 1
common/info.c 27 14
common/params.h 41 0
common/sctools.c 52 50
common/sctools.h 6 17
common/shared.h 13 9
common/tools.c 300 28
common/tools.h 37 3
debian/control 2 2
docs/Makefile 0 2
docs/colors1.png 0 0
docs/pre1.tex 2 2
docs/pre1.txt 4 0
duilder 24 19
ingestd/Makefile 9 7
ingestd/TODO 3 0
ingestd/decode.c 5 2
ingestd/decode_core.c 13 52
ingestd/decode_db.c 15 15
ingestd/decode_ssl.c 18 19
ingestd/ninedogs-ingestd.service 11 9
ingestd/priv.h 11 8
ingestd/stools.c 70 28
ingestd/stools.h 3 2
misc/Makefile 4 6
ninedogs.spec 12 3
test/c/oracle/.gitignore 0 0
test/c/oracle/Dockerfile 23 0
test/c/oracle/build.sh 18 0
test/c/oracle/demo.c 369 0
test/c/oracle/exec-dev-1.sh 9 0
test/c/oracle/exec-dev-bash.sh 10 0
test/curl/1.c 7 1
test/curl/1.run 3 1
test/curl/3.php 0 2
test/curl/3.run 1 1
test/go/.gitignore 0 0
test/go/1.go 23 0
test/go/1.run 1 1
test/go/TODO 3 0
test/info/.gitignore 1 0
test/info/1.c 8 2
test/info/1.run 2 1
test/java/mysql/my1.java 85 0
test/java/mysql/my1.jdb.run 15 0
test/java/mysql/my1.run 36 0
test/java/oracle/TODO 2 0
test/java/oracle/sqlplus-XE.sh 4 0
test/java/oracle/sqlplus.sh 4 0
test/java/oracle/start_oracle.sh 32 0
test/java/oracle/t1.java 98 0
test/java/oracle/t1.jdb.run 14 0
test/java/oracle/t1.run 10 11
test/java/oracle/t2.java 45 0
test/java/oracle/t2.jdb.run 14 0
test/java/oracle/t2.run 10 11
test/java/oracle/t_con_err.java 30 0
test/java/oracle/t_con_err.sh 37 0
test/java/pg/1-no-nd-ja.sh 17 0
test/java/pg/1-no-nd.run 16 0
test/java/pg/pg1.java 49 20
test/java/pg/pg1.jdb.run 15 0
test/java/pg/pg1.run 8 10
test/openssl/expired.sh 6 6
test/openssl/expiring.sh 42 0
test/php-container/exec.sh 3 0
test/php-dns/1.run 1 1
test/php-mysql/1.run 2 1
test/php-mysql/1.run.gdb 0 0
test/php-mysql/1.run.gdb.sh 0 0
test/php-mysql/1.vg.run 3 2
test/php-mysql/stmt_bind_param.php 1 0
test/php-mysql/stmt_bind_param.run 1 1
test/php-oracle/1 4 1
test/php-oracle/1.php 21 0
test/php-oracle/Dockerfile 30 0
test/php-oracle/build.sh 18 0
test/php-oracle/exec-dev-1.sh 9 0
test/php-oracle/exec-dev-bash.sh 9 0
test/php-pg/1.run 1 1
test/php/gd/.gitignore 1 0
test/php/gd/1.php 17 0
test/php/gd/1.run 4 4
test/php/redis/1.php 25 0
test/php/redis/1.run 3 2
test/redis/.gitignore 1 0
test/redis/1.run 14 0
tools/Makefile 7 6
tools/TODO 8 0
tools/cert-notify.c 161 0
tools/ninedogs-cert-notify.service 9 0
tools/ninedogs-cert-notify.timer 9 0
trace/.gitignore 1 0
trace/Makefile 3 9
trace/TODO 6 1
trace/nd-trace.c 822 115
trace/show-colors.c 44 0
webd/Makefile 14 6
webd/TODO 2 0
webd/certs.c 7 8
webd/data.c 94 0
webd/data.h 4 0
webd/machines.TODO 3 0
webd/machines.c 107 0
webd/machines.h 5 0
webd/ninedogs-webd.c 75 10
webd/ninedogs-webd.service 11 11
webd/webroot/index.html 14 17
webd/webroot/js/certs.js 1 1
webd/webroot/js/grid.js 18 6
webd/webroot/js/machine_data.js 178 0
webd/webroot/js/machines.js 329 0
webd/webroot/js/menu.js 2 1
webd/webroot/js/tab.js 268 0
webd/webroot/js/util.js 1 1
webd/webroot/main.css 22 28
webd/webroot/main.js 1 1
File .gitignore changed (mode: 100644) (index dad677a..fe99470)
... ... obj/
20 20 *.db *.db
21 21 *.asm *.asm
22 22 *.tmp *.tmp
23 Makefile.common
24 *.jar
File Makefile.common.in added (mode: 100644) (index 0000000..14f7cf4)
1 CC_SWITCHES := @CC_SWITCHES@
2 I_USR := @USR@
3 I_USR_BIN := @USR_BIN@
4 I_USR_SBIN := @USR_SBIN@
5 I_USR_LIB := @USR_LIB@
6 I_USR_SHARE := @USR_SHARE@
7 I_VAR_LOG := @VAR_LOG@
8 I_VAR_LIB := @VAR_LIB@
9 I_ETC := @ETC@
10
11 export CC := gcc
12 export INCS :=
13 export LIBS :=
14 export CFLAGS := $(CC_SWITCHES)
15 export CFLAGS += -ggdb -Wall -Wextra -pipe
16
17 export GNUTLS_LIBS := $(shell pkg-config --libs gnutls)
18 export GNUTLS_CFLAGS := $(shell pkg-config --cflags gnutls)
19
20 export JSON_LIBS := $(shell pkg-config --libs json-c)
21 export JSON_CFLAGS := $(shell pkg-config --cflags json-c)
22
23 export CFLAGSSO := -ldl -lrt -shared -rdynamic -fPIC
24
25 export CURL_LIBS := $(shell pkg-config libcurl --libs)
26
27 # for shm_open
28 export LIBS += -lrt
29
File Makefile.in changed (mode: 100644) (index ec4811b..746d28d)
1 export CC := gcc
2 export INCS +=
3 export LIBS +=
4 export CFLAGS += @CC_SWITCHES@
5 export CFLAGS += -ggdb -Wall -Wextra -pipe
6 export CFLAGS += -D _FORTIFY_SOURCES=2
1 ALL := common agent ingestd webd trace misc tools docs
7 2
8 export GNUTLS_LIBS += $(shell pkg-config --libs gnutls)
9 export GNUTLS_CFLAGS += $(shell pkg-config --cflags gnutls)
3 all: $(ALL)
10 4
11 export JSON_LIBS += $(shell pkg-config --libs json-c)
12 export JSON_CFLAGS += $(shell pkg-config --cflags json-c)
13
14 export CFLAGSSO = $(CFLAGS) -ldl -shared -rdynamic -fPIC
15
16
17 all: common agent ingestd webd trace misc docs
18
19
20 .PHONY: common
5 .PHONY: $(ALL)
21 6 common: common:
22 7 make -R -C common compile make -R -C common compile
23 8
24 .PHONY: agent
25 9 agent: agent:
26 make -R -C agent compile
10 make -R -C agent
27 11
28 .PHONY: ingestd
29 12 ingestd: ingestd:
30 make -R -C ingestd compile
13 make -R -C ingestd
31 14
32 .PHONY: webd
33 15 webd: webd:
34 make -R -C webd compile
16 make -R -C webd
35 17
36 .PHONY: trace
37 18 trace: trace:
38 make -R -C trace compile
19 make -R -C trace
39 20
40 .PHONY: misc
41 21 misc: misc:
42 make -R -C misc compile
22 make -R -C misc
23
24 tools:
25 make -R -C tools
43 26
44 .PHONY: docs
45 27 docs: docs:
46 make -R -C docs compile
28 make -R -C docs
29
47 30
48 31 .PHONY: install .PHONY: install
49 32 install: install:
50 33 @mkdir -p $(I_VAR_LOG)/ninedogs @mkdir -p $(I_VAR_LOG)/ninedogs
34 @chown -R ninedogs:ninedogs $(I_VAR_LOG)/ninedogs
51 35 @mkdir -p $(I_USR_SHARE)/ninedogs @mkdir -p $(I_USR_SHARE)/ninedogs
52 36 @mkdir -p $(I_VAR_LIB)/ninedogs @mkdir -p $(I_VAR_LIB)/ninedogs
37 @chown -R ninedogs:ninedogs $(I_VAR_LIB)/ninedogs
53 38 @make -C agent install @make -C agent install
54 39 @make -C ingestd install @make -C ingestd install
55 40 @make -C webd install @make -C webd install
56 41 @make -C trace install @make -C trace install
57 42 @make -C misc install @make -C misc install
43 @make -C tools install
58 44 @mkdir -p $(I_ETC)/nginx/conf.d @mkdir -p $(I_ETC)/nginx/conf.d
59 45 @cp -vd samples/nginx.conf $(I_ETC)/nginx/conf.d/ninedogs.conf.sample @cp -vd samples/nginx.conf $(I_ETC)/nginx/conf.d/ninedogs.conf.sample
60 46 @cp -vd --no-clobber samples/nginx.conf $(I_ETC)/nginx/conf.d/ninedogs.conf @cp -vd --no-clobber samples/nginx.conf $(I_ETC)/nginx/conf.d/ninedogs.conf
 
... ... clean:
67 53 @make -R -C ingestd clean @make -R -C ingestd clean
68 54 @make -R -C webd clean @make -R -C webd clean
69 55 @make -R -C trace clean @make -R -C trace clean
56 @make -R -C misc clean
57 @make -R -C tools clean
70 58
File TODO changed (mode: 100644) (index fb26266..1b0b498)
1 1 == Urgent == == Urgent ==
2 2 [ ] Seems curl is taking over SEGV handling. Prevent that, but allow the handler to be called. [ ] Seems curl is taking over SEGV handling. Prevent that, but allow the handler to be called.
3 [ ] Seems that running 'php-container' test, the query does not hit the server.
4 It may be the connection is closed too soon.
5 [ ] Restarting ingestd - rocketgit builder does not reconnect
6 [ ] The whole thing with process_db variable 'stable' seems to not work.
7 Or I do not understand it anymore!
8 [ ] zend_array_to_params_array could be moved in a more generic .c file?
9 [ ] nd_params_array seems to be defined in multiple places.
3 10 [ ] [ ]
4 11
5 12
6 13 == Non-urgent == Non-urgent
14 [ ] Java + mysql
15 [ ] We can compare the result set of db queries and suggest some caching.
16 Better, implement the cache in ninedogs!
17 [ ] Add informations about replication status and incidents.
7 18 [ ] Both client and server side are free (AGPLv3). [ ] Both client and server side are free (AGPLv3).
8 19 Offering this as a SaaS may bring some money to support Offering this as a SaaS may bring some money to support
9 20 the development. the development.
 
11 22 [ ] We can easily provide a vault service by hijacking getenv [ ] We can easily provide a vault service by hijacking getenv
12 23 And providing a filesystem. And providing a filesystem.
13 24 [ ] We can act also as a vault (both env vars and filesystem). [ ] We can act also as a vault (both env vars and filesystem).
25 [ ] Create filters from the log search UI.
26 [ ] Show hostname mismatch: the one in certificate with the one we are connecting to.
27 [ ] When connecting somewhere by https, alert if some intermediate or root cert
28 is not known locally?
14 29 [ ] [ ]
15 30
16 31
File agent/Makefile changed (mode: 100644) (index 93de780..c5ed207)
1 # This is just to allow us to run make here
2 .PHONY: all
3 all:
4 make -R -C .. agent
1 include ../Makefile.common
5 2
6 3 COMMON_H += ../common/ids.h ../common/tools.h ../common/decode_text.h \ COMMON_H += ../common/ids.h ../common/tools.h ../common/decode_text.h \
4 ../common/params.h \
7 5 ctools.h ctools.h
8 6
9 7 CFLAGS += -I../common CFLAGS += -I../common
10 8
11 OBJS := decode.o ctools.o php.o process.o process_core.o process_misc.o \
9 OBJS := decode.o ctools.o process.o process_core.o process_misc.o \
12 10 process_db.o process_ssl.o process_url.o \ process_db.o process_ssl.o process_url.o \
13 11 openssl.o gnutls.o text2process.o \ openssl.o gnutls.o text2process.o \
14 12 python.o curl.o \ python.o curl.o \
13 php-core.o php-curl.o php-mysql.o php-oci.o php-pg.o php.o \
14 c/oci.o \
15 php/gd.o \
16 trace_encode.o \
15 17 ../common/tools.o ../common/info.o ../common/decode_text.o ../common/tools.o ../common/info.o ../common/decode_text.o
16 18
19 all: ninedogs_dlsym_env.so ninedogs_dlsym_func.so ninedogs.so
20
17 21 decode.o: decode.c decode.h process_db.h process_url.h $(COMMON_H) decode.o: decode.c decode.h process_db.h process_url.h $(COMMON_H)
18 22 $(CC) $(CFLAGS) -fPIC -c -o $@ $< $(CC) $(CFLAGS) -fPIC -c -o $@ $<
19 23
20 24 ctools.o: ctools.c $(COMMON_H) ../common/tools.h ctools.o: ctools.c $(COMMON_H) ../common/tools.h
21 25 $(CC) $(CFLAGS) -fPIC -c -o $@ $< $(CC) $(CFLAGS) -fPIC -c -o $@ $<
22 26
23 php.o: php.c php.h process_db.h process_url.h $(COMMON_H)
27 php-core.o: php-core.c php-core.h $(COMMON_H)
28 $(CC) $(CFLAGS) -fPIC -c -o $@ $<
29
30 php-curl.o: php-curl.c php-curl.h php-core.h process_url.h $(COMMON_H)
31 $(CC) $(CFLAGS) -fPIC -c -o $@ $<
32
33 php-mysql.o: php-mysql.c php-mysql.h php-core.h process_db.h $(COMMON_H)
34 $(CC) $(CFLAGS) -fPIC -c -o $@ $<
35
36 php-oci.o: php-oci.c php-oci.h php-core.h process_db.h $(COMMON_H)
37 $(CC) $(CFLAGS) -fPIC -c -o $@ $<
38
39 php-pg.o: php-pg.c php-pg.h php-core.h process_db.h $(COMMON_H)
40 $(CC) $(CFLAGS) -fPIC -c -o $@ $<
41
42 php.o: php.c php.h process_db.h process_url.h php-oci.h $(COMMON_H)
24 43 $(CC) $(CFLAGS) -fPIC -c -o $@ $< $(CC) $(CFLAGS) -fPIC -c -o $@ $<
25 44
26 45 curl.o: curl.c curl.h $(COMMON_H) curl.o: curl.c curl.h $(COMMON_H)
 
... ... process_url.o: process_url.c process_url.h $(COMMON_H)
54 73 process_ssl.o: process_ssl.c process_ssl.h $(COMMON_H) process_ssl.o: process_ssl.c process_ssl.h $(COMMON_H)
55 74 $(CC) $(CFLAGS) -fPIC -c -o $@ $< $(CC) $(CFLAGS) -fPIC -c -o $@ $<
56 75
57 text2process.o: text2process.c text2process.h $(COMMON_H)
76 text2process.o: text2process.c text2process.h process_db.h process_ssl.h $(COMMON_H)
77 $(CC) $(CFLAGS) -fPIC -c -o $@ $<
78
79 trace_encode.o: trace_encode.c trace_encode.h $(COMMON_H)
58 80 $(CC) $(CFLAGS) -fPIC -c -o $@ $< $(CC) $(CFLAGS) -fPIC -c -o $@ $<
59 81
60 82 ninedogs_dlsym_env.so: ninedogs_dlsym_env.c ninedogs_dlsym_env.so: ninedogs_dlsym_env.c
 
... ... ninedogs_dlsym_env.so: ninedogs_dlsym_env.c
63 85 ninedogs_dlsym_func.so: ninedogs_dlsym_func.c ninedogs_dlsym_func.so: ninedogs_dlsym_func.c
64 86 $(CC) $(CFLAGSSO) -Wl,-soname,ninedogs_dlsym_func.so -o $@ $< $(CC) $(CFLAGSSO) -Wl,-soname,ninedogs_dlsym_func.so -o $@ $<
65 87
88
89 c/oci.o: c/oci.c c/oci.h process_db.h $(COMMON_H)
90 $(CC) $(CFLAGS) -fPIC -c -o $@ $<
91
92
93 php/gd.o: php/gd.c php/gd.h $(COMMON_H)
94 $(CC) $(CFLAGS) -fPIC -c -o $@ $<
95
96
66 97 ninedogs.so: ninedogs.c $(OBJS) $(COMMON_H) ../common/shared.h curl.h \ ninedogs.so: ninedogs.c $(OBJS) $(COMMON_H) ../common/shared.h curl.h \
67 process_db.h process_url.h
98 process_db.h process_url.h trace_encode.h
68 99 $(CC) $(CFLAGS) $(CFLAGSSO) -Wl,-soname,ninedogs.so -o $@ ninedogs.c \ $(CC) $(CFLAGS) $(CFLAGSSO) -Wl,-soname,ninedogs.so -o $@ ninedogs.c \
69 100 $(OBJS) $(LIBS) $(GNUTLS_LIBS) $(OBJS) $(LIBS) $(GNUTLS_LIBS)
70 101
71
72 compile: ninedogs_dlsym_env.so ninedogs_dlsym_func.so ninedogs.so
73
74 102 .PHONY: clean .PHONY: clean
75 103 clean: clean:
76 104 @rm -f ninedogs*.so.* *.strace *.log *.out *.o @rm -f ninedogs*.so.* *.strace *.log *.out *.o
77 105
78 106 install: all install: all
79 @mkdir -p $(I_USR_LIB)
107 @mkdir -p $(I_USR_LIB)/ninedogs
80 108 cp -vd ninedogs*.so $(I_USR_LIB) cp -vd ninedogs*.so $(I_USR_LIB)
81 109
File agent/c/TODO added (mode: 100644) (index 0000000..c126628)
1 == Urgent ==
2 [ ] We understand only OCI_NTV_SYNTAX for OciStmtPrepare
3 [ ] When we detach from a server, we need to clean all stmts linked with it.
4 [ ]
5
6 == Not urgent ==
7 [ ] Add 'rcode' decoding.
8 [ ] Decode SUCCESS_WITH_INFO
9 [ ] If we bind the same position/name, should we overwrite a previous entry in nd_params_array_one?
10 [ ]
11
File agent/c/oci.c added (mode: 100644) (index 0000000..f473562)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "../../common/ids.h"
6 #include "../../common/tools.h"
7 #include "../ctools.h"
8 #include "../ninedogs.h"
9 #include "../process_db.h"
10 #include "oci.h"
11
12 // TODO: what about 'ind' and sending nulls
13
14 #define OCI_STMT_TRACK_MAX 100
15 struct oci_stmt_track
16 {
17 void *stmt;
18 const char *q;
19 unsigned int q_len;
20 unsigned int pad;
21 struct nd_params_array binds;
22 };
23 static __thread struct oci_stmt_track track[OCI_STMT_TRACK_MAX];
24
25 static void stmt_clean(void *stmt)
26 {
27 for (unsigned i = 0; i < OCI_STMT_TRACK_MAX; i++) {
28 if (track[i].stmt == stmt) {
29 memset(&track[i], 0, sizeof(track[i]));
30 break;
31 }
32 }
33 }
34
35 static struct oci_stmt_track *stmt_find(const void *stmt)
36 {
37 for (unsigned i = 0; i < OCI_STMT_TRACK_MAX; i++) {
38 if (track[i].stmt == stmt)
39 return &track[i];
40 }
41
42 return NULL;
43 }
44
45 static struct oci_stmt_track *stmt_alloc(const void *func, void *stmt)
46 {
47 for (unsigned i = 0; i < OCI_STMT_TRACK_MAX; i++) {
48 if (track[i].stmt == NULL) {
49 track[i].stmt = stmt;
50 return &track[i];
51 }
52 }
53
54 xlog(0, "%s: cannot find a free slot for stmt %p!\n", func, stmt);
55 return NULL;
56 }
57
58 static void stmt_add_query(void *stmt, const char *q,
59 const unsigned int q_len)
60 {
61 struct oci_stmt_track *s = stmt_find(stmt);
62 if (!s)
63 s = stmt_alloc(__func__, stmt);
64 if (!s)
65 return;
66 s->q = q;
67 s->q_len = q_len;
68 }
69
70 static unsigned char dty_to_nd_type(unsigned short dty)
71 {
72 switch (dty) {
73 case 2: return ND_TYPE_STRING; // SQLT_NUM
74 case 3: return ND_TYPE_INT;
75 case 5: return ND_TYPE_STRING;
76 case 8: return ND_TYPE_STRING; // SQLT_LONG seems to be string
77 default: return ND_TYPE_UNK;
78 }
79 }
80
81 // TODO: this should be moved into 'process_db.c'
82 /* @bind_or_def: 0=bind, 1=def
83 */
84 static void stmt_bind_or_def_by_name_or_pos(const int bind_or_def, void *stmt,
85 const char *name, const unsigned int pos, unsigned short dty,
86 void *value, const int value_size)
87 {
88 xlog(1, "%s: bind_or_def=%u stmt=%p name=[%s] pos=[%u]"
89 " dty=%hu value=%p value_size=%d\n",
90 __func__, bind_or_def, stmt, name, pos, dty,
91 value, value_size);
92
93 struct oci_stmt_track *q = stmt_find(stmt);
94 if (!q)
95 q = stmt_alloc(__func__, stmt);
96 if (!q)
97 return;
98
99 for (unsigned short i = 0; i < ND_PARAMS_MAX; i++) {
100 struct nd_params_array_one *o = &q->binds.list[i];
101
102 if (o->type != ND_TYPE_FREE_SLOT)
103 continue;
104
105 if (name) {
106 snprintf(o->name, sizeof(o->name), "%s", name);
107 o->bind_type = ND_PARAMS_BIND_TYPE_NAME;
108 } else {
109 o->pos = pos;
110 o->bind_type = ND_PARAMS_BIND_TYPE_POS;
111 }
112 o->type = dty_to_nd_type(dty);
113 o->pointer = 1;
114 o->str = value;
115 o->length = value_size;
116 o->bind_way = bind_or_def;
117 break;
118 }
119 }
120
121 static void stmt_bind_by_name(void *stmt, const char *name, unsigned short dty,
122 void *value, const int value_size)
123 {
124 stmt_bind_or_def_by_name_or_pos(ND_PARAMS_BIND_WAY_BOTH, stmt,
125 name, 0 /*pos*/, dty, value, value_size);
126 }
127
128 static void stmt_bind_by_pos(void *stmt, const unsigned int pos, unsigned short dty,
129 void *value, const int value_size)
130 {
131 stmt_bind_or_def_by_name_or_pos(ND_PARAMS_BIND_WAY_BOTH, stmt,
132 NULL/*name*/, pos, dty, value, value_size);
133 }
134
135 static void stmt_def_by_name(void *stmt, const char *name, unsigned short dty,
136 void *value, const int value_size)
137 {
138 stmt_bind_or_def_by_name_or_pos(ND_PARAMS_BIND_WAY_OUT, stmt,
139 name, 0 /*pos*/, dty, value, value_size);
140 }
141
142 static void stmt_def_by_pos(void *stmt, const unsigned int pos, unsigned short dty,
143 void *value, const int value_size)
144 {
145 stmt_bind_or_def_by_name_or_pos(ND_PARAMS_BIND_WAY_OUT, stmt,
146 NULL/*name*/, pos, dty, value, value_size);
147 }
148
149
150 // TODO: check **
151 static sword (*old_OCIAttrSet)(void *, unsigned int, void *, unsigned int,
152 unsigned int, void *);
153 sword OCIAttrSet(void *h, unsigned int htype, void *attr, unsigned int attr_size,
154 unsigned int attr_type, void *oci_err)
155 {
156 if (!old_OCIAttrSet)
157 old_OCIAttrSet = ninedogs_dlsym("OCIAttrSet");
158
159 xlog(100, "%s(h=%p htype=%u attr=%p attr_size=%u attr_type=%u oci_err=%p)\n",
160 __func__, h, htype, attr, attr_size, attr_type, oci_err);
161 sword ret = old_OCIAttrSet(h, htype, attr, attr_size, attr_type, oci_err);
162 my_trace(__func__, "i", 'R', h, htype, attr, attr_size, attr_type, oci_err, ret);
163
164 return ret;
165 }
166
167 static sword (*old_OCIBindByName)(void *, void **, void *, const char *,
168 int, void *, int, unsigned short, void *, unsigned short *,
169 unsigned short *, unsigned int, unsigned int *, unsigned int);
170 sword OCIBindByName(void *stmt, void **bind, void *oci_error,
171 const char *ph, int ph_len, void *value, int value_size,
172 unsigned short dty, void *ind, unsigned short *alen,
173 unsigned short *rcode, unsigned int maxarr_len,
174 unsigned int *curelep, unsigned int mode)
175 {
176 if (!old_OCIBindByName)
177 old_OCIBindByName = ninedogs_dlsym("OCIBindByName");
178
179 sword ret = old_OCIBindByName(stmt, bind, oci_error, ph, ph_len,
180 value, value_size, dty, ind, alen, rcode, maxarr_len,
181 curelep, mode);
182 // we do not send 'value' because it may not be set at this time
183 my_trace(__func__, "i", 'R', stmt, bind, oci_error, ph, ph_len,
184 value_size, dty, ind, alen, rcode, maxarr_len,
185 curelep, mode, ret);
186 if (alen) {
187 char dump[256 * 4 + 1];
188 bin2hex_ascii(dump, alen, 16);
189 xlog(0, " DEBUG: alen: %s.\n", dump);
190 }
191
192 if (ret == 0)
193 stmt_bind_by_name(stmt, ph, dty, value, value_size);
194
195 return ret;
196 }
197
198 static sword (*old_OCIDefineByPos)(void *, void **, void *, unsigned int,
199 void *, int, unsigned short, void *,
200 unsigned short *, unsigned short *, unsigned int);
201 sword OCIDefineByPos(void *stmt, void **defn, void *oci_error, unsigned int pos,
202 void *value, int value_size, unsigned short dty, void *ind,
203 unsigned short *rlen, unsigned short *rcode, unsigned int mode)
204 {
205 if (!old_OCIDefineByPos)
206 old_OCIDefineByPos = ninedogs_dlsym("OCIDefineByPos");
207
208 sword ret = old_OCIDefineByPos(stmt, defn, oci_error, pos,
209 value, value_size, dty, ind, rlen, rcode, mode);
210 my_trace(__func__, "i", 'R', stmt, defn, oci_error, pos,
211 value_size, dty, ind, rlen, rcode, mode, ret);
212
213 #if 0
214 if (alen && *alen) {
215 char dump[256 * 4 + 1];
216 bin2hex_ascii(dump, *alen, 16);
217 xlog(0, " DEBUG: alen: %s.\n", dump);
218 }
219 #endif
220
221 // TODO: store also the query in the tracking; send it only once to the tracer?
222
223 if (ret == 0)
224 stmt_def_by_pos(stmt, pos, dty, value, value_size);
225
226 return ret;
227 }
228
229 static void (*old_OCIHandleAlloc)(const void *, void **, unsigned int,
230 size_t, void **);
231 void OCIHandleAlloc(const void *parent, void **dbh, unsigned int type,
232 size_t extra_mem, void **user_mem)
233 {
234 if (!old_OCIHandleAlloc)
235 old_OCIHandleAlloc = ninedogs_dlsym("OCIHandleAlloc");
236
237 old_OCIHandleAlloc(parent, dbh, type, extra_mem, user_mem);
238 my_trace(__func__, "i", 'R', parent, dbh, type, extra_mem, user_mem);
239
240 //if (type == 4) // 4=stmt
241 // stmt_clean(stmt); TODO - we may want to record 'parent'?
242 }
243
244 static void (*old_OCIHandleFree)(void *, unsigned int);
245 void OCIHandleFree(void *hnd, unsigned int type)
246 {
247 if (!old_OCIHandleFree)
248 old_OCIHandleFree = ninedogs_dlsym("OCIHandleFree");
249
250 old_OCIHandleFree(hnd, type);
251 my_trace(__func__, "i", 'R', hnd, type);
252
253 if (type == 4) // 4=stmt
254 stmt_clean(hnd);
255 }
256
257 // TODO: check **
258 static sword (*old_OCIServerAttach)(void *, void *, char *, int, unsigned int);
259 sword OCIServerAttach(void *oci_server, void *oci_error, char *db_link,
260 int db_link_len, unsigned int mode)
261 {
262 if (!old_OCIServerAttach)
263 old_OCIServerAttach = ninedogs_dlsym("OCIServerAttach");
264
265 my_trace(__func__, "i", 'c', oci_server, oci_error, db_link, db_link_len, mode);
266 sword ret = old_OCIServerAttach(oci_server, oci_error, db_link, db_link_len, mode);
267 my_trace(__func__, "i", 'r', oci_server, oci_error, db_link, db_link_len, mode, ret);
268
269 return ret;
270 }
271
272 static sword (*old_OCIServerDetach)(void *, void *, unsigned int);
273 sword OCIServerDetach(void *oci_server, void *oci_error, unsigned int mode)
274 {
275 if (!old_OCIServerDetach)
276 old_OCIServerDetach = ninedogs_dlsym("OCIServerDetach");
277
278 my_trace(__func__, "i", 'c', oci_server, oci_error, mode);
279 sword ret = old_OCIServerDetach(oci_server, oci_error, mode);
280 my_trace(__func__, "i", 'r', oci_server, oci_error, mode, ret);
281
282 return ret;
283 }
284
285 static sword (*old_OCIStmtExecute)(void *, void *, void *, unsigned int,
286 unsigned int, void *, void *, unsigned int);
287 sword OCIStmtExecute(void *svc, void *stmt, void *err, unsigned int iters,
288 unsigned int rowoff, void *snap_in, void *snap_out, unsigned int mode)
289 {
290 if (!old_OCIStmtExecute)
291 old_OCIStmtExecute = ninedogs_dlsym("OCIStmtExecute");
292
293 struct oci_stmt_track *q = stmt_find(stmt);
294 if (q)
295 my_trace(__func__, "i", 'm', stmt, ND_PARAMS_BIND_WAY_IN,
296 &q->binds, q->q, q->q_len);
297 my_trace(__func__, "i", 'c', svc, stmt, err, iters, rowoff, snap_in, snap_out, mode);
298 sword ret = old_OCIStmtExecute(svc, stmt, err, iters, rowoff, snap_in, snap_out, mode);
299 my_trace(__func__, "i", 'r', svc, stmt, err, iters, rowoff, snap_in, snap_out, mode, ret);
300 if (((ret == 0) || (ret == 1)) && q)
301 my_trace(__func__, "i", 'm', stmt, ND_PARAMS_BIND_WAY_OUT, &q->binds);
302
303 return ret;
304 }
305
306 // TODO: check **
307 static sword (*old_OCIStmtPrepare)(void *, void *, const char *, unsigned int,
308 unsigned int, unsigned int);
309 sword OCIStmtPrepare(void *stmt, void *oci_error, const char *q,
310 unsigned int q_len, unsigned int lang, unsigned int mode)
311 {
312 if (!old_OCIStmtPrepare)
313 old_OCIStmtPrepare = ninedogs_dlsym("OCIStmtPrepare");
314
315 sword ret = old_OCIStmtPrepare(stmt, oci_error, q, q_len, lang, mode);
316 my_trace(__func__, "i", 'R', stmt, oci_error, q, q_len, lang, mode, ret);
317
318 if (ret == 0)
319 stmt_add_query(stmt, q, q_len);
320
321 return ret;
322 }
323
324 static sword (*old_OCITransCommit)(void *, void *, unsigned int);
325 sword OCITransCommit(void *svc, void *oci_error, unsigned int flags)
326 {
327 if (!old_OCITransCommit)
328 old_OCITransCommit = ninedogs_dlsym("OCITransCommit");
329
330 my_trace(__func__, "i", 'c', svc, oci_error, flags);
331 sword ret = old_OCITransCommit(svc, oci_error, flags);
332 my_trace(__func__, "i", 'r', svc, oci_error, flags, ret);
333
334 return ret;
335 }
336
337 static sword (*old_OCITransRollback)(void *, void *, unsigned int);
338 sword OCITransRollback(void *svc, void *oci_error, unsigned int flags)
339 {
340 if (!old_OCITransRollback)
341 old_OCITransRollback = ninedogs_dlsym("OCITransRollback");
342
343 my_trace(__func__, "i", 'c', svc, oci_error, flags);
344 sword ret = old_OCITransRollback(svc, oci_error, flags);
345 my_trace(__func__, "i", 'r', svc, oci_error, flags, ret);
346
347 return ret;
348 }
349
350 static sword (*old_OCITransStart)(void *, void *, unsigned int, unsigned int);
351 sword OCITransStart(void *svc, void *oci_error, unsigned int timeout,
352 unsigned int flags)
353 {
354 if (!old_OCITransStart)
355 old_OCITransStart = ninedogs_dlsym("OCITransStart");
356
357 sword ret = old_OCITransStart(svc, oci_error, timeout, flags);
358 my_trace(__func__, "i", 'R', svc, oci_error, flags, timeout, ret);
359
360 return ret;
361 }
362
363 // TODO: OCISessionBegin
364 // TODO: OCIHandleFree
365 // TODO: OCISessionEnd
366 // TODO: OCITerminate ?
367 // TODO: OCIEnvCreate
368 // TODO: '2' variants!
369 // TODO: OCIStmtRelease
File agent/c/oci.h added (mode: 100644) (index 0000000..99bccb0)
1 typedef signed int sword;
2
3 sword OCIAttrSet(void *h, unsigned int htype, void *attr, unsigned int attr_size,
4 unsigned int attr_type, void *oci_err);
5 sword OCIBindByName(void *stmt, void **bind, void *oci_error,
6 const char *ph, int ph_len, void *value, int value_size,
7 unsigned short dty, void *ind, unsigned short *alen,
8 unsigned short *rcode, unsigned int maxarr_len,
9 unsigned int *curelep, unsigned int mode);
10 sword OCIDefineByPos(void *stmt, void **defn, void *oci_error, unsigned int pos,
11 void *value, int value_size, unsigned short dty, void *ind,
12 unsigned short *rlen, unsigned short *rcode, unsigned int mode);
13 void OCIHandleAlloc(const void *parent, void **dbh, unsigned int type,
14 size_t extra_mem, void **user_mem);
15 void OCIHandleFree(void *hnd, unsigned int type);
16 sword OCIServerAttach(void *oci_server, void *oci_error, char *db_link,
17 int db_link_len, unsigned int mode);
18 sword OCIServerDetach(void *oci_server, void *oci_error, unsigned int mode);
19 sword OCIStmtExecute(void *svc, void *stmt, void *err, unsigned int iters,
20 unsigned int rowoff, void *snap_in, void *snap_out, unsigned int mode);
21 sword OCIStmtPrepare(void *stmt, void *err, const char *q, unsigned int q_len,
22 unsigned int lang, unsigned int mode);
23 sword OCITransCommit(void *svc, void *oci_error, unsigned int flags);
24 sword OCITransRollback(void *svc, void *oci_error, unsigned int flags);
25 sword OCITransStart(void *svc, void *oci_error, unsigned int timeout,
26 unsigned int flags);
27
File agent/ctools.c changed (mode: 100644) (index 48835b7..11cb5f2)
... ... void send_sysinfo(void)
1116 1116
1117 1117 unsigned char *buf; unsigned char *buf;
1118 1118 unsigned int len; unsigned int len;
1119 pack(&buf, &len, "T4 NN u8" "18 58 q8" "r8 f8 s8" "b8 w8 W8" "p2 h8 H8 i4",
1119 pack(&buf, &len, "T4 _N u8" "18 58 q8" "r8 f8 s8" "b8 w8 W8" "p2 h8 H8 i4",
1120 1120 NINEDOGS_NET_CORE_SYSINFO, s.uptime, NINEDOGS_NET_CORE_SYSINFO, s.uptime,
1121 1121 s.loads[0], s.loads[1], s.loads[2], s.loads[0], s.loads[1], s.loads[2],
1122 1122 s.totalram, s.freeram, s.sharedram, s.totalram, s.freeram, s.sharedram,
File agent/ctools.h changed (mode: 100644) (index e93e17b..15beff4)
1 #include <sys/syscall.h>
2
1 3 #include <arpa/inet.h> #include <arpa/inet.h>
2 4 #include <netinet/in.h> #include <netinet/in.h>
3 5 #include <netinet/tcp.h> #include <netinet/tcp.h>
4 6
7 // On RockyLinux 8, gettid is not defined
8 #if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 30))
9 #define gettid() (syscall(SYS_gettid))
10 #endif
11
5 12 struct private struct private
6 13 { {
7 14 int domain; int domain;
File agent/curl.c changed (mode: 100644) (index ebfc058..19e9728)
8 8 extern void *(*old_malloc)(size_t size); extern void *(*old_malloc)(size_t size);
9 9 extern void xlog(const unsigned int level, const char *format, ...); extern void xlog(const unsigned int level, const char *format, ...);
10 10 extern void *ninedogs_dlsym(const char *sym); extern void *ninedogs_dlsym(const char *sym);
11 extern void my_trace(const char *func, const char type, ...);
11 extern void my_trace(const char *func, const char *tf, const char type, ...);
12 12
13 13
14 14 // Track setopt stuff // Track setopt stuff
 
... ... CURL *curl_easy_init(void)
107 107 old_curl_easy_init = ninedogs_dlsym("curl_easy_init"); old_curl_easy_init = ninedogs_dlsym("curl_easy_init");
108 108
109 109 CURL *ret = old_curl_easy_init(); CURL *ret = old_curl_easy_init();
110 my_trace(__func__, 'R', ret);
110 my_trace(__func__, "i", 'R', ret);
111 111 xlog(100, "%s: ret=%p\n", __func__, ret); xlog(100, "%s: ret=%p\n", __func__, ret);
112 112
113 113 return ret; return ret;
 
... ... CURLcode curl_easy_setopt(CURL *handle, CURLoption option, ...)
125 125 old_curl_easy_setopt = ninedogs_dlsym("curl_easy_setopt"); old_curl_easy_setopt = ninedogs_dlsym("curl_easy_setopt");
126 126
127 127 const struct my_curl_easyoption *oi = curl_easy_option_by_id(option); const struct my_curl_easyoption *oi = curl_easy_option_by_id(option);
128 if (!oi)
128 if (!oi) {
129 my_trace(__func__, "i", 'R', handle, 0xff, "?", 0, NULL, 43);
129 130 return 43; // CURLE_BAD_FUNCTION_ARGUMENT return 43; // CURLE_BAD_FUNCTION_ARGUMENT
131 }
130 132
131 133 xlog(100, " DEBUG: setopt %d name=[%s] type=%d (3=obj, 4=str)\n", xlog(100, " DEBUG: setopt %d name=[%s] type=%d (3=obj, 4=str)\n",
132 134 option, oi->name, oi->type); option, oi->name, oi->type);
 
... ... CURLcode curl_easy_setopt(CURL *handle, CURLoption option, ...)
186 188 } }
187 189 } while (0); } while (0);
188 190
189 my_trace(__func__, 'R', handle, oi->type, oi->name, len, a, ret);
191 my_trace(__func__, "i", 'R', handle, oi->type, oi->name, len, a, ret);
190 192
191 193 return ret; return ret;
192 194 } }
 
... ... CURLcode curl_easy_perform(CURL *handle)
208 210 } else { // user set the len after data } else { // user set the len after data
209 211 xlog(101, " DEBUG: %s: we need to log post data as meta!\n", __func__); xlog(101, " DEBUG: %s: we need to log post data as meta!\n", __func__);
210 212 } }
211 my_trace(__func__, 'm', "POSTFIELDS", handle, q->post_data,
213 my_trace(__func__, "i", 'm', "POSTFIELDS", handle, q->post_data,
212 214 q->post_data_len); q->post_data_len);
213 215 break; break;
214 216 } }
215 217
216 my_trace(__func__, 'c', handle);
218 my_trace(__func__, "i", 'c', handle);
217 219 CURLcode ret = old_curl_easy_perform(handle); CURLcode ret = old_curl_easy_perform(handle);
218 my_trace(__func__, 'r', handle, ret);
220 my_trace(__func__, "i", 'r', handle, ret);
219 221 xlog(100, "%s: ret=%d\n", __func__, ret); xlog(100, "%s: ret=%d\n", __func__, ret);
220 222
221 223 return ret; return ret;
 
... ... void curl_easy_cleanup(CURL *handle)
230 232 curl_track_del(handle); curl_track_del(handle);
231 233
232 234 old_curl_easy_cleanup(handle); old_curl_easy_cleanup(handle);
233 my_trace(__func__, 'R', handle);
235 my_trace(__func__, "i", 'R', handle);
234 236 } }
235 237
File agent/java/agent/Makefile changed (mode: 100644) (index b218671..56afa3c)
1 CLASSES := AtmTransformer.class QueryTransformer.class MyInstrumentationAgent.class
1 include ../../../Makefile.common
2
3 CLASSES := QueryTransformer.class MyInstrumentationAgent.class
2 4 JARS := javassist.jar ninedogs.jar JARS := javassist.jar ninedogs.jar
3 5
4 6 ninedogs-agent.jar: Makefile META-INF/MANIFEST.MF ninedogs.jar $(CLASSES) ninedogs-agent.jar: Makefile META-INF/MANIFEST.MF ninedogs.jar $(CLASSES)
 
... ... MyInstrumentationAgent.class: MyInstrumentationAgent.java
24 26 javac -cp . MyInstrumentationAgent.java javac -cp . MyInstrumentationAgent.java
25 27
26 28 install: ninedogs-agent.jar install: ninedogs-agent.jar
27 @mkdir -p $(if $(I_USR_SHARE), $(I_USR_SHARE), /usr/share)/ninedogs
28 @cp -v $(JARS) $(if $(I_USR_SHARE), $(I_USR_SHARE), /usr/share)/ninedogs/
29 @mkdir -p $(I_USR_SHARE)/ninedogs
30 @cp -v ninedogs-agent.jar ninedogs.jar javassist.jar \
31 $(I_USR_SHARE)/ninedogs/
32
29 33
File agent/java/agent/MyInstrumentationAgent.java changed (mode: 100644) (index c90a2c2..deec73d)
... ... import java.lang.instrument.Instrumentation;
4 4
5 5 public class MyInstrumentationAgent public class MyInstrumentationAgent
6 6 { {
7 private static void transform(Class<?> clazz, ClassLoader classLoader, Instrumentation instrumentation)
7 private static void transform(Class<?> clazz, ClassLoader classLoader,
8 Instrumentation instrumentation)
8 9 { {
9 10 String n = clazz.getName(); String n = clazz.getName();
10 11
11 //System.err.println("MyInstrumentationAgent.transform: clazz.getName()=" + n + " classLoader=" + classLoader);
12 //System.err.println("MyInstrumentationAgent.transform: clazz.getName()=["
13 // + n + "] classLoader=[" + classLoader + "]");
12 14
13 15 //if (n.equals("org.postgresql.Driver")) { //if (n.equals("org.postgresql.Driver")) {
14 16 // AtmTransformer dt = new AtmTransformer(n, classLoader); // AtmTransformer dt = new AtmTransformer(n, classLoader);
 
... ... public class MyInstrumentationAgent
17 19 // QueryTransformer dt = new QueryTransformer(n, classLoader); // QueryTransformer dt = new QueryTransformer(n, classLoader);
18 20 // instrumentation.addTransformer(dt, true); // instrumentation.addTransformer(dt, true);
19 21 //if (n.equals("sun.security.ssl.X509TrustManagerImpl")) { //if (n.equals("sun.security.ssl.X509TrustManagerImpl")) {
22 // QueryTransformer qt = new QueryTransformer(n, classLoader);
23 // instrumentation.addTransformer(qt, true); // true = can retransform
24 //} else if (n.equals("oracle.jdbc.OracleResultSet")) {
25 // QueryTransformer qt = new QueryTransformer(n, classLoader);
26 // instrumentation.addTransformer(qt, true); // true = can retransform
27 //} else {
28 // return;
29 //}
30
31 //if (n.startsWith("oracle.jdbc.")) {
20 32 QueryTransformer qt = new QueryTransformer(n, classLoader); QueryTransformer qt = new QueryTransformer(n, classLoader);
21 33 instrumentation.addTransformer(qt, true); // true = can retransform instrumentation.addTransformer(qt, true); // true = can retransform
22 34 //} else { //} else {
23 35 // return; // return;
24 36 //} //}
25 37
26 try {
27 instrumentation.retransformClasses(clazz);
28 } catch (Exception ex) {
29 System.err.println(" transform: fail: " + ex);
30 // TODO: next line was un-commented
31 ///throw new RuntimeException(" Transform failed for class: [" + n + "]", ex);
38 if (instrumentation.isModifiableClass(clazz)) {
39 try {
40 instrumentation.retransformClasses(clazz);
41 } catch (Exception ex) {
42 throw new RuntimeException(" Transform failed for class: [" + n + "]", ex);
43 }
44 } else {
45 System.out.println(" Class [" + n + "] is not modifiable!");
32 46 } }
33 47 } }
34 48
35 private static void transformClass(String className, Instrumentation instrumentation)
49 private static void transformClass(String className,
50 Instrumentation instrumentation)
36 51 { {
37 52 Class<?> targetCls = null; Class<?> targetCls = null;
38 53 ClassLoader targetClassLoader = null; ClassLoader targetClassLoader = null;
39 54
40 System.err.println("MyInstrumentationAgent.transformClass(" + className + ")...");
55 //System.err.println("MyInstrumentationAgent.transformClass("
56 // + className + ")...");
41 57
42 // see if we can get the class using forName
43 //System.err.println(" trying using forName...");
58 if (1 == 1) { // this is the cause for 'circular'!!!
44 59 try { try {
45 targetCls = Class.forName(className);
60 targetCls = Class.forName(className); // name, initialize, loader
61 //System.err.println(" targetCls=" + targetCls);
46 62 targetClassLoader = targetCls.getClassLoader(); targetClassLoader = targetCls.getClassLoader();
63 //System.err.println(" targetClassLoader=" + targetClassLoader);
47 64 transform(targetCls, targetClassLoader, instrumentation); transform(targetCls, targetClassLoader, instrumentation);
48 //System.err.println(" forName worked! return");
49 65 return; return;
50 66 } catch (Exception ex) { } catch (Exception ex) {
51 ///System.err.println(" Exception: " + ex);
67 System.err.println(" Exception: " + ex);
68 //throw ClassNotFoundException(" No loader for class");
69 }
52 70 } }
53 //System.err.println("Class [" + className + "] not found with Class.forName");
54
55 //System.err.println(" iterating all classes...");
56 // otherwise iterate all loaded classes and find what we want
57 71
58 72 for (Class<?> clazz: instrumentation.getAllLoadedClasses()) { for (Class<?> clazz: instrumentation.getAllLoadedClasses()) {
59 73 //System.err.println(" comparing with " + clazz.getName()); //System.err.println(" comparing with " + clazz.getName());
 
... ... public class MyInstrumentationAgent
65 79 } }
66 80 } }
67 81
68 ///System.err.println(" failed to find class " + className);
82 //System.err.println(" class not found");
69 83 //throw new RuntimeException("Failed to find class [" + className + "]"); //throw new RuntimeException("Failed to find class [" + className + "]");
70 84 } }
71 85
72 86 public static void premain(String agentArgs, Instrumentation inst) public static void premain(String agentArgs, Instrumentation inst)
73 87 { {
74 System.err.println("MyInstrumentationAgent.Premain...");
88 System.err.println("MyInstrumentationAgent.premain...");
75 89
76 90 if (1 == 0) { if (1 == 0) {
77 91 // This crashes badly // This crashes badly
78 92 // Transform all classes // Transform all classes
79 93 for (Class<?> clazz: inst.getAllLoadedClasses()) { for (Class<?> clazz: inst.getAllLoadedClasses()) {
80 //System.err.println(" iter " + clazz.getName());
81 transformClass(clazz.getName(), inst);
94 if (clazz.getName().startsWith("oracle") || clazz.getName().startsWith("java/sql")) {
95 System.err.println(" iter1 " + clazz.getName());
96 transformClass(clazz.getName(), inst);
97 }
82 98 } }
83 99 } else { } else {
100 if (2 == 2) { // seems we do not need to activate these
101 transformClass("java.sql.Statement", inst);
102 transformClass("java.sql.ResultSet", inst);
103 transformClass("java.sql.PreparedStatement", inst);
104 transformClass("java.sql.CallableStatement", inst);
105 transformClass("java.sql.Connection", inst);
106 transformClass("java.sql.Driver", inst);
107 transformClass("java.sql.DriverManager", inst);
108 transformClass("java.sql.DriverAction", inst);
109 transformClass("java.sql.Wrapper", inst);
110 }
111
84 112 // This generates Exception in thread "main" java.lang.ClassCircularityError: java/lang/WeakPairMap$Pair$Weak // This generates Exception in thread "main" java.lang.ClassCircularityError: java/lang/WeakPairMap$Pair$Weak
85 //transformClass("org.postgresql.Driver", inst);
86 transformClass("org.postgresql.jdbc.PgPreparedStatement", inst);
87 transformClass("org.postgresql.jdbc.PgResultSet", inst);
113 // Maybe because I tried to capture interfaces. No, it was because I returned 'bytecode' instead of null.
114 if (1 == 1) {
115 transformClass("org.postgresql.Driver", inst);
88 116 transformClass("org.postgresql.jdbc.PgConnection", inst); transformClass("org.postgresql.jdbc.PgConnection", inst);
117 transformClass("org.postgresql.jdbc.PgPreparedStatement", inst);
89 118 transformClass("org.postgresql.jdbc.PgStatement", inst); transformClass("org.postgresql.jdbc.PgStatement", inst);
119 transformClass("org.postgresql.jdbc.PgResultSet", inst);
120 }
90 121
91 122 if (1 == 0) { if (1 == 0) {
123 // Most of these are 'interfaces', not 'classes'!
124 // But, without transorming these, the important ones are NOT working! Not so sure anymore!
125 // Probably is something linked with intializations
126 transformClass("oracle.jdbc.OraclePreparedStatement", inst);
127 transformClass("oracle.jdbc.OracleResultSet", inst);
128 transformClass("oracle.jdbc.OracleConnection", inst);
129 transformClass("oracle.jdbc.OracleStatement", inst);
130 transformClass("oracle.jdbc.OracleCallableStatement", inst);
131 }
132
133 if (1 == 0) {
134 transformClass("oracle.jdbc.OracleConnection", inst);
135 transformClass("oracle.jdbc.OracleConnectionBuilder", inst);
136 transformClass("oracle.jdbc.OracleConnectionStringBuilder", inst); // this is interface
137 transformClass("oracle.jdbc.OracleConnectionStringBuilderImpl", inst);
138 transformClass("oracle.jdbc.OracleConnectionWrapper", inst); // This is very important; without it we cannot access oracle/jdbc/driver/OraclePreparedStatementWrapper/execute
139 }
140
141 if (1 == 0) {
142 transformClass("oracle.jdbc.internal.OracleConnection", inst);
143 transformClass("oracle.jdbc.internal.OraclePreparedStatement", inst);
144 transformClass("oracle.jdbc.internal.OracleStatement", inst);
145 transformClass("oracle.jdbc.internal.OracleCallableStatement", inst);
146 transformClass("oracle.jdbc.internal.AbstractConnectionBuilder", inst);
147 }
148
149 transformClass("oracle.jdbc.driver.PhysicalConnection", inst); // STAY!
150 transformClass("oracle.jdbc.driver.OracleDriver", inst); // STAY!
151 transformClass("oracle.jdbc.driver.OracleStatement", inst); // STAY!
152 transformClass("oracle.jdbc.driver.OracleStatementWrapper", inst); // STAY!
153 transformClass("oracle.jdbc.driver.OraclePreparedStatementWrapper", inst); // STAY!
154 transformClass("oracle.jdbc.driver.OracleCallableStatementWrapper", inst); // STAY!
155 transformClass("oracle.jdbc.driver.InsensitiveScrollableResultSet", inst); // STAY! for ResultSet.next()
156
157 if (2 == 0) {
158 transformClass("oracle.jdbc.driver.OracleSql", inst);
159 transformClass("oracle.jdbc.driver.OracleResultSet", inst);
160 transformClass("oracle.jdbc.driver.GeneratedPhysicalConnection", inst);
161 transformClass("oracle.jdbc.driver.OracleDriverExtension", inst);
162 transformClass("oracle.jdbc.driver.OraclePreparedStatement", inst);
163 transformClass("oracle.jdbc.driver.OracleCallableStatement", inst);
164 transformClass("oracle.jdbc.driver.OracleClosedStatement", inst);
165 transformClass("oracle.jdbc.driver.GeneratedStatement", inst);
166 }
167
168 if (1 == 0) {
169 transformClass("oracle.jdbc.driver.T2CConnection", inst);
170 transformClass("oracle.jdbc.driver.T2CStatement", inst);
171 transformClass("oracle.jdbc.driver.T2CPreparedStatement", inst);
172 transformClass("oracle.jdbc.driver.T2CDirectPathPreparedStatement", inst);
173 transformClass("oracle.jdbc.driver.T2CDriverExtension", inst);
174
175 transformClass("oracle.jdbc.driver.T4CConnection", inst);
176 transformClass("oracle.jdbc.driver.T4CStatement", inst);
177 transformClass("oracle.jdbc.driver.T4CPreparedStatement", inst);
178 transformClass("oracle.jdbc.driver.T4CDirectPathPreparedStatement", inst);
179 transformClass("oracle.jdbc.driver.T4CDriverExtension", inst);
180 }
181
182 // MySQL
183 transformClass("com.mysql.jdbc.Driver", inst);
184 transformClass("com.mysql.cj.jdbc.Driver", inst);
185 transformClass("com.mysql.cj.jdbc.ConnectionImpl", inst);
186 transformClass("com.mysql.cj.jdbc.NonRegisteringDriver", inst);
187 transformClass("com.mysql.cj.jdbc.ClientPreparedStatement", inst);
188 transformClass("com.mysql.cj.jdbc.StatementImpl", inst);
189 transformClass("com.mysql.cj.jdbc.result.ResultSetImpl", inst);
190
191 if (1 == 1) {
92 192 transformClass("java.net.http.HttpClient", inst); transformClass("java.net.http.HttpClient", inst);
93 193 } }
94 194
95 195 //transformClass("sun.security.ssl.X509TrustManager", inst); // not working //transformClass("sun.security.ssl.X509TrustManager", inst); // not working
96 196 //transformClass("javax.net.ssl", inst); // not working //transformClass("javax.net.ssl", inst); // not working
97 197
98 if (1 == 0) {
198 if (1 == 1) {
99 199 transformClass("sun.security.ssl.X509TrustManagerImpl", inst); transformClass("sun.security.ssl.X509TrustManagerImpl", inst);
100 transformClass("java.security.cert.X509Certificate", inst);
200 //interface transformClass("java.security.cert.X509Certificate", inst);
101 201 transformClass("java.security.cert.Certificate", inst); transformClass("java.security.cert.Certificate", inst);
102 202 transformClass("java.security.cert.CertificateFactory", inst); transformClass("java.security.cert.CertificateFactory", inst);
103 203 } }
 
... ... public class MyInstrumentationAgent
111 211 //transformClass("java.io.FileInputStream", inst); //transformClass("java.io.FileInputStream", inst);
112 212 //transformClass("java.io.ByteArrayInputStream", inst); //transformClass("java.io.ByteArrayInputStream", inst);
113 213
114 if (1 == 0) {
214 if (1 == 1) {
115 215 transformClass("javax.net.ssl.X509TrustManager", inst); transformClass("javax.net.ssl.X509TrustManager", inst);
116 216 transformClass("javax.net.ssl.X509KeyManager", inst); transformClass("javax.net.ssl.X509KeyManager", inst);
117 217 transformClass("sun.security.provider.X509Factory", inst); transformClass("sun.security.provider.X509Factory", inst);
 
... ... public class MyInstrumentationAgent
120 220 } }
121 221 } }
122 222
123 System.err.println("Premain finish...");
223 if (2 == 2) {
224 for (Class<?> clazz: inst.getAllLoadedClasses()) {
225 if (clazz.getName().startsWith("oracle.jdbc.")
226 || clazz.getName().startsWith("org.postgresql.")
227 || clazz.getName().startsWith("com.mysql.")
228 || clazz.getName().startsWith("java.sql.")) {
229 System.err.println(" iter2 " + clazz.getName());
230 transformClass(clazz.getName(), inst);
231 }
232 }
233 }
234
235 System.err.println("MyInstrumentationAgent.premain... done");
124 236 } }
125 237 } }
126 238
File agent/java/agent/QueryTransformer.java changed (mode: 100644) (index 29ec08e..0850459)
... ... import javassist.CtMethod;
7 7 import javassist.CtConstructor; import javassist.CtConstructor;
8 8 import javassist.NotFoundException; import javassist.NotFoundException;
9 9
10 import java.lang.Exception;
10 11 import java.io.IOException; import java.io.IOException;
11 12 import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.ClassFileTransformer;
12 13 import java.lang.instrument.IllegalClassFormatException; import java.lang.instrument.IllegalClassFormatException;
 
... ... import java.security.ProtectionDomain;
14 15
15 16 public class QueryTransformer implements ClassFileTransformer public class QueryTransformer implements ClassFileTransformer
16 17 { {
17 private static final String WITHDRAW_MONEY_METHOD = "executeQuery";
18 //private static final String WITHDRAW_MONEY_METHOD = "executeQuery";
18 19
19 20 /** The internal form class name of the class to transform */ /** The internal form class name of the class to transform */
20 21 private String targetClassName; private String targetClassName;
 
... ... public class QueryTransformer implements ClassFileTransformer
26 27 { {
27 28 //System.err.println("QueryTransformer.QueryTransformer: targetClassname=" //System.err.println("QueryTransformer.QueryTransformer: targetClassname="
28 29 // + targetClassName + " loader=" + targetClassLoader); // + targetClassName + " loader=" + targetClassLoader);
29 this.targetClassName = targetClassName;
30 this.targetClassName = targetClassName.replaceAll("\\.", "/"); // replace '.' with '/';
30 31 this.targetClassLoader = targetClassLoader; this.targetClassLoader = targetClassLoader;
31 32 } }
32 33
34 /*
35 * @loader - the defining loader, may be null if bootstrap loader
36 * @className - example: "java/util/List"
37 * @classBeingRedefined - null if is a class load
38 * We should return null if we do not perform any transformation
39 */
33 40 @Override @Override
34 public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
35 ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException
41 public byte[] transform(ClassLoader loader, String className,
42 Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
43 byte[] classfileBuffer) throws IllegalClassFormatException
36 44 { {
37 45 byte[] byteCode = classfileBuffer; byte[] byteCode = classfileBuffer;
38 46
47 if (!className.equals(this.targetClassName)) {
48 //System.err.println(" ignore class [" + className + "] != [" + this.targetClassName + "]");
49 return null;
50 }
51
39 52 if (loader != null) { if (loader != null) {
40 53 if (!loader.equals(this.targetClassLoader)) { if (!loader.equals(this.targetClassLoader)) {
41 54 //System.err.println(" ignore loader [" + loader + "] != [" + this.targetClassLoader + "]"); //System.err.println(" ignore loader [" + loader + "] != [" + this.targetClassLoader + "]");
42 return byteCode;
55 return null;
43 56 } }
44 57 } }
45 58
46 String finalTargetClassName = this.targetClassName.replaceAll("\\.", "/"); //replace . with /
47
48 if (!className.equals(finalTargetClassName)) {
49 //System.err.println(" ignore class [" + className + "] != [" + finalTargetClassName + "]");
50 return byteCode;
51 }
52
53 //System.err.println("QueryTransformer.transform(loader=" + loader
54 // + ", className=" + className
55 // + ", classBeignRedefined=" + classBeingRedefined.getName()
56 // + ", protectionDomain=" + protectionDomain
57 // + ")...");
59 // Activating this will generate a Permission error!
60 if (1 == 0)
61 System.out.println("QueryTransformer.transform(loader=" + loader
62 + ", className=" + className
63 + ", classBeignRedefined=" + classBeingRedefined.getName()
64 + ", protectionDomain=" + protectionDomain
65 + ")...");
58 66
59 67 //String s = new String(byteCode); //String s = new String(byteCode);
60 68 //System.err.println(" bytecode before: " + s); //System.err.println(" bytecode before: " + s);
61 69 try { try {
62 70 ClassPool cp = ClassPool.getDefault(); ClassPool cp = ClassPool.getDefault();
63 CtClass cc = cp.get(targetClassName);
71 CtClass cc = cp.get(targetClassName.replaceAll("/", "."));
64 72 //CtMethod m = cc.getDeclaredMethod(WITHDRAW_MONEY_METHOD); //CtMethod m = cc.getDeclaredMethod(WITHDRAW_MONEY_METHOD);
65 73 //System.err.println(" CtMethod: " + m); //System.err.println(" CtMethod: " + m);
66 74
67 75 // seems this crashes at some point // seems this crashes at some point
68 if (className.equals("TODO java/io/File TODO")) {
76 if (className.equals("TODO java/io/File TODO")
77 || className.startsWith("todo org/postgresql/")) {
78 //System.err.println(" Iterating constructors...");
69 79 CtConstructor[] cons = cc.getDeclaredConstructors(); CtConstructor[] cons = cc.getDeclaredConstructors();
70 80 for (CtConstructor con : cons) { for (CtConstructor con : cons) {
71 81 StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
72 82 StringBuilder eb = new StringBuilder(); StringBuilder eb = new StringBuilder();
73 83
74 84 String sig = con.getSignature(); String sig = con.getSignature();
75 System.err.println(" constructor: " + con + " sig=" + sig);
76 sb.append("ninedogs.log(\"constructor for class " + className + " " + sig + " this=\" + this + \" $0=\" + $0);");
77 eb.append("ninedogs.log(\" exit this: \" + this + \" $0=\" + $0);"); // seems 'this' is always null...
85 //System.err.println(" constructor: " + con + " sig=" + sig);
86 // todo this generates error: sb.append("ninedogs.log(\"constructor for class "
87 // + className + " " + sig + " this=\" + this + \" $0=\" + $0);");
88 sb.append("ninedogs.log(\"constructor for class ["
89 + className + "] sig=[" + sig + "]\");");
90 eb.append("ninedogs.log(\" exit this: \" + this + \" R=\" + $_);"); // seems 'this' is always null...
78 91
79 92 CtClass[] pTypes = con.getParameterTypes(); CtClass[] pTypes = con.getParameterTypes();
80 93 for (int i = 0; i < pTypes.length; i++) for (int i = 0; i < pTypes.length; i++)
81 94 sb.append("ninedogs.log(\" c-para[" + i + "] [" + pTypes[i].getName() + "]: \" + $args[" + i + "]);"); sb.append("ninedogs.log(\" c-para[" + i + "] [" + pTypes[i].getName() + "]: \" + $args[" + i + "]);");
82 95
83 con.insertBefore("{" + sb.toString() + "}");
84 con.insertAfter("{" + eb.toString() + "}");
96 if (sb.length() > 0)
97 con.insertBefore("{" + sb.toString() + "}");
98 if (eb.length() > 0)
99 con.insertAfter("{" + eb.toString() + "}");
85 100 } }
86 101 } }
87 102
88 ///System.err.println(" Iterating methods...");
103 //System.err.println(" Iterating methods...");
89 104 // Searchy for (Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection; // Searchy for (Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;
90 105 CtMethod[] methods = cc.getDeclaredMethods(); CtMethod[] methods = cc.getDeclaredMethods();
91 106 //CtMethod m = cc.getDeclaredMethod("connect", params); //CtMethod m = cc.getDeclaredMethod("connect", params);
92 107 for (CtMethod m : methods) { for (CtMethod m : methods) {
93 108 String sig = m.getSignature(); String sig = m.getSignature();
94 ///System.err.println(" method " + m.getName() + " sig: " + sig + "...");
109 //System.err.println(" className=[" + className + "] method=[" + m.getName() + "] sig=[" + sig + "] byteCode.length=" + byteCode.length);
95 110
96 111 StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
97 112 StringBuilder eb = new StringBuilder(); StringBuilder eb = new StringBuilder();
98 113 StringBuilder ee = new StringBuilder(); StringBuilder ee = new StringBuilder();
99 //CtClass etype = ClassPool.getDefault().get("java.io.IOException");
114 CtClass etype = ClassPool.getDefault().get("java.lang.Exception");
100 115 // TODO: for postgresql code the next code was un-commented! // TODO: for postgresql code the next code was un-commented!
101 116 //CtClass etype = cp.get("org.postgresql.util.PSQLException"); //CtClass etype = cp.get("org.postgresql.util.PSQLException");
102 117
103 118 // This is heavy debug // This is heavy debug
104 119 //sb.append("System.err.println(\"method " + className + "." + m.getName() + " " + sig + "\");"); //sb.append("System.err.println(\"method " + className + "." + m.getName() + " " + sig + "\");");
105 ///sb.append("ninedogs.log(\"method " + className + "." + m.getName() + " " + sig + "\");");
106 ///eb.append("ninedogs.log(\" ret: \" + $_);");
107
108 if (className.equals("org/postgresql/Driver")
109 && m.getName().equals("connect")
110 && sig.equals("(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;")) {
111 System.err.println("========= Intercept connect [" + className + "]");
112 sb.append("ninedogs.log(\"db pg con s \" + $1);");
113 eb.append("ninedogs.log(\"db pg con e \");");
114 ee.append("ninedogs.log(\"db pg con x \" + $e + \"; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
115 } else if (className.equals("org/postgresql/jdbc/PgConnection")
116 && m.getName().equals("prepareStatement")
117 && (sig.equals("(Ljava/lang/String;III)Ljava/sql/PreparedStatement;"))) {
118 System.err.println("========= Intercept prepareStatement [" + className + "] [" + sig + "]");
119 sb.append("ninedogs.log(\"db pg ps s \" + $1);");
120 eb.append("ninedogs.log(\"db pg ps e \");");
121 ee.append("ninedogs.log(\"db pg ps x \" + $e + \"; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
122 } else if (className.equals("org/postgresql/jdbc/PgStatement")
123 && m.getName().equals("executeInternal")
124 && (sig.equals("(Lorg/postgresql/core/CachedQuery;Lorg/postgresql/core/ParameterList;I)V"))) {
125 System.err.println("========= Intercept executeInternal[" + className + "] [" + sig + "]");
126 sb.append("ninedogs.log(\"db pg exe s \" + $1 + \" \" + $2);");
127 eb.append("ninedogs.log(\"db pg exe e \");");
128 ee.append("ninedogs.log(\"db pg exe x \" + $e + \"; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
120 sb.append("ninedogs.log(\"GEN method [" + className + "/" + m.getName() + "] sig=[" + sig + "]: begin\");");
121 // this seems to not be available - sb.append("try { ninedogs.log(\" this=\" + this); } catch (Exception e) {}");
122 // seems I get a compile error - sb.append("try { ninedogs.log(\" $0=\" + $0); } catch (Exception e) {}");
123 eb.append("ninedogs.log(\"GEN method [" + className + "/" + m.getName() + "] sig=[" + sig + "]: R=[\" + $_ + \"]\");");
124 // todo - seems is not working:
125 // if we activate it, it will be executed before specific exception!
126 //ee.append("ninedogs.log(\"GEN method [" + className + "/" + m.getName() + "] sig=[" + sig + "]: EXCEPTION: [\" + $e + \"]\"); throw $e;");
127
128 Boolean ignore_most = false;
129
130 ////////////////////////////////////////////////////////////// MySQL start
131 if (className.equals("com/mysql/cj/jdbc/NonRegisteringDriver")) {
132 if (m.getName().equals("connect")
133 && sig.equals("(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;")) {
134 sb.append("ninedogs.db('M', 'c', 's', $0, $1, $2, null);");
135 eb.append("ninedogs.db('M', 'c', 'e', $0, $1, $2, $_);");
136 ee.append("ninedogs.db('M', 'c', 'x', $0, $1, $2, $e); throw $e;");
137 } else if (ignore_most) {
138 continue;
139 }
140 } else if (className.equals("com/mysql/cj/jdbc/ConnectionImpl")) {
141 if (m.getName().equals("prepareStatement")) {
142 if (sig.equals("(Ljava/lang/String;)Ljava/sql/PreparedStatement;")) { // con.prepareStatement("SELECT ? AS id");
143 sb.append("ninedogs.db('M', 'p', 's', $0, $1, null, null);"); // TODO: not sure we need this
144 eb.append("ninedogs.db('M', 'p', 'e', $0, $1, $_, null);");
145 ee.append("ninedogs.db('M', 'p', 'x', $0, $1, $e, null); throw $e;");
146 } else if (ignore_most) {
147 continue;
148 }
149 } else if (m.getName().equals("createStatement")
150 && sig.equals("()Ljava/sql/Statement;")) { // it links 'con' with 'stmt'; 'sb' is not really useful
151 eb.append("ninedogs.db('M', 'f', 'e', $0, $_, null, null);");
152 ee.append("ninedogs.db('M', 'f', 'x', $0, $e, null, null); throw $e;");
153 } else if (m.getName().equals("close") && sig.equals("()V")) {
154 eb.append("ninedogs.db('M', 'x', 'e', $0, null, null, null);");
155 ee.append("ninedogs.db('M', 'x', 'x', $0, $e, null, null); throw $e;");
156 } else if (ignore_most) {
157 continue;
158 }
159 } else if (className.equals("com/mysql/cj/jdbc/ClientPreparedStatement")) {
160 if (m.getName().equals("getInstance")) { // TODO - really used?
161 if (sig.equals("(Lcom/mysql/cj/jdbc/JdbcConnection;Ljava/lang/String;Ljava/lang/String;)Lcom/mysql/cj/jdbc/ClientPreparedStatement;")) {
162 sb.append("ninedogs.db('M', 'p', 's', $0, $1, null, null);"); // TODO: not sure we need this
163 eb.append("ninedogs.db('M', 'p', 'e', $0, $1, $_, null);");
164 ee.append("ninedogs.db('M', 'p', 'x', $0, $1, $e, null); throw $e;");
165 } else if (sig.equals("TODO ()Ljava/sql/ResultSet;")) {
166 sb.append("ninedogs.db('M', 'e', 's', $0, null, null, null);");
167 eb.append("ninedogs.db('M', 'e', 'e', $0, $_, null, null);");
168 ee.append("ninedogs.db('M', 'e', 'x', $0, $e, null, null); throw $e;");
169 } else if (ignore_most) {
170 continue;
171 }
172 } else if (m.getName().equals("executeQuery")) {
173 if (sig.equals("()Ljava/sql/ResultSet;")) {
174 sb.append("ninedogs.db('M', 'e', 's', $0, null, null, null);");
175 eb.append("ninedogs.db('M', 'e', 'e', $0, $_, null, null);");
176 ee.append("ninedogs.db('M', 'e', 'x', $0, $e, null, null); throw $e;");
177 } else if (ignore_most) {
178 continue;
179 }
180 } else if (m.getName().equals("setInt") && sig.equals("(II)V")) {
181 eb.append("ninedogs.db('M', 'b', 'e', $0, Integer.valueOf($1), Integer.valueOf($2), $_);");
182 ee.append("ninedogs.db('M', 'b', 'x', $0, Integer.valueOf($1), Integer.valueOf($2), $e); throw $e;");
183 } else if (m.getName().equals("setString") && sig.equals("(ILjava/lang/String;)V")) {
184 eb.append("ninedogs.db('M', 'S', 'e', $0, Integer.valueOf($1), $2, $_);");
185 ee.append("ninedogs.db('M', 'S', 'x', $0, Integer.valueOf($1), $2, $e); throw $e;");
186 } else if (ignore_most) {
187 continue;
188 }
189 } else if (className.equals("com/mysql/cj/jdbc/StatementImpl")) {
190 if (m.getName().equals("close") && sig.equals("()V")) {
191 eb.append("ninedogs.db('M', 'w', 'e', $0, null, null, null);");
192 ee.append("ninedogs.db('M', 'w', 'x', $0, $e, null, null); throw $e;");
193 } else if (m.getName().equals("executeQuery")
194 && sig.equals("(Ljava/lang/String;)Ljava/sql/ResultSet;")) { // this is for normal query
195 sb.append("ninedogs.db('M', 'Q', 's', $0, $1, null, null);");
196 eb.append("ninedogs.db('M', 'Q', 'e', $0, $1, $_, null);");
197 ee.append("ninedogs.db('M', 'Q', 'x', $0, $1, $e, null); throw $e;");
198 } else if (ignore_most) {
199 continue;
200 }
201 } else if (className.equals("com/mysql/cj/jdbc/result/ResultSetImpl")) {
202 if (m.getName().equals("next") && sig.equals("()Z")) {
203 sb.append("ninedogs.log(\"db M " + className + "/" + m.getName() + " s: 0=\" + $0);");
204 eb.append("ninedogs.log(\"db M " + className + "/" + m.getName() + " e: 0=\" + $0 + \" R=\" + $_);");
205 ee.append("ninedogs.log(\"db M " + className + "/" + m.getName() + " x: 0=\" + $0 + \" e=[\" + $e + \"]; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
206 } else if (ignore_most) {
207 continue;
208 }
209 ////////////////////////////////////////////////////////////// MySQL END
210
211 ////////////////////////////////////////////////////////////// PostgreSQL start
212 } else if (className.equals("org/postgresql/Driver")) {
213 if (m.getName().equals("connect")
214 && sig.equals("(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;")) {
215 sb.append("ninedogs.db('P', 'c', 's', $0, $1, $2, null);");
216 eb.append("ninedogs.db('P', 'c', 'e', $0, $1, $2, $_);");
217 ee.append("ninedogs.db('P', 'c', 'x', $0, $1, $2, $e); throw $e;"); // + \" e=[\" + $e + \"]; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
218 } else if (ignore_most) {
219 continue;
220 }
221 } else if (className.equals("org/postgresql/jdbc/PgPreparedStatement")) { // 'close' does not exists (it is the one from PgStatement)
222 if (m.getName().equals("executeQuery")) {
223 if (sig.equals("(Lorg/postgresql/core/CachedQuery;Lorg/postgresql/core/ParameterList;I)V")) {
224 sb.append("ninedogs.log(\"db P " + className + "/" + m.getName() + " s: 0=\" + $0);");
225 eb.append("ninedogs.log(\"db P " + className + "/" + m.getName() + " e: 0=\" + $0 + \" R=\" + $_);");
226 ee.append("ninedogs.log(\"db P " + className + "/" + m.getName() + " x: 0=\" + $0 + \" e=[\" + $e + \"]; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
227 } else if (sig.equals("()Ljava/sql/ResultSet;")) {
228 sb.append("ninedogs.db('P', 'e', 's', $0, null, null, null);");
229 eb.append("ninedogs.db('P', 'e', 'e', $0, $_, null, null);");
230 ee.append("ninedogs.db('P', 'e', 'x', $0, $e, null, null); throw $e;");
231 } else if (ignore_most) {
232 continue;
233 }
234 } else if (m.getName().equals("setInt") && sig.equals("(II)V")) {
235 eb.append("ninedogs.db('P', 'b', 'e', $0, Integer.valueOf($1), Integer.valueOf($2), $_);");
236 ee.append("ninedogs.db('P', 'b', 'x', $0, Integer.valueOf($1), Integer.valueOf($2), $e); throw $e;");
237 } else if (m.getName().equals("setString") && sig.equals("(ILjava/lang/String;)V")) {
238 eb.append("ninedogs.db('P', 'S', 'e', $0, Integer.valueOf($1), $2, $_);");
239 ee.append("ninedogs.db('P', 'S', 'x', $0, Integer.valueOf($1), $2, $e); throw $e;");
240 } else if (ignore_most) {
241 continue;
242 }
243 } else if (className.equals("org/postgresql/jdbc/PgStatement")) {
244 if (m.getName().equals("close") && sig.equals("()V")) {
245 eb.append("ninedogs.db('P', 'w', 'e', $0, null, null, null);");
246 ee.append("ninedogs.db('P', 'w', 'x', $0, $e, null, null); throw $e;");
247 } else if (m.getName().equals("executeQuery")
248 && sig.equals("(Ljava/lang/String;)Ljava/sql/ResultSet;")) { // this is for normal query
249 sb.append("ninedogs.db('P', 'Q', 's', $0, $1, null, null);");
250 eb.append("ninedogs.db('P', 'Q', 'e', $0, $1, $_, null);");
251 ee.append("ninedogs.db('P', 'Q', 'x', $0, $1, $e, null); throw $e;");
252 } else if (m.getName().equals("executeQuery")
253 && sig.equals("()Ljava/sql/ResultSet;")) { // this is for prepared query
254 sb.append("ninedogs.db('P', 'P', 's', $0, null, null, null);");
255 eb.append("ninedogs.db('P', 'P', 'e', $0, $_, null, null);");
256 ee.append("ninedogs.db('P', 'P', 'x', $0, $e, null, null); throw $e;");
257 } else if (ignore_most) {
258 continue;
259 }
260 } else if (className.equals("org/postgresql/jdbc/PgResultSet")) {
261 if (m.getName().equals("next") && sig.equals("()Z")) {
262 sb.append("ninedogs.log(\"db P " + className + "/" + m.getName() + " s: 0=\" + $0);");
263 eb.append("ninedogs.log(\"db P " + className + "/" + m.getName() + " e: 0=\" + $0 + \" R=\" + $_);");
264 ee.append("ninedogs.log(\"db P " + className + "/" + m.getName() + " x: 0=\" + $0 + \" e=[\" + $e + \"]; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
265 } else if (ignore_most) {
266 continue;
267 }
268 } else if (className.equals("org/postgresql/jdbc/PgConnection")) {
269 if (m.getName().equals("close") && sig.equals("()V")) {
270 eb.append("ninedogs.db('P', 'x', 'e', $0, null, null, null);");
271 ee.append("ninedogs.db('P', 'x', 'x', $0, $e, null, null); throw $e;");
272 } else if (m.getName().equals("createStatement")
273 && sig.equals("()Ljava/sql/Statement;")) { // it links 'con' with 'stmt'; 'sb' is not really useful
274 eb.append("ninedogs.db('P', 'f', 'e', $0, $_, null, null);");
275 ee.append("ninedogs.db('P', 'f', 'x', $0, $e, null, null); throw $e;");
276 } else if (m.getName().equals("prepareStatement")) {
277 if (sig.equals("(Ljava/lang/String;)Ljava/sql/PreparedStatement;")) { // con.prepareStatement("SELECT ? AS id");
278 sb.append("ninedogs.db('P', 'p', 's', $0, $1, null, null);"); // TODO: not sure we need this
279 eb.append("ninedogs.db('P', 'p', 'e', $0, $1, $_, null);");
280 ee.append("ninedogs.db('P', 'p', 'x', $0, $1, $e, null); throw $e;");
281 } else if (ignore_most) {
282 continue;
283 }
284 } else if (ignore_most) {
285 continue;
286 }
287 ////////////////////////////////////////////////////////////// PostgreSQL END
288
289 ////////////////////////////////////////////////////////////// Certs start
129 290 } else if (className.equals("sun/security/provider/X509Factory") } else if (className.equals("sun/security/provider/X509Factory")
130 291 && m.getName().equals("engineGenerateCertificate") && m.getName().equals("engineGenerateCertificate")
131 && (sig.equals("(Ljava/io/InputStream;)Ljava/security/cert/Certificate;"))) {
132 //System.err.println(" Overwrite engineGenerateCertificate =================================");
292 && sig.equals("(Ljava/io/InputStream;)Ljava/security/cert/Certificate;")) {
133 293 eb.append("ninedogs.log_cert($1, $_);"); eb.append("ninedogs.log_cert($1, $_);");
134 294 } else if (className.equals("java/security/cert/X509Certificate")) { } else if (className.equals("java/security/cert/X509Certificate")) {
295 ////////////////////////////////////////////////////////////// Certs END
296
297 ////////////////////////////////////////////////////////////// Oracle starts
298 } else if (className.equals("oracle/jdbc/driver/OracleDriver")) { // seems we get this connection in java/sql/DriverManager!
299 if (m.getName().equals("connect")) {
300 if (sig.equals("(Ljava/lang/String;Ljava/util/Properties;Loracle/jdbc/internal/AbstractConnectionBuilder;)Ljava/sql/Connection;")) {
301 sb.append("ninedogs.db('O', 'c', 's', $0, $1, $2, null);");
302 eb.append("ninedogs.db('O', 'c', 'e', $0, $1, $2, $_);");
303 ee.append("ninedogs.db('O', 'c', 'x', $0, $1, $2, $e); throw $e;");
304 } else {
305 continue;
306 }
307 } else if (ignore_most) {
308 continue;
309 }
310 } else if (className.equals("oracle/jdbc/driver/PreparedStatement")) {
311 if (m.getName().equals("execute") && sig.equals("()Z")) {
312 sb.append("ninedogs.db('O', 'e', 's', $0, null, null, null);");
313 eb.append("ninedogs.db('O', 'e', 'e', $0, $_, null, null);");
314 ee.append("ninedogs.db('O', 'e', 'x', $0, $e, null, null); throw $e;");
315 } else if (ignore_most) {
316 continue;
317 }
318 } else if (className.equals("oracle/jdbc/driver/PhysicalConnection")) {
319 if (m.getName().equals("prepareStatementInternal")) { // STAY!
320 if (sig.equals("(Ljava/lang/String;Ljava/util/Properties;)Loracle/jdbc/driver/OraclePreparedStatement;")) { // STAY!
321 sb.append("ninedogs.db('O', 'p', 's', $0, $1, null, null);");
322 eb.append("ninedogs.db('O', 'p', 'e', $0, $1, $_, null);");
323 ee.append("ninedogs.db('O', 'p', 'x', $0, $1, $e, null); throw $e;");
324 } else {
325 continue;
326 }
327 } else if (m.getName().equals("prepareStatement")) {
328 continue;
329 } else if (m.getName().equals("createStatement")
330 && sig.equals("()Ljava/sql/Statement;")) { // STAY!
331 eb.append("ninedogs.db('O', 'f', 'e', $0, $_, null, null);");
332 ee.append("ninedogs.db('O', 'f', 'x', $0, $e, null, null); throw $e;");
333 } else if (m.getName().equals("commit")
334 && sig.equals("()V")) { // STAY!
335 sb.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " s: 0=\" + $0);");
336 eb.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " e: 0=\" + $0 + \" R=\" + $_);");
337 ee.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " x: 0=\" + $0 + \" e=[\" + $e + \"]; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
338 } else if (m.getName().equals("rollback")
339 && sig.equals("()V")) { // STAY!
340 sb.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " s: 0=\" + $0);");
341 eb.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " e: 0=\" + $0 + \" R=\" + $_);");
342 ee.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " x: 0=\" + $0 + \" e=[\" + $e + \"]; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
343 } else if (m.getName().equals("close")
344 && sig.equals("()V")) { // STAY!
345 eb.append("ninedogs.db('O', 'x', 'e', $0, null, null, null);");
346 ee.append("ninedogs.db('O', 'x', 'x', $0, $e, null, null); throw $e;");
347 } else if (ignore_most) {
348 continue;
349 }
350 } else if (className.equals("oracle/jdbc/driver/OraclePreparedStatementWrapper")) {
351 if (m.getName().equals("execute") && sig.equals("()Z")) { // STAY!
352 sb.append("ninedogs.db('O', 'E', 's', $0, null, null, null);");
353 eb.append("ninedogs.db('O', 'E', 'e', $0, $_ == true ? $0 : null, null, null);"); // we cannot pass directly bool
354 ee.append("ninedogs.db('O', 'E', 'x', $0, $e, null, null); throw $e;");
355 } else if (m.getName().equals("setInt") && sig.equals("(II)V")) { // STAY!
356 eb.append("ninedogs.db('O', 'b', 'e', $0, Integer.valueOf($1), Integer.valueOf($2), $_);");
357 ee.append("ninedogs.db('O', 'b', 'x', $0, Integer.valueOf($1), Integer.valueOf($2), $e); throw $e;");
358 } else if (ignore_most) {
359 continue;
360 }
361 } else if (className.equals("oracle/jdbc/driver/OracleStatement")) {
362 if (m.getName().equals("executeQuery")
363 && sig.equals("(Ljava/lang/String;)Ljava/sql/ResultSet;")) { // STAY!
364 sb.append("ninedogs.db('O', 'Q', 's', $0, $1, null, null);");
365 eb.append("ninedogs.db('O', 'Q', 'e', $0, $1, $_, null);");
366 ee.append("ninedogs.db('O', 'Q', 'x', $0, $1, $e, null); throw $e;");
367 } else if (ignore_most) {
368 continue;
369 }
370 } else if (className.equals("oracle/jdbc/driver/InsensitiveScrollableResultSet")) {
371 if (m.getName().equals("next")
372 && sig.equals("()Z")) {
373 sb.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " s: 0=\" + $0);");
374 eb.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " e: 0=\" + $0 + \" R=\" + $_);");
375 ee.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " x: 0=\" + $0 + \" e=[\" + $e + \"]; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
376 } else if (ignore_most) {
377 continue;
378 }
379 } else if (className.equals("oracle/jdbc/driver/OracleStatementWrapper")) {
380 if (m.getName().equals("execute") && sig.equals("()Z")) {
381 sb.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " s: 0=\" + $0);");
382 eb.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " e: 0=\" + $0 + \" R=\" + $_);");
383 ee.append("ninedogs.log(\"db O " + className + "/" + m.getName() + " x: 0=\" + $0 + \" e=[\" + $e + \"]; Cause: \" + $e.getCause() + \" \" + $e.getStackTrace() + \".\"); throw $e;");
384 } else if (m.getName().equals("close") && sig.equals("()V")) { // STAY!
385 eb.append("ninedogs.db('O', 'w', 'e', $0, null, null, null);");
386 ee.append("ninedogs.db('O', 'w', 'x', $0, $e, null, null); throw $e;");
387 } else if (m.getName().equals("executeQuery")
388 && sig.equals("(Ljava/lang/String;)Ljava/sql/ResultSet;")) {
389 continue;
390 } else if (m.getName().equals("getResultSet")
391 && sig.equals("()Ljava/sql/ResultSet;")) { // STAY! TODO - not clear if we need 's' variant (if a db round trip takes place)
392 sb.append("ninedogs.db('O', 'g', 's', $0, null, null, null);");
393 eb.append("ninedogs.db('O', 'g', 'e', $0, $_, null, null);");
394 ee.append("ninedogs.db('O', 'g', 'x', $0, $e, null, null); throw $e;");
395 } else if (ignore_most) {
396 continue;
397 }
398 ////////////////////////////////////////////////////////////// Oracle END
135 399 } else { } else {
136 //System.err.println(" unknown class " + className + " in QueryTransformer! ===================");
137 //sb.append("ninedogs.log(\"gen " + className + " " + m.getName() + " " + sig + "\");");
138 //eb.append("ninedogs.log(\" db pg gen done " + className + " " + m.getName() + " " + sig + "\");");
139 //continue;
400 //System.err.println(" unknown class " + className + "/" + m.getName() + " in QueryTransformer! ===================");
401 //sb.append("ninedogs.log(\" gen b " + clas /Name + " " + m.getName() + " " + sig + "\");");
402 //eb.append("ninedogs.log(\" gen e " + className + "/" + m.getName() + " " + sig + "\");");
403 if (ignore_most)
404 continue;
140 405 } }
141 406
142 407 /* /*
 
... ... public class QueryTransformer implements ClassFileTransformer
155 420 //sb.append("sbArgs.append(System.identityHashCode( $0 ) );"); //sb.append("sbArgs.append(System.identityHashCode( $0 ) );");
156 421 */ */
157 422
158 //CtClass[] pTypes = m.getParameterTypes();
159 //for (int i = 0; i < pTypes.length; i++) {
160 //if ((i == 0) && (pTypes[i].toString() == "java.lang.String"))
161 ///sb.append("ninedogs.log(\" para[" + i + "] [" + pTypes[i].getName() + "]: \" + $args[" + i + "]);");
162 // pType.toString() - too verbose
423 if (1 == 1) {
424 CtClass[] pTypes = m.getParameterTypes();
425 for (int i = 0; i < pTypes.length; i++) {
426 sb.append("ninedogs.log(\" para[" + i + "] [" + pTypes[i].getName()
427 + "]: \" + $args[" + i + "]);");
163 428
164 //if (pTypes[i].isPrimitive()) {
165 // sb.append("System.err.println(\" para prim " + i + ": " + pTypes[i].toString() + " prim: \" + $args[" + i + "]);");
166 //} else {
167 // sb.append("System.err.println(\" para !prim " + i + ": \" + System.identityHashCode($args[" + i + "]));");
168 //}
169 //sb.append("System.err.println(\" para " + i + ": class: \" + $args[" + i + "].getClass());");
170 //}
429 if (1 == 0) {
430 if (pTypes[i].toString() == "java.lang.String") {
431 //sb.append("System.err.println(\" " + m.getName() + ": para " + i
432 // + " str: " + pTypes[i].getName() + ": \" + $args[" + i + "]);");
433 //sb.append("ninedogs.log(\" para[" + i + "] [" + pTypes[i].getName()
434 // + "]: \" + $args[" + i + "]);");
435 //pType.toString() - too verbose
436 } else if (pTypes[i].isPrimitive()) {
437 sb.append("System.err.println(\" " + className + ": " + m.getName() + ": para " + i
438 + " prim: " + pTypes[i].toString() + ": value=[\" + $args[" + i + "] + \"]\");");
439 //sb.append("System.err.println(\" " + m.getName() + ": para " + i + " name: " + pTypes[i].getName() + ": \" + $args[" + i + "]);");
440 } else {
441 sb.append("System.err.println(\" " + className + ": " + m.getName() + ": para " + i
442 + " !prim: hash=\" + System.identityHashCode($args[" + i + "])"
443 + " + \": class: \" + $args[" + i + "].getClass() + \" value=[\" + $args[" + i + "] + \"]\");");
444 }
445 }
446 }
447 }
171 448
172 /*
449 /*
173 450 m.insertBefore("{" + sb.toString() + "}"); m.insertBefore("{" + sb.toString() + "}");
174 451
175 452 eb.append("endTime = System.currentTimeMillis();"); eb.append("endTime = System.currentTimeMillis();");
176 453 eb.append("opTime = endTime - startTime;"); eb.append("opTime = endTime - startTime;");
177 454 eb.append("System.err.println(\" " + m.getName() + ": \" + opTime + \"ms: \" + $_);"); eb.append("System.err.println(\" " + m.getName() + ": \" + opTime + \"ms: \" + $_);");
178 455 m.insertAfter("{" + eb.toString() + "}"); m.insertAfter("{" + eb.toString() + "}");
179 */
456 */
180 457
181 if (sb.length() > 0)
182 m.insertBefore("{" + sb.toString() + "}");
183 if (eb.length() > 0)
184 m.insertAfter("{" + eb.toString() + "}");
185 // TODO: this code was un-commented - see above
186 //if (ee.length() > 0)
187 // m.addCatch("{" + ee.toString() + "}", etype);
458 try {
459 if (sb.length() > 0)
460 m.insertBefore("try {" + sb.toString() + "} catch (Exception _e) {}");
461 if (eb.length() > 0)
462 m.insertAfter("try {" + eb.toString() + "} catch (Exception _e) {}");
463 if (ee.length() > 0)
464 m.addCatch("{" + ee.toString() + "}", etype);
465 } catch (Exception e) {
466 System.err.println("Cannot insert code [" + className + "/" + m.getName() + ": " + e);
467 }
188 468 } }
189 469
190 470 byteCode = cc.toBytecode(); byteCode = cc.toBytecode();
191 471 //System.err.println(" bytecode after: " + byteCode); //System.err.println(" bytecode after: " + byteCode);
192 472 cc.detach(); cc.detach();
193 //System.err.println(" bytecode rewritten ok");
194 } catch (NotFoundException | CannotCompileException | IOException e) {
473 } catch (Exception e) {
195 474 System.err.println(" QueryTransformer.transform Exception: " + e); System.err.println(" QueryTransformer.transform Exception: " + e);
475 return null;
196 476 } }
197 477
198 478 return byteCode; return byteCode;
File agent/java/agent/ninedogs.java changed (mode: 100644) (index f57bcf4..9e3c52a)
1 1 import java.io.*; import java.io.*;
2 import java.lang.Integer;
3 import java.util.Properties;
2 4 import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
3 5
4 6 public class ninedogs public class ninedogs
 
... ... public class ninedogs
9 11
10 12 public static void init() public static void init()
11 13 { {
12 System.err.println("ninedogs.init");
14 //System.err.println("ninedogs.init");
13 15
14 16 // First time, get() returns 'null' // First time, get() returns 'null'
15 17 if (init.get() != null) if (init.get() != null)
 
... ... public class ninedogs
19 21 file = new File("/dev/ninedogs"); file = new File("/dev/ninedogs");
20 22 fd = new FileOutputStream(file); fd = new FileOutputStream(file);
21 23 init.set(1); init.set(1);
22 System.err.println("ninedogs.init: init=" + init.get());
24 //System.err.println("ninedogs.init: init=" + init.get());
23 25 } catch (Exception e) { } catch (Exception e) {
24 26 System.err.println("ninedogs.init: exception " + e); System.err.println("ninedogs.init: exception " + e);
25 27 } }
26 28 } }
27 29
28 public static void metric(byte[] s)
30 public static void write(byte[] s)
29 31 { {
30 32 init(); init();
31 33
 
... ... public class ninedogs
39 41 } }
40 42 } }
41 43
42 public static void log(String s)
44 public static byte[] string2ninedogs(char type, byte[] ch)
43 45 { {
44 int stklen = Thread.currentThread().getStackTrace().length;
45 String prefix = "";
46
47 if (stklen >= 5)
48 stklen -= 5;
49 for (int i = 0; i < stklen; i++)
50 prefix += " ";
46 if (ch.length == 0)
47 return new byte[] {};
51 48
52 System.err.println("T" + Thread.currentThread() + " " + prefix + s);
53 }
54
55 public static byte[] string2ninedogs(String type, byte[] ch)
56 {
57 byte[] header = type.getBytes();
58 byte[] len = Integer.toString(ch.length).getBytes();
59 byte[] ret = new byte[header.length + len.length + 1 + ch.length];
49 byte[] len = String.format("%1$04x", ch.length).getBytes();
50 byte[] ret = new byte[1 + len.length + ch.length];
60 51 Integer off = 0; Integer off = 0;
61
62 System.arraycopy(header, 0, ret, 0, header.length); off += header.length;
52 ret[off++] = (byte) type;
63 53 System.arraycopy(len, 0, ret, off, len.length); off += len.length; System.arraycopy(len, 0, ret, off, len.length); off += len.length;
64 ret[off] = ' '; off += 1;
65 54 System.arraycopy(ch, 0, ret, off, ch.length); System.arraycopy(ch, 0, ret, off, ch.length);
66 55
67 56 return ret; return ret;
68 57 } }
69 58
70 public static byte[] string2ninedogs(String type, String s)
59 public static byte[] string2ninedogs(char type, String s)
71 60 { {
72 61 byte[] ch = s.getBytes(); byte[] ch = s.getBytes();
73 62 return string2ninedogs(type, ch); return string2ninedogs(type, ch);
74 63 } }
75 64
65 public static void log(String s)
66 {
67 int stklen = Thread.currentThread().getStackTrace().length;
68 String prefix = "";
69
70 //if (stklen >= 5)
71 // stklen -= 5;
72 for (int i = 0; i < stklen; i++)
73 prefix += " ";
74
75 //System.err.println("T" + Thread.currentThread() + " " + prefix + s);
76 byte[] x = string2ninedogs('L', Thread.currentThread() + "\t" + stklen + "\t" + prefix + s + "\n\0");
77 write(x);
78 }
79
76 80 public static void log_cert(java.io.InputStream is, public static void log_cert(java.io.InputStream is,
77 81 java.security.cert.Certificate cert) java.security.cert.Certificate cert)
78 82 { {
 
... ... public class ninedogs
86 90 Long ts; Long ts;
87 91 int off = 0; int off = 0;
88 92
89 subj = string2ninedogs("s", x.getSubjectX500Principal().toString());
90 issuer = string2ninedogs("i", x.getIssuerX500Principal().toString());
91 alg = string2ninedogs("a", x.getPublicKey().getAlgorithm().toString());
92 ser = string2ninedogs("x", x.getSerialNumber().toString(16));
93 //ser = string2ninedogs("x", x.getSerialNumber().toByteArray());
93 subj = string2ninedogs('s', x.getSubjectX500Principal().toString());
94 issuer = string2ninedogs('i', x.getIssuerX500Principal().toString());
95 alg = string2ninedogs('a', x.getPublicKey().getAlgorithm().toString());
96 ser = string2ninedogs('x', x.getSerialNumber().toString(16));
97 //ser = string2ninedogs('x', x.getSerialNumber().toByteArray());
94 98
95 99 ts = x.getNotBefore().getTime() / 1000; ts = x.getNotBefore().getTime() / 1000;
96 start = string2ninedogs("S", Long.toString(ts));
100 start = string2ninedogs('S', Long.toString(ts));
97 101
98 102 ts = x.getNotAfter().getTime() / 1000; ts = x.getNotAfter().getTime() / 1000;
99 end = string2ninedogs("E", Long.toString(ts));
103 end = string2ninedogs('E', Long.toString(ts));
100 104
101 105 byte[] last = new byte[1 + 1 + subj.length + issuer.length + alg.length + ser.length + start.length + end.length + 1]; byte[] last = new byte[1 + 1 + subj.length + issuer.length + alg.length + ser.length + start.length + end.length + 1];
102 106 last[off] = 'c'; off += 1; // c = cert last[off] = 'c'; off += 1; // c = cert
 
... ... public class ninedogs
108 112 System.arraycopy(start, 0, last, off, start.length); off += start.length; System.arraycopy(start, 0, last, off, start.length); off += start.length;
109 113 System.arraycopy(end, 0, last, off, end.length); off += end.length; System.arraycopy(end, 0, last, off, end.length); off += end.length;
110 114 last[off++] = 0; last[off++] = 0;
111 metric(last);
115 write(last);
116 }
117
118 public static void db(char db_type, char type, char subtype,
119 Object parent_this, Object p1, Object p2, Object p3)
120 {
121 byte[] hash, str ={}, str2 = {}, ret = {}, ex = {}, ex_cause = {};
122 int off = 0;
123 String r = null;
124 Object e = null;
125
126 try {
127 String shash = parent_this != null ? Integer.toHexString(parent_this.hashCode()) : null;
128 hash = string2ninedogs('h', shash);
129 String hp1 = p1 != null ? Integer.toHexString(p1.hashCode()) : null;
130 String hp2 = p2 != null ? Integer.toHexString(p2.hashCode()) : null;
131 String hp3 = p3 != null ? Integer.toHexString(p3.hashCode()) : null;
132
133 log("ninedogs.db: db_type=" + db_type + " type=" + type
134 + " subtype=" + subtype + " hash=" + shash
135 + " p1=[" + p1 + "] p2=[" + p2 + "] p3=[" + p3 + "]");
136
137 if ((subtype != 's') && (subtype != 'e') && (subtype != 'x')) {
138 log("ninedogs.db: invalid subtype " + subtype + "!");
139 return;
140 }
141
142 if (type == 'c') {
143 Properties oprops = (Properties) p2, props = new Properties();
144 props.putAll(oprops);
145 props.remove("password");
146 str = string2ninedogs('c', (String) p1 + " " + props.toString());
147 r = hp3;
148 e = p3;
149 } else if (type == 'Q') { // execute normal query
150 str = string2ninedogs('q', (String) p1);
151 r = hp2;
152 e = p2;
153 } else if (type == 'P') { // PgStatement.executeQuery
154 r = hp1;
155 e = p1;
156 } else if ((type == 'e') || (type == 'E') || (type == 'P')) {
157 r = hp1;
158 e = p1;
159 } else if (type == 'f') { // create statement
160 r = hp1;
161 e = p1;
162 } else if (type == 'p') { // create prepared statement
163 str = string2ninedogs('q', (String) p1);
164 r = hp2;
165 e = p2;
166 } else if (type == 'w') { // Statement/close
167 e = p1;
168 } else if (type == 'x') { // connection/close
169 e = p1;
170 } else if (type == 'g') { // getResultSet
171 r = hp1;
172 e = p1;
173 } else if (type == 'b') { // [P] setInt
174 Integer index = (Integer) p1;
175 str = string2ninedogs('i', index.toString());
176 Integer value = (Integer) p2;
177 str2 = string2ninedogs('v', value.toString());
178 e = p3;
179 } else if (type == 'S') { // [P] setString
180 Integer index = (Integer) p1;
181 str = string2ninedogs('i', index.toString());
182 str2 = string2ninedogs('s', (String) p2);
183 e = p3;
184 } else {
185 log("ninedogs.db: invalid type " + type + "!");
186 return;
187 }
188
189 if ((subtype == 'e') && (r != null)) {
190 ret = string2ninedogs('R', r);
191 } else if (subtype == 'x') {
192 Exception e0 = (java.lang.Exception) e;
193 ex = string2ninedogs('e', e0.toString());
194 java.lang.Throwable t = e0.getCause();
195 if (t != null)
196 ex_cause = string2ninedogs('E', t.toString());
197 }
198
199 int len = 1 + 1 + 1 + 1 + hash.length + str.length
200 + str2.length + ret.length + ex.length + ex_cause.length + 1;
201 //log("ninedogs.db: packing " + len + " bytes");
202 byte[] last = new byte[len];
203 last[off++] = 'D'; // D = db
204 last[off++] = (byte) db_type;
205 last[off++] = (byte) type;
206 last[off++] = (byte) subtype;
207 System.arraycopy(hash, 0, last, off, hash.length); off += hash.length;
208 System.arraycopy(str, 0, last, off, str.length); off += str.length;
209 System.arraycopy(str2, 0, last, off, str2.length); off += str2.length;
210 System.arraycopy(ret, 0, last, off, ret.length); off += ret.length;
211 System.arraycopy(ex, 0, last, off, ex.length); off += ex.length;
212 System.arraycopy(ex_cause, 0, last, off, ex_cause.length); off += ex_cause.length; // TODO: use this
213 last[off++] = 0;
214 write(last);
215 //log("ninedogs.db: wrote " + len + " bytes");
216 } catch (Exception _e) {
217 log("ninedogs.db: exception: " + _e);
218 }
112 219 } }
113 220 } }
114 221
File agent/ninedogs.TODO changed (mode: 100644) (index 5a2fa57..afc944c)
... ... to:
13 13 To add: To add:
14 14 - -
15 15
16 [ ] If a trqacer does not update a counter in 10s, consider it dead.
17 [ ] Remember user what was the prepared query (because we will not have it
18 in clear at the execution time).
19 [ ] socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 10
20 [ ] Load ninedogs.so with an environemnt variable to replace ninedogs.dlsym.so.
21 [ ]
22
File agent/ninedogs.c changed (mode: 100644) (index d1a322b..daff96b)
56 56 #include "info.h" #include "info.h"
57 57 #include "decode_text.h" #include "decode_text.h"
58 58 #include "curl.h" #include "curl.h"
59 #include "trace_encode.h"
59 60
60 61 #define FB_FLAGS_NETSOCK (1 << 0) #define FB_FLAGS_NETSOCK (1 << 0)
61 62 #define FB_FLAGS_COMM (1 << 1) // the fd is used to communicate with us #define FB_FLAGS_COMM (1 << 1) // the fd is used to communicate with us
 
... ... static struct dlopen_node dlopen_nodes[DLOPEN_MAX_ENTRIES]; // TODO: we need loc
85 86 static unsigned char my_malloc[20ULL * 65536ULL]; static unsigned char my_malloc[20ULL * 65536ULL];
86 87 static unsigned long my_malloc_pos; static unsigned long my_malloc_pos;
87 88
89 static unsigned int msgs_lost;
90 static char shared_inited;
88 91 static struct shared *shared; static struct shared *shared;
89 static unsigned char shared_inited;
90 92 static struct nd_info_shared *nd_info; static struct nd_info_shared *nd_info;
91 93 static unsigned char nd_info_inited; static unsigned char nd_info_inited;
92 94 char trace_enabled = 1; char trace_enabled = 1;
 
... ... static int (*old_fstatat)(int dirfd, const char *restrict pathname,
143 145 static int (*old_fstatat64)(int dirfd, const char *restrict pathname, static int (*old_fstatat64)(int dirfd, const char *restrict pathname,
144 146 struct stat64 *restrict statbuf, int flags); struct stat64 *restrict statbuf, int flags);
145 147 static pid_t (*old_fork)(void); static pid_t (*old_fork)(void);
148 static int (*old_shm_open)(const char *name, int oflag, mode_t mode);
146 149
147 150 /* fd helpers */ /* fd helpers */
148 151 static struct fd_node *fd_search(const int fd) static struct fd_node *fd_search(const int fd)
 
... ... static struct fd_node *fd_search(const int fd)
161 164
162 165 static struct fd_node *fd_add(const int fd) static struct fd_node *fd_add(const int fd)
163 166 { {
164 int save_errno;
167 int saved_errno;
165 168
166 169 struct fd_node *q; struct fd_node *q;
167 170
 
... ... static struct fd_node *fd_add(const int fd)
172 175 q = q->next; q = q->next;
173 176 } }
174 177 if (!q) { if (!q) {
175 save_errno = errno;
178 saved_errno = errno;
176 179 q = old_malloc(sizeof(struct fd_node)); q = old_malloc(sizeof(struct fd_node));
177 errno = save_errno;
180 errno = saved_errno;
178 181 if (!q) if (!q)
179 182 return NULL; return NULL;
180 183 memset(q, 0, sizeof(struct fd_node)); memset(q, 0, sizeof(struct fd_node));
 
... ... static void fd_del(const int fd)
204 207 } }
205 208 } }
206 209
207 /* Functions */
208 static void my_trace_put8(unsigned char *buf, unsigned int *i, const uint8_t v)
209 {
210 buf[*i] = v; *i = *i + 1;
211 }
212
213 static void my_trace_put16(unsigned char *buf, unsigned int *i, const uint16_t v)
214 {
215 uint16_t u = htobe16(v);
216 memcpy(buf + *i, &u, 2); *i = *i + 2;
217 }
218
219 static void my_trace_put32(unsigned char *buf, unsigned int *i, const uint32_t v)
220 {
221 uint32_t u = htobe32(v);
222 memcpy(buf + *i, &u, 4); *i = *i + 4;
223 }
224
225 static void my_trace_put64(unsigned char *buf, unsigned int *i, const uint64_t v)
226 {
227 uint64_t u = htobe64(v);
228 memcpy(buf + *i, &u, 8); *i = *i + 8;
229 }
230
231 static void my_trace_put_double(unsigned char *buf, unsigned int *i, const double v)
232 {
233 uint64_t u;
234 memcpy(&u, &v, 8);
235 my_trace_put64(buf, i, u);
236 }
237
238 static void my_trace_put_bool(unsigned char *buf, unsigned int *i, const char v)
239 {
240 buf[*i] = v; *i = *i + 1;
241 }
242
243 static void my_trace_put(unsigned char *buf, unsigned int *i,
244 const void *in, const size_t in_len)
245 {
246 if (in_len == 0)
247 return;
248
249 memcpy(buf + *i, in, in_len);
250 *i = *i + in_len;
251 }
252
253 // Seems that all fields are stored in BE order
254 static void my_trace_sockaddr(unsigned char *buf, unsigned int *i,
255 const struct sockaddr *a, const int len)
256 {
257 my_trace_put16(buf, i, len);
258 my_trace_put(buf, i, a, a ? len : 0);
259 }
260
261 static void my_trace_put_stat(unsigned char *buf, unsigned int *i, struct stat *s)
262 {
263 my_trace_put64(buf, i, s->st_dev);
264 my_trace_put64(buf, i, s->st_ino);
265 my_trace_put32(buf, i, s->st_mode);
266 my_trace_put64(buf, i, s->st_nlink);
267 my_trace_put32(buf, i, s->st_uid);
268 my_trace_put32(buf, i, s->st_gid);
269 my_trace_put64(buf, i, s->st_rdev);
270 my_trace_put64(buf, i, s->st_size);
271 my_trace_put64(buf, i, s->st_blksize);
272 my_trace_put64(buf, i, s->st_blocks);
273 my_trace_put64(buf, i, s->st_atim.tv_sec);
274 my_trace_put32(buf, i, s->st_atim.tv_nsec);
275 my_trace_put64(buf, i, s->st_mtim.tv_sec);
276 my_trace_put32(buf, i, s->st_mtim.tv_nsec);
277 my_trace_put64(buf, i, s->st_ctim.tv_sec);
278 my_trace_put32(buf, i, s->st_ctim.tv_nsec);
279 }
280
281 static void my_trace_put_string_array(unsigned char *buf, unsigned int *i, char *list[])
282 {
283 unsigned int j = 0;
284
285 while (1) {
286 if (!list[j]) {
287 my_trace_put32(buf, i, 0);
288 break;
289 }
290
291 unsigned short len = strlen(list[j]);
292 my_trace_put16(buf, i, len);
293 my_trace_put(buf, i, list[j], len);
294 j++;
295 }
296 }
297
298 static void my_trace_put_hostent(unsigned char *buf, unsigned int *i, struct hostent *he)
299 {
300 if (!he)
301 return;
302
303 int len = strlen(he->h_name);
304 my_trace_put8(buf, i, len);
305 my_trace_put(buf, i, he->h_name, len);
306
307 for (int j = 0; ; j++) {
308 if (!he->h_aliases[j]) {
309 my_trace_put8(buf, i, 0);
310 break;
311 }
312
313 len = strlen(he->h_aliases[j]);
314 my_trace_put8(buf, i, len);
315 my_trace_put(buf, i, he->h_aliases[j], len);
316 }
317
318 my_trace_put8(buf, i, he->h_addrtype);
319 my_trace_put8(buf, i, he->h_length);
320
321 int count = 0;
322 for (int j = 0; ; j++) {
323 if (!he->h_addr_list[j])
324 break;
325 count++;
326 }
327
328 my_trace_put8(buf, i, count);
329 for (int j = 0; j < count; j++) {
330 xlog(0, " DEBUG: addr[%d]=[%s]\n", j, he->h_addr_list[j]);
331 my_trace_put(buf, i, he->h_addr_list[j], he->h_length);
332 }
333 }
334
335 210 /* /*
336 211 * Returns how many byte were stored in * Returns how many byte were stored in
337 212 */ */
338 213 static unsigned int my_trace_encode(unsigned char *buf, static unsigned int my_trace_encode(unsigned char *buf,
339 const char *func, const char type, int save_errno, va_list va)
214 const char *func, const char *tf, const char type, const int saved_errno, va_list va)
340 215 { {
341 216 unsigned int i, ic; unsigned int i, ic;
342 217
218 xlog(100, "%s: func=[%s] tf=[%s] type=%c trace_depth=%hu saved_errno=%d\n",
219 __func__, func, tf, type, trace_depth, saved_errno);
220
343 221 i = 2; // first two bytes are for length i = 2; // first two bytes are for length
344 222 my_trace_put8(buf, &i, SHARED_FUNC); my_trace_put8(buf, &i, SHARED_FUNC);
345 223
346 224 struct timeval tv; struct timeval tv;
347 225 gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
348 226 my_trace_put64(buf, &i, tv.tv_sec * 1000 + tv.tv_usec / 1000); my_trace_put64(buf, &i, tv.tv_sec * 1000 + tv.tv_usec / 1000);
227 uint8_t tf_len = strlen(tf);
228 my_trace_put8(buf, &i, tf_len);
229 my_trace_put(buf, &i, tf, tf_len);
349 230 my_trace_put16(buf, &i, trace_depth); my_trace_put16(buf, &i, trace_depth);
350 231 unsigned short flen = strlen(func); unsigned short flen = strlen(func);
351 232 my_trace_put16(buf, &i, flen); my_trace_put16(buf, &i, flen);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
389 270 int ret = va_arg(va, int); int ret = va_arg(va, int);
390 271 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
391 272 if (ret == -1) if (ret == -1)
392 my_trace_put32(buf, &i, save_errno);
273 my_trace_put32(buf, &i, saved_errno);
393 274 } }
394 275 } else if (strcmp(func, "accept4") == 0) { } else if (strcmp(func, "accept4") == 0) {
395 276 my_trace_put32(buf, &i, va_arg(va, int)); // sock my_trace_put32(buf, &i, va_arg(va, int)); // sock
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
407 288 int ret = va_arg(va, int); int ret = va_arg(va, int);
408 289 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
409 290 if (ret == -1) if (ret == -1)
410 my_trace_put32(buf, &i, save_errno);
291 my_trace_put32(buf, &i, saved_errno);
411 292 } }
412 293 } break; } break;
413 294
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
420 301 int ret = va_arg(va, int); int ret = va_arg(va, int);
421 302 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
422 303 if (ret == -1) if (ret == -1)
423 my_trace_put32(buf, &i, save_errno);
304 my_trace_put32(buf, &i, saved_errno);
424 305 } break; } break;
425 306
426 307 case 'c': case 'c':
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
430 311 int ret = va_arg(va, int); int ret = va_arg(va, int);
431 312 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
432 313 if (ret == -1) if (ret == -1)
433 my_trace_put32(buf, &i, save_errno);
314 my_trace_put32(buf, &i, saved_errno);
434 315 } }
435 316 } else if (strcmp(func, "connect") == 0) { } else if (strcmp(func, "connect") == 0) {
436 317 my_trace_put32(buf, &i, va_arg(va, int)); // sock my_trace_put32(buf, &i, va_arg(va, int)); // sock
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
443 324 int ret = va_arg(va, int); int ret = va_arg(va, int);
444 325 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
445 326 if (ret == -1) if (ret == -1)
446 my_trace_put32(buf, &i, save_errno);
327 my_trace_put32(buf, &i, saved_errno);
447 328 } }
448 329 } else if (strcmp(func, "curl_easy_cleanup") == 0) { } else if (strcmp(func, "curl_easy_cleanup") == 0) {
449 330 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // handle my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // handle
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
465 346 } }
466 347 } }
467 348 } else if (strcmp(func, "curl_easy_perform") == 0) { } else if (strcmp(func, "curl_easy_perform") == 0) {
468 if (type == 'm') {
349 if (type == 'm') { // TODO: this is strange!
469 350 char *info = va_arg(va, char *); char *info = va_arg(va, char *);
470 351 unsigned char len = strlen(info); unsigned char len = strlen(info);
471 352 my_trace_put8(buf, &i, len); my_trace_put8(buf, &i, len);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
548 429 uint64_t h = (uint64_t) va_arg(va, void *); uint64_t h = (uint64_t) va_arg(va, void *);
549 430 my_trace_put64(buf, &i, h); my_trace_put64(buf, &i, h);
550 431 if (h == 0) if (h == 0)
551 my_trace_put32(buf, &i, save_errno);
432 my_trace_put32(buf, &i, saved_errno);
552 433 } }
553 434 } else if (strcmp(func, "dlclose") == 0) { } else if (strcmp(func, "dlclose") == 0) {
554 435 uint64_t h = (uint64_t) va_arg(va, void *); uint64_t h = (uint64_t) va_arg(va, void *);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
556 437 int ret = va_arg(va, int); int ret = va_arg(va, int);
557 438 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
558 439 if (ret == -1) if (ret == -1)
559 my_trace_put32(buf, &i, save_errno);
440 my_trace_put32(buf, &i, saved_errno);
560 441 } break; } break;
561 442
562 443 case 'e': case 'e':
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
571 452 int ret = va_arg(va, int); int ret = va_arg(va, int);
572 453 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
573 454 if (ret == -1) if (ret == -1)
574 my_trace_put32(buf, &i, save_errno);
455 my_trace_put32(buf, &i, saved_errno);
575 456 } }
576 457 } break; } break;
577 458
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
580 461 int ret = va_arg(va, int); int ret = va_arg(va, int);
581 462 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
582 463 if (ret == -1) if (ret == -1)
583 my_trace_put32(buf, &i, save_errno);
464 my_trace_put32(buf, &i, saved_errno);
584 465 } else if ((strcmp(func, "fstatat") == 0) } else if ((strcmp(func, "fstatat") == 0)
585 466 || (strcmp(func, "fstatat64") == 0)) { || (strcmp(func, "fstatat64") == 0)) {
586 467 my_trace_put16(buf, &i, va_arg(va, int)); // dirfd my_trace_put16(buf, &i, va_arg(va, int)); // dirfd
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
595 476 int ret = va_arg(va, int); int ret = va_arg(va, int);
596 477 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
597 478 if (ret == -1) if (ret == -1)
598 my_trace_put32(buf, &i, save_errno);
479 my_trace_put32(buf, &i, saved_errno);
599 480 } }
600 481 } else if ((strcmp(func, "fsync") == 0) } else if ((strcmp(func, "fsync") == 0)
601 482 || (strcmp(func, "fdatasync") == 0)) { || (strcmp(func, "fdatasync") == 0)) {
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
604 485 int ret = va_arg(va, int); int ret = va_arg(va, int);
605 486 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
606 487 if (ret == -1) if (ret == -1)
607 my_trace_put32(buf, &i, save_errno);
488 my_trace_put32(buf, &i, saved_errno);
489 }
490 } else if (strcmp(func, "ftruncate") == 0) {
491 my_trace_put32(buf, &i, va_arg(va, int)); // fd
492 my_trace_put64(buf, &i, va_arg(va, uint64_t)); // length
493 if (type == 'r') {
494 int ret = va_arg(va, int);
495 my_trace_put32(buf, &i, ret);
496 if (ret == -1)
497 my_trace_put32(buf, &i, saved_errno);
608 498 } }
609 499 } break; } break;
610 500
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
636 526 int ret = va_arg(va, int); int ret = va_arg(va, int);
637 527 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
638 528 if (ret == -1) if (ret == -1)
639 my_trace_put32(buf, &i, save_errno);
529 my_trace_put32(buf, &i, saved_errno);
640 530 } }
641 531 } else if (strcmp(func, "gethostbyname_r") == 0) { } else if (strcmp(func, "gethostbyname_r") == 0) {
642 532 char *name = va_arg(va, char *); char *name = va_arg(va, char *);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
670 560 my_trace_put16(buf, &i, max); my_trace_put16(buf, &i, max);
671 561 my_trace_put(buf, &i, xbuf, max); my_trace_put(buf, &i, xbuf, max);
672 562 } else { } else {
673 my_trace_put32(buf, &i, save_errno);
563 my_trace_put32(buf, &i, saved_errno);
674 564 } }
675 565 } }
676 566 } else if (strcmp(func, "getsockopt") == 0) { } else if (strcmp(func, "getsockopt") == 0) {
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
684 574 int ret = va_arg(va, int); int ret = va_arg(va, int);
685 575 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
686 576 if (ret == -1) if (ret == -1)
687 my_trace_put32(buf, &i, save_errno);
577 my_trace_put32(buf, &i, saved_errno);
578 } break;
579
580 case 'i':
581 if ((strcmp(func, "imagecreate") == 0)
582 || (strcmp(func, "imagecreatetruecolor") == 0)) {
583 my_trace_put64(buf, &i, va_arg(va, uint64_t)); // w
584 my_trace_put64(buf, &i, va_arg(va, uint64_t)); // h
585 struct nd_gd_img *img = va_arg(va, struct nd_gd_img *);
586 my_trace_put64(buf, &i, (uint64_t) img->im);
587 } else if (strcmp(func, "imagedestroy") == 0) {
588 struct nd_gd_img *img = va_arg(va, struct nd_gd_img *);
589 my_trace_put64(buf, &i, (uint64_t) img->im);
590 my_trace_put32(buf, &i, img->elap.tv_sec * 1000 + img->elap.tv_usec / 1000);
591 my_trace_put_bool(buf, &i, va_arg(va, int)); // ret
592 } break;
593
594 case 'j':
595 if (strcmp(func, "java/db/connect") == 0) {
596 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
597 my_trace_put8(buf, &i, c->type);
598 my_trace_put16(buf, &i, c->conn_str_len);
599 my_trace_put(buf, &i, c->conn_str, c->conn_str_len);
600 if (type == 'r') {
601 my_trace_put64(buf, &i, (uint64_t) c->dbh);
602 if (c->dbh != NULL) {
603 } else {
604 my_trace_put16(buf, &i, (uint64_t) c->ex_len);
605 my_trace_put(buf, &i, c->ex, c->ex_len);
606 }
607 }
608 } else if (strcmp(func, "java/db/close") == 0) {
609 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
610 my_trace_put8(buf, &i, c->type);
611 my_trace_put64(buf, &i, (uint64_t) c->dbh);
612 } else if ((strcmp(func, "java/db/prepared/execute") == 0)
613 || (strcmp(func, "java/db/stmt/execute") == 0)) {
614 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
615 my_trace_put8(buf, &i, e->type);
616 my_trace_put64(buf, &i, (uint64_t) e->stmt);
617 if (type == 'r') {
618 my_trace_put64(buf, &i, (uint64_t) e->res);
619 if (e->res == NULL) {
620 my_trace_put16(buf, &i, (uint64_t) e->ex_len);
621 my_trace_put(buf, &i, e->ex, e->ex_len);
622 }
623 #if 0
624 TODO
625 if (e->ret == 1) {
626 my_trace_put64(buf, &i, e->num);
627 my_trace_put64(buf, &i, e->aff);
628 }
629 #endif
630 }
631 } else if (strcmp(func, "java/db/prepare") == 0) {
632 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
633 my_trace_put8(buf, &i, e->type);
634 my_trace_put64(buf, &i, (uint64_t) e->dbh);
635 my_trace_put16(buf, &i, e->q_len);
636 my_trace_put(buf, &i, e->q, e->q_len);
637 if (type == 'r') {
638 my_trace_put64(buf, &i, (uint64_t) e->stmt);
639 if (e->stmt == NULL) {
640 my_trace_put16(buf, &i, (uint64_t) e->ex_len);
641 my_trace_put(buf, &i, e->ex, e->ex_len);
642 }
643 }
644 } else if (strcmp(func, "java/db/stmt/create") == 0) {
645 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
646 my_trace_put8(buf, &i, e->type);
647 my_trace_put64(buf, &i, (uint64_t) e->dbh);
648 my_trace_put64(buf, &i, (uint64_t) e->stmt);
649 if (e->stmt == NULL) {
650 my_trace_put16(buf, &i, (uint64_t) e->ex_len);
651 my_trace_put(buf, &i, e->ex, e->ex_len);
652 }
653 } else if (strcmp(func, "java/db/stmt/close") == 0) {
654 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
655 my_trace_put8(buf, &i, e->type);
656 my_trace_put64(buf, &i, (uint64_t) e->stmt);
657 } else if (strcmp(func, "java/db/stmt/execute/sql") == 0) {
658 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
659 my_trace_put8(buf, &i, e->type);
660 my_trace_put64(buf, &i, (uint64_t) e->stmt);
661 my_trace_put16(buf, &i, e->q_len);
662 my_trace_put(buf, &i, e->q, e->q_len);
663 if (type == 'r') {
664 my_trace_put64(buf, &i, (uint64_t) e->res);
665 if (e->res == NULL) {
666 my_trace_put16(buf, &i, (uint64_t) e->ex_len);
667 my_trace_put(buf, &i, e->ex, e->ex_len);
668 }
669 }
670 } else if (strcmp(func, "java/db/result/get") == 0) {
671 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
672 my_trace_put8(buf, &i, e->type);
673 my_trace_put64(buf, &i, (uint64_t) e->stmt);
674 if (type == 'r') {
675 my_trace_put64(buf, &i, (uint64_t) e->res);
676 if (e->res == NULL) {
677 my_trace_put16(buf, &i, (uint64_t) e->ex_len);
678 my_trace_put(buf, &i, e->ex, e->ex_len);
679 }
680 }
681 } else if (strcmp(func, "java/db/stmt/setInt") == 0) {
682 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
683 my_trace_put8(buf, &i, e->type);
684 my_trace_put64(buf, &i, (uint64_t) e->stmt);
685 my_trace_put8(buf, &i, e->params.list[1].length); // abuse alert - used as index
686 my_trace_put32(buf, &i, e->params.list[0].l);
687 my_trace_put64(buf, &i, (uint64_t) e->res);
688 if (e->res == NULL) {
689 my_trace_put16(buf, &i, (uint64_t) e->ex_len);
690 my_trace_put(buf, &i, e->ex, e->ex_len);
691 }
692 } else if (strcmp(func, "java/db/stmt/setString") == 0) {
693 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
694 my_trace_put8(buf, &i, e->type);
695 my_trace_put64(buf, &i, (uint64_t) e->stmt);
696 my_trace_put8(buf, &i, e->params.list[1].length); // abuse alert - used as index
697 my_trace_put16(buf, &i, e->params.list[0].length);
698 my_trace_put(buf, &i, e->params.list[0].str, e->params.list[0].length);
699 my_trace_put64(buf, &i, (uint64_t) e->res);
700 if (e->res == NULL) {
701 my_trace_put16(buf, &i, (uint64_t) e->ex_len);
702 my_trace_put(buf, &i, e->ex, e->ex_len);
703 }
688 704 } break; } break;
689 705
690 706 case 'l': case 'l':
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
694 710 int ret = va_arg(va, int); int ret = va_arg(va, int);
695 711 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
696 712 if (ret == -1) if (ret == -1)
697 my_trace_put32(buf, &i, save_errno);
713 my_trace_put32(buf, &i, saved_errno);
698 714 } else if (strcmp(func, "lseek") == 0) { } else if (strcmp(func, "lseek") == 0) {
699 715 my_trace_put32(buf, &i, va_arg(va, int)); // fd my_trace_put32(buf, &i, va_arg(va, int)); // fd
700 716 my_trace_put64(buf, &i, va_arg(va, uint64_t)); // off my_trace_put64(buf, &i, va_arg(va, uint64_t)); // off
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
703 719 ssize_t ret = va_arg(va, ssize_t); ssize_t ret = va_arg(va, ssize_t);
704 720 my_trace_put64(buf, &i, ret); my_trace_put64(buf, &i, ret);
705 721 if (ret == -1) if (ret == -1)
706 my_trace_put32(buf, &i, save_errno);
722 my_trace_put32(buf, &i, saved_errno);
707 723 } }
708 724 } break; } break;
709 725
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
718 734 int ret = va_arg(va, int); int ret = va_arg(va, int);
719 735 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
720 736 if (ret == -1) if (ret == -1)
721 my_trace_put32(buf, &i, save_errno);
737 my_trace_put32(buf, &i, saved_errno);
722 738 } }
723 739 } else if (strcmp(func, "mysqli_autocommit") == 0) { } else if (strcmp(func, "mysqli_autocommit") == 0) {
724 740 struct db_autocommit *a = va_arg(va, struct db_autocommit *); struct db_autocommit *a = va_arg(va, struct db_autocommit *);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
727 743 if (type == 'r') if (type == 'r')
728 744 my_trace_put_bool(buf, &i, a->ret); my_trace_put_bool(buf, &i, a->ret);
729 745 } else if (strcmp(func, "mysqli_close") == 0) { } else if (strcmp(func, "mysqli_close") == 0) {
730 struct conn *c = va_arg(va, struct conn *);
746 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
731 747 my_trace_put64(buf, &i, (uint64_t) c->dbh); my_trace_put64(buf, &i, (uint64_t) c->dbh);
732 748 if (type == 'r') if (type == 'r')
733 my_trace_put_bool(buf, &i, c->ret);
749 my_trace_put_bool(buf, &i, c->ok);
734 750 } else if (strcmp(func, "mysqli_connect") == 0) { } else if (strcmp(func, "mysqli_connect") == 0) {
735 struct conn *c = va_arg(va, struct conn *);
751 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
736 752 my_trace_put32(buf, &i, c->conn_str_len); my_trace_put32(buf, &i, c->conn_str_len);
737 753 my_trace_put(buf, &i, c->conn_str, c->conn_str_len); my_trace_put(buf, &i, c->conn_str, c->conn_str_len);
738 754 if (type == 'r') if (type == 'r')
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
753 769 struct free_result *fr = va_arg(va, struct free_result *); struct free_result *fr = va_arg(va, struct free_result *);
754 770 my_trace_put64(buf, &i, (uint64_t) fr->res); my_trace_put64(buf, &i, (uint64_t) fr->res);
755 771 } else if (strcmp(func, "mysqli_prepare") == 0) { } else if (strcmp(func, "mysqli_prepare") == 0) {
756 struct prepare *p = va_arg(va, struct prepare *);
772 struct nd_db_stmt *p = va_arg(va, struct nd_db_stmt *);
757 773 my_trace_put64(buf, &i, (uint64_t) p->dbh); my_trace_put64(buf, &i, (uint64_t) p->dbh);
758 774 my_trace_put16(buf, &i, p->q_len); my_trace_put16(buf, &i, p->q_len);
759 775 my_trace_put(buf, &i, p->q, p->q_len); my_trace_put(buf, &i, p->q, p->q_len);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
770 786 my_trace_put64(buf, &i, q->aff); my_trace_put64(buf, &i, q->aff);
771 787 } }
772 788 } else if (strcmp(func, "mysqli_real_connect") == 0) { } else if (strcmp(func, "mysqli_real_connect") == 0) {
773 struct conn *c = va_arg(va, struct conn *);
789 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
774 790 my_trace_put64(buf, &i, (uint64_t) c->dbh); my_trace_put64(buf, &i, (uint64_t) c->dbh);
775 791 my_trace_put32(buf, &i, c->conn_str_len); my_trace_put32(buf, &i, c->conn_str_len);
776 792 my_trace_put(buf, &i, c->conn_str, c->conn_str_len); my_trace_put(buf, &i, c->conn_str, c->conn_str_len);
777 793 my_trace_put32(buf, &i, c->flags); my_trace_put32(buf, &i, c->flags);
778 794 if (type == 'r') if (type == 'r')
779 my_trace_put_bool(buf, &i, c->ret);
795 my_trace_put_bool(buf, &i, c->ok);
780 796 } else if (strcmp(func, "mysqli_stmt_bind_param") == 0) { } else if (strcmp(func, "mysqli_stmt_bind_param") == 0) {
781 797 struct nd_db_bind *b = va_arg(va, struct nd_db_bind *); struct nd_db_bind *b = va_arg(va, struct nd_db_bind *);
782 798 my_trace_put64(buf, &i, (uint64_t) b->stmt); my_trace_put64(buf, &i, (uint64_t) b->stmt);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
784 800 my_trace_put(buf, &i, b->types, b->types_len); my_trace_put(buf, &i, b->types, b->types_len);
785 801 if (type == 'r') if (type == 'r')
786 802 my_trace_put_bool(buf, &i, b->ret); my_trace_put_bool(buf, &i, b->ret);
803 } else if (strcmp(func, "mysqli_stmt_close") == 0) {
804 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
805 my_trace_put64(buf, &i, (uint64_t) e->stmt);
806 if (type == 'r')
807 my_trace_put_bool(buf, &i, e->ret);
787 808 } else if (strcmp(func, "mysqli_stmt_execute") == 0) { } else if (strcmp(func, "mysqli_stmt_execute") == 0) {
788 struct nd_db_execute *e = va_arg(va, struct nd_db_execute *);
809 struct nd_db_stmt *e = va_arg(va, struct nd_db_stmt *);
789 810 my_trace_put64(buf, &i, (uint64_t) e->stmt); my_trace_put64(buf, &i, (uint64_t) e->stmt);
790 if (type == 'c') {
791 my_trace_put16(buf, &i, e->params.len);
792 for (unsigned short j = 0; j < e->params.len; j++) {
793 struct params_array_one *pa = &e->params.list[j];
794 my_trace_put8(buf, &i, pa->type);
795 if (pa->type == ND_TYPE_LONG) {
796 my_trace_put64(buf, &i, pa->l);
797 } else if (pa->type == ND_TYPE_DOUBLE) {
798 my_trace_put_double(buf, &i, pa->d);
799 } else if (pa->type == ND_TYPE_STRING) {
800 my_trace_put16(buf, &i, pa->length);
801 my_trace_put(buf, &i, pa->str, pa->length);
802 }
803 }
804 }
811 if (type == 'c')
812 my_trace_put_params(buf, &i, &e->params,
813 ND_PARAMS_BIND_WAY_BOTH);
805 814 if (type == 'r') { if (type == 'r') {
806 815 my_trace_put_bool(buf, &i, e->ret); my_trace_put_bool(buf, &i, e->ret);
807 816 if (e->ret == 1) { if (e->ret == 1) {
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
810 819 } }
811 820 } }
812 821 } else if (strcmp(func, "mysqli_stmt_prepare") == 0) { } else if (strcmp(func, "mysqli_stmt_prepare") == 0) {
813 struct prepare *p = va_arg(va, struct prepare *);
822 struct nd_db_stmt *p = va_arg(va, struct nd_db_stmt *);
814 823 my_trace_put64(buf, &i, (uint64_t) p->stmt); my_trace_put64(buf, &i, (uint64_t) p->stmt);
815 824 my_trace_put16(buf, &i, p->q_len); my_trace_put16(buf, &i, p->q_len);
816 825 my_trace_put(buf, &i, p->q, p->q_len); my_trace_put(buf, &i, p->q, p->q_len);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
835 844 int ret = va_arg(va, int); int ret = va_arg(va, int);
836 845 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
837 846 if (ret == -1) if (ret == -1)
838 my_trace_put32(buf, &i, save_errno);
847 my_trace_put32(buf, &i, saved_errno);
839 848 } }
840 849 } break; } break;
841 850
842 851 case 'o': case 'o':
843 if ((strcmp(func, "open") == 0)
852 if (strcmp(func, "oci_bind_by_name") == 0) {
853 struct nd_db_stmt *s = va_arg(va, struct nd_db_stmt *);
854 my_trace_put64(buf, &i, (uint64_t) s->stmt);
855 } else if (strcmp(func, "oci_close") == 0) {
856 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
857 my_trace_put64(buf, &i, (uint64_t) c->dbh);
858 } else if (strcmp(func, "oci_execute") == 0) {
859 struct nd_db_stmt *s = va_arg(va, struct nd_db_stmt *);
860 my_trace_put64(buf, &i, (uint64_t) s->stmt);
861 my_trace_put64(buf, &i, (uint64_t) s->oci.mode);
862 if (type == 'r')
863 my_trace_put_bool(buf, &i, (uint64_t) s->ret);
864 } else if (strcmp(func, "oci_parse") == 0) {
865 struct nd_db_stmt *s = va_arg(va, struct nd_db_stmt *);
866 my_trace_put64(buf, &i, (uint64_t) s->dbh);
867 my_trace_put16(buf, &i, (uint16_t) s->q_len);
868 my_trace_put(buf, &i, s->q, s->q_len);
869 if (type == 'r')
870 my_trace_put64(buf, &i, (uint64_t) s->stmt);
871 } else if (strcmp(func, "oci_pconnect") == 0) {
872 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
873 my_trace_put32(buf, &i, c->conn_str_len);
874 my_trace_put(buf, &i, c->conn_str, c->conn_str_len);
875 if (type == 'r')
876 my_trace_put64(buf, &i, (uint64_t) c->dbh);
877 } else if ((strcmp(func, "open") == 0)
844 878 || (strcmp(func, "open64") == 0) || (strcmp(func, "open64") == 0)
845 879 || (strcmp(func, "openat") == 0)) { || (strcmp(func, "openat") == 0)) {
846 880 if (strcmp(func, "openat") == 0) if (strcmp(func, "openat") == 0)
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
855 889 int ret = va_arg(va, int); int ret = va_arg(va, int);
856 890 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
857 891 if (ret == -1) if (ret == -1)
858 my_trace_put32(buf, &i, save_errno);
892 my_trace_put32(buf, &i, saved_errno);
893 }
894 } break;
895
896 case 'O':
897 if (strcmp(func, "OCIAttrSet") == 0) {
898 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // h
899 my_trace_put32(buf, &i, va_arg(va, uint32_t)); // htype
900 void *attr = va_arg(va, void *);
901 uint32_t attr_size = va_arg(va, uint32_t);
902 uint32_t attr_type = va_arg(va, uint32_t);
903 if (attr_type == 23) // do not send password
904 attr_size = 0;
905 my_trace_put32(buf, &i, attr_size);
906 my_trace_put(buf, &i, attr, attr_size);
907 my_trace_put32(buf, &i, attr_type);
908 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // err
909 my_trace_put32(buf, &i, va_arg(va, int32_t)); // ret
910 } else if (strcmp(func, "OCIBindByName") == 0) {
911 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // stmt
912 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // bind
913 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_error
914 const char *ph = va_arg(va, char *);
915 int ph_len = va_arg(va, int), ph_len2;
916 ph_len2 = ph_len > 0 ? ph_len : (int) strlen(ph);
917 my_trace_put32(buf, &i, ph_len2);
918 my_trace_put(buf, &i, ph, ph_len2);
919 int value_size = va_arg(va, int);
920 my_trace_put32(buf, &i, value_size);
921 my_trace_put16(buf, &i, va_arg(va, unsigned int)); // dty
922 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // ind
923 my_trace_put64(buf, &i, (uint64_t) va_arg(va, unsigned short *)); // alen
924 my_trace_put64(buf, &i, (uint64_t) va_arg(va, unsigned short *)); // rcode
925 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // maxarr_len
926 my_trace_put64(buf, &i, (uint64_t) va_arg(va, unsigned int *)); // curelep
927 my_trace_put32(buf, &i, va_arg(va, uint32_t)); // mode
928 my_trace_put32(buf, &i, va_arg(va, int32_t)); // ret
929 } else if (strcmp(func, "OCIDefineByPos") == 0) {
930 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // stmt
931 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // def
932 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_error
933 my_trace_put32(buf, &i, va_arg(va, uint32_t)); // pos
934 my_trace_put32(buf, &i, va_arg(va, int)); // value_size
935 my_trace_put16(buf, &i, va_arg(va, unsigned int)); // dty
936 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // ind
937 my_trace_put64(buf, &i, (uint64_t) va_arg(va, unsigned short *)); // rlen
938 my_trace_put64(buf, &i, (uint64_t) va_arg(va, unsigned short *)); // rcode
939 my_trace_put32(buf, &i, va_arg(va, uint32_t)); // mode
940 my_trace_put32(buf, &i, va_arg(va, int32_t)); // ret
941 } else if (strcmp(func, "OCIHandleAlloc") == 0) {
942 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // parent
943 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // dbh
944 my_trace_put32(buf, &i, va_arg(va, uint32_t)); // type
945 my_trace_put64(buf, &i, (uint64_t) va_arg(va, size_t)); // extra_mem
946 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // user_mem
947 } else if (strcmp(func, "OCIHandleFree") == 0) {
948 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // hnd
949 my_trace_put32(buf, &i, va_arg(va, uint32_t)); // type
950 } else if (strcmp(func, "OCIServerAttach") == 0) {
951 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_server
952 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_error
953 char *db_link = va_arg(va, char *);
954 int32_t db_link_len = va_arg(va, int32_t), a;
955 a = db_link_len < 0 ? 0 : db_link_len;
956 my_trace_put32(buf, &i, a);
957 my_trace_put(buf, &i, db_link, a);
958 my_trace_put32(buf, &i, va_arg(va, uint32_t)); // mode
959 if (type == 'r')
960 my_trace_put32(buf, &i, va_arg(va, int32_t)); // ret
961 } else if (strcmp(func, "OCIServerDetach") == 0) {
962 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_server
963 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_error
964 my_trace_put32(buf, &i, va_arg(va, uint32_t)); // mode
965 if (type == 'r')
966 my_trace_put32(buf, &i, va_arg(va, int32_t)); // ret
967 } else if (strcmp(func, "OCIStmtExecute") == 0) {
968 if (type == 'm') {
969 uint64_t stmt = (uint64_t) va_arg(va, void *);
970 uint8_t bind_way = va_arg(va, int);
971 struct nd_params_array *pa = va_arg(va, struct nd_params_array *);
972 my_trace_put64(buf, &i, stmt);
973 my_trace_put8(buf, &i, bind_way);
974 my_trace_put_params(buf, &i, pa, bind_way);
975 if (bind_way == ND_PARAMS_BIND_WAY_IN) {
976 char *q = va_arg(va, char *);
977 unsigned short q_len = va_arg(va, unsigned int);
978 my_trace_put16(buf, &i, q_len);
979 my_trace_put(buf, &i, q, q_len);
980 }
981 } else {
982 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // svc
983 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // stmt
984 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // err
985 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // iters
986 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // rowoff
987 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // snap_in
988 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // snap_out
989 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // mode
990 if (type == 'r')
991 my_trace_put32(buf, &i, va_arg(va, int)); // ret
859 992 } }
993 } else if (strcmp(func, "OCIStmtPrepare") == 0) {
994 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // stmt
995 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_error
996 char *q = va_arg(va, char *);
997 uint16_t q_len = va_arg(va, uint32_t);
998 my_trace_put16(buf, &i, q_len);
999 my_trace_put(buf, &i, q, q_len);
1000 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // lang
1001 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // mode
1002 my_trace_put32(buf, &i, va_arg(va, int)); // ret
1003 } else if (strcmp(func, "OCITransCommit") == 0) {
1004 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // svc
1005 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_error
1006 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // flags
1007 if (type == 'r')
1008 my_trace_put32(buf, &i, va_arg(va, int)); // ret
1009 } else if (strcmp(func, "OCITransRollback") == 0) {
1010 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // svc
1011 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_error
1012 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // flags
1013 if (type == 'r')
1014 my_trace_put32(buf, &i, va_arg(va, int)); // ret
1015 } else if (strcmp(func, "OCITransStart") == 0) {
1016 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // svc
1017 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // oci_error
1018 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // timeout
1019 my_trace_put32(buf, &i, va_arg(va, unsigned int)); // flags
1020 my_trace_put32(buf, &i, va_arg(va, int)); // ret
860 1021 } break; } break;
861 1022
862 1023 case 'p': case 'p':
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
874 1035 int ret = va_arg(va, int); int ret = va_arg(va, int);
875 1036 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
876 1037 if (ret == -1) if (ret == -1)
877 my_trace_put32(buf, &i, save_errno);
1038 my_trace_put32(buf, &i, saved_errno);
878 1039 } }
879 1040 } else if ((strcmp(func, "pread") == 0) } else if ((strcmp(func, "pread") == 0)
880 1041 || (strcmp(func, "pread64") == 0)) { || (strcmp(func, "pread64") == 0)) {
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
894 1055 my_trace_put16(buf, &i, max); my_trace_put16(buf, &i, max);
895 1056 my_trace_put(buf, &i, buf2, max); // data my_trace_put(buf, &i, buf2, max); // data
896 1057 } else if (ret == -1) } else if (ret == -1)
897 my_trace_put32(buf, &i, save_errno);
1058 my_trace_put32(buf, &i, saved_errno);
898 1059 } }
899 1060 } else if (strcmp(func, "pthread_join") == 0) { } else if (strcmp(func, "pthread_join") == 0) {
900 1061 my_trace_put64(buf, &i, (uint64_t) va_arg(va, pthread_t)); my_trace_put64(buf, &i, (uint64_t) va_arg(va, pthread_t));
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
902 1063 void **retval = va_arg(va, void **); void **retval = va_arg(va, void **);
903 1064 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
904 1065 if (ret == -1) { if (ret == -1) {
905 my_trace_put32(buf, &i, save_errno);
1066 my_trace_put32(buf, &i, saved_errno);
906 1067 } else { } else {
907 1068 my_trace_put64(buf, &i, retval ? (uint64_t) *retval : 0); my_trace_put64(buf, &i, retval ? (uint64_t) *retval : 0);
908 1069 } }
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
915 1076 int ret = va_arg(va, int); int ret = va_arg(va, int);
916 1077 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
917 1078 if (ret == -1) if (ret == -1)
918 my_trace_put32(buf, &i, save_errno);
1079 my_trace_put32(buf, &i, saved_errno);
919 1080 } else if (strcmp(func, "pthread_attr_setstacksize") == 0) { } else if (strcmp(func, "pthread_attr_setstacksize") == 0) {
920 1081 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // attr my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // attr
921 1082 my_trace_put64(buf, &i, (uint64_t) va_arg(va, size_t)); // stack size my_trace_put64(buf, &i, (uint64_t) va_arg(va, size_t)); // stack size
922 1083 int ret = va_arg(va, int); int ret = va_arg(va, int);
923 1084 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
924 1085 if (ret == -1) if (ret == -1)
925 my_trace_put32(buf, &i, save_errno);
1086 my_trace_put32(buf, &i, saved_errno);
926 1087 } else if (strcmp(func, "pthread_create") == 0) { } else if (strcmp(func, "pthread_create") == 0) {
927 1088 my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // thread my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // thread
928 1089 my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // attr TODO - how to encode it? my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // attr TODO - how to encode it?
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
930 1091 int ret = va_arg(va, int); int ret = va_arg(va, int);
931 1092 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
932 1093 if (ret == -1) if (ret == -1)
933 my_trace_put32(buf, &i, save_errno);
1094 my_trace_put32(buf, &i, saved_errno);
934 1095 } else if ((strcmp(func, "pwrite") == 0) } else if ((strcmp(func, "pwrite") == 0)
935 1096 || (strcmp(func, "pwrite64") == 0)) { || (strcmp(func, "pwrite64") == 0)) {
936 1097 void *buf2 = NULL; void *buf2 = NULL;
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
949 1110 ssize_t ret = va_arg(va, ssize_t); ssize_t ret = va_arg(va, ssize_t);
950 1111 my_trace_put64(buf, &i, ret); my_trace_put64(buf, &i, ret);
951 1112 if (ret == -1) if (ret == -1)
952 my_trace_put32(buf, &i, save_errno);
1113 my_trace_put32(buf, &i, saved_errno);
953 1114 } }
954 1115 } else if (strcmp(func, "pg_close") == 0) { } else if (strcmp(func, "pg_close") == 0) {
955 struct conn *c = va_arg(va, struct conn *);
1116 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
956 1117 my_trace_put64(buf, &i, (uint64_t) c->dbh); my_trace_put64(buf, &i, (uint64_t) c->dbh);
957 1118 } else if ((strcmp(func, "pg_connect") == 0) } else if ((strcmp(func, "pg_connect") == 0)
958 1119 || (strcmp(func, "pg_pconnect") == 0)) { || (strcmp(func, "pg_pconnect") == 0)) {
959 struct conn *c = va_arg(va, struct conn *);
1120 struct nd_db_conn *c = va_arg(va, struct nd_db_conn *);
960 1121 my_trace_put32(buf, &i, c->conn_str_len); my_trace_put32(buf, &i, c->conn_str_len);
961 1122 my_trace_put(buf, &i, c->conn_str, c->conn_str_len); my_trace_put(buf, &i, c->conn_str, c->conn_str_len);
962 1123 if (type == 'r') if (type == 'r')
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
973 1134 my_trace_put64(buf, &i, (uint64_t) q->dbh); my_trace_put64(buf, &i, (uint64_t) q->dbh);
974 1135 my_trace_put16(buf, &i, q->q_len); my_trace_put16(buf, &i, q->q_len);
975 1136 my_trace_put(buf, &i, q->q, q->q_len); my_trace_put(buf, &i, q->q, q->q_len);
976 if (type == 'c') {
977 my_trace_put16(buf, &i, q->params.len);
978 for (unsigned short j = 0; j < q->params.len; j++) {
979 struct params_array_one *pa = &q->params.list[j];
980 my_trace_put8(buf, &i, pa->type);
981 if (pa->type == ND_TYPE_LONG) {
982 my_trace_put64(buf, &i, pa->l);
983 } else if (pa->type == ND_TYPE_DOUBLE) {
984 my_trace_put_double(buf, &i, pa->d);
985 } else if (pa->type == ND_TYPE_STRING) {
986 my_trace_put16(buf, &i, pa->length);
987 my_trace_put(buf, &i, pa->str, pa->length);
988 }
989 }
990 }
1137 if (type == 'c')
1138 my_trace_put_params(buf, &i, &q->params,
1139 ND_PARAMS_BIND_WAY_BOTH);
991 1140 if (type == 'r') { if (type == 'r') {
992 1141 my_trace_put64(buf, &i, (uint64_t) q->res); my_trace_put64(buf, &i, (uint64_t) q->res);
993 1142 my_trace_put64(buf, &i, q->num); my_trace_put64(buf, &i, q->num);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1021 1170 my_trace_put(buf, &i, buf2, max); // data my_trace_put(buf, &i, buf2, max); // data
1022 1171 } }
1023 1172 if (ret == -1) if (ret == -1)
1024 my_trace_put32(buf, &i, save_errno);
1173 my_trace_put32(buf, &i, saved_errno);
1025 1174 } }
1026 1175 } else if (strcmp(func, "recv") == 0) { } else if (strcmp(func, "recv") == 0) {
1027 1176 void *buf2 = NULL; void *buf2 = NULL;
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1041 1190 my_trace_put(buf, &i, buf2, max); // data my_trace_put(buf, &i, buf2, max); // data
1042 1191 } }
1043 1192 if (ret == -1) if (ret == -1)
1044 my_trace_put32(buf, &i, save_errno);
1193 my_trace_put32(buf, &i, saved_errno);
1045 1194 } }
1195 } else if (strcmp(func, "recvmsg") == 0) {
1196 my_trace_put32(buf, &i, va_arg(va, int)); // sock
1197 // TODO
1046 1198 } else if (strcmp(func, "recvfrom") == 0) { } else if (strcmp(func, "recvfrom") == 0) {
1047 1199 my_trace_put32(buf, &i, va_arg(va, int)); // sock my_trace_put32(buf, &i, va_arg(va, int)); // sock
1048 1200 struct sockaddr *addr = NULL; struct sockaddr *addr = NULL;
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1059 1211 ssize_t ret = va_arg(va, ssize_t); ssize_t ret = va_arg(va, ssize_t);
1060 1212 my_trace_put64(buf, &i, ret); my_trace_put64(buf, &i, ret);
1061 1213 if (ret == -1) { if (ret == -1) {
1062 my_trace_put32(buf, &i, save_errno);
1214 my_trace_put32(buf, &i, saved_errno);
1063 1215 } else if (ret > 0) { // TODO: not sure if ret is 0 if addr is filled or not } else if (ret > 0) { // TODO: not sure if ret is 0 if addr is filled or not
1064 1216 unsigned short max = ret; unsigned short max = ret;
1065 1217 if (max > 128) max = 128; if (max > 128) max = 128;
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1091 1243 ssize_t ret = va_arg(va, ssize_t); ssize_t ret = va_arg(va, ssize_t);
1092 1244 my_trace_put64(buf, &i, ret); my_trace_put64(buf, &i, ret);
1093 1245 if (ret == -1) if (ret == -1)
1094 my_trace_put32(buf, &i, save_errno);
1246 my_trace_put32(buf, &i, saved_errno);
1095 1247 } }
1096 1248 } else if (strcmp(func, "sendmsg") == 0) { } else if (strcmp(func, "sendmsg") == 0) {
1097 1249 my_trace_put32(buf, &i, va_arg(va, int)); // sock my_trace_put32(buf, &i, va_arg(va, int)); // sock
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1112 1264 ssize_t ret = va_arg(va, ssize_t); ssize_t ret = va_arg(va, ssize_t);
1113 1265 my_trace_put64(buf, &i, ret); my_trace_put64(buf, &i, ret);
1114 1266 if (ret == -1) if (ret == -1)
1115 my_trace_put32(buf, &i, save_errno);
1267 my_trace_put32(buf, &i, saved_errno);
1116 1268 } }
1117 1269 } else if (strcmp(func, "setsockopt") == 0) { } else if (strcmp(func, "setsockopt") == 0) {
1118 1270 my_trace_put32(buf, &i, va_arg(va, int)); // sock my_trace_put32(buf, &i, va_arg(va, int)); // sock
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1125 1277 int ret = va_arg(va, int); int ret = va_arg(va, int);
1126 1278 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
1127 1279 if (ret == -1) if (ret == -1)
1128 my_trace_put32(buf, &i, save_errno);
1280 my_trace_put32(buf, &i, saved_errno);
1129 1281 } else if (strcmp(func, "socket") == 0) { } else if (strcmp(func, "socket") == 0) {
1130 1282 my_trace_put32(buf, &i, va_arg(va, int)); // domain my_trace_put32(buf, &i, va_arg(va, int)); // domain
1131 1283 my_trace_put32(buf, &i, va_arg(va, int)); // type my_trace_put32(buf, &i, va_arg(va, int)); // type
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1133 1285 int ret = va_arg(va, int); int ret = va_arg(va, int);
1134 1286 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
1135 1287 if (ret == -1) if (ret == -1)
1136 my_trace_put32(buf, &i, save_errno);
1288 my_trace_put32(buf, &i, saved_errno);
1137 1289 } else if (strcmp(func, "sqlite3_bind_double") == 0) { } else if (strcmp(func, "sqlite3_bind_double") == 0) {
1138 1290 my_trace_put64(buf, &i, va_arg(va, uint64_t)); // stmt my_trace_put64(buf, &i, va_arg(va, uint64_t)); // stmt
1139 1291 my_trace_put32(buf, &i, va_arg(va, int)); // index my_trace_put32(buf, &i, va_arg(va, int)); // index
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1212 1364 int ret = va_arg(va, int); int ret = va_arg(va, int);
1213 1365 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
1214 1366 if (ret == -1) if (ret == -1)
1215 my_trace_put32(buf, &i, save_errno);
1367 my_trace_put32(buf, &i, saved_errno);
1216 1368 } }
1217 1369 } else if (strcmp(func, "syslog") == 0) { } else if (strcmp(func, "syslog") == 0) {
1218 1370 my_trace_put32(buf, &i, va_arg(va, int)); // prio my_trace_put32(buf, &i, va_arg(va, int)); // prio
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1230 1382 int ret = va_arg(va, int); int ret = va_arg(va, int);
1231 1383 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
1232 1384 if (ret == -1) if (ret == -1)
1233 my_trace_put32(buf, &i, save_errno);
1385 my_trace_put32(buf, &i, saved_errno);
1234 1386 } }
1235 1387 } break; } break;
1236 1388
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1244 1396 int ret = va_arg(va, int); int ret = va_arg(va, int);
1245 1397 my_trace_put32(buf, &i, ret); my_trace_put32(buf, &i, ret);
1246 1398 if (ret == -1) if (ret == -1)
1247 my_trace_put32(buf, &i, save_errno);
1399 my_trace_put32(buf, &i, saved_errno);
1248 1400 } }
1249 1401 } break; } break;
1250 1402
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1266 1418 ssize_t ret = va_arg(va, ssize_t); ssize_t ret = va_arg(va, ssize_t);
1267 1419 my_trace_put64(buf, &i, ret); my_trace_put64(buf, &i, ret);
1268 1420 if (ret == -1) if (ret == -1)
1269 my_trace_put32(buf, &i, save_errno);
1421 my_trace_put32(buf, &i, saved_errno);
1270 1422 } }
1271 1423 } break; } break;
1272 1424 } }
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
1277 1429 uint16_t _u16 = htobe16(i); uint16_t _u16 = htobe16(i);
1278 1430 memcpy(buf, &_u16, 2); memcpy(buf, &_u16, 2);
1279 1431
1432 //char dump[i * 4 + 1];
1433 //bin2hex_ascii(dump, buf, i);
1434 //xlog(0, "%s: packed %u bytes: %s\n", __func__, i, dump);
1280 1435 return i; return i;
1281 1436 } }
1282 1437
1283 void my_trace(const char *func, const char type, ...)
1438 /*
1439 * @tf - trace flags
1440 */
1441 void my_trace(const char *func, const char *tf, const char type, ...)
1284 1442 { {
1285 1443 static __thread unsigned char out[64000]; // I had to reduce this for .NET! Stack too small! static __thread unsigned char out[64000]; // I had to reduce this for .NET! Stack too small!
1286 int save_errno;
1287 1444 va_list va; va_list va;
1288 int locked, r;
1289
1290 save_errno = errno;
1445 int r;
1291 1446
1292 if (nd_info_inited && nd_info->do_fill_buffer == 1) {
1293 unsigned int size, off = 0;
1294 int r = sem_wait(&nd_info->sem); // TODO: check error code
1295 nd_info->do_fill_buffer = 0;
1447 int saved_errno = errno;
1448 do {
1449 if (nd_info_inited && (nd_info->do_fill_buffer == 1)) {
1450 unsigned int size, off = 0;
1451 sem_wait(&nd_info->sem); // TODO: check error code
1452 nd_info->do_fill_buffer = 0;
1453
1454 uint32_t u32 = htobe32(nd_proc_start);
1455 nd_info->buf[off++] = 'S';
1456 memcpy(nd_info->buf + off, &u32, 4); off += 4;
1457
1458 size = export_fd_nodes(nd_info->buf + off,
1459 sizeof(nd_info->buf) - off, fd_nodes, 32);
1460 off += size;
1461
1462 nd_info->buf_size = off;
1463 nd_info->buffer_is_filled = 1;
1464 sem_post(&nd_info->sem); // TODO: check error code
1465 }
1296 1466
1297 uint32_t u32 = htobe32(nd_proc_start);
1298 nd_info->buf[off++] = 'S';
1299 memcpy(nd_info->buf + off, &u32, 4); off += 4;
1467 if (shared_inited == 0)
1468 break;
1300 1469
1301 size = export_fd_nodes(nd_info->buf + off,
1302 sizeof(nd_info->buf) - off, fd_nodes, 32);
1303 off += size;
1470 if (trace_enabled == 0)
1471 break;
1304 1472
1305 nd_info->buf_size = off;
1306 nd_info->buffer_is_filled = 1;
1307 r = sem_post(&nd_info->sem); // TODO: check error code
1308 }
1473 int locked = 0;
1474 while (1) {
1475 unsigned int ava, i;
1309 1476
1310 if (shared_inited == 0)
1311 return;
1477 if (shared->client_flags & ND_SHARED_ONLY_HIGH_LEVEL) {
1478 if (!strstr(tf, "i"))
1479 break;
1480 }
1312 1481
1313 if (trace_enabled == 0)
1314 return;
1482 xlog(200, "%s func=%s tf=[%s] type=%c trace_depth=%hu errno=%d\n",
1483 __func__, func, tf, type, trace_depth, errno);
1315 1484
1316 xlog(200, "%s func=%s type=%c errno=%d\n",
1317 __func__, func, type, errno);
1485 va_start(va, type);
1486 i = my_trace_encode(out, func, tf, type, saved_errno, va);
1487 va_end(va);
1488 if (i == 0) {
1489 xlog(1, "I do not know how to encode [%s][%c]!\n", func, type);
1490 break;
1491 }
1492 char dump[i * 4 + 1];
1493 bin2hex_ascii(dump, out, i);
1494 xlog(201, " gen: %s\n", dump);
1495
1496 // TODO: use an internal buffer if we cannot take the lock and move back to 'trywait'
1497 xlog(201, " head=%u tail=%u junk=%u to_copy=%u [before lock]\n",
1498 shared->head, shared->tail, shared->junk, i);
1499 r = sem_wait(&shared->sem1);
1500 if (r == -1) {
1501 xlog(1, "sem_trywait sem1 error: %m\n");
1502 break;
1503 }
1504 locked = 1;
1505
1506 if (shared->head < shared->tail) {
1507 // s.....head.....tail....e
1508 // head=3 tail=5: 0..h.t.7 => size8-(tail5-head3)=6 => ava = 6
1509 ava = shared->buf_size - (shared->tail - shared->head);
1510 } else if (shared->head == shared->tail) {
1511 ava = shared->buf_size - 1;
1512 } else { // s....tail....head....e 0t...h...9 head=5 tail=1 => ava=4
1513 ava = shared->head - shared->tail;
1514 }
1515 if (ava < i) { // TODO: add to an internal buffer
1516 xlog(1, "%s: not enough available: ava[%u] < i[%u]\n",
1517 __func__, ava, i);
1518 msgs_lost++;
1519 break;
1520 }
1521 unsigned int max = shared->buf_size - shared->tail; // size=11 tail=5 max=6: .....t.....
1522 if (max > i) { // enough space
1523 memcpy(shared->buf + shared->tail, out, i);
1524 shared->tail += i;
1525 } else { // split copy
1526 memcpy(shared->buf + shared->tail, out, max);
1527 memcpy(shared->buf, out + max, i - max);
1528 shared->tail = i - max; // size=13 head=2 tail=5 i=9 max=8: ..h..t....... => 89h..01234567 => tail=1
1529 }
1318 1530
1319 locked = 0;
1320 do {
1321 unsigned int ava, i;
1531 if (msgs_lost == 0)
1532 break;
1322 1533
1323 va_start(va, type);
1324 i = my_trace_encode(out, func, type, save_errno, va);
1325 va_end(va);
1326 if (i == 0) {
1327 xlog(1, "I do not know how to encode [%s][%c]!\n", func, type);
1534 // TODO: inject here '-msgs_lost' message and loop
1535 // TODO: maybe insert it as a flag in every message?
1536 // TODO: or just append it to the current message
1328 1537 break; break;
1329 1538 } }
1330 1539
1331 char dump[i * 4 + 1];
1332 bin2hex_ascii(dump, out, i);
1333 xlog(201, " gen: %s\n", dump);
1540 if (locked) {
1541 r = sem_post(&shared->sem1); // was sem2
1542 if (r == -1)
1543 xlog(1, "sem_post sem1 error: %m\n");
1334 1544
1335 // TODO: use an internal buffer if we cannot take the lock and move back to 'trywait'
1336 xlog(201, " head=%u tail=%u to_copy=%u [start]\n",
1337 shared->head, shared->tail, i);
1338 r = sem_wait(&shared->sem1);
1339 if (r == -1) {
1340 xlog(1, "sem_trywait sem1 error: %m\n");
1341 break;
1545 xlog(201, " head=%u tail=%u [after unlock]\n",
1546 shared->head, shared->tail);
1342 1547 } }
1343 locked = 1;
1344
1345 if (shared->head < shared->tail) {
1346 // s.....head.....tail....e
1347 // head=3 tail=5: 0..h.t.7 => size8-(tail5-head3)=6 => ava = 6
1348 ava = shared->buf_size - (shared->tail - shared->head);
1349 } else if (shared->head == shared->tail) {
1350 ava = shared->buf_size - 1;
1351 } else { // s....tail....head....e 0t...h...9 head=5 tail=1 => ava=4
1352 ava = shared->head - shared->tail;
1353 }
1354 if (ava < i) {
1355 xlog(1, "%s: not enough available: ava[%u] < i[%u]\n",
1356 __func__, ava, i);
1357 shared->msgs_lost++; // TODO: add to an internal buffer
1358 break;
1359 }
1360 unsigned int max = shared->buf_size - shared->tail; // size=11 tail=5 max=6: .....t.....
1361 if (max > i) { // enough space
1362 memcpy(shared->buf + shared->tail, out, i);
1363 shared->tail += i;
1364 } else { // split copy
1365 memcpy(shared->buf + shared->tail, out, max);
1366 memcpy(shared->buf, out + max, i - max);
1367 shared->tail = i - max; // size=13 head=2 tail=5 i=9 max=8: ..h..t....... => 89h..01234567 => tail=1
1368 }
1369 } while (0);
1370
1371 if (locked) {
1372 r = sem_post(&shared->sem1); // was sem2
1373 if (r == -1)
1374 xlog(1, "sem_post sem1 error: %m\n");
1375
1376 xlog(201, " head=%u tail=%u [got lock]\n",
1377 shared->head, shared->tail);
1378 }
1379 1548
1380 if (type == 'c')
1381 trace_depth++;
1382 else if (type == 'r')
1383 trace_depth--;
1549 if (type == 'c')
1550 trace_depth++;
1551 else if (type == 'r')
1552 trace_depth--;
1553 } while (0);
1384 1554
1385 errno = save_errno;
1555 errno = saved_errno;
1386 1556 } }
1387 1557
1388 1558 static void my_on_exit(int ret, void *junk) static void my_on_exit(int ret, void *junk)
1389 1559 { {
1390 1560 xlog(100, "my_on_exit ret=%d junk=%p!\n", ret, junk); xlog(100, "my_on_exit ret=%d junk=%p!\n", ret, junk);
1391 my_trace("-stop", 'R', ret);
1561 my_trace("-stop", "i", 'R', ret);
1392 1562 ninedogs_process_core(NINEDOGS_CORE_STOP, &ret); ninedogs_process_core(NINEDOGS_CORE_STOP, &ret);
1393 1563 } }
1394 1564
 
... ... void _exit(int status)
1397 1567 { {
1398 1568 //write(1, "_exit\n", 6); //write(1, "_exit\n", 6);
1399 1569 xlog(1, "my _exit status=%d!\n", status); xlog(1, "my _exit status=%d!\n", status);
1400 my_trace("-stop", 'R', status);
1570 my_trace("-stop", "i", 'R', status);
1401 1571 old__exit(status); old__exit(status);
1402 1572 } }
1403 1573 #endif #endif
 
... ... static void my_segv(int sig)
1417 1587 for (int j = 0; j < r; j++) for (int j = 0; j < r; j++)
1418 1588 xlog(0, " %s\n", a[j]); xlog(0, " %s\n", a[j]);
1419 1589 } }
1420 my_trace("-segv", 'R', a, r);
1590 my_trace("-segv", "i", 'R', a, r);
1421 1591
1422 1592 exit(1); exit(1);
1423 1593 } }
 
... ... static void ninedogs_child(void)
1484 1654 __attribute__((destructor)) void ninedogs_fini(void) __attribute__((destructor)) void ninedogs_fini(void)
1485 1655 { {
1486 1656 xlog(20, "%s\n", __func__); xlog(20, "%s\n", __func__);
1487 //my_trace("-dest", "r");
1657 //my_trace("-dest", "i", 'R');
1488 1658
1489 1659 if (shared_inited) { if (shared_inited) {
1490 1660 char name[32]; char name[32];
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1529 1699 if (ninedogs_inited == 1) if (ninedogs_inited == 1)
1530 1700 return; return;
1531 1701
1702 // We need to do that here, else we will be called again
1703 ninedogs_inited = 1;
1704
1532 1705 nd_proc_start = time(NULL); nd_proc_start = time(NULL);
1533 1706
1534 1707 //write(1, "ninedogs: init start\n", 21); //write(1, "ninedogs: init start\n", 21);
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1578 1751
1579 1752 log_file = getenv("FORCE_NET_LOG"); log_file = getenv("FORCE_NET_LOG");
1580 1753 if (log_file != NULL) if (log_file != NULL)
1581 Log = open(log_file, O_WRONLY | O_APPEND, 0700);
1754 Log = old_open(log_file, O_WRONLY | O_APPEND, 0700);
1582 1755 else else
1583 1756 Log = dup(2); // TODO Log = dup(2); // TODO
1584 1757
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1783 1956
1784 1957 old_fstatat = old_dlsym(RTLD_NEXT, "fstatat"); old_fstatat = old_dlsym(RTLD_NEXT, "fstatat");
1785 1958 if (old_fstatat == NULL) { if (old_fstatat == NULL) {
1786 xlog(0, " cannot resolve 'fstatat'!\n");
1787 exit(1);
1959 xlog(1, " cannot resolve 'fstatat'!\n");
1960 //exit(1);
1788 1961 } }
1789 1962
1790 1963 old_fstatat64 = old_dlsym(RTLD_NEXT, "fstatat64"); old_fstatat64 = old_dlsym(RTLD_NEXT, "fstatat64");
1791 1964 if (old_fstatat64 == NULL) { if (old_fstatat64 == NULL) {
1792 xlog(0, " cannot resolve 'fstatat64'!\n");
1793 exit(1);
1965 xlog(1, " cannot resolve 'fstatat64'!\n");
1966 //exit(1);
1794 1967 } }
1795 1968
1796 1969 old_fork = old_dlsym(RTLD_NEXT, "fork"); old_fork = old_dlsym(RTLD_NEXT, "fork");
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1799 1972 exit(1); exit(1);
1800 1973 } }
1801 1974
1975 old_shm_open = old_dlsym(RTLD_NEXT, "shm_open");
1976 if (old_shm_open == NULL) {
1977 xlog(0, " cannot resolve 'shm_open'!\n");
1978 exit(1);
1979 }
1980
1802 1981
1803 1982 x = getenv("NINEDOGS_VERBOSE"); x = getenv("NINEDOGS_VERBOSE");
1804 1983 if (x != NULL) if (x != NULL)
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1811 1990
1812 1991 // Preparing the nd-trace support // Preparing the nd-trace support
1813 1992 do { do {
1993 if (shared_inited == 1)
1994 break;
1995
1996 xlog(1, "Initializing shared memory for pid %u...\n", getpid());
1997
1814 1998 char name[32]; char name[32];
1815 1999 snprintf(name, sizeof(name), "/ninedogs-%d", getpid()); snprintf(name, sizeof(name), "/ninedogs-%d", getpid());
1816 int shm = shm_open(name, O_RDWR | O_CREAT | O_EXCL,
2000 int shm = old_shm_open(name, O_RDWR | O_CREAT | O_EXCL,
1817 2001 S_IRUSR | S_IWUSR); S_IRUSR | S_IWUSR);
1818 2002 if (shm == -1) { if (shm == -1) {
1819 xlog(0, "Cannot create shm: %m\n");
2003 xlog(0, "Cannot create shm [%s]: %m\n", name);
1820 2004 break; break;
1821 2005 } }
1822 2006
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1833 2017 } }
1834 2018 xlog(200, "%s: tracing mmap=%p\n", __func__, shared); xlog(200, "%s: tracing mmap=%p\n", __func__, shared);
1835 2019
2020 if (shared->inited == 1) {
2021 xlog(1, "Shared was already initialized!\n");
2022 break;
2023 }
2024
1836 2025 if (sem_init(&shared->sem1, 1, 0 /* locked */) == -1) { if (sem_init(&shared->sem1, 1, 0 /* locked */) == -1) {
1837 2026 xlog(0, "Cannot do sem_init sem1: %m\n"); xlog(0, "Cannot do sem_init sem1: %m\n");
1838 2027 break; break;
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1840 2029
1841 2030 shared->version = SHARED_VERSION; shared->version = SHARED_VERSION;
1842 2031 shared->buf_size = sizeof(shared->buf); shared->buf_size = sizeof(shared->buf);
1843 shared->msgs_lost = 0;
1844 // We want force from start start the wrap around
2032 shared->junk = 0;
2033 // We want force from start the wrap around
1845 2034 shared->tail = shared->head = shared->buf_size - 1; shared->tail = shared->head = shared->buf_size - 1;
2035 shared->client_flags = 0;
2036 shared->inited = 1;
1846 2037
1847 2038 if (sem_post(&shared->sem1) == -1) { if (sem_post(&shared->sem1) == -1) {
1848 2039 xlog(0, "Cannot do sem_post sem1: %m\n"); xlog(0, "Cannot do sem_post sem1: %m\n");
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1854 2045
1855 2046 // Preparing the nd-info support // Preparing the nd-info support
1856 2047 do { do {
2048 if (nd_info_inited == 1)
2049 break;
2050
1857 2051 char name[48]; char name[48];
1858 2052 snprintf(name, sizeof(name), "/ninedogs-info-%d", getpid()); snprintf(name, sizeof(name), "/ninedogs-info-%d", getpid());
1859 int shm = shm_open(name, O_RDWR | O_CREAT | O_EXCL,
2053 int shm = old_shm_open(name, O_RDWR | O_CREAT | O_EXCL,
1860 2054 S_IRUSR | S_IWUSR); S_IRUSR | S_IWUSR);
1861 2055 if (shm == -1) { if (shm == -1) {
1862 xlog(0, "Cannot create shm: %m\n");
2056 xlog(0, "Cannot create shm [%s]: %m\n", name);
1863 2057 break; break;
1864 2058 } }
1865 2059
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1893 2087 nd_info_inited = 1; nd_info_inited = 1;
1894 2088 } while (0); } while (0);
1895 2089
1896 ninedogs_inited = 1;
2090 //ninedogs_inited = 1; - done above
1897 2091 //xlog(1, " init ended.\n"); //xlog(1, " init ended.\n");
1898 2092 //write(1, "ninedogs: init done\n", 20); //write(1, "ninedogs: init done\n", 20);
1899 2093
 
... ... __attribute__((constructor)) void ninedogs_init(void)
1903 2097 x = getenv("JAVA_TOOL_OPTIONS"); x = getenv("JAVA_TOOL_OPTIONS");
1904 2098 if (!x) if (!x)
1905 2099 x = ""; x = "";
1906 snprintf(env, sizeof(env),
1907 "-javaagent:/usr/share/ninedogs/ninedogs-agent.jar %s", x);
1908 setenv("JAVA_TOOL_OPTIONS", env, 1);
2100 else
2101 xlog(40, "old JAVA_TOOL_OPTIONS: [%s]\n", x);
2102 if (!strstr(x, "ninedogs-agent.jar")) {
2103 snprintf(env, sizeof(env),
2104 "-javaagent:/usr/share/ninedogs/ninedogs-agent.jar %s", x);
2105 setenv("JAVA_TOOL_OPTIONS", env, 1);
2106 }
1909 2107
1910 2108 /* .NET stuff */ /* .NET stuff */
1911 2109 /* /*
 
... ... int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
2071 2269 xlog(100, "bind(sockfd=%d)\n", sockfd); xlog(100, "bind(sockfd=%d)\n", sockfd);
2072 2270
2073 2271 int ret = old_bind(sockfd, addr, addrlen); int ret = old_bind(sockfd, addr, addrlen);
2074 my_trace(__func__, 'R', sockfd, addr, addrlen, ret);
2272 my_trace(__func__, "", 'R', sockfd, addr, addrlen, ret);
2075 2273
2076 2274 if (ret == 0) { if (ret == 0) {
2077 2275 struct fd_node *q = fd_search(sockfd); struct fd_node *q = fd_search(sockfd);
 
... ... int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
2087 2285 int setsockopt(int sockfd, int level, int optname, const void *optval, int setsockopt(int sockfd, int level, int optname, const void *optval,
2088 2286 socklen_t optlen) socklen_t optlen)
2089 2287 { {
2288 if (!old_setsockopt)
2289 old_setsockopt = ninedogs_dlsym("setsockopt");
2290
2090 2291 int ret = old_setsockopt(sockfd, level, optname, optval, optlen); int ret = old_setsockopt(sockfd, level, optname, optval, optlen);
2091 my_trace(__func__, 'R', sockfd, level, optname, optlen, optval, ret);
2292 my_trace(__func__, "", 'R', sockfd, level, optname, optlen, optval, ret);
2092 2293
2093 2294 return ret; return ret;
2094 2295 } }
2095 2296
2096 2297 int socket(int domain, int type, int protocol) int socket(int domain, int type, int protocol)
2097 2298 { {
2299 if (!old_socket)
2300 old_socket = ninedogs_dlsym("socket");
2301
2098 2302 char sprotocol[16]; char sprotocol[16];
2099 2303 nd_decode_socket_protocol(sprotocol, sizeof(sprotocol), protocol); nd_decode_socket_protocol(sprotocol, sizeof(sprotocol), protocol);
2100 2304 xlog(100, "socket(domain=%s[%d], type=%s, protocol=%s)\n", xlog(100, "socket(domain=%s[%d], type=%s, protocol=%s)\n",
2101 2305 sdomain(domain), domain, stype(type), sprotocol); sdomain(domain), domain, stype(type), sprotocol);
2102 2306
2103 2307 int sockfd = old_socket(domain, type, protocol); int sockfd = old_socket(domain, type, protocol);
2104 my_trace(__func__, 'R', domain, type, protocol, sockfd);
2308 my_trace(__func__, "", 'R', domain, type, protocol, sockfd);
2105 2309
2106 2310 struct fd_node *q = fd_add(sockfd); struct fd_node *q = fd_add(sockfd);
2107 2311 if (q) { if (q) {
 
... ... int close(int fd)
2123 2327
2124 2328 fd_del(fd); fd_del(fd);
2125 2329
2126 my_trace(__func__, 'c', fd);
2330 my_trace(__func__, "", 'c', fd);
2127 2331 int ret = old_close(fd); int ret = old_close(fd);
2128 my_trace(__func__, 'r', fd, ret);
2332 my_trace(__func__, "", 'r', fd, ret);
2129 2333
2130 2334 return ret; return ret;
2131 2335 } }
 
... ... static void write_common_post(struct fd_node *q, ssize_t ret)
2144 2348
2145 2349 ssize_t write(int fd, const void *buf, size_t count) ssize_t write(int fd, const void *buf, size_t count)
2146 2350 { {
2351 if (!old_write)
2352 old_write = ninedogs_dlsym("write");
2353
2147 2354 struct fd_node *q = fd_search(fd); struct fd_node *q = fd_search(fd);
2148 2355 if (q) { if (q) {
2149 2356 if (q->type == FD_NODE_DEV_NINEDOGS) { if (q->type == FD_NODE_DEV_NINEDOGS) {
 
... ... ssize_t write(int fd, const void *buf, size_t count)
2157 2364
2158 2365 dump(200, "write", buf, count); dump(200, "write", buf, count);
2159 2366
2160 my_trace(__func__, 'c', fd, buf, count);
2367 my_trace(__func__, "", 'c', fd, buf, count);
2161 2368 ssize_t ret = old_write(fd, buf, count); ssize_t ret = old_write(fd, buf, count);
2162 my_trace(__func__, 'r', fd, count, ret);
2369 my_trace(__func__, "", 'r', fd, count, ret);
2163 2370
2164 2371 write_common_post(q, ret); write_common_post(q, ret);
2165 2372 if (q && (ret > 0)) if (q && (ret > 0))
 
... ... ssize_t write(int fd, const void *buf, size_t count)
2170 2377
2171 2378 ssize_t send(int sockfd, const void *buf, size_t len, int flags) ssize_t send(int sockfd, const void *buf, size_t len, int flags)
2172 2379 { {
2380 if (!old_send)
2381 old_send = ninedogs_dlsym("send");
2382
2173 2383 xlog(110, "%s(sockfd=%d, buf, len=%zu, flags=0x%x)\n", xlog(110, "%s(sockfd=%d, buf, len=%zu, flags=0x%x)\n",
2174 2384 __func__, sockfd, len, flags); __func__, sockfd, len, flags);
2175 2385
2176 2386 struct fd_node *q = fd_search(sockfd); struct fd_node *q = fd_search(sockfd);
2177 2387
2178 my_trace(__func__, 'c', sockfd, buf, len, flags);
2388 my_trace(__func__, "", 'c', sockfd, buf, len, flags);
2179 2389 ssize_t ret = old_send(sockfd, buf, len, flags); ssize_t ret = old_send(sockfd, buf, len, flags);
2180 my_trace(__func__, 'r', sockfd, len, flags, ret);
2390 my_trace(__func__, "", 'r', sockfd, len, flags, ret);
2181 2391
2182 2392 write_common_post(q, ret); write_common_post(q, ret);
2183 2393
 
... ... ssize_t send(int sockfd, const void *buf, size_t len, int flags)
2187 2397 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
2188 2398 const struct sockaddr *dest_addr, socklen_t addrlen) const struct sockaddr *dest_addr, socklen_t addrlen)
2189 2399 { {
2400 if (!old_sendto)
2401 old_sendto = ninedogs_dlsym("sendto");
2402
2190 2403 xlog(110, "sendto(sockfd, %d, buf, len=%zu, flags=0x%x, ...)\n", xlog(110, "sendto(sockfd, %d, buf, len=%zu, flags=0x%x, ...)\n",
2191 2404 sockfd, len, flags); sockfd, len, flags);
2192 2405
2193 2406 struct fd_node *q = fd_search(sockfd); struct fd_node *q = fd_search(sockfd);
2194 2407
2195 my_trace(__func__, 'c', sockfd, buf, len, flags, dest_addr, addrlen);
2408 my_trace(__func__, "", 'c', sockfd, buf, len, flags, dest_addr, addrlen);
2196 2409 ssize_t ret = old_sendto(sockfd, buf, len, flags, dest_addr, addrlen); ssize_t ret = old_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
2197 my_trace(__func__, 'r', sockfd, len, flags, ret);
2410 my_trace(__func__, "", 'r', sockfd, len, flags, ret);
2198 2411
2199 2412 write_common_post(q, ret); write_common_post(q, ret);
2200 2413
 
... ... ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
2206 2419 */ */
2207 2420 ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
2208 2421 { {
2422 if (!old_sendmsg)
2423 old_sendmsg = ninedogs_dlsym("sendmsg");
2424
2209 2425 xlog(100, "sendmsg(sockfd=%d, ..., flags=0x%x)\n", xlog(100, "sendmsg(sockfd=%d, ..., flags=0x%x)\n",
2210 2426 sockfd, flags); sockfd, flags);
2211 2427
 
... ... ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
2215 2431 for (unsigned i = 0; i < msg->msg_iovlen; i++) for (unsigned i = 0; i < msg->msg_iovlen; i++)
2216 2432 dump(200, "sendmsg", msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); dump(200, "sendmsg", msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
2217 2433
2218 my_trace(__func__, 'c', sockfd, msg, flags);
2434 my_trace(__func__, "", 'c', sockfd, msg, flags);
2219 2435 ssize_t ret = old_sendmsg(sockfd, msg, flags); ssize_t ret = old_sendmsg(sockfd, msg, flags);
2220 my_trace(__func__, 'r', sockfd, flags, ret);
2436 my_trace(__func__, "", 'r', sockfd, flags, ret);
2221 2437
2222 2438 write_common_post(q, ret); write_common_post(q, ret);
2223 2439
 
... ... ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
2228 2444 ssize_t (*old_lseek)(int fd, off_t off, int whence); ssize_t (*old_lseek)(int fd, off_t off, int whence);
2229 2445 ssize_t lseek(int fd, off_t off, int whence) ssize_t lseek(int fd, off_t off, int whence)
2230 2446 { {
2447 if (!old_lseek)
2448 old_lseek = ninedogs_dlsym("lseek");
2449
2231 2450 xlog(110, "%s(fd=%d, off=%zu, whence=%d)\n", __func__, fd, off, whence); xlog(110, "%s(fd=%d, off=%zu, whence=%d)\n", __func__, fd, off, whence);
2232 2451
2233 2452 if (!old_lseek) if (!old_lseek)
 
... ... ssize_t lseek(int fd, off_t off, int whence)
2235 2454
2236 2455 struct fd_node *q = fd_search(fd); struct fd_node *q = fd_search(fd);
2237 2456
2238 my_trace(__func__, 'c', fd, off, whence);
2457 my_trace(__func__, "", 'c', fd, off, whence);
2239 2458 ssize_t ret = old_lseek(fd, off, whence); ssize_t ret = old_lseek(fd, off, whence);
2240 my_trace(__func__, 'r', fd, off, whence, ret);
2459 my_trace(__func__, "", 'r', fd, off, whence, ret);
2241 2460
2242 2461 if (q && (ret > 0)) if (q && (ret > 0))
2243 2462 q->file.off = ret; q->file.off = ret;
 
... ... static void read_common_post(struct fd_node *q, ssize_t ret)
2261 2480 ssize_t (*old_read)(int fd, void *buf, size_t count); ssize_t (*old_read)(int fd, void *buf, size_t count);
2262 2481 ssize_t read(int fd, void *buf, size_t count) ssize_t read(int fd, void *buf, size_t count)
2263 2482 { {
2483 if (!old_read)
2484 old_read = ninedogs_dlsym("read");
2485
2264 2486 xlog(110, "%s(fd=%d, buf, count=%zu)\n", __func__, fd, count); xlog(110, "%s(fd=%d, buf, count=%zu)\n", __func__, fd, count);
2265 2487
2266 2488 if (!old_read) if (!old_read)
 
... ... ssize_t read(int fd, void *buf, size_t count)
2268 2490
2269 2491 struct fd_node *q = fd_search(fd); struct fd_node *q = fd_search(fd);
2270 2492
2271 my_trace(__func__, 'c', fd, count);
2493 my_trace(__func__, "", 'c', fd, count);
2272 2494 ssize_t ret = old_read(fd, buf, count); ssize_t ret = old_read(fd, buf, count);
2273 my_trace(__func__, 'r', fd, buf, count, ret);
2495 my_trace(__func__, "", 'r', fd, buf, count, ret);
2274 2496
2275 2497 read_common_post(q, ret); read_common_post(q, ret);
2276 2498 if (q && (ret > 0)) if (q && (ret > 0))
 
... ... ssize_t read(int fd, void *buf, size_t count)
2281 2503
2282 2504 ssize_t recv(int sockfd, void *buf, size_t len, int flags) ssize_t recv(int sockfd, void *buf, size_t len, int flags)
2283 2505 { {
2506 if (!old_recv)
2507 old_recv = ninedogs_dlsym("recv");
2508
2284 2509 xlog(110, "%s(sockfd=%d, buf, len=%zu, flags=0x%x)\n", xlog(110, "%s(sockfd=%d, buf, len=%zu, flags=0x%x)\n",
2285 2510 __func__, sockfd, len, flags); __func__, sockfd, len, flags);
2286 2511
2287 2512 struct fd_node *q = fd_search(sockfd); struct fd_node *q = fd_search(sockfd);
2288 2513
2289 my_trace(__func__, 'c', sockfd, len, flags);
2514 my_trace(__func__, "", 'c', sockfd, len, flags);
2290 2515 ssize_t ret = old_recv(sockfd, buf, len, flags); ssize_t ret = old_recv(sockfd, buf, len, flags);
2291 my_trace(__func__, 'r', sockfd, buf, len, flags, ret);
2516 my_trace(__func__, "", 'r', sockfd, buf, len, flags, ret);
2292 2517
2293 2518 read_common_post(q, ret); read_common_post(q, ret);
2294 2519
 
... ... ssize_t recv(int sockfd, void *buf, size_t len, int flags)
2297 2522
2298 2523 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
2299 2524 { {
2525 if (!old_recvmsg)
2526 old_recvmsg = ninedogs_dlsym("recvmsg");
2527
2300 2528 xlog(110, "%s(sockfd=%d, msg, flags=0x%x)\n", xlog(110, "%s(sockfd=%d, msg, flags=0x%x)\n",
2301 2529 __func__, sockfd, flags); __func__, sockfd, flags);
2302 2530
2303 2531 struct fd_node *q = fd_search(sockfd); struct fd_node *q = fd_search(sockfd);
2304 2532
2305 my_trace(__func__, 'c', sockfd, msg, flags);
2533 my_trace(__func__, "", 'c', sockfd, msg, flags);
2306 2534 ssize_t ret = old_recvmsg(sockfd, msg, flags); ssize_t ret = old_recvmsg(sockfd, msg, flags);
2307 my_trace(__func__, 'r', sockfd, msg, flags, ret);
2535 my_trace(__func__, "", 'r', sockfd, msg, flags, ret);
2308 2536
2309 2537 #if 0 #if 0
2310 2538 ssize_t rest = ret; ssize_t rest = ret;
 
... ... ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flags,
2325 2553 { {
2326 2554 struct fd_node *q = fd_search(sockfd); struct fd_node *q = fd_search(sockfd);
2327 2555
2328 my_trace(__func__, 'c', sockfd, len, addrlen ? *addrlen : 0, flags);
2556 if (!old_recvfrom)
2557 old_recvfrom = ninedogs_dlsym("recvfrom");
2558
2559 my_trace(__func__, "", 'c', sockfd, len, addrlen ? *addrlen : 0, flags);
2329 2560 ssize_t ret = old_recvfrom(sockfd, buf, len, flags, src_addr, addrlen); ssize_t ret = old_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
2330 my_trace(__func__, 'r', sockfd, len, src_addr, addrlen ? *addrlen : 0, flags, ret, buf);
2561 my_trace(__func__, "", 'r', sockfd, len, src_addr, addrlen ? *addrlen : 0, flags, ret, buf);
2331 2562
2332 2563 read_common_post(q, ret); read_common_post(q, ret);
2333 2564
 
... ... static void accept_common(int sock, int new)
2350 2581 b->type = FD_NODE_SOCKET; b->type = FD_NODE_SOCKET;
2351 2582 b->socket.backlog = 0; b->socket.backlog = 0;
2352 2583 b->socket.accepts = 0; b->socket.accepts = 0;
2584 b->socket.accept_fd = sock + 1; // 0 is considered invalid
2353 2585 } }
2354 2586
2355 2587 if (a && b) { if (a && b) {
 
... ... static void accept_common(int sock, int new)
2364 2596 */ */
2365 2597 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
2366 2598 { {
2599 if (!old_accept)
2600 old_accept = ninedogs_dlsym("accept");
2601
2367 2602 xlog(100, "accept(sockfd=%d, ...)\n", sockfd); xlog(100, "accept(sockfd=%d, ...)\n", sockfd);
2368 2603
2369 my_trace(__func__, 'c', sockfd, addrlen ? *addrlen : 0);
2604 my_trace(__func__, "", 'c', sockfd, addrlen ? *addrlen : 0);
2370 2605 int new_sock = old_accept(sockfd, addr, addrlen); int new_sock = old_accept(sockfd, addr, addrlen);
2371 my_trace(__func__, 'r', sockfd, addr, addrlen ? *addrlen : 0, new_sock);
2606 my_trace(__func__, "", 'r', sockfd, addr, addrlen ? *addrlen : 0, new_sock);
2372 2607 accept_common(sockfd, new_sock); accept_common(sockfd, new_sock);
2373 2608 return new_sock; return new_sock;
2374 2609 } }
 
... ... int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
2378 2613 */ */
2379 2614 int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
2380 2615 { {
2616 if (!old_accept4)
2617 old_accept4 = ninedogs_dlsym("accept4");
2618
2381 2619 xlog(100, "accept4(sockfd=%d, ...flags=0x%x)\n", sockfd, flags); xlog(100, "accept4(sockfd=%d, ...flags=0x%x)\n", sockfd, flags);
2382 2620
2383 my_trace(__func__, 'c', sockfd, addrlen ? *addrlen : 0, flags);
2621 my_trace(__func__, "", 'c', sockfd, addrlen ? *addrlen : 0, flags);
2384 2622 int new_sock = old_accept4(sockfd, addr, addrlen, flags); int new_sock = old_accept4(sockfd, addr, addrlen, flags);
2385 my_trace(__func__, 'r', sockfd, addr, addrlen ? *addrlen : 0,
2623 my_trace(__func__, "", 'r', sockfd, addr, addrlen ? *addrlen : 0,
2386 2624 flags, new_sock); flags, new_sock);
2387 2625 accept_common(sockfd, new_sock); accept_common(sockfd, new_sock);
2388 2626 return new_sock; return new_sock;
 
... ... int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
2396 2634
2397 2635 xlog(100, "connect(sockfd=%d)\n", sockfd); xlog(100, "connect(sockfd=%d)\n", sockfd);
2398 2636
2399 my_trace(__func__, 'c', sockfd, addr, addrlen);
2637 my_trace(__func__, "", 'c', sockfd, addr, addrlen);
2400 2638 int ret = old_connect(sockfd, addr, addrlen); int ret = old_connect(sockfd, addr, addrlen);
2401 my_trace(__func__, 'r', sockfd, ret);
2639 my_trace(__func__, "", 'r', sockfd, ret);
2402 2640 if ((ret == 0) || (errno == EAGAIN) || (errno == EINPROGRESS)) { if ((ret == 0) || (errno == EAGAIN) || (errno == EINPROGRESS)) {
2403 2641 struct fd_node *q = fd_search(sockfd); struct fd_node *q = fd_search(sockfd);
2404 2642 if (q) { if (q) {
 
... ... int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
2414 2652
2415 2653 int poll(struct pollfd *fds, nfds_t nfds, int timeout) int poll(struct pollfd *fds, nfds_t nfds, int timeout)
2416 2654 { {
2655 if (!old_poll)
2656 old_poll = ninedogs_dlsym("poll");
2657
2417 2658 xlog(100, "poll(fds, %d, %d)\n", nfds, timeout); xlog(100, "poll(fds, %d, %d)\n", nfds, timeout);
2418 2659
2419 my_trace(__func__, 'c', fds, nfds, timeout);
2660 my_trace(__func__, "", 'c', fds, nfds, timeout);
2420 2661 int ret = old_poll(fds, nfds, timeout); int ret = old_poll(fds, nfds, timeout);
2421 my_trace(__func__, 'r', fds, nfds, timeout, ret);
2662 my_trace(__func__, "", 'r', fds, nfds, timeout, ret);
2422 2663
2423 2664 return ret; return ret;
2424 2665 } }
2425 2666
2426 2667 struct hostent *gethostbyname(const char *name) struct hostent *gethostbyname(const char *name)
2427 2668 { {
2669 if (!old_gethostbyname)
2670 old_gethostbyname = ninedogs_dlsym("gethostbyname");
2671
2428 2672 xlog(100, "gethostbyname(%s)\n", name); xlog(100, "gethostbyname(%s)\n", name);
2429 2673
2430 my_trace(__func__, 'c', name);
2674 my_trace(__func__, "i", 'c', name);
2431 2675 struct hostent *ret = old_gethostbyname(name); struct hostent *ret = old_gethostbyname(name);
2432 my_trace(__func__, 'r', name, ret);
2676 my_trace(__func__, "i", 'r', name, ret);
2433 2677
2434 2678 return ret; return ret;
2435 2679 } }
 
... ... int gethostbyname_r(const char *name, struct hostent *restrict ret,
2447 2691 old_gethostbyname_r = ninedogs_dlsym("gethostbyname_r"); old_gethostbyname_r = ninedogs_dlsym("gethostbyname_r");
2448 2692
2449 2693 xlog(100, "gethostbyname_r('%s', buflen=%zu)\n", name, buflen); xlog(100, "gethostbyname_r('%s', buflen=%zu)\n", name, buflen);
2450 my_trace(__func__, 'c', name);
2694 my_trace(__func__, "i", 'c', name);
2451 2695 int r = old_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); int r = old_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
2452 2696 xlog(100, "gethostbyname_r('%s', buflen=%zu) = %d h_errno=%d *result=%p\n", xlog(100, "gethostbyname_r('%s', buflen=%zu) = %d h_errno=%d *result=%p\n",
2453 2697 name, buflen, r, *h_errnop, result ? *result : NULL); name, buflen, r, *h_errnop, result ? *result : NULL);
2454 my_trace(__func__, 'r', name, r, *h_errnop, *result);
2698 my_trace(__func__, "i", 'r', name, r, *h_errnop, *result);
2455 2699
2456 2700 return r; return r;
2457 2701 } }
 
... ... int gethostbyname_r(const char *name, struct hostent *restrict ret,
2459 2703 int getaddrinfo(const char *restrict node, const char *restrict service, int getaddrinfo(const char *restrict node, const char *restrict service,
2460 2704 const struct addrinfo *restrict hints, struct addrinfo **restrict res) const struct addrinfo *restrict hints, struct addrinfo **restrict res)
2461 2705 { {
2706 if (!old_getaddrinfo)
2707 old_getaddrinfo = ninedogs_dlsym("getaddrinfo");
2708
2462 2709 xlog(100, "getaddrinfo(node=%s, service=%s, hints=0x%x)\n", xlog(100, "getaddrinfo(node=%s, service=%s, hints=0x%x)\n",
2463 2710 node, service, hints ? hints : 0); node, service, hints ? hints : 0);
2464 2711
2465 my_trace(__func__, 'c', node, service, hints);
2712 my_trace(__func__, "", 'c', node, service, hints);
2466 2713 int ret = old_getaddrinfo(node, service, hints, res); int ret = old_getaddrinfo(node, service, hints, res);
2467 my_trace(__func__, 'r', node, service, hints, res, ret);
2714 my_trace(__func__, "", 'r', node, service, hints, res, ret);
2468 2715
2469 2716 return ret; return ret;
2470 2717 } }
 
... ... int pthread_create(pthread_t *restrict thread,
2473 2720 const pthread_attr_t *restrict attr, void *(*start_routine)(void *), const pthread_attr_t *restrict attr, void *(*start_routine)(void *),
2474 2721 void *restrict arg) void *restrict arg)
2475 2722 { {
2723 if (!old_pthread_create)
2724 old_pthread_create = ninedogs_dlsym("pthread_create");
2725
2476 2726 //xlog(2, "%s\n", __func__); //xlog(2, "%s\n", __func__);
2477 2727 int ret = old_pthread_create(thread, attr, start_routine, arg); int ret = old_pthread_create(thread, attr, start_routine, arg);
2478 my_trace(__func__, 'R', ret == 0 ? *thread : 0, attr, arg, ret);
2728 my_trace(__func__, "", 'R', ret == 0 ? *thread : 0, attr, arg, ret);
2479 2729
2480 2730 return ret; return ret;
2481 2731 } }
 
... ... int pthread_join(pthread_t thread, void **retval)
2488 2738
2489 2739 //xlog(2, "pthread_join\n"); //xlog(2, "pthread_join\n");
2490 2740 int ret = old_pthread_join(thread, retval); int ret = old_pthread_join(thread, retval);
2491 my_trace(__func__, 'R', thread, ret, ret == 0 ? retval : NULL);
2741 my_trace(__func__, "", 'R', thread, ret, ret == 0 ? retval : NULL);
2492 2742
2493 2743 return ret; return ret;
2494 2744 } }
 
... ... int pthread_attr_init(pthread_attr_t *attr)
2501 2751
2502 2752 xlog(2, "%s\n", __func__); xlog(2, "%s\n", __func__);
2503 2753 int ret = old_pthread_attr_init(attr); int ret = old_pthread_attr_init(attr);
2504 my_trace(__func__, 'R', attr, ret);
2754 my_trace(__func__, "", 'R', attr, ret);
2505 2755
2506 2756 return ret; return ret;
2507 2757 } }
 
... ... int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
2512 2762 if (!old_pthread_attr_setstacksize) if (!old_pthread_attr_setstacksize)
2513 2763 old_pthread_attr_setstacksize = ninedogs_dlsym("pthread_attr_setstacksize"); old_pthread_attr_setstacksize = ninedogs_dlsym("pthread_attr_setstacksize");
2514 2764
2515 xlog(2, "pthread_attr_setstacksize(%p, %zu)\n", attr, stacksize);
2765 xlog(50, "pthread_attr_setstacksize(%p, %zu)\n", attr, stacksize);
2516 2766
2517 2767 int ret = old_pthread_attr_setstacksize(attr, stacksize); int ret = old_pthread_attr_setstacksize(attr, stacksize);
2518 my_trace(__func__, 'R', attr, stacksize, ret);
2768 my_trace(__func__, "", 'R', attr, stacksize, ret);
2519 2769
2520 2770 return ret; return ret;
2521 2771 } }
 
... ... int pthread_setname_np(pthread_t thread, const char *name)
2526 2776 if (!old_pthread_setname_np) if (!old_pthread_setname_np)
2527 2777 old_pthread_setname_np = ninedogs_dlsym("pthread_setname_np"); old_pthread_setname_np = ninedogs_dlsym("pthread_setname_np");
2528 2778
2529 xlog(2, "pthread_setname_np(%lu, %s)\n", thread, name);
2779 xlog(50, "pthread_setname_np(%lu, %s)\n", thread, name);
2530 2780 int ret = old_pthread_setname_np(thread, name); int ret = old_pthread_setname_np(thread, name);
2531 my_trace(__func__, 'R', thread, name, ret);
2781 my_trace(__func__, "", 'R', thread, name, ret);
2532 2782
2533 2783 return ret; return ret;
2534 2784 } }
 
... ... int pthread_setname_np(pthread_t thread, const char *name)
2537 2787 int getsockopt(int sockfd, int level, int optname, void *restrict optval, int getsockopt(int sockfd, int level, int optname, void *restrict optval,
2538 2788 socklen_t *restrict optlen) socklen_t *restrict optlen)
2539 2789 { {
2790 if (!old_getsockopt)
2791 old_getsockopt = ninedogs_dlsym("getsockopt");
2792
2540 2793 xlog(50, "%s(%d, %d, %d, %p, %u)\n", xlog(50, "%s(%d, %d, %d, %p, %u)\n",
2541 2794 __func__, sockfd, level, optname, optval, optlen); __func__, sockfd, level, optname, optval, optlen);
2542 2795
 
... ... int getsockopt(int sockfd, int level, int optname, void *restrict optval,
2560 2813 break; break;
2561 2814 } }
2562 2815
2563 my_trace(__func__, 'R', sockfd, level, optname, optval, *optlen, r);
2816 my_trace(__func__, "", 'R', sockfd, level, optname, optval, *optlen, r);
2564 2817
2565 2818 return r; return r;
2566 2819 } }
2567 2820
2568 2821 int execve(const char *pathname, char *const argv[], char *const envp[]) int execve(const char *pathname, char *const argv[], char *const envp[])
2569 2822 { {
2823 if (!old_execve)
2824 old_execve = ninedogs_dlsym("execve");
2825
2570 2826 xlog(2, "%s(%s, ...)\n", __func__, pathname); xlog(2, "%s(%s, ...)\n", __func__, pathname);
2571 2827
2572 my_trace(__func__, 'c', pathname, argv, envp);
2828 my_trace(__func__, "", 'c', pathname, argv, envp);
2573 2829 int ret = old_execve(pathname, argv, envp); int ret = old_execve(pathname, argv, envp);
2574 my_trace(__func__, 'r', pathname, argv, envp, ret);
2830 my_trace(__func__, "", 'r', pathname, argv, envp, ret);
2575 2831
2576 2832 xlog(2, " ret=%d\n", ret); xlog(2, " ret=%d\n", ret);
2577 2833
 
... ... static int open_common_pre(const char *pathname)
2594 2850 } }
2595 2851
2596 2852 q->type = FD_NODE_DEV_NINEDOGS; q->type = FD_NODE_DEV_NINEDOGS;
2597 xlog(10, "ninedogs special /dev file opened fd=%d\n", ret);
2853 xlog(50, "ninedogs special /dev file opened fd=%d\n", ret);
2598 2854
2599 2855 return ret; return ret;
2600 2856 } }
 
... ... int memfd_create(const char *name, unsigned int flags)
2624 2880 old_memfd_create = ninedogs_dlsym("memfd_create"); old_memfd_create = ninedogs_dlsym("memfd_create");
2625 2881
2626 2882 xlog(100, "%s(%s, 0x%x)\n", __func__, name, flags); xlog(100, "%s(%s, 0x%x)\n", __func__, name, flags);
2627 my_trace(__func__, 'c', name, flags);
2883 my_trace(__func__, "", 'c', name, flags);
2628 2884 int ret = old_memfd_create(name, flags); int ret = old_memfd_create(name, flags);
2629 my_trace(__func__, 'r', name, flags, ret);
2885 my_trace(__func__, "", 'r', name, flags, ret);
2630 2886 open_common_post(FD_NODE_MEMFD, name, flags, 0, ret); open_common_post(FD_NODE_MEMFD, name, flags, 0, ret);
2631 2887 xlog(101, " ret=%d\n", ret); xlog(101, " ret=%d\n", ret);
2632 2888
 
... ... int timerfd_create(int clockid, int flags)
2640 2896 old_timerfd_create = ninedogs_dlsym("timerfd_create"); old_timerfd_create = ninedogs_dlsym("timerfd_create");
2641 2897
2642 2898 xlog(100, "%s(%d, 0x%x)\n", __func__, clockid, flags); xlog(100, "%s(%d, 0x%x)\n", __func__, clockid, flags);
2643 my_trace(__func__, 'c', clockid, flags);
2899 my_trace(__func__, "", 'c', clockid, flags);
2644 2900 int ret = old_timerfd_create(clockid, flags); int ret = old_timerfd_create(clockid, flags);
2645 my_trace(__func__, 'r', clockid, flags, ret);
2901 my_trace(__func__, "", 'r', clockid, flags, ret);
2646 2902 open_common_post(FD_NODE_TIMERFD, "", flags, clockid, ret); open_common_post(FD_NODE_TIMERFD, "", flags, clockid, ret);
2647 2903 xlog(101, " ret=%d\n", ret); xlog(101, " ret=%d\n", ret);
2648 2904
 
... ... int open(const char *pathname, int flags, ...)
2654 2910 mode_t mode = 0; mode_t mode = 0;
2655 2911 va_list va; va_list va;
2656 2912
2913 // We are getting the addresss with getenv
2914 if (!old_open)
2915 ninedogs_init();
2916
2657 2917 if (__OPEN_NEEDS_MODE(flags)) { if (__OPEN_NEEDS_MODE(flags)) {
2658 2918 va_start(va, flags); va_start(va, flags);
2659 2919 mode = va_arg(va, mode_t); mode = va_arg(va, mode_t);
 
... ... int open(const char *pathname, int flags, ...)
2665 2925 return ret; return ret;
2666 2926
2667 2927 xlog(100, "%s(%s, 0x%x, 0x%x)\n", __func__, pathname, flags, mode); xlog(100, "%s(%s, 0x%x, 0x%x)\n", __func__, pathname, flags, mode);
2668 my_trace(__func__, 'c', pathname, flags, mode);
2928 my_trace(__func__, "", 'c', pathname, flags, mode);
2669 2929 ret = old_open(pathname, flags, mode); ret = old_open(pathname, flags, mode);
2670 my_trace(__func__, 'r', pathname, flags, mode, ret);
2930 my_trace(__func__, "", 'r', pathname, flags, mode, ret);
2671 2931 open_common_post(FD_NODE_FILE, pathname, flags, mode, ret); open_common_post(FD_NODE_FILE, pathname, flags, mode, ret);
2672 2932 xlog(101, " ret=%d\n", ret); xlog(101, " ret=%d\n", ret);
2673 2933
 
... ... int open(const char *pathname, int flags, ...)
2676 2936
2677 2937 int open64(const char *pathname, int flags, ...) int open64(const char *pathname, int flags, ...)
2678 2938 { {
2939 if (!old_open64)
2940 old_open64 = ninedogs_dlsym("open64");
2941
2679 2942 mode_t mode = 0; mode_t mode = 0;
2680 2943 va_list va; va_list va;
2681 2944
 
... ... int open64(const char *pathname, int flags, ...)
2690 2953 return ret; return ret;
2691 2954
2692 2955 xlog(100, "%s(%s, %d, %d)\n", __func__, pathname, flags, mode); xlog(100, "%s(%s, %d, %d)\n", __func__, pathname, flags, mode);
2693 my_trace(__func__, 'c', pathname, flags, mode);
2956 my_trace(__func__, "", 'c', pathname, flags, mode);
2694 2957 ret = old_open64(pathname, flags, mode); ret = old_open64(pathname, flags, mode);
2695 my_trace(__func__, 'r', pathname, flags, mode, ret);
2958 my_trace(__func__, "", 'r', pathname, flags, mode, ret);
2696 2959 open_common_post(FD_NODE_FILE, pathname, flags, mode, ret); open_common_post(FD_NODE_FILE, pathname, flags, mode, ret);
2697 2960 xlog(101, " ret=%d\n", ret); xlog(101, " ret=%d\n", ret);
2698 2961
 
... ... int open64(const char *pathname, int flags, ...)
2701 2964
2702 2965 int openat(int dirfd, const char *pathname, int flags, ...) int openat(int dirfd, const char *pathname, int flags, ...)
2703 2966 { {
2967 if (!old_openat)
2968 old_openat = ninedogs_dlsym("openat");
2969
2704 2970 mode_t mode = 0; mode_t mode = 0;
2705 2971 va_list va; va_list va;
2706 2972
 
... ... int openat(int dirfd, const char *pathname, int flags, ...)
2715 2981 return ret; return ret;
2716 2982
2717 2983 xlog(100, "%s(%d, %s, %d, %d)\n", __func__, dirfd, pathname, flags, mode); xlog(100, "%s(%d, %s, %d, %d)\n", __func__, dirfd, pathname, flags, mode);
2718 my_trace(__func__, 'c', dirfd, pathname, flags, mode);
2984 my_trace(__func__, "", 'c', dirfd, pathname, flags, mode);
2719 2985 ret = old_openat(dirfd, pathname, flags, mode); ret = old_openat(dirfd, pathname, flags, mode);
2720 my_trace(__func__, 'r', dirfd, pathname, flags, mode, ret);
2986 my_trace(__func__, "", 'r', dirfd, pathname, flags, mode, ret);
2721 2987 open_common_post(FD_NODE_FILE, pathname, flags, mode, ret); open_common_post(FD_NODE_FILE, pathname, flags, mode, ret);
2722 2988 xlog(101, " ret=%d\n", ret); xlog(101, " ret=%d\n", ret);
2723 2989
 
... ... int openat(int dirfd, const char *pathname, int flags, ...)
2729 2995 static int my_stat(const char *restrict pathname, struct stat *restrict statbuf) static int my_stat(const char *restrict pathname, struct stat *restrict statbuf)
2730 2996 { {
2731 2997 xlog(20, "%s(%s, %p)\n", __func__, pathname, statbuf); xlog(20, "%s(%s, %p)\n", __func__, pathname, statbuf);
2732 my_trace(__func__, 'c', pathname, statbuf);
2998 my_trace(__func__, "", 'c', pathname, statbuf);
2733 2999 int ret = old_stat(pathname, statbuf); int ret = old_stat(pathname, statbuf);
2734 my_trace(__func__, 'r', pathname, statbuf, ret);
3000 my_trace(__func__, "", 'r', pathname, statbuf, ret);
2735 3001 xlog(25, " ret=%d\n", ret); xlog(25, " ret=%d\n", ret);
2736 3002
2737 3003 return ret; return ret;
 
... ... void *dlopen(const char *filename, int flags)
2767 3033 if (!old_dlopen) if (!old_dlopen)
2768 3034 return NULL; return NULL;
2769 3035
2770 my_trace(__func__, 'c', filename, flags);
3036 my_trace(__func__, "", 'c', filename, flags);
2771 3037 void *ret = old_dlopen(filename, flags); void *ret = old_dlopen(filename, flags);
2772 my_trace(__func__, 'r', filename, flags, ret);
3038 my_trace(__func__, "", 'r', filename, flags, ret);
2773 3039 if (filename && ret) { if (filename && ret) {
2774 3040 // TODO: should I add only 'flags=GLOBAL' entries? // TODO: should I add only 'flags=GLOBAL' entries?
2775 3041 unsigned found = 0, first_free = DLOPEN_MAX_ENTRIES; unsigned found = 0, first_free = DLOPEN_MAX_ENTRIES;
 
... ... int dlclose(void *h)
2826 3092 } }
2827 3093 } }
2828 3094
2829 my_trace(__func__, 'R', h, ret);
3095 my_trace(__func__, "", 'R', h, ret);
2830 3096
2831 3097 return ret; return ret;
2832 3098 } }
 
... ... int dlclose(void *h)
2836 3102 */ */
2837 3103 void *ninedogs_dlsym(const char *sym) void *ninedogs_dlsym(const char *sym)
2838 3104 { {
3105 // We are getting the addresss with getenv
3106 ninedogs_init();
3107
2839 3108 xlog(100, "%s: sym [%s]\n", __func__, sym); xlog(100, "%s: sym [%s]\n", __func__, sym);
2840 3109
2841 3110 void *ret = old_dlsym(RTLD_NEXT, sym); void *ret = old_dlsym(RTLD_NEXT, sym);
 
... ... void *ninedogs_dlsym(const char *sym)
2859 3128
2860 3129 ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) ssize_t getrandom(void *buf, size_t buflen, unsigned int flags)
2861 3130 { {
2862 // Seems we cannot use ninedogs_dlsym here!
3131 // We are getting the addresss with getenv
2863 3132 if (!old_getrandom) if (!old_getrandom)
2864 3133 ninedogs_init(); ninedogs_init();
2865 3134
2866 3135 xlog(100, "%s(%p, %zu, 0x%x) [old_getrandom=%p]\n", xlog(100, "%s(%p, %zu, 0x%x) [old_getrandom=%p]\n",
2867 3136 __func__, buf, buflen, flags, old_getrandom); __func__, buf, buflen, flags, old_getrandom);
2868 3137
2869 my_trace(__func__, 'c', buflen, flags);
3138 my_trace(__func__, "", 'c', buflen, flags);
2870 3139 ssize_t ret = old_getrandom(buf, buflen, flags); ssize_t ret = old_getrandom(buf, buflen, flags);
2871 my_trace(__func__, 'r', buf, buflen, flags, ret);
3140 my_trace(__func__, "", 'r', buf, buflen, flags, ret);
2872 3141
2873 3142 return ret; return ret;
2874 3143 } }
 
... ... int nanosleep(const struct timespec *req, struct timespec *rem)
2881 3150 xlog(100, "%s(%ld.%09ld, %p)\n", xlog(100, "%s(%ld.%09ld, %p)\n",
2882 3151 __func__, req->tv_sec, req->tv_nsec, rem); __func__, req->tv_sec, req->tv_nsec, rem);
2883 3152
2884 my_trace(__func__, 'c', req);
3153 my_trace(__func__, "", 'c', req);
2885 3154 int ret = old_nanosleep(req, rem); int ret = old_nanosleep(req, rem);
2886 my_trace(__func__, 'r', req, rem, ret);
3155 my_trace(__func__, "", 'r', req, rem, ret);
2887 3156
2888 3157 return ret; return ret;
2889 3158 } }
 
... ... int unlink(const char *pathname)
2895 3164
2896 3165 xlog(100, "%s(%s)\n", __func__, pathname); xlog(100, "%s(%s)\n", __func__, pathname);
2897 3166
2898 my_trace(__func__, 'c', pathname);
3167 my_trace(__func__, "", 'c', pathname);
2899 3168 int ret = old_unlink(pathname); int ret = old_unlink(pathname);
2900 my_trace(__func__, 'r', pathname, ret);
3169 my_trace(__func__, "", 'r', pathname, ret);
2901 3170
2902 3171 return ret; return ret;
2903 3172 } }
 
... ... int listen(int sock, int backlog)
2910 3179 xlog(100, "%s(%d, %d)\n", __func__, sock, backlog); xlog(100, "%s(%d, %d)\n", __func__, sock, backlog);
2911 3180
2912 3181 int ret = old_listen(sock, backlog); int ret = old_listen(sock, backlog);
2913 my_trace(__func__, 'R', sock, backlog, ret);
3182 my_trace(__func__, "", 'R', sock, backlog, ret);
2914 3183
2915 3184 struct fd_node *q = fd_search(sock); struct fd_node *q = fd_search(sock);
2916 3185 if (q) if (q)
 
... ... void syslog(int priority, const char *format, ...)
2934 3203 va_end(va); va_end(va);
2935 3204
2936 3205 old_syslog(priority, buf); old_syslog(priority, buf);
2937 my_trace(__func__, 'R', priority, buf);
3206 my_trace(__func__, "", 'R', priority, buf);
2938 3207 } }
2939 3208
2940 3209 int fstatat(int dirfd, const char *restrict pathname, int fstatat(int dirfd, const char *restrict pathname,
 
... ... int fstatat(int dirfd, const char *restrict pathname,
2945 3214
2946 3215 xlog(100, "%s(%d, %s, %p, 0x%x)\n", __func__, dirfd, pathname, statbuf, flags); xlog(100, "%s(%d, %s, %p, 0x%x)\n", __func__, dirfd, pathname, statbuf, flags);
2947 3216
2948 my_trace(__func__, 'c', dirfd, pathname, flags);
3217 my_trace(__func__, "", 'c', dirfd, pathname, flags);
2949 3218 int ret = old_fstatat(dirfd, pathname, statbuf, flags); int ret = old_fstatat(dirfd, pathname, statbuf, flags);
2950 my_trace(__func__, 'r', dirfd, pathname, statbuf, flags, ret);
3219 my_trace(__func__, "", 'r', dirfd, pathname, statbuf, flags, ret);
2951 3220
2952 3221 return ret; return ret;
2953 3222 } }
 
... ... int fstatat64(int dirfd, const char *restrict pathname,
2961 3230 xlog(100, "%s(%d, %s, %p, 0x%x)\n", xlog(100, "%s(%d, %s, %p, 0x%x)\n",
2962 3231 __func__, dirfd, pathname, statbuf, flags); __func__, dirfd, pathname, statbuf, flags);
2963 3232
2964 my_trace(__func__, 'c', dirfd, pathname, flags);
3233 my_trace(__func__, "", 'c', dirfd, pathname, flags);
2965 3234 int ret = old_fstatat64(dirfd, pathname, statbuf, flags); int ret = old_fstatat64(dirfd, pathname, statbuf, flags);
2966 my_trace(__func__, 'r', dirfd, pathname, statbuf, flags, ret);
3235 my_trace(__func__, "", 'r', dirfd, pathname, statbuf, flags, ret);
2967 3236
2968 3237 return ret; return ret;
2969 3238 } }
2970 3239
2971 3240 int stat(const char *restrict pathname, struct stat *restrict statbuf) int stat(const char *restrict pathname, struct stat *restrict statbuf)
2972 3241 { {
3242 // We are getting the addresss with getenv
2973 3243 if (!old_stat) if (!old_stat)
2974 old_stat = ninedogs_dlsym("stat");
3244 ninedogs_init();
2975 3245
2976 3246 xlog(100, "%s(%s, %p)\n", __func__, pathname, statbuf); xlog(100, "%s(%s, %p)\n", __func__, pathname, statbuf);
2977 3247
2978 my_trace(__func__, 'c', pathname);
3248 my_trace(__func__, "", 'c', pathname);
2979 3249 int ret = old_stat(pathname, statbuf); int ret = old_stat(pathname, statbuf);
2980 my_trace(__func__, 'r', pathname, statbuf, ret);
3250 my_trace(__func__, "", 'r', pathname, statbuf, ret);
2981 3251
2982 3252 return ret; return ret;
2983 3253 } }
 
... ... int fork(void)
2990 3260 xlog(100, "%s()\n", __func__); xlog(100, "%s()\n", __func__);
2991 3261
2992 3262 int ret = old_fork(); int ret = old_fork();
2993 my_trace(__func__, 'R', ret);
3263 my_trace(__func__, "", 'R', ret);
3264
3265 return ret;
3266 }
3267
3268 int shm_open(const char *name, int oflag, mode_t mode)
3269 {
3270 if (!old_shm_open)
3271 old_shm_open = ninedogs_dlsym("shm_open");
3272
3273 my_trace(__func__, "", 'r', name, oflag, mode);
3274 int ret = old_shm_open(name, oflag, mode);
3275 my_trace(__func__, "", 'r', name, oflag, mode, ret);
2994 3276
2995 3277 return ret; return ret;
2996 3278 } }
 
... ... int fsync(int fd)
3002 3284 old_fsync = ninedogs_dlsym("fsync"); old_fsync = ninedogs_dlsym("fsync");
3003 3285
3004 3286 xlog(100, "%s(%d)\n", __func__, fd); xlog(100, "%s(%d)\n", __func__, fd);
3005 my_trace(__func__, 'c', fd);
3287 my_trace(__func__, "", 'c', fd);
3006 3288 int ret = old_fsync(fd); int ret = old_fsync(fd);
3007 my_trace(__func__, 'r', fd, ret);
3289 my_trace(__func__, "", 'r', fd, ret);
3008 3290
3009 3291 return ret; return ret;
3010 3292 } }
 
... ... int fdatasync(int fd)
3016 3298 old_fdatasync = ninedogs_dlsym("fdatasync"); old_fdatasync = ninedogs_dlsym("fdatasync");
3017 3299
3018 3300 xlog(100, "%s(%d)\n", __func__, fd); xlog(100, "%s(%d)\n", __func__, fd);
3019 my_trace(__func__, 'c', fd);
3301 my_trace(__func__, "", 'c', fd);
3020 3302 int ret = old_fdatasync(fd); int ret = old_fdatasync(fd);
3021 my_trace(__func__, 'r', fd, ret);
3303 my_trace(__func__, "", 'r', fd, ret);
3022 3304
3023 3305 return ret; return ret;
3024 3306 } }
 
... ... ssize_t pread(int fd, void *buf, size_t count, off_t offset)
3030 3312 old_pread = ninedogs_dlsym("pread"); old_pread = ninedogs_dlsym("pread");
3031 3313
3032 3314 xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset); xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset);
3033 my_trace(__func__, 'c', fd, count, offset);
3315 my_trace(__func__, "", 'c', fd, count, offset);
3034 3316 ssize_t ret = old_pread(fd, buf, count, offset); ssize_t ret = old_pread(fd, buf, count, offset);
3035 my_trace(__func__, 'r', fd, buf, count, offset, ret);
3317 my_trace(__func__, "", 'r', fd, buf, count, offset, ret);
3036 3318
3037 3319 return ret; return ret;
3038 3320 } }
 
... ... ssize_t pread64(int fd, void *buf, size_t count, off_t offset)
3044 3326 old_pread64 = ninedogs_dlsym("pread64"); old_pread64 = ninedogs_dlsym("pread64");
3045 3327
3046 3328 xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset); xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset);
3047 my_trace(__func__, 'c', fd, count, offset);
3329 my_trace(__func__, "", 'c', fd, count, offset);
3048 3330 ssize_t ret = old_pread64(fd, buf, count, offset); ssize_t ret = old_pread64(fd, buf, count, offset);
3049 my_trace(__func__, 'r', fd, buf, count, offset, ret);
3331 my_trace(__func__, "", 'r', fd, buf, count, offset, ret);
3050 3332
3051 3333 return ret; return ret;
3052 3334 } }
 
... ... ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset)
3058 3340 old_pwrite = ninedogs_dlsym("pwrite"); old_pwrite = ninedogs_dlsym("pwrite");
3059 3341
3060 3342 xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset); xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset);
3061 my_trace(__func__, 'c', fd, buf, count, offset);
3343 my_trace(__func__, "", 'c', fd, buf, count, offset);
3062 3344 ssize_t ret = old_pwrite(fd, buf, count, offset); ssize_t ret = old_pwrite(fd, buf, count, offset);
3063 my_trace(__func__, 'r', fd, count, offset, ret);
3345 my_trace(__func__, "", 'r', fd, count, offset, ret);
3064 3346
3065 3347 return ret; return ret;
3066 3348 } }
 
... ... ssize_t pwrite64(int fd, const void *buf, size_t count, off_t offset)
3072 3354 old_pwrite64 = ninedogs_dlsym("pwrite64"); old_pwrite64 = ninedogs_dlsym("pwrite64");
3073 3355
3074 3356 xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset); xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset);
3075 my_trace(__func__, 'c', fd, buf, count, offset);
3357 my_trace(__func__, "", 'c', fd, buf, count, offset);
3076 3358 ssize_t ret = old_pwrite64(fd, buf, count, offset); ssize_t ret = old_pwrite64(fd, buf, count, offset);
3077 my_trace(__func__, 'r', fd, count, offset, ret);
3359 my_trace(__func__, "", 'r', fd, count, offset, ret);
3360
3361 return ret;
3362 }
3363
3364 int ftruncate(int fd, off_t length)
3365 {
3366 static int (*old_ftruncate)(int fd, off_t length) = NULL;
3367
3368 if (!old_ftruncate)
3369 old_ftruncate = ninedogs_dlsym("ftruncate");
3370
3371 xlog(100, "%s(fd=%d, %zu)\n", __func__, fd, length);
3372 my_trace(__func__, "", 'c', fd, length);
3373 int ret = old_ftruncate(fd, length);
3374 my_trace(__func__, "", 'r', fd, length, ret);
3375
3376 if (ret == 0) {
3377 struct fd_node *q = fd_search(fd);
3378 if (q && (q->type == FD_NODE_MEMFD)) {
3379 q->file.max = length;
3380 }
3381 }
3078 3382
3079 3383 return ret; return ret;
3080 3384 } }
 
... ... int sqlite3_open(const char *filename, void **ppdb)
3088 3392
3089 3393 xlog(100, "%s(%s)\n", __func__, filename); xlog(100, "%s(%s)\n", __func__, filename);
3090 3394
3091 my_trace(__func__, 'c', filename);
3395 my_trace(__func__, "", 'c', filename);
3092 3396 int ret = old_sqlite3_open(filename, ppdb); int ret = old_sqlite3_open(filename, ppdb);
3093 my_trace(__func__, 'r', filename, ppdb, ret);
3397 my_trace(__func__, "", 'r', filename, ppdb, ret);
3094 3398
3095 3399 return ret; return ret;
3096 3400 } }
 
... ... int sqlite3_open_v2(const char *filename, void **ppdb, int flags, const char *vf
3105 3409 xlog(100, "%s(%s, ppdb, 0x%x, %s)\n", xlog(100, "%s(%s, ppdb, 0x%x, %s)\n",
3106 3410 __func__, filename, flags, vfs); __func__, filename, flags, vfs);
3107 3411
3108 my_trace(__func__, 'c', filename, flags, vfs);
3412 my_trace(__func__, "", 'c', filename, flags, vfs);
3109 3413 int ret = old_sqlite3_open_v2(filename, ppdb, flags, vfs); int ret = old_sqlite3_open_v2(filename, ppdb, flags, vfs);
3110 my_trace(__func__, 'r', filename, ppdb ? *ppdb : NULL, flags, vfs, ret);
3414 my_trace(__func__, "", 'r', filename, ppdb ? *ppdb : NULL, flags, vfs, ret);
3111 3415
3112 3416 return ret; return ret;
3113 3417 } }
 
... ... int sqlite3_open16(const char *filename, void **ppdb)
3122 3426 xlog(100, "%s('%s', ppdb)\n", xlog(100, "%s('%s', ppdb)\n",
3123 3427 __func__, filename); __func__, filename);
3124 3428
3125 my_trace(__func__, 'c', filename);
3429 my_trace(__func__, "", 'c', filename);
3126 3430 int ret = old_sqlite3_open16(filename, ppdb); int ret = old_sqlite3_open16(filename, ppdb);
3127 my_trace(__func__, 'r', filename, ppdb, ret);
3431 my_trace(__func__, "", 'r', filename, ppdb, ret);
3128 3432
3129 3433 return ret; return ret;
3130 3434 } }
 
... ... int sqlite3_exec(void *h, const char *sql,
3140 3444 if (!old_sqlite3_exec) if (!old_sqlite3_exec)
3141 3445 old_sqlite3_exec = ninedogs_dlsym("sqlite3_exec"); old_sqlite3_exec = ninedogs_dlsym("sqlite3_exec");
3142 3446
3143 //my_trace(__func__, 'c', h, sql, callback, callback_arg);
3447 //my_trace(__func__, "", 'c', h, sql, callback, callback_arg);
3144 3448 int ret = old_sqlite3_exec(h, sql, callback, callback_arg, errmsg); int ret = old_sqlite3_exec(h, sql, callback, callback_arg, errmsg);
3145 3449 xlog(100, "%s(h=%p, sql='%s', cb=%p, cba=%p, err='%s')\n", xlog(100, "%s(h=%p, sql='%s', cb=%p, cba=%p, err='%s')\n",
3146 3450 __func__, h, sql, callback, callback_arg, errmsg ? *errmsg : "?"); __func__, h, sql, callback, callback_arg, errmsg ? *errmsg : "?");
3147 //my_trace(__func__, 'r', h, sql, callback, callback_arg, errmsg);
3451 //my_trace(__func__, "", 'r', h, sql, callback, callback_arg, errmsg);
3148 3452
3149 3453 return ret; return ret;
3150 3454 } }
 
... ... int sqlite3_prepare_v2(void *h, const char *sql, int nByte, void **stmt, const c
3156 3460 if (!old_sqlite3_prepare_v2) if (!old_sqlite3_prepare_v2)
3157 3461 old_sqlite3_prepare_v2 = ninedogs_dlsym("sqlite3_prepare_v2"); old_sqlite3_prepare_v2 = ninedogs_dlsym("sqlite3_prepare_v2");
3158 3462
3159 my_trace(__func__, 'c', h, sql, nByte);
3463 my_trace(__func__, "", 'c', h, sql, nByte);
3160 3464 int ret = old_sqlite3_prepare_v2(h, sql, nByte, stmt, tail); int ret = old_sqlite3_prepare_v2(h, sql, nByte, stmt, tail);
3161 3465 xlog(100, "%s(h=%p, sql='%s', nByte=%d, *stmt=%p, tail=[%s]) = %d\n", xlog(100, "%s(h=%p, sql='%s', nByte=%d, *stmt=%p, tail=[%s]) = %d\n",
3162 3466 __func__, h, sql, nByte, stmt ? *stmt : NULL, tail ? *tail : "", ret); __func__, h, sql, nByte, stmt ? *stmt : NULL, tail ? *tail : "", ret);
3163 my_trace(__func__, 'r', h, sql, nByte, stmt ? *stmt : NULL, ret);
3467 my_trace(__func__, "", 'r', h, sql, nByte, stmt ? *stmt : NULL, ret);
3164 3468 // TODO: do we need 'tail'? // TODO: do we need 'tail'?
3165 3469
3166 3470 return ret; return ret;
 
... ... int sqlite3_finalize(void *pstmt)
3175 3479
3176 3480 int ret = old_sqlite3_finalize(pstmt); int ret = old_sqlite3_finalize(pstmt);
3177 3481 xlog(100, "%s(pstmt=%p) = %d\n", __func__, pstmt); xlog(100, "%s(pstmt=%p) = %d\n", __func__, pstmt);
3178 my_trace(__func__, 'R', pstmt, ret);
3482 my_trace(__func__, "", 'R', pstmt, ret);
3179 3483
3180 3484 return ret; return ret;
3181 3485 } }
 
... ... int sqlite3_step(void *stmt)
3187 3491 if (!old_sqlite3_step) if (!old_sqlite3_step)
3188 3492 old_sqlite3_step = ninedogs_dlsym("sqlite3_step"); old_sqlite3_step = ninedogs_dlsym("sqlite3_step");
3189 3493
3190 my_trace(__func__, 'c', stmt);
3494 my_trace(__func__, "", 'c', stmt);
3191 3495 int ret = old_sqlite3_step(stmt); int ret = old_sqlite3_step(stmt);
3192 3496 xlog(100, "%s(stmt=%p) = %d\n", __func__, stmt, ret); xlog(100, "%s(stmt=%p) = %d\n", __func__, stmt, ret);
3193 my_trace(__func__, 'r', stmt, ret);
3497 my_trace(__func__, "", 'r', stmt, ret);
3194 3498
3195 3499 return ret; return ret;
3196 3500 } }
 
... ... int sqlite3_bind_double(void *stmt, int index, double value)
3204 3508
3205 3509 int ret = old_sqlite3_bind_double(stmt, index, value); int ret = old_sqlite3_bind_double(stmt, index, value);
3206 3510 xlog(100, "%s(stmt=%p, %d, %f) = %d\n", __func__, stmt, index, value, ret); xlog(100, "%s(stmt=%p, %d, %f) = %d\n", __func__, stmt, index, value, ret);
3207 my_trace(__func__, 'R', stmt, index, value, ret);
3511 my_trace(__func__, "", 'R', stmt, index, value, ret);
3208 3512
3209 3513 return ret; return ret;
3210 3514 } }
 
... ... int sqlite3_bind_int(void *stmt, int index, int value)
3218 3522
3219 3523 int ret = old_sqlite3_bind_int(stmt, index, value); int ret = old_sqlite3_bind_int(stmt, index, value);
3220 3524 xlog(100, "%s(stmt=%p, %d, %d) = %d\n", __func__, stmt, index, value, ret); xlog(100, "%s(stmt=%p, %d, %d) = %d\n", __func__, stmt, index, value, ret);
3221 my_trace(__func__, 'R', stmt, index, value, ret);
3525 my_trace(__func__, "", 'R', stmt, index, value, ret);
3222 3526
3223 3527 return ret; return ret;
3224 3528 } }
 
... ... int sqlite3_bind_int64(void *stmt, int index, uint64_t value)
3232 3536
3233 3537 int ret = old_sqlite3_bind_int64(stmt, index, value); int ret = old_sqlite3_bind_int64(stmt, index, value);
3234 3538 xlog(100, "%s(stmt=%p, %d, %ld) = %d\n", __func__, stmt, index, value, ret); xlog(100, "%s(stmt=%p, %d, %ld) = %d\n", __func__, stmt, index, value, ret);
3235 my_trace(__func__, 'R', stmt, index, value, ret);
3539 my_trace(__func__, "", 'R', stmt, index, value, ret);
3236 3540
3237 3541 return ret; return ret;
3238 3542 } }
 
... ... int sqlite3_bind_text(void *stmt, int index, const char *value, int len, void *f
3246 3550
3247 3551 int ret = old_sqlite3_bind_text(stmt, index, value, len, func); int ret = old_sqlite3_bind_text(stmt, index, value, len, func);
3248 3552 xlog(100, "%s(stmt=%p, %d, '%s', len=%d) = %d\n", __func__, stmt, index, value, len, ret); xlog(100, "%s(stmt=%p, %d, '%s', len=%d) = %d\n", __func__, stmt, index, value, len, ret);
3249 my_trace(__func__, 'R', stmt, index, value, len, ret);
3553 my_trace(__func__, "", 'R', stmt, index, value, len, ret);
3250 3554
3251 3555 return ret; return ret;
3252 3556 } }
File agent/ninedogs.h changed (mode: 100644) (index 58b0edd..f692475)
1 1 void ninedogs_fini(void); void ninedogs_fini(void);
2 2 void ninedogs_init(void); void ninedogs_init(void);
3 void my_trace(const char *func, const char type, ...);
3 void my_trace(const char *func, const char *tf, const char type, ...);
4 4 void *ninedogs_dlsym(const char *sym); void *ninedogs_dlsym(const char *sym);
5 5
File agent/php-core.c added (mode: 100644) (index 0000000..a9c8174)
1 /*
2 * Description: Monitoring application
3 * Author: Catalin(ux) M. BOIE
4 * E-mail: catab at embedromix dot ro
5 * Web: https://rocketgit.com/user/catalinux/ninedogs
6 */
7
8 #include <signal.h>
9 #include <pthread.h>
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <syslog.h>
14 #include <dlfcn.h>
15 #include <fcntl.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <sys/time.h>
22 #include <time.h>
23 #include <errno.h>
24 #include <dirent.h>
25 #include <asm/unistd.h>
26 #include <fcntl.h>
27 #include <sys/socket.h>
28 #include <arpa/inet.h>
29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
31 #include <poll.h>
32 #include <netdb.h>
33 #include <ctype.h>
34
35 #include "php-core.h"
36 #include "ids.h"
37 #include "tools.h"
38 #include "ctools.h"
39
40 char *php_get_value(const struct zval *z)
41 {
42 static char ret[4096];
43 const struct zval *next;
44
45 if (!z)
46 return "NULL";
47
48 switch (z->u1.v.type) {
49 case 0: return "";
50 case 1: return "";
51 case 2: return "";
52 case 3: return "";
53 case 4: snprintf(ret, sizeof(ret), "%ld", z->value.lval); return ret;
54 case 5: snprintf(ret, sizeof(ret), "%f", z->value.dval); return ret;
55 case 6: {
56 struct zend_string *zs = z->value.str;
57 return zs->val; }
58 case 8:
59 snprintf(ret, sizeof(ret), "%p", z->value.p); return ret;
60 case 9:
61 snprintf(ret, sizeof(ret), "%p", z->value.p); return ret;
62 case 10:
63 next = &z->value.ref->val;
64 return php_get_value(next);
65 case 12:
66 next = z->value.zv;
67 return php_get_value(next);
68 default:
69 snprintf(ret, sizeof(ret), "?%hhu: %p",
70 z->u1.v.type, z->value.str); return ret;
71 }
72 }
73
74 char *php_get_type(const struct zval *z)
75 {
76 static char s[8];
77
78 if (!z)
79 return "NULL";
80
81 switch (z->u1.v.type) {
82 case 0: return "undef";
83 case 1: return "null";
84 case 2: return "false";
85 case 3: return "true";
86 case 4: return "long";
87 case 5: return "double";
88 case 6: return "string";
89 case 7: return "array";
90 case 8: return "object";
91 case 9: return "resource";
92 case 10: return "ref";
93 case 12: return "indirect";
94 default: sprintf(s, "?%hhu", z->u1.v.type); return s;
95 }
96 }
97
98 void php_zval_dump_buf(char *buf, const size_t size,
99 const char *prefix, const struct zval *z)
100 {
101 if (!z) {
102 snprintf(buf, size, "zval is null");
103 return;
104 }
105
106 snprintf(buf, size, "%s%p: type=%s value=[%s] type_flags=%hhu extra=%hu num_args=%u",
107 prefix, z, php_get_type(z), php_get_value(z),
108 z->u1.v.type_flags,
109 z->u1.v.u.extra, z->u2.num_args);
110 }
111
112 void php_zval_dump(const char *prefix, const struct zval *z)
113 {
114 char s[4096];
115
116 php_zval_dump_buf(s, sizeof(s), prefix, z);
117 xlog(100, "%s\n", s);
118 }
119
120 static void php_zed_dump(const char *prefix, struct zend_execute_data *p)
121 {
122 unsigned int num_args, s, i;
123 struct zval *z;
124 char x[64];
125
126 if (!p) {
127 xlog(100, "%szed is null!\n", prefix);
128 return;
129 }
130
131 num_args = p->This.u2.num_args;
132 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
133 dump(100, "zed", p, sizeof(struct zval) * (s + num_args));
134
135 xlog(100, "%szed: p=%p num_args=%hu return_value=%p\n",
136 prefix, p, num_args, p->return_value);
137 //php_zval_dump(prefix, p->return_value);
138 snprintf(x, sizeof(x), "%s This: ", prefix);
139 php_zval_dump(x, &p->This);
140
141 for (i = 0; i < num_args; i++) {
142 char zs[1024];
143
144 z = (struct zval *) p + s; s++;
145 php_zval_dump_buf(zs, sizeof(zs), "", z);
146 xlog(100, "%s para %u: %s\n", prefix, i, zs);
147 }
148 }
149
150 // TODO this is really not related to parameters - rename it
151 // this is obsolete. Use 'zend_to_binary' - not so sure: his is to fill nd_params_array,
152 // zend_to_binary is to binary pack an array.
153 void zend_array_to_params_array(struct nd_params_array *p, struct zend_array *za)
154 {
155 unsigned int i = 0;
156
157 xlog(100, " %s: nTableMask=0x%x nNumUsed=%u nNumOfElements=%u nTableSize=%u"
158 " nInternalPointer=%u flags=0x%x[%s]\n",
159 __func__,
160 za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize,
161 za->nInternalPointer, za->u.flags, za->u.flags & 4 ? "packed" : "");
162
163 struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed;
164 for (; bs != be; bs++) {
165 struct zval *_z = &bs->val;
166
167 if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT
168 _z = _z->value.zv;
169
170 if (_z->u1.v.type == 0 /*IS_UNDEF*/) {
171 xlog(101, " para h=%lu: type undef\n", bs->h);
172 continue;
173 }
174
175 if (_z->u1.v.type == 10) { // REFERENCE
176 xlog(101, " is a reference!\n");
177 _z = &_z->value.ref->val;
178 }
179
180 struct zend_string *zs = bs->key;
181 xlog(101, " para: bs=%p h=%lu key=[%p] type %s: val: %s\n",
182 bs, bs->h, zs, php_get_type(_z), php_get_value(_z));
183
184 p->list[i].bind_way = ND_PARAMS_BIND_WAY_NONE;
185 p->list[i].bind_type = ND_PARAMS_BIND_TYPE_NONE;
186 p->list[i].pointer = 0; // TODO: we may need to revisit this.
187
188 if (_z->u1.v.type == 1) {
189 p->list[i].type = ND_TYPE_NULL;
190 } else if (_z->u1.v.type == 2) {
191 p->list[i].type = ND_TYPE_STRING;
192 p->list[i].str = "false";
193 p->list[i].length = 5;
194 } else if (_z->u1.v.type == 3) {
195 p->list[i].type = ND_TYPE_STRING;
196 p->list[i].str = "true";
197 p->list[i].length = 4;
198 } else if (_z->u1.v.type == 4) {
199 p->list[i].type = ND_TYPE_LONG;
200 p->list[i].l = _z->value.lval;
201 } else if (_z->u1.v.type == 5) {
202 p->list[i].type = ND_TYPE_DOUBLE;
203 p->list[i].d = _z->value.dval;
204 } else if (_z->u1.v.type == 6) {
205 p->list[i].type = ND_TYPE_STRING;
206 struct zend_string *zs = _z->value.str;
207 p->list[i].str = zs->val;
208 p->list[i].length = zs->len;
209 } else {
210 p->list[i].type = ND_TYPE_NULL;
211 xlog(1, " %s: I do not how to encode %d type! Encode as NULL\n",
212 __func__, _z->u1.v.type);
213 }
214
215 i++;
216 if (i == ND_PARAMS_MAX)
217 break;
218 }
219 }
220
221 static unsigned int zend_simple_to_binary(unsigned char *out,
222 const size_t out_size, struct zval *z)
223 {
224 unsigned int off = 0;
225 uint16_t u16;
226 uint64_t u64;
227
228 if (off + 1 + 8 > out_size) // 1+8 for a long
229 return 0;
230
231 if (z->u1.v.type == 1) {
232 out[off++] = ND_TYPE_NULL;
233 } else if (z->u1.v.type == 2) {
234 out[off++] = ND_TYPE_FALSE;
235 } else if (z->u1.v.type == 3) {
236 out[off++] = ND_TYPE_TRUE;
237 } else if (z->u1.v.type == 4) {
238 out[off++] = ND_TYPE_LONG;
239 u64 = htobe64(z->value.lval);
240 memcpy(out + off, &u64, 8); off += 8;
241 } else if (z->u1.v.type == 5) {
242 out[off++] = ND_TYPE_DOUBLE;
243 uint64_t u64 = htobe64(z->value.lval);
244 memcpy(out + off, &u64, 8); off += 8;
245 } else if (z->u1.v.type == 6) {
246 out[off++] = ND_TYPE_STRING;
247 struct zend_string *zs = z->value.str;
248 if (off + 2 + zs->len > out_size)
249 return 0;
250 u16 = htobe16(zs->len);
251 memcpy(out + off, &u16, 2); off += 2;
252 memcpy(out + off, zs->val, zs->len); off += zs->len;
253 } else if (z->u1.v.type == 8) { // object
254 out[off++] = ND_TYPE_POINTER;
255 u64 = htobe64(z->value.lval);
256 memcpy(out + off, &u64, 8); off += 8;
257 } else if (z->u1.v.type == 9) { // resource
258 out[off++] = ND_TYPE_POINTER;
259 u64 = htobe64(z->value.lval);
260 memcpy(out + off, &u64, 8); off += 8;
261 } else {
262 out[off++] = ND_TYPE_UNK;
263 xlog(1, " %s: I do not how to encode %d type! Encode as NULL\n",
264 __func__, z->u1.v.type);
265 }
266
267 return off;
268 }
269
270 // Returns the number of bytes stored in 'out'
271 static unsigned int zend_array_to_binary(unsigned char *out, const size_t out_size,
272 struct zend_array *za)
273 {
274 xlog(100, " %s: nTableMask=0x%x nNumUsed=%u nNumOfElements=%u nTableSize=%u"
275 " nInternalPointer=%u flags=0x%x[%s]\n",
276 __func__,
277 za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize,
278 za->nInternalPointer, za->u.flags, za->u.flags & 4 ? "packed" : "");
279
280 unsigned int off = 0;
281 out[off++] = ND_TYPE_ARRAY_START;
282
283 struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed;
284 for (; bs != be; bs++) {
285 struct zval *_z = &bs->val;
286
287 if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT
288 _z = _z->value.zv;
289
290 if (_z->u1.v.type == 0 /*IS_UNDEF*/) {
291 xlog(101, " para h=%lu: type undef\n", bs->h);
292 continue;
293 }
294
295 if (_z->u1.v.type == 10) { // REFERENCE
296 xlog(101, " is a reference!\n");
297 _z = &_z->value.ref->val;
298 }
299
300 struct zend_string *zs = bs->key;
301 xlog(101, " para: bs=%p h=%lu key=[%p] type %s: val: %s\n",
302 bs, bs->h, zs, php_get_type(_z), php_get_value(_z));
303
304 unsigned int r = zend_simple_to_binary(out + off, out_size - off, _z);
305 if (r == 0)
306 break;
307 off += r;
308 }
309
310 out[off++] = ND_TYPE_ARRAY_END;
311
312 return off;
313 }
314
315 // Returns the number of bytes stored in 'out'
316 unsigned int zend_to_binary(unsigned char *out, const size_t out_size,
317 struct zval *z)
318 {
319 if (z->u1.v.type == 7)
320 return zend_array_to_binary(out, out_size, z->value.arr);
321
322 return zend_simple_to_binary(out, out_size, z);
323 }
324
325 void php_set_para(struct zend_execute_data *e, const unsigned int i,
326 const struct zval *para)
327 {
328 unsigned int s;
329 struct zval *dst;
330
331 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
332 dst = (struct zval *) e + s + i;
333 memcpy(dst, para, sizeof(struct zval));
334 }
335
File agent/php-core.h added (mode: 100644) (index 0000000..9b07134)
1 #ifndef NINEDOGS_PHP_CORE_H
2 #define NINEDOGS_PHP_CORE_H 1
3
4 #include <stdint.h> // for uint32_t
5
6 #include "../common/params.h"
7
8 extern void *(*old_malloc)(size_t size);
9 extern void (*old_free)(void *p);
10
11
12 struct zend_function_entry
13 {
14 const char *fname;
15 void *handler;
16 void *arg_info;
17 unsigned int num_args;
18 unsigned int flags;
19 };
20
21 struct zend_module_entry
22 {
23 unsigned short size;
24 unsigned short pad1;
25 unsigned int zend_api;
26 unsigned char zend_debug;
27 unsigned char zts;
28 unsigned char pad2[6];
29 void *ini_entry;
30 void *deps;
31 const char *name;
32 struct zend_function_entry *functions;
33 void *junk[5];
34 const char *version;
35 size_t globals_size;
36 void *globals;
37 void *globals_ctor;
38 void *globals_dtor;
39 void *post_deactivate_func;
40 int module_started;
41 unsigned char type;
42 unsigned char pad3[3];
43 void *handle;
44 int module_number;
45 int pad4;
46 const char *build_id;
47 };
48
49 typedef long zend_long;
50 typedef unsigned long zend_ulong;
51
52 struct zend_refcounted_h
53 {
54 unsigned int refcount;
55 unsigned int type_info;
56 };
57
58 struct zend_resource
59 {
60 struct zend_refcounted_h gc;
61 int handle;
62 int type;
63 void *ptr;
64 };
65
66 struct zend_string
67 {
68 struct zend_refcounted_h gc;
69 zend_ulong hash;
70 size_t len;
71 char val[1];
72 char pad1[7];
73 };
74
75 struct zend_array
76 {
77 struct zend_refcounted_h gc;
78 union {
79 struct {
80 unsigned char flags;
81 unsigned char _unused;
82 unsigned char nIteratorsCount;
83 unsigned char _unused2;
84 } v;
85 unsigned int flags;
86 } u;
87 unsigned int nTableMask;
88 union {
89 uint32_t *arHash;
90 struct Bucket *arData;
91 struct zval *arPacked;
92 };
93 unsigned int nNumUsed;
94 unsigned int nNumOfElements;
95 unsigned int nTableSize;
96 unsigned int nInternalPointer;
97 zend_long nNextFreeElement;
98 void *dtor;
99 };
100
101 union zend_value
102 {
103 zend_long lval;
104 double dval;
105 void *p;
106 struct zend_string *str;
107 struct zend_array *arr;
108 struct zend_resource *res;
109 struct zend_reference *ref;
110 struct zval *zv;
111 struct {
112 unsigned int w1;
113 unsigned int w2;
114 } ww;
115 };
116
117 struct zval
118 {
119 union zend_value value;
120 union {
121 unsigned int type_info;
122 struct {
123 unsigned char type;
124 unsigned char type_flags;
125 union {
126 unsigned short extra;
127 } u;
128 } v;
129 } u1;
130 union {
131 unsigned int num_args;
132 } u2;
133 };
134
135 struct Bucket
136 {
137 struct zval val;
138 zend_ulong h;
139 struct zend_string *key;
140 };
141
142 struct zend_reference
143 {
144 struct zend_refcounted_h gc;
145 struct zval val;
146 void *sources;
147 };
148
149 struct zend_execute_data
150 {
151 void *opline;
152 struct zend_execute_data *call;
153 struct zval *return_value;
154 void *func;
155 struct zval This;
156 struct zend_execute_data *prev;
157 struct zend_array *symbol_table;
158 void **runtime_cache;
159 struct zend_array *extra_named_params;
160 };
161
162 struct TODOpgsql_link_handle
163 {
164 void *conn; // PGconn
165 struct zend_string *hash;
166 struct HashTable *notices;
167 unsigned char persistent; // bool
168 //zend_object std;
169 unsigned char pad1[7];
170 };
171
172 unsigned int zend_to_binary(unsigned char *out, const size_t out_size,
173 struct zval *z);
174 void php_zval_dump_buf(char *buf, const size_t size,
175 const char *prefix, const struct zval *z);
176 void php_zval_dump(const char *prefix, const struct zval *z);
177 void php_set_para(struct zend_execute_data *e, const unsigned int i,
178 const struct zval *para);
179 void zend_array_to_params_array(struct nd_params_array *p,
180 struct zend_array *za);
181 char *php_get_type(const struct zval *z);
182 char *php_get_value(const struct zval *z);
183
184 #endif
File agent/php-curl.c added (mode: 100644) (index 0000000..ce50e26)
1 #include <stdio.h>
2 #include <string.h>
3
4 #include "ids.h"
5 #include "tools.h"
6 #include "ctools.h"
7
8 #include "curl.h"
9 #include "php-curl.h"
10 #include "process_url.h"
11
12 static void *(*old_curl_init)(struct zend_execute_data *, struct zval *);
13 static void *my_curl_init(struct zend_execute_data *e, struct zval *retv)
14 {
15 struct nd_url b;
16
17 unsigned int num_args = e->This.u2.num_args;
18 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
19
20 if (num_args > 0) {
21 unsigned int s = (sizeof(struct zend_execute_data)
22 + sizeof(struct zval) - 1) / sizeof(struct zval);
23
24 // url
25 struct zval *z = (struct zval *) e + s; s++;
26 php_zval_dump(" url: ", z);
27 struct zend_string *xs = z->value.str;
28 b.url = xs->val;
29 b.url_len = xs->len;
30 } else {
31 b.url = NULL;
32 b.url_len = 0;
33 }
34
35 void *ret = old_curl_init(e, retv);
36 if (!retv)
37 return ret;
38
39 if ((retv->u1.v.type == 7) || (retv->u1.v.type == 8)) { // resource or object
40 b.handle = retv->value.p;
41 } else if (retv->u1.v.type == 2) { // false
42 b.handle = NULL;
43 }
44
45 ninedogs_process_url("curl_init", NINEDOGS_URL_INIT_END, &b);
46
47 return ret;
48 }
49
50 static void *(*old_curl_exec)(struct zend_execute_data *, struct zval *);
51 static void *my_curl_exec(struct zend_execute_data *e, struct zval *retv)
52 {
53 struct nd_url b = { .url_len = 0, .sret_len = 0 };
54
55 unsigned int num_args = e->This.u2.num_args;
56 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
57
58 unsigned int s = (sizeof(struct zend_execute_data)
59 + sizeof(struct zval) - 1) / sizeof(struct zval);
60
61 // handle
62 struct zval *z = (struct zval *) e + s; s++;
63 php_zval_dump(" handle: ", z);
64 b.handle = z->value.p;
65
66 ninedogs_process_url("curl_exec", NINEDOGS_URL_START, &b);
67 void *ret = old_curl_exec(e, retv);
68 if (!retv)
69 return ret;
70
71 if (retv->u1.v.type == 6) { // string
72 struct zend_string *xs = retv->value.str;
73 b.ret = 2;
74 b.sret = xs->val;
75 b.sret_len = xs->len;
76 } else if (retv->u1.v.type == 2) { // false
77 b.ret = 0;
78 } else if (retv->u1.v.type == 3) { // true
79 b.ret = 1;
80 }
81 // TODO: propagate errors
82
83 ninedogs_process_url("curl_exec", NINEDOGS_URL_END, &b);
84
85 return ret;
86 }
87
88 static void *(*old_curl_close)(struct zend_execute_data *, struct zval *);
89 static void *my_curl_close(struct zend_execute_data *e, struct zval *retv)
90 {
91 struct nd_url b = { .url_len = 0, .sret_len = 0 };
92
93 unsigned int num_args = e->This.u2.num_args;
94 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
95
96 unsigned int s = (sizeof(struct zend_execute_data)
97 + sizeof(struct zval) - 1) / sizeof(struct zval);
98
99 // handle
100 struct zval *z = (struct zval *) e + s; s++;
101 php_zval_dump(" handle: ", z);
102 b.handle = z->value.p;
103
104 void *ret = old_curl_close(e, retv);
105 if (!retv)
106 return ret;
107
108 ninedogs_process_url("curl_close", NINEDOGS_URL_CLOSE_END, &b);
109
110 return ret;
111 }
112
113 static void *(*old_curl_setopt)(struct zend_execute_data *, struct zval *);
114 static void *my_curl_setopt(struct zend_execute_data *e, struct zval *retv)
115 {
116 struct nd_url b = { .url_len = 0, .sret_len = 0 };
117
118 unsigned int num_args = e->This.u2.num_args;
119 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
120
121 unsigned int s = (sizeof(struct zend_execute_data)
122 + sizeof(struct zval) - 1) / sizeof(struct zval);
123
124 // handle
125 struct zval *z = (struct zval *) e + s; s++;
126 php_zval_dump(" handle: ", z);
127 b.handle = z->value.p;
128
129 // option
130 z = (struct zval *) e + s; s++;
131 php_zval_dump(" option: ", z);
132 const struct my_curl_easyoption *oi = curl_easy_option_by_id(z->value.lval);
133 if (oi)
134 snprintf(b.op, sizeof(b.op), "%s", oi->name);
135 else
136 snprintf(b.op, sizeof(b.op), "?%ld?", z->value.lval);
137 xlog(100, " option name = %s\n", b.op);
138
139 // value
140 z = (struct zval *) e + s; s++;
141 php_zval_dump(" value: ", z);
142 b.op_value_len = zend_to_binary(b.op_value, sizeof(b.op_value), z);
143
144 void *ret = old_curl_setopt(e, retv);
145 if (!retv)
146 return ret;
147 php_zval_dump(" retv: ", retv);
148
149 if (retv->u1.v.type == 2) { // false
150 b.ret = 0;
151 } else if (retv->u1.v.type == 3) { // true
152 b.ret = 1;
153 }
154 // TODO: propagate errors
155
156 ninedogs_process_url("curl_setopt", NINEDOGS_URL_SETOPT_END, &b);
157
158 return ret;
159 }
160
161 void php_curl_hook(struct zend_function_entry *fe)
162 {
163 if (strcmp(fe->fname, "curl_close") == 0) {
164 old_curl_close = fe->handler;
165 fe->handler = my_curl_close;
166 } else if (strcmp(fe->fname, "curl_init") == 0) {
167 old_curl_init = fe->handler;
168 fe->handler = my_curl_init;
169 } else if (strcmp(fe->fname, "curl_exec") == 0) {
170 old_curl_exec = fe->handler;
171 fe->handler = my_curl_exec;
172 } else if (strcmp(fe->fname, "curl_setopt") == 0) {
173 old_curl_setopt = fe->handler;
174 fe->handler = my_curl_setopt;
175 } else {
176 //xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname);
177 }
178 }
File agent/php-curl.h added (mode: 100644) (index 0000000..d469bd9)
1 #include "php-core.h"
2
3 void php_curl_hook(struct zend_function_entry *fe);
4
File agent/php-mysql.c added (mode: 100644) (index 0000000..0cae262)
1 #include <stdio.h>
2 #include <string.h>
3
4 #include "ids.h"
5 #include "tools.h"
6 #include "php-mysql.h"
7 #include "process_db.h"
8
9 static void *(*old_mysqli_error)(struct zend_execute_data *, struct zval *);
10 static void *(*old_mysqli_affected_rows)(struct zend_execute_data *, struct zval *);
11 static void *(*old_mysqli_num_rows)(struct zend_execute_data *, struct zval *);
12 static void *(*old_mysqli_stmt_affected_rows)(struct zend_execute_data *, struct zval *);
13 static void *(*old_mysqli_stmt_num_rows)(struct zend_execute_data *, struct zval *);
14
15 static void php_mysqli_set_error(struct zend_execute_data *e,
16 struct zval *link, struct query *q)
17 {
18 struct zval rz;
19
20 e->This.u2.num_args = 1;
21 php_set_para(e, 0, link);
22
23 // TODO: we need also the numeric representation of the error!
24 xlog(50, " calling mysqli_error...\n");
25 old_mysqli_error(e, &rz);
26
27 if (rz.u1.v.type == 6) { // string
28 q->err = rz.value.str->val;
29 q->err_len = rz.value.str->len;
30 xlog(40, "%s: set error to [%s]\n", __func__, q->err);
31 } else {
32 q->err = "?";
33 q->err_len = 1;
34 }
35 }
36
37 static void php_mysqli_set_num_aff(struct zend_execute_data *e, struct zval *res,
38 struct query *q)
39 {
40 struct zval rz;
41
42 e->This.u2.num_args = 1;
43
44 //xlog(1, " calling old pg_affected_rows...\n");
45 //php_zed_dump(" e: ", e);
46 old_mysqli_affected_rows(e, &rz); // we need to pass a link here
47 php_zval_dump(" aff_rows: ", &rz);
48 q->aff = rz.value.lval;
49
50 php_set_para(e, 0, res);
51 //xlog(1, " calling old pg_num_rows...\n");
52 //php_zed_dump(" e: ", e);
53 old_mysqli_num_rows(e, &rz); // we need a result here
54 php_zval_dump(" num_rows: ", &rz);
55 q->num = rz.value.lval;
56 }
57
58 static void php_mysqli_stmt_set_num_aff(struct zend_execute_data *e,
59 struct nd_db_stmt *stmt)
60 {
61 struct zval rz;
62
63 e->This.u2.num_args = 1;
64
65 //xlog(1, " calling old mysqli_stmt_affected_rows...\n");
66 //php_zed_dump(" e: ", e);
67 old_mysqli_stmt_affected_rows(e, &rz);
68 php_zval_dump(" aff_rows: ", &rz);
69 stmt->aff = rz.value.lval;
70
71 //xlog(1, " calling old mysqli_stmt_num_rows...\n");
72 //php_zed_dump(" e: ", e);
73 old_mysqli_stmt_num_rows(e, &rz);
74 php_zval_dump(" num_rows: ", &rz);
75 stmt->num = rz.value.lval;
76 }
77
78 static void *(*old_mysqli_connect)(struct zend_execute_data *, struct zval *);
79 static void *my_mysqli_connect(struct zend_execute_data *e, struct zval *retv)
80 {
81 void *ret;
82 unsigned int num_args, s;
83 struct zval *z;
84 struct nd_db_conn c;
85 char *host = "", *user = "", *db = "", *sock = "";
86 int port = 0;
87
88 num_args = e->This.u2.num_args;
89 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
90
91 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
92 c.type = 'M';
93 c.stable = 0;
94 c.ex = NULL; // TODO
95
96 if (num_args >= 1) { // host
97 z = (struct zval *) e + s; s++;
98 //php_zval_dump(" host: ", z);
99 if (z->u1.v.type == 6) // string
100 host = z->value.str->val;
101 }
102
103 if (num_args >= 2) { // user
104 z = (struct zval *) e + s; s++;
105 if (z->u1.v.type == 6) // string
106 user = z->value.str->val;
107 }
108
109 if (num_args >= 3) // pass
110 s++;
111
112 if (num_args >= 4) { // db
113 z = (struct zval *) e + s; s++;
114 if (z->u1.v.type == 6) // string
115 db = z->value.str->val;
116 }
117
118 if (num_args >= 5) { // port
119 z = (struct zval *) e + s; s++;
120 if (z->u1.v.type == 4) // long
121 port = z->value.lval;
122 }
123
124 if (num_args >= 6) { // socket
125 z = (struct zval *) e + s; s++;
126 if (z->u1.v.type == 6) // string
127 sock = z->value.str->val;
128 }
129
130 char conn_str[512];
131 snprintf(conn_str, sizeof(conn_str),
132 "host=%s user=%s port=%d db=%s socket=%s",
133 host, user, port, db, sock);
134 c.conn_str = conn_str;
135 c.conn_str_len = strlen(c.conn_str);
136
137 ninedogs_process_db("mysqli_connect", NINEDOGS_DB_CONN_START, &c);
138 ret = old_mysqli_connect(e, retv);
139 if (!retv) {
140 xlog(1, "DEBUG: old_mysqli_connect returned retv NULL\n");
141 return ret;
142 }
143 //php_zval_dump(" retv: ", retv);
144 // TODO: how to test for error? if (core_globals.last_error_message) {
145
146 // PHP7 returns resource, PHP8.1 returns object
147 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
148 c.dbh = retv->value.p;
149 else
150 c.dbh = NULL;
151 ninedogs_process_db("mysqli_connect", NINEDOGS_DB_CONN_END, &c);
152
153 return ret;
154 }
155
156 static void *(*old_mysqli_real_connect)(struct zend_execute_data *, struct zval *);
157 static void *my_mysqli_real_connect(struct zend_execute_data *e, struct zval *retv)
158 {
159 void *ret;
160 unsigned int num_args, s;
161 struct zval *z;
162 struct nd_db_conn c;
163 char *host = "", *user = "", *db = "", *sock = "";
164 int port = 0;
165
166 num_args = e->This.u2.num_args;
167 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
168
169 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
170 c.type = 'M';
171 c.stable = 0;
172 c.flags = 0;
173 c.ex = NULL; // TODO
174
175 if (num_args >= 1) { // dbh
176 z = (struct zval *) e + s; s++;
177 if ((z->u1.v.type == 8) || (z->u1.v.type == 9)) // object or resource
178 c.dbh = z->value.p;
179 }
180
181 if (num_args >= 2) { // host
182 z = (struct zval *) e + s; s++;
183 //php_zval_dump(" host: ", z);
184 if (z->u1.v.type == 6) // string
185 host = z->value.str->val;
186 }
187
188 if (num_args >= 3) { // user
189 z = (struct zval *) e + s; s++;
190 if (z->u1.v.type == 6) // string
191 user = z->value.str->val;
192 }
193
194 if (num_args >= 4) // pass
195 s++;
196
197 if (num_args >= 5) { // db
198 z = (struct zval *) e + s; s++;
199 if (z->u1.v.type == 6) // string
200 db = z->value.str->val;
201 }
202
203 if (num_args >= 6) { // port
204 z = (struct zval *) e + s; s++;
205 if (z->u1.v.type == 4) // long
206 port = z->value.lval;
207 }
208
209 if (num_args >= 7) { // socket
210 z = (struct zval *) e + s; s++;
211 if (z->u1.v.type == 6) // string
212 sock = z->value.str->val;
213 }
214
215 if (num_args >= 8) { // flags
216 z = (struct zval *) e + s; s++;
217 if (z->u1.v.type == 4) // long
218 c.flags = z->value.lval;
219 }
220
221 char conn_str[512];
222 snprintf(conn_str, sizeof(conn_str),
223 "host=%s user=%s port=%d db=%s socket=%s",
224 host, user, port, db, sock);
225 c.conn_str = conn_str;
226 c.conn_str_len = strlen(c.conn_str);
227
228 ninedogs_process_db("mysqli_real_connect", NINEDOGS_DB_CONN_START, &c);
229 ret = old_mysqli_real_connect(e, retv);
230 if (!retv) {
231 xlog(1, "DEBUG: old_mysqli_real_connect returned retv NULL\n");
232 return ret;
233 }
234 //php_zval_dump(" retv: ", retv);
235 // TODO: how to test for error? if (core_globals.last_error_message) {
236
237 // PHP7 returns resource, PHP8.1 returns object
238 if (retv->u1.v.type == 3)
239 c.ok = 1;
240 else
241 c.ok = 0;
242 ninedogs_process_db("mysqli_real_connect", NINEDOGS_DB_CONN_END, &c);
243
244 return ret;
245 }
246
247 static void *(*old_mysqli_query)(struct zend_execute_data *, struct zval *);
248 static void *my_mysqli_query(struct zend_execute_data *e, struct zval *retv)
249 {
250 void *ret;
251 unsigned int num_args, copy_num_args, s;
252 struct zend_string *q;
253 struct zval *z, copy_para, *para;
254 char do_restore = 0;
255 struct query qs;
256
257 num_args = e->This.u2.num_args;
258
259 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
260
261 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
262 para = (struct zval *) e + s;
263 nd_db_qs_init('M', &qs);
264
265 // link
266 z = (struct zval *) e + s; s++;
267 php_zval_dump(" dbh: ", z);
268 qs.dbh = z->value.p;
269
270 // query
271 z = (struct zval *) e + s; s++;
272 q = z->value.str;
273 xlog(50, " query=%s\n", q->val);
274 qs.q = q->val;
275 qs.q_len = q->len;
276
277 // mode
278 if (num_args >= 3) {
279 z = (struct zval *) e + s; s++;
280 xlog(50, " mode=0x%lx\n", z->value.lval);
281 }
282
283 ninedogs_process_db("mysqli_query", NINEDOGS_DB_QUERY_START, &qs);
284 ret = old_mysqli_query(e, retv);
285 if (!retv)
286 return ret;
287 php_zval_dump(" retv: ", retv);
288
289 copy_num_args = num_args;
290 memcpy(&copy_para, para, sizeof(struct zval));
291
292 if (retv->u1.v.type == 2) { // false
293 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
294 // TODO: do we set num and aff?
295 qs.res = (void *) 0;
296 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
297 qs.num = qs.aff = 0;
298 qs.res = (void *) 1;
299 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
300 qs.res = retv->value.p;
301 php_mysqli_set_num_aff(e, retv, &qs);
302 do_restore = 1;
303 }
304
305 e->This.u2.num_args = copy_num_args;
306 if (do_restore)
307 memcpy(para, &copy_para, sizeof(struct zval));
308
309 ninedogs_process_db("mysqli_query", NINEDOGS_DB_QUERY_END, &qs);
310
311 return ret;
312 }
313
314 static void *(*old_mysqli_close)(struct zend_execute_data *, struct zval *);
315 static void *my_mysqli_close(struct zend_execute_data *e, struct zval *retv)
316 {
317 struct nd_db_conn c;
318
319 unsigned int num_args = e->This.u2.num_args;
320
321 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
322
323 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
324 c.type = 'M';
325
326 // link
327 struct zval *z = (struct zval *) e + s; s++;
328 php_zval_dump(" dbh: ", z);
329 c.dbh = z->value.p;
330
331 void *ret = old_mysqli_close(e, retv);
332 if (!retv)
333 return ret;
334 php_zval_dump(" retv: ", retv);
335
336 if (retv->u1.v.type == 2) { // false
337 c.ok = 0;
338 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
339 // TODO: do we set num and aff?
340 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
341 c.ok = 1;
342 }
343
344 ninedogs_process_db("mysqli_close", NINEDOGS_DB_CONN_CLOSE, &c);
345
346 return ret;
347 }
348
349 static void *(*old_mysqli_fetch_all)(struct zend_execute_data *, struct zval *);
350 static void *my_mysqli_fetch_all(struct zend_execute_data *e, struct zval *retv)
351 {
352 struct query q;
353
354 unsigned int num_args = e->This.u2.num_args;
355 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
356
357 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
358 q.type = 'M';
359
360 // res
361 struct zval *z = (struct zval *) e + s; s++;
362 php_zval_dump(" res: ", z);
363 q.res = z->value.p;
364
365 // mode
366 if (num_args >= 2) {
367 z = (struct zval *) e + s; s++;
368 q.mode = z->value.lval;
369 xlog(50, " mode=0x%lx\n", q.mode);
370 } else {
371 q.mode = 2; // MYSQLI_NUM
372 }
373
374 ninedogs_process_db("mysqli_fetch_all", NINEDOGS_DB_FETCH_START, &q);
375 void *ret = old_mysqli_fetch_all(e, retv);
376 if (!retv)
377 return ret;
378 php_zval_dump(" retv: ", retv);
379
380 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
381 if (retv->u1.v.type == 7) { // array
382 struct zend_array *a = retv->value.arr;
383 q.num = a->nNumUsed;
384 //q.ret = 0;
385 // TODO: do we set num and aff? Should we? We already count them in 'execute'.
386 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
387 q.num = 0;
388 //q.ret = 1;
389 }
390
391 ninedogs_process_db("mysqli_fetch_all", NINEDOGS_DB_FETCH_END, &q);
392
393 return ret;
394 }
395
396 static void *(*old_mysqli_fetch_array)(struct zend_execute_data *, struct zval *);
397 static void *my_mysqli_fetch_array(struct zend_execute_data *e, struct zval *retv)
398 {
399 struct query q;
400
401 unsigned int num_args = e->This.u2.num_args;
402 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
403
404 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
405 q.type = 'M';
406
407 // res
408 struct zval *z = (struct zval *) e + s; s++;
409 php_zval_dump(" res: ", z);
410 q.res = z->value.p;
411
412 // mode
413 if (num_args >= 2) {
414 z = (struct zval *) e + s; s++;
415 q.mode = z->value.lval;
416 xlog(50, " mode=0x%lx\n", q.mode);
417 } else {
418 q.mode = 3; // MYSQLI_BOTH
419 }
420
421 ninedogs_process_db("mysqli_fetch_array", NINEDOGS_DB_FETCH_START, &q);
422 void *ret = old_mysqli_fetch_array(e, retv);
423 if (!retv)
424 return ret;
425 php_zval_dump(" retv: ", retv);
426
427 if (retv->u1.v.type == 7) { // array
428 q.ret = 2;
429 } else if (retv->u1.v.type == 2) { // false - TODO set error
430 q.ret = 1;
431 } else {
432 q.ret = 0;
433 }
434
435 ninedogs_process_db("mysqli_fetch_array", NINEDOGS_DB_FETCH_END, &q);
436
437 return ret;
438 }
439
440 static void *(*old_mysqli_free_result)(struct zend_execute_data *, struct zval *);
441 static void *my_mysqli_free_result(struct zend_execute_data *e, struct zval *retv)
442 {
443 struct free_result fr;
444
445 unsigned int num_args = e->This.u2.num_args;
446 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
447
448 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
449 fr.type = 'M';
450
451 // res
452 struct zval *z = (struct zval *) e + s; s++;
453 php_zval_dump(" res: ", z);
454 fr.res = z->value.p;
455
456 void *ret = old_mysqli_free_result(e, retv);
457 if (!retv)
458 return ret;
459
460 ninedogs_process_db("mysqli_free_result", NINEDOGS_DB_FREE_RESULT, &fr);
461
462 return ret;
463 }
464
465 static void *(*old_mysqli_stmt_close)(struct zend_execute_data *, struct zval *);
466 static void *my_mysqli_stmt_close(struct zend_execute_data *e, struct zval *retv)
467 {
468 struct nd_db_stmt stmt;
469
470 unsigned int num_args = e->This.u2.num_args;
471 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
472
473 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
474 stmt.type = 'M';
475
476 // stmt
477 struct zval *z = (struct zval *) e + s; s++;
478 php_zval_dump(" stmt: ", z);
479 stmt.stmt = z->value.p;
480
481 ninedogs_process_db("mysqli_stmt_close", NINEDOGS_DB_STMT_CLOSE_START, &stmt);
482 void *ret = old_mysqli_stmt_close(e, retv);
483 if (!retv)
484 return ret;
485
486 if (retv->u1.v.type == 3) { // true
487 stmt.ret = 1;
488 } else if (retv->u1.v.type == 2) { // false
489 stmt.ret = 0;
490 }
491
492 ninedogs_process_db("mysqli_stmt_close", NINEDOGS_DB_STMT_CLOSE_END, &stmt);
493
494 return ret;
495 }
496
497 static void *(*old_mysqli_stmt_execute)(struct zend_execute_data *, struct zval *);
498 static void *my_mysqli_stmt_execute(struct zend_execute_data *e, struct zval *retv)
499 {
500 struct nd_db_stmt stmt;
501 char do_restore = 0;
502
503 unsigned int num_args = e->This.u2.num_args;
504 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
505
506 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
507 nd_db_stmt_init('M', &stmt);
508
509 struct zval *para = (struct zval *) e + s;
510
511 // stmt
512 struct zval *z = (struct zval *) e + s; s++;
513 php_zval_dump(" stmt: ", z);
514 stmt.stmt = z->value.p;
515
516 if (num_args >= 2) {
517 z = (struct zval *) e + s; s++;
518 struct zend_array *za = z->value.arr;
519 zend_array_to_params_array(&stmt.params, za);
520 }
521
522 unsigned int copy_num_args = num_args;
523 struct zval copy_para;
524 memcpy(&copy_para, para, sizeof(struct zval));
525
526 ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_START, &stmt);
527 void *ret = old_mysqli_stmt_execute(e, retv);
528 if (!retv)
529 return ret;
530
531 if (retv->u1.v.type == 3) { // true
532 stmt.ret = 1;
533 php_mysqli_stmt_set_num_aff(e, &stmt);
534 do_restore = 1;
535 } else if (retv->u1.v.type == 2) { // false
536 stmt.ret = 0;
537 }
538
539 e->This.u2.num_args = copy_num_args;
540 if (do_restore)
541 memcpy(para, &copy_para, sizeof(struct zval));
542
543 ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_END, &stmt);
544
545 return ret;
546 }
547
548 static void *(*old_mysqli_prepare)(struct zend_execute_data *, struct zval *);
549 static void *my_mysqli_prepare(struct zend_execute_data *e, struct zval *retv)
550 {
551 struct nd_db_stmt stmt;
552
553 unsigned int num_args = e->This.u2.num_args;
554 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
555
556 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
557 stmt.type = 'M';
558
559 // link
560 struct zval *z = (struct zval *) e + s; s++;
561 php_zval_dump(" link: ", z);
562 stmt.dbh = z->value.p;
563
564 // query
565 z = (struct zval *) e + s; s++;
566 struct zend_string *xs = z->value.str;
567 xlog(50, " query=%s\n", xs->val);
568 stmt.q = xs->val;
569 stmt.q_len = xs->len;
570
571 ninedogs_process_db("mysqli_prepare", NINEDOGS_DB_PREPARE_START, &stmt);
572 void *ret = old_mysqli_prepare(e, retv);
573 if (!retv)
574 return ret;
575 php_zval_dump(" retv: ", retv);
576
577 // PHP7 returns resource, PHP8.1 returns object
578 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) {
579 stmt.stmt = retv->value.p;
580 } else if (retv->u1.v.type == 2) { // false
581 stmt.stmt = NULL;
582 }
583
584 ninedogs_process_db("mysqli_prepare", NINEDOGS_DB_PREPARE_END, &stmt);
585
586 return ret;
587 }
588
589 static void *(*old_mysqli_stmt_prepare)(struct zend_execute_data *, struct zval *);
590 static void *my_mysqli_stmt_prepare(struct zend_execute_data *e, struct zval *retv)
591 {
592 struct nd_db_stmt stmt;
593
594 unsigned int num_args = e->This.u2.num_args;
595 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
596
597 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
598 stmt.type = 'M';
599
600 // stmt
601 struct zval *z = (struct zval *) e + s; s++;
602 php_zval_dump(" stmt: ", z);
603 stmt.stmt = z->value.p;
604
605 // query
606 z = (struct zval *) e + s; s++;
607 struct zend_string *xs = z->value.str;
608 xlog(50, " query=%s\n", xs->val);
609 stmt.q = xs->val;
610 stmt.q_len = xs->len;
611
612 ninedogs_process_db("mysqli_stmt_prepare", NINEDOGS_DB_PREPARE_START, &stmt);
613 void *ret = old_mysqli_stmt_prepare(e, retv);
614 if (!retv)
615 return ret;
616 php_zval_dump(" retv: ", retv);
617
618 if (retv->u1.v.type == 3) { // true
619 stmt.ret = 1;
620 } else if (retv->u1.v.type == 2) { // false
621 stmt.ret = 0;
622 }
623
624 ninedogs_process_db("mysqli_stmt_prepare", NINEDOGS_DB_PREPARE_END, &stmt);
625
626 return ret;
627 }
628
629 static void *(*old_mysqli_autocommit)(struct zend_execute_data *, struct zval *);
630 static void *my_mysqli_autocommit(struct zend_execute_data *e, struct zval *retv)
631 {
632 struct db_autocommit a;
633
634 unsigned int num_args = e->This.u2.num_args;
635 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
636
637 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
638 a.type = 'M';
639
640 // link
641 struct zval *z = (struct zval *) e + s; s++;
642 a.link = z->value.p;
643
644 z = (struct zval *) e + s; s++;
645 php_zval_dump(" bool: ", z);
646 a.value = z->u1.v.type == 3;
647
648 ninedogs_process_db("mysqli_autocommit", NINEDOGS_DB_AUTOCOMMIT_START, &a);
649 void *ret = old_mysqli_autocommit(e, retv);
650 if (!retv)
651 return ret;
652
653 if (retv->u1.v.type == 3) { // true
654 a.ret = 1;
655 } else if (retv->u1.v.type == 2) { // false
656 a.ret = 0;
657 }
658
659 ninedogs_process_db("mysqli_autocommit", NINEDOGS_DB_AUTOCOMMIT_END, &a);
660
661 return ret;
662 }
663
664 static void *(*old_mysqli_stmt_bind_param)(struct zend_execute_data *, struct zval *);
665 static void *my_mysqli_stmt_bind_param(struct zend_execute_data *e, struct zval *retv)
666 {
667 struct nd_db_bind b;
668
669 unsigned int num_args = e->This.u2.num_args;
670 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
671
672 unsigned int s = (sizeof(struct zend_execute_data)
673 + sizeof(struct zval) - 1) / sizeof(struct zval);
674 b.type = 'M';
675
676 // stmt
677 struct zval *z = (struct zval *) e + s; s++;
678 //php_zval_dump(" stmt: ", z);
679 b.stmt = z->value.p;
680
681 // types
682 z = (struct zval *) e + s; s++;
683 struct zend_string *xs = z->value.str;
684 b.types = xs->val;
685 b.types_len = xs->len;
686
687 ninedogs_process_db("mysqli_stmt_bind_param",
688 NINEDOGS_DB_BIND_PARAM_START, &b);
689 void *ret = old_mysqli_stmt_bind_param(e, retv);
690 if (!retv)
691 return ret;
692
693 if (retv->u1.v.type == 3) { // true
694 b.ret = 1;
695 } else if (retv->u1.v.type == 2) { // false
696 b.ret = 0;
697 }
698
699 ninedogs_process_db("mysqli_stmt_bind_param",
700 NINEDOGS_DB_BIND_PARAM_END, &b);
701
702 return ret;
703 }
704
705 void php_mysql_hook(struct zend_function_entry *fe)
706 {
707 if (strcmp(fe->fname, "mysqli_autocommit") == 0) {
708 old_mysqli_autocommit = fe->handler;
709 fe->handler = my_mysqli_autocommit;
710 } else if (strcmp(fe->fname, "mysqli_close") == 0) {
711 old_mysqli_close = fe->handler;
712 fe->handler = my_mysqli_close;
713 } else if (strcmp(fe->fname, "mysqli_affected_rows") == 0) {
714 old_mysqli_affected_rows = fe->handler;
715 } else if (strcmp(fe->fname, "mysqli_connect") == 0) {
716 old_mysqli_connect = fe->handler;
717 fe->handler = my_mysqli_connect;
718 } else if (strcmp(fe->fname, "mysqli_error") == 0) {
719 old_mysqli_error = fe->handler;
720 } else if (strcmp(fe->fname, "mysqli_fetch_all") == 0) {
721 old_mysqli_fetch_all = fe->handler;
722 fe->handler = my_mysqli_fetch_all;
723 } else if (strcmp(fe->fname, "mysqli_fetch_array") == 0) {
724 old_mysqli_fetch_array = fe->handler;
725 fe->handler = my_mysqli_fetch_array;
726 } else if (strcmp(fe->fname, "mysqli_free_result") == 0) {
727 old_mysqli_free_result = fe->handler;
728 fe->handler = my_mysqli_free_result;
729 } else if (strcmp(fe->fname, "mysqli_query") == 0) {
730 old_mysqli_query = fe->handler;
731 fe->handler = my_mysqli_query;
732 } else if (strcmp(fe->fname, "mysqli_prepare") == 0) {
733 old_mysqli_prepare = fe->handler;
734 fe->handler = my_mysqli_prepare;
735 } else if (strcmp(fe->fname, "mysqli_num_rows") == 0) {
736 old_mysqli_num_rows = fe->handler;
737 } else if (strcmp(fe->fname, "mysqli_real_connect") == 0) {
738 old_mysqli_real_connect = fe->handler;
739 fe->handler = my_mysqli_real_connect;
740 } else if (strcmp(fe->fname, "mysqli_stmt_affected_rows") == 0) {
741 old_mysqli_stmt_affected_rows = fe->handler;
742 } else if (strcmp(fe->fname, "mysqli_stmt_close") == 0) {
743 old_mysqli_stmt_close = fe->handler;
744 fe->handler = my_mysqli_stmt_close;
745 } else if (strcmp(fe->fname, "mysqli_stmt_execute") == 0) {
746 old_mysqli_stmt_execute = fe->handler;
747 fe->handler = my_mysqli_stmt_execute;
748 } else if (strcmp(fe->fname, "mysqli_stmt_bind_param") == 0) {
749 old_mysqli_stmt_bind_param = fe->handler;
750 fe->handler = my_mysqli_stmt_bind_param;
751 } else if (strcmp(fe->fname, "mysqli_stmt_num_rows") == 0) {
752 old_mysqli_stmt_num_rows = fe->handler;
753 } else if (strcmp(fe->fname, "mysqli_stmt_prepare") == 0) {
754 old_mysqli_stmt_prepare = fe->handler;
755 fe->handler = my_mysqli_stmt_prepare;
756 } else {
757 //xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname);
758 }
759 }
File agent/php-mysql.h added (mode: 100644) (index 0000000..a12d31c)
1 #include "php-core.h"
2
3 void php_mysql_hook(struct zend_function_entry *fe);
4
File agent/php-oci.c added (mode: 100644) (index 0000000..23e76d2)
1 #include <stdio.h>
2 #include <string.h>
3
4 #include "ids.h"
5 #include "tools.h"
6 #include "php-oci.h"
7 #include "process_db.h"
8
9
10 static void *(*old_oci_bind_by_name)(struct zend_execute_data *, struct zval *);
11 static void *my_oci_bind_by_name(struct zend_execute_data *e, struct zval *retv)
12 {
13 unsigned int num_args, s;
14 struct nd_db_stmt stmt;
15 long max_length = -1, type = 0;
16 void *var;
17
18 num_args = e->This.u2.num_args;
19 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
20
21 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
22 nd_db_stmt_init('O', &stmt);
23
24 // stmt
25 struct zval *z = (struct zval *) e + s; s++;
26 php_zval_dump(" stmt: ", z);
27 stmt.stmt = z->value.p;
28
29 // param name
30 z = (struct zval *) e + s; s++;
31 struct zend_string *q = z->value.str;
32 php_zval_dump(" param: ", z);
33 char *param = q->val;
34 unsigned short param_len = q->len;
35
36 // 'var' - reference to variabile
37 z = (struct zval *) e + s; s++;
38 q = z->value.str;
39 php_zval_dump(" var: ", z);
40 var = z->value.p;
41
42 if (num_args >= 4) {
43 z = (struct zval *) e + s; s++;
44 max_length = z->value.lval;
45 }
46
47 if (num_args >= 5) {
48 z = (struct zval *) e + s; s++;
49 type = z->value.lval;
50 }
51
52 // TODO: this is still in development
53 xlog(1, "%s: stmt=%p param=[%s][%hu] var=[%p] max_length=%ld type=%ld\n",
54 __func__, stmt.stmt, param, param_len, var, max_length, type);
55
56 void *ret = old_oci_bind_by_name(e, retv);
57 if (!retv)
58 return ret;
59
60 if (retv->u1.v.type == 3) { // true
61 stmt.ret = 1;
62 } else if (retv->u1.v.type == 2) { // false
63 stmt.ret = 0;
64 }
65
66 ninedogs_process_db("oci_bind_by_name", NINEDOGS_DB_BIND_ONE_PARAM, &stmt);
67
68 return ret;
69 }
70
71 static void *(*old_oci_close)(struct zend_execute_data *, struct zval *);
72 static void *my_oci_close(struct zend_execute_data *e, struct zval *retv)
73 {
74 unsigned int num_args, s;
75 struct nd_db_conn c;
76
77 num_args = e->This.u2.num_args;
78 //xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
79
80 c.type = 'O';
81 c.stable = 0;
82 c.ex = NULL; // TODO
83 if (num_args == 1) {
84 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
85 // handler, may be null
86 struct zval *z = (struct zval *) e + s; s++;
87 c.dbh = z->value.p;
88 //xlog(101, " h=%p\n", c.dbh);
89 } else {
90 c.dbh = NULL;
91 }
92
93 void *ret = old_oci_close(e, retv);
94 ninedogs_process_db("oci_close", NINEDOGS_DB_CONN_CLOSE, &c);
95
96 return ret;
97 }
98
99 static void *(*old_oci_execute)(struct zend_execute_data *, struct zval *);
100 static void *my_oci_execute(struct zend_execute_data *e, struct zval *retv)
101 {
102 unsigned int num_args, s;
103 char do_restore = 0;
104 struct nd_db_stmt stmt;
105
106 num_args = e->This.u2.num_args;
107 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
108
109 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
110 nd_db_stmt_init('O', &stmt);
111 stmt.oci.mode = 0x00000020; // 0x00000020 = OCI_COMMIT_ON_SUCCESS
112
113 struct zval *para = (struct zval *) e + s;
114
115 // stmt
116 struct zval *z = (struct zval *) e + s; s++;
117 php_zval_dump(" stmt: ", z);
118 stmt.stmt = z->value.p;
119
120 if (num_args >= 2) {
121 z = (struct zval *) e + s; s++;
122 stmt.oci.mode = z->value.lval;
123 }
124 xlog(100, "%s: stmt=%p mode=%ld\n", __func__, stmt.stmt, stmt.oci.mode);
125
126 unsigned int copy_num_args = num_args;
127 struct zval copy_para;
128 memcpy(&copy_para, para, sizeof(struct zval));
129
130 ninedogs_process_db("oci_execute", NINEDOGS_DB_EXECUTE_START, &stmt);
131 void *ret = old_oci_execute(e, retv);
132 if (!retv)
133 return ret;
134
135 if (retv->u1.v.type == 3) { // true
136 stmt.ret = 1;
137 // TODO php_oci_stmt_set_num_aff(e, &stmt);
138 do_restore = 1;
139 } else if (retv->u1.v.type == 2) { // false
140 stmt.ret = 0;
141 }
142
143 e->This.u2.num_args = copy_num_args;
144 if (do_restore)
145 memcpy(para, &copy_para, sizeof(struct zval));
146
147 ninedogs_process_db("oci_execute", NINEDOGS_DB_EXECUTE_END, &stmt);
148
149 return ret;
150 }
151
152 static void *(*old_oci_parse)(struct zend_execute_data *, struct zval *);
153 static void *my_oci_parse(struct zend_execute_data *e, struct zval *retv)
154 {
155 unsigned int num_args, s;
156 struct nd_db_stmt stmt;
157
158 num_args = e->This.u2.num_args;
159 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
160
161 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
162 nd_db_stmt_init('O', &stmt);
163
164 // dbh
165 struct zval *z = (struct zval *) e + s; s++;
166 php_zval_dump(" stmt: ", z);
167 stmt.dbh = z->value.p;
168
169 // sql
170 z = (struct zval *) e + s; s++;
171 struct zend_string *q = z->value.str;
172 stmt.q = q->val;
173 stmt.q_len = q->len;
174
175 xlog(100, "%s: dbh=%p sql=%s\n", __func__, stmt.dbh, stmt.q);
176
177 ninedogs_process_db("oci_parse", NINEDOGS_DB_PREPARE_START, &stmt);
178 void *ret = old_oci_parse(e, retv);
179 if (!retv)
180 return ret;
181
182 if (retv->u1.v.type == 2) { // false
183 stmt.stmt = NULL;
184 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
185 stmt.stmt = retv->value.p;
186 }
187
188 ninedogs_process_db("oci_parse", NINEDOGS_DB_PREPARE_END, &stmt);
189
190 return ret;
191 }
192
193 static void *(*old_oci_pconnect)(struct zend_execute_data *, struct zval *);
194 static void *my_oci_pconnect(struct zend_execute_data *e, struct zval *retv)
195 {
196 unsigned int num_args, s;
197 struct zval *z;
198 struct nd_db_conn c;
199 char *user = "", *conn = "", *encoding = "";
200 int session_mode = 0; // 0 = OCI_DEFAULT
201
202 num_args = e->This.u2.num_args;
203 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
204
205 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
206 c.type = 'O';
207 c.stable = 0;
208 c.ex = NULL; // TODO
209
210 if (num_args >= 1) { // username
211 z = (struct zval *) e + s; s++;
212 //php_zval_dump(" host: ", z);
213 if (z->u1.v.type == 6) // string
214 user = z->value.str->val;
215 }
216
217 if (num_args >= 2) // pass
218 s++;
219
220 if (num_args >= 3) { // conn (can be null)
221 z = (struct zval *) e + s; s++;
222 if (z->u1.v.type == 6) // string
223 conn = z->value.str->val;
224 }
225
226 if (num_args >= 4) { // encoding
227 z = (struct zval *) e + s; s++;
228 if (z->u1.v.type == 4) // long
229 encoding = z->value.str->val;
230 }
231
232 if (num_args >= 5) { // session mode
233 z = (struct zval *) e + s; s++;
234 if (z->u1.v.type == 4) // long
235 session_mode = z->value.lval;
236 }
237
238 char conn_str[512];
239 snprintf(conn_str, sizeof(conn_str),
240 "user=%s conn=[%s] encoding=%s session_mode=%d",
241 user, conn, encoding, session_mode);
242 c.conn_str = conn_str;
243 c.conn_str_len = strlen(c.conn_str);
244
245 ninedogs_process_db("oci_pconnect", NINEDOGS_DB_CONN_START, &c);
246 void *ret = old_oci_pconnect(e, retv);
247 if (!retv) {
248 xlog(0, "DEBUG: old_oci_pconnect returned retv NULL\n");
249 return ret;
250 }
251
252 php_zval_dump(" retv: ", retv);
253 // TODO: how to test for error? if (core_globals.last_error_message) {
254
255 // PHP7 returns resource, PHP8.1 returns object
256 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
257 c.dbh = retv->value.p;
258 else
259 c.dbh = NULL;
260 ninedogs_process_db("oci_pconnect", NINEDOGS_DB_CONN_END, &c);
261
262 return ret;
263 }
264
265 void php_oci_hook(struct zend_function_entry *fe)
266 {
267 if (strcmp(fe->fname, "oci_bind_by_name") == 0) {
268 old_oci_bind_by_name = fe->handler;
269 fe->handler = my_oci_bind_by_name;
270 } else if (strcmp(fe->fname, "oci_close") == 0) {
271 old_oci_close = fe->handler;
272 fe->handler = my_oci_close;
273 } else if (strcmp(fe->fname, "oci_execute") == 0) {
274 old_oci_execute = fe->handler;
275 fe->handler = my_oci_execute;
276 } else if (strcmp(fe->fname, "oci_parse") == 0) {
277 old_oci_parse = fe->handler;
278 fe->handler = my_oci_parse;
279 } else if (strcmp(fe->fname, "oci_pconnect") == 0) {
280 old_oci_pconnect = fe->handler;
281 fe->handler = my_oci_pconnect;
282 }
283 }
File agent/php-oci.h added (mode: 100644) (index 0000000..779f8be)
1 #include "php-core.h"
2
3 void php_oci_hook(struct zend_function_entry *fe);
4
File agent/php-pg.c added (mode: 100644) (index 0000000..23aacb1)
1 #include <string.h>
2
3 #include "ids.h"
4 #include "tools.h"
5 #include "php-pg.h"
6 #include "process_db.h"
7
8 static void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *);
9 static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv)
10 {
11 void *ret;
12 unsigned int num_args;
13
14 num_args = e->This.u2.num_args;
15 xlog(1, "%s: e=%p num_args=%hu\n",
16 __func__, e, num_args);
17
18 ret = old_pg_last_error(e, retv);
19 if (!retv)
20 return ret;
21 //php_zval_dump(" retv: ", retv);
22
23 return ret;
24 }
25
26 static void *(*old_pg_close)(struct zend_execute_data *, struct zval *);
27 static void *my_pg_close(struct zend_execute_data *e, struct zval *retv)
28 {
29 void *ret;
30 unsigned int num_args, s;
31 struct zval *z;
32 struct nd_db_conn c;
33
34 num_args = e->This.u2.num_args;
35 //xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
36
37 c.type = 'P';
38 c.stable = 0;
39 c.ex = NULL; // TODO
40 if (num_args == 1) {
41 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
42 // handler, may be null
43 z = (struct zval *) e + s; s++;
44 c.dbh = z->value.p;
45 //xlog(101, " h=%p\n", c.dbh);
46 } else {
47 c.dbh = NULL;
48 }
49
50 ret = old_pg_close(e, retv);
51 ninedogs_process_db("pg_close", NINEDOGS_DB_CONN_CLOSE, &c);
52
53 return ret;
54 }
55
56 static void *(*old_pg_connect)(struct zend_execute_data *, struct zval *);
57 static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv)
58 {
59 void *ret;
60 unsigned int num_args, s;
61 struct zval *z;
62 struct zend_string *q;
63 struct nd_db_conn c;
64
65 num_args = e->This.u2.num_args;
66 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
67
68 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
69 c.type = 'P';
70 c.stable = 0;
71 c.ex = NULL; // TODO
72
73 // connection string
74 z = (struct zval *) e + s; s++;
75 q = z->value.str;
76 c.conn_str = q->val;
77 c.conn_str_len = q->len;
78 //xlog(50, " conn[%u]: %s\n", c.conn_str_len, c.conn_str);
79
80 ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_START, &c);
81 ret = old_pg_connect(e, retv);
82 if (!retv) {
83 xlog(0, "DEBUG: old_pg_connect returned retv NULL\n");
84 return ret;
85 }
86
87 php_zval_dump(" retv: ", retv);
88 // TODO: how to test for error? if (core_globals.last_error_message) {
89
90 // PHP7 returns resource, PHP8.1 returns object
91 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
92 c.dbh = retv->value.p;
93 else
94 c.dbh = NULL;
95 ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_END, &c);
96
97 return ret;
98 }
99
100 static void *(*old_pg_pconnect)(struct zend_execute_data *, struct zval *);
101 static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv)
102 {
103 void *ret;
104 unsigned int num_args, s;
105 struct zval *z;
106 struct zend_string *q;
107 struct nd_db_conn c;
108
109 num_args = e->This.u2.num_args;
110 xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
111
112 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
113 c.type = 'P';
114 c.stable = 0;
115 c.ex = NULL; // TODO
116
117 // connection string
118 z = (struct zval *) e + s; s++;
119 q = z->value.str;
120 c.conn_str = q->val;
121 c.conn_str_len = q->len;
122 xlog(50, " conn: %s\n", c.conn_str);
123
124 ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_START, &c);
125 ret = old_pg_pconnect(e, retv);
126 if (!retv)
127 return ret;
128
129 php_zval_dump(" retv: ", retv);
130 // TODO: how to test for error? if (core_globals.last_error_message) {
131
132 // PHP7 returns resource, PHP8.1 returns object
133 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
134 c.dbh = retv->value.p;
135 else
136 c.dbh = NULL;
137 ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_END, &c);
138
139 return ret;
140 }
141
142 static void *(*old_pg_affected_rows)(struct zend_execute_data *, struct zval *);
143
144 static void *(*old_pg_free_result)(struct zend_execute_data *, struct zval *);
145 static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv)
146 {
147 struct free_result fr;
148
149 unsigned int num_args = e->This.u2.num_args;
150 xlog(200, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
151 //php_zed_dump(" e: ", e);
152 //php_zval_dump(" retv: ", retv);
153
154 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
155 fr.type = 'P';
156
157 // res
158 struct zval *z = (struct zval *) e + s; s++;
159 fr.res = z->value.p;
160
161 void *ret = old_pg_free_result(e, retv);
162 // 'ret' is null here
163
164 if (retv->u1.v.type == 3) { // true
165 fr.ok = 1;
166 } else {
167 // TODO: can we get an error code here?
168 fr.ok = 0;
169 }
170
171 ninedogs_process_db("pg_free_result", NINEDOGS_DB_FREE_RESULT, &fr);
172
173 return ret;
174 }
175
176 static void *(*old_pg_num_rows)(struct zend_execute_data *, struct zval *);
177 static void *my_pg_num_rows(struct zend_execute_data *e, struct zval *retv)
178 {
179 void *ret;
180
181 //unsigned int num_args = e->This.u2.num_args;
182 //xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
183 //php_zed_dump(" e: ", e);
184 //php_zval_dump(" retv: ", retv);
185
186 ret = old_pg_num_rows(e, retv);
187 if (!retv)
188 return ret;
189
190 //php_zval_dump(" retv: ", retv);
191
192 return ret;
193 }
194
195 static void php_pg_set_last_error(struct zend_execute_data *e,
196 struct zval *dbh, struct query *q)
197 {
198 struct zval rz;
199
200 e->This.u2.num_args = dbh ? 1 : 0;
201 if (dbh)
202 php_set_para(e, 0, dbh);
203
204 // TODO: we need also the numeric representation of the error!
205 xlog(50, " calling pg_last_error...\n");
206 old_pg_last_error(e, &rz);
207 //xlog(1, " pg_last_error returned %p; type=%s value=%s\n",
208 // tr, php_get_type(&rz), php_get_value(&rz));
209
210 if (rz.u1.v.type == 6) { // string
211 q->err = rz.value.str->val;
212 q->err_len = rz.value.str->len;
213 xlog(40, "%s: set error to [%s]\n", __func__, q->err);
214 } else {
215 q->err = "?";
216 q->err_len = 1;
217 }
218 }
219
220 static void php_pg_set_num_aff(struct zend_execute_data *e, struct zval *res,
221 struct query *q)
222 {
223 struct zval rz;
224
225 e->This.u2.num_args = 1;
226
227 php_set_para(e, 0, res);
228
229 xlog(100, " calling old pg_num_rows...\n");
230 //php_zed_dump(" e: ", e);
231 old_pg_num_rows(e, &rz);
232 php_zval_dump(" rz: ", &rz);
233 q->num = rz.value.lval;
234
235 xlog(100, " calling old pg_affected_rows...\n");
236 //php_zed_dump(" e: ", e);
237 old_pg_affected_rows(e, &rz);
238 php_zval_dump(" rz: ", &rz);
239 q->aff = rz.value.lval;
240 }
241
242 static void *(*old_pg_query)(struct zend_execute_data *, struct zval *);
243 static void *my_pg_query(struct zend_execute_data *e, struct zval *retv)
244 {
245 void *ret;
246 unsigned int num_args, copy_num_args, s;
247 struct zend_string *q;
248 struct zval *dbh = NULL, *z, copy_para, *para;
249 char do_restore = 0;
250 struct query qs;
251
252 num_args = e->This.u2.num_args;
253
254 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
255
256 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
257 para = (struct zval *) e + s;
258 nd_db_qs_init('P', &qs);
259
260 if (num_args == 2) {
261 // link
262 z = (struct zval *) e + s; s++;
263 //php_zval_dump(" dbh: ", z);
264 qs.dbh = z->value.p;
265 } else {
266 qs.dbh = NULL;
267 }
268
269 // query
270 z = (struct zval *) e + s; s++;
271 q = z->value.str;
272 xlog(50, " query=%s\n", q->val);
273 qs.q = q->val;
274 qs.q_len = q->len;
275
276 ninedogs_process_db("pg_query", NINEDOGS_DB_QUERY_START, &qs);
277 ret = old_pg_query(e, retv);
278 if (!retv)
279 return ret;
280
281 xlog(100, " old %s returned type=%s value=%s\n",
282 __func__, php_get_type(retv), php_get_value(retv));
283
284 copy_num_args = num_args;
285 memcpy(&copy_para, para, sizeof(struct zval));
286
287 if (retv->u1.v.type == 2) { // false
288 php_pg_set_last_error(e, dbh, &qs); // TODO is qs.res set here?
289 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
290 qs.res = retv->value.p;
291 php_pg_set_num_aff(e, retv, &qs);
292 do_restore = 1;
293 }
294
295 e->This.u2.num_args = copy_num_args;
296 if (do_restore)
297 memcpy(para, &copy_para, sizeof(struct zval));
298
299 ninedogs_process_db("pg_query", NINEDOGS_DB_QUERY_END, &qs);
300
301 return ret;
302 }
303
304 static void *(*old_pg_send_query)(struct zend_execute_data *, struct zval *);
305 static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv)
306 {
307 void *ret;
308 unsigned int num_args, s;
309 struct zend_string *q;
310 struct zval *dbh = NULL, *z;
311 struct query qs;
312
313 num_args = e->This.u2.num_args;
314 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
315
316 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
317 nd_db_qs_init('P', &qs);
318
319 // link
320 z = (struct zval *) e + s; s++;
321 php_zval_dump(" dbh: ", z);
322 qs.dbh = z->value.p;
323
324 // query
325 z = (struct zval *) e + s; s++;
326 q = z->value.str;
327 qs.q = q->val;
328 qs.q_len = q->len;
329 xlog(100, " query=%s\n", qs.q);
330
331 ninedogs_process_db("pg_send_query", NINEDOGS_DB_QUERY_START, &qs);
332 ret = old_pg_send_query(e, retv);
333 if (!retv)
334 return ret;
335
336 xlog(101, " old %s returned type=%s value=%s\n",
337 __func__, php_get_type(retv), php_get_value(retv));
338
339 qs.res = NULL;
340 if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int
341 php_pg_set_last_error(e, dbh, &qs);
342 } else if (retv->u1.v.type == 3) { // true = success
343 qs.num = qs.aff = 0;
344 qs.res = (void *) 1; // signal ok
345 }
346
347 ninedogs_process_db("pg_send_query", NINEDOGS_DB_QUERY_END, &qs);
348
349 return ret;
350 }
351
352 // TODO: not clear if on PHP 7 the parameter could be null
353 static void *(*old_pg_get_result)(struct zend_execute_data *, struct zval *);
354 static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv)
355 {
356 void *ret;
357 unsigned int num_args, copy_num_args, s;
358 struct zval *dbh = NULL, *z, copy_para, *para;
359 char do_restore = 0;
360 struct query qs;
361
362 num_args = e->This.u2.num_args;
363 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
364
365 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
366 para = (struct zval *) e + s;
367 nd_db_qs_init('P', &qs);
368
369 // link
370 z = (struct zval *) e + s; s++;
371 //php_zval_dump(" dbh: ", z);
372 qs.dbh = z->value.p;
373
374 ninedogs_process_db("pg_get_result", NINEDOGS_DB_QUERY_START, &qs);
375 ret = old_pg_get_result(e, retv);
376 if (!retv)
377 return ret;
378
379 xlog(100, " old %s returned type=%s value=%s\n",
380 __func__, php_get_type(retv), php_get_value(retv));
381
382 copy_num_args = num_args;
383 memcpy(&copy_para, para, sizeof(struct zval));
384
385 if (retv->u1.v.type == 2) { // false
386 php_pg_set_last_error(e, dbh, &qs);
387 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
388 qs.err = NULL;
389 qs.res = retv->value.p;
390 php_pg_set_num_aff(e, retv, &qs);
391 do_restore = 1;
392 }
393
394 e->This.u2.num_args = copy_num_args;
395 if (do_restore)
396 memcpy(para, &copy_para, sizeof(struct zval));
397
398 ninedogs_process_db("pg_get_result", NINEDOGS_DB_QUERY_END, &qs);
399
400 return ret;
401 }
402
403 static void *(*old_pg_query_params)(struct zend_execute_data *, struct zval *);
404 static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv)
405 {
406 void *ret;
407 unsigned int num_args, s;
408 struct zval copy_para, *para, *z;
409 struct zend_string *q;
410 unsigned int copy_num_args;
411 void *dbh = NULL;
412 char do_restore = 0;
413 struct query qs;
414
415 num_args = e->This.u2.num_args;
416 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
417 //php_zed_dump(" e0: ", e);
418 //php_zval_dump(" retv0: ", retv);
419
420 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
421 para = (struct zval *) e + s;
422 qs.type = 'P';
423
424 if (num_args == 3) {
425 // link
426 z = (struct zval *) e + s; s++;
427 qs.dbh = z->value.p;
428 } else {
429 qs.dbh = NULL;
430 }
431
432 // query
433 z = (struct zval *) e + s; s++;
434 q = z->value.str;
435 qs.q = q->val;
436 qs.q_len = q->len;
437
438 // params (array)
439 z = (struct zval *) e + s; s++;
440 struct zend_array *za = z->value.arr;
441 zend_array_to_params_array(&qs.params, za);
442
443 ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_START, &qs);
444 ret = old_pg_query_params(e, retv);
445 //xlog(200, " old %s: type=%s value=%s\n",
446 // __func__, php_get_type(retv), php_get_value(retv));
447 //php_zed_dump(" e1: ", e);
448 //php_zval_dump(" retv after calling old func: ", retv);
449
450 copy_num_args = e->This.u2.num_args;
451 memcpy(&copy_para, para, sizeof(struct zval));
452
453 if (retv->u1.v.type == 2) { // false
454 php_pg_set_last_error(e, dbh, &qs);
455 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
456 qs.res = retv->value.p;
457 php_pg_set_num_aff(e, retv, &qs);
458 do_restore = 1;
459 }
460
461 //php_zval_dump(" retv before ret: ", retv);
462
463 e->This.u2.num_args = copy_num_args;
464 if (do_restore)
465 memcpy(para, &copy_para, sizeof(struct zval));
466
467 ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_END, &qs);
468
469 return ret;
470 }
471
472 static void *(*old_pg_send_query_params)(struct zend_execute_data *, struct zval *);
473 static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *retv)
474 {
475 void *ret;
476 unsigned int s;
477 struct zval *z;
478 struct zval *dbh;
479 struct zend_string *q;
480 struct query qs;
481
482 unsigned int num_args = e->This.u2.num_args;
483 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
484 //php_zed_dump(" e0: ", e);
485 //php_zval_dump(" retv0: ", retv);
486
487 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
488 qs.type = 'P';
489
490 // link
491 dbh = (struct zval *) e + s; s++;
492 qs.dbh = dbh->value.p;
493
494 // query
495 z = (struct zval *) e + s; s++;
496 q = z->value.str;
497 qs.q = q->val;
498 qs.q_len = q->len;
499
500 // params (array)
501 z = (struct zval *) e + s; s++;
502 struct zend_array *za = z->value.arr;
503 zend_array_to_params_array(&qs.params, za);
504
505 ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_START, &qs);
506 ret = old_pg_send_query_params(e, retv);
507 //xlog(200, " old %s: type=%s value=%s\n",
508 // __func__, php_get_type(retv), php_get_value(retv));
509 //php_zed_dump(" e1: ", e);
510 //php_zval_dump(" retv after calling old func: ", retv);
511
512 qs.res = NULL;
513 if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int (probably 0)
514 php_pg_set_last_error(e, dbh, &qs);
515 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
516 qs.num = qs.aff = 0;
517 qs.res = (void *) 1; // signal ok
518 }
519
520 ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_END, &qs);
521
522 return ret;
523 }
524
525 void php_pg_hook(struct zend_function_entry *fe)
526 {
527 if (strcmp(fe->fname, "pg_close") == 0) {
528 old_pg_close = fe->handler;
529 fe->handler = my_pg_close;
530 } else if (strcmp(fe->fname, "pg_connect") == 0) {
531 old_pg_connect = fe->handler;
532 fe->handler = my_pg_connect;
533 } else if (strcmp(fe->fname, "pg_pconnect") == 0) {
534 old_pg_pconnect = fe->handler;
535 fe->handler = my_pg_pconnect;
536 } else if (strcmp(fe->fname, "pg_num_rows") == 0) {
537 old_pg_num_rows = fe->handler;
538 fe->handler = my_pg_num_rows;
539 } else if (strcmp(fe->fname, "pg_affected_rows") == 0) {
540 old_pg_affected_rows = fe->handler;
541 } else if (strcmp(fe->fname, "pg_free_result") == 0) {
542 old_pg_free_result = fe->handler;
543 fe->handler = my_pg_free_result;
544 } else if (strcmp(fe->fname, "pg_query") == 0) {
545 old_pg_query = fe->handler;
546 fe->handler = my_pg_query;
547 } else if (strcmp(fe->fname, "pg_send_query") == 0) {
548 old_pg_send_query = fe->handler;
549 fe->handler = my_pg_send_query;
550 } else if (strcmp(fe->fname, "pg_query_params") == 0) {
551 old_pg_query_params = fe->handler;
552 fe->handler = my_pg_query_params;
553 } else if (strcmp(fe->fname, "pg_send_query_params") == 0) {
554 old_pg_send_query_params = fe->handler;
555 fe->handler = my_pg_send_query_params;
556 } else if (strcmp(fe->fname, "pg_last_error") == 0) {
557 old_pg_last_error = fe->handler;
558 fe->handler = my_pg_last_error;
559 } else if (strcmp(fe->fname, "pg_get_result") == 0) {
560 old_pg_get_result = fe->handler;
561 fe->handler = my_pg_get_result;
562 } else {
563 //xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname);
564 }
565 }
File agent/php-pg.h added (mode: 100644) (index 0000000..a460cec)
1 #include "php-core.h"
2
3 void php_pg_hook(struct zend_function_entry *fe);
4
File agent/php.TODO changed (mode: 100644) (index ca81503..b31b4f2)
1 1 [ ] We need to fill qs->err_code using PGSQL_DIAG_SQLSTATE. [ ] We need to fill qs->err_code using PGSQL_DIAG_SQLSTATE.
2 2 [ ] Capture pg_close ($db is optional). [ ] Capture pg_close ($db is optional).
3 [ ] MySQL: decode parameters for 'mysqli_stmt_bind_param'.
3 4 [ ] [ ]
File agent/php.c changed (mode: 100644) (index b6613e0..231485b)
38 38 #include <netdb.h> #include <netdb.h>
39 39 #include <ctype.h> #include <ctype.h>
40 40
41 #include "ids.h"
42 #include "php.h"
41 //#include "ids.h"
43 42 #include "tools.h" #include "tools.h"
44 #include "ctools.h"
45 #include "process_db.h"
46 #include "process_url.h"
47 #include "curl.h"
48
49
50 extern void *(*old_malloc)(size_t size);
51 extern void (*old_free)(void *p);
52
53
54 struct zend_function_entry
55 {
56 const char *fname;
57 void *handler;
58 void *arg_info;
59 unsigned int num_args;
60 unsigned int flags;
61 };
62
63 struct zend_module_entry
64 {
65 unsigned short size;
66 unsigned short pad1;
67 unsigned int zend_api;
68 unsigned char zend_debug;
69 unsigned char zts;
70 unsigned char pad2[6];
71 void *ini_entry;
72 void *deps;
73 const char *name;
74 struct zend_function_entry *functions;
75 void *junk[5];
76 const char *version;
77 size_t globals_size;
78 void *globals;
79 void *globals_ctor;
80 void *globals_dtor;
81 void *post_deactivate_func;
82 int module_started;
83 unsigned char type;
84 unsigned char pad3[3];
85 void *handle;
86 int module_number;
87 int pad4;
88 const char *build_id;
89 };
90
91 typedef long zend_long;
92 typedef unsigned long zend_ulong;
93
94 struct zend_refcounted_h
95 {
96 unsigned int refcount;
97 unsigned int type_info;
98 };
99
100 struct zend_resource
101 {
102 struct zend_refcounted_h gc;
103 int handle;
104 int type;
105 void *ptr;
106 };
107
108 struct zend_string
109 {
110 struct zend_refcounted_h gc;
111 zend_ulong hash;
112 size_t len;
113 char val[1];
114 char pad1[7];
115 };
116
117 struct zend_array
118 {
119 struct zend_refcounted_h gc;
120 union {
121 struct {
122 unsigned char flags;
123 unsigned char _unused;
124 unsigned char nIteratorsCount;
125 unsigned char _unused2;
126 } v;
127 unsigned int flags;
128 } u;
129 unsigned int nTableMask;
130 union {
131 uint32_t *arHash;
132 struct Bucket *arData;
133 struct zval *arPacked;
134 };
135 unsigned int nNumUsed;
136 unsigned int nNumOfElements;
137 unsigned int nTableSize;
138 unsigned int nInternalPointer;
139 zend_long nNextFreeElement;
140 void *dtor;
141 };
142
143 union zend_value
144 {
145 zend_long lval;
146 double dval;
147 void *p;
148 struct zend_string *str;
149 struct zend_array *arr;
150 struct zend_resource *res;
151 struct zend_reference *ref;
152 struct zval *zv;
153 struct {
154 unsigned int w1;
155 unsigned int w2;
156 } ww;
157 };
158
159 struct zval
160 {
161 union zend_value value;
162 union {
163 unsigned int type_info;
164 struct {
165 unsigned char type;
166 unsigned char type_flags;
167 union {
168 unsigned short extra;
169 } u;
170 } v;
171 } u1;
172 union {
173 unsigned int num_args;
174 } u2;
175 };
176
177 struct Bucket
178 {
179 struct zval val;
180 zend_ulong h;
181 struct zend_string *key;
182 };
183
184 struct zend_reference
185 {
186 struct zend_refcounted_h gc;
187 struct zval val;
188 void *sources;
189 };
190
191 struct zend_execute_data
192 {
193 void *opline;
194 struct zend_execute_data *call;
195 struct zval *return_value;
196 void *func;
197 struct zval This;
198 struct zend_execute_data *prev;
199 struct zend_array *symbol_table;
200 void **runtime_cache;
201 struct zend_array *extra_named_params;
202 };
203
204 struct TODOpgsql_link_handle
205 {
206 void *conn; // PGconn
207 struct zend_string *hash;
208 struct HashTable *notices;
209 unsigned char persistent; // bool
210 //zend_object std;
211 unsigned char pad1[7];
212 };
213
214 static char *php_get_value(const struct zval *z)
215 {
216 static char ret[4096];
217 const struct zval *next;
218
219 if (!z)
220 return "NULL";
221
222 switch (z->u1.v.type) {
223 case 0: return "";
224 case 1: return "";
225 case 2: return "";
226 case 3: return "";
227 case 4: snprintf(ret, sizeof(ret), "%ld", z->value.lval); return ret;
228 case 5: snprintf(ret, sizeof(ret), "%f", z->value.dval); return ret;
229 case 6:
230 struct zend_string *zs = z->value.str;
231 return zs->val;
232 case 8:
233 snprintf(ret, sizeof(ret), "%p", z->value.p); return ret;
234 case 9:
235 snprintf(ret, sizeof(ret), "%p", z->value.p); return ret;
236 case 10:
237 next = &z->value.ref->val;
238 return php_get_value(next);
239 case 12:
240 next = z->value.zv;
241 return php_get_value(next);
242 default:
243 snprintf(ret, sizeof(ret), "?%hhu: %p",
244 z->u1.v.type, z->value.str); return ret;
245 }
246 }
247
248 static char *php_get_type(const struct zval *z)
249 {
250 static char s[8];
251
252 if (!z)
253 return "NULL";
254
255 switch (z->u1.v.type) {
256 case 0: return "undef";
257 case 1: return "null";
258 case 2: return "false";
259 case 3: return "true";
260 case 4: return "long";
261 case 5: return "double";
262 case 6: return "string";
263 case 7: return "array";
264 case 8: return "object";
265 case 9: return "resource";
266 case 10: return "ref";
267 case 12: return "indirect";
268 default: sprintf(s, "?%hhu", z->u1.v.type); return s;
269 }
270 }
271
272 static void php_zval_dump_buf(char *buf, const size_t size,
273 const char *prefix, const struct zval *z)
274 {
275 if (!z) {
276 snprintf(buf, size, "zval is null");
277 return;
278 }
279
280 snprintf(buf, size, "%s%p: type=%s value=[%s] type_flags=%hhu extra=%hu num_args=%u",
281 prefix, z, php_get_type(z), php_get_value(z),
282 z->u1.v.type_flags,
283 z->u1.v.u.extra, z->u2.num_args);
284 }
285
286 static void php_zval_dump(const char *prefix, const struct zval *z)
287 {
288 char s[4096];
289
290 php_zval_dump_buf(s, sizeof(s), prefix, z);
291 xlog(100, "%s\n", s);
292 }
293
294 static void php_zed_dump(const char *prefix, struct zend_execute_data *p)
295 {
296 unsigned int num_args, s, i;
297 struct zval *z;
298 char x[64];
299
300 if (!p) {
301 xlog(100, "%szed is null!\n", prefix);
302 return;
303 }
304
305 num_args = p->This.u2.num_args;
306 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
307 dump(100, "zed", p, sizeof(struct zval) * (s + num_args));
308
309 xlog(100, "%szed: p=%p num_args=%hu return_value=%p\n",
310 prefix, p, num_args, p->return_value);
311 //php_zval_dump(prefix, p->return_value);
312 snprintf(x, sizeof(x), "%s This: ", prefix);
313 php_zval_dump(x, &p->This);
314
315 for (i = 0; i < num_args; i++) {
316 char zs[1024];
317
318 z = (struct zval *) p + s; s++;
319 php_zval_dump_buf(zs, sizeof(zs), "", z);
320 xlog(100, "%s para %u: %s\n", prefix, i, zs);
321 }
322 }
323
324 // TODO this is really not related to parameters - rename it
325 // this is obsolete. Use 'zend_to_binary'
326 static void zend_array_to_params_array(struct params_array *p, struct zend_array *za)
327 {
328 unsigned int i = 0;
329
330 xlog(100, " %s: nTableMask=0x%x nNumUsed=%u nNumOfElements=%u nTableSize=%u"
331 " nInternalPointer=%u flags=0x%x[%s]\n",
332 __func__,
333 za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize,
334 za->nInternalPointer, za->u.flags, za->u.flags & 4 ? "packed" : "");
335
336 p->len = za->nNumUsed;
337 if (p->len > ND_PARAMS_MAX)
338 p->len = ND_PARAMS_MAX;
339
340 struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed;
341 for (; bs != be; bs++) {
342 struct zval *_z = &bs->val;
343
344 if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT
345 _z = _z->value.zv;
346
347 if (_z->u1.v.type == 0 /*IS_UNDEF*/) {
348 xlog(101, " para h=%lu: type undef\n", bs->h);
349 continue;
350 }
351
352 if (_z->u1.v.type == 10) { // REFERENCE
353 xlog(101, " is a reference!\n");
354 _z = &_z->value.ref->val;
355 }
356
357 struct zend_string *zs = bs->key;
358 xlog(101, " para: bs=%p h=%lu key=[%p] type %s: val: %s\n",
359 bs, bs->h, zs, php_get_type(_z), php_get_value(_z));
360
361 if (_z->u1.v.type == 1) {
362 p->list[i].type = ND_TYPE_NULL;
363 } else if (_z->u1.v.type == 2) {
364 p->list[i].type = ND_TYPE_STRING;
365 p->list[i].str = "false";
366 p->list[i].length = 5;
367 } else if (_z->u1.v.type == 3) {
368 p->list[i].type = ND_TYPE_STRING;
369 p->list[i].str = "true";
370 p->list[i].length = 4;
371 } else if (_z->u1.v.type == 4) {
372 p->list[i].type = ND_TYPE_LONG;
373 p->list[i].l = _z->value.lval;
374 } else if (_z->u1.v.type == 5) {
375 p->list[i].type = ND_TYPE_DOUBLE;
376 p->list[i].d = _z->value.dval;
377 } else if (_z->u1.v.type == 6) {
378 p->list[i].type = ND_TYPE_STRING;
379 struct zend_string *zs = _z->value.str;
380 p->list[i].str = zs->val;
381 p->list[i].length = zs->len;
382 } else {
383 p->list[i].type = ND_TYPE_NULL;
384 xlog(1, " %s: I do not how to encode %d type! Encode as NULL\n",
385 __func__, _z->u1.v.type);
386 }
387
388 i++;
389 if (i == p->len)
390 break;
391 }
392 }
393
394 static unsigned int zend_simple_to_binary(unsigned char *out, const size_t out_size,
395 struct zval *z)
396 {
397 unsigned int off = 0;
398 uint16_t u16;
399 uint64_t u64;
400
401 if (off + 1 + 8 > out_size) // 1+8 for a long
402 return 0;
403
404 if (z->u1.v.type == 1) {
405 out[off++] = ND_TYPE_NULL;
406 } else if (z->u1.v.type == 2) {
407 out[off++] = ND_TYPE_FALSE;
408 } else if (z->u1.v.type == 3) {
409 out[off++] = ND_TYPE_TRUE;
410 } else if (z->u1.v.type == 4) {
411 out[off++] = ND_TYPE_LONG;
412 u64 = htobe64(z->value.lval);
413 memcpy(out + off, &u64, 8); off += 8;
414 } else if (z->u1.v.type == 5) {
415 out[off++] = ND_TYPE_DOUBLE;
416 uint64_t u64 = htobe64(z->value.lval);
417 memcpy(out + off, &u64, 8); off += 8;
418 } else if (z->u1.v.type == 6) {
419 out[off++] = ND_TYPE_STRING;
420 struct zend_string *zs = z->value.str;
421 if (off + 2 + zs->len > out_size)
422 return 0;
423 u16 = htobe16(zs->len);
424 memcpy(out + off, &u16, 2); off += 2;
425 memcpy(out + off, zs->val, zs->len); off += zs->len;
426 } else if (z->u1.v.type == 8) { // object
427 out[off++] = ND_TYPE_POINTER;
428 u64 = htobe64(z->value.lval);
429 memcpy(out + off, &u64, 8); off += 8;
430 } else if (z->u1.v.type == 9) { // resource
431 out[off++] = ND_TYPE_POINTER;
432 u64 = htobe64(z->value.lval);
433 memcpy(out + off, &u64, 8); off += 8;
434 } else {
435 out[off++] = ND_TYPE_UNK;
436 xlog(1, " %s: I do not how to encode %d type! Encode as NULL\n",
437 __func__, z->u1.v.type);
438 }
439
440 return off;
441 }
442
443 // Returns the number of bytes stored in 'out'
444 static unsigned int zend_array_to_binary(unsigned char *out, const size_t out_size,
445 struct zend_array *za)
446 {
447 xlog(100, " %s: nTableMask=0x%x nNumUsed=%u nNumOfElements=%u nTableSize=%u"
448 " nInternalPointer=%u flags=0x%x[%s]\n",
449 __func__,
450 za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize,
451 za->nInternalPointer, za->u.flags, za->u.flags & 4 ? "packed" : "");
452
453 unsigned int off = 0;
454 out[off++] = ND_TYPE_ARRAY_START;
455
456 struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed;
457 for (; bs != be; bs++) {
458 struct zval *_z = &bs->val;
459
460 if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT
461 _z = _z->value.zv;
462
463 if (_z->u1.v.type == 0 /*IS_UNDEF*/) {
464 xlog(101, " para h=%lu: type undef\n", bs->h);
465 continue;
466 }
467
468 if (_z->u1.v.type == 10) { // REFERENCE
469 xlog(101, " is a reference!\n");
470 _z = &_z->value.ref->val;
471 }
472
473 struct zend_string *zs = bs->key;
474 xlog(101, " para: bs=%p h=%lu key=[%p] type %s: val: %s\n",
475 bs, bs->h, zs, php_get_type(_z), php_get_value(_z));
476
477 unsigned int r = zend_simple_to_binary(out + off, out_size - off, _z);
478 if (r == 0)
479 break;
480 off += r;
481 }
482
483 out[off++] = ND_TYPE_ARRAY_END;
484
485 return off;
486 }
487
488 // Returns the number of bytes stored in 'out'
489 static unsigned int zend_to_binary(unsigned char *out, const size_t out_size,
490 struct zval *z)
491 {
492 if (z->u1.v.type == 7)
493 return zend_array_to_binary(out, out_size, z->value.arr);
494
495 return zend_simple_to_binary(out, out_size, z);
496 }
497
498 static void php_set_para(struct zend_execute_data *e, const unsigned int i,
499 const struct zval *para)
500 {
501 unsigned int s;
502 struct zval *dst;
503
504 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
505 dst = (struct zval *) e + s + i;
506 memcpy(dst, para, sizeof(struct zval));
507 }
508
509
510 static void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *);
511 static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv)
512 {
513 void *ret;
514 unsigned int num_args;
515
516 num_args = e->This.u2.num_args;
517 xlog(1, "%s: e=%p num_args=%hu\n",
518 __func__, e, num_args);
519
520 ret = old_pg_last_error(e, retv);
521 if (!retv)
522 return ret;
523 //php_zval_dump(" retv: ", retv);
524
525 return ret;
526 }
527
528 static void *(*old_pg_close)(struct zend_execute_data *, struct zval *);
529 static void *my_pg_close(struct zend_execute_data *e, struct zval *retv)
530 {
531 void *ret;
532 unsigned int num_args, s;
533 struct zval *z;
534 struct conn cs;
535
536 num_args = e->This.u2.num_args;
537 //xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
538
539 cs.type = 'P';
540 if (num_args == 1) {
541 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
542 // handler, may be null
543 z = (struct zval *) e + s; s++;
544 cs.dbh = z->value.p;
545 //xlog(101, " h=%p\n", cs.dbh);
546 } else {
547 cs.dbh = NULL;
548 }
549
550 ret = old_pg_close(e, retv);
551 ninedogs_process_db("pg_close", NINEDOGS_DB_CONN_CLOSE, &cs);
552
553 return ret;
554 }
555
556 static void *(*old_pg_connect)(struct zend_execute_data *, struct zval *);
557 static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv)
558 {
559 void *ret;
560 unsigned int num_args, s;
561 struct zval *z;
562 struct zend_string *q;
563 struct conn cs;
564
565 num_args = e->This.u2.num_args;
566 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
567
568 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
569 cs.type = 'P';
570
571 // connection string
572 z = (struct zval *) e + s; s++;
573 q = z->value.str;
574 cs.conn_str = q->val;
575 cs.conn_str_len = q->len;
576 //xlog(50, " conn[%u]: %s\n", cs.conn_str_len, cs.conn_str);
577
578 ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_START, &cs);
579 ret = old_pg_connect(e, retv);
580 if (!retv) {
581 xlog(0, "DEBUG: old_pg_connect returned retv NULL\n");
582 return ret;
583 }
584
585 php_zval_dump(" retv: ", retv);
586 // TODO: how to test for error? if (core_globals.last_error_message) {
587
588 // PHP7 returns resource, PHP8.1 returns object
589 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
590 cs.dbh = retv->value.p;
591 else
592 cs.dbh = NULL;
593 ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_END, &cs);
594
595 return ret;
596 }
597
598 static void *(*old_pg_pconnect)(struct zend_execute_data *, struct zval *);
599 static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv)
600 {
601 void *ret;
602 unsigned int num_args, s;
603 struct zval *z;
604 struct zend_string *q;
605 struct conn cs;
606
607 num_args = e->This.u2.num_args;
608 xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
609
610 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
611 cs.type = 'P';
612
613 // connection string
614 z = (struct zval *) e + s; s++;
615 q = z->value.str;
616 cs.conn_str = q->val;
617 cs.conn_str_len = q->len;
618 xlog(50, " conn: %s\n", cs.conn_str);
619
620 ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_START, &cs);
621 ret = old_pg_pconnect(e, retv);
622 if (!retv)
623 return ret;
624
625 php_zval_dump(" retv: ", retv);
626 // TODO: how to test for error? if (core_globals.last_error_message) {
627
628 // PHP7 returns resource, PHP8.1 returns object
629 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
630 cs.dbh = retv->value.p;
631 else
632 cs.dbh = NULL;
633 ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_END, &cs);
634
635 return ret;
636 }
637
638 static void *(*old_pg_affected_rows)(struct zend_execute_data *, struct zval *);
639
640 static void *(*old_pg_free_result)(struct zend_execute_data *, struct zval *);
641 static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv)
642 {
643 void *ret;
644 unsigned int s;
645 struct zval *z;
646 struct free_result fr;
647
648 unsigned int num_args = e->This.u2.num_args;
649 xlog(200, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
650 //php_zed_dump(" e: ", e);
651 //php_zval_dump(" retv: ", retv);
652
653 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
654 fr.type = 'P';
655
656 // res
657 z = (struct zval *) e + s; s++;
658 fr.res = z->value.p;
659
660 ret = old_pg_free_result(e, retv);
661 // 'ret' is null here
662
663 if (retv->u1.v.type == 3) { // true
664 fr.ok = 1;
665 } else {
666 // TODO: can we get an error code here?
667 fr.ok = 0;
668 }
669
670 ninedogs_process_db("pg_free_result", NINEDOGS_DB_FREE_RESULT, &fr);
671
672 return ret;
673 }
674
675 static void *(*old_pg_num_rows)(struct zend_execute_data *, struct zval *);
676 static void *my_pg_num_rows(struct zend_execute_data *e, struct zval *retv)
677 {
678 void *ret;
679
680 //unsigned int num_args = e->This.u2.num_args;
681 //xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
682 //php_zed_dump(" e: ", e);
683 //php_zval_dump(" retv: ", retv);
684
685 ret = old_pg_num_rows(e, retv);
686 if (!retv)
687 return ret;
688
689 //php_zval_dump(" retv: ", retv);
690
691 return ret;
692 }
693
694 static void php_pg_set_last_error(struct zend_execute_data *e,
695 struct zval *dbh, struct query *q)
696 {
697 struct zval rz;
698
699 e->This.u2.num_args = dbh ? 1 : 0;
700 if (dbh)
701 php_set_para(e, 0, dbh);
702
703 // TODO: we need also the numeric representation of the error!
704 xlog(50, " calling pg_last_error...\n");
705 old_pg_last_error(e, &rz);
706 //xlog(1, " pg_last_error returned %p; type=%s value=%s\n",
707 // tr, php_get_type(&rz), php_get_value(&rz));
708
709 if (rz.u1.v.type == 6) { // string
710 q->err = rz.value.str->val;
711 q->err_len = rz.value.str->len;
712 xlog(40, "%s: set error to [%s]\n", __func__, q->err);
713 } else {
714 q->err = "?";
715 q->err_len = 1;
716 }
717 }
718
719 static void php_pg_set_num_aff(struct zend_execute_data *e, struct zval *res,
720 struct query *q)
721 {
722 struct zval rz;
723
724 e->This.u2.num_args = 1;
725
726 php_set_para(e, 0, res);
727
728 //xlog(1, " calling old pg_num_rows...\n");
729 //php_zed_dump(" e: ", e);
730 old_pg_num_rows(e, &rz);
731 //php_zval_dump(" rz: ", &rz);
732 q->num = rz.value.lval;
733
734 //xlog(1, " calling old pg_affected_rows...\n");
735 //php_zed_dump(" e: ", e);
736 old_pg_affected_rows(e, &rz);
737 //php_zval_dump(" rz: ", &rz);
738 q->aff = rz.value.lval;
739 }
740
741 static void *(*old_pg_query)(struct zend_execute_data *, struct zval *);
742 static void *my_pg_query(struct zend_execute_data *e, struct zval *retv)
743 {
744 void *ret;
745 unsigned int num_args, copy_num_args, s;
746 struct zend_string *q;
747 struct zval *dbh = NULL, *z, copy_para, *para;
748 char do_restore = 0;
749 struct query qs;
750
751 num_args = e->This.u2.num_args;
752
753 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
754
755 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
756 para = (struct zval *) e + s;
757 qs.type = 'P'; // if dbh is null, we do not know the type
758 qs.params.len = 0;
759
760 if (num_args == 2) {
761 // link
762 z = (struct zval *) e + s; s++;
763 //php_zval_dump(" dbh: ", z);
764 qs.dbh = z->value.p;
765 } else {
766 qs.dbh = NULL;
767 }
768
769 // query
770 z = (struct zval *) e + s; s++;
771 q = z->value.str;
772 xlog(50, " query=%s\n", q->val);
773 qs.q = q->val;
774 qs.q_len = q->len;
775
776 ninedogs_process_db("pg_query", NINEDOGS_DB_QUERY_START, &qs);
777 ret = old_pg_query(e, retv);
778 if (!retv)
779 return ret;
780
781 xlog(100, " old %s returned type=%s value=%s\n",
782 __func__, php_get_type(retv), php_get_value(retv));
783
784 copy_num_args = num_args;
785 memcpy(&copy_para, para, sizeof(struct zval));
786
787 if (retv->u1.v.type == 2) { // false
788 php_pg_set_last_error(e, dbh, &qs); // TODO is qs.res set here?
789 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
790 qs.res = retv->value.p;
791 php_pg_set_num_aff(e, retv, &qs);
792 do_restore = 1;
793 }
794
795 e->This.u2.num_args = copy_num_args;
796 if (do_restore)
797 memcpy(para, &copy_para, sizeof(struct zval));
798
799 ninedogs_process_db("pg_query", NINEDOGS_DB_QUERY_END, &qs);
800
801 return ret;
802 }
803
804 static void *(*old_pg_send_query)(struct zend_execute_data *, struct zval *);
805 static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv)
806 {
807 void *ret;
808 unsigned int num_args, s;
809 struct zend_string *q;
810 struct zval *dbh = NULL, *z;
811 struct query qs;
812
813 num_args = e->This.u2.num_args;
814 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
815
816 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
817 qs.type = 'P';
818 qs.params.len = 0;
819
820 // link
821 z = (struct zval *) e + s; s++;
822 php_zval_dump(" dbh: ", z);
823 qs.dbh = z->value.p;
824
825 // query
826 z = (struct zval *) e + s; s++;
827 q = z->value.str;
828 qs.q = q->val;
829 qs.q_len = q->len;
830 xlog(100, " query=%s\n", qs.q);
831
832 ninedogs_process_db("pg_send_query", NINEDOGS_DB_QUERY_START, &qs);
833 ret = old_pg_send_query(e, retv);
834 if (!retv)
835 return ret;
836
837 xlog(101, " old %s returned type=%s value=%s\n",
838 __func__, php_get_type(retv), php_get_value(retv));
839
840 qs.res = NULL;
841 if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int
842 php_pg_set_last_error(e, dbh, &qs);
843 } else if (retv->u1.v.type == 3) { // true = success
844 qs.num = qs.aff = 0;
845 qs.res = (void *) 1; // signal ok
846 }
847
848 ninedogs_process_db("pg_send_query", NINEDOGS_DB_QUERY_END, &qs);
849
850 return ret;
851 }
852
853 // TODO: not clear if on PHP 7 the parameter could be null
854 static void *(*old_pg_get_result)(struct zend_execute_data *, struct zval *);
855 static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv)
856 {
857 void *ret;
858 unsigned int num_args, copy_num_args, s;
859 struct zval *dbh = NULL, *z, copy_para, *para;
860 char do_restore = 0;
861 struct query qs;
862
863 num_args = e->This.u2.num_args;
864 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
865
866 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
867 para = (struct zval *) e + s;
868 qs.type = 'P';
869 qs.q = NULL;
870 qs.params.len = 0;
871
872 // link
873 z = (struct zval *) e + s; s++;
874 //php_zval_dump(" dbh: ", z);
875 qs.dbh = z->value.p;
876
877 ninedogs_process_db("pg_get_result", NINEDOGS_DB_QUERY_START, &qs);
878 ret = old_pg_get_result(e, retv);
879 if (!retv)
880 return ret;
881
882 xlog(100, " old %s returned type=%s value=%s\n",
883 __func__, php_get_type(retv), php_get_value(retv));
884
885 copy_num_args = num_args;
886 memcpy(&copy_para, para, sizeof(struct zval));
887
888 if (retv->u1.v.type == 2) { // false
889 php_pg_set_last_error(e, dbh, &qs);
890 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
891 qs.err = NULL;
892 qs.res = retv->value.p;
893 php_pg_set_num_aff(e, retv, &qs);
894 do_restore = 1;
895 }
896
897 e->This.u2.num_args = copy_num_args;
898 if (do_restore)
899 memcpy(para, &copy_para, sizeof(struct zval));
900
901 ninedogs_process_db("pg_get_result", NINEDOGS_DB_QUERY_END, &qs);
902
903 return ret;
904 }
905
906 static void *(*old_pg_query_params)(struct zend_execute_data *, struct zval *);
907 static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv)
908 {
909 void *ret;
910 unsigned int num_args, s;
911 struct zval copy_para, *para, *z;
912 struct zend_string *q;
913 unsigned int copy_num_args;
914 void *dbh = NULL;
915 char do_restore = 0;
916 struct query qs;
917
918 num_args = e->This.u2.num_args;
919 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
920 //php_zed_dump(" e0: ", e);
921 //php_zval_dump(" retv0: ", retv);
922
923 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
924 para = (struct zval *) e + s;
925 qs.type = 'P';
926
927 if (num_args == 3) {
928 // link
929 z = (struct zval *) e + s; s++;
930 qs.dbh = z->value.p;
931 } else {
932 qs.dbh = NULL;
933 }
934
935 // query
936 z = (struct zval *) e + s; s++;
937 q = z->value.str;
938 qs.q = q->val;
939 qs.q_len = q->len;
940
941 // params (array)
942 z = (struct zval *) e + s; s++;
943 struct zend_array *za = z->value.arr;
944 zend_array_to_params_array(&qs.params, za);
945
946 ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_START, &qs);
947 ret = old_pg_query_params(e, retv);
948 //xlog(200, " old %s: type=%s value=%s\n",
949 // __func__, php_get_type(retv), php_get_value(retv));
950 //php_zed_dump(" e1: ", e);
951 //php_zval_dump(" retv after calling old func: ", retv);
952
953 copy_num_args = e->This.u2.num_args;
954 memcpy(&copy_para, para, sizeof(struct zval));
955
956 if (retv->u1.v.type == 2) { // false
957 php_pg_set_last_error(e, dbh, &qs);
958 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
959 qs.res = retv->value.p;
960 php_pg_set_num_aff(e, retv, &qs);
961 do_restore = 1;
962 }
963
964 //php_zval_dump(" retv before ret: ", retv);
965
966 e->This.u2.num_args = copy_num_args;
967 if (do_restore)
968 memcpy(para, &copy_para, sizeof(struct zval));
969
970 ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_END, &qs);
971
972 return ret;
973 }
974
975 static void *(*old_pg_send_query_params)(struct zend_execute_data *, struct zval *);
976 static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *retv)
977 {
978 void *ret;
979 unsigned int s;
980 struct zval *z;
981 struct zval *dbh;
982 struct zend_string *q;
983 struct query qs;
984
985 unsigned int num_args = e->This.u2.num_args;
986 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
987 //php_zed_dump(" e0: ", e);
988 //php_zval_dump(" retv0: ", retv);
989
990 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
991 qs.type = 'P';
992
993 // link
994 dbh = (struct zval *) e + s; s++;
995 qs.dbh = dbh->value.p;
996
997 // query
998 z = (struct zval *) e + s; s++;
999 q = z->value.str;
1000 qs.q = q->val;
1001 qs.q_len = q->len;
1002
1003 // params (array)
1004 z = (struct zval *) e + s; s++;
1005 struct zend_array *za = z->value.arr;
1006 zend_array_to_params_array(&qs.params, za);
1007
1008 ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_START, &qs);
1009 ret = old_pg_send_query_params(e, retv);
1010 //xlog(200, " old %s: type=%s value=%s\n",
1011 // __func__, php_get_type(retv), php_get_value(retv));
1012 //php_zed_dump(" e1: ", e);
1013 //php_zval_dump(" retv after calling old func: ", retv);
1014
1015 qs.res = NULL;
1016 if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int (probably 0)
1017 php_pg_set_last_error(e, dbh, &qs);
1018 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
1019 qs.num = qs.aff = 0;
1020 qs.res = (void *) 1; // signal ok
1021 }
1022
1023 ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_END, &qs);
1024
1025 return ret;
1026 }
1027
1028
1029
1030 static void *(*old_mysqli_error)(struct zend_execute_data *, struct zval *);
1031 static void *(*old_mysqli_affected_rows)(struct zend_execute_data *, struct zval *);
1032 static void *(*old_mysqli_num_rows)(struct zend_execute_data *, struct zval *);
1033 static void *(*old_mysqli_stmt_affected_rows)(struct zend_execute_data *, struct zval *);
1034 static void *(*old_mysqli_stmt_num_rows)(struct zend_execute_data *, struct zval *);
1035
1036 static void php_mysqli_set_error(struct zend_execute_data *e,
1037 struct zval *link, struct query *q)
1038 {
1039 struct zval rz;
1040
1041 e->This.u2.num_args = 1;
1042 php_set_para(e, 0, link);
1043
1044 // TODO: we need also the numeric representation of the error!
1045 xlog(50, " calling mysqli_error...\n");
1046 old_mysqli_error(e, &rz);
1047
1048 if (rz.u1.v.type == 6) { // string
1049 q->err = rz.value.str->val;
1050 q->err_len = rz.value.str->len;
1051 xlog(40, "%s: set error to [%s]\n", __func__, q->err);
1052 } else {
1053 q->err = "?";
1054 q->err_len = 1;
1055 }
1056 }
1057
1058 static void php_mysqli_set_num_aff(struct zend_execute_data *e, struct zval *res,
1059 struct query *q)
1060 {
1061 struct zval rz;
1062
1063 e->This.u2.num_args = 1;
1064
1065 //xlog(1, " calling old pg_affected_rows...\n");
1066 //php_zed_dump(" e: ", e);
1067 old_mysqli_affected_rows(e, &rz); // we need to pass a link here
1068 php_zval_dump(" aff_rows: ", &rz);
1069 q->aff = rz.value.lval;
1070
1071 php_set_para(e, 0, res);
1072 //xlog(1, " calling old pg_num_rows...\n");
1073 //php_zed_dump(" e: ", e);
1074 old_mysqli_num_rows(e, &rz); // we need a result here
1075 php_zval_dump(" num_rows: ", &rz);
1076 q->num = rz.value.lval;
1077 }
1078
1079 static void php_mysqli_stmt_set_num_aff(struct zend_execute_data *e,
1080 struct nd_db_execute *q)
1081 {
1082 struct zval rz;
1083
1084 e->This.u2.num_args = 1;
1085
1086 //xlog(1, " calling old mysqli_stmt_affected_rows...\n");
1087 //php_zed_dump(" e: ", e);
1088 old_mysqli_stmt_affected_rows(e, &rz);
1089 php_zval_dump(" aff_rows: ", &rz);
1090 q->aff = rz.value.lval;
1091
1092 //xlog(1, " calling old mysqli_stmt_num_rows...\n");
1093 //php_zed_dump(" e: ", e);
1094 old_mysqli_stmt_num_rows(e, &rz);
1095 php_zval_dump(" num_rows: ", &rz);
1096 q->num = rz.value.lval;
1097 }
1098
1099 void *(*old_mysqli_connect)(struct zend_execute_data *, struct zval *);
1100 static void *my_mysqli_connect(struct zend_execute_data *e, struct zval *retv)
1101 {
1102 void *ret;
1103 unsigned int num_args, s;
1104 struct zval *z;
1105 struct conn cs;
1106 char *host = "", *user = "", *db = "", *sock = "";
1107 int port = 0;
1108
1109 num_args = e->This.u2.num_args;
1110 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1111
1112 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1113 cs.type = 'M';
1114
1115 if (num_args >= 1) { // host
1116 z = (struct zval *) e + s; s++;
1117 //php_zval_dump(" host: ", z);
1118 if (z->u1.v.type == 6) // string
1119 host = z->value.str->val;
1120 }
1121
1122 if (num_args >= 2) { // user
1123 z = (struct zval *) e + s; s++;
1124 if (z->u1.v.type == 6) // string
1125 user = z->value.str->val;
1126 }
1127
1128 if (num_args >= 3) // pass
1129 s++;
1130
1131 if (num_args >= 4) { // db
1132 z = (struct zval *) e + s; s++;
1133 if (z->u1.v.type == 6) // string
1134 db = z->value.str->val;
1135 }
1136
1137 if (num_args >= 5) { // port
1138 z = (struct zval *) e + s; s++;
1139 if (z->u1.v.type == 4) // long
1140 port = z->value.lval;
1141 }
1142
1143 if (num_args >= 6) { // socket
1144 z = (struct zval *) e + s; s++;
1145 if (z->u1.v.type == 6) // string
1146 sock = z->value.str->val;
1147 }
1148
1149 char conn_str[512];
1150 snprintf(conn_str, sizeof(conn_str),
1151 "host=%s user=%s port=%d db=%s socket=%s",
1152 host, user, port, db, sock);
1153 cs.conn_str = conn_str;
1154 cs.conn_str_len = strlen(cs.conn_str);
1155
1156 ninedogs_process_db("mysqli_connect", NINEDOGS_DB_CONN_START, &cs);
1157 ret = old_mysqli_connect(e, retv);
1158 if (!retv) {
1159 xlog(1, "DEBUG: old_mysqli_connect returned retv NULL\n");
1160 return ret;
1161 }
1162 //php_zval_dump(" retv: ", retv);
1163 // TODO: how to test for error? if (core_globals.last_error_message) {
1164
1165 // PHP7 returns resource, PHP8.1 returns object
1166 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
1167 cs.dbh = retv->value.p;
1168 else
1169 cs.dbh = NULL;
1170 ninedogs_process_db("mysqli_connect", NINEDOGS_DB_CONN_END, &cs);
1171
1172 return ret;
1173 }
1174
1175 void *(*old_mysqli_real_connect)(struct zend_execute_data *, struct zval *);
1176 static void *my_mysqli_real_connect(struct zend_execute_data *e, struct zval *retv)
1177 {
1178 void *ret;
1179 unsigned int num_args, s;
1180 struct zval *z;
1181 struct conn cs;
1182 char *host = "", *user = "", *db = "", *sock = "";
1183 int port = 0;
1184
1185 num_args = e->This.u2.num_args;
1186 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1187
1188 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1189 cs.type = 'M';
1190 cs.flags = 0;
1191
1192 if (num_args >= 1) { // dbh
1193 z = (struct zval *) e + s; s++;
1194 if ((z->u1.v.type == 8) || (z->u1.v.type == 9)) // object or resource
1195 cs.dbh = z->value.p;
1196 }
1197
1198 if (num_args >= 2) { // host
1199 z = (struct zval *) e + s; s++;
1200 //php_zval_dump(" host: ", z);
1201 if (z->u1.v.type == 6) // string
1202 host = z->value.str->val;
1203 }
1204
1205 if (num_args >= 3) { // user
1206 z = (struct zval *) e + s; s++;
1207 if (z->u1.v.type == 6) // string
1208 user = z->value.str->val;
1209 }
1210
1211 if (num_args >= 4) // pass
1212 s++;
1213
1214 if (num_args >= 5) { // db
1215 z = (struct zval *) e + s; s++;
1216 if (z->u1.v.type == 6) // string
1217 db = z->value.str->val;
1218 }
1219
1220 if (num_args >= 6) { // port
1221 z = (struct zval *) e + s; s++;
1222 if (z->u1.v.type == 4) // long
1223 port = z->value.lval;
1224 }
1225
1226 if (num_args >= 7) { // socket
1227 z = (struct zval *) e + s; s++;
1228 if (z->u1.v.type == 6) // string
1229 sock = z->value.str->val;
1230 }
1231
1232 if (num_args >= 8) { // flags
1233 z = (struct zval *) e + s; s++;
1234 if (z->u1.v.type == 4) // long
1235 cs.flags = z->value.lval;
1236 }
1237
1238 char conn_str[512];
1239 snprintf(conn_str, sizeof(conn_str),
1240 "host=%s user=%s port=%d db=%s socket=%s",
1241 host, user, port, db, sock);
1242 cs.conn_str = conn_str;
1243 cs.conn_str_len = strlen(cs.conn_str);
1244
1245 ninedogs_process_db("mysqli_real_connect", NINEDOGS_DB_CONN_START, &cs);
1246 ret = old_mysqli_real_connect(e, retv);
1247 if (!retv) {
1248 xlog(1, "DEBUG: old_mysqli_real_connect returned retv NULL\n");
1249 return ret;
1250 }
1251 //php_zval_dump(" retv: ", retv);
1252 // TODO: how to test for error? if (core_globals.last_error_message) {
1253
1254 // PHP7 returns resource, PHP8.1 returns object
1255 if (retv->u1.v.type == 3)
1256 cs.ret = 1;
1257 else
1258 cs.ret = 0;
1259 ninedogs_process_db("mysqli_real_connect", NINEDOGS_DB_CONN_END, &cs);
1260
1261 return ret;
1262 }
1263
1264 void *(*old_mysqli_query)(struct zend_execute_data *, struct zval *);
1265 static void *my_mysqli_query(struct zend_execute_data *e, struct zval *retv)
1266 {
1267 void *ret;
1268 unsigned int num_args, copy_num_args, s;
1269 struct zend_string *q;
1270 struct zval *z, copy_para, *para;
1271 char do_restore = 0;
1272 struct query qs;
1273
1274 num_args = e->This.u2.num_args;
1275
1276 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1277
1278 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1279 para = (struct zval *) e + s;
1280 qs.type = 'M';
1281 qs.params.len = 0;
1282
1283 // link
1284 z = (struct zval *) e + s; s++;
1285 php_zval_dump(" dbh: ", z);
1286 qs.dbh = z->value.p;
1287
1288 // query
1289 z = (struct zval *) e + s; s++;
1290 q = z->value.str;
1291 xlog(50, " query=%s\n", q->val);
1292 qs.q = q->val;
1293 qs.q_len = q->len;
1294
1295 // mode
1296 if (num_args >= 3) {
1297 z = (struct zval *) e + s; s++;
1298 xlog(50, " mode=0x%lx\n", z->value.lval);
1299 }
1300
1301 ninedogs_process_db("mysqli_query", NINEDOGS_DB_QUERY_START, &qs);
1302 ret = old_mysqli_query(e, retv);
1303 if (!retv)
1304 return ret;
1305 php_zval_dump(" retv: ", retv);
1306
1307 copy_num_args = num_args;
1308 memcpy(&copy_para, para, sizeof(struct zval));
1309
1310 if (retv->u1.v.type == 2) { // false
1311 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
1312 // TODO: do we set num and aff?
1313 qs.res = (void *) 0;
1314 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
1315 qs.num = qs.aff = 0;
1316 qs.res = (void *) 1;
1317 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
1318 qs.res = retv->value.p;
1319 php_mysqli_set_num_aff(e, retv, &qs);
1320 do_restore = 1;
1321 }
1322
1323 e->This.u2.num_args = copy_num_args;
1324 if (do_restore)
1325 memcpy(para, &copy_para, sizeof(struct zval));
1326
1327 ninedogs_process_db("mysqli_query", NINEDOGS_DB_QUERY_END, &qs);
1328
1329 return ret;
1330 }
1331
1332 void *(*old_mysqli_close)(struct zend_execute_data *, struct zval *);
1333 static void *my_mysqli_close(struct zend_execute_data *e, struct zval *retv)
1334 {
1335 struct conn c;
1336
1337 unsigned int num_args = e->This.u2.num_args;
1338
1339 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1340
1341 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1342 c.type = 'M';
1343
1344 // link
1345 struct zval *z = (struct zval *) e + s; s++;
1346 php_zval_dump(" dbh: ", z);
1347 c.dbh = z->value.p;
1348
1349 void *ret = old_mysqli_close(e, retv);
1350 if (!retv)
1351 return ret;
1352 php_zval_dump(" retv: ", retv);
1353
1354 if (retv->u1.v.type == 2) { // false
1355 c.ret = 0;
1356 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
1357 // TODO: do we set num and aff?
1358 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
1359 c.ret = 1;
1360 }
1361
1362 ninedogs_process_db("mysqli_close", NINEDOGS_DB_CONN_CLOSE, &c);
1363
1364 return ret;
1365 }
1366
1367 void *(*old_mysqli_fetch_all)(struct zend_execute_data *, struct zval *);
1368 static void *my_mysqli_fetch_all(struct zend_execute_data *e, struct zval *retv)
1369 {
1370 struct query q;
1371
1372 unsigned int num_args = e->This.u2.num_args;
1373 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1374
1375 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1376 q.type = 'M';
1377
1378 // res
1379 struct zval *z = (struct zval *) e + s; s++;
1380 php_zval_dump(" res: ", z);
1381 q.res = z->value.p;
1382
1383 // mode
1384 if (num_args >= 2) {
1385 z = (struct zval *) e + s; s++;
1386 q.mode = z->value.lval;
1387 xlog(50, " mode=0x%lx\n", q.mode);
1388 } else {
1389 q.mode = 2; // MYSQLI_NUM
1390 }
1391
1392 ninedogs_process_db("mysqli_fetch_all", NINEDOGS_DB_FETCH_START, &q);
1393 void *ret = old_mysqli_fetch_all(e, retv);
1394 if (!retv)
1395 return ret;
1396 php_zval_dump(" retv: ", retv);
1397
1398 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
1399 if (retv->u1.v.type == 7) { // array
1400 struct zend_array *a = retv->value.arr;
1401 q.num = a->nNumUsed;
1402 //q.ret = 0;
1403 // TODO: do we set num and aff? Should we? We already count them in 'execute'.
1404 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
1405 q.num = 0;
1406 //q.ret = 1;
1407 }
1408
1409 ninedogs_process_db("mysqli_fetch_all", NINEDOGS_DB_FETCH_END, &q);
1410
1411 return ret;
1412 }
1413
1414 void *(*old_mysqli_fetch_array)(struct zend_execute_data *, struct zval *);
1415 static void *my_mysqli_fetch_array(struct zend_execute_data *e, struct zval *retv)
1416 {
1417 struct query q;
1418
1419 unsigned int num_args = e->This.u2.num_args;
1420 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1421
1422 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1423 q.type = 'M';
1424
1425 // res
1426 struct zval *z = (struct zval *) e + s; s++;
1427 php_zval_dump(" res: ", z);
1428 q.res = z->value.p;
1429
1430 // mode
1431 if (num_args >= 2) {
1432 z = (struct zval *) e + s; s++;
1433 q.mode = z->value.lval;
1434 xlog(50, " mode=0x%lx\n", q.mode);
1435 } else {
1436 q.mode = 3; // MYSQLI_BOTH
1437 }
1438
1439 ninedogs_process_db("mysqli_fetch_array", NINEDOGS_DB_FETCH_START, &q);
1440 void *ret = old_mysqli_fetch_array(e, retv);
1441 if (!retv)
1442 return ret;
1443 php_zval_dump(" retv: ", retv);
1444
1445 if (retv->u1.v.type == 7) { // array
1446 q.ret = 2;
1447 } else if (retv->u1.v.type == 2) { // false - TODO set error
1448 q.ret = 1;
1449 } else {
1450 q.ret = 0;
1451 }
1452
1453 ninedogs_process_db("mysqli_fetch_array", NINEDOGS_DB_FETCH_END, &q);
1454
1455 return ret;
1456 }
1457
1458 void *(*old_mysqli_free_result)(struct zend_execute_data *, struct zval *);
1459 static void *my_mysqli_free_result(struct zend_execute_data *e, struct zval *retv)
1460 {
1461 struct free_result fr;
1462
1463 unsigned int num_args = e->This.u2.num_args;
1464 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1465
1466 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1467 fr.type = 'M';
1468
1469 // res
1470 struct zval *z = (struct zval *) e + s; s++;
1471 php_zval_dump(" res: ", z);
1472 fr.res = z->value.p;
1473
1474 void *ret = old_mysqli_free_result(e, retv);
1475 if (!retv)
1476 return ret;
1477
1478 fr.ok = 1;
1479 ninedogs_process_db("mysqli_free_result", NINEDOGS_DB_FREE_RESULT, &fr);
1480
1481 return ret;
1482 }
1483
1484 void *(*old_mysqli_stmt_execute)(struct zend_execute_data *, struct zval *);
1485 static void *my_mysqli_stmt_execute(struct zend_execute_data *e, struct zval *retv)
1486 {
1487 struct nd_db_execute ex;
1488 char do_restore = 0;
1489
1490 unsigned int num_args = e->This.u2.num_args;
1491 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1492
1493 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1494 ex.type = 'M';
1495 ex.params.len = 0;
1496
1497 struct zval *para = (struct zval *) e + s;
1498
1499 // stmt
1500 struct zval *z = (struct zval *) e + s; s++;
1501 php_zval_dump(" stmt: ", z);
1502 ex.stmt = z->value.p;
1503
1504 if (num_args >= 2) {
1505 z = (struct zval *) e + s; s++;
1506 struct zend_array *za = z->value.arr;
1507 zend_array_to_params_array(&ex.params, za);
1508 }
1509
1510 unsigned int copy_num_args = num_args;
1511 struct zval copy_para;
1512 memcpy(&copy_para, para, sizeof(struct zval));
1513
1514 ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_START, &ex);
1515 void *ret = old_mysqli_stmt_execute(e, retv);
1516 if (!retv)
1517 return ret;
1518
1519 if (retv->u1.v.type == 3) { // true
1520 ex.ret = 1;
1521 php_mysqli_stmt_set_num_aff(e, &ex);
1522 do_restore = 1;
1523 } else if (retv->u1.v.type == 2) { // false
1524 ex.ret = 0;
1525 }
1526
1527 e->This.u2.num_args = copy_num_args;
1528 if (do_restore)
1529 memcpy(para, &copy_para, sizeof(struct zval));
1530
1531 ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_END, &ex);
1532
1533 return ret;
1534 }
1535
1536 void *(*old_mysqli_prepare)(struct zend_execute_data *, struct zval *);
1537 static void *my_mysqli_prepare(struct zend_execute_data *e, struct zval *retv)
1538 {
1539 struct prepare p;
1540
1541 unsigned int num_args = e->This.u2.num_args;
1542 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1543
1544 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1545 p.type = 'M';
1546
1547 // link
1548 struct zval *z = (struct zval *) e + s; s++;
1549 php_zval_dump(" link: ", z);
1550 p.dbh = z->value.p;
1551
1552 // query
1553 z = (struct zval *) e + s; s++;
1554 struct zend_string *xs = z->value.str;
1555 xlog(50, " query=%s\n", xs->val);
1556 p.q = xs->val;
1557 p.q_len = xs->len;
1558
1559 ninedogs_process_db("mysqli_prepare", NINEDOGS_DB_PREPARE_START, &p);
1560 void *ret = old_mysqli_prepare(e, retv);
1561 if (!retv)
1562 return ret;
1563 php_zval_dump(" retv: ", retv);
1564
1565 // PHP7 returns resource, PHP8.1 returns object
1566 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) {
1567 p.stmt = retv->value.p;
1568 } else if (retv->u1.v.type == 2) { // false
1569 p.stmt = NULL;
1570 }
1571
1572 ninedogs_process_db("mysqli_prepare", NINEDOGS_DB_PREPARE_END, &p);
1573
1574 return ret;
1575 }
1576
1577 void *(*old_mysqli_stmt_prepare)(struct zend_execute_data *, struct zval *);
1578 static void *my_mysqli_stmt_prepare(struct zend_execute_data *e, struct zval *retv)
1579 {
1580 struct prepare p;
1581
1582 unsigned int num_args = e->This.u2.num_args;
1583 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1584
1585 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1586 p.type = 'M';
1587
1588 // stmt
1589 struct zval *z = (struct zval *) e + s; s++;
1590 php_zval_dump(" stmt: ", z);
1591 p.stmt = z->value.p;
1592
1593 // query
1594 z = (struct zval *) e + s; s++;
1595 struct zend_string *xs = z->value.str;
1596 xlog(50, " query=%s\n", xs->val);
1597 p.q = xs->val;
1598 p.q_len = xs->len;
1599
1600 ninedogs_process_db("mysqli_stmt_prepare", NINEDOGS_DB_PREPARE_START, &p);
1601 void *ret = old_mysqli_stmt_prepare(e, retv);
1602 if (!retv)
1603 return ret;
1604 php_zval_dump(" retv: ", retv);
1605
1606 if (retv->u1.v.type == 3) { // true
1607 p.ret = 1;
1608 } else if (retv->u1.v.type == 2) { // false
1609 p.ret = 0;
1610 }
1611
1612 ninedogs_process_db("mysqli_stmt_prepare", NINEDOGS_DB_PREPARE_END, &p);
1613
1614 return ret;
1615 }
1616
1617 void *(*old_mysqli_autocommit)(struct zend_execute_data *, struct zval *);
1618 static void *my_mysqli_autocommit(struct zend_execute_data *e, struct zval *retv)
1619 {
1620 struct db_autocommit a;
1621
1622 unsigned int num_args = e->This.u2.num_args;
1623 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1624
1625 unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
1626 a.type = 'M';
1627
1628 // link
1629 struct zval *z = (struct zval *) e + s; s++;
1630 a.link = z->value.p;
1631
1632 z = (struct zval *) e + s; s++;
1633 php_zval_dump(" bool: ", z);
1634 a.value = z->u1.v.type == 3;
1635
1636 ninedogs_process_db("mysqli_autocommit", NINEDOGS_DB_AUTOCOMMIT_START, &a);
1637 void *ret = old_mysqli_autocommit(e, retv);
1638 if (!retv)
1639 return ret;
1640
1641 if (retv->u1.v.type == 3) { // true
1642 a.ret = 1;
1643 } else if (retv->u1.v.type == 2) { // false
1644 a.ret = 0;
1645 }
1646
1647 ninedogs_process_db("mysqli_autocommit", NINEDOGS_DB_AUTOCOMMIT_END, &a);
1648
1649 return ret;
1650 }
1651
1652 void *(*old_mysqli_stmt_bind_param)(struct zend_execute_data *, struct zval *);
1653 static void *my_mysqli_stmt_bind_param(struct zend_execute_data *e, struct zval *retv)
1654 {
1655 struct nd_db_bind b;
1656
1657 unsigned int num_args = e->This.u2.num_args;
1658 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1659
1660 unsigned int s = (sizeof(struct zend_execute_data)
1661 + sizeof(struct zval) - 1) / sizeof(struct zval);
1662 b.type = 'M';
1663
1664 // stmt
1665 struct zval *z = (struct zval *) e + s; s++;
1666 //php_zval_dump(" stmt: ", z);
1667 b.stmt = z->value.p;
1668
1669 // types
1670 z = (struct zval *) e + s; s++;
1671 struct zend_string *xs = z->value.str;
1672 b.types = xs->val;
1673 b.types_len = xs->len;
1674
1675 ninedogs_process_db("mysqli_stmt_bind_param",
1676 NINEDOGS_DB_BIND_PARAM_START, &b);
1677 void *ret = old_mysqli_stmt_bind_param(e, retv);
1678 if (!retv)
1679 return ret;
1680
1681 if (retv->u1.v.type == 3) { // true
1682 b.ret = 1;
1683 } else if (retv->u1.v.type == 2) { // false
1684 b.ret = 0;
1685 }
1686
1687 ninedogs_process_db("mysqli_stmt_bind_param",
1688 NINEDOGS_DB_BIND_PARAM_END, &b);
1689
1690 return ret;
1691 }
1692
1693
1694 //////////////////////////////////////// C U R L
1695 void *(*old_curl_init)(struct zend_execute_data *, struct zval *);
1696 static void *my_curl_init(struct zend_execute_data *e, struct zval *retv)
1697 {
1698 struct nd_url b;
1699
1700 unsigned int num_args = e->This.u2.num_args;
1701 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1702
1703 if (num_args > 0) {
1704 unsigned int s = (sizeof(struct zend_execute_data)
1705 + sizeof(struct zval) - 1) / sizeof(struct zval);
1706
1707 // url
1708 struct zval *z = (struct zval *) e + s; s++;
1709 php_zval_dump(" url: ", z);
1710 struct zend_string *xs = z->value.str;
1711 b.url = xs->val;
1712 b.url_len = xs->len;
1713 } else {
1714 b.url = NULL;
1715 b.url_len = 0;
1716 }
1717
1718 void *ret = old_curl_init(e, retv);
1719 if (!retv)
1720 return ret;
1721
1722 if ((retv->u1.v.type == 7) || (retv->u1.v.type == 8)) { // resource or object
1723 b.handle = retv->value.p;
1724 } else if (retv->u1.v.type == 2) { // false
1725 b.handle = NULL;
1726 }
1727
1728 ninedogs_process_url("curl_init", NINEDOGS_URL_INIT_END, &b);
1729
1730 return ret;
1731 }
1732
1733 void *(*old_curl_exec)(struct zend_execute_data *, struct zval *);
1734 static void *my_curl_exec(struct zend_execute_data *e, struct zval *retv)
1735 {
1736 struct nd_url b = { .url_len = 0, .sret_len = 0 };
1737
1738 unsigned int num_args = e->This.u2.num_args;
1739 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1740
1741 unsigned int s = (sizeof(struct zend_execute_data)
1742 + sizeof(struct zval) - 1) / sizeof(struct zval);
1743
1744 // handle
1745 struct zval *z = (struct zval *) e + s; s++;
1746 php_zval_dump(" handle: ", z);
1747 b.handle = z->value.p;
1748
1749 ninedogs_process_url("curl_exec", NINEDOGS_URL_START, &b);
1750 void *ret = old_curl_exec(e, retv);
1751 if (!retv)
1752 return ret;
1753
1754 if (retv->u1.v.type == 6) { // string
1755 struct zend_string *xs = retv->value.str;
1756 b.ret = 2;
1757 b.sret = xs->val;
1758 b.sret_len = xs->len;
1759 } else if (retv->u1.v.type == 2) { // false
1760 b.ret = 0;
1761 } else if (retv->u1.v.type == 3) { // true
1762 b.ret = 1;
1763 }
1764 // TODO: propagate errors
1765
1766 ninedogs_process_url("curl_exec", NINEDOGS_URL_END, &b);
1767
1768 return ret;
1769 }
1770
1771 void *(*old_curl_close)(struct zend_execute_data *, struct zval *);
1772 static void *my_curl_close(struct zend_execute_data *e, struct zval *retv)
1773 {
1774 struct nd_url b = { .url_len = 0, .sret_len = 0 };
1775
1776 unsigned int num_args = e->This.u2.num_args;
1777 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1778
1779 unsigned int s = (sizeof(struct zend_execute_data)
1780 + sizeof(struct zval) - 1) / sizeof(struct zval);
1781
1782 // handle
1783 struct zval *z = (struct zval *) e + s; s++;
1784 php_zval_dump(" handle: ", z);
1785 b.handle = z->value.p;
1786
1787 void *ret = old_curl_close(e, retv);
1788 if (!retv)
1789 return ret;
1790
1791 ninedogs_process_url("curl_close", NINEDOGS_URL_CLOSE_END, &b);
1792
1793 return ret;
1794 }
1795
1796 void *(*old_curl_setopt)(struct zend_execute_data *, struct zval *);
1797 static void *my_curl_setopt(struct zend_execute_data *e, struct zval *retv)
1798 {
1799 struct nd_url b = { .url_len = 0, .sret_len = 0 };
1800
1801 unsigned int num_args = e->This.u2.num_args;
1802 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1803
1804 unsigned int s = (sizeof(struct zend_execute_data)
1805 + sizeof(struct zval) - 1) / sizeof(struct zval);
1806
1807 // handle
1808 struct zval *z = (struct zval *) e + s; s++;
1809 php_zval_dump(" handle: ", z);
1810 b.handle = z->value.p;
1811
1812 // option
1813 z = (struct zval *) e + s; s++;
1814 php_zval_dump(" option: ", z);
1815 const struct my_curl_easyoption *oi = curl_easy_option_by_id(z->value.lval);
1816 if (oi)
1817 snprintf(b.op, sizeof(b.op), "%s", oi->name);
1818 else
1819 snprintf(b.op, sizeof(b.op), "?%ld?", z->value.lval);
1820 xlog(100, " option name = %s\n", b.op);
1821
1822 // value
1823 z = (struct zval *) e + s; s++;
1824 php_zval_dump(" value: ", z);
1825 b.op_value_len = zend_to_binary(b.op_value, sizeof(b.op_value), z);
1826
1827 void *ret = old_curl_setopt(e, retv);
1828 if (!retv)
1829 return ret;
1830 php_zval_dump(" retv: ", retv);
1831
1832 if (retv->u1.v.type == 2) { // false
1833 b.ret = 0;
1834 } else if (retv->u1.v.type == 3) { // true
1835 b.ret = 1;
1836 }
1837 // TODO: propagate errors
1838
1839 ninedogs_process_url("curl_setopt", NINEDOGS_URL_SETOPT_END, &b);
1840
1841 return ret;
1842 }
1843
1844
43 //#include "ctools.h"
44 #include "php.h"
1845 45
1846 struct zend_module_entry *(*old_get_module)(void);
46 static struct zend_module_entry *(*old_get_module)(void);
1847 47 static struct zend_module_entry *php_hook_get_module_func(void) static struct zend_module_entry *php_hook_get_module_func(void)
1848 48 { {
1849 49 struct zend_module_entry *z, *new; struct zend_module_entry *z, *new;
 
... ... static struct zend_module_entry *php_hook_get_module_func(void)
1897 97 fe = new->functions; fe = new->functions;
1898 98 while (fe && fe->fname) { while (fe && fe->fname) {
1899 99 xlog(100, " func %s handler=%p\n", fe->fname, fe->handler); xlog(100, " func %s handler=%p\n", fe->fname, fe->handler);
1900 if (strncmp(fe->fname, "curl_", 5) == 0) {
1901 if (strcmp(fe->fname, "curl_close") == 0) {
1902 old_curl_close = fe->handler;
1903 fe->handler = my_curl_close;
1904 } else if (strcmp(fe->fname, "curl_init") == 0) {
1905 old_curl_init = fe->handler;
1906 fe->handler = my_curl_init;
1907 } else if (strcmp(fe->fname, "curl_exec") == 0) {
1908 old_curl_exec = fe->handler;
1909 fe->handler = my_curl_exec;
1910 } else if (strcmp(fe->fname, "curl_setopt") == 0) {
1911 old_curl_setopt = fe->handler;
1912 fe->handler = my_curl_setopt;
1913 } else {
1914 //xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname);
1915 }
100 if (strncmp(fe->fname, "oci_", 4) == 0) {
101 php_oci_hook(fe);
102 } else if (strncmp(fe->fname, "curl_", 5) == 0) {
103 php_curl_hook(fe);
1916 104 } else if (strncmp(fe->fname, "pg_", 3) == 0) { } else if (strncmp(fe->fname, "pg_", 3) == 0) {
1917 if (strcmp(fe->fname, "pg_close") == 0) {
1918 old_pg_close = fe->handler;
1919 fe->handler = my_pg_close;
1920 } else if (strcmp(fe->fname, "pg_connect") == 0) {
1921 old_pg_connect = fe->handler;
1922 fe->handler = my_pg_connect;
1923 } else if (strcmp(fe->fname, "pg_pconnect") == 0) {
1924 old_pg_pconnect = fe->handler;
1925 fe->handler = my_pg_pconnect;
1926 } else if (strcmp(fe->fname, "pg_num_rows") == 0) {
1927 old_pg_num_rows = fe->handler;
1928 fe->handler = my_pg_num_rows;
1929 } else if (strcmp(fe->fname, "pg_affected_rows") == 0) {
1930 old_pg_affected_rows = fe->handler;
1931 } else if (strcmp(fe->fname, "pg_free_result") == 0) {
1932 old_pg_free_result = fe->handler;
1933 fe->handler = my_pg_free_result;
1934 } else if (strcmp(fe->fname, "pg_query") == 0) {
1935 old_pg_query = fe->handler;
1936 fe->handler = my_pg_query;
1937 } else if (strcmp(fe->fname, "pg_send_query") == 0) {
1938 old_pg_send_query = fe->handler;
1939 fe->handler = my_pg_send_query;
1940 } else if (strcmp(fe->fname, "pg_query_params") == 0) {
1941 old_pg_query_params = fe->handler;
1942 fe->handler = my_pg_query_params;
1943 } else if (strcmp(fe->fname, "pg_send_query_params") == 0) {
1944 old_pg_send_query_params = fe->handler;
1945 fe->handler = my_pg_send_query_params;
1946 } else if (strcmp(fe->fname, "pg_last_error") == 0) {
1947 old_pg_last_error = fe->handler;
1948 fe->handler = my_pg_last_error;
1949 } else if (strcmp(fe->fname, "pg_get_result") == 0) {
1950 old_pg_get_result = fe->handler;
1951 fe->handler = my_pg_get_result;
1952 } else {
1953 //xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname);
1954 }
105 php_pg_hook(fe);
1955 106 } else if (strncmp(fe->fname, "mysqli_", 7) == 0) { } else if (strncmp(fe->fname, "mysqli_", 7) == 0) {
1956 if (strcmp(fe->fname, "mysqli_autocommit") == 0) {
1957 old_mysqli_autocommit = fe->handler;
1958 fe->handler = my_mysqli_autocommit;
1959 } else if (strcmp(fe->fname, "mysqli_close") == 0) {
1960 old_mysqli_close = fe->handler;
1961 fe->handler = my_mysqli_close;
1962 } else if (strcmp(fe->fname, "mysqli_affected_rows") == 0) {
1963 old_mysqli_stmt_affected_rows = fe->handler;
1964 } else if (strcmp(fe->fname, "mysqli_connect") == 0) {
1965 old_mysqli_connect = fe->handler;
1966 fe->handler = my_mysqli_connect;
1967 } else if (strcmp(fe->fname, "mysqli_error") == 0) {
1968 old_mysqli_error = fe->handler;
1969 } else if (strcmp(fe->fname, "mysqli_fetch_all") == 0) {
1970 old_mysqli_fetch_all = fe->handler;
1971 fe->handler = my_mysqli_fetch_all;
1972 } else if (strcmp(fe->fname, "mysqli_fetch_array") == 0) {
1973 old_mysqli_fetch_array = fe->handler;
1974 fe->handler = my_mysqli_fetch_array;
1975 } else if (strcmp(fe->fname, "mysqli_free_result") == 0) {
1976 old_mysqli_free_result = fe->handler;
1977 fe->handler = my_mysqli_free_result;
1978 } else if (strcmp(fe->fname, "mysqli_query") == 0) {
1979 old_mysqli_query = fe->handler;
1980 fe->handler = my_mysqli_query;
1981 } else if (strcmp(fe->fname, "mysqli_prepare") == 0) {
1982 old_mysqli_prepare = fe->handler;
1983 fe->handler = my_mysqli_prepare;
1984 } else if (strcmp(fe->fname, "mysqli_num_rows") == 0) {
1985 old_mysqli_num_rows = fe->handler;
1986 } else if (strcmp(fe->fname, "mysqli_real_connect") == 0) {
1987 old_mysqli_real_connect = fe->handler;
1988 fe->handler = my_mysqli_real_connect;
1989 } else if (strcmp(fe->fname, "mysqli_stmt_affected_rows") == 0) {
1990 old_mysqli_stmt_affected_rows = fe->handler;
1991 } else if (strcmp(fe->fname, "mysqli_stmt_execute") == 0) {
1992 old_mysqli_stmt_execute = fe->handler;
1993 fe->handler = my_mysqli_stmt_execute;
1994 } else if (strcmp(fe->fname, "mysqli_stmt_bind_param") == 0) {
1995 old_mysqli_stmt_bind_param = fe->handler;
1996 fe->handler = my_mysqli_stmt_bind_param;
1997 } else if (strcmp(fe->fname, "mysqli_stmt_num_rows") == 0) {
1998 old_mysqli_stmt_num_rows = fe->handler;
1999 } else if (strcmp(fe->fname, "mysqli_stmt_prepare") == 0) {
2000 old_mysqli_stmt_prepare = fe->handler;
2001 fe->handler = my_mysqli_stmt_prepare;
2002 } else {
2003 //xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname);
2004 }
107 php_mysql_hook(fe);
108 } else if (strncmp(fe->fname, "image", 5) == 0) {
109 php_gd_hook(fe);
2005 110 } }
2006 111 fe++; fe++;
2007 112 } }
File agent/php.h changed (mode: 100644) (index b2242cd..6d33ae8)
1 #include "php-curl.h"
2 #include "php-mysql.h"
3 #include "php-oci.h"
4 #include "php-pg.h"
5
6 #include "php/gd.h"
1 7
2 8 void *php_hook(void *x); void *php_hook(void *x);
3 9
File agent/php/gd.c added (mode: 100644) (index 0000000..efc1633)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "../../common/ids.h"
6 #include "../../common/tools.h"
7 #include "../ctools.h"
8 #include "../ninedogs.h"
9 #include "../process_db.h"
10 #include "gd.h"
11
12 #define ND_GD_IMG_MAX 100
13 static __thread struct nd_gd_img track[ND_GD_IMG_MAX];
14
15 static void im_clean(const void *im)
16 {
17 for (unsigned i = 0; i < ND_GD_IMG_MAX; i++) {
18 if (track[i].im == im) {
19 memset(&track[i], 0, sizeof(struct nd_gd_img));
20 break;
21 }
22 }
23 }
24
25 static struct nd_gd_img *im_find(const void *im)
26 {
27 for (unsigned i = 0; i < ND_GD_IMG_MAX; i++) {
28 if (track[i].im == im)
29 return &track[i];
30 }
31
32 return NULL;
33 }
34
35 static struct nd_gd_img *im_alloc(struct nd_gd_img *img)
36 {
37 for (unsigned i = 0; i < ND_GD_IMG_MAX; i++) {
38 if (track[i].im == NULL) {
39 memcpy(&track[i].im, img, sizeof(struct nd_gd_img));
40 return &track[i];
41 }
42 }
43
44 return NULL;
45 }
46
47 static void im_add(struct nd_gd_img *img)
48 {
49 struct nd_gd_img *s = im_find(img);
50 if (!s)
51 s = im_alloc(img);
52 }
53
54
55 static void *(*old_gd_imagecreate)(struct zend_execute_data *, struct zval *);
56 static void *my_gd_imagecreate(struct zend_execute_data *e, struct zval *retv)
57 {
58 unsigned int num_args, s;
59 struct nd_gd_img img;
60 long w, h;
61
62 num_args = e->This.u2.num_args;
63 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
64
65 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
66
67 // w
68 struct zval *z = (struct zval *) e + s; s++;
69 php_zval_dump(" w=", z);
70 w = z->value.lval;
71
72 // h
73 z = (struct zval *) e + s; s++;
74 php_zval_dump(" h=", z);
75 h = z->value.lval;
76
77 img.elap.tv_sec = img.elap.tv_usec = 0;
78 ninedogs_now(&img.start);
79 void *ret = old_gd_imagecreate(e, retv);
80 if (!retv)
81 return ret;
82
83 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
84 img.im = retv->value.p;
85 im_add(&img);
86 } else if (retv->u1.v.type == 2) { // false
87 img.im = NULL;
88 }
89
90 my_trace("imagecreate", "i", 'R', w, h, &img);
91
92 return ret;
93 }
94
95 static void *(*old_gd_imagecreatetruecolor)(struct zend_execute_data *, struct zval *);
96 static void *my_gd_imagecreatetruecolor(struct zend_execute_data *e, struct zval *retv)
97 {
98 unsigned int num_args, s;
99 struct nd_gd_img img;
100 long w, h;
101
102 num_args = e->This.u2.num_args;
103 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
104
105 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
106
107 // w
108 struct zval *z = (struct zval *) e + s; s++;
109 php_zval_dump(" w=", z);
110 w = z->value.lval;
111
112 // h
113 z = (struct zval *) e + s; s++;
114 php_zval_dump(" h=", z);
115 h = z->value.lval;
116
117 img.elap.tv_sec = img.elap.tv_usec = 0;
118 ninedogs_now(&img.start);
119 void *ret = old_gd_imagecreatetruecolor(e, retv);
120 if (!retv)
121 return ret;
122
123 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
124 img.im = retv->value.p;
125 im_add(&img);
126 } else if (retv->u1.v.type == 2) { // false
127 img.im = NULL;
128 }
129
130 my_trace("imagecreatetruecolor", "i", 'R', w, h, &img);
131
132 return ret;
133 }
134
135 static void *(*old_gd_imagedestroy)(struct zend_execute_data *, struct zval *);
136 static void *my_gd_imagedestroy(struct zend_execute_data *e, struct zval *retv)
137 {
138 unsigned int num_args, s;
139 struct nd_gd_img *img;
140 struct timeval end;
141 void *im;
142 int r;
143
144 num_args = e->This.u2.num_args;
145 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
146
147 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
148
149 // im
150 struct zval *z = (struct zval *) e + s; s++;
151 php_zval_dump(" im=", z);
152 im = z->value.p;
153
154 void *ret = old_gd_imagedestroy(e, retv);
155 if (!retv)
156 return ret;
157
158 img = im_find(im);
159 if (img) {
160 ninedogs_now(&end);
161 my_time_diff(&img->elap, &end, &img->start);
162 }
163
164 if (retv->u1.v.type == 2) // false
165 r = 0;
166 else
167 r = 1;
168 my_trace("imagedestroy", "i", 'R', img, r);
169 im_clean(im);
170
171 return ret;
172 }
173
174 void php_gd_hook(struct zend_function_entry *fe)
175 {
176 if (strcmp(fe->fname, "imagecreate") == 0) {
177 old_gd_imagecreate = fe->handler;
178 fe->handler = my_gd_imagecreate;
179 } else if (strcmp(fe->fname, "imagecreatetruecolor") == 0) {
180 old_gd_imagecreatetruecolor = fe->handler;
181 fe->handler = my_gd_imagecreatetruecolor;
182 } else if (strcmp(fe->fname, "imagedestroy") == 0) {
183 old_gd_imagedestroy = fe->handler;
184 fe->handler = my_gd_imagedestroy;
185 }
186 }
File agent/php/gd.h added (mode: 100644) (index 0000000..b041d85)
1 #include "../php-core.h"
2
3 struct nd_gd_img
4 {
5 void *im;
6 struct timeval start, elap;
7 };
8
9 void php_gd_hook(struct zend_function_entry *fe);
File agent/process_core.c changed (mode: 100644) (index 28f33e7..f3cc298)
... ... void ninedogs_process_core(const unsigned int type, const void *d)
34 34 xlog(100, "%s: type=%s\n", __func__, type2name(type)); xlog(100, "%s: type=%s\n", __func__, type2name(type));
35 35
36 36 switch (type) { switch (type) {
37 case NINEDOGS_CORE_START:
37 case NINEDOGS_CORE_START: {
38 38 if (start.tv_sec > 0) if (start.tv_sec > 0)
39 39 return; return;
40 40
 
... ... void ninedogs_process_core(const unsigned int type, const void *d)
42 42 xlog(101, "%s: DEBUG: set start to %ld.%03ld\n", xlog(101, "%s: DEBUG: set start to %ld.%03ld\n",
43 43 __func__, start.tv_sec, start.tv_usec / 1000); __func__, start.tv_sec, start.tv_usec / 1000);
44 44
45 do {
46 struct utsname u;
47
48 int r = uname(&u);
49 if (r == -1) {
50 xlog(1, "Cannot call uname: %m\n");
51 break;
52 }
53
54 pack(&buf, &len, "T4 NN ss ns" "rs vs" "ms",
55 NINEDOGS_NET_CORE_UNAME,
56 u.sysname, strlen(u.sysname), u.nodename, strlen(u.nodename),
57 u.release, strlen(u.release), u.version, strlen(u.version),
58 u.machine, strlen(u.machine));
59 if (buf)
60 server_enqueue(buf, len);
61 } while (0);
62 break;
63
64 case NINEDOGS_CORE_STOP:
45 struct utsname u;
46 int r = uname(&u);
47 if (r == -1) {
48 xlog(1, "Cannot call uname: %m\n");
49 break;
50 }
51
52 pack(&buf, &len, "T4 _t ss ns" "rs vs" "ms",
53 NINEDOGS_NET_CORE_UNAME, &start,
54 u.sysname, strlen(u.sysname), u.nodename, strlen(u.nodename),
55 u.release, strlen(u.release), u.version, strlen(u.version),
56 u.machine, strlen(u.machine));
57 if (buf)
58 server_enqueue(buf, len);
59 } break;
60
61 case NINEDOGS_CORE_STOP: {
65 62 int *exit_code = (int *) d; int *exit_code = (int *) d;
66 char *s = getenv("NINEDOGS_SYNC_FLUSH");
63 char *sync_flush = getenv("NINEDOGS_SYNC_FLUSH");
67 64
68 65 ninedogs_now(&stop); ninedogs_now(&stop);
69 66 xlog(101, "%s: DEBUG: set stop to %ld.%03ld\n", xlog(101, "%s: DEBUG: set stop to %ld.%03ld\n",
 
... ... void ninedogs_process_core(const unsigned int type, const void *d)
75 72 ninedogs_process_url_flush(); ninedogs_process_url_flush();
76 73
77 74 // TODO: add page faults, wall time, sys time etc. (getrusage) // TODO: add page faults, wall time, sys time etc. (getrusage)
78 pack(&buf, &len, "T4 st tt x4",
75 pack(&buf, &len, "T4 st _t x4",
79 76 NINEDOGS_NET_CORE_STOP, &start, &stop, *exit_code); NINEDOGS_NET_CORE_STOP, &start, &stop, *exit_code);
80 77 if (buf) if (buf)
81 78 server_enqueue(buf, len); server_enqueue(buf, len);
82 79
83 server_pat(s ? 1 : 0);
80 server_pat(sync_flush ? 1 : 0);
84 81
85 82 server_stop(); server_stop();
86 break;
83 } break;
87 84 } }
88 85 } }
89 86
File agent/process_db.c changed (mode: 100644) (index 6ec5d24..f6d7611)
9 9 #include "process.h" #include "process.h"
10 10 #include "process_db.h" #include "process_db.h"
11 11
12 extern void my_trace(const char *func, const char type, ...);
12 extern void my_trace(const char *func, const char *tf, const char type, ...);
13 13 extern void *(*old_malloc)(size_t size); extern void *(*old_malloc)(size_t size);
14 14 extern void (*old_free)(void *p); extern void (*old_free)(void *p);
15 15
 
... ... static unsigned int gran = 60; // granularity of reports, in seconds
17 17 static unsigned int max_query_len = 8192; // should be received from server? TODO static unsigned int max_query_len = 8192; // should be received from server? TODO
18 18
19 19 // query stuff // query stuff
20 static __thread void *last_db_handle;
20 static __thread struct nd_db_conn *last_db_cn;
21 21
22 22 struct query_node struct query_node
23 23 { {
 
... ... static void query_reset_node(struct query_node *qn)
42 42 qn->process_sum.tv_sec = qn->process_sum.tv_usec = 0; qn->process_sum.tv_sec = qn->process_sum.tv_usec = 0;
43 43 qn->rows = qn->aff = qn->count = 0; qn->rows = qn->aff = qn->count = 0;
44 44 qn->free_calls = qn->free_errs = 0; qn->free_calls = qn->free_errs = 0;
45 qn->res = NULL;
45 46 } }
46 47
47 48 static void query_init_node(struct query_node *qn) static void query_init_node(struct query_node *qn)
 
... ... static void query_send_node(const struct query_node *qn)
64 65 return; return;
65 66 } }
66 67
67 pack(&buf, &len, "T4 hb c8 r8 A8" "_t it at et" "x8 y8",
68 NINEDOGS_NET_DB_QUERY_STATS, qn->hash, sizeof(qn->hash), qn->count, qn->rows, qn->aff,
68 pack(&buf, &len, "T4 hb" "c8 r8 A8" "_t it at et" "x8 y8",
69 NINEDOGS_NET_DB_QUERY_STATS, qn->hash, sizeof(qn->hash),
70 qn->count, qn->rows, qn->aff,
69 71 &qn->ts, &qn->min, &qn->max, &qn->elap, &qn->ts, &qn->min, &qn->max, &qn->elap,
70 72 qn->free_calls, qn->free_errs); qn->free_calls, qn->free_errs);
71 73 if (!buf) { if (!buf) {
 
... ... static void query_hash(unsigned char *hash, const char *q, const unsigned int q_
83 85
84 86 ///////////////////////////////////////////////////// conn stuff ///////////////////////////////////////////////////// conn stuff
85 87
86 struct conn_node
87 {
88 char type;
89 char pad1[3];
90 unsigned int count; // how many connections took place
91 const void *handle;
92 char *conn_str;
93 unsigned int conn_str_len;
94 unsigned int pad2;
95 struct timeval last_query_try;
96 struct timeval ts, min, max, elap;
97 struct query_node *qh, *qt;
98 struct conn_node *next;
99 };
100
101 static __thread struct conn_node *conn_head, *conn_tail;
88 static __thread struct nd_db_conn *conn_head, *conn_tail;
102 89
103 static struct conn_node *conn_get(const char type, const char *conn_str,
104 const unsigned int conn_str_len)
90 static struct nd_db_conn *conn_get_by_conn_str(const char type,
91 const char *conn_str, const unsigned int conn_str_len)
105 92 { {
106 struct conn_node *cn;
93 struct nd_db_conn *cn;
107 94
108 95 xlog(50, "%s: searching for conn_str [%s]\n", __func__, conn_str); xlog(50, "%s: searching for conn_str [%s]\n", __func__, conn_str);
109 96 cn = conn_head; cn = conn_head;
110 97 while (cn) { while (cn) {
111 98 if ((cn->type == type) if ((cn->type == type)
112 99 && (cn->conn_str_len == conn_str_len) && (cn->conn_str_len == conn_str_len)
113 && (strcmp(cn->conn_str, conn_str) == 0)) {
114 xlog(50, " found it; cn=%p cn->handle=%p\n", cn, cn->handle);
100 && (strncmp(cn->conn_str, conn_str, conn_str_len) == 0)) {
101 xlog(50, " found it; cn=%p cn->dbh=%p\n", cn, cn->dbh);
115 102 return cn; return cn;
116 103 } }
117 104 cn = cn->next; cn = cn->next;
 
... ... static struct conn_node *conn_get(const char type, const char *conn_str,
121 108 return NULL; return NULL;
122 109 } }
123 110
124 static struct conn_node *conn_get_by_handle(const void *handle)
111 static struct nd_db_conn *conn_get_by_dbh(const void *dbh)
125 112 { {
126 struct conn_node *cn;
113 struct nd_db_conn *cn;
127 114
128 xlog(50, "%s: searching for conn handle [%p]\n", __func__, handle);
115 xlog(50, "%s: searching for dbh [%p]\n", __func__, dbh);
129 116 cn = conn_head; cn = conn_head;
130 117 while (cn) { while (cn) {
131 if (cn->handle == handle) {
118 if (cn->dbh == dbh) {
132 119 xlog(50, " found a prev conn cn=%p\n", cn); xlog(50, " found a prev conn cn=%p\n", cn);
133 120 return cn; return cn;
134 121 } }
 
... ... static struct conn_node *conn_get_by_handle(const void *handle)
139 126 return NULL; return NULL;
140 127 } }
141 128
142 static void conn_reset_node(struct conn_node *cn)
129 static void conn_reset_node(struct nd_db_conn *cn)
143 130 { {
144 131 struct query_node *qn; struct query_node *qn;
145 132
 
... ... static void conn_reset_node(struct conn_node *cn)
157 144 } }
158 145 } }
159 146
160 static void conn_init_node(struct conn_node *cn)
147 static void conn_init_node(struct nd_db_conn *cn)
161 148 { {
162 149 cn->type = '0'; cn->type = '0';
163 cn->handle = NULL;
150 cn->dbh = NULL;
164 151 cn->qh = cn->qt = NULL; cn->qh = cn->qt = NULL;
165 152 cn->ts.tv_usec = 0; cn->ts.tv_usec = 0;
166 153 conn_reset_node(cn); conn_reset_node(cn);
167 154 } }
168 155
169 static void conn_send_node(const struct conn_node *cn)
156 static void conn_send_node(const struct nd_db_conn *cn)
170 157 { {
171 158 struct query_node *qn; struct query_node *qn;
172 159 unsigned char *buf; unsigned char *buf;
 
... ... static void conn_send_node(const struct conn_node *cn)
191 178 } }
192 179 } }
193 180
194 static void conn_flush_node(struct conn_node *cn, const unsigned int u)
181 static void conn_flush_node(struct nd_db_conn *cn, const unsigned int u)
195 182 { {
196 183 if (cn->ts.tv_sec == 0) if (cn->ts.tv_sec == 0)
197 184 cn->ts.tv_sec = u * gran; cn->ts.tv_sec = u * gran;
 
... ... static void conn_flush_node(struct conn_node *cn, const unsigned int u)
206 193
207 194 static void conn_flush(void) static void conn_flush(void)
208 195 { {
209 struct conn_node *cn;
196 struct nd_db_conn *cn;
210 197
211 198 xlog(50, "%s\n", __func__); xlog(50, "%s\n", __func__);
212 199 cn = conn_head; cn = conn_head;
 
... ... static void conn_flush(void)
219 206 //////////////////// common section //////////////////// common section
220 207 static struct query_node *query_get_by_res(const char type, const void *res) static struct query_node *query_get_by_res(const char type, const void *res)
221 208 { {
222 struct conn_node *cn;
209 struct nd_db_conn *cn;
223 210 struct query_node *qn; struct query_node *qn;
224 211
225 xlog(50, "%s: searching for res %p\n", __func__, res);
212 xlog(50, "%s: searching for type %c and res %p\n", __func__, type, res);
226 213 cn = conn_head; cn = conn_head;
227 214 while (cn) { while (cn) {
228 215 if (cn->type == type) { if (cn->type == type) {
 
... ... static struct query_node *query_get_by_res(const char type, const void *res)
244 231
245 232 void query_send_string(const unsigned char *hash) void query_send_string(const unsigned char *hash)
246 233 { {
247 struct conn_node *cn;
234 struct nd_db_conn *cn;
248 235 struct query_node *qn = NULL; struct query_node *qn = NULL;
249 236 unsigned char *buf; unsigned char *buf;
250 237 unsigned int len; unsigned int len;
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
283 270 unsigned char hash[32]; unsigned char hash[32];
284 271 struct timeval t, elap; struct timeval t, elap;
285 272 unsigned int u; unsigned int u;
286 struct conn *cs;
273 struct nd_db_conn *cn0, *cn;
287 274 struct query *qs; struct query *qs;
275 struct nd_db_stmt *stmt;
288 276 struct timeval end; struct timeval end;
289 277 char *q_copy; char *q_copy;
290 278 unsigned int q_len; unsigned int q_len;
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
292 280 xlog(100, "%s: type=%u\n", __func__, type); xlog(100, "%s: type=%u\n", __func__, type);
293 281
294 282 switch (type) { switch (type) {
295 case NINEDOGS_DB_CONN_START:
296 cs = (struct conn *) d;
297 struct conn_node *cn = conn_get(cs->type, cs->conn_str, cs->conn_str_len);
283 case NINEDOGS_DB_CONN_START: {
284 cn0 = (struct nd_db_conn *) d;
285 cn = conn_get_by_conn_str(cn0->type,
286 cn0->conn_str, cn0->conn_str_len);
298 287 if (!cn) { if (!cn) {
299 char *conn_str_copy = old_malloc(cs->conn_str_len + 1);
288 char *conn_str_copy = old_malloc(cn0->conn_str_len + 1);
300 289 if (!conn_str_copy) { if (!conn_str_copy) {
301 290 xlog(1, " cannot alloc memory!\n"); xlog(1, " cannot alloc memory!\n");
302 291 break; break;
303 292 } }
304 memcpy(conn_str_copy, cs->conn_str, cs->conn_str_len);
305 conn_str_copy[cs->conn_str_len] = '\0';
293 memcpy(conn_str_copy, cn0->conn_str, cn0->conn_str_len);
294 conn_str_copy[cn0->conn_str_len] = '\0';
306 295
307 cn = old_malloc(sizeof(struct conn_node));
296 cn = old_malloc(sizeof(struct nd_db_conn));
308 297 if (!cn) { if (!cn) {
309 298 xlog(1, " cannot alloc memory!\n"); xlog(1, " cannot alloc memory!\n");
310 299 old_free(conn_str_copy); old_free(conn_str_copy);
311 300 break; break;
312 301 } }
313 xlog(100, " allocated conn cn=%p\n", cn);
302 xlog(200, " allocated conn cn=%p\n", cn);
314 303 cn->conn_str = conn_str_copy; cn->conn_str = conn_str_copy;
315 cn->conn_str_len = cs->conn_str_len;
304 cn->conn_str_len = cn0->conn_str_len;
316 305 conn_init_node(cn); conn_init_node(cn);
317 306 cn->next = conn_head; cn->next = conn_head;
318 cn->type = cs->type;
319 ninedogs_now(&cs->start);
307 cn->type = cn0->type;
308 cn->stable = 1;
309 ninedogs_now(&cn->start);
320 310
321 311 conn_head = cn; conn_head = cn;
322 312 if (!conn_tail) if (!conn_tail)
323 313 conn_tail = cn; conn_tail = cn;
324 314 } }
325 cs->cn = cn;
326 my_trace(func, 'c', cs);
327 break;
315 my_trace(func, "i", 'c', cn);
316 } break;
328 317
329 case NINEDOGS_DB_CONN_END:
330 cs = (struct conn *) d;
331 cn = cs->cn;
318 case NINEDOGS_DB_CONN_END: {
319 cn0 = (struct nd_db_conn *) d;
332 320 ninedogs_now(&end); ninedogs_now(&end);
321 if (cn0->stable == 0) {
322 cn = conn_get_by_conn_str(cn0->type,
323 cn0->conn_str, cn0->conn_str_len);
324 if (!cn)
325 break;
326
327 cn->dbh = cn0->dbh; // only here we have the real one
328 xlog(1, "DEBUG: cn0->ex=%p\n", cn0->ex);
329 cn->ex = nd_strdup(cn0->ex, -1);
330 cn->ex_len = cn0->ex_len;
331 } else {
332 cn = cn0;
333 }
333 334 u = end.tv_sec / gran; u = end.tv_sec / gran;
334 335 conn_flush_node(cn, u); conn_flush_node(cn, u);
335 336
336 337 cn->count++; cn->count++;
337 cn->handle = cs->dbh;
338 338 cn->ts.tv_sec = u * gran; cn->ts.tv_sec = u * gran;
339 my_time_diff(&elap, &end, &cs->start);
339 my_time_diff(&elap, &end, &cn->start);
340 340 my_time_add(&cn->elap, &elap); my_time_add(&cn->elap, &elap);
341 341 if (my_time_compare(&cn->min, &elap) > 0) if (my_time_compare(&cn->min, &elap) > 0)
342 342 cn->min = elap; cn->min = elap;
343 343 if (my_time_compare(&cn->max, &elap) < 0) if (my_time_compare(&cn->max, &elap) < 0)
344 344 cn->max = elap; cn->max = elap;
345 last_db_handle = cn;
345 last_db_cn = cn;
346 346 // TODO: if cs->dbh is null, there is an error! // TODO: if cs->dbh is null, there is an error!
347 my_trace(func, 'r', cs);
348 break;
347 my_trace(func, "i", 'r', cn);
348 } break;
349 349
350 case NINEDOGS_DB_CONN_CLOSE:
351 cs = (struct conn *) d;
350 case NINEDOGS_DB_CONN_CLOSE: { // TODO: we should mark the connection as free!
351 cn0 = (struct nd_db_conn *) d;
352 if (cn0->stable == 0) {
353 cn = conn_get_by_dbh(cn0->dbh);
354 if (!cn)
355 break;
356 } else {
357 cn = cn0;
358 }
352 359
353 if (last_db_handle == cs)
354 last_db_handle = NULL;
360 if (last_db_cn == cn)
361 last_db_cn = NULL;
355 362
356 my_trace(func, 'R', cs);
357 break;
363 my_trace(func, "i", 'R', cn);
364 } break;
358 365
359 case NINEDOGS_DB_QUERY_START:
366 case NINEDOGS_DB_QUERY_START: {
360 367 qs = (struct query *) d; qs = (struct query *) d;
361 368
362 369 if (qs->q_len > max_query_len) if (qs->q_len > max_query_len)
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
365 372 q_len = qs->q_len; q_len = qs->q_len;
366 373
367 374 if (qs->dbh == NULL) { if (qs->dbh == NULL) {
368 if (last_db_handle == NULL) {
369 xlog(100, " last_db_handle is NULL!\n");
375 if (last_db_cn == NULL) {
376 xlog(100, " last_db_cn is NULL!\n");
370 377 break; break;
371 378 } }
372 cn = last_db_handle;
379 cn = last_db_cn;
373 380 } else { } else {
374 cn = conn_get_by_handle(qs->dbh);
381 cn = conn_get_by_dbh(qs->dbh);
375 382 if (!cn) if (!cn)
376 383 break; break;
377 384 } }
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
415 422 old_free(q_copy); old_free(q_copy);
416 423 break; break;
417 424 } }
418 xlog(100, " allocated qn=%p for res %p\n", qn, qs->res);
419 425 query_init_node(qn); query_init_node(qn);
420 426 memcpy(qn->hash, hash, sizeof(qn->hash)); memcpy(qn->hash, hash, sizeof(qn->hash));
421 427 qn->query = q_copy; qn->query = q_copy;
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
427 433 cn->qt = qn; cn->qt = qn;
428 434 } }
429 435 qs->qn = qn; qs->qn = qn;
430 my_trace(func, 'c', qs);
431 break;
436 my_trace(func, "i", 'c', qs);
437 } break;
432 438
433 case NINEDOGS_DB_QUERY_END:
439 case NINEDOGS_DB_QUERY_END: {
434 440 qs = (struct query *) d; qs = (struct query *) d;
435 441 ninedogs_now(&end); ninedogs_now(&end);
436 442 u = end.tv_sec / gran; u = end.tv_sec / gran;
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
447 453 qn->res = qs->res; qn->res = qs->res;
448 454 qn->rows += qs->num; qn->rows += qs->num;
449 455 qn->aff += qs->aff; qn->aff += qs->aff;
450 my_time_diff(&elap, &qs->end, &qs->start);
456 my_time_diff(&elap, &end, &qs->start);
451 457 my_time_add(&qn->elap, &elap); my_time_add(&qn->elap, &elap);
452 458 if (my_time_compare(&qn->min, &elap) > 0) if (my_time_compare(&qn->min, &elap) > 0)
453 459 qn->min = elap; qn->min = elap;
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
457 463 xlog(100, " set qn->last_start from qs->start\n"); xlog(100, " set qn->last_start from qs->start\n");
458 464 qn->last_start = qs->start; qn->last_start = qs->start;
459 465 } }
460 my_trace(func, 'r', qs);
461 break;
466 my_trace(func, "i", 'r', qs);
467 } break;
462 468
463 469 case NINEDOGS_DB_FETCH_START: case NINEDOGS_DB_FETCH_START:
464 470 qs = (struct query *) d; qs = (struct query *) d;
465 my_trace(func, 'c', qs);
471 my_trace(func, "i", 'c', qs);
466 472 break; break;
467 473
468 474 case NINEDOGS_DB_FETCH_END: case NINEDOGS_DB_FETCH_END:
469 475 qs = (struct query *) d; qs = (struct query *) d;
470 my_trace(func, 'r', qs);
476 my_trace(func, "i", 'r', qs);
477 break;
478
479 case NINEDOGS_DB_RESULT_GET_START:
480 stmt = (struct nd_db_stmt *) d;
481 my_trace(func, "i", 'c', stmt);
482 break;
483
484 case NINEDOGS_DB_RESULT_GET_END:
485 stmt = (struct nd_db_stmt *) d;
486 my_trace(func, "i", 'r', stmt);
471 487 break; break;
472 488
473 489 case NINEDOGS_DB_PREPARE_START: case NINEDOGS_DB_PREPARE_START:
474 my_trace(func, 'c', (struct prepare *) d);
490 my_trace(func, "i", 'c', (struct prepare *) d);
475 491 break; break;
476 492
477 493 case NINEDOGS_DB_PREPARE_END: case NINEDOGS_DB_PREPARE_END:
478 my_trace(func, 'r', (struct prepare *) d);
494 my_trace(func, "i", 'r', (struct prepare *) d);
479 495 break; break;
480 496
481 497 case NINEDOGS_DB_EXECUTE_START: case NINEDOGS_DB_EXECUTE_START:
482 my_trace(func, 'c', (struct nd_db_execute *) d);
498 my_trace(func, "i", 'c', d);
483 499 break; break;
484 500
485 501 case NINEDOGS_DB_EXECUTE_END: case NINEDOGS_DB_EXECUTE_END:
486 my_trace(func, 'r', (struct nd_db_execute *) d);
502 my_trace(func, "i", 'r', d);
503 break;
504
505 case NINEDOGS_DB_STATEMENT_CREATE_END:
506 my_trace(func, "i", 'R', (struct nd_db_stmt *) d);
507 break;
508
509 case NINEDOGS_DB_STATEMENT_CLOSE_END:
510 my_trace(func, "i", 'R', (struct nd_db_stmt *) d);
487 511 break; break;
488 512
489 513 case NINEDOGS_DB_AUTOCOMMIT_START: case NINEDOGS_DB_AUTOCOMMIT_START:
490 my_trace(func, 'c', (struct db_autocommit *) d);
514 my_trace(func, "i", 'c', (struct db_autocommit *) d);
491 515 break; break;
492 516
493 517 case NINEDOGS_DB_AUTOCOMMIT_END: case NINEDOGS_DB_AUTOCOMMIT_END:
494 my_trace(func, 'r', (struct db_autocommit *) d);
518 my_trace(func, "i", 'r', (struct db_autocommit *) d);
495 519 break; break;
496 520
497 521 case NINEDOGS_DB_BIND_PARAM_START: case NINEDOGS_DB_BIND_PARAM_START:
498 my_trace(func, 'c', (struct nd_db_bind *) d);
522 my_trace(func, "i", 'c', (struct nd_db_bind *) d);
499 523 break; break;
500 524
501 525 case NINEDOGS_DB_BIND_PARAM_END: case NINEDOGS_DB_BIND_PARAM_END:
502 my_trace(func, 'r', (struct nd_db_bind *) d);
526 my_trace(func, "i", 'r', (struct nd_db_bind *) d);
527 break;
528
529 case NINEDOGS_DB_BIND_ONE_PARAM:
530 // We need to search for statement first and copy the parameter. why?
531 my_trace(func, "i", 'R', d);
503 532 break; break;
504 533
505 case NINEDOGS_DB_FREE_RESULT:
534 case NINEDOGS_DB_FREE_RESULT: {
506 535 struct free_result *fr = (struct free_result *) d; struct free_result *fr = (struct free_result *) d;
507 536
508 537 qn = query_get_by_res(fr->type, fr->res); qn = query_get_by_res(fr->type, fr->res);
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
516 545 //my_time_add(&qn->process_sum, &elap); //my_time_add(&qn->process_sum, &elap);
517 546
518 547 qn->res = NULL; qn->res = NULL;
519 my_trace(func, 'R', fr);
548 my_trace(func, "i", 'R', fr);
549 } break;
550
551 case NINEDOGS_DB_STMT_CLOSE_START:
552 my_trace(func, "i", 'c', (struct nd_db_stmt *) d);
520 553 break; break;
554
555 case NINEDOGS_DB_STMT_CLOSE_END:
556 my_trace(func, "i", 'r', (struct nd_db_stmt *) d);
557 break;
558
521 559 } }
522 560
523 561 ninedogs_process_post(); ninedogs_process_post();
 
... ... void ninedogs_process_db_flush(void)
529 567
530 568 conn_flush(); conn_flush();
531 569 } }
570
571 void nd_db_qs_init(const char type, struct query *qs)
572 {
573 qs->type = type;
574 qs->q = NULL;
575 for (unsigned short i = 0; i < ND_PARAMS_MAX; i++)
576 qs->params.list[i].type = ND_TYPE_FREE_SLOT;
577 }
578
579 void nd_db_stmt_init(const char type, struct nd_db_stmt *s)
580 {
581 s->type = type;
582 s->q = NULL;
583 for (unsigned short i = 0; i < ND_PARAMS_MAX; i++)
584 s->params.list[i].type = ND_TYPE_FREE_SLOT;
585 }
File agent/process_db.h changed (mode: 100644) (index dce5b00..f33d8b8)
1 #include <sys/time.h>
1 #ifndef NINEDOGS_PROCESS_DB_H
2 #define NINEDOGS_PROCESS_DB_H 1
2 3
3 struct conn
4 {
5 void *cn; // this is used in process_db
6 char type;
7 char ret;
8 char pad1[2];
9 unsigned int conn_str_len;
10 char *conn_str;
11 void *dbh;
12 struct timeval start;
13 int flags; // used at least by mysqli_real_connect
14 int pad2;
15 };
4 #include <sys/time.h>
16 5
17 #define ND_PARAMS_MAX 100
6 #include "../common/params.h"
18 7
19 #define ND_PARAMS_TYPE_NULL 0
20 #define ND_PARAMS_TYPE_LONG 1
21 #define ND_PARAMS_TYPE_DOUBLE 2
22 #define ND_PARAMS_TYPE_STRING 3
23 struct params_array_one
8 struct nd_db_conn
24 9 { {
25 unsigned char type; // see ND_PARAMS_TYPE_*
26 unsigned char pad1;
27 unsigned short length; // for 'str'
28 unsigned char pad2[4];
29 union {
30 char *str;
31 double d;
32 long l;
33 };
34 };
35
36 struct params_array
37 {
38 unsigned short len;
39 unsigned short pad[3];
40 struct params_array_one list[ND_PARAMS_MAX];
10 char type;
11 char pad1;
12 unsigned short ex_len;
13 unsigned int count; // how many connections took place
14 const void *dbh;
15 const char *conn_str, *ex;
16 unsigned short conn_str_len;
17 unsigned short ok:1; // TODO: we should store this in 'res'
18 unsigned short stable:1; // if 1, it is a real cn, not one passed to process_db
19 unsigned short pad2:14;
20 unsigned int flags;
21 struct timeval last_query_try, start;
22 struct timeval ts, min, max, elap;
23 struct query_node *qh, *qt;
24 struct nd_db_conn *next;
41 25 }; };
42 26
43 27 struct query struct query
44 28 { {
45 29 void *cn; // this is used in process_db void *cn; // this is used in process_db
46 30 void *qn; // this is used in process_db void *qn; // this is used in process_db
47 struct params_array params; // this is used in process_db
31 struct nd_params_array params; // this is used in process_db
48 32 char type; char type;
49 33 char ret; // used at least by mysqli_fetch_array char ret; // used at least by mysqli_fetch_array
50 34 char pad1[2]; char pad1[2];
 
... ... struct query
52 36 unsigned int q_len; unsigned int q_len;
53 37 unsigned int pad2; unsigned int pad2;
54 38 void *dbh; void *dbh;
55 struct timeval start, end;
56 char *q;
39 struct timeval start;
40 const char *q;
57 41 char *err, *err_code; char *err, *err_code;
58 42 unsigned long num, aff, mode; // 'mode' is used by mysql unsigned long num, aff, mode; // 'mode' is used by mysql
59 43 void *res; void *res;
 
... ... struct free_result
68 52 void *res; void *res;
69 53 }; };
70 54
71 struct prepare
72 {
73 char *q;
74 char type;
75 char ret;
76 char pad[2];
77 unsigned int q_len;
78 void *dbh;
79 void *stmt;
80 };
81
82 struct nd_db_execute
55 #define ND_DB_STMT_RET_IS_BOOL 1
56 struct nd_db_stmt
83 57 { {
84 58 void *stmt; void *stmt;
85 struct params_array params; // this is used in process_db
59 const char *q, *ex;
60 struct nd_params_array params; // this is used in process_db
86 61 char type; char type;
87 62 char ret; char ret;
88 char pad1[6];
63 unsigned short flags; // See ND_DB_STMT_*
64 unsigned int q_len; // TODO decide between 16 and 32
65 void *dbh;
66 void *res;
89 67 unsigned long num, aff; unsigned long num, aff;
68 unsigned short ex_len;
69 unsigned short pad[3];
70 // db specific
71 union {
72 struct {
73 long mode;
74 } oci;
75 };
90 76 }; };
91 77
92 78 struct db_autocommit struct db_autocommit
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d);
115 101
116 102 void ninedogs_process_db_flush(void); void ninedogs_process_db_flush(void);
117 103
104 void nd_db_qs_init(const char type, struct query *qs);
105 void nd_db_stmt_init(const char type, struct nd_db_stmt *s);
106
107 #endif
File agent/process_ssl.c changed (mode: 100644) (index ef05bcf..e1fce02)
... ... static void send_info(const char *info, const unsigned short info_len)
17 17 unsigned char *buf; unsigned char *buf;
18 18 unsigned int len; unsigned int len;
19 19
20 pack(&buf, &len, "T4 NN vs",
20 pack(&buf, &len, "T4 _N vs",
21 21 NINEDOGS_NET_SSL_INFO, info, info_len); NINEDOGS_NET_SSL_INFO, info, info_len);
22 22 if (!buf) if (!buf)
23 23 return; return;
 
... ... static void cert_send_node(const struct cert *cn)
32 32 unsigned char *buf; unsigned char *buf;
33 33 unsigned int len; unsigned int len;
34 34
35 pack(&buf, &len, "T4 NN ps" "us" "is" "s8 e8" "nb tc as" "ks K4",
35 pack(&buf, &len, "T4 _N ps" "us" "is" "s8 e8" "nb tc as" "ks K4",
36 36 NINEDOGS_NET_SSL_CERT, cn->uri, cn->uri_len, NINEDOGS_NET_SSL_CERT, cn->uri, cn->uri_len,
37 37 cn->subj, cn->subj_len, cn->subj, cn->subj_len,
38 38 cn->issuer, cn->issuer_len, cn->issuer, cn->issuer_len,
 
... ... void ninedogs_process_ssl(const unsigned int type, const void *d)
148 148 xlog(10, "%s: type=%s d=%p\n", __func__, type2name(type), d); xlog(10, "%s: type=%s d=%p\n", __func__, type2name(type), d);
149 149
150 150 switch (type) { switch (type) {
151 case NINEDOGS_SSL_INFO:
151 case NINEDOGS_SSL_INFO: {
152 152 const struct ssl_info *i = (const struct ssl_info *) d; const struct ssl_info *i = (const struct ssl_info *) d;
153 153 send_info(i->info, i->info_len); send_info(i->info, i->info_len);
154 break;
154 } break;
155 155
156 case NINEDOGS_SSL_CERT:
156 case NINEDOGS_SSL_CERT: {
157 157 const struct cert *c = (const struct cert *) d; const struct cert *c = (const struct cert *) d;
158 158 char send = 0; char send = 0;
159 159 cn = cert_get_by_uri(c->uri); cn = cert_get_by_uri(c->uri);
 
... ... void ninedogs_process_ssl(const unsigned int type, const void *d)
197 197
198 198 if (send) if (send)
199 199 cert_send_node(cn); cert_send_node(cn);
200 break;
200 } break;
201 201 } }
202 202
203 203 ninedogs_process_post(); ninedogs_process_post();
File agent/process_url.c changed (mode: 100644) (index 864a37a..042135f)
9 9 #include "process.h" #include "process.h"
10 10 #include "process_url.h" #include "process_url.h"
11 11
12 extern void my_trace(const char *func, const char type, ...);
12 extern void my_trace(const char *func, const char *tf, const char type, ...);
13 13 extern void *(*old_malloc)(size_t size); extern void *(*old_malloc)(size_t size);
14 14 extern void (*old_free)(void *p); extern void (*old_free)(void *p);
15 15
 
... ... void ninedogs_process_url(const char *func, const unsigned int type, void *d)
222 222 switch (type) { switch (type) {
223 223 // url may be null! we need to intercept 'setopt' and use it // url may be null! we need to intercept 'setopt' and use it
224 224 // TODO: what is the reason to hook this for stats?! Only to capture the url // TODO: what is the reason to hook this for stats?! Only to capture the url
225 case NINEDOGS_URL_INIT_END:
225 case NINEDOGS_URL_INIT_END: {
226 226 in = (struct nd_url *) d; in = (struct nd_url *) d;
227 227 q = search_or_create(in); q = search_or_create(in);
228 228 if (!q) if (!q)
229 229 break; break;
230 my_trace(func, 'R', in);
231 break;
230 my_trace(func, "i", 'R', in);
231 } break;
232 232
233 case NINEDOGS_URL_SETOPT_END:
233 case NINEDOGS_URL_SETOPT_END: {
234 234 in = (struct nd_url *) d; in = (struct nd_url *) d;
235 235 q = search_or_create(in); q = search_or_create(in);
236 236 if (!q) if (!q)
237 237 break; break;
238 my_trace(func, 'R', in);
239 break;
238 my_trace(func, "i", 'R', in);
239 } break;
240 240
241 case NINEDOGS_URL_CLOSE_END:
241 case NINEDOGS_URL_CLOSE_END: {
242 242 in = (struct nd_url *) d; in = (struct nd_url *) d;
243 243 q = search_or_create(in); q = search_or_create(in);
244 244 if (!q) if (!q)
245 245 break; break;
246 my_trace(func, 'R', in);
247 break;
246 my_trace(func, "i", 'R', in);
247 } break;
248 248
249 case NINEDOGS_URL_START:
249 case NINEDOGS_URL_START: {
250 250 in = (struct nd_url *) d; in = (struct nd_url *) d;
251 251 q = search_or_create(in); q = search_or_create(in);
252 252 if (!q) if (!q)
253 253 break; break;
254 254
255 255 in->node = q; // to be used in _END in->node = q; // to be used in _END
256 my_trace(func, 'c', in);
256 my_trace(func, "i", 'c', in);
257 257 ninedogs_now(&in->start); ninedogs_now(&in->start);
258 break;
258 } break;
259 259
260 case NINEDOGS_URL_END:
260 case NINEDOGS_URL_END: {
261 261 in = (struct nd_url *) d; in = (struct nd_url *) d;
262 262 ninedogs_now(&end); ninedogs_now(&end);
263 263 u = end.tv_sec / gran; u = end.tv_sec / gran;
 
... ... void ninedogs_process_url(const char *func, const unsigned int type, void *d)
282 282 } else { } else {
283 283 q->errors++; q->errors++;
284 284 } }
285 my_trace(func, 'r', in);
286 break;
285 my_trace(func, "i", 'r', in);
286 } break;
287 287 } }
288 288
289 289 ninedogs_process_post(); ninedogs_process_post();
File agent/python.c changed (mode: 100644) (index e08913e..e1e504f)
... ... static char *python_get_value(const struct zval *z)
213 213 case 3: return ""; case 3: return "";
214 214 case 4: snprintf(ret, sizeof(ret), "%ld", z->value.lval); return ret; case 4: snprintf(ret, sizeof(ret), "%ld", z->value.lval); return ret;
215 215 case 5: snprintf(ret, sizeof(ret), "%f", z->value.dval); return ret; case 5: snprintf(ret, sizeof(ret), "%f", z->value.dval); return ret;
216 case 6:
216 case 6: {
217 217 struct zend_string *zs = z->value.str; struct zend_string *zs = z->value.str;
218 return zs->val;
218 return zs->val; }
219 219 case 8: case 8:
220 220 snprintf(ret, sizeof(ret), "%p", z->value.p); return ret; snprintf(ret, sizeof(ret), "%p", z->value.p); return ret;
221 221 case 9: case 9:
 
... ... static void python_zed_dump(const char *prefix, struct zend_execute_data *p)
308 308 } }
309 309 } }
310 310
311 #if 0
311 312 static void zend_array_to_params_array(struct query *q, struct zend_array *za) static void zend_array_to_params_array(struct query *q, struct zend_array *za)
312 313 { {
313 314 unsigned int i = 0, max; unsigned int i = 0, max;
 
... ... static void zend_array_to_params_array(struct query *q, struct zend_array *za)
343 344 bs, bs->h, zs, python_get_type(_z), python_get_value(_z)); bs, bs->h, zs, python_get_type(_z), python_get_value(_z));
344 345
345 346 if (_z->u1.v.type == 4) { if (_z->u1.v.type == 4) {
346 q->params.list[i].type = ND_PARAMS_TYPE_LONG;
347 q->params.list[i].type = ND_TYPE_LONG;
347 348 q->params.list[i].l = _z->value.lval; q->params.list[i].l = _z->value.lval;
348 349 } else if (_z->u1.v.type == 5) { } else if (_z->u1.v.type == 5) {
349 q->params.list[i].type = ND_PARAMS_TYPE_DOUBLE;
350 q->params.list[i].type = ND_TYPE_DOUBLE;
350 351 q->params.list[i].d = _z->value.dval; q->params.list[i].d = _z->value.dval;
351 352 } else if (_z->u1.v.type == 6) { } else if (_z->u1.v.type == 6) {
352 q->params.list[i].type = ND_PARAMS_TYPE_STRING;
353 q->params.list[i].type = ND_TYPE_STRING;
353 354 struct zend_string *zs = _z->value.str; struct zend_string *zs = _z->value.str;
354 355 q->params.list[i].str = zs->val; q->params.list[i].str = zs->val;
355 356 q->params.list[i].length = zs->len; q->params.list[i].length = zs->len;
 
... ... static void zend_array_to_params_array(struct query *q, struct zend_array *za)
360 361 break; break;
361 362 } }
362 363 } }
364 #endif
363 365
364 366 void *(*old_python_pg_last_error)(struct zend_execute_data *, struct zval *); void *(*old_python_pg_last_error)(struct zend_execute_data *, struct zval *);
365 367 static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv) static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv)
 
... ... static void *my_pg_close(struct zend_execute_data *e, struct zval *retv)
386 388 void *ret; void *ret;
387 389 unsigned int num_args, s; unsigned int num_args, s;
388 390 struct zval *z; struct zval *z;
389 struct conn cs;
391 struct nd_db_conn c;
390 392
391 393 num_args = e->This.u2.num_args; num_args = e->This.u2.num_args;
392 394 //xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); //xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
393 395
394 cs.type = 'P';
396 c.type = 'P';
395 397 if (num_args == 1) { if (num_args == 1) {
396 398 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
397 399 // handler, may be null // handler, may be null
398 400 z = (struct zval *) e + s; s++; z = (struct zval *) e + s; s++;
399 cs.dbh = z->value.p;
400 //xlog(101, " h=%p\n", cs.dbh);
401 c.dbh = z->value.p;
402 //xlog(101, " h=%p\n", c.dbh);
401 403 } else { } else {
402 cs.dbh = NULL;
404 c.dbh = NULL;
403 405 } }
404 406
405 407 ret = old_python_pg_close(e, retv); ret = old_python_pg_close(e, retv);
406 ninedogs_process_db("pg_close", NINEDOGS_DB_CONN_CLOSE, &cs);
408 ninedogs_process_db("pg_close", NINEDOGS_DB_CONN_CLOSE, &c);
407 409
408 410 return ret; return ret;
409 411 } }
 
... ... static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv)
415 417 unsigned int num_args, s; unsigned int num_args, s;
416 418 struct zval *z; struct zval *z;
417 419 struct zend_string *q; struct zend_string *q;
418 struct conn cs;
420 struct nd_db_conn c;
419 421
420 422 num_args = e->This.u2.num_args; num_args = e->This.u2.num_args;
421 423 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
422 424
423 425 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
424 cs.type = 'P';
426 c.type = 'P';
425 427
426 428 // connection string // connection string
427 429 z = (struct zval *) e + s; s++; z = (struct zval *) e + s; s++;
428 430 q = z->value.str; q = z->value.str;
429 cs.conn_str = q->val;
430 cs.conn_str_len = q->len;
431 //xlog(50, " conn[%u]: %s\n", cs.conn_str_len, cs.conn_str);
431 c.conn_str = q->val;
432 c.conn_str_len = q->len;
433 //xlog(50, " conn[%u]: %s\n", c.conn_str_len, c.conn_str);
432 434
433 ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_START, &cs);
435 ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_START, &c);
434 436 ret = old_python_pg_connect(e, retv); ret = old_python_pg_connect(e, retv);
435 437 if (!retv) { if (!retv) {
436 438 xlog(0, "DEBUG: old_python_pg_connect returned retv NULL\n"); xlog(0, "DEBUG: old_python_pg_connect returned retv NULL\n");
 
... ... static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv)
442 444
443 445 // python7 returns resource, python8.1 returns object // python7 returns resource, python8.1 returns object
444 446 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
445 cs.dbh = retv->value.p;
447 c.dbh = retv->value.p;
446 448 else else
447 cs.dbh = NULL;
448 ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_END, &cs);
449 c.dbh = NULL;
450 ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_END, &c);
449 451
450 452 return ret; return ret;
451 453 } }
 
... ... static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv)
457 459 unsigned int num_args, s; unsigned int num_args, s;
458 460 struct zval *z; struct zval *z;
459 461 struct zend_string *q; struct zend_string *q;
460 struct conn cs;
462 struct nd_db_conn c;
461 463
462 464 num_args = e->This.u2.num_args; num_args = e->This.u2.num_args;
463 465 xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
464 466
465 467 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
466 cs.type = 'P';
468 c.type = 'P';
467 469
468 470 // connection string // connection string
469 471 z = (struct zval *) e + s; s++; z = (struct zval *) e + s; s++;
470 472 q = z->value.str; q = z->value.str;
471 cs.conn_str = q->val;
472 cs.conn_str_len = q->len;
473 xlog(50, " conn: %s\n", cs.conn_str);
473 c.conn_str = q->val;
474 c.conn_str_len = q->len;
475 xlog(50, " conn: %s\n", c.conn_str);
474 476
475 ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_START, &cs);
477 ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_START, &c);
476 478 ret = old_python_pg_pconnect(e, retv); ret = old_python_pg_pconnect(e, retv);
477 479 if (!retv) if (!retv)
478 480 return ret; return ret;
 
... ... static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv)
482 484
483 485 // python7 returns resource, python8.1 returns object // python7 returns resource, python8.1 returns object
484 486 if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9))
485 cs.dbh = retv->value.p;
487 c.dbh = retv->value.p;
486 488 else else
487 cs.dbh = NULL;
488 ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_END, &cs);
489 c.dbh = NULL;
490 ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_END, &c);
489 491
490 492 return ret; return ret;
491 493 } }
 
... ... static void *my_pg_query(struct zend_execute_data *e, struct zval *retv)
619 621 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
620 622 para = (struct zval *) e + s; para = (struct zval *) e + s;
621 623 qs.type = 'P'; // if dbh is null, we do not know the type qs.type = 'P'; // if dbh is null, we do not know the type
622 qs.params.len = 0;
623 624
624 625 if (num_args == 2) { if (num_args == 2) {
625 626 // link // link
 
... ... static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv)
679 680
680 681 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
681 682 qs.type = 'P'; qs.type = 'P';
682 qs.params.len = 0;
683 683
684 684 // link // link
685 685 z = (struct zval *) e + s; s++; z = (struct zval *) e + s; s++;
 
... ... static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv)
731 731 para = (struct zval *) e + s; para = (struct zval *) e + s;
732 732 qs.type = 'P'; qs.type = 'P';
733 733 qs.q = NULL; qs.q = NULL;
734 qs.params.len = 0;
735 734
736 735 // link // link
737 736 z = (struct zval *) e + s; s++; z = (struct zval *) e + s; s++;
File agent/text2process.c changed (mode: 100644) (index d6c5582..32efd68)
1 #include <string.h>
1 #include <errno.h>
2 #include <stdio.h>
2 3 #include <stdlib.h> #include <stdlib.h>
4 #include <string.h>
3 5
4 6 #include "text2process.h" #include "text2process.h"
5 7
 
7 9 #include "tools.h" #include "tools.h"
8 10 #include "ctools.h" #include "ctools.h"
9 11 #include "process_ssl.h" #include "process_ssl.h"
12 #include "process_db.h"
10 13
11 14 extern char trace_enabled; extern char trace_enabled;
12 15
16 /*
17 * Decodes a t2p token (Thhhh...): T=type, hhhh-len_in_hexa
18 */
19 static const char *t2p_decode(char *x, const char *s, unsigned int *off,
20 const unsigned int len, unsigned int *xlen)
21 {
22 const char *ret;
23
24 if (*off + 1 + 4 > len) {
25 xlog(1, "%s: Len %u is too small (1) s+off=[%s]!\n",
26 __func__, len - *off, s + *off);
27 return NULL;
28 }
29
30 *x = s[*off]; *off = *off + 1;
31
32 char hhhh[5];
33 memcpy(hhhh, s + *off, 4); *off = *off + 4; ret = s + *off;
34 hhhh[4] = '\0';
35 *xlen = strtoul(hhhh, NULL, 16);
36
37 if (*off + *xlen > len) {
38 xlog(1, "%s: Len is too small! off=%u len=%u xlen=%u\n",
39 __func__, *off, len, *xlen);
40 return 0;
41 }
42
43 *off = *off + *xlen;
44
45 return ret;
46 }
47
13 48 // Example: Js38 C=ES, O=ACCV, OU=PKIACCV, CN=ACCVRAIZ1i38 C=ES, O=ACCV, // Example: Js38 C=ES, O=ACCV, OU=PKIACCV, CN=ACCVRAIZ1i38 C=ES, O=ACCV,
14 49 // OU=PKIACCV, CN=ACCVRAIZ1a3 RSAx16 5ec3b7a6437fa4e0S10 1304588257E10 1924940257 // OU=PKIACCV, CN=ACCVRAIZ1a3 RSAx16 5ec3b7a6437fa4e0S10 1304588257E10 1924940257
15 50 static void t2p_cert(const char *s, const unsigned int len) static void t2p_cert(const char *s, const unsigned int len)
 
... ... static void t2p_cert(const char *s, const unsigned int len)
35 70 xlog(0, "%s: type '%c' has not enough data: %s\n", __func__, type, s + off); xlog(0, "%s: type '%c' has not enough data: %s\n", __func__, type, s + off);
36 71 return; return;
37 72 } }
38 if (s[off] != ' ') {
39 xlog(0, "%s: type '%c': sublen=%u: ' ' not present at s=[%s]",
40 __func__, type, sublen, s + off);
41 return;
42 }
43 off++;
44 73
45 74 xlog(0, " type=%c sublen=%u s=%s\n", type, sublen, s + off); xlog(0, " type=%c sublen=%u s=%s\n", type, sublen, s + off);
46 75 switch (type) { switch (type) {
 
... ... static void t2p_cert(const char *s, const unsigned int len)
67 96 ninedogs_process_ssl(NINEDOGS_SSL_CERT, &c); ninedogs_process_ssl(NINEDOGS_SSL_CERT, &c);
68 97 } }
69 98
70 void text2process(const char *s, unsigned int len)
99 // Examples:
100 // Pcsh00085674cd4dc003djdbc:postgresql://localhost:5432/ninedogs?ApplicationName=pg1
101 // Pceh00085674cd4dR0008239963d8
102 // TODO: we need to dealocate memory!
103 static void t2p_db(const char *s, const unsigned int len)
71 104 { {
72 xlog(1, "%s: s=%s\n", __func__, s);
105 unsigned int off = 0, xlen, max, etype = 0, index = 0, svalue_len = 0;
106 char db_type, type, subtype, x;
107 unsigned long hash = 0, R = 0;
108 const char *q0 = NULL, *conn_str = NULL, *ex = NULL;
109 unsigned short q0_len = 0, conn_str_len = 0, ex_len = 0;
110 int value = 0;
111 char svalue[65536] = {};
112
113 xlog(90, "%s: s=[%s] len=%u\n", __func__, s, len);
114
115 if (len < 4)
116 return;
117
118 db_type = s[off++];
119 type = s[off++];
120 subtype = s[off++];
121 xlog(1, " db_type=%c type=%c subtype=%c\n", db_type, type, subtype);
122
123 while (off < len) {
124 const char *r = t2p_decode(&x, s, &off, len, &xlen);
125 if (!r)
126 return;
127 if (x == 'h') {
128 char shash[17];
129 max = sizeof(shash) - 1;
130 if (max > xlen)
131 max = xlen;
132 memcpy(shash, r, max); shash[max] = '\0';
133 hash = strtoul(shash, NULL, 16);
134 xlog(1, " hash=0x%lx\n", hash);
135 } else if (x == 'R') {
136 char sret[17];
137 max = sizeof(sret) - 1;
138 if (max > xlen)
139 max = xlen;
140 memcpy(sret, r, max); sret[max] = '\0';
141 R = strtoul(sret, NULL, 16);
142 xlog(1, " R=0x%lx\n", R);
143 } else if (x == 'c') {
144 conn_str = r;
145 conn_str_len = xlen;
146 xlog(90, " conn_str=[%s] conn_str_len=%hu\n", conn_str, conn_str_len);
147 } else if (x == 'q') {
148 q0 = r;
149 q0_len = xlen;
150 xlog(90, " q=[%s] q_len=%hu\n", q0, q0_len);
151 } else if (x == 'e') {
152 ex = r;
153 ex_len = xlen;
154 xlog(90, " ex=[%s] ex_len=%hu\n", ex, ex_len);
155 } else if (x == 'i') { // index for setInt & co.
156 char tmp[32];
157 max = sizeof(tmp) - 1;
158 if (max > xlen)
159 max = xlen;
160 memcpy(tmp, r, max); tmp[max] = '\0';
161 index = strtoul(tmp, NULL, 10);
162 xlog(90, " index=%u\n", index);
163 } else if (x == 'v') { // value for setInt
164 char tmp[32];
165 max = sizeof(tmp) - 1;
166 if (max > xlen)
167 max = xlen;
168 memcpy(tmp, r, max); tmp[max] = '\0';
169 value = strtol(tmp, NULL, 10);
170 xlog(90, " value=%d\n", value);
171 } else if (x == 's') { // value for setString
172 svalue_len = sizeof(svalue) - 1;
173 if (svalue_len > xlen)
174 svalue_len = xlen;
175 memcpy(svalue, r, svalue_len); svalue[svalue_len] = '\0';
176 xlog(90, " svalue_len=%u svalue=%s\n", svalue_len, svalue);
177 } else {
178 xlog(1, "%s: cannot decode type %c! Ignore it.\n", __func__, x);
179 }
180 }
181
182 if (type == 'c') { // connection open
183 struct nd_db_conn c;
184 c.type = db_type;
185 c.stable = 0;
186 c.conn_str = conn_str;
187 c.conn_str_len = conn_str_len;
188 c.ex = ex; c.ex_len = ex_len;
189 if (subtype == 's') {
190 etype = NINEDOGS_DB_CONN_START;
191 } else {
192 c.dbh = (void *) R;
193 etype = NINEDOGS_DB_CONN_END;
194 }
195 ninedogs_process_db("java/db/connect", etype, &c);
196 } else if (type == 'x') { // connection close
197 struct nd_db_conn c;
198 c.type = db_type;
199 c.stable = 0;
200 c.dbh = (void *) hash;
201 ninedogs_process_db("java/db/close", NINEDOGS_DB_CONN_CLOSE, &c);
202 } else if ((type == 'e') || (type == 'E') || (type == 'P')) {
203 // e/E: [] [ResultSet(e)/Boolean(E) rs1 = ps.executeQuery()]
204 // P: [P] [ResultSet rs1 = ps.executeQuery()]
205 struct nd_db_stmt stmt;
206 stmt.type = db_type;
207 stmt.stmt = (void *) hash;
208 stmt.flags |= type == 'E' ? ND_DB_STMT_RET_IS_BOOL : 0;
209 stmt.res = (void *) R;
210 stmt.ex = ex; stmt.ex_len = ex_len;
211 if (subtype == 's')
212 etype = NINEDOGS_DB_EXECUTE_START;
213 else
214 etype = NINEDOGS_DB_EXECUTE_END;
215 if (type == 'P')
216 ninedogs_process_db("java/db/stmt/execute", etype, &stmt);
217 else
218 ninedogs_process_db("java/db/prepared/execute", etype, &stmt);
219 } else if (type == 'p') { // [PreparedStatement stmt = con.prepareStatement("SELECT ? AS id")]
220 struct nd_db_stmt stmt;
221 stmt.type = db_type;
222 stmt.dbh = (void *) hash;
223 stmt.q = q0;
224 stmt.q_len = q0_len;
225 stmt.stmt = (void *) R;
226 stmt.ex = ex; stmt.ex_len = ex_len;
227 if (subtype == 's')
228 etype = NINEDOGS_DB_PREPARE_START;
229 else
230 etype = NINEDOGS_DB_PREPARE_END;
231 ninedogs_process_db("java/db/prepare", etype, &stmt);
232 } else if (type == 'f') { // [Statement stmt = con.createStatement()]
233 struct nd_db_stmt stmt;
234 stmt.type = db_type;
235 stmt.dbh = (void *) hash;
236 stmt.stmt = (void *) R;
237 stmt.ex = ex; stmt.ex_len = ex_len;
238 ninedogs_process_db("java/db/stmt/create", NINEDOGS_DB_STATEMENT_CREATE_END, &stmt);
239 } else if (type == 'w') { // [stmt.close()]
240 struct nd_db_stmt stmt;
241 stmt.type = db_type;
242 stmt.stmt = (void *) hash;
243 ninedogs_process_db("java/db/stmt/close", NINEDOGS_DB_STATEMENT_CLOSE_END, &stmt);
244 } else if (type == 'Q') { // [ResultSet rs2 = stmt.executeQuery("SELECT * FROM n1 LIMIT 2");]
245 struct nd_db_stmt stmt;
246 stmt.type = db_type;
247 stmt.stmt = (void *) hash;
248 stmt.q = q0;
249 stmt.q_len = q0_len;
250 stmt.res = (void *) R;
251 stmt.ex = ex; stmt.ex_len = ex_len;
252 if (subtype == 's')
253 etype = NINEDOGS_DB_PREPARE_START;
254 else
255 etype = NINEDOGS_DB_PREPARE_END;
256 ninedogs_process_db("java/db/stmt/execute/sql", etype, &stmt);
257 } else if (type == 'g') { // [ResultSet rs2 = p1.getResultSet()]
258 struct nd_db_stmt stmt;
259 stmt.type = db_type;
260 stmt.stmt = (void *) hash;
261 stmt.res = (void *) R;
262 stmt.ex = ex; stmt.ex_len = ex_len;
263 if (subtype == 's')
264 etype = NINEDOGS_DB_RESULT_GET_START;
265 else
266 etype = NINEDOGS_DB_RESULT_GET_END;
267 ninedogs_process_db("java/db/result/get", etype, &stmt);
268 } else if (type == 'b') { // [P] [ps.setInt(1, 12345)]
269 struct nd_db_stmt stmt;
270 stmt.type = db_type;
271 stmt.stmt = (void *) hash;
272 if (subtype == 'x')
273 stmt.res = NULL;
274 else
275 stmt.res = (void *) 1; // just to signal that is ok
276 stmt.ex = ex; stmt.ex_len = ex_len;
277 stmt.params.list[1].length = index; // abuse alert - used as index
278 stmt.params.list[0].l = value;
279 ninedogs_process_db("java/db/stmt/setInt",
280 NINEDOGS_DB_BIND_ONE_PARAM, &stmt);
281 } else if (type == 'S') { // [P] [ps.setString(2, "abc")]
282 struct nd_db_stmt stmt;
283 stmt.type = db_type;
284 stmt.stmt = (void *) hash;
285 if (subtype == 'x')
286 stmt.res = NULL;
287 else
288 stmt.res = (void *) 1; // just to signal that is ok
289 stmt.ex = ex; stmt.ex_len = ex_len;
290 stmt.params.list[1].length = index; // abuse alert - used as index
291 stmt.params.list[0].str = svalue;
292 stmt.params.list[0].length = svalue_len;
293 ninedogs_process_db("java/db/stmt/setString",
294 NINEDOGS_DB_BIND_ONE_PARAM, &stmt);
295 } else {
296 xlog(1, "%s: Unknown type [%c]!\n", __func__, type);
297 }
298 }
299
300 void text2process(const char *s, const unsigned int len)
301 {
302 xlog(100, "%s: s=%s\n", __func__, s);
73 303
74 304 if (s[len - 1] != '\0') { if (s[len - 1] != '\0') {
75 305 xlog(0, " Seems we do not have the full string s[len - 1]=[0x%02hhx]!\n", xlog(0, " Seems we do not have the full string s[len - 1]=[0x%02hhx]!\n",
 
... ... void text2process(const char *s, unsigned int len)
83 313 return; return;
84 314 } }
85 315
316 errno = 0;
317
86 318 switch (s[0]) { switch (s[0]) {
87 case 'c': t2p_cert(s + 1, len - 1); break;
88 default: xlog(0, "Unknown text type [%c]!\n", s[0]);
319 case 'c': t2p_cert(s + 1, len - 2); break;
320 case 'D': t2p_db(s + 1, len - 2); break;
321 case 'L': xlog(0, "L: %s", s + 1); break;
322 default: xlog(1, "Unknown text type [%c] [%s]!\n", s[0], s);
89 323 } }
90 324 } }
91 325
File agent/text2process.h changed (mode: 100644) (index 07f47d9..09f195d)
1 void text2process(const char *s, unsigned int len);
1 void text2process(const char *s, const unsigned int len);
2 2
File agent/trace_encode.c added (mode: 100644) (index 0000000..e325706)
1 #include "trace_encode.h"
2
3 #include "../common/ids.h"
4
5 extern void xlog(const unsigned int level, const char *format, ...);
6
7 void my_trace_put8(unsigned char *buf, unsigned int *i, const uint8_t v)
8 {
9 buf[*i] = v; *i = *i + 1;
10 }
11
12 void my_trace_put16(unsigned char *buf, unsigned int *i, const uint16_t v)
13 {
14 uint16_t u = htobe16(v);
15 memcpy(buf + *i, &u, 2); *i = *i + 2;
16 }
17
18 void my_trace_put32(unsigned char *buf, unsigned int *i, const uint32_t v)
19 {
20 uint32_t u = htobe32(v);
21 memcpy(buf + *i, &u, 4); *i = *i + 4;
22 }
23
24 void my_trace_put64(unsigned char *buf, unsigned int *i, const uint64_t v)
25 {
26 uint64_t u = htobe64(v);
27 memcpy(buf + *i, &u, 8); *i = *i + 8;
28 }
29
30 void my_trace_put_double(unsigned char *buf, unsigned int *i, const double v)
31 {
32 uint64_t u;
33 memcpy(&u, &v, 8);
34 my_trace_put64(buf, i, u);
35 }
36
37 void my_trace_put_bool(unsigned char *buf, unsigned int *i, const char v)
38 {
39 buf[*i] = v; *i = *i + 1;
40 }
41
42 void my_trace_put(unsigned char *buf, unsigned int *i,
43 const void *in, const size_t in_len)
44 {
45 //xlog(1, "%s: i=%u in=%p in_len=%zu\n",
46 // __func__, i, in, in_len);
47
48 if (!in) {
49 xlog(1, "in is NULL!\n");
50 return;
51 }
52
53 if (in_len == 0)
54 return;
55
56 memcpy(buf + *i, in, in_len);
57 *i = *i + in_len;
58 }
59
60 // Seems that all fields are stored in BE order
61 void my_trace_sockaddr(unsigned char *buf, unsigned int *i,
62 const struct sockaddr *a, const int len)
63 {
64 my_trace_put16(buf, i, len);
65 my_trace_put(buf, i, a, a ? len : 0);
66 }
67
68 void my_trace_put_stat(unsigned char *buf, unsigned int *i, struct stat *s)
69 {
70 my_trace_put64(buf, i, s->st_dev);
71 my_trace_put64(buf, i, s->st_ino);
72 my_trace_put32(buf, i, s->st_mode);
73 my_trace_put64(buf, i, s->st_nlink);
74 my_trace_put32(buf, i, s->st_uid);
75 my_trace_put32(buf, i, s->st_gid);
76 my_trace_put64(buf, i, s->st_rdev);
77 my_trace_put64(buf, i, s->st_size);
78 my_trace_put64(buf, i, s->st_blksize);
79 my_trace_put64(buf, i, s->st_blocks);
80 my_trace_put64(buf, i, s->st_atim.tv_sec);
81 my_trace_put32(buf, i, s->st_atim.tv_nsec);
82 my_trace_put64(buf, i, s->st_mtim.tv_sec);
83 my_trace_put32(buf, i, s->st_mtim.tv_nsec);
84 my_trace_put64(buf, i, s->st_ctim.tv_sec);
85 my_trace_put32(buf, i, s->st_ctim.tv_nsec);
86 }
87
88 void my_trace_put_string_array(unsigned char *buf, unsigned int *i, char *list[])
89 {
90 unsigned int j = 0;
91
92 while (1) {
93 if (!list[j]) {
94 my_trace_put32(buf, i, 0);
95 break;
96 }
97
98 unsigned short len = strlen(list[j]);
99 my_trace_put16(buf, i, len);
100 my_trace_put(buf, i, list[j], len);
101 j++;
102 }
103 }
104
105 void my_trace_put_hostent(unsigned char *buf, unsigned int *i, struct hostent *he)
106 {
107 if (!he)
108 return;
109
110 int len = strlen(he->h_name);
111 my_trace_put8(buf, i, len);
112 my_trace_put(buf, i, he->h_name, len);
113
114 for (int j = 0; ; j++) {
115 if (!he->h_aliases[j]) {
116 my_trace_put8(buf, i, 0);
117 break;
118 }
119
120 len = strlen(he->h_aliases[j]);
121 my_trace_put8(buf, i, len);
122 my_trace_put(buf, i, he->h_aliases[j], len);
123 }
124
125 my_trace_put8(buf, i, he->h_addrtype);
126 my_trace_put8(buf, i, he->h_length);
127
128 int count = 0;
129 for (int j = 0; ; j++) {
130 if (!he->h_addr_list[j])
131 break;
132 count++;
133 }
134
135 my_trace_put8(buf, i, count);
136 for (int j = 0; j < count; j++) {
137 xlog(0, " DEBUG: addr[%d]=[%s]\n", j, he->h_addr_list[j]);
138 my_trace_put(buf, i, he->h_addr_list[j], he->h_length);
139 }
140 }
141
142 void my_trace_put_params(unsigned char *buf, unsigned int *i,
143 const struct nd_params_array *pa, const unsigned char filter_bind_way)
144 {
145 xlog(1, "%s: filter_bind_way=%hhu\n", __func__, filter_bind_way);
146
147 for (unsigned short j = 0; j < ND_PARAMS_MAX; j++) {
148 const struct nd_params_array_one *o = &pa->list[j];
149 if (o->type == ND_TYPE_FREE_SLOT) // TODO: ever happens?
150 continue;
151
152 xlog(1, "%s: j=%hu type=%hhu bind_way=%hhu bind_type=%hhu pointer=%hhu i=%d str=%p\n",
153 __func__, j, o->type, o->bind_way, o->bind_type, o->pointer, o->i, &o->str);
154 if ((filter_bind_way & o->bind_way) == 0)
155 continue;
156
157 my_trace_put8(buf, i, o->type);
158 my_trace_put8(buf, i, (o->bind_way << 2) | o->bind_type);
159
160 if (o->bind_type == ND_PARAMS_BIND_TYPE_NAME) {
161 unsigned char name_len = strlen(o->name);
162 my_trace_put8(buf, i, name_len);
163 my_trace_put(buf, i, o->name, name_len);
164 } else if (o->bind_type == ND_PARAMS_BIND_TYPE_POS) {
165 my_trace_put16(buf, i, o->pos);
166 }
167
168 if (o->type == ND_TYPE_INT) {
169 my_trace_put32(buf, i, o->pointer ? * (int *) o->str : o->i);
170 } else if (o->type == ND_TYPE_LONG) {
171 my_trace_put64(buf, i, o->pointer ? * (long *) o->str : o->l);
172 } else if (o->type == ND_TYPE_DOUBLE) {
173 my_trace_put_double(buf, i, o->pointer ? * (double *) o->str : o->d);
174 } else if (o->type == ND_TYPE_STRING) {
175 my_trace_put16(buf, i, o->length);
176 my_trace_put(buf, i, o->str, o->length);
177 } else if (o->type == ND_TYPE_UNK) {
178 my_trace_put16(buf, i, o->length);
179 my_trace_put(buf, i, o->str, o->length);
180 }
181 }
182
183 my_trace_put8(buf, i, ND_TYPE_LAST);
184 }
File agent/trace_encode.h added (mode: 100644) (index 0000000..ebd2682)
1 #include <sys/stat.h>
2
3 #include <netdb.h>
4 #include <stdint.h>
5 #include <string.h>
6
7 #include "process_db.h"
8
9 void my_trace_put8(unsigned char *buf, unsigned int *i, const uint8_t v);
10 void my_trace_put16(unsigned char *buf, unsigned int *i, const uint16_t v);
11 void my_trace_put32(unsigned char *buf, unsigned int *i, const uint32_t v);
12 void my_trace_put64(unsigned char *buf, unsigned int *i, const uint64_t v);
13 void my_trace_put_double(unsigned char *buf, unsigned int *i, const double v);
14 void my_trace_put_bool(unsigned char *buf, unsigned int *i, const char v);
15 void my_trace_put(unsigned char *buf, unsigned int *i,
16 const void *in, const size_t in_len);
17 void my_trace_sockaddr(unsigned char *buf, unsigned int *i,
18 const struct sockaddr *a, const int len);
19 void my_trace_put_stat(unsigned char *buf, unsigned int *i, struct stat *s);
20 void my_trace_put_string_array(unsigned char *buf, unsigned int *i, char *list[]);
21 void my_trace_put_hostent(unsigned char *buf, unsigned int *i, struct hostent *he);
22 void my_trace_put_params(unsigned char *buf, unsigned int *i,
23 const struct nd_params_array *pa, const unsigned char filter_bind_way);
24
File common/Makefile changed (mode: 100644) (index d7a4557..2f2a920)
1 # This is just to allow us to run make here
2 .PHONY: all
3 all:
4 make -C .. common
1 include ../Makefile.common
5 2
6 OBJS := tools.o sctools.o info.o decode_text.o
3 OBJS := tools.o sctools.o info.o decode_text.o bin2json.o \
4 bin2struct.o
5
6 all: $(OBJS)
7 7
8 8 tools.o: tools.c tools.h tools.o: tools.c tools.h
9 9 $(CC) $(CFLAGS) -fPIC -c $< $(CC) $(CFLAGS) -fPIC -c $<
 
... ... tools.o: tools.c tools.h
11 11 sctools.o: sctools.c sctools.h tools.h sctools.o: sctools.c sctools.h tools.h
12 12 $(CC) $(CFLAGS) -fPIC -c $< $(CC) $(CFLAGS) -fPIC -c $<
13 13
14 info.o: info.c info.h shared.h decode_text.h
14 info.o: info.c info.h shared.h decode_text.h tools.h
15 15 $(CC) $(CFLAGS) -fPIC -c $< $(CC) $(CFLAGS) -fPIC -c $<
16 16
17 17 decode_text.o: decode_text.c decode_text.h tools.h decode_text.o: decode_text.c decode_text.h tools.h
18 18 $(CC) $(CFLAGS) -fPIC -c $< $(CC) $(CFLAGS) -fPIC -c $<
19 19
20 bin2json.o: bin2json.c bin2json.h tools.h bin2struct.h
21 $(CC) $(CFLAGS) $(JSON_CFLAGS) -fPIC -c $<
22
23 bin2struct.o: bin2struct.c bin2struct.h ids.h tools.h
24 $(CC) $(CFLAGS) -fPIC -c $<
25
20 26 .PHONY: clean .PHONY: clean
21 27 clean: clean:
22 28 @rm -f *.o @rm -f *.o
File common/bin2json.c added (mode: 100644) (index 0000000..e3f805f)
1 #include <string.h>
2
3 #include "ids.h"
4 #include "tools.h"
5 #include "bin2struct.h"
6 #include "bin2json.h"
7
8 /*
9 * Returns how much bytes were used or -1 on error
10 */
11 int nd_bin2json(struct json_object **pj,
12 const unsigned char *buf, const off_t buf_len)
13 {
14 int ret = -1;
15 struct json_object *j;
16 off_t off = 0;
17 do {
18 *pj = NULL;
19
20 //char dump[buf_len * 4 + 1];
21 //bin2hex_ascii(dump, buf, buf_len);
22 //xlog(0, " %s: %s\n", __func__, dump);
23
24 if (buf_len < 4 + 1 + 4) {
25 xlog(0, " %s: Short len (1) %zu\n", __func__, buf_len);
26 return 0;
27 }
28
29 unsigned int plen, type;
30 memcpy(&plen, buf + off, 4); off += 4;
31 plen = be32toh(plen);
32 if (off + plen > buf_len) {
33 xlog(0, " %s: Short len (2) %zu\n", __func__, buf_len);
34 return 0;
35 }
36
37 if (buf[off++] != 'T') {
38 xlog(0, " %s: 'T' not found!\n", __func__);
39 return 0;
40 }
41
42 memcpy(&type, buf + off, 4); off += 4;
43 type = be32toh(type);
44 xlog(0, " %s: plen=%u type=0x%x\n", __func__, plen, type);
45
46 j = json_object_new_object();
47 if (!j) {
48 xlog(0, " %s: Cannot alloc memory for JSON!\n", __func__);
49 return -1;
50 }
51
52 int r = -1;
53 ret = 4 + plen; // sizeof(plen) + plen
54 switch (type) {
55 case NINEDOGS_NET_CORE_SYSINFO: {
56 struct nd_sysinfo s;
57 r = nd_bin2struct_core_sysinfo(&s, buf + off, plen - 1 - 4); // plen - 'T' - 'type'
58 if (r == -1) {
59 ret = -1;
60 break;
61 }
62 json_object_object_add(j, "ts", json_object_new_uint64(s.ts));
63 json_object_object_add(j, "uptime", json_object_new_int(s.si.uptime));
64 json_object_object_add(j, "load1", json_object_new_int(s.si.loads[0]));
65 json_object_object_add(j, "tram", json_object_new_uint64(s.si.totalram * s.si.mem_unit));
66 json_object_object_add(j, "fram", json_object_new_uint64(s.si.freeram * s.si.mem_unit));
67 json_object_object_add(j, "fswap", json_object_new_uint64(s.si.freeswap * s.si.mem_unit));
68 json_object_object_add(j, "procs", json_object_new_uint64(s.si.procs));
69 json_object_object_add(j, "totalhigh", json_object_new_uint64(s.si.totalhigh * s.si.mem_unit));
70 json_object_object_add(j, "freehigh", json_object_new_uint64(s.si.freehigh * s.si.mem_unit));
71 json_object_object_add(j, "sharedram", json_object_new_uint64(s.si.sharedram * s.si.mem_unit));
72 json_object_object_add(j, "bufferram", json_object_new_uint64(s.si.bufferram * s.si.mem_unit));
73 } break;
74
75 default:
76 xlog(0, "%s: unknown type 0x%x\n", __func__, type);
77 break;
78 }
79 if (r == -1)
80 break;
81
82 *pj = j;
83 xlog(0, " %s: returning %d and a good json\n", __func__, ret);
84 return ret;
85 } while (0);
86 json_object_put(j);
87 xlog(0, " %s: returning %d and NULL json\n", __func__, ret);
88 return ret;
89 }
File common/bin2json.h added (mode: 100644) (index 0000000..d52eb68)
1 #include <json.h>
2
3 int nd_bin2json(struct json_object **pj,
4 const unsigned char *buf, const off_t buf_len);
5
File common/bin2struct.c added (mode: 100644) (index 0000000..8c78631)
1 #include <endian.h>
2 #include <string.h>
3
4 #include "tools.h"
5 #include "bin2struct.h"
6
7 int nd_bin2struct_core_sysinfo(struct nd_sysinfo *s,
8 const unsigned char *buf, const unsigned int len)
9 {
10 unsigned int off = 0, ioff;
11 unsigned int r;
12 char c;
13
14 while (off + 1 + 1 <= len) {
15 ioff = off;
16 c = buf[off++];
17 switch (c) {
18 case '_': r = unpack(&s->ts, 't', sizeof(s->ts), buf, len, &off); break;
19 case 'u': r = unpack(&s->si.uptime, '8', sizeof(s->si.uptime), buf, len, &off); break;
20 case '1': r = unpack(&s->si.loads[0], '8', sizeof(s->si.loads[0]), buf, len, &off); break;
21 case '5': r = unpack(&s->si.loads[1], '8', sizeof(s->si.loads[1]), buf, len, &off); break;
22 case 'q': r = unpack(&s->si.loads[2], '8', sizeof(s->si.loads[2]), buf, len, &off); break;
23 case 'r': r = unpack(&s->si.totalram, '8', sizeof(s->si.totalram), buf, len, &off); break;
24 case 'f': r = unpack(&s->si.freeram, '8', sizeof(s->si.freeram), buf, len, &off); break;
25 case 's': r = unpack(&s->si.sharedram, '8', sizeof(s->si.sharedram), buf, len, &off); break;
26 case 'b': r = unpack(&s->si.bufferram, '8', sizeof(s->si.bufferram), buf, len, &off); break;
27 case 'w': r = unpack(&s->si.totalswap, '8', sizeof(s->si.totalswap), buf, len, &off); break;
28 case 'W': r = unpack(&s->si.freeswap, '8', sizeof(s->si.freeswap), buf, len, &off); break;
29 case 'p': r = unpack(&s->si.procs, '2', sizeof(s->si.procs), buf, len, &off); break;
30 case 'h': r = unpack(&s->si.totalhigh, '8', sizeof(s->si.totalhigh), buf, len, &off); break;
31 case 'H': r = unpack(&s->si.freehigh, '8', sizeof(s->si.freehigh), buf, len, &off); break;
32 case 'i': r = unpack(&s->si.mem_unit, '4', sizeof(s->si.mem_unit), buf, len, &off); break;
33 default: r = 0xFFFFFFFE; break;
34 }
35 if (r >= 0xFFFFFFF0) {
36 xlog(1, "%s: Cannot decode core sysinfo r=0x%08x c=%c[0x%02hhx] off=%u/%u!\n",
37 __func__, r, c, c, ioff, len);
38 return -1;
39 }
40 }
41
42 xlog(10, "%s: ts=%llu uptime=%lu loads1=%lu loads5=%lu"
43 " loads15=%lu totalram=%lu freeram=%lu sharedram=%lu"
44 " bufferram=%lu totalswap=%lu freeswap=%lu procs=%u"
45 " totalhigh=%lu freehigh=%lu mem_unit=%u\n",
46 __func__, s->ts, s->si.uptime, s->si.loads[0], s->si.loads[1],
47 s->si.loads[2], s->si.totalram, s->si.freeram, s->si.sharedram,
48 s->si.bufferram, s->si.totalswap, s->si.freeswap, s->si.procs,
49 s->si.totalhigh, s->si.freehigh, s->si.mem_unit);
50
51 return 0;
52 }
53
54 int nd_bin2struct_cert(struct ninedogs_cert *cert, const unsigned char *buf,
55 const unsigned int len)
56 {
57 char c;
58 unsigned int off = 0;
59 unsigned int r;
60 unsigned char serial[63];
61 unsigned short serial_len = 0;
62
63 strcpy(cert->path, "?");
64 strcpy(cert->subj, "?");
65 strcpy(cert->issuer, "?");
66 cert->not_before = 0;
67 cert->not_after = 0;
68 strcpy(cert->sig_alg, "?");
69 strcpy(cert->pk_alg, "?");
70 cert->pk_bits = 0;
71 strcpy(cert->serial, "");
72
73 while (off + 1 + 1 <= len) {
74 c = buf[off++];
75 switch (c) {
76 case '_': r = unpack(&cert->ts, 't', sizeof(cert->ts), buf, len, &off); break;
77 case 'p': r = unpack(cert->path, 's', sizeof(cert->path), buf, len, &off); break;
78 case 'u': r = unpack(cert->subj, 's', sizeof(cert->subj), buf, len, &off); break;
79 case 'i': r = unpack(cert->issuer, 's', sizeof(cert->issuer), buf, len, &off); break;
80 case 's': r = unpack(&cert->not_before, '8', sizeof(cert->not_before), buf, len, &off); break;
81 case 'e': r = unpack(&cert->not_after, '8', sizeof(cert->not_after), buf, len, &off); break;
82 case 'a': r = unpack(cert->sig_alg, 's', sizeof(cert->sig_alg), buf, len, &off); break;
83 case 'n': r = unpack(serial, 'b', sizeof(serial), buf, len, &off); serial_len = r; break;
84 case 't': r = unpack(&cert->type, 'c', sizeof(cert->type), buf, len, &off); break;
85 case 'k': r = unpack(cert->pk_alg, 's', sizeof(cert->pk_alg), buf, len, &off); break;
86 case 'K': r = unpack(&cert->pk_bits, '4', sizeof(cert->pk_bits), buf, len, &off); break;
87 default: r = 0xFFFFFFFE; break;
88 }
89 if (r >= 0xFFFFFFF0) {
90 char dump[len * 2 + 1];
91 bin2hex(dump, buf, len);
92 xlog(1, "%s: Cannot decode ssl cert r=0x%08x c=%c[0x%02hhx] off=%u/%u [%s]!\n",
93 __func__, r, c, c, off, len, dump);
94 return -1;
95 }
96 }
97
98 bin2hex(cert->serial, serial, serial_len);
99
100 xlog(100, "%s: ts=%llu path=[%s] subj=[%s] issuer=[%s] not_before=[%llu]"
101 " not_after=[%llu] serial=[%s] type=%c sig_alg=[%s]"
102 " pk_alg=[%s] pk_bits=%u\n",
103 __func__, cert->ts, cert->path, cert->subj, cert->issuer,
104 cert->not_before, cert->not_after, cert->serial, cert->type,
105 cert->sig_alg, cert->pk_alg, cert->pk_bits);
106
107 return 0;
108 }
109
110 /* related to save_app */
111 int nd_bin2struct_app(struct ninedogs_app *cu,
112 const unsigned char *buf, const unsigned int len)
113 {
114 unsigned int off = 0;
115
116 memset(cu, 0, sizeof(struct ninedogs_app));
117
118 if (len < 8 + 2) {
119 xlog(1, "%s: too less data [%u]!\n", len);
120 return -1;
121 }
122
123 memcpy(&cu->ts, buf + off, 8); off += 8;
124 cu->ts = be64toh(cu->ts);
125
126 memcpy(&cu->cmdline_len, buf + off, 2); off += 2;
127 cu->cmdline_len = be16toh(cu->cmdline_len);
128
129 if (len - off < cu->cmdline_len) {
130 xlog(1, "%s: too less data [%u] (needed %u)!\n",
131 len - off, cu->cmdline_len);
132 return -1;
133 }
134
135 unsigned int max = sizeof(cu->cmdline) - 1;
136 if (max > cu->cmdline_len)
137 max = cu->cmdline_len;
138 memcpy(cu->cmdline, buf + off, max);
139 cu->cmdline[max] = '\0';
140
141 char conv[4096];
142 nd_app_nice(conv, sizeof(conv), cu->cmdline, cu->cmdline_len);
143 xlog(50, "%s: ts=%llu cmdline_len=%u cmdline=[%s]\n",
144 __func__, cu->ts, cu->cmdline_len, conv);
145
146 return 0;
147 }
148
File common/bin2struct.h added (mode: 100644) (index 0000000..5291efc)
1 #include <sys/sysinfo.h>
2
3 struct nd_sysinfo
4 {
5 unsigned long long ts;
6 struct sysinfo si;
7 };
8
9 int nd_bin2struct_core_sysinfo(struct nd_sysinfo *s,
10 const unsigned char *buf, const unsigned int len);
11
12
13 struct ninedogs_cert
14 {
15 char path[256];
16 unsigned long long not_before;
17 unsigned long long not_after;
18 char subj[512];
19 char issuer[512];
20 char serial[128];
21 char sig_alg[32];
22 char pk_alg[32];
23 unsigned int pk_bits;
24 char type;
25 char pad[3];
26 unsigned long long ts;
27 };
28
29 int nd_bin2struct_cert(struct ninedogs_cert *c, const unsigned char *buf,
30 const unsigned int len);
31
32 struct ninedogs_app
33 {
34 unsigned long long ts;
35 unsigned short cmdline_len;
36 unsigned short pad[3];
37 char cmdline[4096];
38 };
39
40 int nd_bin2struct_app(struct ninedogs_app *cu,
41 const unsigned char *buf, const unsigned int len);
42
File common/decode_text.c changed (mode: 100644) (index f456c1e..7b9732a)
... ... void nd_decode_curl_code(char *out, const size_t out_size, const int code)
143 143 switch (code) { switch (code) {
144 144 case 0: snprintf(out, out_size, "ok"); return; case 0: snprintf(out, out_size, "ok"); return;
145 145 case 43: snprintf(out, out_size, "bad_func_arg"); return; case 43: snprintf(out, out_size, "bad_func_arg"); return;
146 case 60: snprintf(out, out_size, "peer_failed_verification"); return;
146 147 } }
147 148
148 149 snprintf(out, out_size, "?%d?", code); snprintf(out, out_size, "?%d?", code);
149 150 } }
151
152
153 void nd_decode_oci_handle_alloc_type(char *out, const size_t out_size,
154 const unsigned int v)
155 {
156 switch (v) {
157 case 1: snprintf(out, out_size, "env"); return;
158 case 2: snprintf(out, out_size, "error"); return;
159 case 3: snprintf(out, out_size, "svcctx"); return;
160 case 4: snprintf(out, out_size, "stmt"); return;
161 case 5: snprintf(out, out_size, "bind"); return;
162 case 6: snprintf(out, out_size, "define"); return;
163 case 7: snprintf(out, out_size, "describe"); return;
164 case 8: snprintf(out, out_size, "server"); return;
165 case 9: snprintf(out, out_size, "session"); return;
166 case 10: snprintf(out, out_size, "trans"); return;
167 case 11: snprintf(out, out_size, "complexobj"); return;
168 case 12: snprintf(out, out_size, "security"); return;
169 case 13: snprintf(out, out_size, "subsription"); return;
170 case 14: snprintf(out, out_size, "dirpath_ctx"); return;
171 case 15: snprintf(out, out_size, "dirpath_column_array"); return;
172 case 16: snprintf(out, out_size, "dirpath_stream"); return;
173 case 17: snprintf(out, out_size, "proc"); return;
174 case 18: snprintf(out, out_size, "dirpath_fn_ctx"); return;
175 case 19: snprintf(out, out_size, "dirpath_fn_col_array"); return;
176 case 20: snprintf(out, out_size, "xadsession"); return;
177 case 21: snprintf(out, out_size, "xadtable"); return;
178 case 22: snprintf(out, out_size, "xadfield"); return;
179 case 23: snprintf(out, out_size, "xadgranule"); return;
180 case 24: snprintf(out, out_size, "xadrecord"); return;
181 case 25: snprintf(out, out_size, "xadio"); return;
182 case 26: snprintf(out, out_size, "cpool"); return;
183 case 27: snprintf(out, out_size, "spool"); return;
184 case 28: snprintf(out, out_size, "admin"); return;
185 case 29: snprintf(out, out_size, "event"); return;
186 case 30: snprintf(out, out_size, "soda_collection"); return;
187 case 31: snprintf(out, out_size, "soda_document"); return;
188 case 32: snprintf(out, out_size, "soda_coll_cursor"); return;
189 case 33: snprintf(out, out_size, "soda_oper_options"); return;
190 case 34: snprintf(out, out_size, "soda_output_options"); return;
191 case 35: snprintf(out, out_size, "soda_metadata"); return;
192 case 36: snprintf(out, out_size, "async"); return;
193 case 37: snprintf(out, out_size, "last"); return;
194 }
195
196 snprintf(out, out_size, "?%u?", v);
197 }
198
199 void nd_decode_oci_attr_type(char *out, const size_t out_size, const unsigned int code)
200 {
201 switch (code) {
202 case 1: snprintf(out, out_size, "fncode"); return;
203 case 2: snprintf(out, out_size, "object"); return;
204 case 3: snprintf(out, out_size, "nonblocking_mode"); return;
205 case 4: snprintf(out, out_size, "sqlcode"); return;
206 case 5: snprintf(out, out_size, "env"); return;
207 case 6: snprintf(out, out_size, "server"); return;
208 case 7: snprintf(out, out_size, "session"); return;
209 case 8: snprintf(out, out_size, "trans"); return;
210 case 9: snprintf(out, out_size, "row_count"); return;
211 case 10: snprintf(out, out_size, "sqlfncode"); return;
212 case 11: snprintf(out, out_size, "prefetch_rows"); return;
213 case 12: snprintf(out, out_size, "nested_prefetch_rows"); return;
214 case 13: snprintf(out, out_size, "prefetch_memory"); return;
215 case 14: snprintf(out, out_size, "nested_prefetch_memory"); return;
216 case 15: snprintf(out, out_size, "char_count"); return;
217 case 16: snprintf(out, out_size, "fsprecision"); return;
218 case 17: snprintf(out, out_size, "lfprecision"); return;
219 case 18: snprintf(out, out_size, "param_count"); return;
220 case 19: snprintf(out, out_size, "rowid"); return;
221 case 20: snprintf(out, out_size, "charset"); return;
222 case 21: snprintf(out, out_size, "nchar"); return;
223 case 22: snprintf(out, out_size, "username"); return;
224 case 23: snprintf(out, out_size, "password"); return;
225 case 24: snprintf(out, out_size, "stmt_type"); return;
226 case 25: snprintf(out, out_size, "internal_name"); return;
227 case 26: snprintf(out, out_size, "external_name"); return;
228 case 27: snprintf(out, out_size, "xid"); return;
229 case 28: snprintf(out, out_size, "trans_lock"); return;
230 case 29: snprintf(out, out_size, "trans_name"); return;
231 case 30: snprintf(out, out_size, "heapalloc"); return;
232 case 31: snprintf(out, out_size, "charset_id"); return;
233 case 32: snprintf(out, out_size, "charset_form"); return;
234 case 33: snprintf(out, out_size, "maxdata_size"); return;
235 case 34: snprintf(out, out_size, "cache_opt_size"); return;
236 case 35: snprintf(out, out_size, "cache_max_size"); return;
237 case 36: snprintf(out, out_size, "pinoption"); return;
238 case 37: snprintf(out, out_size, "alloc_duration"); return;
239 case 38: snprintf(out, out_size, "pin_duration"); return;
240 case 39: snprintf(out, out_size, "fdo"); return;
241 case 40: snprintf(out, out_size, "postprocessing_callback"); return;
242 case 41: snprintf(out, out_size, "postprocessing_context"); return;
243 case 42: snprintf(out, out_size, "rows_returned"); return;
244 case 43: snprintf(out, out_size, "focbk"); return;
245 case 44: snprintf(out, out_size, "in_v8_mode"); return;
246 case 45: snprintf(out, out_size, "lobempty"); return;
247 case 46: snprintf(out, out_size, "sesslang"); return;
248 case 47: snprintf(out, out_size, "visibility"); return;
249 case 48: snprintf(out, out_size, "relative_msgid"); return;
250 case 49: snprintf(out, out_size, "sequence_deviation"); return;
251 case 50: snprintf(out, out_size, "consumer_name"); return;
252 }
253
254 snprintf(out, out_size, "?%u?", code);
255 }
256
257 void nd_decode_oci_lang(char *out, const size_t out_size, const unsigned int code)
258 {
259 switch (code) {
260 case 1: snprintf(out, out_size, "OCI_NTV_SYNTAX"); return;
261 case 2: snprintf(out, out_size, "OCI_V7_SYNTAX"); return;
262 case 3: snprintf(out, out_size, "OCI_V8_SYNTAX"); return;
263 case 0xffffffff: snprintf(out, out_size, "OCI_FOREIGN_SYNTAX"); return;
264 }
265
266 snprintf(out, out_size, "?%u?", code);
267 }
268
269 void nd_decode_oci_mode(char *out, const size_t out_size, const unsigned int mode)
270 {
271 if (mode == 0) {
272 snprintf(out, out_size, "default");
273 return;
274 }
275 char *so = ""; if (mode & 0x0010) so = "|cache_searchonly";
276 char *w = ""; if (mode & 0x0020) w = "|plsql_warnings";
277 char *i = ""; if (mode & 0x0400) i = "|impl_results_client";
278 char *id = ""; if (mode & 0x2000) id = "|get_sql_id";
279 char *ph = ""; if (mode & 0x40000) ph = "|oci_placeholder";
280 char *nb = ""; if (mode & 0x80000000) ph = "|non_blocking";
281
282 snprintf(out, out_size, "0x%x%s%s%s%s%s%s",
283 mode, so, w, i, id, ph, nb);
284 }
285
286 void nd_decode_oci_bind_mode(char *out, const size_t out_size, const unsigned int mode)
287 {
288 if (mode == 0) {
289 snprintf(out, out_size, "default");
290 return;
291 }
292 char *dae = ""; if (mode & 0x00000002) dae = "|data_at_exec";
293 char *df = ""; if (mode & 0x00000002) df = "|dynamic_fetch";
294 char *pw = ""; if (mode & 0x00000004) pw = "|piece_wise";
295 char *bs = ""; if (mode & 0x00000040) bs = "|bind_soft";
296 char *ds = ""; if (mode & 0x00000080) ds = "|define_soft";
297 char *iov = ""; if (mode & 0x00000200) iov = "|iov";
298
299 snprintf(out, out_size, "0x%x%s%s%s%s%s%s",
300 mode, dae, df, pw, bs, ds, iov);
301 }
302
303 void nd_decode_oci_ret(char *out, const size_t out_size, const int ret)
304 {
305 switch (ret) {
306 case -3123: snprintf(out, out_size, "STILL_EXECUTE"); return;
307 case -2: snprintf(out, out_size, "INVALID_HANDLE"); return;
308 case -1: snprintf(out, out_size, "ERROR"); return;
309 case 0: snprintf(out, out_size, "SUCCESS"); return;
310 case 1: snprintf(out, out_size, "SUCCESS_WITH_INFO"); return;
311 case 99: snprintf(out, out_size, "NEED_DATA"); return;
312 case 100: snprintf(out, out_size, "NO_DATA"); return;
313 }
314
315 snprintf(out, out_size, "?%d?", ret);
316 }
317
318 void nd_decode_oci_dty(char *out, const size_t out_size, const unsigned short code)
319 {
320 switch (code) {
321 case 1: snprintf(out, out_size, "SQLT_CHR"); return;
322 case 2: snprintf(out, out_size, "SQLT_NUM"); return;
323 case 3: snprintf(out, out_size, "SQLT_INT"); return;
324 case 4: snprintf(out, out_size, "SQLT_FLT"); return;
325 case 5: snprintf(out, out_size, "SQLT_STR"); return;
326 case 6: snprintf(out, out_size, "SQLT_VNU"); return;
327 case 7: snprintf(out, out_size, "SQLT_PDN"); return;
328 case 8: snprintf(out, out_size, "SQLT_LNG"); return;
329 case 9: snprintf(out, out_size, "SQLT_VCS"); return;
330 case 10: snprintf(out, out_size, "SQLT_NON"); return;
331 case 11: snprintf(out, out_size, "SQLT_RID"); return;
332 case 12: snprintf(out, out_size, "SQLT_DAT"); return;
333 case 15: snprintf(out, out_size, "SQLT_VBI"); return;
334 case 21: snprintf(out, out_size, "SQLT_BFLOAT"); return;
335 case 22: snprintf(out, out_size, "SQLT_BDOUBLE"); return;
336 case 23: snprintf(out, out_size, "SQLT_BIN"); return;
337 case 24: snprintf(out, out_size, "SQLT_LBI"); return;
338 case 68: snprintf(out, out_size, "SQLT_UIN"); return;
339 case 91: snprintf(out, out_size, "SQLT_SLS"); return;
340 case 94: snprintf(out, out_size, "SQLT_LVC"); return;
341 case 95: snprintf(out, out_size, "SQLT_LVB"); return;
342 case 96: snprintf(out, out_size, "SQLT_AFC"); return;
343 case 97: snprintf(out, out_size, "SQLT_AVC"); return;
344 case 100: snprintf(out, out_size, "SQLT_IBFLOAT"); return;
345 case 101: snprintf(out, out_size, "SQLT_IBDOUBLE"); return;
346 case 102: snprintf(out, out_size, "SQLT_CUR"); return;
347 case 104: snprintf(out, out_size, "SQLT_RDD"); return;
348 case 105: snprintf(out, out_size, "SQLT_LAB"); return;
349 case 106: snprintf(out, out_size, "SQLT_OSL"); return;
350 case 108: snprintf(out, out_size, "SQLT_NTY"); return;
351 case 110: snprintf(out, out_size, "SQLT_REF"); return;
352 case 112: snprintf(out, out_size, "SQLT_CLOB"); return;
353 case 113: snprintf(out, out_size, "SQLT_BLOB"); return;
354 case 114: snprintf(out, out_size, "SQLT_BFILEE"); return;
355 case 115: snprintf(out, out_size, "SQLT_CFILEE"); return;
356 case 116: snprintf(out, out_size, "SQLT_RSET"); return;
357 case 119: snprintf(out, out_size, "SQLT_JSON"); return;
358 case 122: snprintf(out, out_size, "SQLT_NCO"); return;
359 case 155: snprintf(out, out_size, "SQLT_VST"); return;
360 case 156: snprintf(out, out_size, "SQLT_ODT"); return;
361 case 184: snprintf(out, out_size, "SQLT_DATE"); return;
362 case 185: snprintf(out, out_size, "SQLT_TIME"); return;
363 case 186: snprintf(out, out_size, "SQLT_TIME_TZ"); return;
364 case 187: snprintf(out, out_size, "SQLT_TIMESTAMP"); return;
365 case 188: snprintf(out, out_size, "SQLT_TIMESTAMP_TZ"); return;
366 case 189: snprintf(out, out_size, "SQLT_INTERVAL_YM"); return;
367 case 190: snprintf(out, out_size, "SQLT_INTERVAL_DS"); return;
368 case 232: snprintf(out, out_size, "SQLT_TIMESTAMP_LTZ"); return;
369 case 241: snprintf(out, out_size, "SQLT_PNTY"); return;
370 case 250: snprintf(out, out_size, "SQLT_REC"); return;
371 case 251: snprintf(out, out_size, "SQLT_TAB"); return;
372 case 252: snprintf(out, out_size, "SQLT_BOL"); return;
373 }
374
375 snprintf(out, out_size, "?%hu?", code);
376 }
377
378 void nd_decode_oci_trans_commit_flags(char *out, const size_t out_size, const unsigned int v)
379 {
380 if (v == 0) {
381 snprintf(out, out_size, "default");
382 return;
383 }
384 char *tp = ""; if (v & 0x01000000) tp = "|two_phase";
385 char *wb = ""; if (v & 0x00000001) wb = "|write_batch";
386 char *wi = ""; if (v & 0x00000002) wi = "|write_immed";
387 char *ww = ""; if (v & 0x00000004) ww = "|write_wait";
388 char *wnw = ""; if (v & 0x00000008) wnw = "|write_no_wait";
389
390 snprintf(out, out_size, "0x%x%s%s%s%s%s",
391 v, tp, wb, wi, ww, wnw);
392 }
393
394 void nd_decode_oci_trans_rollback_flags(char *out, const size_t out_size, const unsigned int v)
395 {
396 if (v == 0) {
397 snprintf(out, out_size, "default");
398 return;
399 }
400
401 snprintf(out, out_size, "0x%x", v);
402 }
403
404 void nd_decode_oci_trans_start_flags(char *out, const size_t out_size, const unsigned int v)
405 {
406 if (v == 0) {
407 snprintf(out, out_size, "default");
408 return;
409 }
410 char *tn = ""; if (v & 0x00000001) tn = "|new";
411 char *jo = ""; if (v & 0x00000002) jo = "|join";
412 char *re = ""; if (v & 0x00000004) re = "|resume";
413 char *pr = ""; if (v & 0x00000008) pr = "|promote";
414 char *ro = ""; if (v & 0x00000100) ro = "|read_only";
415 char *rw = ""; if (v & 0x00000200) rw = "|read_write";
416 char *ser = ""; if (v & 0x00000400) ser = "|serializable";
417 char *lo = ""; if (v & 0x000010000) lo = "|loose";
418 char *ti = ""; if (v & 0x000020000) ti = "|tight";
419 char *nm = ""; if (v & 0x000100000) nm = "|no_migrate";
420 char *se = ""; if (v & 0x000200000) se = "|separable";
421 char *or = ""; if (v & 0x000400000) or = "|ots_resume";
422
423 snprintf(out, out_size, "0x%x%s%s%s%s%s%s%s%s%s%s%s%s",
424 v, tn, jo, re, pr, ro, rw, ser, lo, ti, nm, se, or);
425 }
426
427 void nd_decode_oci_execute_mode(char *out, const size_t out_size, const unsigned int v)
428 {
429 char *p1 = ""; if (v & 0x00000001) p1 = "|batch";
430 char *p2 = ""; if (v & 0x00000002) p2 = "|exact_fetch";
431 char *p3 = ""; if (v & 0x00000008) p3 = "|stmt_scrollable_readonly";
432 char *p4 = ""; if (v & 0x00000010) p4 = "|describe_only";
433 char *p5 = ""; if (v & 0x00000020) p5 = "|commit_on_success"; else p5 = "|no_auto_commit";
434 char *p6 = ""; if (v & 0x00000080) p6 = "|batch_errors";
435 char *p7 = ""; if (v & 0x00000100) p7 = "|parse_only";
436 char *p8 = ""; if (v & 0x00000400) p8 = "|show_dml_warnings";
437 char *p9 = ""; if (v & 0x00020000) p9 = "|result_cache";
438 char *p10 = ""; if (v & 0x00040000) p10 = "|no_result_cache";
439 char *p11 = ""; if (v & 0x00100000) p11 = "|return_row_count_array";
440
441 snprintf(out, out_size, "0x%x%s%s%s%s%s%s%s%s%s%s%s",
442 v, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
443 }
444
File common/decode_text.h changed (mode: 100644) (index 92f6e8c..3b59d25)
... ... void nd_decode_timerfd_flags(char *out, const size_t out_size, const int flags);
7 7 void nd_decode_sockaddr(char *out, const void *s, const socklen_t sl); void nd_decode_sockaddr(char *out, const void *s, const socklen_t sl);
8 8 void nd_decode_curl_code(char *out, const size_t out_size, const int code); void nd_decode_curl_code(char *out, const size_t out_size, const int code);
9 9
10 void nd_decode_oci_handle_alloc_type(char *out, const size_t out_size, const unsigned int code);
11 void nd_decode_oci_attr_type(char *out, const size_t out_size, const unsigned int code);
12 void nd_decode_oci_lang(char *out, const size_t out_size, const unsigned int code);
13 void nd_decode_oci_mode(char *out, const size_t out_size, const unsigned int mode);
14 void nd_decode_oci_bind_mode(char *out, const size_t out_size, const unsigned int mode);
15 void nd_decode_oci_ret(char *out, const size_t out_size, const int ret);
16 void nd_decode_oci_dty(char *out, const size_t out_size, const unsigned short code);
17 void nd_decode_oci_trans_commit_flags(char *out, const size_t out_size, const unsigned int v);
18 void nd_decode_oci_trans_rollback_flags(char *out, const size_t out_size, const unsigned int v);
19 void nd_decode_oci_trans_start_flags(char *out, const size_t out_size, const unsigned int v);
20 void nd_decode_oci_execute_mode(char *out, const size_t out_size, const unsigned int v);
21
File common/ids.h changed (mode: 100644) (index 8da5991..2151586)
... ... enum
64 64 NINEDOGS_DB_AUTOCOMMIT_END, NINEDOGS_DB_AUTOCOMMIT_END,
65 65 NINEDOGS_DB_BIND_PARAM_START, NINEDOGS_DB_BIND_PARAM_START,
66 66 NINEDOGS_DB_BIND_PARAM_END, NINEDOGS_DB_BIND_PARAM_END,
67 NINEDOGS_DB_STATEMENT_CREATE_END,
68 NINEDOGS_DB_STATEMENT_CLOSE_END,
69 NINEDOGS_DB_RESULT_GET_START,
70 NINEDOGS_DB_RESULT_GET_END,
71 NINEDOGS_DB_BIND_ONE_PARAM,
72 NINEDOGS_DB_STMT_CLOSE_START,
73 NINEDOGS_DB_STMT_CLOSE_END,
67 74 NINEDOGS_DB_MAX // this must be last NINEDOGS_DB_MAX // this must be last
68 75 }; };
69 76
 
... ... enum
85 92 NINEDOGS_URL_MAX // this must be last NINEDOGS_URL_MAX // this must be last
86 93 }; };
87 94
95 // TODO: move this into params.h?
88 96 enum enum
89 97 { {
98 ND_TYPE_FREE_SLOT,
90 99 ND_TYPE_NULL, ND_TYPE_NULL,
91 100 ND_TYPE_LONG, ND_TYPE_LONG,
92 101 ND_TYPE_DOUBLE, ND_TYPE_DOUBLE,
 
... ... enum
96 105 ND_TYPE_ARRAY_START, ND_TYPE_ARRAY_START,
97 106 ND_TYPE_ARRAY_END, ND_TYPE_ARRAY_END,
98 107 ND_TYPE_POINTER, ND_TYPE_POINTER,
99 ND_TYPE_UNK
108 ND_TYPE_UNK,
109 ND_TYPE_INT,
110 ND_TYPE_LAST // marker that we sent everything
100 111 }; };
101 112
113 // bit masks for tracer (shared->client_flags)
114 #define ND_SHARED_ONLY_HIGH_LEVEL 1
115
File common/info.c changed (mode: 100644) (index 3ce6d03..9929355)
3 3
4 4 #include <stdio.h> // temp #include <stdio.h> // temp
5 5
6 #include "tools.h"
6 7 #include "shared.h" #include "shared.h"
7 8 #include "info.h" #include "info.h"
8 9 #include "decode_text.h" #include "decode_text.h"
9 10
10 extern void xlog(const unsigned int level, const char *format, ...);
11 11
12 12 /* /*
13 13 * Export one fd node, returns the number of bytes * Export one fd node, returns the number of bytes
 
... ... static unsigned int export_fd_node(unsigned char *out, const struct fd_node *n)
42 42 memcpy(out + off, &n->socket.bind, n->socket.bind_len); off += n->socket.bind_len; memcpy(out + off, &n->socket.bind, n->socket.bind_len); off += n->socket.bind_len;
43 43 u16 = htobe16(n->socket.peer_len); memcpy(out + off, &u16, 2); off += 2; u16 = htobe16(n->socket.peer_len); memcpy(out + off, &u16, 2); off += 2;
44 44 memcpy(out + off, &n->socket.peer, n->socket.peer_len); off += n->socket.peer_len; memcpy(out + off, &n->socket.peer, n->socket.peer_len); off += n->socket.peer_len;
45 u32 = htobe32(n->socket.accept_fd); memcpy(out + off, &u32, 4); off += 4;
45 46 break; break;
46 47
47 48 case FD_NODE_MEMFD: case FD_NODE_MEMFD:
 
... ... static unsigned int export_fd_node(unsigned char *out, const struct fd_node *n)
51 52 memcpy(out + off, n->file.path, path_len); off += path_len; memcpy(out + off, n->file.path, path_len); off += path_len;
52 53 u32 = htobe32(n->file.flags); memcpy(out + off, &u32, 4); off += 4; u32 = htobe32(n->file.flags); memcpy(out + off, &u32, 4); off += 4;
53 54 u64 = htobe64(n->file.off); memcpy(out + off, &u64, 8); off += 8; u64 = htobe64(n->file.off); memcpy(out + off, &u64, 8); off += 8;
55 u64 = htobe64(n->file.max); memcpy(out + off, &u64, 8); off += 8;
54 56 break; break;
55 57
56 58 case FD_NODE_TIMERFD: case FD_NODE_TIMERFD:
 
... ... int decode_fd_node(struct fd_node *n, unsigned char *in, unsigned int *poff)
152 154 memcpy(&n->socket.bind, in + off, n->socket.bind_len); off += n->socket.bind_len; memcpy(&n->socket.bind, in + off, n->socket.bind_len); off += n->socket.bind_len;
153 155 memcpy(&u16, in + off, 2); off += 2; n->socket.peer_len = be16toh(u16); memcpy(&u16, in + off, 2); off += 2; n->socket.peer_len = be16toh(u16);
154 156 memcpy(&n->socket.peer, in + off, n->socket.peer_len); off += n->socket.peer_len; memcpy(&n->socket.peer, in + off, n->socket.peer_len); off += n->socket.peer_len;
157 memcpy(&u32, in + off, 4); off += 4; n->socket.accept_fd = be32toh(u32);
155 158 break; break;
156 159
157 160 case FD_NODE_MEMFD: case FD_NODE_MEMFD:
 
... ... int decode_fd_node(struct fd_node *n, unsigned char *in, unsigned int *poff)
162 165 memcpy(n->file.path, in + off, max); n->file.path[max] = '\0'; off += path_len; memcpy(n->file.path, in + off, max); n->file.path[max] = '\0'; off += path_len;
163 166 memcpy(&u32, in + off, 4); off += 4; n->file.flags = be32toh(u32); memcpy(&u32, in + off, 4); off += 4; n->file.flags = be32toh(u32);
164 167 memcpy(&u64, in + off, 8); off += 8; n->file.off = be64toh(u64); memcpy(&u64, in + off, 8); off += 8; n->file.off = be64toh(u64);
168 memcpy(&u64, in + off, 8); off += 8; n->file.max = be64toh(u64);
165 169 break; break;
166 170
167 171 case FD_NODE_TIMERFD: case FD_NODE_TIMERFD:
 
... ... void decode_fd_node_to_text(char *out, const size_t out_size, struct fd_node *n)
189 193 char base[1024]; char base[1024];
190 194
191 195 switch (n->type) { switch (n->type) {
192 case FD_NODE_FILE:
196 case FD_NODE_FILE: {
193 197 snprintf(base, sizeof(base), snprintf(base, sizeof(base),
194 198 "file fd=%d path=[%s] flags=0x%x mode=0x%x off=%lu", "file fd=%d path=[%s] flags=0x%x mode=0x%x off=%lu",
195 199 n->fd, n->file.path, n->file.flags, n->file.mode, n->file.off); n->fd, n->file.path, n->file.flags, n->file.mode, n->file.off);
196 break;
200 } break;
197 201
198 case FD_NODE_SOCKET:
202 case FD_NODE_SOCKET: {
199 203 char bind[1024], peer[1024]; char bind[1024], peer[1024];
200 204
201 205 if (n->socket.bind_len > 0) if (n->socket.bind_len > 0)
 
... ... void decode_fd_node_to_text(char *out, const size_t out_size, struct fd_node *n)
212 216 nd_decode_socket_type(type, sizeof(type), n->socket.type); nd_decode_socket_type(type, sizeof(type), n->socket.type);
213 217 nd_decode_socket_protocol(protocol, sizeof(protocol), n->socket.protocol); nd_decode_socket_protocol(protocol, sizeof(protocol), n->socket.protocol);
214 218
219 char accept_fd[32];
220 if (n->socket.accept_fd == 0)
221 accept_fd[0] = '\0';
222 else
223 snprintf(accept_fd, sizeof(accept_fd),
224 " accept_fd=%d", n->socket.accept_fd);
225
215 226 snprintf(base, sizeof(base), snprintf(base, sizeof(base),
216 "socket fd=%d %s/%s bind=[%s] peer=[%s] backlog=%d accepts=%lu",
217 n->fd, type, protocol, bind, peer, n->socket.backlog, n->socket.accepts);
218 break;
227 "socket fd=%d %s/%s bind=[%s] peer=[%s] backlog=%d accepts=%lu"
228 "%s",
229 n->fd, type, protocol, bind, peer, n->socket.backlog,
230 n->socket.accepts, accept_fd);
231 } break;
219 232
220 case FD_NODE_MEMFD:
233 case FD_NODE_MEMFD: {
221 234 char mfd_flags[64]; char mfd_flags[64];
222 235 nd_decode_memfd_flags(mfd_flags, sizeof(mfd_flags), n->file.flags); nd_decode_memfd_flags(mfd_flags, sizeof(mfd_flags), n->file.flags);
223 snprintf(base, sizeof(base), "memfd fd=%d path=[%s] flags=%s off=%lu",
224 n->fd, n->file.path, mfd_flags, n->file.off);
225 break;
236 snprintf(base, sizeof(base), "memfd fd=%d path=[%s] flags=%s off=%lu size=%lu",
237 n->fd, n->file.path, mfd_flags, n->file.off, n->file.max);
238 } break;
226 239
227 case FD_NODE_TIMERFD:
240 case FD_NODE_TIMERFD: {
228 241 char clock[32], flags[64]; char clock[32], flags[64];
229 242 nd_decode_clockid(clock, sizeof(clock), n->file.mode); nd_decode_clockid(clock, sizeof(clock), n->file.mode);
230 243 nd_decode_timerfd_flags(flags, sizeof(flags), n->file.flags); nd_decode_timerfd_flags(flags, sizeof(flags), n->file.flags);
231 244 snprintf(base, sizeof(base), "timerfd fd=%d clock=%s flags=%s", snprintf(base, sizeof(base), "timerfd fd=%d clock=%s flags=%s",
232 245 n->fd, clock, flags); n->fd, clock, flags);
233 break;
246 } break;
234 247
235 248 default: default:
236 249 snprintf(out, out_size, "fd=%d unknown type %hhu", n->fd, n->type); snprintf(out, out_size, "fd=%d unknown type %hhu", n->fd, n->type);
237 250 return; return;
238 251 } }
239 252
240 snprintf(out, out_size, "%s ops=%lu/%lu bytes=%lu/%lu errs=%lu/%lu", base,
253 snprintf(out, out_size, "%s ops=%lu/%lu bytes=%lu/%lu errs=%lu/%lu [r/w]", base,
241 254 n->stats[0][0], n->stats[0][1], n->stats[0][0], n->stats[0][1],
242 255 n->stats[1][0], n->stats[1][1], n->stats[1][0], n->stats[1][1],
243 256 n->stats[2][0], n->stats[2][1]); n->stats[2][0], n->stats[2][1]);
File common/params.h added (mode: 100644) (index 0000000..be0720b)
1 #ifndef ND_PARAMS_H
2 #define ND_PARAMS_H 1
3
4 #define ND_PARAMS_BIND_WAY_NONE 0
5 #define ND_PARAMS_BIND_WAY_IN 1
6 #define ND_PARAMS_BIND_WAY_OUT 2
7 #define ND_PARAMS_BIND_WAY_BOTH 3
8
9 #define ND_PARAMS_BIND_TYPE_NONE 0
10 #define ND_PARAMS_BIND_TYPE_NAME 1
11 #define ND_PARAMS_BIND_TYPE_POS 2
12
13 struct nd_params_array_one
14 {
15 unsigned char type; // see ND_TYPE_*
16
17 unsigned char bind_way:2; // See ND_PARAMS_BIND_WAY_*
18 unsigned char bind_type:2; // See ND_PARAMS_BIND_TYPE_*
19 unsigned char pointer:1; // if 1, all values are stored at 'str' pointer
20 unsigned char pad1:3;
21
22 unsigned short length; // for 'str'
23 union {
24 char name[20];
25 unsigned short pos;
26 };
27 union {
28 char *str;
29 double d;
30 long l;
31 int i;
32 };
33 };
34
35 #define ND_PARAMS_MAX 100
36 struct nd_params_array
37 {
38 struct nd_params_array_one list[ND_PARAMS_MAX];
39 };
40
41 #endif
File common/sctools.c changed (mode: 100644) (index 4427cc9..57fe62c)
1 #include <libgen.h>
2 #include <stdio.h>
1 3 #include <string.h> #include <string.h>
2 4
3 5 #include "sctools.h" #include "sctools.h"
4 6 #include "tools.h" #include "tools.h"
5 7
6 extern void xlog(const unsigned int level, const char *format, ...);
8 int nd_for_each_user(int (*cb)(const unsigned int uid, const char *user_dir))
9 {
10 const char *path = "/var/lib/ninedogs/users/by-uid/*/*/*";
7 11
12 glob_t g;
13 int r = glob(path, GLOB_NOSORT | GLOB_ONLYDIR, NULL, &g);
14 if (r == GLOB_NOMATCH)
15 return 0;
16 if (r != 0) {
17 fprintf(stderr, " cannot load users: %m!\n");
18 return -1;
19 }
8 20
9 int decode_cert(struct ninedogs_cert *cert, const unsigned char *buf,
10 const unsigned int len)
11 {
12 char c;
13 unsigned int off = 0;
14 unsigned int r;
15 unsigned char serial[63];
16 unsigned short serial_len = 0;
17
18 strcpy(cert->path, "?");
19 strcpy(cert->subj, "?");
20 strcpy(cert->issuer, "?");
21 cert->not_before = 0;
22 cert->not_after = 0;
23 strcpy(cert->sig_alg, "?");
24 strcpy(cert->pk_alg, "?");
25 cert->pk_bits = 0;
26 strcpy(cert->serial, "");
27
28 while (off + 1 + 1 <= len) {
29 c = buf[off++];
30 switch (c) {
31 case 'N': r = unpack(&cert->ts, 't', sizeof(cert->ts), buf, len, &off); break;
32 case 'p': r = unpack(cert->path, 's', sizeof(cert->path), buf, len, &off); break;
33 case 'u': r = unpack(cert->subj, 's', sizeof(cert->subj), buf, len, &off); break;
34 case 'i': r = unpack(cert->issuer, 's', sizeof(cert->issuer), buf, len, &off); break;
35 case 's': r = unpack(&cert->not_before, '8', sizeof(cert->not_before), buf, len, &off); break;
36 case 'e': r = unpack(&cert->not_after, '8', sizeof(cert->not_after), buf, len, &off); break;
37 case 'a': r = unpack(cert->sig_alg, 's', sizeof(cert->sig_alg), buf, len, &off); break;
38 case 'n': r = unpack(serial, 'b', sizeof(serial), buf, len, &off); serial_len = r; break;
39 case 't': r = unpack(&cert->type, 'c', sizeof(cert->type), buf, len, &off); break;
40 case 'k': r = unpack(cert->pk_alg, 's', sizeof(cert->pk_alg), buf, len, &off); break;
41 case 'K': r = unpack(&cert->pk_bits, '4', sizeof(cert->pk_bits), buf, len, &off); break;
42 default: r = 0xFFFFFFFE; break;
43 }
44 if (r >= 0xFFFFFFF0) {
45 char dump[len * 2 + 1];
46 bin2hex(dump, buf, len);
47 xlog(1, "%s: Cannot decode ssl cert r=0x%08x c=%c[0x%02hhx] off=%u/%u [%s]!\n",
48 __func__, r, c, c, off, len, dump);
49 return -1;
21 int ret = g.gl_pathc;
22 for (unsigned i = 0; i < g.gl_pathc; i++) {
23 unsigned int uid = strtoul(basename(g.gl_pathv[i]), NULL, 16);
24 r = cb(uid, g.gl_pathv[i]);
25 if (r == -1) {
26 ret = -1;
27 break;
50 28 } }
51 29 } }
30 globfree(&g);
31
32 return ret;
33 }
34
35 int nd_load_certs(glob_t *g, const unsigned int uid)
36 {
37 char path[1024];
52 38
53 bin2hex(cert->serial, serial, serial_len);
39 snprintf(path, sizeof(path),
40 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/cert/*",
41 uid, uid >> 8, uid);
54 42
55 xlog(1, "%s: ts=%llu path=[%s] subj=[%s] issuer=[%s] not_before=[%llu]"
56 " not_after=[%llu] serial=[%s] type=%c sig_alg=[%s]"
57 " pk_alg=[%s] pk_bits=%u\n",
58 __func__, cert->ts, cert->path, cert->subj, cert->issuer,
59 cert->not_before, cert->not_after, cert->serial, cert->type,
60 cert->sig_alg, cert->pk_alg, cert->pk_bits);
43 int r = glob(path, GLOB_NOSORT | GLOB_ONLYDIR, NULL, g);
44 if (r == GLOB_NOMATCH)
45 return 0;
46 if (r != 0)
47 return r;
61 48
62 return 0;
49 return g->gl_pathc;
63 50 } }
51
52 int nd_load_cert_users(glob_t *g, const char *cert_path)
53 {
54 char path[1024];
55
56 snprintf(path, sizeof(path), "%s/users/*/*/*", cert_path);
57 int r = glob(path, 0 /*flags*/, NULL, g);
58 if (r == GLOB_NOMATCH)
59 return 0;
60 if (r != 0)
61 return r;
62
63 return g->gl_pathc;
64 }
65
File common/sctools.h changed (mode: 100644) (index 7c63b50..7fb099f)
1 struct ninedogs_cert
2 {
3 char path[256];
4 unsigned long long not_before;
5 unsigned long long not_after;
6 char subj[512];
7 char issuer[512];
8 char serial[128];
9 char sig_alg[32];
10 char pk_alg[32];
11 unsigned int pk_bits;
12 char type;
13 char pad[3];
14 unsigned long long ts;
15 };
1 #include <glob.h>
16 2
17 int decode_cert(struct ninedogs_cert *c, const unsigned char *buf,
18 const unsigned int len);
3 int nd_for_each_user(int (*cb)(const unsigned int uid, const char *user_dir));
4
5 int nd_load_certs(glob_t *g, const unsigned int uid);
6
7 int nd_load_cert_users(glob_t *g, const char *cert_path);
19 8
File common/shared.h changed (mode: 100644) (index ab487bb..447b158)
10 10
11 11 struct shared struct shared
12 12 { {
13 sem_t sem1;
14 unsigned int head, tail; // these can be changed only under semaphore
15 unsigned int new_tail;
16 unsigned int buf_size; // client may be compiled with another version and need to know this
17 unsigned int msgs_lost;
18 unsigned char version;
19 unsigned char done; // set by the target program when it exits; on fork we should make this a counter
20 unsigned char pad[2];
21 unsigned char buf[1024 * 1024];
13 sem_t sem1;
14 volatile unsigned int head, tail; // these can be changed only under semaphore
15 volatile unsigned int junk;
16 unsigned int buf_size; // client may be compiled with another version and need to know this
17 unsigned int client_flags; // set by a tracer
18 unsigned char version;
19 unsigned char done; // set by the target program when it exits; on fork we should make this a counter (TODO)
20 unsigned char inited;
21 unsigned char clients;
22 unsigned char buf[2000000];
22 23 }; };
23 24
24 25
 
... ... struct fd_node
51 52 int flags; int flags;
52 53 mode_t mode; // used also as timerfd::clockid mode_t mode; // used also as timerfd::clockid
53 54 off_t off; off_t off;
55 off_t max; // was is set by ftruncate
54 56 } file; } file;
55 57 struct { struct {
56 58 int domain, type, protocol, backlog; int domain, type, protocol, backlog;
57 59 struct sockaddr_storage bind, peer; struct sockaddr_storage bind, peer;
58 60 socklen_t bind_len, peer_len; socklen_t bind_len, peer_len;
59 61 uint64_t accepts; uint64_t accepts;
62 int accept_fd; // if this is a result of the accept, it will contain the fd doing accept
63 int pad;
60 64 } socket; } socket;
61 65 }; };
62 66 uint64_t stats[3][2]; // 0=ops/1=bytes/2=errors | 0=read/1=write uint64_t stats[3][2]; // 0=ops/1=bytes/2=errors | 0=read/1=write
File common/tools.c changed (mode: 100644) (index adb2c61..567f64e)
1 1 #define _GNU_SOURCE 500 #define _GNU_SOURCE 500
2 2
3 #include <stdio.h>
4 3 #include <ctype.h> #include <ctype.h>
4 #include <curl/curl.h>
5 #include <endian.h>
6 #include <libgen.h>
7 #include <stdio.h>
5 8 #include <unistd.h> #include <unistd.h>
6 9 #include <stdio.h> #include <stdio.h>
7 10 #include <stdlib.h> #include <stdlib.h>
8 11 #include <stdarg.h> #include <stdarg.h>
9 12 #include <string.h> #include <string.h>
10 #include <sys/socket.h>
11 13 #include <sys/random.h> #include <sys/random.h>
14 #include <sys/socket.h>
12 15 #include <sys/time.h> #include <sys/time.h>
13 16 #include <sys/types.h> #include <sys/types.h>
14 17 #include <arpa/inet.h> #include <arpa/inet.h>
 
28 31 #include "tools.h" #include "tools.h"
29 32
30 33
31 extern void xlog(const unsigned int level, const char *format, ...);
32
33
34 34 void ninedogs_now(struct timeval *tv) void ninedogs_now(struct timeval *tv)
35 35 { {
36 36 gettimeofday(tv, NULL); gettimeofday(tv, NULL);
 
... ... static unsigned char hex2bin_one(const char d)
81 81 if ((d >= 'A') && (d <= 'F')) if ((d >= 'A') && (d <= 'F'))
82 82 return d - 'A' + 10; return d - 'A' + 10;
83 83
84 xlog(0, " invalid hex char: %c[%02hhx]\n", d, d);
84 xlog(1, " invalid hex char: %c[%02hhx]\n", d, d);
85 85 return 0xFF; // signal error return 0xFF; // signal error
86 86 } }
87 87
 
... ... void pack(unsigned char **pbuf, unsigned int *len, const char *fmt, ...)
175 175 case 't': needed += 8; va_arg(va, struct timeval *); break; // timeval case 't': needed += 8; va_arg(va, struct timeval *); break; // timeval
176 176 case 'N': needed += 8; break; // "now" case 'N': needed += 8; break; // "now"
177 177 default: default:
178 xlog(0, "invalid format [%c]!\n", *f);
178 xlog(1, "invalid format [%c]!\n", *f);
179 179 abort(); abort();
180 180 } }
181 181
 
... ... void pack(unsigned char **pbuf, unsigned int *len, const char *fmt, ...)
186 186
187 187 q = p = malloc(needed); q = p = malloc(needed);
188 188 if (!p) { if (!p) {
189 xlog(0, "cannot alloc mem [%u]!\n", needed);
189 xlog(1, "cannot alloc mem [%u]!\n", needed);
190 190 return; return;
191 191 } }
192 192
 
... ... void pack(unsigned char **pbuf, unsigned int *len, const char *fmt, ...)
252 252 memcpy(q, &u64be, 8); q += 8; memcpy(q, &u64be, 8); q += 8;
253 253 break; break;
254 254
255 case 't': // struct timeval
255 case 't': { // struct timeval
256 256 struct timeval *tv = va_arg(va, struct timeval *); struct timeval *tv = va_arg(va, struct timeval *);
257 257 u64 = tv->tv_sec * 1000 + tv->tv_usec / 1000; u64 = tv->tv_sec * 1000 + tv->tv_usec / 1000;
258 258 u64be = htobe64(u64); u64be = htobe64(u64);
259 259 memcpy(q, &u64be, 8); q += 8; memcpy(q, &u64be, 8); q += 8;
260 break;
260 } break;
261 261
262 case 'N': // struct timeval "now"
262 case 'N': { // struct timeval "now"
263 263 struct timeval now; struct timeval now;
264 264 ninedogs_now(&now); ninedogs_now(&now);
265 265 u64 = now.tv_sec * 1000 + now.tv_usec / 1000; u64 = now.tv_sec * 1000 + now.tv_usec / 1000;
266 266 u64be = htobe64(u64); u64be = htobe64(u64);
267 267 memcpy(q, &u64be, 8); q += 8; memcpy(q, &u64be, 8); q += 8;
268 break;
268 } break;
269 269
270 270 default: default:
271 xlog(0, "invalid format [%c]!\n", *f);
271 xlog(1, "invalid format [%c]!\n", *f);
272 272 abort(); abort();
273 273 } }
274 274
 
... ... unsigned int unpack(void *dst, const char type, const unsigned int max,
336 336 return 0xFFFFFFF1; return 0xFFFFFFF1;
337 337 } }
338 338 if (u32 + 1 > max) { if (u32 + 1 > max) {
339 xlog(0, " u32[%u] + 1 > max[%u]\n", u32, max);
339 xlog(1, " u32[%u] + 1 > max[%u]\n", u32, max);
340 340 return 0xFFFFFFF2; return 0xFFFFFFF2;
341 341 } }
342 342 memcpy(dst, buf + *off, u32); *off = *off + u32; memcpy(dst, buf + *off, u32); *off = *off + u32;
 
... ... unsigned int unpack(void *dst, const char type, const unsigned int max,
371 371 //Log(60, " decoded u32 %u\n", u32); //Log(60, " decoded u32 %u\n", u32);
372 372 break; break;
373 373
374 case 'N': // "now", timestamp
374 case '_': // "now", timestamp
375 375 case '8': // u64, unsigned case '8': // u64, unsigned
376 376 case 't': // timeval case 't': // timeval
377 377 if (*off + 8 > len) if (*off + 8 > len)
 
... ... char mkdir_recursive(const char *dir, const mode_t mode)
421 421 if (!p) if (!p)
422 422 break; break;
423 423 *p = '\0'; *p = '\0';
424 r = mkdir(path, mode);
424 r = mkdir(path, mode | S_IXUSR);
425 425 *p = '/'; *p = '/';
426 if ((r == -1) && (errno != EEXIST))
426 if ((r == -1) && (errno != EEXIST)) {
427 xlog(1, "%s: cannot create dir [%s]: %m\n", __func__, path);
427 428 return -1; return -1;
429 }
428 430 q = p + 1; q = p + 1;
429 431 } while (1); } while (1);
430 432
431 r = mkdir(path, mode);
432 if ((r == -1) && (errno != EEXIST))
433 r = mkdir(path, mode | S_IXUSR);
434 if ((r == -1) && (errno != EEXIST)) {
435 xlog(1, "%s: cannot create dir [%s]: %m\n", __func__, path);
433 436 return -1; return -1;
437 }
434 438
435 439 return 0; return 0;
436 440 } }
 
... ... int save_buf(int fd, const void *buf, const unsigned int len)
472 476
473 477 off = 0; off = 0;
474 478 do { do {
475 xlog(14, "%s: Writing %u, off %u bytes to fd %d\n", __func__, len - off, off, fd);
479 xlog(50, "%s: Writing %u, off %u bytes to fd %d\n", __func__, len - off, off, fd);
476 480 ssize_t n = write(fd, buf + off, len - off); ssize_t n = write(fd, buf + off, len - off);
477 481 if (n == -1) { if (n == -1) {
478 482 if (errno == EAGAIN) if (errno == EAGAIN)
 
... ... int save_buf(int fd, const void *buf, const unsigned int len)
486 490 return len; return len;
487 491 } }
488 492
489 int save_file(const char *path, const void *buf, const unsigned int len)
493 int save_file(const char *path, const mode_t mode,
494 const void *buf, const unsigned int len)
490 495 { {
491 496 do { do {
492 xlog(14, "%s: Saving %u bytes to %s\n", __func__, len, path);
493 int fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0600);
497 char *copy = nd_strdup(path, -1);
498 char *dir = dirname(copy);
499 int r = mkdir_recursive(dir, 0600);
500 free(copy);
501 if (r == -1)
502 break;
503
504 xlog(50, "%s: Saving %u bytes to %s\n", __func__, len, path);
505 int fd = open(path, mode, 0600);
494 506 if (fd == -1) { if (fd == -1) {
495 507 xlog(1, "%s: [%s] error: %m\n", __func__, path); xlog(1, "%s: [%s] error: %m\n", __func__, path);
496 508 break; break;
497 509 } }
498 510
499 int r = save_buf(fd, buf, len);
511 r = save_buf(fd, buf, len);
500 512 close(fd); close(fd);
501 513 if (r == -1) if (r == -1)
502 514 break; break;
 
... ... int save_file(const char *path, const void *buf, const unsigned int len)
507 519 return -1; return -1;
508 520 } }
509 521
510 int save_dir_file(const char *dir, const char *file, const void *buf,
511 const unsigned int len)
522 int save_dir_file(const char *dir, const char *file, const mode_t mode,
523 const void *buf, const unsigned int len)
512 524 { {
513 525 char path[4096]; char path[4096];
514 526
515 527 snprintf(path, sizeof(path), "%s/%s", dir, file); snprintf(path, sizeof(path), "%s/%s", dir, file);
516 return save_file(path, buf, len);
528 return save_file(path, mode, buf, len);
517 529 } }
518 530
519 531 int load_file(void *buf, const size_t buf_size, const char *path) int load_file(void *buf, const size_t buf_size, const char *path)
520 532 { {
521 533 do { do {
522 xlog(14, "%s: Loading max %u bytes from %s\n", __func__, buf_size, path);
534 xlog(50, "%s: Loading max %u bytes from %s\n", __func__, buf_size, path);
523 535 int fd = open(path, O_RDONLY); int fd = open(path, O_RDONLY);
524 536 if (fd == -1) { if (fd == -1) {
525 537 xlog(1, "%s: [%s] error: %m\n", __func__, path); xlog(1, "%s: [%s] error: %m\n", __func__, path);
 
... ... int load_dir_file_text(char *buf, const size_t buf_size, const char *dir,
563 575 return r; return r;
564 576 } }
565 577
578 int nd_stat_dir_file(struct stat *s, const char *dir, const char *file)
579 {
580 char path[4096];
581 snprintf(path, sizeof(path), "%s/%s", dir, file);
582 return stat(path, s);
583 }
584
585 char *nd_strdup(const char *s, int len)
586 {
587 if (!s || (len == 0))
588 return NULL;
589
590 if (len == -1)
591 len = strlen(s);
592
593 char *ret = malloc(len + 1);
594 if (!ret)
595 return NULL;
596
597 memcpy(ret, s, len);
598 ret[len] = '\0';
599
600 return ret;
601 }
602
603 /*
604 * Loads a string from an user file
605 */
606 int nd_load_uid_file_str(void *out, const size_t out_size,
607 const unsigned int uid, const char *file)
608 {
609 char path[1024];
610 snprintf(path, sizeof(path),
611 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x",
612 uid, uid >> 8, uid);
613 int r = load_dir_file(out, out_size, path, file);
614 if (r == -1)
615 return -1;
616
617 if ((unsigned long) r < out_size) {
618 char *out2 = (char *) out;
619 out2[r] = '\0';
620 }
621
622 return r;
623 }
624
625 /*
626 * Loads a long from an user file
627 */
628 int nd_load_uid_file_long(long *out, const unsigned int uid, const char *file)
629 {
630 long ret;
631
632 int r = nd_load_uid_file_str(&ret, sizeof(ret), uid, file);
633 if (r == -1)
634 return -1;
635
636 *out = be64toh(ret);
637
638 return 0;
639 }
640
641 /*
642 * Saves a long into a user file
643 */
644 int nd_save_uid_file_long(const unsigned int uid, const char *file,
645 const long v)
646 {
647 const long v2 = htobe64(v);
648
649 char path[1024];
650 snprintf(path, sizeof(path),
651 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x",
652 uid, uid >> 8, uid);
653 int r = save_dir_file(path, file, O_CREAT | O_TRUNC | O_WRONLY,
654 &v2, 8);
655 if (r == -1)
656 return -1;
657
658 return 0;
659 }
660
661 /*
662 * Convert a /proc/?/cmdline to a printable form
663 */
664 void nd_app_nice(char *out, const unsigned out_size,
665 const char *in, const unsigned in_len)
666 {
667 unsigned j = 0;
668
669 if (out_size < 3)
670 return;
671
672 out[j++] = '[';
673 for (unsigned i = 0; i < in_len; i++) {
674 if (j + 3 > out_size - 1)
675 break;
676 if (in[i] == '\0') {
677 if (i == in_len - 1)
678 break;
679 out[j++] = ']';
680 out[j++] = ' ';
681 out[j++] = '[';
682 } else {
683 out[j++] = in[i];
684 }
685 }
686
687 out[j++] = ']';
688 out[j] = '\0';
689 }
690
691 void nd_ts_to_str(char *out, const size_t out_size, const unsigned long ts)
692 {
693 struct tm tm;
694 time_t t = ts;
695
696 gmtime_r(&t, &tm);
697 strftime(out, out_size, "%F %T", &tm);
698 }
699
700 /*
701 * Append a string, respecting limits
702 */
703 void nd_str_append(char *out, const size_t out_size, size_t *off,
704 const char *fmt, ...)
705 {
706 if (*off >= out_size)
707 return;
708
709 va_list va;
710
711 va_start(va, fmt);
712 int r = vsnprintf(out + *off, out_size - *off, fmt, va);
713 va_end(va);
714
715 if ((r > 0) && ((unsigned long) r < out_size - *off))
716 *off = *off + r;
717 }
718
719 /*
720 * Removes end characters in @what string
721 */
722 void nd_rtrim(char *s, const char *what)
723 {
724 char *q = s;
725
726 while (*q != '\0')
727 q++;
728 q--;
729
730 while (q >= s) {
731 if (!strchr(what, *q))
732 break;
733 *q = '\0';
734 q--;
735 }
736 }
737
738 /*
739 * Helper for nd_send_mail
740 */
741 struct upload_status { size_t read, total; char *data; } nd_send_mail_status;
742 static size_t nd_send_mail_payload(char *ptr, size_t size, size_t nmemb,
743 void *user)
744 {
745 struct upload_status *us = user;
746 size_t rest;
747
748 xlog(50, "%s: read=%zu total=%zu\n", __func__, us->read, us->total);
749
750 rest = us->total - us->read;
751 if (rest > size * nmemb)
752 rest = size * nmemb;
753
754 memcpy(ptr, us->data + us->read, rest);
755 us->read += rest;
756
757 return rest;
758 }
759
760 int nd_send_mail(const char *to, const char *from, const char *from_nice,
761 const char *subject, const char *body)
762 {
763 CURL *c;
764 CURLcode res;
765 struct curl_slist *tos = NULL;
766 char final[64 * 4096];
767 struct timeval now;
768 char date[100];
769
770 ninedogs_now(&now);
771 struct tm tm = *gmtime(&now.tv_sec);
772 strftime(date, sizeof(date), "%a, %d %b %y %T %z", &tm);
773 snprintf(final, sizeof(final),
774 "Date: %s\r\n"
775 "To: %s\r\n"
776 "From: %s <%s>\r\n"
777 "Message-ID: ninedogs-notification-%ld\r\n"
778 "Subject: %s\r\n"
779 "\r\n" /* empty line to divide headers from body, see RFC5322 */
780 "%s\r\n",
781 date, to, from_nice, from, now.tv_sec, subject, body);
782 xlog(1, "%s: final:\n%s\n", __func__, final);
783
784 c = curl_easy_init();
785 if (!c)
786 return -1;
787
788 curl_easy_setopt(c, CURLOPT_URL, "smtp://localhost:25");
789 //curl_easy_setopt(c, CURLOPT_USERNAME, "kurt");
790 //curl_easy_setopt(c, CURLOPT_PASSWORD, "xipj3plmq");
791 /* Set the authorization identity (identity to act as) */
792 //curl_easy_setopt(c, CURLOPT_SASL_AUTHZID, "ursel");
793 /* Force PLAIN authentication */
794 //curl_easy_setopt(c, CURLOPT_LOGIN_OPTIONS, "AUTH=PLAIN");
795
796 //todo curl_easy_setopt(c, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
797 curl_easy_setopt(c, CURLOPT_MAIL_FROM, from);
798 curl_easy_setopt(c, CURLOPT_VERBOSE, 1L);
799
800 tos = curl_slist_append(tos, to);
801 curl_easy_setopt(c, CURLOPT_MAIL_RCPT, tos);
802
803 curl_easy_setopt(c, CURLOPT_READFUNCTION, nd_send_mail_payload);
804 nd_send_mail_status.data = final;
805 nd_send_mail_status.read = 0;
806 nd_send_mail_status.total = strlen(final);
807 curl_easy_setopt(c, CURLOPT_READDATA, &nd_send_mail_status);
808 curl_easy_setopt(c, CURLOPT_UPLOAD, 1L);
809
810 res = curl_easy_perform(c);
811 if (res == CURLE_OK)
812 curl_slist_free_all(tos);
813
814 curl_easy_cleanup(c);
815
816 return 0;
817 }
818
819 /*
820 * User notification
821 */
822 int nd_user_notify(const unsigned int uid, const char *subject,
823 const char *body)
824 {
825 char email[1024];
826
827 int r = nd_load_uid_file_str(email, sizeof(email), uid, "email");
828 if (r == -1)
829 return -1;
830 nd_rtrim(email, "\n\r\t ");
831 xlog(1, "%s: email=[%s]\n", __func__, email);
832
833 return nd_send_mail(email, "ninedogs-mail@embedromix.ro",
834 "Ninedogs certificate expiration",
835 subject, body);
836 }
837
File common/tools.h changed (mode: 100644) (index f133996..a8815ee)
1 #include <sys/stat.h>
1 2 #include <sys/time.h> #include <sys/time.h>
2 3 #include <stdlib.h> #include <stdlib.h>
3 4
5 extern void xlog(const unsigned int level, const char *format, ...);
6
4 7 void ninedogs_now(struct timeval *tv); void ninedogs_now(struct timeval *tv);
5 8
6 9 void bin2hex(char *out, const void *buf, const unsigned int len); void bin2hex(char *out, const void *buf, const unsigned int len);
 
... ... unsigned long long get_day(time_t now);
23 26 unsigned long long get_hour(time_t now); unsigned long long get_hour(time_t now);
24 27
25 28 int save_buf(int fd, const void *buf, const unsigned int len); int save_buf(int fd, const void *buf, const unsigned int len);
26 int save_file(const char *path, const void *buf, const unsigned int len);
27 int save_dir_file(const char *dir, const char *file, const void *buf,
28 const unsigned int len);
29 int save_file(const char *path, const mode_t mode,
30 const void *buf, const unsigned int len);
31 int save_dir_file(const char *dir, const char *file, const mode_t mode,
32 const void *buf, const unsigned int len);
29 33 int load_file(void *buf, const size_t buf_size, const char *path); int load_file(void *buf, const size_t buf_size, const char *path);
30 34 int load_dir_file(void *buf, const size_t buf_size, int load_dir_file(void *buf, const size_t buf_size,
31 35 const char *dir, const char *file); const char *dir, const char *file);
32 36 int load_dir_file_text(char *buf, const size_t buf_size, int load_dir_file_text(char *buf, const size_t buf_size,
33 37 const char *dir, const char *file); const char *dir, const char *file);
34 38
39 int nd_stat_dir_file(struct stat *s, const char *dir, const char *file);
40
41 char *nd_strdup(const char *s, int len);
42
43 int nd_load_uid_file_str(void *out, const size_t out_size,
44 const unsigned int uid, const char *file);
45
46 int nd_load_uid_file_long(long *out, const unsigned int uid,
47 const char *file);
48 int nd_save_uid_file_long(const unsigned int uid, const char *file,
49 const long v);
50
51 void nd_app_nice(char *out, const unsigned out_size,
52 const char *in, const unsigned in_len);
53
54 void nd_ts_to_str(char *out, const size_t out_size,
55 const unsigned long ts);
56
57 void nd_str_append(char *out, const size_t out_size, size_t *off,
58 const char *fmt, ...);
59
60 void nd_rtrim(char *s, const char *what);
61
62 int nd_send_mail(const char *to, const char *from,
63 const char *from_nice,
64 const char *subject, const char *body);
65
66 int nd_user_notify(const unsigned int uid, const char *subject,
67 const char *body);
68
File debian/control changed (mode: 100644) (index 84ff626..4f8a92e)
... ... Source: ninedogs
2 2 Maintainer: Catalin(ux) M. BOIE <catab@embedromix.ro> Maintainer: Catalin(ux) M. BOIE <catab@embedromix.ro>
3 3 Section: misc Section: misc
4 4 Priority: optional Priority: optional
5 Build-Depends: debhelper (>= 9), libgnutls28-dev, json-c-dev, libcap-dev, texlive-latex-base, texlive-latex-extra, catalinux+Conn
5 Build-Depends: debhelper (>= 9), libgnutls28-dev, json-c-dev, libcap-dev, texlive-latex-base, texlive-latex-extra, libcurl-dev, catalinux+Conn
6 6 Standards-Version: 3.9.6 Standards-Version: 3.9.6
7 7 Homepage: https://rocketgit.com/user/catalinux/ninedogs Homepage: https://rocketgit.com/user/catalinux/ninedogs
8 8 Vcs-Git: git://rocketgit.com/user/catalinux/ninedogs Vcs-Git: git://rocketgit.com/user/catalinux/ninedogs
 
... ... Vcs-Browser: https://rocketgit.com/user/catalinux/ninedogs
10 10
11 11 Package: ninedogs Package: ninedogs
12 12 Architecture: all Architecture: all
13 Depends: ${shlibs:Depends}, ${misc:Depends}, libgnutls30, json-c, libcap, catalinux+Conn
13 Depends: ${shlibs:Depends}, ${misc:Depends}, libgnutls30, json-c, libcap, libcurl, catalinux+Conn
14 14 Description: Light and fast application monitoring and tracing Description: Light and fast application monitoring and tracing
File docs/Makefile changed (mode: 100644) (index ad88c82..98f21bf)
... ... PDFs := pre1.pdf
2 2
3 3 all: $(PDFs) all: $(PDFs)
4 4
5 compile: $(PDFs)
6
7 5 pre1.pdf: pre1.tex pre1.pdf: pre1.tex
8 6 pdflatex $< && pdflatex $< pdflatex $< && pdflatex $<
9 7
File docs/colors1.png added (mode: 100644) (index 0000000..0c2222b)
File docs/pre1.tex changed (mode: 100644) (index 5e966f5..2ae00f1)
... ... recvfrom(5, "\7\0\0\2\0\0\0\2\0\0\0", 32768, MSG_DONTWAIT, NULL, NULL) = 11
275 275 \tiny \tiny
276 276 \begin{verbatim} \begin{verbatim}
277 277 mysqli_real_connect(link=0x7ffba947f190, 'host=h1 user=ninedogs port=3306 db=ninedogs socket=', mysqli_real_connect(link=0x7ffba947f190, 'host=h1 user=ninedogs port=3306 db=ninedogs socket=',
278 flags='0x20|COMPRESS')
278 flags=0x20|COMPRESS)
279 279 mysqli_real_connect(link=0x7ffba947f190, 'host=h1 user=ninedogs port=3306 db=ninedogs socket=', mysqli_real_connect(link=0x7ffba947f190, 'host=h1 user=ninedogs port=3306 db=ninedogs socket=',
280 flags='0x20|COMPRESS') = ok
280 flags=0x20|COMPRESS) = ok
281 281 \end{verbatim} \end{verbatim}
282 282 \end{block} \end{block}
283 283 \end{frame} \end{frame}
File docs/pre1.txt changed (mode: 100644) (index a3035c0..fd94e7b)
... ... Ideas for the first presentation
15 15 - Explain "augmented". - Explain "augmented".
16 16 - Language: C - Language: C
17 17 - Where you can find the latest version of this presentation? - Where you can find the latest version of this presentation?
18 - Switch to 16:9 format
19 - No re-compilation, no hard deployment procedure => easy all over
20 - Package management security updates not done.
21 - add color1.png
18 22 - -
19 23
20 24 - Ce probleme vrei sa le rezolvi? - Ce probleme vrei sa le rezolvi?
File duilder changed (mode: 100755) (index 090eaa8..beaa5e0)
... ... else
543 543 fi fi
544 544
545 545 if [ "${CC_SWITCHES}" = "" ]; then if [ "${CC_SWITCHES}" = "" ]; then
546 CC_SWITCHES="-O3 -fstack-reuse=all -flto -Wtrampolines -Wl,-z,noexecstack -Wl,-z,now -Wl,-z,relro -Wl,-O1 -Wl,-z,noexecstack -fstack-protector-all -Wcast-align -Wformat=2 -Wformat-security -fno-common -Wmissing-prototypes -Wmissing-declarations -Wstrict-overflow -Wstrict-prototypes -fno-guess-branch-probability -fbounds-check -Wl,-O3 -Wpadded -ftree-loop-distribution -ftree-vectorize -ftree-loop-if-convert -ftree-loop-im -ftree-parallelize-loops=4 -fcf-protection -fstack-clash-protection -Wimplicit-fallthrough -fanalyzer"
546 CC_SWITCHES="-O3 -fstack-reuse=all -flto=auto|-flto -Wtrampolines -Wl,-z,noexecstack -Wl,-z,now -Wl,-z,relro -Wl,-O1 -Wl,-z,noexecstack -fstack-protector-all -Wcast-align -Wformat=2 -Wformat-security -fno-common -Wmissing-prototypes -Wmissing-declarations -Wstrict-overflow -Wstrict-prototypes -fno-guess-branch-probability -fbounds-check -Wl,-O3 -Wpadded -ftree-loop-distribution -ftree-vectorize -ftree-loop-if-convert -ftree-loop-im -ftree-parallelize-loops=4 -fcf-protection -fstack-clash-protection -Wimplicit-fallthrough -D_FORTIFY_SOURCES=3|-D_FORTIFY_SOURCES=2 -fanalyzer"
547 547 fi fi
548 548
549 549 if [ "1" = "1" ]; then if [ "1" = "1" ]; then
550 550 _CC_SWITCHES="" _CC_SWITCHES=""
551 551 echo "[*] Search for valid compiler flags..." echo "[*] Search for valid compiler flags..."
552 552 add="" add=""
553 for s in ${CC_SWITCHES}; do
554 echo -n " [*] Testing switch [${s}]..."
555 case ${s} in
556 -Wformat-security) extra=" -Wformat" ;;
557 *) extra="" ;;
558 esac
559 set +e
560 echo "int main(void) { return 0; }" \
561 | gcc ${extra} ${s} -x c -pipe - -o /dev/null 2>>duilder.log
562 E=${?}
563 set -e
564 if [ "${E}" != "0" ]; then
565 echo "not supported"
566 else
567 echo "supported"
568 _CC_SWITCHES="${_CC_SWITCHES}${add}${s}"
569 add=" "
570 fi
553 for s0 in ${CC_SWITCHES}; do
554 list=(${s0/|/ })
555 for s in ${list}; do
556 echo -n " [*] Testing switch [${s}]..."
557 case ${s} in
558 -Wformat-security) extra=" -Wformat" ;;
559 *) extra="" ;;
560 esac
561 set +e
562 echo "int main(void) { return 0; }" \
563 | gcc ${extra} ${s} -x c -pipe - -o /dev/null 2>>duilder.log
564 E=${?}
565 set -e
566 if [ "${E}" != "0" ]; then
567 echo "not supported"
568 else
569 echo "supported"
570 _CC_SWITCHES="${_CC_SWITCHES}${add}${s}"
571 add=" "
572 break # first try will win
573 fi
574 done
571 575 done done
572 576 fi fi
573 577
 
... ... if [ "${BUILD_SDEB}" = "1" ]; then
688 692 AUTOGENERATE="${AUTOGENERATE} debian/control.in debian/changelog.in" AUTOGENERATE="${AUTOGENERATE} debian/control.in debian/changelog.in"
689 693 AUTOGENERATE="${AUTOGENERATE} debian/copyright.in debian/rules.in" AUTOGENERATE="${AUTOGENERATE} debian/copyright.in debian/rules.in"
690 694 fi fi
695 AUTOGENERATE="${AUTOGENERATE} $(find . -name '*.in')"
691 696
692 697 echo "[*] Autogenerate files from .in..." echo "[*] Autogenerate files from .in..."
693 698 for f in ${AUTOGENERATE}; do for f in ${AUTOGENERATE}; do
File ingestd/Makefile changed (mode: 100644) (index be65fb6..d4dc875)
1 COMMON_H += ../common/ids.h ../common/tools.h ../common/sctools.h stools.h priv.h
2 OBJS := ../common/tools.o ../common/sctools.o stools.o \
1 include ../Makefile.common
2
3 COMMON_H += ../common/ids.h ../common/tools.h ../common/bin2struct.h stools.h priv.h
4 OBJS := ../common/tools.o ../common/bin2struct.o \
5 stools.o \
3 6 decode.o decode_core.o decode_db.o decode_ssl.o decode.o decode_core.o decode_db.o decode_ssl.o
4 7
5 8 CFLAGS += -I../common CFLAGS += -I../common
6 9
7 all:
8 make -R -C .. ingestd
9
10 compile: ninedogs-ingestd
10 all: ninedogs-ingestd
11 11
12 12 stools.o: stools.c $(COMMON_H) stools.o: stools.c $(COMMON_H)
13 13 $(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
 
... ... stools.o: stools.c $(COMMON_H)
15 15 decode.o: decode.c decode.h $(COMMON_H) decode.o: decode.c decode.h $(COMMON_H)
16 16 $(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
17 17
18 decode_core.o: decode_core.c decode_core.h $(COMMON_H)
18 decode_core.o: decode_core.c decode_core.h $(COMMON_H) \
19 ../common/bin2struct.h
19 20 $(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
20 21
21 22 decode_db.o: decode_db.c decode_db.h $(COMMON_H) decode_db.o: decode_db.c decode_db.h $(COMMON_H)
 
... ... install: ninedogs-ingestd
32 33 @cp ninedogs-ingestd $(I_USR_SBIN) @cp ninedogs-ingestd $(I_USR_SBIN)
33 34 @mkdir -pv $(I_USR)/lib/systemd/system @mkdir -pv $(I_USR)/lib/systemd/system
34 35 cp -vd *.service $(I_USR)/lib/systemd/system/ cp -vd *.service $(I_USR)/lib/systemd/system/
36 @systemctl daemon-reload
35 37
36 38 .PHONY: clean .PHONY: clean
37 39 clean: clean:
File ingestd/TODO added (mode: 100644) (index 0000000..c3e3da1)
1 [ ] Send local IPs
2 [ ] Seems the server is requesting a query twice!
3 [ ]
File ingestd/decode.c changed (mode: 100644) (index 8055396..0276430)
... ... unsigned int decode(struct Conn *C, unsigned char *buf, const unsigned int len)
24 24 Log(20, "%s: dump: len=%u %s\n", __func__, len, dump); Log(20, "%s: dump: len=%u %s\n", __func__, len, dump);
25 25 free(dump); free(dump);
26 26
27 struct priv *p = Conn_get_private(C);
28
27 29 while (off + 4 + 1 + 4 < len) { while (off + 4 + 1 + 4 < len) {
28 30 flags = 0; flags = 0;
29 31 ioff = off; ioff = off;
 
... ... unsigned int decode(struct Conn *C, unsigned char *buf, const unsigned int len)
33 35 return 0; return 0;
34 36
35 37 if (buf[off++] != 'T') { if (buf[off++] != 'T') {
36 Log(2, "Invalid frame (not starting with T)!\n");
38 Log(2, "Invalid frame (not starting with 'T')!\n");
37 39 Conn_close(C); Conn_close(C);
38 40 return 0; return 0;
39 41 } }
 
... ... unsigned int decode(struct Conn *C, unsigned char *buf, const unsigned int len)
63 65 else if ((flags & DECODE_FLAGS_NO_SAVE) == 0) else if ((flags & DECODE_FLAGS_NO_SAVE) == 0)
64 66 save_data(C, buf + ioff, 4 + plen, ts); save_data(C, buf + ioff, 4 + plen, ts);
65 67
68 save_machine_visibility(C, ts);
69
66 70 off += plen - 1 - 4; off += plen - 1 - 4;
67 71 } }
68 72
69 struct priv *p = Conn_get_private(C);
70 73 if ((p->stop_received == 1) && (p->req_pending == 0)) { if ((p->stop_received == 1) && (p->req_pending == 0)) {
71 74 Log(10, "stop_received == 1 and req_pending is 0 => close connection\n"); Log(10, "stop_received == 1 and req_pending is 0 => close connection\n");
72 75 Conn_close(C); Conn_close(C);
File ingestd/decode_core.c changed (mode: 100644) (index 903ecf6..99cad31)
9 9 #include "tools.h" #include "tools.h"
10 10 #include "stools.h" #include "stools.h"
11 11 #include "priv.h" #include "priv.h"
12 #include "bin2struct.h"
12 13
13 14 static int decode_core_id(struct Conn *C, static int decode_core_id(struct Conn *C,
14 unsigned char *buf, const unsigned int len)
15 unsigned char *buf, const unsigned int len, unsigned long long *ts)
15 16 { {
16 17 unsigned int off = 0, ioff; unsigned int off = 0, ioff;
17 18 struct priv *p = Conn_get_private(C); struct priv *p = Conn_get_private(C);
 
... ... static int decode_core_id(struct Conn *C,
24 25 ioff = off; ioff = off;
25 26 c = buf[off++]; c = buf[off++];
26 27 switch (c) { switch (c) {
28 case '_': r = unpack(ts, 't', sizeof(*ts), buf, len, &off); break;
27 29 case 'I': r = unpack(&p->id.id, 's', 33, buf, len, &off); break; case 'I': r = unpack(&p->id.id, 's', 33, buf, len, &off); break;
28 30 default: r = 0xFFFFFFFE; break; default: r = 0xFFFFFFFE; break;
29 31 } }
 
... ... static int decode_core_uname(struct Conn *C,
106 108 ioff = off; ioff = off;
107 109 c = buf[off++]; c = buf[off++];
108 110 switch (c) { switch (c) {
109 case 'N': r = unpack(ts, 't', sizeof(*ts), buf, len, &off); break;
111 case '_': r = unpack(ts, 't', sizeof(*ts), buf, len, &off); break;
110 112 case 's': r = unpack(&p->uname.sysname, 's', sizeof(p->uname.sysname), buf, len, &off); break; case 's': r = unpack(&p->uname.sysname, 's', sizeof(p->uname.sysname), buf, len, &off); break;
111 113 case 'n': r = unpack(&p->uname.nodename, 's', sizeof(p->uname.nodename), buf, len, &off); break; case 'n': r = unpack(&p->uname.nodename, 's', sizeof(p->uname.nodename), buf, len, &off); break;
112 114 case 'r': r = unpack(&p->uname.release, 's', sizeof(p->uname.release), buf, len, &off); break; case 'r': r = unpack(&p->uname.release, 's', sizeof(p->uname.release), buf, len, &off); break;
 
... ... static int decode_core_uname(struct Conn *C,
128 130 return 0; return 0;
129 131 } }
130 132
131 static int decode_core_sysinfo(unsigned char *buf, const unsigned int len,
132 unsigned long long *ts)
133 {
134 unsigned int off = 0, ioff;
135 unsigned int r;
136 char c;
137 struct sysinfo s;
138
139 while (off + 1 + 1 <= len) {
140 ioff = off;
141 c = buf[off++];
142 switch (c) {
143 case 'N': r = unpack(ts, 't', sizeof(*ts), buf, len, &off); break;
144 case 'u': r = unpack(&s.uptime, '8', sizeof(s.uptime), buf, len, &off); break;
145 case '1': r = unpack(&s.loads[0], '8', sizeof(s.loads[0]), buf, len, &off); break;
146 case '5': r = unpack(&s.loads[1], '8', sizeof(s.loads[1]), buf, len, &off); break;
147 case 'q': r = unpack(&s.loads[2], '8', sizeof(s.loads[2]), buf, len, &off); break;
148 case 'r': r = unpack(&s.totalram, '8', sizeof(s.totalram), buf, len, &off); break;
149 case 'f': r = unpack(&s.freeram, '8', sizeof(s.freeram), buf, len, &off); break;
150 case 's': r = unpack(&s.sharedram, '8', sizeof(s.sharedram), buf, len, &off); break;
151 case 'b': r = unpack(&s.bufferram, '8', sizeof(s.bufferram), buf, len, &off); break;
152 case 'w': r = unpack(&s.totalswap, '8', sizeof(s.totalswap), buf, len, &off); break;
153 case 'W': r = unpack(&s.freeswap, '8', sizeof(s.freeswap), buf, len, &off); break;
154 case 'p': r = unpack(&s.procs, '2', sizeof(s.procs), buf, len, &off); break;
155 case 'h': r = unpack(&s.totalhigh, '8', sizeof(s.totalhigh), buf, len, &off); break;
156 case 'H': r = unpack(&s.freehigh, '8', sizeof(s.freehigh), buf, len, &off); break;
157 case 'i': r = unpack(&s.mem_unit, '4', sizeof(s.mem_unit), buf, len, &off); break;
158 default: r = 0xFFFFFFFE; break;
159 }
160 if (r >= 0xFFFFFFF0) {
161 Log(1, "%s: Cannot decode core sysinfo r=0x%08x c=%c[0x%02hhx] off=%u/%u!\n",
162 __func__, r, c, c, ioff, len);
163 return -1;
164 }
165 }
166
167 Log(10, "%s: ts=%llu uptime=%lu loads1=%lu loads5=%lu loads15=%lu totalram=%lu"
168 " freeram=%lu sharedram=%lu bufferram=%lu totalswap=%lu"
169 " freeswap=%lu procs=%u totalhigh=%lu freehigh=%lu mem_unit=%u\n",
170 __func__, *ts, s.uptime, s.loads[0], s.loads[1], s.loads[2], s.totalram,
171 s.freeram, s.sharedram, s.bufferram, s.totalswap,
172 s.freeswap, s.procs, s.totalhigh, s.freehigh, s.mem_unit);
173
174 return 0;
175 }
176
177 133 static int decode_core_stop(struct Conn *C, static int decode_core_stop(struct Conn *C,
178 134 unsigned char *buf, const unsigned int len) unsigned char *buf, const unsigned int len)
179 135 { {
 
... ... static int decode_core_stop(struct Conn *C,
189 145 c = buf[off++]; c = buf[off++];
190 146 switch (c) { switch (c) {
191 147 case 's': r = unpack(&start, 't', sizeof(start), buf, len, &off); break; case 's': r = unpack(&start, 't', sizeof(start), buf, len, &off); break;
192 case 't': r = unpack(&stop, 't', sizeof(stop), buf, len, &off); break;
148 case '_': r = unpack(&stop, 't', sizeof(stop), buf, len, &off); break;
193 149 case 'x': r = unpack(&exit_code, '4', sizeof(exit_code), buf, len, &off); break; case 'x': r = unpack(&exit_code, '4', sizeof(exit_code), buf, len, &off); break;
194 150 default: r = 0xFFFFFFFE; break; default: r = 0xFFFFFFFE; break;
195 151 } }
 
... ... int decode_core(struct Conn *C, const unsigned int type,
215 171 unsigned char *buf, const unsigned int len, unsigned int *flags, unsigned char *buf, const unsigned int len, unsigned int *flags,
216 172 unsigned long long *ts) unsigned long long *ts)
217 173 { {
174 int r;
218 175 char *dump = Conn_dump(buf, len); char *dump = Conn_dump(buf, len);
219 176 Log(20, "%s: dump: type=%u len=%u %s\n", __func__, type, len, dump); Log(20, "%s: dump: type=%u len=%u %s\n", __func__, type, len, dump);
220 177 free(dump); free(dump);
 
... ... int decode_core(struct Conn *C, const unsigned int type,
225 182 switch (type) { switch (type) {
226 183 case NINEDOGS_NET_CORE_ID: case NINEDOGS_NET_CORE_ID:
227 184 *flags = *flags | DECODE_FLAGS_NO_SAVE; *flags = *flags | DECODE_FLAGS_NO_SAVE;
228 return decode_core_id(C, buf, len);
185 return decode_core_id(C, buf, len, ts);
229 186 case NINEDOGS_NET_CORE_PROC: case NINEDOGS_NET_CORE_PROC:
230 187 return decode_core_proc(C, buf, len); return decode_core_proc(C, buf, len);
231 188 case NINEDOGS_NET_CORE_UNAME: case NINEDOGS_NET_CORE_UNAME:
232 189 return decode_core_uname(C, buf, len, ts); return decode_core_uname(C, buf, len, ts);
233 case NINEDOGS_NET_CORE_SYSINFO:
234 return decode_core_sysinfo(buf, len, ts);
190 case NINEDOGS_NET_CORE_SYSINFO: {
191 struct nd_sysinfo s;
192 r = nd_bin2struct_core_sysinfo(&s, buf, len);
193 if (r != -1)
194 *ts = s.ts;
195 return r; }
235 196 case NINEDOGS_NET_CORE_STOP: case NINEDOGS_NET_CORE_STOP:
236 197 return decode_core_stop(C, buf, len); return decode_core_stop(C, buf, len);
237 198 default: default:
File ingestd/decode_db.c changed (mode: 100644) (index a48bd29..249caeb)
... ... static int decode_query_stats(struct Conn *C, unsigned char *buf, const unsigned
88 88 // If we cannot find the query, we need to request it // If we cannot find the query, we need to request it
89 89 struct priv *p = Conn_get_private(C); struct priv *p = Conn_get_private(C);
90 90 char path[4096]; char path[4096];
91 snprintf(path, sizeof(path), "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/q/%c%c/%c%c/%s/q",
91 snprintf(path, sizeof(path),
92 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x"
93 "/q/%c%c/%c%c/%s/q",
92 94 p->id.client_id, p->id.client_id >> 8, p->id.client_id, p->id.client_id, p->id.client_id >> 8, p->id.client_id,
93 shash[0], shash[1], shash[2], shash[3], shash + 4);
95 shash[0], shash[1], shash[2], shash[3], shash);
94 96 int r2 = stat(path, &s); int r2 = stat(path, &s);
95 97 if ((r2 == -1) && (errno == ENOENT)) { if ((r2 == -1) && (errno == ENOENT)) {
96 98 unsigned char *b; unsigned char *b;
97 99 unsigned int blen; unsigned int blen;
98 Log(1, " Requesting query %s from client because [%s] not found (%m)...\n", shash, path);
100 Log(1, " Requesting query %s from client because [%s] not found (%m)...\n",
101 shash, path);
99 102 pack(&b, &blen, "T4 hb", pack(&b, &blen, "T4 hb",
100 103 NINEDOGS_NET_DB_QUERY_STRING, hash, sizeof(hash)); NINEDOGS_NET_DB_QUERY_STRING, hash, sizeof(hash));
101 104 if (b) { if (b) {
 
... ... static int decode_query_string(struct Conn *C,
117 120 unsigned int off = 0; unsigned int off = 0;
118 121 unsigned char hash[32]; unsigned char hash[32];
119 122 char shash[65], query[8192 + 1]; char shash[65], query[8192 + 1];
120 char path[4096];
121 123
122 124 while (off + 1 + 1 <= len) { while (off + 1 + 1 <= len) {
123 125 unsigned int r; unsigned int r;
 
... ... static int decode_query_string(struct Conn *C,
139 141 __func__, shash, query); __func__, shash, query);
140 142
141 143 // Store query // Store query
142 bin2hex(shash, hash, sizeof(hash));
143 144 struct priv *p = Conn_get_private(C); struct priv *p = Conn_get_private(C);
144 145 p->req_pending--; p->req_pending--;
145 snprintf(path, sizeof(path), "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/q/%c%c/%c%c/%s",
146 char dir[4096];
147 snprintf(dir, sizeof(dir),
148 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x"
149 "/q/%c%c/%c%c/%s",
146 150 p->id.client_id, p->id.client_id >> 8, p->id.client_id, p->id.client_id, p->id.client_id >> 8, p->id.client_id,
147 shash[0], shash[1], shash[2], shash[3], shash + 4);
148 int ret = mkdir_recursive(path, 0700);
151 shash[0], shash[1], shash[2], shash[3], shash);
152 int ret = save_dir_file(dir, shash, O_CREAT | O_WRONLY | O_TRUNC,
153 query, strlen(query));
149 154 if (ret == -1) { if (ret == -1) {
150 Log(1, " cannot create dir [%s]: %m!\n", path);
151 } else {
152 strcat(path, "/");
153 strcat(path, "q");
154 ret = save_file(path, query, strlen(query));
155 if (ret != 0)
156 Log(1, " cannot save query to [%s]: %m\n", path);
155 Log(1, " cannot save query to [%s/%s]: %m\n", dir, shash);
156 return -1;
157 157 } }
158 158
159 159 return 0; return 0;
File ingestd/decode_ssl.c changed (mode: 100644) (index 43a4922..6d84ece)
6 6 #include "ids.h" #include "ids.h"
7 7 #include "decode_ssl.h" #include "decode_ssl.h"
8 8 #include "tools.h" #include "tools.h"
9 #include "sctools.h"
9 #include "bin2struct.h"
10 10 #include "stools.h" #include "stools.h"
11 11 #include "priv.h" #include "priv.h"
12 12
 
... ... static int save_info(struct Conn *C,
23 23 while (off + 1 + 1 <= len) { while (off + 1 + 1 <= len) {
24 24 c = buf[off++]; c = buf[off++];
25 25 switch (c) { switch (c) {
26 case 'N': r = unpack(&ts, 't', sizeof(ts), buf, len, &off); break;
26 case '_': r = unpack(&ts, 't', sizeof(ts), buf, len, &off); break;
27 27 case 'v': r = unpack(info, 's', sizeof(info), buf, len, &off); break; case 'v': r = unpack(info, 's', sizeof(info), buf, len, &off); break;
28 28 default: r = 0xFFFFFFFE; break; default: r = 0xFFFFFFFE; break;
29 29 } }
 
... ... static int save_info(struct Conn *C,
39 39 Log(10, "%s: ts=%llu info=[%s]\n", __func__, ts, info); Log(10, "%s: ts=%llu info=[%s]\n", __func__, ts, info);
40 40
41 41 struct priv *p = Conn_get_private(C); struct priv *p = Conn_get_private(C);
42 char xpath[4096];
43 snprintf(xpath, sizeof(xpath), "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/ssl",
42 char dir[4096];
43 snprintf(dir, sizeof(dir),
44 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/ssl",
44 45 p->id.client_id, p->id.client_id >> 8, p->id.client_id); p->id.client_id, p->id.client_id >> 8, p->id.client_id);
45 mkdir_recursive(xpath, 0700);
46
47 strcat(xpath, "/ver");
48 int ret = save_file(xpath, buf, len);
46 int ret = save_dir_file(dir, "ver", O_CREAT | O_TRUNC | O_WRONLY, buf, len);
49 47 if (ret != 0) if (ret != 0)
50 Log(1, " cannot save ssl info to [%s]: %m\n", xpath);
48 Log(1, " cannot save ssl info to [%s/ver]: %m\n", dir);
51 49
52 50 return 0; return 0;
53 51 } }
 
... ... static int save_cert(struct Conn *C,
60 58
61 59 Log(10, "%s: len=%u\n", __func__, len); Log(10, "%s: len=%u\n", __func__, len);
62 60
63 r = decode_cert(&cert, buf, len);
61 r = nd_bin2struct_cert(&cert, buf, len);
64 62 if (r == -1) if (r == -1)
65 63 return -1; return -1;
66 64
 
... ... static int save_cert(struct Conn *C,
69 67 char cert_hash[65]; char cert_hash[65];
70 68 ninedogs_sha256_hex(cert_hash, to_hash, strlen(to_hash)); ninedogs_sha256_hex(cert_hash, to_hash, strlen(to_hash));
71 69 struct priv *p = Conn_get_private(C); struct priv *p = Conn_get_private(C);
72 char xpath[4096];
73 snprintf(xpath, sizeof(xpath),
70 char dir[4096];
71 snprintf(dir, sizeof(dir),
74 72 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/cert/%s", "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/cert/%s",
75 p->id.client_id, p->id.client_id >> 8, p->id.client_id, cert_hash + 44);
76 mkdir_recursive(xpath, 0700);
73 p->id.client_id, p->id.client_id >> 8, p->id.client_id,
74 cert_hash + 44);
77 75
78 76 // We need to signal what machines are using this cert // We need to signal what machines are using this cert
79 save_app(xpath, C, cert.ts);
77 save_app(dir, C, cert.ts);
80 78
81 strcat(xpath, "/data");
82 r = save_file(xpath, buf, len);
83 if (r != 0)
84 Log(1, " cannot save cert to [%s]: %m\n", xpath);
79 r = save_dir_file(dir, "/data", O_CREAT | O_WRONLY | O_TRUNC, buf, len);
80 if (r != 0) {
81 Log(1, " cannot save cert to [%s/data]: %m\n", dir);
82 return -1;
83 }
85 84
86 85 return 0; return 0;
87 86 } }
File ingestd/ninedogs-ingestd.service changed (mode: 100644) (index 6e80962..6ac6cab)
1 1 [Unit] [Unit]
2 Description=Ninedogs ingestion daemon
2 Description = Ninedogs ingestion daemon
3 3
4 4 [Service] [Service]
5 Type=exec
6 ExecStart=/date/sync/no-crypt/sync1/Dev/ninedogs/ingestd/ninedogs-ingestd
7 PrivateTmp=true
8 Restart=on-failure
9 RestartSec=10
10 ProtectSystem=full
11 NoNewPrivileges=yes
5 Type = exec
6 ExecStart = /date/sync/no-crypt/sync1/Dev/ninedogs/ingestd/ninedogs-ingestd
7 PrivateTmp = true
8 Restart = on-failure
9 RestartSec = 10
10 ProtectSystem = full
11 NoNewPrivileges = yes
12 User = ninedogs
13 Group = ninedogs
12 14
13 15 [Install] [Install]
14 WantedBy=multi-user.target
16 WantedBy = multi-user.target
File ingestd/priv.h changed (mode: 100644) (index 9892f29..f84cfca)
... ... struct priv {
15 15 int dsttime; int dsttime;
16 16 } id; } id;
17 17
18 struct utsname uname;
19 unsigned char pad3[2];
18 struct utsname uname;
19 unsigned char pad3[2];
20 20
21 unsigned int sent_ws:1;
22 unsigned int stop_received:1;
23 unsigned int pad4:30;
24 int fd;
25 unsigned int fd_ts;
26 unsigned int req_pending; // how many answers we wait from client
21 unsigned int sent_ws:1;
22 unsigned int stop_received:1;
23 unsigned int first_saved:1;
24 unsigned int pad4:29;
25
26 int fd;
27 unsigned int fd_ts;
28 unsigned int req_pending; // how many answers we wait from client
29 unsigned long long last_seen_day;
27 30 }; };
File ingestd/stools.c changed (mode: 100644) (index 89f837f..10c809b)
... ... int save_data_check(struct Conn *C, const unsigned char *buf, const unsigned int
55 55
56 56 // We do not want to overwrite an existing file // We do not want to overwrite an existing file
57 57 do { do {
58 snprintf(path, sizeof(path), "/var/lib/ninedogs/check/%llu-%u-%s-%08x",
58 snprintf(path, sizeof(path),
59 "/var/lib/ninedogs/check/%llu-%u-%s-%08x",
59 60 ts, p->id.client_id, p->id.id, rand()); ts, p->id.client_id, p->id.id, rand());
60 61 Log(10, " saving to %s\n", path); Log(10, " saving to %s\n", path);
61 62 fd = open(path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0600); fd = open(path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0600);
 
... ... int save_data(struct Conn *C, const unsigned char *buf, const unsigned int len,
97 98 char path[4096], sts[16]; char path[4096], sts[16];
98 99
99 100 snprintf(path, sizeof(path), snprintf(path, sizeof(path),
100 "/var/lib/ninedogs/%02hhx/%02hhx/%08x/data/%c%c/%c%c/%s/t",
101 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x"
102 "/data/%c%c/%c%c/%s/t",
101 103 p->id.client_id, p->id.client_id >> 8, p->id.client_id, p->id.client_id, p->id.client_id >> 8, p->id.client_id,
102 p->id.id[0], p->id.id[1], p->id.id[2], p->id.id[3], p->id.id + 4);
104 p->id.id[0], p->id.id[1], p->id.id[2], p->id.id[3],
105 p->id.id);
103 106 mkdir_recursive(path, 0700); mkdir_recursive(path, 0700);
104 107 strcat(path, "/"); strcat(path, "/");
105 108 snprintf(sts, sizeof(sts), "%llu", hour); snprintf(sts, sizeof(sts), "%llu", hour);
 
... ... int save_data(struct Conn *C, const unsigned char *buf, const unsigned int len,
121 124 return 0; return 0;
122 125 } }
123 126
127 /*
128 * Save details about when a machine appeared and when was the last time seen
129 */
130 int save_machine_visibility(struct Conn *C, const unsigned long long ts)
131 {
132 struct priv *p = Conn_get_private(C);
133 struct stat s;
134 unsigned short off;
135 int r;
136
137 if ((p->id.client_id == 0) || (ts == 0))
138 return 0;
139
140 Log(10, "%s: client_id=%u ts=%llu\n",
141 __func__, p->id.client_id, ts);
142
143 char dir[4096];
144 snprintf(dir, sizeof(dir),
145 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x"
146 "/data/%c%c/%c%c/%s",
147 p->id.client_id, p->id.client_id >> 8, p->id.client_id,
148 p->id.id[0], p->id.id[1], p->id.id[2], p->id.id[3], p->id.id);
149
150 unsigned char out[64];
151 unsigned long long u64 = htobe64(ts);
152 off = 0;
153 memcpy(out + off, &u64, 8); off += 8;
154
155 r = nd_stat_dir_file(&s, dir, "first_seen");
156 if ((p->first_saved == 0) && (r == -1)) {
157 Log(10, " saving first_seen to %s/first [%llu]\n", dir, ts);
158 r = save_dir_file(dir, "first_seen", O_CREAT | O_WRONLY | O_TRUNC, out, off);
159 if (r == -1)
160 return -1;
161 p->first_saved = 1;
162 }
163
164 unsigned long long day = get_day(ts / 1000);
165 if (p->last_seen_day != day) {
166 Log(10, " saving last_seen %s/last_seen [%llu]\n", dir, ts);
167 int r = save_dir_file(dir, "last_seen", O_CREAT | O_WRONLY | O_TRUNC, out, off);
168 if (r == -1)
169 return -1;
170 p->last_seen_day = day;
171 }
172
173 return 0;
174 }
175
124 176 int save_app(const char *dst, struct Conn *C, const unsigned long long ts) int save_app(const char *dst, struct Conn *C, const unsigned long long ts)
125 177 { {
126 178 struct priv *p = Conn_get_private(C); struct priv *p = Conn_get_private(C);
 
... ... int save_app(const char *dst, struct Conn *C, const unsigned long long ts)
128 180 Log(10, "%s: dst=[%s] client_id=%u ts=%llu\n", Log(10, "%s: dst=[%s] client_id=%u ts=%llu\n",
129 181 __func__, dst, p->id.client_id, ts); __func__, dst, p->id.client_id, ts);
130 182
131 char path[4096];
132 snprintf(path, sizeof(path), "%s/users/%c%c/%s",
133 dst, p->id.id[0], p->id.id[1], p->id.id + 2);
134 mkdir_recursive(path, 0700);
183 char dir[4096];
184 snprintf(dir, sizeof(dir), "%s/users/%c%c/%s",
185 dst, p->id.id[0], p->id.id[1], p->id.id);
186 mkdir_recursive(dir, 0700);
135 187
136 188 unsigned char hash[32]; unsigned char hash[32];
137 189 ninedogs_sha256(hash, p->id.cmdline, p->id.cmdline_len); ninedogs_sha256(hash, p->id.cmdline, p->id.cmdline_len);
138 190 char shash[9]; char shash[9];
139 191 sprintf(shash, "%08x", *(unsigned int *) hash); sprintf(shash, "%08x", *(unsigned int *) hash);
140 192
141 strcat(path, "/");
142 strcat(path, shash);
193 Log(10, " saving to %s/%s\n", dir, shash);
194 unsigned char out[4096];
195 unsigned short off = 0;
196 unsigned long long u64 = htobe64(ts);
197 unsigned short b = htobe16(p->id.cmdline_len);
143 198
144 Log(10, " saving to %s\n", path);
145 int fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0600);
146 if (fd == -1) {
147 Log(1, " Cannot open [%s]: %m\n", path);
148 return -1;
149 }
199 memcpy(out + off, &u64, 8); off += 8;
200 memcpy(out + off, &b, 2); off += 2;
201 memcpy(out + off, p->id.cmdline, p->id.cmdline_len); off += p->id.cmdline_len;
150 202
151 int r;
152 unsigned long long u64 = htobe64(ts);
153 r = save_buf(fd, &u64, 8);
154 if (r != -1) {
155 unsigned short b = htobe16(p->id.cmdline_len);
156 r = save_buf(fd, &b, sizeof(b));
157 }
158 if (r != -1)
159 r = save_buf(fd, p->id.cmdline, p->id.cmdline_len);
160 close(fd);
161 if (r == -1) {
162 unlink(path);
203 int r = save_dir_file(dir, shash, O_CREAT | O_WRONLY | O_TRUNC,
204 out, off);
205 if (r == -1)
163 206 return -1; return -1;
164 }
165 207
166 208 return 0; return 0;
167 209 } }
File ingestd/stools.h changed (mode: 100644) (index c5786ab..969ee38)
... ... int save_data_check(struct Conn *C, const unsigned char *buf,
13 13 int save_data(struct Conn *C, const unsigned char *buf, int save_data(struct Conn *C, const unsigned char *buf,
14 14 const unsigned int len, const unsigned long long ts); const unsigned int len, const unsigned long long ts);
15 15
16 int save_app(const char *dst, struct Conn *C,
17 const unsigned long long ts);
16 int save_machine_visibility(struct Conn *C, const unsigned long long ts);
17
18 int save_app(const char *dst, struct Conn *C, const unsigned long long ts);
18 19
File misc/Makefile changed (mode: 100644) (index f9044f9..2b09e6c)
1 # This is just to allow us to run make here
2 .PHONY: all
3 all:
4 make -R -C .. misc
1 include ../Makefile.common
5 2
6 3 COMMON_H += ../common/shared.h ../common/tools.h ../common/info.h \ COMMON_H += ../common/shared.h ../common/tools.h ../common/info.h \
7 4 ../common/decode_text.h ../common/decode_text.h
 
... ... CFLAGS += -I../common
10 7
11 8 OBJS := ../common/tools.o ../common/info.o ../common/decode_text.o OBJS := ../common/tools.o ../common/info.o ../common/decode_text.o
12 9
10 all: nd-info
11
12 #TODO: Are we using -fPIC for all *.o?
13 13 #decode.o: decode.c decode.h process_db.h $(COMMON_H) #decode.o: decode.c decode.h process_db.h $(COMMON_H)
14 14 # $(CC) $(CFLAGS) -fPIC -c -o $@ $< # $(CC) $(CFLAGS) -fPIC -c -o $@ $<
15 15
16 16 nd-info: nd-info.c $(COMMON_H) $(OBJS) nd-info: nd-info.c $(COMMON_H) $(OBJS)
17 17 $(CC) $(CFLAGS) $@.c -o $@ $(OBJS) $(LIBS) $(CC) $(CFLAGS) $@.c -o $@ $(OBJS) $(LIBS)
18 18
19 compile: nd-info
20
21 19 .PHONY: clean .PHONY: clean
22 20 clean: clean:
23 21 @rm -f nd-info *.sinfo *.log *.out *.o @rm -f nd-info *.sinfo *.log *.out *.o
File ninedogs.spec changed (mode: 100644) (index e73c08e..cc545ab)
... ... Provides: ninedogs
14 14 Conflicts: ninedogs Conflicts: ninedogs
15 15
16 16 Requires: json-c, gnutls, libcap, catalinux+Conn, nginx-filesystem Requires: json-c, gnutls, libcap, catalinux+Conn, nginx-filesystem
17 Requires: libcurl
17 18
18 BuildRequires: systemd-rpm-macros, json-c-devel, gnutls-devel, libcap-devel, catalinux+Conn
19 BuildRequires: systemd-rpm-macros, json-c-devel, gnutls-devel, libcap-devel
20 BuildRequires: libcurl-devel, catalinux+Conn
19 21 # To generate the pdfs: # To generate the pdfs:
20 BuildRequires: texlive-latex, texlive-beamer, texlive-adjustbox, texlive-babel-english
21 BuildRequires: texlive-hyperref, texlive-url
22 BuildRequires: texlive-latex, texlive-beamer, texlive-adjustbox
23 BuildRequires: texlive-babel-english, texlive-hyperref, texlive-url
24 # For tests - TODO - postgres
25 BuildRequires: mysql-connector-java
22 26
23 27 %description %description
24 28 Light and fast APM Light and fast APM
 
... ... Light and fast APM
26 30 %post %post
27 31 %systemd_post ninedogs-ingestd.service %systemd_post ninedogs-ingestd.service
28 32 %systemd_post ninedogs-webd.service %systemd_post ninedogs-webd.service
33 %systemd_post ninedogs-cert-notify.timer
34
35 %pre
36 getent group ninedogs >/dev/null || groupadd -r ninedogs
37 getent passwd ninedogs >/dev/null || useradd -r -g ninedogs -s /bin/bash -m -d /home/ninedogs -c "ninedogs user" ninedogs
29 38
30 39 %preun %preun
31 40 %systemd_preun ninedogs-ingestd.service %systemd_preun ninedogs-ingestd.service
File test/c/oracle/.gitignore copied from file test/info/.gitignore (similarity 100%)
File test/c/oracle/Dockerfile added (mode: 100644) (index 0000000..0401a3d)
1 FROM oraclelinux:8
2
3 # TODO: catalinux+ninedogs
4
5 RUN echo "1"
6 RUN dnf -y --setopt=nodocs install oracle-release-el8 oracle-instantclient-release-el8 \
7 oracle-epel-release-el8 oraclelinux-release-el8 \
8 oraclelinux-developer-release-el8 \
9 gcc make \
10 https://rocketgit.com/op/pkgrepo/main/global/testing/rocky/8/x86_64/os/rocketgit-global-testing-1.1-1.noarch.rpm \
11 \
12 && dnf -y install oracle-instantclient-devel
13
14 RUN dnf -y update
15 RUN dnf -y install gnutls-devel json-c-devel libcap-devel catalinux+Conn \
16 texlive-latex texlive-beamer texlive-adjustbox texlive-babel-english \
17 texlive-hyperref texlive-url
18
19 RUN dnf -y install strace gdb gcc-c++ less cscope
20
21 RUN mkdir /nd
22 COPY copy/ /nd/
23 RUN cd /nd && ./configure && make common && make agent && make -R -C agent install && make trace && make -R -C trace install
File test/c/oracle/build.sh added (mode: 100755) (index 0000000..41185a9)
1 #!/bin/bash
2
3 set -u
4 set -e
5
6 mkdir -p copy
7 rsync -a ../../../ --exclude 'test/' \
8 --include 'configure' --include '*.c' --include '*.h' --include 'duilder' --include 'Makefile*' \
9 --exclude '*.*' \
10 copy
11
12 docker="podman"
13
14 ${docker} build \
15 --tag="ninedogs-c-oracle:latest" \
16 .
17
18 #rm -rf copy
File test/c/oracle/demo.c added (mode: 100644) (index 0000000..f4b01c5)
1 #include <time.h>
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <oci.h>
7 #include <unistd.h>
8
9 /* Define SQL statements to be used in program. */
10 static OCIEnv *envhp = NULL;
11 static OCIError *errhp = NULL;
12
13 static void checkerr(/*_ OCIError *errhp, sword status _*/);
14 static void free_handles(/*svchp, srvhp, authp, stmthp, stmthp1, stmthp2*/);
15 static void logout_detach_server(/*svchp, srvhp, authp*/);
16 static sword finish_demo(/*svchp, srvhp, authp, stmthp, stmthp1, stmthp2 */);
17 static sword status;
18 static boolean logged_on = FALSE;
19
20 int main(int argc, char *argv[])
21 {
22 sword empno, sal, deptno;
23 sword len, len2, rv, dsize, dsize2;
24 sb4 deptlen = 14;
25 sb2 sal_ind, job_ind;
26 sb2 db_type, db2_type;
27 sb1 name_buf[20], name2_buf[20];
28 text *cp, *dept;
29
30 sb2 ind[2]; /* indicator */
31 ub2 alen[2]; /* actual length */
32 ub2 rlen[2]; /* return length */
33
34 OCIDescribe *dschndl1 = (OCIDescribe *) 0,
35 *dschndl2 = (OCIDescribe *) 0,
36 *dschndl3 = (OCIDescribe *) 0;
37
38 OCISession *authp = (OCISession *) 0;
39 OCIServer *srvhp = NULL;
40 OCISvcCtx *svchp = NULL;
41 OCIStmt *inserthp = NULL,
42 *stmthp = NULL,
43 *stmthp1 = NULL;
44 OCIDefine *defnp = (OCIDefine *) 0;
45
46 OCIBind *bnd1p = (OCIBind *) 0; /* the first bind handle */
47 OCIBind *bnd2p = (OCIBind *) 0; /* the second bind handle */
48 OCIBind *bnd3p = (OCIBind *) 0; /* the third bind handle */
49 OCIBind *bnd4p = (OCIBind *) 0; /* the fourth bind handle */
50 OCIBind *bnd5p = (OCIBind *) 0; /* the fifth bind handle */
51 OCIBind *bnd6p = (OCIBind *) 0; /* the sixth bind handle */
52
53 sword errcode = 0;
54
55 sleep(1); // allow ninedogs to attach
56
57 errcode = OCIEnvCreate((OCIEnv **) &envhp, (ub4) OCI_DEFAULT,
58 (dvoid *) 0, (dvoid * (*)(dvoid *,size_t)) 0,
59 (dvoid * (*)(dvoid *, dvoid *, size_t)) 0,
60 (void (*)(dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **) 0);
61 if (errcode != 0) {
62 printf("OCIEnvCreate failed with errcode = %d.\n", errcode);
63 exit(1);
64 }
65
66 (void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR,
67 (size_t) 0, (dvoid **) 0);
68
69 /* server contexts */
70 (void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER,
71 (size_t) 0, (dvoid **) 0);
72
73 (void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX,
74 (size_t) 0, (dvoid **) 0);
75
76 checkerr(errhp, OCIServerAttach(srvhp, errhp, (const OraText *) "r1i:61521/XE", 12, 0));
77
78 /* set attribute server context in the service context */
79 (void) OCIAttrSet( (dvoid *) svchp, OCI_HTYPE_SVCCTX, (dvoid *)srvhp,
80 (ub4) 0, OCI_ATTR_SERVER, (OCIError *) errhp);
81
82 (void) OCIHandleAlloc((dvoid *) envhp, (dvoid **)&authp,
83 (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0);
84
85 (void) OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,
86 "system", 6, (ub4) OCI_ATTR_USERNAME, errhp);
87
88 (void) OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,
89 "pass", 4, (ub4) OCI_ATTR_PASSWORD, errhp);
90
91 checkerr(errhp, OCISessionBegin ( svchp, errhp, authp, OCI_CRED_RDBMS,
92 (ub4) OCI_DEFAULT));
93
94 (void) OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX,
95 (dvoid *) authp, (ub4) 0,
96 (ub4) OCI_ATTR_SESSION, errhp);
97
98 logged_on = TRUE;
99
100
101 checkerr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmthp,
102 OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));
103
104
105 // Create the table
106 char *sql = "CREATE TABLE demo (a int, b varchar(30))";
107 OCIStmtPrepare(stmthp, errhp, (const OraText *) sql, strlen(sql),
108 (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);
109 OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1 /*iters*/, (ub4) 0 /*rowoff*/,
110 (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT);
111
112
113 // Delete everything from 'demo' table
114 OCIStmt *del1 = NULL;
115 checkerr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &del1, OCI_HTYPE_STMT, 0, NULL));
116 sql = "DELETE FROM demo";
117 checkerr(errhp, OCIStmtPrepare(del1, errhp, (const OraText *) sql,
118 (ub4) strlen(sql), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
119 if ((status = OCIStmtExecute(svchp, del1, errhp, (ub4) 1 /*iters*/, (ub4) 0 /*rowoff*/,
120 (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT))
121 && (status != 1)) {
122 checkerr(errhp, status);
123 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
124 return OCI_ERROR;
125 }
126
127
128 // insert
129 int a = 1, c = 0xcc;
130 char b[128];
131 checkerr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &inserthp,
132 OCI_HTYPE_STMT, 0, NULL));
133 sql = "INSERT INTO demo(a, b) VALUES (:a + 1, :b) RETURNING a INTO :c";
134 checkerr(errhp, OCIStmtPrepare(inserthp, errhp, (const OraText *) sql,
135 (ub4) strlen(sql), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
136 /* Bind the placeholders in the INSERT statement. */
137 snprintf(b, sizeof(b), "b=%ld", time(NULL));
138 printf("&a=%p &b=%p &c=%p\n", &a, &b, &c);
139 if (
140 (status = OCIBindByName(inserthp, &bnd1p, errhp, (text *) ":a",
141 -1, (dvoid *) &a, sizeof(a), SQLT_INT, (dvoid *) 0,
142 (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT)) ||
143 (status = OCIBindByName(inserthp, &bnd2p, errhp, (text *) ":b",
144 -1, (dvoid *) b, strlen(b) + 1, SQLT_STR, (dvoid *) 0,
145 (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT)) ||
146 (status = OCIBindByName(inserthp, &bnd3p, errhp, (text *) ":c",
147 -1, (dvoid *) &c, sizeof(c), SQLT_INT, (dvoid *) 0,
148 (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))
149 ) {
150 checkerr(errhp, status);
151 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
152 return OCI_ERROR;
153 }
154 if ((status = OCIStmtExecute(svchp, inserthp, errhp, (ub4) 1 /*iters*/, (ub4) 0 /*rowoff*/,
155 (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT))
156 && (status != 1)) {
157 checkerr(errhp, status);
158 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
159 return OCI_ERROR;
160 }
161
162
163 OCIStmt *sel1 = NULL;
164 char s1[256], n1[16], o1[2];
165 sb2 ind1d, ind1s1, ind1n1, ind1o1, ind1e, ind1num;
166 ub2 rlen1d, rcode1d;
167 ub2 rlen1s1, rcode1s1;
168 ub2 rlen1n1, rcode1n1;
169 ub2 rlen1o1, rcode1o1;
170 ub2 rlen1e, rcode1e;
171 ub2 rlen1num, rcode1num;
172 int d;
173 char e[32];
174 unsigned char num[21]; // this is an internal representation: https://docs.oracle.com/cd/A58617_01/server.804/a58234/datatype.htm
175 OCIDefine *para_d = NULL, *para_s1 = NULL, *para_n1 = NULL, *para_o1 = NULL, *para_e = NULL, *para_num = NULL;
176 checkerr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &sel1,
177 OCI_HTYPE_STMT, 0, NULL));
178 sql = "SELECT demo.a, demo.b, NULL AS bla, demo.b AS overflow1, demo.a AS long1, demo.a AS num1 FROM demo";
179 checkerr(errhp, OCIStmtPrepare(sel1, errhp, (const OraText *) sql,
180 (ub4) strlen(sql), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
181 if ((status = OCIDefineByPos(sel1, &para_d, errhp, 1 /*pos*/,
182 (dvoid *) &d, (sword) sizeof(d), SQLT_INT,
183 (dvoid *) &ind1d, &rlen1d, &rcode1d, OCI_DEFAULT /*mode*/))) {
184 checkerr(errhp, status);
185 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
186 return OCI_ERROR;
187 }
188 if ((status = OCIDefineByPos(sel1, &para_s1, errhp, 2 /*pos*/,
189 (dvoid *) &s1, (sword) sizeof(s1), SQLT_STR,
190 (dvoid *) &ind1s1, (ub2 *) &rlen1s1, &rcode1s1,
191 OCI_DEFAULT /*mode*/))) {
192 checkerr(errhp, status);
193 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
194 return OCI_ERROR;
195 }
196 if ((status = OCIDefineByPos(sel1, &para_n1, errhp, 3 /*pos*/,
197 (dvoid *) &n1, (sword) sizeof(n1), SQLT_STR,
198 (dvoid *) &ind1n1, (ub2 *) &rlen1n1, &rcode1n1,
199 OCI_DEFAULT /*mode*/))) {
200 checkerr(errhp, status);
201 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
202 return OCI_ERROR;
203 }
204 if ((status = OCIDefineByPos(sel1, &para_o1, errhp, 4 /*pos*/,
205 (dvoid *) &o1, (sword) sizeof(o1), SQLT_STR,
206 (dvoid *) &ind1o1, (ub2 *) &rlen1o1, &rcode1o1,
207 OCI_DEFAULT /*mode*/))) {
208 checkerr(errhp, status);
209 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
210 return OCI_ERROR;
211 }
212 if ((status = OCIDefineByPos(sel1, &para_e, errhp, 5 /*pos*/,
213 (dvoid *) &e, (sword) sizeof(e), SQLT_LNG,
214 (dvoid *) &ind1e, (ub2 *) &rlen1e, &rcode1e,
215 OCI_DEFAULT /*mode*/))) {
216 checkerr(errhp, status);
217 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
218 return OCI_ERROR;
219 }
220 if ((status = OCIDefineByPos(sel1, &para_num, errhp, 6 /*pos*/,
221 (dvoid *) &num, (sword) sizeof(num), SQLT_NUM,
222 (dvoid *) &ind1num, (ub2 *) &rlen1num, &rcode1num,
223 OCI_DEFAULT /*mode*/))) {
224 checkerr(errhp, status);
225 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
226 return OCI_ERROR;
227 }
228 if ((status = OCIStmtExecute(svchp, sel1, errhp, (ub4) 1 /*iters*/, (ub4) 0 /*rowoff*/,
229 (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT))
230 && (status != 1)) {
231 checkerr(errhp, status);
232 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
233 return OCI_ERROR;
234 }
235 printf("d: ind1=%hd rlen1=%hu rcode1=%hu\n", ind1d, rlen1d, rcode1d);
236 printf("s1: ind1=%hd rlen1=%hu rcode1=%hu\n", ind1s1, rlen1s1, rcode1s1);
237 printf("n1: ind1=%hd rlen1=%hu rcode1=%hu\n", ind1n1, rlen1n1, rcode1n1);
238 printf("o1: ind1=%hd rlen1=%hu rcode1=%hu\n", ind1o1, rlen1o1, rcode1o1);
239 printf("e: ind1=%hd rlen1=%hu rcode1=%hu\n", ind1e, rlen1e, rcode1e);
240 printf("num: ind1=%hd rlen1=%hu rcode1=%hu\n", ind1num, rlen1num, rcode1num);
241 printf("d=%d s1=[%s] o1=[%s] e=[%s] num=[%s]\n", d, s1, o1, e, num);
242
243 /* Commit the change. */
244 if (status = OCITransCommit(svchp, errhp, OCI_TRANS_WRITEIMMED)) {
245 checkerr(errhp, status);
246 finish_demo(svchp, srvhp, authp,stmthp, stmthp1,inserthp);
247 return OCI_ERROR;
248 }
249
250 OCITransRollback(svchp, errhp, OCI_DEFAULT);
251 }
252
253
254 void checkerr(OCIError *errhp, sword status)
255 {
256 text errbuf[512];
257 sb4 errcode = 0;
258
259 switch (status)
260 {
261 case OCI_SUCCESS:
262 break;
263 case OCI_SUCCESS_WITH_INFO:
264 (void) printf("Error - OCI_SUCCESS_WITH_INFO\n");
265 break;
266 case OCI_NEED_DATA:
267 (void) printf("Error - OCI_NEED_DATA\n");
268 break;
269 case OCI_NO_DATA:
270 (void) printf("Error - OCI_NODATA\n");
271 break;
272 case OCI_ERROR:
273 (void) OCIErrorGet((dvoid *)errhp, (ub4) 1, (text *) NULL, &errcode,
274 errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
275 (void) printf("Error - %.*s\n", 512, errbuf);
276 break;
277 case OCI_INVALID_HANDLE:
278 (void) printf("Error - OCI_INVALID_HANDLE\n");
279 break;
280 case OCI_STILL_EXECUTING:
281 (void) printf("Error - OCI_STILL_EXECUTE\n");
282 break;
283 case OCI_CONTINUE:
284 (void) printf("Error - OCI_CONTINUE\n");
285 break;
286 default:
287 break;
288 }
289 }
290
291 /* ----------------------------------------------------------------- */
292 /* Free the specified handles */
293 /* ----------------------------------------------------------------- */
294 void free_handles(svchp, srvhp, authp, stmthp, stmthp1, stmthp2)
295 OCISvcCtx *svchp;
296 OCIServer *srvhp;
297 OCISession *authp;
298 OCIStmt *stmthp;
299 OCIStmt *stmthp1;
300 OCIStmt *stmthp2;
301 {
302 if (srvhp)
303 (void) OCIHandleFree((dvoid *) srvhp, (ub4) OCI_HTYPE_SERVER);
304 if (svchp)
305 (void) OCIHandleFree((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX);
306 if (errhp)
307 (void) OCIHandleFree((dvoid *) errhp, (ub4) OCI_HTYPE_ERROR);
308 if (authp)
309 (void) OCIHandleFree((dvoid *) authp, (ub4) OCI_HTYPE_SESSION);
310 if (stmthp)
311 (void) OCIHandleFree((dvoid *) stmthp, (ub4) OCI_HTYPE_STMT);
312 if (stmthp1)
313 (void) OCIHandleFree((dvoid *) stmthp1, (ub4) OCI_HTYPE_STMT);
314 if (stmthp2)
315 (void) OCIHandleFree((dvoid *) stmthp2, (ub4) OCI_HTYPE_STMT);
316
317 if (envhp)
318 (void) OCIHandleFree((dvoid *) envhp, (ub4) OCI_HTYPE_ENV);
319
320 return;
321 }
322
323 /*-------------------------------------------------------------------*/
324 /* Logout and detach from the server */
325 /*-------------------------------------------------------------------*/
326 void logout_detach_server(svchp, srvhp, authp)
327 OCISvcCtx *svchp;
328 OCIServer *srvhp;
329 OCISession *authp;
330 {
331 if ((status = OCISessionEnd(svchp, errhp, authp, (ub4) 0)))
332 {
333 printf("FAILED: OCISessionEnd()\n");
334 checkerr(errhp, status);
335 }
336
337 if ((status = OCIServerDetach(srvhp, errhp, (ub4) OCI_DEFAULT)))
338 {
339 printf("FAILED: OCIServerDetach()\n");
340 checkerr(errhp, status);
341 }
342
343 return;
344 }
345
346 /*---------------------------------------------------------------------*/
347 /* Finish demo and clean up */
348 /*---------------------------------------------------------------------*/
349 sword finish_demo(svchp, srvhp, authp, stmthp, stmthp1, stmthp2)
350 OCISvcCtx *svchp;
351 OCIServer *srvhp;
352 OCISession *authp;
353 OCIStmt *stmthp;
354 OCIStmt *stmthp1;
355 OCIStmt *stmthp2;
356 {
357
358 if (logged_on)
359 logout_detach_server(svchp, srvhp, authp);
360
361 free_handles(svchp, srvhp, authp, stmthp, stmthp1, stmthp2);
362
363 OCITerminate(OCI_DEFAULT);
364
365 return OCI_SUCCESS;
366 }
367
368 /* end of file cdemo81.c */
369
File test/c/oracle/exec-dev-1.sh added (mode: 100755) (index 0000000..64de4e6)
1 podman run -ti \
2 -v ${PWD}/1:/1 \
3 -v ${PWD}/demo.c:/usr/share/oracle/21/client64/demo/demo.c \
4 --rm \
5 --namespace nd-test \
6 ninedogs-c-oracle:latest \
7 /1 2>&1 | tee exec-dev-1.out
8
9
File test/c/oracle/exec-dev-bash.sh added (mode: 100755) (index 0000000..c77947b)
1 # -v ${PWD}/1.php:/1.php \
2
3 podman run -ti \
4 -v ${PWD}/1:/1 \
5 --rm \
6 --namespace nd-test \
7 ninedogs-c-oracle:latest \
8 bash
9
10
File test/curl/1.c changed (mode: 100644) (index fd48740..5abb80c)
... ... int main(void)
15 15
16 16 struct curl_slist *list = NULL; struct curl_slist *list = NULL;
17 17 list = curl_slist_append(list, "Content-Type: application/json"); list = curl_slist_append(list, "Content-Type: application/json");
18 list = curl_slist_append(list, "X-ninedogs-bla: 1🐱");
18 list = curl_slist_append(list, "X-ninedogs-bla: 1🐱end");
19 19
20 20
21 21 CURL *curl = curl_easy_init(); CURL *curl = curl_easy_init();
22 usleep(1000 * 1000);
22 23 curl_easy_setopt(curl, CURLOPT_URL, "https://localhost"); curl_easy_setopt(curl, CURLOPT_URL, "https://localhost");
24 usleep(500 * 1000);
23 25 curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POST, 1);
24 26 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
27 usleep(500 * 1000);
25 28 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body_len); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body_len);
29 usleep(200 * 1000);
26 30 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
27 31 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
32 curl_easy_setopt(curl, 0xffffff01, 1); // invalid option
28 33 CURLcode res = curl_easy_perform(curl); CURLcode res = curl_easy_perform(curl);
29 34
35 usleep(2000 * 1000);
30 36 curl_slist_free_all(list); curl_slist_free_all(list);
31 37
32 38 curl_easy_cleanup(curl); curl_easy_cleanup(curl);
File test/curl/1.run changed (mode: 100755) (index 2a51e0d..87e17d8)
... ... export NINEDOGS_VERBOSE=200
12 12 #export LD_DEBUG_OUTPUT=1.ld.txt #export LD_DEBUG_OUTPUT=1.ld.txt
13 13
14 14 ./1 &>1.out & ./1 &>1.out &
15 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
15 #LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace --only-high-level -o 1.nd -p ${!}
16 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace --only-high-level -p ${!}
17 #LD_PRELOAD= LD_DEBUG= gdb ../../trace/nd-trace
16 18
File test/curl/3.php changed (mode: 100644) (index 83df484..00bc6bc)
... ... if (curl_error($c))
17 17
18 18 curl_close($c); curl_close($c);
19 19
20 fclose($fp);
21
File test/curl/3.run changed (mode: 100755) (index 5672b31..ce59fb5)
... ... export NINEDOGS_VERBOSE=201
10 10 #export LD_DEBUG_OUTPUT=1.ld.txt #export LD_DEBUG_OUTPUT=1.ld.txt
11 11
12 12 php 3.php &>3.out & php 3.php &>3.out &
13 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 3.nd -p ${!}
13 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace --only-high-level -o 3.nd -p ${!}
14 14
File test/go/.gitignore copied from file test/info/.gitignore (similarity 100%)
File test/go/1.go added (mode: 100644) (index 0000000..b9c65fe)
1 package main
2
3 import (
4 "crypto/sha256"
5 "fmt"
6 "time"
7 )
8
9 func main() {
10 time.Sleep(2 * time.Second);
11
12 s := "sha256 this string"
13
14 h := sha256.New()
15
16 h.Write([]byte(s))
17
18 bs := h.Sum(nil)
19
20 fmt.Println(s)
21 fmt.Printf("%x\n", bs)
22 }
23
File test/go/1.run copied from file test/curl/1.run (similarity 91%) (mode: 100755) (index 2a51e0d..6eb618c)
2 2
3 3 set -e set -e
4 4
5 gcc 1.c -o 1 -l curl
5 go build 1.go
6 6
7 7 export LD_PRELOAD=../../agent/ninedogs.so export LD_PRELOAD=../../agent/ninedogs.so
8 8
File test/go/TODO added (mode: 100644) (index 0000000..5b81e81)
1 [ ] Find a way to do the tracing. Right now, go programs are
2 statically linked. :(
3 [ ]
File test/info/.gitignore changed (mode: 100644) (index d00491f..f122112)
1 1 1 1
2 *.info
File test/info/1.c changed (mode: 100644) (index 36757bd..777fd91)
7 7 #include <arpa/inet.h> #include <arpa/inet.h>
8 8 #include <fcntl.h> #include <fcntl.h>
9 9 #include <stdio.h> #include <stdio.h>
10 #include <stdlib.h>
10 11 #include <string.h> #include <string.h>
11 12 #include <unistd.h> #include <unistd.h>
12 13
 
... ... int main(void)
92 93
93 94
94 95 // memfd // memfd
95 int mfd = memfd_create("bla", MFD_HUGETLB);
96 int mfd = memfd_create("bla", MFD_CLOEXEC | MFD_ALLOW_SEALING);
97 if (mfd == -1)
98 printf("cannot create memfd: %m\n");
99 r = ftruncate(mfd, 200);
100 if (r == -1)
101 printf("cannot truncate memfd: %m\n");
96 102 write(mfd, "3456", 4); write(mfd, "3456", 4);
97 103
98 104
 
... ... int main(void)
100 106 int tfd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK); int tfd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK);
101 107 printf("tfd = %d: %m\n", tfd); printf("tfd = %d: %m\n", tfd);
102 108
103
109 system("ls -l /proc/self/fd");
104 110 sleep(2); sleep(2);
105 111
106 112 return 0; return 0;
File test/info/1.run changed (mode: 100755) (index dbe9497..10b7304)
... ... export NINEDOGS_VERBOSE=200
13 13
14 14 ./1 &>1.out & ./1 &>1.out &
15 15 LD_PRELOAD= LD_DEBUG= sleep 1 LD_PRELOAD= LD_DEBUG= sleep 1
16 LD_PRELOAD= LD_DEBUG= strace -s2000 -tt -q -o 1.nd_info.strace ../../misc/nd-info -p ${!}
16 #LD_PRELOAD= LD_DEBUG= strace -s2000 -tt -q -o 1.nd_info.strace ../../misc/nd-info -p ${!}
17 LD_PRELOAD= LD_DEBUG= ../../misc/nd-info -p ${!} &>1.info
17 18
File test/java/mysql/my1.java added (mode: 100644) (index 0000000..b72d820)
1 import java.sql.Connection;
2 import java.sql.DriverManager;
3 import java.sql.PreparedStatement;
4 import java.sql.Statement;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7
8 public class my1 {
9 public static void main(String args[]) {
10 try {
11 System.err.println("Starting...");
12 //Class.forName("com.mysql.jdbc.Driver");
13
14 System.err.println("");
15 System.err.println("getConnection...");
16 Connection con = DriverManager
17 .getConnection("jdbc:mysql://localhost/ninedogs",
18 "ninedogs", "pass");
19 System.err.println("Opened database successfully con=" + con);
20
21 System.err.println("");
22 System.err.println("Query (prepared) [PreparedStatement ps = con.prepareStatement(SELECT ? AS id, ? AS str1)]...");
23 PreparedStatement ps = con.prepareStatement("SELECT ? AS id, ? AS str1");
24 System.err.println("Prepared statement: " + ps);
25
26 System.err.println("");
27 System.err.println("Binding para 1 [ps.setInt(1, 12345)]...");
28 ps.setInt(1, 12345);
29
30 System.err.println("");
31 System.err.println("Binding para 2 [ps.setString(2, \"abc\")]...");
32 ps.setString(2, "abc");
33
34 System.err.println("");
35 System.err.println("Binding invalid para 100 [ps.setInt(100, 111)]...");
36 try { ps.setInt(100, 111); } catch (Exception e) { System.err.println("EXEC: " + e); }
37
38 System.err.println("");
39 System.err.println("Executing prepared query [ResultSet rs1 = ps.executeQuery()]...");
40 ResultSet rs1 = ps.executeQuery();
41 System.err.println("Executing prepared query... done rs1=" + rs1);
42
43 System.err.println("");
44 System.err.println("Looping [rs1.next()]...");
45 while (rs1.next()) {
46 int id = rs1.getInt("id");
47 System.err.println(" id=" + id);
48 }
49
50 System.err.println("");
51 System.err.println("Closing prepared statement [ps.close()]...");
52 ps.close();
53
54
55 System.err.println("");
56 System.err.println("Creating statement [Statement stmt = con.createStatement()] (link con with stmt)...");
57 Statement stmt = con.createStatement();
58
59 System.err.println("");
60 System.err.println("Query (normal)... [ResultSet rs2 = stmt.executeQuery('SELECT ...')]");
61 ResultSet rs2 = stmt.executeQuery("SELECT * FROM n1 LIMIT 2");
62 System.err.println("Query (normal) done rs2=" + rs2);
63
64 System.err.println("");
65 System.err.println("Looping [rs2.next()]...");
66 while (rs2.next()) {
67 int id = rs2.getInt("id");
68 System.err.println(" id=" + id);
69 }
70
71 System.err.println("");
72 System.err.println("Closing statement [stmt.close()]...");
73 stmt.close();
74
75 System.err.println(""); System.err.println("Closing connection [con.close()]...");
76 con.close();
77 System.err.println("Done");
78 } catch (Exception e) {
79 e.printStackTrace();
80 System.err.println(e.getClass().getName()+": " + e.getMessage());
81 System.exit(0);
82 }
83
84 }
85 }
File test/java/mysql/my1.jdb.run added (mode: 100755) (index 0000000..ab7ed1c)
1 #!/bin/bash
2
3 set -e
4
5 if [ my1.class -ot my1.java ]; then
6 echo "Compiling..."
7 javac my1.java
8 fi
9
10 # -Xdiag \
11 # -verbose:class \
12 #strace -s2000 -tt -f -o my1.tmp.strace \
13 jdb \
14 -classpath /usr/share/java/postgresql-jdbc.jar:. my1
15
File test/java/mysql/my1.run added (mode: 100755) (index 0000000..bc40d1d)
1 #!/bin/bash
2
3 set -e
4
5 if [ my1.class -ot my1.java ]; then
6 echo "Compiling..."
7 javac my1.java
8 fi
9
10 # We need postgreql-jdbc package
11
12 export LD_PRELOAD=../../../agent/ninedogs.so
13
14 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
15 export NINEDOGS_SERVER_PORT=36000
16 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552
17 export NINEDOGS_VERBOSE=11
18 export NINEDOGS_SYNC_FLUSH=1
19
20 #export LD_DEBUG=all
21 #export LD_DEBUG_OUTPUT=1.ld.txt
22
23 #strace -tt -f -s2000 -o my1.strace \
24 #ltrace -s200 -f -tt -S -o my1.ltrace \
25 #java -cp /usr/share/java/postgresql-jdbc.jar:. my1
26
27
28 # -javaagent:../../agent/java/agent/ninedogs-agent.jar \
29 # -Xdiag \
30 #strace -s20000 -tt -f -e\!mprotect,gettid -o my1.strace \
31 java \
32 -cp /usr/share/java/mysql-connector-java.jar:. my1 &>my1.out &
33
34 echo "Runing trace..."
35 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace --only-high-level -o my1.nd -p ${!}
36
File test/java/oracle/TODO added (mode: 100644) (index 0000000..2861835)
1 [ ] Add DataSource mode to connect to db. Also for rest of the db types.
2 [ ]
File test/java/oracle/sqlplus-XE.sh added (mode: 100755) (index 0000000..dff9586)
1 #!/bin/bash
2
3 podman exec -it nd-java-oracle sqlplus -F system/pass@XE
4
File test/java/oracle/sqlplus.sh added (mode: 100755) (index 0000000..5360638)
1 #!/bin/bash
2
3 podman exec -it nd-java-oracle sqlplus -S -F system/pass@XEPDB1
4
File test/java/oracle/start_oracle.sh added (mode: 100755) (index 0000000..3c68905)
1 #!/bin/bash
2
3 set -e
4
5 if [ ! -r ojdbc11.jar ]; then
6 wget https://download.oracle.com/otn-pub/otn_software/jdbc/218/ojdbc11.jar
7 fi
8
9 url="container-registry.oracle.com/database/express:21.3.0-xe"
10 podman pull ${url} || :
11 podman stop -t0 nd-java-oracle 2>/dev/null || :
12 podman rm nd-java-oracle &>/dev/null || :
13 podman run --rm -d \
14 --name nd-java-oracle \
15 -p 61521:1521 -p 65500:5500 \
16 -e ORACLE_PWD=pass \
17 -e ORACLE_CHARACTERSET=AL32UTF8 \
18 ${url} || :
19 echo -n "Waiting for db to start..."
20 while [ 1 ]; do
21 echo -n "."
22 ./test-conn.sh <<-EOF &>/dev/null
23 SELECT 1 FROM dual;
24 EXIT;
25 /
26 EOF
27 if [ "${?}" = "0" ]; then
28 break
29 fi
30 sleep 3
31 done
32 echo
File test/java/oracle/t1.java added (mode: 100644) (index 0000000..d914b51)
1 import java.sql.*;
2 import java.util.Properties;
3
4 class t1
5 {
6 public static void main(String args[])
7 {
8 try {
9 Class.forName("oracle.jdbc.driver.OracleDriver");
10
11 System.out.println(""); System.out.println("Creating connection...");
12 Connection con = DriverManager.getConnection(
13 "jdbc:oracle:thin:@localhost:61521:XE", "system", "pass");
14 System.out.println("Creating connection... done con=" + con);
15
16 System.out.println(""); System.out.println("Setting autocommit to false...");
17 con.setAutoCommit(false);
18
19 System.out.println(""); System.out.println("Creating statement [Statement stmt = con.createStatement()] con=" + con + "...");
20 Statement stmt = con.createStatement();
21 System.out.println("Creating statement [Statement stmt = con.createStatement()] stmt=" + stmt);
22
23 System.out.println(""); System.out.println("Executing query [ResultSet rs = stmt.executeQuery(\"select 123456789 from dual\")]...");
24 ResultSet rs = stmt.executeQuery("select 123456789 from dual");
25 System.out.println("Executing query... done rs=" + rs);
26
27 System.out.println("");
28 System.out.println("Looping ResultSet rs=" + rs);
29 while (rs.next())
30 System.out.println("ZZZZZZZZZZZZZZZ: " + rs.getInt(1));
31
32 System.out.println("");
33 System.out.println("Closing statement stmt=" + stmt + " [stmt.close()]...");
34 stmt.close();
35 System.out.println("Closing statement stmt=" + stmt + "... done");
36
37
38 // prepared statement
39 System.out.println("");
40 System.out.println("Creating prepared statement [PreparedStatement p1 = con.prepareStatement(\"SELECT ? AS F1, ? AS F2 FROM dual\")]...");
41 PreparedStatement p1 = con.prepareStatement("SELECT ? AS F1, ? AS F2 FROM dual");
42 System.out.println("Creating prepared statement... done p1=" + p1);
43
44 System.out.println("");
45 System.out.println("Binding parameters [p1.setInt(1, 12345)]...");
46 p1.setInt(1, 12345);
47
48 System.out.println("");
49 System.out.println("Binding parameters [p1.setInt(2, \"abcde\")]...");
50 p1.setString(2, "abcde");
51
52 System.err.println("");
53 System.err.println("Binding invalid para 100 [ps.setInt(100, 111)]...");
54 try { p1.setInt(100, 111); } catch (Exception e) { System.err.println("EXEC: " + e); }
55
56 System.out.println("");
57 System.out.println("Executing prepared [p1.execute()] p1=" + p1 + "...");
58 p1.execute();
59 System.out.println("Executing prepared... done");
60
61
62 // Seems this is specific to Oracle
63 System.out.println("");
64 System.out.println("Getting result set [ResultSet rs2 = p1.getResultSet()] (p1=" + p1 + ")...");
65 ResultSet rs2 = p1.getResultSet();
66 System.out.println("Getting result set... done rs2=" + rs2);
67
68 System.out.println("");
69 System.out.println("Looping (rs2=" + rs2 + ")...");
70 while (rs2.next()) {
71 float f1 = rs2.getFloat("F1");
72 String f2 = rs2.getString("F2");
73 System.out.println("f1=" + f1 + " f2=" + f2);
74 }
75
76 System.out.println(""); System.out.println("Closing p1=" + p1 + "...");
77 p1.close();
78
79 System.out.println(""); System.out.println("Commiting...");
80 con.commit();
81 System.out.println("Commiting... done");
82
83 System.out.println(""); System.out.println("Rolling back...");
84 con.rollback();
85 System.out.println("Rolling back... done");
86
87 System.out.println(""); System.out.println("Closing connection (no parameters) con=" + con + "...");
88 con.close();
89 System.out.println("Closing connection... done");
90 } catch (Exception e)
91 {
92 System.out.println("ZZZZZZZZZZZZZZZZ Exception: " + e);
93 }
94
95 System.out.println("Done!");
96 }
97 }
98
File test/java/oracle/t1.jdb.run added (mode: 100755) (index 0000000..b73cc24)
1 #!/bin/bash
2
3 set -e
4
5 if [ t1.class -ot t1.java ]; then
6 echo "Compiling..."
7 javac t1.java
8 fi
9
10 # -Xdiag \
11 # -verbose:class \
12 #strace -s2000 -tt -f -o t1.tmp.strace \
13 jdb -classpath ojdbc11.jar:. t1
14
File test/java/oracle/t1.run copied from file test/java/pg/pg1.run (similarity 50%) (mode: 100755) (index e3bb4c2..36283ee)
2 2
3 3 set -e set -e
4 4
5 if [ pg1.class -ot pg1.java ]; then
5 if [ t1.class -ot t1.java ]; then
6 6 echo "Compiling..." echo "Compiling..."
7 javac pg1.java
7 javac t1.java
8 8 fi fi
9 9
10 10 # We need postgreql-jdbc package # We need postgreql-jdbc package
 
... ... export LD_PRELOAD=../../../agent/ninedogs.so
14 14 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
15 15 export NINEDOGS_SERVER_PORT=36000 export NINEDOGS_SERVER_PORT=36000
16 16 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552
17 export NINEDOGS_VERBOSE=10
17 export NINEDOGS_VERBOSE=11
18 18 export NINEDOGS_SYNC_FLUSH=1 export NINEDOGS_SYNC_FLUSH=1
19 19
20 20 #export LD_DEBUG=all #export LD_DEBUG=all
 
... ... export NINEDOGS_SYNC_FLUSH=1
22 22
23 23 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
24 24 #ltrace -s200 -f -tt -S -o 1.ltrace \ #ltrace -s200 -f -tt -S -o 1.ltrace \
25 #java -cp /usr/share/java/postgresql-jdbc.jar:. pg1
25 #java -cp /usr/share/java/postgresql-jdbc.jar:. t1
26 26
27 #strace -s20000 -f -o 1.strace \
28 # -javaagent:../../agent/java/agent/ninedogs-agent.jar \
27 # -verbose:class \
28 # -Xdiag \
29 #strace -s20000 -f -q -o t1.strace -e\!brk,futex,getpid,gettid,lseek,sysinfo,mmap,munmap,mprotect,pread64 \
29 30 java \ java \
30 -Xdiag \
31 -cp /usr/share/java/postgresql-jdbc.jar:. pg1 2>&1 | tee 1.out &
31 -cp ojdbc11.jar:. t1 &>t1.out &
32 32
33 33 echo "Runing trace..." echo "Runing trace..."
34 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace -o 1.nd -p ${!}
34 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace --only-high-level -o t1.nd -p ${!}
35 35
36 # ninedogs must inject this:
37 # -javaagent:../../../agent/java/agent/ninedogs-agent.jar
36 #LD_PRELOAD= LD_DEBUG= podman stop -t0 nd-java-oracle
38 37
File test/java/oracle/t2.java added (mode: 100644) (index 0000000..470d4a8)
1 // Prepared statement test
2
3 import java.sql.*;
4 import java.util.Properties;
5
6 class t2
7 {
8 public static void main(String args[])
9 {
10 try {
11 Class.forName("oracle.jdbc.driver.OracleDriver");
12
13 System.out.println("Creating connection...");
14 Connection con = DriverManager.getConnection(
15 "jdbc:oracle:thin:@localhost:61521:XE", "system", "pass");
16 System.out.println("Creating connection... done con=" + con);
17
18 System.out.println("Creating prepared statement...");
19 PreparedStatement p1 = con.prepareStatement("SELECT ? AS F1, ? AS F2 FROM dual");
20 System.out.println("Creating prepared statement... done p1=" + p1);
21
22 System.out.println("Binding parameters...");
23 p1.setInt(1, 12345);
24 p1.setString(2, "abcde");
25 System.out.println("Executing prepared (no result expected!)...");
26 p1.execute();
27 System.out.println("Executing prepared (no result expected!)... done");
28
29 System.out.println("Getting result set...");
30 ResultSet rs2 = p1.getResultSet();
31 System.out.println("Getting result set... done rs2=" + rs2);
32 System.out.println("Calling next()...");
33 while (rs2.next()) {
34 float f1 = rs2.getFloat("F1");
35 System.out.println("f1=" + f1);
36 }
37 } catch (Exception e)
38 {
39 System.out.println("ZZZZZZZZZZZZZZZZ Exception: " + e);
40 }
41
42 System.out.println("Done!");
43 }
44 }
45
File test/java/oracle/t2.jdb.run added (mode: 100755) (index 0000000..edbf857)
1 #!/bin/bash
2
3 set -e
4
5 if [ t2.class -ot t2.java ]; then
6 echo "Compiling..."
7 javac t2.java
8 fi
9
10 # -Xdiag \
11 # -verbose:class \
12 #strace -s2000 -tt -f -o t2.tmp.strace \
13 jdb -classpath ojdbc11.jar:. t2
14
File test/java/oracle/t2.run copied from file test/java/pg/pg1.run (similarity 50%) (mode: 100755) (index e3bb4c2..fe0b807)
2 2
3 3 set -e set -e
4 4
5 if [ pg1.class -ot pg1.java ]; then
5 if [ t2.class -ot t2.java ]; then
6 6 echo "Compiling..." echo "Compiling..."
7 javac pg1.java
7 javac t2.java
8 8 fi fi
9 9
10 10 # We need postgreql-jdbc package # We need postgreql-jdbc package
 
... ... export LD_PRELOAD=../../../agent/ninedogs.so
14 14 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
15 15 export NINEDOGS_SERVER_PORT=36000 export NINEDOGS_SERVER_PORT=36000
16 16 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552
17 export NINEDOGS_VERBOSE=10
17 export NINEDOGS_VERBOSE=49
18 18 export NINEDOGS_SYNC_FLUSH=1 export NINEDOGS_SYNC_FLUSH=1
19 19
20 20 #export LD_DEBUG=all #export LD_DEBUG=all
 
... ... export NINEDOGS_SYNC_FLUSH=1
22 22
23 23 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
24 24 #ltrace -s200 -f -tt -S -o 1.ltrace \ #ltrace -s200 -f -tt -S -o 1.ltrace \
25 #java -cp /usr/share/java/postgresql-jdbc.jar:. pg1
25 #java -cp /usr/share/java/postgresql-jdbc.jar:. t2
26 26
27 #strace -s20000 -f -o 1.strace \
28 # -javaagent:../../agent/java/agent/ninedogs-agent.jar \
27 # -verbose:class \
28 # -Xdiag \
29 strace -s20000 -f -q -o t2.strace -e\!brk,futex,getpid,gettid,lseek,sysinfo,mmap,munmap,mprotect,pread64 \
29 30 java \ java \
30 -Xdiag \
31 -cp /usr/share/java/postgresql-jdbc.jar:. pg1 2>&1 | tee 1.out &
31 -cp ojdbc11.jar:. t2 2>&1 | tee t2.out &
32 32
33 33 echo "Runing trace..." echo "Runing trace..."
34 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace -o 1.nd -p ${!}
34 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace -o t2.nd -p ${!}
35 35
36 # ninedogs must inject this:
37 # -javaagent:../../../agent/java/agent/ninedogs-agent.jar
36 #LD_PRELOAD= LD_DEBUG= podman stop -t0 nd-java-oracle
38 37
File test/java/oracle/t_con_err.java added (mode: 100644) (index 0000000..f2db8c8)
1 import java.sql.*;
2 import java.util.Properties;
3
4 class t_con_err
5 {
6 public static void main(String args[])
7 {
8 try {
9 Class.forName("oracle.jdbc.driver.OracleDriver");
10
11 try {
12 System.out.println("Creating connection con0...");
13 Properties props = new Properties();
14 props.put("user", "user-bla");
15 props.put("password", "password-bla");
16 props.put("v$session.program", "Application name");
17 Connection con0 = DriverManager.getConnection(
18 "jdbc:oracle:thin:@wrong-host:61521:XE", props);
19 System.out.println("Creating connection con0... done");
20 } catch (Exception e) {
21 }
22 } catch (Exception e)
23 {
24 System.out.println("ZZZZZZZZZZZZZZZZ Exception: " + e);
25 }
26
27 System.out.println("Done!");
28 }
29 }
30
File test/java/oracle/t_con_err.sh added (mode: 100755) (index 0000000..be65e15)
1 #!/bin/bash
2
3 set -e
4
5 if [ t_con_err.class -ot t_con_err.java ]; then
6 echo "Compiling..."
7 javac t_con_err.java
8 fi
9
10 # We need postgreql-jdbc package
11
12 export LD_PRELOAD=../../../agent/ninedogs.so
13
14 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
15 export NINEDOGS_SERVER_PORT=36000
16 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552
17 export NINEDOGS_VERBOSE=49
18 export NINEDOGS_SYNC_FLUSH=1
19
20 #export LD_DEBUG=all
21 #export LD_DEBUG_OUTPUT=1.ld.txt
22
23 #strace -tt -f -s2000 -o 1.strace \
24 #ltrace -s200 -f -tt -S -o 1.ltrace \
25 #java -cp /usr/share/java/postgresql-jdbc.jar:. t_con_err
26
27 # -verbose:class \
28 # -Xdiag \
29 #strace -s20000 -f -q -o t_con_err.strace -e\!brk,futex,getpid,gettid,lseek,sysinfo,mmap,munmap,mprotect,pread64 \
30 java \
31 -cp ojdbc11.jar:. t_con_err &>t_con_err.out &
32
33 echo "Runing trace..."
34 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace -o t_con_err.nd -p ${!}
35
36 #LD_PRELOAD= LD_DEBUG= podman stop -t0 nd-java-oracle
37
File test/java/pg/1-no-nd-ja.sh added (mode: 100755) (index 0000000..d7c182f)
1 #!/bin/bash
2
3 set -e
4
5 if [ pg1.class -ot pg1.java ]; then
6 echo "Compiling..."
7 javac pg1.java
8 fi
9
10 # We need postgreql-jdbc package
11
12 #strace -s20000 -f -o 1.strace \
13 # -javaagent:../../agent/java/agent/ninedogs-agent.jar \
14 java \
15 -javaagent:../../../agent/java/agent/ninedogs-agent.jar \
16 -cp /usr/share/java/postgresql-jdbc.jar:. pg1 2>&1 | tee 1-no-nd.out
17
File test/java/pg/1-no-nd.run added (mode: 100755) (index 0000000..0ff5d2b)
1 #!/bin/bash
2
3 set -e
4
5 if [ pg1.class -ot pg1.java ]; then
6 echo "Compiling..."
7 javac pg1.java
8 fi
9
10 # We need postgreql-jdbc package
11
12 #strace -s20000 -f -o 1.strace \
13 # -javaagent:../../agent/java/agent/ninedogs-agent.jar \
14 java \
15 -cp /usr/share/java/postgresql-jdbc.jar:. pg1 2>&1 | tee 1-no-nd.out
16
File test/java/pg/pg1.java changed (mode: 100644) (index ec3004b..1ffa904)
... ... import java.sql.SQLException;
7 7
8 8 public class pg1 { public class pg1 {
9 9 public static void main(String args[]) { public static void main(String args[]) {
10 Connection c = null;
11 10 try { try {
12 11 System.err.println("Starting..."); System.err.println("Starting...");
13
14 12 Class.forName("org.postgresql.Driver"); Class.forName("org.postgresql.Driver");
13
14 System.err.println("");
15 15 System.err.println("getConnection..."); System.err.println("getConnection...");
16 c = DriverManager
16 Connection con = DriverManager
17 17 .getConnection("jdbc:postgresql://localhost:5432/ninedogs?ApplicationName=pg1", .getConnection("jdbc:postgresql://localhost:5432/ninedogs?ApplicationName=pg1",
18 "ninedogs", "");
19 System.err.println("Opened database successfully");
20
21 System.err.println("Query (prepared)...");
22 System.err.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx prepare start");
23 PreparedStatement preparedStatement = c.prepareStatement("SELECT ? AS id");
24 System.err.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx prepare end");
25 preparedStatement.setInt(1, 1);
26 System.err.println("Prepared statement: " + preparedStatement);
27
28 System.err.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx execute q start");
29 ResultSet rs1 = preparedStatement.executeQuery();
30 System.err.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx execute q end");
18 "ninedogs", "");
19 System.err.println("Opened database successfully con=" + con);
20
21 System.err.println("");
22 System.err.println("Query (prepared) [PreparedStatement ps = con.prepareStatement(SELECT ? AS id, ? AS str1)]...");
23 PreparedStatement ps = con.prepareStatement("SELECT ? AS id, ? AS str1");
24 System.err.println("Prepared statement: " + ps);
25
26 System.err.println("");
27 System.err.println("Binding para 1 [ps.setInt(1, 12345)]...");
28 ps.setInt(1, 12345);
29
30 System.err.println("");
31 System.err.println("Binding para 2 [ps.setString(2, \"abc\")]...");
32 ps.setString(2, "abc");
33
34 System.err.println("");
35 System.err.println("Binding invalid para 100 [ps.setInt(100, 111)]...");
36 try { ps.setInt(100, 111); } catch (Exception e) { System.err.println("EXEC: " + e); }
37
38 System.err.println("");
39 System.err.println("Executing prepared query [ResultSet rs1 = ps.executeQuery()]...");
40 ResultSet rs1 = ps.executeQuery();
41 System.err.println("Executing prepared query... done rs1=" + rs1);
42
43 System.err.println("");
44 System.err.println("Looping [rs1.next()]...");
31 45 while (rs1.next()) { while (rs1.next()) {
32 46 int id = rs1.getInt("id"); int id = rs1.getInt("id");
33 47 System.err.println(" id=" + id); System.err.println(" id=" + id);
34 48 } }
35 49
36 50 System.err.println(""); System.err.println("");
37 System.err.println("Query (normal)...");
38 Statement stmt = c.createStatement();
51 System.err.println("Closing prepared statement [ps.close()]...");
52 ps.close();
53
54
55 System.err.println("");
56 System.err.println("Creating statement [Statement stmt = con.createStatement()] (link con with stmt)...");
57 Statement stmt = con.createStatement();
58
59 System.err.println("");
60 System.err.println("Query (normal)... [ResultSet rs2 = stmt.executeQuery('SELECT ...')]");
39 61 ResultSet rs2 = stmt.executeQuery("SELECT * FROM n1 LIMIT 2"); ResultSet rs2 = stmt.executeQuery("SELECT * FROM n1 LIMIT 2");
40 System.err.println("Query (normal) done");
62 System.err.println("Query (normal) done rs2=" + rs2);
63
64 System.err.println("");
65 System.err.println("Looping [rs2.next()]...");
41 66 while (rs2.next()) { while (rs2.next()) {
42 67 int id = rs2.getInt("id"); int id = rs2.getInt("id");
43 68 System.err.println(" id=" + id); System.err.println(" id=" + id);
44 69 } }
70
71 System.err.println("");
72 System.err.println("Closing statement [stmt.close()]...");
45 73 stmt.close(); stmt.close();
46 74
47 c.close();
75 System.err.println(""); System.err.println("Closing connection [con.close()]...");
76 con.close();
48 77 System.err.println("Done"); System.err.println("Done");
49 78 } catch (Exception e) { } catch (Exception e) {
50 79 e.printStackTrace(); e.printStackTrace();
File test/java/pg/pg1.jdb.run added (mode: 100755) (index 0000000..e11ca2c)
1 #!/bin/bash
2
3 set -e
4
5 if [ pg1.class -ot pg1.java ]; then
6 echo "Compiling..."
7 javac pg1.java
8 fi
9
10 # -Xdiag \
11 # -verbose:class \
12 #strace -s2000 -tt -f -o pg1.tmp.strace \
13 jdb \
14 -classpath /usr/share/java/postgresql-jdbc.jar:. pg1
15
File test/java/pg/pg1.run changed (mode: 100755) (index e3bb4c2..53fb625)
... ... export LD_PRELOAD=../../../agent/ninedogs.so
14 14 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
15 15 export NINEDOGS_SERVER_PORT=36000 export NINEDOGS_SERVER_PORT=36000
16 16 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552
17 export NINEDOGS_VERBOSE=10
17 export NINEDOGS_VERBOSE=110
18 18 export NINEDOGS_SYNC_FLUSH=1 export NINEDOGS_SYNC_FLUSH=1
19 19
20 20 #export LD_DEBUG=all #export LD_DEBUG=all
21 21 #export LD_DEBUG_OUTPUT=1.ld.txt #export LD_DEBUG_OUTPUT=1.ld.txt
22 22
23 #strace -tt -f -s2000 -o 1.strace \
24 #ltrace -s200 -f -tt -S -o 1.ltrace \
23 #strace -tt -f -s2000 -o pg1.strace \
24 #ltrace -s200 -f -tt -S -o pg1.ltrace \
25 25 #java -cp /usr/share/java/postgresql-jdbc.jar:. pg1 #java -cp /usr/share/java/postgresql-jdbc.jar:. pg1
26 26
27 #strace -s20000 -f -o 1.strace \
27
28 28 # -javaagent:../../agent/java/agent/ninedogs-agent.jar \ # -javaagent:../../agent/java/agent/ninedogs-agent.jar \
29 # -Xdiag \
30 #strace -s20000 -tt -f -e\!mprotect,gettid -o pg1.strace \
29 31 java \ java \
30 -Xdiag \
31 -cp /usr/share/java/postgresql-jdbc.jar:. pg1 2>&1 | tee 1.out &
32 -cp /usr/share/java/postgresql-jdbc.jar:. pg1 &>pg1.out &
32 33
33 34 echo "Runing trace..." echo "Runing trace..."
34 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace -o 1.nd -p ${!}
35
36 # ninedogs must inject this:
37 # -javaagent:../../../agent/java/agent/ninedogs-agent.jar
35 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace --only-high-level -o pg1.nd -p ${!}
38 36
File test/openssl/expired.sh copied from file test/openssl/run.sh (similarity 74%) (mode: 100755) (index 85565d3..0cb3ee1)
1 1 #!/bin/bash #!/bin/bash
2 2
3 if [ ! -r certificate.crt ]; then
3 if [ ! -r expired-certificate.crt ]; then
4 4 openssl req -x509 \ openssl req -x509 \
5 5 -utf8 \ -utf8 \
6 6 -sha256 \ -sha256 \
7 7 -nodes \ -nodes \
8 -days 365 \
8 -days 1 \
9 9 -set_serial 0x112233 \ -set_serial 0x112233 \
10 -subj '/C=RO/CN=aaa.example.com/L=Brasov/O=openssl' \
10 -subj '/C=RO/CN=expired.example.com/L=Brasov/O=openssl' \
11 11 -addext 'subjectAltName = DNS:bbb.example.com, DNS:ccc.example.com, DNS:șșș.example.com' \ -addext 'subjectAltName = DNS:bbb.example.com, DNS:ccc.example.com, DNS:șșș.example.com' \
12 12 -newkey rsa:4096 \ -newkey rsa:4096 \
13 13 -keyout private.key \ -keyout private.key \
14 -out certificate.crt
14 -out expired-certificate.crt
15 15 fi fi
16 16
17 17 # To debug # To debug
 
... ... export LD_DEBUG_OUTPUT="1.ld.txt"
31 31 export DEBUGINFOD_URLS= export DEBUGINFOD_URLS=
32 32
33 33 #export GNUTLS_DEBUG_LEVEL=99 #export GNUTLS_DEBUG_LEVEL=99
34 #export SSLKEYLOGFILE=run.key
34 #export SSLKEYLOGFILE=expired.key
35 35
36 36 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
37 37 #valgrind -v --trace-children=yes \ #valgrind -v --trace-children=yes \
38 38 #ltrace -S -s200 -f -tt -S -o 1.ltrace \ #ltrace -S -s200 -f -tt -S -o 1.ltrace \
39 openssl x509 -in certificate.crt -text -noout 2>&1 | LD_PRELOAD= LD_DEBUG= tee run.out
39 openssl x509 -in expired-certificate.crt -text -noout 2>&1 | LD_PRELOAD= LD_DEBUG= tee expired.out
40 40
41 41
File test/openssl/expiring.sh added (mode: 100755) (index 0000000..2eea4bb)
1 #!/bin/bash
2
3 rm -f expiring-certificate.crt
4 openssl req -x509 \
5 -utf8 \
6 -sha256 \
7 -nodes \
8 -days 13 \
9 -set_serial 0x112233ee \
10 -subj '/C=RO/CN=expiring.example.com/L=Brasov/O=openssl' \
11 -addext 'subjectAltName = DNS:bbb.example.com, DNS:ccc.example.com, DNS:șșș.example.com' \
12 -newkey rsa:4096 \
13 -keyout private.key \
14 -out expiring-certificate.crt
15
16 # To debug
17 #openssl s_server -cert fullchain.pem -key privkey.pem -port 6002 -debug -status_verbose -msg
18
19 export LD_PRELOAD=../../agent/ninedogs.so
20
21 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
22 export NINEDOGS_SERVER_PORT=36000
23 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55552
24 export NINEDOGS_VERBOSE=50
25 export NINEDOGS_SYNC_FLUSH=1
26
27 #export LD_DEBUG=all
28 export LD_DEBUG_OUTPUT="expiring.ld.txt"
29
30 export DEBUGINFOD_URLS=
31
32 #export GNUTLS_DEBUG_LEVEL=99
33 #export SSLKEYLOGFILE=run.key
34
35 #strace -tt -f -s2000 -o 1.strace \
36 #valgrind -v --trace-children=yes \
37 #ltrace -S -s200 -f -tt -S -o 1.ltrace \
38 openssl x509 -in expiring-certificate.crt -text -noout 2>&1 | LD_PRELOAD= LD_DEBUG= tee expiring.out
39
40 # To have another user
41 openssl x509 -in expiring-certificate.crt -text 2>&1 | LD_PRELOAD= LD_DEBUG= tee -a expiring.out
42
File test/php-container/exec.sh changed (mode: 100755) (index a41ea9d..bb187dc)
8 8 #strace -s200 -tt -f -q -o podman.strace \ #strace -s200 -tt -f -q -o podman.strace \
9 9 podman run -ti --rm \ podman run -ti --rm \
10 10 \ \
11 -e NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro \
12 -e NINEDOGS_SERVER_PORT=36000 \
13 -e NINEDOGS_ID=ba446a981b387e831db3f6a730c55513 \
11 14 -e LD_PRELOAD=ninedogs.so \ -e LD_PRELOAD=ninedogs.so \
12 15 \ \
13 16 -v ${PWD}/1.php:/1.php \ -v ${PWD}/1.php:/1.php \
File test/php-dns/1.run changed (mode: 100755) (index 4b7d12e..3ba0032)
... ... export DEBUGINFOD_URLS=
17 17 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
18 18 #ltrace -s200 -f -tt -S -o 1.ltrace \ #ltrace -s200 -f -tt -S -o 1.ltrace \
19 19 php 1.php &>1.out & php 1.php &>1.out &
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace --only-high-level -o 1.nd -p ${!}
21 21
File test/php-mysql/1.run changed (mode: 100755) (index e5cbc8e..1b05148)
... ... export DEBUGINFOD_URLS=
17 17 #valgrind -v --trace-children=yes \ #valgrind -v --trace-children=yes \
18 18 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
19 19 php 1.php &>1.out & php 1.php &>1.out &
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
20 #LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
21 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace --only-high-level -o 1.nd -p ${!}
21 22
File test/php-mysql/1.run.gdb copied from file test/php-pg/1.run.gdb (similarity 100%)
File test/php-mysql/1.run.gdb.sh copied from file test/php-pg/1.run.gdb.sh (similarity 100%)
File test/php-mysql/1.vg.run copied from file test/php-mysql/1.run (similarity 68%) (mode: 100755) (index e5cbc8e..1be6147)
... ... export DEBUGINFOD_URLS=
16 16 #ltrace -s200 -f -tt -S -o 1.ltrace \ #ltrace -s200 -f -tt -S -o 1.ltrace \
17 17 #valgrind -v --trace-children=yes \ #valgrind -v --trace-children=yes \
18 18 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
19 php 1.php &>1.out &
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
19 valgrind -v --track-origins=yes php 1.php &>1.vg.out </dev/null &
20 #LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
21 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace --only-high-level -o 1.vg.nd -p ${!}
21 22
File test/php-mysql/stmt_bind_param.php changed (mode: 100644) (index 4045b38..4528162)
... ... mysqli_stmt_execute($stmt);
31 31 echo 'Calling mysqli_stmt_execute 2...' . "\n"; echo 'Calling mysqli_stmt_execute 2...' . "\n";
32 32 $a = 2; $b = $a + 1; $c = 8.4; $d = 'bla2'; $e = 'bla3'; $a = 2; $b = $a + 1; $c = 8.4; $d = 'bla2'; $e = 'bla3';
33 33 mysqli_stmt_execute($stmt); mysqli_stmt_execute($stmt);
34 mysqli_stmt_close($stmt);
34 35
35 36 echo 'Done!' . "\n"; echo 'Done!' . "\n";
36 37
File test/php-mysql/stmt_bind_param.run changed (mode: 100755) (index bca3d2f..ab189f2)
... ... export DEBUGINFOD_URLS=
17 17 #valgrind -v --trace-children=yes \ #valgrind -v --trace-children=yes \
18 18 #strace -tt -f -s2000 -o stmt_bind_param.strace \ #strace -tt -f -s2000 -o stmt_bind_param.strace \
19 19 php stmt_bind_param.php &>stmt_bind_param.out & php stmt_bind_param.php &>stmt_bind_param.out &
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o stmt_bind_param.nd -p ${!}
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace --only-high-level -o stmt_bind_param.nd -p ${!}
21 21
File test/php-oracle/1 copied from file test/php-container/1 (similarity 58%) (mode: 100755) (index 5454f81..4f27c4a)
2 2
3 3 # This will be executed inside the container # This will be executed inside the container
4 4
5 echo "TERM=${TERM}"
6
5 7 export LD_PRELOAD=ninedogs.so export LD_PRELOAD=ninedogs.so
6 export NINEDOGS_VERBOSE=0
8 export NINEDOGS_VERBOSE=1
7 9 php /1.php & php /1.php &
10 #LD_PRELOAD= nd-trace --only-high-level -p ${!}
8 11 LD_PRELOAD= nd-trace -p ${!} LD_PRELOAD= nd-trace -p ${!}
9 12
File test/php-oracle/1.php added (mode: 100644) (index 0000000..8d6a23a)
1 <?php
2
3 sleep(1);
4
5 $db = oci_pconnect('system', 'pass', 'r1i:61521/XE', "", OCI_DEFAULT);
6 if ($db === FALSE)
7 die();
8
9 $stid = oci_parse($db, 'SELECT :p1 AS xx, NULL AS yy FROM dual');
10 $p1 = 'before';
11 oci_bind_by_name($stid, ':p1', $p1);
12 $p1 = 'after'; // setting value AFTER binding!
13 oci_execute($stid);
14 oci_execute($stid, OCI_NO_AUTO_COMMIT);
15 $row = oci_fetch_array($stid, OCI_ASSOC|OCI_RETURN_NULLS);
16 print_r($row);
17 oci_free_statement($stid);
18
19 oci_close($db);
20
21 echo 'Done!' . "\n";
File test/php-oracle/Dockerfile added (mode: 100644) (index 0000000..f43bfeb)
1 FROM oraclelinux:8
2
3 # TODO: catalinux+ninedogs
4
5 RUN echo "1"
6 RUN dnf -y --setopt=nodocs install oracle-release-el8 oracle-instantclient-release-el8 \
7 oracle-epel-release-el8 oraclelinux-release-el8 \
8 oraclelinux-developer-release-el8 \
9 gcc make \
10 https://rocketgit.com/op/pkgrepo/main/global/testing/rocky/8/x86_64/os/rocketgit-global-testing-1.1-1.noarch.rpm \
11 \
12 && dnf -y module enable php:8.0 \
13 \
14 && dnf -y install oracle-instantclient-devel \
15 php-cli php-opcache php-pear php-devel
16
17 RUN pecl install oci8-3.0.1
18
19 RUN echo "extension=oci8.so" >> /etc/php.ini
20
21 RUN dnf -y update
22 RUN dnf -y install gnutls-devel json-c-devel libcap-devel catalinux+Conn \
23 texlive-latex texlive-beamer texlive-adjustbox texlive-babel-english \
24 texlive-hyperref texlive-url
25
26 RUN dnf -y install strace gdb
27
28 RUN mkdir /nd
29 COPY copy/ /nd/
30 RUN cd /nd && ./configure && make common && make agent && make -R -C agent install && make trace && make -R -C trace install
File test/php-oracle/build.sh added (mode: 100755) (index 0000000..0e29305)
1 #!/bin/bash
2
3 set -u
4 set -e
5
6 mkdir -p copy
7 rsync -a ../../ --exclude 'test/' \
8 --include 'configure' --include '*.c' --include '*.h' --include 'duilder' --include 'Makefile*' \
9 --exclude '*.*' \
10 copy
11
12 docker="podman"
13
14 ${docker} build \
15 --tag="ninedogs-php-oracle:latest" \
16 .
17
18 #rm -rf copy
File test/php-oracle/exec-dev-1.sh added (mode: 100755) (index 0000000..45fcdf1)
1 podman run -ti \
2 -v ${PWD}/1.php:/1.php \
3 -v ${PWD}/1:/1 \
4 --rm \
5 --namespace nd-test \
6 ninedogs-php-oracle:latest \
7 /1 2>&1 | tee exec-dev-1.out
8
9
File test/php-oracle/exec-dev-bash.sh added (mode: 100755) (index 0000000..5993480)
1 podman run -ti \
2 -v ${PWD}/1.php:/1.php \
3 -v ${PWD}/1:/1 \
4 --rm \
5 --namespace nd-test \
6 ninedogs-php-oracle:latest \
7 bash
8
9
File test/php-pg/1.run changed (mode: 100755) (index 0d2f00a..09cc4a3)
... ... export DEBUGINFOD_URLS=
17 17 #valgrind -v --trace-children=yes \ #valgrind -v --trace-children=yes \
18 18 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
19 19 php 1.php &>1.out & php 1.php &>1.out &
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace --only-high-level -o 1.nd -p ${!}
File test/php/gd/.gitignore added (mode: 100644) (index 0000000..e33609d)
1 *.png
File test/php/gd/1.php added (mode: 100644) (index 0000000..ae28576)
1 <?php
2 error_reporting(E_ALL);
3
4 sleep(1);
5
6 for ($i = 0; $i < 10; $i++) {
7 $im = imagecreatetruecolor(100, 100);
8 $color = imagecolorallocate($im, 0, 255, 0);
9 imagestring($im, 5, 3, 9, 'bla', $color);
10 imagepng($im, '1.png');
11 usleep(1000 * $i * 100);
12 imagedestroy($im);
13 }
14
15 exit(1);
16
17
File test/php/gd/1.run copied from file test/php-dns/1.run (similarity 72%) (mode: 100755) (index 4b7d12e..0635d57)
1 1 #!/bin/bash #!/bin/bash
2 2
3 export LD_PRELOAD=../../agent/ninedogs.so
3 export LD_PRELOAD=../../../agent/ninedogs.so
4 4
5 5 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
6 6 export NINEDOGS_SERVER_PORT=36000 export NINEDOGS_SERVER_PORT=36000
 
... ... export LD_DEBUG_OUTPUT=1.ld.txt
13 13
14 14 export DEBUGINFOD_URLS= export DEBUGINFOD_URLS=
15 15
16 #ltrace -s200 -f -tt -S -o 1.ltrace \
16 17 #valgrind -v --trace-children=yes \ #valgrind -v --trace-children=yes \
17 18 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
18 #ltrace -s200 -f -tt -S -o 1.ltrace \
19 19 php 1.php &>1.out & php 1.php &>1.out &
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
21
20 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace --only-high-level -o 1.nd -p ${!}
21 LD_PRELOAD= LD_DEBUG= cat 1.nd
File test/php/redis/1.php added (mode: 100644) (index 0000000..ac30f7a)
1 <?php
2 error_reporting(E_ALL);
3
4 sleep(1);
5
6 $redis = phpiredis_connect('127.0.0.1', 56379); // normal connection
7
8 $response = phpiredis_command_bs($redis, array('DEL', 'test0'));
9
10 for ($i = 0; $i < 1000; $i++) {
11 $response = phpiredis_multi_command_bs($redis,
12 array(
13 array('SET', 'test' . $i, $i),
14 array('GET', 'test' . $i)
15 )
16 );
17 }
18
19 $response = phpiredis_multi_command_bs($redis,
20 array(
21 array('GET', 'test0')
22 )
23 );
24
25 print_r($response);
File test/php/redis/1.run copied from file test/php-pg/1.run (similarity 75%) (mode: 100755) (index 0d2f00a..122a997)
1 1 #!/bin/bash #!/bin/bash
2 2
3 export LD_PRELOAD=../../agent/ninedogs.so
3 export LD_PRELOAD=../../../agent/ninedogs.so
4 4
5 5 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
6 6 export NINEDOGS_SERVER_PORT=36000 export NINEDOGS_SERVER_PORT=36000
 
... ... export DEBUGINFOD_URLS=
17 17 #valgrind -v --trace-children=yes \ #valgrind -v --trace-children=yes \
18 18 #strace -tt -f -s2000 -o 1.strace \ #strace -tt -f -s2000 -o 1.strace \
19 19 php 1.php &>1.out & php 1.php &>1.out &
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o 1.nd -p ${!}
20 LD_PRELOAD= LD_DEBUG= ../../../trace/nd-trace -o 1.nd -p ${!}
21 LD_PRELOAD= LD_DEBUG= cat 1.nd
File test/redis/.gitignore added (mode: 100644) (index 0000000..58c2a9d)
1 *.rdb
File test/redis/1.run added (mode: 100755) (index 0000000..6ec084f)
1 #!/bin/bash
2
3 set -e
4
5 export LD_PRELOAD=../../agent/ninedogs.so
6
7 export NINEDOGS_VERBOSE=300
8
9 #export LD_DEBUG=symbols
10 export LD_DEBUG_OUTPUT=1.ld.txt
11
12 /usr/bin/redis-server --port 56379 &>1.out &
13 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -p ${!}
14
File tools/Makefile changed (mode: 100644) (index 3ae7ac7..4424a54)
1 1 include ../Makefile.common include ../Makefile.common
2 2
3 3 COMMON_H += ../common/ids.h ../common/tools.h ../common/decode_text.h \ COMMON_H += ../common/ids.h ../common/tools.h ../common/decode_text.h \
4 ../common/params.h \
5 ctools.h
4 ../common/sctools.h ../common/bin2struct.h
6 5
7 6 CFLAGS += -I../common CFLAGS += -I../common
8 7
9 8 OBJS := \ OBJS := \
10 ../common/tools.o ../common/info.o ../common/decode_text.o
9 ../common/tools.o ../common/info.o ../common/decode_text.o \
10 ../common/sctools.o ../common/bin2struct.o
11 11
12 12 ALL_TOOLS := cert-notify ALL_TOOLS := cert-notify
13 13
14 14 all: $(ALL_TOOLS) all: $(ALL_TOOLS)
15 15
16 16 cert-notify: cert-notify.c Makefile $(COMMON_H) $(OBJS) cert-notify: cert-notify.c Makefile $(COMMON_H) $(OBJS)
17 $(CC) $(CFLAGS) $@.c -o $@ $(OBJS)
17 $(CC) $(CFLAGS) $@.c -o $@ $(OBJS) $(CURL_LIBS)
18 18
19 19 .PHONY: clean .PHONY: clean
20 20 clean: clean:
21 21 @rm -f $(ALL_TOOLS) @rm -f $(ALL_TOOLS)
22 22
23 23 install: all install: all
24 @mkdir -p $(if $(I_USR_BIN), $(I_USR_BIN), /usr/bin)
24 @mkdir -p $(I_USR_BIN)
25 25 cp -vd $(ALL_TOOLS) $(I_USR_BIN) cp -vd $(ALL_TOOLS) $(I_USR_BIN)
26
26 @mkdir -pv $(I_USR)/lib/systemd/system
27 cp -vd *.service *.timer $(I_USR)/lib/systemd/system/
File tools/TODO changed (mode: 100644) (index acdcb58..edeca5a)
1 1 [ ] Log when the cert was last time used. [ ] Log when the cert was last time used.
2 [ ] Logic:
3 for each uid
4 list /var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x
5 foreach cert/%s hash file
6 test expiration
7 notify if needed (rate-limit)
8 [ ] Seems I need the full path to cvertificate. Can we extract it?
9 [ ] Should I keep track of last notification per usr or per cert?
2 10 [ ] [ ]
File tools/cert-notify.c changed (mode: 100644) (index e69de29..395742f)
1 #include <libgen.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4
5 #include <bin2struct.h>
6 #include <sctools.h>
7 #include <tools.h>
8
9 static unsigned debug = 10;
10
11 void xlog(const unsigned int level, const char *format, ...)
12 {
13 va_list ap;
14 char a[4096];
15 size_t len;
16
17 if (level > debug)
18 return;
19
20 va_start(ap, format);
21 len = vsnprintf(a, sizeof(a), format, ap);
22 va_end(ap);
23
24 if (len >= sizeof(a) - 1)
25 len = sizeof(a) - 1;
26 a[len] = '\0';
27 fprintf(stderr, "%s", a);
28 }
29
30 static int user_cb(const unsigned int uid, const char *user_dir)
31 {
32 glob_t certs;
33 struct timeval now;
34 int r, ret = 0;
35 long hours, last_notification;
36 char msg[64 * 4096];
37 size_t msg_off = 0;
38 char *add = "";
39 unsigned int count = 0;
40
41 xlog(0, "%s: uid=%u user_dir=[%s]\n",
42 __func__, uid, user_dir);
43
44 r = nd_load_uid_file_long(&hours, uid,
45 "settings/certs/cert-notification-hours-before");
46 if (r == -1)
47 hours = 15 * 24;
48 xlog(10, " hour = %ld\n", hours);
49
50 r = nd_load_uid_file_long(&last_notification, uid,
51 "state/certs/cert-notification-last");
52 if (r == -1)
53 last_notification = 0;
54 xlog(10, " last_notification = %ld\n", last_notification);
55
56 ninedogs_now(&now);
57 if (last_notification + 24 * 3600 > now.tv_sec) {
58 xlog(1, " notification too early; last was at %u [%d]\n",
59 last_notification, last_notification + 24 * 3600 - now.tv_sec);
60 return 0;
61 }
62 long next_notification = now.tv_sec + 24 * 3600; // compute proper "tomorrow"
63 r = nd_save_uid_file_long(uid, "state/certs/cert-notification-last", next_notification);
64 if (r == -1)
65 return -1;
66
67 r = nd_load_certs(&certs, uid);
68 if (r <= 0)
69 return r;
70 for (unsigned int i = 0; i < certs.gl_pathc; i++) {
71 unsigned char data[4096];
72 r = load_dir_file(data, sizeof(data), certs.gl_pathv[i], "data");
73 if (r == -1) {
74 ret = -1;
75 break;
76 }
77
78 struct ninedogs_cert cert;
79 r = nd_bin2struct_cert(&cert, data, r);
80 if (r == -1) {
81 ret = -1;
82 break;
83 }
84
85 if (cert.not_after < (unsigned long) now.tv_sec) // already expired
86 continue;
87
88 if (cert.not_after - hours * 3600 >= (unsigned long) now.tv_sec) // expire in the future
89 continue;
90
91 char not_before[32], not_after[32];
92 nd_ts_to_str(not_before, sizeof(not_before), cert.not_before);
93 nd_ts_to_str(not_after, sizeof(not_after), cert.not_after);
94 xlog(0, " subj=[%s] path=[%s] issuer=[%s] serial=[%s] %s -> %s\n",
95 cert.subj, cert.path, cert.issuer, cert.serial, not_before, not_after);
96 nd_str_append(msg, sizeof(msg), &msg_off,
97 "%sSubject: %s\nIssuer: %s\nPath: %s\nSerial: %s"
98 "\nNot before: %s\nNot after: %s\n",
99 add, cert.subj, cert.issuer, cert.path, cert.serial,
100 not_before, not_after);
101 add = "\n\n";
102
103 glob_t users;
104 r = nd_load_cert_users(&users, certs.gl_pathv[i]);
105 if (r == -1) {
106 ret = -1;
107 break;
108 }
109 nd_str_append(msg, sizeof(msg), &msg_off, "Users:\n");
110 for (unsigned j = 0; j < users.gl_pathc; j++) {
111 // example: /var/lib/ninedogs/users/by-uid/01/00/00000001/cert/dcf86835cf357b94393a/users/ba/ba446a981b387e831db3f6a730c55552/379561e8
112 // Warning! dirname modifies string in place!
113
114 unsigned char data[4096];
115 int r = load_file(data, sizeof(data), users.gl_pathv[j]);
116 if (r == -1)
117 return -1;
118 struct ninedogs_app app;
119 r = nd_bin2struct_app(&app, data, r);
120 if (r == -1) {
121 ret = -1;
122 break;
123 }
124
125 char *q = dirname(users.gl_pathv[j]);
126 char *user_client_id = basename(q); q = dirname(q);
127 char cmd[4096], sts[64];
128 nd_app_nice(cmd, sizeof(cmd), app.cmdline, app.cmdline_len);
129 nd_ts_to_str(sts, sizeof(sts), app.ts / 1000);
130 xlog(0, " user_client_id=[%s]"
131 "\n cmdline=[%s] ts=%lld [%s]\n",
132 user_client_id, cmd, app.ts, sts);
133 nd_str_append(msg, sizeof(msg), &msg_off,
134 " Command: %s\n Last start of command: %s\n",
135 cmd, sts);
136 }
137 globfree(&users);
138 xlog(0, "\n");
139 if (ret == -1)
140 break;
141 count++;
142 }
143 globfree(&certs);
144 if (ret != 0)
145 return ret;
146
147 xlog(1, "%s: msg:\n=======================\n%s\n=================\n", __func__, msg);
148 char subject[128];
149 snprintf(subject, sizeof(subject),
150 "Expiring certificates (%u)", count);
151 nd_user_notify(uid, subject, msg);
152
153 return ret;
154 }
155
156 int main(void)
157 {
158 nd_for_each_user(user_cb);
159
160 return 0;
161 }
File tools/ninedogs-cert-notify.service added (mode: 100644) (index 0000000..96ce6ec)
1 [Unit]
2 Description = Notify users about certificates problems (about to expire etc.)
3 Documentation = https://rocketgit.com/user/catalinux/ninedogs
4
5 [Service]
6 ExecStart = /usr/bin/cert-notify
7 Type = simple
8 User = ninedogs
9 Group = ninedogs
File tools/ninedogs-cert-notify.timer added (mode: 100644) (index 0000000..50b2ce1)
1 [Unit]
2 Description = Notify users about certificates problems (about to expire etc.)
3
4 [Timer]
5 OnCalendar = hourly
6 Persistent = true
7
8 [Install]
9 WantedBy=timers.target
File trace/.gitignore changed (mode: 100644) (index c9b8944..6b00866)
1 1 nd-trace nd-trace
2 show-colors
File trace/Makefile changed (mode: 100644) (index 9cefeea..0a39190)
1 # This is just to allow us to run make here
2 .PHONY: all
3 all:
4 make -R -C .. trace
1 include ../Makefile.common
5 2
6 3 COMMON_H += ../common/shared.h ../common/tools.h ../common/decode_text.h \ COMMON_H += ../common/shared.h ../common/tools.h ../common/decode_text.h \
7 ../common/ids.h
4 ../common/ids.h ../common/params.h
8 5
9 6 CFLAGS += -I../common CFLAGS += -I../common
10 7
11 8 OBJS := ../common/tools.o ../common/decode_text.o OBJS := ../common/tools.o ../common/decode_text.o
12 9
13 #decode.o: decode.c decode.h process_db.h $(COMMON_H)
14 # $(CC) $(CFLAGS) -fPIC -c -o $@ $<
10 all: nd-trace
15 11
16 12 nd-trace: nd-trace.c $(COMMON_H) $(OBJS) nd-trace: nd-trace.c $(COMMON_H) $(OBJS)
17 13 $(CC) $(CFLAGS) $@.c -o $@ $(OBJS) $(LIBS) $(CC) $(CFLAGS) $@.c -o $@ $(OBJS) $(LIBS)
18 14
19 compile: nd-trace
20
21 15 .PHONY: clean .PHONY: clean
22 16 clean: clean:
23 17 @rm -f nd-trace *.strace *.log *.out *.o @rm -f nd-trace *.strace *.log *.out *.o
File trace/TODO changed (mode: 100644) (index d8d97e0..c37a8c0)
4 4
5 5 == Non urgent == == Non urgent ==
6 6 [ ] We need to respect UTF-8 in bin2hex_ascii [ ] We need to respect UTF-8 in bin2hex_ascii
7 [ ] show if a semaphore is locked or not
8 [ ] Ask the 'server' to provide the prepared statement/connection if we attached too late.
9 [ ] How much time it took (Bogdan S).
10 [ ] Colors (Bogdan S).
11 [ ] Do not use colors if output is not a tty!
12 [ ] When using TLS, trace also meta info: expiration, CN etc.
7 13 [ ] [ ]
8
File trace/nd-trace.c changed (mode: 100644) (index 2265606..375f3e5)
25 25 #include <unistd.h> #include <unistd.h>
26 26
27 27 #include "ids.h" #include "ids.h"
28 #include "params.h"
28 29 #include "shared.h" #include "shared.h"
29 30 #include "tools.h" #include "tools.h"
30 31 #include "decode_text.h" #include "decode_text.h"
31 32
33 struct theme
34 {
35 char *name;
36 unsigned int colors;
37 unsigned int color_default;
38
39 unsigned int color_func_i_c, color_func_i_r, color_func_i_m;
40 unsigned int color_func_n_c, color_func_n_r, color_func_n_m;
41 unsigned int color_ts_s, color_ts_e, color_ts_bad;
42 unsigned int color_ret_ok, color_ret_error, color_flags;
43 };
44
45 static const struct theme themes[] =
46 {
47 { .name = "def",
48 .colors = 256, .color_default = 3,
49 .color_func_i_c = 196, .color_func_i_r = 202, .color_func_i_m = 207,
50 .color_func_n_c = 46, .color_func_n_r = 70, .color_func_n_m = 90,
51 .color_ts_s = 246, .color_ts_e = 255, .color_ts_bad = 196,
52 .color_ret_ok = 48, .color_ret_error = 197, .color_flags = 46
53 },
54 { .name = NULL }
55 };
56 static const char *theme_name = "def";
57 static const char *theme_s1 = "", *theme_s2 = "", *theme_e = "";
58 static const struct theme *theme = NULL;
59
32 60 static const struct option options[] = static const struct option options[] =
33 61 { {
34 {"pid", required_argument, NULL, 'p'},
35 {"output", required_argument, NULL, 'o'},
36 {NULL, 0, NULL, 0}
62 {"pid", required_argument, NULL, 'p'},
63 {"output", required_argument, NULL, 'o'},
64 {"only-high-level", no_argument, NULL, 'H'},
65 {"theme", required_argument, NULL, 't'},
66 {NULL, 0, NULL, 0}
37 67 }; };
38 68
39 69 static void usage(void) static void usage(void)
40 70 { {
41 71 fprintf(stderr, fprintf(stderr,
42 72 "Usage: nd-trace [options]\n" "Usage: nd-trace [options]\n"
43 " --pid -p pid to trace (can be added multiple times)\n"
44 " --output -o where to store the output\n"
73 " --pid -p pid to trace (can be added multiple times)\n"
74 " --output -o where to store the output\n"
75 " --only-high-level -H log only high level, if possible\n"
76 " --theme -t do not show output with colors ['def']\n"
77 " If output is not a tty, no theme is used\n"
45 78 "\n"); "\n");
46 79 exit(1); exit(1);
47 80 } }
48 81
49 82 static FILE *outf; static FILE *outf;
50 83 static unsigned int do_exit; static unsigned int do_exit;
84 static pid_t pids[256];
85 static unsigned int no_pids;
86 static char only_high_level;
87 static uint64_t last_ts;
88
89 /*
90 * Set the theme
91 */
92 static void nd_trace_color_set_theme(void)
93 {
94 unsigned theme_colors;
95
96 if (!isatty(fileno(outf)))
97 return;
98
99 const char *term = getenv("TERM");
100 //fprintf(outf, "TERM=[%s]\n", term); fflush(outf);
101 if (term == NULL)
102 return;
103
104 if (strcmp(term, "xterm-256color") == 0) {
105 theme_colors = 256;
106 } else if (strcmp(term, "xterm") == 0) {
107 theme_colors = 16;
108 } else {
109 return;
110 }
111
112 //fprintf(outf, "Searching for theme [%s] and %u colors...\n",
113 // theme_name, theme_colors); fflush(outf);
114 for (int i = 0; themes[i].name != NULL; i++) {
115 if (strcmp(themes[i].name, theme_name) != 0)
116 continue;
117 if (themes[i].colors != theme_colors)
118 continue;
119 theme = &themes[i];
120 break;
121 }
122 if (!theme) {
123 fprintf(outf, " Theme [%s/%u] not found, using no theme.\n",
124 theme_name, theme_colors);
125 return;
126 }
127
128 if (theme->colors == 16) {
129 theme_s1 = "\x1b["; theme_s2 = "m";
130 theme_e = "\x1b[0m";
131 } else if (theme->colors == 256) {
132 theme_s1 = "\x1b[38;5;"; theme_s2 = "m";
133 theme_e = "\x1b[0m";
134 }
135
136 fprintf(outf, "Theme set to [%s] based on term [%s]; colors=%u\n",
137 theme->name, term, theme->colors);
138 }
139
140 /*
141 * Color output
142 */
143 static void nd_trace_color(char *out, const size_t out_size,
144 const char *str, const char *category, const char type,
145 const char *flags, const uint64_t u64)
146 {
147 char scolor[4] = { 0 };
148 //fprintf(outf, "%s: str=[%s] category=[%s] u64=%lu\n",
149 // __func__, str, category, u64); fflush(outf);
150
151 if (!theme)
152 goto no_theme;
153
154 unsigned color = theme->color_default;
155 if (strcmp(category, "func") == 0) {
156 if (strstr("i", flags)) {
157 if ((type == 'c') || (type == 'R'))
158 color = theme->color_func_i_c;
159 else if (type == 'r')
160 color = theme->color_func_i_r;
161 else if (type == 'm')
162 color = theme->color_func_i_m;
163 } else {
164 if ((type == 'c') || (type == 'R'))
165 color = theme->color_func_n_c;
166 else if (type == 'r')
167 color = theme->color_func_n_r;
168 else if (type == 'm')
169 color = theme->color_func_n_m;
170 }
171 } else if (strcmp(category, "ts") == 0) { // 'u64' contains milliseconds
172 if (u64 >= 2000)
173 color = theme->color_ts_bad;
174 else if (u64 >= 1000)
175 color = theme->color_ts_e;
176 else
177 color = theme->color_ts_s + u64 / 100;
178 } else if (strcmp(category, "error") == 0) {
179 if (u64 == 0)
180 color = theme->color_ret_ok;
181 else
182 color = theme->color_ret_error;
183 } else if (strcmp(category, "flags") == 0) {
184 color = theme->color_flags;
185 }
186 snprintf(scolor, sizeof(scolor), "%u", color);
187
188 no_theme:
189 int r = snprintf(out, out_size, "%s%s%s%s%s",
190 theme_s1, scolor, theme_s2, str, theme_e);
191 // we will not color things if we do not have enough space
192 if ((unsigned) r > out_size)
193 snprintf(out, out_size, "%s", str);
194 }
195
51 196
52 197 static uint8_t decode8(unsigned char *d, unsigned int *i) static uint8_t decode8(unsigned char *d, unsigned int *i)
53 198 { {
 
... ... static uint64_t decode64(unsigned char *d, unsigned int *i)
81 226 return be64toh(u); return be64toh(u);
82 227 } }
83 228
84 static uint8_t decode_bool(const char *prefix, char *out, size_t out_size,
229 static uint8_t decode_bool(const char *prefix, char *out0, size_t out_size,
85 230 unsigned char *d, unsigned int *i) unsigned char *d, unsigned int *i)
86 231 { {
232 char out[out_size];
233
87 234 uint8_t v = d[*i]; *i = *i + 1; uint8_t v = d[*i]; *i = *i + 1;
88 235 snprintf(out, out_size, "%s%s", prefix, v == 0 ? "nok" : "ok"); snprintf(out, out_size, "%s%s", prefix, v == 0 ? "nok" : "ok");
236 nd_trace_color(out0, out_size, out, "error", '-', "", 0);
89 237 return v; return v;
90 238 } }
91 239
92 240 // TODO: more to add from /usr/include/asm-generic/errno.h // TODO: more to add from /usr/include/asm-generic/errno.h
93 static void decode_errno(char *out, unsigned out_max, const int e)
241 // TODO: move this in common
242 static void decode_errno(char *out0, unsigned out_max, const int e)
94 243 { {
244 char out[out_max];
245
95 246 switch (e) { switch (e) {
96 247 case EPERM: snprintf(out, out_max, "EPERM"); break; case EPERM: snprintf(out, out_max, "EPERM"); break;
97 248 case ENOENT: snprintf(out, out_max, "ENOENT"); break; case ENOENT: snprintf(out, out_max, "ENOENT"); break;
 
... ... static void decode_errno(char *out, unsigned out_max, const int e)
134 285
135 286 default: snprintf(out, out_max, "%d", e); break; default: snprintf(out, out_max, "%d", e); break;
136 287 } }
288
289 nd_trace_color(out0, out_max, out, "error", '-', "", 0);
137 290 } }
138 291
139 292 static int decode_ret_int(char *out, unsigned out_max, static int decode_ret_int(char *out, unsigned out_max,
 
... ... static void *decode_ret_pointer(char *out, unsigned out_max,
179 332 return ret; return ret;
180 333 } }
181 334
335 char out2[32];
336 nd_trace_color(out2, sizeof(out2), "NULL", "error", '-', "", 0);
337 snprintf(out, out_max, " = %s", out2);
338
339 return ret;
340 }
341
342 static void *decode_ret_pointer_errno(char *out, unsigned out_max,
343 unsigned char *d, unsigned int *i)
344 {
345 void *ret = (void *) decode64(d, i);
346 if (ret) {
347 snprintf(out, out_max, " = %p", ret);
348 return ret;
349 }
350
182 351 int xerrno = decode32(d, i); int xerrno = decode32(d, i);
183 352 char err[64]; char err[64];
184 353 decode_errno(err, sizeof(err), xerrno); decode_errno(err, sizeof(err), xerrno);
185 snprintf(out, out_max, " = %p (%s)", ret, err);
354 char out2[64];
355 nd_trace_color(out2, sizeof(out2), err, "error", '-', "", 0);
356 snprintf(out, out_max, " = %p (%s)", ret, out2);
186 357
187 358 return ret; return ret;
188 359 } }
 
... ... static socklen_t decode_sockaddr(char *out, unsigned char *d, unsigned int *i)
218 389 return sl; return sl;
219 390 } }
220 391
221 static int decode_sock_level(char *out, unsigned out_size,
392 static int decode_sock_level(char *out0, unsigned out_size,
222 393 unsigned char *d, unsigned int *i) unsigned char *d, unsigned int *i)
223 394 { {
395 char out[out_size];
396
224 397 int level = decode32(d, i); int level = decode32(d, i);
225 398
226 399 switch (level) { switch (level) {
 
... ... static int decode_sock_level(char *out, unsigned out_size,
236 409 default: snprintf(out, out_size, "todo(%d)", level); break; default: snprintf(out, out_size, "todo(%d)", level); break;
237 410 } }
238 411
412 nd_trace_color(out0, out_size, out, "flags", '-', "", 0);
239 413 return level; return level;
240 414 } }
241 415
 
... ... static void decode_sock_optname_socket(char *out, unsigned out_size,
265 439 } }
266 440 } }
267 441
442 #ifndef IP_RECVERR_RFC4884
443 #define IP_RECVERR_RFC4884 26
444 #endif
268 445 static void decode_sock_optname_ip(char *out, unsigned out_size, static void decode_sock_optname_ip(char *out, unsigned out_size,
269 446 const int optname) const int optname)
270 447 { {
 
... ... static void decode_sock_optname_ip(char *out, unsigned out_size,
326 503 } }
327 504 } }
328 505
506 #ifndef IPV6_MULTICAST_ALL
507 #define IPV6_MULTICAST_ALL 29
508 #endif
509 #ifndef IPV6_ROUTER_ALERT_ISOLATE
510 #define IPV6_ROUTER_ALERT_ISOLATE 30
511 #endif
512 #ifndef IPV6_RECVERR_RFC4884
513 #define IPV6_RECVERR_RFC4884 31
514 #endif
329 515 static void decode_sock_optname_ipv6(char *out, unsigned out_size, static void decode_sock_optname_ipv6(char *out, unsigned out_size,
330 516 const int optname) const int optname)
331 517 { {
 
... ... static void decode_sock_optname_ipv6(char *out, unsigned out_size,
388 574 } }
389 575 } }
390 576
577 #ifndef TCP_ZEROCOPY_RECEIVE
578 #define TCP_ZEROCOPY_RECEIVE 35
579 #endif
580 #ifndef TCP_INQ
581 #define TCP_INQ 36
582 #endif
583 #ifndef TCP_TX_DELAY
584 #define TCP_TX_DELAY 37
585 #endif
586 #ifndef UDP_GRO
587 #define UDP_GRO 104
588 #endif
391 589 static void decode_sock_optname_tcp(char *out, unsigned out_size, static void decode_sock_optname_tcp(char *out, unsigned out_size,
392 590 const int optname) const int optname)
393 591 { {
 
... ... static void decode_sock_optname_tcp(char *out, unsigned out_size,
434 632 } }
435 633 } }
436 634
635 #ifndef UDP_SEGMENT
636 #define UDP_SEGMENT 103
637 #endif
437 638 static void decode_sock_optname_udp(char *out, unsigned out_size, static void decode_sock_optname_udp(char *out, unsigned out_size,
438 639 const int optname) const int optname)
439 640 { {
 
... ... static int decode_mysqli_mode(char *out, size_t out_size,
696 897 } }
697 898
698 899 static void decode_query_params(char *out, size_t out_size, static void decode_query_params(char *out, size_t out_size,
699 unsigned char *d, unsigned int *i)
900 unsigned char filter_bind_way, unsigned char *d, unsigned int *i)
700 901 { {
902 unsigned short j;
701 903 size_t len, rest = out_size - 1 - 1; // -1 for \0 and -1 for '}' size_t len, rest = out_size - 1 - 1; // -1 for \0 and -1 for '}'
702 904
703 uint16_t params_len = decode16(d, i);
704 if (params_len == 0) {
705 out[0] = '\0';
706 return;
707 }
905 //fprintf(outf, "%s: filter_bind_way=%hhu\n", __func__, filter_bind_way);
708 906
709 907 if (rest >= 2) { if (rest >= 2) {
710 908 strcpy(out, " {"); strcpy(out, " {");
 
... ... static void decode_query_params(char *out, size_t out_size,
712 910 } }
713 911
714 912 char *add = "", do_break = 0; char *add = "", do_break = 0;
715 for (unsigned short j = 0; j < params_len; j++) {
913 j = 1;
914 while (1) {
716 915 char value[64]; char value[64];
717 916 uint8_t type = decode8(d, i); uint8_t type = decode8(d, i);
718 if (type == 0) { // NULL
917 if (type == ND_TYPE_LAST)
918 break;
919
920 uint8_t bind_info = decode8(d, i); // (o->bind_way << 2) | o->bind_type
921 uint8_t bind_type = bind_info & 3;
922 uint8_t bind_way = (bind_info >> 2) & 3;
923 char head[128];
924
925 const char *way = "";
926 if (bind_way == ND_PARAMS_BIND_WAY_IN)
927 way = "IN:";
928 else if (bind_way == ND_PARAMS_BIND_WAY_OUT)
929 way = "OUT:";
930 else if (bind_way == ND_PARAMS_BIND_WAY_BOTH)
931 way = "IN/OUT:";
932
933 //fprintf(outf, " filter_bind_way=[%s] type=%hhu bind_type=%hhu bind_way=%hhu\n",
934 // way, type, bind_type, bind_way);
935
936 if (bind_type == ND_PARAMS_BIND_TYPE_NAME) {
937 uint8_t name_len = decode8(d, i);
938 char name[name_len * 4 + 1];
939 bin2hex_ascii(name, d + *i, name_len); *i = *i + name_len;
940 snprintf(head, sizeof(head), "%s'%s'", way, name);
941 } else if (bind_type == ND_PARAMS_BIND_TYPE_POS) {
942 snprintf(head, sizeof(head), "%s%hu", way, decode16(d, i));
943 } else {
944 snprintf(head, sizeof(head), "%s%hu", way, j);
945 }
946
947 if (type == ND_TYPE_NULL) { // NULL
719 948 snprintf(value, sizeof(value), snprintf(value, sizeof(value),
720 "%hu:NULL", j + 1);
721 } else if (type == 1) { // long
949 "%s:NULL", head);
950 } else if (type == ND_TYPE_INT) {
722 951 snprintf(value, sizeof(value), snprintf(value, sizeof(value),
723 "%hu:long:%ld", j + 1, decode64(d, i));
724 } else if (type == 2) { // double
952 "%s:int:%d", head, decode32(d, i));
953 } else if (type == ND_TYPE_LONG) {
954 snprintf(value, sizeof(value),
955 "%s:long:%ld", head, decode64(d, i));
956 } else if (type == ND_TYPE_DOUBLE) {
725 957 double dd; double dd;
726 958 uint64_t u = decode64(d, i); uint64_t u = decode64(d, i);
727 959 memcpy(&dd, &u, 8); memcpy(&dd, &u, 8);
728 960 snprintf(value, sizeof(value), snprintf(value, sizeof(value),
729 "%hu:double:%f", j + 1, dd);
730 } else if (type == 3) { // string
961 "%s:double:%f", head, dd);
962 } else if ((type == ND_TYPE_STRING) || (type == ND_TYPE_UNK)) {
731 963 uint16_t len = decode16(d, i); uint16_t len = decode16(d, i);
732 964 char s[len * 4 + 1]; char s[len * 4 + 1];
733 965 bin2hex_ascii(s, d + *i, len); *i = *i + len; bin2hex_ascii(s, d + *i, len); *i = *i + len;
734 966 snprintf(value, sizeof(value), snprintf(value, sizeof(value),
735 "%hu:str:'%s'", j + 1, s);
967 "%s:str:'%s'", head, s);
736 968 } else { } else {
737 969 snprintf(value, sizeof(value), snprintf(value, sizeof(value),
738 "%hu:unk, ...", j + 1);
970 "%s:unk, ...", head);
739 971 do_break = 1; // we cannot continue do_break = 1; // we cannot continue
740 972 } }
741 973
 
... ... static void decode_query_params(char *out, size_t out_size,
743 975 if (len > rest) if (len > rest)
744 976 break; break;
745 977
746 strcat(out, add);
747 strcat(out, value);
748 add = ", ";
749 rest -= len;
978 if (filter_bind_way & bind_way) {
979 strcat(out, add);
980 strcat(out, value);
981 add = ", ";
982 rest -= len;
983 }
750 984
751 985 if (do_break) if (do_break)
752 986 break; break;
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
909 1143 { {
910 1144 unsigned int i = 0; unsigned int i = 0;
911 1145 unsigned short func_len, trace_depth; unsigned short func_len, trace_depth;
912 char type, line[64000], rest[2000];
1146 char type, line[64000], line2[64000], rest[4000];
913 1147 uint64_t t; uint64_t t;
914 1148
915 1149 line[0] = '\0'; line[0] = '\0';
1150 line2[0] = '\0';
916 1151 rest[0] = '\0'; rest[0] = '\0';
917 1152
918 1153 t = decode64(d, &i); t = decode64(d, &i);
1154 uint8_t tf_len = decode8(d, &i);
1155 char tf[tf_len + 1];
1156 memcpy(tf, d + i, tf_len); i += tf_len;
1157 tf[tf_len] = '\0';
919 1158 trace_depth = decode16(d, &i); trace_depth = decode16(d, &i);
920 1159 func_len = decode16(d, &i); func_len = decode16(d, &i);
921 1160 char func[func_len * 4 + 1]; char func[func_len * 4 + 1];
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
923 1162 type = d[i++]; type = d[i++];
924 1163 uint32_t pid = decode32(d, &i); uint32_t pid = decode32(d, &i);
925 1164 uint32_t tid = decode32(d, &i); uint32_t tid = decode32(d, &i);
926 //fprintf(outf, "%s: t=%lu func_len=%hu func=[%s] type=%c pid=%u tid=%u\n",
927 // __func__, t, func_len, func, type, pid, tid);
1165 //fprintf(outf, "%s: t=%lu func_len=%hu func=[%s] tf=[%s] type=%c pid=%u tid=%u\n",
1166 // __func__, t, func_len, func, tf, type, pid, tid);
1167
1168 if (only_high_level && !strstr(tf, "i"))
1169 return;
928 1170
929 1171 switch (func[0]) { switch (func[0]) {
930 1172 case '-': // project specific case '-': // project specific
931 1173 if (strcmp(func, "-stop") == 0) { if (strcmp(func, "-stop") == 0) {
932 1174 int ret = decode32(d, &i); int ret = decode32(d, &i);
933 sprintf(line, "() = %d", ret);
1175 sprintf(rest, "exit code = %d", ret);
1176 char color[64];
1177 nd_trace_color(color, sizeof(color), rest, "error", '-', "", ret);
1178 sprintf(line, ": %s", color);
934 1179 if (pid == parent) do_exit++; if (pid == parent) do_exit++;
935 1180 } else if (strcmp(func, "-segv") == 0) { } else if (strcmp(func, "-segv") == 0) {
936 1181 int r = decode32(d, &i); int r = decode32(d, &i);
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
943 1188 strcat(line, l); strcat(line, l);
944 1189 } }
945 1190 if (pid == parent) do_exit++; if (pid == parent) do_exit++;
1191 } else if (strcmp(func, "-msgs_lost") == 0) {
1192 sprintf(rest, "ninedogs: messages lost: %u", decode32(d, &i));
1193 nd_trace_color(line, sizeof(line), rest, "error", '-', "", 1);
946 1194 } break; } break;
947 1195
948 1196 case 'a': case 'a':
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1018 1266 uint8_t oplen = decode8(d, &i); uint8_t oplen = decode8(d, &i);
1019 1267 char op[oplen * 4 + 1]; char op[oplen * 4 + 1];
1020 1268 bin2hex_ascii(op, d + i, oplen); i += oplen; bin2hex_ascii(op, d + i, oplen); i += oplen;
1021 char types[4096];
1269 char types[4096], types2[4096];
1022 1270 decode_types(types, sizeof(types), d, &i); decode_types(types, sizeof(types), d, &i);
1271 nd_trace_color(types2, sizeof(types2), types, "flags", type, tf, 0);
1023 1272 if (type == 'r') { if (type == 'r') {
1024 uint8_t ret = decode8(d, &i);
1273 uint8_t ret = decode8(d, &i); // TODO: decode error
1025 1274 snprintf(rest, sizeof(rest), " = %s", ret == 1 ? "ok" : "nok"); snprintf(rest, sizeof(rest), " = %s", ret == 1 ? "ok" : "nok");
1026 1275 } }
1027 sprintf(line, "(0x%lx, %s, %s)%s", handle, op, types, rest);
1276 sprintf(line, "(0x%lx, %s, %s)%s", handle, op, types2, rest);
1028 1277 } else if (strcmp(func, "curl_exec") == 0) { // php } else if (strcmp(func, "curl_exec") == 0) { // php
1029 1278 uint64_t handle = decode64(d, &i); uint64_t handle = decode64(d, &i);
1030 1279 if (type == 'r') { if (type == 'r') {
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1047 1296 } else if (strcmp(func, "curl_easy_perform") == 0) { } else if (strcmp(func, "curl_easy_perform") == 0) {
1048 1297 if (type == 'm') { if (type == 'm') {
1049 1298 uint8_t len = decode8(d, &i); uint8_t len = decode8(d, &i);
1050 char info[len * 4 + 1];
1299 char info[len * 4 + 1], info2[len * 4 + 1];
1051 1300 bin2hex_ascii(info, d + i, len); i += len; bin2hex_ascii(info, d + i, len); i += len;
1301 nd_trace_color(info2, sizeof(info2), info, "flags", type, tf, 0);
1052 1302 uint64_t handle = decode64(d, &i); uint64_t handle = decode64(d, &i);
1053 1303 uint16_t post_len = decode16(d, &i); uint16_t post_len = decode16(d, &i);
1054 1304 char post[post_len * 4 + 1]; char post[post_len * 4 + 1];
1055 1305 bin2hex_ascii(post, d + i, post_len); i += post_len; bin2hex_ascii(post, d + i, post_len); i += post_len;
1056 sprintf(line, "(0x%lx) %s: %s", handle, info, post);
1306 sprintf(line, "(0x%lx): meta: %s: %s", handle, info2, post);
1057 1307 } else { } else {
1058 1308 uint64_t handle = decode64(d, &i); uint64_t handle = decode64(d, &i);
1059 1309 if (type == 'r') { if (type == 'r') {
1060 1310 int ret = decode32(d, &i); int ret = decode32(d, &i);
1061 1311 nd_decode_curl_code(rest, sizeof(rest), ret); nd_decode_curl_code(rest, sizeof(rest), ret);
1062 sprintf(line, "(0x%lx) = %s", handle, rest);
1312 char sret[sizeof(rest)];
1313 nd_trace_color(sret, sizeof(sret), rest,
1314 "error", type, tf, ret == 0 ? 0 : 1);
1315 sprintf(line, "(0x%lx) = %s", handle, sret);
1063 1316 } else { } else {
1064 1317 sprintf(line, "(0x%lx)", handle); sprintf(line, "(0x%lx)", handle);
1065 1318 } }
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1069 1322 uint64_t handle = decode64(d, &i); uint64_t handle = decode64(d, &i);
1070 1323 uint8_t type = decode8(d, &i); uint8_t type = decode8(d, &i);
1071 1324 uint8_t option_len = decode8(d, &i); uint8_t option_len = decode8(d, &i);
1072 char option[option_len * 4 + 1];
1325 char option[option_len * 4 + 1], option2[option_len * 4 + 32];
1073 1326 bin2hex_ascii(option, d + i, option_len); i += option_len; bin2hex_ascii(option, d + i, option_len); i += option_len;
1327 nd_trace_color(option2, sizeof(option2), option, "flags", type, tf, 0);
1074 1328 if ((type == 0) || (type == 2)) { // long or off_t if ((type == 0) || (type == 2)) { // long or off_t
1075 1329 snprintf(rest, sizeof(rest), "%ld", decode64(d, &i)); snprintf(rest, sizeof(rest), "%ld", decode64(d, &i));
1076 1330 } else if ((type == 3) || (type == 4)) { // object or string } else if ((type == 3) || (type == 4)) { // object or string
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1090 1344 snprintf(rest, sizeof(rest), "%p", (void *) decode64(d, &i)); snprintf(rest, sizeof(rest), "%p", (void *) decode64(d, &i));
1091 1345 } }
1092 1346 int ret = decode32(d, &i); int ret = decode32(d, &i);
1093 char sret[32];
1347 char sret[32], sret2[64];
1094 1348 nd_decode_curl_code(sret, sizeof(sret), ret); nd_decode_curl_code(sret, sizeof(sret), ret);
1349 nd_trace_color(sret2, sizeof(sret2), sret,
1350 "error", type, tf, ret == 0 ? 0 : 1);
1095 1351 sprintf(line, "(0x%lx, %s, %s) = %s", sprintf(line, "(0x%lx, %s, %s) = %s",
1096 handle, option, rest, sret);
1352 handle, option2, rest, sret2);
1097 1353 } break; } break;
1098 1354
1099 1355 case 'd': case 'd':
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1104 1360 char flags[128]; char flags[128];
1105 1361 decode_dlopen_flags(flags, sizeof(flags), d, &i); decode_dlopen_flags(flags, sizeof(flags), d, &i);
1106 1362 if (type == 'r') if (type == 'r')
1107 decode_ret_pointer(rest, sizeof(rest), d, &i);
1363 decode_ret_pointer_errno(rest, sizeof(rest), d, &i);
1108 1364 sprintf(line, "('%s', '%s')%s", filename, flags, rest); sprintf(line, "('%s', '%s')%s", filename, flags, rest);
1109 1365 } else if (strcmp(func, "dlclose") == 0) { } else if (strcmp(func, "dlclose") == 0) {
1110 1366 void *h = (void *) decode64(d, &i); void *h = (void *) decode64(d, &i);
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1121 1377 decode_string_array(argv, sizeof(argv), d, &i); decode_string_array(argv, sizeof(argv), d, &i);
1122 1378 decode_string_array(envp, sizeof(envp), d, &i); decode_string_array(envp, sizeof(envp), d, &i);
1123 1379 if (type == 'r') if (type == 'r')
1124 decode_ret_pointer(rest, sizeof(rest), d, &i);
1380 decode_ret_pointer_errno(rest, sizeof(rest), d, &i);
1125 1381 sprintf(line, "('%s', %s, %s)%s", sprintf(line, "('%s', %s, %s)%s",
1126 1382 pathname, argv, envp, rest); pathname, argv, envp, rest);
1383 // special action here. We need to switch to the new pid
1384 // TODO: close previous one?
1385 if (no_pids < 256) {
1386 pids[no_pids] = pid;
1387 no_pids++;
1388 }
1127 1389 } break; } break;
1128 1390
1129 1391 case 'f': case 'f':
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1140 1402 decode_stat(sstat, sizeof(sstat), d, &i); decode_stat(sstat, sizeof(sstat), d, &i);
1141 1403 int flags = decode32(d, &i); int flags = decode32(d, &i);
1142 1404 if (type == 'r') if (type == 'r')
1143 decode_ret_pointer(rest, sizeof(rest), d, &i);
1405 decode_ret_pointer_errno(rest, sizeof(rest), d, &i);
1144 1406 sprintf(line, "(%s, '%s', {%s}, 0x%x)%s", sprintf(line, "(%s, '%s', {%s}, 0x%x)%s",
1145 1407 dirfd, pathname, sstat, flags, rest); dirfd, pathname, sstat, flags, rest);
1146 1408 } else if ((strcmp(func, "fsync") == 0) } else if ((strcmp(func, "fsync") == 0)
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1149 1411 if (type == 'r') if (type == 'r')
1150 1412 decode_ret_int(rest, sizeof(rest), d, &i); decode_ret_int(rest, sizeof(rest), d, &i);
1151 1413 sprintf(line, "(%d)%s", fd, rest); sprintf(line, "(%d)%s", fd, rest);
1414 } else if (strcmp(func, "ftruncate") == 0) {
1415 int fd = decode32(d, &i);
1416 uint64_t len = decode64(d, &i);
1417 if (type == 'r')
1418 decode_ret_int(rest, sizeof(rest), d, &i);
1419 sprintf(line, "(fd=%d, len=%lu)%s", fd, len, rest);
1152 1420 } break; } break;
1153 1421
1154 1422 case 'g': case 'g':
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1234 1502 sock, level, optname, optval, optlen, rest); sock, level, optname, optval, optlen, rest);
1235 1503 } break; } break;
1236 1504
1505 case 'i':
1506 if ((strcmp(func, "imagecreate") == 0)
1507 || (strcmp(func, "imagecreatetruecolor") == 0)) {
1508 uint64_t w = decode64(d, &i);
1509 uint64_t h = decode64(d, &i);
1510 decode_ret_pointer(rest, sizeof(rest), d, &i);
1511 sprintf(line, "(w=%lu, h=%lu)%s", w, h, rest);
1512 } else if (strcmp(func, "imagedestroy") == 0) {
1513 uint64_t im = decode64(d, &i);
1514 uint32_t elap_ms = decode32(d, &i);
1515 decode_bool("", rest, sizeof(rest), d, &i);
1516 char elap[64], elap2[64];
1517 snprintf(elap, sizeof(elap), "[image generation time: %ums]", elap_ms);
1518 nd_trace_color(elap2, sizeof(elap2), elap, "ts", type, tf, elap_ms);
1519 sprintf(line, "(0x%lx) = %s %s", im, rest, elap2);
1520 }
1521 break;
1522
1523 case 'j':
1524 if (strcmp(func, "java/db/connect") == 0) {
1525 char db_type = decode8(d, &i);
1526 uint16_t cs_len = decode16(d, &i);
1527 char cs[cs_len * 4 + 1];
1528 bin2hex_ascii(cs, d + i, cs_len); i += cs_len;
1529 if (type == 'r') {
1530 uint64_t dbh = decode64(d, &i);
1531 if (dbh != 0) {
1532 snprintf(rest, sizeof(rest), " = 0x%lx", dbh);
1533 } else {
1534 uint16_t ex_len = decode16(d, &i);
1535 char ex[ex_len * 4 + 1];
1536 bin2hex_ascii(ex, d + i, ex_len); i += ex_len;
1537 snprintf(rest, sizeof(rest), " = nok [%s]", ex);
1538 }
1539 }
1540 sprintf(line, "/%c('%s')%s", db_type, cs, rest);
1541 } else if (strcmp(func, "java/db/close") == 0) {
1542 char db_type = decode8(d, &i);
1543 uint64_t dbh = decode64(d, &i);
1544 sprintf(line, "/%c(0x%lx) = ok", db_type, dbh);
1545 } else if ((strcmp(func, "java/db/prepared/execute") == 0)
1546 || (strcmp(func, "java/db/stmt/execute") == 0)) {
1547 char db_type = decode8(d, &i);
1548 uint64_t stmt = decode64(d, &i);
1549 if (type == 'r') {
1550 uint64_t res = decode64(d, &i);
1551 if (res != 0) {
1552 snprintf(rest, sizeof(rest), " = ok");
1553 } else {
1554 uint16_t ex_len = decode16(d, &i);
1555 char ex[ex_len * 4 + 1];
1556 bin2hex_ascii(ex, d + i, ex_len); i += ex_len;
1557 snprintf(rest, sizeof(rest), " = nok [%s]", ex);
1558 }
1559 }
1560 sprintf(line, "/%c(0x%lx)%s", db_type, stmt, rest);
1561 } else if (strcmp(func, "java/db/prepare") == 0) {
1562 char db_type = decode8(d, &i);
1563 uint64_t dbh = decode64(d, &i);
1564 uint16_t q_len = decode16(d, &i);
1565 char q[q_len * 4 + 1];
1566 bin2hex_ascii(q, d + i, q_len); i += q_len;
1567 if (type == 'r') {
1568 uint64_t stmt = decode64(d, &i);
1569 if (stmt != 0) {
1570 snprintf(rest, sizeof(rest), " = 0x%lx", stmt);
1571 } else {
1572 uint16_t ex_len = decode16(d, &i);
1573 char ex[ex_len * 4 + 1];
1574 bin2hex_ascii(ex, d + i, ex_len); i += ex_len;
1575 snprintf(rest, sizeof(rest), " = nok [%s]", ex);
1576 }
1577 }
1578 sprintf(line, "/%c(0x%lx, '%s')%s", db_type, dbh, q, rest);
1579 } else if (strcmp(func, "java/db/stmt/create") == 0) {
1580 char db_type = decode8(d, &i);
1581 uint64_t dbh = decode64(d, &i);
1582 uint64_t stmt = decode64(d, &i);
1583 if (stmt != 0) {
1584 snprintf(rest, sizeof(rest), " = 0x%lx", stmt);
1585 } else {
1586 uint16_t ex_len = decode16(d, &i);
1587 char ex[ex_len * 4 + 1];
1588 bin2hex_ascii(ex, d + i, ex_len); i += ex_len;
1589 snprintf(rest, sizeof(rest), " = nok [%s]", ex);
1590 }
1591 sprintf(line, "/%c(0x%lx)%s", db_type, dbh, rest);
1592 } else if (strcmp(func, "java/db/stmt/close") == 0) {
1593 char db_type = decode8(d, &i);
1594 uint64_t stmt = decode64(d, &i);
1595 sprintf(line, "/%c(0x%lx) = ok", db_type, stmt);
1596 } else if (strcmp(func, "java/db/stmt/execute/sql") == 0) {
1597 char db_type = decode8(d, &i);
1598 uint64_t stmt = decode64(d, &i);
1599 uint16_t q_len = decode16(d, &i);
1600 char q[q_len * 4 + 1];
1601 bin2hex_ascii(q, d + i, q_len); i += q_len;
1602 if (type == 'r') {
1603 uint64_t res = decode64(d, &i);
1604 if (res != 0) {
1605 snprintf(rest, sizeof(rest), " = 0x%lx", res);
1606 } else {
1607 uint16_t ex_len = decode16(d, &i);
1608 char ex[ex_len * 4 + 1];
1609 bin2hex_ascii(ex, d + i, ex_len); i += ex_len;
1610 snprintf(rest, sizeof(rest), " = nok [%s]", ex);
1611 }
1612 }
1613 sprintf(line, "/%c(0x%lx, '%s')%s", db_type, stmt, q, rest);
1614 } else if (strcmp(func, "java/db/result/get") == 0) {
1615 char db_type = decode8(d, &i);
1616 uint64_t stmt = decode64(d, &i);
1617 if (type == 'r') {
1618 uint64_t res = decode64(d, &i);
1619 if (res != 0) {
1620 snprintf(rest, sizeof(rest), " = 0x%lx", res);
1621 } else {
1622 uint16_t ex_len = decode16(d, &i);
1623 char ex[ex_len * 4 + 1];
1624 bin2hex_ascii(ex, d + i, ex_len); i += ex_len;
1625 snprintf(rest, sizeof(rest), " = nok [%s]", ex);
1626 }
1627 }
1628 sprintf(line, "/%c(0x%lx)%s", db_type, stmt, rest);
1629 } else if (strcmp(func, "java/db/stmt/setInt") == 0) {
1630 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
1631 char db_type = decode8(d, &i);
1632 uint64_t stmt = decode64(d, &i);
1633 uint8_t index = decode8(d, &i);
1634 int32_t value = decode32(d, &i);
1635 uint64_t res = decode64(d, &i);
1636 if (res != 0) {
1637 snprintf(rest, sizeof(rest), " = ok");
1638 } else {
1639 uint16_t ex_len = decode16(d, &i);
1640 char ex[ex_len * 4 + 1];
1641 bin2hex_ascii(ex, d + i, ex_len); i += ex_len;
1642 snprintf(rest, sizeof(rest), " = nok [%s]", ex);
1643 }
1644 sprintf(line, "/%c(0x%lx, %hhu, %d)%s",
1645 db_type, stmt, index, value, rest);
1646 } else if (strcmp(func, "java/db/stmt/setString") == 0) {
1647 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
1648 char db_type = decode8(d, &i);
1649 uint64_t stmt = decode64(d, &i);
1650 uint8_t index = decode8(d, &i);
1651 uint16_t vlen = decode16(d, &i);
1652 char value[vlen * 4 + 1];
1653 bin2hex_ascii(value, d + i, vlen); i += vlen;
1654 uint64_t res = decode64(d, &i);
1655 if (res != 0) {
1656 snprintf(rest, sizeof(rest), " = ok");
1657 } else {
1658 uint16_t ex_len = decode16(d, &i);
1659 char ex[ex_len * 4 + 1];
1660 bin2hex_ascii(ex, d + i, ex_len); i += ex_len;
1661 snprintf(rest, sizeof(rest), " = nok [%s]", ex);
1662 }
1663 sprintf(line, "/%c(0x%lx, %hhu, '%s')%s",
1664 db_type, stmt, index, value, rest);
1665 } break;
1666
1237 1667 case 'l': case 'l':
1238 1668 if (strcmp(func, "listen") == 0) { if (strcmp(func, "listen") == 0) {
1239 1669 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump); //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1345 1775 decode_mysql_real_connect_flags(flags, sizeof(flags), d, &i); decode_mysql_real_connect_flags(flags, sizeof(flags), d, &i);
1346 1776 if (type == 'r') if (type == 'r')
1347 1777 decode_bool(" = ", rest, sizeof(rest), d, &i); decode_bool(" = ", rest, sizeof(rest), d, &i);
1348 sprintf(line, "(link=0x%lx, '%s', flags='%s')%s", link, cs, flags, rest);
1778 sprintf(line, "(link=0x%lx, '%s', flags=%s)%s", link, cs, flags, rest);
1349 1779 } else if (strcmp(func, "mysqli_stmt_bind_param") == 0) { } else if (strcmp(func, "mysqli_stmt_bind_param") == 0) {
1350 1780 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump); //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
1351 1781 uint64_t stmt = decode64(d, &i); uint64_t stmt = decode64(d, &i);
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1356 1786 decode_bool(" = ", rest, sizeof(rest), d, &i); decode_bool(" = ", rest, sizeof(rest), d, &i);
1357 1787 sprintf(line, "(stmt=0x%lx, types='%s', ...)%s", sprintf(line, "(stmt=0x%lx, types='%s', ...)%s",
1358 1788 stmt, types, rest); stmt, types, rest);
1789 } else if (strcmp(func, "mysqli_stmt_close") == 0) {
1790 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
1791 uint64_t stmt = decode64(d, &i);
1792 if (type == 'r') {
1793 uint8_t ret = decode8(d, &i);
1794 snprintf(rest, sizeof(rest), " = %s", ret == 1 ? "ok" : "nok");
1795 }
1796 sprintf(line, "(stmt=0x%lx)%s", stmt, rest);
1359 1797 } else if (strcmp(func, "mysqli_stmt_execute") == 0) { } else if (strcmp(func, "mysqli_stmt_execute") == 0) {
1360 1798 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump); //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
1361 1799 uint64_t stmt = decode64(d, &i); uint64_t stmt = decode64(d, &i);
1362 1800 if (type == 'c') { if (type == 'c') {
1363 decode_query_params(rest, sizeof(rest), d, &i);
1801 decode_query_params(rest, sizeof(rest),
1802 ND_PARAMS_BIND_WAY_BOTH, d, &i);
1364 1803 sprintf(line, "(stmt=0x%lx%s%s)", sprintf(line, "(stmt=0x%lx%s%s)",
1365 1804 stmt, rest[0] ? ", " : "", rest); stmt, rest[0] ? ", " : "", rest);
1366 1805 } else if (type == 'r') { } else if (type == 'r') {
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1404 1843 } break; } break;
1405 1844
1406 1845 case 'o': case 'o':
1407 if ((strcmp(func, "open") == 0)
1846 if (strcmp(func, "oci_bind_by_name") == 0) {
1847 uint64_t stmt = decode64(d, &i);
1848 sprintf(line, "(stmt=0x%lx)", stmt);
1849 } else if (strcmp(func, "oci_close") == 0) {
1850 uint64_t h = decode64(d, &i);
1851 sprintf(line, "(0x%lx)", h);
1852 } else if (strcmp(func, "oci_execute") == 0) {
1853 uint64_t stmt = decode64(d, &i);
1854 uint64_t mode = decode64(d, &i);
1855 if (type == 'r') {
1856 uint8_t ret = decode8(d, &i);
1857 if (ret == 1)
1858 snprintf(rest, sizeof(rest), " = ok");
1859 else
1860 snprintf(rest, sizeof(rest), " = nok");
1861 }
1862 char s_mode[128];
1863 nd_decode_oci_execute_mode(s_mode, sizeof(s_mode), mode);
1864 sprintf(line, "(stmt=0x%lx, %s)%s", stmt, s_mode, rest);
1865 } else if (strcmp(func, "oci_parse") == 0) {
1866 uint64_t dbh = decode64(d, &i);
1867 uint16_t q_len = decode16(d, &i);
1868 char q[q_len * 4 + 1];
1869 bin2hex_ascii(q, d + i, q_len); i += q_len;
1870 if (type == 'r') {
1871 uint64_t stmt = decode64(d, &i);
1872 snprintf(rest, sizeof(rest), " = 0x%lx", stmt);
1873 }
1874 sprintf(line, "(dbh=0x%lx, '%s')%s", dbh, q, rest);
1875 } else if (strcmp(func, "oci_pconnect") == 0) {
1876 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
1877 uint32_t cs_len = decode32(d, &i);
1878 char cs[cs_len * 4 + 1];
1879 bin2hex_ascii(cs, d + i, cs_len); i += cs_len;
1880 if (type == 'r') {
1881 uint64_t h = decode64(d, &i);
1882 snprintf(rest, sizeof(rest), " = 0x%lx", h);
1883 }
1884 sprintf(line, "('%s')%s", cs, rest);
1885 } else if ((strcmp(func, "open") == 0)
1408 1886 || (strcmp(func, "open64") == 0) || (strcmp(func, "open64") == 0)
1409 1887 || (strcmp(func, "openat") == 0)) { || (strcmp(func, "openat") == 0)) {
1410 1888 char dirfd[32]; char dirfd[32];
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1423 1901 dirfd, pathname, flags, mode, rest); dirfd, pathname, flags, mode, rest);
1424 1902 } break; } break;
1425 1903
1904 case 'O':
1905 if (strcmp(func, "OCIAttrSet") == 0) {
1906 uint64_t h = decode64(d, &i);
1907 uint32_t htype = decode32(d, &i);
1908 unsigned int attr_size = decode32(d, &i);
1909 char attr[attr_size * 4 + 1];
1910 bin2hex_ascii(attr, d + i, attr_size); i += attr_size;
1911 unsigned int attr_type = decode32(d, &i);
1912 uint64_t err = decode64(d, &i);
1913 char s_htype[32];
1914 nd_decode_oci_handle_alloc_type(s_htype, sizeof(s_htype), htype);
1915 char s_attr_type[32];
1916 nd_decode_oci_attr_type(s_attr_type, sizeof(s_attr_type), attr_type);
1917 int32_t ret = decode32(d, &i);
1918 sprintf(line, "(h=0x%lx, htype=%s, attr='%s'"
1919 ", attr_type=%s, err=0x%lx) = %d",
1920 h, s_htype, attr, s_attr_type, err, ret);
1921 } else if (strcmp(func, "OCIBindByName") == 0) {
1922 uint64_t stmt = decode64(d, &i);
1923 uint64_t bind = decode64(d, &i);
1924 uint64_t oci_error = decode64(d, &i);
1925 unsigned int ph_len = decode32(d, &i);
1926 char ph[ph_len * 4 + 1];
1927 bin2hex_ascii(ph, d + i, ph_len); i += ph_len;
1928 int value_size = decode32(d, &i);
1929 uint16_t dty = decode16(d, &i);
1930 uint64_t ind = decode64(d, &i);
1931 uint64_t alen = decode64(d, &i);
1932 uint64_t rcode = decode64(d, &i);
1933 uint32_t maxarr_len = decode32(d, &i);
1934 uint64_t curelep = decode64(d, &i);
1935 uint32_t mode = decode32(d, &i);
1936 int32_t ret = decode32(d, &i);
1937 char s_dty[32], s_ind[32], s_mode[128], s_ret[32];
1938 nd_decode_oci_dty(s_dty, sizeof(s_dty), dty);
1939 //nd_decode_oci_ind(s_ind, sizeof(s_ind), ind);
1940 nd_decode_oci_bind_mode(s_mode, sizeof(s_mode), mode);
1941 nd_decode_oci_ret(s_ret, sizeof(s_ret), ret);
1942 sprintf(line, "(0x%lx, 0x%lx, 0x%lx, '%s', value, value_size=%d"
1943 ", dty=%s, ind=0x%lx, alen=0x%lx, rcode=0x%lx, %u, curelep=0x%lx, mode=%s) = %s",
1944 stmt, bind, oci_error, ph, value_size,
1945 s_dty, ind, alen, rcode, maxarr_len, curelep, s_mode, s_ret);
1946 } else if (strcmp(func, "OCIDefineByPos") == 0) {
1947 uint64_t stmt = decode64(d, &i);
1948 uint64_t def = decode64(d, &i);
1949 uint64_t oci_error = decode64(d, &i);
1950 uint32_t pos = decode32(d, &i);
1951 int value_size = decode32(d, &i);
1952 uint16_t dty = decode16(d, &i);
1953 uint64_t ind = decode64(d, &i);
1954 uint64_t rlen = decode64(d, &i);
1955 uint64_t rcode = decode64(d, &i);
1956 uint32_t mode = decode32(d, &i);
1957 int32_t ret = decode32(d, &i);
1958 char s_dty[32], s_ind[32], s_mode[128], s_ret[32];
1959 nd_decode_oci_dty(s_dty, sizeof(s_dty), dty);
1960 //nd_decode_oci_ind(s_ind, sizeof(s_ind), ind);
1961 nd_decode_oci_bind_mode(s_mode, sizeof(s_mode), mode);
1962 nd_decode_oci_ret(s_ret, sizeof(s_ret), ret);
1963 sprintf(line, "(0x%lx, 0x%lx, 0x%lx, pos=%u, value, value_size=%d"
1964 ", %s, ind=0x%lx, rlen=0x%lx, rcode=0x%lx, mode=%s) = %s",
1965 stmt, def, oci_error, pos, value_size,
1966 s_dty, ind, rlen, rcode, s_mode, s_ret);
1967 } else if (strcmp(func, "OCIHandleAlloc") == 0) {
1968 uint64_t parent = decode64(d, &i);
1969 uint64_t dbh = decode64(d, &i);
1970 uint32_t type = decode32(d, &i);
1971 size_t extra_mem = decode64(d, &i);
1972 uint64_t user_mem = decode64(d, &i);
1973 char s_type[32];
1974 nd_decode_oci_handle_alloc_type(s_type, sizeof(s_type), type);
1975 sprintf(line, "(0x%lx, 0x%lx, %s, %zu, 0x%lx)",
1976 parent, dbh, s_type, extra_mem, user_mem);
1977 } else if (strcmp(func, "OCIHandleFree") == 0) {
1978 uint64_t hnd = decode64(d, &i);
1979 uint32_t type = decode32(d, &i);
1980 char s_type[32];
1981 nd_decode_oci_handle_alloc_type(s_type, sizeof(s_type), type);
1982 sprintf(line, "(0x%lx, %s)", hnd, s_type);
1983 } else if (strcmp(func, "OCIServerAttach") == 0) {
1984 uint64_t oci_server = decode64(d, &i);
1985 uint64_t oci_error = decode64(d, &i);
1986 int32_t db_link_len = decode32(d, &i), a;
1987 a = db_link_len < 0 ? 0 : db_link_len;
1988 char db_link[a * 4 + 1];
1989 bin2hex_ascii(db_link, d + i, a); i += a;
1990 uint32_t mode = decode32(d, &i);
1991 if (type == 'r')
1992 snprintf(rest, sizeof(rest), " = %d", decode32(d, &i));
1993 char s_mode[128];
1994 nd_decode_oci_mode(s_mode, sizeof(s_mode), mode);
1995 sprintf(line, "(0x%lx, 0x%lx, '%s', %d, mode=%s)%s",
1996 oci_server, oci_error, db_link, db_link_len, s_mode, rest);
1997 } else if (strcmp(func, "OCIServerDetach") == 0) {
1998 uint64_t oci_server = decode64(d, &i);
1999 uint64_t oci_error = decode64(d, &i);
2000 uint32_t mode = decode32(d, &i);
2001 if (type == 'r')
2002 snprintf(rest, sizeof(rest), " = %d", decode32(d, &i));
2003 char s_mode[128];
2004 nd_decode_oci_mode(s_mode, sizeof(s_mode), mode);
2005 sprintf(line, "(0x%lx, 0x%lx, mode=%s)%s",
2006 oci_server, oci_error, s_mode, rest);
2007 } else if (strcmp(func, "OCIStmtExecute") == 0) {
2008 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
2009 if (type == 'm') {
2010 uint64_t stmt = decode64(d, &i);
2011 unsigned char bind_way = decode8(d, &i);
2012 decode_query_params(rest, sizeof(rest), bind_way, d, &i);
2013 if (bind_way == ND_PARAMS_BIND_WAY_IN) {
2014 uint16_t q_len = decode16(d, &i);
2015 char q[q_len * 4 + 1];
2016 bin2hex_ascii(q, d + i, q_len); i += q_len;
2017 sprintf(line, ": meta: stmt=0x%lx: sql: %s", stmt, q);
2018 if (strcmp(rest, " {}") != 0)
2019 sprintf(line2, ": meta: stmt=0x%lx: binds:%s", stmt, rest);
2020 } else {
2021 sprintf(line, ": meta: stmt=0x%lx: binds:%s", stmt, rest);
2022 }
2023 } else {
2024 uint64_t svc = decode64(d, &i);
2025 uint64_t stmt = decode64(d, &i);
2026 uint64_t err = decode64(d, &i);
2027 uint32_t iters = decode32(d, &i);
2028 uint32_t rowoff = decode32(d, &i);
2029 uint64_t snap_in = decode64(d, &i);
2030 uint64_t snap_out = decode64(d, &i);
2031 uint32_t mode = decode32(d, &i);
2032 if (type == 'r') {
2033 int ret = decode32(d, &i);
2034 char s_ret[32];
2035 nd_decode_oci_ret(s_ret, sizeof(s_ret), ret);
2036 snprintf(rest, sizeof(rest), " = %s", s_ret);
2037 }
2038 char s_mode[128];
2039 nd_decode_oci_execute_mode(s_mode, sizeof(s_mode), mode);
2040 sprintf(line, "(0x%lx, 0x%lx, 0x%lx iters=%u rowoff=%u, 0x%lx, 0x%lx, %s)%s",
2041 svc, stmt, err, iters, rowoff, snap_in, snap_out, s_mode, rest);
2042 }
2043 } else if (strcmp(func, "OCIStmtPrepare") == 0) {
2044 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(outf, "DUMP[%s][%c]: %s\n", func, type, dump);
2045 uint64_t stmt = decode64(d, &i);
2046 uint64_t oci_error = decode64(d, &i);
2047 uint16_t q_len = decode16(d, &i);
2048 char q[q_len * 4 + 1];
2049 bin2hex_ascii(q, d + i, q_len); i += q_len;
2050 uint32_t lang = decode32(d, &i);
2051 uint32_t mode = decode32(d, &i);
2052 int32_t ret = decode32(d, &i);
2053 char s_lang[32], s_mode[128];
2054 nd_decode_oci_lang(s_lang, sizeof(s_lang), lang);
2055 nd_decode_oci_mode(s_mode, sizeof(s_mode), mode);
2056 sprintf(line, "(0x%lx, 0x%lx, '%s', %s, mode=%s) = %d",
2057 stmt, oci_error, q, s_lang, s_mode, ret);
2058 } else if (strcmp(func, "OCITransCommit") == 0) {
2059 uint64_t svc = decode64(d, &i);
2060 uint64_t oci_error = decode64(d, &i);
2061 uint32_t flags = decode32(d, &i);
2062 if (type == 'r') {
2063 int ret = decode32(d, &i);
2064 char s_ret[32];
2065 nd_decode_oci_ret(s_ret, sizeof(s_ret), ret);
2066 snprintf(rest, sizeof(rest), " = %s", s_ret);
2067 }
2068 char s_flags[128];
2069 nd_decode_oci_trans_commit_flags(s_flags, sizeof(s_flags), flags);
2070 sprintf(line, "(0x%lx, 0x%lx, %s)%s",
2071 svc, oci_error, s_flags, rest);
2072 } else if (strcmp(func, "OCITransRollback") == 0) {
2073 uint64_t svc = decode64(d, &i);
2074 uint64_t oci_error = decode64(d, &i);
2075 uint32_t flags = decode32(d, &i);
2076 if (type == 'r') {
2077 int ret = decode32(d, &i);
2078 char s_ret[32];
2079 nd_decode_oci_ret(s_ret, sizeof(s_ret), ret);
2080 snprintf(rest, sizeof(rest), " = %s", s_ret);
2081 }
2082 char s_flags[128];
2083 nd_decode_oci_trans_rollback_flags(s_flags, sizeof(s_flags), flags);
2084 sprintf(line, "(0x%lx, 0x%lx, %s)%s",
2085 svc, oci_error, s_flags, rest);
2086 } else if (strcmp(func, "OCITransStart") == 0) {
2087 uint64_t svc = decode64(d, &i);
2088 uint64_t oci_error = decode64(d, &i);
2089 uint32_t timeout = decode32(d, &i);
2090 uint32_t flags = decode32(d, &i);
2091 int ret = decode32(d, &i);
2092 char s_flags[128], s_ret[32];
2093 nd_decode_oci_trans_start_flags(s_flags, sizeof(s_flags), flags);
2094 nd_decode_oci_ret(s_ret, sizeof(s_ret), ret);
2095 sprintf(line, "(0x%lx, 0x%lx, %us, %s) = %s",
2096 svc, oci_error, timeout, s_flags, s_ret);
2097 } break;
2098
1426 2099 case 'p': case 'p':
1427 2100 if (strcmp(func, "poll") == 0) { if (strcmp(func, "poll") == 0) {
1428 2101 uint16_t nf = decode32(d, &i); uint16_t nf = decode32(d, &i);
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1514 2187 char q[q_len * 4 + 1]; char q[q_len * 4 + 1];
1515 2188 bin2hex_ascii(q, d + i, q_len); i += q_len; bin2hex_ascii(q, d + i, q_len); i += q_len;
1516 2189 if (type == 'c') { if (type == 'c') {
1517 decode_query_params(rest, sizeof(rest), d, &i);
2190 decode_query_params(rest, sizeof(rest),
2191 ND_PARAMS_BIND_WAY_BOTH, d, &i);
1518 2192 } else if (type == 'r') { } else if (type == 'r') {
1519 2193 uint64_t res = decode64(d, &i); uint64_t res = decode64(d, &i);
1520 2194 uint64_t rows = decode64(d, &i); uint64_t rows = decode64(d, &i);
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1864 2538 memset(space, ' ', max); memset(space, ' ', max);
1865 2539 space[max] = '\0'; space[max] = '\0';
1866 2540
1867 if (pid == tid)
1868 fprintf(outf, "%lu.%03lu %10u%s %s%s\n",
1869 t / 1000, t % 1000, pid, space, func, line);
1870 else
1871 fprintf(outf, "%lu.%03lu %10u %10u%s %s%s\n",
1872 t / 1000, t % 1000, pid, tid, space, func, line);
2541 char cfunc[128];
2542 if (theme)
2543 nd_trace_color(cfunc, sizeof(cfunc), func, "func", type, tf, 0);
2544
2545 char sts[32], sts2[64];
2546 snprintf(sts, sizeof(sts), "%lu.%03lu", t / 1000, t % 1000);
2547 nd_trace_color(sts2, sizeof(sts2), sts, "ts", '-', "",
2548 last_ts == 0 ? 0 : t - last_ts);
2549
2550 if (pid == tid) {
2551 fprintf(outf, "%s %10u %s %s%s\n",
2552 sts2, pid, space, theme ? cfunc : func, line);
2553 if (line2[0] != '\0')
2554 fprintf(outf, "%s %10u %s %s%s\n",
2555 sts2, pid, space, theme ? cfunc : func, line2);
2556 } else {
2557 fprintf(outf, "%s %10u %10u %s %s%s\n",
2558 sts2, pid, tid, space, theme ? cfunc : func, line);
2559 if (line2[0] != '\0')
2560 fprintf(outf, "%s %10u %10u %s %s%s\n",
2561 sts2, pid, tid, space, theme ? cfunc : func, line2);
2562 }
2563
2564 last_ts = t;
1873 2565 } }
1874 2566
1875 2567 static void decode(const pid_t parent, unsigned char *d, size_t len) static void decode(const pid_t parent, unsigned char *d, size_t len)
 
... ... int main(int argc, char *argv[])
1893 2585 int c, r; int c, r;
1894 2586 int options_index = 0; int options_index = 0;
1895 2587 char *out_file = NULL; char *out_file = NULL;
1896 pid_t pids[256];
1897 2588 int sm[256]; int sm[256];
1898 2589 char version[256]; char version[256];
1899 2590 struct shared *shared[256]; struct shared *shared[256];
1900 unsigned int no_pids = 0;
1901 2591
1902 2592 // Disabling ninedogs.so for the tracer // Disabling ninedogs.so for the tracer
1903 2593 int fd = open("/dev/ninedogs", O_WRONLY); int fd = open("/dev/ninedogs", O_WRONLY);
 
... ... int main(int argc, char *argv[])
1913 2603
1914 2604 setlinebuf(stderr); setlinebuf(stderr);
1915 2605
1916 while ((c = getopt_long(argc, argv, "p:o:", options, &options_index)) != -1) {
2606 while ((c = getopt_long(argc, argv, "p:o:Ht:", options, &options_index)) != -1) {
1917 2607 switch (c) { switch (c) {
1918 2608 case 'o': out_file = optarg; break; case 'o': out_file = optarg; break;
1919 2609 case 'p': if (no_pids < 256) pids[no_pids++] = strtoull(optarg, NULL, 10); break; case 'p': if (no_pids < 256) pids[no_pids++] = strtoull(optarg, NULL, 10); break;
2610 case 'H': only_high_level = 1; break;
2611 case 't': theme_name = optarg; break;
1920 2612 default: usage(); default: usage();
1921 2613 } }
1922 2614 } }
 
... ... int main(int argc, char *argv[])
1940 2632
1941 2633 //pid_t my_pid = getpid(); //pid_t my_pid = getpid();
1942 2634
1943 again:
1944 for (unsigned i = 0; i < no_pids; i++) {
1945 if (sm[i] >= 0)
1946 continue;
1947
1948 char name[32];
1949 snprintf(name, sizeof(name), "/ninedogs-%d", pids[i]);
1950 sm[i] = shm_open(name, O_RDWR, 0);
1951 if (sm[i] == -1) {
1952 //fprintf(stderr, "%u: Cannot do shm_open: %m\n", pids[i]);
1953 continue;
1954 }
1955 fprintf(stderr, "%u: shm_open returned %d\n", pids[i], sm[i]);
1956
1957 shared[i] = mmap(NULL, sizeof(struct shared),
1958 PROT_READ | PROT_WRITE, MAP_SHARED, sm[i], 0);
1959 if (shared[i] == MAP_FAILED) {
1960 //fprintf(stderr, "Cannot mmap i%u: %m\n", i);
1961 close(sm[i]);
1962 sm[i] = -1;
1963 continue;
1964 }
1965
1966 fprintf(stderr, "%u: Attached\n", pids[i]);
1967
1968 #if 0
1969 unsigned j = 0;
1970 shared[i]->buf[j++] = SHARED_CMD_INIT;
1971 shared[i]->buf[j++] = SHARED_VERSION;
1972 memcpy(shared[i]->buf + j, &my_pid, sizeof(pid_t));
1973 j += sizeof(pid_t);
1974
1975 r = sem_post(&shared[i]->sem1);
1976 if (r == -1) {
1977 fprintf(stderr, "%u: Cannot post sem1: %m\n", pids[i]);
1978 return 1;
1979 }
1980 #endif
1981 }
2635 nd_trace_color_set_theme();
1982 2636
2637 again:
1983 2638 for (unsigned i = 0; i < no_pids; i++) { for (unsigned i = 0; i < no_pids; i++) {
1984 2639 unsigned char *p; unsigned char *p;
1985 unsigned int ava;
2640 unsigned int ava, head, tail, used;
1986 2641 unsigned char buf[64000]; unsigned char buf[64000];
1987 2642 struct stat s; struct stat s;
1988 2643
2644 if (sm[i] < 0) {
2645 char name[32];
2646 snprintf(name, sizeof(name), "/ninedogs-%d", pids[i]);
2647 sm[i] = shm_open(name, O_RDWR, 0);
2648 if (sm[i] == -1) {
2649 //fprintf(stderr, "%u: Cannot do shm_open: %m\n", pids[i]);
2650 continue;
2651 }
2652 //fprintf(stderr, "%u: shm_open returned %d\n", pids[i], sm[i]);
2653
2654 shared[i] = mmap(NULL, sizeof(struct shared),
2655 PROT_READ | PROT_WRITE, MAP_SHARED, sm[i], 0);
2656 if (shared[i] == MAP_FAILED) {
2657 fprintf(stderr, "%u: Cannot mmap: %m\n", pids[i]);
2658 close(sm[i]);
2659 sm[i] = -1;
2660 continue;
2661 }
2662
2663 fprintf(stderr, "%u: attached\n", pids[i]);
2664 // we use '|' because we may have a concurrent tracer attached
2665 shared[i]->clients++;
2666 shared[i]->client_flags |= only_high_level == 1 ? ND_SHARED_ONLY_HIGH_LEVEL : 0;
2667 }
2668
1989 2669 if (do_exit == no_pids) { if (do_exit == no_pids) {
2670 shared[i]->clients--;
1990 2671 fprintf(stderr, "Bye!\n"); fprintf(stderr, "Bye!\n");
1991 2672 break; break;
1992 2673 } }
 
... ... int main(int argc, char *argv[])
2004 2685 return 1; return 1;
2005 2686 } }
2006 2687
2688 // Only here we can read 'head' and 'tail'
2689 head = shared[i]->head;
2690 tail = shared[i]->tail;
2691
2007 2692 r = sem_post(&shared[i]->sem1); r = sem_post(&shared[i]->sem1);
2008 2693 if (r == -1) { if (r == -1) {
2009 2694 fprintf(stderr, "%u: Cannot post sem1: %m\n", pids[i]); fprintf(stderr, "%u: Cannot post sem1: %m\n", pids[i]);
 
... ... int main(int argc, char *argv[])
2016 2701 } }
2017 2702
2018 2703 // tail-1 points to last value available // tail-1 points to last value available
2019 if (shared[i]->tail == shared[i]->head)
2704 if (tail == head)
2020 2705 continue; continue;
2021 else if (shared[i]->head < shared[i]->tail) // 01h3t5 => ava = 2
2022 ava = shared[i]->tail - shared[i]->head;
2706 else if (head < tail) // 01h3t5 => ava = 2
2707 ava = tail - head;
2023 2708 else // 01t345h78 => ava = 2 + (9 - 6) = 5 else // 01t345h78 => ava = 2 + (9 - 6) = 5
2024 ava = shared[i]->tail + (shared[i]->buf_size - shared[i]->head);
2709 ava = tail + (shared[i]->buf_size - head);
2025 2710
2026 //fprintf(outf, "RING[%u]: head=%u tail=%u new_tail=%u msgs_lost=%u [after lock]\n",
2027 // i, shared[i]->head, shared[i]->tail, shared[i]->new_tail, shared[i]->msgs_lost);
2711 //fprintf(outf, "RING[%u]: head=%u tail=%u ava=%u [after lock]\n",
2712 // i, head, tail, ava);
2028 2713
2029 2714 //char dump[ava * 4 + 1]; //char dump[ava * 4 + 1];
2030 2715 //bin2hex_ascii(dump, shared[i]->buf + shared[i]->head, ava); //bin2hex_ascii(dump, shared[i]->buf + shared[i]->head, ava);
2031 2716 //fprintf(outf, "DUMP0[%hu]: %s\n", ava, dump); //fprintf(outf, "DUMP0[%hu]: %s\n", ava, dump);
2032 2717
2718 used = 0;
2033 2719 while (ava >= 2) { while (ava >= 2) {
2034 2720 unsigned short plen; unsigned short plen;
2035 2721
2036 2722 // TODO: we may have a byte at the end and the other at the beginning! // TODO: we may have a byte at the end and the other at the beginning!
2037 if (shared[i]->buf_size - shared[i]->head == 1) { // ...h size=4 h=3 => max=1 or ..h. max=2
2723 if (shared[i]->buf_size - head == 1) { // ...h size=4 h=3 => max=1 or ..h. max=2
2038 2724 // Split length! // Split length!
2039 plen = shared[i]->buf[shared[i]->head] << 8;
2725 plen = shared[i]->buf[head] << 8;
2040 2726 plen |= shared[i]->buf[0]; plen |= shared[i]->buf[0];
2041 2727 } else { } else {
2042 memcpy(&plen, shared[i]->buf + shared[i]->head, sizeof(plen));
2728 memcpy(&plen, shared[i]->buf + head, sizeof(plen));
2043 2729 plen = be16toh(plen); plen = be16toh(plen);
2044 2730 } }
2045 2731 if (plen > ava) { if (plen > ava) {
 
... ... int main(int argc, char *argv[])
2048 2734 break; break;
2049 2735 } }
2050 2736
2051 if (shared[i]->head + plen <= shared[i]->buf_size) { // dddt...hddd size=11, head=7, plen=4 => 10 <= 11
2052 p = shared[i]->buf + shared[i]->head;
2737 if (head + plen <= shared[i]->buf_size) { // dddt...hddd size=11, head=7, plen=4 => 10 <= 11
2738 p = shared[i]->buf + head;
2053 2739 } else { // split data! dddt...hddd size=11, head=7, plen=8 => max=4 } else { // split data! dddt...hddd size=11, head=7, plen=8 => max=4
2054 unsigned int max = shared[i]->buf_size - shared[i]->head;
2740 unsigned int max = shared[i]->buf_size - head;
2055 2741 if (max > plen) max = plen; if (max > plen) max = plen;
2056 2742 //fprintf(outf, " DEBUG: split data. max=%u\n", max); //fprintf(outf, " DEBUG: split data. max=%u\n", max);
2057 2743 //fprintf(outf, " DEBUG: copy to buf from %p+%u, %u bytes\n", shared[i]->buf, shared[i]->head, max); //fprintf(outf, " DEBUG: copy to buf from %p+%u, %u bytes\n", shared[i]->buf, shared[i]->head, max);
2058 memcpy(buf, shared[i]->buf + shared[i]->head, max);
2744 memcpy(buf, shared[i]->buf + head, max);
2059 2745 //fprintf(outf, " DEBUG: copy to buf+%u from %p, %u bytes\n", max, shared[i]->buf, plen - max); //fprintf(outf, " DEBUG: copy to buf+%u from %p, %u bytes\n", max, shared[i]->buf, plen - max);
2060 2746 memcpy(buf + max, shared[i]->buf, plen - max); memcpy(buf + max, shared[i]->buf, plen - max);
2061 2747 p = buf; p = buf;
 
... ... int main(int argc, char *argv[])
2065 2751 char dump[plen * 4 + 1]; char dump[plen * 4 + 1];
2066 2752 bin2hex_ascii(dump, p, plen); bin2hex_ascii(dump, p, plen);
2067 2753 fprintf(outf, "%u: DUMP[%hu] head=%u: %s\n", fprintf(outf, "%u: DUMP[%hu] head=%u: %s\n",
2068 pids[i], plen, shared[i]->head, dump);
2754 pids[i], plen, head, dump);
2069 2755 } }
2070 2756
2071 2757 decode(pids[i], p + 2, plen - 2); decode(pids[i], p + 2, plen - 2);
2072 2758
2073 shared[i]->head = (shared[i]->head + plen) % shared[i]->buf_size;
2074 2759 ava -= plen; ava -= plen;
2075 //fprintf(outf, " DEBUG: ava[%u] after substracting plen[%hu]; no_pids=%u\n", ava, plen, no_pids);
2760 head = (head + plen) % shared[i]->buf_size;
2761 used += plen;
2762 //fprintf(outf, " DEBUG: ava[%u] after substracting plen[%hu]; no_pids=%u\n",
2763 // ava, plen, no_pids);
2764 }
2765
2766 r = sem_wait(&shared[i]->sem1);
2767 if (r == -1) {
2768 fprintf(stderr, "%u: Cannot wait for sem1: %m\n", pids[i]);
2769 return 1;
2770 }
2771
2772 // Only here we can change 'head'
2773 shared[i]->head = head;
2774 shared[i]->junk++;
2775 //fprintf(outf, " DEBUG: shared[%u]->head moved to %u\n", i, shared[i]->head);
2776
2777 r = sem_post(&shared[i]->sem1);
2778 if (r == -1) {
2779 fprintf(stderr, "%u: Cannot post sem1: %m\n", pids[i]);
2780 return 1;
2076 2781 } }
2077 2782 } }
2078 2783
2079 if (!do_exit)
2784 if (!do_exit) {
2785 usleep(100 * 1000);
2080 2786 goto again; goto again;
2787 }
2081 2788
2082 2789 // TODO: print some stats // TODO: print some stats
2083 2790 return 0; return 0;
File trace/show-colors.c added (mode: 100644) (index 0000000..d978a2e)
1 #include <stdio.h>
2
3
4 int main(void)
5 {
6 printf("256 colors:\n");
7 // background
8 // first 16 are special
9 for (int i = 0; i < 2; i++) {
10 for (int j = 0; j < 8; j++) {
11 int color = i * 8 + j;
12 printf("\e[48;5;%dm %4d \e[0m", color, color);
13 }
14 printf("\n");
15 }
16 for (int i = 16; i < 256; i++) {
17 printf("\e[48;5;%dm %4d \e[0m", i, i);
18 if (i % 15 == 0)
19 printf("\n");
20 }
21 printf("\n");
22
23 // foreground
24 for (int i = 0; i < 32; i++) {
25 for (int j = 0; j < 8; j++) {
26 int color = i * 8 + j;
27 printf("\e[38;5;%dm %8d \e[0m", color, color);
28 }
29 printf("\n");
30 }
31 printf("\n");
32
33
34 printf("8 colors:\n");
35 for (int i = 30; i < 38; i++)
36 printf("\e[%dm %4d \e[0m", i, i);
37 printf("\n");
38
39 for (int i = 30; i < 38; i++)
40 printf("\e[1;%dm %4d \e[0m", i, i);
41 printf("\n");
42
43 return 0;
44 }
File webd/Makefile changed (mode: 100644) (index cd69c58..ad0a3da)
1 COMMON_H += ../common/ids.h ../common/tools.h ../common/sctools.h stools.h priv.h
2 OBJS := ../common/tools.o ../common/sctools.o stools.o certs.o
1 include ../Makefile.common
3 2
4 CFLAGS += -I../common $(JSON_CFLAGS)
3 COMMON_H += ../common/ids.h ../common/tools.h ../common/bin2struct.h \
4 stools.h priv.h
5 OBJS := ../common/tools.o ../common/bin2struct.o ../common/bin2json.o \
6 stools.o certs.o machines.o data.o
5 7
6 all:
7 make -R -C .. webd
8 CFLAGS += -I../common $(JSON_CFLAGS)
8 9
9 compile: ninedogs-webd
10 all: ninedogs-webd
10 11
11 12 stools.o: stools.c $(COMMON_H) stools.o: stools.c $(COMMON_H)
12 13 $(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
 
... ... stools.o: stools.c $(COMMON_H)
14 15 certs.o: certs.c $(COMMON_H) certs.o: certs.c $(COMMON_H)
15 16 $(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
16 17
18 machines.o: machines.c $(COMMON_H)
19 $(CC) $(CFLAGS) -c $<
20
21 data.o: data.c $(COMMON_H) ../common/bin2json.h
22 $(CC) $(CFLAGS) -c $<
23
17 24 ninedogs-webd: ninedogs-webd.c certs.h $(OBJS) ninedogs-webd: ninedogs-webd.c certs.h $(OBJS)
18 25 $(CC) $(CFLAGS) $@.c -o $@ $(OBJS) -lConn -lcap $(LIBS) \ $(CC) $(CFLAGS) $@.c -o $@ $(OBJS) -lConn -lcap $(LIBS) \
19 26 $(JSON_LIBS) $(GNUTLS_LIBS) $(JSON_LIBS) $(GNUTLS_LIBS)
 
... ... install: ninedogs-webd
25 32 @cp -av webroot $(I_USR_SHARE)/ninedogs @cp -av webroot $(I_USR_SHARE)/ninedogs
26 33 @mkdir -pv $(I_USR)/lib/systemd/system @mkdir -pv $(I_USR)/lib/systemd/system
27 34 cp -vd *.service $(I_USR)/lib/systemd/system/ cp -vd *.service $(I_USR)/lib/systemd/system/
35 @systemctl daemon-reload
28 36
29 37 .PHONY: clean .PHONY: clean
30 38 clean: clean:
File webd/TODO changed (mode: 100644) (index 8148f87..3834693)
20 20 to be able to send the updats. to be able to send the updats.
21 21 [ ] Seems I cannot use 'use strict' in init.js because 'wv' wil not be global! [ ] Seems I cannot use 'use strict' in init.js because 'wv' wil not be global!
22 22 [ ] We should inform the user if browser time is off from the real time. [ ] We should inform the user if browser time is off from the real time.
23 [ ] Mark expired certificates.
24 [ ] Mark last use of cached items and evict them.
23 25 [ ] [ ]
File webd/certs.c changed (mode: 100644) (index b431d44..910776b)
4 4
5 5 #include "priv.h" #include "priv.h"
6 6 #include "tools.h" #include "tools.h"
7 #include "sctools.h"
7 #include "bin2struct.h"
8 8 #include "stools.h" #include "stools.h"
9 9 #include "certs.h" #include "certs.h"
10 10
 
... ... static int certs_load_one(struct Conn *C, const char *dir,
25 25 if (r == -1) if (r == -1)
26 26 return -1; return -1;
27 27
28 r = decode_cert(&cert, data, r);
28 r = nd_bin2struct_cert(&cert, data, r);
29 29 if (r == -1) if (r == -1)
30 30 return -1; return -1;
31 31
32 if (cert.ts < start_from) {
33 xlog(0, "Ignoring [%s] because cert.ts[%lu] < start_from[%lu]\n",
32 if (cert.ts <= start_from) {
33 xlog(100, "Ignoring [%s] because cert.ts[%lu] <= start_from[%lu]\n",
34 34 cert.subj, cert.ts, start_from); cert.subj, cert.ts, start_from);
35 35 return 0; return 0;
36 36 } }
 
... ... int certs_load(struct Conn *C, const unsigned long long start_from,
77 77 { {
78 78 char path[4096]; char path[4096];
79 79
80 xlog(0, "%s: loading certs updated after %u...\n", __func__, start_from);
80 xlog(100, "%s: loading certs updated after %llu...\n", __func__, start_from);
81 81
82 82 *next_start = start_from; *next_start = start_from;
83 83
 
... ... int certs_load(struct Conn *C, const unsigned long long start_from,
86 86 snprintf(path, sizeof(path), snprintf(path, sizeof(path),
87 87 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/cert/*", "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/cert/*",
88 88 p->u.uid, p->u.uid >> 8, p->u.uid); p->u.uid, p->u.uid >> 8, p->u.uid);
89 xlog(0, " searching in %s\n", path);
89 xlog(100, " searching in %s\n", path);
90 90
91 91 glob_t g; glob_t g;
92 92 int r = glob(path, GLOB_NOSORT, NULL, &g); int r = glob(path, GLOB_NOSORT, NULL, &g);
 
... ... int certs_load(struct Conn *C, const unsigned long long start_from,
95 95 return -1; return -1;
96 96 } }
97 97
98 xlog(0, "found %u certs\n", g.gl_pathc);
98 xlog(100, "found %u certs\n", g.gl_pathc);
99 99 int ret = g.gl_pathc; int ret = g.gl_pathc;
100 100 for (unsigned i = 0; i < g.gl_pathc; i++) { for (unsigned i = 0; i < g.gl_pathc; i++) {
101 xlog(0, "Found file [%s]\n", g.gl_pathv[i]);
102 101 r = certs_load_one(C, g.gl_pathv[i], start_from, next_start); r = certs_load_one(C, g.gl_pathv[i], start_from, next_start);
103 102 if (r == -1) if (r == -1)
104 103 ret = -1; ret = -1;
File webd/data.c added (mode: 100644) (index 0000000..39ac581)
1 #include <sys/stat.h>
2
3 #include <glob.h>
4 #include <libgen.h>
5 #include <time.h>
6 #include <stdio.h>
7
8 #include "priv.h"
9 #include "tools.h"
10 #include "sctools.h"
11 #include "stools.h"
12 #include "data.h"
13 #include "bin2json.h"
14
15 /*
16 * Loads one machine
17 * Returns -1 on error
18 */
19 static int data_load_one(struct Conn *C, char *dir,
20 const char *machine_id, const unsigned long long hour)
21 {
22 xlog(0, "%s: dir=[%s] hour=[%llu]\n", __func__, dir, hour);
23
24 do {
25 char file[16];
26 snprintf(file, sizeof(file), "%llu", hour);
27
28 struct stat s;
29 int r = nd_stat_dir_file(&s, dir, file);
30 if (r == -1) {
31 xlog(100, " File [%s/%s] not found\n", dir, file);
32 break;
33 }
34
35 unsigned char *p = malloc(s.st_size);
36 if (!p) {
37 xlog(100, " Cannot alloc memory (%zu)!\n", s.st_size);
38 return 0;
39 }
40
41 r = load_dir_file(p, s.st_size, dir, file);
42 if (r == -1) {
43 free(p);
44 return -1;
45 }
46
47 off_t off = 0;
48 while (off < s.st_size) {
49 xlog(0, " %s: off=%zu/%zu\n", __func__, off, s.st_size);
50 struct json_object *j;
51 r = nd_bin2json(&j, p + off, s.st_size - off);
52 if (r <= 0)
53 break;
54 off += r;
55
56 if (!j)
57 continue;
58
59 const char *sj = json_object_to_json_string(j); // TODO: check error code
60 char code[64000];
61 snprintf(code, sizeof(code), "wv.machines.func.add_data('%s', %s);",
62 machine_id, sj);
63 push_code(C, code, "machine-data");
64 json_object_put(j);
65 }
66 } while (0);
67
68 // We need to signal that an hour was sent completely
69 char code[256];
70 snprintf(code, sizeof(code), "wv.machines.func.data_done('%s');",
71 machine_id);
72 push_code(C, code, "machine-data-done");
73
74 return 1;
75 }
76
77 /*
78 * Loads machine data
79 * Returns 0 on success, -1 on error.
80 */
81 int data_load(struct Conn *C, const char *machine_id, const unsigned long long hour)
82 {
83 struct priv *p = Conn_get_private(C);
84 char dir[4096];
85 snprintf(dir, sizeof(dir),
86 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/data/%c%c/%c%c/%s/t",
87 p->u.uid, p->u.uid >> 8, p->u.uid,
88 machine_id[0], machine_id[1], machine_id[2], machine_id[3], machine_id);
89 int r = data_load_one(C, dir, machine_id, hour);
90 if (r == -1)
91 return -1;
92
93 return 0;
94 }
File webd/data.h added (mode: 100644) (index 0000000..030cb66)
1 #include <Conn.h>
2
3 int data_load(struct Conn *C, const char *machine_id,
4 const unsigned long long hour);
File webd/machines.TODO added (mode: 100644) (index 0000000..07a3dbb)
1 [ ] Hierarchy
2 [ ] A host not yet added may be added to a special list
3 [ ]
File webd/machines.c added (mode: 100644) (index 0000000..eb6ad3f)
1 #include <glob.h>
2 #include <libgen.h>
3 #include <time.h>
4 #include <stdio.h>
5
6 #include "priv.h"
7 #include "tools.h"
8 #include "sctools.h"
9 #include "stools.h"
10 #include "machines.h"
11
12 /*
13 * Loads one machine
14 * Returns -1 on error
15 */
16 static int machines_load_one(struct Conn *C, char *dir,
17 const unsigned long long start_from, unsigned long long *next_start)
18 {
19 int r;
20 struct json_object *j;
21 const char *sj;
22 unsigned long long first_seen, last_seen;
23
24 xlog(0, " %s: dir=[%s]\n", __func__, dir);
25
26 r = load_dir_file(&first_seen, sizeof(first_seen), dir, "first_seen");
27 if (r == -1)
28 return -1;
29 first_seen = be64toh(first_seen);
30
31 r = load_dir_file(&last_seen, sizeof(last_seen), dir, "last_seen");
32 if (r == -1)
33 return -1;
34 last_seen = be64toh(last_seen);
35
36 if (first_seen <= start_from) {
37 xlog(100, " Ignoring because first_seen[%llu] <= start_from[%llu]\n",
38 first_seen, start_from);
39 return 0;
40 }
41
42 // TODO: deal with error codes
43 xlog(0, " Sending [%s]...\n", dir);
44 j = json_object_new_object();
45 if (!j) {
46 xlog(0, " Cannot alloc memory for answer!\n");
47 return 0;
48 }
49
50 char *id = basename(dir);
51 json_object_object_add(j, "id", json_object_new_string(id));
52 json_object_object_add(j, "first_seen", json_object_new_uint64(first_seen / 1000));
53 json_object_object_add(j, "last_seen", json_object_new_uint64(last_seen / 1000));
54 sj = json_object_to_json_string(j);
55
56 char code[8192];
57 snprintf(code, sizeof(code), "wv.machines.func.update(%s);", sj);
58 push_code(C, code, "machine-update");
59 json_object_put(j);
60
61 // TODO: not sure this is correct
62 if (*next_start < first_seen)
63 *next_start = first_seen;
64
65 return 1;
66 }
67
68 /*
69 * Loads machines
70 * @start_from is used to send only the updates
71 * Returns number of entries loaded, -1 on error.
72 */
73 int machines_load(struct Conn *C, const unsigned long long start_from,
74 unsigned long long *next_start)
75 {
76 char path[4096];
77
78 xlog(100, "%s: loading machines updated after %u...\n", __func__, start_from);
79
80 *next_start = start_from;
81
82 struct priv *p = Conn_get_private(C);
83
84 snprintf(path, sizeof(path),
85 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/data/*/*/*",
86 p->u.uid, p->u.uid >> 8, p->u.uid);
87 xlog(100, " searching in %s\n", path);
88
89 glob_t g;
90 int r = glob(path, GLOB_NOSORT, NULL, &g);
91 if (r != 0) {
92 xlog(0, " cannot load machines: %m!\n");
93 return -1;
94 }
95
96 xlog(100, " found %u machine(s)\n", g.gl_pathc);
97 int ret = g.gl_pathc;
98 for (unsigned i = 0; i < g.gl_pathc; i++) {
99 xlog(0, " %s: Found file [%s]\n", __func__, g.gl_pathv[i]);
100 r = machines_load_one(C, g.gl_pathv[i], start_from, next_start);
101 if (r == -1)
102 ret = -1;
103 }
104 globfree(&g);
105
106 return ret;
107 }
File webd/machines.h added (mode: 100644) (index 0000000..bc52440)
1 #include <Conn.h>
2
3 int machines_load(struct Conn *C, const unsigned long long start_from,
4 unsigned long long *next_start);
5
File webd/ninedogs-webd.c changed (mode: 100644) (index daa886d..260dd5e)
26 26 #include "tools.h" #include "tools.h"
27 27 #include "stools.h" #include "stools.h"
28 28 #include "certs.h" #include "certs.h"
29 #include "machines.h"
29 30
30 31 /* Global variables */ /* Global variables */
31 32 unsigned int debug = 3; // recommended 1 for production unsigned int debug = 3; // recommended 1 for production
 
... ... static void trigger(struct Conn *C)
116 117 push_file(C, DIR "/js/lstate.js"); push_file(C, DIR "/js/lstate.js");
117 118 push_file(C, DIR "/js/estate.js"); push_file(C, DIR "/js/estate.js");
118 119 push_file(C, DIR "/js/grid.js"); push_file(C, DIR "/js/grid.js");
120 push_file(C, DIR "/js/tab.js");
119 121 push_file(C, DIR "/js/time.js"); push_file(C, DIR "/js/time.js");
120 122 push_file(C, DIR "/js/certs.js"); push_file(C, DIR "/js/certs.js");
123 push_file(C, DIR "/js/machines.js");
124 //push_file(C, DIR "/js/machine_data.js");
121 125 push_file(C, DIR "/js/set.js"); push_file(C, DIR "/js/set.js");
122 126 push_file(C, DIR "/js/reports.js"); push_file(C, DIR "/js/reports.js");
123 127 push_file(C, DIR "/js/admin.js"); push_file(C, DIR "/js/admin.js");
 
... ... static void login_save_logout_cookie(struct Conn *C)
307 311 "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/cookies", "/var/lib/ninedogs/users/by-uid/%02hhx/%02hhx/%08x/cookies",
308 312 p->u.uid & 0xFF, (p->u.uid >> 8) & 0xFF, p->u.uid); p->u.uid & 0xFF, (p->u.uid >> 8) & 0xFF, p->u.uid);
309 313 Log(0, " Saving cookie into [%s]\n", dir); Log(0, " Saving cookie into [%s]\n", dir);
310 mkdir_recursive(dir, 0700);
311 save_dir_file(dir, p->u.cookie, "", 0);
314 save_dir_file(dir, p->u.cookie, O_CREAT | O_TRUNC | O_WRONLY, "", 0);
312 315 } while (0); } while (0);
313 316 } }
314 317
 
... ... static unsigned int settings_save(const char *dir,
501 504 { {
502 505 int r; int r;
503 506
504 r = save_dir_file(dir, file, value, strlen(value));
507 r = save_dir_file(dir, file, O_CREAT | O_TRUNC | O_WRONLY, value, strlen(value));
505 508 if (r == -1) if (r == -1)
506 509 return 0; return 0;
507 510
 
... ... static void certs(struct Conn *C, struct json_object *j)
596 599 push_code(C, code, "set-answer"); push_code(C, code, "set-answer");
597 600 } }
598 601
602 static void machines(struct Conn *C, struct json_object *j)
603 {
604 struct json_object *q;
605
606 Log(0, "%llu %s json:\n%s\n",
607 Conn_get_id(C), __func__, json_object_to_json_string_ext(j,
608 JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY));
609
610 json_object_object_get_ex(j, "subop", &q);
611 const char *subop = json_object_get_string(q);
612 if (!subop) {
613 Log(0, "\tNo subop! Abort!\n");
614 return;
615 }
616
617 json_object_object_get_ex(j, "id", &q);
618 const char *machine_id = json_object_get_string(q);
619
620 json_object_object_get_ex(j, "ts", &q);
621 const unsigned long long ts = json_object_get_uint64(q);
622
623 Log(0, "%llu %s subop %s\n", Conn_get_id(C), __func__, subop);
624 if (strcmp(subop, "send-data") == 0) {
625 if (!machine_id || !ts) {
626 Log(0, "%s: No machine_id or ts!\n", __func__);
627 return;
628 }
629 data_load(C, machine_id, get_hour(ts)); // TODO: check error code
630 return;
631 } else {
632 Log(0, "Unknown subop!\n");
633 }
634 }
635
599 636 /* /*
600 637 * Processing estate from clients * Processing estate from clients
601 638 */ */
602 639 static void estate(struct Conn *C, struct json_object *j) static void estate(struct Conn *C, struct json_object *j)
603 640 { {
604 struct json_object *q;
641 struct json_object *q, *data;
642 char code[512];
605 643
606 Log(0, "%llu %s json:\n%s\n",
607 Conn_get_id(C), __func__, json_object_to_json_string_ext(j,
644 Log(0, "%llu %s: json:\n%s\n",
645 Conn_get_id(C), __func__,
646 json_object_to_json_string_ext(j,
608 647 JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY)); JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY));
609 648
610 json_object_object_get_ex(j, "files", &q);
649 json_object_object_get_ex(j, "data", &data);
650
651 json_object_object_get_ex(data, "files", &q);
611 652 const char *files = json_object_get_string(q); const char *files = json_object_get_string(q);
612 653 if (files) { if (files) {
613 654 Log(0, "\testate: files: %s!\n", files); Log(0, "\testate: files: %s!\n", files);
614 655 } }
615 656
616 657 unsigned long long start_from = 0, next_start; unsigned long long start_from = 0, next_start;
617 json_object_object_get_ex(j, "certs", &q);
658 json_object_object_get_ex(data, "certs", &q);
618 659 const char *certs = json_object_get_string(q); const char *certs = json_object_get_string(q);
619 660 if (certs) { if (certs) {
620 661 start_from = strtoull(certs, NULL, 10); start_from = strtoull(certs, NULL, 10);
 
... ... static void estate(struct Conn *C, struct json_object *j)
623 664 int r = certs_load(C, start_from, &next_start); int r = certs_load(C, start_from, &next_start);
624 665 // TODO: what to do in case of errors? // TODO: what to do in case of errors?
625 666 // We should notify the client that is not ok yet. // We should notify the client that is not ok yet.
626 char code[512];
627 667 if (r >= 0) if (r >= 0)
628 668 snprintf(code, sizeof(code), snprintf(code, sizeof(code),
629 669 "wv.estate.func.update('certs', '%llu');" "wv.estate.func.update('certs', '%llu');"
 
... ... static void estate(struct Conn *C, struct json_object *j)
633 673 snprintf(code, sizeof(code), snprintf(code, sizeof(code),
634 674 "wv.lstate.func.update('certs-ok', 0);"); "wv.lstate.func.update('certs-ok', 0);");
635 675 push_code(C, code, "certs-ok"); push_code(C, code, "certs-ok");
676
677 json_object_object_get_ex(data, "machines", &q);
678 const char *machines = json_object_get_string(q);
679 if (machines) {
680 start_from = strtoull(machines, NULL, 10);
681 Log(0, "\testate: machines: start_from=%llu!\n", start_from);
682 }
683 r = machines_load(C, start_from, &next_start);
684 // TODO: what to do in case of errors?
685 // We should notify the client that is not ok yet.
686 if (r >= 0)
687 snprintf(code, sizeof(code),
688 "wv.estate.func.update('machines', '%llu');"
689 "wv.lstate.func.update('machines-ok', 1);",
690 next_start);
691 else
692 snprintf(code, sizeof(code),
693 "wv.lstate.func.update('machines-ok', 0);");
694 push_code(C, code, "machines-ok");
636 695 } }
637 696
638 697 static void process_json(struct Conn *C, struct json_object *j) static void process_json(struct Conn *C, struct json_object *j)
 
... ... static void process_json(struct Conn *C, struct json_object *j)
766 825 return; return;
767 826 } }
768 827
828 if (strcmp(s_op, "machines") == 0) {
829 machines(C, j);
830 json_object_put(answer);
831 return;
832 }
833
769 834 if (strcmp(s_op, "estate") == 0) { if (strcmp(s_op, "estate") == 0) {
770 835 estate(C, j); estate(C, j);
771 836 json_object_put(answer); json_object_put(answer);
 
... ... static void process_json(struct Conn *C, struct json_object *j)
778 843 return; return;
779 844 } }
780 845
781 Log(0, "\tInvalid operation [%s]!\n", s_op);
846 Log(0, "\t%s: Invalid operation [%s]!\n", __func__, s_op);
782 847 json_object_put(answer); json_object_put(answer);
783 848 } }
784 849
File webd/ninedogs-webd.service changed (mode: 100644) (index f57aec8..2bf43a8)
1 1 [Unit] [Unit]
2 Description=Ninedogs Websocket daemon
2 Description = Ninedogs Websocket daemon
3 3
4 4 [Service] [Service]
5 Type=exec
6 ExecStart=/date/sync/no-crypt/sync1/Dev/ninedogs/webd/ninedogs-webd
7 #User=rocketgit
8 #Group=rocketgit
9 PrivateTmp=true
10 Restart=on-failure
11 RestartSec=10
12 ProtectSystem=full
13 NoNewPrivileges=yes
5 Type = exec
6 ExecStart = /date/sync/no-crypt/sync1/Dev/ninedogs/webd/ninedogs-webd
7 PrivateTmp = true
8 Restart = on-failure
9 RestartSec = 10
10 ProtectSystem = full
11 NoNewPrivileges = yes
12 User = ninedogs
13 Group = ninedogs
14 14
15 15 [Install] [Install]
16 WantedBy=multi-user.target
16 WantedBy = multi-user.target
File webd/webroot/index.html changed (mode: 100644) (index cb1dafc..6666fe3)
9 9 <link rel="stylesheet" href="main.css"> <link rel="stylesheet" href="main.css">
10 10 </head> </head>
11 11
12 <body onLoad="my_start()">
13
14 12 <!-- <!--
15 13 // This file is part of ninedogs project // This file is part of ninedogs project
16 14 // Copyright: Catalin(ux) M. BOIE // Copyright: Catalin(ux) M. BOIE
17 15 --> -->
18 16
19 <!-- <span id="app_status">Unknown queue status</span> -->
20 <span id="my_status">Unknown status</span>
21 <span id="add_status">-</span>
22
23
24 <div id="main_menu" class="menu">?</div>
17 <body onLoad="my_start()">
18 <div id="main_menu" class="menu">?</div>
25 19
26 <div id="body" class="content">?</div>
20 <div id="my_body">?</div>
27 21
28 <br />
29 <div class="bottom">
30 <small>Copyright: Catalin(ux) M. BOIE</small>
31 </div>
22 <div id="my_status">Unknown status</div>
23 <div id="add_status">-</div>
32 24
33 <details>
34 <summary>Debug</summary>
35 <div id="debug"></div>
36 </details>
25 <div class="bottom">
26 <small>Copyright: Catalin(ux) M. BOIE</small>
27 </div>
37 28
29 <div>
30 <details>
31 <summary>Debug</summary>
32 <div id="debug"></div>
33 </details>
34 </div>
38 35 </body> </body>
39 36
40 37 </html> </html>
File webd/webroot/js/certs.js changed (mode: 100644) (index 69716cf..870f463)
... ... wv.certs.func.main = function()
65 65 // Called by server to add an cert // Called by server to add an cert
66 66 wv.certs.func.update = function(i) wv.certs.func.update = function(i)
67 67 { {
68 wv.debug('certs.func.update...');
68 //wv.debug('certs.func.update...');
69 69 certs = wv.conf.func.load('certs'); certs = wv.conf.func.load('certs');
70 70 if (typeof certs.list === 'undefined') if (typeof certs.list === 'undefined')
71 71 certs.list = {}; certs.list = {};
File webd/webroot/js/grid.js changed (mode: 100644) (index 87c209e..571cdab)
... ... wv.grid.func.drop = function(e)
111 111 const a = src_id.split('/'); const a = src_id.split('/');
112 112
113 113 const what = a[0]; const what = a[0];
114 data = wv.conf.func.load(what);
114 var data = wv.conf.func.load(what);
115 115 if (typeof data === 'undefined') if (typeof data === 'undefined')
116 116 return; return;
117 117
 
... ... wv.grid.func.drop = function(e)
134 134 */ */
135 135 wv.grid.func.display = function(what) wv.grid.func.display = function(what)
136 136 { {
137 wv.debug('grid.func.display');
137 wv.debug('grid.func.display what=' + what);
138 138
139 139 data = wv.conf.func.load(what); data = wv.conf.func.load(what);
140 140 if (typeof data === 'undefined') { if (typeof data === 'undefined') {
141 141 wv.debug('data for ' + what + ' is not defined'); wv.debug('data for ' + what + ' is not defined');
142 142 return; return;
143 143 } }
144 if (typeof data.events === 'undefined')
145 data.events = {}
146
144 147 var div = document.getElementById(data.target_div); var div = document.getElementById(data.target_div);
148 if (!div) {
149 console.log('cannot find div [' + data.target_div + ']');
150 return;
151 }
145 152
146 153 if (typeof data.list === 'undefined') { if (typeof data.list === 'undefined') {
147 154 if (typeof data.text_no_data === 'undefined') if (typeof data.text_no_data === 'undefined')
 
... ... wv.grid.func.display = function(what)
171 178 var tr = thead.insertRow(); var tr = thead.insertRow();
172 179 if (typeof data.fields_order === 'undefined') if (typeof data.fields_order === 'undefined')
173 180 data.fields_order = Object.keys(data.fields); data.fields_order = Object.keys(data.fields);
181 console.log('data.fields_order='); console.log(data.fields_order);
174 182 // TODO: if the server pushes more fields, we must refresh data.fields_order // TODO: if the server pushes more fields, we must refresh data.fields_order
175 183 data.fields_order.forEach((f, junk) => { data.fields_order.forEach((f, junk) => {
176 184 var th = document.createElement('th'); var th = document.createElement('th');
 
... ... wv.grid.func.display = function(what)
193 201 si.style.color = 'white'; si.style.color = 'white';
194 202 si.style.backgroundColor = 'red'; si.style.backgroundColor = 'red';
195 203 si.style.float = 'right'; si.style.float = 'right';
204 si.style.cursor = 'pointer';
196 205 if ((typeof data.sort_info[f] === 'undefined') if ((typeof data.sort_info[f] === 'undefined')
197 206 || (data.sort_info[f].order == 0)) { || (data.sort_info[f].order == 0)) {
198 207 x = ''; x = '';
 
... ... wv.grid.func.display = function(what)
213 222 var tbody = t.createTBody(); var tbody = t.createTBody();
214 223 data.sort_keys.forEach((key, index) => { data.sort_keys.forEach((key, index) => {
215 224 var tr = tbody.insertRow(); var tr = tbody.insertRow();
225 tr.id = what + '/' + key + '/tr';
226 if (typeof data.events.row_click !== 'undefined') {
227 tr.style.cursor = 'pointer';
228 tr.onclick = function() { data.events.row_click.func(this.id); };
229 }
230
216 231 data.fields_order.forEach((f, junk) => { data.fields_order.forEach((f, junk) => {
217 232 var td = tr.insertCell(); var td = tr.insertCell();
218 233 td.style.border = '1px solid black'; td.style.border = '1px solid black';
 
... ... wv.grid.func.display = function(what)
228 243 }); });
229 244 t.appendChild(tbody); t.appendChild(tbody);
230 245
231 try {
232 div.removeChild(div.children[0]);
233 } catch (e) {}
234 div.appendChild(t);
246 div.replaceChildren(t);
235 247 } }
236 248
File webd/webroot/js/machine_data.js added (mode: 100644) (index 0000000..66cd94b)
1 // machine_data.js
2
3 wv.module.func.load('conf');
4 wv.module.func.load('time');
5 wv.module.func.load('grid');
6 wv.module.func.load('tab');
7
8 try {
9
10 if (typeof wv.machine_data === 'undefined')
11 wv.machine_data = {};
12 if (typeof wv.machine_data.html === 'undefined')
13 wv.machine_data.html = {};
14 if (typeof wv.machine_data.func === 'undefined')
15 wv.machine_data.func = {};
16 if (typeof wv.machine_data.queue === 'undefined')
17 wv.machine_data.queue = {};
18
19 wv.machine_data.html.main = `
20 <!-- <b>List of machine_data</b>
21 <div id="machine_data_list"></div> -->
22 <div id="machine_data_tabs" class="flex1" style="flex-grow: 1"></div>
23 `;
24
25 // === Functions ===
26
27 wv.machine_data.func.render_type = function(t)
28 {
29 if (t == "O")
30 return "OpenSSL";
31 else if (t == "G")
32 return "GnuTLS";
33 else if (t == "J")
34 return "Java";
35
36 return t;
37 }
38
39 wv.machine_data.func.machine_body = function(name, pos, o)
40 {
41 console.log('machine_body: name=' + name + ' pos=' + pos);
42
43 const id = name + '/' + pos + '/b';
44 var div = document.getElementById(id);
45 if (!div) {
46 console.log(' DEBUG: div with id ' + id + ' not found');
47 return;
48 }
49 div.innerHTML = 'Machine ' + o.name + '<br />'
50 + '<pre>' + JSON.stringify(o) + '</pre>';
51
52 // Requesting data
53 // TODO: check if is cached first! In a generic way.
54 const j = {
55 op: 'machine_data',
56 subop: 'send-data',
57 id: o.name,
58 ts: Math.trunc(Date.now() / 1000)
59 };
60 wv.util.send(JSON.stringify(j));
61 }
62
63 wv.machine_data.func.machine_click = function(id)
64 {
65 console.log('machine_click: id=' + id);
66 const a = id.split('/');
67 const what = a[0];
68 const machine_id = a[1];
69 const o = { name: machine_id, func: wv.machine_data.func.machine_body };
70 wv.tab.func.add_tab(what, o);
71 }
72
73 wv.machine_data.func.list_machine_data = function(name, o)
74 {
75 console.log('func.list_machine_data: name=' + name);
76
77 machine_data = wv.conf.func.load(name);
78 machine_data.target_div = 'machine_data_list';
79 machine_data.fields = {
80 id: { name: 'ID' },
81 first_seen: { name: 'First seen', render: wv.time.func.render_ts },
82 last_seen: { name: 'Last seen', render: wv.time.func.render_ts }
83 };
84 machine_data.sort_info = {
85 id: { order: 1 }
86 };
87 machine_data.events = {
88 row_click: { func: wv.machine_data.func.machine_click }
89 };
90 machine_data.text_no_data = 'No machine_data found.';
91 wv.grid.func.display(name);
92 }
93
94 wv.machine_data.func.show_machine_data = function()
95 {
96 machine_data = {
97 name: 'machine_data',
98 target_div: 'machine_data_tabs',
99 tabs: [
100 {
101 name: 'machine_data',
102 body: '<div id="machine_data_list" />',
103 func: wv.machine_data.func.list_machine_data,
104 func_para: 'machine_data',
105 can_be_closed: 0
106 }
107 ],
108 style: {
109 main_class: 'flex1',
110 main: [
111 { name: 'display', value: 'flex' },
112 { name: 'flex-direction', value: 'column' }
113 ],
114 body_group_class: 'flex1',
115 body_group: [
116 { name: 'flex-grow', value: '1' }
117 ],
118 body: [
119 { name: 'flex-grow', value: '1' }
120 ]
121 }
122 };
123 wv.tab.func.display(machine_data);
124 // TODO: move flex stuff in 'tab.js' and remove it from here.
125 }
126
127 // This is called when 'machine_data' menu is clicked
128 wv.machine_data.func.main = function()
129 {
130 if (wv.login.ok != 1) {
131 div_body.innerHTML = 'You must login.';
132 return;
133 }
134
135 div_body.innerHTML = wv.machine_data.html.main;
136 wv.machine_data.func.show_machine_data();
137 }
138
139 // Called by server to add an cert
140 wv.machine_data.func.update = function(machine_id, j)
141 {
142 //wv.debug('machine_data.func.update: machine_id=' + machine_id);
143 //console.log(j);
144
145 var job = wv.machines.jobs[machine_id];
146 if (typeof job.data === 'undefined')
147 job.data = {};
148 const ts = j.ts;
149 delete j.ts;
150 job.data[ts] = j;
151 // TODO: save data in cache
152 // Requesting previous date
153 job.end -= 24 * 3600;
154 job.status = 1;
155 wv.machines.func.process_jobs();
156 }
157
158 wv.machine_data.func.update_answer = function(status, msg)
159 {
160 wv.debug('machine_data.func.update_answer status=' + status + ' msg=' + msg);
161
162 if (status == 1) { // ok
163 var b = document.getElementById('set_status_ok');
164 } else {
165 var b = document.getElementById('set_status_err');
166 }
167 b.innerHTML = msg;
168
169 return true;
170 }
171
172 wv.machine_data.func.init = function()
173 {
174 }
175
176 } catch (e) {
177 console.log('machine_data.js exception: ' + e);
178 }
File webd/webroot/js/machines.js added (mode: 100644) (index 0000000..5ac6b4c)
1 // machines.js
2
3 wv.module.func.load('conf');
4 wv.module.func.load('time');
5 wv.module.func.load('grid');
6 wv.module.func.load('tab');
7
8 try {
9
10 if (typeof wv.machines === 'undefined')
11 wv.machines = {};
12 if (typeof wv.machines.html === 'undefined')
13 wv.machines.html = {};
14 if (typeof wv.machines.func === 'undefined')
15 wv.machines.func = {};
16
17 if (typeof wv.machines.jobs === 'undefined')
18 wv.machines.jobs = {};
19
20 wv.machines.html.main = `
21 <!-- <b>List of machines</b>
22 <div id="machines_list"></div> -->
23 <div id="machines_tabs" class="flex1" style="flex-grow: 1"></div>
24 `;
25
26 // === Functions ===
27
28 wv.machines.func.render_type = function(t)
29 {
30 if (t == "O")
31 return "OpenSSL";
32 else if (t == "G")
33 return "GnuTLS";
34 else if (t == "J")
35 return "Java";
36
37 return t;
38 }
39
40 wv.machines.func.draw_one = function(job, x, y1, y2, color)
41 {
42 job.ctx.beginPath();
43 job.ctx.moveTo(x + 0, y1);
44 job.ctx.lineTo(x + 0, y2);
45 job.ctx.lineTo(x + 2, y2);
46 job.ctx.lineTo(x + 2, y1);
47 job.ctx.closePath();
48 job.ctx.fillStyle = color;
49 job.ctx.fill();
50 //job.ctx.lineWidth = 1;
51 //job.ctx.stroke();
52 }
53
54 wv.machines.func.draw_graph = function(job)
55 {
56 console.log('func.draw_graph');
57
58 job.ctx.clearRect(0, 0, job.canvas.width, job.canvas.height);
59
60 const keys = Object.keys(job.data);
61 const one_graph_height = 100;
62 const space_between_graphs = 30;
63
64 // Compute maximums
65 var count = 0;
66 var max = {};
67 keys.forEach((ts, junk) => {
68 const metrics = Object.keys(job.data[ts]);
69 metrics.forEach((k, junk) => {
70 if (typeof max[k] === 'undefined')
71 max[k] = job.data[ts][k];
72 else if (max[k] < job.data[ts][k])
73 max[k] = job.data[ts][k];
74 });
75 count++;
76 });
77 console.log('max: ' + JSON.stringify(max));
78
79 // Compute factors
80 const factor = {};
81 Object.keys(max).forEach((k, junk) => {
82 factor[k] = max[k] / one_graph_height;
83 });
84 console.log('factor: ' + JSON.stringify(factor));
85
86 // Draw rectangles around graphics
87 pos = 1;
88 var x = job.canvas.width - 20;
89 Object.keys(max).forEach((k, junk) => {
90 const y1 = 10 + pos * (one_graph_height + space_between_graphs);
91 const y2 = y1 - one_graph_height;
92 job.ctx.font = "13pt Arial";
93 job.ctx.fillStyle = 'red';
94 job.ctx.fillText(k, 11, y2 - 5);
95 job.ctx.beginPath();
96 job.ctx.moveTo(0 + 10, y1);
97 job.ctx.lineTo(0 + 10, y2);
98 job.ctx.lineTo(x + 10, y2);
99 job.ctx.lineTo(x + 10, y1);
100 job.ctx.closePath();
101 job.ctx.fillStyle = 'black';
102 job.ctx.fill();
103 pos++;
104 });
105
106 for (i = 0; i < keys.length; i++) {
107 var ts = keys[i]; // milliseconds
108 var x = 10 + Math.trunc((ts / 1000 - job.start) / 60) * 3;
109 pos = 1;
110 Object.keys(max).forEach((k, junk) => {
111 const h = Math.trunc(job.data[ts][k] / factor[k]);
112 const y1 = 10 + pos * (one_graph_height + space_between_graphs);
113 const y2 = y1 - h;
114 wv.machines.func.draw_one(job, x, y1, y2, '#0f0');
115 pos++;
116 });
117 //console.log('ts=' + ts + ' start=' + job.start + ' h=' + h + ' x=' + x + ' y2=' + y2);
118 }
119 }
120
121 wv.machines.func.process_job = function(job)
122 {
123 console.log('job.status=' + job.status);
124
125 if (job.status == 0) {
126 console.log('preparing canvas...');
127 job.canvas = document.getElementById(job.canvas_id);
128 job.canvas.width = 1200;
129 job.canvas.height = 2000;
130 job.canvas.style.backgroundColor = '#eee';
131 job.ctx = job.canvas.getContext('2d');
132 //job.ctx.beginPath();
133 //job.ctx.moveTo(25, 25);
134 //job.ctx.lineTo(105, 50);
135 //job.ctx.lineTo(105, 150);
136 //job.ctx.fill();
137 job.data = {};
138 job.status = 1;
139 }
140 if (job.status == 1) {
141 if (job.start > job.end) { // we have all data
142 console.log('We have all data!');
143 job.status = 2;
144 //console.log('job.data:' + JSON.stringify(job.data));
145 wv.machines.func.draw_graph(job);
146 } else {
147 console.log('requesting ts ' + job.end + ' (start=' + job.start + ') diff=' + (job.end - job.start));
148 // TODO: check if is cached first! In a generic way.
149 const json = {
150 op: 'machines',
151 subop: 'send-data',
152 id: job.id,
153 ts: job.end
154 };
155 wv.util.send(JSON.stringify(json));
156 }
157 }
158 }
159
160 wv.machines.func.add_data = function(machine_id, j)
161 {
162 wv.debug('machines.func.add_data: machine_id=' + machine_id);
163 //console.log(j);
164
165 var job = wv.machines.jobs[machine_id];
166 const ts = j.ts;
167 delete j.ts;
168 if (ts >= job.start * 1000)
169 job.data[ts] = j;
170 // TODO: save data in cache
171 }
172
173 wv.machines.func.data_done = function(machine_id)
174 {
175 wv.debug('machines.func.data_done: machine_id=' + machine_id);
176
177 var job = wv.machines.jobs[machine_id];
178
179 // Progress bar
180 job.ctx.clearRect(0, 0, job.canvas.width, job.canvas.height);
181 job.ctx.beginPath();
182 job.ctx.moveTo(10, 10);
183 job.ctx.lineTo(5 * Object.keys(job.data).length, 10);
184 job.ctx.lineTo(5 * Object.keys(job.data).length, 15);
185 job.ctx.lineTo(10, 15);
186 job.ctx.closePath();
187 job.ctx.fillStyle = 'yellow';
188 job.ctx.fill();
189 job.ctx.lineWidth = 1;
190 job.ctx.stroke();
191
192 job.end -= 3600;
193 job.status = 1;
194 wv.machines.func.process_job(job);
195 }
196
197 wv.machines.func.machine_body = function(name, pos, o)
198 {
199 console.log('machine_body: name=' + name + ' pos=' + pos);
200
201 const id = name + '/' + pos + '/b';
202 var div = document.getElementById(id);
203 if (!div) {
204 console.log(' DEBUG: div with id ' + id + ' not found');
205 return;
206 }
207 const canvas_id = id + '/canvas';
208 div.innerHTML = '<canvas id = "' + id + '/canvas' + '"></canvas>';
209
210 // Add the job to the global queue
211 const end = Math.trunc(Date.now() / 1000);
212 wv.machines.jobs[o.name] = {
213 id: o.name,
214 start: end - 2 * 3600, // todo 25
215 end: end,
216 canvas_id: id + '/canvas',
217 status: 0 // 0 = prepare canvas, 1 = send/recv_request, 2 = 3 = done
218 };
219 wv.machines.func.process_job(wv.machines.jobs[o.name]);
220 }
221
222 wv.machines.func.machine_click = function(id)
223 {
224 console.log('machine_click: id=' + id);
225 const a = id.split('/');
226 const what = a[0];
227 const machine_id = a[1];
228 const o = { name: machine_id, func: wv.machines.func.machine_body };
229 wv.tab.func.add_tab(what, o);
230 }
231
232 wv.machines.func.list_machines = function(name, o)
233 {
234 console.log('func.list_machines: name=' + name);
235
236 machines = wv.conf.func.load(name);
237 machines.target_div = 'machines_list';
238 machines.fields = {
239 id: { name: 'ID' },
240 first_seen: { name: 'First seen', render: wv.time.func.render_ts },
241 last_seen: { name: 'Last seen', render: wv.time.func.render_ts }
242 };
243 machines.sort_info = {
244 id: { order: 1 }
245 };
246 machines.events = {
247 row_click: { func: wv.machines.func.machine_click }
248 };
249 machines.text_no_data = 'No machines found.';
250 wv.grid.func.display(name);
251 }
252
253 wv.machines.func.show_machines = function()
254 {
255 machines = {
256 name: 'machines',
257 target_div: 'machines_tabs',
258 tabs: [
259 {
260 name: 'Machines',
261 body: '<div id="machines_list" />',
262 func: wv.machines.func.list_machines,
263 func_para: 'machines',
264 can_be_closed: 0
265 }
266 ],
267 style: {
268 main_class: 'flex1',
269 main: [
270 { name: 'display', value: 'flex' },
271 { name: 'flex-direction', value: 'column' }
272 ],
273 body_group_class: 'flex1',
274 body_group: [
275 { name: 'flex-grow', value: '1' }
276 ],
277 body: [
278 { name: 'flex-grow', value: '1' }
279 ]
280 }
281 };
282 wv.tab.func.display(machines);
283 // TODO: move flex stuff in 'tab.js' and remove it from here.
284 }
285
286 // This is called when 'machines' menu is clicked
287 wv.machines.func.main = function()
288 {
289 if (wv.login.ok != 1) {
290 div_body.innerHTML = 'You must login.';
291 return;
292 }
293
294 div_body.innerHTML = wv.machines.html.main;
295 wv.machines.func.show_machines();
296 }
297
298 // Called by server to add an cert
299 wv.machines.func.update = function(i)
300 {
301 wv.debug('machines.func.update...');
302 machines = wv.conf.func.load('machines');
303 if (typeof machines.list === 'undefined')
304 machines.list = {};
305 machines.list[i.id] = i;
306 wv.conf.func.update('machines', 'list', machines.list);
307 }
308
309 wv.machines.func.update_answer = function(status, msg)
310 {
311 wv.debug('machines.func.update_answer status=' + status + ' msg=' + msg);
312
313 if (status == 1) { // ok
314 var b = document.getElementById('set_status_ok');
315 } else {
316 var b = document.getElementById('set_status_err');
317 }
318 b.innerHTML = msg;
319
320 return true;
321 }
322
323 wv.machines.func.init = function()
324 {
325 }
326
327 } catch (e) {
328 console.log('machines.js exception: ' + e);
329 }
File webd/webroot/js/menu.js changed (mode: 100644) (index c87bb27..0586e3d)
... ... wv.menu = function(w)
6 6
7 7 switch (w) { switch (w) {
8 8 case 'set': wv.set.func.main(); break; case 'set': wv.set.func.main(); break;
9 case 'machines': wv.machines.func.main(); break;
9 10 case 'certs': wv.certs.func.main(); break; case 'certs': wv.certs.func.main(); break;
10 11 case 'admin': wv.admin.func.main(); break; case 'admin': wv.admin.func.main(); break;
11 12 default: wv.home.func.main(); break; default: wv.home.func.main(); break;
 
... ... wv.menu = function(w)
16 17 wv.html.main_menu = ` wv.html.main_menu = `
17 18 <span class="menu_item" onclick="wv.menu('home')">Home</span> <span class="menu_item" onclick="wv.menu('home')">Home</span>
18 19 <span class="menu_item" onclick="wv.menu('set')">Settings</span> <span class="menu_item" onclick="wv.menu('set')">Settings</span>
20 <span class="menu_item" onclick="wv.menu('machines')">Machines</span>
19 21 <span class="menu_item" onclick="wv.menu('certs')">Certificates</span> <span class="menu_item" onclick="wv.menu('certs')">Certificates</span>
20 22 <span class="menu_item menu_admin" onclick="wv.menu('admin')">Admin</span> <span class="menu_item menu_admin" onclick="wv.menu('admin')">Admin</span>
21 23 <span class="menu_item" onclick="wv.login.func.logout()">Logout</span> <span class="menu_item" onclick="wv.login.func.logout()">Logout</span>
22 <br /><br />
23 24 `; `;
File webd/webroot/js/tab.js added (mode: 100644) (index 0000000..976d680)
1 // tab.js
2 //wv.module.func.load('conf');
3
4 try {
5
6 if (typeof wv.tab === 'undefined')
7 wv.tab = {};
8 if (typeof wv.tab.func === 'undefined')
9 wv.tab.func = {};
10
11 // Here we keep all the tabs, indexed by 'name'
12 if (typeof wv.tab.list === 'undefined')
13 wv.tab.list = {};
14
15 wv.tab.func.drag_start = function(e)
16 {
17 e.dataTransfer.setData('text/plain', e.target.id);
18 }
19
20 wv.tab.func.drag_enter = function(e)
21 {
22 e.preventDefault(); // without this, we cannot drop
23 }
24
25 wv.tab.func.drag_over = function(e)
26 {
27 e.preventDefault(); // whitout this, we cannot drop
28 }
29
30 wv.tab.func.drag_leave = function(e)
31 {
32 }
33
34 wv.tab.func.drop = function(e)
35 {
36 e.preventDefault(); // without this, browser redirects to the id of the column :(
37
38 //console.log('tab.func.drop:'); console.log(e);
39 const src_id = e.dataTransfer.getData('text/plain');
40 const dst_id = e.target.id;
41
42 const a = src_id.split('/');
43 const name = a[0];
44 var data = wv.tab.list[name];
45 if (typeof data === 'undefined')
46 return;
47
48 const src_f = a[1];
49
50 const d = dst_id.split('/');
51 const dst_f = d[1];
52
53 var i_src = data.tab_order.indexOf(src_f);
54 var i_dst = data.tab_order.indexOf(dst_f);
55 data.tab_order.splice(i_src, 1);
56 data.tab_order.splice(i_dst, 0, src_f);
57 wv.tab.func.display(data);
58 }
59
60 wv.tab.func.activate_tab = function(id)
61 {
62 var id;
63
64 const a = id.split('/');
65 const name = a[0];
66 var data = wv.tab.list[name];
67
68 var parent = document.getElementById(data.target_div);
69
70 var top = parent.children[0];
71 keys = Object.keys(top.children);
72 id = name + '/' + a[1] + '/h/label';
73 keys.forEach((k, junk) => {
74 label = top.children[k].children[0];
75 if (label.id == id)
76 label.style.color = 'red';
77 else
78 label.style.color = 'black';
79 });
80
81 // body
82 var bot = parent.children[1];
83 keys = Object.keys(bot.children);
84 id = name + '/' + a[1] + '/b';
85 keys.forEach((k, junk) => {
86 if (bot.children[k].id == id)
87 bot.children[k].style.display = 'block';
88 else
89 bot.children[k].style.display = 'none';
90 });
91 }
92
93 // TODO: move this in util?
94 wv.tab.func.apply_style = function(obj, i, key)
95 {
96 if (typeof i.style[key + '_class'] !== 'undefined')
97 obj.classList.add(i.style[key + '_class']);
98
99 if (typeof i.style[key] !== 'undefined') {
100 keys = Object.keys(i.style[key]);
101 keys.forEach((c, junk) => {
102 x = i.style[key][c];
103 obj.style[x['name']] = x['value'];
104 });
105 }
106 }
107
108 wv.tab.func.close_tab = function(id)
109 {
110 const a = id.split('/');
111 const name = a[0];
112 const pos = a[1];
113
114 var data = wv.tab.list[name];
115 var index = data.tab_order.indexOf(pos).toString();
116 //console.log('id=' + id + ' index=' + index + ' todo check type');
117 data.tab_order.splice(index, 1); // todo this is not correct
118 data.tabs.splice(index, 1);
119 //console.log('active_tab=' + data.active_tab + ' index=' + index);
120 if (data.active_tab === index)
121 data.active_tab = '0';
122 wv.tab.func.display(data);
123 }
124
125 // TODO: we need to check if the tab is already open. Not clear.
126 wv.tab.func.add_tab = function(name, o)
127 {
128 //console.log('func.add_tab: name=' + name); console.log(o);
129 var data = wv.tab.list[name];
130
131 var index = data.tabs.push(o) - 1;
132 index = index.toString(); // because Object.keys return strings
133 //console.log('new index=' + index);
134 data.tab_order.push(index);
135 data.active_tab = index;
136 //console.log('set active tab to ' + data.active_tab);
137 wv.tab.func.display(data);
138 }
139
140 /*
141 * Draws tabs
142 * @i - info about tabs
143 */
144 // TODO: if we delete the current tab, we need to make active the left one or the right one
145 // TODO: we should not redraw what was not changed!
146 wv.tab.func.display = function(i)
147 {
148 var div, text;
149
150 wv.debug('tab.func.display i.name=' + i.name);
151
152 // Is already rendered?
153 if (typeof wv.tab.list[i.name] === 'undefined')
154 wv.tab.list[i.name] = i;
155 i = wv.tab.list[i.name];
156
157 var tab_group = document.createElement('div');
158 tab_group.id = i.name + '/group';
159 tab_group.classList.add('tab_main_div');
160 tab_group.style.border = '1px solid black';
161 tab_group.style.margin = '3px';
162 tab_group.style.padding = '5px';
163 wv.tab.func.apply_style(tab_group, i, 'main');
164
165 if (typeof i.tab_order === 'undefined')
166 i.tab_order = Object.keys(i.tabs);
167
168 var tab_header = document.createElement('div');
169 tab_header.id = i.name + '/header';
170 wv.tab.func.apply_style(tab_header, i, 'header_group');
171 var tab_body = document.createElement('div');
172 tab_body.id = i.name + '/body';
173 wv.tab.func.apply_style(tab_body, i, 'body_group');
174 //console.log('i.tab_order:'); console.log(i.tab_order);
175 i.tab_order.forEach((t, junk) => {
176 //if (typeof i.tabs[t].my_dirty === 'undefined')
177 // i.tabs[t].my_dirty = 1;
178 //if (i.tabs[t].my_dirty == 0)
179 // continue;
180 // TODO: whos sets my_dirty? Not so easy - we need to copy the previous DOM
181
182 var base_id = i.name + '/' + t;
183 if (typeof i.active_tab === 'undefined')
184 i.active_tab = t;
185
186 // header
187 var d = document.createElement('div');
188 d.id = base_id + '/h';
189 d.style.padding = '2px 4px';
190 //d.style.margin = '0 2px';
191 d.style.display = 'inline-block'; // todo switch to flex
192 d.style.border = '1px solid black';
193 d.draggable = 'true';
194 d.addEventListener('dragstart', wv.tab.func.drag_start);
195 d.addEventListener('dragenter', wv.tab.func.drag_enter);
196 d.addEventListener('dragover', wv.tab.func.drag_over);
197 d.addEventListener('dragleave', wv.tab.func.drag_leave);
198 d.addEventListener('drop', wv.tab.func.drop);
199
200 var label = document.createElement('span');
201 label.id = base_id + '/h/label';
202 label.style.color = 'black';
203 label.style.cursor = 'pointer';
204 if (i.active_tab == t)
205 label.style.color = 'red';
206 text = document.createTextNode(i.tabs[t].name);
207 label.appendChild(text);
208 label.onclick = function() { wv.tab.func.activate_tab(this.id); };
209 d.appendChild(label);
210
211 if ((typeof i.tabs[t].can_be_closed === 'undefined')
212 || (i.tabs[t].can_be_closed == 1)) {
213 text = document.createTextNode(' ');
214 d.appendChild(text);
215
216 var close = document.createElement('span');
217 close.id = base_id + '/h-close';
218 close.style.color = 'white';
219 close.style.backgroundColor = 'red';
220 close.style.border = '1px solid black';
221 close.style.cursor = 'pointer';
222 text = document.createTextNode('x');
223 close.appendChild(text);
224 close.onclick = function() { wv.tab.func.close_tab(this.id); };
225 d.appendChild(close);
226 }
227
228 wv.tab.func.apply_style(d, i, 'header');
229 tab_header.appendChild(d);
230
231 // body
232 var d = document.createElement('div');
233 d.id = base_id + '/b';
234 d.style.border = '1px solid black';
235 d.style.padding = '3px';
236 if (i.active_tab == t)
237 d.style.display = 'block';
238 else
239 d.style.display = 'none';
240
241 wv.tab.func.apply_style(d, i, 'body');
242
243 if (typeof i.tabs[t].body !== 'undefined') {
244 //console.log('we have body: ' + i.tabs[t].body);
245 d.innerHTML = i.tabs[t].body;
246 }
247 tab_body.appendChild(d);
248 });
249
250 div = document.getElementById(i.target_div);
251 div.replaceChildren(tab_header, tab_body);
252
253 // We can call functions only after we populated the DOM
254 i.tab_order.forEach((t, junk) => {
255 if (typeof i.tabs[t].func !== 'undefined') {
256 if (typeof i.tabs[t].func_para !== 'undefined')
257 para = i.tabs[t].func_para;
258 else
259 para = i.name + '/' + t;
260 //console.log('DEBUG: we have a func attached to t=' + t);
261 i.tabs[t].func(i.name, t, i.tabs[t]);
262 }
263 });
264 }
265
266 } catch (e) {
267 console.log('tab.js exception: ' + e);
268 }
File webd/webroot/js/util.js changed (mode: 100644) (index 70a6df5..0bfad0f)
... ... wv.util.func.notify = function(from, msg)
49 49
50 50 wv.util.send = function(s) wv.util.send = function(s)
51 51 { {
52 wv.debug('Sending: ' + s);
52 //wv.debug('Sending: ' + s);
53 53 ws.send(s); ws.send(s);
54 54 } }
55 55
File webd/webroot/main.css changed (mode: 100644) (index 9f61879..54bc7c3)
1 body {
2 padding: 5px;
3 x-display: flex;
4 x-flex-direction: column;
1 html {
5 2 font-family: sans; font-family: sans;
6 font-size: 9pt;
3 font-size: 11pt;
7 4 margin: 0; margin: 0;
5 height: 100%;
8 6 } }
9 7
10 pre {
11 margin: 0;
8 body {
9 margin: 3px;
10 display: flex;
11 flex-direction: column;
12 height: 100%;
13 }
14
15 .flex1 {
16 display: flex;
17 flex-direction: column;
12 18 } }
13 19
14 20 #my_status, #app_status, #add_status { #my_status, #app_status, #add_status {
15 21 border: 1px solid black; border: 1px solid black;
16 22 padding: 3px; padding: 3px;
17 margin: 2px;
23 margin: 2px 0;
18 24 display: inline-block; display: inline-block;
19 x-flex: 1 100%;
20 25 } }
21 26
22 27 .menu { .menu {
23 28 xxx-border: 1px solid black; xxx-border: 1px solid black;
24 margin: 2px;
29 margin: 2px 0;
25 30 padding: 0 5px 0 0; padding: 0 5px 0 0;
26 x-flex: 1 100%;
27 x-display: flex;
28 x-flex-direction: row;
29 x-flex-wrap: wrap;
30 x-justify-content: flex-start;
31 x-align-items: stretch;
32 x-align-content: flex-start;
33 31 } }
34 32
35 33 .menu_item { .menu_item {
36 34 border: 1px solid green; border: 1px solid green;
37 margin: 0 5px 0 0;
38 padding: 5px;
35 padding: 2px 4px;
39 36 background-color: yellow; background-color: yellow;
40 37 font-weight: bold; font-weight: bold;
41 38 cursor: pointer; cursor: pointer;
 
... ... pre {
46 43 display: none; display: none;
47 44 } }
48 45
49 .content {
46 #my_body {
50 47 xxx-border: 1px solid black; xxx-border: 1px solid black;
51 margin: 2px;
48 margin: 2px 0;
52 49 xxx-padding: 5px; xxx-padding: 5px;
53 50
54 x-flex: 1 100%;
55 x-display: flex;
56 x-flex-direction: column;
57 x-flex-wrap: wrap;
58 x-justify-content: flex-start;
59 x-align-items: stretch;
60 x-align-content: flex-start;
51 flex-grow: 1;
52
53 display: flex;
54 flex-direction: column;
61 55 } }
62 56
63 57 .gem { .gem {
File webd/webroot/main.js changed (mode: 100644) (index 6582ce7..538d8b4)
... ... function my_start()
128 128 div_debug = document.getElementById('debug'); div_debug = document.getElementById('debug');
129 129 div_status = document.getElementById('my_status'); div_status = document.getElementById('my_status');
130 130 div_menu = document.getElementById('main_menu'); div_menu = document.getElementById('main_menu');
131 div_body = document.getElementById('body');
131 div_body = document.getElementById('my_body');
132 132
133 133 // Ask permission for notifications (if not already granted) // Ask permission for notifications (if not already granted)
134 134 Notification.requestPermission().then(function(r) { notify_perm = r; }); Notification.requestPermission().then(function(r) { notify_perm = r; });
Date/time (UTC) Type Misc Labels
2023-03-15 06:48 build fedora-37-x86_64 worker/r1 builder/color=fff worker_elap/1126s wait_time/174912s date/2023-03-13 time/05:53
2023-03-15 07:05 build fedora-rawhide-x86_64 worker/r1 builder/color=fff worker_elap/964s wait_time/176093s date/2023-03-13 time/05:53
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/catalinux/ninedogs

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/catalinux/ninedogs

Clone this repository using git:
git clone git://git.rocketgit.com/user/catalinux/ninedogs

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main