XRootD
Loading...
Searching...
No Matches
XrdSutPFile Class Reference

#include <XrdSutPFile.hh>

+ Collaboration diagram for XrdSutPFile:

Public Member Functions

 XrdSutPFile (const char *n, kXR_int32 openmode=kPFEcreate, kXR_int32 createmode=0600, bool hashtab=1)
 
 XrdSutPFile (const XrdSutPFile &f)
 
virtual ~XrdSutPFile ()
 
kXR_int32 Browse (void *out=0)
 
kXR_int32 Close (kXR_int32 d=-1)
 
bool Init (const char *n, kXR_int32 openmode=kPFEcreate, kXR_int32 createmode=0600, bool hashtab=1)
 
bool IsValid () const
 
kXR_int32 LastError () const
 
const char * LastErrStr () const
 
const char * Name () const
 
kXR_int32 Open (kXR_int32 opt, bool *wasopen=0, const char *nam=0, kXR_int32 createmode=0600)
 
kXR_int32 ReadCount (const char *nm, int &cnt)
 
kXR_int32 ReadEntry (const char *name, XrdSutPFEntry &ent, int opt=0)
 
kXR_int32 ReadEntry (kXR_int32 ofs, XrdSutPFEntry &ent)
 
kXR_int32 RemoveEntries (const char *name, char opt)
 
kXR_int32 RemoveEntry (const char *name)
 
kXR_int32 RemoveEntry (kXR_int32 ofs)
 
kXR_int32 ResetCount (const char *nm)
 
kXR_int32 RetrieveHeader (XrdSutPFHeader &hd)
 
kXR_int32 SearchEntries (const char *name, char opt, kXR_int32 *ofs=0, kXR_int32 nofs=1)
 
kXR_int32 SearchSpecialEntries (kXR_int32 *ofs=0, kXR_int32 nofs=1)
 
kXR_int32 Trim (const char *fbak=0)
 
kXR_int32 UpdateCount (const char *nm, int *cnt=0, int step=1, bool reset=0)
 
kXR_int32 UpdateHeader (XrdSutPFHeader hd)
 
kXR_int32 WriteEntry (XrdSutPFEntry ent)
 

Friends

class XrdSutPFCache
 

Detailed Description

Definition at line 121 of file XrdSutPFile.hh.

Constructor & Destructor Documentation

◆ XrdSutPFile() [1/2]

XrdSutPFile::XrdSutPFile ( const char * n,
kXR_int32 openmode = kPFEcreate,
kXR_int32 createmode = 0600,
bool hashtab = 1 )

Definition at line 187 of file XrdSutPFile.cc.

189{
190 // Constructor
191
192 name = 0;
193 if (n) {
194 name = new char[strlen(n)+1];
195 if (name)
196 strcpy(name,n);
197 }
198 valid = 0;
199 fFd = -1;
200 fHTutime = -1;
201 fHashTable = 0;
202
203 valid = Init(n, openmode, createmode, hashtab);
204}
bool Init(const char *n, kXR_int32 openmode=kPFEcreate, kXR_int32 createmode=0600, bool hashtab=1)

References Init().

+ Here is the call graph for this function:

◆ XrdSutPFile() [2/2]

XrdSutPFile::XrdSutPFile ( const XrdSutPFile & f)

Definition at line 207 of file XrdSutPFile.cc.

208{
209 // Copy constructor
210
211 name = 0;
212 if (f.name) {
213 name = new char[strlen(f.name)+1];
214 if (name)
215 strcpy(name,f.name);
216 }
217 fFd = f.fFd ;
218}

◆ ~XrdSutPFile()

XrdSutPFile::~XrdSutPFile ( )
virtual

Definition at line 221 of file XrdSutPFile.cc.

222{
223 // Destructor
224
225 if (name)
226 delete[] name;
227 name = 0;
228 if (fHashTable)
229 delete fHashTable;
230 fHashTable = 0;
231
232 Close();
233}
kXR_int32 Close(kXR_int32 d=-1)

References Close().

+ Here is the call graph for this function:

Member Function Documentation

◆ Browse()

kXR_int32 XrdSutPFile::Browse ( void * out = 0)

Definition at line 1624 of file XrdSutPFile.cc.

1625{
1626 // Display the content of the file
1627
1628 // Make sure we got an open stream
1629 if (Open(1) < 0)
1630 return -1;
1631
1632 // Read header
1633 XrdSutPFHeader hdr;
1634 if (ReadHeader(hdr) < 0) {
1635 Close();
1636 return -1;
1637 }
1638
1639 // Time strings
1640 struct tm tst;
1641 char sctime[256] = {0};
1642 time_t ttmp = hdr.ctime;
1643 localtime_r(&ttmp,&tst);
1644 asctime_r(&tst,sctime);
1645 sctime[strlen(sctime)-1] = 0;
1646 char sitime[256] = {0};
1647 ttmp = hdr.itime;
1648 localtime_r(&ttmp,&tst);
1649 asctime_r(&tst,sitime);
1650 sitime[strlen(sitime)-1] = 0;
1651
1652 // Default is stdout
1653 FILE *out = oout ? (FILE *)oout : stdout;
1654
1655 fprintf(out,"//-----------------------------------------------------"
1656 "--------------------//\n");
1657 fprintf(out,"//\n");
1658 fprintf(out,"// File: %s\n",name);
1659 fprintf(out,"// ID: %s\n",hdr.fileID);
1660 fprintf(out,"// Version: %d\n",hdr.version);
1661 fprintf(out,"// Last change : %s (%d sec)\n",sctime,hdr.ctime);
1662 fprintf(out,"// Index change: %s (%d sec)\n",sitime,hdr.itime);
1663 fprintf(out,"//\n");
1664 fprintf(out,"// Number of Entries: %d\n",hdr.entries);
1665 fprintf(out,"// Bytes unreachable: %d\n",hdr.jnksiz);
1666 fprintf(out,"//\n");
1667
1668 if (hdr.entries > 0) {
1669
1670 // Special entries first, if any
1672 if (ns > 0) {
1673 // Allocate space for offsets
1674 kXR_int32 *sofs = new kXR_int32[ns];
1675 if (sofs) {
1676 // Get offsets
1677 ns = SearchSpecialEntries(sofs,ns);
1678 fprintf(out,"// Special entries (%d):\n",ns);
1679 int i = 0;
1680 for (; i<ns; i++) {
1681
1682 // Read entry index at ofs
1683 XrdSutPFEntInd ind;
1684 if (ReadInd(sofs[i], ind) < 0) {
1685 Close();
1686 return -1;
1687 }
1688
1689 if (ind.entofs) {
1690 // Read entry
1691 XrdSutPFEntry ent;
1692 if (ReadEnt(ind.entofs, ent) < 0) {
1693 Close();
1694 return -1;
1695 }
1696 char smt[20] = {0};
1697 XrdSutTimeString(ent.mtime,smt);
1698 std::string buffer;
1699 char buf[2048] = {0};
1700 memset(buf,0,2048);
1701 sprintf(buf,"// #%d mod:%s",i+1,smt);
1702 buffer = buf;
1703 sprintf(buf," name:%s",ind.name);
1704 buffer += buf;
1705 fprintf(out,"%s\n",buffer.c_str());
1706
1707 buffer.clear();
1708 sprintf(buf,"// buf");
1709 buffer = buf;
1710
1711 if (ent.cnt == 1) {
1712 if (ent.buf1.len && ent.buf1.buf)
1713 {
1714 sprintf(buf,": %.*s",ent.buf1.len,ent.buf1.buf);
1715 buffer += buf;
1716 }
1717 if (ent.buf2.len && ent.buf2.buf)
1718 {
1719 sprintf(buf,": %.*s",ent.buf2.len,ent.buf2.buf);
1720 buffer += buf;
1721 }
1722 if (ent.buf3.len && ent.buf3.buf)
1723 {
1724 sprintf(buf,": %.*s",ent.buf3.len,ent.buf3.buf);
1725 buffer += buf;
1726 }
1727 if (ent.buf4.len && ent.buf4.buf)
1728 {
1729 sprintf(buf,": %.*s",ent.buf4.len,ent.buf4.buf);
1730 buffer += buf;
1731 }
1732 } else {
1733 sprintf(buf,":%d:%d:%d:%d",
1734 ent.buf1.len,ent.buf2.len,ent.buf3.len,
1735 ent.buf4.len);
1736 buffer += buf;
1737 buffer += " (protected)";
1738 }
1739 fprintf(out,"%s\n",buf);
1740 }
1741 }
1742 fprintf(out,"//\n");
1743 delete[] sofs;
1744 }
1745 }
1746
1747 if (hdr.entries > ns)
1748 fprintf(out,"// Normal entries (%d):\n",hdr.entries-ns);
1749
1750 kXR_int32 nn = 0;
1751 kXR_int32 nxtofs = hdr.indofs;
1752 while (nxtofs) {
1753
1754 // Read entry index at ofs
1755 XrdSutPFEntInd ind;
1756 if (ReadInd(nxtofs, ind) < 0) {
1757 Close();
1758 return -3;
1759 }
1760
1761 if (ind.entofs) {
1762 // Read entry
1763 XrdSutPFEntry ent;
1764 if (ReadEnt(ind.entofs, ent) < 0) {
1765 Close();
1766 return -4;
1767 }
1768 if (ent.status != kPFE_special) {
1769 char smt[20] = {0};
1770 XrdSutTimeString(ent.mtime,smt);
1771
1772 nn++;
1773 fprintf(out,
1774 "// #:%d st:%d cn:%d buf:%d,%d,%d,%d mod:%s name:%s\n",
1775 nn,ent.status,ent.cnt,ent.buf1.len,ent.buf2.len,ent.buf3.len,
1776 ent.buf4.len,smt,ind.name);
1777 }
1778 }
1779
1780 // Read next
1781 nxtofs = ind.nxtofs;
1782 }
1783 fprintf(out,"//\n");
1784 }
1785 fprintf(out,"//-----------------------------------------------------"
1786 "--------------------//\n");
1787
1788 // Close the file
1789 Close();
1790
1791 return 0;
1792}
int kXR_int32
Definition XPtypes.hh:89
int XrdSutTimeString(int t, char *st, int opt)
Definition XrdSutAux.cc:311
@ kPFE_special
kXR_int32 len
kXR_int32 entofs
kXR_int32 nxtofs
kXR_int32 mtime
XrdSutPFBuf buf3
XrdSutPFBuf buf1
XrdSutPFBuf buf2
XrdSutPFBuf buf4
kXR_int32 itime
kXR_int32 entries
kXR_int32 version
kXR_int32 ctime
kXR_int32 jnksiz
kXR_int32 indofs
char fileID[kFileIDSize]
kXR_int32 SearchSpecialEntries(kXR_int32 *ofs=0, kXR_int32 nofs=1)
kXR_int32 Open(kXR_int32 opt, bool *wasopen=0, const char *nam=0, kXR_int32 createmode=0600)

