#include "NetErrors.h"
#include "TCastorFile.h"
#include "TError.h"
#include <stdlib.h>
#include <errno.h>
#ifdef _WIN32
#include <WinDef.h>
#include <WinSock2.h>
#endif
#ifdef R__CASTOR2
#include <stager_api.h> // For the new CASTOR 2 Stager
#include <RfioTURL.h> // For the new url parsing
#endif
#define RFIO_KERNEL // Get access to extra symbols in the headers
#include <stage_api.h> // Dial with CASTOR stager
#include <rfio_api.h> // Util routines from rfio
#include <Cns_api.h> // Dial with CASTOR Name Server
#include <Cglobals.h>
#include <rfio_constants.h>
#define RFIO_USE_CASTOR_V2 "RFIO_USE_CASTOR_V2"
#define RFIO_HSM_BASETYPE 0x0
#define RFIO_HSM_CNS RFIO_HSM_BASETYPE+1
extern "C" { int rfio_HsmIf_reqtoput (char *); }
extern "C" { int DLL_DECL rfio_parse(char *, char **, char **); }
extern "C" { int rfio_HsmIf_IsHsmFile (const char *); }
extern "C" { char *getconfent(char *, char *, int); }
extern int tStageHostKey;
extern int tStagePortKey;
extern int tSvcClassKey;
extern int tCastorVersionKey;
int TCastorFile::ParseAndSetGlobal()
{
char **globalHost, **globalSvc;
int *globalVersion, *globalPort;
char *myHost, *mySvcClass;
int myVersion, myPort;
int ret;
char *options, *myCastorVersion, *path2, *path1, *q1, *q;
int versionNum;
char *myTurl;
int newTurl=0;
globalHost = globalSvc = 0;
myHost = mySvcClass = 0;
versionNum = 0;
globalVersion = globalPort = 0;
myVersion = myPort = 0;
myTurl = strdup(fUrl.GetFile());
options = strdup(fUrl.GetOptions());
path2 = strstr(options,"path=");
if (path2) {
newTurl = 1;
path2 += 5;
}
if (newTurl) {
q = strstr(myTurl,":");
q1 = strstr(myTurl,"/");
if (myTurl!=q && myTurl!=q1) {
if (q && q1) {
*q='\0';
q+=1;
fUrl.SetHost(myTurl);
*q1='\0';
q1+=1;
fUrl.SetPort(atoi(q));
}
if (!q && q1) {
*q1='\0';
q1+=1;
fUrl.SetHost(myTurl);
}
} else {
if(q1) q1+=1;
}
if (q1) {
fUrl.SetFile(q1);
} else {
fUrl.SetFile("");
}
}
free(myTurl);
ret=Cglobals_get(&tStageHostKey,(void **)&globalHost,sizeof(void*));
if (ret<0) return -1;
if (*globalHost) {
free(*globalHost);
*globalHost=0;
}
if (strcmp(fUrl.GetHost(),"")) {
*globalHost=strdup(fUrl.GetHost());
}
ret=Cglobals_get(&tStagePortKey,(void **)&globalPort,sizeof(int));
if (ret<0) {
if (*globalHost) {
free(*globalHost);
*globalHost=0;
}
return -1;
}
*globalPort=0;
if (fUrl.GetPort()>0) {
*globalPort=fUrl.GetPort();
}
mySvcClass=strstr(options,"svcClass=");
if (mySvcClass) {
mySvcClass+=9;
}
myCastorVersion=strstr(options,"castorVersion=");
if (myCastorVersion) {
myCastorVersion+=14;
}
if (mySvcClass) {
q1=strstr(mySvcClass,"&");
if (q1) {
*q1='\0';
}
}
if (myCastorVersion) {
q1=strstr(myCastorVersion,"&");
if (q1){
*q1='\0';
}
}
if (path2) {
q1=strstr(path2,"&");
if(q1) {
*q1='\0';
}
}
path1 = (char*)fUrl.GetFile();
if (strcmp(path1,"") && path2) {
if (*globalHost) {
free(*globalHost);
*globalHost=0;
}
free(options);
return -1;
}
if (!strcmp(path1,"") && !path2) {
if (*globalHost) {
free(*globalHost);
*globalHost=0;
}
free(options);
return(-1);
}
if (path2) {
fUrl.SetFile(path2);
}
ret=Cglobals_get(&tSvcClassKey,(void **)&globalSvc,sizeof(void*));
if (ret<0) {
if(*globalHost){
free(*globalHost);
*globalHost=0;
}
free(options);
return -1;
}
if (*globalSvc) {
free(*globalSvc);
*globalSvc=0;
}
if (mySvcClass && strcmp(mySvcClass,"")) {
*globalSvc=strdup(mySvcClass);
}
ret=Cglobals_get(&tCastorVersionKey,(void **)&globalVersion,sizeof(int));
if (ret<0) {
serrno = EINVAL;
if (*globalHost) {
free(*globalHost);
*globalHost=0;
}
if (*globalSvc) {
free(*globalSvc);
*globalSvc=0;
}
free(options);
return -1;
}
*globalVersion=0;
if (myCastorVersion) {
if (!strcmp(myCastorVersion,"2")) {
versionNum=2;
}
if (!strcmp(myCastorVersion,"1")) {
versionNum=1;
}
}
if (versionNum) {
*globalVersion=versionNum;
}
ret=getDefaultForGlobal(globalHost,globalPort,globalSvc,globalVersion);
if (ret<0) {
if (*globalHost) {
free(*globalHost);
*globalHost=0;
}
if (*globalSvc) {
free(*globalSvc);
*globalSvc=0;
}
free(options);
return -1;
}
free(options);
path1=strdup(fUrl.GetFile());
if (strstr(path1,"/castor")== path1) {
fUrl.SetHost("");
fUrl.SetPort(0);
}
free(path1);
return 0;
}
static int UseCastor2API()
{
int *auxVal=0;
int ret=Cglobals_get(& tCastorVersionKey, (void**) &auxVal,sizeof(int));
if (ret==0) {
return *auxVal==2?1:0;
}
return 0;
}
ClassImp(TCastorFile)
TCastorFile::TCastorFile(const char *url, Option_t *option, const char *ftitle,
Int_t compress, Int_t netopt)
: TNetFile(url, ftitle, compress, kFALSE)
{
fIsCastor = kFALSE;
fWrittenTo = kFALSE;
TString opt = option;
opt.ToUpper();
if (opt == "NEW" || opt == "CREATE")
opt = "RECREATE";
Create(url, opt, netopt);
}
void TCastorFile::FindServerAndPath()
{
int ret=ParseAndSetGlobal();
if (ret<0) {
Error("FindServerAndPath", "can't parse the turl given");
return;
}
if (!UseCastor2API()) {
struct stgcat_entry *stcp_output = 0;
if (rfio_HsmIf_IsHsmFile(fUrl.GetFile()) == RFIO_HSM_CNS) {
int flags = O_RDONLY;
struct Cns_filestat st;
int rc;
char stageoutbuf[1025];
char stageerrbuf[1025];
if (strlen(fUrl.GetFile()) > STAGE_MAX_HSMLENGTH) {
serrno = ENAMETOOLONG;
Error("FindServerAndPath", "can't open %s, error %d (%s)", fUrl.GetFile(), serrno, sstrerror(serrno));
return;
}
if (fOption == "CREATE" || fOption == "RECREATE" || fOption == "UPDATE")
flags |= O_RDWR;
if (fOption == "CREATE" || fOption == "RECREATE")
flags |= O_CREAT | O_TRUNC;
memset(&st, 0, sizeof(st));
rc = Cns_stat(fUrl.GetFile(), &st);
if (rc == -1 || ((flags & O_TRUNC) != 0))
st.filesize = 0;
if (stage_setoutbuf(stageoutbuf, 1024) != 0) {
Error("FindServerAndPath", "can't open %s, stage_setoutbuf, error %d (%s)",
fUrl.GetFile(), serrno, sstrerror(serrno));
return;
}
if (stage_seterrbuf(stageerrbuf, 1024) != 0) {
Error("FindServerAndPath", "can't open %s, stage_seterrbuf, error %d (%s)",
fUrl.GetFile(), serrno, sstrerror(serrno));
return;
}
struct stgcat_entry stcp_input;
int nstcp_output;
memset(&stcp_input, 0, sizeof(struct stgcat_entry));
strcpy(stcp_input.u1.h.xfile, fUrl.GetFile());
if (flags == O_RDONLY || st.filesize > 0) {
if (stage_in_hsm((u_signed64) 0,
(int) flags,
(char *) 0,
(char *) 0,
(int) 1,
(struct stgcat_entry *) &stcp_input,
(int *) &nstcp_output,
(struct stgcat_entry **) &stcp_output,
(int) 0,
(struct stgpath_entry *) 0
) != 0) {
Error("FindServerAndPath", "can't open %s, stage_in_hsm error %d (%s)",
fUrl.GetFile(), serrno, sstrerror(serrno));
return;
}
} else {
if (stage_out_hsm((u_signed64) 0,
(int) flags,
(mode_t) 0666,
(char *) 0,
(char *) 0,
(int) 1,
(struct stgcat_entry *) &stcp_input,
(int *) &nstcp_output,
(struct stgcat_entry **) &stcp_output,
(int) 0,
(struct stgpath_entry *) 0
) != 0) {
Error("FindServerAndPath", "can't open %s, stage_out_hsm error %d (%s)",
fUrl.GetFile(), serrno, sstrerror(serrno));
return;
}
}
if ((nstcp_output != 1) || (stcp_output == 0) ||
(*(stcp_output->ipath) == '\0')) {
serrno = SEINTERNAL;
if (stcp_output != 0) free(stcp_output);
Error("FindServerAndPath", "can't open %s, error %d (%s)",
fUrl.GetFile(), serrno, sstrerror(serrno));
return;
}
char *filename;
char *realhost = 0;
rfio_parse(stcp_output->ipath, &realhost, &filename);
if (realhost == 0) {
serrno = SEINTERNAL;
Error("FindServerAndPath", "can't open %s, get disk server hostname from %s error %d (%s)",
fUrl.GetFile(), stcp_output->ipath, errno, sstrerror(serrno));
free(stcp_output);
return;
}
fDiskServer = realhost;
if (filename[0] != '/') {
fInternalPath = "/";
fInternalPath += filename;
} else {
fInternalPath = filename;
}
if (st.filesize == 0) {
fWrittenTo = kTRUE;
}
}
TString r;
TString fqdn;
TInetAddress addr = gSystem->GetHostByName(fDiskServer);
if (addr.IsValid()) {
fqdn = addr.GetHostName();
if (fqdn == "UnNamedHost")
fqdn = addr.GetHostAddress();
if (fqdn.EndsWith(".cern.ch") || fqdn.BeginsWith("137.138."))
r = "rootug:;
else
r = "root:;
} else
r = "root:;
r += fDiskServer + "/";
r += fInternalPath;
TUrl rurl(r);
fUrl = rurl;
Info("FindServerAndPath"," fDiskServer: %s, r: %s", fDiskServer.Data(), r.Data());
fInternalPath = stcp_output->ipath;
free(stcp_output);
} else {
#ifdef R__CASTOR2
int flags = O_RDONLY;
int rc;
struct stage_io_fileresp *response = 0;
char *requestId = 0, *url = 0;
char stageerrbuf[1025];
if (fOption == "CREATE" || fOption == "RECREATE" || fOption == "UPDATE")
flags |= O_RDWR;
if (fOption == "CREATE" || fOption == "RECREATE")
flags |= O_CREAT | O_TRUNC;
stage_seterrbuf(stageerrbuf, 1024);
int* auxVal;
char ** auxPoint;
struct stage_options opts;
opts.stage_host=0;
opts.stage_port=0;
opts.service_class=0;
opts.stage_version=0;
ret=Cglobals_get(& tStageHostKey, (void**) &auxPoint,sizeof(void*));
if(ret==0){
opts.stage_host=*auxPoint;
}
ret=Cglobals_get(& tStagePortKey, (void**) &auxVal,sizeof(int));
if(ret==0){
opts.stage_port=*auxVal;
}
opts.stage_version=2;
ret=Cglobals_get(& tSvcClassKey, (void**) &auxPoint,sizeof(void*));
if (ret==0){
opts.service_class=*auxPoint;
}
rc = stage_open(0,
MOVER_PROTOCOL_ROOT,
(fUrl.GetFile()),
flags,
(mode_t) 0666,
0,
&response,
&requestId,
&opts);
if (rc != 0) {
Error("FindServerAndPath", "stage_open failed: %s (%s)",
sstrerror(serrno), stageerrbuf);
if (response) free(response);
if (requestId) free(requestId);
return;
}
if (response == 0) {
Error("FindServerAndPath", "response was null for %s (Request %s) %d/%s",
fUrl.GetFile(), requestId,
serrno, sstrerror(serrno));
if (requestId) free(requestId);
return;
}
if (response->errorCode != 0) {
serrno = response->errorCode;
Error("FindServerAndPath", "error getting file %s (Request %s) %d/%s",
fUrl.GetFile(), requestId,
serrno, sstrerror(serrno));
free(response);
if (requestId) free(requestId);
return;
}
url = stage_geturl(response);
if (url == 0) {
Error("FindServerAndPath", "error getting file %s (Request %s) %d/%s",
fUrl.GetFile(), requestId,
serrno, sstrerror(serrno));
free(response);
if (requestId) free(requestId);
return;
}
TUrl rurl(url);
TString p;
TString fqdn = rurl.GetHostFQDN();
if (fqdn.EndsWith(".cern.ch") || fqdn.BeginsWith("137.138."))
p = "rootug";
else
p = "root";
rurl.SetProtocol(p);
fUrl = rurl;
if (response) free(response);
if (url) free(url);
if (requestId) free(requestId);
#endif
}
fIsCastor = kTRUE;
}
Int_t TCastorFile::SysClose(Int_t fd)
{
Int_t r = TNetFile::SysClose(fd);
if (!UseCastor2API()) {
if (fIsCastor && fWrittenTo) {
rfio_HsmIf_reqtoput((char *)fInternalPath.Data());
fWrittenTo = kFALSE;
}
}
return r;
}
Bool_t TCastorFile::WriteBuffer(const char *buf, Int_t len)
{
if (TNetFile::WriteBuffer(buf, len))
return kTRUE;
if (!UseCastor2API()) {
if (fIsCastor && !fWrittenTo && len > 0) {
stage_hsm_t hsmfile;
memset(&hsmfile, 0, sizeof(hsmfile));
strcpy(hsmfile.upath, fInternalPath);
if (stage_updc_filchg(0, &hsmfile) < 0) {
Error("WriteBuffer", "error calling stage_updc_filchg");
return kTRUE;
}
fWrittenTo = kTRUE;
}
}
return kFALSE;
}
void TCastorFile::ConnectServer(Int_t *stat, EMessageTypes *kind, Int_t netopt,
Int_t tcpwindowsize, Bool_t forceOpen,
Bool_t forceRead)
{
FindServerAndPath();
if (fIsCastor) {
TNetFile::ConnectServer(stat, kind, netopt, tcpwindowsize, forceOpen, forceRead);
} else {
*stat = kErrFileOpen;
*kind = kROOTD_ERR;
}
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.