pispas_service\service/
server.rs

1pub mod pispas_server {
2    use std::net::{TcpListener, TcpStream};
3    use std::io::{Write};
4    #[cfg(not(target_os = "windows"))]
5
6    use {
7        users::{get_user_by_uid},
8        users::os::unix::UserExt,
9        nix::sys::signal::{self, Signal},
10        nix::unistd::Pid,
11    };
12
13
14
15    const DEFAULT_CICLES_TO_WAIT_IN_MS: u64 = 500;
16    use anyhow::anyhow;
17    use std::collections::HashMap;
18    use std::thread;
19
20    use easy_trace::instruments::tracing::{error, info, warn};
21    use easy_trace::prelude::debug;
22    use parking_lot::RwLock;
23    use sharing::service::{Action, DriverStatus};
24    use std::io::Read;
25
26    use std::sync::atomic::{AtomicBool, Ordering};
27    use std::sync::Arc;
28    use std::thread::sleep;
29    use std::time::Duration;
30    #[cfg(target_os = "windows")]
31    use {
32        std::os::windows::ffi::OsStrExt,
33        winapi::um::{
34            errhandlingapi::GetLastError,
35            fileapi::CreateFileW,
36            handleapi::CloseHandle,
37            handleapi::DuplicateHandle,
38            minwinbase::STILL_ACTIVE,
39            processthreadsapi::GetCurrentProcess,
40            processthreadsapi::{GetExitCodeProcess, TerminateProcess},
41            winnt::{DUPLICATE_SAME_ACCESS, HANDLE},
42            winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE},
43            winnt::{GENERIC_READ, GENERIC_WRITE},
44        }
45    };
46
47
48    pub type CancelToken = Arc<AtomicBool>;// Cambiar la estructura HandlePair para ser multiplataforma
49    #[derive(Debug)]
50    pub struct HandlePair {
51        #[cfg(windows)]
52        pub original: HANDLE,           // El que mantiene el service para protección
53        #[cfg(windows)]
54        pub duplicated: Option<HANDLE>, // El que se envía al módulo
55
56        #[cfg(unix)]
57        pub _original: std::fs::File,    // El que mantiene el service para protección
58        #[cfg(unix)]
59        pub duplicated: Option<i32>,    // File descriptor que se envía al módulo
60
61        #[cfg(unix)]
62        pub file_path: String,          // Path del archivo para Unix
63    }
64
65
66    #[derive(Debug, Clone)]
67    pub struct MyHandler {
68        #[cfg(windows)]
69        pub handle: HANDLE,
70        #[cfg(unix)]
71        pub pid: u32,
72        #[cfg(unix)]
73        process_dead: Arc<std::sync::atomic::AtomicBool>,
74    }
75    unsafe impl Send for MyHandler {}
76
77    unsafe impl Sync for MyHandler {}
78    #[cfg(unix)]
79    impl MyHandler {
80        pub fn new(pid: u32) -> Self {
81            Self {
82                pid,
83                process_dead: Arc::new(AtomicBool::new(false)),
84            }
85        }
86
87        pub fn _get_pid(&self) -> u32 {
88            self.pid
89        }
90
91        pub fn try_wait(&self) -> sharing::PisPasResult<Option<i32>> {
92            if self.process_dead.load(Ordering::Relaxed) {
93                return Ok(Some(0));
94            }
95
96            let pid = Pid::from_raw(self.pid as i32);
97
98            match signal::kill(pid, None) {
99                Ok(_) => {
100                    // Proceso existe y está vivo
101                    Ok(None)
102                }
103                Err(nix::errno::Errno::ESRCH) => {
104                    // Proceso no existe (terminó)
105                    self.process_dead.store(true, Ordering::Relaxed);
106                    tracing::info!("Process {} has terminated", self.pid);
107                    Ok(Some(0))
108                }
109                Err(e) => {
110                    // Otro error (EPERM, etc.) - asumir que sigue vivo
111                    tracing::warn!("Error checking process {}: {} - assuming alive", self.pid, e);
112                    Ok(None)
113                }
114            }
115        }
116
117        pub fn kill(&self) -> sharing::PisPasResult<()> {
118            let pid = Pid::from_raw(self.pid as i32);
119
120            // Verificar si el proceso existe primero
121            match signal::kill(pid, None) {
122                Ok(_) => {
123                    // El proceso existe, intentar terminarlo gracefully con SIGTERM
124                    match signal::kill(pid, Signal::SIGTERM) {
125                        Ok(_) => {
126                            tracing::info!("Sent SIGTERM to process {}", self.pid);
127                            std::thread::sleep(Duration::from_millis(1000));
128
129                            // Verificar si terminó
130                            match signal::kill(pid, None) {
131                                Ok(_) => {
132                                    // Aún vivo, usar SIGKILL (forzado)
133                                    match signal::kill(pid, Signal::SIGKILL) {
134                                        Ok(_) => {
135                                            tracing::info!("Sent SIGKILL to process {}", self.pid);
136                                            self.process_dead.store(true, Ordering::Relaxed);
137                                            Ok(())
138                                        }
139                                        Err(e) => {
140                                            tracing::error!("Failed to kill process {}: {}", self.pid, e);
141                                            Err(anyhow!("Failed to kill process {}: {}", self.pid, e))
142                                        }
143                                    }
144                                }
145                                Err(_) => {
146                                    // Proceso terminado exitosamente con SIGTERM
147                                    tracing::info!("Process {} terminated gracefully with SIGTERM", self.pid);
148                                    self.process_dead.store(true, Ordering::Relaxed);
149                                    Ok(())
150                                }
151                            }
152                        }
153                        Err(e) => {
154                            tracing::error!("Failed to send SIGTERM to process {}: {}", self.pid, e);
155                            Err(anyhow!("Failed to send SIGTERM to process {}: {}", self.pid, e))
156                        }
157                    }
158                }
159                Err(nix::errno::Errno::ESRCH) => {
160                    // El proceso no existe (ya está muerto)
161                    tracing::info!("Process {} not found (already dead)", self.pid);
162                    self.process_dead.store(true, Ordering::Relaxed);
163                    Ok(())
164                }
165                Err(e) => {
166                    tracing::error!("Error accessing process {}: {}", self.pid, e);
167                    Err(anyhow!("Error accessing process {}: {}", self.pid, e))
168                }
169            }
170        }
171
172        pub fn _is_alive(&self) -> sharing::PisPasResult<bool> {
173            if self.process_dead.load(Ordering::Relaxed) {
174                return Ok(false);
175            }
176
177            let pid = Pid::from_raw(self.pid as i32);
178            info!("Trying to kill pid {}", self.pid);
179            match signal::kill(pid, None) {
180                Ok(_) => Ok(true),
181                Err(nix::errno::Errno::ESRCH) => {
182                    self.process_dead.store(true, Ordering::Relaxed);
183                    Ok(false)
184                }
185                Err(e) => {
186                    tracing::warn!("Error checking if process {} is alive: {}", self.pid, e);
187                    // En caso de duda, asumir que está vivo
188                    Ok(true)
189                }
190            }
191        }
192    }
193    #[cfg(windows)]
194    impl MyHandler {
195        pub fn new(handle: HANDLE) -> Self {
196            Self { handle }
197        }
198        pub fn get_handle(&self) -> HANDLE {
199            self.handle
200        }
201    }
202    impl Clone for HandlePair {
203        fn clone(&self) -> Self {
204            #[cfg(windows)]
205            {
206                Self {
207                    original: self.original,
208                    duplicated: self.duplicated,
209                }
210            }
211
212            #[cfg(unix)]
213            {
214                // En Unix, no podemos clonar File directamente
215                // Crear un File dummy que apunte al mismo path
216                match std::fs::File::open(&self.file_path) {
217                    Ok(file) => Self {
218                        _original: file,
219                        duplicated: self.duplicated,
220                        file_path: self.file_path.clone(),
221                    },
222                    Err(_) => {
223                        // Si falla, crear un archivo temporal
224                        let temp_file = std::fs::File::create("/tmp/pispas_clone_dummy")
225                            .unwrap_or_else(|_| panic!("Failed to create dummy file"));
226                        Self {
227                            _original: temp_file,
228                            duplicated: self.duplicated,
229                            file_path: self.file_path.clone(),
230                        }
231                    }
232                }
233            }
234        }
235    }
236
237    // 3. AÑADIR imports para sysinfo:
238
239    unsafe impl Send for HandlePair {}
240    unsafe impl Sync for HandlePair {}
241
242    impl HandlePair {
243        #[cfg(windows)]
244        pub fn new(original: HANDLE, duplicated: Option<HANDLE>) -> Self {
245            Self {
246                original,
247                duplicated,
248            }
249        }
250
251        #[cfg(unix)]
252        pub fn new_unix(original: std::fs::File, file_path: String) -> Self {
253            Self {
254                _original: original,
255                duplicated: None,
256                file_path,
257            }
258        }
259
260        #[cfg(windows)]
261        pub fn _get_handle(&self) -> HANDLE {
262            self.original
263        }
264
265
266        #[cfg(windows)]
267        pub fn get_duplicated(&self) -> HANDLE {
268            self.duplicated.unwrap_or(std::ptr::null_mut())
269        }
270
271        #[cfg(unix)]
272        pub fn get_duplicated(&self) -> i32 {
273            self.duplicated.unwrap_or(-1)
274        }
275
276        #[cfg(windows)]
277        pub fn has_original(&self) -> bool {
278            !self.original.is_null()
279        }
280
281        #[cfg(unix)]
282        pub fn has_original(&self) -> bool {
283            true // En Unix, si el File existe, es válido
284        }
285
286        #[cfg(windows)]
287        pub fn is_valid(&self) -> bool {
288            !self.original.is_null()
289                && self.duplicated.is_some()
290                && self.get_duplicated() != std::ptr::null_mut()
291        }
292
293        #[cfg(unix)]
294        pub fn is_valid(&self) -> bool {
295            self.duplicated.is_some() && self.get_duplicated() != -1
296        }
297
298        #[cfg(windows)]
299        pub fn close_all(&self) {
300            unsafe {
301                if !self.original.is_null() {
302                    CloseHandle(self.original);
303                }
304                if let Some(dup_handle) = self.duplicated {
305                    if dup_handle != std::ptr::null_mut() {
306                        CloseHandle(dup_handle);
307                    }
308                }
309            }
310        }
311
312        pub fn close_duplicated(&self) {
313            #[cfg(windows)]
314            {
315                if let Some(dup_handle) = self.duplicated {
316                    if dup_handle != std::ptr::null_mut() {
317                        unsafe {
318                            CloseHandle(dup_handle);
319                        }
320                    }
321                }
322            }
323
324            #[cfg(unix)]
325            {
326                // En Unix, cerramos el fd duplicado si existe
327                if let Some(fd) = self.duplicated {
328                    if fd != -1 {
329                        unsafe {
330                            libc::close(fd);
331                        }
332                    }
333                }
334            }
335        }
336
337
338        // #[cfg(unix)]
339        // pub fn close_original(&self) {
340        //     // En Unix, el File se cierra automáticamente cuando se hace drop
341        //     // No hacemos nada aquí
342        // }
343
344        #[cfg(unix)]
345        pub fn close_all(&self) {
346            // En Unix, el File se cierra automáticamente cuando se hace drop
347            // Solo cerramos el fd duplicado si existe
348            if let Some(fd) = self.duplicated {
349                if fd != -1 {
350                    unsafe {
351                        libc::close(fd);
352                    }
353                }
354            }
355        }
356    }
357
358    #[derive(Debug)]
359    pub struct Server {
360        process: Option<MyHandler>,
361        tray_status: Arc<RwLock<DriverStatus>>,
362        subcribe_vector: Vec<Arc<RwLock<TcpStream>>>,
363        started: bool,
364        last_status_send: Arc<RwLock<String>>,
365        map_files: Arc<RwLock<HashMap<String, Option<HandlePair>>>>,
366    }
367
368    impl Server {
369        pub fn new() -> Self {
370            Self {
371                process: None,
372                tray_status: Arc::new(RwLock::new(DriverStatus::Launched)),
373                subcribe_vector: Vec::new(),
374                started: false,
375                last_status_send: Arc::new(RwLock::new(String::new())),
376                map_files: Arc::new(RwLock::new(HashMap::new())),
377            }
378        }
379
380        #[cfg(unix)]
381        fn create_or_open_protected_file(
382            &mut self,
383            file_path: &str,
384        ) -> sharing::PisPasResult<(std::fs::File, i32)> {
385            use std::fs::OpenOptions;
386            use std::os::unix::io::{AsRawFd};
387
388            info!("Creating/opening protected file (Unix): {}", file_path);
389
390            // Crear el directorio si no existe
391            if let Some(parent) = std::path::Path::new(file_path).parent() {
392                std::fs::create_dir_all(parent)
393                    .map_err(|e| anyhow!("Failed to create directory: {}", e))?;
394            }
395            
396            if let Err(e) = self.verify_and_restore_from_backup(file_path) {
397                warn!("Failed to verify/restore backup for {}: {}", file_path, e);
398            }
399
400
401            // Abrir el archivo con permisos de lectura/escritura
402            let original_file = OpenOptions::new()
403                .create(true)
404                .read(true)
405                .write(true)
406                .open(file_path)
407                .map_err(|e| anyhow!("Failed to open file: {}", e))?;
408
409            // En Unix, duplicamos el file descriptor
410            let original_fd = original_file.as_raw_fd();
411            let duplicated_fd = unsafe { libc::dup(original_fd) };
412
413            if duplicated_fd == -1 {
414                return Err(anyhow!("Failed to duplicate file descriptor"));
415            }
416
417            info!(
418            "File opened with protection (Unix): {}, original_fd={}, duplicated_fd={}",
419            file_path, original_fd, duplicated_fd
420        );
421
422            Ok((original_file, duplicated_fd))
423        }
424        #[cfg(target_os = "windows")]
425
426        /// Creates or opens the specified file and returns a duplicated handle
427        /// El service.exe mantiene el handle principal para protección contra borrados
428        /// Returns both original and duplicated handles
429        fn create_or_open_protected_file(
430            &mut self,
431            file_path: &str,
432            target_process: HANDLE,
433        ) -> sharing::PisPasResult<(HANDLE, HANDLE)> {
434            info!(
435                "Creating/opening protected file: {}, target process: {:?}",
436                file_path, target_process
437            );
438
439
440            // Crear el directorio si no existe
441            if let Some(parent) = std::path::Path::new(file_path).parent() {
442                std::fs::create_dir_all(parent)
443                    .map_err(|e| anyhow!("Failed to create directory: {}", e))?;
444            }
445
446
447            if let Err(e) = self.verify_and_restore_from_backup(file_path) {
448                warn!("Failed to verify/restore backup for {}: {}", file_path, e);
449            }
450
451            // Convertir path a UTF-16
452            let wide_path: Vec<u16> = std::ffi::OsStr::new(file_path)
453                .encode_wide()
454                .chain(std::iter::once(0))
455                .collect();
456
457            let original_handle = unsafe {
458                CreateFileW(
459                    wide_path.as_ptr(),
460                    GENERIC_READ | GENERIC_WRITE,
461                    FILE_SHARE_READ | FILE_SHARE_WRITE,
462                    std::ptr::null_mut(),
463                    winapi::um::fileapi::OPEN_ALWAYS, // Crear si no existe, abrir si existe
464                    0,
465                    std::ptr::null_mut(),
466                )
467            };
468
469            if original_handle == winapi::um::handleapi::INVALID_HANDLE_VALUE {
470                let error_code = unsafe { GetLastError() };
471                return Err(anyhow!(
472                    "Failed to open file with protection: error code {}",
473                    error_code
474                ));
475            }
476
477            info!("File opened with delete protection: {}", file_path);
478
479            // Duplicate the handle HACIA EL PROCESO DESTINO
480            let mut duplicated_handle: HANDLE = std::ptr::null_mut();
481            let current_process = unsafe { GetCurrentProcess() };
482
483            let result = unsafe {
484                DuplicateHandle(
485                    current_process,
486                    original_handle,
487                    target_process,
488                    &mut duplicated_handle,
489                    0,
490                    1,
491                    DUPLICATE_SAME_ACCESS,
492                )
493            };
494
495            if result == 0 {
496                let error_code = unsafe { GetLastError() };
497                unsafe { CloseHandle(original_handle) };
498                return Err(anyhow!(
499                    "Failed to duplicate handle to target process: error code {}",
500                    error_code
501                ));
502            }
503
504            info!(
505                "Handle duplicated with delete protection for {}: original={:?}, duplicated={:?}",
506                file_path, original_handle, duplicated_handle
507            );
508
509            Ok((original_handle, duplicated_handle))
510        }
511
512        #[cfg(target_os = "windows")]
513        fn close_duplicated_handle_from_map(&mut self) {
514            let mut map_files = self.map_files.write();
515            info!("Closing all duplicated handles in map maps {:?}", map_files);
516
517            for (path, handle_opt) in map_files.iter_mut() {
518                if let Some(safe_handle) = handle_opt {
519                    safe_handle.close_duplicated();
520                    safe_handle.duplicated = None;
521                    info!("Closed duplicated handle for: {}", path);
522                }
523            }
524        }
525
526        fn handle_get_handle_request(
527            &mut self,
528            file_path: &str,
529            stream: Arc<RwLock<TcpStream>>,
530        ) -> sharing::PisPasResult<()> {
531            info!("Handling GET_HANDLE request for file: {}", file_path);
532
533            // Obtener el identificador del proceso target
534            #[cfg(windows)]
535            let target_process = if let Some(process_pair) = &self.process {
536                process_pair.get_handle()
537            } else {
538                error!("No target process available for handle duplication");
539                let response = "HANDLE_ERROR:No target process available";
540                Self::write_stream(stream, response)?;
541                return Ok(());
542            };
543
544            // ✅ Verificar si YA existe el original (después de restart)
545            {
546                let map_files = self.map_files.read();
547                if let Some(Some(handle_pair)) = map_files.get(file_path) {
548                    if handle_pair.has_original() {
549                        info!("Found existing original for: {}, re-duplicating", file_path);
550
551                        #[cfg(windows)]
552                        {
553                            // RE-DUPLICAR el original hacia el NUEVO proceso
554                            let mut new_duplicated: HANDLE = std::ptr::null_mut();
555                            let result = unsafe {
556                                DuplicateHandle(
557                                    GetCurrentProcess(),
558                                    handle_pair.original,  // ← El original que nunca cerramos
559                                    target_process,         // ← El nuevo proceso
560                                    &mut new_duplicated,
561                                    0,
562                                    1,
563                                    DUPLICATE_SAME_ACCESS,
564                                )
565                            };
566
567                            if result != 0 {
568                                drop(map_files); // Liberar read lock
569
570                                // Actualizar el mapa con el nuevo duplicado
571                                let mut map_files = self.map_files.write();
572                                if let Some(Some(hp)) = map_files.get_mut(file_path) {
573                                    hp.duplicated = Some(new_duplicated);
574                                }
575
576                                let response = format!("HANDLE_OK:{}", new_duplicated as usize);
577                                Self::write_stream(stream, &response)?;
578                                info!("Re-duplicated handle successfully: {:?}", new_duplicated);
579                                return Ok(());
580                            } else {
581                                let error_code = unsafe { GetLastError() };
582                                error!("Failed to re-duplicate: error {}", error_code);
583                                // Continuar para crear uno nuevo
584                            }
585                        }
586
587                        #[cfg(unix)]
588                        {
589                            use std::os::fd::AsRawFd;
590
591                            let duplicated_fd = unsafe { libc::dup(handle_pair._original.as_raw_fd()) };
592                            if duplicated_fd != -1 {
593                                drop(map_files);
594
595                                let mut map_files = self.map_files.write();
596                                if let Some(Some(hp)) = map_files.get_mut(file_path) {
597                                    hp.duplicated = Some(duplicated_fd);
598                                }
599
600                                let response = format!("HANDLE_OK:{}", duplicated_fd);
601                                Self::write_stream(stream, &response)?;
602                                info!("Re-duplicated fd successfully: {}", duplicated_fd);
603                                return Ok(());
604                            }
605                        }
606                    }
607                }
608            }
609
610            // Create or open the file and add to map
611            #[cfg(windows)]
612            match self.create_or_open_protected_file(file_path, target_process) {
613                Ok((original_handle, duplicated_handle)) => {
614                    let handle_pair = HandlePair::new(original_handle, Some(duplicated_handle));
615
616                    {
617                        let mut map_files = self.map_files.write();
618                        map_files.insert(file_path.to_string(), Some(handle_pair));
619                    }
620
621                    let response = format!("HANDLE_OK:{}", duplicated_handle as usize);
622                    Self::write_stream(stream, &response)?;
623                    info!("Successfully created and mapped file handle for: {}", file_path);
624                    info!(
625                        "Original handle protected in service: {:?}",
626                        original_handle
627                    );
628                    info!(
629                        "Duplicated handle sent to target process: {:?}",
630                        duplicated_handle
631                    );
632                }
633                Err(e) => {
634                    error!("Failed to create/open protected file {}: {}", file_path, e);
635                    let mut map_files = self.map_files.write();
636                    map_files.insert(file_path.to_string(), None);
637                    let response = format!("HANDLE_ERROR:{}", e);
638                    Self::write_stream(stream, &response)?;
639                }
640            }
641
642            #[cfg(unix)]
643            match self.create_or_open_protected_file(file_path) {
644                Ok((original_file, duplicated_fd)) => {
645                    let handle_pair = HandlePair::new_unix(original_file, file_path.to_string());
646                    // Actualizar con el fd duplicado
647                    let mut handle_pair = handle_pair;
648                    handle_pair.duplicated = Some(duplicated_fd);
649
650                    {
651                        let mut map_files = self.map_files.write();
652                        map_files.insert(file_path.to_string(), Some(handle_pair));
653                    }
654
655                    let response = format!("HANDLE_OK:{}", duplicated_fd);
656                    Self::write_stream(stream, &response)?;
657                    info!("Successfully created and mapped file descriptor for: {}", file_path);
658                }
659                Err(e) => {
660                    error!("Failed to create/open protected file {}: {}", file_path, e);
661                    let mut map_files = self.map_files.write();
662                    map_files.insert(file_path.to_string(), None);
663                    let response = format!("HANDLE_ERROR:{}", e);
664                    Self::write_stream(stream, &response)?;
665                }
666            }
667
668            Ok(())
669        }
670
671
672        /// Verifica si existe backup y restaura si es necesario
673        fn verify_and_restore_from_backup(&self, file_path: &str) -> sharing::PisPasResult<()> {
674            let backup_dir = sharing::paths::user_home();
675
676            if !backup_dir.exists() {
677                info!(
678                    "Backup directory does not exist, creating: {}",
679                    backup_dir.display()
680                );
681                match std::fs::create_dir_all(&backup_dir) {
682                    Ok(_) => info!("Backup directory created: {}", backup_dir.display()),
683                    Err(e) => {
684                        error!("Failed to create backup directory: {}", e);
685                        return Ok(()); // No es crítico
686                    }
687                }
688            }
689
690            info!("🔍 Checking backup directory: {}", backup_dir.display());
691
692            if let Some(filename) = std::path::Path::new(file_path).file_name() {
693                let backup_file_path = backup_dir.join(filename);
694
695                // Si no existe el backup, no hay nada que restaurar
696                if !backup_file_path.exists() {
697                    info!(
698                        "✅ No backup found for: {} - will create new file",
699                        filename.to_string_lossy()
700                    );
701                    return Ok(());
702                }
703
704                info!("🎯 Backup found: {}", backup_file_path.display());
705
706                // Si el archivo original no existe, restaurar desde backup
707                if !std::path::Path::new(file_path).exists() {
708                    info!(
709                        "🔄 Original file missing, restoring from backup: {}",
710                        file_path
711                    );
712
713                    // Crear directorio si no existe
714                    if let Some(parent) = std::path::Path::new(file_path).parent() {
715                        std::fs::create_dir_all(parent).map_err(|e| {
716                            anyhow!("Failed to create directory for restore: {}", e)
717                        })?;
718                    }
719
720                    std::fs::copy(&backup_file_path, file_path)
721                        .map_err(|e| anyhow!("Failed to restore from backup: {}", e))?;
722
723                    info!(
724                        "✅ RESTORED: {} ← {}",
725                        file_path,
726                        backup_file_path.display()
727                    );
728                    return Ok(());
729                }
730
731                // Si el archivo original existe pero es diferente al backup, SIEMPRE sobrescribir
732                match self.files_are_different(file_path, &backup_file_path) {
733                    Ok(true) => {
734                        info!("Files differ, OVERWRITING with backup: {}", file_path);
735                        std::fs::copy(&backup_file_path, file_path)
736                            .map_err(|e| anyhow!("Failed to overwrite with backup: {}", e))?;
737                        info!(
738                            "OVERWRITTEN: {} ← {}",
739                            file_path,
740                            backup_file_path.display()
741                        );
742                    }
743                    Ok(false) => {
744                        info!("Files match, no restoration needed: {}", file_path);
745                    }
746                    Err(e) => {
747                        warn!("Failed to compare files: {}", e);
748                    }
749                }
750            } else {
751                warn!("Could not extract filename from path: {}", file_path);
752            }
753
754            Ok(())
755        }
756
757
758        /// Cierra todos los handles de archivos mapeados al finalizar el servicio
759        pub fn cleanup_file_handles(&mut self) {
760            info!("Cleaning up all mapped file handles");
761            let mut map_files = self.map_files.write();
762
763            for (_, handle_opt) in map_files.iter() {
764                if let Some(safe_handle) = handle_opt {
765                    safe_handle.close_all();
766                }
767            }
768
769            map_files.clear();
770            info!("All file handles cleaned up");
771        }
772
773        /// Lista todos los archivos actualmente mapeados (para debugging)
774        pub fn _list_mapped_files(&self) -> Vec<String> {
775            let map_files = self.map_files.read();
776            map_files.keys().cloned().collect()
777        }
778
779        /// Remueve un archivo específico del mapa y cierra su handle
780        pub fn _remove_file_mapping(&mut self, file_path: &str) -> sharing::PisPasResult<()> {
781            let mut map_files = self.map_files.write();
782
783            if let Some(handle_opt) = map_files.remove(file_path) {
784                if let Some(safe_handle) = handle_opt {
785                    safe_handle.close_all();
786                }
787                info!("File mapping removed: {}", file_path);
788            } else {
789                warn!(
790                    "Attempted to remove non-existent file mapping: {}",
791                    file_path
792                );
793            }
794
795            Ok(())
796        }
797
798        fn write_stream(
799            stream: Arc<RwLock<TcpStream>>,
800            message: &str,
801        ) -> sharing::PisPasResult<()> {
802            match stream.write().write_all(message.as_bytes()) {
803                Ok(_) => {
804                    info!("Message sent: {}", message);
805                    Ok(())
806                }
807                Err(e) => {
808                    error!("Error writing to stream: {:?}", e);
809                    return Err(anyhow!("Error writing to stream: {:?}", e));
810                }
811            }
812        }
813
814        pub fn change_status(&mut self, status: DriverStatus) {
815            info!("Attempting to change status to: {:?}", status);
816
817            let old_status = {
818                let current_status = self.tray_status.read();
819                info!("Current status: {:?}", *current_status);
820                current_status.clone()
821            };
822
823            {
824                let mut tray_status = self.tray_status.write();
825                *tray_status = status.clone();
826                info!("Status successfully changed to: {:?}", *tray_status);
827            }
828
829            // ✅ Forzar notificación si el estado realmente cambió
830            if old_status != status {
831                self.notify_subscriber(&status.to_string());
832            }
833        }
834
835        #[cfg(unix)]
836        fn launch_process(&mut self, _: bool) -> sharing::PisPasResult<DriverStatus> {
837            match sharing::natives::api::get_first_logged_user() {
838                Ok((username, uid)) => {
839                    if let Some(user) = get_user_by_uid(uid) {
840                        let tray_string = format!(
841                            "{}/.config/pispas/{}",
842                            user.home_dir().display(),
843                            sharing::PRINT_SERVICE
844                        );
845                        info!("Launching tray icon for user: {} at path: {}", username, tray_string);
846                        match sharing::natives::api::run_in_all_sessions(&tray_string, "", Some(&username), Some(uid)) {
847                            Ok(pid) => {
848                                self.change_status(DriverStatus::Running);
849                                self.process = Some(MyHandler::new(pid));
850                                self.started = true;
851                                info!("Tray icon launched for user: {} with PID: {}", username, pid);
852                            }
853                            Err(err) => {
854                                self.change_status(DriverStatus::Warning);
855                                self.process = None;
856                                error!("Error launching tray icon: {} for user {}", err, username);
857                            }
858                        }
859                    }
860                }
861                Err(e) => {
862                    self.change_status(DriverStatus::Warning);
863                    self.process = None;
864                    error!("Failed to get first logged user: {}", e);
865                }
866            }
867            Ok(self.tray_status.read().clone())
868        }
869        #[cfg(target_os = "windows")]
870        fn launch_process(&mut self, launch_first: bool) -> sharing::PisPasResult<DriverStatus> {
871            info!(
872                "Launching Print service current thread_id {:?}",
873                thread::current().id()
874            );
875            let print_service = sharing::paths::print_service_path().display().to_string();
876
877            let cmd = format!("\"{}\"", print_service);
878            info!("Command to run: {}", cmd);
879
880            match sharing::natives::api::run_in_all_sessions(
881                &print_service,
882                "",
883                false,
884                launch_first,
885            ) {
886                Ok(proc) => {
887                    if let Some(handler) = proc {
888                        let handler = MyHandler::new(handler);
889                        info!("Handle: {:?}", handler.get_handle());
890                        self.change_status(DriverStatus::Running);
891                        self.process = Some(handler);
892                        self.started = true;
893                        info!("PrintService launched successfully");
894                    } else {
895                        error!("Error launching PrintService: None");
896                    }
897                }
898                Err(e) => {
899                    self.change_status(DriverStatus::Warning);
900                    self.process = None;
901                    return Err(anyhow!("Error launching Pispas Service: {}", e));
902                }
903            }
904            Ok(self.tray_status.read().clone())
905        }
906        #[cfg(target_os = "windows")]
907        pub fn stop_process(&mut self) -> sharing::PisPasResult<DriverStatus> {
908            if let Some(proc_handler) = self.process.as_mut() {
909                info!(
910                    "Stopping Print service current thread_id {:?}",
911                    thread::current().id()
912                );
913                let result = unsafe { TerminateProcess(proc_handler.get_handle(), 1) }; // Código de salida 1
914                if result != 0 {
915                    info!("PrintService stopped");
916                    unsafe { CloseHandle(proc_handler.get_handle()) };
917                    self.change_status(DriverStatus::Stopped);
918                    self.process = None;
919                    self.started = false;
920
921                    // self.cleanup_file_handles();
922                } else {
923                    let error_code = unsafe { GetLastError() };
924                    self.change_status(DriverStatus::Warning);
925                    return Err(anyhow!("Error stopping Pispas Service: {}", error_code));
926                }
927                sharing::proc::kill_process_by_name(sharing::ORDER_KITCHEN);
928            } else {
929                warn!("Stop request for non running service");
930            }
931            Ok(self.tray_status.read().clone())
932        }
933        #[cfg(unix)]
934        fn stop_process(&mut self) -> sharing::PisPasResult<DriverStatus> {
935            if let Some(proc) = self.process.as_mut() {
936                debug!("Stopping PispasModules current thread_id {:?}", std::thread::current().id());
937                match proc.kill() {
938                    Ok(_) => {
939                        debug!("PispasModules stopped");
940                        self.process = None;
941                        self.change_status(DriverStatus::Stopped);
942                    }
943                    Err(e) => {
944                        warn!("Error stopping web-driver: {} (process might already be dead)", e);
945                        self.process = None;
946                        self.change_status(DriverStatus::Stopped);
947                    }
948                }
949            } else {
950                warn!("Stop request for non running service");
951            }
952            //fallback
953            kill_process_by_name(sharing::PRINT_SERVICE);
954            Ok(self.tray_status.read().clone())
955        }
956
957        /// Handles the CLOSE_HANDLE request for a specific file path
958        fn handle_close_handle_request(
959            &mut self,
960            file_path: &str,
961            stream: Arc<RwLock<TcpStream>>,
962        ) -> sharing::PisPasResult<()> {
963            info!("Handling CLOSE_HANDLE request for file: {}", file_path);
964
965            let mut map_files = self.map_files.write();
966
967            if let Some(handle_opt) = map_files.get(file_path) {
968                if let Some(safe_handle) = handle_opt {
969                    if safe_handle.has_original() {
970                        info!("Closing handle for file: {}", file_path);
971                        safe_handle.close_all();
972
973                        // Remove from map after closing
974                        map_files.remove(file_path);
975
976                        // Send success response
977                        let response = "HANDLE_CLOSED:OK";
978                        Self::write_stream(stream, response)?;
979                        info!("Successfully closed and removed handle for: {}", file_path);
980                    } else {
981                        // Handle exists but is invalid
982                        map_files.remove(file_path);
983                        let response = "HANDLE_CLOSED:INVALID";
984                        Self::write_stream(stream, response)?;
985                        info!("Removed invalid handle for: {}", file_path);
986                    }
987                } else {
988                    // Handle entry exists but is None (failed creation)
989                    map_files.remove(file_path);
990                    let response = "HANDLE_CLOSED:NOT_FOUND";
991                    Self::write_stream(stream, response)?;
992                    info!("Removed failed handle entry for: {}", file_path);
993                }
994            } else {
995                // No entry found for this file path
996                let response = "HANDLE_CLOSED:NOT_FOUND";
997                Self::write_stream(stream, response)?;
998                warn!("Attempted to close non-existent handle for: {}", file_path);
999            }
1000
1001            Ok(())
1002        }
1003        fn process_message(
1004            pispas_service: Arc<RwLock<Server>>,
1005            message: &str,
1006            stream: Arc<RwLock<TcpStream>>,
1007            needs_close: CancelToken,
1008        ) -> sharing::PisPasResult<()> {
1009            info!("Message received: {}", message);
1010            let action: Action = message.into();
1011            info!("Action: {:?}", action.to_string());
1012            if message == Action::Subscribe.to_string() {
1013                pispas_service.write().subcribe_vector.push(stream.clone());
1014                info!(
1015                    "Subscribed new client, total: {}",
1016                    pispas_service.read().subcribe_vector.len()
1017                );
1018            }
1019            let status = pispas_service.read().tray_status.read().clone();
1020            if message == Action::Restart.to_string() {
1021                if status == DriverStatus::Running || status == DriverStatus::Warning {
1022                    info!(
1023                        "Restart stream request, change tray status to Stopped == {:?}",
1024                        status
1025                    );
1026                    pispas_service.write().change_status(DriverStatus::Restart);
1027                    // sleep(Duration::from_millis(3800));
1028                    // info!("Start stream request, change tray status to Running == {:?}", status);
1029                    // pispas_service.write().change_status(DriverStatus::Running);
1030                } else if status == DriverStatus::Stopped {
1031                    pispas_service.write().change_status(DriverStatus::Launched);
1032                }
1033            }
1034
1035            if message == Action::Stop.to_string() {
1036                pispas_service.write().change_status(DriverStatus::Stopped);
1037                info!(
1038                    "Stop stream request, change tray status to Stopped == {:?}",
1039                    DriverStatus::Stopped
1040                );
1041            }
1042
1043            if message == Action::Start.to_string() && status == DriverStatus::Stopped {
1044                pispas_service.write().change_status(DriverStatus::Launched);
1045                info!(
1046                    "Start stream request, change tray status to Running == {:?}",
1047                    DriverStatus::Launched
1048                );
1049            }
1050
1051            if message == Action::Update.to_string() {
1052                // Use block_on to run the Future synchronously
1053                let rt = tokio::runtime::Runtime::new().unwrap();
1054                rt.block_on(updates::check_and_launch(&sharing::get_version()));
1055            }
1056            if message.starts_with("MessageBox:") {
1057                let msg = message.trim_start_matches("MessageBox:").trim();
1058                if !msg.is_empty() {
1059                    pispas_service
1060                        .write()
1061                        .notify_subscriber(&DriverStatus::MessageBox(msg.to_string()).to_string());
1062                } else {
1063                    info!("No message provided for MessageBox.");
1064                }
1065            }
1066            // Handle GET_HANDLE requests with file path
1067            if let Action::GetHandle(file_path) = &action {
1068                let mut service = pispas_service.write();
1069                service.handle_get_handle_request(&file_path, stream.clone())?;
1070                needs_close.store(true, Ordering::Relaxed);
1071                return Ok(());
1072            }
1073            if let Action::CloseHandle(file_path) = &action {
1074                let mut service = pispas_service.write();
1075                service.handle_close_handle_request(&file_path, stream.clone())?;
1076                needs_close.store(true, Ordering::Relaxed);
1077                return Ok(());
1078            }
1079            if message == Action::Close.to_string() {
1080                let mut service = pispas_service.write();
1081
1082                if let Some(pos) = service
1083                    .subcribe_vector
1084                    .iter()
1085                    .position(|s| Arc::ptr_eq(s, &stream))
1086                {
1087                    service.subcribe_vector.remove(pos);
1088                    info!(
1089                        "Unsubscribed a client, total: {}",
1090                        service.subcribe_vector.len()
1091                    );
1092                }
1093            }
1094            let new_status = pispas_service.read().tray_status.read().clone();
1095            info!("Tray status changed to: {:?}", new_status);
1096            if message == Action::Subscribe.to_string() {
1097                match stream.write().set_nonblocking(true) {
1098                    Ok(_) => {
1099                        info!("Non blocking set");
1100                    }
1101                    Err(e) => {
1102                        info!("Non blocking not available {:?}", e);
1103                    }
1104                };
1105                Self::write_stream(stream, new_status.to_string().as_str())?;
1106            } else {
1107                info!("Close stream request");
1108                needs_close.store(true, Ordering::Relaxed);
1109            }
1110            Ok(())
1111        }
1112
1113        pub fn notify_subscriber(&mut self, message: &str) {
1114            if message == *self.last_status_send.read() {
1115                return;
1116            }
1117            let mut stream_remove = Vec::new();
1118            for (i, sub) in self.subcribe_vector.iter().enumerate() {
1119                match Self::write_stream(sub.clone(), message) {
1120                    Ok(_) => {
1121                        info!("Message to client subcribe sent: {}", message);
1122                        if !message.starts_with("MessageBox:") {
1123                            *self.last_status_send.write() = message.to_string();
1124                        }
1125                    }
1126                    Err(e) => {
1127                        stream_remove.push(i);
1128                        error!("Error writing to stream: {:?}", e);
1129                    }
1130                }
1131            }
1132            if !stream_remove.is_empty() {
1133                for &index in stream_remove.iter().rev() {
1134                    self.subcribe_vector.remove(index);
1135                }
1136            }
1137        }
1138
1139        pub fn handle_message(
1140            pispas_service: Arc<RwLock<Server>>,
1141            stream: Arc<RwLock<TcpStream>>,
1142            stop: CancelToken,
1143        ) {
1144            let need_close = CancelToken::default();
1145            if let Err(e) = stream.write().set_nonblocking(true) {
1146                info!("Non blocking not available {:?}", e);
1147            };
1148            loop {
1149                sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS));
1150                if need_close.load(Ordering::Relaxed) || stop.load(Ordering::Relaxed) {
1151                    sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS));
1152                    info!("Terminate thread");
1153                    break;
1154                }
1155
1156                let mut buffer = Vec::new(); // Use a dynamic Vec to store the incoming message
1157
1158                loop {
1159                    let mut partial_buffer = [0; 1024];
1160                    match stream.write().read(&mut partial_buffer) {
1161                        Ok(size) => {
1162                            if size == 0 {
1163                                sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS)); // Wait a bit before trying again
1164                                continue;
1165                            }
1166                            buffer.extend_from_slice(&partial_buffer[..size]);
1167                            if size < partial_buffer.len() {
1168                                break; // Finished reading the complete message
1169                            }
1170                        }
1171                        Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
1172                            // Operation would block, wait a bit and try again
1173                            sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS)); // Wait a bit before trying again
1174                            continue;
1175                        }
1176                        Err(e) => {
1177                            error!("Failed to read from socket in dedicated thread: {}", e);
1178                            break;
1179                        }
1180                    }
1181                }
1182
1183                let message = String::from_utf8_lossy(&buffer).to_string();
1184
1185                match Server::process_message(
1186                    pispas_service.clone(),
1187                    &message,
1188                    stream.clone(),
1189                    need_close.clone(),
1190                ) {
1191                    Ok(_) => {}
1192                    Err(e) => {
1193                        error!("Error processing message: {:?}", e);
1194                    }
1195                }
1196                info!("Message processed: {}", message);
1197            }
1198        }
1199
1200        fn watchdog(thread_service: Arc<RwLock<Server>>, thread_cancel: CancelToken) {
1201            //Thread to monitor the process status
1202            thread::spawn(move || loop {
1203                if thread_cancel.load(Ordering::Relaxed) {
1204                    info!("WATCHDOG: Terminate thread, stop requested");
1205                    if let Err(e) = thread_service.write().on_service_stop() {
1206                        error!("Failed to execute service stop cleanup: {}", e);
1207                    }
1208                    match thread_service.write().stop_process() {
1209                        Ok(_) => {
1210                            thread_service
1211                                .write()
1212                                .notify_subscriber(DriverStatus::Stopped.to_string().as_str());
1213                        }
1214                        Err(e) => {
1215                            error!("Failed to stop process {}", e);
1216                        }
1217                    }
1218                    
1219                    sharing::proc::kill_process_by_name(sharing::TRAY_ICON_NAME);
1220                    return;
1221                }
1222
1223                match thread_service.write().check() {
1224                    Ok(_) => {}
1225                    Err(e) => {
1226                        error!("Failed to check process {}", e);
1227                    }
1228                }
1229                #[cfg(target_os = "windows")]
1230                {
1231                    let thread_clone = thread_service.clone();
1232                    Self::still_active_process(thread_clone.clone());
1233                }
1234
1235                sleep(Duration::from_millis(800));
1236            });
1237        }
1238
1239
1240        #[cfg(target_os = "windows")]
1241        fn still_active_process(thread_clone: Arc<RwLock<Server>>) {
1242            let proc_handler = {
1243                let guard = thread_clone.write();
1244                guard.process.clone()
1245            };
1246            if let Some(proc_handler) = proc_handler {
1247                let mut exit_code: u32 = 0;
1248                let ret = unsafe { GetExitCodeProcess(proc_handler.get_handle(), &mut exit_code) };
1249
1250                if ret == 0 {
1251                    error!("Failed to get exit code of process");
1252                    let error_code = unsafe { GetLastError() };
1253                    error!("Error code: {}", error_code);
1254                    let mut guard = thread_clone.write();
1255                    guard.process = None;
1256                } else if exit_code != STILL_ACTIVE {
1257                    // EndProcess
1258                    let status = {
1259                        let guard = thread_clone.read();
1260                        let x = guard.tray_status.read().clone();
1261                        x
1262                    };
1263                    if status == DriverStatus::Running || status == DriverStatus::Warning {
1264                        // change process to None to launch the thread again
1265                        let mut guard = thread_clone.write();
1266                        guard.process = None;
1267                        static EXIT_CODES_TO_IGNORE: &[u32] = &[3221226091, 3228369022, 1073807364];
1268
1269                        if EXIT_CODES_TO_IGNORE.contains(&exit_code) {
1270                            warn!("process exited with code {}, restarting but ignoring warning, changing status to Launched", exit_code);
1271                            guard.change_status(DriverStatus::Launched);
1272                        } else {
1273                            error!("process exited, re*starting with exit_code {}", exit_code);
1274                            guard.change_status(DriverStatus::Warning);
1275                        }
1276                        sleep(Duration::from_millis(1000)); //time to wait before restart
1277                    } else if status != DriverStatus::Stopped {
1278                        info!(
1279                            "process exited, keeping stopped. Driver status: {:?}",
1280                            status
1281                        );
1282                    }
1283                }
1284            }
1285        }
1286
1287        /// Método interno del server para manejar el evento de stop
1288        pub fn on_service_stop(&mut self) -> sharing::PisPasResult<()> {
1289            info!("Service stopping - backing up protected files");
1290
1291            // Usar user_home para backup
1292            let backup_dir = sharing::paths::user_home();
1293
1294            let map_files = self.map_files.read();
1295            let mut backup_count = 0;
1296            info!("Backing up files to: {}", backup_dir.display());
1297            for (original_path, handle_opt) in map_files.iter() {
1298                if let Some(safe_handle) = handle_opt {
1299                    if safe_handle.is_valid() {
1300                        #[cfg(windows)]
1301                        {
1302                            use winapi::um::fileapi::FlushFileBuffers;
1303                            unsafe {
1304                                FlushFileBuffers(safe_handle.original);
1305                            }
1306                        }
1307
1308                        #[cfg(unix)]
1309                        {
1310                            use std::os::unix::io::AsRawFd;
1311                            unsafe {
1312                                libc::fsync(safe_handle._original.as_raw_fd());
1313                            }
1314                        }
1315                        if let Some(filename) = std::path::Path::new(original_path).file_name() {
1316                            let backup_file_path = backup_dir.join(filename);
1317
1318                            match std::fs::copy(original_path, &backup_file_path) {
1319                                Ok(_) => {
1320                                    info!(
1321                                        "Backed up: {} → {}",
1322                                        original_path,
1323                                        backup_file_path.display()
1324                                    );
1325                                    backup_count += 1;
1326                                }
1327                                Err(e) => {
1328                                    error!("Failed to backup {}: {}", original_path, e);
1329                                }
1330                            }
1331                        }
1332                    }
1333                }
1334            }
1335
1336            info!(
1337                "Backup completed: {} files backed up to {}",
1338                backup_count,
1339                backup_dir.display()
1340            );
1341            drop(map_files); // Release the read lock before cleanup
1342            self.cleanup_file_handles();
1343
1344            Ok(())
1345        }
1346
1347        /// Compara si dos archivos son diferentes
1348        fn files_are_different(
1349            &self,
1350            file1: &str,
1351            file2: &std::path::Path,
1352        ) -> sharing::PisPasResult<bool> {
1353            use std::fs;
1354
1355            let content1 =
1356                fs::read(file1).map_err(|e| anyhow!("Failed to read {}: {}", file1, e))?;
1357            let content2 = fs::read(file2)
1358                .map_err(|e| anyhow!("Failed to read {}: {}", file2.display(), e))?;
1359
1360            Ok(content1 != content2)
1361        }
1362
1363        fn start_server(
1364            listener: Arc<RwLock<TcpListener>>,
1365            stop_arc: CancelToken,
1366            pispas_service: Arc<RwLock<Server>>,
1367        ) {
1368            loop {
1369                sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS));
1370                for connection in listener.write().incoming() {
1371                    match connection {
1372                        Ok(stream) => {
1373                            info!("New connection");
1374                            let stream_arc = Arc::new(RwLock::new(stream));
1375                            let thread_stream = stream_arc.clone();
1376
1377                            let thread_token = stop_arc.clone();
1378                            let thread_service = pispas_service.clone();
1379                            thread::spawn(move || {
1380                                info!("New thread thread_id: {:?}", thread::current().id());
1381                                Server::handle_message(
1382                                    thread_service.clone(),
1383                                    thread_stream,
1384                                    thread_token,
1385                                );
1386                            });
1387                        }
1388                        Err(_) => {
1389                            sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS)); //wait for process stop
1390                            if stop_arc.load(Ordering::Relaxed) {
1391                                if let Err(e) = pispas_service.write().on_service_stop() {
1392                                    error!("Failed to execute service stop cleanup: {}", e);
1393                                }
1394                                info!("STOP KILL KILL server");
1395                                return;
1396                            }
1397                        }
1398                    }
1399                }
1400            }
1401        }
1402
1403        pub fn run_server(pispas_service: Arc<RwLock<Server>>, stop_arc: CancelToken) {
1404            let socket_name = sharing::CHANNEL_NAME;
1405
1406            // 🧹 CLEANUP SIMPLE: Solo remover archivo anterior si existe
1407            if std::path::Path::new(socket_name).exists() {
1408                info!("Removing stale socket file: {}", socket_name);
1409                if let Err(e) = std::fs::remove_file(socket_name) {
1410                    warn!("Failed to remove stale socket, trying anyway: {}", e);
1411                }
1412            }
1413
1414            let listener_result = TcpListener::bind(sharing::CHANNEL_NAME);
1415
1416            let listener = match listener_result {
1417                Ok(listener) => {
1418                    info!("✅ Successfully bound to socket: {}", socket_name);
1419                    listener
1420                }
1421                Err(e) => {
1422                    error!("❌ Error binding to socket: {:?}", e);
1423                    return;
1424                }
1425            };
1426
1427            // 🛡️ SIMPLE CLEANUP ON EXIT: Registrar cleanup para Ctrl+C
1428            let cleanup_socket_name = socket_name.to_string();
1429            let cleanup_stop_arc = stop_arc.clone();
1430
1431            thread::spawn(move || {
1432                while !cleanup_stop_arc.load(Ordering::Relaxed) {
1433                    sleep(Duration::from_millis(3000));
1434                }
1435                info!("🧹 Cleaning up socket on shutdown: {}", cleanup_socket_name);
1436                let _ = std::fs::remove_file(&cleanup_socket_name);
1437            });
1438
1439            if let Err(error) = listener.set_nonblocking(true) {
1440                error!("Failed to set non-blocking: {:?}", error);
1441            }
1442            let thread_cancel = stop_arc.clone();
1443            let listener: Arc<RwLock<TcpListener>> = Arc::new(RwLock::new(listener));
1444            let thread_service = pispas_service.clone();
1445            updates::launch_thread(stop_arc.clone());
1446
1447            Server::watchdog(thread_service.clone(), thread_cancel.clone());
1448
1449            #[cfg(target_os = "macos")]
1450            thread::spawn(move || {
1451                info!("Waiting for user login to launch tray...");
1452
1453                loop {
1454                    if let Ok((username, uid)) = sharing::natives::api::get_first_logged_user() {
1455                        if let Some(user) = get_user_by_uid(uid) {
1456                            let tray_string = format!(
1457                                "{}/.config/pispas/{}",
1458                                user.home_dir().display(),
1459                                sharing::TRAY_ICON_NAME
1460                            );
1461                            info!("User {} logged in, launching tray", username);
1462                            let _ = sharing::natives::api::run_in_all_sessions(&tray_string, "", Some(&username), Some(uid));
1463                            break;
1464                        }
1465                    }
1466                    sleep(Duration::from_secs(3));
1467                }
1468            });
1469
1470
1471            let tray_string = sharing::paths::tray_icon_path().display().to_string();
1472            #[cfg(target_os = "windows")]
1473            if let Err(err) =
1474                sharing::natives::api::run_in_all_sessions(&tray_string, "", true, false)
1475            {
1476                error!("Error launching tray icon: {} for all users", err);
1477            }
1478
1479            #[cfg(not(target_os = "windows"))]
1480            if let Err(err) =
1481                sharing::natives::api::run_in_all_sessions(&tray_string, "", None, None)
1482            {
1483                error!("Error launching tray icon: {} for all users", err);
1484            }
1485
1486            Server::start_server(listener.clone(), stop_arc.clone(), pispas_service.clone());
1487
1488            // 🧹 CLEANUP FINAL
1489            info!("🧹 Final cleanup of socket: {}", socket_name);
1490            let _ = std::fs::remove_file(socket_name);
1491        }
1492	
1493	#[cfg(target_os = "macos")]
1494	 pub fn check(&mut self) -> sharing::PisPasResult<()> {
1495            let status = self.tray_status.read().clone();
1496            if let Some(proc) = self.process.as_mut() {
1497                match proc.try_wait() {
1498                    Ok(Some(exit_status)) => {
1499                        if status == DriverStatus::Running
1500                            || status == DriverStatus::Warning
1501                        {
1502                            tracing::warn!("Web driver process exited with status: {} restarting", exit_status);
1503                            self.launch_process(false)?;
1504                            self.change_status(DriverStatus::Warning);
1505                            self.notify_subscriber(&DriverStatus::Warning.to_string().as_str());
1506                            std::thread::sleep(Duration::from_secs(2));
1507
1508                        } else {
1509                            tracing::warn!("Web driver process exited with status: {} keep stopped", exit_status);
1510                        }
1511                    }
1512                    Err(e) => {
1513                        tracing::error!("Error checking web driver process: {} stopping", e);
1514                    }
1515                    Ok(None) => {
1516                        if status == DriverStatus::Stopped {
1517                            tracing::warn!("Web driver process running with status: {:?}", status);
1518                            self.stop_process()?;
1519                            self.notify_subscriber(&DriverStatus::Stopped.to_string().as_str())
1520                        }
1521                        if status == DriverStatus::Restart {
1522                            warn!("Web driver process running with status: {:?}, restarting", status);
1523                            self.stop_process()?;
1524                            std::thread::sleep(Duration::from_secs(1));
1525                            self.launch_process(false)?;
1526                            self.change_status(DriverStatus::Running);
1527                            self.notify_subscriber(&self.tray_status.clone().read().to_string().as_str());
1528                        }
1529                    }
1530                }
1531            }
1532            else{
1533                if status == DriverStatus::Running || status == DriverStatus::Launched {
1534                    tracing::warn!("Web driver process launched with status: {:?}", status);
1535                    self.launch_process(false)?;
1536                    self.change_status(DriverStatus::Running);
1537                    self.notify_subscriber(&self.tray_status.clone().read().to_string().as_str());
1538                }
1539                debug!("Web driver process is None, launching new process");
1540                debug!("status: {:?}", status);
1541            }
1542
1543            Ok(())
1544        }	
1545    
1546    	#[cfg(target_os = "windows")]
1547        pub fn check(&mut self) -> sharing::PisPasResult<()> {
1548            let status = {
1549                let guard = self.tray_status.read();
1550                guard.clone()
1551            };
1552
1553            match self.process {
1554                Some(_) => {
1555                    match status {
1556                        DriverStatus::Stopped => {
1557                            warn!("PrintService process stopped with status: {:?}", status);
1558                            self.stop_process()?;
1559                            self.close_duplicated_handle_from_map();
1560                            self.notify_subscriber(&status.to_string());
1561                        }
1562                        DriverStatus::Launched => {
1563                            self.change_status(DriverStatus::Running);
1564                        }
1565                        DriverStatus::Restart => {
1566                            warn!("PrintService process restarted with status: {:?}", status);
1567                            self.close_duplicated_handle_from_map();
1568                            self.stop_process()?;
1569                            sleep(Duration::from_millis(700));
1570                            self.launch_process(false)?;
1571                            sleep(Duration::from_millis(700));
1572                            self.change_status(DriverStatus::Running);
1573                            let new_status = {
1574                                let guard = self.tray_status.read();
1575                                guard.to_string()
1576                            };
1577                            self.notify_subscriber(&new_status);
1578                        }
1579                        _ => {} // Otros estados no necesitan acción cuando hay proceso
1580                    }
1581                }
1582                None => {
1583                    match status {
1584                        DriverStatus::Launched | DriverStatus::Running => {
1585                            warn!("PrintService process launched with status: {:?}", status);
1586                            let is_launched = !self.started;
1587                            self.launch_process(is_launched)?;
1588                            self.change_status(DriverStatus::Running);
1589                            let new_status = {
1590                                let guard = self.tray_status.read();
1591                                guard.to_string()
1592                            };
1593                            self.notify_subscriber(&new_status);
1594                        }
1595                        DriverStatus::Warning => {
1596                            warn!("PrintService process warning with status: {:?}", status);
1597                            self.close_duplicated_handle_from_map();
1598                            self.launch_process(false)?;
1599                            self.change_status(DriverStatus::Warning);
1600                            let new_status = {
1601                                let guard = self.tray_status.read();
1602                                guard.to_string()
1603                            };
1604                            self.notify_subscriber(&new_status);
1605                        }
1606                        DriverStatus::Stopped => {
1607                            self.close_duplicated_handle_from_map();
1608                            debug!("PrintService process stopped with status: {:?}", status);
1609                            if self.started {
1610                                self.change_status(DriverStatus::Stopped);
1611                                self.notify_subscriber(&status.to_string());
1612                            }
1613                        }
1614                        _ => {} // Otros estados
1615                    }
1616                }
1617            }
1618            Ok(())
1619        }
1620    }
1621}
1622
1623pub use pispas_server::*;
1624