References XrdSutPFBuf::buf, XrdSutPFEntry::buf1, XrdSutPFEntry::buf2, XrdSutPFEntry::buf3, XrdSutPFEntry::buf4, Close(), XrdSutPFEntry::cnt, XrdSutPFHeader::ctime, XrdSutPFEntInd::entofs, XrdSutPFHeader::entries, XrdSutPFHeader::fileID, XrdSutPFHeader::indofs, XrdSutPFHeader::itime, XrdSutPFHeader::jnksiz, kPFE_special, XrdSutPFBuf::len, XrdSutPFEntry::mtime, XrdSutPFEntInd::name, XrdSutPFEntInd::nxtofs, Open(), SearchSpecialEntries(), XrdSutPFEntry::status, XrdSutPFHeader::version, and XrdSutTimeString().

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Close()

kXR_int32 XrdSutPFile::Close ( kXR_int32 d = -1)

Definition at line 450 of file XrdSutPFile.cc.

451{
452 // Close the open stream or descriptor fd, if > -1 .
453 // The file is unlocked before.
454
455 // If not open, do nothing
456 if (fd < 0)
457 fd = fFd;
458 if (fd < 0)
459 return 0;
460
461 //
462 // Unlock the file
463 struct flock flck;
464 memset(&flck, 0, sizeof(flck));
465 flck.l_type = F_UNLCK;
466 flck.l_whence = SEEK_SET;
467 if (fcntl(fd, F_SETLK, &flck) == -1) {
468 close(fd);
469 return Err(kPFErrUnlocking,"Close",(const char *)&fd);
470 }
471
472 //
473 // Close it
474 close(fd);
475
476 // Reset file descriptor
477 if (fd == fFd)
478 fFd = -1;
479
480 return 0;
481}
#define Err(p, a, b, c)
int fcntl(int fd, int cmd,...)
#define close(a)
Definition XrdPosix.hh:43
@ kPFErrUnlocking

References close, Err, fcntl(), and kPFErrUnlocking.

Referenced by ~XrdSutPFile(), Browse(), XrdSutPFCache::Flush(), Init(), XrdSutPFCache::Load(), ReadEntry(), ReadEntry(), RemoveEntry(), RemoveEntry(), RetrieveHeader(), SearchEntries(), SearchSpecialEntries(), Trim(), UpdateCount(), UpdateHeader(), and WriteEntry().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Init()

bool XrdSutPFile::Init ( const char * n,
kXR_int32 openmode = kPFEcreate,
kXR_int32 createmode = 0600,
bool hashtab = 1 )

Definition at line 236 of file XrdSutPFile.cc.

238{
239 // (re)initialize PFile
240
241 // Make sure it is closed
242 Close();
243
244 // Reset members
245 if (name)
246 delete[] name;
247 name = 0;
248 if (n) {
249 name = new char[strlen(n)+1];
250 if (name)
251 strcpy(name,n);
252 }
253 valid = 0;
254 fFd = -1;
255 fHTutime = -1;
256 if (fHashTable)
257 delete fHashTable;
258 fHashTable = 0;
259
260 // If name is missing nothing can be done
261 if (!name)
262 return 0;
263
264 // open modes
265 bool create = (openmode & kPFEcreate);
266 bool leaveopen = (openmode & kPFEopen);
267
268 // If file does not exists, create it with default header
269 struct stat st;
270 if (stat(name, &st) == -1) {
271 if (errno == ENOENT) {
272 if (create) {
273 if (Open(1,0,0,createmode) > 0) {
274 kXR_int32 ct = (kXR_int32)time(0);
276 WriteHeader(hdr);
277 valid = 1;
278 if (!leaveopen)
279 Close();
280 }
281 } else {
282 Err(kPFErrNoFile,"Init",name);
283 }
284 }
285 } else {
286 // Fill the the hash table
287 if (Open(1) > 0) {
288 if (hashtab)
289 UpdateHashTable();
290 valid = 1;
291 if (!leaveopen)
292 Close();
293 }
294 }
295 // We are done
296 return valid;
297}
#define stat(a, b)
Definition XrdPosix.hh:96
#define kPFEopen
@ kPFErrNoFile
#define kDefFileID
#define kPFEcreate
#define kXrdIFVersion

References Close(), Err, kDefFileID, kPFEcreate, kPFEopen, kPFErrNoFile, kXrdIFVersion, Open(), and stat.

Referenced by XrdSutPFile(), XrdSecProtocolpwd::Init(), and main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsValid()

bool XrdSutPFile::IsValid ( ) const
inline

Definition at line 170 of file XrdSutPFile.hh.

170{ return valid; }

Referenced by XrdSutPFCache::Flush(), XrdSecProtocolpwd::Init(), XrdSutPFCache::Load(), and main().

+ Here is the caller graph for this function:

