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 "mehr.h"
45 #include "schwarzschraube.h"
46 #include "teleport.h"
47 #include "common.h"
48
49 #include <sysalloc.h>
50
51 /*)))
52 ||| That file contains 'native' KFile and KDirectory based nodes
53 ||| Both nodes are implemented as XFSKfsNode
54 ||| That kind of node represent real path which exists in system
55 (((*/
56
57 /*)))
58 |||
59 +++ FileNode, and other simple containers
60 |||
61 (((*/
62 struct XFSKfsNode {
63 struct XFSNode node;
64
65 XFSNType type; /* possible Dir and File */
66 const char * path; /* Path for object */
67 const char * perm; /* Permissions in format "rwxrwxrwx u:g:o" */
68 };
69
70 struct XFSKfsFileEditor {
71 struct XFSFileEditor Papahen;
72
73 struct KFile * File;
74 };
75
76 struct XFSKfsAttrEditor {
77 struct XFSAttrEditor Papahen;
78
79 char perm [ 16 ]; /* there we are storing 'const' object */
80 };
81
82 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
83 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
84 /*_* *_*/
85 /*_* KfsNode is living here *_*/
86 /*_* *_*/
87 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
88 /*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*/
89
90 /*)))
91 |||
92 +++ KfsNode virtual table is Living here :lol:
93 |||
94 (((*/
95 static rc_t CC _KfsNodeFlavor_v1 (
96 const struct XFSNode * self
97 );
98 static rc_t CC _KfsNodeDispose_v1 (
99 const struct XFSNode * self
100 );
101 static rc_t CC _KfsFileNodeFindNode_v1 (
102 const struct XFSNode * self,
103 const struct XFSPath * Path,
104 uint32_t PathIndex,
105 const struct XFSNode ** Node
106 );
107 static rc_t CC _KfsDirNodeFindNode_v1 (
108 const struct XFSNode * self,
109 const struct XFSPath * Path,
110 uint32_t PathIndex,
111 const struct XFSNode ** Node
112 );
113 static rc_t CC _KfsNodeDir_v1 (
114 const struct XFSNode * self,
115 const struct XFSDirEditor ** Dir
116 );
117 static rc_t CC _KfsNodeFile_v1 (
118 const struct XFSNode * self,
119 const struct XFSFileEditor ** File
120 );
121 static rc_t CC _KfsNodeAttr_v1 (
122 const struct XFSNode * self,
123 const struct XFSAttrEditor ** Attr
124 );
125 static rc_t CC _KfsNodeDescribe_v1 (
126 const struct XFSNode * self,
127 char * Buffer,
128 size_t BufferSize
129 );
130
131 static const struct XFSNode_vt_v1 _sKfsFileNodeVT_v1 = {
132 1, 1, /* nin naj */
133 _KfsNodeFlavor_v1,
134 _KfsNodeDispose_v1,
135 _KfsFileNodeFindNode_v1,
136 NULL, /* NO DIR */
137 _KfsNodeFile_v1,
138 _KfsNodeAttr_v1,
139 _KfsNodeDescribe_v1
140 };
141
142 static const struct XFSNode_vt_v1 _sKfsDirNodeVT_v1 = {
143 1, 1, /* nin naj */
144 _KfsNodeFlavor_v1,
145 _KfsNodeDispose_v1,
146 _KfsDirNodeFindNode_v1,
147 _KfsNodeDir_v1,
148 NULL, /* NO FILE */
149 _KfsNodeAttr_v1,
150 _KfsNodeDescribe_v1
151 };
152
153 static
154 rc_t CC
XFSKfsNodeMake(struct XFSKfsNode ** Node,XFSNType Type,const char * Name)155 XFSKfsNodeMake (
156 struct XFSKfsNode ** Node,
157 XFSNType Type,
158 const char * Name
159 )
160 {
161 rc_t RCt;
162 struct XFSKfsNode * TheNode;
163
164 RCt = 0;
165 TheNode = NULL;
166
167 if ( Node == NULL || Name == NULL ) {
168 return XFS_RC ( rcNull );
169 }
170
171 * Node = NULL;
172
173 if ( Type != kxfsFile && Type != kxfsDir ) {
174 return XFS_RC ( rcUnsupported );
175 }
176
177 TheNode = calloc ( 1, sizeof ( struct XFSKfsNode ) );
178 if ( TheNode == NULL ) {
179 RCt = XFS_RC ( rcExhausted );
180 }
181 else {
182 RCt = XFSNodeInitVT (
183 & ( TheNode -> node),
184 Name,
185 ( const union XFSNode_vt * ) ( Type == kxfsDir
186 ? ( & _sKfsDirNodeVT_v1 )
187 : ( & _sKfsFileNodeVT_v1 )
188 )
189 );
190 if ( RCt == 0 ) {
191
192 TheNode -> type = Type;
193
194 /* This is duplicate, but necessary one
195 */
196 TheNode -> node . vt = Type == kxfsDir
197 ? ( ( const union XFSNode_vt * ) & _sKfsDirNodeVT_v1 )
198 : ( ( const union XFSNode_vt * ) & _sKfsFileNodeVT_v1 )
199 ;
200
201 * Node = TheNode;
202 }
203 }
204
205 if ( RCt != 0 ) {
206 if ( TheNode != NULL ) {
207 XFSNodeDispose ( & ( TheNode -> node ) );
208 TheNode = NULL;
209 }
210 }
211
212 /*
213 pLogMsg ( klogDebug, "XFSKfsNodeMake ND[$(node)] NM[$(name)] TP[$(type)]", "node=%p,name=%s,type=%d", ( void * ) TheNode, Name, Type );
214 */
215
216 return RCt;
217 } /* XFSKfsNodeMake () */
218
219 static
220 rc_t CC
XFSKfsNodeMakeEx(struct XFSKfsNode ** Node,XFSNType Type,const char * Name,const char * Path,const char * Perm)221 XFSKfsNodeMakeEx (
222 struct XFSKfsNode ** Node,
223 XFSNType Type,
224 const char * Name,
225 const char * Path,
226 const char * Perm
227 )
228 {
229 struct XFSKfsNode * TempNode;
230 rc_t RCt;
231
232 RCt = 0;
233 TempNode = NULL;
234
235 if ( Node == NULL || Name == NULL || Path == NULL ) {
236 return XFS_RC ( rcNull );
237 }
238
239 * Node = NULL;
240
241 RCt = XFSKfsNodeMake ( & TempNode, Type, Name );
242 if ( RCt == 0 ) {
243 RCt = XFS_StrDup ( Path, & ( TempNode -> path ) );
244 if ( RCt == 0 ) {
245 if ( Perm != NULL ) {
246 RCt = XFS_StrDup ( Perm, & ( TempNode -> perm ) );
247 }
248 if ( RCt == 0 ) {
249 * Node = TempNode;
250 }
251 }
252 }
253
254 if ( RCt != 0 ) {
255 if ( TempNode != NULL ) {
256 XFSNodeDispose ( & ( TempNode -> node ) );
257 TempNode = NULL;
258 }
259 }
260
261 return RCt;
262 } /* XFSKfsNodeMakeEx () */
263
264 uint32_t CC
_KfsNodeFlavor_v1(const struct XFSNode * self)265 _KfsNodeFlavor_v1 ( const struct XFSNode * self )
266 {
267 return _sFlavorOfKfs;
268 } /* _KfsNodeFlavor_v1 () */
269
270 static
271 rc_t CC
XFSKfsNodeDispose(const struct XFSKfsNode * self)272 XFSKfsNodeDispose ( const struct XFSKfsNode * self )
273 {
274 struct XFSKfsNode * Node = ( struct XFSKfsNode * ) self;
275
276 /*
277 pLogMsg ( klogDebug, "XFSKfsNodeDispose ( $(node) ) TP[$(type)]", "node=%p,type=%d", ( void * ) Node, ( Node == NULL ? 0 : Node -> type ) );
278 */
279
280 if ( Node == 0 ) {
281 return 0;
282 }
283
284 if ( Node -> perm != NULL ) {
285 free ( ( char * ) Node -> perm );
286 Node -> perm = NULL;
287 }
288
289 if ( Node -> path != NULL ) {
290 free ( ( char * ) Node -> path );
291 Node -> path = NULL;
292 }
293
294 Node -> type = 0;
295
296 free ( Node );
297
298 return 0;
299 } /* XFSKfsNodeDispose () */
300
301 rc_t CC
_KfsNodeDispose_v1(const struct XFSNode * self)302 _KfsNodeDispose_v1 ( const struct XFSNode * self )
303 {
304 return XFSKfsNodeDispose ( ( struct XFSKfsNode * ) self );
305 } /* _KfsNodeDispose_v1 () */
306
307 /*)))
308 |||
309 +++ There will be two methods to find node: for KDir and for KFile
310 |||
311 (((*/
312
313 /*)) KFile version
314 ((*/
315 rc_t CC
_KfsFileNodeFindNode_v1(const struct XFSNode * self,const struct XFSPath * Path,uint32_t PathIndex,const struct XFSNode ** Node)316 _KfsFileNodeFindNode_v1 (
317 const struct XFSNode * self,
318 const struct XFSPath * Path,
319 uint32_t PathIndex,
320 const struct XFSNode ** Node
321 )
322 {
323 rc_t RCt;
324 uint32_t PathCount;
325 const char * NodeName;
326 bool IsLast;
327
328 RCt = 0;
329 PathCount = 0;
330 NodeName = NULL;
331 IsLast = false;
332
333 RCt = XFSNodeFindNodeCheckInitStandard (
334 self,
335 Path,
336 PathIndex,
337 Node,
338 & NodeName,
339 & PathCount,
340 & IsLast
341 );
342 if ( RCt == 0 ) {
343 if ( IsLast ) {
344 RCt = XFSNodeAddRef ( self );
345
346 * Node = self;
347 }
348 }
349
350 return RCt;
351 } /* _KfsFileNodeFindNode () */
352
353 /*)) KDir version
354 ((*/
355 rc_t CC
_KfsDirNodeFindNode_v1(const struct XFSNode * self,const struct XFSPath * Path,uint32_t PathIndex,const struct XFSNode ** Node)356 _KfsDirNodeFindNode_v1 (
357 const struct XFSNode * self,
358 const struct XFSPath * Path,
359 uint32_t PathIndex,
360 const struct XFSNode ** Node
361 )
362 {
363 rc_t RCt;
364 uint32_t PathCount;
365 const char * NodeName;
366 struct XFSKfsNode * KfsNode;
367 bool IsLast;
368 KDirectory * NativeDir;
369 XFSNType Type;
370 const struct XFSPath * xPath, * yPath;
371
372 RCt = 0;
373 PathCount = 0;
374 NodeName = NULL;
375 KfsNode = NULL;
376 IsLast = false;
377 NativeDir = NULL;
378 Type = kxfsNotFound;
379 xPath = yPath = NULL;
380
381 RCt = XFSNodeFindNodeCheckInitStandard (
382 self,
383 Path,
384 PathIndex,
385 Node,
386 & NodeName,
387 & PathCount,
388 & IsLast
389 );
390 if ( RCt == 0 ) {
391 if ( IsLast ) {
392 RCt = XFSNodeAddRef ( self );
393
394 * Node = self;
395
396 return RCt;
397 }
398
399 KfsNode = ( struct XFSKfsNode * ) self;
400 if ( KfsNode -> path == NULL ) {
401 return XFS_RC ( rcInvalid );
402 }
403
404 /*) Here we are trying to create new node
405 (*/
406 RCt = XFSPathFrom ( Path, PathIndex + 1, & xPath );
407 if ( RCt == 0 ) {
408 RCt = XFSPathMake (
409 & yPath,
410 true,
411 "%s/%s",
412 KfsNode -> path,
413 XFSPathGet ( xPath )
414 );
415 if ( RCt == 0 ) {
416 RCt = KDirectoryNativeDir ( & NativeDir );
417 if ( RCt == 0 ) {
418 switch ( KDirectoryPathType ( NativeDir, XFSPathGet ( yPath ) ) ) {
419 case kptFile :
420 Type = kxfsFile;
421 break;
422 case kptDir :
423 Type = kxfsDir;
424 break;
425 default :
426 RCt = XFS_RC ( rcInvalid );
427 break;
428 }
429 if ( RCt == 0 ) {
430 RCt = XFSKfsNodeMakeEx (
431 & KfsNode,
432 Type,
433 XFSPathName ( yPath ),
434 XFSPathGet ( yPath ),
435 NULL
436 );
437 if ( RCt == 0 ) {
438 * Node = & ( KfsNode -> node );
439 }
440 }
441
442 KDirectoryRelease ( NativeDir );
443 }
444
445 XFSPathRelease ( yPath );
446 }
447
448 XFSPathRelease ( xPath );
449 }
450 }
451
452 return RCt;
453 } /* _KfsDirNodeFindNode () */
454
455 /*)))
456 |||
457 +++ Unified DirEditor
458 |||
459 (((*/
460 static
461 rc_t CC
_KfsDir_dispose_v1(const struct XFSEditor * self)462 _KfsDir_dispose_v1 ( const struct XFSEditor * self )
463 {
464 /*
465 pLogMsg ( klogDebug, "_KfsDir_dispose_v1 ( $(editor) )", "editor=%p", ( void * ) self );
466 */
467
468 if ( self != NULL ) {
469 free ( ( struct XFSDirEditor * ) self );
470 }
471
472 return 0;
473 } /* _KfsDir_dispose_v1 () */
474
475 static
476 rc_t CC
_KfsDir_list_v1(const struct XFSDirEditor * self,const struct KNamelist ** List)477 _KfsDir_list_v1 (
478 const struct XFSDirEditor * self,
479 const struct KNamelist ** List
480 )
481 {
482 KDirectory * NativeDir;
483 const struct XFSKfsNode * Node;
484 struct KNamelist * TempList;
485 rc_t RCt;
486
487 RCt = 0;
488 NativeDir = NULL;
489 Node = NULL;
490 TempList = NULL;
491
492 if ( self == NULL || List == NULL ) {
493 return XFS_RC ( rcNull );
494 }
495 * List = NULL;
496
497 Node = ( const struct XFSKfsNode * ) XFSEditorNode (
498 & ( self -> Papahen )
499 );
500 if ( Node == NULL ) {
501 return XFS_RC ( rcInvalid );
502 }
503
504 if ( Node -> path == NULL ) {
505 return XFS_RC ( rcInvalid );
506 }
507
508 if ( Node -> type != kxfsDir ) {
509 return XFS_RC ( rcInvalid );
510 }
511
512 RCt = KDirectoryNativeDir ( & NativeDir );
513 if ( RCt == 0 ) {
514 RCt = KDirectoryList (
515 NativeDir,
516 & TempList,
517 NULL, /* Filter Func */
518 NULL, /* Filter Data */
519 Node -> path
520 );
521 if ( RCt == 0 ) {
522 * List = TempList;
523 }
524 else {
525 if ( TempList != NULL ) {
526 KNamelistRelease ( TempList );
527 }
528 }
529
530 KDirectoryRelease ( NativeDir );
531 }
532
533 return RCt;
534 } /* _KfsDir_list_v1 () */
535
536 static
537 rc_t CC
_KfsDir_find_v1(const struct XFSDirEditor * self,const char * Name,const struct XFSNode ** Node)538 _KfsDir_find_v1 (
539 const struct XFSDirEditor * self,
540 const char * Name,
541 const struct XFSNode ** Node
542 )
543 {
544 KDirectory * NativeDir;
545 const struct XFSKfsNode * KfsNode;
546 struct XFSKfsNode * TempNode;
547 uint32_t FileType;
548 XFSNType Type;
549 char FullPath [ XFS_SIZE_4096 ];
550 size_t NumWrit;
551 rc_t RCt;
552
553 RCt = 0;
554 NativeDir = NULL;
555 KfsNode = NULL;
556 TempNode = NULL;
557 FileType = kptNotFound;
558 Type = kxfsNotFound;
559 NumWrit = 0;
560 * FullPath = 0;
561
562 if ( self == NULL || Name == NULL || Node == NULL ) {
563 return XFS_RC ( rcNull );
564 }
565
566 * Node = NULL;
567
568 KfsNode = ( const struct XFSKfsNode * ) XFSEditorNode (
569 & ( self -> Papahen )
570 );
571 if ( KfsNode == NULL ) {
572 return XFS_RC ( rcInvalid );
573 }
574
575 if ( KfsNode -> path == NULL ) {
576 return XFS_RC ( rcInvalid );
577 }
578
579 RCt = string_printf (
580 FullPath,
581 sizeof ( FullPath ),
582 & NumWrit,
583 "%s/%s",
584 KfsNode -> path,
585 Name
586 );
587 if ( RCt == 0 ) {
588
589 RCt = KDirectoryNativeDir ( & NativeDir );
590 if ( RCt == 0 ) {
591 FileType = KDirectoryPathType ( NativeDir, FullPath );
592 switch ( FileType ) {
593 case kptFile :
594 Type = kxfsFile;
595 break;
596 case kptDir :
597 Type = kxfsDir;
598 break;
599 default :
600 RCt = XFS_RC ( rcUnsupported );
601 break;
602 }
603 if ( RCt == 0 ) {
604 RCt = XFSKfsNodeMakeEx (
605 & TempNode,
606 Type,
607 Name,
608 FullPath,
609 KfsNode -> perm
610 );
611 if ( RCt == 0 ) {
612 * Node = ( const struct XFSNode * ) TempNode;
613 }
614 }
615
616 KDirectoryRelease ( NativeDir );
617 }
618 }
619
620 return RCt;
621 } /* _KfsDir_find_v1 () */
622
623 static
624 rc_t CC
_KfsDir_create_file_v1(const struct XFSDirEditor * self,const char * Name,XFSNMode Mode,const struct XFSHandle ** Handle)625 _KfsDir_create_file_v1 (
626 const struct XFSDirEditor * self,
627 const char * Name,
628 XFSNMode Mode,
629 const struct XFSHandle ** Handle
630 )
631 {
632 struct KDirectory * NativeDir;
633 struct KFile * File;
634 bool Update;
635 KCreateMode CreateMode;
636 char Path [ XFS_SIZE_4096 ];
637 struct XFSKfsNode * KfsNode, * TempNode;
638 struct XFSKfsFileEditor * FileEditor;
639 const struct XFSHandle * TempHandle;
640 size_t NumWritten;
641 rc_t RCt;
642
643 NativeDir = NULL;
644 File = NULL;
645 Update = false;
646 CreateMode = kcmCreate;
647 * Path = 0;
648 KfsNode = TempNode = NULL;
649 FileEditor = NULL;
650 TempHandle = NULL;
651 NumWritten = 0;
652 RCt = 0;
653
654 if ( self == NULL || Name == NULL || Handle == NULL ) {
655 return XFS_RC ( rcNull );
656 }
657
658 * Handle = NULL;
659
660 KfsNode = ( struct XFSKfsNode * ) XFSEditorNode (
661 & ( self -> Papahen )
662 );
663 if ( KfsNode -> path == NULL ) {
664 return XFS_RC ( rcInvalid );
665 }
666
667 RCt = string_printf (
668 Path,
669 sizeof ( Path ),
670 & NumWritten,
671 "%s/%s",
672 KfsNode -> path,
673 Name
674 );
675 if ( RCt != 0 ) {
676 return RCt;
677 }
678
679 Update = Mode == kxfsReadWrite;
680 CreateMode = kcmCreate;
681
682 /* Here we are */
683 RCt = KDirectoryNativeDir ( & NativeDir );
684 if ( RCt == 0 ) {
685 RCt = KDirectoryCreateFile (
686 NativeDir,
687 & File,
688 Update,
689 XFSPermRODefNodeNum (),
690 CreateMode,
691 Path
692 );
693 if ( RCt == 0 ) {
694 RCt = XFSKfsNodeMakeEx (
695 & TempNode,
696 kxfsFile,
697 Name,
698 Path,
699 KfsNode -> perm
700 );
701 if ( RCt == 0 ) {
702 RCt = XFSNodeFileEditor (
703 & ( TempNode -> node ),
704 ( const struct XFSFileEditor ** ) & FileEditor
705 );
706 if ( RCt == 0 ) {
707 FileEditor -> File = File;
708 RCt = XFSHandleMake (
709 & ( TempNode -> node ),
710 & TempHandle
711 );
712 if ( RCt == 0 ) {
713 XFSHandleSet ( TempHandle, FileEditor );
714
715 * Handle = TempHandle;
716 }
717 }
718 }
719 }
720
721 KDirectoryRelease ( NativeDir );
722 }
723
724 if ( RCt != 0 ) {
725 * Handle = NULL;
726
727 if ( TempHandle != NULL ) {
728 XFSHandleRelease ( TempHandle );
729 }
730 else {
731 if ( FileEditor != NULL ) {
732 XFSEditorDispose ( ( const struct XFSEditor * ) FileEditor );
733 }
734 }
735
736 if ( File != NULL ) {
737 KFileRelease ( File );
738 }
739 }
740
741 return RCt;
742 } /* _KfsDir_create_file_v1 () */
743
744 static
745 rc_t CC
_KfsDir_create_dir_v1(const struct XFSDirEditor * self,const char * Name)746 _KfsDir_create_dir_v1 (
747 const struct XFSDirEditor * self,
748 const char * Name
749 )
750 {
751 rc_t RCt;
752 KDirectory * NativeDir;
753 struct XFSKfsNode * KfsNode;
754 char Path [ XFS_SIZE_4096 ];
755 size_t NumWritten;
756
757 RCt = 0;
758 NativeDir = NULL;
759 KfsNode = NULL;
760 * Path = 0;
761 NumWritten = 0;
762
763 if ( self == NULL || Name == NULL ) {
764 return XFS_RC ( rcNull );
765 }
766
767 KfsNode = ( struct XFSKfsNode * ) XFSEditorNode (
768 & ( self -> Papahen )
769 );
770 if ( KfsNode -> path == NULL ) {
771 return XFS_RC ( rcInvalid );
772 }
773
774 RCt = string_printf (
775 Path,
776 sizeof ( Path ),
777 & NumWritten,
778 "%s/%s",
779 KfsNode -> path,
780 Name
781 );
782 if ( RCt != 0 ) {
783 return RCt;
784 }
785
786 RCt = KDirectoryNativeDir ( & NativeDir );
787 if ( RCt == 0 ) {
788 RCt = KDirectoryCreateDir (
789 NativeDir,
790 XFSPermRODefContNum (),
791 kcmCreate,
792 Path
793 );
794
795 KDirectoryRelease ( NativeDir );
796 }
797
798 return RCt;
799 } /* _KfsDir_create_dir_v1 () */
800
801 static
802 rc_t CC
_KfsDir_delete_v1(const struct XFSDirEditor * self,const char * Name)803 _KfsDir_delete_v1 (
804 const struct XFSDirEditor * self,
805 const char * Name
806 )
807 {
808 rc_t RCt;
809 KDirectory * NativeDir;
810 struct XFSKfsNode * KfsNode;
811 char Path [ XFS_SIZE_4096 ];
812 size_t NumWritten;
813
814 RCt = 0;
815 NativeDir = NULL;
816 KfsNode = NULL;
817 * Path = 0;
818 NumWritten = 0;
819
820 if ( self == NULL || Name == NULL ) {
821 return XFS_RC ( rcNull );
822 }
823
824 KfsNode = ( struct XFSKfsNode * ) XFSEditorNode (
825 & ( self -> Papahen )
826 );
827 if ( KfsNode -> path == NULL ) {
828 return XFS_RC ( rcInvalid );
829 }
830
831 RCt = string_printf (
832 Path,
833 sizeof ( Path ),
834 & NumWritten,
835 "%s/%s",
836 KfsNode -> path,
837 Name
838 );
839 if ( RCt != 0 ) {
840 return RCt;
841 }
842
843 RCt = KDirectoryNativeDir ( & NativeDir );
844 if ( RCt == 0 ) {
845 RCt = KDirectoryRemove ( NativeDir, true, Path );
846
847 KDirectoryRelease ( NativeDir );
848 }
849
850 return RCt;
851 } /* _KfsDir_delete_v1 () */
852
853 rc_t CC
_KfsDir_move_v1(const struct XFSDirEditor * self,const char * OldName,const struct XFSNode * NewDir,const char * NewName)854 _KfsDir_move_v1 (
855 const struct XFSDirEditor * self,
856 const char * OldName,
857 const struct XFSNode * NewDir,
858 const char * NewName
859 )
860 {
861 rc_t RCt;
862 struct XFSKfsNode * KfsNode;
863 struct XFSKfsNode * NewKfsNode;
864 KDirectory * NativeDir;
865 char OldPath [ XFS_SIZE_4096 ];
866 char NewPath [ XFS_SIZE_4096 ];
867 size_t NumWritten;
868
869 RCt = 0;
870 KfsNode = NULL;
871 NewKfsNode = NULL;
872 NativeDir = NULL;
873 * OldPath = * NewPath = 0;
874 NumWritten = 0;
875
876 if ( self == NULL || OldName == NULL || NewDir == NULL
877 || NewName == NULL
878 ) {
879 return XFS_RC ( rcNull );
880 }
881
882 /*) TODO it is temporary, until we will do
883 (*/
884 if ( XFSNodeFlavor ( NewDir ) !=
885 XFSNodeFlavor ( ( self -> Papahen ) . Node ) ) {
886 return XFS_RC ( rcInvalid );
887 }
888
889 KfsNode = ( struct XFSKfsNode * ) XFSEditorNode (
890 & ( self -> Papahen )
891 );
892 if ( KfsNode -> path == NULL ) {
893 return XFS_RC ( rcInvalid );
894 }
895
896 NewKfsNode = ( struct XFSKfsNode * ) NewDir;
897 if ( NewKfsNode -> path == NULL ) {
898 return XFS_RC ( rcInvalid );
899 }
900
901 RCt = string_printf (
902 OldPath,
903 sizeof ( OldPath ),
904 & NumWritten,
905 "%s/%s",
906 KfsNode -> path,
907 OldName
908 );
909 if ( RCt != 0 ) {
910 return RCt;
911 }
912
913 RCt = string_printf (
914 NewPath,
915 sizeof ( NewPath ),
916 & NumWritten,
917 "%s/%s",
918 NewKfsNode -> path,
919 NewName
920 );
921 if ( RCt != 0 ) {
922 return RCt;
923 }
924
925 RCt = KDirectoryNativeDir ( & NativeDir );
926 if ( RCt == 0 ) {
927 RCt = KDirectoryRename ( NativeDir, true, OldPath, NewPath );
928
929 KDirectoryRelease ( NativeDir );
930 }
931
932 return RCt;
933 } /* _KfsDir_move_v1 () */
934
935 rc_t CC
_KfsNodeDir_v1(const struct XFSNode * self,const struct XFSDirEditor ** Dir)936 _KfsNodeDir_v1 (
937 const struct XFSNode * self,
938 const struct XFSDirEditor ** Dir
939 )
940 {
941 rc_t RCt;
942 struct XFSDirEditor * Editor;
943
944 RCt = 0;
945 Editor = NULL;
946
947 if ( self == NULL || Dir == NULL ) {
948 return XFS_RC ( rcNull );
949 }
950
951 * Dir = NULL;
952
953 if ( ( ( struct XFSKfsNode * ) self ) -> type != kxfsDir ) {
954 return XFS_RC ( rcInvalid );
955 }
956
957 Editor = calloc ( 1, sizeof ( struct XFSDirEditor ) );
958 if ( Editor == NULL ) {
959 return XFS_RC ( rcExhausted );
960 }
961
962 RCt = XFSEditorInit (
963 & ( Editor -> Papahen ),
964 self,
965 _KfsDir_dispose_v1
966 );
967
968 if ( RCt == 0 ) {
969 Editor -> list = _KfsDir_list_v1;
970 Editor -> find = _KfsDir_find_v1;
971 Editor -> create_file = _KfsDir_create_file_v1;
972 Editor -> create_dir = _KfsDir_create_dir_v1;
973 Editor -> delete = _KfsDir_delete_v1;
974 Editor -> move = _KfsDir_move_v1;
975
976 * Dir = Editor;
977 }
978 else {
979 free ( Editor );
980 }
981
982 return RCt;
983 } /* _KfsNodeDir_v1 () */
984
985 /*)))
986 |||
987 +++ Unified FileEditor
988 |||
989 (((*/
990
991 static
992 rc_t CC
_KfsFile_dispose_v1(const struct XFSEditor * self)993 _KfsFile_dispose_v1 ( const struct XFSEditor * self )
994 {
995 struct XFSKfsFileEditor * Editor = ( struct XFSKfsFileEditor * ) self;
996
997 /*
998 pLogMsg ( klogDebug, "_KfsFile_dispose_v1 ( $(editor) )", "editor=%p", ( void * ) self );
999 */
1000
1001 if ( Editor != NULL ) {
1002 if ( Editor -> File != NULL ) {
1003 KFileRelease ( Editor -> File );
1004
1005 Editor -> File = NULL;
1006 }
1007
1008 free ( Editor );
1009 }
1010
1011 return 0;
1012 } /* _KfsFile_dispose_v1 () */
1013
1014 static
1015 rc_t CC
_KfsFile_open_v1(const struct XFSFileEditor * self,XFSNMode Mode)1016 _KfsFile_open_v1 (
1017 const struct XFSFileEditor * self,
1018 XFSNMode Mode
1019 )
1020 {
1021 KFile * File;
1022 const struct XFSKfsNode * Node;
1023 KDirectory * NativeDir;
1024 rc_t RCt;
1025
1026 File = NULL;
1027 Node = NULL;
1028 NativeDir = NULL;
1029 RCt = 0;
1030
1031 if ( self == NULL ) {
1032 return XFS_RC ( rcNull );
1033 }
1034
1035 Node = ( const struct XFSKfsNode * ) XFSEditorNode (
1036 & ( self -> Papahen )
1037 );
1038 if ( Node == NULL ) {
1039 return XFS_RC ( rcInvalid );
1040 }
1041
1042 if ( Node -> type != kxfsFile ) {
1043 return XFS_RC ( rcInvalid );
1044 }
1045
1046 if ( Node -> path == NULL ) {
1047 return XFS_RC ( rcInvalid );
1048 }
1049
1050 RCt = KDirectoryNativeDir ( & NativeDir );
1051 if ( RCt == 0 ) {
1052 if ( Mode == kxfsRead ) {
1053 RCt = KDirectoryOpenFileRead (
1054 NativeDir,
1055 ( const KFile ** ) & File,
1056 Node -> path
1057 );
1058 }
1059 else {
1060 RCt = KDirectoryOpenFileWrite (
1061 NativeDir,
1062 & File,
1063 ( Mode & kxfsRead ) == kxfsRead,
1064 Node -> path
1065 );
1066 }
1067 if ( RCt == 0 ) {
1068 ( ( struct XFSKfsFileEditor * ) self ) -> File = File;
1069 }
1070
1071 KDirectoryRelease ( NativeDir );
1072 }
1073
1074 return RCt;
1075 } /* _KfsFile_open_v1 () */
1076
1077 static
1078 rc_t CC
_KfsFile_close_v1(const struct XFSFileEditor * self)1079 _KfsFile_close_v1 ( const struct XFSFileEditor * self )
1080 {
1081 struct XFSKfsFileEditor * Editor;
1082 rc_t RCt;
1083
1084 Editor = NULL;
1085 RCt = 0;
1086
1087 if ( self == NULL ) {
1088 return XFS_RC ( rcNull );
1089 }
1090
1091
1092 Editor = ( struct XFSKfsFileEditor * ) self;
1093
1094 if ( Editor -> File != NULL ) {
1095 RCt = KFileRelease ( Editor -> File );
1096
1097 Editor -> File = NULL;
1098 }
1099
1100 return RCt;
1101 } /* _KfsFile_close_v1 () */
1102
1103 static
1104 rc_t CC
_KfsFile_read_v1(const struct XFSFileEditor * self,uint64_t Offset,void * Buffer,size_t SizeToRead,size_t * NumReaded)1105 _KfsFile_read_v1 (
1106 const struct XFSFileEditor * self,
1107 uint64_t Offset,
1108 void * Buffer,
1109 size_t SizeToRead,
1110 size_t * NumReaded
1111 )
1112 {
1113 struct XFSKfsFileEditor * Editor;
1114 rc_t RCt;
1115
1116 Editor = NULL;
1117 RCt = 0;
1118
1119 if ( self == NULL ) {
1120 return XFS_RC ( rcNull );
1121 }
1122
1123 Editor = ( struct XFSKfsFileEditor * ) self;
1124
1125 if ( Editor -> File == NULL ) {
1126 return XFS_RC ( rcInvalid );
1127 }
1128
1129 RCt = KFileReadAll (
1130 Editor -> File,
1131 Offset,
1132 Buffer,
1133 SizeToRead,
1134 NumReaded
1135 );
1136
1137 /* here may be debutt */
1138
1139 return RCt;
1140 } /* _KfsFile_read_v1 () */
1141
1142 static
1143 rc_t CC
_KfsFile_write_v1(const struct XFSFileEditor * self,uint64_t Offset,const void * Buffer,size_t SizeToWrite,size_t * NumWritten)1144 _KfsFile_write_v1 (
1145 const struct XFSFileEditor * self,
1146 uint64_t Offset,
1147 const void * Buffer,
1148 size_t SizeToWrite,
1149 size_t * NumWritten
1150 )
1151 {
1152 struct XFSKfsFileEditor * Editor;
1153 rc_t RCt;
1154
1155 Editor = NULL;
1156 RCt = 0;
1157
1158 if ( self == NULL ) {
1159 return XFS_RC ( rcNull );
1160 }
1161
1162 Editor = ( struct XFSKfsFileEditor * ) self;
1163
1164 if ( Editor -> File == NULL ) {
1165 return XFS_RC ( rcInvalid );
1166 }
1167
1168 RCt = KFileWriteAll (
1169 Editor -> File,
1170 Offset,
1171 Buffer,
1172 SizeToWrite,
1173 NumWritten
1174 );
1175
1176
1177 /* here may be debutt */
1178
1179 return RCt;
1180 } /* _KfsFile_write_v1 () */
1181
1182 static
1183 rc_t CC
_KfsFile_size_v1(const struct XFSFileEditor * self,uint64_t * Size)1184 _KfsFile_size_v1 (
1185 const struct XFSFileEditor * self,
1186 uint64_t * Size
1187 )
1188 {
1189 const struct XFSKfsNode * Node;
1190 KDirectory * NativeDir;
1191 const struct KFile * File;
1192 uint64_t TempSize;
1193 rc_t RCt;
1194
1195 Node = NULL;
1196 NativeDir = NULL;
1197 File = NULL;
1198 TempSize = 0;
1199 RCt = 0;
1200
1201 XFS_CSA ( Size, 0 )
1202 XFS_CAN ( self )
1203 XFS_CAN ( Size )
1204
1205 Node = ( const struct XFSKfsNode * ) XFSEditorNode (
1206 & ( self -> Papahen )
1207 );
1208
1209 if ( Node == NULL ) {
1210 return XFS_RC ( rcInvalid );
1211 }
1212
1213 if ( Node -> type != kxfsFile ) {
1214 return XFS_RC ( rcInvalid );
1215 }
1216
1217 if ( Node -> path == NULL ) {
1218 return XFS_RC ( rcInvalid );
1219 }
1220
1221 File = ( ( struct XFSKfsFileEditor * ) self ) -> File;
1222 if ( File == NULL ) {
1223 RCt = KDirectoryNativeDir ( & NativeDir );
1224 if ( RCt == 0 ) {
1225 RCt = KDirectoryFileSize (
1226 NativeDir,
1227 & TempSize,
1228 Node -> path
1229 );
1230
1231 KDirectoryRelease ( NativeDir );
1232 }
1233 }
1234 else {
1235 RCt = KFileSize ( File, & TempSize );
1236 }
1237 if ( RCt == 0 ) {
1238 * Size = TempSize;
1239 }
1240
1241 return RCt;
1242 } /* _KfsFile_size_v1 () */
1243
1244 static
1245 rc_t CC
_KfsFile_set_size_v1(const struct XFSFileEditor * self,uint64_t Size)1246 _KfsFile_set_size_v1 (
1247 const struct XFSFileEditor * self,
1248 uint64_t Size
1249 )
1250 {
1251 rc_t RCt;
1252 const struct XFSKfsNode * Node;
1253 KDirectory * NativeDir;
1254 struct KFile * File;
1255
1256 RCt = 0;
1257 Node = NULL;
1258 NativeDir = NULL;
1259 File = NULL;
1260
1261 XFS_CAN ( self )
1262
1263 Node = ( const struct XFSKfsNode * ) XFSEditorNode (
1264 & ( self -> Papahen )
1265 );
1266
1267 if ( Node == NULL ) {
1268 return XFS_RC ( rcInvalid );
1269 }
1270
1271 if ( Node -> type != kxfsFile ) {
1272 return XFS_RC ( rcInvalid );
1273 }
1274
1275 if ( Node -> path == NULL ) {
1276 return XFS_RC ( rcInvalid );
1277 }
1278
1279 File = ( ( struct XFSKfsFileEditor * ) self ) -> File;
1280 if ( File == NULL ) {
1281
1282 RCt = KDirectoryNativeDir ( & NativeDir );
1283 if ( RCt == 0 ) {
1284 RCt = KDirectorySetFileSize ( NativeDir, Size, Node -> path);
1285
1286 KDirectoryRelease ( NativeDir );
1287 }
1288 }
1289 else {
1290 RCt = KFileSetSize ( File, Size );
1291 }
1292
1293 return RCt;
1294 } /* _KfsFile_set_size_v1 () */
1295
1296 rc_t CC
_KfsNodeFile_v1(const struct XFSNode * self,const struct XFSFileEditor ** File)1297 _KfsNodeFile_v1 (
1298 const struct XFSNode * self,
1299 const struct XFSFileEditor ** File
1300 )
1301 {
1302 rc_t RCt;
1303 struct XFSKfsFileEditor * FileEditor;
1304 struct XFSFileEditor * Editor;
1305
1306 RCt = 0;
1307 FileEditor = NULL;
1308 Editor = NULL;
1309
1310 if ( self == NULL || File == NULL ) {
1311 return XFS_RC ( rcNull );
1312 }
1313
1314 * File = NULL;
1315
1316 if ( ( ( struct XFSKfsNode * ) self ) -> type != kxfsFile ) {
1317 return XFS_RC ( rcInvalid );
1318 }
1319
1320 FileEditor = calloc ( 1, sizeof ( struct XFSKfsFileEditor ) );
1321 if ( FileEditor == NULL ) {
1322 return XFS_RC ( rcExhausted );
1323 }
1324
1325 Editor = & ( FileEditor -> Papahen );
1326
1327 RCt = XFSEditorInit (
1328 & ( Editor -> Papahen ),
1329 self,
1330 _KfsFile_dispose_v1
1331 );
1332
1333 if ( RCt == 0 ) {
1334 Editor -> open = _KfsFile_open_v1;
1335 Editor -> close = _KfsFile_close_v1;
1336 Editor -> read = _KfsFile_read_v1;
1337 Editor -> write = _KfsFile_write_v1;
1338 Editor -> size = _KfsFile_size_v1;
1339 Editor -> set_size = _KfsFile_set_size_v1;
1340
1341 * File = Editor;
1342 }
1343 else {
1344 free ( Editor );
1345 }
1346
1347 return RCt;
1348 } /* _KfsNodeFile_v1 () */
1349
1350 /*)))
1351 |||
1352 +++ Unified Attr
1353 |||
1354 (((*/
1355
1356 static
1357 rc_t CC
_KfsAttr_dispose_v1(const struct XFSEditor * self)1358 _KfsAttr_dispose_v1 ( const struct XFSEditor * self )
1359 {
1360 /*
1361 pLogMsg ( klogDebug, "_KfsAttr_dispose_v1 ( $(editor) )", "editor=%p", ( void * ) self );
1362 */
1363
1364 if ( self != NULL ) {
1365 free ( ( struct XFSKfsAttrEditor * ) self );
1366 }
1367
1368 return 0;
1369 } /* _KfsAttr_dispose_v1 () */
1370
1371 /*)) Something unusual. Will check-initialize NativeDir and Node
1372 // NativeDir and Node could be NULL
1373 ((*/
1374 static
1375 rc_t CC
_KfsAttr_init_check_v1(const struct XFSAttrEditor * self,const struct XFSKfsNode ** Node,KDirectory ** NativeDir)1376 _KfsAttr_init_check_v1 (
1377 const struct XFSAttrEditor * self,
1378 const struct XFSKfsNode ** Node,
1379 KDirectory ** NativeDir
1380
1381 )
1382 {
1383 rc_t RCt;
1384 const struct XFSKfsNode * RetNode;
1385 KDirectory * Dir;
1386
1387 RCt = 0;
1388 RetNode = NULL;
1389 Dir = NULL;
1390
1391 if ( Node != NULL ) {
1392 * Node = NULL;
1393 }
1394
1395 if ( NativeDir != NULL ) {
1396 * NativeDir = NULL;
1397 }
1398
1399 if ( self == NULL ) {
1400 return XFS_RC ( rcNull );
1401 }
1402
1403 RetNode = ( const struct XFSKfsNode * ) XFSEditorNode (
1404 & ( self -> Papahen )
1405 );
1406
1407 if ( RetNode == NULL ) {
1408 return XFS_RC ( rcInvalid );
1409 }
1410
1411 if ( RetNode -> path == NULL ) {
1412 return XFS_RC ( rcInvalid );
1413 }
1414
1415 if ( NativeDir != NULL ) {
1416 RCt = KDirectoryNativeDir ( & Dir );
1417 if ( RCt == 0 ) {
1418 * NativeDir = Dir;
1419 }
1420 }
1421
1422 if ( RCt == 0 ) {
1423 if ( Node != NULL ) {
1424 * Node = RetNode;
1425 }
1426 }
1427
1428 return RCt;
1429 } /* _KfsAttr_init_check_v1 () */
1430
1431 static
1432 rc_t CC
_KfsAttr_permissions_v1(const struct XFSAttrEditor * self,const char ** Permissions)1433 _KfsAttr_permissions_v1 (
1434 const struct XFSAttrEditor * self,
1435 const char ** Permissions
1436 )
1437 {
1438 const struct XFSKfsNode * Node;
1439 KDirectory * NativeDir;
1440 uint32_t Access;
1441 char * BF;
1442 rc_t RCt;
1443
1444 Node = NULL;
1445 NativeDir = NULL;
1446 BF = NULL;
1447 RCt = 0;
1448
1449 if ( Permissions == NULL ) {
1450 return XFS_RC ( rcNull );
1451 }
1452 * Permissions = NULL;
1453
1454 RCt = _KfsAttr_init_check_v1 ( self, & Node, & NativeDir );
1455 if ( RCt == 0 ) {
1456 if ( Node -> perm != NULL ) {
1457 * Permissions = Node -> perm;
1458 }
1459 else {
1460 RCt = KDirectoryAccess ( NativeDir, & Access, Node -> path );
1461 if ( RCt == 0 ) {
1462 BF = ( ( struct XFSKfsAttrEditor * ) self ) -> perm;
1463 RCt = XFSPermToChar (
1464 Access,
1465 BF,
1466 sizeof ( ( ( struct XFSKfsAttrEditor * ) self ) -> perm )
1467 );
1468 if ( RCt == 0 ) {
1469 if ( Node -> type == kxfsDir ) {
1470 BF [ 0 ] = 'r';
1471 BF [ 2 ] = 'x';
1472 }
1473
1474 * Permissions = ( const char * ) BF;
1475 }
1476 }
1477 }
1478
1479 KDirectoryRelease ( NativeDir );
1480 }
1481
1482 return RCt;
1483 } /* _KfsAttr_permissions_v1 () */
1484
1485 static
1486 rc_t CC
_KfsAttr_set_permissions_v1(const struct XFSAttrEditor * self,const char * Permissions)1487 _KfsAttr_set_permissions_v1 (
1488 const struct XFSAttrEditor * self,
1489 const char * Permissions
1490 )
1491 {
1492 rc_t RCt;
1493 const struct XFSKfsNode * Node;
1494 KDirectory * NativeDir;
1495 uint32_t Access;
1496
1497 RCt = 0;
1498 NativeDir = NULL;
1499 Node = NULL;
1500
1501 if ( Permissions == NULL ) {
1502 return XFS_RC ( rcNull );
1503 }
1504
1505 RCt = _KfsAttr_init_check_v1 ( self, & Node, & NativeDir );
1506 if ( RCt == 0 ) {
1507 if ( Node -> perm != NULL ) {
1508 RCt = XFSPermToNum ( Node -> perm, & Access );
1509 }
1510 else {
1511 RCt = XFSPermToNum ( Permissions, & Access );
1512 }
1513 if ( RCt == 0 ) {
1514 RCt = KDirectorySetAccess (
1515 NativeDir,
1516 false,
1517 Access,
1518 Access,
1519 Node -> path
1520 );
1521 }
1522
1523 KDirectoryRelease ( NativeDir );
1524 }
1525
1526 return RCt;
1527 } /* _KfsAttr_set_permissions_v1 () */
1528
1529 static
1530 rc_t CC
_KfsAttr_date_v1(const struct XFSAttrEditor * self,KTime_t * Time)1531 _KfsAttr_date_v1 (
1532 const struct XFSAttrEditor * self,
1533 KTime_t * Time
1534 )
1535 {
1536 const struct XFSKfsNode * Node;
1537 KDirectory * NativeDir;
1538 KTime_t TempTime;
1539 rc_t RCt;
1540
1541 Node = NULL;
1542 NativeDir = NULL;
1543 TempTime = 0;
1544 RCt = 0;
1545
1546 if ( Time == NULL ) {
1547 return XFS_RC ( rcNull );
1548 }
1549 * Time = 0;
1550
1551 RCt = _KfsAttr_init_check_v1 ( self, & Node, & NativeDir );
1552 if ( RCt == 0 ) {
1553 RCt = KDirectoryDate ( NativeDir, & TempTime, Node -> path );
1554 if ( RCt == 0 ) {
1555 * Time = TempTime;
1556 }
1557
1558 KDirectoryRelease ( NativeDir );
1559 }
1560
1561 return RCt;
1562 } /* _KfsAttr_date_v1 () */
1563
1564 static
1565 rc_t CC
_KfsAttr_set_date_v1(const struct XFSAttrEditor * self,KTime_t Time)1566 _KfsAttr_set_date_v1 (
1567 const struct XFSAttrEditor * self,
1568 KTime_t Time
1569 )
1570 {
1571 rc_t RCt;
1572 const struct XFSKfsNode * Node;
1573 KDirectory * NativeDir;
1574
1575 RCt = 0;
1576 NativeDir = NULL;
1577 Node = NULL;
1578
1579 RCt = _KfsAttr_init_check_v1 ( self, & Node, & NativeDir );
1580 if ( RCt == 0 ) {
1581 RCt = KDirectorySetDate ( NativeDir, true, Time, Node -> path );
1582
1583 KDirectoryRelease ( NativeDir );
1584 }
1585
1586 return RCt;
1587 } /* _KfsAttr_set_date_v1 () */
1588
1589 static
1590 rc_t CC
_KfsAttr_type_v1(const struct XFSAttrEditor * self,XFSNType * Type)1591 _KfsAttr_type_v1 (
1592 const struct XFSAttrEditor * self,
1593 XFSNType * Type
1594 )
1595 {
1596 const struct XFSKfsNode * Node;
1597 rc_t RCt;
1598
1599 Node = NULL;
1600 RCt = 0;
1601
1602 if ( Type == NULL ) {
1603 return XFS_RC ( rcNull );
1604 }
1605 * Type = kxfsFile;
1606
1607 RCt = _KfsAttr_init_check_v1 ( self, & Node, NULL );
1608 if ( RCt == 0 ) {
1609 * Type = Node -> type;
1610 }
1611
1612 return RCt;
1613 } /* _KfsAttr_type_v1 () */
1614
1615 static
1616 rc_t CC
_KfsNodeAttr_v1(const struct XFSNode * self,const struct XFSAttrEditor ** Attr)1617 _KfsNodeAttr_v1 (
1618 const struct XFSNode * self,
1619 const struct XFSAttrEditor ** Attr
1620 )
1621 {
1622 rc_t RCt;
1623 struct XFSKfsAttrEditor * KfsEditor;
1624 struct XFSAttrEditor * Editor;
1625
1626 RCt = 0;
1627 KfsEditor = NULL;
1628 Editor = NULL;
1629
1630 if ( self == NULL || Attr == NULL ) {
1631 return XFS_RC ( rcNull );
1632 }
1633
1634 * Attr = NULL;
1635
1636 KfsEditor = calloc ( 1, sizeof ( struct XFSKfsAttrEditor ) );
1637 if ( KfsEditor == NULL ) {
1638 return XFS_RC ( rcExhausted );
1639 }
1640
1641 Editor = & ( KfsEditor -> Papahen );
1642
1643 RCt = XFSEditorInit (
1644 & ( Editor -> Papahen ),
1645 self,
1646 _KfsAttr_dispose_v1
1647 );
1648
1649 if ( RCt == 0 ) {
1650 Editor -> permissions = _KfsAttr_permissions_v1;
1651 Editor -> set_permissions = _KfsAttr_set_permissions_v1;
1652 Editor -> date = _KfsAttr_date_v1;
1653 Editor -> set_date = _KfsAttr_set_date_v1;
1654 Editor -> type = _KfsAttr_type_v1;
1655
1656 * Attr = Editor;
1657 }
1658 else {
1659 free ( KfsEditor );
1660 }
1661
1662 return RCt;
1663 } /* _KfsNodeAttr_v1 () */
1664
1665 /*)))
1666 |||
1667 +++ Unified Discribe
1668 |||
1669 (((*/
1670
1671 rc_t CC
_KfsNodeDescribe_v1(const struct XFSNode * self,char * Buffer,size_t BufferSize)1672 _KfsNodeDescribe_v1 (
1673 const struct XFSNode * self,
1674 char * Buffer,
1675 size_t BufferSize
1676 )
1677 {
1678 rc_t RCt;
1679 size_t NumWrit;
1680 const char * Abbr;
1681
1682 RCt = 0;
1683 NumWrit = 0;
1684 Abbr = NULL;
1685
1686 if ( Buffer == NULL || BufferSize == 0 ) {
1687 return XFS_RC ( rcNull );
1688 }
1689
1690 Abbr = ( ( const struct XFSKfsNode * ) self ) -> type == kxfsDir
1691 ? "DIR"
1692 : "FILE"
1693 ;
1694
1695 if ( self == NULL ) {
1696 string_printf (
1697 Buffer,
1698 BufferSize,
1699 & NumWrit,
1700 "NODE (%s)[NULL][NULL]",
1701 Abbr
1702 );
1703 }
1704 else {
1705 string_printf (
1706 Buffer,
1707 BufferSize,
1708 & NumWrit,
1709 "NODE (%s)[%s][0x%p]",
1710 Abbr,
1711 self -> Name,
1712 self
1713 );
1714 }
1715
1716 return RCt;
1717 } /* _KfsNodeDescribe_v1 () */
1718
1719 /*)))
1720 |||
1721 +++ FileNode lives here
1722 |||
1723 (((*/
1724
1725 /*))
1726 (( Node make/dispose
1727 ))
1728 ((*/
1729
1730 static
1731 rc_t CC
_KfsNodeConstructor(const struct XFSModel * Model,const struct XFSModelNode * Template,const char * Alias,XFSNType Type,const struct XFSNode ** Node)1732 _KfsNodeConstructor (
1733 const struct XFSModel * Model,
1734 const struct XFSModelNode * Template,
1735 const char * Alias,
1736 XFSNType Type,
1737 const struct XFSNode ** Node
1738 )
1739 {
1740 rc_t RCt;
1741 struct XFSKfsNode * TheNode;
1742 const char * NodeName;
1743
1744 RCt = 0;
1745 TheNode = NULL;
1746 NodeName = NULL;
1747
1748 if ( Model == NULL || Template == NULL || Node == NULL ) {
1749 return XFS_RC ( rcNull );
1750 }
1751
1752 * Node = NULL;
1753
1754 NodeName = Alias == NULL ? XFSModelNodeName ( Template ) : Alias;
1755
1756 RCt = XFSKfsNodeMakeEx (
1757 & TheNode,
1758 Type,
1759 NodeName,
1760 XFSModelNodeProperty ( Template, XFS_MODEL_SOURCE ),
1761 XFSModelNodeSecurity ( Template )
1762 );
1763 if ( RCt == 0 ) {
1764 * Node = ( struct XFSNode * ) TheNode;
1765 }
1766
1767 if ( RCt != 0 ) {
1768 * Node = NULL;
1769
1770 if ( TheNode != NULL ) {
1771 XFSKfsNodeDispose ( TheNode );
1772 }
1773 }
1774
1775 return RCt;
1776 } /* _KfsNodeConstructor () */
1777
1778 /*)))
1779 |||
1780 +++ Non-Teleport methods to create nodes
1781 |||
1782 (((*/
1783 LIB_EXPORT
1784 rc_t CC
XFSFileNodeMakeHandle(const struct XFSHandle ** Handle,struct XFSNode * FileNode,struct KFile * File)1785 XFSFileNodeMakeHandle (
1786 const struct XFSHandle ** Handle,
1787 struct XFSNode * FileNode,
1788 struct KFile * File
1789 )
1790 {
1791 rc_t RCt;
1792 const struct XFSHandle * TheHandle;
1793 struct XFSKfsFileEditor * Editor;
1794
1795 RCt = 0;
1796 TheHandle = NULL;
1797 Editor = NULL;
1798
1799 XFS_CSAN ( Handle )
1800 XFS_CAN ( Handle )
1801 XFS_CAN ( FileNode )
1802 XFS_CAN ( File )
1803
1804 RCt = XFSNodeFileEditor (
1805 FileNode,
1806 ( const struct XFSFileEditor ** ) & Editor
1807 );
1808 if ( RCt == 0 ) {
1809 Editor -> File = File;
1810
1811 RCt = XFSHandleMake ( FileNode, & TheHandle );
1812 if ( RCt == 0 ) {
1813 XFSHandleSet ( TheHandle, Editor );
1814
1815 * Handle = TheHandle;
1816 }
1817 }
1818
1819 if ( RCt != 0 ) {
1820 * Handle = NULL;
1821
1822 if ( TheHandle != NULL ) {
1823 XFSHandleRelease ( TheHandle );
1824 }
1825 else {
1826 if ( Editor != NULL ) {
1827 XFSEditorDispose ( ( const struct XFSEditor * ) Editor );
1828 }
1829 }
1830 }
1831
1832 return RCt;
1833 } /* XFSFileNodeMakeHandle () */
1834
1835 LIB_EXPORT
1836 rc_t CC
XFSFileNodeMake(struct XFSNode ** Node,const char * Path,const char * Name,const char * Perm)1837 XFSFileNodeMake (
1838 struct XFSNode ** Node,
1839 const char * Path,
1840 const char * Name,
1841 const char * Perm
1842 )
1843 {
1844 rc_t RCt;
1845 struct XFSKfsNode * TheNode;
1846
1847 RCt = 0;
1848 TheNode = NULL;
1849
1850 if ( Node != NULL ) {
1851 * Node = NULL;
1852 }
1853
1854 if ( Path == NULL || Name == NULL || Node == NULL ) {
1855 return XFS_RC ( rcNull );
1856 }
1857
1858 RCt = XFSKfsNodeMakeEx ( & TheNode, kxfsFile, Name, Path, Perm );
1859 if ( RCt == 0 ) {
1860 * Node = & ( TheNode -> node );
1861 }
1862
1863 return RCt;
1864 } /* XFSFileNodeMake () */
1865
1866 LIB_EXPORT
1867 rc_t CC
XFSDirNodeMake(struct XFSNode ** Node,const char * Path,const char * Name,const char * Perm)1868 XFSDirNodeMake (
1869 struct XFSNode ** Node,
1870 const char * Path,
1871 const char * Name,
1872 const char * Perm
1873 )
1874 {
1875 rc_t RCt;
1876 struct XFSKfsNode * TheNode;
1877
1878 RCt = 0;
1879 TheNode = NULL;
1880
1881 if ( Node != NULL ) {
1882 * Node = NULL;
1883 }
1884
1885 if ( Path == NULL || Name == NULL || Node == NULL ) {
1886 return XFS_RC ( rcNull );
1887 }
1888
1889 RCt = XFSKfsNodeMakeEx ( & TheNode, kxfsDir, Name, Path, Perm );
1890 if ( RCt == 0 ) {
1891 * Node = & ( TheNode -> node );
1892 }
1893
1894 return RCt;
1895 } /* XFSDirNodeMake () */
1896
1897 /*)))
1898 |||
1899 +++ FileNode has a Teleport, and it is HERE
1900 |||
1901 (((*/
1902 static
1903 rc_t CC
_FileNodeConstructor(const struct XFSModel * Model,const struct XFSModelNode * Template,const char * Alias,const struct XFSNode ** Node)1904 _FileNodeConstructor (
1905 const struct XFSModel * Model,
1906 const struct XFSModelNode * Template,
1907 const char * Alias,
1908 const struct XFSNode ** Node
1909 )
1910 {
1911 rc_t RCt;
1912
1913 RCt = _KfsNodeConstructor (
1914 Model,
1915 Template,
1916 Alias,
1917 kxfsFile,
1918 Node
1919 );
1920
1921 /*
1922 pLogMsg ( klogDebug, "_FileNodeConstructor ( $(model), $(template) (\"$(name)\"), \"$(alias)\" )", "model=%p,templat=%p,name=%s,alias=%s", ( void * ) Model, ( void * ) Template, XFSModelNodeName ( Template ), ( Alias == NULL ? "NULL" : Alias ) );
1923 */
1924
1925 return RCt;
1926 } /* _FileNodeConstructor () */
1927
1928 static
1929 rc_t CC
_FileNodeValidator(const struct XFSModel * Model,const struct XFSModelNode * Template,const char * Alias,uint32_t Flags)1930 _FileNodeValidator (
1931 const struct XFSModel * Model,
1932 const struct XFSModelNode * Template,
1933 const char * Alias,
1934 uint32_t Flags
1935 )
1936 {
1937 rc_t RCt;
1938
1939 RCt = 0;
1940
1941 /*
1942 pLogMsg ( klogDebug, "_FileNodeValidator ( $(model), $(template) (\"$(name)\"), \"$(alias)\" )", "model=%p,templat=%p,name=%s,alias=%s", ( void * ) Model, ( void * ) Template, XFSModelNodeName ( Template ), ( Alias == NULL ? "NULL" : Alias ) );
1943 */
1944
1945 return RCt;
1946 } /* _FileNodeValidator () */
1947
1948 static const struct XFSTeleport _sFileNodeTeleport = {
1949 _FileNodeConstructor,
1950 _FileNodeValidator,
1951 false
1952 };
1953
1954
1955 LIB_EXPORT
1956 rc_t CC
XFSFileProvider(const struct XFSTeleport ** Teleport)1957 XFSFileProvider ( const struct XFSTeleport ** Teleport )
1958 {
1959 if ( Teleport == NULL ) {
1960 return XFS_RC ( rcNull );
1961 }
1962
1963 * Teleport = & _sFileNodeTeleport;
1964
1965 return 0;
1966 } /* XFSFileProvider () */
1967
1968 /*)))
1969 |||
1970 +++ DirNode has a Teleport, and it is HERE
1971 |||
1972 (((*/
1973 static
1974 rc_t CC
_DirNodeConstructor(const struct XFSModel * Model,const struct XFSModelNode * Template,const char * Alias,const struct XFSNode ** Node)1975 _DirNodeConstructor (
1976 const struct XFSModel * Model,
1977 const struct XFSModelNode * Template,
1978 const char * Alias,
1979 const struct XFSNode ** Node
1980 )
1981 {
1982 rc_t RCt;
1983
1984 RCt = _KfsNodeConstructor (
1985 Model,
1986 Template,
1987 Alias,
1988 kxfsDir,
1989 Node
1990 );
1991
1992 /*
1993 pLogMsg ( klogDebug, "_DirNodeConstructor ( $(model), $(template) (\"$(name)\"), \"$(alias)\" )", "model=%p,templat=%p,name=%s,alias=%s", ( void * ) Model, ( void * ) Template, XFSModelNodeName ( Template ), ( Alias == NULL ? "NULL" : Alias ) );
1994 */
1995
1996 return RCt;
1997 } /* _DirNodeConstructor () */
1998
1999 static
2000 rc_t CC
_DirNodeValidator(const struct XFSModel * Model,const struct XFSModelNode * Template,const char * Alias,uint32_t Flags)2001 _DirNodeValidator (
2002 const struct XFSModel * Model,
2003 const struct XFSModelNode * Template,
2004 const char * Alias,
2005 uint32_t Flags
2006 )
2007 {
2008 rc_t RCt;
2009
2010 RCt = 0;
2011
2012 /*
2013 pLogMsg ( klogDebug, "_DirNodeValidator ( $(model), $(template) (\"$(name)\"), \"$(alias)\" )", "model=%p,templat=%p,name=%s,alias=%s", ( void * ) Model, ( void * ) Template, XFSModelNodeName ( Template ), ( Alias == NULL ? "NULL" : Alias ) );
2014 */
2015
2016 return RCt;
2017 } /* _DirNodeValidator () */
2018
2019 static const struct XFSTeleport _sDirNodeTeleport = {
2020 _DirNodeConstructor,
2021 _DirNodeValidator,
2022 false
2023 };
2024
2025
2026 LIB_EXPORT
2027 rc_t CC
XFSDirectoryProvider(const struct XFSTeleport ** Teleport)2028 XFSDirectoryProvider ( const struct XFSTeleport ** Teleport )
2029 {
2030 if ( Teleport == NULL ) {
2031 return XFS_RC ( rcNull );
2032 }
2033
2034 * Teleport = & _sDirNodeTeleport;
2035
2036 return 0;
2037 } /* XFSDirectoryProvider () */
2038
2039