From: Adam Dickmeiss Date: Sat, 26 Mar 2011 21:59:37 +0000 (+0100) Subject: Implement pazpar2_play utility X-Git-Tag: v1.5.5~4^2~1 X-Git-Url: http://sru.miketaylor.org.uk/?a=commitdiff_plain;h=9b8a842cb328ac45bff04dae8f7e564ba1fc3b3e;p=pazpar2-moved-to-github.git Implement pazpar2_play utility This will read the HTTP request file that is generated by Pazpar2 when option -R is used. At this point, the timings are not used (all requests executed without pause). --- diff --git a/src/.gitignore b/src/.gitignore index b810359..1430d65 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,5 +1,6 @@ yaz pazpar2 +pazpar2_play Makefile Makefile.in config.h diff --git a/src/Makefile.am b/src/Makefile.am index 5ff1aa8..c956188 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,7 @@ # This file is part of Pazpar2. sbin_PROGRAMS = pazpar2 +noinst_PROGRAMS = pazpar2_play EXTRA_DIST = pazpar2.rpm.init pazpar2.rpm.logrotate @@ -34,6 +35,9 @@ libpazpar2_a_SOURCES = pazpar2_config.c pazpar2_config.h eventl.c eventl.h \ pazpar2_SOURCES = pazpar2.c pazpar2_LDADD = libpazpar2.a $(YAZLIB) +pazpar2_play_SOURCES = pazpar2_play.c +pazpar2_play_LDADD = $(YAZLIB) + test_sel_thread_SOURCES = test_sel_thread.c test_sel_thread_LDADD = libpazpar2.a $(YAZLIB) diff --git a/src/pazpar2_play.c b/src/pazpar2_play.c new file mode 100644 index 0000000..298a3d3 --- /dev/null +++ b/src/pazpar2_play.c @@ -0,0 +1,231 @@ +/* This file is part of Pazpar2. + Copyright (C) 2006-2011 Index Data + +Pazpar2 is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct con { + int fd; + long long id; + struct con *next; +}; + + +static int run(FILE *inf, struct addrinfo *res) +{ + long long tv_sec0; + long long tv_usec0; + struct con *cons = 0; + while (1) + { + long long tv_sec1; + long long tv_usec1; + long long id; + int sz, r, c; + char req[100]; + size_t i; + struct con **conp; + c = fgetc(inf); + if (c == EOF) + break; + + for (i = 0; c != '\n' && i < (sizeof(req)-2); i++) + { + req[i] = c; + c = fgetc(inf); + } + req[i] = 0; + r = sscanf(req, "%lld %lld %lld %d", &tv_sec1, &tv_usec1, &id, &sz); + if (r != 4) + { + fprintf(stderr, "bad line %s\n", req); + return -1; + } + for (conp = &cons; *conp; conp = &(*conp)->next) + if ((*conp)->id == id) + break; + if (!*conp) + { + struct addrinfo *rp; + int r, fd = -1; + for (rp = res; rp; rp = rp->ai_next) + { + fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (fd != -1) + break; + } + if (fd == -1) + { + fprintf(stderr, "socket: cannot create\n"); + return -1; + } + r = connect(fd, rp->ai_addr, rp->ai_addrlen); + if (r) + { + fprintf(stderr, "socket: cannot connect\n"); + return -1; + } + + *conp = xmalloc(sizeof(**conp)); + (*conp)->id = id; + (*conp)->fd = fd; + (*conp)->next = 0; + } + if (sz == 0) + { + struct con *c = *conp; + *conp = c->next; + close(c->fd); + xfree(c); + } + else + { + size_t cnt = 0; + while (cnt < sz) + { + char buf[1024]; + ssize_t w; + size_t r; + size_t toread = sz - cnt; + + if (toread > sizeof(buf)) + toread = sizeof(buf); + r = fread(buf, 1, toread, inf); + if (r != toread) + { + fprintf(stderr, "fread truncated. toread=%lld r=%lld\n", + (long long) toread, (long long) r); + return -1; + } + w = write((*conp)->fd, buf, toread); + if (w != toread) + { + fprintf(stderr, "write truncated\n"); + return -1; + } + cnt += toread; + } + } + } + return 0; +} + +static void usage(void) +{ + fprintf(stderr, "Usage: pazpar2_play infile host\n" + " -v level Set log level\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + int ret; + char *arg; + char *host = 0; + const char *file = 0; + while ((ret = options("v:", argv, argc, &arg)) != -2) + { + switch (ret) + { + case 'v': + yaz_log_init_level(yaz_log_mask_str(arg)); + break; + case 0: + if (!file) + file = arg; + else if (!host) + host = xstrdup(arg); + else + { + usage(); + } + break; + default: + usage(); + exit(1); + } + } + if (host && file) + { + char *port; + char *cp; + FILE *inf; + + struct addrinfo hints, *res; + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + cp = strchr(host, ':'); + if (*cp) + { + *cp = 0; + port = cp+1; + } + else + { + port = "80"; + } + if (getaddrinfo(host, port, &hints, &res)) + { + fprintf(stderr, "cannot resolve %s:%s\n", host, port); + exit(1); + } + + inf = fopen(file, "rb"); + if (!inf) + { + fprintf(stderr, "cannot open %s\n", file); + exit(1); + } + run(inf, res); + fclose(inf); + } + else + usage(); + return 0; +} + + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +