1 /*===========================================================================
2  *
3  *                            PUBLIC DOMAIN NOTICE
4  *               National Center for Biotechnology Information
5  *
6  *  This software/database is a "United States Government Work" under the
7  *  terms of the United States Copyright Act.  It was written as part of
8  *  the author's official duties as a United States Government employee and
9  *  thus cannot be copyrighted.  This software/database is freely available
10  *  to the public for use. The National Library of Medicine and the U.S.
11  *  Government have not placed any restriction on its use or reproduction.
12  *
13  *  Although all reasonable efforts have been taken to ensure the accuracy
14  *  and reliability of the software and data, the NLM and the U.S.
15  *  Government do not and cannot warrant the performance or results that
16  *  may be obtained by using this software or data. The NLM and the U.S.
17  *  Government disclaim all warranties, express or implied, including
18  *  warranties of performance, merchantability or fitness for any particular
19  *  purpose.
20  *
21  *  Please cite the author in any work or product based on this material.
22  *
23  * ===========================================================================
24  *
25  */
26 #include <klib/rc.h>
27 #include <klib/out.h>
28 #include <klib/text.h>
29 #include <klib/refcount.h>
30 #include <klib/printf.h>
31 #include <klib/log.h>
32 
33 #include <kfs/file.h>
34 #include <kfs/directory.h>
35 
36 #include <xfs/model.h>
37 #include <xfs/tree.h>
38 #include <xfs/node.h>
39 #include <xfs/path.h>
40 #include <xfs/editors.h>
41 #include <xfs/handle.h>
42 #include <xfs/perm.h>
43 
44 #include "xtar.h"
45 #include "mehr.h"
46 #include "schwarzschraube.h"
47 #include "teleport.h"
48 #include "common.h"
49 
50 #include <sysalloc.h>
51 
52 #include <string.h>     /* memset */
53 
54 /*)))
55  |||    That file contains 'archive' XFSTar based nodes
56 (((*/
57 
58 /*)))
59  |||
60  +++    TarRootNode, TarNode, and others
61  |||
62 (((*/
63 struct XFSTarNode {
64     struct XFSNode node;
65 
66     const struct XFSTarEntry * entry;
67 };
68 
69 struct XFSTarRootNode {
70     struct XFSTarNode node;
71 
72     const struct XFSTar * tar;
73 };
74 
75 struct XFSTarFileEditor {
76     struct XFSFileEditor Papahen;
77 
78     const struct XFSTarEntry * entry;
79 };
80 
81 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
82 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
83 /*_*                                                               *_*/
84 /*_* TarNode is living here                                       *_*/
85 /*_*                                                               *_*/
86 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
87 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
88 
89 /*)))
90  |||
91  +++    TarNode virtual table is Living here :lol:
92  |||
93 (((*/
94 static rc_t CC _TarNodeFlavor_v1 (
95                                 const struct XFSNode * self
96                                 );
97 static rc_t CC _TarNodeDispose_v1 (
98                                 const struct XFSNode * self
99                                 );
100 static rc_t CC _TarRootNodeDispose_v1 (
101                                 const struct XFSNode * self
102                                 );
103 static rc_t CC _TarNodeFindNode_v1 (
104                                 const struct XFSNode * self,
105                                 const struct XFSPath * Path,
106                                 uint32_t PathIndex,
107                                 const struct XFSNode ** Node
108                                 );
109 static rc_t CC _TarNodeDir_v1 (
110                                 const struct XFSNode * self,
111                                 const struct XFSDirEditor ** Dir
112                                 );
113 static rc_t CC _TarNodeFile_v1 (
114                                 const struct XFSNode * self,
115                                 const struct XFSFileEditor ** File
116                                 );
117 static rc_t CC _TarNodeAttr_v1 (
118                                 const struct XFSNode * self,
119                                 const struct XFSAttrEditor ** Attr
120                                 );
121 static rc_t CC _TarNodeDescribe_v1 (
122                                 const struct XFSNode * self,
123                                 char * Buffer,
124                                 size_t BufferSize
125                                 );
126 
127 static const struct XFSNode_vt_v1 _sTarRootNodeVT_v1 = {
128                                         1, 1,   /* nin naj */
129                                         _TarNodeFlavor_v1,
130                                         _TarRootNodeDispose_v1,
131                                         _TarNodeFindNode_v1,
132                                         _TarNodeDir_v1,
133                                         _TarNodeFile_v1,
134                                         _TarNodeAttr_v1,
135                                         _TarNodeDescribe_v1
136                                         };
137 
138 static const struct XFSNode_vt_v1 _sTarNodeVT_v1 = {
139                                         1, 1,   /* nin naj */
140                                         _TarNodeFlavor_v1,
141                                         _TarNodeDispose_v1,
142                                         NULL,
143                                         _TarNodeDir_v1,
144                                         _TarNodeFile_v1,
145                                         _TarNodeAttr_v1,
146                                         _TarNodeDescribe_v1
147                                         };
148 
149 
150 static
151 rc_t CC
XFSTarNodeMake(struct XFSNode ** Node,const char * Name,const struct XFSTarEntry * Entry)152 XFSTarNodeMake (
153     struct XFSNode ** Node,
154     const char * Name,
155     const struct XFSTarEntry * Entry
156 )
157 {
158     rc_t RCt;
159     struct XFSTarNode * xNode;
160 
161     RCt = 0;
162     xNode = NULL;
163 
164     if ( Node != NULL ) {
165         * Node = NULL;
166     }
167 
168     if ( Node == NULL || Name == NULL || Entry == NULL ) {
169         return XFS_RC ( rcNull );
170     }
171 
172     xNode = calloc ( 1, sizeof ( struct XFSTarNode ) );
173     if ( xNode == NULL ) {
174         return XFS_RC ( rcNull );
175     }
176 
177     RCt = XFSNodeInitVT (
178                     & ( xNode -> node ),
179                     Name,
180                     ( const union XFSNode_vt * ) & _sTarNodeVT_v1
181                     );
182 
183     if ( RCt == 0 ) {
184         RCt = XFSTarEntryAddRef ( Entry );
185         if ( RCt == 0 ) {
186             xNode -> entry = Entry;
187 
188             * Node = & ( xNode -> node );
189         }
190     }
191 
192     if ( RCt != 0 ) {
193         if ( xNode != NULL ) {
194             RCt = XFSNodeDispose ( & ( xNode -> node ) );
195         }
196     }
197 
198     return RCt;
199 }   /* XFSTarNodeMake () */
200 
201 static
202 rc_t CC
XFSTarRootNodeMake(struct XFSNode ** Node,const char * Name,const char * Path)203 XFSTarRootNodeMake (
204     struct XFSNode ** Node,
205     const char * Name,
206     const char * Path
207 )
208 {
209     rc_t RCt;
210     struct XFSTarRootNode * xNode;
211     const struct XFSTar * Tar;
212     const struct XFSTarEntry * Entry;
213 
214     RCt = 0;
215     xNode = NULL;
216     Tar = NULL;
217     Entry = NULL;
218 
219     if ( Node != NULL ) {
220         * Node = NULL;
221     }
222 
223     if ( Node == NULL || Name == NULL || Path == NULL ) {
224         return XFS_RC ( rcNull );
225     }
226 
227     xNode = calloc ( 1, sizeof ( struct XFSTarRootNode ) );
228     if ( xNode == NULL ) {
229         return XFS_RC ( rcExhausted );
230     }
231 
232     RCt = XFSNodeInitVT (
233                     & ( xNode -> node . node),
234                     Name,
235                     ( const union XFSNode_vt * ) & _sTarRootNodeVT_v1
236                     );
237     if ( RCt == 0 ) {
238         RCt = XFSTarFindOrCreate ( Path, & Tar );
239         if ( RCt == 0 ) {
240             RCt = XFSTarGetEntry ( Tar, "/", & Entry );
241             if ( RCt == 0 ) {
242                 if ( Entry == NULL ) {
243                     RCt = XFS_RC ( rcInvalid );
244                 }
245                 else {
246                     xNode -> node . entry = Entry;
247                     xNode -> tar = Tar;
248 
249                     * Node = & ( xNode -> node . node );
250                 }
251             }
252         }
253     }
254 
255     if ( RCt != 0 ) {
256         if ( xNode != NULL ) {
257             XFSNodeDispose ( ( const struct XFSNode * ) & ( xNode -> node ) );
258         }
259     }
260 
261     return RCt;
262 }   /* XFSTarRootNodeMake () */
263 
264 uint32_t CC
_TarNodeFlavor_v1(const struct XFSNode * self)265 _TarNodeFlavor_v1 ( const struct XFSNode * self )
266 {
267     return _sFlavorOfTar;
268 }   /* _TarNodeFlavor_v1 () */
269 
270 static
271 rc_t CC
XFSTarNodeDispose(const struct XFSTarNode * self)272 XFSTarNodeDispose ( const struct XFSTarNode * self )
273 {
274     struct XFSTarNode * Node = ( struct XFSTarNode * ) self;
275 
276 /*
277 pLogMsg ( klogDebug, "XFSTarNodeDispose ( $(node) )", "node=%p", ( void * ) Node );
278 */
279 
280     if ( Node == 0 ) {
281         return 0;
282     }
283 
284     if ( Node -> entry != NULL ) {
285         XFSTarEntryRelease ( Node -> entry );
286 
287         Node -> entry = NULL;
288     }
289 
290     free ( Node );
291 
292     return 0;
293 }   /* XFSTarNodeDispose () */
294 
295 static
296 rc_t CC
XFSTarRootNodeDispose(const struct XFSTarRootNode * self)297 XFSTarRootNodeDispose ( const struct XFSTarRootNode * self )
298 {
299     struct XFSTarRootNode * Node = ( struct XFSTarRootNode * ) self;
300 
301 /*
302 pLogMsg ( klogDebug, "XFSTarRootNodeDispose ( $(node) )", "node=%p", ( void * ) Node );
303 */
304 
305     if ( Node == 0 ) {
306         return 0;
307     }
308 
309     if ( Node -> tar != NULL ) {
310         XFSTarRelease ( ( struct XFSTar * ) Node -> tar );
311         Node -> tar = NULL;
312     }
313 
314     XFSTarNodeDispose ( & ( Node -> node ) );
315 
316     return 0;
317 }   /* XFSTarRootNodeDispose () */
318 
319 rc_t CC
_TarRootNodeDispose_v1(const struct XFSNode * self)320 _TarRootNodeDispose_v1 ( const struct XFSNode * self )
321 {
322     return XFSTarRootNodeDispose ( ( const struct XFSTarRootNode * ) self );
323 }   /* _TarRootNodeDispose_v1 () */
324 
325 rc_t CC
_TarNodeDispose_v1(const struct XFSNode * self)326 _TarNodeDispose_v1 ( const struct XFSNode * self )
327 {
328     return XFSTarNodeDispose ( ( const struct XFSTarNode * ) self );
329 }   /* _TarNodeDispose_v1 () */
330 
331 /*)))
332  |||
333  +++  There are two methods to find node: for Root and non Root nodes
334  |||
335 (((*/
336 
337 /*)) KDir version
338  ((*/
339 rc_t CC
_TarNodeFindNode_v1(const struct XFSNode * self,const struct XFSPath * Path,uint32_t PathIndex,const struct XFSNode ** Node)340 _TarNodeFindNode_v1 (
341             const struct XFSNode * self,
342             const struct XFSPath * Path,
343             uint32_t PathIndex,
344             const struct XFSNode ** Node
345 )
346 {
347     rc_t RCt;
348     uint32_t PathCount;
349     const char * NodeName;
350     struct XFSTarRootNode * RootNode;
351     struct XFSNode * RetNode;
352     const struct XFSTarEntry * Entry;
353     const struct XFSPath * xPath;
354     bool IsLast;
355 
356     RCt = 0;
357     PathCount = 0;
358     NodeName = NULL;
359     RootNode = NULL;
360     RetNode = NULL;
361     Entry = NULL;
362     xPath = NULL;
363     IsLast = false;
364 
365     RCt = XFSNodeFindNodeCheckInitStandard (
366                                             self,
367                                             Path,
368                                             PathIndex,
369                                             Node,
370                                             & NodeName,
371                                             & PathCount,
372                                             & IsLast
373                                             );
374     if ( RCt == 0 ) {
375         if ( IsLast ) {
376             RCt = XFSNodeAddRef ( self );
377 
378             * Node = self;
379 
380             return RCt;
381         }
382 
383         RootNode = ( struct XFSTarRootNode * ) self;
384         if ( RootNode -> tar == NULL ) {
385             return XFS_RC ( rcInvalid );
386         }
387 
388         RCt = XFSPathFrom ( Path, PathIndex + 1, & xPath );
389         if ( RCt == 0 ) {
390             RCt = XFSTarGetEntry (
391                                 RootNode -> tar,
392                                 XFSPathGet ( xPath ),
393                                 & Entry
394                                 );
395             if ( RCt == 0 ) {
396                 RCt = XFSTarNodeMake (
397                                     & RetNode,
398                                     XFSPathName ( Path ),/* NodeName, */
399                                     Entry
400                                     );
401                 if ( RCt == 0 ) {
402                     * Node = RetNode;
403                 }
404             }
405 
406             XFSPathRelease ( xPath );
407         }
408     }
409 
410     return RCt;
411 }   /* _TarNodeFindNode () */
412 
413 /*)))
414  |||
415  +++  Unified DirEditor
416  |||
417 (((*/
418 static
419 rc_t CC
_TarDir_dispose_v1(const struct XFSEditor * self)420 _TarDir_dispose_v1 ( const struct XFSEditor * self )
421 {
422     struct XFSDirEditor * Editor = ( struct XFSDirEditor * ) self;
423 /*
424     pLogMsg ( klogDebug, "_TarDir_dispose_v1 ( $(editor) )", "editor=%p", ( void * ) self );
425 */
426 
427     if ( Editor != NULL ) {
428         free ( Editor );
429     }
430 
431     return 0;
432 }   /* _TarDir_dispose_v1 () */
433 
434 static
435 rc_t CC
_TarDir_list_v1(const struct XFSDirEditor * self,const struct KNamelist ** List)436 _TarDir_list_v1 (
437                 const struct XFSDirEditor * self,
438                 const struct KNamelist ** List
439 )
440 {
441     rc_t RCt;
442     const struct XFSTarNode * Node;
443     struct KNamelist * TempList;
444 
445     RCt = 0;
446     Node = NULL;
447     TempList = NULL;
448 
449     if ( List != NULL ) {
450         * List = NULL;
451     }
452 
453     if ( self == NULL || List == NULL ) {
454         return XFS_RC ( rcNull );
455     }
456 
457     Node = ( const struct XFSTarNode * ) XFSEditorNode (
458                                                 & ( self -> Papahen )
459                                                 );
460     if ( Node == NULL ) {
461         return XFS_RC ( rcInvalid );
462     }
463 
464     if ( Node -> entry == NULL ) {
465         return XFS_RC ( rcInvalid );
466     }
467 
468     RCt = XFSTarEntryList ( Node -> entry, & TempList );
469     if ( RCt == 0 ) {
470         * List = TempList;
471     }
472 
473     return RCt;
474 }   /* _TarDir_list_v1 () */
475 
476 static
477 rc_t CC
_TarDir_find_v1(const struct XFSDirEditor * self,const char * Name,const struct XFSNode ** Node)478 _TarDir_find_v1 (
479                 const struct XFSDirEditor * self,
480                 const char * Name,
481                 const struct XFSNode ** Node
482 )
483 {
484     rc_t RCt;
485     const struct XFSTarNode * TarNode;
486     struct XFSNode * TempNode;
487     const struct XFSTarEntry * TempEntry;
488 
489     RCt = 0;
490     TarNode = NULL;
491     TempNode = NULL;
492     TempEntry = NULL;
493 
494     if ( Node != NULL ) {
495         * Node = NULL;
496     }
497 
498     if ( self == NULL || Name == NULL || Node == NULL ) {
499         return XFS_RC ( rcNull );
500     }
501 
502     TarNode = ( const struct XFSTarNode * ) XFSEditorNode (
503                                                 & ( self -> Papahen )
504                                                 );
505     if ( TarNode == NULL ) {
506         return XFS_RC ( rcInvalid );
507     }
508 
509     if ( TarNode -> entry == NULL ) {
510         return XFS_RC ( rcInvalid );
511     }
512 
513     RCt = XFSTarEntryGetChild ( TarNode -> entry, Name, & TempEntry );
514     if ( RCt == 0 ) {
515         RCt = XFSTarNodeMake ( & TempNode, Name, TempEntry );
516         if ( RCt == 0 ) {
517             * Node = TempNode;
518         }
519     }
520 
521     return RCt;
522 }   /* _TarDir_find_v1 () */
523 
524 rc_t CC
_TarNodeDir_v1(const struct XFSNode * self,const struct XFSDirEditor ** Dir)525 _TarNodeDir_v1 (
526             const struct XFSNode * self,
527             const struct XFSDirEditor ** Dir
528 )
529 {
530     rc_t RCt;
531     struct XFSDirEditor * Editor;
532     const struct XFSTarNode * Node;
533 
534     RCt = 0;
535     Editor = NULL;
536     Node = ( const struct XFSTarNode * ) self;
537 
538     if ( Dir != NULL ) {
539         * Dir = NULL;
540     }
541 
542     if ( self == NULL || Dir == NULL ) {
543         return XFS_RC ( rcNull );
544     }
545 
546     if ( Node -> entry == NULL ) {
547         return XFS_RC ( rcInvalid );
548     }
549 
550     if ( ! XFSTarEntryIsFolder ( Node -> entry ) ) {
551         return XFS_RC ( rcInvalid );
552     }
553 
554     Editor = calloc ( 1, sizeof ( struct XFSDirEditor ) );
555     if ( Editor == NULL ) {
556         return XFS_RC ( rcExhausted );
557     }
558 
559     memset ( Editor, 0, sizeof ( struct XFSDirEditor ) );
560 
561     RCt = XFSEditorInit (
562                     & ( Editor -> Papahen ),
563                     self,
564                     _TarDir_dispose_v1
565                     );
566 
567     if ( RCt == 0 ) {
568         Editor -> list = _TarDir_list_v1;
569         Editor -> find = _TarDir_find_v1;
570 
571         * Dir = Editor;
572     }
573     else {
574         free ( Editor );
575     }
576 
577     return RCt;
578 }   /* _TarNodeDir_v1 () */
579 
580 /*)))
581  |||
582  +++  Unified FileEditor
583  |||
584 (((*/
585 
586 static
587 rc_t CC
_TarFile_dispose_v1(const struct XFSEditor * self)588 _TarFile_dispose_v1 ( const struct XFSEditor * self )
589 {
590     struct XFSTarFileEditor * Editor = ( struct XFSTarFileEditor * ) self;
591 /*
592     pLogMsg ( klogDebug, "_TarNodeFile_dispose_v1 ( $(editor) )", "editor=%p", ( void * ) self );
593 */
594 
595     if ( Editor != NULL ) {
596         if ( Editor -> entry != NULL ) {
597             XFSTarEntryRelease ( Editor -> entry );
598 
599             Editor -> entry = NULL;
600         }
601 
602         free ( Editor );
603     }
604 
605     return 0;
606 }   /* _TarFile_dispose_v1 () */
607 
608 static
609 rc_t CC
_TarFile_open_v1(const struct XFSFileEditor * self,XFSNMode Mode)610 _TarFile_open_v1 (
611                     const struct XFSFileEditor * self,
612                     XFSNMode Mode
613 )
614 {
615     rc_t RCt;
616     const struct XFSTarNode * Node;
617     struct XFSTarFileEditor * Editor;
618 
619     RCt = 0;
620     Node = NULL;
621     Editor = ( struct XFSTarFileEditor * ) self;
622 
623     if ( Mode != kxfsRead ) {
624         return XFS_RC ( rcInvalid );
625     }
626 
627     if ( self == NULL ) {
628         return XFS_RC ( rcNull );
629     }
630 
631     Node = ( const struct XFSTarNode * ) XFSEditorNode (
632                                                 & ( self -> Papahen )
633                                                 );
634     if ( Node == NULL ) {
635         return XFS_RC ( rcInvalid );
636     }
637 
638     if ( Node -> entry == NULL ) {
639         return XFS_RC ( rcInvalid );
640     }
641 
642     Editor = ( struct XFSTarFileEditor * ) self;
643     if ( Editor -> entry == NULL ) {
644         if ( ! XFSTarEntryIsOpen ( Node -> entry ) ) {
645             RCt = XFSTarEntryOpen ( Node -> entry );
646         }
647         if ( RCt == 0 ) {
648             Editor -> entry = Node -> entry;
649         }
650     }
651 
652     return RCt;
653 }   /* _TarFile_open_v1 () */
654 
655 static
656 rc_t CC
_TarFile_close_v1(const struct XFSFileEditor * self)657 _TarFile_close_v1 ( const struct XFSFileEditor * self )
658 {
659     rc_t RCt;
660     struct XFSTarFileEditor * Editor;
661 
662     RCt = 0;
663     Editor = ( struct XFSTarFileEditor * ) self;
664 
665     if ( Editor == NULL ) {
666         return XFS_RC ( rcNull );
667     }
668 
669 
670     if ( Editor -> entry != NULL ) {
671         RCt = XFSTarEntryClose ( Editor -> entry );
672         if ( RCt == 0 ) {
673             RCt = XFSTarEntryRelease ( Editor -> entry );
674 
675             Editor -> entry = NULL;
676         }
677     }
678 
679     return RCt;
680 }   /* _TarFile_close_v1 () */
681 
682 static
683 rc_t CC
_TarFile_read_v1(const struct XFSFileEditor * self,uint64_t Offset,void * Buffer,size_t SizeToRead,size_t * NumReaded)684 _TarFile_read_v1 (
685                     const struct XFSFileEditor * self,
686                     uint64_t Offset,
687                     void * Buffer,
688                     size_t SizeToRead,
689                     size_t * NumReaded
690 )
691 {
692     rc_t RCt;
693     struct XFSTarFileEditor * Editor;
694 
695     RCt = 0;
696     Editor = ( struct XFSTarFileEditor * ) self;
697 
698     if ( Editor == NULL ) {
699         return XFS_RC ( rcNull );
700     }
701 
702 
703     if ( Editor -> entry == NULL ) {
704         return XFS_RC ( rcInvalid );
705     }
706 
707     RCt = XFSTarEntryRead (
708                         Editor -> entry,
709                         Offset,
710                         Buffer,
711                         SizeToRead,
712                         NumReaded
713                         );
714 
715     return RCt;
716 }   /* _TarFile_read_v1 () */
717 
718 static
719 rc_t CC
_TarFile_size_v1(const struct XFSFileEditor * self,uint64_t * Size)720 _TarFile_size_v1 (
721                         const struct XFSFileEditor * self,
722                         uint64_t * Size
723 )
724 {
725     rc_t RCt;
726     struct XFSTarNode * Node;
727 
728     RCt = 0;
729     Node = NULL;
730 
731     XFS_CSA ( Size, 0 )
732     XFS_CAN ( self )
733     XFS_CAN ( Size )
734 
735     Node = ( struct XFSTarNode * ) XFSEditorNode (
736                                                 & ( self -> Papahen )
737                                                 );
738 
739     if ( Node == NULL ) {
740         return XFS_RC ( rcInvalid );
741     }
742 
743     if ( Node -> entry == NULL ) {
744         return XFS_RC ( rcInvalid );
745     }
746 
747     if ( XFSTarEntryIsFolder ( Node -> entry ) ) {
748         * Size = 0;
749     }
750     else {
751         RCt = XFSTarEntrySize ( Node -> entry, Size );
752         if ( RCt != 0 ) {
753             * Size = 0;
754         }
755     }
756 
757     return RCt;
758 }   /* _TarFile_size_v1 () */
759 
760 rc_t CC
_TarNodeFile_v1(const struct XFSNode * self,const struct XFSFileEditor ** File)761 _TarNodeFile_v1 (
762             const struct XFSNode * self,
763             const struct XFSFileEditor ** File
764 )
765 {
766     rc_t RCt;
767     struct XFSTarFileEditor * FileEditor;
768     struct XFSFileEditor * Editor;
769 
770     RCt = 0;
771     FileEditor = NULL;
772     Editor = NULL;
773 
774     if ( File != NULL ) {
775         * File = NULL;
776     }
777 
778     if ( self == NULL || File == NULL ) {
779         return XFS_RC ( rcNull );
780     }
781 
782     FileEditor = calloc ( 1, sizeof ( struct XFSTarFileEditor ) );
783     if ( FileEditor == NULL ) {
784         return XFS_RC ( rcExhausted );
785     }
786 
787     memset ( FileEditor, 0, sizeof ( struct XFSTarFileEditor ) );
788 
789     Editor = & ( FileEditor -> Papahen );
790 
791     RCt = XFSEditorInit (
792                     & ( Editor -> Papahen ),
793                     self,
794                     _TarFile_dispose_v1
795                     );
796 
797     if ( RCt == 0 ) {
798         Editor -> open = _TarFile_open_v1;
799         Editor -> close = _TarFile_close_v1;
800         Editor -> read = _TarFile_read_v1;
801         Editor -> size = _TarFile_size_v1;
802 
803         * File = Editor;
804     }
805     else {
806         free ( Editor );
807     }
808 
809     return RCt;
810 }   /* _TarNodeFile_v1 () */
811 
812 /*)))
813  |||
814  +++  Unified Attr
815  |||
816 (((*/
817 
818 static
819 rc_t CC
_TarAttr_dispose_v1(const struct XFSEditor * self)820 _TarAttr_dispose_v1 ( const struct XFSEditor * self )
821 {
822 /*
823     pLogMsg ( klogDebug, "_TarAttr_dispose_v1 ( $(editor) )", "editor=%p", ( void * ) self );
824 */
825 
826     if ( self != NULL ) {
827         free ( ( struct XFSAttrEditor * ) self );
828     }
829 
830     return 0;
831 }   /* _TarAttr_dispose_v1 () */
832 
833 static
834 rc_t CC
_TarAttr_init_check_v1(const struct XFSAttrEditor * self,const struct XFSTarEntry ** Entry)835 _TarAttr_init_check_v1 (
836                 const struct XFSAttrEditor * self,
837                 const struct XFSTarEntry ** Entry
838 )
839 {
840     struct XFSTarNode * Node = NULL;
841 
842     if ( Entry != NULL ) {
843         * Entry = NULL;
844     }
845 
846     if ( self == NULL || Entry == NULL ) {
847         return XFS_RC ( rcNull );
848     }
849 
850     Node = ( struct XFSTarNode * ) XFSEditorNode (
851                                                 & ( self -> Papahen )
852                                                 );
853     if ( Node == NULL ) {
854         return XFS_RC ( rcInvalid );
855     }
856 
857     if ( Node -> entry == NULL ) {
858         return XFS_RC ( rcInvalid );
859     }
860 
861     * Entry = Node -> entry;
862 
863     return 0;
864 }   /* _TarAttr_init_check_v1 () */
865 
866 static
867 rc_t CC
_TarAttr_permissions_v1(const struct XFSAttrEditor * self,const char ** Permissions)868 _TarAttr_permissions_v1 (
869                         const struct XFSAttrEditor * self,
870                         const char ** Permissions
871 )
872 {
873     rc_t RCt;
874     const struct XFSTarEntry * Entry;
875 
876     RCt = 0;
877     Entry = NULL;
878 
879     if ( Permissions == NULL ) {
880         return XFS_RC ( rcNull );
881     }
882     * Permissions = NULL;
883 
884     RCt = _TarAttr_init_check_v1 ( self, & Entry );
885     if ( RCt == 0 ) {
886         * Permissions = XFSTarEntryIsFolder ( Entry )
887                                         ? XFSPermRODefContChar ()
888                                         : XFSPermRODefNodeChar ()
889                                         ;
890     }
891 
892     return RCt;
893 }   /* _TarAttr_permissions_v1 () */
894 
895 
896 static
897 rc_t CC
_TarAttr_date_v1(const struct XFSAttrEditor * self,KTime_t * Time)898 _TarAttr_date_v1 (
899                         const struct XFSAttrEditor * self,
900                         KTime_t * Time
901 )
902 {
903     rc_t RCt;
904     const struct XFSTarEntry * Entry;
905 
906     RCt = 0;
907     Entry = NULL;
908 
909     if ( Time == NULL ) {
910         return XFS_RC ( rcNull );
911     }
912     * Time = 0;
913 
914     RCt = _TarAttr_init_check_v1 ( self, & Entry );
915     if ( RCt == 0 ) {
916         RCt = XFSTarEntryTime ( Entry, Time );
917         if ( RCt != 0 ) {
918             * Time = 0;
919         }
920     }
921 
922     return RCt;
923 }   /* _TarAttr_date_v1 () */
924 
925 static
926 rc_t CC
_TarAttr_type_v1(const struct XFSAttrEditor * self,XFSNType * Type)927 _TarAttr_type_v1 (
928                         const struct XFSAttrEditor * self,
929                         XFSNType * Type
930 )
931 {
932     rc_t RCt;
933     const struct XFSTarEntry * Entry;
934 
935     RCt = 0;
936     Entry = NULL;
937 
938     if ( Type == NULL ) {
939         return XFS_RC ( rcNull );
940     }
941     * Type = kxfsNotFound;
942 
943     RCt = _TarAttr_init_check_v1 ( self, & Entry );
944     if ( RCt == 0 ) {
945         * Type = XFSTarEntryIsFolder ( Entry ) ? kxfsDir : kxfsFile ;
946     }
947 
948     return RCt;
949 }   /* _TarAttr_type_v1 () */
950 
951 static
952 rc_t CC
_TarNodeAttr_v1(const struct XFSNode * self,const struct XFSAttrEditor ** Attr)953 _TarNodeAttr_v1 (
954             const struct XFSNode * self,
955             const struct XFSAttrEditor ** Attr
956 )
957 {
958     rc_t RCt;
959     struct XFSAttrEditor * Editor;
960 
961     RCt = 0;
962     Editor = NULL;
963 
964     if ( self == NULL || Attr == NULL ) {
965         return XFS_RC ( rcNull );
966     }
967 
968     * Attr = NULL;
969 
970     Editor = calloc ( 1, sizeof ( struct XFSAttrEditor ) );
971     if ( Editor == NULL ) {
972         return XFS_RC ( rcExhausted );
973     }
974 
975     RCt = XFSEditorInit (
976                     & ( Editor -> Papahen ),
977                     self,
978                     _TarAttr_dispose_v1
979                     );
980     if ( RCt == 0 ) {
981         Editor -> permissions = _TarAttr_permissions_v1;
982         Editor -> date = _TarAttr_date_v1;
983         Editor -> type = _TarAttr_type_v1;
984 
985         * Attr = Editor;
986     }
987     else {
988         free ( Editor );
989     }
990 
991     return RCt;
992 }   /* _TarNodeAttr_v1 () */
993 
994 /*)))
995  |||
996  +++  Unified Discribe
997  |||
998 (((*/
999 
1000 rc_t CC
_TarNodeDescribe_v1(const struct XFSNode * self,char * Buffer,size_t BufferSize)1001 _TarNodeDescribe_v1 (
1002             const struct XFSNode * self,
1003             char * Buffer,
1004             size_t BufferSize
1005 )
1006 {
1007     rc_t RCt;
1008     size_t NumWrit;
1009     const char * Abbr;
1010 
1011     RCt = 0;
1012     NumWrit = 0;
1013     Abbr = NULL;
1014 
1015     if ( Buffer == NULL || BufferSize == 0 ) {
1016         return XFS_RC ( rcNull );
1017     }
1018 
1019     Abbr = XFSTarEntryIsFolder ( ( ( const struct XFSTarNode * ) self ) -> entry )
1020             ? "TAR FOLDER"
1021             : "TAR NODE"
1022             ;
1023 
1024     if ( self == NULL ) {
1025         string_printf (
1026                     Buffer,
1027                     BufferSize,
1028                     & NumWrit,
1029                     "NODE (%s)[NULL][NULL]",
1030                     Abbr
1031                     );
1032     }
1033     else {
1034         string_printf (
1035                     Buffer,
1036                     BufferSize,
1037                     & NumWrit,
1038                     "NODE (%s)[%s][0x%p]",
1039                     Abbr,
1040                     self -> Name,
1041                     self
1042                     );
1043     }
1044 
1045     return RCt;
1046 }   /* _TarNodeDescribe_v1 () */
1047 
1048 /*)))
1049  |||
1050  +++    FileNode lives here
1051  |||
1052 (((*/
1053 
1054 /*))
1055  ((     Node make/dispose
1056   ))
1057  ((*/
1058 
1059 /*)))
1060  |||
1061  +++    Non-Teleport methods to create nodes
1062  |||
1063 (((*/
1064 
1065 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
1066 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
1067 /* ALL BELOW TODO!!!                                               */
1068 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
1069 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
1070 /*)))
1071  |||
1072  +++    TarRootNode has a Teleport, and it is HERE
1073  |||
1074 (((*/
1075 static
1076 rc_t CC
_TarArchiveNodeConstructor(const struct XFSModel * Model,const struct XFSModelNode * Template,const char * Alias,const struct XFSNode ** Node)1077 _TarArchiveNodeConstructor (
1078             const struct XFSModel * Model,
1079             const struct XFSModelNode * Template,
1080             const char * Alias,
1081             const struct XFSNode ** Node
1082 )
1083 {
1084     rc_t RCt;
1085     struct XFSNode * TheNode;
1086     const char * NodeName;
1087 
1088     RCt = 0;
1089     TheNode = NULL;
1090     NodeName = NULL;
1091 
1092     if ( Node != NULL ) {
1093         * Node = NULL;
1094     }
1095 
1096     if ( Model == NULL || Template == NULL || Node == NULL ) {
1097         return XFS_RC ( rcNull );
1098     }
1099 
1100     NodeName = Alias == NULL ? XFSModelNodeName ( Template ) : Alias;
1101 
1102     RCt = XFSTarRootNodeMake (
1103                     & TheNode,
1104                     NodeName,
1105                     XFSModelNodeProperty ( Template, XFS_MODEL_SOURCE )
1106                     );
1107     if ( RCt == 0 ) {
1108         * Node = ( struct XFSNode * ) TheNode;
1109     }
1110 
1111     if ( RCt != 0 ) {
1112         * Node = NULL;
1113 
1114         if ( TheNode != NULL ) {
1115             XFSTarRootNodeDispose ( ( const struct XFSTarRootNode * ) TheNode );
1116         }
1117     }
1118 
1119     return RCt;
1120 }   /* _TarArchiveNodeConstructor () */
1121 
1122 /*)))
1123  |||
1124  +++    TarRootNode has a Teleport, and it is HERE
1125  |||
1126 (((*/
1127 static
1128 rc_t CC
_TarArchiveConstructor(const struct XFSModel * Model,const struct XFSModelNode * Template,const char * Alias,const struct XFSNode ** Node)1129 _TarArchiveConstructor (
1130             const struct XFSModel * Model,
1131             const struct XFSModelNode * Template,
1132             const char * Alias,
1133             const struct XFSNode ** Node
1134 )
1135 {
1136     rc_t RCt;
1137 
1138     RCt = _TarArchiveNodeConstructor (
1139                                         Model,
1140                                         Template,
1141                                         Alias,
1142                                         Node
1143                                         );
1144 
1145 /*
1146 pLogMsg ( klogDebug, "_TarArchiveConstructor ( $(node), $(template) (\"$(name)\"), \"$(alias)\" )", "node=%p,template=%p,name=%s,alias=%s", ( void * ) Model, ( void * ) Template, XFSModelNodeName ( Template ), ( Alias == NULL ? "NULL" : Alias ) );
1147 */
1148 
1149     return RCt;
1150 }   /* _TarArchiveConstructor () */
1151 
1152 static
1153 rc_t CC
_TarArchiveValidator(const struct XFSModel * Model,const struct XFSModelNode * Template,const char * Alias,uint32_t Flags)1154 _TarArchiveValidator (
1155             const struct XFSModel * Model,
1156             const struct XFSModelNode * Template,
1157             const char * Alias,
1158             uint32_t Flags
1159 )
1160 {
1161     rc_t RCt;
1162 
1163     RCt = 0;
1164 
1165 /*
1166 pLogMsg ( klogDebug, "_TarArchiveValidator ( $(node), $(template) (\"$(name)\"), \"$(alias)\" )", "node=%p,template=%p,name=%s,alias=%s", ( void * ) Model, ( void * ) Template, XFSModelNodeName ( Template ), ( Alias == NULL ? "NULL" : Alias ) );
1167 */
1168 
1169     return RCt;
1170 }   /* _TarArchiveValidator () */
1171 
1172 static const struct XFSTeleport _sTarArchiveTeleport = {
1173                                         _TarArchiveConstructor,
1174                                         _TarArchiveValidator,
1175                                         false
1176                                         };
1177 
1178 
1179 LIB_EXPORT
1180 rc_t CC
XFSTarArchiveProvider(const struct XFSTeleport ** Teleport)1181 XFSTarArchiveProvider ( const struct XFSTeleport ** Teleport )
1182 {
1183     if ( Teleport == NULL ) {
1184         return XFS_RC ( rcNull );
1185     }
1186 
1187     * Teleport = & _sTarArchiveTeleport;
1188 
1189     return 0;
1190 }   /* XFSTarArchiveProvider () */
1191 
1192 LIB_EXPORT
1193 rc_t CC
XFSTarArchiveNodeMake(struct XFSNode ** Node,const char * Name,const char * Path,const char * Perm)1194 XFSTarArchiveNodeMake (
1195                 struct XFSNode ** Node,
1196                 const char * Name,
1197                 const char * Path,
1198                 const char * Perm
1199 )
1200 {
1201     rc_t RCt;
1202     struct XFSNode * TheNode;
1203 
1204     RCt = 0;
1205 
1206     if ( Node != NULL ) {
1207         * Node = NULL;
1208     }
1209 
1210     if ( Name == NULL || Path == NULL || Node == NULL ) {
1211         return XFS_RC ( rcNull ) ;
1212     }
1213 
1214     RCt = XFSTarRootNodeMake ( & TheNode, Name, Path );
1215     if ( RCt == 0 ) {
1216         * Node = TheNode;
1217     }
1218     else {
1219         if ( TheNode != NULL ) {
1220             XFSTarRootNodeDispose ( ( const struct XFSTarRootNode * ) TheNode );
1221         }
1222     }
1223 
1224     return RCt;
1225 }   /* XFSTarArchiveNodeMake () */
1226