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

srmv2_dirreq.c

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

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

#include <sys/stat.h>
#include "Cgrp.h"
#include "Cnetdb.h"
#include "Cpwd.h"
#include "dpm.h"
#include "dpm_api.h"
#include "dpm_server.h"
#include "dpm_util.h"
#include "dpns_api.h"
#include "serrno.h"
#include "srm_server.h"
#include "srmv2H.h"
extern char db_name[33];
extern char db_pwd[33];
extern char db_srvr[33];
extern char db_user[33];
extern int Cgroupmatch (gid_t, int, gid_t *);
static int na_key = -1;

/*                Directory Functions                       */

int
ns1__srmMkdir (struct soap *soap, struct ns1__srmMkdirRequest *req, struct ns1__srmMkdirResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      char logbuf[CA_MAXSFNLEN+7];
      int nbfqans;
      int nbgids;
      struct ns1__srmMkdirResponse *repp;
      char *sfn;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "Mkdir");
      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 response structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmMkdirResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      rep->srmMkdirResponse = 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->SURL) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "SURL is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->SURL) > CA_MAXSFNLEN ||
          (sfn = sfnfromsurl (req->SURL)) == NULL) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREPATH;
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREPATH);
      }
      sprintf (logbuf, "Mkdir %s", req->SURL);
      srm_logreq (func, logbuf);

      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 (Cns_mkdir (sfn, 0775) < 0) {
            repp->returnStatus->explanation = soap_strdup (soap, sstrerror (serrno));
            repp->returnStatus->statusCode = serrno2statuscode (serrno);
      } else
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

removedir (struct soap *soap, char *dir)
{
      char curdir[CA_MAXPATHLEN+1];
      struct dirlist {
            char *d_name;
            struct dirlist *next;
      };
      Cns_DIR *dirp;
      struct dirlist *dlc;          /* pointer to current directory in the list */
      struct dirlist *dlf = NULL;   /* pointer to first directory in the list */
      struct dirlist *dll;          /* pointer to last directory in the list */
      struct Cns_direnstat *dxp;
      struct dpm_filestatus *filestatuses = NULL;
      char fullpath[CA_MAXPATHLEN+1];
      int i;
      int nbreplicas;
      int nbreplies = 0;
      char *pathp = &fullpath[0];
      struct Cns_filereplicax *rep_entries;

      if ((dirp = Cns_opendir (dir)) == NULL)
            return (-1);

      while ((dxp = Cns_readdirx (dirp)) != NULL) {
            if (dxp->filemode & S_IFDIR) {
                  if ((dlc = (struct dirlist *)
                      soap_malloc (soap, sizeof(struct dirlist))) == NULL ||
                      (dlc->d_name = soap_strdup (soap, dxp->d_name)) == NULL) {
                        return (-2);
                  }
                  dlc->next = 0;
                  if (dlf == NULL)
                        dlf = dlc;
                  else
                        dll->next = dlc;
                  dll = dlc;
            } else {
                  sprintf (fullpath, "%s/%s", dir, dxp->d_name);
                  rep_entries = NULL;
                  if (Cns_getreplicax (fullpath, NULL, NULL, &nbreplicas,
                      &rep_entries) < 0) {
                        free (rep_entries);
                        continue;
                  }
                  for (i = 0; i < nbreplicas; i++) {
                        if ((rep_entries + i)->r_type == 'P') break;
                  }
                  if (nbreplicas  == 0 || (rep_entries + i)->ltime <= time (0)) {
                        (void) dpm_rm (1, &pathp, &nbreplies, &filestatuses);
                        dpm_free_filest (nbreplies, filestatuses);
                  }
                  free (rep_entries);
            }
      }
      (void) Cns_closedir (dirp);
      while (dlf) {
            sprintf (curdir, "%s/%s", dir, dlf->d_name);
            (void) removedir (soap, curdir);
            soap_dealloc (soap, dlf->d_name);
            dlc = dlf;
            dlf = dlf->next;
            soap_dealloc (soap, dlc);
      }
      return (Cns_rmdir (dir));
}

