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

dpmcopy_main.c

/*
 * Copyright (C) 2007-2008 by CERN/IT/GD/ITR
 * All rights reserved
 */

#ifndef lint
static char sccsid[] = "@(#)$RCSfile: dpmcopy_main.c,v $ $Revision: 1.6 $ $Date: 2009/01/11 00:43:26 $ CERN IT-GD/ITR Jean-Philippe Baud";
#endif /* not lint */

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#if defined(_WIN32)
#include <winsock2.h>
#else
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#endif
#include "Cnetdb.h"
#include "Cinit.h"
#include "dpm.h"
#include "dpm_api.h"
#include "dpm_backend.h"
#include "dpm_server.h"
#include "dpm_util.h"
#include "dpmcopy_constants.h"
#include "dpmcopy_server.h"
#include "dpns_api.h"
#include "marshall.h"
#include "net.h"
#include "patchlevel.h"
#include "serrno.h"
#define DEFPOLLINT 5

/*
 * Maximum number of sockets on which the server can listen
 */
#define MAX_LISTEN_SOCKS        16

char db_name[33];
char db_pwd[33];
char db_srvr[33];
char db_user[33];
char func[16];
int jid;
char localdomain[CA_MAXHOSTNAMELEN+1];
char localhost[CA_MAXHOSTNAMELEN+1];
char logfile[CA_MAXPATHLEN+1];
int maxfds;
int nb_file_err;
int nbchildren;
int reqctr;
int listen_ipv4only=0, listen_ipv6only=0;
static int na_key = -1;
extern gid_t *Cdecode_groups (char *, int *);
extern int Cdomainname (char *, int);
extern int isTrustedHost (int, char *, char *, char *, char *);
extern char *optarg;
extern int optind;
void check_child_exit();
void wait4child();
#ifdef CSEC 
#include <Csec_api.h>
Csec_context_t sec_ctx;
char *Csec_mech;
char *Csec_auth_id;
#endif

dpmcopy_main(main_args)
struct main_args *main_args;
{
      struct addrinfo *ai;
      struct addrinfo *aitop;
      int bol;
      int c;
      char cfbuf[80];
      FILE *cf;
      time_t curtime;
      struct dpm_dbfd dbfd;
      DBLISTPTR dblistptr;
      void doit (int);
      struct dpm_req dpm_req;
      char dpmconfigfile[CA_MAXPATHLEN+1];
      struct sockaddr_storage from;
      int fromlen;
      int gaierrno;
      char *getconfent();
      struct addrinfo hints;
      int i;
      time_t lastcheckconfig = 0;
      time_t lastdbpoll = 0;
      int listen_socks[MAX_LISTEN_SOCKS];
      int maxchildren = DPM_MAXWORKERS;
      int nfds;
      int num_listen_socks;
      int on = 1; /* for REUSEADDR and IPV6_V6ONLY */
      char *p;
      char *p_n, *p_p, *p_s, *p_u;
      int pid;
      void procreq(char *, char *, char *, char *);
      fd_set readfd, readmask;
      int rqfd;
      int s;
      char strport[NI_MAXSERV];
      struct timeval timeval;

      jid = getpid();
      strcpy (func, "dpmcopyd");
      dpmconfigfile[0] = '\0';
      strcpy (logfile, LOGFILE);

      /* process command line options if any */

      while ((c = getopt (main_args->argc, main_args->argv, "46c:l:")) != EOF) {
            switch (c) {
            case '4':
                  listen_ipv4only++;
                  break;
            case '6':
                  listen_ipv6only++;
                  break;
            case 'c':
                  strncpy (dpmconfigfile, optarg, sizeof(dpmconfigfile));
                  dpmconfigfile[sizeof(dpmconfigfile) - 1] = '\0';
                  break;
            case 'l':
                  strncpy (logfile, optarg, sizeof(logfile));
                  logfile[sizeof(logfile) - 1] = '\0';
                  break;
            }
      }

