filelist.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: filelist.cc,v 1.14 1999/12/26 06:59:00 jgg Exp $
  4. /* ######################################################################
  5. File List Structures
  6. This module has a large group of services all relating to the binary
  7. file list. Each individual record type has an read and write function
  8. that can be used to store it into a unpacked structure.
  9. ##################################################################### */
  10. /*}}}*/
  11. // Include files /*{{{*/
  12. #ifdef __GNUG__
  13. #pragma implementation "dsync/filelist.h"
  14. #endif
  15. #include <dsync/filelist.h>
  16. #include <dsync/error.h>
  17. #include <system.h>
  18. #include <time.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <iostream>
  22. using namespace std;
  23. /*}}}*/
  24. // FList::Step - Step to the next record /*{{{*/
  25. // ---------------------------------------------------------------------
  26. /* This is an encompassing function to read a single record of any type
  27. from the IO */
  28. bool dsFList::Step(IO &IO)
  29. {
  30. if (!(_error->PendingError() == false && IO.ReadInt(Tag,1) == true))
  31. return false;
  32. Entity = 0;
  33. File = 0;
  34. switch (Tag)
  35. {
  36. case dsFList::tHeader:
  37. Head.Tag = Tag;
  38. Head.Read(IO);
  39. IO.Header = Head;
  40. break;
  41. case dsFList::tDirMarker:
  42. case dsFList::tDirStart:
  43. case dsFList::tDirectory:
  44. Dir.Tag = Tag;
  45. Entity = &Dir;
  46. return Dir.Read(IO);
  47. case dsFList::tNormalFile:
  48. NFile.Tag = Tag;
  49. Entity = &NFile;
  50. File = &NFile;
  51. return NFile.Read(IO);
  52. case dsFList::tSymlink:
  53. SLink.Tag = Tag;
  54. Entity = &SLink;
  55. return SLink.Read(IO);
  56. case dsFList::tDeviceSpecial:
  57. DevSpecial.Tag = Tag;
  58. Entity = &DevSpecial;
  59. return DevSpecial.Read(IO);
  60. case dsFList::tFilter:
  61. Filt.Tag = Tag;
  62. return Filt.Read(IO);
  63. case dsFList::tUidMap:
  64. UMap.Tag = Tag;
  65. return UMap.Read(IO);
  66. case dsFList::tGidMap:
  67. UMap.Tag = Tag;
  68. return UMap.Read(IO);
  69. case dsFList::tHardLink:
  70. HLink.Tag = Tag;
  71. Entity = &HLink;
  72. File = &HLink;
  73. return HLink.Read(IO);
  74. case dsFList::tTrailer:
  75. Trail.Tag = Tag;
  76. return Trail.Read(IO);
  77. case dsFList::tRSyncChecksum:
  78. RChk.Tag = Tag;
  79. return RChk.Read(IO);
  80. case dsFList::tAggregateFile:
  81. AgFile.Tag = Tag;
  82. return AgFile.Read(IO);
  83. case tRSyncEnd:
  84. case tDirEnd:
  85. return true;
  86. default:
  87. return _error->Error("Corrupted file list");
  88. }
  89. return true;
  90. }
  91. /*}}}*/
  92. // FList::Print - Print out the record /*{{{*/
  93. // ---------------------------------------------------------------------
  94. /* This simply displays the record */
  95. bool dsFList::Print(ostream &out)
  96. {
  97. char S[1024];
  98. switch (Tag)
  99. {
  100. case tHeader:
  101. {
  102. snprintf(S,sizeof(S),"H Sig=%lx Maj=%lu Min=%lu Epoch=%lu Count=%lu\n",
  103. Head.Signature,Head.MajorVersion,Head.MinorVersion,
  104. Head.Epoch,Head.FlagCount);
  105. out << S;
  106. break;
  107. }
  108. case tDirMarker:
  109. case tDirStart:
  110. case tDirectory:
  111. {
  112. if (Tag == tDirMarker)
  113. snprintf(S,sizeof(S),"DM Mod=%lu",
  114. Dir.ModTime+Head.Epoch);
  115. if (Tag == tDirStart)
  116. snprintf(S,sizeof(S),"DS Mod=%lu",
  117. Dir.ModTime+Head.Epoch);
  118. if (Tag == tDirectory)
  119. snprintf(S,sizeof(S),"D Mod=%lu",
  120. Dir.ModTime+Head.Epoch);
  121. out << S;
  122. if ((Head.Flags[Tag] & Directory::FlPerm) != 0)
  123. {
  124. snprintf(S,sizeof(S)," Perm=%lo",Dir.Permissions);
  125. out << S;
  126. }
  127. if ((Head.Flags[Tag] & Directory::FlOwner) != 0)
  128. {
  129. snprintf(S,sizeof(S)," U=%lu G=%lu",Dir.User,Dir.Group);
  130. out << S;
  131. }
  132. snprintf(S,sizeof(S)," N='%s'\n",Dir.Name.c_str());
  133. out << S;
  134. break;
  135. }
  136. case tDirEnd:
  137. out << "DE" << endl;
  138. break;
  139. case tHardLink:
  140. case tNormalFile:
  141. {
  142. snprintf(S,sizeof(S),"F Mod=%lu",File->ModTime+Head.Epoch);
  143. out << S;
  144. if ((Head.Flags[Tag] & NormalFile::FlPerm) != 0)
  145. {
  146. snprintf(S,sizeof(S)," Perm=%lo",File->Permissions);
  147. out << S;
  148. }
  149. if ((Head.Flags[Tag] & NormalFile::FlOwner) != 0)
  150. {
  151. snprintf(S,sizeof(S)," U=%lu G=%lu",File->User,File->Group);
  152. out << S;
  153. }
  154. if ((Head.Flags[Tag] & NormalFile::FlMD5) != 0)
  155. {
  156. char S[16*2+1];
  157. for (unsigned int I = 0; I != 16; I++)
  158. sprintf(S+2*I,"%02x",File->MD5[I]);
  159. S[16*2] = 0;
  160. out << " MD5=" << S;
  161. }
  162. if (Tag == tHardLink)
  163. out << " Ser=" << HLink.Serial;
  164. snprintf(S,sizeof(S)," Sz=%lu N='%s'\n",File->Size,File->Name.c_str());
  165. out << S;
  166. break;
  167. }
  168. case tDeviceSpecial:
  169. {
  170. snprintf(S,sizeof(S),"S Mod=%lu",DevSpecial.ModTime+Head.Epoch);
  171. out << S;
  172. if ((Head.Flags[Tag] & DeviceSpecial::FlPerm) != 0)
  173. {
  174. snprintf(S,sizeof(S)," Perm=%lo",DevSpecial.Permissions);
  175. out << S;
  176. }
  177. if ((Head.Flags[Tag] & DeviceSpecial::FlOwner) != 0)
  178. {
  179. snprintf(S,sizeof(S)," U=%lu G=%lu",DevSpecial.User,DevSpecial.Group);
  180. out << S;
  181. }
  182. snprintf(S,sizeof(S)," N='%s'\n",DevSpecial.Name.c_str());
  183. out << S;
  184. break;
  185. }
  186. case tSymlink:
  187. {
  188. snprintf(S,sizeof(S),"L Mod=%lu",SLink.ModTime+Head.Epoch);
  189. out << S;
  190. if ((Head.Flags[Tag] & Symlink::FlOwner) != 0)
  191. {
  192. snprintf(S,sizeof(S)," U=%lu G=%lu",SLink.User,SLink.Group);
  193. out << S;
  194. }
  195. snprintf(S,sizeof(S)," N='%s' T='%s'\n",SLink.Name.c_str(),SLink.To.c_str());
  196. out << S;
  197. break;
  198. }
  199. case dsFList::tTrailer:
  200. {
  201. snprintf(S,sizeof(S),"T Sig=%lx\n",Trail.Signature);
  202. out << S;
  203. break;
  204. }
  205. case dsFList::tRSyncChecksum:
  206. {
  207. snprintf(S,sizeof(S),"RC BlockSize=%lu FileSize=%lu\n",RChk.BlockSize,RChk.FileSize);
  208. out << S;
  209. break;
  210. }
  211. case dsFList::tAggregateFile:
  212. {
  213. snprintf(S,sizeof(S),"RAG File='%s'\n",AgFile.File.c_str());
  214. break;
  215. }
  216. case tRSyncEnd:
  217. out << "RSE" << endl;
  218. break;
  219. default:
  220. return _error->Error("Unknown tag %u",Tag);
  221. }
  222. return true;
  223. }
  224. /*}}}*/
  225. // IO::IO - Constructor /*{{{*/
  226. // ---------------------------------------------------------------------
  227. /* */
  228. dsFList::IO::IO()
  229. {
  230. NoStrings = false;
  231. }
  232. /*}}}*/
  233. // IO::ReadNum - Read a variable byte number coded with WriteNum /*{{{*/
  234. // ---------------------------------------------------------------------
  235. /* Read a variable byte encoded number, see WriteNum */
  236. bool dsFList::IO::ReadNum(unsigned long &Number)
  237. {
  238. unsigned int I = 0;
  239. Number = 0;
  240. while (1)
  241. {
  242. unsigned char Byte = 0;
  243. if (Read(&Byte,1) == false)
  244. return false;
  245. Number |= (Byte & 0x7F) << 7*I;
  246. if ((Byte & (1<<7)) == 0)
  247. return true;
  248. I++;
  249. }
  250. }
  251. /*}}}*/
  252. // IO::WriteNum - Write a variable byte number /*{{{*/
  253. // ---------------------------------------------------------------------
  254. /* This encodes the given number into a variable number of bytes and writes
  255. it to the stream. This is done by encoding it in 7 bit chunks and using
  256. the 8th bit as a continuation flag */
  257. bool dsFList::IO::WriteNum(unsigned long Number)
  258. {
  259. unsigned char Bytes[10];
  260. unsigned int I = 0;
  261. while (1)
  262. {
  263. Bytes[I] = Number & 0x7F;
  264. Number >>= 7;
  265. if (Number != 0)
  266. Bytes[I] |= (1<<7);
  267. else
  268. break;
  269. I++;
  270. }
  271. return Write(Bytes,I+1);
  272. }
  273. /*}}}*/
  274. // IO::ReadInt - Read an unsigned int written by WriteInt /*{{{*/
  275. // ---------------------------------------------------------------------
  276. /* Read an unsigned integer of a given number of bytes, see WriteInt */
  277. bool dsFList::IO::ReadInt(unsigned long &Number,unsigned char Count)
  278. {
  279. unsigned char Bytes[8];
  280. if (Read(&Bytes,Count) == false)
  281. return false;
  282. Number = 0;
  283. for (unsigned int I = 0; I != Count; I++)
  284. Number |= (Bytes[I] << I*8);
  285. return true;
  286. }
  287. /*}}}*/
  288. // IO::WriteInt - Write an unsigned int with a number of bytes /*{{{*/
  289. // ---------------------------------------------------------------------
  290. /* This writes the number of bytes in least-significant-byte first order */
  291. bool dsFList::IO::WriteInt(unsigned long Number,unsigned char Count)
  292. {
  293. unsigned char Bytes[8];
  294. for (unsigned int I = 0; I != Count; I++)
  295. Bytes[I] = (Number >> I*8);
  296. return Write(Bytes,Count);
  297. }
  298. /*}}}*/
  299. // IO::ReadInt - Read an signed int written by WriteInt /*{{{*/
  300. // ---------------------------------------------------------------------
  301. /* Read a signed integer of a given number of bytes, see WriteInt */
  302. bool dsFList::IO::ReadInt(signed long &Number,unsigned char Count)
  303. {
  304. unsigned char Bytes[8];
  305. if (Read(&Bytes,Count) == false)
  306. return false;
  307. Number = 0;
  308. for (unsigned int I = 0; I != Count; I++)
  309. Number |= (Bytes[I] << I*8);
  310. return true;
  311. }
  312. /*}}}*/
  313. // IO::WriteInt - Write an signed int with a number of bytes /*{{{*/
  314. // ---------------------------------------------------------------------
  315. /* This writes the number of bytes in least-significant-byte first order */
  316. bool dsFList::IO::WriteInt(signed long Number,unsigned char Count)
  317. {
  318. unsigned char Bytes[8];
  319. for (unsigned int I = 0; I != Count; I++)
  320. Bytes[I] = (Number >> I*8);
  321. return Write(Bytes,Count);
  322. }
  323. /*}}}*/
  324. // IO::ReadString - Read a string written by WriteString /*{{{*/
  325. // ---------------------------------------------------------------------
  326. /* If NoStrings is set then the string is not allocated into memory, this
  327. saves time when scanning a file */
  328. bool dsFList::IO::ReadString(string &Foo)
  329. {
  330. char S[1024];
  331. unsigned long Len;
  332. if (ReadNum(Len) == false)
  333. return false;
  334. if (Len >= sizeof(S))
  335. return _error->Error("String buffer too small");
  336. if (Read(S,Len) == false)
  337. return false;
  338. S[Len] = 0;
  339. if (NoStrings == false)
  340. Foo = S;
  341. else
  342. Foo = string();
  343. return true;
  344. }
  345. /*}}}*/
  346. // IO::WriteString - Write a string to the stream /*{{{*/
  347. // ---------------------------------------------------------------------
  348. /* Write a string, we encode a Number contianing the length and then the
  349. string itself */
  350. bool dsFList::IO::WriteString(string const &Foo)
  351. {
  352. return WriteNum(Foo.length()) && Write(Foo.c_str(),strlen(Foo.c_str()));
  353. }
  354. /*}}}*/
  355. // Header::Header - Constructor /*{{{*/
  356. // ---------------------------------------------------------------------
  357. /* The constructor sets the current signature and version information */
  358. dsFList::Header::Header() : Signature(0x97E78AB), MajorVersion(0),
  359. MinorVersion(1)
  360. {
  361. Tag = dsFList::tHeader;
  362. FlagCount = _count(Flags);
  363. memset(Flags,0,sizeof(Flags));
  364. Epoch = (unsigned long)time(0);
  365. }
  366. /*}}}*/
  367. // Header::Read - Read the coded header /*{{{*/
  368. // ---------------------------------------------------------------------
  369. /* */
  370. bool dsFList::Header::Read(IO &IO)
  371. {
  372. // Read the contents
  373. if ((IO.ReadInt(Signature,4) &&
  374. IO.ReadInt(MajorVersion,2) && IO.ReadInt(MinorVersion,2) &&
  375. IO.ReadNum(Epoch) && IO.ReadInt(FlagCount,1)) == false)
  376. return false;
  377. unsigned long RealFlagCount = FlagCount;
  378. if (FlagCount > _count(Flags))
  379. FlagCount = _count(Flags);
  380. // Read the flag array
  381. for (unsigned int I = 0; I != RealFlagCount; I++)
  382. {
  383. unsigned long Jnk;
  384. if (I >= FlagCount)
  385. {
  386. if (IO.ReadInt(Jnk,4) == false)
  387. return false;
  388. }
  389. else
  390. {
  391. if (IO.ReadInt(Flags[I],4) == false)
  392. return false;
  393. }
  394. }
  395. return true;
  396. }
  397. /*}}}*/
  398. // Header::Write - Write the coded header /*{{{*/
  399. // ---------------------------------------------------------------------
  400. /* */
  401. bool dsFList::Header::Write(IO &IO)
  402. {
  403. FlagCount = _count(Flags);
  404. // Write the contents
  405. if ((IO.WriteInt(Tag,1) && IO.WriteInt(Signature,4) &&
  406. IO.WriteInt(MajorVersion,2) && IO.WriteInt(MinorVersion,2) &&
  407. IO.WriteNum(Epoch) && IO.WriteInt(FlagCount,1)) == false)
  408. return false;
  409. // Write the flag array
  410. for (unsigned int I = 0; I != FlagCount; I++)
  411. if (IO.WriteInt(Flags[I],4) == false)
  412. return false;
  413. return true;
  414. }
  415. /*}}}*/
  416. // Directory::Read - Read a coded directory record /*{{{*/
  417. // ---------------------------------------------------------------------
  418. /* */
  419. bool dsFList::Directory::Read(IO &IO)
  420. {
  421. unsigned long F = IO.Header.Flags[Tag];
  422. if ((IO.ReadInt(ModTime,4)) == false)
  423. return false;
  424. if ((F & FlPerm) == FlPerm && IO.ReadInt(Permissions,2) == false)
  425. return false;
  426. if ((F & FlOwner) == FlOwner && (IO.ReadNum(User) &&
  427. IO.ReadNum(Group)) == false)
  428. return false;
  429. if (IO.ReadString(Name) == false)
  430. return false;
  431. return true;
  432. }
  433. /*}}}*/
  434. // Directory::Write - Write a compacted directory record /*{{{*/
  435. // ---------------------------------------------------------------------
  436. /* */
  437. bool dsFList::Directory::Write(IO &IO)
  438. {
  439. unsigned long F = IO.Header.Flags[Tag];
  440. if ((IO.WriteInt(Tag,1) && IO.WriteInt(ModTime,4)) == false)
  441. return false;
  442. if ((F & FlPerm) == FlPerm && IO.WriteInt(Permissions,2) == false)
  443. return false;
  444. if ((F & FlOwner) == FlOwner && (IO.WriteNum(User) &&
  445. IO.WriteNum(Group)) == false)
  446. return false;
  447. if (IO.WriteString(Name) == false)
  448. return false;
  449. return true;
  450. }
  451. /*}}}*/
  452. // NormalFile::Read - Read the compacted file record /*{{{*/
  453. // ---------------------------------------------------------------------
  454. /* */
  455. bool dsFList::NormalFile::Read(IO &IO)
  456. {
  457. unsigned long F = IO.Header.Flags[Tag];
  458. if ((IO.ReadInt(ModTime,4)) == false)
  459. return false;
  460. if ((F & FlPerm) == FlPerm && IO.ReadInt(Permissions,2) == false)
  461. return false;
  462. if ((F & FlOwner) == FlOwner && (IO.ReadNum(User) &&
  463. IO.ReadNum(Group)) == false)
  464. return false;
  465. if ((IO.ReadString(Name) && IO.ReadNum(Size)) == false)
  466. return false;
  467. if ((F & FlMD5) == FlMD5 && IO.Read(&MD5,16) == false)
  468. return false;
  469. return true;
  470. }
  471. /*}}}*/
  472. // NormalFile::write - Write the compacted file record /*{{{*/
  473. // ---------------------------------------------------------------------
  474. /* */
  475. bool dsFList::NormalFile::Write(IO &IO)
  476. {
  477. unsigned long F = IO.Header.Flags[Tag];
  478. if ((IO.WriteInt(Tag,1) && IO.WriteInt(ModTime,4)) == false)
  479. return false;
  480. if ((F & FlPerm) == FlPerm && IO.WriteInt(Permissions,2) == false)
  481. return false;
  482. if ((F & FlOwner) == FlOwner && (IO.WriteNum(User) &&
  483. IO.WriteNum(Group)) == false)
  484. return false;
  485. if ((IO.WriteString(Name) && IO.WriteNum(Size)) == false)
  486. return false;
  487. if ((F & FlMD5) == FlMD5 && IO.Write(&MD5,16) == false)
  488. return false;
  489. return true;
  490. }
  491. /*}}}*/
  492. // Symlink::Read - Read a compacted symlink record /*{{{*/
  493. // ---------------------------------------------------------------------
  494. /* */
  495. bool dsFList::Symlink::Read(IO &IO)
  496. {
  497. unsigned long F = IO.Header.Flags[Tag];
  498. if ((IO.ReadInt(ModTime,4)) == false)
  499. return false;
  500. if ((F & FlOwner) == FlOwner && (IO.ReadNum(User) &&
  501. IO.ReadNum(Group)) == false)
  502. return false;
  503. if ((IO.ReadString(Name) && IO.ReadInt(Compress,1) &&
  504. IO.ReadString(To)) == false)
  505. return false;
  506. // Decompress the string
  507. if (Compress != 0)
  508. {
  509. if ((Compress & (1<<7)) == (1<<7))
  510. To += Name;
  511. if ((Compress & 0x7F) != 0)
  512. To = string(IO.LastSymlink,0,Compress & 0x7F) + To;
  513. }
  514. IO.LastSymlink = To;
  515. return true;
  516. }
  517. /*}}}*/
  518. // Symlink::Write - Write a compacted symlink record /*{{{*/
  519. // ---------------------------------------------------------------------
  520. /* This performs the symlink compression described in the file list
  521. document. */
  522. bool dsFList::Symlink::Write(IO &IO)
  523. {
  524. unsigned long F = IO.Header.Flags[Tag];
  525. if ((IO.WriteInt(Tag,1) && IO.WriteInt(ModTime,4)) == false)
  526. return false;
  527. if ((F & FlOwner) == FlOwner && (IO.WriteNum(User) &&
  528. IO.WriteNum(Group)) == false)
  529. return false;
  530. if (IO.WriteString(Name) == false)
  531. return false;
  532. // Attempt to remove the trailing text
  533. bool Trail = false;
  534. if (To.length() >= Name.length())
  535. {
  536. unsigned int I = To.length() - Name.length();
  537. for (unsigned int J = 0; I < To.length(); I++, J++)
  538. if (To[I] != Name[J])
  539. break;
  540. if (I == To.length())
  541. Trail = true;
  542. }
  543. // Compress the symlink target
  544. Compress = 0;
  545. unsigned int Len = To.length();
  546. if (Trail == true)
  547. Len -= Name.length();
  548. for (; Compress < Len && Compress < IO.LastSymlink.length() &&
  549. Compress < 0x7F; Compress++)
  550. if (To[Compress] != IO.LastSymlink[Compress])
  551. break;
  552. // Set the trail flag
  553. if (Trail == true)
  554. Compress |= (1<<7);
  555. // Write the compresion byte
  556. if (IO.WriteInt(Compress,1) == false)
  557. return false;
  558. // Write the data string
  559. if (Trail == true)
  560. {
  561. if (IO.WriteString(string(To,Compress & 0x7F,To.length() - Name.length() - (Compress & 0x7F))) == false)
  562. return false;
  563. }
  564. else
  565. {
  566. if (IO.WriteString(string(To,Compress,To.length() - Compress)) == false)
  567. return false;
  568. }
  569. IO.LastSymlink = To;
  570. return true;
  571. }
  572. /*}}}*/
  573. // DeviceSpecial::Read - Read a compacted device special record /*{{{*/
  574. // ---------------------------------------------------------------------
  575. /* */
  576. bool dsFList::DeviceSpecial::Read(IO &IO)
  577. {
  578. unsigned long F = IO.Header.Flags[Tag];
  579. if ((IO.ReadInt(ModTime,4)) == false)
  580. return false;
  581. if (IO.ReadInt(Permissions,2) == false)
  582. return false;
  583. if ((F & FlOwner) == FlOwner && (IO.ReadNum(User) &&
  584. IO.ReadNum(Group)) == false)
  585. return false;
  586. if ((IO.ReadNum(Dev) && IO.ReadString(Name)) == false)
  587. return false;
  588. return true;
  589. }
  590. /*}}}*/
  591. // DeviceSpecial::Write - Write a compacted device special record /*{{{*/
  592. // ---------------------------------------------------------------------
  593. /* */
  594. bool dsFList::DeviceSpecial::Write(IO &IO)
  595. {
  596. unsigned long F = IO.Header.Flags[Tag];
  597. if ((IO.WriteInt(Tag,1) && IO.WriteInt(ModTime,4)) == false)
  598. return false;
  599. if (IO.WriteInt(Permissions,2) == false)
  600. return false;
  601. if ((F & FlOwner) == FlOwner && (IO.WriteNum(User) &&
  602. IO.WriteNum(Group)) == false)
  603. return false;
  604. if ((IO.WriteNum(Dev) && IO.WriteString(Name)) == false)
  605. return false;
  606. return true;
  607. }
  608. /*}}}*/
  609. // Filter::Read - Read a compacted filter record /*{{{*/
  610. // ---------------------------------------------------------------------
  611. /* */
  612. bool dsFList::Filter::Read(IO &IO)
  613. {
  614. if ((IO.ReadInt(Type,1) &&
  615. IO.ReadString(Pattern)) == false)
  616. return false;
  617. return true;
  618. }
  619. /*}}}*/
  620. // Filter::Write - Write a compacted filter record /*{{{*/
  621. // ---------------------------------------------------------------------
  622. /* */
  623. bool dsFList::Filter::Write(IO &IO)
  624. {
  625. if ((IO.WriteInt(Tag,1) && IO.WriteInt(Type,1) &&
  626. IO.WriteString(Pattern)) == false)
  627. return false;
  628. return true;
  629. }
  630. /*}}}*/
  631. // UidGidMap::Read - Read a compacted Uid/Gid map record /*{{{*/
  632. // ---------------------------------------------------------------------
  633. /* */
  634. bool dsFList::UidGidMap::Read(IO &IO)
  635. {
  636. unsigned long F = IO.Header.Flags[Tag];
  637. if ((IO.ReadNum(FileID)) == false)
  638. return false;
  639. if ((F & FlRealID) == FlRealID && IO.ReadNum(RealID) == false)
  640. return false;
  641. if (IO.ReadString(Name) == false)
  642. return false;
  643. return true;
  644. }
  645. /*}}}*/
  646. // UidGidMap::Write - Write a compacted Uid/Gid map record /*{{{*/
  647. // ---------------------------------------------------------------------
  648. /* */
  649. bool dsFList::UidGidMap::Write(IO &IO)
  650. {
  651. unsigned long F = IO.Header.Flags[Tag];
  652. if ((IO.WriteInt(Tag,1) && IO.WriteNum(FileID)) == false)
  653. return false;
  654. if ((F & FlRealID) == FlRealID && IO.WriteNum(RealID) == false)
  655. return false;
  656. if (IO.WriteString(Name) == false)
  657. return false;
  658. return true;
  659. }
  660. /*}}}*/
  661. // HardLink::Read - Read the compacted link record /*{{{*/
  662. // ---------------------------------------------------------------------
  663. /* */
  664. bool dsFList::HardLink::Read(IO &IO)
  665. {
  666. unsigned long F = IO.Header.Flags[Tag];
  667. if ((IO.ReadInt(ModTime,4) && IO.ReadNum(Serial)) == false)
  668. return false;
  669. if ((F & FlPerm) == FlPerm && IO.ReadInt(Permissions,2) == false)
  670. return false;
  671. if ((F & FlOwner) == FlOwner && (IO.ReadNum(User) &&
  672. IO.ReadNum(Group)) == false)
  673. return false;
  674. if ((IO.ReadString(Name) && IO.ReadNum(Size)) == false)
  675. return false;
  676. if ((F & FlMD5) == FlMD5 && IO.Read(&MD5,16) == false)
  677. return false;
  678. return true;
  679. }
  680. /*}}}*/
  681. // HardLink::Write - Write the compacted file record /*{{{*/
  682. // ---------------------------------------------------------------------
  683. /* */
  684. bool dsFList::HardLink::Write(IO &IO)
  685. {
  686. unsigned long F = IO.Header.Flags[Tag];
  687. if ((IO.WriteInt(Tag,1) && IO.WriteInt(ModTime,4) &&
  688. IO.ReadNum(Serial)) == false)
  689. return false;
  690. if ((F & FlPerm) == FlPerm && IO.WriteInt(Permissions,2) == false)
  691. return false;
  692. if ((F & FlOwner) == FlOwner && (IO.WriteNum(User) &&
  693. IO.WriteNum(Group)) == false)
  694. return false;
  695. if ((IO.WriteString(Name) && IO.WriteNum(Size)) == false)
  696. return false;
  697. if ((F & FlMD5) == FlMD5 && IO.Write(&MD5,16) == false)
  698. return false;
  699. return true;
  700. }
  701. /*}}}*/
  702. // Trailer::Trailer - Constructor /*{{{*/
  703. // ---------------------------------------------------------------------
  704. /* */
  705. dsFList::Trailer::Trailer() : Tag(dsFList::tTrailer), Signature(0xBA87E79)
  706. {
  707. }
  708. /*}}}*/
  709. // Trailer::Read - Read a compacted tail record /*{{{*/
  710. // ---------------------------------------------------------------------
  711. /* */
  712. bool dsFList::Trailer::Read(IO &IO)
  713. {
  714. if (IO.ReadInt(Signature,4) == false)
  715. return false;
  716. return true;
  717. }
  718. /*}}}*/
  719. // Trailer::Write - Write a compacted tail record /*{{{*/
  720. // ---------------------------------------------------------------------
  721. /* */
  722. bool dsFList::Trailer::Write(IO &IO)
  723. {
  724. if ((IO.WriteInt(Tag,1) &&
  725. IO.WriteInt(Signature,4)) == false)
  726. return false;
  727. return true;
  728. }
  729. /*}}}*/
  730. // RSyncChecksum::RSyncChecksum - Constructor /*{{{*/
  731. // ---------------------------------------------------------------------
  732. /* */
  733. dsFList::RSyncChecksum::RSyncChecksum() : Tag(dsFList::tRSyncChecksum),
  734. Sums(0)
  735. {
  736. }
  737. /*}}}*/
  738. // RSyncChecksum::~RSyncChecksum - Constructor /*{{{*/
  739. // ---------------------------------------------------------------------
  740. /* */
  741. dsFList::RSyncChecksum::~RSyncChecksum()
  742. {
  743. delete [] Sums;
  744. }
  745. /*}}}*/
  746. // RSyncChecksum::Read - Read a compacted device special record /*{{{*/
  747. // ---------------------------------------------------------------------
  748. /* */
  749. bool dsFList::RSyncChecksum::Read(IO &IO)
  750. {
  751. if ((IO.ReadNum(BlockSize) && IO.ReadNum(FileSize)) == false)
  752. return false;
  753. // Read in the checksum table
  754. delete [] Sums;
  755. Sums = new unsigned char[(FileSize + BlockSize-1)/BlockSize*20];
  756. if (IO.Read(Sums,(FileSize + BlockSize-1)/BlockSize*20) == false)
  757. return false;
  758. return true;
  759. }
  760. /*}}}*/
  761. // RSyncChecksum::Write - Write a compacted device special record /*{{{*/
  762. // ---------------------------------------------------------------------
  763. /* */
  764. bool dsFList::RSyncChecksum::Write(IO &IO)
  765. {
  766. if ((IO.WriteInt(Tag,1) && IO.WriteNum(BlockSize) &&
  767. IO.WriteNum(FileSize)) == false)
  768. return false;
  769. if (IO.Write(Sums,(FileSize + BlockSize-1)/BlockSize*20) == false)
  770. return false;
  771. return true;
  772. }
  773. /*}}}*/
  774. // AggregateFile::Read - Read a aggregate file record /*{{{*/
  775. // ---------------------------------------------------------------------
  776. /* */
  777. bool dsFList::AggregateFile::Read(IO &IO)
  778. {
  779. return IO.ReadString(File);
  780. }
  781. /*}}}*/
  782. // AggregateFile::Write - Write a compacted filter record /*{{{*/
  783. // ---------------------------------------------------------------------
  784. /* */
  785. bool dsFList::AggregateFile::Write(IO &IO)
  786. {
  787. if ((IO.WriteInt(Tag,1) && IO.WriteString(File)) == false)
  788. return false;
  789. return true;
  790. }
  791. /*}}}*/