◆ LastError()

kXR_int32 XrdSutPFile::LastError ( ) const
inline

Definition at line 172 of file XrdSutPFile.hh.

172{ return fError; }

Referenced by main().

+ Here is the caller graph for this function:

◆ LastErrStr()

const char * XrdSutPFile::LastErrStr ( ) const
inline

Definition at line 173 of file XrdSutPFile.hh.

173{ return (const char *)fErrStr.c_str(); }
const char * c_str() const

References XrdOucString::c_str().

Referenced by XrdSutPFCache::Flush(), and XrdSutPFCache::Load().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Name()

const char * XrdSutPFile::Name ( ) const
inline

Definition at line 168 of file XrdSutPFile.hh.

168{ return (const char *)name; }

Referenced by XrdSecProtocolpwd::XrdSecProtocolpwd(), GetEntry(), main(), and RemoveEntries().

+ Here is the caller graph for this function:

◆ Open()

kXR_int32 XrdSutPFile::Open ( kXR_int32 opt,
bool * wasopen = 0,
const char * nam = 0,
kXR_int32 createmode = 0600 )

Definition at line 300 of file XrdSutPFile.cc.

302{
303 // Open the stream, so defining fFd .
304 // Valid options:
305 // 0 read only
306 // 1 read/write append
307 // 2 read/write truncate
308 // For options 1 and 2 the file is created, if not existing,
309 // and permission set to createmode (default: 0600).
310 // If the file name ends with 'XXXXXX' and it does not exist,
311 // it is created as temporary using mkstemp.
312 // The file is also exclusively locked.
313 // If nam is defined it is used as file name
314 // If the file is already open and wasopen is allocated, then *wasopen
315 // is set to true
316 // The file descriptor of the open file is returned
317 XrdOucString copt(opt);
318
319 // Reset was open flag
320 if (wasopen) *wasopen = 0;
321
322 // File name must be defined
323 char *fnam = (char *)nam;
324 if (!fnam)
325 fnam = name;
326 if (!fnam)
327 return Err(kPFErrBadInputs,"Open");
328
329 // If already open, do nothing
330 if (!nam && fFd > -1) {
331 if (opt > 0) {
332 // Make sure that the write flag is set
333 long omode = 0;
334 if (fcntl(fFd, F_GETFL, &omode) != -1) {
335 if (!(omode | O_WRONLY))
336 return Err(kPFErrFileAlreadyOpen,"Open");
337 }
338 }
339 if (wasopen) *wasopen = 1;
340 return fFd;
341 }
342
343 // Ok, we have a file name ... check if it exists already
344 bool newfile = 0;
345 struct stat st;
346 if (stat(fnam, &st) == -1) {
347 if (errno != ENOENT) {
348 return Err(kPFErrNoFile,"Open",fnam);
349 } else {
350 if (opt == 0)
351 return Err(kPFErrStat,"Open",fnam);
352 newfile = 1;
353 }
354 }
355
356 // Now open it
357 if (!nam)
358 fFd = -1;
359 kXR_int32 fd = -1;
360 //
361 // If we have to create a new file and the file name ends with
362 // 'XXXXXX', make it temporary with mkstemp
363 char *pn = strstr(fnam,"XXXXXX");
364 if (pn && (pn == (fnam + strlen(fnam) - 6))) {
365 if (opt > 0 && newfile) {
366 fd = mkstemp(fnam);
367 if (fd <= -1)
368 return Err(kPFErrFileOpen,"Open",fnam);
369 }
370 }
371 //
372 // If normal file act according to requests
373 if (fd <= -1) {
374 kXR_int32 mode = 0;
375 switch (opt) {
376 case 2:
377 //
378 // Forcing truncation in Read / Write mode
379 mode |= (O_TRUNC | O_RDWR) ;
380 if (newfile)
381 mode |= O_CREAT ;
382 break;
383 case 1:
384 //
385 // Read / Write
386 mode |= O_RDWR ;
387 if (newfile)
388 mode |= O_CREAT ;
389 break;
390 case 0:
391 //
392 // Read only
393 mode = O_RDONLY ;
394 break;
395 default:
396 //
397 // Unknown option
398 return Err(kPFErrBadOp,"Open",copt.c_str());
399 }
400
401 // Open file (createmode is only used if O_CREAT is set)
402 fd = open(fnam, mode, createmode);
403 if (fd <= -1)
404 return Err(kPFErrFileOpen,"Open",fnam);
405 }
406
407 //
408 // Shared or exclusive lock of the whole file
409 int lockmode = (opt > 0) ? (F_WRLCK | F_RDLCK) : F_RDLCK;
410 int lck = kMaxLockTries;
411 int rc = 0;
412 while (lck && rc == -1) {
413 struct flock flck;
414 memset(&flck, 0, sizeof(flck));
415 flck.l_type = lockmode;
416 flck.l_whence = SEEK_SET;
417 if ((rc = fcntl(fd, F_SETLK, &flck)) == 0)
418 break;
419 struct timespec lftp, rqtp = {1, 0};
420 while (nanosleep(&rqtp, &lftp) < 0 && errno == EINTR) {
421 rqtp.tv_sec = lftp.tv_sec;
422 rqtp.tv_nsec = lftp.tv_nsec;
423 }
424 }
425 if (rc == -1) {
426 if (errno == EACCES || errno == EAGAIN) {
427 // File locked by other process
428 int pid = -1;
429 struct flock flck;
430 memset(&flck, 0, sizeof(flck));
431 flck.l_type = lockmode;
432 flck.l_whence = SEEK_SET;
433 if (fcntl(fd,F_GETLK,&flck) != -1)
434 pid = flck.l_pid;
435 close(fd);
436 return Err(kPFErrFileLocked,"Open",fnam,(const char *)&pid);
437 } else {
438 // Error
439 return Err(kPFErrLocking,"Open",fnam,(const char *)&fd);
440 }
441 }
442
443 // Ok, we got the file open and locked
444 if (!nam)
445 fFd = fd;
446 return fd;
447}
#define open
Definition XrdPosix.hh:71
@ kPFErrFileLocked
@ kPFErrBadInputs
@ kPFErrStat
@ kPFErrBadOp
@ kPFErrFileOpen
@ kPFErrLocking
@ kPFErrFileAlreadyOpen
#define kMaxLockTries

References XrdOucString::c_str(), close, Err, fcntl(), kMaxLockTries, kPFErrBadInputs, kPFErrBadOp, kPFErrFileAlreadyOpen, kPFErrFileLocked, kPFErrFileOpen, kPFErrLocking, kPFErrNoFile, kPFErrStat, open, and stat.

Referenced by Browse(), Init(), ReadEntry(), ReadEntry(), RemoveEntry(), RemoveEntry(), RetrieveHeader(), SearchEntries(), SearchSpecialEntries(), Trim(), UpdateCount(), UpdateHeader(), and WriteEntry().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadCount()

kXR_int32 XrdSutPFile::ReadCount ( const char * nm,
int & cnt )
inline

Definition at line 184 of file XrdSutPFile.hh.

184{ return UpdateCount(nm,&cnt,0); }
kXR_int32 UpdateCount(const char *nm, int *cnt=0, int step=1, bool reset=0)

References UpdateCount().

+ Here is the call graph for this function:

◆ ReadEntry() [1/2]

kXR_int32 XrdSutPFile::ReadEntry ( const char * name,
XrdSutPFEntry & ent,
int opt = 0 )

Definition at line 909 of file XrdSutPFile.cc.