      if (listen_ipv4only && listen_ipv6only) {
            dpmlogit (func, "Can not choose to listen for only IPv4 and "
                "also only for IPv6\n");
            return (USERR);
      }

      dpmlogit (func, "started (DPMCOPYD %s-%d)\n", BASEVERSION, PATCHLEVEL);
      gethostname (localhost, CA_MAXHOSTNAMELEN+1);
      if (Cdomainname (localdomain, sizeof(localdomain)) < 0) {
            dpmlogit (func, "Unable to get local domain name\n");
            return (SYERR);
      }
      if (strchr (localhost, '.') == NULL) {
            strcat (localhost, ".");
            strcat (localhost, localdomain);
      }

      /* get DB login info from the Disk Pool Manager server config file */

      if (! *dpmconfigfile) {
            if (strncmp (DPMCONFIG, "%SystemRoot%\\", 13) == 0 &&
                (p = getenv ("SystemRoot")))
                  sprintf (dpmconfigfile, "%s%s", p, strchr (DPMCONFIG, '\\'));
            else
                  strcpy (dpmconfigfile, DPMCONFIG);
      }
      if ((cf = fopen (dpmconfigfile, "r")) == NULL) {
            dpmlogit (func, DP023, dpmconfigfile);
            return (CONFERR);
      }
      if (fgets (cfbuf, sizeof(cfbuf), cf) &&
          strlen (cfbuf) >= 5 && (p_u = strtok (cfbuf, "/\n")) &&
          (p_p = strtok (NULL, "@\n")) && (p_s = strtok (NULL, "/\n"))) {
            if ((p_n = strtok (NULL, "\n")))
                  strcpy (db_name, p_n);
            else
                  strcpy (db_name, "dpm_db");
            strcpy (db_user, p_u);
            strcpy (db_pwd, p_p);
            strcpy (db_srvr, p_s);
      } else {
            dpmlogit (func, DP009, dpmconfigfile, "incorrect");
            return (CONFERR);
      }
      (void) fclose (cf);

      /* connect to the database */

      memset (&dbfd, 0, sizeof(dbfd));
      if (dpm_opendb (db_srvr, db_user, db_pwd, db_name, &dbfd) < 0)
            return (SYERR);

      FD_ZERO (&readmask);
      FD_ZERO (&readfd);
#if ! defined(_WIN32)
      signal (SIGINT, SIG_DFL);
      signal (SIGPIPE, SIG_IGN);
      signal (SIGXFSZ, SIG_IGN);
#endif

      /* open request socket */

      serrno = 0;
      memset (&hints, 0, sizeof(struct addrinfo));
      if (listen_ipv4only)
            hints.ai_family = PF_INET;
      else if (listen_ipv6only)
            hints.ai_family = PF_INET6;
      else
            hints.ai_family = PF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_flags = AI_PASSIVE;

      if ((p = getenv ("DPMCOPYD_PORT")) || (p = getconfent ("DPMCOPYD", "PORT", 0))) {
            strncpy (strport, p, sizeof(strport));
            strport[sizeof(strport)-1] = '\0';
      } else {
            snprintf (strport, sizeof(strport), "%u", DPMCOPYD_PORT);
      }

      if (gaierrno=Cgetaddrinfo (NULL, strport, &hints, &aitop)) {
            dpmlogit (func, DP002, "Cgetaddrinfo",
                (gaierrno != EAI_SYSTEM) ? Cgai_strerror(gaierrno) : neterror());
            return (CONFERR);
      }

