GPLv2. Added appendix with full license. Added refernece to that from
[pazpar2-moved-to-github.git] / src / pazpar2.c
index 63966b1..7875938 100644 (file)
@@ -1,4 +1,23 @@
-/* $Id: pazpar2.c,v 1.64 2007-04-08 20:52:09 quinn Exp $ */
+/* $Id: pazpar2.c,v 1.70 2007-04-10 08:48:56 adam Exp $
+   Copyright (c) 2006-2007, Index Data.
+
+This file is part of Pazpar2.
+
+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 Pazpar2; see the file LICENSE.  If not, write to the
+Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+ */
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -48,7 +67,6 @@ static void client_fatal(struct client *cl);
 static void connection_destroy(struct connection *co);
 static int client_prep_connection(struct client *cl);
 static void ingest_records(struct client *cl, Z_Records *r);
-//static struct conf_retrievalprofile *database_retrieval_profile(struct database *db);
 void session_alert_watch(struct session *s, int what);
 char *session_setting_oneval(struct session *s, struct database *db, int offset);
 
@@ -119,6 +137,23 @@ static int send_apdu(struct client *c, Z_APDU *a)
     return 0;
 }
 
+// Set authentication token in init if one is set for the client
+// TODO: Extend this to handle other schemes than open (should be simple)
+static void init_authentication(struct client *cl, Z_InitRequest *req)
+{
+    struct database *db = cl->database;
+    struct session *se = cl->session;
+    char *auth = session_setting_oneval(se, db, PZ_AUTHENTICATION);
+
+    if (auth)
+    {
+        Z_IdAuthentication *idAuth = odr_malloc(global_parameters.odr_out,
+                sizeof(*idAuth));
+        idAuth->which = Z_IdAuthentication_open;
+        idAuth->u.open = auth;
+        req->idAuthentication = idAuth;
+    }
+}
 
 static void send_init(IOCHAN i)
 {
@@ -139,6 +174,7 @@ static void send_init(IOCHAN i)
     ODR_MASK_SET(a->u.initRequest->protocolVersion, Z_ProtocolVersion_2);
     ODR_MASK_SET(a->u.initRequest->protocolVersion, Z_ProtocolVersion_3);
 
+    init_authentication(cl, a->u.initRequest);
 
     /* add virtual host if tunneling through Z39.50 proxy */
     
@@ -147,8 +183,6 @@ static void send_init(IOCHAN i)
         yaz_oi_set_string_oidval(&a->u.initRequest->otherInfo, 
                                  global_parameters.odr_out, VAL_PROXY,
                                  1, cl->database->url);
-    
-
 
     if (send_apdu(cl, a) >= 0)
     {
@@ -232,7 +266,7 @@ static void send_search(IOCHAN i)
 
     if (!(piggyback = session_setting_oneval(se, db, PZ_PIGGYBACK)) || *piggyback == '1')
     {
-        if ((recsyn = session_setting_oneval(se, db, PZ_NATIVESYNTAX)))
+        if ((recsyn = session_setting_oneval(se, db, PZ_REQUESTSYNTAX)))
             a->u.searchRequest->preferredRecordSyntax =
                     yaz_str_to_z3950oid(global_parameters.odr_out,
                     CLASS_RECSYN, recsyn);
@@ -280,7 +314,7 @@ static void send_present(IOCHAN i)
 
     a->u.presentRequest->resultSetId = "Default";
 
-    if ((recsyn = session_setting_oneval(se, db, PZ_NATIVESYNTAX)))
+    if ((recsyn = session_setting_oneval(se, db, PZ_REQUESTSYNTAX)))
         a->u.presentRequest->preferredRecordSyntax =
                 yaz_str_to_z3950oid(global_parameters.odr_out,
                 CLASS_RECSYN, recsyn);
@@ -1063,7 +1097,7 @@ static struct connection *connection_create(struct client *cl)
     cl->connection = new;
     new->link = link;
 
-    new->iochan = iochan_create(cs_fileno(link), 0, handler, 0);
+    new->iochan = iochan_create(cs_fileno(link), handler, 0);
     iochan_setdata(new->iochan, new);
     new->iochan->next = channel_list;
     channel_list = new->iochan;
@@ -1124,114 +1158,6 @@ static int client_prep_connection(struct client *cl)
         return 0;
 }
 
-#ifdef GAGA // Moved to database.c
-
-// This function will most likely vanish when a proper target profile mechanism is
-// introduced.
-void load_simpletargets(const char *fn)
-{
-    FILE *f = fopen(fn, "r");
-    char line[256];
-
-    if (!f)
-    {
-        yaz_log(YLOG_WARN|YLOG_ERRNO, "open %s", fn);
-        exit(1);
-    }
-
-    while (fgets(line, 255, f))
-    {
-        char *url, *db;
-        char *name;
-        struct host *host;
-        struct database *database;
-
-        if (strncmp(line, "target ", 7))
-            continue;
-        line[strlen(line) - 1] = '\0';
-
-        if ((name = strchr(line, ';')))
-            *(name++) = '\0';
-
-        url = line + 7;
-        if ((db = strchr(url, '/')))
-            *(db++) = '\0';
-        else
-            db = "Default";
-
-        yaz_log(YLOG_LOG, "Target: %s, '%s'", url, db);
-        for (host = hosts; host; host = host->next)
-            if (!strcmp((const char *) url, host->hostport))
-                break;
-        if (!host)
-        {
-            struct addrinfo *addrinfo, hints;
-            char *port;
-            char ipport[128];
-            unsigned char addrbuf[4];
-            int res;
-
-            host = xmalloc(sizeof(struct host));
-            host->hostport = xstrdup(url);
-            host->connections = 0;
-
-            if ((port = strchr(url, ':')))
-                *(port++) = '\0';
-            else
-                port = "210";
-
-            hints.ai_flags = 0;
-            hints.ai_family = PF_INET;
-            hints.ai_socktype = SOCK_STREAM;
-            hints.ai_protocol = IPPROTO_TCP;
-            hints.ai_addrlen = 0;
-            hints.ai_addr = 0;
-            hints.ai_canonname = 0;
-            hints.ai_next = 0;
-            // This is not robust code. It assumes that getaddrinfo returns AF_INET
-            // address.
-            if ((res = getaddrinfo(url, port, &hints, &addrinfo)))
-            {
-                yaz_log(YLOG_WARN, "Failed to resolve %s: %s", url, gai_strerror(res));
-                xfree(host->hostport);
-                xfree(host);
-                continue;
-            }
-            assert(addrinfo->ai_family == PF_INET);
-            memcpy(addrbuf, &((struct sockaddr_in*)addrinfo->ai_addr)->sin_addr.s_addr, 4);
-            sprintf(ipport, "%u.%u.%u.%u:%s",
-                    addrbuf[0], addrbuf[1], addrbuf[2], addrbuf[3], port);
-            host->ipport = xstrdup(ipport);
-            freeaddrinfo(addrinfo);
-            host->next = hosts;
-            hosts = host;
-        }
-        database = xmalloc(sizeof(struct database));
-        database->host = host;
-        database->url = xmalloc(strlen(url) + strlen(db) + 2);
-        strcpy(database->url, url);
-        strcat(database->url, "/");
-        strcat(database->url, db);
-        if (name)
-            database->name = xstrdup(name);
-        else
-            database->name = 0;
-        
-        database->databases = xmalloc(2 * sizeof(char *));
-        database->databases[0] = xstrdup(db);
-        database->databases[1] = 0;
-        database->errors = 0;
-        database->qprofile = 0;
-        database->rprofile = database_retrieval_profile(database);
-        database->next = databases;
-        databases = database;
-
-    }
-    fclose(f);
-}
-
-#endif
-
 static struct client *client_create(void)
 {
     struct client *r;
@@ -1300,7 +1226,6 @@ static void select_targets_callback(void *context, struct database *db)
     se->clients = cl;
 }
 
-// This should be extended with parameters to control selection criteria
 // Associates a set of clients with a session;
 int select_targets(struct session *se, struct database_criterion *crit)
 {
@@ -1377,7 +1302,6 @@ char *search(struct session *se, char *query, char *filter)
     criteria = parse_filter(se->nmem, filter);
     strcpy(se->query, query);
     se->requestid++;
-    // Release any existing clients
     select_targets(se, criteria);
     for (cl = se->clients; cl; cl = cl->next)
     {
@@ -1409,12 +1333,12 @@ void destroy_session(struct session *s)
     wrbuf_destroy(s->wrbuf);
 }
 
-struct session *new_session() 
+struct session *new_session(NMEM nmem) 
 {
     int i;
-    struct session *session = xmalloc(sizeof(*session));
+    struct session *session = nmem_malloc(nmem, sizeof(*session));
 
-    yaz_log(YLOG_DEBUG, "New pazpar2 session");
+    yaz_log(YLOG_DEBUG, "New Pazpar2 session");
     
     session->total_hits = 0;
     session->total_records = 0;
@@ -1424,6 +1348,7 @@ struct session *new_session()
     session->clients = 0;
     session->expected_maxrecs = 0;
     session->query[0] = '\0';
+    session->session_nmem = nmem;
     session->nmem = nmem_create();
     session->wrbuf = wrbuf_alloc();
     for (i = 0; i <= SESSION_WATCH_MAX; i++)