X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Fclient.c;h=076b5e5e9f66a95043ce177998f3d27a3bf8aeac;hb=8c04107cfb8985794d301b2c58a0b5c60723c487;hp=dffb359fe1aba1ba2d5a91967d342596f45a7abf;hpb=c0a89e3e20189dbb2073522cc888e5b84a53df04;p=pazpar2-moved-to-github.git diff --git a/src/client.c b/src/client.c index dffb359..076b5e5 100644 --- a/src/client.c +++ b/src/client.c @@ -1,7 +1,5 @@ -/* $Id: client.c,v 1.27 2007-10-02 10:32:03 adam Exp $ - Copyright (c) 2006-2007, Index Data. - -This file is part of Pazpar2. +/* This file is part of Pazpar2. + Copyright (C) 2006-2008 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 @@ -14,22 +12,34 @@ 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 Pazpar2; see the file LICENSE. If not, write to the -Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - */ +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ /** \file client.c \brief Z39.50 client */ +#if HAVE_CONFIG_H +#include +#endif + #include #include #include +#if HAVE_SYS_TIME_H #include +#endif +#if HAVE_UNISTD_H #include +#endif +#if HAVE_SYS_SOCKET_H #include +#endif +#if HAVE_NETDB_H #include +#endif #include #include #include @@ -48,16 +58,14 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include -#if HAVE_CONFIG_H -#include "cconfig.h" -#endif - #define USE_TIMING 0 #if USE_TIMING #include #endif +#if HAVE_NETINET_IN_H #include +#endif #include "pazpar2.h" @@ -84,11 +92,13 @@ struct client { struct show_raw { int active; // whether this request has been sent to the server int position; + int binary; char *syntax; char *esn; void (*error_handler)(void *data, const char *addinfo); void (*record_handler)(void *data, const char *buf, size_t sz); void *data; + struct show_raw *next; }; static const char *client_states[] = { @@ -236,32 +246,37 @@ int client_show_raw_begin(struct client *cl, int position, void *data, void (*error_handler)(void *data, const char *addinfo), void (*record_handler)(void *data, const char *buf, - size_t sz)) + size_t sz), + void **data2, + int binary) { - if (cl->show_raw) - { /* raw show already in progress */ - return -1; - } + struct show_raw *rr, **rrp; if (!cl->connection) { /* the client has no connection */ - return -2; + return -1; } - cl->show_raw = xmalloc(sizeof(*cl->show_raw)); - cl->show_raw->position = position; - cl->show_raw->active = 0; - cl->show_raw->data = data; - cl->show_raw->error_handler = error_handler; - cl->show_raw->record_handler = record_handler; + rr = xmalloc(sizeof(*rr)); + *data2 = rr; + rr->position = position; + rr->active = 0; + rr->data = data; + rr->error_handler = error_handler; + rr->record_handler = record_handler; + rr->binary = binary; if (syntax) - cl->show_raw->syntax = xstrdup(syntax); + rr->syntax = xstrdup(syntax); else - cl->show_raw->syntax = 0; + rr->syntax = 0; if (esn) - cl->show_raw->esn = xstrdup(esn); + rr->esn = xstrdup(esn); else - cl->show_raw->esn = 0; + rr->esn = 0; + rr->next = 0; + + for (rrp = &cl->show_raw; *rrp; rrp = &(*rrp)->next) + ; + *rrp = rr; - if (cl->state == Client_Failed) { client_show_raw_error(cl, "client failed"); @@ -277,27 +292,42 @@ int client_show_raw_begin(struct client *cl, int position, return 0; } -void client_show_raw_reset(struct client *cl) +void client_show_raw_remove(struct client *cl, void *data) +{ + struct show_raw *rr = data; + struct show_raw **rrp = &cl->show_raw; + while (*rrp != rr) + rrp = &(*rrp)->next; + if (*rrp) + { + *rrp = rr->next; + xfree(rr); + } +} + +void client_show_raw_dequeue(struct client *cl) { - xfree(cl->show_raw); - cl->show_raw = 0; + struct show_raw *rr = cl->show_raw; + + cl->show_raw = rr->next; + xfree(rr); } static void client_show_raw_error(struct client *cl, const char *addinfo) { - if (cl->show_raw) + while (cl->show_raw) { cl->show_raw->error_handler(cl->show_raw->data, addinfo); - client_show_raw_reset(cl); + client_show_raw_dequeue(cl); } } static void client_show_raw_cancel(struct client *cl) { - if (cl->show_raw) + while (cl->show_raw) { cl->show_raw->error_handler(cl->show_raw->data, "cancel"); - client_show_raw_reset(cl); + client_show_raw_dequeue(cl); } } @@ -545,6 +575,21 @@ static void ingest_raw_records(struct client *cl, Z_Records *r) return; } + if (cl->show_raw && cl->show_raw->binary) + { + Z_External *rec = npr->u.databaseRecord; + if (rec->which == Z_External_octet) + { + cl->show_raw->record_handler(cl->show_raw->data, + (const char *) + rec->u.octet_aligned->buf, + rec->u.octet_aligned->len); + client_show_raw_dequeue(cl); + } + else + client_show_raw_error(cl, "no records"); + } + doc = record_to_xml(client_get_database(cl), npr->u.databaseRecord); if (!doc) { @@ -555,12 +600,13 @@ static void ingest_raw_records(struct client *cl, Z_Records *r) xmlDocDumpMemory(doc, &buf_out, &len_out); xmlFreeDoc(doc); - cl->show_raw->record_handler(cl->show_raw->data, - (const char *) buf_out, len_out); - + if (cl->show_raw) + { + cl->show_raw->record_handler(cl->show_raw->data, + (const char *) buf_out, len_out); + client_show_raw_dequeue(cl); + } xmlFree(buf_out); - xfree(cl->show_raw); - cl->show_raw = 0; } static void ingest_records(struct client *cl, Z_Records *r)