      num_listen_socks = 0;
      for (ai = aitop; ai; ai = ai->ai_next) {
            int fo = 0;
            if (ai->ai_family != PF_INET && ai->ai_family != PF_INET6)
                  continue;
            if (num_listen_socks >= MAX_LISTEN_SOCKS) {
                  dpmlogit (func, "Too many listen sockets\n");
                  freeaddrinfo (aitop);
                  return (CONFERR);
            }
            if ((s = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol))<0)
                  continue;
            if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) {
                  dpmlogit (func, DP002, "setsockopt (SO_REUSEADDR)", neterror());
                  close (s);
                  continue;
            }
            if (ai->ai_family == PF_INET6) {
#ifdef IPV6_V6ONLY
                  if (setsockopt (s, IPPROTO_IPV6, IPV6_V6ONLY,
                      (char *)&on, sizeof(on))) {
                        fo = 1;
                        dpmlogit (func, DP002, "setsockopt (IPV6_V6ONLY)", neterror());
                  }
#else
                  fo = 1;
#endif
            }
            if (bind (s, ai->ai_addr, ai->ai_addrlen) < 0) {
                  dpmlogit (func, DP002, "bind", neterror());
                  close (s);
                  continue;
            }
            if (fo) {
#ifdef IPV6_V6ONLY
                  dpmlogit (func, "Was not able to set the IPV6_V6ONLY "
                      "socket option on the IPv6 listen socket\n");
#else
                  dpmlogit (func, "Was compiled on a system that does not "
                      "support the IPV6_V6ONLY socket option\n");
#endif
                  if (listen_ipv6only) {
                        dpmlogit (func, "Not proceeding as the IPv6 only flag was specified\n");
                        return (CONFERR);
                  }
                  dpmlogit (func, "Incoming IPv4 will be accepted and handled as "
                      "IPv4-mapped IPv6 addresses\n");
            }
            listen_socks[num_listen_socks] = s;
            ++num_listen_socks;
            listen (s, 5) ;
      }
      freeaddrinfo (aitop);

      if (num_listen_socks == 0) {
            dpmlogit (func, "Could not listen on any sockets\n");
            return (CONFERR);
      }

      nfds = -1;
      for (i=0; i<num_listen_socks; ++i) {
            FD_SET (listen_socks[i], &readmask);
            if (listen_socks[i]>nfds)
                  nfds = listen_socks[i];
      }
      ++nfds;

#ifdef CSEC
      /* initialise the security context for the first time */
      Csec_server_initContext (&sec_ctx, CSEC_SERVICE_TYPE_HOST, NULL);
#endif

      /* main loop */

      while (1) {
            /* check if any child has ended */

            check_child_exit();

            /* check if config parameters have changed */

            if ((curtime = time (0)) > lastcheckconfig + CHKCONFIGINT) {
                  lastcheckconfig = curtime;
                  if ((p = getconfent ("DPMCOPYD", "MAX_WORKERS", 0)))
                        maxchildren = atoi (p);
            }
            for (i=0; i < num_listen_socks; ++i) {
                  s = listen_socks[i];
                  if (FD_ISSET (s, &readfd)) {
                        FD_CLR (s, &readfd);
                        fromlen = sizeof(from);
                        rqfd = accept (s, (struct sockaddr *) &from, &fromlen);
                        doit (rqfd);
                  }
            }
            while (reqctr > 0) {
                  if (nbchildren + 1 > maxchildren) break;
                  pid = fork ();
                  switch (pid) {
                  case -1:
                        dpmlogit (func, DP002, "fork", strerror (errno));
                        break;
                  case 0:
                        for (i=0; i < num_listen_socks; ++i)
                              close (listen_socks[i]);
                        jid = getpid();
                        procreq (db_srvr, db_user, db_pwd, db_name);
                        break;
                  default:
                        nbchildren++;
                        dpmlogit (func, "decrementing reqctr\n");
                        reqctr--;
                  }
            }

            /* regularly poll the DB for work */

            if (reqctr == 0 && nbchildren < maxchildren &&
                (curtime = time (0)) > lastdbpoll + DPM_DBPINGI) {
                  lastdbpoll = curtime;
                  bol = 1;
                  while ((c = dpm_list_pending_req (&dbfd, bol, &dpm_req,
                      0, NULL, 0, &dblistptr)) == 0) {
                        bol = 0;
                        if (dpm_req.status != DPM_QUEUED4COPY) continue;
                        dpmlogit (func, "incrementing reqctr (DB poll)\n");
                        reqctr++;
                  }
                  (void) dpm_list_pending_req (&dbfd, bol, &dpm_req,
                      0, NULL, 1, &dblistptr);  /* free res */
            }

            memcpy (&readfd, &readmask, sizeof(readmask));
            timeval.tv_sec = CHECKI;
            timeval.tv_usec = 0;
            if (select (maxfds, &readfd, (fd_set *)0, (fd_set *)0, &timeval) < 0) {
                  FD_ZERO (&readfd);
            }
      }
      (void) dpm_closedb (&dbfd);
      exit (0);
}