911{
912 // Read entry with tag from file
913 // If it does not exist, if opt == 1 search also for wild-card
914 // matching entries; if more than 1 return the one that matches
915 // the best, base on the number of characters matching.
916 // If more wild-card entries have the same level of matching,
917 // the first found is returned.
918 ent.Reset();
919
920 // Make sure that we got a tag (otherwise we can't do nothing)
921 if (!tag)
922 return Err(kPFErrBadInputs,"ReadEntry");
923
924 // Make sure we got an open stream
925 bool wasopen = 0;
926 if (Open(1 &wasopen) < 0)
927 return -1;
928
929 // Read the header
930 XrdSutPFHeader header;
931 if (ReadHeader(header) < 0) {
932 if (!wasopen) Close();
933 return -1;
934 }
935
936 // Check if the HashTable needs to be updated
937 if (fHashTable && header.itime > fHTutime) {
938 // Update the table
939 if (UpdateHashTable() < 0) {
940 if (!wasopen) Close();
941 return -1;
942 }
943 }
944 //
945 // Get index entry associated with tag, if any
946 XrdSutPFEntInd ind;
947 bool found = 0;
948 if (fHashTable) {
949 kXR_int32 *reftmp = fHashTable->Find(tag);
950 kXR_int32 refofs = reftmp ? *reftmp : -1;
951 if (refofs > 0) {
952 // Read it out
953 if (ReadInd(refofs, ind) < 0) {
954 if (!wasopen) Close();
955 return -1;
956 }
957 found = 1;
958 }
959 } else {
960 // Get offset of the first index entry
961 kXR_int32 indofs = header.indofs;
962 while (indofs > 0) {
963 // Read it out
964 if (ReadInd(indofs, ind) < 0) {
965 if (!wasopen) Close();
966 return -1;
967 }
968 // Check compatibility
969 if (strlen(ind.name) == strlen(tag)) {
970 if (!strncmp(ind.name,tag,strlen(tag))) {
971 found = 1;
972 break;
973 }
974 }
975 // Next index entry
976 indofs = ind.nxtofs;
977 }
978 }
979 //
980 // If not found and requested, try also wild-cards
981 if (!found && opt == 1) {
982 //
983 // If > 1 we will keep the best matching, i.e. the one
984 // matching most of the chars in tag
985 kXR_int32 refofs = -1;
986 kXR_int32 nmmax = 0;
987 kXR_int32 iofs = header.indofs;
988 XrdOucString stag(tag);
989 while (iofs) {
990 //
991 // Read it out
992 if (ReadInd(iofs, ind) < 0) {
993 if (!wasopen) Close();
994 return -1;
995 }
996 //
997 // Check compatibility, if active
998 if (ind.entofs > 0) {
999 int match = stag.matches(ind.name);
1000 if (match > nmmax && ind.entofs > 0) {
1001 nmmax = match;
1002 refofs = iofs;
1003 }
1004 }
1005 //
1006 // Next index entry
1007 iofs = ind.nxtofs;
1008 }
1009 //
1010 // Read it out
1011 if (refofs > 0) {
1012 if (ReadInd(refofs, ind) < 0) {
1013 if (!wasopen) Close();
1014 return -1;
1015 }
1016 found = 1;
1017 }
1018 }
1019
1020 // Read the entry, if found
1021 kXR_int32 nr = 0;
1022 if (found) {
1023
1024 // Read entry if active
1025 if (ind.entofs) {
1026 if ((nr = ReadEnt(ind.entofs, ent)) < 0) {
1027 if (!wasopen) Close();
1028 return -1;
1029 }
1030 // Fill the name
1031 ent.SetName(ind.name);
1032 }
1033 }
1034
1035 // Close the file
1036 if (!wasopen) Close();
1037
1038 return nr;
1039}
T * Find(const char *KeyVal, time_t *KeyTime=0)
void SetName(const char *n=0)

References Close(), XrdSutPFEntInd::entofs, Err, XrdOucHash< T >::Find(), XrdSutPFHeader::indofs, XrdSutPFHeader::itime, kPFErrBadInputs, XrdOucString::matches(), XrdSutPFEntInd::name, XrdSutPFEntInd::nxtofs, Open(), XrdSutPFEntry::Reset(), and XrdSutPFEntry::SetName().

Referenced by XrdSutPFCache::Flush(), GetEntry(), XrdSecProtocolpwd::Init(), and main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadEntry() [2/2]

kXR_int32 XrdSutPFile::ReadEntry ( kXR_int32 ofs,
XrdSutPFEntry & ent )

Definition at line 1042 of file XrdSutPFile.cc.

1043{
1044 // Read entry at ofs from file
1045
1046 // Make sure that ofs makes sense
1047 if (ofs <= 0)
1048 return Err(kPFErrBadInputs,"ReadEntry");
1049
1050 // Make sure we got an open stream
1051 bool wasopen = 0;
1052 if (Open(1, &wasopen) < 0)
1053 return -1;
1054
1055 kXR_int32 nr = 0;
1056
1057 // Read index entry out
1058 XrdSutPFEntInd ind;
1059 if (ReadInd(ofs, ind) < 0) {
1060 if (!wasopen) Close();
1061 return -1;
1062 }
1063
1064 // Read entry
1065 if ((nr = ReadEnt(ind.entofs, ent)) < 0) {
1066 if (!wasopen) Close();
1067 return -1;
1068 }
1069
1070 // Fill the name
1071 ent.SetName(ind.name);
1072
1073 // Close the file
1074 if (!wasopen) Close();
1075
1076 return nr;
1077}

References Close(), XrdSutPFEntInd::entofs, Err, kPFErrBadInputs, XrdSutPFEntInd::name, Open(), and XrdSutPFEntry::SetName().

+ Here is the call graph for this function:

◆ RemoveEntries()

kXR_int32 XrdSutPFile::RemoveEntries ( const char * name,
char opt )

Definition at line 2014 of file XrdSutPFile.cc.

2015{
2016 // Remove entries whose tag is compatible with 'tag', according
2017 // to compatibility option 'opt'.
2018 // For opt = 0 tags starting with 'tag'
2019 // for opt = 1 tags containing the wild card '*' are matched.
2020 // Return number of entries removed
2021 EPNAME("PFile::RemoveEntries");
2022
2023 //
2024 // Get number of entries related
2025 int nm = SearchEntries(tag,opt);
2026 if (nm) {
2027 DEBUG("found "<<nm<<" entries for tag '"<<tag<<"'");
2028 //
2029 // Book vector for offsets
2030 int *ofs = new int[nm];
2031 //
2032 // Get number of entries related
2033 SearchEntries(tag,0,ofs,nm);
2034 //
2035 // Read entries now
2036 int i = 0;
2037 for (; i < nm ; i++) {
2038 if (RemoveEntry(ofs[i]) == 0) {
2039 DEBUG("entry for tag '"<<tag<<"' removed from file");
2040 } else {
2041 DEBUG("entry for tag '"<<tag<<"' not found in file");
2042 }
2043 }
2044 } else {
2045 DEBUG("no entry for tag '"<<tag<<"' found in file: "<<Name());
2046 }
2047 // We are done
2048 return nm;
2049}
#define DEBUG(x)
#define EPNAME(x)
kXR_int32 SearchEntries(const char *name, char opt, kXR_int32 *ofs=0, kXR_int32 nofs=1)
const char * Name() const
kXR_int32 RemoveEntry(const char *name)

References DEBUG, EPNAME, Name(), RemoveEntry(), and SearchEntries().

+ Here is the call graph for this function:

◆ RemoveEntry() [1/2]

kXR_int32 XrdSutPFile::RemoveEntry ( const char * name)

Definition at line 1080 of file XrdSutPFile.cc.