int
ns1__srmRmdir (struct soap *soap, struct ns1__srmRmdirRequest *req, struct ns1__srmRmdirResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      char logbuf[CA_MAXSFNLEN+7];
      int nbfqans;
      int nbgids;
      int rc;
      int rflag = 0;
      struct ns1__srmRmdirResponse *repp;
      char *sfn;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "Rmdir");
      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 response structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmRmdirResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      rep->srmRmdirResponse = 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->SURL) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "SURL is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->SURL) > CA_MAXSFNLEN ||
          (sfn = sfnfromsurl (req->SURL)) == NULL) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREPATH;
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREPATH);
      }
      if (req->recursive && *req->recursive == true_)
            rflag++;
      sprintf (logbuf, "Rmdir %s", req->SURL);
      srm_logreq (func, logbuf);

      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 (rflag) {
            dpm_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
            dpm_client_setAuthorizationId (uid, gid, "GSI", clientdn);
            if (voname && fqan)
                  dpm_client_setVOMS_data (voname, fqan, nbfqans);
            rc = removedir (soap, sfn);
      } else
            rc = Cns_rmdir (sfn);
      if (rc < 0) {
            repp->returnStatus->explanation = soap_strdup (soap, sstrerror (serrno));
            if (serrno == EEXIST)
                  repp->returnStatus->statusCode = SRM_USCORENON_USCOREEMPTY_USCOREDIRECTORY;
            else
                  repp->returnStatus->statusCode = serrno2statuscode (serrno);
      } else
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmRm (struct soap *soap, struct ns1__srmRmRequest *req, struct ns1__srmRmResponse_ *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;
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nbreplies = 0;
      int nbsurls;
      struct ns1__TSURLReturnStatus *repfilep;
      struct ns1__srmRmResponse *repp;
      char **surls = NULL;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "Rm");
      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 response structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmRmResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->arrayOfFileStatuses = NULL;
      rep->srmRmResponse = 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->arrayOfSURLs) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "arrayOfFilePaths is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      nbsurls = req->arrayOfSURLs->__sizeurlArray;

      /* Allocate the array of file statuses */

      if ((repp->arrayOfFileStatuses =
          soap_malloc (soap, sizeof(struct ns1__ArrayOfTSURLReturnStatus))) == NULL ||
          (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++;
      }

      nb_file_err = nbsurls - 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_rm (j, surls, &nbreplies, &filestatuses) < 0 && ! filestatuses) {
                  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);
            }
      }

      /* Copy the status (and error string) for each file */

      for (i = 0; i < req->arrayOfSURLs->__sizeurlArray; 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");
                  continue;
            }
            if ((filestatuses+i)->surl)
                  free ((filestatuses+i)->surl);
            if ((repfilep->status->statusCode =
                dpmstatus2statuscode ((filestatuses+i)->status, '\0', 0, 0)))
                  nb_file_err++;
            if ((filestatuses+i)->errstring) {
                  repfilep->status->explanation =
                        soap_strdup (soap, (filestatuses+i)->errstring);
                  free ((filestatuses+i)->errstring);
            } else
                  repfilep->status->explanation = NULL;
      }
      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);
}

char *
decode_group(gid_t gid, gid_t *sav_gid, char *sav_gidstr)
{
      struct group *gr;

      if (gid != *sav_gid) {
#ifdef VIRTUAL_ID
            if (gid == 0)
                  return ("root");
            *sav_gid = gid;
            if (Cns_getgrpbygid (*sav_gid, sav_gidstr) < 0)
#else
            *sav_gid = gid;
            if (gr = Cgetgrgid (*sav_gid))
                  strcpy (sav_gidstr, gr->gr_name);
            else
#endif
                  sprintf (sav_gidstr, "%d", *sav_gid);
      }
      return (sav_gidstr);
}

