syslog_rs/sync/
syslog_sync_shared.rs

1/*-
2 * syslog-rs - a syslog client translated from libc to rust
3 * 
4 * Copyright 2025 Aleksandr Morozov
5 * 
6 * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
7 * the European Commission - subsequent versions of the EUPL (the "Licence").
8 * 
9 * You may not use this work except in compliance with the Licence.
10 * 
11 * You may obtain a copy of the Licence at:
12 * 
13 *    https://joinup.ec.europa.eu/software/page/eupl
14 * 
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 * Licence for the specific language governing permissions and limitations
19 * under the Licence.
20 */
21
22use std::{str, sync::Arc};
23
24// ATOMIC ACCESS
25use super::{syslog_sync_internal::SyncSyslogInternal, syslog_trait::SyslogApi};
26
27
28use std::sync::Mutex;
29
30
31use crate::{formatters::SyslogFormatter, map_error_code, socket::TapTypeData};
32use crate::common::*;
33use crate::error::SyRes;
34
35
36
37/// A common instance which describes the syslog state
38#[derive(Debug, Clone)]
39pub struct SyslogShared<F: SyslogFormatter>
40{   
41    /// A giantly locked syslog data
42    inner: Arc<Mutex<SyncSyslogInternal<F>>>,
43}
44
45unsafe impl<F: SyslogFormatter> Send for SyslogShared<F> {}
46unsafe impl<F: SyslogFormatter> Sync for SyslogShared<F> {}
47
48/*
49impl<F: SyslogFormatter> Drop for SyslogShared<F>
50{
51    fn drop(&mut self) 
52    {
53        match self.inner.lock()
54        {
55            Ok(mut inner) => 
56                {inner.disconnectlog();},
57            Err(e) => 
58                eprintln!("~syslog socket poisoned! '{}'", e),
59        }
60    }
61}*/
62
63impl<F: SyslogFormatter> SyslogShared<F>
64{
65    pub 
66    fn openlog(ident: Option<&str>, logstat: LogStat, facility: LogFacility, net_tap: TapTypeData) -> SyRes<SyslogShared<F>> 
67    {
68        let mut syslog = 
69            SyncSyslogInternal::<F>::new(ident, logstat, facility, net_tap)?;
70       
71        if logstat.contains(LogStat::LOG_NDELAY) == true
72        {
73            syslog.connectlog()?;
74        }
75
76        return Ok( 
77            Self
78            {
79                inner: Arc::new(Mutex::new(syslog)),
80            }
81        );
82    }
83}
84
85impl<F: SyslogFormatter> SyslogApi for SyslogShared<F>
86{
87    fn connectlog(&mut self) -> SyRes<()>
88    {
89        return 
90            self
91                .inner
92                .lock()
93                .map_err(|e| 
94                    map_error_code!(MutexPoisoned, "{}", e)
95                )?
96                .connectlog();
97    }
98
99    fn setlogmask(&self, logmask: i32) -> SyRes<i32> 
100    {
101        let pri = 
102            self
103                .inner
104                .lock()
105                .map_err(|e| 
106                    map_error_code!(MutexPoisoned, "{}", e)
107                )?
108                .set_logmask(logmask);
109
110        return Ok(pri);
111    }
112
113    fn closelog(&self) -> SyRes<()> 
114    {
115        return 
116            self
117                .inner
118                .lock()
119                .map_err(|e| 
120                    map_error_code!(MutexPoisoned, "{}", e)
121                )?
122                .disconnectlog();
123    }
124
125    #[inline]
126    fn syslog(&self, pri: Priority, fmt: String) 
127    {
128        self.vsyslog(pri, fmt);
129    }
130
131    #[inline]
132    fn vsyslog<S: AsRef<str>>(&self, pri: Priority, fmt: S) 
133    {
134        if let Ok(mut inner) = self.inner.lock()
135        {
136            inner.vsyslog1(pri, fmt.as_ref())
137        }
138
139        return;
140    }
141
142    /// This function can be used to update the facility name, for example
143    /// after fork().
144    /// 
145    /// # Arguments
146    /// 
147    /// * `ident` - a new identity (up to 48 UTF8 chars)
148    fn change_identity(&self, ident: &str) -> SyRes<()>
149    {
150        self
151            .inner
152            .lock()
153            .map_err(|e| 
154                map_error_code!(MutexPoisoned, "{}", e)
155            )?
156            .set_logtag(ident, true);
157
158        return Ok(());
159    }
160
161    fn reconnect(&self) -> SyRes<()>
162    {
163        let mut lock = 
164            self
165                .inner
166                .lock()
167                .map_err(|e| 
168                    map_error_code!(MutexPoisoned, "{}", e)
169                )?;
170
171        
172        lock.disconnectlog()?;
173
174        lock.connectlog()?;
175            
176        return Ok(());
177    }
178
179    fn update_tap_data(&self, tap_data: TapTypeData) -> SyRes<()>
180    {
181        let mut lock = 
182            self
183                .inner
184                .lock()
185                .map_err(|e| 
186                    map_error_code!(MutexPoisoned, "{}", e)
187                )?;
188
189        return lock.update_tap_data(tap_data);
190    }
191
192}
193