1081{
1082 // Remove entry with tag from file
1083 // The entry is set inactive, so that it is hidden and it will
1084 // be physically removed at next Trim
1085
1086 // Make sure that we got a tag (otherwise we can't do nothing)
1087 if (!tag || !strlen(tag))
1088 return Err(kPFErrBadInputs,"RemoveEntry");
1089
1090 // Make sure we got an open stream
1091 if (Open(1) < 0)
1092 return -1;
1093
1094 // Read the header
1095 XrdSutPFHeader header;
1096 if (ReadHeader(header) < 0) {
1097 Close();
1098 return -1;
1099 }
1100
1101 // Check if the HashTable needs to be updated
1102 if (fHashTable && header.itime > fHTutime) {
1103 // Update the table
1104 if (UpdateHashTable() < 0) {
1105 Close();
1106 return -1;
1107 }
1108 }
1109
1110 // Get offset of the index entry associated with tag, if any
1111 XrdSutPFEntInd ind;
1112 bool found = 0;
1113 kXR_int32 indofs = -1;
1114 if (fHashTable) {
1115 kXR_int32 *indtmp = fHashTable->Find(tag);
1116 indofs = indtmp ? *indtmp : indofs;
1117 if (indofs > 0) {
1118 // Read it out
1119 if (ReadInd(indofs, ind) < 0) {
1120 Close();
1121 return -1;
1122 }
1123 found = 1;
1124 }
1125 } else {
1126 // Get offset of the first index entry
1127 indofs = header.indofs;
1128 while (indofs > 0) {
1129 // Read it out
1130 if (ReadInd(indofs, ind) < 0) {
1131 Close();
1132 return -1;
1133 }
1134 // Check compatibility
1135 if (strlen(ind.name) == strlen(tag)) {
1136 if (!strncmp(ind.name,tag,strlen(tag))) {
1137 found = 1;
1138 break;
1139 }
1140 }
1141 // Next index entry
1142 indofs = ind.nxtofs;
1143 }
1144 }
1145 //
1146 // Get entry now, if index found
1147 if (found) {
1148 // Reset entry area
1149 short status = kPFE_inactive;
1150 if (lseek(fFd, ind.entofs, SEEK_SET) == -1) {
1151 Close();
1152 return Err(kPFErrSeek,"RemoveEntry",
1153 "SEEK_SET",(const char *)&fFd);
1154 }
1155 while (write(fFd, &status, sizeof(short)) < 0 &&
1156 errno == EINTR) errno = 0;
1157 // Reset entry area
1158 if (Reset(ind.entofs + sizeof(short), ind.entsiz - sizeof(short)) < 0) {
1159 Close();
1160 return -1;
1161 }
1162 // Set entofs to null
1163 ind.entofs = 0;
1164 if (WriteInd(indofs, ind) < 0) {
1165 Close();
1166 return -1;
1167 }
1168 // Count as unused bytes
1169 header.jnksiz += ind.entsiz;
1170 // Decrease number of entries
1171 header.entries--;
1172 // Update times
1173 header.ctime = (kXR_int32)time(0);
1174 header.itime = header.ctime;
1175 // Update header
1176 if (WriteHeader(header) < 0) {
1177 Close();
1178 return -1;
1179 }
1180
1181 // Ok: close the file and return
1182 Close();
1183 return 0;
1184 }
1185
1186 // Close the file
1187 Close();
1188 // entry non-existing
1189 return -1;
1190}
#define lseek(a, b, c)
Definition XrdPosix.hh:47
#define write(a, b, c)
Definition XrdPosix.hh:110
@ kPFE_inactive
@ kPFErrSeek
kXR_int32 entsiz

References Close(), XrdSutPFHeader::ctime, XrdSutPFEntInd::entofs, XrdSutPFHeader::entries, XrdSutPFEntInd::entsiz, Err, XrdOucHash< T >::Find(), XrdSutPFHeader::indofs, XrdSutPFHeader::itime, XrdSutPFHeader::jnksiz, kPFE_inactive, kPFErrBadInputs, kPFErrSeek, lseek, XrdSutPFEntInd::name, XrdSutPFEntInd::nxtofs, Open(), and write.

Referenced by main(), and RemoveEntries().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RemoveEntry() [2/2]

kXR_int32 XrdSutPFile::RemoveEntry ( kXR_int32 ofs)

Definition at line 1193 of file XrdSutPFile.cc.

1194{
1195 // Remove entry at entry index offset ofs from file
1196 // The entry is set inactive, so that it is hidden and it will
1197 // be physically removed at next Trim
1198
1199 // Make sure that we got a tag (otherwise we can't do nothing)
1200 if (ofs <= 0)
1201 return Err(kPFErrBadInputs,"RemoveEntry");
1202
1203 // Make sure we got an open stream
1204 if (Open(1) < 0)
1205 return -1;
1206
1207 // Read the header
1208 XrdSutPFHeader header;
1209 if (ReadHeader(header) < 0) {
1210 Close();
1211 return -1;
1212 }
1213
1214 // Check if the HashTable needs to be updated
1215 if (header.itime > fHTutime) {
1216 // Update the table
1217 if (UpdateHashTable() < 0) {
1218 Close();
1219 return -1;
1220 }
1221 }
1222 //
1223 // Read it out
1224 XrdSutPFEntInd ind;
1225 if (ReadInd(ofs, ind) < 0) {
1226 Close();
1227 return -1;
1228 }
1229 //
1230 // Reset entry area
1231 short status = kPFE_inactive;
1232 if (lseek(fFd, ind.entofs, SEEK_SET) == -1) {
1233 Close();
1234 return Err(kPFErrSeek,"RemoveEntry",
1235 "SEEK_SET",(const char *)&fFd);
1236 }
1237 while (write(fFd, &status, sizeof(short)) < 0 &&
1238 errno == EINTR) errno = 0;
1239 // Reset entry area
1240 if (Reset(ind.entofs + sizeof(short), ind.entsiz - sizeof(short)) < 0) {
1241 Close();
1242 return -1;
1243 }
1244 // Set entofs to null
1245 ind.entofs = 0;
1246 if (WriteInd(ofs, ind) < 0) {
1247 Close();
1248 return -1;
1249 }
1250 // Count as unused bytes
1251 header.jnksiz += ind.entsiz;
1252 // Decrease number of entries
1253 header.entries--;
1254 // Update times
1255 header.ctime = (kXR_int32)time(0);
1256 header.itime = header.ctime;
1257 // Update header
1258 if (WriteHeader(header) < 0) {
1259 Close();
1260 return -1;
1261 }
1262 //
1263 // Ok: close the file and return
1264 Close();
1265 return 0;
1266}

References Close(), XrdSutPFHeader::ctime, XrdSutPFEntInd::entofs, XrdSutPFHeader::entries, XrdSutPFEntInd::entsiz, Err, XrdSutPFHeader::itime, XrdSutPFHeader::jnksiz, kPFE_inactive, kPFErrBadInputs, kPFErrSeek, lseek, Open(), and write.

+ Here is the call graph for this function:

◆ ResetCount()

kXR_int32 XrdSutPFile::ResetCount ( const char * nm)
inline

Definition at line 183 of file XrdSutPFile.hh.

183{ return UpdateCount(nm,0,0,1); }

References UpdateCount().

+ Here is the call graph for this function:

◆ RetrieveHeader()

kXR_int32 XrdSutPFile::RetrieveHeader ( XrdSutPFHeader & hd)

Definition at line 503 of file XrdSutPFile.cc.

504{
505 // Retrieve number of entries in the file
506
507 //
508 // Open the file
509 bool wasopen = 0;
510 if (Open(1, &wasopen) < 0)
511 return -1;
512
513 // Read header
514 kXR_int32 rc = ReadHeader(hd);
515
516 // Close the file
517 if (!wasopen) Close();
518
519 return rc;
520}

References Close(), and Open().

Referenced by Trim().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SearchEntries()

kXR_int32 XrdSutPFile::SearchEntries ( const char * name,
char opt,
kXR_int32 * ofs = 0,
kXR_int32 nofs = 1 )

Definition at line 2052 of file XrdSutPFile.cc.