char *
decode_user(uid_t uid, uid_t *sav_uid, char *sav_uidstr)
{
      struct passwd *pw;

      if (uid != *sav_uid) {
#ifdef VIRTUAL_ID
            if (uid == 0)
                  return ("root");
            *sav_uid = uid;
            if (Cns_getusrbyuid (*sav_uid, sav_uidstr) < 0)
#else
            *sav_uid = uid;
            if (pw = Cgetpwuid (*sav_uid))
                  strcpy (sav_uidstr, pw->pw_name);
            else
#endif
                  sprintf (sav_uidstr, "%d", *sav_uid);
      }
      return (sav_uidstr);
}

listdir (struct soap *soap, char *dir, int nbfiles, int fflag, int nblevels, int level, int offset, int count, struct ns1__TMetaDataPathDetail *repfilep, gid_t *sav_gid, char *sav_gidstr, uid_t *sav_uid, char *sav_uidstr, uid_t uid, int nbgids, gid_t *gids)
{
      struct dirlist {
            char *d_name;
            int dirsize;
            struct ns1__TMetaDataPathDetail *repfilep;
            struct dirlist *next;
      };
      Cns_DIR *dirp;
      struct dirlist *dlc;          /* pointer to current directory in the list */
      struct dirlist *dlf = NULL;   /* pointer to first directory in the list */
      struct dirlist *dll;          /* pointer to last directory in the list */
      struct Cns_direnstatg *dxp;
      int i = 0;
      int j = 0;
      char path[CA_MAXPATHLEN+1];

      nbfiles -= offset;
      if (nbfiles > count)
            nbfiles = count;
      if (nbfiles <= 0)
            return (0);
      if ((repfilep->arrayOfSubPaths =
          soap_malloc (soap, sizeof(struct ns1__ArrayOfTMetaDataPathDetail))) == NULL ||
          (repfilep->arrayOfSubPaths->pathDetailArray =
          soap_malloc (soap, nbfiles * sizeof(struct ns1__TMetaDataPathDetail *))) == NULL)
            return (-2);
      if ((dirp = Cns_opendir (dir)) == NULL) {
            repfilep->arrayOfSubPaths = NULL;
            return (-1);
      }
      while ((dxp = Cns_readdirg (dirp)) != NULL) {
            if (j++ < offset) continue;
            if (i >= nbfiles) break;
            if ((repfilep->arrayOfSubPaths->pathDetailArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TMetaDataPathDetail))) == NULL)
                  return (-2);
            sprintf (path, "%s/%s", dir, dxp->d_name);
            listentry (soap, path, dxp, fflag, nblevels, level, offset, count,
                repfilep->arrayOfSubPaths->pathDetailArray[i++],
                sav_gid, sav_gidstr, sav_uid, sav_uidstr, uid, nbgids, gids);
            if (level < nblevels && (dxp->filemode & S_IFDIR) && dxp->nlink) {
                  if ((dlc = (struct dirlist *) 
                      soap_malloc (soap, sizeof(struct dirlist))) == NULL ||
                      (dlc->d_name = soap_strdup (soap, dxp->d_name)) == NULL) {
                        return (-2);
                  }
                  dlc->dirsize = dxp->nlink;
                  dlc->repfilep = repfilep->arrayOfSubPaths->pathDetailArray[i-1];
                  dlc->next = 0;
                  if (dlf == NULL)
                        dlf = dlc;
                  else
                        dll->next = dlc;
                  dll = dlc;
            }
      }
      (void) Cns_closedir (dirp);
      repfilep->arrayOfSubPaths->__sizepathDetailArray = i;
      while (dlf) {
            if (strcmp (dir, "/"))
                  sprintf (path, "%s/%s", dir, dlf->d_name);
            else
                  sprintf (path, "/%s", dlf->d_name);
            listdir (soap, path, dlf->dirsize, fflag, nblevels, level + 1,
                offset, count, dlf->repfilep, sav_gid, sav_gidstr, sav_uid,
                sav_uidstr, uid, nbgids, gids);
            soap_dealloc (soap, dlf->d_name);
            dlc = dlf;
            dlf = dlf->next;
            soap_dealloc (soap, dlc);
      }
      return (0);
}

