basicftp/
lib.rs

1use core::panic;
2use std::env::Args;
3use std::fmt::format;
4use std::fs::{self, metadata, read, DirEntry, File};
5use std::io::{BufReader, BufWriter, Read, Write};
6use std::net::IpAddr;
7use std::path::Path;
8use std::process::Command;
9use std::sync::{Arc, Mutex};
10use std::thread::{sleep, JoinHandle};
11use std::time::{Duration, UNIX_EPOCH};
12use std::{
13    collections::HashMap,
14    net::{SocketAddr, TcpListener, TcpStream},
15    thread::Thread,
16};
17use std::{path, thread};
18
19type ArcClient = Arc<Client>;
20pub struct RustTP {
21    server_con: TcpListener,
22
23    //this is a list of top directorys which comprise the / directory of the fs,
24    directories: Arc<Vec<String>>,
25    client_addrs: Mutex<HashMap<SocketAddr, ArcClient>>,
26    add: Arc<String>,
27    root_store: Arc<String>,
28}
29
30struct Client {
31    addr: SocketAddr,
32    stream: Mutex<TcpStream>,
33    datastream: Mutex<Option<TcpStream>>,
34    stream_type: StreamType,
35    current_path: Arc<Mutex<String>>,
36    real_path: Arc<Mutex<String>>,
37    base_directories:  Arc<Vec<String>>,
38    add: Arc<String>,
39    root_store: Arc<String>,
40}
41
42enum StreamType {
43    ASCII,
44    BINARY,
45    EBCDIC,
46}
47
48static DIRECTORYMODE: i32 = 1;
49
50#[allow(dead_code)]
51trait SendResponse {
52    //series 100
53    fn send110(stream: &mut TcpStream) {
54        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
55    }
56
57    fn send125(stream: &mut TcpStream) {
58        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
59    }
60
61    fn send150(stream: &mut TcpStream) {
62        stream
63            .write(b"150 Opening data connection for file list.\r\n")
64            .unwrap();
65        stream.flush().unwrap();
66        ;
67    }
68
69    // series 200
70    fn send200(stream: &mut TcpStream) {
71        
72        stream.write_all(b"200 command ok\r\n").unwrap();
73        stream.flush().unwrap();
74    }
75    fn send202(stream: &mut TcpStream) {
76        stream.write_all(b"202 no action needed\r\n").unwrap();
77    }
78
79    fn send211(stream: &mut TcpStream) {
80        stream.write_all(b"211-Features:\r\nEPSV\r\n211 End\r\n").unwrap();
81        stream.flush().unwrap();
82    }
83
84    fn send212(stream: &mut TcpStream) {
85        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
86    }
87
88    fn send213(stream: &mut TcpStream) {
89        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
90    }
91
92    fn send214(stream: &mut TcpStream) {
93        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
94    }
95
96    fn send215(stream: &mut TcpStream) {
97        stream.write_all(b"215 UNIX Type: L8\r\n").unwrap();
98        stream.flush().unwrap();
99    }
100
101    fn send220(stream: &mut TcpStream) {
102        stream.write_all(b"220 FTP Server ready\r\n").unwrap();
103        stream.flush().unwrap();
104    }
105
106    fn send221(stream: &mut TcpStream) {
107        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
108    }
109
110    fn send225(stream: &mut TcpStream) {
111        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
112    }
113
114    fn send226(stream: &mut TcpStream) {
115        stream.write_all(b"226 Transfer complete\r\n").unwrap();
116        stream.flush().unwrap();
117    }
118
119    fn send227(stream: &mut TcpStream, addr: String) -> TcpListener {
120        let listener = TcpListener::bind("0.0.0.0:0").unwrap(); // 0.0.0.0 binds to any available IP on a random port
121
122        let port = listener.local_addr().unwrap().port(); // Get the randomly assigned port
123
124        // Convert the port to the format required by PASV (p1, p2)
125        let p1 = port / 256;
126        let p2 = port % 256;
127        println!("ad {addr}");
128        let ad: Vec<String> = addr.clone().split(".").map(|e| e.to_string()).collect();
129
130        let binding = listener.local_addr().unwrap().ip().to_string();
131        let vec: Vec<&str> = binding.split(".").collect();
132
133        let str = format!("227 Entering Passive Mode ({},{},{},{},{},{})\r\n", ad[0],ad[1],ad[2],ad[3],p1, p2);
134        //vec[0], vec[1], vec[2],vec[3]
135        println!("port is {port}");
136
137        stream.write_all(str.as_bytes()).unwrap();
138        stream.flush().unwrap();
139        listener
140    }
141
142    fn send228(stream: &mut TcpStream) {
143        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
144    }
145
146    fn send229(stream: &mut TcpStream) -> TcpListener {
147        let listener = TcpListener::bind("0.0.0.0:0").unwrap(); 
148        let port = listener.local_addr().unwrap().port();
149        println!("{}", format!("229 (|||{port}|)\r\n"));
150        stream.write_all(format!("229 Entering Extended Passive Mode (|||{port}|)\r\n").as_bytes()).unwrap();
151        stream.flush().unwrap();
152        listener
153    }
154
155    fn send230(stream: &mut TcpStream) {
156        stream.write_all(b"230 User logged in\r\n").unwrap();
157        stream.flush().unwrap();
158    }
159
160    fn send232(stream: &mut TcpStream) {
161        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
162    }
163
164    fn send234(stream: &mut TcpStream) {
165        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
166    }
167
168    fn send235(stream: &mut TcpStream) {
169        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
170    }
171
172    fn send250(stream: &mut TcpStream) {
173        stream.write_all(b"250 DIRSTYLE set to WINDOWS\r\n").unwrap();
174    }
175
176    fn send257(stream: &mut TcpStream, path: String) {
177        print!("path is {path}");
178        stream
179            .write(format!("257 \"{path}\" is directory\r\n").as_bytes())
180            .unwrap();
181        stream.flush().unwrap();
182        ;
183    }
184
185    //series 300
186
187    fn send300(stream: &mut TcpStream) {
188        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
189    }
190
191    fn send331(stream: &mut TcpStream) {
192        stream.write_all(b"331 Guest login okay, send your complete email address as your password.\r\n").unwrap();
193        stream.flush().unwrap();
194    }
195
196    fn send332(stream: &mut TcpStream) {
197        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
198    }
199
200    fn send334(stream: &mut TcpStream) {
201        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
202    }
203
204    fn send336(stream: &mut TcpStream) {
205        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
206    }
207
208    //series 400
209    fn send421(stream: &mut TcpStream) {
210        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
211    }
212
213    fn send425(stream: &mut TcpStream) {
214        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
215    }
216
217    fn send426(stream: &mut TcpStream) {
218        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
219    }
220
221    fn send430(stream: &mut TcpStream) {
222        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
223    }
224
225    fn send431(stream: &mut TcpStream) {
226        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
227    }
228
229    fn send434(stream: &mut TcpStream) {
230        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
231    }
232
233    fn send450(stream: &mut TcpStream) {
234        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
235    }
236
237    fn send451(stream: &mut TcpStream) {
238        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
239    }
240
241    fn send452(stream: &mut TcpStream) {
242        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
243    }
244
245    //series 500
246    fn send500(stream: &mut TcpStream){
247        stream.write_all(b"500 do not try again fucker\r\n").unwrap();
248    }
249
250    fn send501(stream: &mut TcpStream) {
251        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
252    }
253
254    fn send502(stream: &mut TcpStream) {
255        stream.write_all(b"502 Command not implemented.\r\n").unwrap();
256    }
257
258    fn send503(stream: &mut TcpStream) {
259        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
260    }
261
262    fn send504(stream: &mut TcpStream) {
263        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
264    }
265
266    fn send530(stream: &mut TcpStream) {
267        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
268    }
269
270    fn send532(stream: &mut TcpStream) {
271        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
272    }
273
274    fn send533(stream: &mut TcpStream) {
275        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
276    }
277
278    fn send534(stream: &mut TcpStream) {
279        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
280    }
281
282    fn send535(stream: &mut TcpStream) {
283        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
284    }
285
286    fn send536(stream: &mut TcpStream) {
287        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
288    }
289
290    fn send537(stream: &mut TcpStream) {
291        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
292    }
293
294    fn send550(stream: &mut TcpStream) {
295        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
296    }
297
298    fn send551(stream: &mut TcpStream) {
299        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
300    }
301
302    fn send552(stream: &mut TcpStream) {
303        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
304    }
305
306    fn send553(stream: &mut TcpStream) {
307        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
308    }
309
310    //series 600
311
312    fn send600(stream: &mut TcpStream) {
313        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
314    }
315
316    fn send631(stream: &mut TcpStream) {
317        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
318    }
319
320    fn send632(stream: &mut TcpStream) {
321        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
322    }
323
324    fn send633(stream: &mut TcpStream) {
325        stream.write_all(b"110 MARK yyyy = mmmm\r\n").unwrap();
326    }
327
328    //new commands
329}
330
331trait SendData {}
332
333//what this project is, i want this to be a ftp file server for windows
334// initial MVP:
335// directory designation
336// file retreival
337// active mode.
338//anonymous no auth check
339
340impl RustTP {
341    pub fn new_with_paths(path_list: Vec<String>,address: &str, root_store: &str) ->(Arc<Self>, JoinHandle<()>) {
342        let toc = TcpListener::bind("0.0.0.0:21").unwrap();
343        let rs = Arc::new(RustTP {
344            server_con: toc,
345            client_addrs: Mutex::new(HashMap::new()),
346            directories: Arc::new(path_list),
347            add: Arc::new(address.to_owned()),
348            root_store: Arc::new(root_store.to_owned()),
349        });
350        let t= rs.clone().start_event_loop();
351        (rs,t)
352    }
353
354    pub fn new(address: &str,root_store: &str) -> (Arc<Self>, JoinHandle<()>) {
355        let toc = TcpListener::bind(address.to_owned() + ":21").unwrap();
356        let rs = Arc::new(RustTP {
357            server_con: toc,
358            client_addrs: Mutex::new(HashMap::new()),
359            directories: Arc::new(Vec::new()),
360            add: Arc::new(address.to_owned()),
361            root_store: Arc::new(root_store.to_owned()),
362        });
363        let t = rs.clone().start_event_loop();
364        (rs,t)
365    }
366
367    fn start_event_loop(self: Arc<Self>) -> JoinHandle<()> {
368        thread::spawn(move || {
369            while let Ok(t) = self.server_con.accept() {
370                let stream = t.0;
371                let addr = t.1;
372                println!("new client connected with {:?}", addr);
373                let client = Client::new(addr, stream, self.directories.clone(), self.add.clone(), self.root_store.clone());
374                let mut lock = self.client_addrs.lock().unwrap();
375                lock.insert(addr, client);
376                drop(lock);
377            }
378        })
379    }
380
381
382}
383
384impl SendResponse for Client {}
385
386impl Client {
387    fn new(addr: SocketAddr, stream: TcpStream, dir:  Arc<Vec<String>>, ad: Arc<String>, root_store: Arc<String>) -> ArcClient {
388        //loop
389        println!("ad: {ad}");
390        let s = Arc::new(Client {
391            addr,
392            stream: Mutex::new(stream),
393            datastream: Mutex::new(None),
394            stream_type: StreamType::ASCII,
395            current_path: Arc::new(Mutex::new(String::from("/"))),
396            base_directories: dir,
397            real_path: Arc::new(Mutex::new("/".to_string())),
398            add: ad,
399            root_store
400        });
401        s.clone().start_event_loop();
402        return s;
403    }
404
405    fn start_event_loop(self: Arc<Self>) {
406        thread::spawn(move || {
407            let mut buf: [u8; 1000] = [0; 1000];
408        let mut stream = self.stream.lock().unwrap();
409        Client::send220(&mut stream);
410        stream.flush().unwrap();
411        let stream = &mut stream;
412        stream.set_read_timeout(Some(Duration::new(200, 0))).unwrap();
413        stream.set_nonblocking(false).unwrap();
414        while let Ok(size) = stream.read(&mut buf) {
415            let data = &buf[..size];
416
417            if size == 0 {
418                println!("connection closed");
419                return;
420            }
421
422            let comm = String::from_utf8_lossy(data);
423
424            println!("command received from {:?}: {:?}", self.addr, comm);
425            let word = &comm[..4].to_uppercase();
426
427            match word.as_str() {
428                "USER" => {
429                    Client::send331(stream);
430                }
431                "PASS" => {
432                    Client::send230(stream);
433                }
434                "ACCT" => {}
435                "CWD " => {
436                    let s = comm[4..].trim().to_string();
437                    let mut iter = s.split("/");
438                    let firstDir = iter.next().unwrap();
439                    if let Some(found) = self.base_directories.iter().find(|string| {
440                        string.split("/").last().unwrap() == firstDir
441                    }){
442                        let mut l2k = self.real_path.lock().unwrap();
443                        *l2k = found.to_owned().to_owned() + "/" + &iter.map(|d| d.to_owned() + "/").collect::<String>();
444                        println!("real path is {l2k}");
445                    } else {
446                        let mut l2k = self.real_path.lock().unwrap();
447                        *l2k = "/".to_string();
448                        println!("real path is /");
449                    }
450                
451                    let mut lock = self.current_path.lock().unwrap();
452                    let mut clone = s.clone();
453                    if !clone.starts_with("/"){
454                        clone.insert(0, '/');
455                    }
456                    println!("{clone} : os the new directory");
457                    *lock = clone;
458                    Client::send200(stream);
459                }
460                "CDUP" => {}
461                "SMNT" => {}
462                "QUIT" => {
463                    panic!();
464                }
465                "REIN" => {}
466                "PORT" => {
467                    let args = comm[4..].trim();
468                    self.clone().handle_active(args);
469                    Client::send226(stream);
470                }
471                "PASV" => {
472                    self.clone().handle_pasv(stream);
473                }
474                "TYPE" => {
475                    Client::send200(stream);
476                }
477                "STRU" => {}
478                "MODE" => {}
479                "RETR" => {
480                    Client::send150(stream);
481                    let args =  comm[4..].trim();
482                    self.clone().send_from_buffered(args);
483                    Client::send226(stream);
484                }
485                "STOR" => {
486                    Client::send150(stream);
487                    let args = comm[4..].trim();
488                    self.clone().receive_file(args);
489                    Client::send226(stream);
490                }
491                "STOU" => {}
492                "APPE" => {}
493                "ALLO" => {}
494                "REST" => {}
495                "RNFR" => {}
496                "RNTO" => {}
497                "ABOR" => {}
498                "DELE" => {}
499                "RMD " => {}
500                "MKD " => {
501                    let args = comm[4..].trim();
502                    self.clone().create_dir(args);
503                    Client::send200(stream);
504                }
505                "PWD\r" => {
506                    let path = self.current_path.lock().unwrap();
507                    Client::send257(stream, path.clone());
508                }
509                "LIST" => {
510                    Client::send150(stream);
511                    //send directory data over coolstreams
512                    self.clone().sendDirectoryInfo();
513                    Client::send226(stream);
514                }
515                "NLST" => {}
516                "SITE" => {
517                    Client::send502(stream);
518                }
519                "SYST" => {
520                    Client::send215(stream);
521
522                }
523                "STAT" => {
524                    Client::send502(stream);
525                }
526                "HELP" => {}
527                "NOOP" => {
528                    Client::send200(stream);
529                }
530                "OPTS" => {
531                    Client::send200(stream);
532                }
533                "FEAT" => {
534                    Client::send211(stream);
535                },
536                "EPSV" => {
537                    if size > 6{
538                        Client::send200(stream);
539                    } else {
540                        self.clone().handle_epsv(stream);
541                    }                    
542                }
543                _ => {
544                    println!("command was not parsed: {comm}");
545                    Client::send500(stream)
546                },
547            }
548        }
549        println!("erorred out");
550        });
551        
552    }
553
554    fn top_dir_to_real_path(self: Arc<Self>, name: &str) -> Option<String>{
555        return self.base_directories.iter().find(|dir| {
556            dir.split("/").last().unwrap() == name
557        }).cloned();
558    }
559
560    fn create_dir(self: Arc<Self>, name: &str){
561        let parsedpath = if name.contains("/") {
562            let mut liter = name.split("/");
563            let top_most = liter.next().unwrap();
564            let path = self.clone().top_dir_to_real_path(top_most).unwrap();
565            let total_path = path + "/" + liter.map(|pat| pat.to_owned() + "/").collect::<String>().as_str();
566            total_path
567        } else {
568            self.root_store.clone().to_string() + "/" + name
569        };
570        fs::create_dir(parsedpath).unwrap();
571    }
572
573
574    fn receive_file(self: Arc<Self>,name: &str){
575        let parsedpath = if name.contains("/") {
576            let mut liter = name.split("/");
577            let top_most = liter.next().unwrap();
578            let path = self.clone().top_dir_to_real_path(top_most).unwrap();
579            let total_path = path + "/" + liter.map(|pat| pat.to_owned() + "/").collect::<String>().as_str();
580            total_path
581        } else {
582            self.root_store.clone().to_string() + "/" + name
583        };
584
585        let parsedpath = if parsedpath.ends_with("/") {parsedpath.strip_suffix("/").unwrap().to_string()} else {parsedpath};
586
587        println!("path to store file is {}",parsedpath);
588        let mut file = File::create(parsedpath).unwrap();
589        let mut  reader = self.datastream.lock().unwrap();
590        let mut buffer = [0u8;32000];
591
592        println!("startng reading process");
593        if let Some(mut reeder) = reader.take() {
594            reeder.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
595            println!("set timeout");
596            while let Ok(size) = reeder.read(&mut buffer) {
597                if size == 0{
598                    println!("file contents finished.");
599                    break;
600                }
601                let data = &buffer[..size];
602                println!("buffer ereceievedf");
603                file.write(data).unwrap();
604            }
605        }else {
606            println!("reader was empty?");
607        }
608 
609    }
610
611    fn sendDirectoryInfo(self: Arc<Self>) {
612        let mut lock = self.datastream.lock().unwrap();
613        let curr = self.current_path.lock().unwrap().clone();
614        let mut ls_list: String = String::new();
615        if curr == "/" {
616            //print everything in top directories list.
617            ls_list = self.base_directories.iter().map(|dir| {
618                let metadata = metadata(dir).unwrap();
619                let filetype = if metadata.is_dir() {'d'} else {'-'};
620                let file_size = metadata.len();
621                let name = Path::file_name(Path::new(dir)).unwrap().to_str().unwrap();
622                let links = if metadata.is_dir() {2} else {1};
623                //let permissions = if metadata.is_dir() {"drwxr-xr-x"} else {"rw-r--r--"};
624                format!("{filetype}rw-r--r-- {links} user group {file_size} Oct 1 10:00 {name}\r\n")
625            }).collect::<String>();
626        } else {
627            let realpath = self.real_path.lock().unwrap().clone();
628            println!("path given is {realpath}");
629            let entries = fs::read_dir(realpath).unwrap();
630            ls_list = entries.map(|entry| {
631                get_file_info(&entry.unwrap())
632            }).collect::<String>();
633    
634        }
635
636        //println!("directory {curr} list of stuff {:?}",ls_list);
637
638        if let Some(mut stream) = lock.take() {
639            stream.write_all(ls_list.as_bytes()).unwrap();
640            stream.flush().unwrap();
641        } else {
642        }
643        drop(lock);
644        self.clone().close_data_stream();
645    }
646    fn handle_epsv(self: Arc<Self>, stream: &mut TcpStream){
647        let list = Client::send229(stream);
648        println!("stream: started waiting onconnection {:?}",list);
649        let clie = list.accept().unwrap();
650        println!("stream: accepted connection at {:?}", clie.1);
651        self.datastream.lock().unwrap().replace(clie.0);
652    }
653    fn close_data_stream(self: Arc<Self>) {
654        let mut lock = self.datastream.lock().unwrap();
655        if lock.is_some() {
656            drop(lock.take());
657        }
658    }
659
660    fn send_rudimentary_data(self: Arc<Self>, data: &[u8]) {
661        let mut lock = self.datastream.lock().unwrap();
662        if let Some(mut stream) = lock.take() {
663            stream.write_all(&data).unwrap();
664        }
665        drop(lock);
666
667        self.clone().close_data_stream();
668    }
669
670    fn send_from_buffered(self: Arc<Self>, file_name: &str) {
671
672        let currdir = self.real_path.lock().unwrap().clone();
673
674        let top_most = file_name.split("/").next().unwrap();
675
676        let real = self.base_directories.iter().find(|e| {
677            let bot_most = e.split("/").last().unwrap();
678            bot_most.trim() == top_most
679        });
680
681        
682        let mut ite = file_name.split("/").into_iter();
683        ite.next();
684        let relpath = real.unwrap().to_owned() + "/" + &ite.map(|e| e.to_owned() + "/").collect::<String>();
685        let s = real.unwrap();
686        println!("path foudn now :{} given {s}", relpath);
687        let relpath = if relpath.ends_with("/") {relpath.strip_suffix("/").unwrap().to_string()} else {relpath};
688        let file = File::open(relpath).unwrap();
689        let mut buffer = vec![0u8; 32000];
690        let mut reader = BufReader::new(file);
691        let mut lock = self.datastream.lock().unwrap();
692        if let Some(mut stream) = lock.take() {
693            stream.set_nodelay(true).unwrap();
694            loop {
695                match reader.read(&mut buffer) {
696                    Ok(0) => break, // EOF reached
697                    Ok(bytes_read) => {
698                        stream.write_all(&buffer[..bytes_read]).unwrap();
699                    }
700                    Err(e) => {
701                        eprintln!("Error reading file: {}", e);
702                        break;
703                    }
704                }
705            }
706        }
707    }
708
709    fn handle_pasv(self: Arc<Self>, stream: &mut TcpStream) {
710        let list = Client::send227(stream, self.add.clone().to_string());
711        println!("stream: started waiting onconnection {:?}",list);
712        let clie = list.accept().unwrap();
713        println!("stream: accepted connection at {:?}", clie.1);
714        self.datastream.lock().unwrap().replace(clie.0);
715        //setConnection create field in Client, mutex<listner>.
716    }
717
718    fn handle_active(self: Arc<Self>, addrstr: &str) {
719        let numbers: Vec<&str> = addrstr.split(",").collect();
720        let port = numbers[4].parse::<i32>().unwrap() * 256 + numbers[5].parse::<i32>().unwrap();
721        let ip = numbers[..4].join(".");
722        println!("active add given: {}:{}", ip, port);
723        let stream = TcpStream::connect(format!("{}:{}", ip, port)).unwrap();
724        self.datastream.lock().unwrap().replace(stream);
725    }
726}
727
728
729impl Drop for Client {
730    fn drop(&mut self) { 
731        println!("client dropped");
732     }
733}
734
735fn get_file_info(entry: &DirEntry) -> String {
736    let metadata = entry.metadata().unwrap();
737    
738    // File permissions
739    let permissions = metadata.permissions();
740    let links = if metadata.is_dir() {2} else {1};
741    let filetype = if (metadata.is_dir()) {'d'} else {'-'};
742    // File size
743    let file_size = metadata.len();
744    let binding = entry.path().display().to_string();
745    let name = binding.split("/").last().unwrap();
746    let name =  name.split("\\").last().unwrap();
747    println!("{} interpreted",name);
748
749    
750    // Last modified time
751    let modified_time = metadata.modified().unwrap_or(UNIX_EPOCH)
752        .duration_since(UNIX_EPOCH).unwrap()
753        .as_secs();
754    let s = format!(
755        "{filetype}rw-r--r-- {links} user group {file_size} Oct 1 10:00 {name}\r\n"
756    );
757    s
758}
759
760//make paths vector editable in runtime for makedir.