main(argc, argv)
int argc;
char **argv;
{
#if ! defined(_WIN32)
      struct main_args main_args;

      if ((maxfds = Cinitdaemon ("dpmcopyd", wait4child)) < 0)
            exit (SYERR);
      main_args.argc = argc;
      main_args.argv = argv;
      exit (dpmcopy_main (&main_args));
#else
      if (Cinitservice ("dpmcopyd", &dpmcopy_main))
            exit (SYERR);
#endif
}

void
doit(s)
int s;
{
      int c;
      const char *clienthost = NULL;
      const char *clientip;
      int magic;
      char req_data[REQBUFSZ-3*LONGSIZE];
      int req_type;

      if ((clientip =
          Cgetnetaddress (s, NULL, 0, &na_key, NULL, NULL, NI_NUMERICHOST, 0)) == NULL) {
            clientip = "unknown";
      }

#ifdef CSEC
      Csec_server_initContext (&sec_ctx, CSEC_SERVICE_TYPE_HOST, NULL);
      if (Csec_server_establishContext (&sec_ctx, s) < 0) {
            dpmlogit (func, "[%s]: Could not establish an authenticated connection: %s !\n",
                clientip, Csec_getErrorMessageSummary (LOGBUFSZ-140));
            netclose (s);
            return;
      }
      Csec_server_getClientId (&sec_ctx, &Csec_mech, &Csec_auth_id);
      if (strcmp (Csec_mech, "ID") != 0 &&
           Csec_isIdAService (Csec_mech, Csec_auth_id) < 0 ||
           ! isTrustedHost (s, localhost, localdomain, "DPM", "TRUST")) {
            dpmlogit (func, "[%s]: Host is not trusted, identity provided was (%s,\"%s\")\n",
                clientip, Csec_mech, Csec_auth_id);
            sendrep (s, DPM_RC, EACCES);
            return;
      }
#endif
      if ((c = getreq (s, &magic, &req_type, req_data, &clienthost)) == 0) {
            if (req_type == DPM_INCREQCTR) {
                  dpmlogit (func, "inc_reqctr request from %s\n", clienthost);
                  reqctr++;
            }
      } else {
            dpmlogit (func, "[%s]: Failure getting the request: %s\n",
                clientip, sstrerror(c));
      }
      sendrep (s, DPM_RC, c);
}

void
dpmcopy_set_errstring (s1, s2, s3, errstring, errstringsiz)
char *s1;
char *s2;
char *s3;
char *errstring;
int errstringsiz;
{
      int l;

      l = strlen (s1);
      strcpy (errstring, s1);
      if (s3)
            snprintf (errstring+l, errstringsiz-l, ": %s", s3);
      else if (*s2 && strstr (s2, "Failed for all SURLs") == NULL)
            snprintf (errstring+l, errstringsiz-l, ": %s", s2);
}