2054{
2055 // Get offsets of the first nofs entries whose tag is compatible
2056 // with 'tag', according to compatibility option 'opt'.
2057 // For opt = 0 tags starting with 'tag' are searched for;
2058 // For opt = 1 tags containing the wild card '*' matching tag
2059 // are searched for.
2060 // For opt = 2 tags matching tag are searched for; tag may contain
2061 // the wild card '*'.
2062 // The caller is responsible for memory pointed by 'ofs'.
2063 // Return number of entries found (<= nofs).
2064 // If ofs = 0, return total number of entries matching the
2065 // condition.
2066
2067 // Make sure that we got a tag
2068 if (!tag)
2069 return Err(kPFErrBadInputs,"SearchEntries");
2070
2071 // Make sure we got an open stream
2072 bool wasopen = 0;
2073 if (Open(1,&wasopen) < 0)
2074 return -1;
2075
2076 // Read the header
2077 XrdSutPFHeader header;
2078 if (ReadHeader(header) < 0) {
2079 if (!wasopen) Close();
2080 return -1;
2081 }
2082
2083 // Get offset of the first index entry
2084 kXR_int32 indofs = header.indofs;
2085
2086 // Scan entries
2087 kXR_int32 no = 0;
2088 XrdOucString smatch;
2089 if (opt == 1)
2090 smatch.assign(tag, 0);
2091 while (indofs) {
2092
2093 // Read it out
2094 XrdSutPFEntInd ind;
2095 if (ReadInd(indofs, ind) < 0) {
2096 if (!wasopen) Close();
2097 return -1;
2098 }
2099
2100 // Check compatibility
2101 int match = 0;
2102 if (opt == 0) {
2103 if (!strncmp(ind.name,tag,strlen(tag)))
2104 match = 1;
2105 } else if (opt == 1) {
2106 match = smatch.matches(ind.name);
2107 } else if (opt == 2) {
2108 smatch.assign(ind.name, 0);
2109 match = smatch.matches(tag);
2110 }
2111
2112 if (match > 0 && ind.entofs > 0) {
2113 no++;
2114 if (ofs) {
2115 ofs[no-1] = indofs;
2116 if (no == nofs) {
2117 // We are done
2118 break;
2119 }
2120 }
2121 }
2122
2123 // Next index entry
2124 indofs = ind.nxtofs;
2125 }
2126
2127 // Close the file
2128 if (!wasopen) Close();
2129
2130 return no;
2131}
void assign(const char *s, int j, int k=-1)
int matches(const char *s, char wch=' *')

References XrdOucString::assign(), Close(), XrdSutPFEntInd::entofs, Err, XrdSutPFHeader::indofs, kPFErrBadInputs, XrdOucString::matches(), XrdSutPFEntInd::name, XrdSutPFEntInd::nxtofs, and Open().

Referenced by main(), and RemoveEntries().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SearchSpecialEntries()

kXR_int32 XrdSutPFile::SearchSpecialEntries ( kXR_int32 * ofs = 0,
kXR_int32 nofs = 1 )

Definition at line 2134 of file XrdSutPFile.cc.

2136{
2137 // Get offsets of the first nofs entries with status
2138 // kPFE_special.
2139 // The caller is responsible for memory pointed by 'ofs'.
2140 // Return number of entries found (<= nofs).
2141 // If ofs = 0, return total number of special entries.
2142
2143 // Make sure we got an open stream
2144 bool wasopen = 0;
2145 if (Open(1,&wasopen) < 0)
2146 return -1;
2147
2148 // Read the header
2149 XrdSutPFHeader header;
2150 if (ReadHeader(header) < 0) {
2151 if (!wasopen) Close();
2152 return -1;
2153 }
2154
2155 // Get offset of the first index entry
2156 kXR_int32 indofs = header.indofs;
2157
2158 // Scan entries
2159 kXR_int32 no = 0;
2160 while (indofs) {
2161
2162 // Read index
2163 XrdSutPFEntInd ind;
2164 if (ReadInd(indofs, ind) < 0) {
2165 if (!wasopen) Close();
2166 return -1;
2167 }
2168
2169 // If active ...
2170 if (ind.entofs > 0) {
2171
2172 // Read entry out
2173 XrdSutPFEntry ent;
2174 if (ReadEnt(ind.entofs, ent) < 0) {
2175 if (!wasopen) Close();
2176 return -1;
2177 }
2178 // If special ...
2179 if (ent.status == kPFE_special) {
2180 // Record the offset ...
2181 no++;
2182 if (ofs) {
2183 ofs[no-1] = indofs;
2184 if (no == nofs) {
2185 // We are done
2186 break;
2187 }
2188 }
2189 }
2190 }
2191
2192 // Next index entry
2193 indofs = ind.nxtofs;
2194 }
2195
2196 // Close the file
2197 if (!wasopen) Close();
2198
2199 return no;
2200}

References Close(), XrdSutPFEntInd::entofs, XrdSutPFHeader::indofs, kPFE_special, XrdSutPFEntInd::nxtofs, Open(), and XrdSutPFEntry::status.

Referenced by Browse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Trim()

kXR_int32 XrdSutPFile::Trim ( const char * fbak = 0)

Definition at line 1795 of file XrdSutPFile.cc.

1796{
1797 // Trim away unreachable entries from the file
1798 // Previous content is save in a file name fbak, the default
1799 // being 'name'.bak
1800 EPNAME("PFile::Trim");
1801
1802 // Retrieve header, first, to check if there is anything to trim
1803 XrdSutPFHeader header;
1804 if (RetrieveHeader(header) < 0)
1805 return -1;
1806 if (header.jnksiz <= 0) {
1807 DEBUG("nothing to trim - return ");
1808 return -1;
1809 }
1810
1811 // Get name of backup file
1812 char *nbak = (char *)fbak;
1813 if (!nbak) {
1814 // Use default
1815 nbak = new char[strlen(name)+5];
1816 if (!nbak)
1817 return Err(kPFErrOutOfMemory,"Trim");
1818 sprintf(nbak,"%s.bak",name);
1819 DEBUG("backup file: "<<nbak);
1820 }
1821
1822 // Move file
1823 if (rename(name,nbak) == -1)
1824 return Err(kPFErrFileRename,"Trim",name,nbak);
1825
1826 // Create new file
1827 int fdnew = Open(1);
1828 if (fdnew < 0)
1829 return -1;
1830
1831 // Open backup file
1832 int fdbck = Open(1,0,nbak);
1833 if (fdbck < 0) {
1834 Close();
1835 return -1;
1836 }
1837
1838 // Read the header from backup file
1839 fFd = fdbck;
1840 if (ReadHeader(header) < 0) {
1841 Close(fdnew); Close(fdbck);
1842 return -1;
1843 }
1844
1845 // Copy it to new file
1846 fFd = fdnew;
1847 if (WriteHeader(header) < 0) {
1848 Close(fdnew); Close(fdbck);
1849 return -1;
1850 }
1851 kXR_int32 wrofs = lseek(fdnew, 0, SEEK_CUR);
1852 if (wrofs == -1) {
1853 Close(fdnew); Close(fdbck);
1854 return Err(kPFErrSeek,"Trim",
1855 "SEEK_CUR",(const char *)&fdnew);
1856 }
1857
1858 // Read active entries now and save them to new file
1859 bool firstind = 1;
1860 XrdSutPFEntInd ind, indlast;
1861 XrdSutPFEntry ent;
1862
1863 kXR_int32 nxtofs = header.indofs;
1864 kXR_int32 lastofs = nxtofs;
1865
1866 while (nxtofs) {
1867
1868 // Read index entry
1869 fFd = fdbck;
1870 if (ReadInd(nxtofs,ind) < 0) {
1871 Close(fdnew); Close(fdbck);
1872 return -1;
1873 }
1874
1875 // Get Next index entry before updating index entry
1876 nxtofs = ind.nxtofs;
1877
1878 // Read entry, if active
1879 if (ind.entofs > 0) {
1880 fFd = fdbck;
1881 if (ReadEnt(ind.entofs,ent) < 0) {
1882 Close(fdnew); Close(fdbck);
1883 return -1;
1884 }
1885 // Update index entry
1886 ind.entofs = wrofs;
1887
1888 // Write active entry
1889 fFd = fdnew;
1890 if (WriteEnt(wrofs,ent) < 0) {
1891 Close(fdnew); Close(fdbck);
1892 return -1;
1893 }
1894
1895 // Update write offset
1896 if ((wrofs = lseek(fdnew, 0, SEEK_CUR)) == -1) {
1897 Close(fdnew); Close(fdbck);
1898 return Err(kPFErrSeek,"Trim",
1899 "SEEK_CUR",(const char *)&fdnew);
1900 }
1901
1902 if (firstind) {
1903 // Update header
1904 header.indofs = wrofs;
1905 firstind = 0;
1906 } else {
1907 // Update previous index entry
1908 indlast.nxtofs = wrofs;
1909 fFd = fdnew;
1910 if (WriteInd(lastofs,indlast) < 0) {
1911 Close(fdnew); Close(fdbck);
1912 return -1;
1913 }
1914 }
1915
1916 // Save this index for later updates
1917 indlast = ind;
1918 lastofs = wrofs;
1919
1920 // Last index entry, for now
1921 ind.nxtofs = 0;
1922
1923 // Write active index entry
1924 fFd = fdnew;
1925 if (WriteInd(wrofs,ind) < 0) {
1926 Close(fdnew); Close(fdbck);
1927 return -1;
1928 }
1929
1930 // Update write offset
1931 if ((wrofs = lseek(fdnew, 0, SEEK_CUR)) == -1) {
1932 Close(fdnew); Close(fdbck);
1933 return Err(kPFErrSeek,"Trim",
1934 "SEEK_CUR",(const char *)&fdnew);
1935 }
1936 }
1937 }
1938
1939 // Close backup file
1940 Close(fdbck);
1941 fFd = fdnew;
1942
1943 // Update header
1944 header.ctime = (kXR_int32)time(0);
1945 header.itime = header.ctime;
1946 header.jnksiz = 0;
1947
1948 // Copy it to new file
1949 if (WriteHeader(header) < 0) {
1950 Close();;
1951 return -1;
1952 }
1953
1954 // Close the file
1955 Close();
1956
1957 return 0;
1958}
#define rename(a, b)
Definition XrdPosix.hh:87
@ kPFErrOutOfMemory
@ kPFErrFileRename
kXR_int32 RetrieveHeader(XrdSutPFHeader &hd)

