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

srmv2_xferreq.c

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

#ifndef lint
static char sccsid[] = "@(#)$RCSfile: srmv2_xferreq.c,v $ $Revision: 1.16 $ $Date: 2008/09/24 11:25:01 $ CERN Jean-Philippe Baud";
#endif /* not lint */

#include <string.h>
#include <sys/types.h>
#include <uuid/uuid.h>
#include "Cnetdb.h"
#include "dpm.h"
#include "dpm_api.h"
#include "dpm_server.h"
#include "dpns_api.h"
#include "serrno.h"
#include "srm_server.h"
#include "srmv2H.h"
extern char db_name[33];
extern char db_pwd[33];
extern char db_srvr[33];
extern char db_user[33];
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;

/*                Data Transfer Functions                   */

dpmstatus2statuscode (int status, char r_type, int isfile, time_t pintime)
{
      switch (status & 0xF000) {
      case DPM_SUCCESS:
            return (SRM_USCORESUCCESS);
      case DPM_QUEUED:
            return (SRM_USCOREREQUEST_USCOREQUEUED);
      case DPM_ACTIVE:
            return (SRM_USCOREREQUEST_USCOREINPROGRESS);
      case DPM_READY:
      case DPM_RUNNING:
            if (r_type == 'P')
                  return (SRM_USCORESPACE_USCOREAVAILABLE);
            else
                  return ((pintime > time (0)) ? SRM_USCOREFILE_USCOREPINNED :
                      SRM_USCOREFILE_USCORELIFETIME_USCOREEXPIRED);
      case DPM_DONE:
            if (isfile) {
                  if (r_type == 'D')      /* PutDone */
                        return (SRM_USCORESUCCESS);
                  return ((pintime > time (0)) ? SRM_USCORESUCCESS :
                      SRM_USCOREFILE_USCOREIN_USCORECACHE);
            } else
                  return (SRM_USCOREPARTIAL_USCORESUCCESS);
      case DPM_ABORTED:
            return (SRM_USCOREABORTED);
      case DPM_EXPIRED:
            return (SRM_USCOREFILE_USCORELIFETIME_USCOREEXPIRED);
      case DPM_RELEASED:
            return (SRM_USCORERELEASED);
      case DPM_TO_BE_RECALLED:
            return (SRM_USCOREREQUEST_USCOREINPROGRESS);
      default:
            if (isfile && status == (DPM_FAILED | EINVAL))
                  return (SRM_USCOREFAILURE);
            return (serrno2statuscode (status & 0xFFF));
      }
}

marshall_BOF (struct soap *soap, struct ns1__TBringOnlineRequestFileStatus *repfilep, struct dpm_get_filereq *gfr_entry)
{
      time_t current_time = time(0);

      if ((repfilep->fileSize = soap_malloc (soap, sizeof(ULONG64))))
            *repfilep->fileSize = gfr_entry->actual_size;
      if ((repfilep->sourceSURL =
          soap_strdup (soap, gfr_entry->from_surl)) == NULL)
            return (-1);
      if ((repfilep->remainingPinTime = soap_malloc (soap, sizeof(int))))
            *repfilep->remainingPinTime = (gfr_entry->lifetime == 0x7FFFFFFF) ?
                -1 : (gfr_entry->lifetime > current_time) ?
                gfr_entry->lifetime - current_time : 0;
      repfilep->status->statusCode =
          dpmstatus2statuscode (gfr_entry->status, 'B', 1, gfr_entry->lifetime);
      if (*gfr_entry->errstring)
            repfilep->status->explanation = soap_strdup (soap, gfr_entry->errstring);
      return (0);
}

marshall_CPR (struct soap *soap, struct ns1__TCopyRequestFileStatus *repfilep, struct dpm_copy_filereq *cpr_entry)
{
      time_t current_time = time(0);

      if ((repfilep->fileSize = soap_malloc (soap, sizeof(ULONG64))))
            *repfilep->fileSize = cpr_entry->actual_size;
      if ((repfilep->sourceSURL =
          soap_strdup (soap, cpr_entry->from_surl)) == NULL)
            return (-1);
      if ((repfilep->remainingFileLifetime = soap_malloc (soap, sizeof(int))))
            *repfilep->remainingFileLifetime = (cpr_entry->f_lifetime == 0x7FFFFFFF) ?
                -1 : (cpr_entry->f_lifetime > current_time) ?
                cpr_entry->f_lifetime - current_time : 0;
      repfilep->status->statusCode =
          dpmstatus2statuscode (cpr_entry->status, 'C', 1, cpr_entry->f_lifetime);
      if (*cpr_entry->errstring)
            repfilep->status->explanation = soap_strdup (soap, cpr_entry->errstring);
      if ((repfilep->targetSURL =
          soap_strdup (soap, cpr_entry->to_surl)) == NULL)
            return (-1);
      return (0);
}

marshall_GFR (struct soap *soap, struct ns1__TGetRequestFileStatus *repfilep, struct dpm_get_filereq *gfr_entry)
{
      time_t current_time = time(0);
      char *p;
      char turl[CA_MAXSFNLEN+1];

      if ((repfilep->fileSize = soap_malloc (soap, sizeof(ULONG64))))
            *repfilep->fileSize = gfr_entry->actual_size;
      if ((repfilep->sourceSURL =
          soap_strdup (soap, gfr_entry->from_surl)) == NULL)
            return (-1);
      if ((repfilep->remainingPinTime = soap_malloc (soap, sizeof(int))))
            *repfilep->remainingPinTime = (gfr_entry->lifetime == 0x7FFFFFFF) ?
                -1 : (gfr_entry->lifetime > current_time) ?
                gfr_entry->lifetime - current_time : 0;
      repfilep->status->statusCode =
          dpmstatus2statuscode (gfr_entry->status, 'G', 1, gfr_entry->lifetime);
      if (*gfr_entry->errstring)
            repfilep->status->explanation = soap_strdup (soap, gfr_entry->errstring);
      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->transferURL = soap_strdup (soap, turl);
      }
      return (0);
}

marshall_PFR (struct soap *soap, struct ns1__TPutRequestFileStatus *repfilep, struct dpm_put_filereq *pfr_entry)
{
      time_t current_time = time(0);
      char *p;
      char turl[CA_MAXSFNLEN+1];

      if ((repfilep->fileSize = soap_malloc (soap, sizeof(ULONG64))))
            *repfilep->fileSize =
                (pfr_entry->actual_size & INT64_NEG) ? 0 : pfr_entry->actual_size;
      if ((repfilep->SURL =
          soap_strdup (soap, pfr_entry->to_surl)) == NULL)
            return (-1);
      if ((repfilep->remainingPinLifetime = soap_malloc (soap, sizeof(int))))
            *repfilep->remainingPinLifetime = (pfr_entry->lifetime == 0x7FFFFFFF) ?
                -1 : (pfr_entry->lifetime > current_time) ?
                pfr_entry->lifetime - current_time : 0;
      if ((repfilep->remainingFileLifetime = soap_malloc (soap, sizeof(int))))
            *repfilep->remainingFileLifetime = (pfr_entry->f_lifetime == 0x7FFFFFFF) ?
                -1 : (pfr_entry->f_lifetime > current_time) ?
                pfr_entry->f_lifetime - current_time : 0;
      repfilep->status->statusCode =
          dpmstatus2statuscode (pfr_entry->status, 'P', 1, pfr_entry->status == DPM_DONE ?
          pfr_entry->f_lifetime : pfr_entry->lifetime);
      if (*pfr_entry->errstring)
            repfilep->status->explanation = soap_strdup (soap, pfr_entry->errstring);
      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->transferURL = soap_strdup (soap, turl);
      }
      return (0);
}

