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

send2dpm.c

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

#ifndef lint
static char sccsid[] = "@(#)$RCSfile: send2dpm.c,v $ $Revision: 1.19 $ $Date: 2009/09/16 15:16:25 $ CERN IT-GD/CT Jean-Philippe Baud";
#endif /* not lint */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#if defined(_WIN32)
#include <winsock2.h>
#else
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#endif
#include "Cnetdb.h"
#ifdef CSEC
#include "Csec_api.h"
#endif
#include "dpm.h"
#include "dpm_api.h"
#include "marshall.h"
#include "net.h"
#include "serrno.h"
#if defined(_WIN32)
extern char *ws_strerr;
#endif

/* send2dpm - send a request to the disk pool manager and wait for the reply */

send2dpm(host, reqp, reql, user_repbuf, user_repbuf_len, repbuf2, nbstruct)
char *host;
char *reqp;
int reql;
char *user_repbuf;
int user_repbuf_len;
void **repbuf2;
int *nbstruct;
{
      int actual_replen = 0;
      struct addrinfo *ai;
      struct addrinfo *aitop;
      int alloced = 0;
      int c;
      struct dpm_copyfilestatus *cpr_entry;
#ifdef CSEC
      Csec_context_t ctx;
#endif
      struct dpm_space_metadata *spacemd;
      char dpmhost[CA_MAXHOSTNAMELEN+1];
      struct dpm_fs *elemp;
      int errflag = 0;
      char errstring[256];
      struct dpm_filestatus *filestatus;
      char func[16];
      int gaierrno;
      char *getconfent();
      char *getenv();
      struct dpm_getfilestatus *gfr_entry;
      struct addrinfo hints;
      int i;
      int isconnected;
      int magic;
      int n;
      char *neterrstr = NULL;
      char *p;
      struct dpm_putfilestatus *pfr_entry;
      struct dpm_pool *poolp;
      char prtbuf[PRTBUFSZ];
      char *q;
      int rep_type;
      char repbuf[REPBUFSZ];
      int repbuf2sz;
      int s;
      int save_serrno;
      char s_token[CA_MAXDPMTOKENLEN+1];
      char **s_tokens;
      char strport[NI_MAXSERV];
      struct dpm_reqsummary *summary;
      char surl[CA_MAXSFNLEN+1];
      struct dpm_api_thread_info *thip = NULL;
      struct dpm_tokeninfo *tokeninfo;

      strcpy (func, "send2dpm");
      if ((p = getenv ("DPM_PORT")) || (p = getconfent ("DPM", "PORT", 0))) {
            strncpy (strport, p, sizeof(strport));
            strport[sizeof(strport)-1] = '\0';
      } else {
            snprintf (strport, sizeof(strport), "%u", DPM_PORT);
            serrno = 0;
      }
      if (host && *host)
            strcpy (dpmhost, host);
      else if ((p = getenv ("DPM_HOST")) || (p = getconfent ("DPM", "HOST", 0)))
            strcpy (dpmhost, p);
      else {
#if defined(DPM_HOST)
            strcpy (dpmhost, DPM_HOST);
#else
            gethostname (dpmhost, sizeof(dpmhost));
#endif
            serrno = 0;
      }

      memset (&hints, 0, sizeof(struct addrinfo));
      hints.ai_family = PF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
#ifdef AI_ADDRCONFIG
      hints.ai_flags |= AI_ADDRCONFIG;
#endif

      gaierrno = Cgetaddrinfo (dpmhost, strport, &hints, &aitop);

      if (gaierrno !=0 && serrno == 0)
            serrno = SENOSHOST;

      if (gaierrno == EAI_NONAME) {
            dpm_errmsg (func, DP009, "Host unknown:", dpmhost);
            return (-1);
      } else if (gaierrno != 0) { 
            dpm_errmsg (func, "Error during lookup of %s: %s\n",
                        dpmhost, Cgai_strerror (gaierrno));
            return (-1);
      }

      isconnected = 0;
      save_serrno = 0;
      for (ai = aitop; ai && !isconnected; ai = ai->ai_next) {
            if (ai->ai_family != PF_INET && ai->ai_family != PF_INET6)
                  continue;
            if ((s = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol))<0) {
                  continue;
            }

            if (connect (s, ai->ai_addr, ai->ai_addrlen) < 0) {
#if defined(_WIN32)  
                  if (WSAGetLastError() == WSAEAFNOSUPPORT) {
#else
                  if (errno == EAFNOSUPPORT) {
#endif
                        (void) netclose (s);
                        continue;
                  }
#if defined(_WIN32)
                  if (WSAGetLastError() == WSAECONNREFUSED) {
#else
                  if (errno == ECONNREFUSED) {
#endif
                        save_serrno = EDPMNACT;
                  } else {
                        save_serrno = SECOMERR;
                  }

                  p = neterror ();
                  if (neterrstr)
                        free (neterrstr);
                  neterrstr = strdup (p);
                  (void) netclose (s);
            } else {
                  isconnected = 1;
            }
      }

      freeaddrinfo (aitop);
      if (!isconnected) {
            serrno = (save_serrno) ? save_serrno : SECOMERR;
            switch(serrno) {
                  case EDPMNACT:
                        dpm_errmsg (func, DP000, dpmhost);
                        break;
                  default:
                        if (neterrstr) {
                              dpm_errmsg (func, DP002, "connect", neterrstr);
                        } else {
                              dpm_errmsg (func, "Could not create "
                                          "an outgoing connection\n");
                        }
                        break;
            }
            if (neterrstr)
                  free (neterrstr);
            return (-1);
      }
      if (neterrstr) {
            free (neterrstr);
            neterrstr = NULL;
      }

#ifdef CSEC
      Csec_client_initContext (&ctx, CSEC_SERVICE_TYPE_HOST, NULL);
      if (dpm_apiinit (&thip) == 0) {
            if (thip->use_authorization_id &&
                *thip->Csec_mech && *thip->Csec_auth_id) {
                  Csec_client_setAuthorizationId (&ctx,
                      thip->Csec_mech, thip->Csec_auth_id);
                  if (thip->voname && thip->fqan)
                        Csec_client_setVOMS_data (&ctx,
                            thip->voname, thip->fqan, thip->nbfqan);
            }
            if (thip->Csec_opt)
                  Csec_client_setSecurityOpts (&ctx, thip->Csec_opt);
      }
      if (Csec_client_establishContext (&ctx, s) < 0) {
            if (serrno != SECOMERR && serrno != SETIMEDOUT)
                  dpm_errmsg (func, DP002, "send", Csec_getErrorMessageSummary (PRTBUFSZ-48));
            (void) netclose (s);
            Csec_clearContext (&ctx);
            return (-1);
      }
      Csec_clearContext (&ctx);
#endif

      /* send request to DPM server */

      if ((n = netwrite (s, reqp, reql)) <= 0) {
            if (n == 0)
                  dpm_errmsg (func, DP002, "send", sys_serrlist[SERRNO]);
            else
                  dpm_errmsg (func, DP002, "send", neterror());
            (void) netclose (s);
            serrno = SECOMERR;
            return (-1);
      }

      /* get reply */

      while (1) {
            if ((n = netread (s, repbuf, 3 * LONGSIZE)) <= 0) {
                  if (n == 0)
                        dpm_errmsg (func, DP002, "recv", sys_serrlist[SERRNO]);
                  else
                        dpm_errmsg (func, DP002, "recv", neterror());
                  (void) netclose (s);
                  serrno = SECOMERR;
                  return (-1);
            }
            p = repbuf;
            unmarshall_LONG (p, magic) ;
            unmarshall_LONG (p, rep_type) ;
            unmarshall_LONG (p, c) ;
            if (rep_type == DPM_IRC)
                  return (0);
            if (rep_type == DPM_RC) {
                  (void) netclose (s);
                  if (errflag)
                        c = ENOMEM;
                  if (c) {
                        serrno = c;
                        c = -1;
                  }
                  break;
            }
            if (c > REPBUFSZ) {
                  dpm_errmsg (func, "reply too large\n");
                  serrno = SEINTERNAL;
                  return (-1);
            }
            if (c && (n = netread (s, repbuf, c)) <= 0) {
                  if (n == 0)
                        dpm_errmsg (func, DP002, "recv", sys_serrlist[SERRNO]);
                  else
                        dpm_errmsg (func, DP002, "recv", neterror());
                  (void) netclose (s);
                  serrno = SECOMERR;
                  return (-1);
            }
            p = repbuf;
            if (rep_type == MSG_ERR) {
                  unmarshall_STRING (p, prtbuf);
                  dpm_errmsg (NULL, "%s", prtbuf);
            } else if (rep_type == MSG_GET) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        unmarshall_LONG (p, *nbstruct);
                        if (*nbstruct && (*repbuf2 =
                            malloc (*nbstruct * sizeof(struct dpm_getfilestatus))) == NULL) {
                              errflag++;
                              continue;
                        }
                        alloced = 1;
                        gfr_entry = (struct dpm_getfilestatus *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        unmarshall_STRING (p, surl);
                        if (! *surl)
                              gfr_entry->from_surl = NULL;
                        else if ((gfr_entry->from_surl = strdup (surl)) == NULL)
                              errflag++;
                        unmarshall_STRING (p, surl);
                        if (! *surl)
                              gfr_entry->turl = NULL;
                        else if ((gfr_entry->turl = strdup (surl)) == NULL)
                              errflag++;
                        unmarshall_HYPER (p, gfr_entry->filesize);
                        unmarshall_LONG (p, gfr_entry->status);
                        unmarshall_STRING (p, errstring);
                        if (! *errstring)
                              gfr_entry->errstring = NULL;
                        else if ((gfr_entry->errstring = strdup (errstring)) == NULL)
                              errflag++;
                        unmarshall_TIME_T (p, gfr_entry->pintime);
                        gfr_entry++;
                  }
            } else if (rep_type == MSG_PUT) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        unmarshall_LONG (p, *nbstruct);
                        if (*nbstruct && (*repbuf2 =
                            malloc (*nbstruct * sizeof(struct dpm_putfilestatus))) == NULL) {
                              errflag++;
                              continue;
                        }
                        alloced = 1;
                        pfr_entry = (struct dpm_putfilestatus *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        unmarshall_STRING (p, surl);
                        if (! *surl)
                              pfr_entry->to_surl = NULL;
                        else if ((pfr_entry->to_surl = strdup (surl)) == NULL)
                              errflag++;
                        unmarshall_STRING (p, surl);
                        if (! *surl)
                              pfr_entry->turl = NULL;
                        else if ((pfr_entry->turl = strdup (surl)) == NULL)
                              errflag++;
                        unmarshall_HYPER (p, pfr_entry->filesize);
                        unmarshall_LONG (p, pfr_entry->status);
                        unmarshall_STRING (p, errstring);
                        if (! *errstring)
                              pfr_entry->errstring = NULL;
                        else if ((pfr_entry->errstring = strdup (errstring)) == NULL)
                              errflag++;
                        unmarshall_TIME_T (p, pfr_entry->pintime);
                        unmarshall_TIME_T (p, pfr_entry->f_lifetime);
                        pfr_entry++;
                  }
            } else if (rep_type == MSG_COPY) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        unmarshall_LONG (p, *nbstruct);
                        if (*nbstruct && (*repbuf2 =
                            malloc (*nbstruct * sizeof(struct dpm_copyfilestatus))) == NULL) {
                              errflag++;
                              continue;
                        }
                        alloced = 1;
                        cpr_entry = (struct dpm_copyfilestatus *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        unmarshall_STRING (p, surl);
                        if (! *surl)
                              cpr_entry->from_surl = NULL;
                        else if ((cpr_entry->from_surl = strdup (surl)) == NULL)
                              errflag++;
                        unmarshall_STRING (p, surl);
                        if (! *surl)
                              cpr_entry->to_surl = NULL;
                        else if ((cpr_entry->to_surl = strdup (surl)) == NULL)
                              errflag++;
                        unmarshall_HYPER (p, cpr_entry->filesize);
                        unmarshall_LONG (p, cpr_entry->status);
                        unmarshall_STRING (p, errstring);
                        if (! *errstring)
                              cpr_entry->errstring = NULL;
                        else if ((cpr_entry->errstring = strdup (errstring)) == NULL)
                              errflag++;
                        unmarshall_TIME_T (p, cpr_entry->f_lifetime);
                        cpr_entry++;
                  }
            } else if (rep_type == MSG_SURLST) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        unmarshall_LONG (p, *nbstruct);
                        if (*nbstruct && (*repbuf2 =
                            malloc (*nbstruct * sizeof(struct dpm_filestatus))) == NULL) {
                              errflag++;
                              continue;
                        }
                        alloced = 1;
                        filestatus = (struct dpm_filestatus *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        unmarshall_STRING (p, surl);
                        if (! *surl)
                              filestatus->surl = NULL;
                        else if ((filestatus->surl = strdup (surl)) == NULL)
                              errflag++;
                        unmarshall_LONG (p, filestatus->status);
                        unmarshall_STRING (p, errstring);
                        if (! *errstring)
                              filestatus->errstring = NULL;
                        else if ((filestatus->errstring = strdup (errstring)) == NULL)
                              errflag++;
                        filestatus++;
                  }
            } else if (rep_type == MSG_FS) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        unmarshall_LONG (p, *nbstruct);
                        if (*nbstruct && (*repbuf2 =
                            malloc (*nbstruct * sizeof(struct dpm_fs))) == NULL) {
                              errflag++;
                              continue;
                        }
                        alloced = 1;
                        elemp = (struct dpm_fs *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        unmarshall_STRING (p, elemp->poolname);
                        unmarshall_STRING (p, elemp->server);
                        unmarshall_STRING (p, elemp->fs);
                        unmarshall_HYPER (p, elemp->capacity);
                        unmarshall_HYPER (p, elemp->free);
                        unmarshall_LONG (p, elemp->status);
                        elemp++;
                  }
            } else if (rep_type == MSG_POOL) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        unmarshall_LONG (p, *nbstruct);
                        if (*nbstruct && (*repbuf2 =
                            malloc (*nbstruct * sizeof(struct dpm_pool))) == NULL) {
                              errflag++;
                              continue;
                        }
                        alloced = 1;
                        poolp = (struct dpm_pool *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        unmarshall_STRING (p, poolp->poolname);
                        unmarshall_HYPER (p, poolp->defsize);
                        unmarshall_LONG (p, poolp->gc_start_thresh);
                        unmarshall_LONG (p, poolp->gc_stop_thresh);
                        unmarshall_LONG (p, poolp->defpintime);
                        unmarshall_STRING (p, poolp->fss_policy);
                        unmarshall_STRING (p, poolp->gc_policy);
                        unmarshall_STRING (p, poolp->rs_policy);
                        unmarshall_BYTE (p, poolp->s_type);
                        unmarshall_HYPER (p, poolp->capacity);
                        unmarshall_HYPER (p, poolp->free);
                        unmarshall_LONG (p, poolp->nbelem);
                        unmarshall_STRING (p, poolp->mig_policy);
                        unmarshall_BYTE (p, poolp->ret_policy);
                        unmarshall_LONG (p, poolp->def_lifetime);
                        unmarshall_LONG (p, poolp->max_lifetime);
                        unmarshall_LONG (p, poolp->maxpintime);
                        unmarshall_LONG (p, poolp->nbgids);
                        if ((poolp->gids = malloc (poolp->nbgids * sizeof(gid_t))) == NULL) {
                              errflag++;
                              break;
                        }
                        for (i = 0; i < poolp->nbgids; i++)
                              unmarshall_LONG (p, poolp->gids[i]);
                        poolp++;
                  }
            } else if (rep_type == MSG_SUMMARY) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        unmarshall_LONG (p, *nbstruct);
                        if (*nbstruct && (*repbuf2 =
                            malloc (*nbstruct * sizeof(struct dpm_reqsummary))) == NULL) {
                              errflag++;
                              continue;
                        }
                        *nbstruct = 0;
                        alloced = 1;
                        summary = (struct dpm_reqsummary *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        unmarshall_STRING (p, summary->r_token);
                        unmarshall_BYTE (p, summary->r_type);
                        unmarshall_LONG (p, summary->nb_reqfiles);
                        unmarshall_LONG (p, summary->nb_queued);
                        unmarshall_LONG (p, summary->nb_progress);
                        summary->nb_finished = summary->nb_reqfiles -
                              (summary->nb_queued + summary->nb_progress);
                        summary++;
                        (*nbstruct)++;
                  }
            } else if (rep_type == MSG_REQIDS) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        repbuf2sz = 4096;
                        if ((*repbuf2 = malloc (repbuf2sz)) == NULL) {
                              errflag++;
                              continue;
                        }
                        alloced = 1;
                        *nbstruct = 0;
                        tokeninfo = (struct dpm_tokeninfo *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        if ((char *)tokeninfo - (char *)(*repbuf2) +
                            sizeof(struct dpm_tokeninfo) > repbuf2sz) {
                              repbuf2sz += 4096;
                              if ((q = realloc (*repbuf2, repbuf2sz)) == NULL) {
                                    errflag++;
                                    break;
                              }
                              *repbuf2 = q;
                              tokeninfo = ((struct dpm_tokeninfo *) *repbuf2) + *nbstruct;
                        }
                        unmarshall_STRING (p, tokeninfo->r_token);
                        unmarshall_TIME_T (p, tokeninfo->c_time);
                        (*nbstruct)++;
                        tokeninfo++;
                  }
            } else if (rep_type == MSG_SPCMD) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        unmarshall_LONG (p, *nbstruct);
                        if (*nbstruct && (*repbuf2 =
                            malloc (*nbstruct * sizeof(struct dpm_space_metadata))) == NULL) {
                              errflag++;
                              continue;
                        }
                        *nbstruct = 0;
                        alloced = 1;
                        spacemd = (struct dpm_space_metadata *) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        unmarshall_BYTE (p, spacemd->s_type);
                        unmarshall_STRING (p, spacemd->s_token);
                        unmarshall_LONG (p, spacemd->s_uid);
                        unmarshall_LONG (p, spacemd->s_gid);
                        unmarshall_BYTE (p, spacemd->ret_policy);
                        unmarshall_BYTE (p, spacemd->ac_latency);
                        unmarshall_STRING (p, spacemd->u_token);
                        if (magic > DPM_MAGIC) {
                              unmarshall_STRING (p, spacemd->client_dn);
                        } else
                              spacemd->client_dn[0] = '\0';
                        unmarshall_HYPER (p, spacemd->t_space);
                        unmarshall_HYPER (p, spacemd->g_space);
                        unmarshall_HYPER (p, spacemd->u_space);
                        unmarshall_STRING (p, spacemd->poolname);
                        unmarshall_TIME_T (p, spacemd->a_lifetime);
                        unmarshall_TIME_T (p, spacemd->r_lifetime);
                        if (magic > DPM_MAGIC) {
                              unmarshall_LONG (p, spacemd->nbgids);
                              if ((spacemd->gids = malloc (spacemd->nbgids * sizeof(gid_t))) == NULL) {
                                    errflag++;
                                    break;
                              }
                              for (i = 0; i < spacemd->nbgids; i++)
                                    unmarshall_LONG (p, spacemd->gids[i]);
                        } else {
                              if (spacemd->s_gid) {
                                    spacemd->nbgids = 1;
                                    if ((spacemd->gids = malloc (spacemd->nbgids * sizeof(gid_t))) == NULL) {
                                          errflag++;
                                          break;
                                    }
                                    spacemd->gids[0] = spacemd->s_gid;
                              } else {
                                    spacemd->nbgids = 0;
                                    spacemd->gids = NULL;
                              }
                        }
                        spacemd++;
                        (*nbstruct)++;
                  }
            } else if (rep_type == MSG_SPCTKN) {
                  if (errflag) continue;
                  if (alloced == 0) {
                        repbuf2sz = 4096;
                        if ((*repbuf2 = malloc (repbuf2sz)) == NULL) {
                              errflag++;
                              continue;
                        }
                        alloced = 1;
                        *nbstruct = 0;
                        s_tokens = (char **) *repbuf2;
                  }
                  while (p < repbuf + c) {
                        if (*nbstruct >= repbuf2sz/sizeof(char *)) {
                              repbuf2sz += 4096;
                              if ((q = realloc (*repbuf2, repbuf2sz)) == NULL) {
                                    errflag++;
                                    break;
                              }
                              *repbuf2 = q;
                              s_tokens = ((char **) *repbuf2);
                        }
                        unmarshall_STRING (p, s_token);
                        if((s_tokens[*nbstruct] = strdup (s_token)) == NULL) {
                              errflag++;
                              break;
                        }
                        (*nbstruct)++;
                  }
            } else if (user_repbuf) {
                  if (actual_replen + c <= user_repbuf_len)
                        n = c;
                  else
                        n = user_repbuf_len - actual_replen;
                  if (n) {
                        memcpy (user_repbuf + actual_replen, repbuf, n);
                        actual_replen += n;
                  }
            }
      }
      return (c);
}

Generated by  Doxygen 1.6.0   Back to index