XRootD
Loading...
Searching...
No Matches
XrdFrcUtils.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d F r c U t i l s . c c */
4/* */
5/* (c) 2009 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 <unistd.h>
34#include <utime.h>
35#include <sys/stat.h>
36#include <sys/types.h>
37
38#include "XrdFrc/XrdFrcTrace.hh"
39#include "XrdFrc/XrdFrcUtils.hh"
40#include "XrdFrc/XrdFrcXAttr.hh"
41
42#include "XrdOuc/XrdOucSxeq.hh"
43#include "XrdOuc/XrdOucUtils.hh"
44#include "XrdOuc/XrdOucXAttr.hh"
45
46#include "XrdSys/XrdSysError.hh"
49
50using namespace XrdFrc;
51
52/******************************************************************************/
53/* A s k */
54/******************************************************************************/
55
56char XrdFrcUtils::Ask(char dflt, const char *Msg1, const char *Msg2,
57 const char *Msg3)
58{
59 const char *Hint;
60 char Answer[8];
61 int n;
62
63 Hint = (dflt == 'y' ? " (y | n | a): " : " (n | y | a): ");
64
65 do {std::cerr <<"frm_admin: " <<Msg1 <<Msg2 <<Msg3 <<Hint;
66 std::cin.getline(Answer, sizeof(Answer));
67 if (!*Answer) return dflt;
68
69 n = strlen(Answer);
70 if (!strncmp("yes", Answer, n)) return 'y';
71 if (!strncmp("no", Answer, n)) return 'n';
72 if (!strncmp("abort",Answer, n)) return 'a';
73 } while(1);
74 return 'a';
75}
76
77/******************************************************************************/
78/* c h k U R L */
79/******************************************************************************/
80
81int XrdFrcUtils::chkURL(const char *Url)
82{
83 const char *Elem;
84
85// Verify that this is a valid url and return offset to the lfn
86//
87 if (!(Elem = index(Url, ':'))) return 0;
88 if (Elem[1] != '/' || Elem[2] != '/') return 0;
89 if (!(Elem = index(Elem+3, '/')) || Elem[1] != '/') return 0;
90 Elem++;
91
92// At this point ignore all leading slashes but one
93//
94 while(Elem[1] == '/') Elem++;
95 return Elem - Url;
96}
97
98/******************************************************************************/
99/* m a k e P a t h */
100/******************************************************************************/
101
102char *XrdFrcUtils::makePath(const char *iName, const char *Path, int Mode)
103{
104 char *bPath;
105 int rc;
106
107// Generate an frm-specific admin path
108//
109 bPath = XrdOucUtils::genPath(Path, iName, "frm");
110
111// Create the admin directory if it does not exists and a mode supplied
112//
113 if (Mode > 0 && (rc = XrdOucUtils::makePath(bPath, Mode)))
114 {Say.Emsg("makePath", rc, "create directory", bPath);
115 return 0;
116 }
117
118// Return the actual adminpath we are to use (this has been strduped).
119//
120 return bPath;
121}
122
123/******************************************************************************/
124/* m a k e Q D i r */
125/******************************************************************************/
126
127char *XrdFrcUtils::makeQDir(const char *Path, int Mode)
128{
129 char qPath[1040], qLink[1032];
130 int n, lksz, rc;
131
132// Generate an frm-specific queue path
133//
134 strcpy(qPath, Path);
135 n = strlen(qPath);
136 if (qPath[n-1] != '/') qPath[n++] = '/';
137 strcpy(qPath+n, "Queues/");
138
139// If the target is a symlink, optimize the path
140//
141 if ((lksz = readlink(qPath, qLink, sizeof(qLink)-1)) > 0)
142 {qLink[lksz] = '\0';
143 if (qLink[lksz-1] != '/') {qLink[lksz++] = '/'; qLink[lksz++] = '\0';}
144 if (*qLink == '/') strcpy(qPath, qLink);
145 else strcpy(qPath+n, qLink);
146 }
147
148// Create the queue directory if it does not exists
149//
150 if (Mode > 0 && (rc = XrdOucUtils::makePath(qPath, Mode)))
151 {Say.Emsg("makeQDir", rc, "create directory", qPath);
152 return 0;
153 }
154
155// Return the actual adminpath we are to use
156//
157 return strdup(qPath);
158}
159
160/******************************************************************************/
161/* M a p M 2 O */
162/******************************************************************************/
163
164int XrdFrcUtils::MapM2O(const char *Nop, const char *Pop)
165{
166 int Options = 0;
167
168// Map processing options to request options
169//
170 if (index(Pop, 'w')) Options |= XrdFrcRequest::makeRW;
171 if (*Nop != '-')
172 {if (index(Pop, 's') || index(Pop, 'n'))
173 Options |= XrdFrcRequest::msgSucc;
174 if (index(Pop, 'f') || !index(Pop, 'q'))
175 Options |= XrdFrcRequest::msgFail;
176 }
177
178// All done
179//
180 return Options;
181}
182
183/******************************************************************************/
184/* M a p R 2 Q */
185/******************************************************************************/
186
187int XrdFrcUtils::MapR2Q(char Opc, int *Flags)
188{
189
190// Simply map the request code to the relevant queue
191//
192 switch(Opc)
193 {case 0 :
194 case '+': return XrdFrcRequest::stgQ;
195 case '^': if (Flags) *Flags = XrdFrcRequest::Purge;
196 return XrdFrcRequest::migQ;
197 case '&': return XrdFrcRequest::migQ;
198 case '<': return XrdFrcRequest::getQ;
199 case '=': if (Flags) *Flags |= XrdFrcRequest::Purge;
200 return XrdFrcRequest::putQ;
201 case '>': return XrdFrcRequest::putQ;
202 default: break;
203 }
204 return XrdFrcRequest::nilQ;
205}
206
207/******************************************************************************/
208/* M a p V 2 I */
209/******************************************************************************/
210
211int XrdFrcUtils::MapV2I(const char *vName, XrdFrcRequest::Item &ICode)
212{
213 static struct ITypes {const char *IName; XrdFrcRequest::Item ICode;}
214 ITList[] = {{"lfn", XrdFrcRequest::getLFN},
215 {"lfncgi", XrdFrcRequest::getLFNCGI},
216 {"mode", XrdFrcRequest::getMODE},
217 {"obj", XrdFrcRequest::getOBJ},
218 {"objcgi", XrdFrcRequest::getOBJCGI},
219 {"op", XrdFrcRequest::getOP},
220 {"prty", XrdFrcRequest::getPRTY},
221 {"qwt", XrdFrcRequest::getQWT},
222 {"rid", XrdFrcRequest::getRID},
223 {"tod", XrdFrcRequest::getTOD},
224 {"note", XrdFrcRequest::getNOTE},
225 {"tid", XrdFrcRequest::getUSER}};
226 static const int ITNum = sizeof(ITList)/sizeof(struct ITypes);
227 int i;
228
229// Simply map the variable name to the item code
230//
231 for (i = 0; i < ITNum; i++)
232 if (!strcmp(vName, ITList[i].IName))
233 {ICode = ITList[i].ICode; return 1;}
234 return 0;
235}
236
237/******************************************************************************/
238/* U n i q u e */
239/******************************************************************************/
240
241int XrdFrcUtils::Unique(const char *lkfn, const char *myProg)
242{
243 static const int Mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
244 FLOCK_t lock_args;
245 int myFD, rc;
246
247// Open the lock file first in r/w mode
248//
249 if ((myFD = open(lkfn, O_RDWR|O_CREAT, Mode)) < 0)
250 {Say.Emsg("Unique",errno,"open",lkfn); return 0;}
251
252// Establish locking options
253//
254 bzero(&lock_args, sizeof(lock_args));
255 lock_args.l_type = F_WRLCK;
256
257// Perform action.
258//
259 do {rc = fcntl(myFD,F_SETLK,&lock_args);}
260 while(rc < 0 && errno == EINTR);
261 if (rc < 0)
262 {Say.Emsg("Unique", errno, "obtain the run lock on", lkfn);
263 Say.Emsg("Unique", "Another", myProg, "may already be running!");
264 close(myFD);
265 return 0;
266 }
267
268// All done
269//
270 return 1;
271}
272
273/******************************************************************************/
274/* u p d t C p y */
275/******************************************************************************/
276
277int XrdFrcUtils::updtCpy(const char *Pfn, int Adj)
278{
280 struct stat Stat;
281
282// Make sure the base file exists
283//
284 if (stat(Pfn, &Stat)) {Say.Emsg("updCpy", errno,"stat pfn ",Pfn); return 0;}
285
286// Set correct copy time based on need
287//
288 cpyInfo.Attr.cpyTime = static_cast<long long>(Stat.st_mtime + Adj);
289 return cpyInfo.Set(Pfn) == 0;
290}
291
292/******************************************************************************/
293/* U t i m e */
294/******************************************************************************/
295
296int XrdFrcUtils::Utime(const char *Path, time_t tVal)
297{
298 struct utimbuf tbuf = {tVal, tVal};
299 int rc;
300
301// Set the time
302//
303 do {rc = utime(Path, &tbuf);} while(rc && errno == EINTR);
304 if (rc) Say.Emsg("Utils", errno, "set utime for pfn", Path);
305
306// All done
307//
308 return rc == 0;
309}
struct stat Stat
Definition XrdCks.cc:49
XrdOucPup XrdCmsParser::Pup & Say
int fcntl(int fd, int cmd,...)
#define close(a)
Definition XrdPosix.hh:48
#define open
Definition XrdPosix.hh:76
#define stat(a, b)
Definition XrdPosix.hh:101
int Mode
XrdOucString Path
#define FLOCK_t
static const int stgQ
static const int getQ
static const int migQ
static const int putQ
static const int Purge
static const int msgFail
static const int makeRW
static const int msgSucc
static const int nilQ
static int chkURL(const char *Url)
static char Ask(char dflt, const char *Msg1, const char *Msg2="", const char *Msg3="")
static int MapR2Q(char Opc, int *Flags=0)
static int Unique(const char *lkfn, const char *myProg)
static char * makePath(const char *iName, const char *Path, int Mode)
static int MapV2I(const char *Opc, XrdFrcRequest::Item &ICode)
static int Utime(const char *Path, time_t tVal)
static char * makeQDir(const char *Path, int Mode)
static int MapM2O(const char *Nop, const char *Pop)
static int updtCpy(const char *Pfn, int Adj)
static char * genPath(const char *path, const char *inst, const char *psfx=0)
static int makePath(char *path, mode_t mode, bool reset=false)
int Set(const char *Path, int fd=-1)