66int XrdOssArcCompose::minLenDSN = 4;
67int XrdOssArcCompose::minLenFN = 4;
74 int& rc,
bool isW,
bool optfn)
86 if (!strncmp(
Config.arcvPathLFN, path,
Config.arcvPathLEN))
88 path +=
Config.arcvPathLEN;
90 else if (!strncmp(
Config.arcvPathLFN, path,
Config.arcvPathLEN-1)
91 && strlen(path) < (
size_t)
Config.arcvPathLEN)
93 path +=
Config.arcvPathLEN-1;
95 else if (!strncmp(
Config.bkupPathLFN, path,
Config.bkupPathLEN))
97 path +=
Config.bkupPathLEN;
100 else {rc = EDOM;
return;}
105 if ((rc = getDSN(path)))
return;
106 if (!env) {rc = 0;
return;}
110 const char* theFN = 0;
116 if (isW) {rc = EROFS;
return;}
124 {
const char* fn = rindex(path,
'/');
125 if (fn && fn != path)
131 if (!theFN && !(theFN = env->
Get(
"ossarc.fn")))
134 ecMsg.Msg(
"Compose",
"CGI ossarc.fn=<target_fname> not specified");
147 ecMsg.Msg(
"Compose",
"Backup filename cannot refer to an archive");
151 }
else fl2arc =
true;
158 {
const char* colon = index(theFN,
':');
166 ecMsg.Msg(
"Compose",
"File scope not specified though implied");
169 flScope.assign(theFN, colon - theFN);
172 if ((
int)
flName.length() < minLenDSN)
174 ecMsg.Msg(
"Compose",
"Dataset name is too short");
181 const char* atName[] = {
"Archive",
"Backup"};
183 DEBUG(
"Type="<<atName[
didType]<<
" f2a="<<fl2arc<<
" fscpDF="<<fscpDS
189 rc = (fl2arc ? SetarName() : 0);
198 if (snprintf(buff, blen,
"%s:%s",
flScope.c_str(),
flName.c_str()) >= blen)
200 Elog.Emsg(
"Compose", ENAMETOOLONG,
"generate archive member name "
201 "in dataset",
dsName.c_str());
202 ecMsg.Msg(
"Compose",
"Archive member name", fn.c_str(),
"is too long");
218 if (addafn) n = snprintf(buff, blen,
"%s/%s/%s/%s",
Config.tapePath,
220 else n = snprintf(buff, blen,
"%s/%s/%s",
Config.tapePath,
227 Elog.Emsg(
"Compose", ENAMETOOLONG,
"generate archive path for dataset",
243 std::string retdir(dsn);
244 int n = retdir.length();
246 for (
int i = 0; i < n; i++)
if (retdir[i] ==
'/') retdir[i] =
'%';
257 std::string retdsn(dir);
258 int n = retdsn.length();
260 for (
int i = 0; i < n; i++)
if (retdsn[i] ==
'%') retdsn[i] =
'/';
269int XrdOssArcCompose::getDSN(
const char *path)
274 const char* colon = index(path,
':');
275 if (!colon || *path ==
':')
276 {
ecMsg.Msg(
"Compose",
"Dataset scope not specified");
279 dsScope.assign(path, colon - path);
283 if ((
int)strlen(colon+1) < minLenDSN)
284 {
ecMsg.
Msg(
"Compose",
"dataset name is too short");
307 int n = strlen(path);
311 if (n <=
Config.arfSfxLen)
return false;
324 return !strncmp(
Config.arcvPathLFN, path,
Config.arcvPathLEN);
333 return !strncmp(
Config.bkupPathLFN, path,
Config.bkupPathLEN);
342 return !strncmp(
Config.arcvPathLFN, path,
Config.arcvPathLEN) ||
350int XrdOssArcCompose::SetarName()
359 const char* argV[] = {
"which",
Config.arFName, fName.c_str(),
361 int argC =
sizeof(argV)/
sizeof(
char*);
367 <<argV[1]<<
' '<<argV[2]<<
' '<<argV[3]<<
' '<<argV[4]);
390 if (
arName ==
"!ENOENT") rc = ENOENT;
392 else if (!rc) rc = EPROTO;
397 ecMsg.
Msg(
"Compose",
"Unable to determine name of the dataset",
398 dName.c_str(),
"archive for", fName.c_str(),
414 const char* argV[] = {
"stat",
"cgi", Scope, Name};
415 int argC =
sizeof(argV)/
sizeof(
char*);
420 DEBUG(
"Running "<<
Config.BkpUtilName<<
' '<<argV[0]<<
' '
421 <<argV[1]<<
' '<<argV[2]<<
' '<<argV[3]);
428 if (!(rc =
Config.BkpUtilProg->Run(&cmdSup, argV, argC)))
432 {
if (!(rc = StatDecode(*
Stat, resp))) aOK =
true;
433 else if (!strcmp(
"!ENOENT", resp)) rc = ENOENT;
437 rc2 =
Config.BkpUtilProg->RunDone(cmdSup);
452int XrdOssArcCompose::StatDecode(
struct stat&
Stat,
const char* resp)
460 memset(&
Stat, 0,
sizeof(
struct stat));
462 if (StatGet(
"uid", env, val))
Stat.st_uid = int(val);
465 if (StatGet(
"gid", env, val))
Stat.st_gid = int(val);
468 if (StatGet(
"size", env, val))
Stat.st_size = val;
471 if (StatGet(
"atime", env, val))
Stat.st_atime = time_t(val);
473 if (StatGet(
"mtime", env, val))
Stat.st_mtime = time_t(val);
475 if (StatGet(
"ctime", env, val))
Stat.st_ctime = time_t(val);
480 if (!(infoP = env.Get(
"mode")))
481 {
DEBUG(
"Missing 'mode' in stat resp '"<<env.Env(n)<<
"'");
487 Stat.st_mode = S_IRUSR | S_IRGRP;
488 if (!strcmp(infoP,
"FILE"))
Stat.st_mode |= S_IFREG;
489 else Stat.st_mode = S_IFDIR | S_IXUSR | S_IXGRP;
500bool XrdOssArcCompose::StatGet(
const char* var,
XrdOucEnv& env,
long long& val)
509 if (!(varval = env.
Get(var)))
510 {
DEBUG(
"Missing '"<<var<<
"' in stat resp '"<<env.
Env(n)<<
"'");
516 val = strtoll(varval, &endval, 10);
517 if (*endval == 0)
return true;
521 DEBUG(
"Invalid '"<<var<<
'='<<varval<<
"' in stat resp '"<<env.
Env(n)<<
"'");
const char * XrdSysE2T(int errcode)
static bool isArcPath(const char *path)
static int Stat(const char *Scope, const char *Name, struct stat *Stat)
static bool isArcFile(const char *path)
XrdOssArcCompose(const char *path, XrdOucEnv *env, int &retc, bool isW=true, bool optfn=false)
static std::string Dir2DSN(const char *dir)
static std::string DSN2Dir(const char *dsn)
static bool isMine(const char *path)
static bool isBkpPath(const char *path)
int ArcMember(char *buff, int blen)
int ArcPath(char *buff, int blen, bool addafn=false)
char * Get(const char *varname)
int RunDone(XrdOucStream &cmd) const
int Run(XrdOucStream *Sp, const char *argV[], int argc=0, const char *envV[]=0) const
char * GetToken(int lowcase=0)
XrdSysError Elog(0, "OssArc_")