int
getreq(s, magic, req_type, req_data, clienthost)
int s;
int *magic;
int *req_type;
char *req_data;
const char **clienthost;
{
      int l;
      unsigned int msglen;
      int n;
      char *rbp;
      char req_hdr[3*LONGSIZE];

      serrno = 0;
      l = netread_timeout (s, req_hdr, sizeof(req_hdr), DPM_TIMEOUT);
      if (l == sizeof(req_hdr)) {
            rbp = req_hdr;
            unmarshall_LONG (rbp, n);
            *magic = n;
            unmarshall_LONG (rbp, n);
            *req_type = n;
            unmarshall_LONG (rbp, msglen);
            if (msglen > REQBUFSZ) {
                  dpmlogit (func, DP046, REQBUFSZ);
                  return (-1);
            }
            l = msglen - sizeof(req_hdr);
            n = netread_timeout (s, req_data, l, DPM_TIMEOUT);
            if (n > 0 && n == l) {
                  if (*clienthost == NULL) {
                        if ((*clienthost =
                            Cgetnetaddress (s, NULL, 0, &na_key, NULL, NULL, 0, 0)) == NULL) {
                              dpmlogit (func, "Could not find the address of the client\n");
                              return (SEINTERNAL);
                        }
                  }
                  return (0);
            }
            l = n;
      }
      if (l > 0)
            dpmlogit (func, DP004, l);
      else if (l < 0)
            dpmlogit (func, DP002, "netread", neterror());
      return (SEINTERNAL);
}

int
upd_cpr(dbfd, rec_addrf, cpr_entry)
struct dpm_dbfd *dbfd;
dpm_dbrec_addr *rec_addrf;
struct dpm_copy_filereq *cpr_entry;
{
      (void) dpm_update_cpr_entry (dbfd, rec_addrf, cpr_entry);
      (void) dpm_end_tr (dbfd);
      if ((cpr_entry->status & 0xF000) == DPM_FAILED)
            nb_file_err++;
      return (0);
}

int
upd_cpr2(dbfd, r_token, from_surl, to_surl, filesize, status, errstring, f_lifetime, cpr_entry)
struct dpm_dbfd *dbfd;
char *r_token;
char *from_surl;
char *to_surl;
u_signed64 filesize;
int status;
char *errstring;
time_t f_lifetime;
struct dpm_copy_filereq *cpr_entry;
{
      dpm_dbrec_addr rec_addrf;

      (void) dpm_start_tr (0, dbfd);
      if (dpm_get_cpr_by_surls (dbfd, r_token,
          from_surl, to_surl, cpr_entry, 1, &rec_addrf) == 0) {
            if (cpr_entry->status == DPM_ACTIVE) {
                  cpr_entry->actual_size = filesize;
                  cpr_entry->status = status;
                  if (errstring)
                        strcpy (cpr_entry->errstring, errstring);
                  if (status == 0)
                        cpr_entry->f_lifetime = f_lifetime;
                  (void) dpm_update_cpr_entry (dbfd, &rec_addrf, cpr_entry);
            }
      } else
            cpr_entry->status = status;
      (void) dpm_end_tr (dbfd);
      if ((cpr_entry->status & 0xF000) == DPM_FAILED)
            nb_file_err++;
      return (0);
}

