Logo Search packages:      
Sourcecode: lfc version File versions  Download package

srmv1_procreq.c

/*
 * Copyright (C) 2004-2008 by CERN
 * All rights reserved
 */

#ifndef lint
static char sccsid[] = "@(#)$RCSfile: srmv1_procreq.c,v $ $Revision: 1.32 $ $Date: 2009/08/27 13:04:10 $ CERN Jean-Philippe Baud";
#endif /* not lint */

#include <sys/types.h>
#include "Cgrp.h"
#include "Cnetdb.h"
#include "Cpwd.h"
#include "dpm.h"
#include "dpm_api.h"
#include "dpm_server.h"
#include "dpm_util.h"
#include "dpns_api.h"
#include "serrno.h"
#include "srm_server.h"
#include "srmv1H.h"
extern char db_name[33];
extern char db_pwd[33];
extern char db_srvr[33];
extern char db_user[33];
static char *f_stat[] = {"Ready", "Pending", "Pending", "Ready", "Running", "Done", "Failed", "Failed", "", "", "Done", "Pending"};
extern char localdomain[CA_MAXHOSTNAMELEN+1];
extern int nb_supported_protocols;
extern char **supported_protocols;
char *Cencode_groups (int, gid_t *, char *);
static int na_key = -1;

int ns5__put (struct soap *soap, struct ArrayOfstring *srcarray, struct ArrayOfstring *surlarray, struct ArrayOflong *sizearray, struct ArrayOfboolean *permarray, struct ArrayOfstring *protoarray, struct ns5__putResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      struct dpm_req dpm_req;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      int i;
      int j;
      char logbuf[CA_MAXSFNLEN+16];
      int nbfqans;
      int nbgids;
      int nbreqfiles;
      int nb_file_err = 0;
      struct dpm_put_filereq pfr_entry;
      struct ns1__RequestFileStatus *repfilep;
      char selected_protocol[CA_MAXPROTOLEN+1];
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      u_signed64 unique_id;
      char *voname;

      strcpy (func, "put");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            soap_sender_fault (soap, "Could not get user mapping", NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            dpm_client_setVOMS_data (voname, fqan, nbfqans);

      memset ((char *) &dpm_req, 0, sizeof(dpm_req));
      dpm_req.ctime = time (0);
      if (surlarray)
            nbreqfiles = surlarray->__size;
      else {
            nbreqfiles = 0;
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "surlarray is required");
      }

      /* Allocate the reply structure */

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      if ((rep->_Result->type = soap_strdup (soap, "Put")) == NULL ||
          (rep->_Result->state = soap_malloc (soap, 8)) == NULL ||
          (rep->_Result->submitTime = soap_strdup (soap, soap_dateTime2s (soap, dpm_req.ctime))) == NULL ||
          (rep->_Result->fileStatuses =
            soap_malloc (soap, sizeof(struct ArrayOfRequestFileStatus))) == NULL ||
          (nbreqfiles > 0 && (rep->_Result->fileStatuses->__ptr =
            soap_malloc (soap, nbreqfiles * sizeof(struct ns1__RequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      rep->_Result->fileStatuses->__size = nbreqfiles;
      for (i = 0; i < nbreqfiles; i++) {
            if ((rep->_Result->fileStatuses->__ptr[i] =
                soap_malloc (soap, sizeof(struct ns1__RequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
      }

      dpm_req.r_uid = uid;
      dpm_req.r_gid = gid;
      strcpy (dpm_req.client_dn, clientdn);
      (void) Cencode_groups (nbgids, gids, dpm_req.groups);
      strcpy (dpm_req.clienthost, clienthost);
      dpm_req.r_type = 'P';

      /* Negociate protocol */

      if (! protoarray) {
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "protoarray is required");
      } else {
            *selected_protocol = '\0';
            for (i = 0; i < protoarray->__size; i++) {
                  if (! protoarray->__ptr[i]) continue;
                  for (j = 0; j < nb_supported_protocols; j++) {
                        if (strcmp (protoarray->__ptr[i], supported_protocols[j]) == 0) {
                              strcpy (selected_protocol, protoarray->__ptr[i]);
                              break;
                        }
                  }
                  if (*selected_protocol) break;
            }
            if (! *selected_protocol) {
                  dpm_req.status = DPM_FAILED | SEPROTONOTSUP;
                  strcpy (dpm_req.errstring, "Protocol not supported");
            }
      }

      /* Connect to the database if not done yet */

      if (! thip->db_open_done) {
            if (dpm_opendb (db_srvr, db_user, db_pwd, db_name, &thip->dbfd) < 0) {
                  soap_sender_fault (soap, "DB open error", NULL);
                  RETURN (SOAP_FAULT);
            }
            thip->db_open_done = 1;
            thip->last_db_use = time (0);
      } else {
            if ((curtime = time (0)) > thip->last_db_use + DPM_DBPINGI)
                  (void) dpm_pingdb (&thip->dbfd);
            thip->last_db_use = curtime;
      }

      /* Start transaction */

      (void) dpm_start_tr (thip->s, &thip->dbfd);

      if (dpm_unique_id (&thip->dbfd, &unique_id) < 0) {
            soap_sender_fault (soap, "Can't get req uniqueid", NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_req.r_ordinal = unique_id & 0xFFFFFFFF;
      sprintf (dpm_req.r_token, "%d", dpm_req.r_ordinal);
      rep->_Result->requestId = dpm_req.r_ordinal;
      sprintf (logbuf, "put %d %s", dpm_req.r_ordinal, dpm_req.r_token);
      srm_logreq (func, logbuf);

      if (! dpm_req.status)
            dpm_req.status = DPM_QUEUED;
      dpm_req.nbreqfiles = nbreqfiles;

      /* Get and check the individual file requests */

      for (i = 0; i < nbreqfiles; i++) {
            memset (&pfr_entry, 0, sizeof(pfr_entry));
            strcpy (pfr_entry.r_token, dpm_req.r_token);
            pfr_entry.f_ordinal = i;
            pfr_entry.status = DPM_QUEUED;
            if (strlen (surlarray->__ptr[i]) > CA_MAXSFNLEN)
                  pfr_entry.status = DPM_FAILED | SENAMETOOLONG;
            strncpy (pfr_entry.to_surl, surlarray->__ptr[i], CA_MAXSFNLEN);
            if (permarray && i < permarray->__size)
                  pfr_entry.f_type = permarray->__ptr[i] ? 'P' : 'V';
            else
                  pfr_entry.f_type = DEFAULT_SPACE_TYPE;
            pfr_entry.ret_policy = '_';
            pfr_entry.ac_latency = 'O';
            if (sizearray && i < sizearray->__size)
                  pfr_entry.requested_size = sizearray->__ptr[i];
            if (pfr_entry.requested_size & INT64_NEG) {
                  pfr_entry.status = DPM_FAILED | EINVAL;
                  strcpy (pfr_entry.errstring, "negative value for requested size");
            }
            strcpy (pfr_entry.protocol, selected_protocol);
            sprintf (logbuf, "put %d %s", i, pfr_entry.to_surl);
            srm_logreq (func, logbuf);
            if (pfr_entry.status != DPM_QUEUED) {
                  nb_file_err++;
                  if (*pfr_entry.errstring)
                        srmlogit (func, "file %d: %s\n", i, pfr_entry.errstring);
            }
            if (dpm_insert_pfr_entry (&thip->dbfd, &pfr_entry) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }

            repfilep = rep->_Result->fileStatuses->__ptr[i];
            memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
            repfilep->SURL = surlarray->__ptr[i];
            repfilep->state = soap_strdup (soap, f_stat[pfr_entry.status >> 12]);
            repfilep->fileId = i;
      }
      if (dpm_req.status == DPM_QUEUED && nb_file_err == nbreqfiles) {
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "Failed for all SURLs");
      }

      if (dpm_req.status == DPM_QUEUED) {
            if (dpm_insert_pending_entry (&thip->dbfd, &dpm_req) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }
            dpm_end_tr (&thip->dbfd);
            if (dpm_inc_reqctr () < 0)
                  srmlogit (func, "dpm_inc_reqctr failed: %s\n", sstrerror (serrno));
      } else {
            if (dpm_insert_xferreq_entry (&thip->dbfd, &dpm_req) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }
      }

      strcpy (rep->_Result->state, (dpm_req.status == DPM_QUEUED) ? "Pending" : "Failed");
      if (*dpm_req.errstring)
            rep->_Result->errorMessage = soap_strdup (soap, dpm_req.errstring);
      rep->_Result->retryDeltaTime = 1;
      RETURN (SOAP_OK);
}

int ns5__get (struct soap *soap, struct ArrayOfstring *surlarray, struct ArrayOfstring *protoarray, struct ns5__getResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      struct dpm_req dpm_req;
      char **fqan;
      char func[16];
      struct dpm_get_filereq gfr_entry;
      gid_t gid;
      gid_t *gids;
      int i;
      int j;
      char logbuf[CA_MAXSFNLEN+16];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreqfiles;
      struct ns1__RequestFileStatus *repfilep;
      char selected_protocol[CA_MAXPROTOLEN+1];
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      u_signed64 unique_id;
      char *voname;

      strcpy (func, "get");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            soap_sender_fault (soap, "Could not get user mapping", NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            dpm_client_setVOMS_data (voname, fqan, nbfqans);

      memset ((char *) &dpm_req, 0, sizeof(dpm_req));
      dpm_req.ctime = time (0);
      if (surlarray)
            nbreqfiles = surlarray->__size;
      else {
            nbreqfiles = 0;
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "surlarray is required");
      }

      /* Allocate the reply structure */

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      if ((rep->_Result->type = soap_strdup (soap, "Get")) == NULL ||
          (rep->_Result->state = soap_malloc (soap, 8)) == NULL ||
          (rep->_Result->submitTime = soap_strdup (soap, soap_dateTime2s (soap, dpm_req.ctime))) == NULL ||
          (rep->_Result->fileStatuses =
            soap_malloc (soap, sizeof(struct ArrayOfRequestFileStatus))) == NULL ||
          (nbreqfiles > 0 && (rep->_Result->fileStatuses->__ptr =
            soap_malloc (soap, nbreqfiles * sizeof(struct ns1__RequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      rep->_Result->fileStatuses->__size = nbreqfiles;
      for (i = 0; i < nbreqfiles; i++) {
            if ((rep->_Result->fileStatuses->__ptr[i] =
                soap_malloc (soap, sizeof(struct ns1__RequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
      }

      dpm_req.r_uid = uid;
      dpm_req.r_gid = gid;
      strcpy (dpm_req.client_dn, clientdn);
      (void) Cencode_groups (nbgids, gids, dpm_req.groups);
      strcpy (dpm_req.clienthost, clienthost);
      dpm_req.r_type = 'G';

      /* Negociate protocol */

      if (! protoarray) {
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "protoarray is required");
      } else {
            *selected_protocol = '\0';
            for (i = 0; i < protoarray->__size; i++) {
                  if (! protoarray->__ptr[i]) continue;
                  for (j = 0; j < nb_supported_protocols; j++) {
                        if (strcmp (protoarray->__ptr[i], supported_protocols[j]) == 0) {
                              strcpy (selected_protocol, protoarray->__ptr[i]);
                              break;
                        }
                  }
                  if (*selected_protocol) break;
            }
            if (! *selected_protocol) {
                  dpm_req.status = DPM_FAILED | SEPROTONOTSUP;
                  strcpy (dpm_req.errstring, "Protocol not supported");
            }
      }

      /* Connect to the database if not done yet */

      if (! thip->db_open_done) {
            if (dpm_opendb (db_srvr, db_user, db_pwd, db_name, &thip->dbfd) < 0) {
                  soap_sender_fault (soap, "DB open error", NULL);
                  RETURN (SOAP_FAULT);
            }
            thip->db_open_done = 1;
            thip->last_db_use = time (0);
      } else {
            if ((curtime = time (0)) > thip->last_db_use + DPM_DBPINGI)
                  (void) dpm_pingdb (&thip->dbfd);
            thip->last_db_use = curtime;
      }

      /* Start transaction */

      (void) dpm_start_tr (thip->s, &thip->dbfd);

      if (dpm_unique_id (&thip->dbfd, &unique_id) < 0) {
            soap_sender_fault (soap, "Can't get req uniqueid", NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_req.r_ordinal = unique_id & 0xFFFFFFFF;
      sprintf (dpm_req.r_token, "%d", dpm_req.r_ordinal);
      rep->_Result->requestId = dpm_req.r_ordinal;
      sprintf (logbuf, "get %d %s", dpm_req.r_ordinal, dpm_req.r_token);
      srm_logreq (func, logbuf);

      if (! dpm_req.status)
            dpm_req.status = DPM_QUEUED;
      dpm_req.nbreqfiles = nbreqfiles;

      /* Get and check the individual file requests */

      for (i = 0; i < nbreqfiles; i++) {
            memset (&gfr_entry, 0, sizeof(gfr_entry));
            strcpy (gfr_entry.r_token, dpm_req.r_token);
            gfr_entry.f_ordinal = i;
            gfr_entry.r_uid = uid;
            gfr_entry.status = DPM_QUEUED;
            if (strlen (surlarray->__ptr[i]) > CA_MAXSFNLEN)
                  gfr_entry.status = DPM_FAILED | SENAMETOOLONG;
            strncpy (gfr_entry.from_surl, surlarray->__ptr[i], CA_MAXSFNLEN);
            gfr_entry.f_type = 'V';
            gfr_entry.ret_policy = '_';
            strcpy (gfr_entry.protocol, selected_protocol);
            sprintf (logbuf, "get %d %s", i, gfr_entry.from_surl);
            srm_logreq (func, logbuf);
            if (gfr_entry.status != DPM_QUEUED) {
                  nb_file_err++;
                  if (*gfr_entry.errstring)
                        srmlogit (func, "file %d: %s\n", i, gfr_entry.errstring);
            }
            if (dpm_insert_gfr_entry (&thip->dbfd, &gfr_entry) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }

            repfilep = rep->_Result->fileStatuses->__ptr[i];
            memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
            repfilep->SURL = surlarray->__ptr[i];
            repfilep->state = soap_strdup (soap, f_stat[gfr_entry.status >> 12]);
            repfilep->fileId = i;
      }
      if (dpm_req.status == DPM_QUEUED && nb_file_err == nbreqfiles) {
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "Failed for all SURLs");
      }

      if (dpm_req.status == DPM_QUEUED) {
            if (dpm_insert_pending_entry (&thip->dbfd, &dpm_req) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }
            dpm_end_tr (&thip->dbfd);
            if (dpm_inc_reqctr () < 0)
                  srmlogit (func, "dpm_inc_reqctr failed\n");
      } else {
            if (dpm_insert_xferreq_entry (&thip->dbfd, &dpm_req) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }
      }

      strcpy (rep->_Result->state, (dpm_req.status == DPM_QUEUED) ? "Pending" : "Failed");
      if (*dpm_req.errstring)
            rep->_Result->errorMessage = soap_strdup (soap, dpm_req.errstring);
      rep->_Result->retryDeltaTime = 1;
      RETURN (SOAP_OK);
}

int ns5__copy (struct soap *soap, struct ArrayOfstring *from_surls, struct ArrayOfstring *to_surls, struct ArrayOfboolean *rlsarray, struct ns5__copyResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      struct dpm_copy_filereq cpr_entry;
      time_t curtime;
      struct dpm_req dpm_req;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      int i;
      char logbuf[2*CA_MAXSFNLEN+18];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreqfiles;
      char proxy_filename[sizeof(P_tmpdir)+CA_MAXDPMTOKENLEN+4];
      struct ns1__RequestFileStatus *repfilep;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      u_signed64 unique_id;
      char *voname;

      strcpy (func, "copy");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

#if 1
      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      rep->_Result->state = soap_strdup (soap, "Failed");
      rep->_Result->errorMessage = soap_strdup (soap, "Method not supported");
      RETURN (SOAP_OK);
#else
      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            soap_sender_fault (soap, "Could not get user mapping", NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            dpm_client_setVOMS_data (voname, fqan, nbfqans);

      memset ((char *) &dpm_req, 0, sizeof(dpm_req));
      dpm_req.ctime = time (0);
      if (from_surls)
            nbreqfiles = from_surls->__size;
      else {
            nbreqfiles = 0;
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "from_surls is required");
      }
      if (! to_surls) {
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "to_surls is required");
      } else if (to_surls->__size != nbreqfiles) {
            soap_sender_fault (soap, "from_surls and to_surls array sizes are not equal", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      if ((rep->_Result->type = soap_strdup (soap, "Copy")) == NULL ||
          (rep->_Result->state = soap_malloc (soap, 8)) == NULL ||
          (rep->_Result->submitTime = soap_strdup (soap, soap_dateTime2s (soap, dpm_req.ctime))) == NULL ||
          (rep->_Result->fileStatuses =
            soap_malloc (soap, sizeof(struct ArrayOfRequestFileStatus))) == NULL ||
          (nbreqfiles > 0 && (rep->_Result->fileStatuses->__ptr =
            soap_malloc (soap, nbreqfiles * sizeof(struct ns1__RequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      rep->_Result->fileStatuses->__size = nbreqfiles;
      for (i = 0; i < nbreqfiles; i++) {
            if ((rep->_Result->fileStatuses->__ptr[i] =
                soap_malloc (soap, sizeof(struct ns1__RequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
      }

      dpm_req.r_uid = uid;
      dpm_req.r_gid = gid;
      strcpy (dpm_req.client_dn, clientdn);
      (void) Cencode_groups (nbgids, gids, dpm_req.groups);
      strcpy (dpm_req.clienthost, clienthost);
      dpm_req.r_type = 'C';

      /* Connect to the database if not done yet */

      if (! thip->db_open_done) {
            if (dpm_opendb (db_srvr, db_user, db_pwd, db_name, &thip->dbfd) < 0) {
                  soap_sender_fault (soap, "DB open error", NULL);
                  RETURN (SOAP_FAULT);
            }
            thip->db_open_done = 1;
            thip->last_db_use = time (0);
      } else {
            if ((curtime = time (0)) > thip->last_db_use + DPM_DBPINGI)
                  (void) dpm_pingdb (&thip->dbfd);
            thip->last_db_use = curtime;
      }

      /* Start transaction */

      (void) dpm_start_tr (thip->s, &thip->dbfd);

      if (dpm_unique_id (&thip->dbfd, &unique_id) < 0) {
            soap_sender_fault (soap, "Can't get req uniqueid", NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_req.r_ordinal = unique_id & 0xFFFFFFFF;
      sprintf (dpm_req.r_token, "%d", dpm_req.r_ordinal);
      rep->_Result->requestId = dpm_req.r_ordinal;
      sprintf (logbuf, "copy %d %s", dpm_req.r_ordinal, dpm_req.r_token);
      srm_logreq (func, logbuf);

      if (! dpm_req.status)
            dpm_req.status = DPM_QUEUED;
      dpm_req.nbreqfiles = nbreqfiles;

      /* Get and check the individual file requests */

      for (i = 0; i < nbreqfiles; i++) {
            memset (&cpr_entry, 0, sizeof(cpr_entry));
            strcpy (cpr_entry.r_token, dpm_req.r_token);
            cpr_entry.f_ordinal = i;
            cpr_entry.status = DPM_QUEUED;
            if (strlen (from_surls->__ptr[i]) > CA_MAXSFNLEN)
                  cpr_entry.status = DPM_FAILED | SENAMETOOLONG;
            strncpy (cpr_entry.from_surl, from_surls->__ptr[i], CA_MAXSFNLEN);
            if (strlen (to_surls->__ptr[i]) > CA_MAXSFNLEN)
                  cpr_entry.status = DPM_FAILED | SENAMETOOLONG;
            strncpy (cpr_entry.to_surl, to_surls->__ptr[i], CA_MAXSFNLEN);
            cpr_entry.f_type = '_';
            cpr_entry.ret_policy = '_';
            cpr_entry.ac_latency = '_';
            sprintf (logbuf, "copy %d %s %s", i, cpr_entry.from_surl,
                cpr_entry.to_surl);
            srm_logreq (func, logbuf);
            if (cpr_entry.status != DPM_QUEUED) {
                  nb_file_err++;
                  if (*cpr_entry.errstring)
                        srmlogit (func, "file %d: %s\n", i, cpr_entry.errstring);
            }
            if (dpm_insert_cpr_entry (&thip->dbfd, &cpr_entry) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }

            repfilep = rep->_Result->fileStatuses->__ptr[i];
            memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
            repfilep->SURL = is_surl_local (from_surls->__ptr[i]) ?
                from_surls->__ptr[i] : to_surls->__ptr[i];
            repfilep->state = soap_strdup (soap, f_stat[cpr_entry.status >> 12]);
            repfilep->fileId = i;
            repfilep->sourceFilename = from_surls->__ptr[i];
            repfilep->destFilename = to_surls->__ptr[i];
      }
      if (dpm_req.status == DPM_QUEUED && nb_file_err == nbreqfiles) {
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "Failed for all SURLs");
      }

      if (dpm_req.status == DPM_QUEUED) {
            if (! has_delegated_credentials (soap)) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "No delegated credential available");
            } else {
                  (void) build_proxy_filename (proxy_filename, dpm_req.r_token);
                  if (export_delegated_credentials (soap, proxy_filename) < 0) {
                        dpm_req.status = DPM_FAILED | EINVAL;
                        strcpy (dpm_req.errstring, "Could not export credentials");
                  }
            }
      }

      if (dpm_req.status == DPM_QUEUED) {
            dpm_req.status = DPM_QUEUED4COPY;
            if (dpm_insert_pending_entry (&thip->dbfd, &dpm_req) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }
            dpm_end_tr (&thip->dbfd);
            if (dpmcopy_inc_reqctr () < 0)
                  srmlogit (func, "dpmcopy_inc_reqctr failed\n");
      } else {
            if (dpm_insert_xferreq_entry (&thip->dbfd, &dpm_req) < 0) {
                  soap_sender_fault (soap, "DB insert error", NULL);
                  RETURN (SOAP_FAULT);
            }
      }

      strcpy (rep->_Result->state, (dpm_req.status == DPM_QUEUED) ? "Pending" : "Failed");
      if (*dpm_req.errstring)
            rep->_Result->errorMessage = soap_strdup (soap, dpm_req.errstring);
      rep->_Result->retryDeltaTime = 1;
#endif
      RETURN (SOAP_OK);
}

int ns5__ping (struct soap *soap, struct ns5__pingResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "ping");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      rep->_Result = true_;
      RETURN (SOAP_OK);
}

int ns5__pin (struct soap *soap, struct ArrayOfstring *turlarray, struct ns5__pinResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "pin");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      rep->_Result->state = soap_strdup (soap, "Failed");
      rep->_Result->errorMessage = soap_strdup (soap, "Method not supported");
      RETURN (SOAP_OK);
}

int ns5__unPin (struct soap *soap, struct ArrayOfstring *turlarray, int reqid, struct ns5__unPinResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "unPin");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      rep->_Result->state = soap_strdup (soap, "Failed");
      rep->_Result->errorMessage = soap_strdup (soap, "Method not supported");
      RETURN (SOAP_OK);
}

int ns5__setFileStatus (struct soap *soap, int reqid, int fileid, char *state, struct ns5__setFileStatusResponse *rep)
{
      int bol;
      int c;
      char clientdn[256];
      const char *clienthost;
      struct dpm_copy_filereq cpr_entry;
      time_t curtime;
      DBLISTPTR dblistptr;
      struct dpm_req dpm_req;
      int errflag = 0;
      struct dpm_filestatus *filestatuses = NULL;
      char **fqan;
      char func[16];
      struct dpm_get_filereq gfr_entry;
      gid_t gid;
      gid_t *gids;
      int i;
      int istate;
      char logbuf[44];
      int nbfqans;
      int nbgids;
      int nbreplies = 0;
      char *p;
      struct dpm_put_filereq pfr_entry;
      char r_token[CA_MAXDPMTOKENLEN+1];
      dpm_dbrec_addr rec_addrf;
      struct ns1__RequestFileStatus *repfilep;
      char *surl;
      struct srm_srv_thread_info *thip = soap->user;
      char turl[CA_MAXSFNLEN+1];
      uid_t uid;
      char *voname;

      strcpy (func, "setFileStatus");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            soap_sender_fault (soap, "Could not get user mapping", NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            dpm_client_setVOMS_data (voname, fqan, nbfqans);

      /* Allocate the reply structure */

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));

      /* Connect to the database if not done yet */

      if (! thip->db_open_done) {
            if (dpm_opendb (db_srvr, db_user, db_pwd, db_name, &thip->dbfd) < 0) {
                  soap_sender_fault (soap, "DB open error", NULL);
                  RETURN (SOAP_FAULT);
            }
            thip->db_open_done = 1;
            thip->last_db_use = time (0);
      } else {
            if ((curtime = time (0)) > thip->last_db_use + DPM_DBPINGI)
                  (void) dpm_pingdb (&thip->dbfd);
            thip->last_db_use = curtime;
      }

      /* Get the request type */

      sprintf (r_token, "%d", reqid);
      sprintf (logbuf, "setFileStatus %d %d %.7s", reqid, fileid, state ? state : "NULL");
      srm_logreq (func, logbuf);
      if (! state) {
            soap_sender_fault (soap, "state is required", NULL);
            RETURN (SOAP_FAULT);
      }
      if (dpm_get_pending_req_by_token (&thip->dbfd, r_token, &dpm_req, 0, NULL) < 0 &&
          dpm_get_req_by_token (&thip->dbfd, r_token, &dpm_req, 0, NULL) < 0) {
            if (serrno == ENOENT) {
                  rep->_Result->errorMessage = soap_strdup (soap, "Unknown reqid");
                  RETURN (SOAP_OK);
            }
            soap_sender_fault (soap, "DB fetch error", NULL);
            RETURN (SOAP_FAULT);
      }
      if ((rep->_Result->type = soap_malloc (soap, 5)) == NULL ||
          (rep->_Result->state = soap_malloc (soap, 8)) == NULL ||
          (rep->_Result->submitTime = soap_strdup (soap, soap_dateTime2s (soap, dpm_req.ctime))) == NULL ||
          (dpm_req.stime && (rep->_Result->startTime =
            soap_strdup (soap, soap_dateTime2s (soap, dpm_req.stime))) == NULL) ||
          (dpm_req.etime && (rep->_Result->finishTime =
            soap_strdup (soap, soap_dateTime2s (soap, dpm_req.etime))) == NULL) ||
          (rep->_Result->fileStatuses =
            soap_malloc (soap, sizeof(struct ArrayOfRequestFileStatus))) == NULL ||
          (dpm_req.nbreqfiles > 0 && (rep->_Result->fileStatuses->__ptr =
            soap_malloc (soap, dpm_req.nbreqfiles * sizeof(struct ns1__RequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      rep->_Result->fileStatuses->__size = dpm_req.nbreqfiles;
      for (i = 0; i < dpm_req.nbreqfiles; i++) {
            if ((rep->_Result->fileStatuses->__ptr[i] =
                soap_malloc (soap, sizeof(struct ns1__RequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
      }
      rep->_Result->requestId = reqid;

      /* Check the specified state */

      for (i = 0; i < sizeof(f_stat)/sizeof(char *); i++)
            if (strcmp (state, f_stat[i]) == 0) break;
      if (i >= sizeof(f_stat)/sizeof(char *)) {
            soap_sender_fault (soap, "Invalid state", NULL);
            RETURN (SOAP_FAULT);
      }
      istate = i << 12;

      /* Start transaction */

      (void) dpm_start_tr (thip->s, &thip->dbfd);

      /* Update the file status and return all file requests for this reqid */

      bol = 1;
      i = 0;
      switch (dpm_req.r_type) {
      case 'C':
            if (dpm_get_cpr_by_fullid (&thip->dbfd, dpm_req.r_token,
                fileid, &cpr_entry, 1, &rec_addrf) < 0) {
                  soap_sender_fault (soap, sstrerror (serrno), NULL);
                  RETURN (SOAP_FAULT);
            }
            switch (istate) {
            case DPM_DONE:
                  break;
            case DPM_FAILED:
                  break;
            default:
                  errflag = 1;
            }
            if (errflag) {
                  soap_sender_fault (soap, "Invalid state", NULL);
                  RETURN (SOAP_FAULT);
            }
            cpr_entry.status = istate;
            if (dpm_update_cpr_entry (&thip->dbfd, &rec_addrf, &cpr_entry) < 0) {
                  soap_sender_fault (soap, "DB update error", NULL);
                  RETURN (SOAP_FAULT);
            }
            strcpy (rep->_Result->type, "Copy");
            while ((c = dpm_list_cpr_entry (&thip->dbfd, bol, r_token,
                &cpr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  repfilep = rep->_Result->fileStatuses->__ptr[i];
                  memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
                  repfilep->SURL = is_surl_local (cpr_entry.from_surl) ?
                        soap_strdup (soap, cpr_entry.from_surl) :
                        soap_strdup (soap, cpr_entry.to_surl);
                  repfilep->size = cpr_entry.actual_size;
                  repfilep->state = soap_strdup (soap, f_stat[cpr_entry.status >> 12]);
                  repfilep->fileId = i;
                  repfilep->sourceFilename = soap_strdup (soap, cpr_entry.from_surl);
                  repfilep->destFilename = soap_strdup (soap, cpr_entry.from_surl);
                  i++;
            }
            (void) dpm_list_cpr_entry (&thip->dbfd, bol, r_token,
                &cpr_entry, 0, NULL, 1, &dblistptr);  /* free res */
            break;
      case 'G':
            if (dpm_get_gfr_by_fullid (&thip->dbfd, dpm_req.r_token,
                fileid, &gfr_entry, 1, &rec_addrf) < 0) {
                  soap_sender_fault (soap, sstrerror (serrno), NULL);
                  RETURN (SOAP_FAULT);
            }
            switch (istate) {
            case DPM_RUNNING:
                  if (gfr_entry.status != DPM_READY) errflag = 1;
                  break;
            case DPM_DONE:
                  if (gfr_entry.status != DPM_READY &&
                      gfr_entry.status != DPM_RUNNING) errflag = 1;
                  break;
            case DPM_FAILED:
                  break;
            default:
                  errflag = 1;
            }
            if (errflag) {
                  soap_sender_fault (soap, "Invalid state", NULL);
                  RETURN (SOAP_FAULT);
            }
            gfr_entry.status = istate;
            if (dpm_update_gfr_entry (&thip->dbfd, &rec_addrf, &gfr_entry) < 0) {
                  soap_sender_fault (soap, "DB update error", NULL);
                  RETURN (SOAP_FAULT);
            }
            strcpy (rep->_Result->type, "Get");
            while ((c = dpm_list_gfr_entry (&thip->dbfd, bol, r_token,
                &gfr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  repfilep = rep->_Result->fileStatuses->__ptr[i];
                  memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
                  repfilep->SURL = soap_strdup (soap, gfr_entry.from_surl);
                  repfilep->size = gfr_entry.actual_size;
                  repfilep->state = soap_strdup (soap, f_stat[gfr_entry.status >> 12]);
                  repfilep->fileId = i;
                  if (*gfr_entry.pfn) {
                        if (strcmp (gfr_entry.protocol, "rfio") == 0)
                              p = strchr (gfr_entry.pfn, ':') + 1;
                        else
                              p = gfr_entry.pfn;
                        sprintf (turl, "%s://%s/%s", gfr_entry.protocol,
                            gfr_entry.server, p);
                        repfilep->TURL = soap_strdup (soap, turl);
                  }
                  i++;
            }
            (void) dpm_list_gfr_entry (&thip->dbfd, bol, r_token,
                &gfr_entry, 0, NULL, 1, &dblistptr);  /* free res */
            break;
      case 'P':
            if (dpm_get_pfr_by_fullid (&thip->dbfd, dpm_req.r_token,
                fileid, &pfr_entry, istate != DPM_DONE ? 1 : 0, &rec_addrf) < 0) {
                  soap_sender_fault (soap, sstrerror (serrno), NULL);
                  RETURN (SOAP_FAULT);
            }
            switch (istate) {
            case DPM_RUNNING:
                  if (pfr_entry.status != DPM_READY) errflag = 1;
                  break;
            case DPM_DONE:
                  if (pfr_entry.status != DPM_READY &&
                      pfr_entry.status != DPM_RUNNING) errflag = 1;
                  break;
            case DPM_FAILED:
                  break;
            default:
                  errflag = 1;
            }
            if (errflag) {
                  soap_sender_fault (soap, "Invalid state", NULL);
                  RETURN (SOAP_FAULT);
            }
            if (istate == DPM_DONE) {
                  surl = pfr_entry.to_surl;
                  if ((c = dpm_putdone (r_token, 1, &surl, &nbreplies,
                      &filestatuses)) < 0) {
                        srmlogit (func, "dpm_putdone failed: %s\n", sstrerror (serrno));
                        dpm_free_filest (nbreplies, filestatuses);
                        soap_sender_fault (soap, sstrerror (serrno), NULL);
                        RETURN (SOAP_FAULT);
                  }
                  if (c == DPM_EXPIRED) {
                        dpm_free_filest (nbreplies, filestatuses);
                        soap_sender_fault (soap, "TURL expired", NULL);
                        RETURN (SOAP_FAULT);
                  }
                  dpm_free_filest (nbreplies, filestatuses);
            } else {
                  pfr_entry.status = istate;
                  if (dpm_update_pfr_entry (&thip->dbfd, &rec_addrf, &pfr_entry) < 0) {
                        soap_sender_fault (soap, "DB update error", NULL);
                        RETURN (SOAP_FAULT);
                  }
            }
            strcpy (rep->_Result->type, "Put");
            while ((c = dpm_list_pfr_entry (&thip->dbfd, bol, r_token,
                &pfr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  repfilep = rep->_Result->fileStatuses->__ptr[i];
                  memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
                  repfilep->SURL = soap_strdup (soap, pfr_entry.to_surl);
                  repfilep->size = (pfr_entry.actual_size & INT64_NEG) ? 0 : pfr_entry.actual_size;
                  repfilep->state = soap_strdup (soap, f_stat[pfr_entry.status >> 12]);
                  repfilep->fileId = i;
                  if (*pfr_entry.pfn) {
                        if (strcmp (pfr_entry.protocol, "rfio") == 0)
                              p = strchr (pfr_entry.pfn, ':') + 1;
                        else
                              p = pfr_entry.pfn;
                        sprintf (turl, "%s://%s/%s", pfr_entry.protocol,
                            pfr_entry.server, p);
                        repfilep->TURL = soap_strdup (soap, turl);
                  }
                  i++;
            }
            (void) dpm_list_pfr_entry (&thip->dbfd, bol, r_token,
                &pfr_entry, 0, NULL, 1, &dblistptr);  /* free res */
            break;
      }

      rep->_Result->fileStatuses->__size = i;
      strcpy (rep->_Result->state, f_stat[dpm_req.status >> 12]);
      if (*dpm_req.errstring)
            rep->_Result->errorMessage = soap_strdup (soap, dpm_req.errstring);
      else if ((dpm_req.status & DPM_FAILED) == DPM_FAILED)
            rep->_Result->errorMessage =
                soap_strdup (soap, sstrerror (dpm_req.status & 0xFFF));
      rep->_Result->retryDeltaTime = 10;
      RETURN (SOAP_OK);
}

int ns5__getRequestStatus (struct soap *soap, int reqid, struct ns5__getRequestStatusResponse *rep)
{
      int bol;
      int c;
      char clientdn[256];
      const char *clienthost;
      struct dpm_copy_filereq cpr_entry;
      time_t curtime;
      DBLISTPTR dblistptr;
      struct dpm_req dpm_req;
      char errstring[256];
      char func[17];
      struct dpm_get_filereq gfr_entry;
      int i;
      char logbuf[29];
      char *p;
      struct dpm_put_filereq pfr_entry;
      char r_token[CA_MAXDPMTOKENLEN+1];
      struct ns1__RequestFileStatus *repfilep;
      struct srm_srv_thread_info *thip = soap->user;
      char turl[CA_MAXSFNLEN+1];

      strcpy (func, "getRequestStatus");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      /* Allocate the reply structure */

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));

      sprintf (logbuf, "getRequestStatus %d", reqid);
      srm_logreq (func, logbuf);

      /* Connect to the database if not done yet */

      if (! thip->db_open_done) {
            if (dpm_opendb (db_srvr, db_user, db_pwd, db_name, &thip->dbfd) < 0) {
                  soap_sender_fault (soap, "DB open error", NULL);
                  RETURN (SOAP_FAULT);
            }
            thip->db_open_done = 1;
            thip->last_db_use = time (0);
      } else {
            if ((curtime = time (0)) > thip->last_db_use + DPM_DBPINGI)
                  (void) dpm_pingdb (&thip->dbfd);
            thip->last_db_use = curtime;
      }

      /* Get the request type */

      sprintf (r_token, "%d", reqid);
      if (dpm_get_pending_req_by_token (&thip->dbfd, r_token, &dpm_req, 0, NULL) < 0 &&
          dpm_get_req_by_token (&thip->dbfd, r_token, &dpm_req, 0, NULL) < 0) {
            if (serrno == ENOENT) {
                  rep->_Result->errorMessage = soap_strdup (soap, "Unknown reqid");
                  RETURN (SOAP_OK);
            }
            soap_sender_fault (soap, "DB fetch error", NULL);
            RETURN (SOAP_FAULT);
      }
      if ((rep->_Result->type = soap_malloc (soap, 5)) == NULL ||
          (rep->_Result->state = soap_malloc (soap, 8)) == NULL ||
          (rep->_Result->submitTime = soap_strdup (soap, soap_dateTime2s (soap, dpm_req.ctime))) == NULL ||
          (dpm_req.stime && (rep->_Result->startTime =
            soap_strdup (soap, soap_dateTime2s (soap, dpm_req.stime))) == NULL) ||
          (dpm_req.etime && (rep->_Result->finishTime =
            soap_strdup (soap, soap_dateTime2s (soap, dpm_req.etime))) == NULL) ||
          (rep->_Result->fileStatuses =
            soap_malloc (soap, sizeof(struct ArrayOfRequestFileStatus))) == NULL ||
          (dpm_req.nbreqfiles > 0 && (rep->_Result->fileStatuses->__ptr =
            soap_malloc (soap, dpm_req.nbreqfiles * sizeof(struct ns1__RequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      rep->_Result->fileStatuses->__size = dpm_req.nbreqfiles;
      for (i = 0; i < dpm_req.nbreqfiles; i++) {
            if ((rep->_Result->fileStatuses->__ptr[i] =
                soap_malloc (soap, sizeof(struct ns1__RequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
      }
      rep->_Result->requestId = reqid;

      /* Return all file requests for this reqid */

      bol = 1;
      errstring[0] = '\0';
      i = 0;
      switch (dpm_req.r_type) {
      case 'C':
            strcpy (rep->_Result->type, "Copy");
            while ((c = dpm_list_cpr_entry (&thip->dbfd, bol, r_token,
                &cpr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  repfilep = rep->_Result->fileStatuses->__ptr[i];
                  memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
                  repfilep->SURL = is_surl_local (cpr_entry.from_surl) ?
                        soap_strdup (soap, cpr_entry.from_surl) :
                        soap_strdup (soap, cpr_entry.to_surl);
                  repfilep->size = cpr_entry.actual_size;
                  repfilep->state = soap_strdup (soap, f_stat[cpr_entry.status >> 12]);
                  repfilep->fileId = i;
                  repfilep->sourceFilename = soap_strdup (soap, cpr_entry.from_surl);
                  repfilep->destFilename = soap_strdup (soap, cpr_entry.from_surl);
                  i++;
            }
            (void) dpm_list_cpr_entry (&thip->dbfd, bol, r_token,
                &cpr_entry, 0, NULL, 1, &dblistptr);  /* free res */
            if (dpm_req.nbreqfiles == 1)
                  strcpy (errstring, cpr_entry.errstring);
            break;
      case 'G':
            strcpy (rep->_Result->type, "Get");
            while ((c = dpm_list_gfr_entry (&thip->dbfd, bol, r_token,
                &gfr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  repfilep = rep->_Result->fileStatuses->__ptr[i];
                  memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
                  repfilep->SURL = soap_strdup (soap, gfr_entry.from_surl);
                  repfilep->size = gfr_entry.actual_size;
                  repfilep->state = soap_strdup (soap, f_stat[gfr_entry.status >> 12]);
                  repfilep->fileId = i;
                  if (*gfr_entry.pfn) {
                        if (strcmp (gfr_entry.protocol, "rfio") == 0)
                              p = strchr (gfr_entry.pfn, ':') + 1;
                        else
                              p = gfr_entry.pfn;
                        sprintf (turl, "%s://%s/%s", gfr_entry.protocol,
                            gfr_entry.server, p);
                        repfilep->TURL = soap_strdup (soap, turl);
                  }
                  i++;
            }
            (void) dpm_list_gfr_entry (&thip->dbfd, bol, r_token,
                &gfr_entry, 0, NULL, 1, &dblistptr);  /* free res */
            if (dpm_req.nbreqfiles == 1)
                  strcpy (errstring, gfr_entry.errstring);
            break;
      case 'P':
            strcpy (rep->_Result->type, "Put");
            while ((c = dpm_list_pfr_entry (&thip->dbfd, bol, r_token,
                &pfr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  repfilep = rep->_Result->fileStatuses->__ptr[i];
                  memset (repfilep, 0, sizeof(struct ns1__RequestFileStatus));
                  repfilep->SURL = soap_strdup (soap, pfr_entry.to_surl);
                  repfilep->size = (pfr_entry.actual_size & INT64_NEG) ? 0 : pfr_entry.actual_size;
                  repfilep->state = soap_strdup (soap, f_stat[pfr_entry.status >> 12]);
                  repfilep->fileId = i;
                  if (*pfr_entry.pfn) {
                        if (strcmp (pfr_entry.protocol, "rfio") == 0)
                              p = strchr (pfr_entry.pfn, ':') + 1;
                        else
                              p = pfr_entry.pfn;
                        sprintf (turl, "%s://%s/%s", pfr_entry.protocol,
                            pfr_entry.server, p);
                        repfilep->TURL = soap_strdup (soap, turl);
                  }
                  i++;
            }
            (void) dpm_list_pfr_entry (&thip->dbfd, bol, r_token,
                &pfr_entry, 0, NULL, 1, &dblistptr);  /* free res */
            if (dpm_req.nbreqfiles == 1)
                  strcpy (errstring, pfr_entry.errstring);
            break;
      }

      strcpy (rep->_Result->state, f_stat[dpm_req.status >> 12]);
      if (*errstring)
            rep->_Result->errorMessage = soap_strdup (soap, errstring);
      else if (*dpm_req.errstring && strcmp (dpm_req.errstring, "Failed for all SURLs"))
            rep->_Result->errorMessage = soap_strdup (soap, dpm_req.errstring);
      else if ((dpm_req.status & DPM_FAILED) == DPM_FAILED)
            rep->_Result->errorMessage =
                soap_strdup (soap, sstrerror (dpm_req.status & 0xFFF));
      rep->_Result->retryDeltaTime = 10;
      RETURN (SOAP_OK);
}

int ns5__getFileMetaData (struct soap *soap, struct ArrayOfstring *surlarray, struct ns5__getFileMetaDataResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      char *errmsg = NULL;
      int flags;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      struct group *gr;
      int i;
      Cns_list list;
      char logbuf[CA_MAXSFNLEN+17];
      struct Cns_filereplica *lp;
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreqfiles;
      struct passwd *pw;
      struct ns1__FileMetaData *repfilep;
      char *sfn;
      struct Cns_filestatg st;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char vidstr[256];
      char *voname;

      strcpy (func, "getFileMetaData");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if (! surlarray) {
            soap_sender_fault (soap, "surlarray is required", NULL);
            RETURN (SOAP_FAULT);
      }
      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            soap_sender_fault (soap, "Could not get user mapping", NULL);
            RETURN (SOAP_FAULT);
      }
      Cns_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      Cns_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            Cns_client_setVOMS_data (voname, fqan, nbfqans);

      nbreqfiles = surlarray->__size;
      if ((rep->_Result = soap_malloc (soap, sizeof(struct ArrayOfFileMetaData))) == NULL ||
          (rep->_Result->__ptr =
            soap_malloc (soap, nbreqfiles * sizeof(struct ns1__FileMetaData *))) == NULL) {
            RETURN (SOAP_EOM);
      }
      rep->_Result->__size = nbreqfiles;
      for (i = 0; i < nbreqfiles; i++) {
            sprintf (logbuf, "getFileMetaData %.1103s", surlarray->__ptr[i]);
            srm_logreq (func, logbuf);
            if ((rep->_Result->__ptr[i] = repfilep =
                soap_malloc (soap, sizeof(struct ns1__FileMetaData))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repfilep, 0, sizeof(struct ns1__FileMetaData));
            if ((sfn = sfnfromsurl (surlarray->__ptr[i])) == NULL) {
                  nb_file_err++;
                  if (! errmsg)
                        errmsg = soap_strdup (soap, "bad SURL syntax");
                  continue;
            }
            if (Cns_statg (sfn, NULL, &st) < 0) {
                  nb_file_err++;
                  if (! errmsg)
                        errmsg = soap_strdup (soap, sstrerror (serrno));
                  continue;
            }
            repfilep->SURL = surlarray->__ptr[i];
            repfilep->size = st.filesize;
#ifdef VIRTUAL_ID
            if (st.uid == 0)
                  repfilep->owner = soap_strdup (soap, "root");
            else if (Cns_getusrbyuid (st.uid, vidstr) == 0)
                  repfilep->owner = soap_strdup (soap, vidstr);
            if (st.gid == 0)
                  repfilep->group = soap_strdup (soap, "root");
            else if (Cns_getgrpbygid (st.gid, vidstr) == 0)
                  repfilep->group = soap_strdup (soap, vidstr);
#else
            if ((pw = Cgetpwuid (st.uid)))
                  repfilep->owner = soap_strdup (soap, pw->pw_name);
            if ((gr = Cgetgrgid (st.gid)))
                  repfilep->group = soap_strdup (soap, gr->gr_name);
#endif
            repfilep->permMode = st.filemode;
            if (*st.csumtype)
                  repfilep->checksumType = soap_strdup (soap, csumtype2srmname (st.csumtype));
            if (*st.csumvalue)
                  repfilep->checksumValue = soap_strdup (soap, st.csumvalue);
            flags = CNS_LIST_BEGIN;
            curtime = time (0);
            while ((lp = Cns_listreplica (sfn, NULL, flags, &list)) != NULL) {
                  flags = CNS_LIST_CONTINUE;
                  if (lp->status == '-')
                        repfilep->isCached = true_;
                  if (lp->ptime > curtime)
                        repfilep->isPinned = true_;
                  if (lp->f_type == 'P')
                        repfilep->isPermanent = true_;
            }
            (void) Cns_listreplica (sfn, NULL, CNS_LIST_END, &list);
      }
      if (nb_file_err == nbreqfiles && errmsg) {
            soap_sender_fault (soap, errmsg, NULL);
            RETURN (SOAP_FAULT);
      }
      RETURN (SOAP_OK);
}

int ns5__mkPermanent (struct soap *soap, struct ArrayOfstring *surlarray, struct ns5__mkPermanentResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "mkPermanent");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      rep->_Result->state = soap_strdup (soap, "Failed");
      rep->_Result->errorMessage = soap_strdup (soap, "Method not supported");
      RETURN (SOAP_OK);
}

int ns5__getEstGetTime (struct soap *soap, struct ArrayOfstring *surlarray, struct ArrayOfstring *protoarray, struct ns5__getEstGetTimeResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "getEstGetTime");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      rep->_Result->state = soap_strdup (soap, "Failed");
      rep->_Result->errorMessage = soap_strdup (soap, "Method not supported");
      RETURN (SOAP_OK);
}

int ns5__getEstPutTime (struct soap *soap, struct ArrayOfstring *srcarray, struct ArrayOfstring *surlarray, struct ArrayOflong *sizearray, struct ArrayOfboolean *permarray, struct ArrayOfstring *protoarray, struct ns5__getEstPutTimeResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "getEstPutTime");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ns1__RequestStatus))) == NULL)
            RETURN (SOAP_EOM);
      memset (rep->_Result, 0, sizeof(struct ns1__RequestStatus));
      rep->_Result->state = soap_strdup (soap, "Failed");
      rep->_Result->errorMessage = soap_strdup (soap, "Method not supported");
      RETURN (SOAP_OK);
}

int ns5__advisoryDelete (struct soap *soap, struct ArrayOfstring *surlarray, struct ns5__advisoryDeleteResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      struct dpm_filestatus *filestatuses = NULL;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      int nbfqans;
      int nbgids;
      int nbreplies = 0;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "advisoryDelete");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            soap_sender_fault (soap, "Could not get user mapping", NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            dpm_client_setVOMS_data (voname, fqan, nbfqans);

      if (! surlarray) {
            soap_sender_fault (soap, "surlarray is required", NULL);
            RETURN (SOAP_FAULT);
      }
      if (dpm_rm (surlarray->__size, surlarray->__ptr,
          &nbreplies, &filestatuses) < 0) {
            dpm_free_filest (nbreplies, filestatuses);
            soap_sender_fault (soap, sstrerror (serrno), NULL);
            RETURN (SOAP_FAULT);
      }
      dpm_free_filest (nbreplies, filestatuses);
      RETURN (SOAP_OK);
}

int ns5__getProtocols (struct soap *soap, struct ns5__getProtocolsResponse *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      int i;
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "getProtocols");
      get_client_dn (soap, clientdn, sizeof(clientdn));
      clienthost = Cgetnetaddress (-1, &soap->peer, soap->peerlen, &na_key, NULL, NULL, 0, 0);
      if (!clienthost) clienthost = "(unknown)";
      srmlogit (func, "request by %s from %s\n", clientdn, clienthost);

      if ((rep->_Result = soap_malloc (soap, sizeof(struct ArrayOfstring))) == NULL)
            RETURN (SOAP_EOM);
      if ((rep->_Result->__ptr =
          soap_malloc (soap, nb_supported_protocols * sizeof(char *))) == NULL)
            RETURN (SOAP_EOM);
      rep->_Result->__size = nb_supported_protocols;
      for (i = 0; i < nb_supported_protocols; i++) {
            if ((rep->_Result->__ptr[i] =
                soap_strdup (soap, supported_protocols[i])) == NULL)
                  RETURN (SOAP_EOM);
      }
      RETURN (SOAP_OK);
}

Generated by  Doxygen 1.6.0   Back to index