References Close(), XrdSutPFHeader::ctime, DEBUG, XrdSutPFEntInd::entofs, EPNAME, Err, XrdSutPFHeader::indofs, XrdSutPFHeader::itime, XrdSutPFHeader::jnksiz, kPFErrFileRename, kPFErrOutOfMemory, kPFErrSeek, lseek, XrdSutPFEntInd::nxtofs, Open(), rename, and RetrieveHeader().

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ UpdateCount()

kXR_int32 XrdSutPFile::UpdateCount ( const char * nm,
int * cnt = 0,
int step = 1,
bool reset = 0 )

Definition at line 795 of file XrdSutPFile.cc.

797{
798 // Update counter for entry with 'tag', if any.
799 // If reset is true, counter is firts reset.
800 // The counter is updated by 'step'.
801 // Default: no reset, increase by 1.
802 // If cnt is defined, fill it with the updated counter.
803 // Returns 0 or -1 in case of error
804
805 // Make sure that we got a tag (otherwise we can't do nothing)
806 if (!tag)
807 return Err(kPFErrBadInputs,"UpdateCount");
808
809 // Make sure we got an open stream
810 if (Open(1) < 0)
811 return -1;
812
813 // Read the header
814 XrdSutPFHeader header;
815 if (ReadHeader(header) < 0) {
816 Close();
817 return -1;
818 }
819
820 // Check if the HashTable needs to be updated
821 if (fHashTable && header.itime > fHTutime) {
822 // Update the table
823 if (UpdateHashTable() < 0) {
824 Close();
825 return -1;
826 }
827 }
828 //
829 // Get index entry associated with tag, if any
830 XrdSutPFEntInd ind;
831 bool found = 0;
832 if (fHashTable) {
833 kXR_int32 *refofs = fHashTable->Find(tag);
834 if (*refofs > 0) {
835 // Read it out
836 if (ReadInd(*refofs, ind) < 0) {
837 Close();
838 return -1;
839 }
840 found = 1;
841 }
842 } else {
843 // Get offset of the first index entry
844 kXR_int32 indofs = header.indofs;
845 while (indofs > 0) {
846 // Read it out
847 if (ReadInd(indofs, ind) < 0) {
848 Close();
849 return -1;
850 }
851 // Check compatibility
852 if (strlen(ind.name) == strlen(tag)) {
853 if (!strncmp(ind.name,tag,strlen(tag))) {
854 found = 1;
855 break;
856 }
857 }
858 // Next index entry
859 indofs = ind.nxtofs;
860 }
861 }
862 //
863 // Read the entry, if found
864 XrdSutPFEntry ent;
865 bool changed = 0;
866 if (found) {
867
868 // Read entry if active
869 if (ind.entofs) {
870 if (ReadEnt(ind.entofs, ent) < 0) {
871 Close();
872 return -1;
873 }
874 //
875 // Reset counter if required
876 if (reset && ent.cnt != 0) {
877 changed = 1;
878 ent.cnt = 0;
879 }
880 //
881 // Update counter
882 if (step != 0) {
883 changed = 1;
884 ent.cnt += step;
885 }
886 //
887 // Update entry in file, if anything changed
888 if (changed) {
889 ent.mtime = (kXR_int32)time(0);
890 if (WriteEnt(ind.entofs, ent) < 0) {
891 Close();
892 return -1;
893 }
894 }
895 //
896 // Fill output
897 if (cnt)
898 *cnt = ent.cnt;
899 }
900 }
901
902 // Close the file
903 Close();
904
905 return 0;
906}

References Close(), XrdSutPFEntry::cnt, XrdSutPFEntInd::entofs, Err, XrdOucHash< T >::Find(), XrdSutPFHeader::indofs, XrdSutPFHeader::itime, kPFErrBadInputs, XrdSutPFEntry::mtime, XrdSutPFEntInd::name, XrdSutPFEntInd::nxtofs, and Open().

Referenced by ReadCount(), and ResetCount().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ UpdateHeader()

kXR_int32 XrdSutPFile::UpdateHeader ( XrdSutPFHeader hd)

Definition at line 484 of file XrdSutPFile.cc.

485{
486 // Write/Update header to beginning of file
487
488 //
489 // Open the file
490 if (Open(1) < 0)
491 return -1;
492
493 // Write
494 kXR_int32 nw = WriteHeader(hd);
495
496 // Close the file
497 Close();
498
499 return nw;
500}

References Close(), and Open().

+ Here is the call graph for this function:

◆ WriteEntry()

kXR_int32 XrdSutPFile::WriteEntry ( XrdSutPFEntry ent)

Definition at line 585 of file XrdSutPFile.cc.

