Logo ROOT   6.16/01
Reference Guide
TCastorFile.cxx
Go to the documentation of this file.
1// @(#)root/castor:$Id$
2// Author: Fons Rademakers + Jean-Damien Durand 17/09/2003 + Ben Couturier 31/05/2005
3// + Giulia Taurelli 26/04/2006
4
5/*************************************************************************
6 * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13/**
14\class TCastorFile TCastorFile.cxx
15\ingroup IO
16A TNetFile interfaced to the Castor storage backend
17
18A TCastorFile is like a normal TNetFile except that it obtains the
19remote node (disk server) via the CASTOR API, once the disk server
20and the local file path are determined, the file will be accessed
21via the rootd daemon. File names have to be specified like:
22~~~{.bash}
23castor:/castor/cern.ch/user/r/rdm/bla.root
24~~~
25
26If Castor 2.1 is used the file names can also be specified
27in the following ways:
28~~~{.bash}
29castor://stager_host:stager_port/?path=/castor/cern.ch/user/r/rdm/bla.root&svcClass=MYSVCLASS&castorVersion=MYCASTORVERSION
30castor://stager_host/?path=/castor/cern.ch/user/r/rdm/bla.root&svcClass=MYSVCLASS&castorVersion=MYCASTORVERSION
31castor:///castor?path=/castor/cern.ch/user/r/rdm/bla.root&svcClass=MYSVCLASS&castorVersion=MYCASTORVERSION
32~~~
33
34The path is mandatory as parameter but all the other ones are optional.
35Use "&rootAuth=<auth_prot_code>" in the option field to force the
36specified authentication protocol when contacting the server, e.g.
37~~~{.bash}
38castor:///castor?path=/castor/cern.ch/user/r/rdm/bla.root&svcClass=MYSVCLASS&castorVersion=MYCASTORVERSION&rootAuth=3
39~~~
40
41will try first the globus/GSI protocol; available protocols are
42 -# passwd
43 -# srp
44 -# krb5
45 -# globus
46 -# ssh
47 -# uidgid
48
49The default is taken from the env ROOTCASTORAUTH.
50*/
51
52#include "NetErrors.h"
53#include "TCastorFile.h"
54#include "TError.h"
55
56#include <stdlib.h>
57#include <errno.h>
58
59#ifdef _WIN32
60#include <WinDef.h>
61#include <WinSock2.h>
62#endif
63
64#ifdef R__CASTOR2
65#include <stager_api.h> // For the new CASTOR 2 Stager
66#endif
67#define RFIO_KERNEL // Get access to extra symbols in the headers
68#include <stage_api.h> // Dial with CASTOR stager
69#include <rfio_api.h> // Util routines from rfio
70#include <Cns_api.h> // Dial with CASTOR Name Server
71#include <Cglobals.h>
72#include <rfio_constants.h>
73
74#define RFIO_USE_CASTOR_V2 "RFIO_USE_CASTOR_V2"
75#define RFIO_HSM_BASETYPE 0x0
76#define RFIO_HSM_CNS RFIO_HSM_BASETYPE+1
77
78extern "C" { int rfio_HsmIf_reqtoput (char *); }
79extern "C" { int rfio_parse(char *, char **, char **); }
80extern "C" { int rfio_HsmIf_IsHsmFile (const char *); }
81extern "C" { char *getconfent(char *, char *, int); }
82
83#ifdef R__CASTOR2
84extern int tStageHostKey;
85extern int tStagePortKey;
86extern int tSvcClassKey;
87extern int tCastorVersionKey;
88extern "C" { int use_castor2_api(); }
89
90
91/// Function that checks whether we should use the old or new stager API.
92static int UseCastor2API()
93{
94 int version = use_castor2_api();
95 return version;
96}
97
98#else
99
100// Function that checks whether we should use the old or new stager API.
101static int UseCastor2API()
102{
103 char *p;
104
105 if (((p = getenv(RFIO_USE_CASTOR_V2)) == 0) &&
106 ((p = getconfent("RFIO","USE_CASTOR_V2",0)) == 0)) {
107 // Variable not set: compat mode
108 return 0;
109 }
110 if ((strcmp(p,"YES") == 0) || (strcmp(p,"yes") == 0) || (atoi(p) == 1)) {
111 // Variable set to yes or 1 but old CASTOR 1: compat mode + warning
112 static int once = 0;
113 if (!once) {
114 ::Warning("UseCastor2API", "asked to use CASTOR 2, but linked with CASTOR 1");
115 once = 1;
116 }
117 return 0;
118 }
119 // Variable set but not to 1 : compat mode
120 return 0;
121}
122
123#endif
124
125/// Determine the authentication protocol to be tried first from the url
126/// string or from defaults. The auth option, if any, is removed from 'url'.
127static const char *GetAuthProto(TString &url)
128{
129 const Int_t rootNumSec = 6;
130 const char *protoSec[rootNumSec] = {"rootup", "roots", "rootk",
131 "rootg", "rooth", "rootug" };
132 TString p = url;
133 Int_t ii = p.Index("&rootAuth=");
134 if (ii != kNPOS) {
135 Int_t jj = p.Index("&", ii+1);
136 if (jj != kNPOS)
137 p.Remove(jj);
138 p.Remove(0,ii);
139 url.ReplaceAll(p, "");
140 p.ReplaceAll("&rootAuth=", "");
141 }
142 if (p.Length() <= 0)
143 // Use defaults
144 p = getenv("ROOTCASTORAUTH");
145
146 Int_t sec = -1;
147 if (p.Length() > 0 && p.IsDigit()) {
148 sec = p.Atoi();
149 if (sec < 0 || sec > (rootNumSec - 1))
150 sec = -1;
151 }
152
153 // Done
154 return ((sec > -1 && sec < rootNumSec) ? protoSec[sec] : "root");
155}
156
158
159///////////////////////////////////////////////////////////////////////////////
160/// Create a TCastorFile. A TCastorFile is like a normal TNetFile except
161/// that it obtains the remote node (disk server) via the CASTOR API, once
162/// the disk server and the local file path are determined, the file will
163/// be accessed via the rootd daemon. File names have to be specified like:
164/// castor:/castor/cern.ch/user/r/rdm/bla.root.
165/// The other arguments are the same as for TNetFile and TFile.
166
167TCastorFile::TCastorFile(const char *url, Option_t *option, const char *ftitle,
168 Int_t compress, Int_t netopt)
169 : TNetFile(url, ftitle, compress, kFALSE)
170{
173
174 // Extract the authentication info, if any; removing it from the options
175 TString u(url);
177 fUrl.SetUrl(u);
178
179 if (gDebug > 0)
180 Info("TCastorFile","fAuthProto = %s, u: %s", fAuthProto.Data(), u.Data());
181
182 // file is always created by stage_out_hsm() and therefore
183 // exists when opened by rootd
184 TString opt = option;
185 opt.ToUpper();
186 if (opt == "NEW" || opt == "CREATE")
187 opt = "RECREATE";
188
189 Create(url, opt, netopt);
190}
191
192///////////////////////////////////////////////////////////////////////////////
193/// Find the CASTOR disk server and internal file path.
195{
196 // just call rfio_parse and no extra parsing is added here to that
197
198 TString castorturl;
199 char *host=0;
200 char *name=0;
201
202 // to be able to use the turl starting with castor:
203 if (!strcmp(fUrl.GetProtocol(),"castor"))
204 castorturl.Form("%s://%s", "rfio", fUrl.GetFile());
205 else
206 castorturl.Form("%s://%s", fUrl.GetProtocol(), fUrl.GetFile());
207 if (strlen(fUrl.GetOptions()) > 0)
208 castorturl += TString::Format("?%s", fUrl.GetOptions());
209
210 // the complete turl in fname
211 TString fname = castorturl; // for compatibility with rfio_parse interface
212 if (::rfio_parse((char *)fname.Data(), &host, &name)>=0) {
213 castorturl.Form("%s",(!name || !strstr(name,"/castor"))?fname.Data():name);
214 fname = castorturl.Data();
215
216 } else {
217 Error("FindServerAndPath", "error parsing %s", fUrl.GetUrl());
218 return;
219 }
220
221 if (!UseCastor2API()) {
222
223 struct stgcat_entry *stcp_output = 0;
225 // This is a CASTOR file
226 int flags = O_RDONLY;
227 struct Cns_filestat st;
228 int rc;
229 char stageoutbuf[1025];
230 char stageerrbuf[1025];
231
232 // Check with internal stage limits - preventing overflow afterwards
233 if (strlen(fUrl.GetFile()) > STAGE_MAX_HSMLENGTH) {
234 serrno = ENAMETOOLONG;
235 Error("FindServerAndPath", "can't open %s, error %d (%s)", fUrl.GetFile(), serrno, sstrerror(serrno));
236 return;
237 }
238
239 // Prepare the flags
240 if (fOption == "CREATE" || fOption == "RECREATE" || fOption == "UPDATE")
241 flags |= O_RDWR;
242 if (fOption == "CREATE" || fOption == "RECREATE")
243 flags |= O_CREAT | O_TRUNC;
244
245 // Check if an existing file is going to be updated
246 memset(&st, 0, sizeof(st));
247 rc = Cns_stat(fUrl.GetFile(), &st);
248
249 // Make sure that filesize is 0 if file doesn't exist
250 // or that we will create (stage_out) if O_TRUNC.
251 if (rc == -1 || ((flags & O_TRUNC) != 0))
252 st.filesize = 0;
253
254 // Makes sure stage api does not write automatically to stdout/stderr
255 if (stage_setoutbuf(stageoutbuf, 1024) != 0) {
256 Error("FindServerAndPath", "can't open %s, stage_setoutbuf, error %d (%s)",
257 fUrl.GetFile(), serrno, sstrerror(serrno));
258 return;
259 }
260 if (stage_seterrbuf(stageerrbuf, 1024) != 0) {
261 Error("FindServerAndPath", "can't open %s, stage_seterrbuf, error %d (%s)",
262 fUrl.GetFile(), serrno, sstrerror(serrno));
263 return;
264 }
265
266 struct stgcat_entry stcp_input;
267 int nstcp_output;
268
269 memset(&stcp_input, 0, sizeof(struct stgcat_entry));
270 strlcpy(stcp_input.u1.h.xfile, fUrl.GetFile(), sizeof(stcp_input.u1.h.xfile));
271 if (flags == O_RDONLY || st.filesize > 0) {
272 // Do a recall
273 if (stage_in_hsm((u_signed64) 0, // Ebusy is possible...
274 (int) flags, // open flags
275 (char *) 0, // hostname
276 (char *) 0, // pooluser
277 (int) 1, // nstcp_input
278 (struct stgcat_entry *) &stcp_input, // stcp_input
279 (int *) &nstcp_output, // nstcp_output
280 (struct stgcat_entry **) &stcp_output, // stcp_output
281 (int) 0, // nstpp_input
282 (struct stgpath_entry *) 0 // stpp_input
283 ) != 0) {
284 Error("FindServerAndPath", "can't open %s, stage_in_hsm error %d (%s)",
285 fUrl.GetFile(), serrno, sstrerror(serrno));
286 return;
287 }
288 } else {
289 // Do a creation
290 if (stage_out_hsm((u_signed64) 0, // Ebusy is possible...
291 (int) flags, // open flags
292 (mode_t) 0666, // open mode (c.f. also umask)
293 // Note: This is S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, c.f. fopen(2)
294 (char *) 0, // hostname
295 (char *) 0, // pooluser
296 (int) 1, // nstcp_input
297 (struct stgcat_entry *) &stcp_input, // stcp_input
298 (int *) &nstcp_output, // nstcp_output
299 (struct stgcat_entry **) &stcp_output, // stcp_output
300 (int) 0, // nstpp_input
301 (struct stgpath_entry *) 0 // stpp_input
302 ) != 0) {
303 Error("FindServerAndPath", "can't open %s, stage_out_hsm error %d (%s)",
304 fUrl.GetFile(), serrno, sstrerror(serrno));
305 return;
306 }
307 }
308 if ((nstcp_output != 1) || (stcp_output == 0) ||
309 (*(stcp_output->ipath) == '\0')) {
310 // Impossible
311 serrno = SEINTERNAL;
312 if (stcp_output != 0) free(stcp_output);
313 Error("FindServerAndPath", "can't open %s, error %d (%s)",
314 fUrl.GetFile(), serrno, sstrerror(serrno));
315 return;
316 }
317
318 // Parse orig string to get disk server host
319 char *filename;
320 char *realhost = 0;
321
322 rfio_parse(stcp_output->ipath, &realhost, &filename);
323 if (realhost == 0) {
324 serrno = SEINTERNAL;
325 Error("FindServerAndPath", "can't open %s, get disk server hostname from %s error %d (%s)",
326 fUrl.GetFile(), stcp_output->ipath, errno, sstrerror(serrno));
327 free(stcp_output);
328 return;
329 }
330 // Save real host and internal path
331 fDiskServer = realhost;
332 if (filename[0] != '/') {
333 // Make file 'local' to the host
334 fInternalPath = "/";
335 fInternalPath += filename;
336 } else {
337 fInternalPath = filename;
338 }
339
340 if (st.filesize == 0) {
341 // Will force notification to stage when the file is closed
343 }
344 }
345
346 // Set the protocol prefix for TNetFile.
347 // For the cern.ch domain we set the default authentication
348 // method to UidGid, i.e. as for rfiod, unless there is a specific
349 // request (from options or envs); for this we need
350 // the full FQDN or address in "nnn.mmm.iii.jjj" form
352 if (fAuthProto == "root") {
353 TString fqdn;
355 if (addr.IsValid()) {
356 fqdn = addr.GetHostName();
357 if (fqdn.EndsWith(".cern.ch") || fqdn.BeginsWith("137.138."))
358 r = "rootug://";
359 else
360 r = "root://";
361 } else
362 r = "root://";
363 } else {
364 // Fix the format
365 r += "://";
366 }
367
368 // Update fUrl with new path
369 r += fDiskServer + "/";
370 r += fInternalPath;
371 TUrl rurl(r);
372 fUrl = rurl;
373
374 if (gDebug > 0)
375 Info("FindServerAndPath"," fDiskServer: %s, r: %s", fDiskServer.Data(), r.Data());
376
377 // Now ipath is not null and contains the real internal path on the disk
378 // server 'host', e.g. it is fDiskServer:fInternalPath
379 fInternalPath = stcp_output==0?0:stcp_output->ipath;
380 if (stcp_output)
381 free(stcp_output);
382 } else {
383
384#ifdef R__CASTOR2
385
386 // We use the new stager API
387 // I use fname which has the Turl already parsed correctly
388
389 int flags = O_RDONLY;
390 int rc;
391 struct stage_io_fileresp *response = 0;
392 char *requestId = 0, *url = 0;
393 char stageerrbuf[1025];
394
395 // Prepare the flags
396 if (fOption == "CREATE" || fOption == "RECREATE" || fOption == "UPDATE")
397 flags |= O_RDWR;
398 if (fOption == "CREATE" || fOption == "RECREATE")
399 flags |= O_CREAT | O_TRUNC;
400
401 stage_seterrbuf(stageerrbuf, 1024);
402
403 int* auxVal;
404 char ** auxPoint;
405 struct stage_options opts;
406 opts.stage_host=0;
407 opts.stage_port=0;
408 opts.service_class=0;
409 opts.stage_version=0;
410
411 void *ptrPoint = &auxPoint;
412 void *ptrVal = &auxVal;
413 int ret=Cglobals_get(& tStageHostKey, (void**)ptrPoint,sizeof(void*));
414 if(ret==0){
415 opts.stage_host=*auxPoint;
416 }
417 ret=Cglobals_get(& tStagePortKey, (void**)ptrVal,sizeof(int));
418 if(ret==0){
419 opts.stage_port=*auxVal;
420 }
421 opts.stage_version=2;
422 ret=Cglobals_get(& tSvcClassKey, (void**)ptrPoint,sizeof(void*));
423 if (ret==0){
424 opts.service_class=*auxPoint;
425 }
426
427 // in stage_open I use the fname which is the result of the rfio_parsing
428 rc = stage_open(0,
429 MOVER_PROTOCOL_ROOT,
430 (char *)fname.Data(),
431 flags,
432 (mode_t) 0666,
433 0,
434 &response,
435 &requestId,
436 &opts); // global values used as options
437
438 if (rc != 0) {
439 Error("FindServerAndPath", "stage_open failed: %s (%s)",
440 sstrerror(serrno), stageerrbuf);
441 if (response) free(response);
442 if (requestId) free(requestId);
443 return;
444 }
445
446 if (response == 0) {
447 Error("FindServerAndPath", "response was null for %s (Request %s) %d/%s",
448 fname.Data(), requestId,
449 serrno, sstrerror(serrno));
450 if (requestId) free(requestId);
451 return;
452 }
453
454 if (response->errorCode != 0) {
455 serrno = response->errorCode;
456 Error("FindServerAndPath", "error getting file %s (Request %s) %d/%s",
457 fname.Data(), requestId,
458 serrno, sstrerror(serrno));
459 free(response);
460 if (requestId) free(requestId);
461 return;
462 }
463
464 url = stage_geturl(response);
465
466 if (url == 0) {
467 Error("FindServerAndPath", "error getting file %s (Request %s) %d/%s",
468 fname.Data(), requestId,
469 serrno, sstrerror(serrno));
470 free(response);
471 if (requestId) free(requestId);
472 return;
473 }
474
475 TUrl rurl(url);
476 // Set the protocol prefix for TNetFile.
477 // For the cern.ch domain we set the default authentication
478 // method to UidGid, i.e. as for rfiod, unless there is a specific
479 // request (from options or envs); for this we need
480 // the full FQDN or address in "nnn.mmm.iii.jjj" form
482 if (fAuthProto == "root") {
483 TString fqdn = rurl.GetHostFQDN();
484 if (fqdn.EndsWith(".cern.ch") || fqdn.BeginsWith("137.138."))
485 fAuthProto = "rootug";
486 }
487
488 // Update protocol and fUrl
490 fUrl = rurl;
491
492 if (response) free(response);
493 if (url) free(url);
494 if (requestId) free(requestId);
495#endif
496
497 }
498
500}
501
502///////////////////////////////////////////////////////////////////////////////
503/// Close currently open file.
504
506{
507
508
510
511 if (!UseCastor2API()) {
512 if (fIsCastor && fWrittenTo) {
513#ifndef R__CASTOR2
514 // CASTOR file was created or modified
516#endif
518 }
519 }
520
521 return r;
522}
523
524///////////////////////////////////////////////////////////////////////////////
525/// Write specified byte range to remote file via rootd daemon.
526/// Returns kTRUE in case of error.
527
529{
530 if (TNetFile::WriteBuffer(buf, len))
531 return kTRUE;
532
533 if (!UseCastor2API()) {
534 if (fIsCastor && !fWrittenTo && len > 0) {
535 stage_hsm_t hsmfile;
536
537 // Change status of file in stage catalog from STAGED to STAGEOUT
538 memset(&hsmfile, 0, sizeof(hsmfile));
539 hsmfile.upath = StrDup(fInternalPath);
540 if (stage_updc_filchg(0, &hsmfile) < 0) {
541 Error("WriteBuffer", "error calling stage_updc_filchg");
542 delete [] hsmfile.upath;
543 return kTRUE;
544 }
545 delete [] hsmfile.upath;
547 }
548 }
549
550 return kFALSE;
551}
552
553///////////////////////////////////////////////////////////////////////////////
554/// Connect to remote rootd server on CASTOR disk server.
555
557 Int_t tcpwindowsize, Bool_t forceOpen,
558 Bool_t forceRead)
559{
561
562 // Continue only if successful
563 if (fIsCastor) {
564 TNetFile::ConnectServer(stat, kind, netopt, tcpwindowsize, forceOpen, forceRead);
565 } else {
566 // Failure: fill these to signal it to TNetFile
567 *stat = kErrFileOpen;
568 *kind = kROOTD_ERR;
569 }
570}
EMessageTypes
Definition: MessageTypes.h:27
@ kROOTD_ERR
Definition: MessageTypes.h:113
@ kErrFileOpen
Definition: NetErrors.h:32
ROOT::R::TRInterface & r
Definition: Object.C:4
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:363
R__EXTERN Int_t gDebug
Definition: Rtypes.h:90
int rfio_HsmIf_reqtoput(char *)
#define RFIO_USE_CASTOR_V2
Definition: TCastorFile.cxx:74
static const char * GetAuthProto(TString &url)
Determine the authentication protocol to be tried first from the url string or from defaults.
int rfio_parse(char *, char **, char **)
static int UseCastor2API()
#define RFIO_HSM_CNS
Definition: TCastorFile.cxx:76
int rfio_HsmIf_IsHsmFile(const char *)
char * getconfent(char *, char *, int)
void Warning(const char *location, const char *msgfmt,...)
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2465
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
#define free
Definition: civetweb.c:1539
A TNetFile interfaced to the Castor storage backend.
Definition: TCastorFile.h:18
Bool_t fWrittenTo
true if data has been written to file
Definition: TCastorFile.h:24
Bool_t WriteBuffer(const char *buf, Int_t len)
Write specified byte range to remote file via rootd daemon.
Bool_t fIsCastor
true if internal path is valid
Definition: TCastorFile.h:23
Int_t SysClose(Int_t fd)
Close currently open file.
TString fInternalPath
CASTOR internal path.
Definition: TCastorFile.h:22
void ConnectServer(Int_t *stat, EMessageTypes *kind, Int_t netopt, Int_t tcpwindowsize, Bool_t forceOpen, Bool_t forceRead)
Connect to remote rootd server on CASTOR disk server.
TString fDiskServer
CASTOR remote disk server.
Definition: TCastorFile.h:21
void FindServerAndPath()
Find the CASTOR disk server and internal file path.
TString fAuthProto
Used to specific the auth protocol.
Definition: TCastorFile.h:26
TUrl fUrl
!URL of file
Definition: TFile.h:105
TString fOption
File options.
Definition: TFile.h:86
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:36
const char * GetHostName() const
Definition: TInetAddress.h:71
Bool_t IsValid() const
Definition: TInetAddress.h:76
virtual void Create(const char *url, Option_t *option, Int_t netopt)
Create a NetFile object.
Definition: TNetFile.cxx:671
virtual void ConnectServer(Int_t *stat, EMessageTypes *kind, Int_t netopt, Int_t tcpwindowsize, Bool_t forceOpen, Bool_t forceRead)
Connect to remote rootd server.
Definition: TNetFile.cxx:581
Int_t SysClose(Int_t fd)
Close currently open file.
Definition: TNetFile.cxx:155
Bool_t WriteBuffer(const char *buf, Int_t len)
Write specified byte range to remote file via rootd daemon.
Definition: TNetFile.cxx:499
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1896
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2152
const char * Data() const
Definition: TString.h:364
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1738
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1113
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2286
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2264
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2334
This class represents a WWW compatible URL.
Definition: TUrl.h:35
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
const char * GetFile() const
Definition: TUrl.h:72
void SetUrl(const char *url, Bool_t defaultIsFile=kFALSE)
Parse url character string and split in its different subcomponents.
Definition: TUrl.cxx:108
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition: TUrl.cxx:518
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition: TUrl.cxx:467
const char * GetOptions() const
Definition: TUrl.h:74
const char * GetProtocol() const
Definition: TUrl.h:67