XRootD
XrdCpFile.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C p F i l e . c c */
4 /* */
5 /* (c) 2012 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cerrno>
32 #include <fcntl.h>
33 #include <cstring>
34 #include <strings.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 
38 #include "XrdApps/XrdCpFile.hh"
39 #include "XrdOuc/XrdOucNSWalk.hh"
40 
41 /******************************************************************************/
42 /* S t a t i c M e m b e r s */
43 /******************************************************************************/
44 
45 const char *XrdCpFile::mPfx = 0;
46 
47 /******************************************************************************/
48 /* C o n s t r u c t o r */
49 /******************************************************************************/
50 
51 XrdCpFile::XrdCpFile(const char *FSpec, int &badURL)
52 {
53  static struct proto {const char *pHdr; int pHsz; PType pVal;}
54  pTab[] = {{"xroot://", 8, isXroot},
55  {"xroots://", 9, isXroots},
56  {"root://", 7, isXroot},
57  {"roots://", 8, isXroots},
58  {"http://", 7, isHttp},
59  {"https://", 8, isHttps},
60  {"dav://", 6, isHttp},
61  {"davs://", 7, isHttps},
62  {"pelican://", 10, isPelican},
63  {"s3://", 5, isS3}
64  };
65  static int pTnum = sizeof(pTab)/sizeof(struct proto);
66  const char *Slash;
67  int i;
68 
69 // Do some common initialization
70 //
71  Doff = 0;
72  Dlen = 0;
73  Next = 0;
74  fSize = 0;
75  badURL= 0;
76  memset(ProtName, 0, sizeof(ProtName));
77 
78 // Copy out the path and remove trailing slashes (except the last one)
79 //
80  Path = strdup(FSpec);
81  i = strlen(Path);
82  while(i) if (Path[i-1] != '/' || (i > 1 && Path[i-2] != '/')) break;
83  else Path[--i] = 0;
84 
85 // Check for stdin stdout spec
86 //
87  if (!strcmp(Path, "-"))
88  {Protocol = isStdIO;
89  return;
90  }
91 
92 // Dtermine protocol of the incoming spec
93 //
94  for (i = 0; i < pTnum; i++)
95  {if (!strncmp(FSpec, pTab[i].pHdr, pTab[i].pHsz))
96  {Protocol = pTab[i].pVal;
97  memcpy(ProtName, pTab[i].pHdr, pTab[i].pHsz-3);
98  return;
99  }
100  }
101 
102 // See if this is a file
103 //
104  Protocol = isFile;
105  if (!strncmp(Path, "file://", 7))
106  {char *pP = Path + 7;
107  if (!strncmp(pP, "localhost", 9)) memmove( Path, pP + 9, strlen( pP + 9 ) + 1 );
108  else if (*pP == '/') memmove( Path, pP, strlen( pP ) + 1 );
109  else {Protocol = isOther;
110  strcpy(ProtName, "remote");
111  return;
112  }
113  }
114 
115 // Set the default Doff and Dlen assuming non-recursive copy
116 //
117  if ((Slash = rindex(Path, '/'))) Dlen = Doff = Slash - Path + 1;
118 }
119 
120 /******************************************************************************/
121 
122 XrdCpFile::XrdCpFile(char *FSpec, struct stat &Stat, short doff, short dlen)
123  : Next(0), Path(FSpec), Doff(doff), Dlen(dlen),
124  Protocol(isFile), fSize(Stat.st_size)
125  {strcpy(ProtName, "file");}
126 
127 /******************************************************************************/
128 /* E x t e n d */
129 /******************************************************************************/
130 
131 int XrdCpFile::Extend(XrdCpFile **pLast, int &nFile, long long &nBytes)
132 {
134  XrdOucNSWalk::NSEnt *nP, *nnP;
135  XrdCpFile *fP, *pP = this;
136  int rc;
137  short dlen, doff = strlen(Path);
138 
139  nsObj.setMsgOn(mPfx);
140 
141  while((nP = nsObj.Index(rc)) && rc == 0)
142  {do {dlen = nP->Plen - doff;
143  fP = new XrdCpFile(nP->Path, nP->Stat, doff, dlen);
144  nFile++; nBytes += nP->Stat.st_size; nP->Path = 0;
145  pP->Next = fP; pP = fP;
146  nnP = nP->Next; delete nP;
147  } while((nP = nnP));
148  }
149 
150  if (pLast) *pLast = pP;
151  return rc;
152 }
153 
154 /******************************************************************************/
155 /* R e s o l v e */
156 /******************************************************************************/
157 
159 {
160  struct stat Stat;
161 
162 // Ignore this call if this is not a file
163 //
164  if (Protocol != isFile) return 0;
165 
166 // This should exist but it might not, the caller will determine what to do
167 //
168  char *cgibeg = strchr( Path, '?' );
169  if( cgibeg ) *cgibeg = '\0';
170  if (stat(Path, &Stat)) return errno;
171  if( cgibeg ) *cgibeg = '?';
172 
173 // Find out what this really is
174 //
175  if (S_ISREG(Stat.st_mode)) fSize = Stat.st_size;
176  else if (S_ISDIR(Stat.st_mode)) Protocol = isDir;
177  else if (!strcmp(Path, "/dev/null")) Protocol = isDevNull;
178  else if (!strcmp(Path, "/dev/zero")) Protocol = isDevZero;
179  else return ENOTSUP;
180 
181 // All is well
182 //
183  return 0;
184 }
struct stat Stat
Definition: XrdCks.cc:49
#define stat(a, b)
Definition: XrdPosix.hh:105
XrdOucString Path
short Doff
Definition: XrdCpFile.hh:46
PType Protocol
Definition: XrdCpFile.hh:49
int Resolve()
Definition: XrdCpFile.cc:158
int Extend(XrdCpFile **pLast, int &nFile, long long &nBytes)
Definition: XrdCpFile.cc:131
long long fSize
Definition: XrdCpFile.hh:51
char * Path
Definition: XrdCpFile.hh:45
char ProtName[8]
Definition: XrdCpFile.hh:50
XrdCpFile * Next
Definition: XrdCpFile.hh:44
short Dlen
Definition: XrdCpFile.hh:47
static const int retFile
void setMsgOn(const char *pfx)
NSEnt * Index(int &rc, const char **dPath=0)
Definition: XrdOucNSWalk.cc:93
static const int Recurse
ProtocolImpl< false > Protocol
struct NSEnt * Next
Definition: XrdOucNSWalk.hh:48