int
ns1__srmPrepareToGet (struct soap *soap, struct ns1__srmPrepareToGetRequest *req, struct ns1__srmPrepareToGetResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      struct dpm_req dpm_req;
      char f_type;
      char **fqan;
      char func[16];
      struct dpm_get_filereq gfr_entry;
      gid_t gid;
      gid_t *gids;
      int i;
      int j;
      time_t lifetime = 0;
      char logbuf[CA_MAXSFNLEN+25];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreqfiles;
      struct ns1__TGetRequestFileStatus *repfilep;
      struct ns1__srmPrepareToGetResponse *repp;
      struct ns1__TGetFileRequest *reqfilep;
      char ret_policy;
      char *s_token = NULL;
      char selected_protocol[CA_MAXPROTOLEN+1];
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      u_signed64 unique_id;
      uuid_t uuid;
      char *voname;

      strcpy (func, "PrepareToGet");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      memset ((char *) &dpm_req, 0, sizeof(dpm_req));
      dpm_req.ctime = time (0);

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmPrepareToGetResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->requestToken = NULL;
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      repp->remainingTotalRequestTime = NULL;
      rep->srmPrepareToGetResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      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 (req->arrayOfFileRequests)
            nbreqfiles = req->arrayOfFileRequests->__sizerequestArray;
      else {
            nbreqfiles = 0;
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "arrayOfFileRequests is required");
      }
      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTGetRequestFileStatus))) == NULL ||
          (nbreqfiles > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreqfiles * sizeof(struct ns1__TGetRequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreqfiles;
      for (i = 0; i < nbreqfiles; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TGetRequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TGetRequestFileStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            repp->arrayOfFileStatuses->statusArray[i]->status->explanation = NULL;
      }

      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 (! req->transferParameters ||
          ! req->transferParameters->arrayOfTransferProtocols)
            strcpy (selected_protocol, "gsiftp");
      else {
            *selected_protocol = '\0';
            for (i = 0; i < req->transferParameters->arrayOfTransferProtocols->__sizestringArray; i++) {
                  if (! req->transferParameters->arrayOfTransferProtocols->stringArray[i]) continue;
                  for (j = 0; j < nb_supported_protocols; j++) {
                        if (strcmp (req->transferParameters->arrayOfTransferProtocols->stringArray[i], supported_protocols[j]) == 0) {
                              strcpy (selected_protocol, req->transferParameters->arrayOfTransferProtocols->stringArray[i]);
                              break;
                        }
                  }
                  if (*selected_protocol) break;
            }
            if (! *selected_protocol) {
                  dpm_req.status = DPM_FAILED | SEPROTONOTSUP;
                  strcpy (dpm_req.errstring, "Protocol(s) not supported");
            }
      }
      if (req->userRequestDescription) {
            if (strlen (req->userRequestDescription) >= 256) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid user request description");
            }
            strncpy (dpm_req.u_token, req->userRequestDescription, 255);
      }
      if (req->desiredFileStorageType) {
            if (*req->desiredFileStorageType == VOLATILE)
                  f_type = 'V';
            else if (*req->desiredFileStorageType == DURABLE)
                  f_type = 'D';
            else if (*req->desiredFileStorageType == PERMANENT)
                  f_type = 'P';
            else {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid file storage type");
            }
      } else
            f_type = DEFAULT_SPACE_TYPE;
      dpm_req.retrytime = req->desiredTotalRequestTime ? *req->desiredTotalRequestTime : 0;
      if (req->desiredPinLifeTime) {
            if (*req->desiredPinLifeTime < 0)   /* infinite */
                  lifetime = 0x7FFFFFFF;
            else
                  lifetime = *req->desiredPinLifeTime;
      }
      if (req->targetSpaceToken) {
            if (strlen (req->targetSpaceToken) > CA_MAXDPMTOKENLEN) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid space token");
            } else
                  s_token = req->targetSpaceToken;
      }
      if (req->targetFileRetentionPolicyInfo) {
            if (req->targetFileRetentionPolicyInfo->retentionPolicy == REPLICA)
                  ret_policy = 'R';
            else if (req->targetFileRetentionPolicyInfo->retentionPolicy == OUTPUT)
                  ret_policy = 'O';
            else if (req->targetFileRetentionPolicyInfo->retentionPolicy == CUSTODIAL)
                  ret_policy = 'C';
            else {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid retention policy");
            }
            if (req->targetFileRetentionPolicyInfo->accessLatency &&
                *req->targetFileRetentionPolicyInfo->accessLatency != ONLINE) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid access latency");
            }
      } else
            ret_policy = '_';

      /* 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) {
                  repp->arrayOfFileStatuses = NULL;
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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) {
            repp->arrayOfFileStatuses = NULL;
            repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
            repp->returnStatus->explanation = soap_strdup (soap, "Can't get req uniqueid");
            RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
      }
      dpm_req.r_ordinal = unique_id & 0xFFFFFFFF;
      uuid_generate (uuid);
      uuid_unparse (uuid, dpm_req.r_token);
      sprintf (logbuf, "PrepareToGet %d %s", dpm_req.r_ordinal, dpm_req.r_token);
      srm_logreq (func, logbuf);

      dpm_req.ctime = time (0);
      if (! dpm_req.status)
            dpm_req.status = DPM_QUEUED;
      dpm_req.nbreqfiles = nbreqfiles;

      /* Build 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;
            reqfilep = req->arrayOfFileRequests->requestArray[i];
            if (! reqfilep->sourceSURL) {
                  gfr_entry.status = DPM_FAILED | EINVAL;
                  strcpy (gfr_entry.errstring, "Pointer to SURL is NULL");
            } else {
                  if (strlen (reqfilep->sourceSURL) > CA_MAXSFNLEN)
                        gfr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  strncpy (gfr_entry.from_surl,
                      reqfilep->sourceSURL, CA_MAXSFNLEN);
            }
            gfr_entry.lifetime = lifetime;
            gfr_entry.f_type = f_type;
            if (s_token)
                  strcpy (gfr_entry.s_token, s_token);
            gfr_entry.ret_policy = ret_policy;
            if (reqfilep->dirOption) {
                  if (reqfilep->dirOption->allLevelRecursive ||
                      reqfilep->dirOption->isSourceADirectory ||
                      reqfilep->dirOption->numOfLevels) {
                        gfr_entry.status = DPM_FAILED | EINVAL;
                        strcpy (gfr_entry.errstring, "dirOption is not supported");
                  }
            }
            strcpy (gfr_entry.protocol, selected_protocol);
            sprintf (logbuf, "PrepareToGet %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 = repp->arrayOfFileStatuses->statusArray[i];
            repfilep->sourceSURL = reqfilep->sourceSURL;
            repfilep->status->statusCode =
                (gfr_entry.status == DPM_QUEUED) ? SRM_USCOREREQUEST_USCOREQUEUED :
                (gfr_entry.status == (DPM_FAILED | SENAMETOOLONG)) ? SRM_USCOREINVALID_USCOREPATH :
                SRM_USCOREFAILURE;
            if (*gfr_entry.errstring)
                  repfilep->status->explanation = soap_strdup (soap, gfr_entry.errstring);
      }

      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);
            }
      }
      repp->requestToken = soap_strdup (soap, dpm_req.r_token);
      repp->returnStatus->statusCode =
          dpmstatus2statuscode (dpm_req.status, 'G', 0, 0);
      if (*dpm_req.errstring)
            repp->returnStatus->explanation = soap_strdup (soap, dpm_req.errstring);
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmStatusOfGetRequest (struct soap *soap, struct ns1__srmStatusOfGetRequestRequest *req, struct ns1__srmStatusOfGetRequestResponse_ *rep)
{
      int bol = 1;
      int c;
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      DBLISTPTR dblistptr;
      struct dpm_req dpm_req;
      char func[19];
      struct dpm_get_filereq gfr_entry;
      int i;
      char logbuf[CA_MAXSFNLEN+20];
      int nbfromsurls;
      int nbreplies;
      struct ns1__srmStatusOfGetRequestResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "StatusOfGetRequest");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmStatusOfGetRequestResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      repp->remainingTotalRequestTime = NULL;
      rep->srmStatusOfGetRequestResponse = repp;

      if (! req->requestToken) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "requestToken is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      sprintf (logbuf, "StatusOfGetRequest %s", req->requestToken);
      srm_logreq (func, logbuf);

      if (req->arrayOfSourceSURLs)
            nbfromsurls = req->arrayOfSourceSURLs->__sizeurlArray;
      else
            nbfromsurls = 0;

      /* 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) {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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 global request status */

      if (dpm_get_pending_req_by_token (&thip->dbfd, req->requestToken,
          &dpm_req, 0, NULL) < 0 &&
          dpm_get_req_by_token (&thip->dbfd, req->requestToken,
          &dpm_req, 0, NULL) < 0) {
            if (serrno == ENOENT) {
                  repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                  repp->returnStatus->explanation = soap_strdup (soap, "Unknown request token");
            } else {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB fetch error");
            }
            RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
      }

      if (dpm_req.r_type != 'G') {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "request type mismatch");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      if (nbfromsurls == 0)   /* Get the number of file requests from the DB */
            nbreplies = dpm_req.nbreqfiles;
      else
            nbreplies = nbfromsurls;

      /* Allocate the reply file structures */

      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTGetRequestFileStatus))) == NULL ||
          (nbreplies > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreplies * sizeof(struct ns1__TGetRequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreplies;
      for (i = 0; i < nbreplies; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TGetRequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TGetRequestFileStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            repp->arrayOfFileStatuses->statusArray[i]->status->explanation = NULL;
      }

      if (nbfromsurls == 0) { /* return all file requests for this token */
            i = 0;
            while ((c = dpm_list_gfr_entry (&thip->dbfd, bol, req->requestToken,
                &gfr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  if (marshall_GFR (soap, repp->arrayOfFileStatuses->statusArray[i],
                      &gfr_entry) < 0) {
                        (void) dpm_list_gfr_entry (&thip->dbfd, bol,
                            req->requestToken, &gfr_entry,
                            0, NULL, 1, &dblistptr);  /* free res */
                        RETURN (SOAP_EOM);
                  }
                  i++;
            }
            (void) dpm_list_gfr_entry (&thip->dbfd, bol, req->requestToken,
                &gfr_entry, 0, NULL, 1, &dblistptr);  /* free res */
      } else {    /* return information about specified file requests */
            for (i = 0; i < nbfromsurls; i++) {
                  if (! req->arrayOfSourceSURLs->urlArray[i]) {
                        memset (&gfr_entry, 0, sizeof(gfr_entry));
                        gfr_entry.status = DPM_FAILED | EINVAL;
                        strcpy (gfr_entry.errstring, "Pointer to SURL is NULL");
                  } else if (strlen (req->arrayOfSourceSURLs->urlArray[i]) > CA_MAXSFNLEN) {
                        memset (&gfr_entry, 0, sizeof(gfr_entry));
                        strncpy (gfr_entry.from_surl, req->arrayOfSourceSURLs->urlArray[i], CA_MAXSFNLEN);
                        gfr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  } else if (dpm_get_gfr_by_surl (&thip->dbfd, req->requestToken,
                      req->arrayOfSourceSURLs->urlArray[i], &gfr_entry, 0, NULL) < 0) {
                        memset (&gfr_entry, 0, sizeof(gfr_entry));
                        strcpy (gfr_entry.from_surl, req->arrayOfSourceSURLs->urlArray[i]);
                        gfr_entry.status = DPM_FAILED | serrno;
                  }
                  sprintf (logbuf, "StatusOfGetRequest %s", gfr_entry.from_surl);
                  srm_logreq (func, logbuf);
                  if (marshall_GFR (soap, repp->arrayOfFileStatuses->statusArray[i],
                      &gfr_entry) < 0)
                        RETURN (SOAP_EOM);
            }
      }
      if ((dpm_req.status & 0xF000) == DPM_FAILED || dpm_req.status == DPM_DONE) {
            if (strcmp (dpm_req.errstring, "Failed for all SURLs") == 0)
                  repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            else
                  repp->returnStatus->statusCode =
                      dpmstatus2statuscode (dpm_req.status, 'G', 0, 0);
      } else
            repp->returnStatus->statusCode =
                dpmstatus2statuscode (dpm_req.status, 'G', 0, 0);
      if (*dpm_req.errstring)
            repp->returnStatus->explanation = soap_strdup (soap, dpm_req.errstring);
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmPrepareToPut (struct soap *soap, struct ns1__srmPrepareToPutRequest *req, struct ns1__srmPrepareToPutResponse_ *rep)
{
      char ac_latency;
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      struct dpm_req dpm_req;
      time_t f_lifetime = 0;
      char f_type;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      int i;
      int j;
      time_t lifetime = 0;
      char logbuf[CA_MAXSFNLEN+25];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreqfiles;
      struct dpm_put_filereq pfr_entry;
      struct ns1__TPutRequestFileStatus *repfilep;
      struct ns1__srmPrepareToPutResponse *repp;
      struct ns1__TPutFileRequest *reqfilep;
      char ret_policy;
      char *s_token = NULL;
      char selected_protocol[CA_MAXPROTOLEN+1];
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      u_signed64 unique_id;
      uuid_t uuid;
      char *voname;

      strcpy (func, "PrepareToPut");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      memset ((char *) &dpm_req, 0, sizeof(dpm_req));
      dpm_req.ctime = time (0);

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmPrepareToPutResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->requestToken = NULL;
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      repp->remainingTotalRequestTime = NULL;
      rep->srmPrepareToPutResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      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 (req->arrayOfFileRequests)
            nbreqfiles = req->arrayOfFileRequests->__sizerequestArray;
      else {
            nbreqfiles = 0;
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "arrayOfFileRequests is required");
      }
      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTPutRequestFileStatus))) == NULL ||
          (nbreqfiles > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreqfiles * sizeof(struct ns1__TPutRequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreqfiles;
      for (i = 0; i < nbreqfiles; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TPutRequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TPutRequestFileStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            repp->arrayOfFileStatuses->statusArray[i]->status->explanation = NULL;
      }

      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 (! req->transferParameters ||
          ! req->transferParameters->arrayOfTransferProtocols)
            strcpy (selected_protocol, "gsiftp");
      else {
            *selected_protocol = '\0';
            for (i = 0; i < req->transferParameters->arrayOfTransferProtocols->__sizestringArray; i++) {
                  if (! req->transferParameters->arrayOfTransferProtocols->stringArray[i]) continue;
                  for (j = 0; j < nb_supported_protocols; j++) {
                        if (strcmp (req->transferParameters->arrayOfTransferProtocols->stringArray[i], supported_protocols[j]) == 0) {
                              strcpy (selected_protocol, req->transferParameters->arrayOfTransferProtocols->stringArray[i]);
                              break;
                        }
                  }
                  if (*selected_protocol) break;
            }
            if (! *selected_protocol) {
                  dpm_req.status = DPM_FAILED | SEPROTONOTSUP;
                  strcpy (dpm_req.errstring, "Protocol(s) not supported");
            }
      }
      if (req->userRequestDescription) {
            if (strlen (req->userRequestDescription) >= 256) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid user request description");
            }
            strncpy (dpm_req.u_token, req->userRequestDescription, 255);
      }
      if (req->overwriteOption) {
            if (*req->overwriteOption == NEVER || *req->overwriteOption == ALWAYS)
                  dpm_req.flags = *req->overwriteOption;
            else {
                  dpm_req.status = DPM_FAILED | SEOPNOTSUP;
                  strcpy (dpm_req.errstring, "overwriteOption value not supported");
            }
      } else
            dpm_req.flags = 0;
      if (req->desiredFileStorageType) {
            if (*req->desiredFileStorageType == VOLATILE)
                  f_type = 'V';
            else if (*req->desiredFileStorageType == DURABLE)
                  f_type = 'D';
            else if (*req->desiredFileStorageType == PERMANENT)
                  f_type = 'P';
            else {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid file storage type");
            }
      } else
            f_type = DEFAULT_SPACE_TYPE;
      dpm_req.retrytime = req->desiredTotalRequestTime ? *req->desiredTotalRequestTime : 0;
      if (req->desiredPinLifeTime) {
            if (*req->desiredPinLifeTime < 0)   /* infinite */
                  lifetime = 0x7FFFFFFF;
            else
                  lifetime = *req->desiredPinLifeTime;
      }
      if (req->desiredFileLifeTime) {
            if (*req->desiredFileLifeTime < 0)  /* infinite */
                  f_lifetime = 0x7FFFFFFF;
            else
                  f_lifetime = *req->desiredFileLifeTime;
      }
      if (req->targetSpaceToken) {
            if (strlen (req->targetSpaceToken) > CA_MAXDPMTOKENLEN) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid space token");
            } else
                  s_token = req->targetSpaceToken;
      }
      if (req->targetFileRetentionPolicyInfo) {
            if (req->targetFileRetentionPolicyInfo->retentionPolicy == REPLICA)
                  ret_policy = 'R';
            else if (req->targetFileRetentionPolicyInfo->retentionPolicy == OUTPUT)
                  ret_policy = 'O';
            else if (req->targetFileRetentionPolicyInfo->retentionPolicy == CUSTODIAL)
                  ret_policy = 'C';
            else {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid retention policy");
            }
            if (req->targetFileRetentionPolicyInfo->accessLatency) {
                  if (*req->targetFileRetentionPolicyInfo->accessLatency == ONLINE)
                        ac_latency = 'O';
                  else if (*req->targetFileRetentionPolicyInfo->accessLatency == NEARLINE)
                        ac_latency = 'N';
                  else {
                        dpm_req.status = DPM_FAILED | EINVAL;
                        strcpy (dpm_req.errstring, "Invalid access latency");
                  }
            } else
                  ac_latency = 'O';
      } else {
            ret_policy = '_';
            ac_latency = 'O';
      }

      /* 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) {
                  repp->arrayOfFileStatuses = NULL;
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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) {
            repp->arrayOfFileStatuses = NULL;
            repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
            repp->returnStatus->explanation = soap_strdup (soap, "Can't get req uniqueid");
            RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
      }
      dpm_req.r_ordinal = unique_id & 0xFFFFFFFF;
      uuid_generate (uuid);
      uuid_unparse (uuid, dpm_req.r_token);
      sprintf (logbuf, "PrepareToPut %d %s", dpm_req.r_ordinal, dpm_req.r_token);
      srm_logreq (func, logbuf);

      dpm_req.ctime = time (0);
      if (! dpm_req.status)
            dpm_req.status = DPM_QUEUED;
      dpm_req.nbreqfiles = nbreqfiles;

      /* Build 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;
            reqfilep = req->arrayOfFileRequests->requestArray[i];
            if (! reqfilep->targetSURL) {
                  pfr_entry.status = DPM_FAILED | EINVAL;
                  strcpy (pfr_entry.errstring, "Pointer to SURL is NULL");
            } else {
                  if (strlen (reqfilep->targetSURL) > CA_MAXSFNLEN)
                        pfr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  strncpy (pfr_entry.to_surl,
                      reqfilep->targetSURL, CA_MAXSFNLEN);
            }
            pfr_entry.lifetime = lifetime;
            pfr_entry.f_lifetime = f_lifetime;
            pfr_entry.f_type = f_type;
            if (s_token)
                  strcpy (pfr_entry.s_token, s_token);
            pfr_entry.ret_policy = ret_policy;
            pfr_entry.ac_latency = ac_latency;
            if (reqfilep->expectedFileSize)
                  pfr_entry.requested_size = *reqfilep->expectedFileSize;
            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, "PrepareToPut %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 = repp->arrayOfFileStatuses->statusArray[i];
            repfilep->SURL = reqfilep->targetSURL;
            repfilep->status->statusCode = 
                (pfr_entry.status == DPM_QUEUED) ? SRM_USCOREREQUEST_USCOREQUEUED :
                (pfr_entry.status == (DPM_FAILED | SENAMETOOLONG)) ? SRM_USCOREINVALID_USCOREPATH :
                SRM_USCOREFAILURE;
            if (*pfr_entry.errstring)
                  repfilep->status->explanation = soap_strdup (soap, pfr_entry.errstring);
      }

      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);
            }
      }
      repp->requestToken = soap_strdup (soap, dpm_req.r_token);
      repp->returnStatus->statusCode =
          dpmstatus2statuscode (dpm_req.status, 'P', 0, 0);
      if (*dpm_req.errstring)
            repp->returnStatus->explanation = soap_strdup (soap, dpm_req.errstring);
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmStatusOfPutRequest (struct soap *soap, struct ns1__srmStatusOfPutRequestRequest *req, struct ns1__srmStatusOfPutRequestResponse_ *rep)
{
      int bol = 1;
      int c;
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      DBLISTPTR dblistptr;
      struct dpm_req dpm_req;
      char func[19];
      struct dpm_put_filereq pfr_entry;
      int i;
      char logbuf[CA_MAXSFNLEN+20];
      int nbreplies;
      int nbtosurls;
      struct ns1__srmStatusOfPutRequestResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "StatusOfPutRequest");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmStatusOfPutRequestResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      repp->remainingTotalRequestTime = NULL;
      rep->srmStatusOfPutRequestResponse = repp;

      if (! req->requestToken) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "requestToken is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      sprintf (logbuf, "StatusOfPutRequest %s", req->requestToken);
      srm_logreq (func, logbuf);

      if (req->arrayOfTargetSURLs)
            nbtosurls = req->arrayOfTargetSURLs->__sizeurlArray;
      else
            nbtosurls = 0;

      /* 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) {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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 global request status */

      if (dpm_get_pending_req_by_token (&thip->dbfd, req->requestToken,
          &dpm_req, 0, NULL) < 0 &&
          dpm_get_req_by_token (&thip->dbfd, req->requestToken,
          &dpm_req, 0, NULL) < 0) {
            if (serrno == ENOENT) {
                  repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                  repp->returnStatus->explanation = soap_strdup (soap, "Unknown request token");
            } else {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB fetch error");
            }
            RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
      }

      if (dpm_req.r_type != 'P') {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "request type mismatch");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      if (nbtosurls == 0)     /* Get the number of file requests from the DB */

            nbreplies = dpm_req.nbreqfiles;
      else
            nbreplies = nbtosurls;

      /* Allocate the reply file structures */

      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTPutRequestFileStatus))) == NULL ||
          (nbreplies > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreplies * sizeof(struct ns1__TPutRequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreplies;
      for (i = 0; i < nbreplies; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TPutRequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TPutRequestFileStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            repp->arrayOfFileStatuses->statusArray[i]->status->explanation = NULL;
      }

      if (nbtosurls == 0) {   /* return all file requests for this token */
            i = 0;
            while ((c = dpm_list_pfr_entry (&thip->dbfd, bol, req->requestToken,
                &pfr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  if (marshall_PFR (soap, repp->arrayOfFileStatuses->statusArray[i],
                      &pfr_entry) < 0) {
                        (void) dpm_list_pfr_entry (&thip->dbfd, bol,
                            req->requestToken, &pfr_entry,
                            0, NULL, 1, &dblistptr);  /* free res */
                        RETURN (SOAP_EOM);
                  }
                  i++;
            }
            (void) dpm_list_pfr_entry (&thip->dbfd, bol, req->requestToken,
                &pfr_entry, 0, NULL, 1, &dblistptr);  /* free res */
      } else {    /* return information about specified file requests */
            for (i = 0; i < nbtosurls; i++) {
                  if (! req->arrayOfTargetSURLs->urlArray[i]) {
                        memset (&pfr_entry, 0, sizeof(pfr_entry));
                        pfr_entry.status = DPM_FAILED | EINVAL;
                        strcpy (pfr_entry.errstring, "Pointer to SURL is NULL");
                  } else if (strlen (req->arrayOfTargetSURLs->urlArray[i]) > CA_MAXSFNLEN) {
                        memset (&pfr_entry, 0, sizeof(pfr_entry));
                        strncpy (pfr_entry.to_surl, req->arrayOfTargetSURLs->urlArray[i], CA_MAXSFNLEN);
                        pfr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  } else if (dpm_get_pfr_by_surl (&thip->dbfd, req->requestToken,
                      req->arrayOfTargetSURLs->urlArray[i], &pfr_entry, 0, NULL) < 0) {
                        memset (&pfr_entry, 0, sizeof(pfr_entry));
                        strcpy (pfr_entry.to_surl, req->arrayOfTargetSURLs->urlArray[i]);
                        pfr_entry.status = DPM_FAILED | serrno;
                  }
                  sprintf (logbuf, "StatusOfPutRequest %s", pfr_entry.to_surl);
                  srm_logreq (func, logbuf);
                  if (marshall_PFR (soap, repp->arrayOfFileStatuses->statusArray[i],
                      &pfr_entry) < 0)
                        RETURN (SOAP_EOM);
            }
      }
      if ((dpm_req.status & 0xF000) == DPM_FAILED || dpm_req.status == DPM_DONE) {
            if (strcmp (dpm_req.errstring, "Failed for all SURLs") == 0)
                  repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            else if (strcmp (dpm_req.errstring, "Space lifetime expired") == 0)
                  repp->returnStatus->statusCode =
                      SRM_USCORESPACE_USCORELIFETIME_USCOREEXPIRED;
            else if (strcmp (dpm_req.errstring, "Insufficient space left associated with token") == 0)
                  repp->returnStatus->statusCode =
                      SRM_USCOREEXCEED_USCOREALLOCATION;
            else
                  repp->returnStatus->statusCode =
                      dpmstatus2statuscode (dpm_req.status, 'P', 0, 0);
      } else
            repp->returnStatus->statusCode =
                dpmstatus2statuscode (dpm_req.status, 'P', 0, 0);
      if (*dpm_req.errstring)
            repp->returnStatus->explanation = soap_strdup (soap, dpm_req.errstring);
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmCopy (struct soap *soap, struct ns1__srmCopyRequest *req, struct ns1__srmCopyResponse_ *rep)
{
      char ac_latency;
      char clientdn[256];
      const char *clienthost;
      struct dpm_copy_filereq cpr_entry;
      time_t curtime;
      struct dpm_req dpm_req;
      time_t f_lifetime = 0;
      char f_type;
      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__TCopyRequestFileStatus *repfilep;
      struct ns1__srmCopyResponse *repp;
      struct ns1__TCopyFileRequest *reqfilep;
      char ret_policy;
      char *s_token = NULL;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      u_signed64 unique_id;
      uuid_t uuid;
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      memset ((char *) &dpm_req, 0, sizeof(dpm_req));
      dpm_req.ctime = time (0);

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmCopyResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->requestToken = NULL;
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      repp->remainingTotalRequestTime = NULL;
      rep->srmCopyResponse = repp;

#if 0
      repp->returnStatus->statusCode = SRM_USCORENOT_USCORESUPPORTED;
      RETURNSC (SOAP_OK, SRM_USCORENOT_USCORESUPPORTED);
#else
      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      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 (req->arrayOfFileRequests)
            nbreqfiles = req->arrayOfFileRequests->__sizerequestArray;
      else {
            nbreqfiles = 0;
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "arrayOfFileRequests is required");
      }
      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTCopyRequestFileStatus))) == NULL ||
          (nbreqfiles > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreqfiles * sizeof(struct ns1__TCopyRequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreqfiles;
      for (i = 0; i < nbreqfiles; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TCopyRequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TCopyRequestFileStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            repp->arrayOfFileStatuses->statusArray[i]->status->explanation = NULL;
      }

      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';

      if (req->userRequestDescription) {
            if (strlen (req->userRequestDescription) >= 256) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid user request description");
            }
            strncpy (dpm_req.u_token, req->userRequestDescription, 255);
      }
      if (req->overwriteOption) {
            if (*req->overwriteOption == NEVER || *req->overwriteOption == ALWAYS)
                  dpm_req.flags = *req->overwriteOption;
            else {
                  dpm_req.status = DPM_FAILED | SEOPNOTSUP;
                  strcpy (dpm_req.errstring, "overwriteOption value not supported");
            }
      } else
            dpm_req.flags = 0;
      if (req->targetFileStorageType) {
            if (*req->targetFileStorageType == VOLATILE)
                  f_type = 'V';
            else if (*req->targetFileStorageType == DURABLE)
                  f_type = 'D';
            else if (*req->targetFileStorageType == PERMANENT)
                  f_type = 'P';
            else {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid file storage type");
            }
      } else
            f_type = '_';
      dpm_req.retrytime = req->desiredTotalRequestTime ? *req->desiredTotalRequestTime : 0;
      if (req->desiredTargetSURLLifeTime) {
            if (*req->desiredTargetSURLLifeTime < 0)  /* infinite */
                  f_lifetime = 0x7FFFFFFF;
            else
                  f_lifetime = *req->desiredTargetSURLLifeTime;
      }
      if (req->targetSpaceToken) {
            if (strlen (req->targetSpaceToken) > CA_MAXDPMTOKENLEN) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid space token");
            } else
                  s_token = req->targetSpaceToken;
      }
      if (req->targetFileRetentionPolicyInfo) {
            if (req->targetFileRetentionPolicyInfo->retentionPolicy == REPLICA)
                  ret_policy = 'R';
            else if (req->targetFileRetentionPolicyInfo->retentionPolicy == OUTPUT)
                  ret_policy = 'O';
            else if (req->targetFileRetentionPolicyInfo->retentionPolicy == CUSTODIAL)
                  ret_policy = 'C';
            else {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid retention policy");
            }
            if (req->targetFileRetentionPolicyInfo->accessLatency) {
                  if (*req->targetFileRetentionPolicyInfo->accessLatency == ONLINE)
                        ac_latency = 'O';
                  else if (*req->targetFileRetentionPolicyInfo->accessLatency == NEARLINE)
                        ac_latency = 'N';
                  else {
                        dpm_req.status = DPM_FAILED | EINVAL;
                        strcpy (dpm_req.errstring, "Invalid access latency");
                  }
            } else
                  ac_latency = '_';
      } else {
            ret_policy = '_';
            ac_latency = '_';
      }

      /* 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) {
                  repp->arrayOfFileStatuses = NULL;
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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) {
            repp->arrayOfFileStatuses = NULL;
            repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
            repp->returnStatus->explanation = soap_strdup (soap, "Can't get req uniqueid");
            RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
      }
      dpm_req.r_ordinal = unique_id & 0xFFFFFFFF;
      uuid_generate (uuid);
      uuid_unparse (uuid, dpm_req.r_token);
      sprintf (logbuf, "Copy %d %s", dpm_req.r_ordinal, dpm_req.r_token);
      srm_logreq (func, logbuf);

      dpm_req.ctime = time (0);
      if (! dpm_req.status)
            dpm_req.status = DPM_QUEUED;
      dpm_req.nbreqfiles = nbreqfiles;

      /* Build 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;
            reqfilep = req->arrayOfFileRequests->requestArray[i];
            if (! reqfilep->sourceSURL) {
                  cpr_entry.status = DPM_FAILED | EINVAL;
                  strcpy (cpr_entry.errstring, "Pointer to sourceSURL is NULL");
            } else {
                  if (strlen (reqfilep->sourceSURL) > CA_MAXSFNLEN)
                        cpr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  strncpy (cpr_entry.from_surl,
                      reqfilep->sourceSURL, CA_MAXSFNLEN);
            }
            if (! reqfilep->targetSURL) {
                  cpr_entry.status = DPM_FAILED | EINVAL;
                  strcpy (cpr_entry.errstring, "Pointer to targetSURL is NULL");
            } else {
                  if (strlen (reqfilep->targetSURL) > CA_MAXSFNLEN)
                        cpr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  strncpy (cpr_entry.to_surl,
                      reqfilep->targetSURL, CA_MAXSFNLEN);
            }
            cpr_entry.f_lifetime = f_lifetime;
            cpr_entry.f_type = f_type;
            if (s_token)
                  strcpy (cpr_entry.s_token, s_token);
            cpr_entry.ret_policy = ret_policy;
            cpr_entry.ac_latency = ac_latency;
            if (reqfilep->dirOption && reqfilep->dirOption->isSourceADirectory)
                  cpr_entry.flags = 1;
            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 = repp->arrayOfFileStatuses->statusArray[i];
            repfilep->sourceSURL = reqfilep->sourceSURL;
            repfilep->targetSURL = reqfilep->targetSURL;
            repfilep->status->statusCode =
                (cpr_entry.status == DPM_QUEUED) ? SRM_USCOREREQUEST_USCOREQUEUED :
                (cpr_entry.status == (DPM_FAILED | SENAMETOOLONG)) ? SRM_USCOREINVALID_USCOREPATH :
                SRM_USCOREFAILURE;
            if (*cpr_entry.errstring)
                  repfilep->status->explanation = soap_strdup (soap, cpr_entry.errstring);
      }

      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: %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);
            }
      }
      repp->requestToken = soap_strdup (soap, dpm_req.r_token);
      repp->returnStatus->statusCode =
          dpmstatus2statuscode (dpm_req.status, 'C', 0, 0);
      if (*dpm_req.errstring)
            repp->returnStatus->explanation = soap_strdup (soap, dpm_req.errstring);
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
#endif
}

int
ns1__srmStatusOfCopyRequest (struct soap *soap, struct ns1__srmStatusOfCopyRequestRequest *req, struct ns1__srmStatusOfCopyRequestResponse_ *rep)
{
      int bol = 1;
      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 func[20];
      int i;
      char logbuf[2*CA_MAXSFNLEN+22];
      int nbreplies;
      int nbsurls;
      struct ns1__srmStatusOfCopyRequestResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "StatusOfCopyRequest");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmStatusOfCopyRequestResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      repp->remainingTotalRequestTime = NULL;
      rep->srmStatusOfCopyRequestResponse = repp;

      if (! req->requestToken) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "requestToken is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      sprintf (logbuf, "StatusOfCopyRequest %s", req->requestToken);
      srm_logreq (func, logbuf);

      if (req->arrayOfSourceSURLs)
            nbsurls = req->arrayOfSourceSURLs->__sizeurlArray;
      else
            nbsurls = 0;

      /* 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) {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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 global request status */

      if (dpm_get_pending_req_by_token (&thip->dbfd, req->requestToken,
          &dpm_req, 0, NULL) < 0 &&
          dpm_get_req_by_token (&thip->dbfd, req->requestToken,
          &dpm_req, 0, NULL) < 0) {
            if (serrno == ENOENT) {
                  repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                  repp->returnStatus->explanation = soap_strdup (soap, "Unknown request token");
            } else {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB fetch error");
            }
            RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
      }

      if (dpm_req.r_type != 'C') {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "request type mismatch");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      if (nbsurls == 0) /* Get the number of file requests from the DB */

            nbreplies = dpm_req.nbreqfiles;
      else
            nbreplies = nbsurls;

      /* Allocate the reply file structures */

      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTCopyRequestFileStatus))) == NULL ||
          (nbreplies > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreplies * sizeof(struct ns1__TCopyRequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreplies;
      for (i = 0; i < nbreplies; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TCopyRequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TCopyRequestFileStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            repp->arrayOfFileStatuses->statusArray[i]->status->explanation = NULL;
      }

      if (nbsurls == 0) {     /* return all file requests for this token */
            i = 0;
            while ((c = dpm_list_cpr_entry (&thip->dbfd, bol, req->requestToken,
                &cpr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  if (marshall_CPR (soap, repp->arrayOfFileStatuses->statusArray[i],
                      &cpr_entry) < 0) {
                        (void) dpm_list_cpr_entry (&thip->dbfd, bol,
                            req->requestToken, &cpr_entry,
                            0, NULL, 1, &dblistptr);  /* free res */
                        RETURN (SOAP_EOM);
                  }
                  i++;
            }
            (void) dpm_list_cpr_entry (&thip->dbfd, bol, req->requestToken,
                &cpr_entry, 0, NULL, 1, &dblistptr);  /* free res */
      } else {    /* return information about specified file requests */
            for (i = 0; i < nbsurls; i++) {
                  if (! req->arrayOfSourceSURLs->urlArray[i] ||
                      ! req->arrayOfTargetSURLs->urlArray[i]) {
                        memset (&cpr_entry, 0, sizeof(cpr_entry));
                        cpr_entry.status = DPM_FAILED | EINVAL;
                        strcpy (cpr_entry.errstring, "Pointer to SURL is NULL");
                  } else if (strlen (req->arrayOfSourceSURLs->urlArray[i]) > CA_MAXSFNLEN ||
                      strlen (req->arrayOfTargetSURLs->urlArray[i]) > CA_MAXSFNLEN) {
                        memset (&cpr_entry, 0, sizeof(cpr_entry));
                        strncpy (cpr_entry.from_surl, req->arrayOfSourceSURLs->urlArray[i], CA_MAXSFNLEN);
                        strncpy (cpr_entry.to_surl, req->arrayOfTargetSURLs->urlArray[i], CA_MAXSFNLEN);
                        cpr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  } else if (dpm_get_cpr_by_surls (&thip->dbfd, req->requestToken,
                      req->arrayOfSourceSURLs->urlArray[i],
                      req->arrayOfTargetSURLs->urlArray[i], &cpr_entry, 0, NULL) < 0) {
                        memset (&cpr_entry, 0, sizeof(cpr_entry));
                        strcpy (cpr_entry.from_surl, req->arrayOfSourceSURLs->urlArray[i]);
                        strcpy (cpr_entry.to_surl, req->arrayOfTargetSURLs->urlArray[i]);
                        cpr_entry.status = DPM_FAILED | serrno;
                  }
                  sprintf (logbuf, "StatusOfCopyRequest %s %s",
                      cpr_entry.from_surl, cpr_entry.to_surl);
                  srm_logreq (func, logbuf);
                  if (marshall_CPR (soap, repp->arrayOfFileStatuses->statusArray[i], &cpr_entry) < 0)
                        RETURN (SOAP_EOM);
            }
      }
      if ((dpm_req.status & 0xF000) == DPM_FAILED || dpm_req.status == DPM_DONE) {
            if (strcmp (dpm_req.errstring, "Failed for all SURLs") == 0)
                  repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            else
                  repp->returnStatus->statusCode =
                      dpmstatus2statuscode (dpm_req.status, 'C', 0, 0);
      } else
            repp->returnStatus->statusCode =
                dpmstatus2statuscode (dpm_req.status, 'C', 0, 0);
      if (*dpm_req.errstring)
            repp->returnStatus->explanation = soap_strdup (soap, dpm_req.errstring);
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmBringOnline (struct soap *soap, struct ns1__srmBringOnlineRequest *req, struct ns1__srmBringOnlineResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      struct dpm_req dpm_req;
      char f_type;
      char **fqan;
      char func[16];
      struct dpm_get_filereq gfr_entry;
      gid_t gid;
      gid_t *gids;
      int i;
      int j;
      time_t lifetime = 0;
      char logbuf[CA_MAXSFNLEN+25];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreqfiles;
      struct ns1__TBringOnlineRequestFileStatus *repfilep;
      struct ns1__srmBringOnlineResponse *repp;
      struct ns1__TGetFileRequest *reqfilep;
      char ret_policy;
      char *s_token = NULL;
      char selected_protocol[CA_MAXPROTOLEN+1];
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      u_signed64 unique_id;
      uuid_t uuid;
      char *voname;

      strcpy (func, "BringOnline");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      memset ((char *) &dpm_req, 0, sizeof(dpm_req));
      dpm_req.ctime = time (0);

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmBringOnlineResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->requestToken = NULL;
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      repp->remainingTotalRequestTime = NULL;
      repp->remainingDeferredStartTime = NULL;
      rep->srmBringOnlineResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      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 (req->arrayOfFileRequests)
            nbreqfiles = req->arrayOfFileRequests->__sizerequestArray;
      else {
            nbreqfiles = 0;
            dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "arrayOfFileRequests is required");
      }
      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTBringOnlineRequestFileStatus))) == NULL ||
          (nbreqfiles > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreqfiles * sizeof(struct ns1__TBringOnlineRequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreqfiles;
      for (i = 0; i < nbreqfiles; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TBringOnlineRequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TBringOnlineRequestFileStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            repp->arrayOfFileStatuses->statusArray[i]->status->explanation = NULL;
      }

      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 = 'B';

      /* Check protocols */

      if (! req->transferParameters ||
          ! req->transferParameters->arrayOfTransferProtocols)
            strcpy (selected_protocol, "gsiftp");
      else {
            *selected_protocol = '\0';
            for (i = 0; i < req->transferParameters->arrayOfTransferProtocols->__sizestringArray; i++) {
                  if (! req->transferParameters->arrayOfTransferProtocols->stringArray[i]) continue;
                  for (j = 0; j < nb_supported_protocols; j++) {
                        if (strcmp (req->transferParameters->arrayOfTransferProtocols->stringArray[i], supported_protocols[j]) == 0) {
                              strcpy (selected_protocol, req->transferParameters->arrayOfTransferProtocols->stringArray[i]);
                              break;
                        }
                  }
                  if (*selected_protocol) break;
            }
            if (! *selected_protocol) {
                  dpm_req.status = DPM_FAILED | SEPROTONOTSUP;
                  strcpy (dpm_req.errstring, "Protocol(s) not supported");
            }
      }
      if (req->userRequestDescription) {
            if (strlen (req->userRequestDescription) >= 256) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid user request description");
            }
            strncpy (dpm_req.u_token, req->userRequestDescription, 255);
      }
      if (req->desiredFileStorageType) {
            if (*req->desiredFileStorageType == VOLATILE)
                  f_type = 'V';
            else if (*req->desiredFileStorageType == DURABLE)
                  f_type = 'D';
            else if (*req->desiredFileStorageType == PERMANENT)
                  f_type = 'P';
            else {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid file storage type");
            }
      } else
            f_type = DEFAULT_SPACE_TYPE;
      dpm_req.retrytime = req->desiredTotalRequestTime ? *req->desiredTotalRequestTime : 0;
      if (req->desiredLifeTime) {
            if (*req->desiredLifeTime < 0)      /* infinite */
                  lifetime = 0x7FFFFFFF;
            else
                  lifetime = *req->desiredLifeTime;
      }
      if (req->targetSpaceToken) {
            if (strlen (req->targetSpaceToken) > CA_MAXDPMTOKENLEN) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid space token");
            } else
                  s_token = req->targetSpaceToken;
      }
      if (req->targetFileRetentionPolicyInfo) {
            if (req->targetFileRetentionPolicyInfo->retentionPolicy == REPLICA)
                  ret_policy = 'R';
            else if (req->targetFileRetentionPolicyInfo->retentionPolicy == OUTPUT)
                  ret_policy = 'O';
            else if (req->targetFileRetentionPolicyInfo->retentionPolicy == CUSTODIAL)
                  ret_policy = 'C';
            else {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid retention policy");
            }
            if (req->targetFileRetentionPolicyInfo->accessLatency &&
                *req->targetFileRetentionPolicyInfo->accessLatency != ONLINE) {
                  dpm_req.status = DPM_FAILED | EINVAL;
                  strcpy (dpm_req.errstring, "Invalid access latency");
            }
      } else
            ret_policy = '_';

      /* 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) {
                  repp->arrayOfFileStatuses = NULL;
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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) {
            repp->arrayOfFileStatuses = NULL;
            repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
            repp->returnStatus->explanation = soap_strdup (soap, "Can't get req uniqueid");
            RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
      }
      dpm_req.r_ordinal = unique_id & 0xFFFFFFFF;
      uuid_generate (uuid);
      uuid_unparse (uuid, dpm_req.r_token);
      sprintf (logbuf, "BringOnline %d %s", dpm_req.r_ordinal, dpm_req.r_token);
      srm_logreq (func, logbuf);

      dpm_req.ctime = time (0);
      if (! dpm_req.status)
            dpm_req.status = DPM_QUEUED;
      dpm_req.nbreqfiles = nbreqfiles;

      /* Build 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;
            reqfilep = req->arrayOfFileRequests->requestArray[i];
            if (! reqfilep->sourceSURL) {
                  gfr_entry.status = DPM_FAILED | EINVAL;
                  strcpy (gfr_entry.errstring, "Pointer to SURL is NULL");
            } else {
                  if (strlen (reqfilep->sourceSURL) > CA_MAXSFNLEN)
                        gfr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  strncpy (gfr_entry.from_surl,
                      reqfilep->sourceSURL, CA_MAXSFNLEN);
            }
            gfr_entry.lifetime = lifetime;
            gfr_entry.f_type = f_type;
            if (s_token)
                  strcpy (gfr_entry.s_token, s_token);
            gfr_entry.ret_policy = ret_policy;
            if (reqfilep->dirOption) {
                  if (reqfilep->dirOption->allLevelRecursive ||
                      reqfilep->dirOption->isSourceADirectory ||
                      reqfilep->dirOption->numOfLevels) {
                        gfr_entry.status = DPM_FAILED | EINVAL;
                        strcpy (gfr_entry.errstring, "dirOption is not supported");
                  }
            }
            strcpy (gfr_entry.protocol, selected_protocol);
            sprintf (logbuf, "BringOnline %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 = repp->arrayOfFileStatuses->statusArray[i];
            repfilep->sourceSURL = reqfilep->sourceSURL;
            repfilep->status->statusCode =
                (gfr_entry.status == DPM_QUEUED) ? SRM_USCOREREQUEST_USCOREQUEUED :
                (gfr_entry.status == (DPM_FAILED | SENAMETOOLONG)) ? SRM_USCOREINVALID_USCOREPATH :
                SRM_USCOREFAILURE;
            if (*gfr_entry.errstring)
                  repfilep->status->explanation = soap_strdup (soap, gfr_entry.errstring);
      }

      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);
            }
      }
      repp->requestToken = soap_strdup (soap, dpm_req.r_token);
      repp->returnStatus->statusCode =
          dpmstatus2statuscode (dpm_req.status, 'B', 0, 0);
      if (*dpm_req.errstring)
            repp->returnStatus->explanation = soap_strdup (soap, dpm_req.errstring);
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmStatusOfBringOnlineRequest (struct soap *soap, struct ns1__srmStatusOfBringOnlineRequestRequest *req, struct ns1__srmStatusOfBringOnlineRequestResponse_ *rep)
{
      int bol = 1;
      int c;
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      DBLISTPTR dblistptr;
      struct dpm_req dpm_req;
      char func[27];
      struct dpm_get_filereq gfr_entry;
      int i;
      char logbuf[CA_MAXSFNLEN+20];
      int nbfromsurls;
      int nbreplies;
      struct ns1__srmStatusOfBringOnlineRequestResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "StatusOfBringOnlineRequest");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmStatusOfBringOnlineRequestResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      repp->remainingTotalRequestTime = NULL;
      repp->remainingDeferredStartTime = NULL;
      rep->srmStatusOfBringOnlineRequestResponse = repp;

      if (! req->requestToken) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "requestToken is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      sprintf (logbuf, "StatusOfBringOnlineRequest %s", req->requestToken);
      srm_logreq (func, logbuf);

      if (req->arrayOfSourceSURLs)
            nbfromsurls = req->arrayOfSourceSURLs->__sizeurlArray;
      else
            nbfromsurls = 0;

      /* 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) {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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 global request status */

      if (dpm_get_pending_req_by_token (&thip->dbfd, req->requestToken,
          &dpm_req, 0, NULL) < 0 &&
          dpm_get_req_by_token (&thip->dbfd, req->requestToken,
          &dpm_req, 0, NULL) < 0) {
            if (serrno == ENOENT) {
                  repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                  repp->returnStatus->explanation = soap_strdup (soap, "Unknown request token");
            } else {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB fetch error");
            }
            RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
      }

      if (dpm_req.r_type != 'B') {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "request type mismatch");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      if (nbfromsurls == 0)   /* Get the number of file requests from the DB */
            nbreplies = dpm_req.nbreqfiles;
      else
            nbreplies = nbfromsurls;

      /* Allocate the reply file structures */

      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTBringOnlineRequestFileStatus))) == NULL ||
          (nbreplies > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreplies * sizeof(struct ns1__TBringOnlineRequestFileStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreplies;
      for (i = 0; i < nbreplies; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TBringOnlineRequestFileStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TBringOnlineRequestFileStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            repp->arrayOfFileStatuses->statusArray[i]->status->explanation = NULL;
      }

      if (nbfromsurls == 0) { /* return all file requests for this token */
            i = 0;
            while ((c = dpm_list_gfr_entry (&thip->dbfd, bol, req->requestToken,
                &gfr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                  bol = 0;
                  if (marshall_BOF (soap, repp->arrayOfFileStatuses->statusArray[i],
                      &gfr_entry) < 0) {
                        (void) dpm_list_gfr_entry (&thip->dbfd, bol,
                            req->requestToken, &gfr_entry,
                            0, NULL, 1, &dblistptr);  /* free res */
                        RETURN (SOAP_EOM);
                  }
                  i++;
            }
            (void) dpm_list_gfr_entry (&thip->dbfd, bol, req->requestToken,
                &gfr_entry, 0, NULL, 1, &dblistptr);  /* free res */
      } else {    /* return information about specified file requests */
            for (i = 0; i < nbfromsurls; i++) {
                  if (! req->arrayOfSourceSURLs->urlArray[i]) {
                        memset (&gfr_entry, 0, sizeof(gfr_entry));
                        gfr_entry.status = DPM_FAILED | EINVAL;
                        strcpy (gfr_entry.errstring, "Pointer to SURL is NULL");
                  } else if (strlen (req->arrayOfSourceSURLs->urlArray[i]) > CA_MAXSFNLEN) {
                        memset (&gfr_entry, 0, sizeof(gfr_entry));
                        strncpy (gfr_entry.from_surl, req->arrayOfSourceSURLs->urlArray[i], CA_MAXSFNLEN);
                        gfr_entry.status = DPM_FAILED | SENAMETOOLONG;
                  } else if (dpm_get_gfr_by_surl (&thip->dbfd, req->requestToken,
                      req->arrayOfSourceSURLs->urlArray[i], &gfr_entry, 0, NULL) < 0) {
                        memset (&gfr_entry, 0, sizeof(gfr_entry));
                        strcpy (gfr_entry.from_surl, req->arrayOfSourceSURLs->urlArray[i]);
                        gfr_entry.status = DPM_FAILED | serrno;
                  }
                  sprintf (logbuf, "StatusOfBringOnlineRequest %s", gfr_entry.from_surl);
                  srm_logreq (func, logbuf);
                  if (marshall_BOF (soap, repp->arrayOfFileStatuses->statusArray[i],
                      &gfr_entry) < 0)
                        RETURN (SOAP_EOM);
            }
      }
      if ((dpm_req.status & 0xF000) == DPM_FAILED || dpm_req.status == DPM_DONE) {
            if (strcmp (dpm_req.errstring, "Failed for all SURLs") == 0)
                  repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            else
                  repp->returnStatus->statusCode =
                      dpmstatus2statuscode (dpm_req.status, 'B', 0, 0);
      } else
            repp->returnStatus->statusCode =
                dpmstatus2statuscode (dpm_req.status, 'B', 0, 0);
      if (*dpm_req.errstring)
            repp->returnStatus->explanation = soap_strdup (soap, dpm_req.errstring);
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmReleaseFiles (struct soap *soap, struct ns1__srmReleaseFilesRequest *req, struct ns1__srmReleaseFilesResponse_ *rep)
{
      int bol;
      int c;
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      DBLISTPTR dblistptr;
      struct dpm_req dpm_req;
      char **fqan;
      char func[16];
      struct dpm_get_filereq gfr_entry;
      gid_t gid;
      gid_t *gids;
      int i;
      char logbuf[CA_MAXSFNLEN+25];
      int nb_errors;
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreplies;
      int nbsurls;
      dpm_dbrec_addr rec_addr;
      struct ns1__TSURLReturnStatus *repfilep;
      struct ns1__srmReleaseFilesResponse *repp;
      int status;
      char *surl;
      time_t t1;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "ReleaseFiles");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmReleaseFilesResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      rep->srmReleaseFilesResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      Cns_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      Cns_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            Cns_client_setVOMS_data (voname, fqan, nbfqans);

      if (! req->requestToken && ! req->arrayOfSURLs) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation =
                soap_strdup (soap, "At least one of requestToken and SURLs must be provided");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }
      if (req->requestToken && strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      sprintf (logbuf, "ReleaseFiles %s", req->requestToken ? req->requestToken : "nil");
      srm_logreq (func, logbuf);

      if (req->arrayOfSURLs)
            nbsurls = req->arrayOfSURLs->__sizeurlArray;
      else
            nbsurls = 0;

      /* 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) {
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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;
      }

      if (req->requestToken) {
            if (dpm_get_req_by_token (&thip->dbfd, req->requestToken,
                &dpm_req, 0, NULL) < 0) {
                  if (serrno == ENOENT) {
                        repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                        repp->returnStatus->explanation =
                            soap_strdup (soap, "Unknown request token");
                  } else {
                        repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                        repp->returnStatus->explanation =
                            soap_strdup (soap, "DB fetch error");
                  }
                  RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
            }
            if (dpm_req.r_type != 'G' && dpm_req.r_type != 'B') {
                  repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                  repp->returnStatus->explanation =
                      soap_strdup (soap, "ReleaseFiles only valid on PrepareToGet/BringOnline req");
                  RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
            }
      }

      if (nbsurls == 0) /* Get the number of file requests from the DB */
            nbreplies = dpm_req.nbreqfiles;
      else
            nbreplies = nbsurls;

      /* Allocate the reply file structures */

      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTSURLReturnStatus))) == NULL ||
          (nbreplies > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbreplies * sizeof(struct ns1__TSURLReturnStatus *))) == NULL))
            RETURN (SOAP_EOM);

      repp->arrayOfFileStatuses->__sizestatusArray = nbreplies;
      for (i = 0; i < nbreplies; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TSURLReturnStatus))) == NULL ||
                (repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
      }

      if (nbsurls == 0) {     /* release all file requests for this token */
            for (i = 0; i < dpm_req.nbreqfiles; i++) {
                  (void) dpm_start_tr (thip->s, &thip->dbfd);
                  if (dpm_get_gfr_by_fullid (&thip->dbfd, dpm_req.r_token,
                            i, &gfr_entry, 1, &rec_addr) < 0) {
                        (void) dpm_abort_tr (&thip->dbfd);
                        repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                        repp->returnStatus->explanation =
                            soap_strdup (soap, "DB fetch error");
                        repp->arrayOfFileStatuses = NULL;
                        RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
                  }
                  repfilep = repp->arrayOfFileStatuses->statusArray[i];
                  repfilep->status->explanation = NULL;
                  if ((repfilep->surl =
                      soap_strdup (soap, gfr_entry.from_surl)) == NULL) {
                        (void) dpm_abort_tr (&thip->dbfd);
                        RETURN (SOAP_EOM);
                  }
                  if (dpm_relonefile (thip, &gfr_entry, &rec_addr,
                      &status) < 0) {
                        repfilep->status->statusCode = serrno2statuscode (status & 0xFFF);
                        (void) dpm_abort_tr (&thip->dbfd);
                        nb_file_err++;
                  } else {
                        repfilep->status->statusCode = SRM_USCORESUCCESS;
                        (void) dpm_end_tr (&thip->dbfd);
                  }
            }
      } else {    /* release specified file requests */
            for (i = 0; i < nbsurls; i++) {
                  repfilep = repp->arrayOfFileStatuses->statusArray[i];
                  surl = req->arrayOfSURLs->urlArray[i];
                  repfilep->surl = surl;
                  if (! surl) {
                        repfilep->status->statusCode = SRM_USCOREFAILURE;
                        repfilep->status->explanation =
                              soap_strdup (soap, "Pointer to SURL is NULL");
                        nb_file_err++;
                        continue;
                  }
                  repfilep->status->explanation = NULL;
                  if (strlen (surl) > CA_MAXSFNLEN) {
                        repfilep->status->statusCode = SRM_USCOREINVALID_USCOREPATH;
                        nb_file_err++;
                        continue;
                  }
                  sprintf (logbuf, "ReleaseFiles %d %s", i, surl);
                  srm_logreq (func, logbuf);
                  if (req->requestToken) {
                        (void) dpm_start_tr (thip->s, &thip->dbfd);
                        if (dpm_get_gfr_by_surl (&thip->dbfd, req->requestToken,
                            surl, &gfr_entry, 1, &rec_addr) < 0) {
                              repfilep->status->statusCode = serrno2statuscode (serrno);
                              (void) dpm_abort_tr (&thip->dbfd);
                              nb_file_err++;
                        } else if (dpm_relonefile (thip, &gfr_entry, &rec_addr,
                            &status) < 0) {
                              repfilep->status->statusCode = serrno2statuscode (status & 0xFFF);
                              (void) dpm_abort_tr (&thip->dbfd);
                              nb_file_err++;
                        } else {
                              repfilep->status->statusCode = SRM_USCORESUCCESS;
                              (void) dpm_end_tr (&thip->dbfd);
                        }
                  } else {
                        bol = 1;
                        while ((c = dpm_get_gfr_by_surl_uid (&thip->dbfd, bol,
                            surl, uid, &gfr_entry, 0, NULL, 0, &dblistptr)) == 0) {
                              bol = 0;
                              nb_errors = 0;
                              (void) dpm_start_tr (thip->s, &thip->dbfd);
                              if (dpm_get_gfr_by_fullid (&thip->dbfd, 
                                  gfr_entry.r_token, gfr_entry.f_ordinal,
                                  &gfr_entry, 1, &rec_addr) < 0) {
                                    repfilep->status->statusCode =
                                        serrno2statuscode (serrno);
                                    (void) dpm_abort_tr (&thip->dbfd);
                                    nb_errors++;
                              } else if (dpm_relonefile (thip, &gfr_entry, &rec_addr,
                                  &status) < 0) {
                                    repfilep->status->statusCode =
                                        serrno2statuscode (status & 0xFFF);
                                    (void) dpm_abort_tr (&thip->dbfd);
                                    nb_errors++;
                              } else {
                                    (void) dpm_end_tr (&thip->dbfd);
                              }
                        }
                        (void) dpm_get_gfr_by_surl_uid (&thip->dbfd, bol,
                            surl, uid, &gfr_entry, 0, NULL, 1, &dblistptr);
                        if (c > 0 && bol) {
                              repfilep->status->statusCode = SRM_USCOREINVALID_USCOREPATH;
                              nb_file_err++;
                        } else if (c < 0) {
                              repfilep->status->statusCode = serrno2statuscode (serrno);
                              nb_file_err++;
                        } else if (nb_errors)
                              nb_file_err++;
                        else
                              repfilep->status->statusCode = SRM_USCORESUCCESS;
                  }
            }
      }
      if (nb_file_err == 0)
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      else if (nb_file_err != nbreplies)
            repp->returnStatus->statusCode = SRM_USCOREPARTIAL_USCORESUCCESS;
      else {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Failed for all SURLs");
      }
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmPutDone (struct soap *soap, struct ns1__srmPutDoneRequest *req, struct ns1__srmPutDoneResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      struct dpm_filestatus *filestatuses = NULL;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      int i;
      int j;
      char logbuf[CA_MAXSFNLEN+20];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreplies = 0;
      int nbsurls;
      struct ns1__TSURLReturnStatus *repfilep;
      struct ns1__srmPutDoneResponse *repp;
      int status;
      char **surls = NULL;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "PutDone");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmPutDoneResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      rep->srmPutDoneResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      if (! req->requestToken) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "requestToken is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      sprintf (logbuf, "PutDone %s", req->requestToken);
      srm_logreq (func, logbuf);

      if (! req->arrayOfSURLs) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "arrayOfSiteURLs is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      nbsurls = req->arrayOfSURLs->__sizeurlArray;

      /* Allocate the reply file structures */

      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTSURLReturnStatus))) == NULL ||
          (nbsurls > 0 && ((repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbsurls * sizeof(struct ns1__TSURLReturnStatus *))) == NULL ||
            (surls = soap_malloc (soap, nbsurls * sizeof (char *))) == NULL)))
            RETURN (SOAP_EOM);
      repp->arrayOfFileStatuses->__sizestatusArray = nbsurls;

      j = 0;
      for (i = 0; i < nbsurls; i++) {
            surls[j] = req->arrayOfSURLs->urlArray[i];
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TSURLReturnStatus))) == NULL ||
                (repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            if (surls[j]) j++;
      }

      if (j > 0) {
            dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
            thip->errbuf[0] = '\0';
            dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
            if (voname && fqan)
                  dpm_client_setVOMS_data (voname, fqan, nbfqans);

            if (dpm_putdone (req->requestToken, j, surls,
                &nbreplies, &filestatuses) < 0 && ! filestatuses) {
                  srmlogit (func, "dpm_putdone failed: %s\n", sstrerror (serrno));
                  repp->arrayOfFileStatuses = NULL;
                  repp->returnStatus->statusCode = serrno2statuscode (serrno);
                  if (*thip->errbuf) {
                        thip->errbuf[strlen(thip->errbuf)-1] = '\0';
                        repp->returnStatus->explanation = soap_strdup (soap, thip->errbuf);
                  }
                  RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
            }
      }

      j = 0;
      for (i = 0; i < nbsurls; i++) {
            repfilep = repp->arrayOfFileStatuses->statusArray[i];
            repfilep->surl = req->arrayOfSURLs->urlArray[i];
            if (! req->arrayOfSURLs->urlArray[i]) {
                  repfilep->status->statusCode = SRM_USCOREINVALID_USCOREPATH;
                  repfilep->status->explanation =
                        soap_strdup (soap, "Pointer to SURL is NULL");
                  nb_file_err++;
                  continue;
            }
            if ((filestatuses+j)->surl)
                  free ((filestatuses+j)->surl);
            repfilep->status->statusCode =
                  dpmstatus2statuscode ((filestatuses+j)->status, 'D', 1, 0);
            if ((filestatuses+j)->errstring) {
                  repfilep->status->explanation =
                        soap_strdup (soap, (filestatuses+j)->errstring);
                  free ((filestatuses+j)->errstring);
            } else
                  repfilep->status->explanation = NULL;
            if (((filestatuses+j)->status & 0xF000) == DPM_FAILED ||
                (filestatuses+j)->status == DPM_EXPIRED)
                  nb_file_err++;
            j++;
      }
      free (filestatuses);
      if (nb_file_err == 0)
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      else if (nb_file_err != nbsurls)
            repp->returnStatus->statusCode = SRM_USCOREPARTIAL_USCORESUCCESS;
      else {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Failed for all SURLs");
      }
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmAbortRequest (struct soap *soap, struct ns1__srmAbortRequestRequest *req, struct ns1__srmAbortRequestResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      char logbuf[CA_MAXDPMTOKENLEN+14];
      int nbfqans;
      int nbgids;
      struct ns1__srmAbortRequestResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "AbortRequest");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmAbortRequestResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      rep->srmAbortRequestResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      if (! req->requestToken) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "requestToken is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      sprintf (logbuf, "AbortRequest %s", req->requestToken);
      srm_logreq (func, logbuf);

      dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      thip->errbuf[0] = '\0';
      dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            dpm_client_setVOMS_data (voname, fqan, nbfqans);

      if (dpm_abortreq (req->requestToken) < 0) {
            srmlogit (func, "dpm_abortreq failed: %s\n", sstrerror (serrno));
            repp->returnStatus->statusCode = serrno2statuscode (serrno);
            if (*thip->errbuf) {
                  thip->errbuf[strlen(thip->errbuf)-1] = '\0';
                  repp->returnStatus->explanation = soap_strdup (soap, thip->errbuf);
            }
      } else
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmAbortFiles (struct soap *soap, struct ns1__srmAbortFilesRequest *req, struct ns1__srmAbortFilesResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      struct dpm_filestatus *filestatuses = NULL;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      int i;
      int j;
      char logbuf[CA_MAXSFNLEN+20];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreplies = 0;
      int nbsurls;
      struct ns1__TSURLReturnStatus *repfilep;
      struct ns1__srmAbortFilesResponse *repp;
      int status;
      char **surls = NULL;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "AbortFiles");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmAbortFilesResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      rep->srmAbortFilesResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      if (! req->requestToken) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "requestToken is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      sprintf (logbuf, "AbortFiles %s", req->requestToken);
      srm_logreq (func, logbuf);

      if (! req->arrayOfSURLs) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "arrayOfSiteURLs is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      nbsurls = req->arrayOfSURLs->__sizeurlArray;

      /* Allocate the reply file structures */

      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTSURLReturnStatus))) == NULL ||
          (nbsurls > 0 && ((repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbsurls * sizeof(struct ns1__TSURLReturnStatus *))) == NULL ||
            (surls = soap_malloc (soap, nbsurls * sizeof (char *))) == NULL)))
            RETURN (SOAP_EOM);
      repp->arrayOfFileStatuses->__sizestatusArray = nbsurls;

      j = 0;
      for (i = 0; i < nbsurls; i++) {
            surls[j] = req->arrayOfSURLs->urlArray[i];
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TSURLReturnStatus))) == NULL ||
                (repp->arrayOfFileStatuses->statusArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            if (surls[j]) j++;
      }

      if (j > 0) {
            dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
            thip->errbuf[0] = '\0';
            dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
            if (voname && fqan)
                  dpm_client_setVOMS_data (voname, fqan, nbfqans);

            if (dpm_abortfiles (req->requestToken, j, surls,
                &nbreplies, &filestatuses) < 0 && ! filestatuses) {
                  srmlogit (func, "dpm_abortfiles failed: %s\n", sstrerror (serrno));
                  repp->arrayOfFileStatuses = NULL;
                  repp->returnStatus->statusCode = serrno2statuscode (serrno);
                  if (*thip->errbuf) {
                        thip->errbuf[strlen(thip->errbuf)-1] = '\0';
                        repp->returnStatus->explanation = soap_strdup (soap, thip->errbuf);
                  }
                  RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
            }
      }

      j = 0;
      for (i = 0; i < nbsurls; i++) {
            repfilep = repp->arrayOfFileStatuses->statusArray[i];
            repfilep->surl = req->arrayOfSURLs->urlArray[i];
            if (! req->arrayOfSURLs->urlArray[i]) {
                  repfilep->status->statusCode = SRM_USCOREINVALID_USCOREPATH;
                  repfilep->status->explanation =
                        soap_strdup (soap, "Pointer to SURL is NULL");
                  nb_file_err++;
                  continue;
            }
            if ((filestatuses+j)->surl)
                  free ((filestatuses+j)->surl);
            repfilep->status->statusCode =
                  dpmstatus2statuscode ((filestatuses+j)->status, '\0', 0, 0);
            if ((filestatuses+j)->errstring) {
                  repfilep->status->explanation =
                        soap_strdup (soap, (filestatuses+j)->errstring);
                  free ((filestatuses+j)->errstring);
            } else
                  repfilep->status->explanation = NULL;
            if (((filestatuses+j)->status & 0xF000) == DPM_FAILED)
                  nb_file_err++;
            j++;
      }
      free (filestatuses);
      if (nb_file_err == 0)
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      else if (nb_file_err != nbsurls)
            repp->returnStatus->statusCode = SRM_USCOREPARTIAL_USCORESUCCESS;
      else {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Failed for all SURLs");
      }
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmSuspendRequest (struct soap *soap, struct ns1__srmSuspendRequestRequest *req, struct ns1__srmSuspendRequestResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      struct ns1__srmSuspendRequestResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "SuspendRequest");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmSuspendRequestResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->returnStatus->statusCode = SRM_USCORENOT_USCORESUPPORTED;
      rep->srmSuspendRequestResponse = repp;
      RETURNSC (SOAP_OK, SRM_USCORENOT_USCORESUPPORTED);
}