int
get_copy_type(dbfd, dpm_req, cpr_entry, nbfiles)
struct dpm_dbfd *dbfd;
struct dpm_req *dpm_req;
struct dpm_copy_filereq *cpr_entry;
int *nbfiles;
{
      int c;
      int dest_is_local;
      int i;
      int j = 0;
      dpm_dbrec_addr rec_addrf;
      int src_is_local;
      int surl_is_local;

      for (i = 0; i < dpm_req->nbreqfiles; i++) {
            (void) dpm_start_tr (0, dbfd);
            if (dpm_get_cpr_by_fullid (dbfd, dpm_req->r_token, i,
                cpr_entry, 1, &rec_addrf) < 0) {
                  dpm_abort_tr (dbfd);
                  continue;
            }
            if (cpr_entry->status != DPM_QUEUED) {    /* No need to process */
                  dpm_abort_tr (dbfd);
                  if (cpr_entry->status == DPM_ABORTED ||
                      (cpr_entry->status & 0xF000) == DPM_FAILED)
                        nb_file_err++;
                  continue;
            }
            surl_is_local = 0;
            if (strncmp (cpr_entry->from_surl, "srm://", 6) == 0) {
                  if ((c = is_surl_local (cpr_entry->from_surl)) < 0) {
                        cpr_entry->status = DPM_FAILED | EINVAL;
                        strcpy (cpr_entry->errstring, "Bad SURL syntax");
                        (void) upd_cpr (dbfd, &rec_addrf, cpr_entry);
                        continue;
                  } else if (c)
                        surl_is_local = 1;
            } else
                  surl_is_local = 1;
            if (j == 0)
                  src_is_local = surl_is_local;
            else if (surl_is_local != src_is_local) {
                  cpr_entry->status = DPM_FAILED | EINVAL;
                  strcpy (cpr_entry->errstring, "All transfers must be in the same direction");
                  (void) upd_cpr (dbfd, &rec_addrf, cpr_entry);
                  continue;
            }
            surl_is_local = 0;
            if (strncmp (cpr_entry->to_surl, "srm://", 6) == 0) {
                  if ((c = is_surl_local (cpr_entry->to_surl)) < 0) {
                        cpr_entry->status = DPM_FAILED | EINVAL;
                        strcpy (cpr_entry->errstring, "Bad SURL syntax");
                        (void) upd_cpr (dbfd, &rec_addrf, cpr_entry);
                        continue;
                  } else if (c)
                        surl_is_local = 1;
            } else
                  surl_is_local = 1;
            if (j == 0)
                  dest_is_local = surl_is_local;
            else if (surl_is_local != dest_is_local) {
                  cpr_entry->status = DPM_FAILED | EINVAL;
                  strcpy (cpr_entry->errstring, "All transfers must be in the same direction");
                  (void) upd_cpr (dbfd, &rec_addrf, cpr_entry);
                  continue;
            }
            if (j == 0) {
                  if (src_is_local == 0 && dest_is_local == 0) {
                        cpr_entry->status = DPM_FAILED | EINVAL;
                        strcpy (cpr_entry->errstring, "src and dest are both remote");
                        (void) upd_cpr (dbfd, &rec_addrf, cpr_entry);
                        continue;
                  }
            }
            j++;
      }
      if (j == 0 && nb_file_err)
            return (-1);
      *nbfiles = j;
      if (src_is_local)
            return (dest_is_local ? 0 : 1);
      return (2);
}