586{
587 // Write entry to file
588 // Look first if an entry with the same name exists: in such
589 // case try to overwrite the allocated file region; if the space
590 // is not enough, set the existing entry inactive and write
591 // the new entry at the end of the file, updating all the
592 // pointers.
593 // File must be opened in read/write mode (O_RDWR).
594
595 // Make sure that the entry is named (otherwise we can't do nothing)
596 if (!ent.name)
597 return Err(kPFErrBadInputs,"WriteEntry");
598
599 //
600 // Ready to write: open the file
601 bool wasopen = 0;
602 if (Open(1, &wasopen) < 0)
603 return -1;
604
605 kXR_int32 ofs = 0;
606 kXR_int32 nw = 0;
607 kXR_int32 indofs = 0;
608 // Read the header
609 XrdSutPFHeader header;
610 if (ReadHeader(header) < 0) {
611 if (!wasopen) Close();
612 return -1;
613 }
614 if ((ofs = lseek(fFd, 0, SEEK_CUR)) == -1) {
615 if (!wasopen) Close();
616 return Err(kPFErrSeek,"WriteEntry","SEEK_CUR",(const char *)&fFd);
617 }
618
619 XrdSutPFEntInd ind;
620 // If first entry, write it, update the info and return
621 if (header.entries == 0) {
622 if ((nw = WriteEnt(ofs, ent)) < 0) {
623 if (!wasopen) Close();
624 return -1;
625 }
626 ind.SetName(ent.name);
627 ind.nxtofs = 0;
628 ind.entofs = ofs;
629 ind.entsiz = nw;
630 indofs = ofs + nw;
631 if (WriteInd(indofs, ind) < 0) {
632 if (!wasopen) Close();
633 return -1;
634 }
635 // Update header
636 header.entries = 1;
637 header.indofs = indofs;
638 header.ctime = time(0);
639 header.itime = header.ctime;
640 if (WriteHeader(header) < 0) {
641 if (!wasopen) Close();
642 return -1;
643 }
644 if (!wasopen) Close();
645 return nw;
646 }
647
648 // First Localize existing entry, if any
649 kXR_int32 nr = 1;
650 bool found = 0;
651 indofs = header.indofs;
652 kXR_int32 lastindofs = indofs;
653 while (!found && nr > 0 && indofs > 0) {
654 nr = ReadInd(indofs, ind);
655 if (nr) {
656 if (ind.entofs > 0 && !strcmp(ent.name,ind.name)) {
657 found = 1;
658 break;
659 }
660 lastindofs = indofs;
661 indofs = ind.nxtofs;
662 }
663 }
664
665 //
666 // If an entry already exists and there is enough space to
667 // store the update, write the update at the already allocated
668 // space; if not, add it at the end.
669 if (found) {
670 // Update
671 kXR_int32 ct = 0;
672 if (ind.entsiz >= ent.Length()) {
673 // The offset is set inside ...
674 if ((nw = WriteEnt(ind.entofs, ent)) < 0) {
675 if (!wasopen) Close();
676 return -1;
677 }
678 } else {
679 // Add it at the end
680 kXR_int32 entofs = 0;
681 if ((entofs = lseek(fFd, 0, SEEK_END)) == -1) {
682 if (!wasopen) Close();
683 return Err(kPFErrSeek,"WriteEntry",
684 "SEEK_END",(const char *)&fFd);
685 }
686 if ((nw = WriteEnt(entofs, ent)) < 0) {
687 if (!wasopen) Close();
688 return -1;
689 }
690 // Set existing entry inactive
691 kXR_int32 wrtofs = ind.entofs;
692 if (lseek(fFd, wrtofs, SEEK_SET) == -1) {
693 if (!wasopen) Close();
694 return Err(kPFErrSeek,"WriteEntry",
695 "SEEK_SET",(const char *)&fFd);
696 }
697 short status = kPFE_inactive;
698 while (write(fFd, &status, sizeof(short)) < 0 &&
699 errno == EINTR) errno = 0;
700 // Reset entry area
701 if (Reset(wrtofs + sizeof(short), ind.entsiz - sizeof(short)) < 0) {
702 if (!wasopen) Close();
703 return -1;
704 }
705 // Count as unused bytes
706 header.jnksiz += ind.entsiz;
707 if (lseek(fFd, kOfsJnkSiz, SEEK_SET) == -1) {
708 if (!wasopen) Close();
709 return Err(kPFErrSeek,"WriteEntry",
710 "SEEK_SET",(const char *)&fFd);
711 }
712 while (write(fFd, &header.jnksiz, sizeof(kXR_int32)) < 0 &&
713 errno == EINTR) errno = 0;
714 // Update the entry index and new size
715 wrtofs = indofs + 2*sizeof(kXR_int32);
716 if (lseek(fFd, wrtofs, SEEK_SET) == -1) {
717 if (!wasopen) Close();
718 return Err(kPFErrSeek,"WriteEntry",
719 "SEEK_SET",(const char *)&fFd);
720 }
721 while (write(fFd, &entofs, sizeof(kXR_int32)) < 0 &&
722 errno == EINTR) errno = 0;
723 while (write(fFd, &nw, sizeof(kXR_int32)) < 0 &&
724 errno == EINTR) errno = 0;
725 // Update time of change of index
726 ct = (kXR_int32)time(0);
727 header.itime = ct;
728 if (lseek(fFd, kOfsItime, SEEK_SET) == -1) {
729 if (!wasopen) Close();
730 return Err(kPFErrSeek,"WriteEntry",
731 "SEEK_SET",(const char *)&fFd);
732 }
733 while (write(fFd, &header.itime, sizeof(kXR_int32)) < 0 &&
734 errno == EINTR) errno = 0;
735 }
736 // Update time of change in header
737 header.ctime = (ct > 0) ? ct : time(0);
738 if (lseek(fFd, kOfsCtime, SEEK_SET) == -1) {
739 if (!wasopen) Close();
740 return Err(kPFErrSeek,"WriteEntry",
741 "SEEK_SET",(const char *)&fFd);
742 }
743 while (write(fFd, &header.ctime, sizeof(kXR_int32)) < 0 &&
744 errno == EINTR) errno = 0;
745 if (!wasopen) Close();
746 return nw;
747 }
748
749 //
750 // If new name, add the entry at the end
751 if ((ofs = lseek(fFd, 0, SEEK_END)) == -1) {
752 if (!wasopen) Close();
753 return Err(kPFErrSeek,"WriteEntry",
754 "SEEK_END",(const char *)&fFd);
755 }
756 if ((nw = WriteEnt(ofs, ent)) < 0) {
757 if (!wasopen) Close();
758 return -1;
759 }
760 //
761 // Create new index entry
762 XrdSutPFEntInd newind(ent.name, 0, ofs, nw);
763 if (WriteInd(ofs+nw, newind) < 0) {
764 if (!wasopen) Close();
765 return -1;
766 }
767 //
768 // Update previous index entry
769 ind.nxtofs = ofs + nw;
770 kXR_int32 wrtofs = lastindofs + sizeof(kXR_int32);
771 if (lseek(fFd, wrtofs, SEEK_SET) == -1) {
772 if (!wasopen) Close();
773 return Err(kPFErrSeek,"WriteEntry",
774 "SEEK_SET",(const char *)&fFd);
775 }
776 while (write(fFd, &ind.nxtofs, sizeof(kXR_int32)) < 0 &&
777 errno == EINTR) errno = 0;
778
779 // Update header
780 header.entries += 1;
781 header.ctime = time(0);
782 header.itime = header.ctime;
783 if (WriteHeader(header) < 0) {
784 if (!wasopen) Close();
785 return -1;
786 }
787
788 // Close the file
789 if (!wasopen) Close();
790
791 return nw;
792}
#define kOfsJnkSiz
#define kOfsCtime
#define kOfsItime
if(ec< 0) ec
void SetName(const char *n=0)
kXR_int32 Length() const

References Close(), XrdSutPFHeader::ctime, XrdSutPFEntInd::entofs, XrdSutPFHeader::entries, XrdSutPFEntInd::entsiz, Err, XrdSutPFHeader::indofs, XrdSutPFHeader::itime, XrdSutPFHeader::jnksiz, kOfsCtime, kOfsItime, kOfsJnkSiz, kPFE_inactive, kPFErrBadInputs, kPFErrSeek, XrdSutPFEntry::Length(), lseek, XrdSutPFEntInd::name, XrdSutPFEntry::name, XrdSutPFEntInd::nxtofs, Open(), XrdSutPFEntInd::SetName(), and write.

Referenced by XrdSutPFCache::Flush(), and main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ XrdSutPFCache

friend class XrdSutPFCache
friend

Definition at line 123 of file XrdSutPFile.hh.


The documentation for this class was generated from the following files: