Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TNetFile.cxx
Go to the documentation of this file.
1// @(#)root/net:$Id$
2// Author: Fons Rademakers 14/08/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/**
13\file TNetFile.cxx
14\class TNetFile
15\ingroup IO
16
17A TNetFile is like a normal TFile except that it reads and writes
18its data via a rootd server (for more on the rootd daemon see the
19source files in `root/rootd/src/`). TNetFile file names are in
20standard URL format with protocol "root" or "roots". The following
21are valid TNetFile URL's:
22- `root://hpbrun.cern.ch/root/hsimple.root`
23- `root://pcna49a:5151/~na49/data/run821.root`
24- `root://pcna49d.cern.ch:5050//v1/data/run810.root`
25
26The only difference with the well known httpd URL's is that the root
27of the remote file tree is the user's home directory. Therefore an
28absolute pathname requires a // after the host or port specifier
29(see last example). Further the expansion of the standard shell
30characters, like ~, $, .., are handled as expected.
31TNetFile (actually TUrl) uses 1094 as default port for rootd.
32
33Connecting to a rootd requires the remote user id and password.
34TNetFile allows three ways for you to provide your login:
35 Setting it globally via the static functions:
361. TAuthenticate::SetGlobalUser() and TAuthenticate::SetGlobalPasswd()
372. Getting it from the `~/.netrc` file (same file as used by ftp)
383. Command line prompt
39The different methods will be tried in the order given above.
40On machines with AFS rootd will authenticate using AFS (if it was
41compiled with AFS support).
42
43If the protocol is specified as "rootk" kerberos5 will be used for
44authentication.
45
46The rootd daemon lives in the directory `$ROOTSYS/bin`. It can be
47started either via inetd or by hand from the command line (no need
48to be super user).
49**/
50
51#include <cerrno>
52
53#include "Bytes.h"
54#include "NetErrors.h"
55#include "TApplication.h"
56#include "TEnv.h"
57#include "TNetFile.h"
58#include "TPSocket.h"
59#include "TROOT.h"
60#include "TSysEvtHandler.h"
61#include "TSystem.h"
62#include "TTimeStamp.h"
63#include "TVirtualPerfStats.h"
64
65// fgClientProtocol is now in TAuthenticate
66
67
68////////////////////////////////////////////////////////////////////////////////
69/// Create a TNetFile object. This is actually done inside Create(), so
70/// for a description of the options and other arguments see Create().
71/// Normally a TNetFile is created via TFile::Open().
72
75 : TFile(url, strstr(option, "_WITHOUT_GLOBALREGISTRATION") != nullptr ? "NET_WITHOUT_GLOBALREGISTRATION" : "NET",
77 fEndpointUrl(url)
78{
79 fSocket = 0;
81}
82
83////////////////////////////////////////////////////////////////////////////////
84/// Create a TNetFile object. To be used by derived classes, that need
85/// to initialize the TFile base class but not open a connection at this
86/// moment.
87
89 : TFile(url, "NET", ftitle, compress), fEndpointUrl(url)
90{
91 fSocket = 0;
92 fProtocol = 0;
93 fErrorCode = 0;
94 fNetopt = 0;
95}
96
97////////////////////////////////////////////////////////////////////////////////
98/// TNetFile dtor. Send close message and close socket.
99
104
105////////////////////////////////////////////////////////////////////////////////
106/// Open a remote file. Requires fOption to be set correctly.
107
108Int_t ROOT::Deprecated::TNetFile::SysOpen(const char * /*file*/, Int_t /*flags*/, UInt_t /*mode*/)
109{
110 if (!fSocket) {
111
112 Create(fUrl.GetUrl(), fOption, fNetopt);
113 if (!fSocket) return -1;
114
115 } else {
116
117 if (fProtocol > 15) {
118 fSocket->Send(Form("%s %s", fUrl.GetFile(), ToLower(fOption).Data()),
120 } else {
121 // Old daemon versions expect an additional slash at beginning
122 fSocket->Send(Form("/%s %s", fUrl.GetFile(), ToLower(fOption).Data()),
124 }
125
126 EMessageTypes kind;
127 int stat;
128 Recv(stat, kind);
129
130 if (kind == kROOTD_ERR) {
131 PrintError("SysOpen", stat);
132 return -1;
133 }
134 }
135
136 // This means ok for net files
137 return -2; // set as fD in ReOpen
138}
139
140////////////////////////////////////////////////////////////////////////////////
141/// Close currently open file.
142
144{
145 if (fSocket)
146 fSocket->Send(kROOTD_CLOSE);
147
148 return 0;
149}
150
151////////////////////////////////////////////////////////////////////////////////
152/// Return file stat information. The interface and return value is
153/// identical to TSystem::GetPathInfo().
154
156{
157 if (fProtocol < 3) return 1;
158
159 if (!fSocket) return 1;
160
161 fSocket->Send(kROOTD_FSTAT);
162
163 char msg[1024];
164 Int_t kind;
165 fSocket->Recv(msg, sizeof(msg), kind);
166
167 Int_t mode, uid, gid, islink;
168 Long_t dev, ino;
169
170 if (fProtocol > 12) {
171#ifdef R__WIN32
172 sscanf(msg, "%ld %ld %d %d %d %I64d %ld %d", &dev, &ino, &mode,
173 &uid, &gid, size, modtime, &islink);
174#else
175 sscanf(msg, "%ld %ld %d %d %d %lld %ld %d", &dev, &ino, &mode,
176 &uid, &gid, size, modtime, &islink);
177#endif
178 if (dev == -1)
179 return 1;
180 if (id)
181 *id = (dev << 24) + ino;
182 if (flags) {
183 *flags = 0;
185 *flags |= 1;
186 if (R_ISDIR(mode))
187 *flags |= 2;
188 if (!R_ISREG(mode) && !R_ISDIR(mode))
189 *flags |= 4;
190 }
191 } else {
192#ifdef R__WIN32
193 sscanf(msg, "%ld %I64d %ld %ld", id, size, flags, modtime);
194#else
195 sscanf(msg, "%ld %lld %ld %ld", id, size, flags, modtime);
196#endif
197 if (*id == -1)
198 return 1;
199 }
200
201 return 0;
202}
203
204////////////////////////////////////////////////////////////////////////////////
205/// Close remote file.
206
208{
209 if (!fSocket) return;
210
211 TFile::Close(opt);
212
213 if (fProtocol > 6)
214 fSocket->Send(kROOTD_BYE);
215
216 SafeDelete(fSocket);
217
218 fD = -1; // so TFile::IsOpen() returns false when in TFile::~TFile
219}
220
221////////////////////////////////////////////////////////////////////////////////
222/// Flush file to disk.
223
225{
226 FlushWriteCache();
227
228 if (fSocket && fWritable)
229 fSocket->Send(kROOTD_FLUSH);
230}
231
232////////////////////////////////////////////////////////////////////////////////
233/// Initialize a TNetFile object.
234
236{
237 Seek(0);
238
239 TFile::Init(create);
240 fD = -2; // so TFile::IsOpen() returns true when in TFile::~TFile
241}
242
243////////////////////////////////////////////////////////////////////////////////
244/// Retruns kTRUE if file is open, kFALSE otherwise.
245
247{
248 return fSocket == 0 ? kFALSE : kTRUE;
249}
250
251////////////////////////////////////////////////////////////////////////////////
252/// Print some info about the net file.
253
255{
256 const char *fname = fUrl.GetFile();
257 Printf("URL: %s", ((TUrl*)&fUrl)->GetUrl());
258 Printf("Remote file: %s", &fname[1]);
259 Printf("Remote user: %s", fUser.Data());
260 Printf("Title: %s", fTitle.Data());
261 Printf("Option: %s", fOption.Data());
262 Printf("Bytes written: %lld", fBytesWrite);
263 Printf("Bytes read: %lld", fBytesRead);
264}
265
266////////////////////////////////////////////////////////////////////////////////
267/// Print error string depending on error code.
268
270{
271 fErrorCode = err;
272 Error(where, "%s", gRootdErrStr[err]);
273}
274
275////////////////////////////////////////////////////////////////////////////////
276/// Reopen a file with a different access mode, like from READ to
277/// UPDATE or from NEW, CREATE, RECREATE, UPDATE to READ. Thus the
278/// mode argument can be either "READ" or "UPDATE". The method returns
279/// 0 in case the mode was successfully modified, 1 in case the mode
280/// did not change (was already as requested or wrong input arguments)
281/// and -1 in case of failure, in which case the file cannot be used
282/// anymore.
283
285{
286 if (fProtocol < 7) {
287 Error("ReOpen", "operation not supported by remote rootd (protocol = %d)",
288 fProtocol);
289 return 1;
290 }
291
292 return TFile::ReOpen(mode);
293}
294
295////////////////////////////////////////////////////////////////////////////////
296/// Read specified byte range from remote file via rootd daemon.
297/// Returns kTRUE in case of error.
298
300{
301 if (!fSocket) return kTRUE;
302 if (len == 0)
303 return kFALSE;
304
306
307 Int_t st;
308 if ((st = ReadBufferViaCache(buf, len))) {
309 if (st == 2)
310 return kTRUE;
311 return kFALSE;
312 }
313
316
317 Double_t start = 0;
318 if (gPerfStats) start = TTimeStamp();
319
320 if (fSocket->Send(Form("%lld %d", fOffset, len), kROOTD_GET) < 0) {
321 Error("ReadBuffer", "error sending kROOTD_GET command");
322 result = kTRUE;
323 goto end;
324 }
325
326 Int_t stat, n;
327 EMessageTypes kind;
328
329 fErrorCode = -1;
330 if (Recv(stat, kind) < 0 || kind == kROOTD_ERR) {
331 PrintError("ReadBuffer", stat);
332 result = kTRUE;
333 goto end;
334 }
335
336 while ((n = fSocket->RecvRaw(buf, len)) < 0 && TSystem::GetErrno() == EINTR)
338
339 if (n != len) {
340 Error("ReadBuffer", "error receiving buffer of length %d, got %d", len, n);
341 result = kTRUE;
342 goto end;
343 }
344
345 fOffset += len;
346
347 fBytesRead += len;
348 fReadCalls++;
349#ifdef R__WIN32
350 SetFileBytesRead(GetFileBytesRead() + len);
351 SetFileReadCalls(GetFileReadCalls() + 1);
352#else
353 fgBytesRead += len;
354 fgReadCalls++;
355#endif
356
357end:
358
359 if (gPerfStats)
360 gPerfStats->FileReadEvent(this, len, start);
361
364
365 return result;
366}
367
368////////////////////////////////////////////////////////////////////////////////
369/// Read specified byte range from remote file via rootd daemon.
370/// Returns kTRUE in case of error.
371
373{
374 SetOffset(pos);
375 return ReadBuffer(buf, len);
376}
377
378////////////////////////////////////////////////////////////////////////////////
379/// Read a list of buffers given in pos[] and len[] and return it in a single
380/// buffer.
381/// Returns kTRUE in case of error.
382
384{
385 if (!fSocket) return kTRUE;
386
387 // If it's an old version of the protocol try the default TFile::ReadBuffers
388 if (fProtocol < 17)
389 return TFile::ReadBuffers(buf, pos, len, nbuf);
390
391 Int_t stat;
392 Int_t blockSize = 262144; //Let's say we transfer 256KB at the time
394 EMessageTypes kind;
395 TString data_buf; // buf to put the info
396
399
400 Double_t start = 0;
401 if (gPerfStats) start = TTimeStamp();
402
403 // Make the string with a list of offsets and lengths
406 for(Int_t i = 0; i < nbuf; i++) {
407 data_buf += pos[i] + fArchiveOffset;
408 data_buf += "-";
409 data_buf += len[i];
410 data_buf += "/";
411 total_len += len[i];
412 }
413
414 // Send the command with the length of the info and number of buffers
415 if (fSocket->Send(Form("%d %d %d", nbuf, data_buf.Length(), blockSize),
416 kROOTD_GETS) < 0) {
417 Error("ReadBuffers", "error sending kROOTD_GETS command");
418 result = kTRUE;
419 goto end;
420 }
421 // Send buffer with the list of offsets and lengths
422 if (fSocket->SendRaw(data_buf, data_buf.Length()) < 0) {
423 Error("ReadBuffers", "error sending buffer");
424 result = kTRUE;
425 goto end;
426 }
427
428 fErrorCode = -1;
429 if (Recv(stat, kind) < 0 || kind == kROOTD_ERR) {
430 PrintError("ReadBuffers", stat);
431 result = kTRUE;
432 goto end;
433 }
434
435 actual_pos = 0;
436 while (actual_pos < total_len) {
438 if (left > blockSize)
439 left = blockSize;
440
441 Int_t n;
442 while ((n = fSocket->RecvRaw(buf + actual_pos, Int_t(left))) < 0 &&
445
446 if (n != Int_t(left)) {
447 Error("GetBuffers", "error receiving buffer of length %d, got %d",
448 Int_t(left), n);
449 result = kTRUE ;
450 goto end;
451 }
452 actual_pos += left;
453 }
454
455 fBytesRead += total_len;
456 fReadCalls++;
457#ifdef R__WIN32
458 SetFileBytesRead(GetFileBytesRead() + total_len);
459 SetFileReadCalls(GetFileReadCalls() + 1);
460#else
461 fgBytesRead += total_len;
462 fgReadCalls++;
463#endif
464
465end:
466
467 if (gPerfStats)
468 gPerfStats->FileReadEvent(this, total_len, start);
469
472
473 // If found problems try the generic implementation
474 if (result) {
475 if (gDebug > 0)
476 Info("ReadBuffers", "Couldnt use the specific implementation, calling TFile::ReadBuffers");
477 return TFile::ReadBuffers(buf, pos, len, nbuf);
478 }
479
480 return result;
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// Write specified byte range to remote file via rootd daemon.
485/// Returns kTRUE in case of error.
486
488{
489 if (!fSocket || !fWritable) return kTRUE;
490
492
493 Int_t st;
494 if ((st = WriteBufferViaCache(buf, len))) {
495 if (st == 2)
496 return kTRUE;
497 return kFALSE;
498 }
499
501
502 if (fSocket->Send(Form("%lld %d", fOffset, len), kROOTD_PUT) < 0) {
503 SetBit(kWriteError);
504 Error("WriteBuffer", "error sending kROOTD_PUT command");
505 result = kTRUE;
506 goto end;
507 }
508 if (fSocket->SendRaw(buf, len) < 0) {
509 SetBit(kWriteError);
510 Error("WriteBuffer", "error sending buffer");
511 result = kTRUE;
512 goto end;
513 }
514
515 Int_t stat;
516 EMessageTypes kind;
517
518 fErrorCode = -1;
519 if (Recv(stat, kind) < 0 || kind == kROOTD_ERR) {
520 SetBit(kWriteError);
521 PrintError("WriteBuffer", stat);
522 result = kTRUE;
523 goto end;
524 }
525
526 fOffset += len;
527
528 fBytesWrite += len;
529#ifdef R__WIN32
530 SetFileBytesWritten(GetFileBytesWritten() + len);
531#else
532 fgBytesWrite += len;
533#endif
534
535end:
537
538 return result;
539}
540
541////////////////////////////////////////////////////////////////////////////////
542/// Return status from rootd server and message kind. Returns -1 in
543/// case of error otherwise 8 (sizeof 2 words, status and kind).
544
546{
547 kind = kROOTD_ERR;
548 status = 0;
549
550 if (!fSocket) return -1;
551
552 Int_t what;
553 Int_t n = fSocket->Recv(status, what);
554 kind = (EMessageTypes) what;
555 return n;
556}
557
558////////////////////////////////////////////////////////////////////////////////
559/// Set position from where to start reading.
560
562{
563 SetOffset(offset, pos);
564}
565
566////////////////////////////////////////////////////////////////////////////////
567/// Connect to remote rootd server.
568
572{
573 TString fn = fUrl.GetFile();
574
575 // Create Authenticated socket
576 Int_t sSize = netopt < -1 ? -netopt : 1;
577 TString url(fUrl.GetProtocol());
578 if (url.Contains("root")) {
579 url.Insert(4,"dp");
580 } else {
581 url = "rootdp";
582 }
583 url += TString(Form("://%s@%s:%d",
584 fUrl.GetUser(), fUrl.GetHost(), fUrl.GetPort()));
586 if (!fSocket || (fSocket && !ROOT::Deprecated::TSocketFriend::IsAuthenticated(*fSocket))) {
587 if (sSize > 1)
588 Error("TNetFile", "can't open %d-stream connection to rootd on "
589 "host %s at port %d", sSize, fUrl.GetHost(), fUrl.GetPort());
590 else
591 Error("TNetFile", "can't open connection to rootd on "
592 "host %s at port %d", fUrl.GetHost(), fUrl.GetPort());
593 *kind = kROOTD_ERR;
594 goto zombie;
595 }
596
597 // Check if rootd supports new options
598 fProtocol = fSocket->GetRemoteProtocol();
599 if (forceRead && fProtocol < 5) {
600 Warning("ConnectServer", "rootd does not support \"+read\" option");
602 }
603
604 // Open the file
605 if (fProtocol < 16)
606 // For backward compatibility we need to add a '/' at the beginning
607 fn.Insert(0,"/");
608 if (forceOpen)
609 fSocket->Send(Form("%s %s", fn.Data(),
610 ToLower("f"+fOption).Data()), kROOTD_OPEN);
611 else if (forceRead)
612 fSocket->Send(Form("%s %s", fn.Data(), "+read"), kROOTD_OPEN);
613 else
614 fSocket->Send(Form("%s %s", fn.Data(),
615 ToLower(fOption).Data()), kROOTD_OPEN);
616
618 int tmpstat;
619 Recv(tmpstat, tmpkind);
620 *stat = tmpstat;
621 *kind = tmpkind;
622
623 return;
624
625zombie:
626 // error in file opening occurred, make this object a zombie
627 MakeZombie();
628 SafeDelete(fSocket);
630}
631
632////////////////////////////////////////////////////////////////////////////////
633/// Create a NetFile object. A net file is the same as a TFile
634/// except that it is being accessed via a rootd server. The url
635/// argument must be of the form: root[k]://host.dom.ain/file.root.
636/// When protocol is "rootk" try using kerberos5 authentication.
637/// If the file specified in the URL does not exist, is not accessable
638/// or can not be created the kZombie bit will be set in the TNetFile
639/// object. Use IsZombie() to see if the file is accessable.
640/// If the remote daemon thinks the file is still connected, while you are
641/// sure this is not the case you can force open the file by preceding the
642/// option argument with an "-", e.g.: "-recreate". Do this only
643/// in cases when you are very sure nobody else is using the file.
644/// To bypass the writelock on a file, to allow the reading of a file
645/// that is being written by another process, explicitly specify the
646/// "+read" option ("read" being the default option).
647/// The netopt argument can be used to specify the size of the tcp window in
648/// bytes (for more info see: http://www.psc.edu/networking/perf_tune.html).
649/// The default and minimum tcp window size is 65535 bytes.
650/// If netopt < -1 then |netopt| is the number of parallel sockets that will
651/// be used to connect to rootd. This option should be used on fat pipes
652/// (i.e. high bandwidth, high latency links). The ideal number of parallel
653/// sockets depends on the bandwidth*delay product. Generally 5-7 is a good
654/// number.
655/// For a description of the option and other arguments see the TFile ctor.
656/// The preferred interface to this constructor is via TFile::Open().
657
658void ROOT::Deprecated::TNetFile::Create(const char * /*url*/, Option_t *option, Int_t netopt)
659{
660 Int_t tcpwindowsize = 65535;
661
662 fErrorCode = -1;
663 fNetopt = netopt;
664 fOption = option;
665
667 if (option[0] == '-') {
668 fOption = &option[1];
670 }
671 // accept 'f', like 'frecreate' still for backward compatibility
672 if (option[0] == 'F' || option[0] == 'f') {
673 fOption = &option[1];
675 }
676
678 if (!strcasecmp(option, "+read")) {
679 fOption = &option[1];
681 }
682
683 fOption.ToUpper();
684
685 if (fOption == "NEW")
686 fOption = "CREATE";
687
688 Bool_t create = (fOption == "CREATE") ? kTRUE : kFALSE;
689 Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
690 Bool_t update = (fOption == "UPDATE") ? kTRUE : kFALSE;
691 if (!create && !recreate && !update) {
692 fOption = "READ";
693 }
694
695 if (!fUrl.IsValid()) {
696 Error("Create", "invalid URL specified: %s", fUrl.GetUrl());
697 goto zombie;
698 }
699
700 if (netopt > tcpwindowsize)
702
703 // Open connection to remote rootd server
704 EMessageTypes kind;
705 Int_t stat;
706 ConnectServer(&stat, &kind, netopt, tcpwindowsize, forceOpen, forceRead);
707 if (gDebug > 2) Info("Create", "got from host %d %d", stat, kind);
708
709 if (kind == kROOTD_ERR) {
710 PrintError("Create", stat);
711 Error("Create", "failing on file %s", fUrl.GetUrl());
712 goto zombie;
713 }
714
715 if (recreate) {
716 create = kTRUE;
717 fOption = "CREATE";
718 }
719
720 if (update && stat > 1) {
721 create = kTRUE;
722 stat = 1;
723 }
724
725 if (stat == 1)
726 fWritable = kTRUE;
727 else
728 fWritable = kFALSE;
729
730 Init(create);
731 return;
732
733zombie:
734 // error in file opening occurred, make this object a zombie
735 MakeZombie();
736 SafeDelete(fSocket);
738}
739
740////////////////////////////////////////////////////////////////////////////////
741/// Create a NetFile object using an existing connection (socket s).
742/// Provided for use in TNetXNGFile.
743/// See:
744/// TNetFile::Create(const char *url, Option_t *option, Int_t netopt)
745/// for details about the arguments.
746
748{
749 // Import socket
750 fSocket = s;
751
752 // Create the connection
753 Create(s->GetUrl(), option, netopt);
754}
755
756////////////////////////////////////////////////////////////////////////////////
757/// Return kTRUE if 'url' matches the coordinates of this file.
758/// Check the full URL, including port and FQDN.
759
761{
762 // Run standard check on fUrl, first
764 if (rc)
765 // Ok, standard check enough
766 return kTRUE;
767
768 // Check also endpoint URL
769 TUrl u(url);
770 if (!strcmp(u.GetFile(),fEndpointUrl.GetFile())) {
771 // Candidate info
772 TString fqdn = u.GetHostFQDN();
773
774 // Check ports
775 if (u.GetPort() == fEndpointUrl.GetPort()) {
776 TString fqdnref = fEndpointUrl.GetHostFQDN();
777 if (fqdn == fqdnref)
778 // Ok, coordinates match
779 return kTRUE;
780 }
781 }
782
783 // Default is not matching
784 return kFALSE;
785}
786
787//
788// TNetSystem: the directory handler for net files
789//
790
791////////////////////////////////////////////////////////////////////////////////
792/// Create helper class that allows directory access via rootd.
793/// Use ftpowner = TRUE (default) if this instance is responsible
794/// for cleaning of the underlying TFTP connection; this allows
795/// to have control on the order of the final cleaning.
796
798 : TSystem("-root", "Net file Helper System")
799{
800 // name must start with '-' to bypass the TSystem singleton check
801 SetName("root");
802
803 fDir = kFALSE;
804 fDirp = 0;
805 fFTP = 0;
807 fUser = "";
808 fHost = "";
809 fPort = -1;
811}
812
813////////////////////////////////////////////////////////////////////////////////
814/// Create helper class that allows directory access via rootd.
815/// Use ftpowner = TRUE (default) if this instance is responsible
816/// for cleaning of the underlying TFTP connection; this allows
817/// to have control on the order of the final cleaning.
818
820 : TSystem("-root", "Net file Helper System")
821{
822 // name must start with '-' to bypass the TSystem singleton check
823 SetName("root");
824
827 Create(url);
828}
829
830////////////////////////////////////////////////////////////////////////////////
831/// Parse and save coordinates of the remote entity (user, host, port, ...)
832
834{
835 TUrl turl(url);
836
837 // Remote username: local as default
838 fUser = turl.GetUser();
839 if (!fUser.Length()) {
841 if (u)
842 fUser = u->fUser;
843 delete u;
844 }
845
846 // Check and save the host FQDN ...
847 fHost = turl.GetHostFQDN();
848
849 // Remote port: the default should be 1094 because we are here
850 // only if the protocol is "root://"
851 fPort = turl.GetPort();
852}
853
854////////////////////////////////////////////////////////////////////////////////
855/// Create a TNetSystem object.
856
858{
859 // If we got here protocol must be at least its short form "^root.*:" :
860 // make sure that it is in the full form to avoid problems in TFTP
862 if (!surl.Contains("://")) {
863 surl.Insert(surl.Index(":")+1,"//");
864 }
865 TUrl turl(surl);
866
867 fDir = kFALSE;
868 fDirp = 0;
869 fFTP = 0;
870
871 // Check locality, taking into account possible prefixes
872 fLocalPrefix = "";
873 fIsLocal = kFALSE;
874 // We may have been asked explicitly to go through the daemon
875 Bool_t forceRemote = gEnv->GetValue("Path.ForceRemote", 0);
877 if (opts.Contains("remote=1"))
879 else if (opts.Contains("remote=0"))
881 if (!forceRemote) {
882 if ((fIsLocal = TSystem::IsPathLocal(url))) {
883 fLocalPrefix = gEnv->GetValue("Path.Localroot","");
884 // Nothing more to do
885 return;
886 }
887 }
888
889 // Fill in user, host, port
890 InitRemoteEntity(surl);
891
892 // Build a TFTP url
893 if (fHost.Length()) {
894 TString eurl = "";
895 // First the protocol
896 if (strlen(turl.GetProtocol())) {
897 eurl = turl.GetProtocol();
898 eurl += "://";
899 } else
900 eurl = "root://";
901 // Add user, if specified
902 if (strlen(turl.GetUser())) {
903 eurl += turl.GetUser();
904 eurl += "@";
905 }
906 // Add host
907 eurl += fHost;
908 // Add port
909 eurl += ":";
910 eurl += turl.GetPort();
911
912 fFTP = new TFTP(eurl, 1, TFTP::kDfltWindowSize, sock);
913 if (fFTP && fFTP->IsOpen()) {
914 if (fFTP->GetSocket()->GetRemoteProtocol() < 12) {
915 Error("Create",
916 "remote daemon does not support 'system' functionality");
917 fFTP->Close();
918 delete fFTP;
919 } else {
920 fUser = ROOT::Deprecated::TSocketFriend::GetSecContext(*fFTP->GetSocket())->GetUser();
921 fHost = ROOT::Deprecated::TSocketFriend::GetSecContext(*fFTP->GetSocket())->GetHost();
922 // If responsible for the TFTP connection, remove it from the
923 // socket global list to avoid problems with double deletion
924 // at final cleanup
925 if (fFTPOwner)
926 gROOT->GetListOfSockets()->Remove(fFTP);
927 }
928 }
929 }
930}
931
932////////////////////////////////////////////////////////////////////////////////
933/// Destructor
934
936{
937 // Close FTP connection
938 if (fFTPOwner) {
939 if (fFTP) {
940 if (fFTP->IsOpen()) {
941
942 // Close remote directory if still open
943 if (fDir) {
944 fFTP->FreeDirectory(kFALSE);
945 fDir = kFALSE;
946 }
947 fFTP->Close();
948 }
949 delete fFTP;
950 }
951 }
952 fDirp = 0;
953 fFTP = 0;
954}
955
956////////////////////////////////////////////////////////////////////////////////
957/// Make a directory via rootd.
958
960{
961 // If local, use the local TSystem
962 if (fIsLocal) {
963 TString edir = TUrl(dir).GetFile();
964 if (!fLocalPrefix.IsNull())
965 edir.Insert(0, fLocalPrefix);
966 return gSystem->MakeDirectory(edir);
967 }
968
969 if (fFTP && fFTP->IsOpen()) {
970 // Extract the directory name
971 TString edir = TUrl(dir).GetFile();
972 return fFTP->MakeDirectory(edir,kFALSE);
973 }
974 return -1;
975}
976
977////////////////////////////////////////////////////////////////////////////////
978/// Open a directory and return an opaque pointer to a dir structure.
979/// Returns nullptr in case of error.
980
982{
983 // If local, use the local TSystem
984 if (fIsLocal) {
985 TString edir = TUrl(dir).GetFile();
986 if (!fLocalPrefix.IsNull())
987 edir.Insert(0, fLocalPrefix);
988 return gSystem->OpenDirectory(edir);
989 }
990
991 if (!fFTP || !fFTP->IsOpen())
992 return nullptr;
993
994 if (fDir) {
995 if (gDebug > 0)
996 Info("OpenDirectory", "a directory is already open: close it first");
997 fFTP->FreeDirectory(kFALSE);
998 fDir = kFALSE;
999 }
1000
1001 // Extract the directory name
1002 TString edir = TUrl(dir).GetFile();
1003
1004 if (fFTP->OpenDirectory(edir,kFALSE)) {
1005 fDir = kTRUE;
1006 fDirp = (void *)&fDir;
1007 return fDirp;
1008 } else
1009 return nullptr;
1010}
1011
1012////////////////////////////////////////////////////////////////////////////////
1013/// Free directory via rootd.
1014
1016{
1017 // If local, use the local TSystem
1018 if (fIsLocal) {
1020 return;
1021 }
1022
1023 if (dirp != fDirp) {
1024 Error("FreeDirectory", "invalid directory pointer (should never happen)");
1025 return;
1026 }
1027
1028 if (fFTP && fFTP->IsOpen()) {
1029 if (fDir) {
1030 fFTP->FreeDirectory(kFALSE);
1031 fDir = kFALSE;
1032 fDirp = 0;
1033 }
1034 }
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038/// Get directory entry via rootd. Returns 0 in case no more entries.
1039
1041{
1042 // If local, use the local TSystem
1043 if (fIsLocal) {
1044 return gSystem->GetDirEntry(dirp);
1045 }
1046
1047 if (dirp != fDirp) {
1048 Error("GetDirEntry", "invalid directory pointer (should never happen)");
1049 return 0;
1050 }
1051
1052 if (fFTP && fFTP->IsOpen() && fDir) {
1053 return fFTP->GetDirEntry(kFALSE);
1054 }
1055 return 0;
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Get info about a file. Info is returned in the form of a FileStat_t
1060/// structure (see TSystem.h).
1061/// The function returns 0 in case of success and 1 if the file could
1062/// not be stat'ed.
1063
1065{
1066 // If local, use the local TSystem
1067 if (fIsLocal) {
1068 TString epath = TUrl(path).GetFile();
1069 if (!fLocalPrefix.IsNull())
1070 epath.Insert(0, fLocalPrefix);
1071 return gSystem->GetPathInfo(epath, buf);
1072 }
1073
1074 if (fFTP && fFTP->IsOpen()) {
1075 // Extract the directory name
1076 TString epath = TUrl(path).GetFile();
1077 fFTP->GetPathInfo(epath, buf, kFALSE);
1078 return 0;
1079 }
1080 return 1;
1081}
1082
1083////////////////////////////////////////////////////////////////////////////////
1084/// Returns FALSE if one can access a file using the specified access mode.
1085/// Mode is the same as for the Unix access(2) function.
1086/// Attention, bizarre convention of return value!!
1087
1089{
1090 // If local, use the local TSystem
1091 if (fIsLocal) {
1092 TString epath = TUrl(path).GetFile();
1093 if (!fLocalPrefix.IsNull())
1094 epath.Insert(0, fLocalPrefix);
1095 return gSystem->AccessPathName(epath, mode);
1096 }
1097
1098 if (fFTP && fFTP->IsOpen()) {
1099 // Extract the directory name
1100 TString epath = TUrl(path).GetFile();
1101 return fFTP->AccessPathName(epath, mode, kFALSE);
1102 }
1103 return kTRUE;
1104}
1105
1106////////////////////////////////////////////////////////////////////////////////
1107/// Check consistency of this helper with the one required
1108/// by 'path' or 'dirptr'.
1109
1111{
1112 // Standard check: only the protocol part of 'path' is required to match
1114 if (!checkstd) return kFALSE;
1115
1116 // Require match of 'user' and 'host'
1117 Bool_t checknet = path ? kFALSE : kTRUE;
1118 if (path && strlen(path)) {
1119
1120 // Get user name
1121 TUrl url(path);
1122 TString user = url.GetUser();
1123 if (user.IsNull() && !fUser.IsNull()) {
1125 if (u)
1126 user = u->fUser;
1127 delete u;
1128 }
1129
1130 // Get host name
1131 TString host = url.GetHostFQDN();
1132
1133 // Get port
1134 Int_t port = url.GetPort();
1135 if (gDebug > 1)
1136 Info("ConsistentWith", "fUser:'%s' (%s), fHost:'%s' (%s), fPort:%d (%d)",
1137 fUser.Data(), user.Data(), fHost.Data(), host.Data(),
1138 fPort, port);
1139
1140 if (user == fUser && host == fHost && port == fPort)
1141 checknet = kTRUE;
1142 }
1143
1144 return (checkstd && checknet);
1145}
1146
1147////////////////////////////////////////////////////////////////////////////////
1148/// Remove a path
1149
1151{
1152 // If local, use the local TSystem
1153 if (fIsLocal) {
1154 TString epath = TUrl(path).GetFile();
1155 if (!fLocalPrefix.IsNull())
1156 epath.Insert(0, fLocalPrefix);
1157 return gSystem->Unlink(epath);
1158 }
1159
1160 // Not implemented for rootd
1161 Warning("Unlink", "functionality not implemented - ignored (path: %s)", path);
1162 return -1;
1163}
EMessageTypes
@ kROOTD_FSTAT
@ kROOTD_OPEN
@ kROOTD_BYE
@ kROOTD_GET
@ kROOTD_PUT
@ kROOTD_ERR
@ kROOTD_CLOSE
@ kROOTD_FLUSH
@ kROOTD_GETS
R__EXTERN const char * gRootdErrStr[]
Definition NetErrors.h:72
#define SafeDelete(p)
Definition RConfig.hxx:531
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
R__EXTERN TApplication * gApplication
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:783
#define gROOT
Definition TROOT.h:426
void ReadBuffer(char *&buffer) override
TString ToLower(const TString &s)
Return a lower-case version of str.
Definition TString.cxx:1503
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2509
EAccessMode
Definition TSystem.h:51
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:126
Bool_t R_ISDIR(Int_t mode)
Definition TSystem.h:123
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
@ kS_IXOTH
Definition TSystem.h:120
@ kS_IXUSR
Definition TSystem.h:112
@ kS_IXGRP
Definition TSystem.h:116
#define gPerfStats
void Init(Bool_t create) override
Initialize a TNetFile object.
Definition TNetFile.cxx:235
Bool_t ReadBuffer(char *buf, Int_t len) override
Read specified byte range from remote file via rootd daemon.
Definition TNetFile.cxx:299
Bool_t WriteBuffer(const char *buf, Int_t len) override
Write specified byte range to remote file via rootd daemon.
Definition TNetFile.cxx:487
Bool_t Matches(const char *url) override
Return kTRUE if 'url' matches the coordinates of this file.
Definition TNetFile.cxx:760
virtual void Create(const char *url, Option_t *option, Int_t netopt)
Create a NetFile object.
Definition TNetFile.cxx:658
Int_t SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime) override
Return file stat information.
Definition TNetFile.cxx:155
Int_t SysClose(Int_t fd) override
Close currently open file.
Definition TNetFile.cxx:143
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:569
void Print(Option_t *option) const override
Print some info about the net file.
Definition TNetFile.cxx:254
Bool_t IsOpen() const override
Retruns kTRUE if file is open, kFALSE otherwise.
Definition TNetFile.cxx:246
Int_t Recv(Int_t &status, EMessageTypes &kind)
Return status from rootd server and message kind.
Definition TNetFile.cxx:545
Int_t ReOpen(Option_t *mode) override
Reopen a file with a different access mode, like from READ to UPDATE or from NEW, CREATE,...
Definition TNetFile.cxx:284
Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf) override
Read a list of buffers given in pos[] and len[] and return it in a single buffer.
Definition TNetFile.cxx:383
void Flush() override
Flush file to disk.
Definition TNetFile.cxx:224
void PrintError(const char *where, Int_t err)
Print error string depending on error code.
Definition TNetFile.cxx:269
void Seek(Long64_t offset, ERelativeTo pos=kBeg) override
Set position from where to start reading.
Definition TNetFile.cxx:561
void Close(Option_t *option="") override
Close remote file.
Definition TNetFile.cxx:207
Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode) override
Open a remote file. Requires fOption to be set correctly.
Definition TNetFile.cxx:108
virtual ~TNetFile()
TNetFile dtor. Send close message and close socket.
Definition TNetFile.cxx:100
virtual ~TNetSystem()
Destructor.
Definition TNetFile.cxx:935
Bool_t AccessPathName(const char *path, EAccessMode mode) override
Returns FALSE if one can access a file using the specified access mode.
void Create(const char *url, TSocket *sock=nullptr)
Create a TNetSystem object.
Definition TNetFile.cxx:857
void * OpenDirectory(const char *name) override
Open a directory and return an opaque pointer to a dir structure.
Definition TNetFile.cxx:981
Int_t GetPathInfo(const char *path, FileStat_t &buf) override
Get info about a file.
Int_t MakeDirectory(const char *name) override
Make a directory via rootd.
Definition TNetFile.cxx:959
Bool_t ConsistentWith(const char *path, void *dirptr) override
Check consistency of this helper with the one required by 'path' or 'dirptr'.
void InitRemoteEntity(const char *url)
Parse and save coordinates of the remote entity (user, host, port, ...)
Definition TNetFile.cxx:833
TNetSystem(const TNetSystem &)=delete
const char * GetDirEntry(void *dirp=nullptr) override
Get directory entry via rootd. Returns 0 in case no more entries.
int Unlink(const char *path) override
Remove a path.
void FreeDirectory(void *dirp=nullptr) override
Free directory via rootd.
TSignalHandler * GetSignalHandler() const
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:503
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
virtual Int_t ReOpen(Option_t *mode)
Reopen a file with a different access mode.
Definition TFile.cxx:2214
virtual Bool_t Matches(const char *name)
Return kTRUE if 'url' matches the coordinates of this file.
Definition TFile.cxx:4472
virtual Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read the nbuf blocks described in arrays pos and len.
Definition TFile.cxx:1873
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition TFile.cxx:638
ERelativeTo
Definition TFile.h:277
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:980
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
void HandleDelayedSignal()
This class implements client sockets.
Definition TSocket.h:54
const char * GetUrl() const
Definition TSocket.h:152
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:384
Bool_t IsNull() const
Definition TString.h:422
Abstract base class defining a generic interface to the underlying Operating System.
Definition TSystem.h:276
virtual void IgnoreInterrupt(Bool_t ignore=kTRUE)
If ignore is true ignore the interrupt signal, else restore previous behaviour.
Definition TSystem.cxx:600
static void ResetErrno()
Static function resetting system error number.
Definition TSystem.cxx:282
static Int_t GetErrno()
Static function returning system error number.
Definition TSystem.cxx:274
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:855
virtual void * OpenDirectory(const char *name)
Open a directory.
Definition TSystem.cxx:846
virtual Bool_t IsPathLocal(const char *path)
Returns TRUE if the url in 'path' points to the local file system.
Definition TSystem.cxx:1316
virtual int MakeDirectory(const char *name)
Make a directory.
Definition TSystem.cxx:836
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1409
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1307
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:863
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1392
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition TSystem.cxx:1612
virtual Bool_t ConsistentWith(const char *path, void *dirptr=nullptr)
Check consistency of this helper with the one required by 'path' or 'dirptr'.
Definition TSystem.cxx:813
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition TTimeStamp.h:45
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetFile() const
Definition TUrl.h:69
const char * GetOptions() const
Definition TUrl.h:71
const Int_t n
Definition legend1.C:16
static const char * what
Definition stlLoader.cc:5
static TSocket * CreateAuthSocket(const char *user, const char *host, Int_t port, Int_t size=0, Int_t tcpwindowsize=-1, TSocket *s=nullptr, Int_t *err=nullptr)
Creates a socket or a parallel socket and authenticates to the remote server specified in 'url' on re...
Definition TSocket.cxx:1431
static Bool_t IsAuthenticated(const TSocket &s)
Definition TSocket.cxx:42
static TSecContext * GetSecContext(const TSocket &s)
Definition TSocket.cxx:52