void
procreq(db_srvr, db_user, db_pwd, db_name)
char *db_srvr;
char *db_user;
char *db_pwd;
char *db_name;
{
      int alloced_gids = 0;
      int c;
      struct dpm_copy_filereq cpr_entry;
      struct dpm_dbfd dbfd;
      struct dpm_req dpm_req;
      char errbuf[256];
      char **fqan = NULL;
      gid_t *gids = NULL;
      int i;
      int nbfiles;
      int nbgids;
      char *p;
      static char proxy_env[sizeof(P_tmpdir)+CA_MAXDPMTOKENLEN+20];
      dpm_dbrec_addr rec_addr;
      int status;
      char *voname = NULL;

      /* Connect to the database */

      dpm_seterrbuf (errbuf, sizeof(errbuf));
      memset (&dbfd, 0, sizeof(dbfd));
      if (dpm_opendb (db_srvr, db_user, db_pwd, db_name, &dbfd) < 0)
            exit (SYERR);

      /* Get next request and mark it "active" */

      (void) dpm_start_tr (0, &dbfd);
      if (dpm_get_next_req (&dbfd, DPM_QUEUED4COPY, &dpm_req, 1, &rec_addr) < 0) {
            dpm_abort_tr (&dbfd);
            (void) dpm_closedb (&dbfd);
            exit (serrno == ENOENT ? 0 : SYERR);
      }
      if (dpm_req.stime == 0)
            dpm_req.stime = time (0);
      dpm_req.status = DPM_ACTIVE;
      if (dpm_update_pending_entry (&dbfd, &rec_addr, &dpm_req) < 0) {
            dpm_abort_tr (&dbfd);
            (void) dpm_closedb (&dbfd);
            exit (serrno == ENOENT ? 0 : SYERR);
      }
      dpm_end_tr (&dbfd);

      nbgids = 1;
      gids = &dpm_req.r_gid;
#ifdef CSEC
      if (dpm_req.r_uid) {
            dpm_client_setAuthorizationId (dpm_req.r_uid, dpm_req.r_gid,
                "GSI", dpm_req.client_dn);
#ifdef VIRTUAL_ID
#ifdef USE_VOMS
            if ((gids = Cdecode_groups (dpm_req.groups, &nbgids)) == NULL)
                  goto free_voms_info;
            alloced_gids = 1;
            if ((fqan = calloc (nbgids, sizeof(char *))) == NULL)
                  goto free_voms_info;
            if (Cns_getgrpbygids (nbgids, gids, fqan) < 0)
                  goto free_voms_info;
            if ((voname = strdup (fqan[0])) == NULL)
                  goto free_voms_info;
            if ((p = strchr (voname, '/')))
                  *p = '\0';

            /* pass the VOMS auth data to the DPM */
            dpm_client_setVOMS_data (voname, fqan, nbgids);
#endif
#endif
      }
#endif
      dpmlogit (func, "processing request %s from %s\n", dpm_req.r_token,
          dpm_req.client_dn);

      strcpy (proxy_env, "X509_USER_PROXY=");
      (void) build_proxy_filename (proxy_env+16, dpm_req.r_token);
      putenv (proxy_env);
      unsetenv ("X509_USER_CERT");
      unsetenv ("X509_USER_KEY");

      /* process request according to copy type */

      status = get_copy_type (&dbfd, &dpm_req, &cpr_entry, &nbfiles);
      switch (status) {
      case 0:
            status = dpmcopy_local (&dbfd, &dpm_req, &cpr_entry, nbfiles);
            break;
      case 1:
            status = dpmcopy_push (&dbfd, &dpm_req, &cpr_entry, nbfiles);
            break;
      case 2:
            status = dpmcopy_pull (&dbfd, &dpm_req, &cpr_entry, nbfiles);
            break;
      default:
            break;
      }

      (void) unlink (proxy_env + 16);           /* remove delegated proxy */

      /* Move the request to the non-pending queue */

      (void) dpm_start_tr (0, &dbfd);
      if ((c = dpm_get_pending_req_by_token (&dbfd, dpm_req.r_token, &dpm_req,
          1, &rec_addr)) < 0) {
            dpm_abort_tr (&dbfd);
            (void) dpm_closedb (&dbfd);
            exit (serrno == ENOENT ? 0 : SYERR);
      }
      if (dpm_delete_pending_entry (&dbfd, &rec_addr) < 0) {
            dpm_abort_tr (&dbfd);
            (void) dpm_closedb (&dbfd);
            exit (SYERR);
      }
      dpm_req.etime = time (0);
      if (nb_file_err == 0)
            dpm_req.status = DPM_SUCCESS;
      else if (nb_file_err != dpm_req.nbreqfiles)
            dpm_req.status = DPM_DONE;
      else {
            if (dpm_req.nbreqfiles == 1)
                  dpm_req.status = cpr_entry.status;
            else
                  dpm_req.status = DPM_FAILED | EINVAL;
            strcpy (dpm_req.errstring, "Failed for all SURLs");
      }
      if (dpm_insert_xferreq_entry (&dbfd, &dpm_req) < 0) {
            dpm_abort_tr (&dbfd);
            (void) dpm_closedb (&dbfd);
            exit (SYERR);
      }
      dpm_end_tr (&dbfd);

free_voms_info:
      free (voname);
      if (fqan) {
            for (i = 0; i < nbgids; i++)
                  free (fqan[i]);
            free (fqan);
      }
      if (alloced_gids)
            free (gids);
      (void) dpm_closedb (&dbfd);
      exit (0);
}

#if ! defined(_WIN32)
void
wait4child()
{
}

void
check_child_exit()
{
      pid_t pid;
      int status;

      while ((pid = waitpid (-1, &status, WNOHANG)) > 0) {
            dpmlogit (func, "process %d exiting with status %x\n",
                pid, status & 0xFFFF);
            nbchildren--;
      }
}
#endif

Generated by  Doxygen 1.6.0   Back to index