1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . IO ;
4
+ using Cmf . CLI . Core ;
5
+ using Cmf . CLI . Core . Interfaces ;
6
+ using Cmf . CLI . Utilities ;
7
+ using Microsoft . TemplateEngine . Utils ;
8
+ using SMBLibrary ;
9
+ using SMBLibrary . Client ;
10
+
11
+ namespace Core . Objects
12
+ {
13
+ public class CIFSClient : ICIFSClient
14
+ {
15
+ public string Server { get ; private set ; }
16
+ public List < SharedFolder > SharedFolders { get ; private set ; }
17
+ public bool IsConnected { get ; private set ; }
18
+
19
+ private ISMBClient _smbClient ;
20
+ private string _domain ;
21
+ private string _username ;
22
+ private string _password ;
23
+
24
+ public CIFSClient ( string server , IEnumerable < Uri > uris )
25
+ {
26
+ Server = server ;
27
+ _smbClient = new SMB2Client ( ) ;
28
+ _domain = Environment . GetEnvironmentVariable ( "CIFS_DOMAIN" ) ;
29
+ _username = Environment . GetEnvironmentVariable ( "CIFS_USERNAME" ) ;
30
+ _password = Environment . GetEnvironmentVariable ( "CIFS_PASSWORD" ) ;
31
+ if ( string . IsNullOrEmpty ( _domain ) || string . IsNullOrEmpty ( _username ) || string . IsNullOrEmpty ( _password ) )
32
+ {
33
+ throw new CliException ( "CIFS credentials not found in environment variables" ) ;
34
+ }
35
+
36
+ Connect ( ) ;
37
+
38
+ if ( IsConnected )
39
+ {
40
+ SharedFolders = [ ] ;
41
+ uris . ForEach ( uri => SharedFolders . Add ( new SharedFolder ( uri , _smbClient ) ) ) ;
42
+ }
43
+ }
44
+
45
+ public void Connect ( )
46
+ {
47
+ Log . Debug ( $ "Connecting to SMB server { Server } with username { _username } ") ;
48
+ IsConnected = _smbClient . Connect ( Server , SMBTransportType . DirectTCPTransport ) ;
49
+ if ( ! IsConnected )
50
+ {
51
+ Log . Debug ( $ "Failed to connect to { Server } ") ;
52
+ Log . Warning ( $ "Failed to connect to { Server } ") ;
53
+ }
54
+
55
+ var status = _smbClient . Login ( _domain , _username , _password ) ;
56
+ if ( status != NTStatus . STATUS_SUCCESS )
57
+ {
58
+ Log . Debug ( $ "Fail status { status } ") ;
59
+ Log . Warning ( $ "Failed to login to { Server } with username { _username } ") ;
60
+ }
61
+ }
62
+
63
+ public void Disconnect ( )
64
+ {
65
+ // Implement disconnection logic here
66
+ Console . WriteLine ( "Disconnecting from SMB server" ) ;
67
+ }
68
+ }
69
+
70
+ public class SharedFolder : ISharedFolder
71
+ {
72
+ public bool Exists { get ; private set ; }
73
+ private ISMBFileStore _smbFileStore { get ; set ; }
74
+ private ISMBClient _client { get ; set ; }
75
+ private string _server { get ; set ; }
76
+ private string _share { get ; set ; }
77
+ private string _path { get ; set ; }
78
+ private Uri _uri { get ; set ; }
79
+
80
+ public SharedFolder ( Uri uri , ISMBClient client )
81
+ {
82
+ _client = client ;
83
+ _server = uri . Host ;
84
+ _share = uri . PathAndQuery . Split ( "/" ) [ 1 ] ;
85
+ _path = uri . PathAndQuery . Replace ( $ "/{ _share } ", "" ) . Substring ( 1 ) ;
86
+ _uri = uri ;
87
+ Load ( ) ;
88
+ }
89
+
90
+ private void Load ( )
91
+ {
92
+ _smbFileStore = _client . TreeConnect ( _share , out NTStatus status ) ;
93
+ if ( status != NTStatus . STATUS_SUCCESS )
94
+ {
95
+ Log . Debug ( $ "Fail status { status } ") ;
96
+ Log . Warning ( $ "Failed to connect to share { _share } on { _server } ") ;
97
+ Exists = false ;
98
+ }
99
+ else
100
+ {
101
+ Exists = true ;
102
+ }
103
+ }
104
+
105
+ public Tuple < Uri , Stream > GetFile ( string fileName )
106
+ {
107
+ Tuple < Uri , Stream > fileStream = null ;
108
+ var filepath = $ "{ _path } /{ fileName } ";
109
+ var status = _smbFileStore . CreateFile ( out object fileHandle , out FileStatus fileStatus , filepath , AccessMask . GENERIC_READ , SMBLibrary . FileAttributes . Normal , ShareAccess . Read | ShareAccess . Write , CreateDisposition . FILE_OPEN , CreateOptions . FILE_NON_DIRECTORY_FILE , null ) ;
110
+ if ( status == NTStatus . STATUS_SUCCESS )
111
+ {
112
+ var stream = new MemoryStream ( ) ;
113
+ long bytesRead = 0 ;
114
+ while ( true )
115
+ {
116
+ status = _smbFileStore . ReadFile ( out byte [ ] data , fileHandle , bytesRead , ( int ) _client . MaxReadSize ) ;
117
+ if ( status != NTStatus . STATUS_SUCCESS && status != NTStatus . STATUS_END_OF_FILE )
118
+ {
119
+ throw new Exception ( $ "Failed to read file { filepath } ") ;
120
+ }
121
+
122
+ if ( status == NTStatus . STATUS_END_OF_FILE || data . Length == 0 )
123
+ {
124
+ break ;
125
+ }
126
+ bytesRead += data . Length ;
127
+ stream . Write ( data , 0 , data . Length ) ;
128
+ }
129
+ var uri = new Uri ( _uri , filepath ) ;
130
+ fileStream = new Tuple < Uri , Stream > ( uri , stream ) ;
131
+ }
132
+
133
+ return fileStream ;
134
+ }
135
+ }
136
+ }
0 commit comments