listentry (struct soap *soap, char *path, struct Cns_filestatg *statbuf, int fflag, int nblevels, int level, int offset, int count, struct ns1__TMetaDataPathDetail *repfilep, gid_t *sav_gid, char *sav_gidstr, uid_t *sav_uid, char *sav_uidstr, uid_t uid, int nbgids, gid_t *gids)
{
      time_t current_time;
      struct dpm_space_reserv dpm_spcmd;
      static enum ns1__TPermissionMode f_modes[] = {NONE, X, W, WX, R, RX, RW, RWX};
      static enum ns1__TFileType ftypes[] = {FILE_, DIRECTORY, LINK};
      int i;
      int j;
      static enum ns1__TFileLocality ltypes[] = {ONLINE_, NEARLINE_, ONLINE_USCOREAND_USCORENEARLINE, LOST, NONE_, UNAVAILABLE};
      int nbreplicas = 0;
      int nearline = 0;
      int online = 0;
      struct Cns_filereplicax *rep_entries = NULL;
      static enum ns1__TFileStorageType s_types[] = {VOLATILE, DURABLE, PERMANENT};
      char *sfn;
      struct Cns_filestatg st;
      struct srm_srv_thread_info *thip = soap->user;

      memset (repfilep, 0, sizeof(struct ns1__TMetaDataPathDetail));
      if ((repfilep->status =
          soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL)
            return (-2);
      memset (repfilep->status, 0, sizeof(struct ns1__TReturnStatus));
      if (! statbuf) {
            if (! path) {
                  repfilep->status->statusCode = SRM_USCOREINVALID_USCOREPATH;
                  repfilep->status->explanation = soap_strdup (soap, "Pointer to SURL is NULL");
                  return (-1);
            }
            if (strlen (path) > CA_MAXSFNLEN ||
                (sfn = sfnfromsurl (path)) == NULL) {
                  repfilep->status->statusCode = SRM_USCOREINVALID_USCOREPATH;
                  return (-1);
            }
            repfilep->path = sfn;
            if (Cns_statg (sfn, NULL, &st) < 0) {
                  repfilep->status->explanation = soap_strdup (soap, sstrerror (serrno));
                  repfilep->status->statusCode = serrno2statuscode (serrno);
                  return (-1);
            }
      } else {
            if ((repfilep->path = soap_strdup (soap, path)) == NULL)
                  return (-2);
            memcpy (&st, statbuf, sizeof(struct Cns_filestatg));
      }
      if ((repfilep->size = soap_malloc (soap, sizeof(ULONG64))))
            *repfilep->size = (st.filemode & S_IFDIR) ? 0 : st.filesize;
      if (st.filemode & S_IFDIR)
            repfilep->type = &ftypes[DIRECTORY];
      else if ((st.filemode & S_IFLNK) == S_IFLNK)
            repfilep->type = &ftypes[LINK];
      else
            repfilep->type = &ftypes[FILE_];
      if (fflag == 0)
            goto end_entry;
      repfilep->createdAtTime =
            soap_strdup (soap, soap_dateTime2s (soap, st.ctime));
      repfilep->lastModificationTime =
            soap_strdup (soap, soap_dateTime2s (soap, st.mtime));
      if ((st.filemode & S_IFDIR) == 0 && level == 0 &&
          Cns_getreplicax (sfn, NULL, NULL, &nbreplicas, &rep_entries) == 0) {
            for (i = 0; i < nbreplicas; i++) {
                  if ((rep_entries + i)->r_type == 'P') break;
            }
            if (i < nbreplicas) {
                  if ((rep_entries + i)->f_type == 'V')
                        repfilep->fileStorageType = &s_types[VOLATILE];
                  else if ((rep_entries + i)->f_type == 'D')
                        repfilep->fileStorageType = &s_types[DURABLE];
                  else
                        repfilep->fileStorageType = &s_types[PERMANENT];
                  current_time = time (0);
                  if ((repfilep->lifetimeLeft = soap_malloc (soap, sizeof(int))))
                        *repfilep->lifetimeLeft = ((rep_entries + i)->ltime == 0x7FFFFFFF) ?
                            -1 : ((rep_entries + i)->ltime > current_time) ?
                            (rep_entries + i)->ltime - current_time : 0;
            }
            for (i = 0; i < nbreplicas; i++) {
                  if ((rep_entries + i)->status == '-')
                        online++;
                  else if ((rep_entries + i)->status == 'N')
                        nearline++;
            }
            if (online) {
                  if (nearline)
                        repfilep->fileLocality = &ltypes[ONLINE_USCOREAND_USCORENEARLINE];
                  else
                        repfilep->fileLocality = &ltypes[ONLINE_];
            } else if (nearline)
                  repfilep->fileLocality = &ltypes[NEARLINE_];
            else
                  repfilep->fileLocality = &ltypes[NONE_];

            /* check if any space token associated with this file */

            j = 0;
            for (i = 0; i < nbreplicas; i++)
                  if (*(rep_entries + i)->setname) j++;
            if (j && (repfilep->arrayOfSpaceTokens =
                soap_malloc (soap, sizeof(struct ns1__ArrayOfString))) &&
                (repfilep->arrayOfSpaceTokens->stringArray =
                soap_malloc (soap, j * sizeof(char *)))) {
                  j = 0;
                  for (i = 0; i < nbreplicas; i++) {
                        if (! *(rep_entries + i)->setname) continue;
                        if (dpm_get_spcmd_by_token (&thip->dbfd,
                            (rep_entries + i)->setname,
                            &dpm_spcmd, 0, NULL) < 0) continue;
                        if (((dpm_spcmd.s_gid &&
                            ! Cgroupmatch (dpm_spcmd.s_gid, nbgids, gids)) ||
                            (dpm_spcmd.s_uid && uid != dpm_spcmd.s_uid)) &&
                            uid != 0) continue;
                        if ((repfilep->arrayOfSpaceTokens->stringArray[j] =
                            soap_strdup (soap, (rep_entries + i)->setname)))
                              j++;
                  }
                  if (j)
                        repfilep->arrayOfSpaceTokens->__sizestringArray = j;
                  else
                        repfilep->arrayOfSpaceTokens = NULL;
            }
      }
      free (rep_entries);
      if ((repfilep->ownerPermission =
          soap_malloc (soap, sizeof(struct ns1__TUserPermission)))) {
            repfilep->ownerPermission->userID =
                soap_strdup (soap, decode_user (st.uid, sav_uid, sav_uidstr));
            repfilep->ownerPermission->mode = (st.filemode >> 6) & 7;
      }
      if ((repfilep->groupPermission =
          soap_malloc (soap, sizeof(struct ns1__TGroupPermission)))) {
            repfilep->groupPermission->groupID =
                soap_strdup (soap, decode_group (st.gid, sav_gid, sav_gidstr));
            repfilep->groupPermission->mode = (st.filemode >> 3) & 7;
      }
      repfilep->otherPermission = &f_modes[st.filemode & 7];
      if (*st.csumtype)
            repfilep->checkSumType =
                soap_strdup (soap, csumtype2srmname (st.csumtype));
      if (*st.csumvalue)
            repfilep->checkSumValue = soap_strdup (soap, st.csumvalue);
end_entry:
      if ((st.filemode & S_IFDIR) == 0 || level >= nblevels || st.nlink == 0)
            return (0);
      return (listdir (soap, repfilep->path, st.nlink, fflag, nblevels, level + 1,
          offset, count, repfilep, sav_gid, sav_gidstr, sav_uid, sav_uidstr,
          uid, nbgids, gids));
}

int
ns1__srmLs (struct soap *soap, struct ns1__srmLsRequest *req, struct ns1__srmLsResponse_ *rep)
{
      int c;
      char clientdn[256];
      const char *clienthost;
      int count;
      time_t curtime;
      int fflag;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      int i;
      char logbuf[CA_MAXSFNLEN+4];
      int nb_file_err = 0;
      int nbfqans;
      int nbgids;
      int nblevels;
      int nbsurls;
      int offset;
      struct ns1__srmLsResponse *repp;
      gid_t sav_gid = -1;
      char sav_gidstr[256];
      uid_t sav_uid = -1;
      char sav_uidstr[256];
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "Ls");
      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 response structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmLsResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->requestToken = NULL;
      repp->details = NULL;
      repp->returnStatus->explanation = NULL;
      rep->srmLsResponse = 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->arrayOfSURLs) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "arrayOfSURLs is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (req->fileStorageType) {
            repp->returnStatus->statusCode = SRM_USCORENOT_USCORESUPPORTED;
            repp->returnStatus->explanation = soap_strdup (soap, "filtering by fileStorageType is not supported");
            RETURNSC (SOAP_OK, SRM_USCORENOT_USCORESUPPORTED);
      }
      if (req->allLevelRecursive && *req->allLevelRecursive)
            nblevels = 0x7FFFFFFF;
      else if (req->numOfLevels)
            nblevels = *req->numOfLevels;
      else
            nblevels = 1;
      if (req->fullDetailedList && *req->fullDetailedList == true_)
            fflag = 1;
      else
            fflag = 0;

      nbsurls = req->arrayOfSURLs->__sizeurlArray;
      if (req->offset && *req->offset && nbsurls > 1) {
            repp->returnStatus->statusCode = SRM_USCORENOT_USCORESUPPORTED;
            repp->returnStatus->explanation = soap_strdup (soap, "offset is not supported when nbsurls > 1");
            RETURNSC (SOAP_OK, SRM_USCORENOT_USCORESUPPORTED);
      }
      if (req->offset)
            offset = *req->offset;
      else
            offset = 0;
      if (req->count)
            count = *req->count;
      else
            count = 5000;
      if (count < 0 || offset < 0) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREREQUEST;
            repp->returnStatus->explanation = soap_strdup (soap, "Negative value for count or offset");
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREREQUEST);
      }

      if (fflag) {

            /* 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 ((repp->details =
            soap_malloc (soap, sizeof(struct ns1__ArrayOfTMetaDataPathDetail))) == NULL ||
          (nbsurls > 0 && (repp->details->pathDetailArray =
            soap_malloc (soap, nbsurls * sizeof(struct ns1__TMetaDataPathDetail *))) == NULL))
            RETURN (SOAP_EOM);

      Cns_seterrbuf (thip->errbuf, sizeof(thip->errbuf));
      Cns_client_setAuthorizationId (uid, gid, "GSI", clientdn);
      if (voname && fqan)
            Cns_client_setVOMS_data (voname, fqan, nbfqans);

      repp->details->__sizepathDetailArray = nbsurls;
      for (i = 0; i < nbsurls; i++) {
            sprintf (logbuf, "Ls %s", req->arrayOfSURLs->urlArray[i]);
            srm_logreq (func, logbuf);
            if ((repp->details->pathDetailArray[i] =
                soap_malloc (soap, sizeof(struct ns1__TMetaDataPathDetail))) == NULL)
                  RETURN (SOAP_EOM);
            c = listentry (soap, req->arrayOfSURLs->urlArray[i],
                NULL, fflag, nblevels, 0, offset, count,
                repp->details->pathDetailArray[i],
                &sav_gid, sav_gidstr, &sav_uid, sav_uidstr, uid, nbgids, gids);
            if (c == -2)
                  RETURN (SOAP_EOM);
            if (c == -1)
                  nb_file_err++;
      }
      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;
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

int
ns1__srmStatusOfLsRequest (struct soap *soap, struct ns1__srmStatusOfLsRequestRequest *req, struct ns1__srmStatusOfLsRequestResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      char func[18];
      gid_t gid;
      struct ns1__srmStatusOfLsRequestResponse *repp;
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;

      strcpy (func, "StatusOfLsRequest");
      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__srmStatusOfLsRequestResponse))) == NULL)
            RETURN (SOAP_EOM);
      memset (repp, 0, sizeof(struct ns1__srmStatusOfLsRequestResponse));
      if ((repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      repp->returnStatus->statusCode = SRM_USCORENOT_USCORESUPPORTED;
      rep->srmStatusOfLsRequestResponse = repp;
      RETURNSC (SOAP_OK, SRM_USCORENOT_USCORESUPPORTED);
}

int
ns1__srmMv (struct soap *soap, struct ns1__srmMvRequest *req, struct ns1__srmMvResponse_ *rep)
{
      char clientdn[256];
      const char *clienthost;
      char **fqan;
      char func[16];
      gid_t gid;
      gid_t *gids;
      char logbuf[2*CA_MAXSFNLEN+5];
      int nbfqans;
      int nbgids;
      char *p;
      struct ns1__srmMvResponse *repp;
      char *sfn1;
      char *sfn2;
      struct Cns_filestat st;
      char tgtfile[CA_MAXSFNLEN+1];
      struct srm_srv_thread_info *thip = soap->user;
      uid_t uid;
      char *voname;

      strcpy (func, "Mv");
      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 response structure */

      if ((repp = soap_malloc (soap, sizeof(struct ns1__srmMvResponse))) == NULL ||
          (repp->returnStatus = soap_malloc (soap, sizeof(struct ns1__TReturnStatus))) == NULL) {
            RETURN (SOAP_EOM);
      }
      repp->returnStatus->explanation = NULL;
      rep->srmMvResponse = 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->fromSURL) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "fromSURL is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (! req->toSURL) {
            repp->returnStatus->statusCode = SRM_USCOREFAILURE;
            repp->returnStatus->explanation = soap_strdup (soap, "toSURL is required");
            RETURNSC (SOAP_OK, SRM_USCOREFAILURE);
      }
      if (strlen (req->fromSURL) > CA_MAXSFNLEN ||
          strlen (req->toSURL) > CA_MAXSFNLEN ||
          (sfn1 = sfnfromsurl (req->fromSURL)) == NULL ||
          (sfn2 = sfnfromsurl (req->toSURL)) == NULL) {
            repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREPATH;
            RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREPATH);
      }
      sprintf (logbuf, "Mv %s %s", req->fromSURL, req->toSURL);
      srm_logreq (func, logbuf);

      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 (Cns_stat (sfn2, &st) == 0 && (st.filemode & S_IFDIR)) {
            p = strrchr (sfn1, '/') + 1;
            if (strlen (sfn2) + strlen (p) + 1 > CA_MAXSFNLEN) {
                  repp->returnStatus->statusCode = SRM_USCOREINVALID_USCOREPATH;
                  RETURNSC (SOAP_OK, SRM_USCOREINVALID_USCOREPATH);
            }
            sprintf (tgtfile, "%s/%s", sfn2, p);
            sfn2 = tgtfile;
      }
      if (Cns_rename (sfn1, sfn2) < 0) {
            repp->returnStatus->explanation = soap_strdup (soap, sstrerror (serrno));
            repp->returnStatus->statusCode = serrno2statuscode (serrno);
      } else
            repp->returnStatus->statusCode = SRM_USCORESUCCESS;
      RETURNSC (SOAP_OK, repp->returnStatus->statusCode);
}

Generated by  Doxygen 1.6.0   Back to index