int
ns1__srmResumeRequest (struct soap *soap, struct ns1__srmResumeRequestRequest *req, struct ns1__srmResumeRequestResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[16];
      struct ns1__srmResumeRequestResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "ResumeRequest");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmResumeRequestResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->returnStatus->statusCode = SRM_USCORENOT_USCORESUPPORTED;
      rep->srmResumeRequestResponse = repp;
      RETURNSC (SOAP_OK, SRM_USCORENOT_USCORESUPPORTED);
}

int
ns1__srmGetRequestSummary (struct soap *soap, struct ns1__srmGetRequestSummaryRequest *req, struct ns1__srmGetRequestSummaryResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      time_t curtime;
      char func[18];
      int i;
      int nb_errors = 0;
      int nb_failed;
      int nb_progress;
      int nb_queued;
      int nbreqfiles;
      int nbtokens;
      int r_status;
      char *r_token;
      char r_type;
      struct ns1__srmGetRequestSummaryResponse *repp;
      struct ns1__TRequestSummary *reptokenp;
      static enum ns1__TRequestType rtypes[] = {PREPARE_USCORETO_USCOREGET, PREPARE_USCORETO_USCOREPUT, COPY, BRING_USCOREONLINE};
      struct srm_srv_thread_info *thip = soap->user;

      strcpy (func, "GetRequestSummary");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmGetRequestSummaryResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfRequestSummaries = NULL;
      rep->srmGetRequestSummaryResponse = repp;

      if (! req->arrayOfRequestTokens) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "arrayOfRequestTokens is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      nbtokens = req->arrayOfRequestTokens->__sizestringArray;

      /* Allocate the array of request summaries */

      if ((repp->arrayOfRequestSummaries =
          soap_malloc (soap, sizeof(struct ns1__ArrayOfTRequestSummary))) == NULL ||
          (repp->arrayOfRequestSummaries->summaryArray =
          soap_malloc (soap, nbtokens * sizeof(struct ns1__TRequestSummary *))) == NULL)
            RETURN (SOAP_EOM);
      repp->arrayOfRequestSummaries->__sizesummaryArray = nbtokens;
      for (i = 0; i < nbtokens; i++) {
            if ((repp->arrayOfRequestSummaries->summaryArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TRequestSummary))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfRequestSummaries->summaryArray[i], 0, sizeof(struct ns1__TRequestSummary));
            if ((repp->arrayOfRequestSummaries->summaryArray[i]->status =
                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
      }

      /* 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) {
                  repp->arrayOfRequestSummaries = NULL;
                  repp->returnStatus->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                  repp->returnStatus->explanation = soap_strdup (soap, "DB open error");
                  RETURNSC (SOAP_OK, SRM_USCOREINTERNAL_USCOREERROR);
            }
            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;
      }

      for (i = 0; i < nbtokens; i++) {
            reptokenp = repp->arrayOfRequestSummaries->summaryArray[i];
            reptokenp->requestToken = req->arrayOfRequestTokens->stringArray[i];
            if ( ! req->arrayOfRequestTokens->stringArray[i]) {
                  reptokenp->status->statusCode = SRM_USCOREFAILURE;
                  reptokenp->status->explanation = soap_strdup (soap, "requestToken is required");
                  nb_errors++;
                  continue;
            }
            r_token = req->arrayOfRequestTokens->stringArray[i];
            if (strlen (r_token) > CA_MAXDPMTOKENLEN) {
                  reptokenp->status->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                  reptokenp->status->explanation = soap_strdup (soap, "Invalid request token");
                  nb_errors++;
                  continue;
            }
            if (dpm_getonereqsummary (thip, r_token, &r_type, &r_status,
                &nbreqfiles, &nb_queued, &nb_progress, &nb_failed) < 0) {
                  if (serrno == ENOENT) {
                        reptokenp->status->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                        reptokenp->status->explanation = soap_strdup (soap, "Unknown request token");
                  } else {
                        reptokenp->status->statusCode = SRM_USCOREINTERNAL_USCOREERROR;
                        reptokenp->status->explanation = soap_strdup (soap, "DB fetch error");
                  }
                  nb_errors++;
                  continue;
            }
            reptokenp->status->statusCode = dpmstatus2statuscode (r_status, '\0', 0, 0);
            reptokenp->status->explanation = NULL;
            if (r_type == 'G')
                  reptokenp->requestType = &rtypes[PREPARE_USCORETO_USCOREGET];
            else if (r_type == 'P')
                  reptokenp->requestType = &rtypes[PREPARE_USCORETO_USCOREPUT];
            else if (r_type == 'C')
                  reptokenp->requestType = &rtypes[COPY];
            else if (r_type == 'B')
                  reptokenp->requestType = &rtypes[BRING_USCOREONLINE];
            if ((reptokenp->totalNumFilesInRequest = soap_malloc (soap, sizeof(int))))
                  *reptokenp->totalNumFilesInRequest = nbreqfiles;
            if ((reptokenp->numOfCompletedFiles = soap_malloc (soap, sizeof(int))))
                  *reptokenp->numOfCompletedFiles = nbreqfiles -
                      (nb_queued + nb_progress);
            if ((reptokenp->numOfWaitingFiles = soap_malloc (soap, sizeof(int))))
                  *reptokenp->numOfWaitingFiles = nb_queued;
            if ((reptokenp->numOfFailedFiles = soap_malloc (soap, sizeof(int))))
                  *reptokenp->numOfFailedFiles = nb_failed;
      }
      if (nb_errors == 0)
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      else if (nb_errors != nbtokens)
            repp->returnStatus->statusCode = SRM_USCOREPARTIAL_USCORESUCCESS;
      else {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Failed for all tokens");
      }
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmExtendFileLifeTime (struct soap *soap, struct ns1__srmExtendFileLifeTimeRequest *req, struct ns1__srmExtendFileLifeTimeResponse_ *rep)
{
      time_t actual_lifetime;
      int c;
      char clientdn[256];
      const char *clienthost;
      struct dpm_req dpm_req;
      char **fqan;
      char func[19];
      gid_t gid;
      gid_t *gids;
      int i;
      time_t lifetime = 0;
      char logbuf[CA_MAXSFNLEN+31];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbsurls;
      char *r_token;
      struct ns1__TSURLLifetimeReturnStatus *repfilep;
      struct ns1__srmExtendFileLifeTimeResponse *repp;
      char *surl;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "ExtendFileLifeTime");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmExtendFileLifeTimeResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      rep->srmExtendFileLifeTimeResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      if (req->newPinLifeTime && ! req->requestToken) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Extending pin lifetime requires token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }
      if (req->requestToken && strlen (req->requestToken) > CA_MAXDPMTOKENLEN) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Invalid request token");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }
      if (req->newPinLifeTime) {
            r_token = req->requestToken;
            if (*req->newPinLifeTime < 0) /* infinite */
                  lifetime = 0x7FFFFFFF;
            else
                  lifetime = *req->newPinLifeTime;
      } else {
            r_token = "";
            if (req->newFileLifeTime) {
                  if (*req->newFileLifeTime < 0)      /* infinite */
                        lifetime = 0x7FFFFFFF;
                  else
                        lifetime = *req->newFileLifeTime;
            }
      }

      sprintf (logbuf, "ExtendFileLifeTime %s %d", r_token, lifetime);
      srm_logreq (func, logbuf);

      if (! req->arrayOfSURLs) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "arrayOfSURLs is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      nbsurls = req->arrayOfSURLs->__sizeurlArray;

      /* Allocate the reply file structures */

      if ((repp->arrayOfFileStatuses =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTSURLLifetimeReturnStatus))) == NULL ||
          (nbsurls > 0 && (repp->arrayOfFileStatuses->statusArray =
            soap_malloc (soap, nbsurls * sizeof(struct ns1__TSURLLifetimeReturnStatus *))) == NULL))
            RETURN (SOAP_EOM);
      repp->arrayOfFileStatuses->__sizestatusArray = nbsurls;

      for (i = 0; i < nbsurls; i++) {
            if ((repp->arrayOfFileStatuses->statusArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TSURLLifetimeReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
            memset (repp->arrayOfFileStatuses->statusArray[i], 0, sizeof(struct ns1__TSURLLifetimeReturnStatus));
            if ((repp->arrayOfFileStatuses->statusArray[i]->status =

                soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
                  RETURN (SOAP_EOM);
      }

      dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      thip->errbuf[0] = '\0';
      dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            dpm_client_setVOMS_data (voname, fqan, nbfqans);

      for (i = 0; i < nbsurls; i++) {
            repfilep = repp->arrayOfFileStatuses->statusArray[i];
            surl = req->arrayOfSURLs->urlArray[i];
            repfilep->surl = surl;
            repfilep->status->explanation = NULL;
            if (! surl) {
                  repfilep->status->statusCode = SRM_USCOREFAILURE;
                  repfilep->status->explanation =
                        soap_strdup (soap, "Pointer to SURL is NULL");
                  nb_file_err++;
                  continue;
            }
            if (strlen (surl) > CA_MAXSFNLEN) {
                  repfilep->status->statusCode = SRM_USCOREINVALID_USCOREPATH;
                  nb_file_err++;
                  continue;
            }
            sprintf (logbuf, "ExtendFileLifeTime %d %s", i, surl);
            srm_logreq (func, logbuf);

            if ((c = dpm_extendfilelife (r_token, surl, lifetime,
                &actual_lifetime)) != 0) {
                  if (c < 0) {
                        srmlogit (func, "dpm_extendfilelife failed: %s\n",
                            sstrerror (serrno));
                        repfilep->status->statusCode = serrno2statuscode (serrno);
                  } else
                        repfilep->status->statusCode =
                            dpmstatus2statuscode (c, 'E', 1, 0);
                  if (*thip->errbuf) {
                        thip->errbuf[strlen(thip->errbuf)-1] = '\0';
                        repfilep->status->explanation = soap_strdup (soap, thip->errbuf);
                  }
                  nb_file_err++;
                  continue;
            }
            repfilep->status->statusCode = SRM_USCORESUCCESS;
            if (*r_token) {
                  if ((repfilep->pinLifetime =
                      soap_malloc (soap, sizeof(int))) == NULL)
                        RETURN (SOAP_EOM);
                  *repfilep->pinLifetime =
                      (actual_lifetime != 0x7FFFFFFF) ? actual_lifetime : -1;
            } else {
                  if ((repfilep->fileLifetime =
                      soap_malloc (soap, sizeof(int))) == NULL)
                        RETURN (SOAP_EOM);
                  *repfilep->fileLifetime =
                      (actual_lifetime != 0x7FFFFFFF) ? actual_lifetime : -1;
            }
      }
      if (nb_file_err == 0)
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      else if (nb_file_err != nbsurls)
            repp->returnStatus->statusCode = SRM_USCOREPARTIAL_USCORESUCCESS;
      else {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Failed for all SURLs");
      }
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmGetRequestTokens (struct soap *soap, struct ns1__srmGetRequestTokensRequest *req, struct ns1__srmGetRequestTokensResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      char **fqan;
      char func[17];
      gid_t gid;
      gid_t *gids;
      int i;
      char logbuf[273];
      int nbfqans;
      int nbgids;
      int nbreplies = 0;
      struct ns1__srmGetRequestTokensResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;
      struct dpm_tokeninfo *tokeninfos = NULL;
      uid_t uid;
      char *voname;

      strcpy (func, "GetRequestTokens");
      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 (! req) {
            soap_sender_fault (soap, "NULL request", NULL);
            RETURN (SOAP_FAULT);
      }

      /* Allocate the reply structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmGetRequestTokensResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfRequestTokens = NULL;
      rep->srmGetRequestTokensResponse = repp;

      if (get_client_full_id (soap, clientdn, &voname, &fqan, &nbfqans, &uid, &gid, &nbgids, &gids) < 0) {
            repp->returnStatus->statusCode = SRM_USCOREAUTHENTICATION_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "Could not get user mapping");
            RETURNSC (SOAP_OK, SRM_USCOREAUTHENTICATION_USCOREFAILURE);
      }
      dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      thip->errbuf[0] = '\0';
      dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            dpm_client_setVOMS_data (voname, fqan, nbfqans);

      if (req->userRequestDescription) {
            if (strlen (req->userRequestDescription) >= 256) {
                  repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
                  repp->returnStatus->explanation =
                      soap_strdup (soap, "Invalid user request description");
                  RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
            }
      }
      sprintf (logbuf, "GetRequestTokens %s", req->userRequestDescription ?
          req->userRequestDescription : "");
      srm_logreq (func, logbuf);

      if (dpm_getreqid (req->userRequestDescription, &nbreplies, &tokeninfos) < 0) {
            srmlogit (func, "dpm_getreqid failed: %s\n", sstrerror (serrno));
            repp->returnStatus->statusCode = serrno2statuscode (serrno);
            if (tokeninfos)
                  free (tokeninfos);
            if (*thip->errbuf) {
                  thip->errbuf[strlen(thip->errbuf)-1] = '\0';
                  repp->returnStatus->explanation = soap_strdup (soap, thip->errbuf);
            }
            RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
      }

      /* Allocate the array of request tokens */

      if ((repp->arrayOfRequestTokens =
          soap_malloc (soap, sizeof(struct ns1__ArrayOfTRequestTokenReturn))) == NULL ||
          (repp->arrayOfRequestTokens->tokenArray =
          soap_malloc (soap, nbreplies * sizeof(struct ns1__TRequestTokenReturn *))) == NULL) {
            free (tokeninfos);
            RETURN (SOAP_EOM);
      }

      repp->arrayOfRequestTokens->__sizetokenArray = nbreplies;
      for (i = 0; i < nbreplies; i++) {
            if ((repp->arrayOfRequestTokens->tokenArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TRequestTokenReturn))) == NULL ||
                (repp->arrayOfRequestTokens->tokenArray[i]->requestToken =
                soap_strdup (soap, (tokeninfos+i)->r_token)) == NULL) {
                  free (tokeninfos);
                  RETURN (SOAP_EOM);
            }
            if ((repp->arrayOfRequestTokens->tokenArray[i]->createdAtTime =
                soap_strdup (soap, soap_dateTime2s (soap, (tokeninfos+i)->c_time))) == NULL) {
                  free (tokeninfos);
                  RETURN (SOAP_EOM);
            }
      }
      free (tokeninfos);
      repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      RETURNSC (SOAP_OK, SRM_USCORESUCCESS);
}

Generated by  Doxygen 1.6.0   Back to index