File agent/ninedogs.c changed (mode: 100644) (index 0619a40..b3a0dd7) |
45 |
45 |
#include "ninedogs.h" |
#include "ninedogs.h" |
46 |
46 |
#include "ids.h" |
#include "ids.h" |
47 |
47 |
#include "php.h" |
#include "php.h" |
|
48 |
|
#include "python.h" |
48 |
49 |
#include "tools.h" |
#include "tools.h" |
49 |
50 |
#include "ctools.h" |
#include "ctools.h" |
50 |
51 |
#include "process_core.h" |
#include "process_core.h" |
|
52 |
|
#include "process_db.h" |
51 |
53 |
#include "text2process.h" |
#include "text2process.h" |
52 |
54 |
#include "shared.h" |
#include "shared.h" |
53 |
55 |
|
|
|
... |
... |
static unsigned long my_malloc_pos; |
89 |
91 |
static struct shared *shared; |
static struct shared *shared; |
90 |
92 |
static char shared_inited; |
static char shared_inited; |
91 |
93 |
static char trace_enabled = 1; |
static char trace_enabled = 1; |
|
94 |
|
static __thread unsigned short trace_depth; |
92 |
95 |
|
|
93 |
96 |
static char ninedogs_inited; |
static char ninedogs_inited; |
94 |
97 |
static void *(*old_realloc)(void *ptr, size_t size); |
static void *(*old_realloc)(void *ptr, size_t size); |
|
... |
... |
static ssize_t (*old_sendto)(int sockfd, const void *buf, size_t len, int flag |
104 |
107 |
static ssize_t (*old_sendmsg)(int sockfd, const struct msghdr *msg, int flags); |
static ssize_t (*old_sendmsg)(int sockfd, const struct msghdr *msg, int flags); |
105 |
108 |
static ssize_t (*old_recv)(int sockfd, void *buf, size_t len, int flags); |
static ssize_t (*old_recv)(int sockfd, void *buf, size_t len, int flags); |
106 |
109 |
static ssize_t (*old_recvmsg)(int sockfd, struct msghdr *msg, int flags); |
static ssize_t (*old_recvmsg)(int sockfd, struct msghdr *msg, int flags); |
|
110 |
|
static ssize_t (*old_recvfrom)(int sockfd, void *restrict buf, size_t len, int flags, |
|
111 |
|
struct sockaddr *restrict src_addr, socklen_t *restrict addrlen); |
107 |
112 |
static int (*old_accept)(int sockfd, struct sockaddr *addr, socklen_t *addrlen); |
static int (*old_accept)(int sockfd, struct sockaddr *addr, socklen_t *addrlen); |
108 |
113 |
static int (*old_accept4)(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags); |
static int (*old_accept4)(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags); |
109 |
114 |
static int (*old_connect)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); |
static int (*old_connect)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); |
|
... |
... |
static int (*old_fstatat)(int dirfd, const char *restrict pathname, |
139 |
144 |
struct stat *restrict statbuf, int flags); |
struct stat *restrict statbuf, int flags); |
140 |
145 |
static int (*old_fstatat64)(int dirfd, const char *restrict pathname, |
static int (*old_fstatat64)(int dirfd, const char *restrict pathname, |
141 |
146 |
struct stat64 *restrict statbuf, int flags); |
struct stat64 *restrict statbuf, int flags); |
|
147 |
|
static pid_t (*old_fork)(void); |
142 |
148 |
|
|
143 |
149 |
/* fd helpers */ |
/* fd helpers */ |
144 |
150 |
static struct fd_node *fd_search(const int fd) |
static struct fd_node *fd_search(const int fd) |
|
... |
... |
static void my_trace_put64(unsigned char *buf, unsigned int *i, const uint64_t v |
218 |
224 |
memcpy(buf + *i, &u, 8); *i = *i + 8; |
memcpy(buf + *i, &u, 8); *i = *i + 8; |
219 |
225 |
} |
} |
220 |
226 |
|
|
|
227 |
|
static void my_trace_put_double(unsigned char *buf, unsigned int *i, const double v) |
|
228 |
|
{ |
|
229 |
|
uint64_t u = htobe64(v); |
|
230 |
|
memcpy(buf + *i, &u, 8); *i = *i + 8; |
|
231 |
|
} |
|
232 |
|
|
|
233 |
|
static void my_trace_put_bool(unsigned char *buf, unsigned int *i, const char v) |
|
234 |
|
{ |
|
235 |
|
buf[*i] = v; *i = *i + 1; |
|
236 |
|
} |
|
237 |
|
|
221 |
238 |
static void my_trace_put(unsigned char *buf, unsigned int *i, |
static void my_trace_put(unsigned char *buf, unsigned int *i, |
222 |
239 |
const void *in, const size_t in_len) |
const void *in, const size_t in_len) |
223 |
240 |
{ |
{ |
|
... |
... |
static void my_trace_put_stat(unsigned char *buf, unsigned int *i, struct stat * |
256 |
273 |
my_trace_put32(buf, i, s->st_ctim.tv_nsec); |
my_trace_put32(buf, i, s->st_ctim.tv_nsec); |
257 |
274 |
} |
} |
258 |
275 |
|
|
|
276 |
|
static void my_trace_put_string_array(unsigned char *buf, unsigned int *i, char *list[]) |
|
277 |
|
{ |
|
278 |
|
unsigned int j = 0; |
|
279 |
|
|
|
280 |
|
while (1) { |
|
281 |
|
if (!list[j]) { |
|
282 |
|
my_trace_put32(buf, i, 0); |
|
283 |
|
break; |
|
284 |
|
} |
|
285 |
|
|
|
286 |
|
unsigned short len = strlen(list[j]); |
|
287 |
|
my_trace_put16(buf, i, len); |
|
288 |
|
my_trace_put(buf, i, list[j], len); |
|
289 |
|
j++; |
|
290 |
|
} |
|
291 |
|
} |
|
292 |
|
|
259 |
293 |
/* |
/* |
260 |
294 |
* Returns how many byte were stored in |
* Returns how many byte were stored in |
261 |
295 |
*/ |
*/ |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
263 |
297 |
const char *func, const char type, int save_errno, va_list va) |
const char *func, const char type, int save_errno, va_list va) |
264 |
298 |
{ |
{ |
265 |
299 |
unsigned int i, ic; |
unsigned int i, ic; |
266 |
|
uint64_t u64; |
|
267 |
300 |
|
|
268 |
301 |
i = 2; // first two bytes are for length |
i = 2; // first two bytes are for length |
269 |
302 |
my_trace_put8(buf, &i, SHARED_FUNC); |
my_trace_put8(buf, &i, SHARED_FUNC); |
270 |
303 |
|
|
271 |
304 |
struct timeval tv; |
struct timeval tv; |
272 |
305 |
gettimeofday(&tv, NULL); |
gettimeofday(&tv, NULL); |
273 |
|
u64 = tv.tv_sec * 1000 + tv.tv_usec / 1000; |
|
274 |
|
my_trace_put64(buf, &i, u64); |
|
|
306 |
|
my_trace_put64(buf, &i, tv.tv_sec * 1000 + tv.tv_usec / 1000); |
|
307 |
|
my_trace_put16(buf, &i, trace_depth); |
275 |
308 |
unsigned short flen = strlen(func); |
unsigned short flen = strlen(func); |
276 |
309 |
my_trace_put16(buf, &i, flen); |
my_trace_put16(buf, &i, flen); |
277 |
310 |
my_trace_put(buf, &i, func, flen); |
my_trace_put(buf, &i, func, flen); |
278 |
311 |
my_trace_put8(buf, &i, type); |
my_trace_put8(buf, &i, type); |
279 |
|
my_trace_put32(buf, &i, htobe32(getpid())); |
|
280 |
|
my_trace_put32(buf, &i, htobe32(gettid())); |
|
|
312 |
|
my_trace_put32(buf, &i, getpid()); |
|
313 |
|
my_trace_put32(buf, &i, gettid()); |
281 |
314 |
|
|
282 |
315 |
ic = i; |
ic = i; |
283 |
316 |
switch (func[0]) { |
switch (func[0]) { |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
388 |
421 |
} else if (strcmp(func, "dlclose") == 0) { |
} else if (strcmp(func, "dlclose") == 0) { |
389 |
422 |
uint64_t h = (uint64_t) va_arg(va, void *); |
uint64_t h = (uint64_t) va_arg(va, void *); |
390 |
423 |
my_trace_put64(buf, &i, h); |
my_trace_put64(buf, &i, h); |
|
424 |
|
int ret = va_arg(va, int); |
|
425 |
|
my_trace_put32(buf, &i, ret); |
|
426 |
|
if (ret == -1) |
|
427 |
|
my_trace_put32(buf, &i, save_errno); |
|
428 |
|
} break; |
|
429 |
|
|
|
430 |
|
case 'e': |
|
431 |
|
if (strcmp(func, "execve") == 0) { |
|
432 |
|
char *pathname = va_arg(va, char *); |
|
433 |
|
unsigned short len = strlen(pathname); |
|
434 |
|
my_trace_put16(buf, &i, len); |
|
435 |
|
my_trace_put(buf, &i, pathname, len); |
|
436 |
|
my_trace_put_string_array(buf, &i, va_arg(va, char **)); // argv |
|
437 |
|
my_trace_put_string_array(buf, &i, va_arg(va, char **)); // envp |
391 |
438 |
if (type == 'r') { |
if (type == 'r') { |
392 |
439 |
int ret = va_arg(va, int); |
int ret = va_arg(va, int); |
393 |
440 |
my_trace_put32(buf, &i, ret); |
my_trace_put32(buf, &i, ret); |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
397 |
444 |
} break; |
} break; |
398 |
445 |
|
|
399 |
446 |
case 'f': |
case 'f': |
400 |
|
if ((strcmp(func, "fstatat") == 0) |
|
|
447 |
|
if (strcmp(func, "fork") == 0) { |
|
448 |
|
int ret = va_arg(va, int); |
|
449 |
|
my_trace_put32(buf, &i, ret); |
|
450 |
|
if (ret == -1) |
|
451 |
|
my_trace_put32(buf, &i, save_errno); |
|
452 |
|
} else if ((strcmp(func, "fstatat") == 0) |
401 |
453 |
|| (strcmp(func, "fstatat64") == 0)) { |
|| (strcmp(func, "fstatat64") == 0)) { |
402 |
454 |
my_trace_put16(buf, &i, va_arg(va, int)); // dirfd |
my_trace_put16(buf, &i, va_arg(va, int)); // dirfd |
403 |
455 |
char *pathname = va_arg(va, char *); |
char *pathname = va_arg(va, char *); |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
417 |
469 |
|
|
418 |
470 |
case 'g': |
case 'g': |
419 |
471 |
if (strcmp(func, "getaddrinfo") == 0) { |
if (strcmp(func, "getaddrinfo") == 0) { |
420 |
|
uint16_t len; |
|
421 |
|
|
|
422 |
472 |
char *node = va_arg(va, char *); |
char *node = va_arg(va, char *); |
423 |
|
len = node ? strlen(node) : 0xFFFF; |
|
|
473 |
|
uint16_t len = node ? strlen(node) : 0xFFFF; |
424 |
474 |
my_trace_put16(buf, &i, len); |
my_trace_put16(buf, &i, len); |
425 |
475 |
if (node) |
if (node) |
426 |
476 |
my_trace_put(buf, &i, node, len); |
my_trace_put(buf, &i, node, len); |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
467 |
517 |
my_trace_put32(buf, &i, save_errno); |
my_trace_put32(buf, &i, save_errno); |
468 |
518 |
} |
} |
469 |
519 |
} |
} |
|
520 |
|
} else if (strcmp(func, "getsockopt") == 0) { |
|
521 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // sock |
|
522 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // level |
|
523 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // optname |
|
524 |
|
void *optval = va_arg(va, void *); |
|
525 |
|
socklen_t optlen = va_arg(va, socklen_t); |
|
526 |
|
my_trace_put32(buf, &i, optlen); |
|
527 |
|
my_trace_put(buf, &i, optval, optlen); |
|
528 |
|
int ret = va_arg(va, int); |
|
529 |
|
my_trace_put32(buf, &i, ret); |
|
530 |
|
if (ret == -1) |
|
531 |
|
my_trace_put32(buf, &i, save_errno); |
470 |
532 |
} break; |
} break; |
471 |
533 |
|
|
472 |
534 |
case 'l': |
case 'l': |
473 |
535 |
if (strcmp(func, "listen") == 0) { |
if (strcmp(func, "listen") == 0) { |
474 |
536 |
my_trace_put32(buf, &i, va_arg(va, int)); // sock |
my_trace_put32(buf, &i, va_arg(va, int)); // sock |
475 |
537 |
my_trace_put32(buf, &i, va_arg(va, int)); // backlog |
my_trace_put32(buf, &i, va_arg(va, int)); // backlog |
476 |
|
if (type == 'r') { |
|
477 |
|
int ret = va_arg(va, int); |
|
478 |
|
my_trace_put32(buf, &i, ret); |
|
479 |
|
if (ret == -1) |
|
480 |
|
my_trace_put32(buf, &i, save_errno); |
|
481 |
|
} |
|
|
538 |
|
int ret = va_arg(va, int); |
|
539 |
|
my_trace_put32(buf, &i, ret); |
|
540 |
|
if (ret == -1) |
|
541 |
|
my_trace_put32(buf, &i, save_errno); |
|
542 |
|
} break; |
|
543 |
|
|
|
544 |
|
case 'm': |
|
545 |
|
if (strcmp(func, "mysqli_close") == 0) { |
|
546 |
|
struct conn *c = va_arg(va, struct conn *); |
|
547 |
|
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
|
548 |
|
if (type == 'r') |
|
549 |
|
my_trace_put_bool(buf, &i, c->ret); |
|
550 |
|
} else if (strcmp(func, "mysqli_connect") == 0) { |
|
551 |
|
struct conn *c = va_arg(va, struct conn *); |
|
552 |
|
my_trace_put32(buf, &i, c->conn_str_len); |
|
553 |
|
my_trace_put(buf, &i, c->conn_str, c->conn_str_len); |
|
554 |
|
if (type == 'r') |
|
555 |
|
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
|
556 |
|
} else if (strcmp(func, "mysqli_real_connect") == 0) { |
|
557 |
|
struct conn *c = va_arg(va, struct conn *); |
|
558 |
|
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
|
559 |
|
my_trace_put32(buf, &i, c->conn_str_len); |
|
560 |
|
my_trace_put(buf, &i, c->conn_str, c->conn_str_len); |
|
561 |
|
my_trace_put32(buf, &i, c->flags); |
|
562 |
|
if (type == 'r') |
|
563 |
|
my_trace_put_bool(buf, &i, c->ret); |
|
564 |
|
/* TODO |
|
565 |
|
} else if (strcmp(func, "mysqli_prepare") == 0) { |
|
566 |
|
struct query *q = va_arg(va, struct query *); |
|
567 |
|
my_trace_put64(buf, &i, (uint64_t) q->dbh); |
|
568 |
|
my_trace_put16(buf, &i, q->q_len); |
|
569 |
|
my_trace_put(buf, &i, q->q, q->q_len); |
|
570 |
|
if (type == 'r') |
|
571 |
|
my_trace_put_bool(buf, &i, c->ret); |
|
572 |
|
*/ |
|
573 |
|
} else if (strcmp(func, "mysqli_query") == 0) { |
|
574 |
|
struct query *q = va_arg(va, struct query *); |
|
575 |
|
my_trace_put64(buf, &i, (uint64_t) q->dbh); |
|
576 |
|
my_trace_put16(buf, &i, q->q_len); |
|
577 |
|
my_trace_put(buf, &i, q->q, q->q_len); |
|
578 |
|
if (type == 'r') |
|
579 |
|
my_trace_put64(buf, &i, (uint64_t) q->res); |
482 |
580 |
} break; |
} break; |
483 |
581 |
|
|
484 |
582 |
case 'n': |
case 'n': |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
539 |
637 |
if (ret == -1) |
if (ret == -1) |
540 |
638 |
my_trace_put32(buf, &i, save_errno); |
my_trace_put32(buf, &i, save_errno); |
541 |
639 |
} |
} |
|
640 |
|
} else if (strcmp(func, "pg_close") == 0) { |
|
641 |
|
uint64_t h = va_arg(va, uint64_t); // handle |
|
642 |
|
my_trace_put64(buf, &i, h); |
|
643 |
|
} else if ((strcmp(func, "pg_connect") == 0) |
|
644 |
|
|| (strcmp(func, "pg_pconnect") == 0)) { |
|
645 |
|
char *cs = va_arg(va, char *); |
|
646 |
|
unsigned int cs_len = va_arg(va, unsigned int); |
|
647 |
|
my_trace_put32(buf, &i, cs_len); |
|
648 |
|
my_trace_put(buf, &i, cs, cs_len); |
|
649 |
|
if (type == 'r') |
|
650 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // handle |
|
651 |
|
} else if (strcmp(func, "pg_free_result") == 0) { |
|
652 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // res |
|
653 |
|
my_trace_put8(buf, &i, va_arg(va, int)); // ret |
|
654 |
|
} else if ((strcmp(func, "pg_query") == 0) |
|
655 |
|
|| (strcmp(func, "pg_query_params") == 0) |
|
656 |
|
|| (strcmp(func, "pg_send_query") == 0) |
|
657 |
|
|| (strcmp(func, "pg_send_query_params") == 0)) { |
|
658 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // dbh |
|
659 |
|
char *q = va_arg(va, void *); |
|
660 |
|
unsigned short q_len = va_arg(va, unsigned int); |
|
661 |
|
my_trace_put16(buf, &i, q_len); |
|
662 |
|
my_trace_put(buf, &i, q, q_len); |
|
663 |
|
if (type == 'c') { |
|
664 |
|
uint16_t params_len = va_arg(va, unsigned); |
|
665 |
|
my_trace_put16(buf, &i, params_len); |
|
666 |
|
uint16_t max = params_len; |
|
667 |
|
if (max > ND_PARAMS_MAX) max = ND_PARAMS_MAX; |
|
668 |
|
my_trace_put16(buf, &i, max); |
|
669 |
|
struct params_array *pa = va_arg(va, void *); |
|
670 |
|
for (unsigned short j = 0; j < max; j++) { |
|
671 |
|
my_trace_put8(buf, &i, pa->type); |
|
672 |
|
if (pa->type == ND_PARAMS_TYPE_LONG) { |
|
673 |
|
my_trace_put64(buf, &i, pa->l); |
|
674 |
|
} else if (pa->type == ND_PARAMS_TYPE_DOUBLE) { |
|
675 |
|
my_trace_put_double(buf, &i, pa->d); |
|
676 |
|
} else if (pa->type == ND_PARAMS_TYPE_STRING) { |
|
677 |
|
my_trace_put16(buf, &i, pa->length); |
|
678 |
|
my_trace_put(buf, &i, pa->str, pa->length); |
|
679 |
|
} |
|
680 |
|
pa++; |
|
681 |
|
} |
|
682 |
|
} |
|
683 |
|
if (type == 'r') { |
|
684 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // res |
|
685 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // rows |
|
686 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // aff |
|
687 |
|
} |
|
688 |
|
} else if (strcmp(func, "pg_get_result") == 0) { |
|
689 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // dbh |
|
690 |
|
(void) va_arg(va, void *); // ignore q |
|
691 |
|
(void) va_arg(va, unsigned int); // ignore q_len |
|
692 |
|
if (type == 'r') { |
|
693 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // res |
|
694 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // rows |
|
695 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // aff |
|
696 |
|
} |
542 |
697 |
} break; |
} break; |
543 |
698 |
|
|
544 |
699 |
case 'r': |
case 'r': |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
557 |
712 |
if (max > 128) |
if (max > 128) |
558 |
713 |
max = 128; |
max = 128; |
559 |
714 |
my_trace_put16(buf, &i, max); |
my_trace_put16(buf, &i, max); |
560 |
|
memcpy(buf + i, buf2, max); i += max; // data |
|
|
715 |
|
my_trace_put(buf, &i, buf2, max); // data |
561 |
716 |
} |
} |
562 |
717 |
if (ret == -1) |
if (ret == -1) |
563 |
718 |
my_trace_put32(buf, &i, save_errno); |
my_trace_put32(buf, &i, save_errno); |
564 |
719 |
} |
} |
|
720 |
|
} else if (strcmp(func, "recvfrom") == 0) { |
|
721 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // sock |
|
722 |
|
struct sockaddr *addr = NULL; |
|
723 |
|
my_trace_put64(buf, &i, va_arg(va, uint64_t)); // len |
|
724 |
|
if (type == 'r') |
|
725 |
|
addr = va_arg(va, void *); |
|
726 |
|
socklen_t addrlen = va_arg(va, socklen_t); |
|
727 |
|
if (!addr) |
|
728 |
|
addrlen = 0; |
|
729 |
|
my_trace_put32(buf, &i, addrlen); |
|
730 |
|
int flags = va_arg(va, int); |
|
731 |
|
my_trace_put32(buf, &i, flags); |
|
732 |
|
if (type == 'r') { |
|
733 |
|
ssize_t ret = va_arg(va, ssize_t); |
|
734 |
|
my_trace_put64(buf, &i, ret); |
|
735 |
|
if (ret == -1) { |
|
736 |
|
my_trace_put32(buf, &i, save_errno); |
|
737 |
|
} else if (ret > 0) { // TODO: not sure if ret is 0 if addr is filled or not |
|
738 |
|
unsigned short max = ret; |
|
739 |
|
if (max > 128) max = 128; |
|
740 |
|
my_trace_put16(buf, &i, max); |
|
741 |
|
void *buf = va_arg(va, void *); |
|
742 |
|
my_trace_put(buf, &i, buf, max); |
|
743 |
|
if (addrlen) |
|
744 |
|
my_trace_put(buf, &i, addr, addrlen); |
|
745 |
|
} |
|
746 |
|
} |
565 |
747 |
} break; |
} break; |
566 |
748 |
|
|
567 |
749 |
case 's': |
case 's': |
568 |
750 |
if (strcmp(func, "send") == 0) { |
if (strcmp(func, "send") == 0) { |
|
751 |
|
const void *data = NULL; |
569 |
752 |
my_trace_put32(buf, &i, va_arg(va, int)); // sock |
my_trace_put32(buf, &i, va_arg(va, int)); // sock |
570 |
|
const void *data = va_arg(va, void *); |
|
|
753 |
|
if (type == 'c') |
|
754 |
|
data = va_arg(va, void *); |
571 |
755 |
size_t len = va_arg(va, size_t); |
size_t len = va_arg(va, size_t); |
572 |
756 |
my_trace_put64(buf, &i, len); |
my_trace_put64(buf, &i, len); |
573 |
757 |
my_trace_put32(buf, &i, va_arg(va, ssize_t)); // flags |
my_trace_put32(buf, &i, va_arg(va, ssize_t)); // flags |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
623 |
807 |
my_trace_put32(buf, &i, va_arg(va, int)); // domain |
my_trace_put32(buf, &i, va_arg(va, int)); // domain |
624 |
808 |
my_trace_put32(buf, &i, va_arg(va, int)); // type |
my_trace_put32(buf, &i, va_arg(va, int)); // type |
625 |
809 |
my_trace_put32(buf, &i, va_arg(va, int)); // protocol |
my_trace_put32(buf, &i, va_arg(va, int)); // protocol |
|
810 |
|
int ret = va_arg(va, int); |
|
811 |
|
my_trace_put32(buf, &i, ret); |
|
812 |
|
if (ret == -1) |
|
813 |
|
my_trace_put32(buf, &i, save_errno); |
|
814 |
|
} else if (strcmp(func, "sqlite3_open_v2") == 0) { |
|
815 |
|
char *filename = va_arg(va, char *); |
|
816 |
|
uint16_t filename_len = strlen(filename); |
|
817 |
|
my_trace_put16(buf, &i, filename_len); |
|
818 |
|
if (filename_len) my_trace_put(buf, &i, filename, filename_len); |
|
819 |
|
// TODO: test for zero should be put in the function |
|
820 |
|
uint64_t pdb; |
|
821 |
|
if (type == 'r') |
|
822 |
|
pdb = va_arg(va, uint64_t); |
|
823 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // flags |
|
824 |
|
char *vfs = va_arg(va, char *); |
|
825 |
|
uint16_t vfs_len = vfs ? strlen(vfs) : 0; |
|
826 |
|
my_trace_put16(buf, &i, vfs_len); |
|
827 |
|
if (vfs_len) my_trace_put(buf, &i, vfs, vfs_len); |
626 |
828 |
if (type == 'r') { |
if (type == 'r') { |
627 |
829 |
int ret = va_arg(va, int); |
int ret = va_arg(va, int); |
628 |
830 |
my_trace_put32(buf, &i, ret); |
my_trace_put32(buf, &i, ret); |
629 |
|
if (ret == -1) |
|
630 |
|
my_trace_put32(buf, &i, save_errno); |
|
|
831 |
|
if (ret == 0) |
|
832 |
|
my_trace_put64(buf, &i, pdb); |
631 |
833 |
} |
} |
|
834 |
|
} else if (strcmp(func, "sqlite3_prepare_v2") == 0) { |
|
835 |
|
uint64_t h = va_arg(va, uint64_t); |
|
836 |
|
my_trace_put64(buf, &i, h); |
|
837 |
|
char *sql = va_arg(va, char *); |
|
838 |
|
uint32_t sql_len = strlen(sql); |
|
839 |
|
my_trace_put32(buf, &i, sql_len); |
|
840 |
|
if (sql_len) my_trace_put(buf, &i, sql, sql_len); |
|
841 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // nByte |
|
842 |
|
if (type == 'r') { |
|
843 |
|
my_trace_put64(buf, &i, va_arg(va, uint64_t)); // stmt |
|
844 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
|
845 |
|
} |
|
846 |
|
} else if (strcmp(func, "sqlite3_step") == 0) { |
|
847 |
|
uint64_t stmt = va_arg(va, uint64_t); |
|
848 |
|
my_trace_put64(buf, &i, stmt); |
|
849 |
|
if (type == 'r') |
|
850 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
632 |
851 |
} else if (strcmp(func, "stat") == 0) { |
} else if (strcmp(func, "stat") == 0) { |
633 |
852 |
char *pathname = va_arg(va, char *); |
char *pathname = va_arg(va, char *); |
634 |
853 |
unsigned short len = strlen(pathname); |
unsigned short len = strlen(pathname); |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
696 |
915 |
return i; |
return i; |
697 |
916 |
} |
} |
698 |
917 |
|
|
699 |
|
static void my_trace(const char *func, const char type, ...) |
|
|
918 |
|
void my_trace(const char *func, const char type, ...) |
700 |
919 |
{ |
{ |
701 |
920 |
int save_errno; |
int save_errno; |
702 |
921 |
va_list va; |
va_list va; |
|
... |
... |
static void my_trace(const char *func, const char type, ...) |
710 |
929 |
|
|
711 |
930 |
save_errno = errno; |
save_errno = errno; |
712 |
931 |
|
|
713 |
|
xlog(0, "%s func=%s type=%c errno=%d\n", __func__, func, type, errno); |
|
|
932 |
|
xlog(200, "%s func=%s type=%c errno=%d\n", |
|
933 |
|
__func__, func, type, errno); |
714 |
934 |
|
|
715 |
935 |
locked = 0; |
locked = 0; |
716 |
936 |
do { |
do { |
|
... |
... |
static void my_trace(const char *func, const char type, ...) |
721 |
941 |
i = my_trace_encode(out, func, type, save_errno, va); |
i = my_trace_encode(out, func, type, save_errno, va); |
722 |
942 |
va_end(va); |
va_end(va); |
723 |
943 |
if (i == 0) { |
if (i == 0) { |
724 |
|
xlog(0, "I do not know how to encode [%s][%c]!\n", func, type); |
|
|
944 |
|
xlog(1, "I do not know how to encode [%s][%c]!\n", func, type); |
725 |
945 |
break; |
break; |
726 |
946 |
} |
} |
727 |
947 |
|
|
728 |
948 |
char dump[i * 4 + 1]; |
char dump[i * 4 + 1]; |
729 |
949 |
bin2hex_ascii(dump, out, i); |
bin2hex_ascii(dump, out, i); |
730 |
|
xlog(0, " gen: %s\n", dump); |
|
|
950 |
|
xlog(201, " gen: %s\n", dump); |
731 |
951 |
|
|
732 |
|
xlog(0, " head=%u tail=%u to_copy=%u [start]\n", |
|
|
952 |
|
// TODO: use an internal buffer if we cannot take the lock and move back to 'trywait' |
|
953 |
|
xlog(201, " head=%u tail=%u to_copy=%u [start]\n", |
733 |
954 |
shared->head, shared->tail, i); |
shared->head, shared->tail, i); |
734 |
|
r = sem_trywait(&shared->sem1); |
|
|
955 |
|
r = sem_wait(&shared->sem1); |
735 |
956 |
if (r == -1) { |
if (r == -1) { |
736 |
|
xlog(0, "sem_trywait sem1 error: %m\n"); |
|
|
957 |
|
xlog(1, "sem_trywait sem1 error: %m\n"); |
737 |
958 |
break; |
break; |
738 |
959 |
} |
} |
739 |
960 |
locked = 1; |
locked = 1; |
|
... |
... |
static void my_trace(const char *func, const char type, ...) |
748 |
969 |
ava = shared->head - shared->tail; |
ava = shared->head - shared->tail; |
749 |
970 |
} |
} |
750 |
971 |
if (ava < i) { |
if (ava < i) { |
751 |
|
xlog(0, "%s: not enough available: ava[%u] < i[%u]\n", |
|
|
972 |
|
xlog(1, "%s: not enough available: ava[%u] < i[%u]\n", |
752 |
973 |
__func__, ava, i); |
__func__, ava, i); |
753 |
974 |
shared->msgs_lost++; // TODO: add to an internal buffer |
shared->msgs_lost++; // TODO: add to an internal buffer |
754 |
975 |
break; |
break; |
755 |
976 |
} |
} |
756 |
|
unsigned int max = shared->buf_size - shared->tail; // size=11 tail=5 max=6: .....t..... |
|
|
977 |
|
unsigned int max = shared->buf_size - shared->tail; // size=11 tail=5 max=6: .....t..... |
757 |
978 |
if (max > i) { // enough space |
if (max > i) { // enough space |
758 |
979 |
memcpy(shared->buf + shared->tail, out, i); |
memcpy(shared->buf + shared->tail, out, i); |
759 |
980 |
shared->tail += i; |
shared->tail += i; |
|
... |
... |
static void my_trace(const char *func, const char type, ...) |
762 |
983 |
memcpy(shared->buf, out + max, i - max); |
memcpy(shared->buf, out + max, i - max); |
763 |
984 |
shared->tail = i - max; // size=13 head=2 tail=5 i=9 max=8: ..h..t....... => 89h..01234567 => tail=1 |
shared->tail = i - max; // size=13 head=2 tail=5 i=9 max=8: ..h..t....... => 89h..01234567 => tail=1 |
764 |
985 |
} |
} |
765 |
|
|
|
766 |
|
shared->tail = shared->tail; |
|
767 |
|
|
|
768 |
986 |
} while (0); |
} while (0); |
769 |
987 |
|
|
770 |
988 |
if (locked) { |
if (locked) { |
771 |
989 |
r = sem_post(&shared->sem1); // was sem2 |
r = sem_post(&shared->sem1); // was sem2 |
772 |
990 |
if (r == -1) |
if (r == -1) |
773 |
|
xlog(0, "sem_post sem1 error: %m\n"); |
|
|
991 |
|
xlog(1, "sem_post sem1 error: %m\n"); |
774 |
992 |
|
|
775 |
|
xlog(0, " head=%u tail=%u shared->tail=%u [got lock]\n", |
|
776 |
|
shared->head, shared->tail, shared->tail); |
|
|
993 |
|
xlog(201, " head=%u tail=%u [got lock]\n", |
|
994 |
|
shared->head, shared->tail); |
777 |
995 |
} |
} |
778 |
996 |
|
|
|
997 |
|
if (type == 'c') |
|
998 |
|
trace_depth++; |
|
999 |
|
else if (type == 'r') |
|
1000 |
|
trace_depth--; |
|
1001 |
|
|
779 |
1002 |
errno = save_errno; |
errno = save_errno; |
780 |
1003 |
} |
} |
781 |
1004 |
|
|
782 |
1005 |
static void my_on_exit(int ret, void *junk) |
static void my_on_exit(int ret, void *junk) |
783 |
1006 |
{ |
{ |
784 |
1007 |
xlog(100, "my_on_exit ret=%d junk=%p!\n", ret, junk); |
xlog(100, "my_on_exit ret=%d junk=%p!\n", ret, junk); |
785 |
|
my_trace("-stop", 'r', ret); |
|
|
1008 |
|
my_trace("-stop", 'R', ret); |
786 |
1009 |
ninedogs_process_core(NINEDOGS_CORE_STOP, &ret); |
ninedogs_process_core(NINEDOGS_CORE_STOP, &ret); |
787 |
1010 |
} |
} |
788 |
1011 |
|
|
|
... |
... |
void _exit(int status) |
791 |
1014 |
{ |
{ |
792 |
1015 |
//write(1, "_exit\n", 6); |
//write(1, "_exit\n", 6); |
793 |
1016 |
xlog(1, "my _exit status=%d!\n", status); |
xlog(1, "my _exit status=%d!\n", status); |
794 |
|
my_trace("-stop", 'r', status); |
|
|
1017 |
|
my_trace("-stop", 'R', status); |
795 |
1018 |
old__exit(status); |
old__exit(status); |
796 |
1019 |
} |
} |
797 |
1020 |
#endif |
#endif |
|
... |
... |
static void my_segv(int sig) |
811 |
1034 |
for (int j = 0; j < r; j++) |
for (int j = 0; j < r; j++) |
812 |
1035 |
xlog(0, " %s\n", a[j]); |
xlog(0, " %s\n", a[j]); |
813 |
1036 |
} |
} |
814 |
|
my_trace("-segv", 'r', a, r); |
|
|
1037 |
|
my_trace("-segv", 'R', a, r); |
815 |
1038 |
|
|
816 |
1039 |
exit(1); |
exit(1); |
817 |
1040 |
} |
} |
|
... |
... |
static void ninedogs_child(void) |
877 |
1100 |
|
|
878 |
1101 |
__attribute__((destructor)) void ninedogs_fini(void) |
__attribute__((destructor)) void ninedogs_fini(void) |
879 |
1102 |
{ |
{ |
880 |
|
xlog(0, "%s\n", __func__); |
|
|
1103 |
|
xlog(20, "%s\n", __func__); |
881 |
1104 |
//my_trace("-dest", "r"); |
//my_trace("-dest", "r"); |
882 |
1105 |
if (shared_inited) { |
if (shared_inited) { |
883 |
1106 |
char name[128]; |
char name[128]; |
|
... |
... |
__attribute__((constructor)) void ninedogs_init(void) |
916 |
1139 |
return; |
return; |
917 |
1140 |
|
|
918 |
1141 |
//write(1, "ninedogs: init start\n", 21); |
//write(1, "ninedogs: init start\n", 21); |
919 |
|
dlh = dlmopen(LM_ID_BASE, "/date/sync/no-crypt/sync1/Dev/ninedogs/agent/ninedogs_dlsym_env.so", |
|
|
1142 |
|
dlh = dlmopen(LM_ID_BASE, "/usr/lib64/ninedogs_dlsym_env.so", |
920 |
1143 |
RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND); |
RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND); |
|
1144 |
|
if (!dlh) |
|
1145 |
|
dlh = dlmopen(LM_ID_BASE, "/usr/lib/ninedogs_dlsym_env.so", |
|
1146 |
|
RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND); |
|
1147 |
|
if (!dlh) |
|
1148 |
|
dlh = dlmopen(LM_ID_BASE, "/date/sync/no-crypt/sync1/Dev/ninedogs/agent/ninedogs_dlsym_env.so", |
|
1149 |
|
RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND); |
921 |
1150 |
//write(1, "ae\n", 3); |
//write(1, "ae\n", 3); |
922 |
1151 |
if (!dlh) |
if (!dlh) |
923 |
1152 |
exit(1); |
exit(1); |
|
... |
... |
__attribute__((constructor)) void ninedogs_init(void) |
1183 |
1412 |
exit(1); |
exit(1); |
1184 |
1413 |
} |
} |
1185 |
1414 |
|
|
|
1415 |
|
old_fork = old_dlsym(RTLD_NEXT, "fork"); |
|
1416 |
|
if (old_fork == NULL) { |
|
1417 |
|
xlog(0, " cannot resolve 'fork'!\n"); |
|
1418 |
|
exit(1); |
|
1419 |
|
} |
|
1420 |
|
|
1186 |
1421 |
|
|
1187 |
1422 |
x = getenv("NINEDOGS_VERBOSE"); |
x = getenv("NINEDOGS_VERBOSE"); |
1188 |
1423 |
if (x != NULL) |
if (x != NULL) |
|
... |
... |
__attribute__((constructor)) void ninedogs_init(void) |
1214 |
1449 |
xlog(0, "Cannot do mmap: %m\n"); |
xlog(0, "Cannot do mmap: %m\n"); |
1215 |
1450 |
break; |
break; |
1216 |
1451 |
} |
} |
1217 |
|
xlog(0, "%s: shared=%p\n", __func__, shared); |
|
|
1452 |
|
xlog(200, "%s: shared=%p\n", __func__, shared); |
1218 |
1453 |
|
|
1219 |
1454 |
if (sem_init(&shared->sem1, 1, 1) == -1) { |
if (sem_init(&shared->sem1, 1, 1) == -1) { |
1220 |
1455 |
xlog(0, "Cannot do sem_init sem1: %m\n"); |
xlog(0, "Cannot do sem_init sem1: %m\n"); |
1221 |
1456 |
break; |
break; |
1222 |
1457 |
} |
} |
1223 |
1458 |
|
|
|
1459 |
|
shared->version = SHARED_VERSION; |
1224 |
1460 |
shared->buf_size = sizeof(shared->buf); |
shared->buf_size = sizeof(shared->buf); |
1225 |
1461 |
shared->msgs_lost = 0; |
shared->msgs_lost = 0; |
1226 |
1462 |
// We want force from start start the wrap around |
// We want force from start start the wrap around |
|
... |
... |
__attribute__((constructor)) void ninedogs_init(void) |
1239 |
1475 |
x = getenv("JAVA_TOOL_OPTIONS"); |
x = getenv("JAVA_TOOL_OPTIONS"); |
1240 |
1476 |
if (!x) |
if (!x) |
1241 |
1477 |
x = ""; |
x = ""; |
1242 |
|
snprintf(env, sizeof(env), "-javaagent:../../../agent/java/agent/ninedogs-agent.jar %s", x); |
|
|
1478 |
|
snprintf(env, sizeof(env), "-javaagent:/usr/share/ninedogs/ninedogs-agent.jar %s", x); |
1243 |
1479 |
setenv("JAVA_TOOL_OPTIONS", env, 1); |
setenv("JAVA_TOOL_OPTIONS", env, 1); |
1244 |
1480 |
|
|
1245 |
1481 |
/* .NET stuff */ |
/* .NET stuff */ |
|
... |
... |
__attribute__((constructor)) void ninedogs_init(void) |
1255 |
1491 |
|
|
1256 |
1492 |
ninedogs_process_core(NINEDOGS_CORE_START, NULL); |
ninedogs_process_core(NINEDOGS_CORE_START, NULL); |
1257 |
1493 |
|
|
|
1494 |
|
xlog(100, "%s: done; my pid %d\n", __func__, getpid()); |
1258 |
1495 |
} |
} |
1259 |
1496 |
|
|
1260 |
1497 |
void *realloc(void *ptr, size_t size) |
void *realloc(void *ptr, size_t size) |
|
... |
... |
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
1407 |
1644 |
return -1; |
return -1; |
1408 |
1645 |
|
|
1409 |
1646 |
saddr(tmp, sizeof(tmp), (struct sockaddr *) addr); |
saddr(tmp, sizeof(tmp), (struct sockaddr *) addr); |
1410 |
|
xlog(1, "bind(sockfd=%d, %s)\n", sockfd, tmp); |
|
|
1647 |
|
xlog(100, "bind(sockfd=%d, %s)\n", sockfd, tmp); |
1411 |
1648 |
|
|
1412 |
1649 |
memcpy(&new, addr, addrlen); |
memcpy(&new, addr, addrlen); |
1413 |
1650 |
|
|
|
... |
... |
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
1424 |
1661 |
} while (0); |
} while (0); |
1425 |
1662 |
|
|
1426 |
1663 |
ret = old_bind(sockfd, (struct sockaddr *) &new, addrlen); |
ret = old_bind(sockfd, (struct sockaddr *) &new, addrlen); |
1427 |
|
my_trace(__func__, 'r', sockfd, &new, addrlen, ret); |
|
|
1664 |
|
my_trace(__func__, 'R', sockfd, &new, addrlen, ret); |
1428 |
1665 |
|
|
1429 |
1666 |
return ret; |
return ret; |
1430 |
1667 |
} |
} |
|
... |
... |
int socket(int domain, int type, int protocol) |
1495 |
1732 |
{ |
{ |
1496 |
1733 |
int sockfd; |
int sockfd; |
1497 |
1734 |
|
|
1498 |
|
xlog(50, "socket(domain=%s[%d], type=%s, protocol=%s)\n", |
|
|
1735 |
|
xlog(100, "socket(domain=%s[%d], type=%s, protocol=%s)\n", |
1499 |
1736 |
sdomain(domain), domain, stype(type), sprotocol(protocol)); |
sdomain(domain), domain, stype(type), sprotocol(protocol)); |
1500 |
1737 |
|
|
1501 |
1738 |
sockfd = old_socket(domain, type, protocol); |
sockfd = old_socket(domain, type, protocol); |
1502 |
1739 |
//if (sockfd != -1) |
//if (sockfd != -1) |
1503 |
1740 |
// socket_create_callback(sockfd, domain, type); |
// socket_create_callback(sockfd, domain, type); |
1504 |
|
|
|
1505 |
|
my_trace(__func__, 'r', domain, type, protocol, sockfd); |
|
|
1741 |
|
my_trace(__func__, 'R', domain, type, protocol, sockfd); |
1506 |
1742 |
|
|
1507 |
1743 |
return sockfd; |
return sockfd; |
1508 |
1744 |
} |
} |
|
... |
... |
int close(int fd) |
1519 |
1755 |
//del(fd); |
//del(fd); |
1520 |
1756 |
fd_del(fd); |
fd_del(fd); |
1521 |
1757 |
|
|
|
1758 |
|
my_trace(__func__, 'c', fd); |
1522 |
1759 |
ret = old_close(fd); |
ret = old_close(fd); |
1523 |
|
|
|
1524 |
1760 |
my_trace(__func__, 'r', fd, ret); |
my_trace(__func__, 'r', fd, ret); |
1525 |
1761 |
|
|
1526 |
1762 |
return ret; |
return ret; |
|
... |
... |
ssize_t send(int sockfd, const void *buf, size_t len, int flags) |
1577 |
1813 |
struct node *q; |
struct node *q; |
1578 |
1814 |
ssize_t ret; |
ssize_t ret; |
1579 |
1815 |
|
|
1580 |
|
xlog(50, "%s(sockfd=%d, buf, len=%zu, flags=0x%x)\n", |
|
|
1816 |
|
xlog(110, "%s(sockfd=%d, buf, len=%zu, flags=0x%x)\n", |
1581 |
1817 |
__func__, sockfd, len, flags); |
__func__, sockfd, len, flags); |
1582 |
1818 |
|
|
1583 |
1819 |
/* We do not touch non network sockets */ |
/* We do not touch non network sockets */ |
|
... |
... |
ssize_t send(int sockfd, const void *buf, size_t len, int flags) |
1587 |
1823 |
} |
} |
1588 |
1824 |
|
|
1589 |
1825 |
my_trace(__func__, 'c', sockfd, buf, len, flags); |
my_trace(__func__, 'c', sockfd, buf, len, flags); |
1590 |
|
|
|
1591 |
1826 |
ret = old_send(sockfd, buf, len, flags); |
ret = old_send(sockfd, buf, len, flags); |
1592 |
|
|
|
1593 |
1827 |
my_trace(__func__, 'r', sockfd, len, flags, ret); |
my_trace(__func__, 'r', sockfd, len, flags, ret); |
1594 |
1828 |
|
|
1595 |
1829 |
return ret; |
return ret; |
|
... |
... |
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, |
1601 |
1835 |
struct node *q; |
struct node *q; |
1602 |
1836 |
ssize_t ret; |
ssize_t ret; |
1603 |
1837 |
|
|
1604 |
|
xlog(50, "sendto(sockfd, %d, buf, len=%zu, flags=0x%x, ...)\n", |
|
|
1838 |
|
xlog(110, "sendto(sockfd, %d, buf, len=%zu, flags=0x%x, ...)\n", |
1605 |
1839 |
sockfd, len, flags); |
sockfd, len, flags); |
1606 |
1840 |
|
|
1607 |
1841 |
/* We do not touch non network sockets */ |
/* We do not touch non network sockets */ |
|
... |
... |
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, |
1611 |
1845 |
} |
} |
1612 |
1846 |
|
|
1613 |
1847 |
my_trace(__func__, 'c', sockfd, buf, len, flags, dest_addr, addrlen); |
my_trace(__func__, 'c', sockfd, buf, len, flags, dest_addr, addrlen); |
1614 |
|
|
|
1615 |
1848 |
ret = old_sendto(sockfd, buf, len, flags, dest_addr, addrlen); |
ret = old_sendto(sockfd, buf, len, flags, dest_addr, addrlen); |
1616 |
|
|
|
1617 |
1849 |
my_trace(__func__, 'r', sockfd, len, flags, ret); |
my_trace(__func__, 'r', sockfd, len, flags, ret); |
1618 |
1850 |
|
|
1619 |
1851 |
return ret; |
return ret; |
|
... |
... |
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) |
1629 |
1861 |
struct sockaddr_storage new_dest; |
struct sockaddr_storage new_dest; |
1630 |
1862 |
*/ |
*/ |
1631 |
1863 |
|
|
1632 |
|
xlog(50, "sendmsg(sockfd=%d, ..., flags=0x%x)\n", |
|
|
1864 |
|
xlog(100, "sendmsg(sockfd=%d, ..., flags=0x%x)\n", |
1633 |
1865 |
sockfd, flags); |
sockfd, flags); |
1634 |
1866 |
|
|
1635 |
1867 |
/* TODO: log also this! */ |
/* TODO: log also this! */ |
|
... |
... |
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) |
1637 |
1869 |
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); |
1638 |
1870 |
|
|
1639 |
1871 |
my_trace(__func__, 'c', sockfd, msg, flags); |
my_trace(__func__, 'c', sockfd, msg, flags); |
1640 |
|
|
|
1641 |
1872 |
ret = old_sendmsg(sockfd, msg, flags); |
ret = old_sendmsg(sockfd, msg, flags); |
1642 |
1873 |
xlog(50, " returned %zd\n", ret); |
xlog(50, " returned %zd\n", ret); |
1643 |
|
|
|
1644 |
1874 |
my_trace(__func__, 'r', sockfd, flags, ret); |
my_trace(__func__, 'r', sockfd, flags, ret); |
1645 |
1875 |
|
|
1646 |
1876 |
return ret; |
return ret; |
|
... |
... |
ssize_t recv(int sockfd, void *buf, size_t len, int flags) |
1651 |
1881 |
struct node *q; |
struct node *q; |
1652 |
1882 |
ssize_t ret; |
ssize_t ret; |
1653 |
1883 |
|
|
1654 |
|
xlog(50, "%s(sockfd=%d, buf, len=%zu, flags=0x%x)\n", |
|
|
1884 |
|
xlog(110, "%s(sockfd=%d, buf, len=%zu, flags=0x%x)\n", |
1655 |
1885 |
__func__, sockfd, len, flags); |
__func__, sockfd, len, flags); |
1656 |
1886 |
|
|
1657 |
1887 |
my_trace(__func__, 'c', sockfd, len, flags); |
my_trace(__func__, 'c', sockfd, len, flags); |
1658 |
|
|
|
1659 |
1888 |
ret = old_recv(sockfd, buf, len, flags); |
ret = old_recv(sockfd, buf, len, flags); |
1660 |
|
|
|
1661 |
1889 |
/* We do not touch non network sockets */ |
/* We do not touch non network sockets */ |
1662 |
1890 |
q = get(sockfd); |
q = get(sockfd); |
1663 |
1891 |
if (q && (q->priv.flags & FB_FLAGS_NETSOCK)) { |
if (q && (q->priv.flags & FB_FLAGS_NETSOCK)) { |
|
... |
... |
ssize_t recv(int sockfd, void *buf, size_t len, int flags) |
1665 |
1893 |
if (ret > 0) |
if (ret > 0) |
1666 |
1894 |
dump(200, "recv", buf, ret); |
dump(200, "recv", buf, ret); |
1667 |
1895 |
} |
} |
1668 |
|
|
|
1669 |
1896 |
my_trace(__func__, 'r', sockfd, buf, len, flags, ret); |
my_trace(__func__, 'r', sockfd, buf, len, flags, ret); |
1670 |
1897 |
|
|
1671 |
1898 |
return ret; |
return ret; |
|
... |
... |
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) |
1678 |
1905 |
unsigned int i; |
unsigned int i; |
1679 |
1906 |
size_t rest; |
size_t rest; |
1680 |
1907 |
|
|
1681 |
|
xlog(50, "%s(sockfd=%d, msg, flags=0x%x)\n", |
|
|
1908 |
|
xlog(110, "%s(sockfd=%d, msg, flags=0x%x)\n", |
1682 |
1909 |
__func__, sockfd, flags); |
__func__, sockfd, flags); |
1683 |
1910 |
|
|
1684 |
1911 |
my_trace(__func__, 'c', sockfd, msg, flags); |
my_trace(__func__, 'c', sockfd, msg, flags); |
1685 |
|
|
|
1686 |
1912 |
ret = old_recvmsg(sockfd, msg, flags); |
ret = old_recvmsg(sockfd, msg, flags); |
1687 |
|
|
|
1688 |
1913 |
/* We do not touch non network sockets */ |
/* We do not touch non network sockets */ |
1689 |
1914 |
q = get(sockfd); |
q = get(sockfd); |
1690 |
1915 |
if (q && (q->priv.flags & FB_FLAGS_NETSOCK) && (ret != -1)) { |
if (q && (q->priv.flags & FB_FLAGS_NETSOCK) && (ret != -1)) { |
|
... |
... |
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) |
1701 |
1926 |
return ret; |
return ret; |
1702 |
1927 |
} |
} |
1703 |
1928 |
|
|
|
1929 |
|
ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flags, |
|
1930 |
|
struct sockaddr *restrict src_addr, socklen_t *restrict addrlen) |
|
1931 |
|
{ |
|
1932 |
|
ssize_t ret; |
|
1933 |
|
//TODO? struct node *q; |
|
1934 |
|
|
|
1935 |
|
my_trace(__func__, 'c', sockfd, len, addrlen ? *addrlen : 0, flags); |
|
1936 |
|
ret = old_recvfrom(sockfd, buf, len, flags, src_addr, addrlen); |
|
1937 |
|
my_trace(__func__, 'r', sockfd, len, src_addr, addrlen ? *addrlen : 0, flags, ret, buf); |
|
1938 |
|
|
|
1939 |
|
return ret; |
|
1940 |
|
} |
|
1941 |
|
|
1704 |
1942 |
/* |
/* |
1705 |
1943 |
* We have to hijack accept because the program may be a daemon. |
* We have to hijack accept because the program may be a daemon. |
1706 |
1944 |
*/ |
*/ |
|
... |
... |
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) |
1710 |
1948 |
struct node *q; |
struct node *q; |
1711 |
1949 |
struct private *p; |
struct private *p; |
1712 |
1950 |
|
|
1713 |
|
xlog(2, "accept(sockfd=%d, ...)\n", sockfd); |
|
|
1951 |
|
xlog(100, "accept(sockfd=%d, ...)\n", sockfd); |
1714 |
1952 |
|
|
1715 |
1953 |
my_trace(__func__, 'c', sockfd, addrlen ? *addrlen : 0); |
my_trace(__func__, 'c', sockfd, addrlen ? *addrlen : 0); |
1716 |
|
|
|
1717 |
1954 |
new_sock = old_accept(sockfd, addr, addrlen); |
new_sock = old_accept(sockfd, addr, addrlen); |
1718 |
1955 |
if (new_sock != -1) { |
if (new_sock != -1) { |
1719 |
1956 |
/* We must find out domain and type for accepting socket */ |
/* We must find out domain and type for accepting socket */ |
|
... |
... |
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) |
1724 |
1961 |
socket_create_callback(new_sock, p->domain, p->type); |
socket_create_callback(new_sock, p->domain, p->type); |
1725 |
1962 |
} |
} |
1726 |
1963 |
} |
} |
1727 |
|
|
|
1728 |
1964 |
my_trace(__func__, 'r', sockfd, addr, addrlen ? *addrlen : 0, new_sock); |
my_trace(__func__, 'r', sockfd, addr, addrlen ? *addrlen : 0, new_sock); |
1729 |
1965 |
|
|
1730 |
1966 |
return new_sock; |
return new_sock; |
|
... |
... |
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) |
1739 |
1975 |
struct node *q; |
struct node *q; |
1740 |
1976 |
struct private *p; |
struct private *p; |
1741 |
1977 |
|
|
1742 |
|
xlog(2, "accept4(sockfd=%d, ...flags=0x%x)\n", sockfd, flags); |
|
|
1978 |
|
xlog(100, "accept4(sockfd=%d, ...flags=0x%x)\n", sockfd, flags); |
1743 |
1979 |
|
|
1744 |
1980 |
my_trace(__func__, 'c', sockfd, addrlen ? *addrlen : 0, flags); |
my_trace(__func__, 'c', sockfd, addrlen ? *addrlen : 0, flags); |
1745 |
|
|
|
1746 |
1981 |
new_sock = old_accept4(sockfd, addr, addrlen, flags); |
new_sock = old_accept4(sockfd, addr, addrlen, flags); |
1747 |
1982 |
if (new_sock != -1) { |
if (new_sock != -1) { |
1748 |
1983 |
/* We must find out domain and type for accepting socket */ |
/* We must find out domain and type for accepting socket */ |
|
... |
... |
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) |
1753 |
1988 |
socket_create_callback(new_sock, p->domain, p->type); |
socket_create_callback(new_sock, p->domain, p->type); |
1754 |
1989 |
} |
} |
1755 |
1990 |
} |
} |
1756 |
|
|
|
1757 |
1991 |
my_trace(__func__, 'r', sockfd, addr, addrlen ? *addrlen : 0, |
my_trace(__func__, 'r', sockfd, addr, addrlen ? *addrlen : 0, |
1758 |
1992 |
flags, new_sock); |
flags, new_sock); |
1759 |
1993 |
|
|
|
... |
... |
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) |
1762 |
1996 |
|
|
1763 |
1997 |
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
1764 |
1998 |
{ |
{ |
1765 |
|
struct node *q; |
|
|
1999 |
|
//struct node *q; |
1766 |
2000 |
int ret; |
int ret; |
1767 |
2001 |
char sdest[128]; |
char sdest[128]; |
1768 |
2002 |
|
|
1769 |
2003 |
saddr(sdest, sizeof(sdest), addr); |
saddr(sdest, sizeof(sdest), addr); |
1770 |
|
xlog(2, "connect(sockfd=%d, %s)\n", sockfd, sdest); |
|
|
2004 |
|
xlog(100, "connect(sockfd=%d, %s)\n", sockfd, sdest); |
1771 |
2005 |
|
|
1772 |
|
q = get(sockfd); |
|
1773 |
|
if (q) |
|
1774 |
|
gettimeofday(&q->priv.conn_time, NULL); |
|
|
2006 |
|
// TODO |
|
2007 |
|
//q = get(sockfd); |
|
2008 |
|
//if (q) |
|
2009 |
|
// gettimeofday(&q->priv.conn_time, NULL); |
1775 |
2010 |
|
|
1776 |
2011 |
my_trace(__func__, 'c', sockfd, addr, addrlen); |
my_trace(__func__, 'c', sockfd, addr, addrlen); |
1777 |
|
|
|
1778 |
2012 |
ret = old_connect(sockfd, addr, addrlen); |
ret = old_connect(sockfd, addr, addrlen); |
1779 |
2013 |
if (ret == 0) { |
if (ret == 0) { |
1780 |
|
struct timeval e, f; |
|
|
2014 |
|
//struct timeval e, f; |
1781 |
2015 |
|
|
1782 |
|
gettimeofday(&e, NULL); |
|
1783 |
|
my_time_diff(&f, &e, &q->priv.conn_time); |
|
1784 |
|
xlog(3, " took %u.%03u\n", f.tv_sec, f.tv_usec / 1000); |
|
|
2016 |
|
//gettimeofday(&e, NULL); |
|
2017 |
|
//my_time_diff(&f, &e, &q->priv.conn_time); |
|
2018 |
|
//xlog(100, " took %u.%03u\n", f.tv_sec, f.tv_usec / 1000); |
1785 |
2019 |
} else { |
} else { |
1786 |
|
xlog(3, " failed: %m\n"); |
|
|
2020 |
|
xlog(100, " failed: %m\n"); |
1787 |
2021 |
} |
} |
1788 |
|
|
|
1789 |
2022 |
my_trace(__func__, 'r', sockfd, ret); |
my_trace(__func__, 'r', sockfd, ret); |
1790 |
2023 |
|
|
1791 |
2024 |
return ret; |
return ret; |
|
... |
... |
int poll(struct pollfd *fds, nfds_t nfds, int timeout) |
1795 |
2028 |
{ |
{ |
1796 |
2029 |
int ret; |
int ret; |
1797 |
2030 |
|
|
1798 |
|
xlog(40, "poll(fds, %d, %d)\n", nfds, timeout); |
|
|
2031 |
|
xlog(100, "poll(fds, %d, %d)\n", nfds, timeout); |
1799 |
2032 |
|
|
1800 |
2033 |
my_trace(__func__, 'c', fds, nfds, timeout); |
my_trace(__func__, 'c', fds, nfds, timeout); |
1801 |
|
|
|
1802 |
2034 |
ret = old_poll(fds, nfds, timeout); |
ret = old_poll(fds, nfds, timeout); |
1803 |
|
|
|
1804 |
2035 |
my_trace(__func__, 'r', fds, nfds, timeout, ret); |
my_trace(__func__, 'r', fds, nfds, timeout, ret); |
1805 |
2036 |
|
|
1806 |
2037 |
return ret; |
return ret; |
|
... |
... |
struct hostent *gethostbyname(const char *name) |
1810 |
2041 |
{ |
{ |
1811 |
2042 |
struct hostent *ret; |
struct hostent *ret; |
1812 |
2043 |
|
|
1813 |
|
xlog(2, "gethostbyname(%s)\n", name); |
|
|
2044 |
|
xlog(100, "gethostbyname(%s)\n", name); |
1814 |
2045 |
|
|
1815 |
2046 |
my_trace(__func__, 'c', name); |
my_trace(__func__, 'c', name); |
1816 |
|
|
|
1817 |
2047 |
ret = old_gethostbyname(name); |
ret = old_gethostbyname(name); |
1818 |
|
|
|
1819 |
2048 |
my_trace(__func__, 'r', name, ret); |
my_trace(__func__, 'r', name, ret); |
1820 |
2049 |
|
|
1821 |
2050 |
return ret; |
return ret; |
|
... |
... |
int getaddrinfo(const char *restrict node, const char *restrict service, |
1826 |
2055 |
{ |
{ |
1827 |
2056 |
int ret; |
int ret; |
1828 |
2057 |
|
|
1829 |
|
xlog(2, "getaddrinfo(node=%s, service=%s, hints=0x%x)\n", |
|
|
2058 |
|
xlog(100, "getaddrinfo(node=%s, service=%s, hints=0x%x)\n", |
1830 |
2059 |
node, service, hints ? hints : 0); |
node, service, hints ? hints : 0); |
1831 |
2060 |
|
|
1832 |
2061 |
my_trace(__func__, 'c', node, service, hints); |
my_trace(__func__, 'c', node, service, hints); |
1833 |
|
|
|
1834 |
2062 |
ret = old_getaddrinfo(node, service, hints, res); |
ret = old_getaddrinfo(node, service, hints, res); |
1835 |
|
|
|
1836 |
2063 |
my_trace(__func__, 'r', node, service, hints, res, ret); |
my_trace(__func__, 'r', node, service, hints, res, ret); |
1837 |
2064 |
|
|
1838 |
2065 |
return ret; |
return ret; |
1839 |
2066 |
} |
} |
1840 |
2067 |
|
|
|
2068 |
|
// TODO: not yet in trace |
1841 |
2069 |
int pthread_create(pthread_t *restrict thread, |
int pthread_create(pthread_t *restrict thread, |
1842 |
2070 |
const pthread_attr_t *restrict attr, void *(*start_routine)(void *), |
const pthread_attr_t *restrict attr, void *(*start_routine)(void *), |
1843 |
2071 |
void *restrict arg) |
void *restrict arg) |
|
... |
... |
int pthread_create(pthread_t *restrict thread, |
1847 |
2075 |
//xlog(2, "pthread_create\n"); |
//xlog(2, "pthread_create\n"); |
1848 |
2076 |
|
|
1849 |
2077 |
ret = old_pthread_create(thread, attr, start_routine, arg); |
ret = old_pthread_create(thread, attr, start_routine, arg); |
1850 |
|
my_trace(__func__, 'r', thread, attr, arg, ret); |
|
|
2078 |
|
my_trace(__func__, 'R', thread, attr, arg, ret); |
1851 |
2079 |
|
|
1852 |
2080 |
return ret; |
return ret; |
1853 |
2081 |
} |
} |
|
... |
... |
int pthread_join(pthread_t thread, void **retval) |
1859 |
2087 |
//xlog(2, "pthread_join\n"); |
//xlog(2, "pthread_join\n"); |
1860 |
2088 |
|
|
1861 |
2089 |
ret = old_pthread_join(thread, retval); |
ret = old_pthread_join(thread, retval); |
1862 |
|
my_trace(__func__, 'r', retval, ret); |
|
|
2090 |
|
my_trace(__func__, 'R', retval, ret); |
1863 |
2091 |
|
|
1864 |
2092 |
return ret; |
return ret; |
1865 |
2093 |
} |
} |
|
... |
... |
int pthread_attr_init(pthread_attr_t *attr) |
1873 |
2101 |
xlog(2, "%s\n", __func__); |
xlog(2, "%s\n", __func__); |
1874 |
2102 |
|
|
1875 |
2103 |
ret = old_pthread_attr_init(attr); |
ret = old_pthread_attr_init(attr); |
1876 |
|
my_trace(__func__, 'r', attr, ret); |
|
|
2104 |
|
my_trace(__func__, 'R', attr, ret); |
1877 |
2105 |
|
|
1878 |
2106 |
return ret; |
return ret; |
1879 |
2107 |
} |
} |
|
... |
... |
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) |
1885 |
2113 |
//xlog(2, "pthread_attr_setstacksize(%zu)\n", stacksize); |
//xlog(2, "pthread_attr_setstacksize(%zu)\n", stacksize); |
1886 |
2114 |
|
|
1887 |
2115 |
ret = old_pthread_attr_setstacksize(attr, stacksize); |
ret = old_pthread_attr_setstacksize(attr, stacksize); |
1888 |
|
|
|
1889 |
|
my_trace(__func__, 'r', attr, stacksize, ret); |
|
|
2116 |
|
my_trace(__func__, 'R', attr, stacksize, ret); |
1890 |
2117 |
|
|
1891 |
2118 |
return ret; |
return ret; |
1892 |
2119 |
} |
} |
1893 |
2120 |
|
|
|
2121 |
|
// TODO: not yet in tracing (done on nd-trace) |
1894 |
2122 |
int getsockopt(int sockfd, int level, int optname, void *restrict optval, |
int getsockopt(int sockfd, int level, int optname, void *restrict optval, |
1895 |
2123 |
socklen_t *restrict optlen) |
socklen_t *restrict optlen) |
1896 |
2124 |
{ |
{ |
|
... |
... |
int getsockopt(int sockfd, int level, int optname, void *restrict optval, |
1919 |
2147 |
break; |
break; |
1920 |
2148 |
} |
} |
1921 |
2149 |
|
|
1922 |
|
my_trace(__func__, 'r', sockfd, level, optname, optval, optlen, r); |
|
|
2150 |
|
my_trace(__func__, 'R', sockfd, level, optname, optval, *optlen, r); |
1923 |
2151 |
|
|
1924 |
2152 |
return r; |
return r; |
1925 |
2153 |
} |
} |
|
... |
... |
int open(const char *pathname, int flags, ...) |
1950 |
2178 |
if (ret == -1) |
if (ret == -1) |
1951 |
2179 |
return -1; |
return -1; |
1952 |
2180 |
struct fd_node *q = fd_add(ret); |
struct fd_node *q = fd_add(ret); |
|
2181 |
|
if (q) { |
1953 |
2182 |
q->flags |= FD_NODE_DEV_NINEDOGS; |
q->flags |= FD_NODE_DEV_NINEDOGS; |
1954 |
|
xlog(0, "APP Metrics opened fd=%d flags=0x%08x\n", |
|
1955 |
|
ret, q->flags); |
|
|
2183 |
|
xlog(0, "APP Metrics opened fd=%d flags=0x%08x\n", |
|
2184 |
|
ret, q->flags); |
|
2185 |
|
} |
1956 |
2186 |
return ret; |
return ret; |
1957 |
2187 |
} |
} |
1958 |
2188 |
|
|
|
... |
... |
int open(const char *pathname, int flags, ...) |
1962 |
2192 |
va_end(va); |
va_end(va); |
1963 |
2193 |
} |
} |
1964 |
2194 |
|
|
1965 |
|
my_trace(__func__, 'c', pathname, flags, mode); |
|
1966 |
|
|
|
1967 |
2195 |
xlog(20, "%s(%s, %d, %d)\n", __func__, pathname, flags, mode); |
xlog(20, "%s(%s, %d, %d)\n", __func__, pathname, flags, mode); |
|
2196 |
|
my_trace(__func__, 'c', pathname, flags, mode); |
1968 |
2197 |
ret = old_open(pathname, flags, mode); |
ret = old_open(pathname, flags, mode); |
1969 |
|
xlog(25, " ret=%d\n", ret); |
|
1970 |
|
|
|
1971 |
2198 |
my_trace(__func__, 'r', pathname, flags, mode, ret); |
my_trace(__func__, 'r', pathname, flags, mode, ret); |
|
2199 |
|
xlog(25, " ret=%d\n", ret); |
1972 |
2200 |
|
|
1973 |
2201 |
return ret; |
return ret; |
1974 |
2202 |
} |
} |
|
... |
... |
int open64(const char *pathname, int flags, ...) |
1996 |
2224 |
va_end(va); |
va_end(va); |
1997 |
2225 |
} |
} |
1998 |
2226 |
|
|
1999 |
|
xlog(20, "%s(%s, %d, %d)\n", __func__, pathname, flags, mode); |
|
|
2227 |
|
xlog(100, "%s(%s, %d, %d)\n", __func__, pathname, flags, mode); |
|
2228 |
|
my_trace(__func__, 'c', pathname, flags, mode); |
2000 |
2229 |
ret = old_open64(pathname, flags, mode); |
ret = old_open64(pathname, flags, mode); |
2001 |
|
xlog(25, " ret=%d\n", ret); |
|
2002 |
|
|
|
2003 |
2230 |
my_trace(__func__, 'r', pathname, flags, mode, ret); |
my_trace(__func__, 'r', pathname, flags, mode, ret); |
|
2231 |
|
xlog(101, " ret=%d\n", ret); |
2004 |
2232 |
|
|
2005 |
2233 |
return ret; |
return ret; |
2006 |
2234 |
} |
} |
|
... |
... |
int openat(int dirfd, const char *pathname, int flags, ...) |
2012 |
2240 |
va_list va; |
va_list va; |
2013 |
2241 |
|
|
2014 |
2242 |
if (strcmp(pathname, "/dev/ninedogs") == 0) { |
if (strcmp(pathname, "/dev/ninedogs") == 0) { |
2015 |
|
ret = old_open64("/dev/null", O_WRONLY); |
|
|
2243 |
|
ret = old_openat(0, "/dev/null", O_WRONLY); |
2016 |
2244 |
if (ret == -1) |
if (ret == -1) |
2017 |
2245 |
return -1; |
return -1; |
2018 |
2246 |
struct fd_node *q = fd_add(ret); |
struct fd_node *q = fd_add(ret); |
|
... |
... |
int openat(int dirfd, const char *pathname, int flags, ...) |
2029 |
2257 |
} |
} |
2030 |
2258 |
|
|
2031 |
2259 |
xlog(20, "%s(%d, %s, %d, %d)\n", __func__, dirfd, pathname, flags, mode); |
xlog(20, "%s(%d, %s, %d, %d)\n", __func__, dirfd, pathname, flags, mode); |
|
2260 |
|
my_trace(__func__, 'c', dirfd, pathname, flags, mode); |
2032 |
2261 |
ret = old_openat(dirfd, pathname, flags, mode); |
ret = old_openat(dirfd, pathname, flags, mode); |
2033 |
|
xlog(25, " ret=%d\n", ret); |
|
2034 |
|
|
|
2035 |
2262 |
my_trace(__func__, 'r', dirfd, pathname, flags, mode, ret); |
my_trace(__func__, 'r', dirfd, pathname, flags, mode, ret); |
|
2263 |
|
xlog(25, " ret=%d\n", ret); |
2036 |
2264 |
|
|
2037 |
2265 |
return ret; |
return ret; |
2038 |
2266 |
} |
} |
2039 |
2267 |
|
|
|
2268 |
|
#if 0 |
|
2269 |
|
// TODO: remove this |
2040 |
2270 |
static int my_stat(const char *restrict pathname, struct stat *restrict statbuf) |
static int my_stat(const char *restrict pathname, struct stat *restrict statbuf) |
2041 |
2271 |
{ |
{ |
2042 |
2272 |
int ret; |
int ret; |
2043 |
2273 |
|
|
2044 |
2274 |
xlog(20, "%s(%s, %p)\n", __func__, pathname, statbuf); |
xlog(20, "%s(%s, %p)\n", __func__, pathname, statbuf); |
|
2275 |
|
my_trace(__func__, 'c', pathname, statbuf); |
2045 |
2276 |
ret = old_stat(pathname, statbuf); |
ret = old_stat(pathname, statbuf); |
2046 |
|
xlog(25, " ret=%d\n", ret); |
|
2047 |
|
|
|
2048 |
2277 |
my_trace(__func__, 'r', pathname, statbuf, ret); |
my_trace(__func__, 'r', pathname, statbuf, ret); |
|
2278 |
|
xlog(25, " ret=%d\n", ret); |
2049 |
2279 |
|
|
2050 |
2280 |
return ret; |
return ret; |
2051 |
2281 |
} |
} |
|
2282 |
|
#endif |
2052 |
2283 |
|
|
2053 |
2284 |
void *dlsym(void *restrict handle, const char *restrict symbol) |
void *dlsym(void *restrict handle, const char *restrict symbol) |
2054 |
2285 |
{ |
{ |
|
... |
... |
void *dlsym(void *restrict handle, const char *restrict symbol) |
2061 |
2292 |
ret = old_dlsym(handle, symbol); |
ret = old_dlsym(handle, symbol); |
2062 |
2293 |
xlog(50, "%s(%p, %s) = %p\n", __func__, handle, symbol, ret); |
xlog(50, "%s(%p, %s) = %p\n", __func__, handle, symbol, ret); |
2063 |
2294 |
|
|
2064 |
|
if (ret) { |
|
2065 |
|
if (strcmp(symbol, "get_module") == 0) |
|
2066 |
|
ret = php_hook(ret); |
|
2067 |
|
//else if (strcmp(symbol, "open") == 0) |
|
2068 |
|
// ret = my_open; |
|
2069 |
|
else if (strcmp(symbol, "stat") == 0) |
|
2070 |
|
ret = my_stat; |
|
2071 |
|
} |
|
|
2295 |
|
if (!ret) |
|
2296 |
|
return NULL; |
|
2297 |
|
|
|
2298 |
|
if (strcmp(symbol, "get_module") == 0) |
|
2299 |
|
ret = php_hook(ret); |
|
2300 |
|
//else if (strcmp(symbol, "open") == 0) |
|
2301 |
|
// ret = my_open; |
|
2302 |
|
//else if (strcmp(symbol, "stat") == 0) |
|
2303 |
|
// ret = my_stat; |
|
2304 |
|
else if (strncmp(symbol, "PyInit__", 8) == 0) |
|
2305 |
|
return python_hook(symbol, ret); |
2072 |
2306 |
|
|
2073 |
2307 |
return ret; |
return ret; |
2074 |
2308 |
} |
} |
|
... |
... |
void *dlopen(const char *filename, int flags) |
2080 |
2314 |
if (!old_dlopen) |
if (!old_dlopen) |
2081 |
2315 |
return NULL; |
return NULL; |
2082 |
2316 |
|
|
|
2317 |
|
my_trace(__func__, 'c', filename, flags); |
2083 |
2318 |
ret = old_dlopen(filename, flags); |
ret = old_dlopen(filename, flags); |
|
2319 |
|
my_trace(__func__, 'r', filename, flags, ret); |
2084 |
2320 |
xlog(100, "%s(%s, 0x%x) = %p\n", __func__, filename, flags, ret); |
xlog(100, "%s(%s, 0x%x) = %p\n", __func__, filename, flags, ret); |
2085 |
|
if (!ret) { |
|
|
2321 |
|
if (ret) { |
2086 |
2322 |
// TODO: should I add only 'flags=GLOBAL' entries? |
// TODO: should I add only 'flags=GLOBAL' entries? |
|
2323 |
|
unsigned found = 0, first_free = DLOPEN_MAX_ENTRIES; |
2087 |
2324 |
for (unsigned i = 0; i < DLOPEN_MAX_ENTRIES; i++) { |
for (unsigned i = 0; i < DLOPEN_MAX_ENTRIES; i++) { |
2088 |
|
if (filename == NULL) |
|
2089 |
|
break; |
|
2090 |
|
|
|
2091 |
2325 |
if (dlopen_nodes[i].p == ret) { |
if (dlopen_nodes[i].p == ret) { |
|
2326 |
|
xlog(101, "%s: path [%s] already stored in pos %u\n", |
|
2327 |
|
__func__, filename, i); |
2092 |
2328 |
dlopen_nodes[i].count++; |
dlopen_nodes[i].count++; |
|
2329 |
|
found = 1; |
2093 |
2330 |
break; |
break; |
2094 |
2331 |
} |
} |
2095 |
|
if (dlopen_nodes[i].p == NULL) { |
|
2096 |
|
unsigned int max = strlen(filename); |
|
2097 |
|
if (max > sizeof(dlopen_nodes[i].path) - 1) |
|
2098 |
|
max = sizeof(dlopen_nodes[i].path) - 1; |
|
2099 |
|
memcpy(dlopen_nodes[i].path, filename, max); |
|
2100 |
|
dlopen_nodes[i].path[max] = '\0'; |
|
2101 |
|
dlopen_nodes[i].p = ret; |
|
2102 |
|
dlopen_nodes[i].count = 1; |
|
2103 |
|
break; |
|
2104 |
|
} |
|
|
2332 |
|
|
|
2333 |
|
if (dlopen_nodes[i].p == NULL) |
|
2334 |
|
if (first_free == DLOPEN_MAX_ENTRIES) |
|
2335 |
|
first_free = i; |
|
2336 |
|
} |
|
2337 |
|
xlog(101, "%s: found=%u first_free=%u\n", __func__, found, first_free); |
|
2338 |
|
|
|
2339 |
|
if ((found == 0) && (first_free != DLOPEN_MAX_ENTRIES)) { |
|
2340 |
|
xlog(101, "%s: store path [%s] in pos %u\n", |
|
2341 |
|
__func__, filename, first_free); |
|
2342 |
|
unsigned int max = strlen(filename); |
|
2343 |
|
if (max > sizeof(dlopen_nodes[first_free].path) - 1) |
|
2344 |
|
max = sizeof(dlopen_nodes[first_free].path) - 1; |
|
2345 |
|
memcpy(dlopen_nodes[first_free].path, filename, max); |
|
2346 |
|
dlopen_nodes[first_free].path[max] = '\0'; |
|
2347 |
|
dlopen_nodes[first_free].p = ret; |
|
2348 |
|
dlopen_nodes[first_free].count = 1; |
2105 |
2349 |
} |
} |
2106 |
2350 |
} |
} |
2107 |
2351 |
|
|
2108 |
|
my_trace(__func__, 'r', filename, flags, ret); |
|
2109 |
|
|
|
2110 |
2352 |
return ret; |
return ret; |
2111 |
2353 |
} |
} |
2112 |
2354 |
|
|
|
... |
... |
int dlclose(void *h) |
2114 |
2356 |
{ |
{ |
2115 |
2357 |
int ret; |
int ret; |
2116 |
2358 |
|
|
2117 |
|
//xlog(100, "%s(%p)\n", __func__, h); |
|
|
2359 |
|
xlog(100, "%s(%p)\n", __func__, h); |
2118 |
2360 |
|
|
2119 |
2361 |
if (!old_dlclose) |
if (!old_dlclose) |
2120 |
2362 |
return 0; |
return 0; |
|
... |
... |
int dlclose(void *h) |
2124 |
2366 |
for (unsigned i = 0; i < DLOPEN_MAX_ENTRIES; i++) { |
for (unsigned i = 0; i < DLOPEN_MAX_ENTRIES; i++) { |
2125 |
2367 |
if (dlopen_nodes[i].p == h) { |
if (dlopen_nodes[i].p == h) { |
2126 |
2368 |
dlopen_nodes[i].count--; |
dlopen_nodes[i].count--; |
2127 |
|
if (dlopen_nodes[i].count == 0) |
|
|
2369 |
|
if (dlopen_nodes[i].count == 0) { |
2128 |
2370 |
dlopen_nodes[i].p = NULL; |
dlopen_nodes[i].p = NULL; |
|
2371 |
|
xlog(100, "%s: freeing file [%s] on pos %u\n", |
|
2372 |
|
__func__, dlopen_nodes[i].path, i); |
|
2373 |
|
} |
2129 |
2374 |
break; |
break; |
2130 |
2375 |
} |
} |
2131 |
2376 |
} |
} |
2132 |
2377 |
} |
} |
2133 |
2378 |
|
|
2134 |
|
my_trace(__func__, 'r', h, ret); |
|
|
2379 |
|
my_trace(__func__, 'R', h, ret); |
2135 |
2380 |
|
|
2136 |
2381 |
return ret; |
return ret; |
2137 |
2382 |
} |
} |
|
... |
... |
void *ninedogs_dlsym(const char *sym) |
2143 |
2388 |
{ |
{ |
2144 |
2389 |
void *ret; |
void *ret; |
2145 |
2390 |
|
|
|
2391 |
|
xlog(100, "%s: sym [%s]\n", __func__, sym); |
|
2392 |
|
|
2146 |
2393 |
ret = old_dlsym(RTLD_NEXT, sym); |
ret = old_dlsym(RTLD_NEXT, sym); |
2147 |
2394 |
if (ret) |
if (ret) |
2148 |
2395 |
return ret; |
return ret; |
2149 |
2396 |
|
|
2150 |
2397 |
for (unsigned i = 0; i < DLOPEN_MAX_ENTRIES; i++) { |
for (unsigned i = 0; i < DLOPEN_MAX_ENTRIES; i++) { |
|
2398 |
|
if (!dlopen_nodes[i].p) |
|
2399 |
|
continue; |
|
2400 |
|
|
2151 |
2401 |
ret = old_dlsym(dlopen_nodes[i].p, sym); |
ret = old_dlsym(dlopen_nodes[i].p, sym); |
2152 |
2402 |
if (ret) { |
if (ret) { |
2153 |
|
xlog(0, "%s: sym [%s] found in [%s]\n", |
|
|
2403 |
|
xlog(100, "%s: sym [%s] found in [%s]\n", |
2154 |
2404 |
__func__, sym, dlopen_nodes[i].path); |
__func__, sym, dlopen_nodes[i].path); |
2155 |
2405 |
return ret; |
return ret; |
2156 |
2406 |
} |
} |
|
... |
... |
ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) |
2166 |
2416 |
if (!old_getrandom) |
if (!old_getrandom) |
2167 |
2417 |
ninedogs_init(); |
ninedogs_init(); |
2168 |
2418 |
|
|
2169 |
|
xlog(20, "%s(%p, %zu, 0x%x) [old_getrandom=%p]\n", |
|
|
2419 |
|
xlog(100, "%s(%p, %zu, 0x%x) [old_getrandom=%p]\n", |
2170 |
2420 |
__func__, buf, buflen, flags, old_getrandom); |
__func__, buf, buflen, flags, old_getrandom); |
2171 |
2421 |
|
|
2172 |
2422 |
my_trace(__func__, 'c', buflen, flags); |
my_trace(__func__, 'c', buflen, flags); |
|
... |
... |
int nanosleep(const struct timespec *req, struct timespec *rem) |
2183 |
2433 |
if (!old_nanosleep) |
if (!old_nanosleep) |
2184 |
2434 |
ninedogs_init(); |
ninedogs_init(); |
2185 |
2435 |
|
|
2186 |
|
xlog(20, "%s(%ld.%09ld, %p)\n", |
|
|
2436 |
|
xlog(100, "%s(%ld.%09ld, %p)\n", |
2187 |
2437 |
__func__, req->tv_sec, req->tv_nsec, rem); |
__func__, req->tv_sec, req->tv_nsec, rem); |
2188 |
2438 |
|
|
2189 |
2439 |
my_trace(__func__, 'c', req); |
my_trace(__func__, 'c', req); |
|
... |
... |
int unlink(const char *pathname) |
2200 |
2450 |
if (!old_unlink) |
if (!old_unlink) |
2201 |
2451 |
ninedogs_init(); |
ninedogs_init(); |
2202 |
2452 |
|
|
2203 |
|
xlog(20, "%s(%s)\n", __func__, pathname); |
|
|
2453 |
|
xlog(100, "%s(%s)\n", __func__, pathname); |
2204 |
2454 |
|
|
2205 |
2455 |
my_trace(__func__, 'c', pathname); |
my_trace(__func__, 'c', pathname); |
2206 |
2456 |
ret = old_unlink(pathname); |
ret = old_unlink(pathname); |
|
... |
... |
int listen(int sock, int backlog) |
2216 |
2466 |
if (!old_listen) |
if (!old_listen) |
2217 |
2467 |
ninedogs_init(); |
ninedogs_init(); |
2218 |
2468 |
|
|
2219 |
|
xlog(20, "%s(%d, %d)\n", __func__, sock, backlog); |
|
|
2469 |
|
xlog(100, "%s(%d, %d)\n", __func__, sock, backlog); |
2220 |
2470 |
|
|
2221 |
2471 |
ret = old_listen(sock, backlog); |
ret = old_listen(sock, backlog); |
2222 |
|
my_trace(__func__, 'r', sock, backlog, ret); |
|
|
2472 |
|
my_trace(__func__, 'R', sock, backlog, ret); |
2223 |
2473 |
|
|
2224 |
2474 |
return ret; |
return ret; |
2225 |
2475 |
} |
} |
|
... |
... |
void syslog(int priority, const char *format, ...) |
2232 |
2482 |
if (!old_syslog) |
if (!old_syslog) |
2233 |
2483 |
ninedogs_init(); |
ninedogs_init(); |
2234 |
2484 |
|
|
2235 |
|
xlog(20, "%s(%d)\n", __func__, priority); |
|
|
2485 |
|
xlog(100, "%s(%d)\n", __func__, priority); |
2236 |
2486 |
|
|
2237 |
2487 |
va_start(va, format); |
va_start(va, format); |
2238 |
2488 |
vsnprintf(buf, sizeof(buf), format, va); |
vsnprintf(buf, sizeof(buf), format, va); |
2239 |
2489 |
va_end(va); |
va_end(va); |
2240 |
2490 |
|
|
2241 |
2491 |
old_syslog(priority, buf); |
old_syslog(priority, buf); |
2242 |
|
my_trace(__func__, 'r', priority, buf); |
|
|
2492 |
|
my_trace(__func__, 'R', priority, buf); |
2243 |
2493 |
} |
} |
2244 |
2494 |
|
|
2245 |
2495 |
int fstatat(int dirfd, const char *restrict pathname, |
int fstatat(int dirfd, const char *restrict pathname, |
|
... |
... |
int fstatat(int dirfd, const char *restrict pathname, |
2250 |
2500 |
if (!old_fstatat) |
if (!old_fstatat) |
2251 |
2501 |
ninedogs_init(); |
ninedogs_init(); |
2252 |
2502 |
|
|
2253 |
|
xlog(20, "%s(%d, %s, %p, 0x%x)\n", __func__, dirfd, pathname, statbuf, flags); |
|
|
2503 |
|
xlog(100, "%s(%d, %s, %p, 0x%x)\n", __func__, dirfd, pathname, statbuf, flags); |
2254 |
2504 |
|
|
2255 |
2505 |
my_trace(__func__, 'c', dirfd, pathname, flags); |
my_trace(__func__, 'c', dirfd, pathname, flags); |
2256 |
2506 |
ret = old_fstatat(dirfd, pathname, statbuf, flags); |
ret = old_fstatat(dirfd, pathname, statbuf, flags); |
|
... |
... |
int fstatat64(int dirfd, const char *restrict pathname, |
2267 |
2517 |
if (!old_fstatat64) |
if (!old_fstatat64) |
2268 |
2518 |
ninedogs_init(); |
ninedogs_init(); |
2269 |
2519 |
|
|
2270 |
|
xlog(20, "%s(%d, %s, %p, 0x%x)\n", |
|
|
2520 |
|
xlog(100, "%s(%d, %s, %p, 0x%x)\n", |
2271 |
2521 |
__func__, dirfd, pathname, statbuf, flags); |
__func__, dirfd, pathname, statbuf, flags); |
2272 |
2522 |
|
|
2273 |
2523 |
my_trace(__func__, 'c', dirfd, pathname, flags); |
my_trace(__func__, 'c', dirfd, pathname, flags); |
|
... |
... |
int fstatat64(int dirfd, const char *restrict pathname, |
2277 |
2527 |
return ret; |
return ret; |
2278 |
2528 |
} |
} |
2279 |
2529 |
|
|
2280 |
|
int newfstatat(int dirfd, const char *restrict pathname, |
|
2281 |
|
struct stat64 *restrict statbuf, int flags) |
|
|
2530 |
|
int stat(const char *restrict pathname, struct stat *restrict statbuf) |
2282 |
2531 |
{ |
{ |
2283 |
2532 |
int ret; |
int ret; |
2284 |
2533 |
|
|
2285 |
|
if (!old_fstatat64) |
|
|
2534 |
|
if (!old_stat) |
2286 |
2535 |
ninedogs_init(); |
ninedogs_init(); |
2287 |
2536 |
|
|
2288 |
|
xlog(20, "%s(%d, %s, %p, 0x%x)\n", |
|
2289 |
|
__func__, dirfd, pathname, statbuf, flags); |
|
|
2537 |
|
xlog(100, "%s(%s, %p)\n", |
|
2538 |
|
__func__, pathname, statbuf); |
2290 |
2539 |
|
|
2291 |
|
my_trace(__func__, 'c', dirfd, pathname, flags); |
|
2292 |
|
ret = old_fstatat64(dirfd, pathname, statbuf, flags); |
|
2293 |
|
my_trace(__func__, 'r', dirfd, pathname, statbuf, flags, ret); |
|
|
2540 |
|
my_trace(__func__, 'c', pathname); |
|
2541 |
|
ret = old_stat(pathname, statbuf); |
|
2542 |
|
my_trace(__func__, 'r', pathname, statbuf, ret); |
2294 |
2543 |
|
|
2295 |
2544 |
return ret; |
return ret; |
2296 |
2545 |
} |
} |
2297 |
2546 |
|
|
2298 |
|
int stat(const char *restrict pathname, struct stat *restrict statbuf) |
|
|
2547 |
|
int fork(void) |
2299 |
2548 |
{ |
{ |
2300 |
2549 |
int ret; |
int ret; |
2301 |
2550 |
|
|
2302 |
|
if (!old_stat) |
|
|
2551 |
|
if (!old_fork) |
2303 |
2552 |
ninedogs_init(); |
ninedogs_init(); |
2304 |
2553 |
|
|
2305 |
|
xlog(20, "%s(%s, %p)\n", |
|
2306 |
|
__func__, pathname, statbuf); |
|
|
2554 |
|
xlog(100, "%s()\n", __func__); |
2307 |
2555 |
|
|
2308 |
|
my_trace(__func__, 'c', pathname); |
|
2309 |
|
ret = old_stat(pathname, statbuf); |
|
2310 |
|
my_trace(__func__, 'r', pathname, statbuf, ret); |
|
|
2556 |
|
ret = old_fork(); |
|
2557 |
|
my_trace(__func__, 'R', ret); |
|
2558 |
|
|
|
2559 |
|
return ret; |
|
2560 |
|
} |
|
2561 |
|
|
|
2562 |
|
static int (*old_sqlite3_open)(const char *, void **); |
|
2563 |
|
int sqlite3_open(const char *filename, void **ppdb) |
|
2564 |
|
{ |
|
2565 |
|
int ret; |
|
2566 |
|
|
|
2567 |
|
if (!old_sqlite3_open) |
|
2568 |
|
old_sqlite3_open = ninedogs_dlsym("sqlite3_open"); |
|
2569 |
|
|
|
2570 |
|
xlog(100, "%s(%s)\n", __func__, filename); |
|
2571 |
|
|
|
2572 |
|
my_trace(__func__, 'c', filename); |
|
2573 |
|
ret = old_sqlite3_open(filename, ppdb); |
|
2574 |
|
my_trace(__func__, 'r', filename, ppdb, ret); |
|
2575 |
|
|
|
2576 |
|
return ret; |
|
2577 |
|
} |
|
2578 |
|
|
|
2579 |
|
static int (*old_sqlite3_open_v2)(const char *, void **, int, const char *); |
|
2580 |
|
int sqlite3_open_v2(const char *filename, void **ppdb, int flags, const char *vfs) |
|
2581 |
|
{ |
|
2582 |
|
int ret; |
|
2583 |
|
|
|
2584 |
|
if (!old_sqlite3_open_v2) |
|
2585 |
|
old_sqlite3_open_v2 = ninedogs_dlsym("sqlite3_open_v2"); |
|
2586 |
|
|
|
2587 |
|
xlog(100, "%s(%s, ppdb, 0x%x, %s)\n", |
|
2588 |
|
__func__, filename, flags, vfs); |
|
2589 |
|
|
|
2590 |
|
my_trace(__func__, 'c', filename, flags, vfs); |
|
2591 |
|
ret = old_sqlite3_open_v2(filename, ppdb, flags, vfs); |
|
2592 |
|
my_trace(__func__, 'r', filename, ppdb ? *ppdb : NULL, flags, vfs, ret); |
2311 |
2593 |
|
|
2312 |
2594 |
return ret; |
return ret; |
2313 |
2595 |
} |
} |
|
2596 |
|
|
|
2597 |
|
static int (*old_sqlite3_open16)(const char *, void **); |
|
2598 |
|
int sqlite3_open16(const char *filename, void **ppdb) |
|
2599 |
|
{ |
|
2600 |
|
int ret; |
|
2601 |
|
|
|
2602 |
|
if (!old_sqlite3_open16) |
|
2603 |
|
old_sqlite3_open16 = ninedogs_dlsym("sqlite3_open16"); |
|
2604 |
|
|
|
2605 |
|
xlog(100, "%s('%s', ppdb)\n", |
|
2606 |
|
__func__, filename); |
|
2607 |
|
|
|
2608 |
|
my_trace(__func__, 'c', filename); |
|
2609 |
|
ret = old_sqlite3_open16(filename, ppdb); |
|
2610 |
|
my_trace(__func__, 'r', filename, ppdb, ret); |
|
2611 |
|
|
|
2612 |
|
return ret; |
|
2613 |
|
} |
|
2614 |
|
|
|
2615 |
|
// TODO: this seems to be only a wrapper |
|
2616 |
|
static int (*old_sqlite3_exec)(void *h, const char *sql, |
|
2617 |
|
int (*callback)(void *, int, char **, char **), void *, char **errmsg); |
|
2618 |
|
int sqlite3_exec(void *h, const char *sql, |
|
2619 |
|
int (*callback)(void *, int, char **, char **), void *callback_arg, char **errmsg) |
|
2620 |
|
{ |
|
2621 |
|
int ret; |
|
2622 |
|
|
|
2623 |
|
if (!old_sqlite3_exec) |
|
2624 |
|
old_sqlite3_exec = ninedogs_dlsym("sqlite3_exec"); |
|
2625 |
|
|
|
2626 |
|
//my_trace(__func__, 'c', h, sql, callback, callback_arg); |
|
2627 |
|
ret = old_sqlite3_exec(h, sql, callback, callback_arg, errmsg); |
|
2628 |
|
xlog(100, "%s(h=%p, sql='%s', cb=%p, cba=%p, err='%s')\n", |
|
2629 |
|
__func__, h, sql, callback, callback_arg, errmsg ? *errmsg : "?"); |
|
2630 |
|
//my_trace(__func__, 'r', h, sql, callback, callback_arg, errmsg); |
|
2631 |
|
|
|
2632 |
|
return ret; |
|
2633 |
|
} |
|
2634 |
|
|
|
2635 |
|
static int (*old_sqlite3_prepare_v2)(void *, const char *, int, void **, const char **); |
|
2636 |
|
int sqlite3_prepare_v2(void *h, const char *sql, int nByte, void **stmt, const char **tail) |
|
2637 |
|
{ |
|
2638 |
|
int ret; |
|
2639 |
|
|
|
2640 |
|
if (!old_sqlite3_prepare_v2) |
|
2641 |
|
old_sqlite3_prepare_v2 = ninedogs_dlsym("sqlite3_prepare_v2"); |
|
2642 |
|
|
|
2643 |
|
my_trace(__func__, 'c', h, sql, nByte); |
|
2644 |
|
ret = old_sqlite3_prepare_v2(h, sql, nByte, stmt, tail); |
|
2645 |
|
xlog(100, "%s(h=%p, sql='%s', nByte=%d, *stmt=%p, tail=[%s]) = %d\n", |
|
2646 |
|
__func__, h, sql, nByte, stmt ? *stmt : NULL, tail ? *tail : "", ret); |
|
2647 |
|
my_trace(__func__, 'r', h, sql, nByte, stmt ? *stmt : NULL, ret); |
|
2648 |
|
// TODO: do we need 'tail'? |
|
2649 |
|
|
|
2650 |
|
return ret; |
|
2651 |
|
} |
|
2652 |
|
|
|
2653 |
|
static int (*old_sqlite3_step)(void *); |
|
2654 |
|
int sqlite3_step(void *stmt) |
|
2655 |
|
{ |
|
2656 |
|
int ret; |
|
2657 |
|
|
|
2658 |
|
if (!old_sqlite3_step) |
|
2659 |
|
old_sqlite3_step = ninedogs_dlsym("sqlite3_step"); |
|
2660 |
|
|
|
2661 |
|
my_trace(__func__, 'c', stmt); |
|
2662 |
|
ret = old_sqlite3_step(stmt); |
|
2663 |
|
xlog(100, "%s(stmt=%p) = %d\n", __func__, stmt, ret); |
|
2664 |
|
my_trace(__func__, 'r', stmt, ret); |
|
2665 |
|
|
|
2666 |
|
return ret; |
|
2667 |
|
} |
|
2668 |
|
|
File agent/php.c changed (mode: 100644) (index 5e656a4..94e2548) |
... |
... |
struct zend_module_entry |
68 |
68 |
unsigned char pad2[6]; |
unsigned char pad2[6]; |
69 |
69 |
void *ini_entry; |
void *ini_entry; |
70 |
70 |
void *deps; |
void *deps; |
71 |
|
char *name; |
|
|
71 |
|
const char *name; |
72 |
72 |
struct zend_function_entry *functions; |
struct zend_function_entry *functions; |
73 |
73 |
void *junk[5]; |
void *junk[5]; |
74 |
74 |
const char *version; |
const char *version; |
75 |
75 |
size_t globals_size; |
size_t globals_size; |
|
76 |
|
void *globals; |
|
77 |
|
void *globals_ctor; |
|
78 |
|
void *globals_dtor; |
|
79 |
|
void *post_deactivate_func; |
|
80 |
|
int module_started; |
|
81 |
|
unsigned char type; |
|
82 |
|
unsigned char pad3[3]; |
|
83 |
|
void *handle; |
|
84 |
|
int module_number; |
|
85 |
|
int pad4; |
|
86 |
|
const char *build_id; |
76 |
87 |
}; |
}; |
77 |
88 |
|
|
78 |
89 |
typedef long zend_long; |
typedef long zend_long; |
|
... |
... |
struct zend_array |
111 |
122 |
unsigned char nIteratorsCount; |
unsigned char nIteratorsCount; |
112 |
123 |
unsigned char _unused2; |
unsigned char _unused2; |
113 |
124 |
} v; |
} v; |
114 |
|
unsigned int flags; |
|
|
125 |
|
unsigned int flags; |
115 |
126 |
} u; |
} u; |
116 |
127 |
unsigned int nTableMask; |
unsigned int nTableMask; |
117 |
|
struct Bucket *arData; |
|
|
128 |
|
union { |
|
129 |
|
uint32_t *arHash; |
|
130 |
|
struct Bucket *arData; |
|
131 |
|
struct zval *arPacked; |
|
132 |
|
}; |
118 |
133 |
unsigned int nNumUsed; |
unsigned int nNumUsed; |
119 |
134 |
unsigned int nNumOfElements; |
unsigned int nNumOfElements; |
120 |
135 |
unsigned int nTableSize; |
unsigned int nTableSize; |
|
... |
... |
struct Bucket |
166 |
181 |
|
|
167 |
182 |
struct zend_reference |
struct zend_reference |
168 |
183 |
{ |
{ |
169 |
|
unsigned int refcount; |
|
170 |
|
unsigned int pad1; |
|
171 |
|
struct zval val; |
|
172 |
|
/* more thigs follows */ |
|
|
184 |
|
struct zend_refcounted_h gc; |
|
185 |
|
struct zval val; |
|
186 |
|
void *sources; |
173 |
187 |
}; |
}; |
174 |
188 |
|
|
175 |
189 |
struct zend_execute_data |
struct zend_execute_data |
|
... |
... |
static void php_zed_dump(const char *prefix, struct zend_execute_data *p) |
305 |
319 |
} |
} |
306 |
320 |
} |
} |
307 |
321 |
|
|
|
322 |
|
static void zend_array_to_params_array(struct query *q, struct zend_array *za) |
|
323 |
|
{ |
|
324 |
|
unsigned int i = 0, max; |
|
325 |
|
|
|
326 |
|
xlog(100, " nTableMask=0x%x nNumUsed=%u nNumOfElements=%u nTableSize=%u" |
|
327 |
|
" nInternalPointer=%u flags=0x%x[%s]\n", |
|
328 |
|
za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize, |
|
329 |
|
za->nInternalPointer, za->u.flags, za->u.flags & 4 ? "packed" : ""); |
|
330 |
|
|
|
331 |
|
max = za->nNumUsed; |
|
332 |
|
if (max > ND_PARAMS_MAX) |
|
333 |
|
max = ND_PARAMS_MAX; |
|
334 |
|
|
|
335 |
|
struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed; |
|
336 |
|
for (; bs != be; bs++) { |
|
337 |
|
struct zval *_z = &bs->val; |
|
338 |
|
|
|
339 |
|
if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT |
|
340 |
|
_z = _z->value.zv; |
|
341 |
|
|
|
342 |
|
if (_z->u1.v.type == 0 /*IS_UNDEF*/) { |
|
343 |
|
xlog(101, " para h=%lu: type undef\n", bs->h); |
|
344 |
|
continue; |
|
345 |
|
} |
|
346 |
|
|
|
347 |
|
if (_z->u1.v.type == 10) { // REFERENCE |
|
348 |
|
xlog(101, " is a reference!\n"); |
|
349 |
|
_z = &_z->value.ref->val; |
|
350 |
|
} |
|
351 |
|
|
|
352 |
|
struct zend_string *zs = bs->key; |
|
353 |
|
xlog(101, " para: bs=%p h=%lu key=[%p] type %s: val: %s\n", |
|
354 |
|
bs, bs->h, zs, php_get_type(_z), php_get_value(_z)); |
|
355 |
|
|
|
356 |
|
if (_z->u1.v.type == 4) { |
|
357 |
|
q->params[i].type = ND_PARAMS_TYPE_LONG; |
|
358 |
|
q->params[i].l = _z->value.lval; |
|
359 |
|
} else if (_z->u1.v.type == 5) { |
|
360 |
|
q->params[i].type = ND_PARAMS_TYPE_DOUBLE; |
|
361 |
|
q->params[i].d = _z->value.dval; |
|
362 |
|
} else if (_z->u1.v.type == 6) { |
|
363 |
|
q->params[i].type = ND_PARAMS_TYPE_STRING; |
|
364 |
|
struct zend_string *zs = _z->value.str; |
|
365 |
|
q->params[i].str = zs->val; |
|
366 |
|
q->params[i].length = zs->len; |
|
367 |
|
} |
|
368 |
|
|
|
369 |
|
i++; |
|
370 |
|
if (i == max) |
|
371 |
|
break; |
|
372 |
|
} |
|
373 |
|
|
|
374 |
|
q->params_len = za->nNumUsed; |
|
375 |
|
} |
|
376 |
|
|
308 |
377 |
void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *); |
void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *); |
309 |
378 |
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) |
310 |
379 |
{ |
{ |
|
... |
... |
static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv) |
324 |
393 |
return ret; |
return ret; |
325 |
394 |
} |
} |
326 |
395 |
|
|
|
396 |
|
void *(*old_pg_close)(struct zend_execute_data *, struct zval *); |
|
397 |
|
static void *my_pg_close(struct zend_execute_data *e, struct zval *retv) |
|
398 |
|
{ |
|
399 |
|
void *ret; |
|
400 |
|
unsigned int num_args, s; |
|
401 |
|
struct zval *z; |
|
402 |
|
struct conn cs; |
|
403 |
|
|
|
404 |
|
num_args = e->This.u2.num_args; |
|
405 |
|
//xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
406 |
|
|
|
407 |
|
cs.type = 'P'; |
|
408 |
|
if (num_args == 1) { |
|
409 |
|
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
410 |
|
// handler, may be null |
|
411 |
|
z = (struct zval *) e + s; s++; |
|
412 |
|
cs.dbh = z->value.p; |
|
413 |
|
//xlog(101, " h=%p\n", cs.dbh); |
|
414 |
|
} else { |
|
415 |
|
cs.dbh = NULL; |
|
416 |
|
} |
|
417 |
|
|
|
418 |
|
ret = old_pg_close(e, retv); |
|
419 |
|
ninedogs_process_db("pg_close", NINEDOGS_DB_CONN_CLOSE, &cs); |
|
420 |
|
|
|
421 |
|
return ret; |
|
422 |
|
} |
|
423 |
|
|
327 |
424 |
void *(*old_pg_connect)(struct zend_execute_data *, struct zval *); |
void *(*old_pg_connect)(struct zend_execute_data *, struct zval *); |
328 |
425 |
static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) |
329 |
426 |
{ |
{ |
|
... |
... |
static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) |
334 |
431 |
struct conn cs; |
struct conn cs; |
335 |
432 |
|
|
336 |
433 |
num_args = e->This.u2.num_args; |
num_args = e->This.u2.num_args; |
337 |
|
xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
|
434 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
338 |
435 |
|
|
339 |
436 |
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); |
340 |
437 |
cs.type = 'P'; |
cs.type = 'P'; |
|
... |
... |
static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) |
344 |
441 |
q = z->value.str; |
q = z->value.str; |
345 |
442 |
cs.conn_str = q->val; |
cs.conn_str = q->val; |
346 |
443 |
cs.conn_str_len = q->len; |
cs.conn_str_len = q->len; |
347 |
|
xlog(50, " conn: %s\n", cs.conn_str); |
|
|
444 |
|
//xlog(50, " conn[%u]: %s\n", cs.conn_str_len, cs.conn_str); |
348 |
445 |
|
|
349 |
|
ninedogs_now(&cs.start); |
|
|
446 |
|
ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_START, &cs); |
350 |
447 |
ret = old_pg_connect(e, retv); |
ret = old_pg_connect(e, retv); |
351 |
|
if (!retv) |
|
|
448 |
|
if (!retv) { |
|
449 |
|
xlog(0, "DEBUG: old_pg_connect returned retv NULL\n"); |
352 |
450 |
return ret; |
return ret; |
353 |
|
ninedogs_now(&cs.end); |
|
|
451 |
|
} |
354 |
452 |
|
|
355 |
|
//php_zval_dump(" retv: ", retv); |
|
|
453 |
|
php_zval_dump(" retv: ", retv); |
356 |
454 |
// TODO: how to test for error? if (core_globals.last_error_message) { |
// TODO: how to test for error? if (core_globals.last_error_message) { |
357 |
455 |
|
|
358 |
456 |
// PHP7 returns resource, PHP8.1 returns object |
// PHP7 returns resource, PHP8.1 returns object |
359 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { |
|
|
457 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) |
360 |
458 |
cs.dbh = retv->value.p; |
cs.dbh = retv->value.p; |
361 |
|
ninedogs_process_db(NINEDOGS_DB_CONN, &cs); |
|
362 |
|
} |
|
|
459 |
|
else |
|
460 |
|
cs.dbh = NULL; |
|
461 |
|
ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_END, &cs); |
363 |
462 |
|
|
364 |
463 |
return ret; |
return ret; |
365 |
464 |
} |
} |
|
... |
... |
static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv) |
386 |
485 |
cs.conn_str_len = q->len; |
cs.conn_str_len = q->len; |
387 |
486 |
xlog(50, " conn: %s\n", cs.conn_str); |
xlog(50, " conn: %s\n", cs.conn_str); |
388 |
487 |
|
|
389 |
|
ninedogs_now(&cs.start); |
|
|
488 |
|
ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_START, &cs); |
390 |
489 |
ret = old_pg_pconnect(e, retv); |
ret = old_pg_pconnect(e, retv); |
391 |
490 |
if (!retv) |
if (!retv) |
392 |
491 |
return ret; |
return ret; |
393 |
|
ninedogs_now(&cs.end); |
|
394 |
492 |
|
|
395 |
|
//php_zval_dump(" retv: ", retv); |
|
|
493 |
|
php_zval_dump(" retv: ", retv); |
396 |
494 |
// TODO: how to test for error? if (core_globals.last_error_message) { |
// TODO: how to test for error? if (core_globals.last_error_message) { |
397 |
495 |
|
|
398 |
496 |
// PHP7 returns resource, PHP8.1 returns object |
// PHP7 returns resource, PHP8.1 returns object |
399 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { |
|
|
497 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) |
400 |
498 |
cs.dbh = retv->value.p; |
cs.dbh = retv->value.p; |
401 |
|
ninedogs_process_db(NINEDOGS_DB_CONN, &cs); |
|
402 |
|
} |
|
|
499 |
|
else |
|
500 |
|
cs.dbh = NULL; |
|
501 |
|
ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_END, &cs); |
403 |
502 |
|
|
404 |
503 |
return ret; |
return ret; |
405 |
504 |
} |
} |
|
... |
... |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
414 |
513 |
struct free_result fr; |
struct free_result fr; |
415 |
514 |
|
|
416 |
515 |
unsigned int num_args = e->This.u2.num_args; |
unsigned int num_args = e->This.u2.num_args; |
417 |
|
xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
|
516 |
|
xlog(200, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
418 |
517 |
//php_zed_dump(" e: ", e); |
//php_zed_dump(" e: ", e); |
419 |
518 |
//php_zval_dump(" retv: ", retv); |
//php_zval_dump(" retv: ", retv); |
420 |
519 |
|
|
|
... |
... |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
434 |
533 |
fr.ok = 0; |
fr.ok = 0; |
435 |
534 |
} |
} |
436 |
535 |
|
|
437 |
|
ninedogs_process_db(NINEDOGS_DB_FREE_RESULT, &fr); |
|
|
536 |
|
ninedogs_process_db("pg_free_result", NINEDOGS_DB_FREE_RESULT, &fr); |
438 |
537 |
|
|
439 |
538 |
return ret; |
return ret; |
440 |
539 |
} |
} |
|
... |
... |
static void php_set_para(struct zend_execute_data *e, const unsigned int i, |
469 |
568 |
memcpy(dst, para, sizeof(struct zval)); |
memcpy(dst, para, sizeof(struct zval)); |
470 |
569 |
} |
} |
471 |
570 |
|
|
472 |
|
static void php_set_last_error(struct zend_execute_data *e, |
|
|
571 |
|
static void php_pg_set_last_error(struct zend_execute_data *e, |
473 |
572 |
struct zval *dbh, struct query *q) |
struct zval *dbh, struct query *q) |
474 |
573 |
{ |
{ |
475 |
574 |
struct zval rz; |
struct zval rz; |
|
... |
... |
static void php_set_last_error(struct zend_execute_data *e, |
494 |
593 |
} |
} |
495 |
594 |
} |
} |
496 |
595 |
|
|
497 |
|
static void php_set_num_aff(struct zend_execute_data *e, struct zval *res, |
|
|
596 |
|
static void php_pg_set_num_aff(struct zend_execute_data *e, struct zval *res, |
498 |
597 |
struct query *q) |
struct query *q) |
499 |
598 |
{ |
{ |
500 |
599 |
struct zval rz; |
struct zval rz; |
|
... |
... |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
533 |
632 |
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); |
534 |
633 |
para = (struct zval *) e + s; |
para = (struct zval *) e + s; |
535 |
634 |
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 |
|
635 |
|
qs.params_len = 0; |
536 |
636 |
|
|
537 |
637 |
if (num_args == 2) { |
if (num_args == 2) { |
538 |
638 |
// link |
// link |
|
... |
... |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
550 |
650 |
qs.q = q->val; |
qs.q = q->val; |
551 |
651 |
qs.q_len = q->len; |
qs.q_len = q->len; |
552 |
652 |
|
|
553 |
|
ninedogs_now(&qs.start); |
|
|
653 |
|
ninedogs_process_db("pg_query", NINEDOGS_DB_QUERY_START, &qs); |
554 |
654 |
ret = old_pg_query(e, retv); |
ret = old_pg_query(e, retv); |
555 |
655 |
if (!retv) |
if (!retv) |
556 |
656 |
return ret; |
return ret; |
557 |
|
ninedogs_now(&qs.end); |
|
558 |
657 |
|
|
559 |
658 |
xlog(100, " old %s returned type=%s value=%s\n", |
xlog(100, " old %s returned type=%s value=%s\n", |
560 |
659 |
__func__, php_get_type(retv), php_get_value(retv)); |
__func__, php_get_type(retv), php_get_value(retv)); |
|
... |
... |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
563 |
662 |
memcpy(©_para, para, sizeof(struct zval)); |
memcpy(©_para, para, sizeof(struct zval)); |
564 |
663 |
|
|
565 |
664 |
if (retv->u1.v.type == 2) { // false |
if (retv->u1.v.type == 2) { // false |
566 |
|
php_set_last_error(e, dbh, &qs); |
|
|
665 |
|
php_pg_set_last_error(e, dbh, &qs); // TODO is qs.res set here? |
567 |
666 |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
568 |
|
qs.res = retv->value.str; |
|
569 |
|
php_set_num_aff(e, retv, &qs); |
|
|
667 |
|
qs.res = retv->value.p; |
|
668 |
|
php_pg_set_num_aff(e, retv, &qs); |
570 |
669 |
do_restore = 1; |
do_restore = 1; |
571 |
670 |
} |
} |
572 |
671 |
|
|
|
... |
... |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
574 |
673 |
if (do_restore) |
if (do_restore) |
575 |
674 |
memcpy(para, ©_para, sizeof(struct zval)); |
memcpy(para, ©_para, sizeof(struct zval)); |
576 |
675 |
|
|
577 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
676 |
|
ninedogs_process_db("pg_query", NINEDOGS_DB_QUERY_END, &qs); |
578 |
677 |
|
|
579 |
678 |
return ret; |
return ret; |
580 |
679 |
} |
} |
|
... |
... |
static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv) |
593 |
692 |
|
|
594 |
693 |
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); |
595 |
694 |
qs.type = 'P'; |
qs.type = 'P'; |
|
695 |
|
qs.params_len = 0; |
596 |
696 |
|
|
597 |
697 |
// link |
// link |
598 |
698 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
|
... |
... |
static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv) |
606 |
706 |
qs.q_len = q->len; |
qs.q_len = q->len; |
607 |
707 |
xlog(100, " query=%s\n", qs.q); |
xlog(100, " query=%s\n", qs.q); |
608 |
708 |
|
|
609 |
|
ninedogs_now(&qs.start); |
|
|
709 |
|
ninedogs_process_db("pg_send_query", NINEDOGS_DB_QUERY_START, &qs); |
610 |
710 |
ret = old_pg_send_query(e, retv); |
ret = old_pg_send_query(e, retv); |
611 |
711 |
if (!retv) |
if (!retv) |
612 |
712 |
return ret; |
return ret; |
613 |
|
ninedogs_now(&qs.end); |
|
614 |
713 |
|
|
615 |
|
xlog(1, " old %s returned type=%s value=%s\n", |
|
|
714 |
|
xlog(101, " old %s returned type=%s value=%s\n", |
616 |
715 |
__func__, php_get_type(retv), php_get_value(retv)); |
__func__, php_get_type(retv), php_get_value(retv)); |
617 |
716 |
|
|
618 |
717 |
qs.res = NULL; |
qs.res = NULL; |
619 |
718 |
if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int |
if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int |
620 |
|
php_set_last_error(e, dbh, &qs); |
|
|
719 |
|
php_pg_set_last_error(e, dbh, &qs); |
621 |
720 |
} else if (retv->u1.v.type == 3) { // true = success |
} else if (retv->u1.v.type == 3) { // true = success |
622 |
721 |
qs.num = qs.aff = 0; |
qs.num = qs.aff = 0; |
|
722 |
|
qs.res = (void *) 1; // signal ok |
623 |
723 |
} |
} |
624 |
724 |
|
|
625 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
725 |
|
ninedogs_process_db("pg_send_query", NINEDOGS_DB_QUERY_END, &qs); |
626 |
726 |
|
|
627 |
727 |
return ret; |
return ret; |
628 |
728 |
} |
} |
|
... |
... |
static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) |
644 |
744 |
para = (struct zval *) e + s; |
para = (struct zval *) e + s; |
645 |
745 |
qs.type = 'P'; |
qs.type = 'P'; |
646 |
746 |
qs.q = NULL; |
qs.q = NULL; |
|
747 |
|
qs.params_len = 0; |
647 |
748 |
|
|
648 |
749 |
// link |
// link |
649 |
750 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
650 |
751 |
//php_zval_dump(" dbh: ", z); |
//php_zval_dump(" dbh: ", z); |
651 |
752 |
qs.dbh = z->value.p; |
qs.dbh = z->value.p; |
652 |
753 |
|
|
653 |
|
ninedogs_now(&qs.start); |
|
|
754 |
|
ninedogs_process_db("pg_get_result", NINEDOGS_DB_QUERY_START, &qs); |
654 |
755 |
ret = old_pg_get_result(e, retv); |
ret = old_pg_get_result(e, retv); |
655 |
756 |
if (!retv) |
if (!retv) |
656 |
757 |
return ret; |
return ret; |
657 |
|
ninedogs_now(&qs.end); |
|
658 |
758 |
|
|
659 |
759 |
xlog(100, " old %s returned type=%s value=%s\n", |
xlog(100, " old %s returned type=%s value=%s\n", |
660 |
760 |
__func__, php_get_type(retv), php_get_value(retv)); |
__func__, php_get_type(retv), php_get_value(retv)); |
|
... |
... |
static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) |
663 |
763 |
memcpy(©_para, para, sizeof(struct zval)); |
memcpy(©_para, para, sizeof(struct zval)); |
664 |
764 |
|
|
665 |
765 |
if (retv->u1.v.type == 2) { // false |
if (retv->u1.v.type == 2) { // false |
666 |
|
php_set_last_error(e, dbh, &qs); |
|
|
766 |
|
php_pg_set_last_error(e, dbh, &qs); |
667 |
767 |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
668 |
768 |
qs.err = NULL; |
qs.err = NULL; |
669 |
|
qs.res = retv->value.str; |
|
670 |
|
php_set_num_aff(e, retv, &qs); |
|
|
769 |
|
qs.res = retv->value.p; |
|
770 |
|
php_pg_set_num_aff(e, retv, &qs); |
671 |
771 |
do_restore = 1; |
do_restore = 1; |
672 |
772 |
} |
} |
673 |
773 |
|
|
|
... |
... |
static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) |
675 |
775 |
if (do_restore) |
if (do_restore) |
676 |
776 |
memcpy(para, ©_para, sizeof(struct zval)); |
memcpy(para, ©_para, sizeof(struct zval)); |
677 |
777 |
|
|
678 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
778 |
|
ninedogs_process_db("pg_get_result", NINEDOGS_DB_QUERY_END, &qs); |
679 |
779 |
|
|
680 |
780 |
return ret; |
return ret; |
681 |
781 |
} |
} |
|
... |
... |
static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) |
693 |
793 |
struct query qs; |
struct query qs; |
694 |
794 |
|
|
695 |
795 |
num_args = e->This.u2.num_args; |
num_args = e->This.u2.num_args; |
696 |
|
//xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
|
796 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
697 |
797 |
//php_zed_dump(" e0: ", e); |
//php_zed_dump(" e0: ", e); |
698 |
798 |
//php_zval_dump(" retv0: ", retv); |
//php_zval_dump(" retv0: ", retv); |
699 |
799 |
|
|
|
... |
... |
static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) |
717 |
817 |
|
|
718 |
818 |
// params (array) |
// params (array) |
719 |
819 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
720 |
|
#if 1 |
|
721 |
|
struct zend_array *za; |
|
722 |
|
za = z->value.arr; |
|
723 |
|
xlog(200, " nTableMask=%u nNumUsed=%u nNumOfElements=%u nTableSize=%u nInternalPointer=%u\n", |
|
724 |
|
za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize, za->nInternalPointer); |
|
|
820 |
|
struct zend_array *za = z->value.arr; |
|
821 |
|
zend_array_to_params_array(&qs, za); |
725 |
822 |
|
|
726 |
|
struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed; |
|
727 |
|
unsigned int i = 1; |
|
728 |
|
for (; bs != be; bs++) { |
|
729 |
|
struct zval *_z = &bs->val; |
|
730 |
|
|
|
731 |
|
if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT |
|
732 |
|
_z = _z->value.zv; |
|
733 |
|
|
|
734 |
|
if (_z->u1.v.type == 0 /*IS_UNDEF*/) continue; |
|
735 |
|
|
|
736 |
|
if (_z->u1.v.type == 10) { // REFERENCE |
|
737 |
|
xlog(1, " is a reference!\n"); |
|
738 |
|
_z = &_z->value.ref->val; |
|
739 |
|
} |
|
740 |
|
|
|
741 |
|
xlog(200, " para %u: type %s: val: %s\n", |
|
742 |
|
i, php_get_type(_z), php_get_value(_z)); |
|
743 |
|
i++; |
|
744 |
|
} |
|
745 |
|
#endif |
|
746 |
|
|
|
747 |
|
ninedogs_now(&qs.start); |
|
|
823 |
|
ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_START, &qs); |
748 |
824 |
ret = old_pg_query_params(e, retv); |
ret = old_pg_query_params(e, retv); |
749 |
|
ninedogs_now(&qs.end); |
|
750 |
825 |
//xlog(200, " old %s: type=%s value=%s\n", |
//xlog(200, " old %s: type=%s value=%s\n", |
751 |
826 |
// __func__, php_get_type(retv), php_get_value(retv)); |
// __func__, php_get_type(retv), php_get_value(retv)); |
752 |
827 |
//php_zed_dump(" e1: ", e); |
//php_zed_dump(" e1: ", e); |
753 |
|
//php_zval_dump(" retv1 after calling old func: ", retv); |
|
|
828 |
|
//php_zval_dump(" retv after calling old func: ", retv); |
754 |
829 |
|
|
755 |
830 |
copy_num_args = e->This.u2.num_args; |
copy_num_args = e->This.u2.num_args; |
756 |
831 |
memcpy(©_para, para, sizeof(struct zval)); |
memcpy(©_para, para, sizeof(struct zval)); |
757 |
832 |
|
|
758 |
833 |
if (retv->u1.v.type == 2) { // false |
if (retv->u1.v.type == 2) { // false |
759 |
|
php_set_last_error(e, dbh, &qs); |
|
|
834 |
|
php_pg_set_last_error(e, dbh, &qs); |
760 |
835 |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
761 |
|
qs.res = retv->value.str; |
|
762 |
|
php_set_num_aff(e, retv, &qs); |
|
|
836 |
|
qs.res = retv->value.p; |
|
837 |
|
php_pg_set_num_aff(e, retv, &qs); |
763 |
838 |
do_restore = 1; |
do_restore = 1; |
764 |
839 |
} |
} |
765 |
840 |
|
|
|
... |
... |
static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) |
769 |
844 |
if (do_restore) |
if (do_restore) |
770 |
845 |
memcpy(para, ©_para, sizeof(struct zval)); |
memcpy(para, ©_para, sizeof(struct zval)); |
771 |
846 |
|
|
772 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
847 |
|
ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_END, &qs); |
773 |
848 |
|
|
774 |
849 |
return ret; |
return ret; |
775 |
850 |
} |
} |
|
... |
... |
static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *r |
784 |
859 |
struct zend_string *q; |
struct zend_string *q; |
785 |
860 |
struct query qs; |
struct query qs; |
786 |
861 |
|
|
787 |
|
//unsigned int num_args = e->This.u2.num_args; |
|
788 |
|
//xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
|
862 |
|
unsigned int num_args = e->This.u2.num_args; |
|
863 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
789 |
864 |
//php_zed_dump(" e0: ", e); |
//php_zed_dump(" e0: ", e); |
790 |
865 |
//php_zval_dump(" retv0: ", retv); |
//php_zval_dump(" retv0: ", retv); |
791 |
866 |
|
|
|
... |
... |
static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *r |
804 |
879 |
|
|
805 |
880 |
// params (array) |
// params (array) |
806 |
881 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
807 |
|
#if 1 |
|
808 |
|
struct zend_array *za; |
|
809 |
|
za = z->value.arr; |
|
810 |
|
xlog(200, " nTableMask=%u nNumUsed=%u nNumOfElements=%u nTableSize=%u nInternalPointer=%u\n", |
|
811 |
|
za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize, za->nInternalPointer); |
|
|
882 |
|
struct zend_array *za = z->value.arr; |
|
883 |
|
zend_array_to_params_array(&qs, za); |
812 |
884 |
|
|
813 |
|
struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed; |
|
814 |
|
unsigned int i = 1; |
|
815 |
|
for (; bs != be; bs++) { |
|
816 |
|
struct zval *_z = &bs->val; |
|
817 |
|
|
|
818 |
|
if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT |
|
819 |
|
_z = _z->value.zv; |
|
820 |
|
|
|
821 |
|
if (_z->u1.v.type == 0 /*IS_UNDEF*/) continue; |
|
822 |
|
|
|
823 |
|
if (_z->u1.v.type == 10) { // REFERENCE |
|
824 |
|
xlog(1, " is a reference!\n"); |
|
825 |
|
_z = &_z->value.ref->val; |
|
826 |
|
} |
|
827 |
|
|
|
828 |
|
xlog(200, " para %u: type %s: val: %s\n", |
|
829 |
|
i, php_get_type(_z), php_get_value(_z)); |
|
830 |
|
i++; |
|
831 |
|
} |
|
832 |
|
#endif |
|
833 |
|
|
|
834 |
|
ninedogs_now(&qs.start); |
|
|
885 |
|
ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_START, &qs); |
835 |
886 |
ret = old_pg_send_query_params(e, retv); |
ret = old_pg_send_query_params(e, retv); |
836 |
|
ninedogs_now(&qs.end); |
|
837 |
887 |
//xlog(200, " old %s: type=%s value=%s\n", |
//xlog(200, " old %s: type=%s value=%s\n", |
838 |
888 |
// __func__, php_get_type(retv), php_get_value(retv)); |
// __func__, php_get_type(retv), php_get_value(retv)); |
839 |
889 |
//php_zed_dump(" e1: ", e); |
//php_zed_dump(" e1: ", e); |
840 |
|
//php_zval_dump(" retv1 after calling old func: ", retv); |
|
|
890 |
|
//php_zval_dump(" retv after calling old func: ", retv); |
841 |
891 |
|
|
842 |
892 |
qs.res = NULL; |
qs.res = NULL; |
843 |
893 |
if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int (probably 0) |
if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int (probably 0) |
844 |
|
php_set_last_error(e, dbh, &qs); |
|
|
894 |
|
php_pg_set_last_error(e, dbh, &qs); |
845 |
895 |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
846 |
896 |
qs.num = qs.aff = 0; |
qs.num = qs.aff = 0; |
|
897 |
|
qs.res = (void *) 1; // signal ok |
|
898 |
|
} |
|
899 |
|
|
|
900 |
|
ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_END, &qs); |
|
901 |
|
|
|
902 |
|
return ret; |
|
903 |
|
} |
|
904 |
|
|
|
905 |
|
|
|
906 |
|
void *(*old_mysqli_connect)(struct zend_execute_data *, struct zval *); |
|
907 |
|
static void *my_mysqli_connect(struct zend_execute_data *e, struct zval *retv) |
|
908 |
|
{ |
|
909 |
|
void *ret; |
|
910 |
|
unsigned int num_args, s; |
|
911 |
|
struct zval *z; |
|
912 |
|
struct conn cs; |
|
913 |
|
char *host = "", *user = "", *db = "", *sock = ""; |
|
914 |
|
int port = 0; |
|
915 |
|
|
|
916 |
|
num_args = e->This.u2.num_args; |
|
917 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
918 |
|
|
|
919 |
|
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
920 |
|
cs.type = 'M'; |
|
921 |
|
|
|
922 |
|
if (num_args >= 1) { // host |
|
923 |
|
z = (struct zval *) e + s; s++; |
|
924 |
|
php_zval_dump(" host: ", z); |
|
925 |
|
if (z->u1.v.type == 6) // string |
|
926 |
|
host = z->value.str->val; |
|
927 |
|
} |
|
928 |
|
|
|
929 |
|
if (num_args >= 2) { // user |
|
930 |
|
z = (struct zval *) e + s; s++; |
|
931 |
|
if (z->u1.v.type == 6) // string |
|
932 |
|
user = z->value.str->val; |
|
933 |
|
} |
|
934 |
|
|
|
935 |
|
if (num_args >= 3) // pass |
|
936 |
|
s++; |
|
937 |
|
|
|
938 |
|
if (num_args >= 4) { // db |
|
939 |
|
z = (struct zval *) e + s; s++; |
|
940 |
|
if (z->u1.v.type == 6) // string |
|
941 |
|
db = z->value.str->val; |
|
942 |
|
} |
|
943 |
|
|
|
944 |
|
if (num_args >= 5) { // port |
|
945 |
|
z = (struct zval *) e + s; s++; |
|
946 |
|
if (z->u1.v.type == 4) // long |
|
947 |
|
port = z->value.lval; |
|
948 |
|
} |
|
949 |
|
|
|
950 |
|
if (num_args >= 6) { // socket |
|
951 |
|
z = (struct zval *) e + s; s++; |
|
952 |
|
if (z->u1.v.type == 6) // string |
|
953 |
|
sock = z->value.str->val; |
|
954 |
|
} |
|
955 |
|
|
|
956 |
|
char conn_str[512]; |
|
957 |
|
snprintf(conn_str, sizeof(conn_str), |
|
958 |
|
"host=%s user=%s port=%d db=%s socket=%s", |
|
959 |
|
host, user, port, db, sock); |
|
960 |
|
cs.conn_str = conn_str; |
|
961 |
|
cs.conn_str_len = strlen(cs.conn_str); |
|
962 |
|
|
|
963 |
|
ninedogs_process_db("mysqli_connect", NINEDOGS_DB_CONN_START, &cs); |
|
964 |
|
ret = old_mysqli_connect(e, retv); |
|
965 |
|
if (!retv) { |
|
966 |
|
xlog(1, "DEBUG: old_mysqli_connect returned retv NULL\n"); |
|
967 |
|
return ret; |
|
968 |
|
} |
|
969 |
|
//php_zval_dump(" retv: ", retv); |
|
970 |
|
// TODO: how to test for error? if (core_globals.last_error_message) { |
|
971 |
|
|
|
972 |
|
// PHP7 returns resource, PHP8.1 returns object |
|
973 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) |
|
974 |
|
cs.dbh = retv->value.p; |
|
975 |
|
else |
|
976 |
|
cs.dbh = NULL; |
|
977 |
|
ninedogs_process_db("mysqli_connect", NINEDOGS_DB_CONN_END, &cs); |
|
978 |
|
|
|
979 |
|
return ret; |
|
980 |
|
} |
|
981 |
|
|
|
982 |
|
void *(*old_mysqli_real_connect)(struct zend_execute_data *, struct zval *); |
|
983 |
|
static void *my_mysqli_real_connect(struct zend_execute_data *e, struct zval *retv) |
|
984 |
|
{ |
|
985 |
|
void *ret; |
|
986 |
|
unsigned int num_args, s; |
|
987 |
|
struct zval *z; |
|
988 |
|
struct conn cs; |
|
989 |
|
char *host = "", *user = "", *db = "", *sock = ""; |
|
990 |
|
int port = 0; |
|
991 |
|
|
|
992 |
|
num_args = e->This.u2.num_args; |
|
993 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
994 |
|
|
|
995 |
|
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
996 |
|
cs.type = 'M'; |
|
997 |
|
cs.flags = 0; |
|
998 |
|
|
|
999 |
|
if (num_args >= 1) { // dbh |
|
1000 |
|
z = (struct zval *) e + s; s++; |
|
1001 |
|
if ((z->u1.v.type == 8) || (z->u1.v.type == 9)) // object or resource |
|
1002 |
|
cs.dbh = z->value.p; |
|
1003 |
|
} |
|
1004 |
|
|
|
1005 |
|
if (num_args >= 2) { // host |
|
1006 |
|
z = (struct zval *) e + s; s++; |
|
1007 |
|
php_zval_dump(" host: ", z); |
|
1008 |
|
if (z->u1.v.type == 6) // string |
|
1009 |
|
host = z->value.str->val; |
|
1010 |
|
} |
|
1011 |
|
|
|
1012 |
|
if (num_args >= 3) { // user |
|
1013 |
|
z = (struct zval *) e + s; s++; |
|
1014 |
|
if (z->u1.v.type == 6) // string |
|
1015 |
|
user = z->value.str->val; |
|
1016 |
|
} |
|
1017 |
|
|
|
1018 |
|
if (num_args >= 4) // pass |
|
1019 |
|
s++; |
|
1020 |
|
|
|
1021 |
|
if (num_args >= 5) { // db |
|
1022 |
|
z = (struct zval *) e + s; s++; |
|
1023 |
|
if (z->u1.v.type == 6) // string |
|
1024 |
|
db = z->value.str->val; |
|
1025 |
|
} |
|
1026 |
|
|
|
1027 |
|
if (num_args >= 6) { // port |
|
1028 |
|
z = (struct zval *) e + s; s++; |
|
1029 |
|
if (z->u1.v.type == 4) // long |
|
1030 |
|
port = z->value.lval; |
|
1031 |
|
} |
|
1032 |
|
|
|
1033 |
|
if (num_args >= 7) { // socket |
|
1034 |
|
z = (struct zval *) e + s; s++; |
|
1035 |
|
if (z->u1.v.type == 6) // string |
|
1036 |
|
sock = z->value.str->val; |
|
1037 |
|
} |
|
1038 |
|
|
|
1039 |
|
if (num_args >= 8) { // flags |
|
1040 |
|
z = (struct zval *) e + s; s++; |
|
1041 |
|
if (z->u1.v.type == 4) // long |
|
1042 |
|
cs.flags = z->value.lval; |
|
1043 |
|
} |
|
1044 |
|
|
|
1045 |
|
char conn_str[512]; |
|
1046 |
|
snprintf(conn_str, sizeof(conn_str), |
|
1047 |
|
"host=%s user=%s port=%d db=%s socket=%s", |
|
1048 |
|
host, user, port, db, sock); |
|
1049 |
|
cs.conn_str = conn_str; |
|
1050 |
|
cs.conn_str_len = strlen(cs.conn_str); |
|
1051 |
|
|
|
1052 |
|
ninedogs_process_db("mysqli_real_connect", NINEDOGS_DB_CONN_START, &cs); |
|
1053 |
|
ret = old_mysqli_real_connect(e, retv); |
|
1054 |
|
if (!retv) { |
|
1055 |
|
xlog(1, "DEBUG: old_mysqli_real_connect returned retv NULL\n"); |
|
1056 |
|
return ret; |
|
1057 |
|
} |
|
1058 |
|
//php_zval_dump(" retv: ", retv); |
|
1059 |
|
// TODO: how to test for error? if (core_globals.last_error_message) { |
|
1060 |
|
|
|
1061 |
|
// PHP7 returns resource, PHP8.1 returns object |
|
1062 |
|
if (retv->u1.v.type == 3) |
|
1063 |
|
cs.ret = 1; |
|
1064 |
|
else |
|
1065 |
|
cs.ret = 0; |
|
1066 |
|
ninedogs_process_db("mysqli_real_connect", NINEDOGS_DB_CONN_END, &cs); |
|
1067 |
|
|
|
1068 |
|
return ret; |
|
1069 |
|
} |
|
1070 |
|
|
|
1071 |
|
void *(*old_mysqli_query)(struct zend_execute_data *, struct zval *); |
|
1072 |
|
static void *my_mysqli_query(struct zend_execute_data *e, struct zval *retv) |
|
1073 |
|
{ |
|
1074 |
|
void *ret; |
|
1075 |
|
unsigned int num_args, copy_num_args, s; |
|
1076 |
|
struct zend_string *q; |
|
1077 |
|
struct zval *z, copy_para, *para; |
|
1078 |
|
char do_restore = 0; |
|
1079 |
|
struct query qs; |
|
1080 |
|
|
|
1081 |
|
num_args = e->This.u2.num_args; |
|
1082 |
|
|
|
1083 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1084 |
|
|
|
1085 |
|
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1086 |
|
para = (struct zval *) e + s; |
|
1087 |
|
qs.type = 'M'; |
|
1088 |
|
qs.params_len = 0; |
|
1089 |
|
|
|
1090 |
|
// link |
|
1091 |
|
z = (struct zval *) e + s; s++; |
|
1092 |
|
php_zval_dump(" dbh: ", z); |
|
1093 |
|
qs.dbh = z->value.p; |
|
1094 |
|
|
|
1095 |
|
// query |
|
1096 |
|
z = (struct zval *) e + s; s++; |
|
1097 |
|
q = z->value.str; |
|
1098 |
|
xlog(50, " query=%s\n", q->val); |
|
1099 |
|
qs.q = q->val; |
|
1100 |
|
qs.q_len = q->len; |
|
1101 |
|
|
|
1102 |
|
// mode |
|
1103 |
|
if (num_args >= 3) { |
|
1104 |
|
z = (struct zval *) e + s; s++; |
|
1105 |
|
xlog(50, " mode=0x%lx\n", z->value.lval); |
|
1106 |
|
} |
|
1107 |
|
|
|
1108 |
|
ninedogs_process_db("mysqli_query", NINEDOGS_DB_QUERY_START, &qs); |
|
1109 |
|
ret = old_mysqli_query(e, retv); |
|
1110 |
|
if (!retv) |
|
1111 |
|
return ret; |
|
1112 |
|
php_zval_dump(" retv: ", retv); |
|
1113 |
|
|
|
1114 |
|
copy_num_args = num_args; |
|
1115 |
|
memcpy(©_para, para, sizeof(struct zval)); |
|
1116 |
|
|
|
1117 |
|
if (retv->u1.v.type == 2) { // false |
|
1118 |
|
// TODO php_mysqli_set_last_error(e, dbh, &qs); // TODO is qs.res set here? |
|
1119 |
|
// TODO: do we set num and aff? |
|
1120 |
|
qs.res = (void *) 0; |
|
1121 |
|
} else if (retv->u1.v.type == 3) { // true (for queries not returning rows) |
|
1122 |
|
qs.num = qs.aff = 0; |
|
1123 |
|
qs.res = (void *) 1; |
|
1124 |
|
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
|
1125 |
|
qs.res = retv->value.p; |
|
1126 |
|
//TODO php_mysqli_set_num_aff(e, retv, &qs); |
|
1127 |
|
do_restore = 1; |
|
1128 |
|
} |
|
1129 |
|
|
|
1130 |
|
e->This.u2.num_args = copy_num_args; |
|
1131 |
|
if (do_restore) |
|
1132 |
|
memcpy(para, ©_para, sizeof(struct zval)); |
|
1133 |
|
|
|
1134 |
|
ninedogs_process_db("mysqli_query", NINEDOGS_DB_QUERY_END, &qs); |
|
1135 |
|
|
|
1136 |
|
return ret; |
|
1137 |
|
} |
|
1138 |
|
|
|
1139 |
|
void *(*old_mysqli_close)(struct zend_execute_data *, struct zval *); |
|
1140 |
|
static void *my_mysqli_close(struct zend_execute_data *e, struct zval *retv) |
|
1141 |
|
{ |
|
1142 |
|
struct conn c; |
|
1143 |
|
|
|
1144 |
|
unsigned int num_args = e->This.u2.num_args; |
|
1145 |
|
|
|
1146 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1147 |
|
|
|
1148 |
|
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1149 |
|
struct zval *para = (struct zval *) e + s; |
|
1150 |
|
c.type = 'M'; |
|
1151 |
|
|
|
1152 |
|
// link |
|
1153 |
|
struct zval *z = (struct zval *) e + s; s++; |
|
1154 |
|
php_zval_dump(" dbh: ", z); |
|
1155 |
|
c.dbh = z->value.p; |
|
1156 |
|
|
|
1157 |
|
void *ret = old_mysqli_close(e, retv); |
|
1158 |
|
if (!retv) |
|
1159 |
|
return ret; |
|
1160 |
|
php_zval_dump(" retv: ", retv); |
|
1161 |
|
|
|
1162 |
|
if (retv->u1.v.type == 2) { // false |
|
1163 |
|
c.ret = 0; |
|
1164 |
|
// TODO php_mysqli_set_last_error(e, dbh, &qs); // TODO is qs.res set here? |
|
1165 |
|
// TODO: do we set num and aff? |
|
1166 |
|
} else if (retv->u1.v.type == 3) { // true (for queries not returning rows) |
|
1167 |
|
c.ret = 1; |
847 |
1168 |
} |
} |
848 |
1169 |
|
|
849 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
1170 |
|
ninedogs_process_db("mysqli_close", NINEDOGS_DB_CONN_CLOSE, &c); |
850 |
1171 |
|
|
851 |
1172 |
return ret; |
return ret; |
852 |
1173 |
} |
} |
853 |
1174 |
|
|
|
1175 |
|
|
854 |
1176 |
struct zend_module_entry *(*old_get_module)(void); |
struct zend_module_entry *(*old_get_module)(void); |
855 |
1177 |
static struct zend_module_entry *php_hook_get_module_func(void) |
static struct zend_module_entry *php_hook_get_module_func(void) |
856 |
1178 |
{ |
{ |
|
... |
... |
static struct zend_module_entry *php_hook_get_module_func(void) |
859 |
1181 |
unsigned int count; |
unsigned int count; |
860 |
1182 |
|
|
861 |
1183 |
z = old_get_module(); |
z = old_get_module(); |
|
1184 |
|
xlog(100, " %s: calling old_get_module returned %p\n", __func__, z); |
862 |
1185 |
if (!z) |
if (!z) |
863 |
1186 |
return NULL; |
return NULL; |
864 |
1187 |
|
|
865 |
|
if (strcmp(z->name, "pgsql") != 0) |
|
|
1188 |
|
xlog(100, " %s: name=[%s] size=%hu zend_api=%u zts=%hhu version=[%s] functions=%p" |
|
1189 |
|
" build_id=[%s]\n", |
|
1190 |
|
__func__, z->name, z->size, z->zend_api, z->zts, z->version, z->functions, |
|
1191 |
|
z->build_id); |
|
1192 |
|
|
|
1193 |
|
if (sizeof(struct zend_module_entry) != z->size) { |
|
1194 |
|
xlog(1, "%s: sizeof(struct zend_module_entry)[%zu] is not %hu!\n", |
|
1195 |
|
sizeof(struct zend_module_entry), z->size); |
866 |
1196 |
return z; |
return z; |
|
1197 |
|
} |
867 |
1198 |
|
|
868 |
|
xlog(100, " %s: name=%s size=%hu zend_api=%u zts=%hhu version=%s functions=%p\n", |
|
869 |
|
__func__, z->name, z->size, z->zend_api, z->zts, z->version, z->functions); |
|
|
1199 |
|
if (!z->functions) |
|
1200 |
|
return z; |
870 |
1201 |
|
|
871 |
1202 |
count = 0; |
count = 0; |
872 |
1203 |
fe = z->functions; |
fe = z->functions; |
|
... |
... |
static struct zend_module_entry *php_hook_get_module_func(void) |
894 |
1225 |
memcpy(new->functions, z->functions, (count + 1) * sizeof(struct zend_function_entry)); |
memcpy(new->functions, z->functions, (count + 1) * sizeof(struct zend_function_entry)); |
895 |
1226 |
|
|
896 |
1227 |
fe = new->functions; |
fe = new->functions; |
897 |
|
while (fe->fname) { |
|
898 |
|
//xlog(2, " func %s handler=%p\n", fe->fname, fe->handler); |
|
899 |
|
if (strcmp(fe->fname, "pg_connect") == 0) { |
|
900 |
|
old_pg_connect = fe->handler; |
|
901 |
|
fe->handler = my_pg_connect; |
|
902 |
|
} else if (strcmp(fe->fname, "pg_pconnect") == 0) { |
|
903 |
|
old_pg_pconnect = fe->handler; |
|
904 |
|
fe->handler = my_pg_pconnect; |
|
905 |
|
} else if (strcmp(fe->fname, "pg_num_rows") == 0) { |
|
906 |
|
old_pg_num_rows = fe->handler; |
|
907 |
|
fe->handler = my_pg_num_rows; |
|
908 |
|
} else if (strcmp(fe->fname, "pg_affected_rows") == 0) { |
|
909 |
|
old_pg_affected_rows = fe->handler; |
|
910 |
|
} else if (strcmp(fe->fname, "pg_free_result") == 0) { |
|
911 |
|
old_pg_free_result = fe->handler; |
|
912 |
|
fe->handler = my_pg_free_result; |
|
913 |
|
} else if (strcmp(fe->fname, "pg_query") == 0) { |
|
914 |
|
old_pg_query = fe->handler; |
|
915 |
|
fe->handler = my_pg_query; |
|
916 |
|
} else if (strcmp(fe->fname, "pg_send_query") == 0) { |
|
917 |
|
old_pg_send_query = fe->handler; |
|
918 |
|
fe->handler = my_pg_send_query; |
|
919 |
|
} else if (strcmp(fe->fname, "pg_query_params") == 0) { |
|
920 |
|
old_pg_query_params = fe->handler; |
|
921 |
|
fe->handler = my_pg_query_params; |
|
922 |
|
} else if (strcmp(fe->fname, "pg_send_query_params") == 0) { |
|
923 |
|
old_pg_send_query_params = fe->handler; |
|
924 |
|
fe->handler = my_pg_send_query_params; |
|
925 |
|
} else if (strcmp(fe->fname, "pg_last_error") == 0) { |
|
926 |
|
old_pg_last_error = fe->handler; |
|
927 |
|
fe->handler = my_pg_last_error; |
|
928 |
|
} else if (strcmp(fe->fname, "pg_get_result") == 0) { |
|
929 |
|
old_pg_get_result = fe->handler; |
|
930 |
|
fe->handler = my_pg_get_result; |
|
931 |
|
} else { |
|
932 |
|
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
|
|
1228 |
|
while (fe && fe->fname) { |
|
1229 |
|
xlog(2, " fe=%p\n", fe); |
|
1230 |
|
xlog(100, " func %s handler=%p\n", fe->fname, fe->handler); |
|
1231 |
|
if (strncmp(fe->fname, "pg_", 3) == 0) { |
|
1232 |
|
if (strcmp(fe->fname, "pg_close") == 0) { |
|
1233 |
|
old_pg_close = fe->handler; |
|
1234 |
|
fe->handler = my_pg_close; |
|
1235 |
|
} else if (strcmp(fe->fname, "pg_connect") == 0) { |
|
1236 |
|
old_pg_connect = fe->handler; |
|
1237 |
|
fe->handler = my_pg_connect; |
|
1238 |
|
} else if (strcmp(fe->fname, "pg_pconnect") == 0) { |
|
1239 |
|
old_pg_pconnect = fe->handler; |
|
1240 |
|
fe->handler = my_pg_pconnect; |
|
1241 |
|
} else if (strcmp(fe->fname, "pg_num_rows") == 0) { |
|
1242 |
|
old_pg_num_rows = fe->handler; |
|
1243 |
|
fe->handler = my_pg_num_rows; |
|
1244 |
|
} else if (strcmp(fe->fname, "pg_affected_rows") == 0) { |
|
1245 |
|
old_pg_affected_rows = fe->handler; |
|
1246 |
|
} else if (strcmp(fe->fname, "pg_free_result") == 0) { |
|
1247 |
|
old_pg_free_result = fe->handler; |
|
1248 |
|
fe->handler = my_pg_free_result; |
|
1249 |
|
} else if (strcmp(fe->fname, "pg_query") == 0) { |
|
1250 |
|
old_pg_query = fe->handler; |
|
1251 |
|
fe->handler = my_pg_query; |
|
1252 |
|
} else if (strcmp(fe->fname, "pg_send_query") == 0) { |
|
1253 |
|
old_pg_send_query = fe->handler; |
|
1254 |
|
fe->handler = my_pg_send_query; |
|
1255 |
|
} else if (strcmp(fe->fname, "pg_query_params") == 0) { |
|
1256 |
|
old_pg_query_params = fe->handler; |
|
1257 |
|
fe->handler = my_pg_query_params; |
|
1258 |
|
} else if (strcmp(fe->fname, "pg_send_query_params") == 0) { |
|
1259 |
|
old_pg_send_query_params = fe->handler; |
|
1260 |
|
fe->handler = my_pg_send_query_params; |
|
1261 |
|
} else if (strcmp(fe->fname, "pg_last_error") == 0) { |
|
1262 |
|
old_pg_last_error = fe->handler; |
|
1263 |
|
fe->handler = my_pg_last_error; |
|
1264 |
|
} else if (strcmp(fe->fname, "pg_get_result") == 0) { |
|
1265 |
|
old_pg_get_result = fe->handler; |
|
1266 |
|
fe->handler = my_pg_get_result; |
|
1267 |
|
} else { |
|
1268 |
|
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
|
1269 |
|
} |
|
1270 |
|
} else if (strncmp(fe->fname, "mysqli_", 7) == 0) { |
|
1271 |
|
if (strcmp(fe->fname, "mysqli_close") == 0) { |
|
1272 |
|
old_mysqli_close = fe->handler; |
|
1273 |
|
fe->handler = my_mysqli_close; |
|
1274 |
|
} else if (strcmp(fe->fname, "mysqli_connect") == 0) { |
|
1275 |
|
old_mysqli_connect = fe->handler; |
|
1276 |
|
fe->handler = my_mysqli_connect; |
|
1277 |
|
} else if (strcmp(fe->fname, "mysqli_query") == 0) { |
|
1278 |
|
old_mysqli_query = fe->handler; |
|
1279 |
|
fe->handler = my_mysqli_query; |
|
1280 |
|
} else if (strcmp(fe->fname, "mysqli_real_connect") == 0) { |
|
1281 |
|
old_mysqli_real_connect = fe->handler; |
|
1282 |
|
fe->handler = my_mysqli_real_connect; |
|
1283 |
|
} else { |
|
1284 |
|
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
|
1285 |
|
} |
933 |
1286 |
} |
} |
934 |
1287 |
fe++; |
fe++; |
935 |
1288 |
} |
} |
|
... |
... |
static struct zend_module_entry *php_hook_get_module_func(void) |
939 |
1292 |
|
|
940 |
1293 |
void *php_hook(void *x) |
void *php_hook(void *x) |
941 |
1294 |
{ |
{ |
|
1295 |
|
xlog(100, "%s x=%p\n", __func__, x); |
942 |
1296 |
old_get_module = x; |
old_get_module = x; |
943 |
1297 |
return php_hook_get_module_func; |
return php_hook_get_module_func; |
944 |
1298 |
} |
} |
945 |
1299 |
|
|
|
1300 |
|
#if 0 |
946 |
1301 |
typedef struct { |
typedef struct { |
947 |
1302 |
const char *driver_name; |
const char *driver_name; |
948 |
1303 |
size_t driver_name_len; |
size_t driver_name_len; |
|
... |
... |
typedef struct { |
950 |
1305 |
int (*db_handle_factory)(void *dbh, void *driver_options); |
int (*db_handle_factory)(void *dbh, void *driver_options); |
951 |
1306 |
} pdo_driver_t; |
} pdo_driver_t; |
952 |
1307 |
|
|
953 |
|
#if 0 |
|
954 |
1308 |
pdo_driver_t old, my_driver; |
pdo_driver_t old, my_driver; |
955 |
1309 |
int php_pdo_register_driver(pdo_driver_t *driver) |
int php_pdo_register_driver(pdo_driver_t *driver) |
956 |
1310 |
{ |
{ |
File agent/python.c copied from file agent/php.c (similarity 63%) (mode: 100644) (index 5e656a4..fe40f5d) |
39 |
39 |
#include <ctype.h> |
#include <ctype.h> |
40 |
40 |
|
|
41 |
41 |
#include "ids.h" |
#include "ids.h" |
42 |
|
#include "php.h" |
|
|
42 |
|
#include "python.h" |
43 |
43 |
#include "tools.h" |
#include "tools.h" |
44 |
44 |
#include "ctools.h" |
#include "ctools.h" |
45 |
45 |
#include "process_db.h" |
#include "process_db.h" |
|
... |
... |
struct zend_array |
111 |
111 |
unsigned char nIteratorsCount; |
unsigned char nIteratorsCount; |
112 |
112 |
unsigned char _unused2; |
unsigned char _unused2; |
113 |
113 |
} v; |
} v; |
114 |
|
unsigned int flags; |
|
|
114 |
|
unsigned int flags; |
115 |
115 |
} u; |
} u; |
116 |
116 |
unsigned int nTableMask; |
unsigned int nTableMask; |
117 |
|
struct Bucket *arData; |
|
|
117 |
|
union { |
|
118 |
|
uint32_t *arHash; |
|
119 |
|
struct Bucket *arData; |
|
120 |
|
struct zval *arPacked; |
|
121 |
|
}; |
118 |
122 |
unsigned int nNumUsed; |
unsigned int nNumUsed; |
119 |
123 |
unsigned int nNumOfElements; |
unsigned int nNumOfElements; |
120 |
124 |
unsigned int nTableSize; |
unsigned int nTableSize; |
|
... |
... |
struct Bucket |
166 |
170 |
|
|
167 |
171 |
struct zend_reference |
struct zend_reference |
168 |
172 |
{ |
{ |
169 |
|
unsigned int refcount; |
|
170 |
|
unsigned int pad1; |
|
171 |
|
struct zval val; |
|
172 |
|
/* more thigs follows */ |
|
|
173 |
|
struct zend_refcounted_h gc; |
|
174 |
|
struct zval val; |
|
175 |
|
void *sources; |
173 |
176 |
}; |
}; |
174 |
177 |
|
|
175 |
178 |
struct zend_execute_data |
struct zend_execute_data |
|
... |
... |
struct TODOpgsql_link_handle |
195 |
198 |
unsigned char pad1[7]; |
unsigned char pad1[7]; |
196 |
199 |
}; |
}; |
197 |
200 |
|
|
198 |
|
static char *php_get_value(const struct zval *z) |
|
|
201 |
|
static char *python_get_value(const struct zval *z) |
199 |
202 |
{ |
{ |
200 |
203 |
static char ret[4096]; |
static char ret[4096]; |
201 |
204 |
const struct zval *next; |
const struct zval *next; |
|
... |
... |
static char *php_get_value(const struct zval *z) |
219 |
222 |
snprintf(ret, sizeof(ret), "%p", z->value.p); return ret; |
snprintf(ret, sizeof(ret), "%p", z->value.p); return ret; |
220 |
223 |
case 10: |
case 10: |
221 |
224 |
next = &z->value.ref->val; |
next = &z->value.ref->val; |
222 |
|
return php_get_value(next); |
|
|
225 |
|
return python_get_value(next); |
223 |
226 |
case 12: |
case 12: |
224 |
227 |
next = z->value.zv; |
next = z->value.zv; |
225 |
|
return php_get_value(next); |
|
|
228 |
|
return python_get_value(next); |
226 |
229 |
default: |
default: |
227 |
230 |
snprintf(ret, sizeof(ret), "?%hhu: %p", |
snprintf(ret, sizeof(ret), "?%hhu: %p", |
228 |
231 |
z->u1.v.type, z->value.str); return ret; |
z->u1.v.type, z->value.str); return ret; |
229 |
232 |
} |
} |
230 |
233 |
} |
} |
231 |
234 |
|
|
232 |
|
static char *php_get_type(const struct zval *z) |
|
|
235 |
|
static char *python_get_type(const struct zval *z) |
233 |
236 |
{ |
{ |
234 |
237 |
static char s[8]; |
static char s[8]; |
235 |
238 |
|
|
|
... |
... |
static char *php_get_type(const struct zval *z) |
253 |
256 |
} |
} |
254 |
257 |
} |
} |
255 |
258 |
|
|
256 |
|
static void php_zval_dump_buf(char *buf, const size_t size, |
|
|
259 |
|
static void python_zval_dump_buf(char *buf, const size_t size, |
257 |
260 |
const char *prefix, const struct zval *z) |
const char *prefix, const struct zval *z) |
258 |
261 |
{ |
{ |
259 |
262 |
if (!z) { |
if (!z) { |
|
... |
... |
static void php_zval_dump_buf(char *buf, const size_t size, |
262 |
265 |
} |
} |
263 |
266 |
|
|
264 |
267 |
snprintf(buf, size, "%s%p: type=%s value=[%s] type_flags=%hhu extra=%hu num_args=%u", |
snprintf(buf, size, "%s%p: type=%s value=[%s] type_flags=%hhu extra=%hu num_args=%u", |
265 |
|
prefix, z, php_get_type(z), php_get_value(z), |
|
|
268 |
|
prefix, z, python_get_type(z), python_get_value(z), |
266 |
269 |
z->u1.v.type_flags, |
z->u1.v.type_flags, |
267 |
270 |
z->u1.v.u.extra, z->u2.num_args); |
z->u1.v.u.extra, z->u2.num_args); |
268 |
271 |
} |
} |
269 |
272 |
|
|
270 |
|
static void php_zval_dump(const char *prefix, const struct zval *z) |
|
|
273 |
|
static void python_zval_dump(const char *prefix, const struct zval *z) |
271 |
274 |
{ |
{ |
272 |
275 |
char s[4096]; |
char s[4096]; |
273 |
276 |
|
|
274 |
|
php_zval_dump_buf(s, sizeof(s), prefix, z); |
|
|
277 |
|
python_zval_dump_buf(s, sizeof(s), prefix, z); |
275 |
278 |
xlog(100, "%s\n", s); |
xlog(100, "%s\n", s); |
276 |
279 |
} |
} |
277 |
280 |
|
|
278 |
|
static void php_zed_dump(const char *prefix, struct zend_execute_data *p) |
|
|
281 |
|
static void python_zed_dump(const char *prefix, struct zend_execute_data *p) |
279 |
282 |
{ |
{ |
280 |
283 |
unsigned int num_args, s, i; |
unsigned int num_args, s, i; |
281 |
284 |
struct zval *z; |
struct zval *z; |
|
... |
... |
static void php_zed_dump(const char *prefix, struct zend_execute_data *p) |
292 |
295 |
|
|
293 |
296 |
xlog(100, "%szed: p=%p num_args=%hu return_value=%p\n", |
xlog(100, "%szed: p=%p num_args=%hu return_value=%p\n", |
294 |
297 |
prefix, p, num_args, p->return_value); |
prefix, p, num_args, p->return_value); |
295 |
|
//php_zval_dump(prefix, p->return_value); |
|
|
298 |
|
//python_zval_dump(prefix, p->return_value); |
296 |
299 |
snprintf(x, sizeof(x), "%s This: ", prefix); |
snprintf(x, sizeof(x), "%s This: ", prefix); |
297 |
|
php_zval_dump(x, &p->This); |
|
|
300 |
|
python_zval_dump(x, &p->This); |
298 |
301 |
|
|
299 |
302 |
for (i = 0; i < num_args; i++) { |
for (i = 0; i < num_args; i++) { |
300 |
303 |
char zs[1024]; |
char zs[1024]; |
301 |
304 |
|
|
302 |
305 |
z = (struct zval *) p + s; s++; |
z = (struct zval *) p + s; s++; |
303 |
|
php_zval_dump_buf(zs, sizeof(zs), "", z); |
|
|
306 |
|
python_zval_dump_buf(zs, sizeof(zs), "", z); |
304 |
307 |
xlog(100, "%s para %u: %s\n", prefix, i, zs); |
xlog(100, "%s para %u: %s\n", prefix, i, zs); |
305 |
308 |
} |
} |
306 |
309 |
} |
} |
307 |
310 |
|
|
308 |
|
void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *); |
|
|
311 |
|
static void zend_array_to_params_array(struct query *q, struct zend_array *za) |
|
312 |
|
{ |
|
313 |
|
unsigned int i = 0, max; |
|
314 |
|
|
|
315 |
|
xlog(100, " nTableMask=0x%x nNumUsed=%u nNumOfElements=%u nTableSize=%u" |
|
316 |
|
" nInternalPointer=%u flags=0x%x[%s]\n", |
|
317 |
|
za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize, |
|
318 |
|
za->nInternalPointer, za->u.flags, za->u.flags & 4 ? "packed" : ""); |
|
319 |
|
|
|
320 |
|
max = za->nNumUsed; |
|
321 |
|
if (max > ND_PARAMS_MAX) |
|
322 |
|
max = ND_PARAMS_MAX; |
|
323 |
|
|
|
324 |
|
struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed; |
|
325 |
|
for (; bs != be; bs++) { |
|
326 |
|
struct zval *_z = &bs->val; |
|
327 |
|
|
|
328 |
|
if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT |
|
329 |
|
_z = _z->value.zv; |
|
330 |
|
|
|
331 |
|
if (_z->u1.v.type == 0 /*IS_UNDEF*/) { |
|
332 |
|
xlog(101, " para h=%lu: type undef\n", bs->h); |
|
333 |
|
continue; |
|
334 |
|
} |
|
335 |
|
|
|
336 |
|
if (_z->u1.v.type == 10) { // REFERENCE |
|
337 |
|
xlog(101, " is a reference!\n"); |
|
338 |
|
_z = &_z->value.ref->val; |
|
339 |
|
} |
|
340 |
|
|
|
341 |
|
struct zend_string *zs = bs->key; |
|
342 |
|
xlog(101, " para: bs=%p h=%lu key=[%p] type %s: val: %s\n", |
|
343 |
|
bs, bs->h, zs, python_get_type(_z), python_get_value(_z)); |
|
344 |
|
|
|
345 |
|
if (_z->u1.v.type == 4) { |
|
346 |
|
q->params[i].type = ND_PARAMS_TYPE_LONG; |
|
347 |
|
q->params[i].l = _z->value.lval; |
|
348 |
|
} else if (_z->u1.v.type == 5) { |
|
349 |
|
q->params[i].type = ND_PARAMS_TYPE_DOUBLE; |
|
350 |
|
q->params[i].d = _z->value.dval; |
|
351 |
|
} else if (_z->u1.v.type == 6) { |
|
352 |
|
q->params[i].type = ND_PARAMS_TYPE_STRING; |
|
353 |
|
struct zend_string *zs = _z->value.str; |
|
354 |
|
q->params[i].str = zs->val; |
|
355 |
|
q->params[i].length = zs->len; |
|
356 |
|
} |
|
357 |
|
|
|
358 |
|
i++; |
|
359 |
|
if (i == max) |
|
360 |
|
break; |
|
361 |
|
} |
|
362 |
|
|
|
363 |
|
q->params_len = za->nNumUsed; |
|
364 |
|
} |
|
365 |
|
|
|
366 |
|
void *(*old_python_pg_last_error)(struct zend_execute_data *, struct zval *); |
309 |
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) |
310 |
368 |
{ |
{ |
311 |
369 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv) |
315 |
373 |
xlog(1, "%s: e=%p num_args=%hu\n", |
xlog(1, "%s: e=%p num_args=%hu\n", |
316 |
374 |
__func__, e, num_args); |
__func__, e, num_args); |
317 |
375 |
|
|
318 |
|
ret = old_pg_last_error(e, retv); |
|
|
376 |
|
ret = old_python_pg_last_error(e, retv); |
319 |
377 |
if (!retv) |
if (!retv) |
320 |
378 |
return ret; |
return ret; |
321 |
379 |
|
|
322 |
|
//php_zval_dump(" retv: ", retv); |
|
|
380 |
|
//python_zval_dump(" retv: ", retv); |
323 |
381 |
|
|
324 |
382 |
return ret; |
return ret; |
325 |
383 |
} |
} |
326 |
384 |
|
|
327 |
|
void *(*old_pg_connect)(struct zend_execute_data *, struct zval *); |
|
|
385 |
|
void *(*old_python_pg_close)(struct zend_execute_data *, struct zval *); |
|
386 |
|
static void *my_pg_close(struct zend_execute_data *e, struct zval *retv) |
|
387 |
|
{ |
|
388 |
|
void *ret; |
|
389 |
|
unsigned int num_args, s; |
|
390 |
|
struct zval *z; |
|
391 |
|
struct conn cs; |
|
392 |
|
|
|
393 |
|
num_args = e->This.u2.num_args; |
|
394 |
|
//xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
395 |
|
|
|
396 |
|
cs.type = 'P'; |
|
397 |
|
if (num_args == 1) { |
|
398 |
|
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
399 |
|
// handler, may be null |
|
400 |
|
z = (struct zval *) e + s; s++; |
|
401 |
|
cs.dbh = z->value.p; |
|
402 |
|
//xlog(101, " h=%p\n", cs.dbh); |
|
403 |
|
} else { |
|
404 |
|
cs.dbh = NULL; |
|
405 |
|
} |
|
406 |
|
|
|
407 |
|
ret = old_python_pg_close(e, retv); |
|
408 |
|
ninedogs_process_db("pg_close", NINEDOGS_DB_CONN_CLOSE, &cs); |
|
409 |
|
|
|
410 |
|
return ret; |
|
411 |
|
} |
|
412 |
|
|
|
413 |
|
void *(*old_python_pg_connect)(struct zend_execute_data *, struct zval *); |
328 |
414 |
static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) |
329 |
415 |
{ |
{ |
330 |
416 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) |
334 |
420 |
struct conn cs; |
struct conn cs; |
335 |
421 |
|
|
336 |
422 |
num_args = e->This.u2.num_args; |
num_args = e->This.u2.num_args; |
337 |
|
xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
|
423 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
338 |
424 |
|
|
339 |
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); |
340 |
426 |
cs.type = 'P'; |
cs.type = 'P'; |
|
... |
... |
static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) |
344 |
430 |
q = z->value.str; |
q = z->value.str; |
345 |
431 |
cs.conn_str = q->val; |
cs.conn_str = q->val; |
346 |
432 |
cs.conn_str_len = q->len; |
cs.conn_str_len = q->len; |
347 |
|
xlog(50, " conn: %s\n", cs.conn_str); |
|
|
433 |
|
//xlog(50, " conn[%u]: %s\n", cs.conn_str_len, cs.conn_str); |
348 |
434 |
|
|
349 |
|
ninedogs_now(&cs.start); |
|
350 |
|
ret = old_pg_connect(e, retv); |
|
351 |
|
if (!retv) |
|
|
435 |
|
ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_START, &cs); |
|
436 |
|
ret = old_python_pg_connect(e, retv); |
|
437 |
|
if (!retv) { |
|
438 |
|
xlog(0, "DEBUG: old_python_pg_connect returned retv NULL\n"); |
352 |
439 |
return ret; |
return ret; |
353 |
|
ninedogs_now(&cs.end); |
|
|
440 |
|
} |
354 |
441 |
|
|
355 |
|
//php_zval_dump(" retv: ", retv); |
|
|
442 |
|
python_zval_dump(" retv: ", retv); |
356 |
443 |
// TODO: how to test for error? if (core_globals.last_error_message) { |
// TODO: how to test for error? if (core_globals.last_error_message) { |
357 |
444 |
|
|
358 |
|
// PHP7 returns resource, PHP8.1 returns object |
|
359 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { |
|
|
445 |
|
// python7 returns resource, python8.1 returns object |
|
446 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) |
360 |
447 |
cs.dbh = retv->value.p; |
cs.dbh = retv->value.p; |
361 |
|
ninedogs_process_db(NINEDOGS_DB_CONN, &cs); |
|
362 |
|
} |
|
|
448 |
|
else |
|
449 |
|
cs.dbh = NULL; |
|
450 |
|
ninedogs_process_db("pg_connect", NINEDOGS_DB_CONN_END, &cs); |
363 |
451 |
|
|
364 |
452 |
return ret; |
return ret; |
365 |
453 |
} |
} |
366 |
454 |
|
|
367 |
|
void *(*old_pg_pconnect)(struct zend_execute_data *, struct zval *); |
|
|
455 |
|
void *(*old_python_pg_pconnect)(struct zend_execute_data *, struct zval *); |
368 |
456 |
static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv) |
369 |
457 |
{ |
{ |
370 |
458 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv) |
386 |
474 |
cs.conn_str_len = q->len; |
cs.conn_str_len = q->len; |
387 |
475 |
xlog(50, " conn: %s\n", cs.conn_str); |
xlog(50, " conn: %s\n", cs.conn_str); |
388 |
476 |
|
|
389 |
|
ninedogs_now(&cs.start); |
|
390 |
|
ret = old_pg_pconnect(e, retv); |
|
|
477 |
|
ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_START, &cs); |
|
478 |
|
ret = old_python_pg_pconnect(e, retv); |
391 |
479 |
if (!retv) |
if (!retv) |
392 |
480 |
return ret; |
return ret; |
393 |
|
ninedogs_now(&cs.end); |
|
394 |
481 |
|
|
395 |
|
//php_zval_dump(" retv: ", retv); |
|
|
482 |
|
python_zval_dump(" retv: ", retv); |
396 |
483 |
// TODO: how to test for error? if (core_globals.last_error_message) { |
// TODO: how to test for error? if (core_globals.last_error_message) { |
397 |
484 |
|
|
398 |
|
// PHP7 returns resource, PHP8.1 returns object |
|
399 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { |
|
|
485 |
|
// python7 returns resource, python8.1 returns object |
|
486 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) |
400 |
487 |
cs.dbh = retv->value.p; |
cs.dbh = retv->value.p; |
401 |
|
ninedogs_process_db(NINEDOGS_DB_CONN, &cs); |
|
402 |
|
} |
|
|
488 |
|
else |
|
489 |
|
cs.dbh = NULL; |
|
490 |
|
ninedogs_process_db("pg_pconnect", NINEDOGS_DB_CONN_END, &cs); |
403 |
491 |
|
|
404 |
492 |
return ret; |
return ret; |
405 |
493 |
} |
} |
406 |
494 |
|
|
407 |
|
void *(*old_pg_affected_rows)(struct zend_execute_data *, struct zval *); |
|
|
495 |
|
void *(*old_python_pg_affected_rows)(struct zend_execute_data *, struct zval *); |
408 |
496 |
|
|
409 |
|
void *(*old_pg_free_result)(struct zend_execute_data *, struct zval *); |
|
|
497 |
|
void *(*old_python_pg_free_result)(struct zend_execute_data *, struct zval *); |
410 |
498 |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
411 |
499 |
{ |
{ |
412 |
500 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
414 |
502 |
struct free_result fr; |
struct free_result fr; |
415 |
503 |
|
|
416 |
504 |
unsigned int num_args = e->This.u2.num_args; |
unsigned int num_args = e->This.u2.num_args; |
417 |
|
xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
418 |
|
//php_zed_dump(" e: ", e); |
|
419 |
|
//php_zval_dump(" retv: ", retv); |
|
|
505 |
|
xlog(200, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
506 |
|
//python_zed_dump(" e: ", e); |
|
507 |
|
//python_zval_dump(" retv: ", retv); |
420 |
508 |
|
|
421 |
509 |
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); |
422 |
510 |
struct zval *z = (struct zval *) e + s; |
struct zval *z = (struct zval *) e + s; |
|
... |
... |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
424 |
512 |
fr.type = 'P'; |
fr.type = 'P'; |
425 |
513 |
fr.res = z->value.p; |
fr.res = z->value.p; |
426 |
514 |
|
|
427 |
|
ret = old_pg_free_result(e, retv); // ret will be NULL! |
|
|
515 |
|
ret = old_python_pg_free_result(e, retv); // ret will be NULL! |
428 |
516 |
// 'ret' is null here |
// 'ret' is null here |
429 |
517 |
|
|
430 |
518 |
if (retv->u1.v.type == 3) { // true |
if (retv->u1.v.type == 3) { // true |
|
... |
... |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
434 |
522 |
fr.ok = 0; |
fr.ok = 0; |
435 |
523 |
} |
} |
436 |
524 |
|
|
437 |
|
ninedogs_process_db(NINEDOGS_DB_FREE_RESULT, &fr); |
|
|
525 |
|
ninedogs_process_db("pg_free_result", NINEDOGS_DB_FREE_RESULT, &fr); |
438 |
526 |
|
|
439 |
527 |
return ret; |
return ret; |
440 |
528 |
} |
} |
441 |
529 |
|
|
442 |
|
void *(*old_pg_num_rows)(struct zend_execute_data *, struct zval *); |
|
|
530 |
|
void *(*old_python_pg_num_rows)(struct zend_execute_data *, struct zval *); |
443 |
531 |
static void *my_pg_num_rows(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_num_rows(struct zend_execute_data *e, struct zval *retv) |
444 |
532 |
{ |
{ |
445 |
533 |
void *ret; |
void *ret; |
446 |
534 |
|
|
447 |
535 |
//unsigned int num_args = e->This.u2.num_args; |
//unsigned int num_args = e->This.u2.num_args; |
448 |
536 |
//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); |
449 |
|
//php_zed_dump(" e: ", e); |
|
450 |
|
//php_zval_dump(" retv: ", retv); |
|
|
537 |
|
//python_zed_dump(" e: ", e); |
|
538 |
|
//python_zval_dump(" retv: ", retv); |
451 |
539 |
|
|
452 |
|
ret = old_pg_num_rows(e, retv); |
|
|
540 |
|
ret = old_python_pg_num_rows(e, retv); |
453 |
541 |
if (!retv) |
if (!retv) |
454 |
542 |
return ret; |
return ret; |
455 |
543 |
|
|
456 |
|
//php_zval_dump(" retv: ", retv); |
|
|
544 |
|
//python_zval_dump(" retv: ", retv); |
457 |
545 |
|
|
458 |
546 |
return ret; |
return ret; |
459 |
547 |
} |
} |
460 |
548 |
|
|
461 |
|
static void php_set_para(struct zend_execute_data *e, const unsigned int i, |
|
|
549 |
|
static void python_set_para(struct zend_execute_data *e, const unsigned int i, |
462 |
550 |
const struct zval *para) |
const struct zval *para) |
463 |
551 |
{ |
{ |
464 |
552 |
unsigned int s; |
unsigned int s; |
|
... |
... |
static void php_set_para(struct zend_execute_data *e, const unsigned int i, |
469 |
557 |
memcpy(dst, para, sizeof(struct zval)); |
memcpy(dst, para, sizeof(struct zval)); |
470 |
558 |
} |
} |
471 |
559 |
|
|
472 |
|
static void php_set_last_error(struct zend_execute_data *e, |
|
|
560 |
|
static void python_set_last_error(struct zend_execute_data *e, |
473 |
561 |
struct zval *dbh, struct query *q) |
struct zval *dbh, struct query *q) |
474 |
562 |
{ |
{ |
475 |
563 |
struct zval rz; |
struct zval rz; |
476 |
564 |
|
|
477 |
565 |
e->This.u2.num_args = dbh ? 1 : 0; |
e->This.u2.num_args = dbh ? 1 : 0; |
478 |
566 |
if (dbh) |
if (dbh) |
479 |
|
php_set_para(e, 0, dbh); |
|
|
567 |
|
python_set_para(e, 0, dbh); |
480 |
568 |
|
|
481 |
569 |
// TODO: we need also the numeric representation of the error! |
// TODO: we need also the numeric representation of the error! |
482 |
570 |
xlog(50, " calling pg_last_error...\n"); |
xlog(50, " calling pg_last_error...\n"); |
483 |
|
old_pg_last_error(e, &rz); |
|
|
571 |
|
old_python_pg_last_error(e, &rz); |
484 |
572 |
//xlog(1, " pg_last_error returned %p; type=%s value=%s\n", |
//xlog(1, " pg_last_error returned %p; type=%s value=%s\n", |
485 |
|
// tr, php_get_type(&rz), php_get_value(&rz)); |
|
|
573 |
|
// tr, python_get_type(&rz), python_get_value(&rz)); |
486 |
574 |
|
|
487 |
575 |
if (rz.u1.v.type == 6) { // string |
if (rz.u1.v.type == 6) { // string |
488 |
576 |
q->err = rz.value.str->val; |
q->err = rz.value.str->val; |
|
... |
... |
static void php_set_last_error(struct zend_execute_data *e, |
494 |
582 |
} |
} |
495 |
583 |
} |
} |
496 |
584 |
|
|
497 |
|
static void php_set_num_aff(struct zend_execute_data *e, struct zval *res, |
|
|
585 |
|
static void python_set_num_aff(struct zend_execute_data *e, struct zval *res, |
498 |
586 |
struct query *q) |
struct query *q) |
499 |
587 |
{ |
{ |
500 |
588 |
struct zval rz; |
struct zval rz; |
501 |
589 |
|
|
502 |
590 |
e->This.u2.num_args = 1; |
e->This.u2.num_args = 1; |
503 |
591 |
|
|
504 |
|
php_set_para(e, 0, res); |
|
|
592 |
|
python_set_para(e, 0, res); |
505 |
593 |
|
|
506 |
594 |
//xlog(1, " calling old pg_num_rows...\n"); |
//xlog(1, " calling old pg_num_rows...\n"); |
507 |
|
//php_zed_dump(" e: ", e); |
|
508 |
|
old_pg_num_rows(e, &rz); |
|
509 |
|
//php_zval_dump(" rz: ", &rz); |
|
|
595 |
|
//python_zed_dump(" e: ", e); |
|
596 |
|
old_python_pg_num_rows(e, &rz); |
|
597 |
|
//python_zval_dump(" rz: ", &rz); |
510 |
598 |
q->num = rz.value.lval; |
q->num = rz.value.lval; |
511 |
599 |
|
|
512 |
600 |
//xlog(1, " calling old pg_affected_rows...\n"); |
//xlog(1, " calling old pg_affected_rows...\n"); |
513 |
|
//php_zed_dump(" e: ", e); |
|
514 |
|
old_pg_affected_rows(e, &rz); |
|
515 |
|
//php_zval_dump(" rz: ", &rz); |
|
|
601 |
|
//python_zed_dump(" e: ", e); |
|
602 |
|
old_python_pg_affected_rows(e, &rz); |
|
603 |
|
//python_zval_dump(" rz: ", &rz); |
516 |
604 |
q->aff = rz.value.lval; |
q->aff = rz.value.lval; |
517 |
605 |
} |
} |
518 |
606 |
|
|
519 |
|
void *(*old_pg_query)(struct zend_execute_data *, struct zval *); |
|
|
607 |
|
void *(*old_python_pg_query)(struct zend_execute_data *, struct zval *); |
520 |
608 |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
521 |
609 |
{ |
{ |
522 |
610 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
533 |
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); |
534 |
622 |
para = (struct zval *) e + s; |
para = (struct zval *) e + s; |
535 |
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 |
|
624 |
|
qs.params_len = 0; |
536 |
625 |
|
|
537 |
626 |
if (num_args == 2) { |
if (num_args == 2) { |
538 |
627 |
// link |
// link |
539 |
628 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
540 |
|
//php_zval_dump(" dbh: ", z); |
|
|
629 |
|
//python_zval_dump(" dbh: ", z); |
541 |
630 |
qs.dbh = z->value.p; |
qs.dbh = z->value.p; |
542 |
631 |
} else { |
} else { |
543 |
632 |
qs.dbh = NULL; |
qs.dbh = NULL; |
|
... |
... |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
550 |
639 |
qs.q = q->val; |
qs.q = q->val; |
551 |
640 |
qs.q_len = q->len; |
qs.q_len = q->len; |
552 |
641 |
|
|
553 |
|
ninedogs_now(&qs.start); |
|
554 |
|
ret = old_pg_query(e, retv); |
|
|
642 |
|
ninedogs_process_db("pg_query", NINEDOGS_DB_QUERY_START, &qs); |
|
643 |
|
ret = old_python_pg_query(e, retv); |
555 |
644 |
if (!retv) |
if (!retv) |
556 |
645 |
return ret; |
return ret; |
557 |
|
ninedogs_now(&qs.end); |
|
558 |
646 |
|
|
559 |
647 |
xlog(100, " old %s returned type=%s value=%s\n", |
xlog(100, " old %s returned type=%s value=%s\n", |
560 |
|
__func__, php_get_type(retv), php_get_value(retv)); |
|
|
648 |
|
__func__, python_get_type(retv), python_get_value(retv)); |
561 |
649 |
|
|
562 |
650 |
copy_num_args = num_args; |
copy_num_args = num_args; |
563 |
651 |
memcpy(©_para, para, sizeof(struct zval)); |
memcpy(©_para, para, sizeof(struct zval)); |
564 |
652 |
|
|
565 |
653 |
if (retv->u1.v.type == 2) { // false |
if (retv->u1.v.type == 2) { // false |
566 |
|
php_set_last_error(e, dbh, &qs); |
|
|
654 |
|
python_set_last_error(e, dbh, &qs); // TODO is qs.res set here? |
567 |
655 |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
568 |
656 |
qs.res = retv->value.str; |
qs.res = retv->value.str; |
569 |
|
php_set_num_aff(e, retv, &qs); |
|
|
657 |
|
python_set_num_aff(e, retv, &qs); |
570 |
658 |
do_restore = 1; |
do_restore = 1; |
571 |
659 |
} |
} |
572 |
660 |
|
|
|
... |
... |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
574 |
662 |
if (do_restore) |
if (do_restore) |
575 |
663 |
memcpy(para, ©_para, sizeof(struct zval)); |
memcpy(para, ©_para, sizeof(struct zval)); |
576 |
664 |
|
|
577 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
665 |
|
ninedogs_process_db("pg_query", NINEDOGS_DB_QUERY_END, &qs); |
578 |
666 |
|
|
579 |
667 |
return ret; |
return ret; |
580 |
668 |
} |
} |
581 |
669 |
|
|
582 |
|
void *(*old_pg_send_query)(struct zend_execute_data *, struct zval *); |
|
|
670 |
|
void *(*old_python_pg_send_query)(struct zend_execute_data *, struct zval *); |
583 |
671 |
static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv) |
584 |
672 |
{ |
{ |
585 |
673 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv) |
593 |
681 |
|
|
594 |
682 |
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); |
595 |
683 |
qs.type = 'P'; |
qs.type = 'P'; |
|
684 |
|
qs.params_len = 0; |
596 |
685 |
|
|
597 |
686 |
// link |
// link |
598 |
687 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
599 |
|
php_zval_dump(" dbh: ", z); |
|
|
688 |
|
python_zval_dump(" dbh: ", z); |
600 |
689 |
qs.dbh = z->value.p; |
qs.dbh = z->value.p; |
601 |
690 |
|
|
602 |
691 |
// query |
// query |
|
... |
... |
static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv) |
606 |
695 |
qs.q_len = q->len; |
qs.q_len = q->len; |
607 |
696 |
xlog(100, " query=%s\n", qs.q); |
xlog(100, " query=%s\n", qs.q); |
608 |
697 |
|
|
609 |
|
ninedogs_now(&qs.start); |
|
610 |
|
ret = old_pg_send_query(e, retv); |
|
|
698 |
|
ninedogs_process_db("pg_send_query", NINEDOGS_DB_QUERY_START, &qs); |
|
699 |
|
ret = old_python_pg_send_query(e, retv); |
611 |
700 |
if (!retv) |
if (!retv) |
612 |
701 |
return ret; |
return ret; |
613 |
|
ninedogs_now(&qs.end); |
|
614 |
702 |
|
|
615 |
|
xlog(1, " old %s returned type=%s value=%s\n", |
|
616 |
|
__func__, php_get_type(retv), php_get_value(retv)); |
|
|
703 |
|
xlog(101, " old %s returned type=%s value=%s\n", |
|
704 |
|
__func__, python_get_type(retv), python_get_value(retv)); |
617 |
705 |
|
|
618 |
706 |
qs.res = NULL; |
qs.res = NULL; |
619 |
707 |
if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int |
if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int |
620 |
|
php_set_last_error(e, dbh, &qs); |
|
|
708 |
|
python_set_last_error(e, dbh, &qs); |
621 |
709 |
} else if (retv->u1.v.type == 3) { // true = success |
} else if (retv->u1.v.type == 3) { // true = success |
622 |
710 |
qs.num = qs.aff = 0; |
qs.num = qs.aff = 0; |
|
711 |
|
qs.res = (void *) 1; // signal ok |
623 |
712 |
} |
} |
624 |
713 |
|
|
625 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
714 |
|
ninedogs_process_db("pg_send_query", NINEDOGS_DB_QUERY_END, &qs); |
626 |
715 |
|
|
627 |
716 |
return ret; |
return ret; |
628 |
717 |
} |
} |
629 |
718 |
|
|
630 |
|
// TODO: not clear if on PHP 7 the parameter could be null |
|
631 |
|
void *(*old_pg_get_result)(struct zend_execute_data *, struct zval *); |
|
|
719 |
|
// TODO: not clear if on python 7 the parameter could be null |
|
720 |
|
void *(*old_python_pg_get_result)(struct zend_execute_data *, struct zval *); |
632 |
721 |
static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) |
633 |
722 |
{ |
{ |
634 |
723 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) |
644 |
733 |
para = (struct zval *) e + s; |
para = (struct zval *) e + s; |
645 |
734 |
qs.type = 'P'; |
qs.type = 'P'; |
646 |
735 |
qs.q = NULL; |
qs.q = NULL; |
|
736 |
|
qs.params_len = 0; |
647 |
737 |
|
|
648 |
738 |
// link |
// link |
649 |
739 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
650 |
|
//php_zval_dump(" dbh: ", z); |
|
|
740 |
|
//python_zval_dump(" dbh: ", z); |
651 |
741 |
qs.dbh = z->value.p; |
qs.dbh = z->value.p; |
652 |
742 |
|
|
653 |
|
ninedogs_now(&qs.start); |
|
654 |
|
ret = old_pg_get_result(e, retv); |
|
|
743 |
|
ninedogs_process_db("pg_get_result", NINEDOGS_DB_QUERY_START, &qs); |
|
744 |
|
ret = old_python_pg_get_result(e, retv); |
655 |
745 |
if (!retv) |
if (!retv) |
656 |
746 |
return ret; |
return ret; |
657 |
|
ninedogs_now(&qs.end); |
|
658 |
747 |
|
|
659 |
748 |
xlog(100, " old %s returned type=%s value=%s\n", |
xlog(100, " old %s returned type=%s value=%s\n", |
660 |
|
__func__, php_get_type(retv), php_get_value(retv)); |
|
|
749 |
|
__func__, python_get_type(retv), python_get_value(retv)); |
661 |
750 |
|
|
662 |
751 |
copy_num_args = num_args; |
copy_num_args = num_args; |
663 |
752 |
memcpy(©_para, para, sizeof(struct zval)); |
memcpy(©_para, para, sizeof(struct zval)); |
664 |
753 |
|
|
665 |
754 |
if (retv->u1.v.type == 2) { // false |
if (retv->u1.v.type == 2) { // false |
666 |
|
php_set_last_error(e, dbh, &qs); |
|
|
755 |
|
python_set_last_error(e, dbh, &qs); |
667 |
756 |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
668 |
757 |
qs.err = NULL; |
qs.err = NULL; |
669 |
758 |
qs.res = retv->value.str; |
qs.res = retv->value.str; |
670 |
|
php_set_num_aff(e, retv, &qs); |
|
|
759 |
|
python_set_num_aff(e, retv, &qs); |
671 |
760 |
do_restore = 1; |
do_restore = 1; |
672 |
761 |
} |
} |
673 |
762 |
|
|
|
... |
... |
static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) |
675 |
764 |
if (do_restore) |
if (do_restore) |
676 |
765 |
memcpy(para, ©_para, sizeof(struct zval)); |
memcpy(para, ©_para, sizeof(struct zval)); |
677 |
766 |
|
|
678 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
767 |
|
ninedogs_process_db("pg_get_result", NINEDOGS_DB_QUERY_END, &qs); |
679 |
768 |
|
|
680 |
769 |
return ret; |
return ret; |
681 |
770 |
} |
} |
682 |
771 |
|
|
683 |
|
void *(*old_pg_query_params)(struct zend_execute_data *, struct zval *); |
|
|
772 |
|
void *(*old_python_pg_query_params)(struct zend_execute_data *, struct zval *); |
684 |
773 |
static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) |
685 |
774 |
{ |
{ |
686 |
775 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) |
693 |
782 |
struct query qs; |
struct query qs; |
694 |
783 |
|
|
695 |
784 |
num_args = e->This.u2.num_args; |
num_args = e->This.u2.num_args; |
696 |
|
//xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
697 |
|
//php_zed_dump(" e0: ", e); |
|
698 |
|
//php_zval_dump(" retv0: ", retv); |
|
|
785 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
786 |
|
//python_zed_dump(" e0: ", e); |
|
787 |
|
//python_zval_dump(" retv0: ", retv); |
699 |
788 |
|
|
700 |
789 |
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); |
701 |
790 |
para = (struct zval *) e + s; |
para = (struct zval *) e + s; |
|
... |
... |
static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) |
717 |
806 |
|
|
718 |
807 |
// params (array) |
// params (array) |
719 |
808 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
720 |
|
#if 1 |
|
721 |
|
struct zend_array *za; |
|
722 |
|
za = z->value.arr; |
|
723 |
|
xlog(200, " nTableMask=%u nNumUsed=%u nNumOfElements=%u nTableSize=%u nInternalPointer=%u\n", |
|
724 |
|
za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize, za->nInternalPointer); |
|
725 |
|
|
|
726 |
|
struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed; |
|
727 |
|
unsigned int i = 1; |
|
728 |
|
for (; bs != be; bs++) { |
|
729 |
|
struct zval *_z = &bs->val; |
|
730 |
|
|
|
731 |
|
if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT |
|
732 |
|
_z = _z->value.zv; |
|
733 |
|
|
|
734 |
|
if (_z->u1.v.type == 0 /*IS_UNDEF*/) continue; |
|
735 |
|
|
|
736 |
|
if (_z->u1.v.type == 10) { // REFERENCE |
|
737 |
|
xlog(1, " is a reference!\n"); |
|
738 |
|
_z = &_z->value.ref->val; |
|
739 |
|
} |
|
|
809 |
|
struct zend_array *za = z->value.arr; |
|
810 |
|
zend_array_to_params_array(&qs, za); |
740 |
811 |
|
|
741 |
|
xlog(200, " para %u: type %s: val: %s\n", |
|
742 |
|
i, php_get_type(_z), php_get_value(_z)); |
|
743 |
|
i++; |
|
744 |
|
} |
|
745 |
|
#endif |
|
746 |
|
|
|
747 |
|
ninedogs_now(&qs.start); |
|
748 |
|
ret = old_pg_query_params(e, retv); |
|
749 |
|
ninedogs_now(&qs.end); |
|
|
812 |
|
ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_START, &qs); |
|
813 |
|
ret = old_python_pg_query_params(e, retv); |
750 |
814 |
//xlog(200, " old %s: type=%s value=%s\n", |
//xlog(200, " old %s: type=%s value=%s\n", |
751 |
|
// __func__, php_get_type(retv), php_get_value(retv)); |
|
752 |
|
//php_zed_dump(" e1: ", e); |
|
753 |
|
//php_zval_dump(" retv1 after calling old func: ", retv); |
|
|
815 |
|
// __func__, python_get_type(retv), python_get_value(retv)); |
|
816 |
|
//python_zed_dump(" e1: ", e); |
|
817 |
|
//python_zval_dump(" retv after calling old func: ", retv); |
754 |
818 |
|
|
755 |
819 |
copy_num_args = e->This.u2.num_args; |
copy_num_args = e->This.u2.num_args; |
756 |
820 |
memcpy(©_para, para, sizeof(struct zval)); |
memcpy(©_para, para, sizeof(struct zval)); |
757 |
821 |
|
|
758 |
822 |
if (retv->u1.v.type == 2) { // false |
if (retv->u1.v.type == 2) { // false |
759 |
|
php_set_last_error(e, dbh, &qs); |
|
|
823 |
|
python_set_last_error(e, dbh, &qs); |
760 |
824 |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
761 |
825 |
qs.res = retv->value.str; |
qs.res = retv->value.str; |
762 |
|
php_set_num_aff(e, retv, &qs); |
|
|
826 |
|
python_set_num_aff(e, retv, &qs); |
763 |
827 |
do_restore = 1; |
do_restore = 1; |
764 |
828 |
} |
} |
765 |
829 |
|
|
766 |
|
//php_zval_dump(" retv before ret: ", retv); |
|
|
830 |
|
//python_zval_dump(" retv before ret: ", retv); |
767 |
831 |
|
|
768 |
832 |
e->This.u2.num_args = copy_num_args; |
e->This.u2.num_args = copy_num_args; |
769 |
833 |
if (do_restore) |
if (do_restore) |
770 |
834 |
memcpy(para, ©_para, sizeof(struct zval)); |
memcpy(para, ©_para, sizeof(struct zval)); |
771 |
835 |
|
|
772 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
836 |
|
ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_END, &qs); |
773 |
837 |
|
|
774 |
838 |
return ret; |
return ret; |
775 |
839 |
} |
} |
776 |
840 |
|
|
777 |
|
void *(*old_pg_send_query_params)(struct zend_execute_data *, struct zval *); |
|
|
841 |
|
void *(*old_python_pg_send_query_params)(struct zend_execute_data *, struct zval *); |
778 |
842 |
static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *retv) |
static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *retv) |
779 |
843 |
{ |
{ |
780 |
844 |
void *ret; |
void *ret; |
|
... |
... |
static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *r |
784 |
848 |
struct zend_string *q; |
struct zend_string *q; |
785 |
849 |
struct query qs; |
struct query qs; |
786 |
850 |
|
|
787 |
|
//unsigned int num_args = e->This.u2.num_args; |
|
788 |
|
//xlog(1, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
789 |
|
//php_zed_dump(" e0: ", e); |
|
790 |
|
//php_zval_dump(" retv0: ", retv); |
|
|
851 |
|
unsigned int num_args = e->This.u2.num_args; |
|
852 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
853 |
|
//python_zed_dump(" e0: ", e); |
|
854 |
|
//python_zval_dump(" retv0: ", retv); |
791 |
855 |
|
|
792 |
856 |
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); |
793 |
857 |
qs.type = 'P'; |
qs.type = 'P'; |
|
... |
... |
static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *r |
804 |
868 |
|
|
805 |
869 |
// params (array) |
// params (array) |
806 |
870 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
807 |
|
#if 1 |
|
808 |
|
struct zend_array *za; |
|
809 |
|
za = z->value.arr; |
|
810 |
|
xlog(200, " nTableMask=%u nNumUsed=%u nNumOfElements=%u nTableSize=%u nInternalPointer=%u\n", |
|
811 |
|
za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize, za->nInternalPointer); |
|
|
871 |
|
struct zend_array *za = z->value.arr; |
|
872 |
|
zend_array_to_params_array(&qs, za); |
812 |
873 |
|
|
813 |
|
struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed; |
|
814 |
|
unsigned int i = 1; |
|
815 |
|
for (; bs != be; bs++) { |
|
816 |
|
struct zval *_z = &bs->val; |
|
817 |
|
|
|
818 |
|
if (_z && (_z->u1.v.type == 12)) // 12=IS_INDIRECT |
|
819 |
|
_z = _z->value.zv; |
|
820 |
|
|
|
821 |
|
if (_z->u1.v.type == 0 /*IS_UNDEF*/) continue; |
|
822 |
|
|
|
823 |
|
if (_z->u1.v.type == 10) { // REFERENCE |
|
824 |
|
xlog(1, " is a reference!\n"); |
|
825 |
|
_z = &_z->value.ref->val; |
|
826 |
|
} |
|
827 |
|
|
|
828 |
|
xlog(200, " para %u: type %s: val: %s\n", |
|
829 |
|
i, php_get_type(_z), php_get_value(_z)); |
|
830 |
|
i++; |
|
831 |
|
} |
|
832 |
|
#endif |
|
833 |
|
|
|
834 |
|
ninedogs_now(&qs.start); |
|
835 |
|
ret = old_pg_send_query_params(e, retv); |
|
836 |
|
ninedogs_now(&qs.end); |
|
|
874 |
|
ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_START, &qs); |
|
875 |
|
ret = old_python_pg_send_query_params(e, retv); |
837 |
876 |
//xlog(200, " old %s: type=%s value=%s\n", |
//xlog(200, " old %s: type=%s value=%s\n", |
838 |
|
// __func__, php_get_type(retv), php_get_value(retv)); |
|
839 |
|
//php_zed_dump(" e1: ", e); |
|
840 |
|
//php_zval_dump(" retv1 after calling old func: ", retv); |
|
|
877 |
|
// __func__, python_get_type(retv), python_get_value(retv)); |
|
878 |
|
//python_zed_dump(" e1: ", e); |
|
879 |
|
//python_zval_dump(" retv after calling old func: ", retv); |
841 |
880 |
|
|
842 |
881 |
qs.res = NULL; |
qs.res = NULL; |
843 |
882 |
if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int (probably 0) |
if ((retv->u1.v.type == 2) || (retv->u1.v.type == 4)) { // false or int (probably 0) |
844 |
|
php_set_last_error(e, dbh, &qs); |
|
|
883 |
|
python_set_last_error(e, dbh, &qs); |
845 |
884 |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
} else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource |
846 |
885 |
qs.num = qs.aff = 0; |
qs.num = qs.aff = 0; |
|
886 |
|
qs.res = (void *) 1; // signal ok |
847 |
887 |
} |
} |
848 |
888 |
|
|
849 |
|
ninedogs_process_db(NINEDOGS_DB_QUERY, &qs); |
|
|
889 |
|
ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_END, &qs); |
850 |
890 |
|
|
851 |
891 |
return ret; |
return ret; |
852 |
892 |
} |
} |
853 |
893 |
|
|
854 |
|
struct zend_module_entry *(*old_get_module)(void); |
|
855 |
|
static struct zend_module_entry *php_hook_get_module_func(void) |
|
|
894 |
|
struct zend_module_entry *(*old_python_get_module)(void); |
|
895 |
|
static struct zend_module_entry *python_hook_get_module_func(void) |
856 |
896 |
{ |
{ |
857 |
897 |
struct zend_module_entry *z, *new; |
struct zend_module_entry *z, *new; |
858 |
898 |
struct zend_function_entry *fe; |
struct zend_function_entry *fe; |
859 |
899 |
unsigned int count; |
unsigned int count; |
860 |
900 |
|
|
861 |
|
z = old_get_module(); |
|
|
901 |
|
z = old_python_get_module(); |
862 |
902 |
if (!z) |
if (!z) |
863 |
903 |
return NULL; |
return NULL; |
864 |
904 |
|
|
|
... |
... |
static struct zend_module_entry *php_hook_get_module_func(void) |
896 |
936 |
fe = new->functions; |
fe = new->functions; |
897 |
937 |
while (fe->fname) { |
while (fe->fname) { |
898 |
938 |
//xlog(2, " func %s handler=%p\n", fe->fname, fe->handler); |
//xlog(2, " func %s handler=%p\n", fe->fname, fe->handler); |
899 |
|
if (strcmp(fe->fname, "pg_connect") == 0) { |
|
900 |
|
old_pg_connect = fe->handler; |
|
|
939 |
|
if (strcmp(fe->fname, "pg_close") == 0) { |
|
940 |
|
old_python_pg_close = fe->handler; |
|
941 |
|
fe->handler = my_pg_close; |
|
942 |
|
} else if (strcmp(fe->fname, "pg_connect") == 0) { |
|
943 |
|
old_python_pg_connect = fe->handler; |
901 |
944 |
fe->handler = my_pg_connect; |
fe->handler = my_pg_connect; |
902 |
945 |
} else if (strcmp(fe->fname, "pg_pconnect") == 0) { |
} else if (strcmp(fe->fname, "pg_pconnect") == 0) { |
903 |
|
old_pg_pconnect = fe->handler; |
|
|
946 |
|
old_python_pg_pconnect = fe->handler; |
904 |
947 |
fe->handler = my_pg_pconnect; |
fe->handler = my_pg_pconnect; |
905 |
948 |
} else if (strcmp(fe->fname, "pg_num_rows") == 0) { |
} else if (strcmp(fe->fname, "pg_num_rows") == 0) { |
906 |
|
old_pg_num_rows = fe->handler; |
|
|
949 |
|
old_python_pg_num_rows = fe->handler; |
907 |
950 |
fe->handler = my_pg_num_rows; |
fe->handler = my_pg_num_rows; |
908 |
951 |
} else if (strcmp(fe->fname, "pg_affected_rows") == 0) { |
} else if (strcmp(fe->fname, "pg_affected_rows") == 0) { |
909 |
|
old_pg_affected_rows = fe->handler; |
|
|
952 |
|
old_python_pg_affected_rows = fe->handler; |
910 |
953 |
} else if (strcmp(fe->fname, "pg_free_result") == 0) { |
} else if (strcmp(fe->fname, "pg_free_result") == 0) { |
911 |
|
old_pg_free_result = fe->handler; |
|
|
954 |
|
old_python_pg_free_result = fe->handler; |
912 |
955 |
fe->handler = my_pg_free_result; |
fe->handler = my_pg_free_result; |
913 |
956 |
} else if (strcmp(fe->fname, "pg_query") == 0) { |
} else if (strcmp(fe->fname, "pg_query") == 0) { |
914 |
|
old_pg_query = fe->handler; |
|
|
957 |
|
old_python_pg_query = fe->handler; |
915 |
958 |
fe->handler = my_pg_query; |
fe->handler = my_pg_query; |
916 |
959 |
} else if (strcmp(fe->fname, "pg_send_query") == 0) { |
} else if (strcmp(fe->fname, "pg_send_query") == 0) { |
917 |
|
old_pg_send_query = fe->handler; |
|
|
960 |
|
old_python_pg_send_query = fe->handler; |
918 |
961 |
fe->handler = my_pg_send_query; |
fe->handler = my_pg_send_query; |
919 |
962 |
} else if (strcmp(fe->fname, "pg_query_params") == 0) { |
} else if (strcmp(fe->fname, "pg_query_params") == 0) { |
920 |
|
old_pg_query_params = fe->handler; |
|
|
963 |
|
old_python_pg_query_params = fe->handler; |
921 |
964 |
fe->handler = my_pg_query_params; |
fe->handler = my_pg_query_params; |
922 |
965 |
} else if (strcmp(fe->fname, "pg_send_query_params") == 0) { |
} else if (strcmp(fe->fname, "pg_send_query_params") == 0) { |
923 |
|
old_pg_send_query_params = fe->handler; |
|
|
966 |
|
old_python_pg_send_query_params = fe->handler; |
924 |
967 |
fe->handler = my_pg_send_query_params; |
fe->handler = my_pg_send_query_params; |
925 |
968 |
} else if (strcmp(fe->fname, "pg_last_error") == 0) { |
} else if (strcmp(fe->fname, "pg_last_error") == 0) { |
926 |
|
old_pg_last_error = fe->handler; |
|
|
969 |
|
old_python_pg_last_error = fe->handler; |
927 |
970 |
fe->handler = my_pg_last_error; |
fe->handler = my_pg_last_error; |
928 |
971 |
} else if (strcmp(fe->fname, "pg_get_result") == 0) { |
} else if (strcmp(fe->fname, "pg_get_result") == 0) { |
929 |
|
old_pg_get_result = fe->handler; |
|
|
972 |
|
old_python_pg_get_result = fe->handler; |
930 |
973 |
fe->handler = my_pg_get_result; |
fe->handler = my_pg_get_result; |
931 |
974 |
} else { |
} else { |
932 |
975 |
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
|
... |
... |
static struct zend_module_entry *php_hook_get_module_func(void) |
937 |
980 |
return new; |
return new; |
938 |
981 |
} |
} |
939 |
982 |
|
|
940 |
|
void *php_hook(void *x) |
|
|
983 |
|
static void *(*old_sqlite3)(void); |
|
984 |
|
static void *new_sqlite3(void) |
941 |
985 |
{ |
{ |
942 |
|
old_get_module = x; |
|
943 |
|
return php_hook_get_module_func; |
|
944 |
|
} |
|
|
986 |
|
void *ret; |
945 |
987 |
|
|
946 |
|
typedef struct { |
|
947 |
|
const char *driver_name; |
|
948 |
|
size_t driver_name_len; |
|
949 |
|
unsigned long api_version; |
|
950 |
|
int (*db_handle_factory)(void *dbh, void *driver_options); |
|
951 |
|
} pdo_driver_t; |
|
952 |
|
|
|
953 |
|
#if 0 |
|
954 |
|
pdo_driver_t old, my_driver; |
|
955 |
|
int php_pdo_register_driver(pdo_driver_t *driver) |
|
956 |
|
{ |
|
957 |
|
int r; |
|
958 |
|
|
|
959 |
|
hookup_php(); |
|
960 |
|
|
|
961 |
|
xlog(2, "%s driver=%p name=%s\n", __func__, driver, driver->driver_name); |
|
962 |
|
if (driver) { |
|
963 |
|
if (strcmp(driver->driver_name, "pgsql") == 0) { |
|
964 |
|
xlog(2, " hook db_handle_factory\n"); |
|
965 |
|
memcpy(&my_driver, driver, sizeof(pdo_driver_t)); |
|
966 |
|
old.db_handle_factory = driver->db_handle_factory; |
|
967 |
|
my_driver.db_handle_factory = my_db_handle_factory; |
|
968 |
|
r = old_php_pdo_register_driver(&my_driver); |
|
969 |
|
} else { |
|
970 |
|
xlog(2, " NOT hooking db_handle_factory\n"); |
|
971 |
|
r = old_php_pdo_register_driver(driver); |
|
972 |
|
} |
|
973 |
|
} else { |
|
974 |
|
r = -1; |
|
975 |
|
} |
|
|
988 |
|
xlog(0, "%s\n", __func__); |
|
989 |
|
ret = old_sqlite3(); |
|
990 |
|
|
|
991 |
|
return ret; |
|
992 |
|
} |
976 |
993 |
|
|
977 |
|
return r; |
|
|
994 |
|
static void *python_hook_sqlite3(void *x) |
|
995 |
|
{ |
|
996 |
|
old_sqlite3 = x; |
|
997 |
|
return new_sqlite3; |
978 |
998 |
} |
} |
979 |
999 |
|
|
980 |
|
#endif |
|
|
1000 |
|
void *python_hook(const char *symbol, void *x) |
|
1001 |
|
{ |
|
1002 |
|
xlog(0, "%s: symbol=[%s] x=%p\n", __func__, symbol, x); |
|
1003 |
|
|
|
1004 |
|
if (strcmp(symbol, "PyInit__sqlite3") == 0) |
|
1005 |
|
return python_hook_sqlite3(x); |
981 |
1006 |
|
|
|
1007 |
|
return x; |
|
1008 |
|
} |
File trace/nd-trace.c changed (mode: 100644) (index 8c2ffa7..03197de) |
8 |
8 |
#include <sys/un.h> |
#include <sys/un.h> |
9 |
9 |
|
|
10 |
10 |
#include <arpa/inet.h> |
#include <arpa/inet.h> |
|
11 |
|
#include <dlfcn.h> |
11 |
12 |
#include <errno.h> |
#include <errno.h> |
12 |
13 |
#include <fcntl.h> |
#include <fcntl.h> |
13 |
14 |
#include <getopt.h> |
#include <getopt.h> |
|
... |
... |
static void usage(void) |
43 |
44 |
exit(1); |
exit(1); |
44 |
45 |
} |
} |
45 |
46 |
|
|
46 |
|
static FILE *out; |
|
47 |
|
static char do_exit; |
|
|
47 |
|
static FILE *out; |
|
48 |
|
static unsigned int do_exit; |
48 |
49 |
|
|
49 |
50 |
static uint8_t decode8(unsigned char *d, unsigned int *i) |
static uint8_t decode8(unsigned char *d, unsigned int *i) |
50 |
51 |
{ |
{ |
|
... |
... |
static uint64_t decode64(unsigned char *d, unsigned int *i) |
78 |
79 |
return be64toh(u); |
return be64toh(u); |
79 |
80 |
} |
} |
80 |
81 |
|
|
|
82 |
|
static uint8_t decode_bool(const char *prefix, char *out, size_t out_size, |
|
83 |
|
unsigned char *d, unsigned int *i) |
|
84 |
|
{ |
|
85 |
|
uint8_t v = d[*i]; *i = *i + 1; |
|
86 |
|
snprintf(out, out_size, "%s%s", prefix, v == 0 ? "NOK" : "OK"); |
|
87 |
|
return v; |
|
88 |
|
} |
|
89 |
|
|
81 |
90 |
static char *decode_socket_domain(const int d) |
static char *decode_socket_domain(const int d) |
82 |
91 |
{ |
{ |
83 |
92 |
switch (d) { |
switch (d) { |
|
... |
... |
static socklen_t decode_sockaddr(char *out, unsigned char *d, unsigned int *i) |
241 |
250 |
struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &ss; |
struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &ss; |
242 |
251 |
char addr6[40]; |
char addr6[40]; |
243 |
252 |
inet_ntop(ss.ss_family, &s6->sin6_addr, addr6, sizeof(addr6)); |
inet_ntop(ss.ss_family, &s6->sin6_addr, addr6, sizeof(addr6)); |
244 |
|
sprintf(out, "ipv6/%s/%hu/f%u/s%u", |
|
|
253 |
|
sprintf(out, "ipv6/%s/%hu/flow=%u/scope=%u", |
245 |
254 |
addr6, be16toh(s6->sin6_port), |
addr6, be16toh(s6->sin6_port), |
246 |
255 |
be32toh(s6->sin6_flowinfo), be32toh(s6->sin6_scope_id)); |
be32toh(s6->sin6_flowinfo), be32toh(s6->sin6_scope_id)); |
247 |
256 |
break; |
break; |
|
... |
... |
static void decode_stat(char *out, unsigned out_size, |
566 |
575 |
s.st_mtim.tv_sec, s.st_mtim.tv_nsec, s.st_ctim.tv_sec, s.st_ctim.tv_nsec); |
s.st_mtim.tv_sec, s.st_mtim.tv_nsec, s.st_ctim.tv_sec, s.st_ctim.tv_nsec); |
567 |
576 |
} |
} |
568 |
577 |
|
|
569 |
|
static void decode_func(unsigned char *d) |
|
|
578 |
|
static void decode_string_array(char *out, size_t out_size, |
|
579 |
|
unsigned char *d, unsigned int *i) |
|
580 |
|
{ |
|
581 |
|
size_t rest = out_size; |
|
582 |
|
char *add = ""; |
|
583 |
|
|
|
584 |
|
strcpy(out, ""); |
|
585 |
|
|
|
586 |
|
while (1) { |
|
587 |
|
unsigned short len = decode16(d, i); |
|
588 |
|
if (len == 0) |
|
589 |
|
break; |
|
590 |
|
|
|
591 |
|
char e[len * 4 + 1]; |
|
592 |
|
bin2hex_ascii(e, d + *i, len); *i = *i + len; |
|
593 |
|
|
|
594 |
|
unsigned int e_len = strlen(e); |
|
595 |
|
if (e_len + 2 > rest) // 2 for ', ' |
|
596 |
|
break; |
|
597 |
|
|
|
598 |
|
strcat(out, add); |
|
599 |
|
strcat(out, e); |
|
600 |
|
add = ", "; |
|
601 |
|
rest -= e_len + 2; |
|
602 |
|
} |
|
603 |
|
} |
|
604 |
|
|
|
605 |
|
static int decode_sqlite3_ret(char *out, unsigned out_size, |
|
606 |
|
unsigned char *d, unsigned int *i) |
|
607 |
|
{ |
|
608 |
|
unsigned int ret = decode32(d, i); |
|
609 |
|
|
|
610 |
|
switch (ret) { |
|
611 |
|
case 0: snprintf(out, out_size, "OK"); break; |
|
612 |
|
case 1: snprintf(out, out_size, "ERROR"); break; |
|
613 |
|
case 2: snprintf(out, out_size, "INTERNAL"); break; |
|
614 |
|
case 3: snprintf(out, out_size, "PERM"); break; |
|
615 |
|
case 4: snprintf(out, out_size, "ABORT"); break; |
|
616 |
|
case 5: snprintf(out, out_size, "BUSY"); break; |
|
617 |
|
case 6: snprintf(out, out_size, "LOCKED"); break; |
|
618 |
|
case 7: snprintf(out, out_size, "NOMEM"); break; |
|
619 |
|
case 8: snprintf(out, out_size, "READONLY"); break; |
|
620 |
|
case 9: snprintf(out, out_size, "INTERRUPT"); break; |
|
621 |
|
case 10: snprintf(out, out_size, "IOERR"); break; |
|
622 |
|
case 11: snprintf(out, out_size, "CORRUPT"); break; |
|
623 |
|
case 12: snprintf(out, out_size, "NOTFOUND"); break; |
|
624 |
|
case 13: snprintf(out, out_size, "FULL"); break; |
|
625 |
|
case 14: snprintf(out, out_size, "CANTOPEN"); break; |
|
626 |
|
case 15: snprintf(out, out_size, "PROTOCOL"); break; |
|
627 |
|
case 16: snprintf(out, out_size, "EMPTY"); break; |
|
628 |
|
case 17: snprintf(out, out_size, "SCHEMA"); break; |
|
629 |
|
case 18: snprintf(out, out_size, "TOOBIG"); break; |
|
630 |
|
case 19: snprintf(out, out_size, "CONSTRAINT"); break; |
|
631 |
|
case 20: snprintf(out, out_size, "MISMATCH"); break; |
|
632 |
|
case 21: snprintf(out, out_size, "MISUSE"); break; |
|
633 |
|
case 22: snprintf(out, out_size, "NOLFS"); break; |
|
634 |
|
case 23: snprintf(out, out_size, "AUTH"); break; |
|
635 |
|
case 24: snprintf(out, out_size, "FORMAT"); break; |
|
636 |
|
case 25: snprintf(out, out_size, "RANGE"); break; |
|
637 |
|
case 26: snprintf(out, out_size, "NOTADB"); break; |
|
638 |
|
case 27: snprintf(out, out_size, "NOTICE"); break; |
|
639 |
|
case 28: snprintf(out, out_size, "WARNING"); break; |
|
640 |
|
case 100: snprintf(out, out_size, "ROW"); break; |
|
641 |
|
case 101: snprintf(out, out_size, "DONE"); break; |
|
642 |
|
default: snprintf(out, out_size, "todo(%u)", ret); |
|
643 |
|
} |
|
644 |
|
|
|
645 |
|
return ret; |
|
646 |
|
} |
|
647 |
|
|
|
648 |
|
static int decode_mysql_real_connect_flags(char *out, unsigned out_size, |
|
649 |
|
unsigned char *d, unsigned int *i) |
|
650 |
|
{ |
|
651 |
|
int ret = decode32(d, i); |
|
652 |
|
|
|
653 |
|
char *found_rows = ""; if (ret & 2) found_rows = "|FOUND_ROWS"; |
|
654 |
|
char *compress = ""; if (ret & 32) compress = "|COMPRESS"; |
|
655 |
|
char *dont_ver = ""; if (ret & 64) dont_ver = "|SSL_DONT_VERIFY_SERVER_CERT"; |
|
656 |
|
char *ignore_space = ""; if (ret & 256) ignore_space = "|IGNORE_SPACE"; |
|
657 |
|
char *interact = ""; if (ret & 1024) interact = "|INTERACTIVE"; |
|
658 |
|
char *ssl = ""; if (ret & 2048) ssl = "SSL"; |
|
659 |
|
|
|
660 |
|
snprintf(out, out_size, "%x%s%s%s%s%s%s", |
|
661 |
|
ret, found_rows, compress, dont_ver, |
|
662 |
|
ignore_space, interact, ssl); |
|
663 |
|
|
|
664 |
|
return ret; |
|
665 |
|
} |
|
666 |
|
|
|
667 |
|
static int decode_dlopen_flags(char *out, size_t out_size, |
|
668 |
|
unsigned char *d, unsigned int *i) |
|
669 |
|
{ |
|
670 |
|
int ret = decode32(d, i); |
|
671 |
|
|
|
672 |
|
char *lazy = ""; if (ret & RTLD_LAZY) lazy = "|LAZY"; |
|
673 |
|
char *now = ""; if (ret & RTLD_NOW) lazy = "|NOW"; |
|
674 |
|
char *global = ""; if (ret & RTLD_GLOBAL) global = "|GLOBAL"; |
|
675 |
|
char *local = ""; if (ret & RTLD_LOCAL) local = "|LOCAL"; |
|
676 |
|
char *nodel = ""; if (ret & RTLD_NODELETE) nodel = "|NODELETE"; |
|
677 |
|
char *noload = ""; if (ret & RTLD_NOLOAD) nodel = "|NOLOAD"; |
|
678 |
|
char *deep = ""; if (ret & RTLD_DEEPBIND) deep = "|DEEPBIND"; |
|
679 |
|
|
|
680 |
|
snprintf(out, out_size, "%s%s%s%s%s%s%s", |
|
681 |
|
lazy, now, global, local, nodel, noload, deep); |
|
682 |
|
|
|
683 |
|
return ret; |
|
684 |
|
} |
|
685 |
|
|
|
686 |
|
static void decode_func(const uint32_t parent, unsigned char *d) |
570 |
687 |
{ |
{ |
571 |
688 |
unsigned int i = 0; |
unsigned int i = 0; |
572 |
|
unsigned short func_len; |
|
|
689 |
|
unsigned short func_len, trace_depth; |
573 |
690 |
char type, line[64000], rest[2000]; |
char type, line[64000], rest[2000]; |
574 |
691 |
uint64_t t; |
uint64_t t; |
575 |
692 |
|
|
|
... |
... |
static void decode_func(unsigned char *d) |
577 |
694 |
rest[0] = '\0'; |
rest[0] = '\0'; |
578 |
695 |
|
|
579 |
696 |
t = decode64(d, &i); |
t = decode64(d, &i); |
|
697 |
|
trace_depth = decode16(d, &i); |
580 |
698 |
func_len = decode16(d, &i); |
func_len = decode16(d, &i); |
581 |
699 |
char func[func_len * 4 + 1]; |
char func[func_len * 4 + 1]; |
582 |
700 |
bin2hex_ascii(func, d + i, func_len); i += func_len; |
bin2hex_ascii(func, d + i, func_len); i += func_len; |
|
... |
... |
static void decode_func(unsigned char *d) |
591 |
709 |
if (strcmp(func, "-stop") == 0) { |
if (strcmp(func, "-stop") == 0) { |
592 |
710 |
int ret = decode32(d, &i); |
int ret = decode32(d, &i); |
593 |
711 |
sprintf(line, "() = %d", ret); |
sprintf(line, "() = %d", ret); |
594 |
|
do_exit = 1; |
|
|
712 |
|
if (pid == parent) do_exit++; |
595 |
713 |
} else if (strcmp(func, "-segv") == 0) { |
} else if (strcmp(func, "-segv") == 0) { |
596 |
714 |
int r = decode32(d, &i); |
int r = decode32(d, &i); |
597 |
715 |
sprintf(line, ":"); |
sprintf(line, ":"); |
598 |
716 |
for (int j = 0; j < r; j++) { |
for (int j = 0; j < r; j++) { |
599 |
717 |
unsigned char len = decode8(d, &i); |
unsigned char len = decode8(d, &i); |
600 |
718 |
char l[len * 4 + 1]; |
char l[len * 4 + 1]; |
601 |
|
bin2hex(l, d + i, len); i += len; |
|
|
719 |
|
bin2hex_ascii(l, d + i, len); i += len; |
602 |
720 |
strcat(line, " "); |
strcat(line, " "); |
603 |
721 |
strcat(line, l); |
strcat(line, l); |
604 |
722 |
} |
} |
605 |
|
do_exit = 1; |
|
|
723 |
|
if (pid == parent) do_exit++; |
606 |
724 |
} break; |
} break; |
607 |
725 |
|
|
608 |
726 |
case 'a': |
case 'a': |
|
... |
... |
static void decode_func(unsigned char *d) |
667 |
785 |
uint16_t len = decode16(d, &i); |
uint16_t len = decode16(d, &i); |
668 |
786 |
char filename[len * 4 + 1]; |
char filename[len * 4 + 1]; |
669 |
787 |
bin2hex_ascii(filename, d + i, len); i += len; |
bin2hex_ascii(filename, d + i, len); i += len; |
670 |
|
int flags = decode32(d, &i); |
|
|
788 |
|
char flags[128]; |
|
789 |
|
decode_dlopen_flags(flags, sizeof(flags), d, &i); |
671 |
790 |
if (type == 'r') |
if (type == 'r') |
672 |
791 |
decode_ret_pointer(rest, sizeof(rest), d, &i); |
decode_ret_pointer(rest, sizeof(rest), d, &i); |
673 |
|
sprintf(line, "('%s', 0x%x)%s", filename, flags, rest); |
|
|
792 |
|
sprintf(line, "('%s', '%s')%s", filename, flags, rest); |
674 |
793 |
} else if (strcmp(func, "dlclose") == 0) { |
} else if (strcmp(func, "dlclose") == 0) { |
675 |
794 |
void *h = (void *) decode64(d, &i); |
void *h = (void *) decode64(d, &i); |
676 |
|
if (type == 'r') |
|
677 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
|
795 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
678 |
796 |
sprintf(line, "(%p)%s", h, rest); |
sprintf(line, "(%p)%s", h, rest); |
679 |
797 |
} break; |
} break; |
680 |
798 |
|
|
|
799 |
|
case 'e': |
|
800 |
|
if (strcmp(func, "execve") == 0) { |
|
801 |
|
char argv[4096], envp[4096]; |
|
802 |
|
uint16_t len = decode16(d, &i); |
|
803 |
|
char pathname[len * 4 + 1]; |
|
804 |
|
bin2hex_ascii(pathname, d + i, len); i += len; |
|
805 |
|
decode_string_array(argv, sizeof(argv), d, &i); |
|
806 |
|
decode_string_array(envp, sizeof(envp), d, &i); |
|
807 |
|
if (type == 'r') |
|
808 |
|
decode_ret_pointer(rest, sizeof(rest), d, &i); |
|
809 |
|
sprintf(line, "('%s', {%s}, {%s})%s", |
|
810 |
|
pathname, argv, envp, rest); |
|
811 |
|
} break; |
|
812 |
|
|
681 |
813 |
case 'f': |
case 'f': |
682 |
|
if ((strcmp(func, "fstatat") == 0) |
|
|
814 |
|
if (strcmp(func, "fork") == 0) { |
|
815 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
816 |
|
sprintf(line, "()%s", rest); |
|
817 |
|
} else if ((strcmp(func, "fstatat") == 0) |
683 |
818 |
|| (strcmp(func, "fstat64") == 0)) { |
|| (strcmp(func, "fstat64") == 0)) { |
684 |
819 |
char dirfd[32], sstat[512]; |
char dirfd[32], sstat[512]; |
685 |
820 |
decode_dirfd(dirfd, sizeof(dirfd), d, &i, ""); |
decode_dirfd(dirfd, sizeof(dirfd), d, &i, ""); |
|
... |
... |
static void decode_func(unsigned char *d) |
692 |
827 |
decode_ret_pointer(rest, sizeof(rest), d, &i); |
decode_ret_pointer(rest, sizeof(rest), d, &i); |
693 |
828 |
sprintf(line, "(%s, '%s', {%s}, 0x%x)%s", |
sprintf(line, "(%s, '%s', {%s}, 0x%x)%s", |
694 |
829 |
dirfd, pathname, sstat, flags, rest); |
dirfd, pathname, sstat, flags, rest); |
695 |
|
} else if (strcmp(func, "dlclose") == 0) { |
|
696 |
|
void *h = (void *) decode64(d, &i); |
|
697 |
|
if (type == 'r') |
|
698 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
699 |
|
sprintf(line, "(%p)%s", h, rest); |
|
700 |
830 |
} break; |
} break; |
701 |
831 |
|
|
702 |
832 |
case 'g': |
case 'g': |
|
... |
... |
static void decode_func(unsigned char *d) |
775 |
905 |
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
776 |
906 |
int sock = decode32(d, &i); |
int sock = decode32(d, &i); |
777 |
907 |
int backlog = decode32(d, &i); |
int backlog = decode32(d, &i); |
778 |
|
if (type == 'r') |
|
779 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
|
908 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
780 |
909 |
sprintf(line, "(%d, %d)%s", sock, backlog, rest); |
sprintf(line, "(%d, %d)%s", sock, backlog, rest); |
781 |
910 |
} break; |
} break; |
782 |
911 |
|
|
|
912 |
|
case 'm': |
|
913 |
|
if (strcmp(func, "mysqli_close") == 0) { |
|
914 |
|
uint64_t link = decode64(d, &i); |
|
915 |
|
if (type == 'r') |
|
916 |
|
decode_bool(" = ", rest, sizeof(rest), d, &i); |
|
917 |
|
sprintf(line, "(link=0x%lx)%s", link, rest); |
|
918 |
|
} else if (strcmp(func, "mysqli_connect") == 0) { |
|
919 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
920 |
|
uint32_t cs_len = decode32(d, &i); |
|
921 |
|
char cs[cs_len * 4 + 1]; |
|
922 |
|
bin2hex_ascii(cs, d + i, cs_len); i += cs_len; |
|
923 |
|
if (type == 'r') |
|
924 |
|
decode_bool(" = ", rest, sizeof(rest), d, &i); |
|
925 |
|
sprintf(line, "('%s')%s", cs, rest); |
|
926 |
|
} else if (strcmp(func, "mysqli_query") == 0) { |
|
927 |
|
uint64_t link = decode64(d, &i); |
|
928 |
|
uint16_t q_len = decode16(d, &i); |
|
929 |
|
char q[q_len * 4 + 1]; |
|
930 |
|
bin2hex_ascii(q, d + i, q_len); i += q_len; |
|
931 |
|
if (type == 'r') { |
|
932 |
|
uint64_t res = decode64(d, &i); |
|
933 |
|
if (res == 0) |
|
934 |
|
snprintf(rest, sizeof(rest), " = nok"); |
|
935 |
|
else if (res == 1) |
|
936 |
|
snprintf(rest, sizeof(rest), " = ok"); |
|
937 |
|
else |
|
938 |
|
snprintf(rest, sizeof(rest), " = 0x%lx", res); |
|
939 |
|
} |
|
940 |
|
sprintf(line, "(link=0x%lx, '%s')%s", link, q, rest); |
|
941 |
|
} else if (strcmp(func, "mysqli_real_connect") == 0) { |
|
942 |
|
uint64_t link = decode64(d, &i); |
|
943 |
|
uint32_t cs_len = decode32(d, &i); |
|
944 |
|
char cs[cs_len * 4 + 1]; |
|
945 |
|
bin2hex_ascii(cs, d + i, cs_len); i += cs_len; |
|
946 |
|
char flags[512]; |
|
947 |
|
decode_mysql_real_connect_flags(flags, sizeof(flags), d, &i); |
|
948 |
|
if (type == 'r') |
|
949 |
|
decode_bool(" = ", rest, sizeof(rest), d, &i); |
|
950 |
|
sprintf(line, "(link=0x%lx, '%s', flags='%s')%s", link, cs, flags, rest); |
|
951 |
|
} break; |
|
952 |
|
|
783 |
953 |
case 'n': |
case 'n': |
784 |
954 |
if (strcmp(func, "nanosleep") == 0) { |
if (strcmp(func, "nanosleep") == 0) { |
785 |
955 |
struct timespec req; |
struct timespec req; |
|
... |
... |
static void decode_func(unsigned char *d) |
799 |
969 |
} break; |
} break; |
800 |
970 |
|
|
801 |
971 |
case 'o': |
case 'o': |
802 |
|
if ((strcmp(func, "open") == 0) || (strcmp(func, "open64") == 0) |
|
|
972 |
|
if ((strcmp(func, "open") == 0) |
|
973 |
|
|| (strcmp(func, "open64") == 0) |
803 |
974 |
|| (strcmp(func, "openat") == 0)) { |
|| (strcmp(func, "openat") == 0)) { |
804 |
975 |
char dirfd[32]; |
char dirfd[32]; |
805 |
976 |
if (strcmp(func, "openat") == 0) |
if (strcmp(func, "openat") == 0) |
|
... |
... |
static void decode_func(unsigned char *d) |
807 |
978 |
else |
else |
808 |
979 |
dirfd[0] = '\0'; |
dirfd[0] = '\0'; |
809 |
980 |
uint16_t len = decode16(d, &i); |
uint16_t len = decode16(d, &i); |
810 |
|
char filename[len * 4 + 1]; |
|
811 |
|
bin2hex_ascii(filename, d + i, len); i += len; |
|
|
981 |
|
char pathname[len * 4 + 1]; |
|
982 |
|
bin2hex_ascii(pathname, d + i, len); i += len; |
812 |
983 |
int flags = decode32(d, &i); |
int flags = decode32(d, &i); |
813 |
984 |
mode_t mode = decode32(d, &i); |
mode_t mode = decode32(d, &i); |
814 |
985 |
if (type == 'r') |
if (type == 'r') |
815 |
986 |
decode_ret_int(rest, sizeof(rest), d, &i); |
decode_ret_int(rest, sizeof(rest), d, &i); |
816 |
|
sprintf(line, "('%s'%s, 0x%x, 0x%x)%s", |
|
817 |
|
dirfd, filename, flags, mode, rest); |
|
|
987 |
|
sprintf(line, "(%s'%s', 0x%x, 0x%x)%s", |
|
988 |
|
dirfd, pathname, flags, mode, rest); |
818 |
989 |
} break; |
} break; |
819 |
990 |
|
|
820 |
991 |
case 'p': |
case 'p': |
|
... |
... |
static void decode_func(unsigned char *d) |
839 |
1010 |
decode_ret_int(rest, sizeof(rest), d, &i); |
decode_ret_int(rest, sizeof(rest), d, &i); |
840 |
1011 |
sprintf(line, "([%s], %u, %d)%s", |
sprintf(line, "([%s], %u, %d)%s", |
841 |
1012 |
list, nf, timeout, rest); |
list, nf, timeout, rest); |
|
1013 |
|
} else if (strcmp(func, "pg_close") == 0) { |
|
1014 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1015 |
|
uint64_t h = decode64(d, &i); |
|
1016 |
|
sprintf(line, "(0x%lx)", h); |
|
1017 |
|
} else if ((strcmp(func, "pg_connect") == 0) |
|
1018 |
|
|| (strcmp(func, "pg_pconnect") == 0)) { |
|
1019 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1020 |
|
uint32_t cs_len = decode32(d, &i); |
|
1021 |
|
char cs[cs_len * 4 + 1]; |
|
1022 |
|
bin2hex_ascii(cs, d + i, cs_len); i += cs_len; |
|
1023 |
|
if (type == 'r') { |
|
1024 |
|
uint64_t h = decode64(d, &i); |
|
1025 |
|
snprintf(rest, sizeof(rest), " = 0x%lx", h); |
|
1026 |
|
} |
|
1027 |
|
sprintf(line, "('%s')%s", cs, rest); |
|
1028 |
|
} else if (strcmp(func, "pg_free_result") == 0) { |
|
1029 |
|
void *res = (void *) decode64(d, &i); |
|
1030 |
|
uint8_t ret = decode8(d, &i); |
|
1031 |
|
sprintf(line, "(%p) = %s", res, ret == 1 ? "ok" : "nok"); |
|
1032 |
|
} else if ((strcmp(func, "pg_query") == 0) |
|
1033 |
|
|| (strcmp(func, "pg_query_params") == 0) |
|
1034 |
|
|| (strcmp(func, "pg_send_query") == 0) |
|
1035 |
|
|| (strcmp(func, "pg_send_query_params") == 0)) { |
|
1036 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1037 |
|
uint64_t dbh = decode64(d, &i); |
|
1038 |
|
uint16_t q_len = decode16(d, &i); |
|
1039 |
|
char q[q_len * 4 + 1]; |
|
1040 |
|
bin2hex_ascii(q, d + i, q_len); i += q_len; |
|
1041 |
|
while (type == 'c') { |
|
1042 |
|
uint16_t params_len = decode16(d, &i); |
|
1043 |
|
uint16_t max = decode16(d, &i); |
|
1044 |
|
if (max == 0) |
|
1045 |
|
break; |
|
1046 |
|
|
|
1047 |
|
// TODO: 'rest' may not be big enough! |
|
1048 |
|
strcpy(rest, " {"); |
|
1049 |
|
char *add = ""; |
|
1050 |
|
for (unsigned short j = 0; j < max; j++) { |
|
1051 |
|
char value[64]; |
|
1052 |
|
uint8_t type = decode8(d, &i); |
|
1053 |
|
if (type == 1) { // long |
|
1054 |
|
snprintf(value, sizeof(value), |
|
1055 |
|
"%hu:long:%ld", j + 1, decode64(d, &i)); |
|
1056 |
|
} else if (type == 2) { // double |
|
1057 |
|
snprintf(value, sizeof(value), |
|
1058 |
|
"%hu:double:%f", j + 1, (double) decode64(d, &i)); |
|
1059 |
|
} else if (type == 3) { // string |
|
1060 |
|
uint16_t len = decode16(d, &i); |
|
1061 |
|
char s[len * 4 + 1]; |
|
1062 |
|
bin2hex_ascii(s, d + i, len); i += len; |
|
1063 |
|
snprintf(value, sizeof(value), |
|
1064 |
|
"%hu:str:'%s'", j + 1, s); |
|
1065 |
|
} |
|
1066 |
|
|
|
1067 |
|
strcat(rest, add); |
|
1068 |
|
strcat(rest, value); |
|
1069 |
|
add = ", "; |
|
1070 |
|
} |
|
1071 |
|
if (max < params_len) |
|
1072 |
|
strcat(rest, "..."); |
|
1073 |
|
strcat(rest, "}"); |
|
1074 |
|
break; |
|
1075 |
|
} |
|
1076 |
|
if (type == 'r') { |
|
1077 |
|
uint64_t res = decode64(d, &i); |
|
1078 |
|
uint64_t rows = decode64(d, &i); |
|
1079 |
|
uint64_t aff = decode64(d, &i); |
|
1080 |
|
if (res == 1) // pg_send_query[_params] |
|
1081 |
|
snprintf(rest, sizeof(rest), |
|
1082 |
|
" = ok [%lu rows, %lu aff]", |
|
1083 |
|
rows, aff); |
|
1084 |
|
else if (res == 0) // pg_send_query[_params] TODO when this happens? pg_query returns false |
|
1085 |
|
snprintf(rest, sizeof(rest), " = nok"); // TODO: error code |
|
1086 |
|
else |
|
1087 |
|
snprintf(rest, sizeof(rest), |
|
1088 |
|
" = 0x%lx [%lu rows, %lu aff]", |
|
1089 |
|
res, rows, aff); |
|
1090 |
|
} |
|
1091 |
|
sprintf(line, "(h=0x%lx, '%s')%s", dbh, q, rest); |
|
1092 |
|
} else if (strcmp(func, "pg_get_result") == 0) { |
|
1093 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1094 |
|
uint64_t dbh = decode64(d, &i); |
|
1095 |
|
if (type == 'r') { |
|
1096 |
|
uint64_t res = decode64(d, &i); |
|
1097 |
|
uint64_t rows = decode64(d, &i); |
|
1098 |
|
uint64_t aff = decode64(d, &i); |
|
1099 |
|
snprintf(rest, sizeof(rest), " = 0x%lx [%lu rows, %lu aff]", |
|
1100 |
|
res, rows, aff); |
|
1101 |
|
} |
|
1102 |
|
sprintf(line, "(h=0x%lx)%s", dbh, rest); |
842 |
1103 |
} break; |
} break; |
843 |
1104 |
|
|
844 |
1105 |
case 'r': |
case 'r': |
|
... |
... |
static void decode_func(unsigned char *d) |
862 |
1123 |
sprintf(line, "(%d)%s", sock, rest); |
sprintf(line, "(%d)%s", sock, rest); |
863 |
1124 |
} |
} |
864 |
1125 |
} |
} |
|
1126 |
|
} else if (strcmp(func, "recvfrom") == 0) { |
|
1127 |
|
int sock = decode32(d, &i); |
|
1128 |
|
uint64_t len = decode64(d, &i); |
|
1129 |
|
int addrlen = decode32(d, &i); |
|
1130 |
|
int flags = decode32(d, &i); |
|
1131 |
|
if (type == 'c') |
|
1132 |
|
sprintf(line, "(%d, buf, %zu, 0x%x, addr, %u)", |
|
1133 |
|
sock, len, flags, addrlen); |
|
1134 |
|
while (type == 'r') { |
|
1135 |
|
ssize_t ret = decode_ret_int64(rest, sizeof(rest), d, &i); |
|
1136 |
|
if (ret <= 0) |
|
1137 |
|
break; |
|
1138 |
|
uint16_t max = decode16(d, &i); |
|
1139 |
|
char buf[max * 4 + 1]; |
|
1140 |
|
bin2hex_ascii(buf, d + i, max); i += max; |
|
1141 |
|
if (addrlen == 0) |
|
1142 |
|
break; |
|
1143 |
|
char addr[addrlen * 2 + 1]; |
|
1144 |
|
bin2hex(addr, d + i, addrlen); i += addrlen; // TODO: we need to decode this! |
|
1145 |
|
sprintf(line, "(%d, '%s'%s, %zd, 0x%x, '%s')%s", |
|
1146 |
|
sock, buf, len > max ? "..." : "", |
|
1147 |
|
len, flags, addr, rest); |
|
1148 |
|
break; |
|
1149 |
|
} |
865 |
1150 |
} break; |
} break; |
866 |
1151 |
|
|
867 |
1152 |
case 's': |
case 's': |
|
... |
... |
static void decode_func(unsigned char *d) |
923 |
1208 |
int xdomain = decode32(d, &i); |
int xdomain = decode32(d, &i); |
924 |
1209 |
int xtype = decode32(d, &i); |
int xtype = decode32(d, &i); |
925 |
1210 |
int xprotocol = decode32(d, &i); |
int xprotocol = decode32(d, &i); |
926 |
|
if (type == 'r') |
|
927 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
|
1211 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
928 |
1212 |
sprintf(line, "(%s, %s, %d)%s", |
sprintf(line, "(%s, %s, %d)%s", |
929 |
1213 |
decode_socket_domain(xdomain), |
decode_socket_domain(xdomain), |
930 |
1214 |
decode_socket_type(xtype), xprotocol, rest); |
decode_socket_type(xtype), xprotocol, rest); |
|
1215 |
|
} else if (strcmp(func, "sqlite3_open_v2") == 0) { |
|
1216 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1217 |
|
uint16_t filename_len = decode16(d, &i); |
|
1218 |
|
char filename[filename_len * 4 + 1]; |
|
1219 |
|
bin2hex_ascii(filename, d + i, filename_len); i += filename_len; |
|
1220 |
|
int flags = decode32(d, &i); |
|
1221 |
|
uint16_t vfs_len = decode16(d, &i); |
|
1222 |
|
char vfs[vfs_len * 4 + 1]; |
|
1223 |
|
bin2hex_ascii(vfs, d + i, vfs_len); i += vfs_len; |
|
1224 |
|
|
|
1225 |
|
if (type == 'c') { |
|
1226 |
|
sprintf(line, "('%s', 0x%x, '%s')", |
|
1227 |
|
filename, flags, vfs); |
|
1228 |
|
} else { |
|
1229 |
|
char err[64]; |
|
1230 |
|
int ret = decode_sqlite3_ret(err, sizeof(err), d, &i); |
|
1231 |
|
uint64_t pdb = 0; |
|
1232 |
|
if (ret == 0) |
|
1233 |
|
pdb = decode64(d, &i); |
|
1234 |
|
sprintf(line, "('%s', 0x%lx, 0x%x, '%s') = %s", |
|
1235 |
|
filename, pdb, flags, vfs, err); |
|
1236 |
|
} |
|
1237 |
|
} else if (strcmp(func, "sqlite3_prepare_v2") == 0) { |
|
1238 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1239 |
|
uint64_t h = decode64(d, &i); |
|
1240 |
|
uint32_t sql_len = decode32(d, &i); |
|
1241 |
|
char sql[sql_len * 4 + 1]; |
|
1242 |
|
bin2hex_ascii(sql, d + i, sql_len); i += sql_len; |
|
1243 |
|
int nByte = decode32(d, &i); |
|
1244 |
|
if (type == 'c') { |
|
1245 |
|
sprintf(line, "(0x%lx, '%s', %d, stmt, tail)", |
|
1246 |
|
h, sql, nByte); |
|
1247 |
|
} else { |
|
1248 |
|
uint64_t stmt = decode64(d, &i); |
|
1249 |
|
char err[64]; |
|
1250 |
|
decode_sqlite3_ret(err, sizeof(err), d, &i); |
|
1251 |
|
sprintf(line, "(0x%lx, '%s', %d, 0x%lx, tail) = %s", |
|
1252 |
|
h, sql, nByte, stmt, err); |
|
1253 |
|
} |
|
1254 |
|
} else if (strcmp(func, "sqlite3_step") == 0) { |
|
1255 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1256 |
|
uint64_t stmt = decode64(d, &i); |
|
1257 |
|
if (type == 'c') { |
|
1258 |
|
sprintf(line, "(0x%lx)", stmt); |
|
1259 |
|
} else { |
|
1260 |
|
char err[64]; |
|
1261 |
|
decode_sqlite3_ret(err, sizeof(err), d, &i); |
|
1262 |
|
sprintf(line, "(0x%lx) = %s", stmt, err); |
|
1263 |
|
} |
931 |
1264 |
} else if (strcmp(func, "stat") == 0) { |
} else if (strcmp(func, "stat") == 0) { |
932 |
1265 |
uint16_t len = decode16(d, &i); |
uint16_t len = decode16(d, &i); |
933 |
1266 |
char pathname[len * 4 + 1]; |
char pathname[len * 4 + 1]; |
|
... |
... |
static void decode_func(unsigned char *d) |
985 |
1318 |
return; |
return; |
986 |
1319 |
} |
} |
987 |
1320 |
|
|
|
1321 |
|
char space[4096]; |
|
1322 |
|
unsigned short max = sizeof(space) - 1; |
|
1323 |
|
if (max > trace_depth) |
|
1324 |
|
max = trace_depth; |
|
1325 |
|
memset(space, ' ', max); |
|
1326 |
|
space[max] = '\0'; |
|
1327 |
|
|
988 |
1328 |
if (pid == tid) |
if (pid == tid) |
989 |
|
fprintf(out, "%lu.%03lu %10u %s%s\n", |
|
990 |
|
t / 1000, t % 1000, pid, func, line); |
|
|
1329 |
|
fprintf(out, "%lu.%03lu %10u%s %s%s\n", |
|
1330 |
|
t / 1000, t % 1000, pid, space, func, line); |
991 |
1331 |
else |
else |
992 |
|
fprintf(out, "%lu.%03lu %10u %10u %s%s\n", |
|
993 |
|
t / 1000, t % 1000, pid, tid, func, line); |
|
|
1332 |
|
fprintf(out, "%lu.%03lu %10u %10u%s %s%s\n", |
|
1333 |
|
t / 1000, t % 1000, pid, tid, space, func, line); |
994 |
1334 |
} |
} |
995 |
1335 |
|
|
996 |
|
static void decode(unsigned char *d, size_t len) |
|
|
1336 |
|
static void decode(const pid_t parent, unsigned char *d, size_t len) |
997 |
1337 |
{ |
{ |
998 |
1338 |
unsigned int i = 0; |
unsigned int i = 0; |
999 |
1339 |
char type; |
char type; |
1000 |
1340 |
|
|
1001 |
1341 |
type = d[i++]; |
type = d[i++]; |
1002 |
1342 |
if (type == 'F') { |
if (type == 'F') { |
1003 |
|
decode_func(d + i); |
|
|
1343 |
|
decode_func(parent, d + i); |
1004 |
1344 |
} else { |
} else { |
1005 |
1345 |
fprintf(out, "I do not know how to decode type [%c]!\n", type); |
fprintf(out, "I do not know how to decode type [%c]!\n", type); |
1006 |
1346 |
char dump[len * 4 + 1]; |
char dump[len * 4 + 1]; |
|
... |
... |
int main(int argc, char *argv[]) |
1016 |
1356 |
char *out_file = NULL; |
char *out_file = NULL; |
1017 |
1357 |
pid_t pids[256]; |
pid_t pids[256]; |
1018 |
1358 |
int sm[256]; |
int sm[256]; |
|
1359 |
|
char version[256]; |
1019 |
1360 |
struct shared *shared[256]; |
struct shared *shared[256]; |
1020 |
1361 |
unsigned int no_pids = 0; |
unsigned int no_pids = 0; |
1021 |
1362 |
|
|
|
1363 |
|
for (unsigned i = 0; i < 256; i++) { |
|
1364 |
|
sm[i] = -2; |
|
1365 |
|
version[i] = 0; |
|
1366 |
|
} |
|
1367 |
|
|
1022 |
1368 |
setlinebuf(stderr); |
setlinebuf(stderr); |
1023 |
1369 |
|
|
1024 |
1370 |
while ((c = getopt_long(argc, argv, "p:o:", options, &options_index)) != -1) { |
while ((c = getopt_long(argc, argv, "p:o:", options, &options_index)) != -1) { |
|
... |
... |
int main(int argc, char *argv[]) |
1048 |
1394 |
|
|
1049 |
1395 |
//pid_t my_pid = getpid(); |
//pid_t my_pid = getpid(); |
1050 |
1396 |
|
|
|
1397 |
|
again: |
1051 |
1398 |
for (unsigned i = 0; i < no_pids; i++) { |
for (unsigned i = 0; i < no_pids; i++) { |
|
1399 |
|
if (sm[i] >= 0) |
|
1400 |
|
continue; |
|
1401 |
|
|
1052 |
1402 |
char name[128]; |
char name[128]; |
1053 |
1403 |
snprintf(name, sizeof(name), "/ninedogs-%d", pids[i]); |
snprintf(name, sizeof(name), "/ninedogs-%d", pids[i]); |
1054 |
1404 |
|
|
1055 |
1405 |
sm[i] = shm_open(name, O_RDWR, 0); |
sm[i] = shm_open(name, O_RDWR, 0); |
1056 |
1406 |
if (sm[i] == -1) { |
if (sm[i] == -1) { |
1057 |
|
fprintf(stderr, "Cannot do shm_open i%u pid %d: %m\n", i, pids[i]); |
|
1058 |
|
return 1; |
|
|
1407 |
|
//fprintf(stderr, "%u: Cannot do shm_open: %m\n", pids[i]); |
|
1408 |
|
continue; |
1059 |
1409 |
} |
} |
1060 |
|
fprintf(stderr, "shm_open i%u = %d\n", i, sm[i]); |
|
|
1410 |
|
fprintf(stderr, "%u: shm_open returned %d\n", pids[i], sm[i]); |
1061 |
1411 |
|
|
1062 |
1412 |
shared[i] = mmap(NULL, sizeof(struct shared), |
shared[i] = mmap(NULL, sizeof(struct shared), |
1063 |
1413 |
PROT_READ | PROT_WRITE, MAP_SHARED, sm[i], 0); |
PROT_READ | PROT_WRITE, MAP_SHARED, sm[i], 0); |
1064 |
1414 |
if (shared[i] == MAP_FAILED) { |
if (shared[i] == MAP_FAILED) { |
1065 |
|
fprintf(stderr, "Cannot mmap i%u: %m\n", i); |
|
1066 |
|
return 1; |
|
|
1415 |
|
//fprintf(stderr, "Cannot mmap i%u: %m\n", i); |
|
1416 |
|
close(sm[i]); |
|
1417 |
|
sm[i] = -1; |
|
1418 |
|
continue; |
1067 |
1419 |
} |
} |
1068 |
1420 |
|
|
|
1421 |
|
fprintf(stderr, "%u: Attached\n", pids[i]); |
|
1422 |
|
|
1069 |
1423 |
#if 0 |
#if 0 |
1070 |
1424 |
unsigned j = 0; |
unsigned j = 0; |
1071 |
1425 |
shared[i]->buf[j++] = SHARED_CMD_INIT; |
shared[i]->buf[j++] = SHARED_CMD_INIT; |
|
... |
... |
int main(int argc, char *argv[]) |
1075 |
1429 |
|
|
1076 |
1430 |
r = sem_post(&shared[i]->sem1); |
r = sem_post(&shared[i]->sem1); |
1077 |
1431 |
if (r == -1) { |
if (r == -1) { |
1078 |
|
fprintf(stderr, "Cannot post sem1: %m\n"); |
|
|
1432 |
|
fprintf(stderr, "%u: Cannot post sem1: %m\n", pids[i]); |
1079 |
1433 |
return 1; |
return 1; |
1080 |
1434 |
} |
} |
1081 |
1435 |
#endif |
#endif |
1082 |
1436 |
} |
} |
1083 |
1437 |
|
|
1084 |
|
while (1) { |
|
1085 |
1438 |
for (unsigned i = 0; i < no_pids; i++) { |
for (unsigned i = 0; i < no_pids; i++) { |
1086 |
1439 |
unsigned char *p; |
unsigned char *p; |
1087 |
1440 |
unsigned int ava; |
unsigned int ava; |
1088 |
1441 |
unsigned char buf[64000]; |
unsigned char buf[64000]; |
1089 |
1442 |
struct stat s; |
struct stat s; |
1090 |
1443 |
|
|
1091 |
|
if (do_exit) { |
|
|
1444 |
|
if (do_exit == no_pids) { |
1092 |
1445 |
fprintf(stderr, "Bye!\n"); |
fprintf(stderr, "Bye!\n"); |
1093 |
1446 |
break; |
break; |
1094 |
1447 |
} |
} |
1095 |
1448 |
|
|
1096 |
1449 |
fstat(sm[i], &s); |
fstat(sm[i], &s); |
1097 |
1450 |
if (s.st_size == 0) { |
if (s.st_size == 0) { |
1098 |
|
fprintf(out, "size[%u](fd %d)=%ld\n", i, sm[i], s.st_size); |
|
|
1451 |
|
//fprintf(out, "%u: Shared memory size is zero!\n", pids[i]); |
1099 |
1452 |
continue; |
continue; |
1100 |
1453 |
} |
} |
|
1454 |
|
//fprintf(out, "%u: Shared memory size: %ld\n", pids[i], s.st_size); |
1101 |
1455 |
|
|
1102 |
1456 |
r = sem_wait(&shared[i]->sem1); |
r = sem_wait(&shared[i]->sem1); |
1103 |
1457 |
if (r == -1) { |
if (r == -1) { |
1104 |
|
fprintf(stderr, "Cannot wait for sem1: %m\n"); |
|
|
1458 |
|
fprintf(stderr, "%u: Cannot wait for sem1: %m\n", pids[i]); |
1105 |
1459 |
return 1; |
return 1; |
1106 |
1460 |
} |
} |
1107 |
1461 |
|
|
1108 |
1462 |
r = sem_post(&shared[i]->sem1); |
r = sem_post(&shared[i]->sem1); |
1109 |
1463 |
if (r == -1) { |
if (r == -1) { |
1110 |
|
fprintf(stderr, "Cannot post sem1: %m\n"); |
|
|
1464 |
|
fprintf(stderr, "%u: Cannot post sem1: %m\n", pids[i]); |
1111 |
1465 |
return 1; |
return 1; |
1112 |
1466 |
} |
} |
1113 |
1467 |
|
|
|
1468 |
|
if (version[i] == 0) { |
|
1469 |
|
version[i] = shared[i]->version; |
|
1470 |
|
fprintf(out, "%u: version is %hhu\n", pids[i], version[i]); |
|
1471 |
|
} |
|
1472 |
|
|
1114 |
1473 |
// tail-1 points to last value available |
// tail-1 points to last value available |
1115 |
1474 |
if (shared[i]->tail == shared[i]->head) |
if (shared[i]->tail == shared[i]->head) |
1116 |
1475 |
continue; |
continue; |
|
... |
... |
while (1) { |
1139 |
1498 |
plen = be16toh(plen); |
plen = be16toh(plen); |
1140 |
1499 |
} |
} |
1141 |
1500 |
if (plen > ava) { |
if (plen > ava) { |
1142 |
|
fprintf(out, " Too short packet: plen=%hu > ava[%u]!\n", |
|
1143 |
|
plen, ava); |
|
|
1501 |
|
fprintf(out, "%u: Too short packet: plen=%hu > ava[%u]!\n", |
|
1502 |
|
pids[i], plen, ava); |
1144 |
1503 |
break; |
break; |
1145 |
1504 |
} |
} |
1146 |
1505 |
|
|
|
... |
... |
while (1) { |
1160 |
1519 |
if (0) { |
if (0) { |
1161 |
1520 |
char dump[plen * 4 + 1]; |
char dump[plen * 4 + 1]; |
1162 |
1521 |
bin2hex_ascii(dump, p, plen); |
bin2hex_ascii(dump, p, plen); |
1163 |
|
fprintf(out, " DUMP[%hu] head=%u: %s\n", plen, shared[i]->head, dump); |
|
|
1522 |
|
fprintf(out, "%u: DUMP[%hu] head=%u: %s\n", |
|
1523 |
|
pids[i], plen, shared[i]->head, dump); |
1164 |
1524 |
} |
} |
1165 |
1525 |
|
|
1166 |
|
decode(p + 2, plen - 2); |
|
|
1526 |
|
decode(pids[i], p + 2, plen - 2); |
1167 |
1527 |
|
|
1168 |
1528 |
shared[i]->head = (shared[i]->head + plen) % shared[i]->buf_size; |
shared[i]->head = (shared[i]->head + plen) % shared[i]->buf_size; |
1169 |
1529 |
ava -= plen; |
ava -= plen; |
|
... |
... |
while (1) { |
1171 |
1531 |
} |
} |
1172 |
1532 |
} |
} |
1173 |
1533 |
|
|
1174 |
|
if (do_exit) |
|
1175 |
|
break; |
|
1176 |
|
} |
|
|
1534 |
|
if (!do_exit) |
|
1535 |
|
goto again; |
|
1536 |
|
|
1177 |
1537 |
// TODO: print some stats |
// TODO: print some stats |
1178 |
1538 |
return 0; |
return 0; |
1179 |
1539 |
} |
} |