Skip to main content

syd/
lib.rs

1//
2// libsyd: Rust-based C library for syd interaction via /dev/syd
3// lib/src/lib.rs: syd API C Library
4//
5// Copyright (c) 2023, 2024, 2025, 2026 Ali Polatel <alip@chesswob.org>
6//
7// SPDX-License-Identifier: LGPL-3.0
8
9//! # libsyd - syd API Rust Library
10//!
11//! `libsyd` is a C library written in Rust that implements the syd
12//! stat API, providing an interface to the `/dev/syd` of syd. It
13//! allows for runtime configuration and interaction with the syd
14//! sandboxing environment.
15//!
16//! ## Overview
17//! The library is designed to interact with the syd sandboxing
18//! environment, offering functionalities to check and modify the state
19//! of the sandbox lock, and perform system calls to `/dev/syd`.
20//!
21//! For more detailed information and usage instructions, refer to the syd
22//! manual, available at [syd Manual](http://man.exherbo.org/syd.2.html).
23//!
24//! ## Author
25//! Ali Polatel <alip@chesswob.org>
26
27// We like safe, clean and simple code with documentation.
28#![deny(missing_docs)]
29#![deny(clippy::allow_attributes_without_reason)]
30#![deny(clippy::arithmetic_side_effects)]
31#![deny(clippy::as_ptr_cast_mut)]
32#![deny(clippy::as_underscore)]
33#![deny(clippy::assertions_on_result_states)]
34#![deny(clippy::borrow_as_ptr)]
35#![deny(clippy::branches_sharing_code)]
36#![deny(clippy::case_sensitive_file_extension_comparisons)]
37#![deny(clippy::cast_lossless)]
38#![deny(clippy::cast_possible_truncation)]
39#![deny(clippy::cast_possible_wrap)]
40#![deny(clippy::cast_precision_loss)]
41#![deny(clippy::cast_ptr_alignment)]
42#![deny(clippy::cast_sign_loss)]
43#![deny(clippy::checked_conversions)]
44#![deny(clippy::clear_with_drain)]
45#![deny(clippy::clone_on_ref_ptr)]
46#![deny(clippy::cloned_instead_of_copied)]
47#![deny(clippy::cognitive_complexity)]
48#![deny(clippy::collection_is_never_read)]
49#![deny(clippy::copy_iterator)]
50#![deny(clippy::create_dir)]
51#![deny(clippy::dbg_macro)]
52#![deny(clippy::debug_assert_with_mut_call)]
53#![deny(clippy::decimal_literal_representation)]
54#![deny(clippy::default_trait_access)]
55#![deny(clippy::default_union_representation)]
56#![deny(clippy::derive_partial_eq_without_eq)]
57#![deny(clippy::doc_link_with_quotes)]
58#![deny(clippy::doc_markdown)]
59#![deny(clippy::explicit_into_iter_loop)]
60#![deny(clippy::explicit_iter_loop)]
61#![deny(clippy::fallible_impl_from)]
62#![deny(clippy::missing_safety_doc)]
63#![deny(clippy::undocumented_unsafe_blocks)]
64
65use std::{
66    ffi::{CStr, OsStr, OsString},
67    fmt,
68    fs::{symlink_metadata, Metadata},
69    os::{
70        fd::RawFd,
71        linux::fs::MetadataExt as LinuxMetadataExt,
72        raw::{c_char, c_int},
73        unix::{
74            ffi::OsStrExt,
75            fs::{FileTypeExt, MetadataExt as UnixMetadataExt},
76        },
77    },
78    path::{Path, PathBuf},
79};
80
81/// `lock_state_t_t` type represents possible states for the sandbox lock.
82#[expect(non_camel_case_types)]
83pub type lock_state_t = u8;
84
85/// The sandbox lock is off, allowing all sandbox commands.
86pub const LOCK_OFF: lock_state_t = 0;
87/// The sandbox lock is set to on for all processes except the initial
88/// process (syd exec child).
89pub const LOCK_EXEC: lock_state_t = 1;
90/// The sandbox lock is in drop-only mode, allowing only privilege-dropping
91/// sandbox commands.
92pub const LOCK_DROP: lock_state_t = 2;
93/// The sandbox lock is in read-only mode, allowing only read-only access
94/// to sandbox state.
95pub const LOCK_READ: lock_state_t = 3;
96/// The sandbox lock is on, disallowing all sandbox commands.
97pub const LOCK_ON: lock_state_t = 4;
98
99// An enumeration of the possible states for the sandbox lock.
100#[repr(u8)]
101#[derive(Copy, Clone, Debug)]
102enum LockState {
103    // The sandbox lock is off, allowing all sandbox commands.
104    Off = LOCK_OFF,
105    // The sandbox lock is set to on for all processes except the initial
106    // process (syd exec child).
107    Exec = LOCK_EXEC,
108    // The sandbox lock is in drop-only mode, allowing only privilege-dropping
109    // sandbox commands.
110    Drop = LOCK_DROP,
111    // The sandbox lock is in read-only mode, allowing only read-only access
112    // to sandbox state.
113    Read = LOCK_READ,
114    // The sandbox lock is on, disallowing all sandbox commands.
115    On = LOCK_ON,
116}
117
118impl TryFrom<lock_state_t> for LockState {
119    type Error = ();
120
121    fn try_from(value: lock_state_t) -> Result<Self, Self::Error> {
122        match value {
123            LOCK_OFF => Ok(LockState::Off),
124            LOCK_EXEC => Ok(LockState::Exec),
125            LOCK_DROP => Ok(LockState::Drop),
126            LOCK_READ => Ok(LockState::Read),
127            LOCK_ON => Ok(LockState::On),
128            _ => Err(()),
129        }
130    }
131}
132
133impl fmt::Display for LockState {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        let state_str = match self {
136            LockState::Off => "off",
137            LockState::Exec => "exec",
138            LockState::Drop => "drop",
139            LockState::Read => "read",
140            LockState::On => "on",
141        };
142        write!(f, "{state_str}")
143    }
144}
145
146/// `action_t` type represents possible sandboxing action values.
147#[expect(non_camel_case_types)]
148pub type action_t = u8;
149
150/// Allow system call.
151pub const ACTION_ALLOW: action_t = 0;
152/// Allow system call and warn.
153pub const ACTION_WARN: action_t = 1;
154/// Deny system call silently.
155pub const ACTION_FILTER: action_t = 2;
156/// Deny system call and warn.
157pub const ACTION_DENY: action_t = 3;
158/// Deny system call, warn and panic the current Syd thread.
159pub const ACTION_PANIC: action_t = 4;
160/// Deny system call, warn and stop the offending process.
161pub const ACTION_STOP: action_t = 5;
162/// Deny system call, warn and abort the offending process.
163pub const ACTION_ABORT: action_t = 6;
164/// Deny system call, warn and kill the offending process.
165pub const ACTION_KILL: action_t = 7;
166/// Warn, and exit Syd immediately with deny errno as exit value.
167pub const ACTION_EXIT: action_t = 8;
168
169// An enumeration of the possible actions for sandboxing.
170#[repr(u8)]
171#[derive(Copy, Clone, Debug)]
172enum Action {
173    // Allow system call.
174    Allow = ACTION_ALLOW,
175    // Allow system call and warn.
176    Warn = ACTION_WARN,
177    // Deny system call silently.
178    Filter = ACTION_FILTER,
179    // Deny system call and warn.
180    Deny = ACTION_DENY,
181    // Deny system call, warn and panic the current Syd thread.
182    Panic = ACTION_PANIC,
183    // Deny system call, warn and stop the offending process.
184    Stop = ACTION_STOP,
185    // Deny system call, warn and abort offending process.
186    Abort = ACTION_ABORT,
187    // Deny system call, warn and kill the offending process.
188    Kill = ACTION_KILL,
189    // Warn, and exit Syd immediately with deny errno as exit value.
190    Exit = ACTION_EXIT,
191}
192
193impl TryFrom<action_t> for Action {
194    type Error = ();
195
196    fn try_from(value: action_t) -> Result<Self, Self::Error> {
197        match value {
198            ACTION_ALLOW => Ok(Action::Allow),
199            ACTION_WARN => Ok(Action::Warn),
200            ACTION_FILTER => Ok(Action::Filter),
201            ACTION_DENY => Ok(Action::Deny),
202            ACTION_PANIC => Ok(Action::Panic),
203            ACTION_STOP => Ok(Action::Stop),
204            ACTION_ABORT => Ok(Action::Abort),
205            ACTION_KILL => Ok(Action::Kill),
206            ACTION_EXIT => Ok(Action::Exit),
207            _ => Err(()),
208        }
209    }
210}
211
212impl fmt::Display for Action {
213    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214        let action_str = match self {
215            Action::Allow => "allow",
216            Action::Warn => "warn",
217            Action::Filter => "filter",
218            Action::Deny => "deny",
219            Action::Panic => "panic",
220            Action::Stop => "stop",
221            Action::Abort => "abort",
222            Action::Kill => "kill",
223            Action::Exit => "exit",
224        };
225        write!(f, "{action_str}")
226    }
227}
228
229const EFAULT: i32 = 14;
230const EINVAL: i32 = 22;
231const LIB_MAJOR: &'static str = env!("CARGO_PKG_VERSION_MAJOR");
232const SYD_ATIME: i64 = 505958400;
233const SYD_CTIME: i64 = -2036448000;
234const SYD_MTIME: i64 = -842745600;
235
236fn check_stat(stat: &Metadata) -> bool {
237    let lib_major = if let Ok(lib_major) = LIB_MAJOR.parse() {
238        lib_major
239    } else {
240        return false;
241    };
242
243    // Check file type.
244    if !stat.file_type().is_char_device() {
245        return false;
246    }
247
248    // Check timestamps.
249    if stat.st_atime() != SYD_ATIME {
250        return false;
251    }
252    if stat.st_ctime() != SYD_CTIME {
253        return false;
254    }
255    if stat.st_mtime() != SYD_MTIME {
256        return false;
257    }
258
259    let rdev = stat.rdev();
260
261    let api_major = (rdev >> 8) & 0xff;
262    let api_minor = rdev & 0xff;
263
264    // Device type represents syd(2) API version.
265    // See RETURN VALUE section in syd(2) manual page.
266    api_major == lib_major && api_minor >= 1
267}
268
269fn stat<P: AsRef<Path>>(path: P) -> c_int {
270    match symlink_metadata(path) {
271        Ok(stat) if check_stat(&stat) => 0,
272        Ok(_) => -EINVAL,
273        Err(error) => match error.raw_os_error() {
274            Some(e) => e.checked_neg().unwrap_or(-EINVAL),
275            None => -EINVAL,
276        },
277    }
278}
279
280fn esyd<P: AsRef<Path>>(rule: P, elem: *const c_char, op: u8) -> c_int {
281    if !matches!(op, b'+' | b'-' | b'^' | b':') {
282        return -EINVAL;
283    }
284
285    if elem.is_null() {
286        return -EFAULT;
287    }
288
289    // SAFETY: Trust that `elem` is a null-terminated string.
290    let elem = unsafe { CStr::from_ptr(elem) };
291    let elem = OsStr::from_bytes(elem.to_bytes());
292
293    // Manually concatenate the path segments
294    let mut path = OsString::from("/dev/syd/");
295    path.push(rule.as_ref());
296    path.push(OsStr::from_bytes(&[op]));
297    path.push(elem);
298
299    // Convert the OsString to PathBuf
300    let path = PathBuf::from(path);
301
302    stat(path)
303}
304
305/// Performs a syd API check
306///
307/// The caller is advised to perform this check before
308/// calling any other syd API calls.
309///
310/// Returns API number on success, negated errno on failure.
311#[no_mangle]
312pub extern "C" fn syd_api() -> c_int {
313    match stat("/dev/syd/3") {
314        0 => 3,
315        n => n,
316    }
317}
318
319/// Performs an lstat system call on the file "/dev/syd".
320///
321/// Returns 0 on success, negated errno on failure.
322#[no_mangle]
323pub extern "C" fn syd_check() -> c_int {
324    stat("/dev/syd")
325}
326
327/// Causes syd to exit immediately with code 127
328///
329/// Returns 0 on success, negated errno on failure.
330#[no_mangle]
331pub extern "C" fn syd_panic() -> c_int {
332    stat("/dev/syd/panic")
333}
334
335/// Causes syd to reset sandboxing to the default state.
336/// Allowlists, denylists and filters are going to be cleared.
337///
338/// Returns 0 on success, negated errno on failure.
339#[no_mangle]
340pub extern "C" fn syd_reset() -> c_int {
341    stat("/dev/syd/reset")
342}
343
344/// Causes syd to read configuration from the given file descriptor.
345///
346/// Returns 0 on success, negated errno on failure.
347#[no_mangle]
348pub extern "C" fn syd_load(fd: c_int) -> c_int {
349    let fd = match RawFd::try_from(fd) {
350        Ok(fd) if fd < 0 => return -EINVAL,
351        Ok(fd) => fd,
352        Err(_) => return -EINVAL,
353    };
354    stat(&format!("/dev/syd/load/{fd}"))
355}
356
357/// Sets the state of the sandbox lock.
358///
359/// state: The desired state of the sandbox lock.
360///
361/// Returns 0 on success, negated errno on failure.
362#[no_mangle]
363pub extern "C" fn syd_lock(state: lock_state_t) -> c_int {
364    // Convert lock_state_t enum to corresponding lock state string.
365    let state = match LockState::try_from(state) {
366        Ok(state) => state,
367        Err(_) => return -EINVAL,
368    };
369
370    stat(&format!("/dev/syd/lock:{state}"))
371}
372
373/// Checks if Filesystem sandboxing is enabled.
374///
375/// Returns true if Filesystem sandboxing is enabled, false otherwise.
376#[no_mangle]
377pub extern "C" fn syd_enabled_fs() -> bool {
378    stat("/dev/syd/sandbox/fs?") == 0
379}
380
381/// Enable Filesystem sandboxing.
382///
383/// Returns 0 on success, negated errno on failure.
384#[no_mangle]
385pub extern "C" fn syd_enable_fs() -> c_int {
386    stat("/dev/syd/sandbox/fs:on")
387}
388
389/// Disable Filesystem sandboxing.
390///
391/// Returns 0 on success, negated errno on failure.
392#[no_mangle]
393pub extern "C" fn syd_disable_fs() -> c_int {
394    stat("/dev/syd/sandbox/fs:off")
395}
396
397/// Checks if walk sandboxing is enabled.
398///
399/// Returns true if walk sandboxing is enabled, false otherwise.
400#[no_mangle]
401pub extern "C" fn syd_enabled_walk() -> bool {
402    stat("/dev/syd/sandbox/walk?") == 0
403}
404
405/// Enable walk sandboxing.
406///
407/// Returns 0 on success, negated errno on failure.
408#[no_mangle]
409pub extern "C" fn syd_enable_walk() -> c_int {
410    stat("/dev/syd/sandbox/walk:on")
411}
412
413/// Disable walk sandboxing.
414///
415/// Returns 0 on success, negated errno on failure.
416#[no_mangle]
417pub extern "C" fn syd_disable_walk() -> c_int {
418    stat("/dev/syd/sandbox/walk:off")
419}
420
421/// Checks if stat sandboxing is enabled.
422///
423/// Returns true if stat sandboxing is enabled, false otherwise.
424#[no_mangle]
425pub extern "C" fn syd_enabled_stat() -> bool {
426    stat("/dev/syd/sandbox/stat?") == 0
427}
428
429/// Enable stat sandboxing.
430///
431/// Returns 0 on success, negated errno on failure.
432#[no_mangle]
433pub extern "C" fn syd_enable_stat() -> c_int {
434    stat("/dev/syd/sandbox/stat:on")
435}
436
437/// Disable stat sandboxing.
438///
439/// Returns 0 on success, negated errno on failure.
440#[no_mangle]
441pub extern "C" fn syd_disable_stat() -> c_int {
442    stat("/dev/syd/sandbox/stat:off")
443}
444
445/// Checks if read sandboxing is enabled.
446///
447/// Returns true if read sandboxing is enabled, false otherwise.
448#[no_mangle]
449pub extern "C" fn syd_enabled_read() -> bool {
450    stat("/dev/syd/sandbox/read?") == 0
451}
452
453/// Enable read sandboxing.
454///
455/// Returns 0 on success, negated errno on failure.
456#[no_mangle]
457pub extern "C" fn syd_enable_read() -> c_int {
458    stat("/dev/syd/sandbox/read:on")
459}
460
461/// Disable read sandboxing.
462///
463/// Returns 0 on success, negated errno on failure.
464#[no_mangle]
465pub extern "C" fn syd_disable_read() -> c_int {
466    stat("/dev/syd/sandbox/read:off")
467}
468
469/// Checks if write sandboxing is enabled.
470///
471/// Returns true if write sandboxing is enabled, false otherwise.
472#[no_mangle]
473pub extern "C" fn syd_enabled_write() -> bool {
474    stat("/dev/syd/sandbox/write?") == 0
475}
476
477/// Enable write sandboxing.
478///
479/// Returns 0 on success, negated errno on failure.
480#[no_mangle]
481pub extern "C" fn syd_enable_write() -> c_int {
482    stat("/dev/syd/sandbox/write:on")
483}
484
485/// Disable write sandboxing.
486///
487/// Returns 0 on success, negated errno on failure.
488#[no_mangle]
489pub extern "C" fn syd_disable_write() -> c_int {
490    stat("/dev/syd/sandbox/write:off")
491}
492
493/// Checks if exec sandboxing is enabled.
494///
495/// Returns true if exec sandboxing is enabled, false otherwise.
496#[no_mangle]
497pub extern "C" fn syd_enabled_exec() -> bool {
498    stat("/dev/syd/sandbox/exec?") == 0
499}
500
501/// Enable exec sandboxing.
502///
503/// Returns 0 on success, negated errno on failure.
504#[no_mangle]
505pub extern "C" fn syd_enable_exec() -> c_int {
506    stat("/dev/syd/sandbox/exec:on")
507}
508
509/// Disable exec sandboxing.
510///
511/// Returns 0 on success, negated errno on failure.
512#[no_mangle]
513pub extern "C" fn syd_disable_exec() -> c_int {
514    stat("/dev/syd/sandbox/exec:off")
515}
516
517/// Checks if ioctl sandboxing is enabled.
518///
519/// Returns true if ioctl sandboxing is enabled, false otherwise.
520#[no_mangle]
521pub extern "C" fn syd_enabled_ioctl() -> bool {
522    stat("/dev/syd/sandbox/ioctl?") == 0
523}
524
525/// Enable ioctl sandboxing.
526///
527/// Returns 0 on success, negated errno on failure.
528#[no_mangle]
529pub extern "C" fn syd_enable_ioctl() -> c_int {
530    stat("/dev/syd/sandbox/ioctl:on")
531}
532
533/// Disable ioctl sandboxing.
534///
535/// Returns 0 on success, negated errno on failure.
536#[no_mangle]
537pub extern "C" fn syd_disable_ioctl() -> c_int {
538    stat("/dev/syd/sandbox/ioctl:off")
539}
540
541/// Checks if create sandboxing is enabled.
542///
543/// Returns true if create sandboxing is enabled, false otherwise.
544#[no_mangle]
545pub extern "C" fn syd_enabled_create() -> bool {
546    stat("/dev/syd/sandbox/create?") == 0
547}
548
549/// Enable create sandboxing.
550///
551/// Returns 0 on success, negated errno on failure.
552#[no_mangle]
553pub extern "C" fn syd_enable_create() -> c_int {
554    stat("/dev/syd/sandbox/create:on")
555}
556
557/// Disable create sandboxing.
558///
559/// Returns 0 on success, negated errno on failure.
560#[no_mangle]
561pub extern "C" fn syd_disable_create() -> c_int {
562    stat("/dev/syd/sandbox/create:off")
563}
564
565/// Checks if delete sandboxing is enabled.
566///
567/// Returns true if delete sandboxing is enabled, false otherwise.
568#[no_mangle]
569pub extern "C" fn syd_enabled_delete() -> bool {
570    stat("/dev/syd/sandbox/delete?") == 0
571}
572
573/// Enable delete sandboxing.
574///
575/// Returns 0 on success, negated errno on failure.
576#[no_mangle]
577pub extern "C" fn syd_enable_delete() -> c_int {
578    stat("/dev/syd/sandbox/delete:on")
579}
580
581/// Disable delete sandboxing.
582///
583/// Returns 0 on success, negated errno on failure.
584#[no_mangle]
585pub extern "C" fn syd_disable_delete() -> c_int {
586    stat("/dev/syd/sandbox/delete:off")
587}
588
589/// Checks if rename sandboxing is enabled.
590///
591/// Returns true if rename sandboxing is enabled, false otherwise.
592#[no_mangle]
593pub extern "C" fn syd_enabled_rename() -> bool {
594    stat("/dev/syd/sandbox/rename?") == 0
595}
596
597/// Enable rename sandboxing.
598///
599/// Returns 0 on success, negated errno on failure.
600#[no_mangle]
601pub extern "C" fn syd_enable_rename() -> c_int {
602    stat("/dev/syd/sandbox/rename:on")
603}
604
605/// Disable rename sandboxing.
606///
607/// Returns 0 on success, negated errno on failure.
608#[no_mangle]
609pub extern "C" fn syd_disable_rename() -> c_int {
610    stat("/dev/syd/sandbox/rename:off")
611}
612
613/// Checks if symlink sandboxing is enabled.
614///
615/// Returns true if symlink sandboxing is enabled, false otherwise.
616#[no_mangle]
617pub extern "C" fn syd_enabled_symlink() -> bool {
618    stat("/dev/syd/sandbox/symlink?") == 0
619}
620
621/// Enable symlink sandboxing.
622///
623/// Returns 0 on success, negated errno on failure.
624#[no_mangle]
625pub extern "C" fn syd_enable_symlink() -> c_int {
626    stat("/dev/syd/sandbox/symlink:on")
627}
628
629/// Disable symlink sandboxing.
630///
631/// Returns 0 on success, negated errno on failure.
632#[no_mangle]
633pub extern "C" fn syd_disable_symlink() -> c_int {
634    stat("/dev/syd/sandbox/symlink:off")
635}
636
637/// Checks if truncate sandboxing is enabled.
638///
639/// Returns true if truncate sandboxing is enabled, false otherwise.
640#[no_mangle]
641pub extern "C" fn syd_enabled_truncate() -> bool {
642    stat("/dev/syd/sandbox/truncate?") == 0
643}
644
645/// Enable truncate sandboxing.
646///
647/// Returns 0 on success, negated errno on failure.
648#[no_mangle]
649pub extern "C" fn syd_enable_truncate() -> c_int {
650    stat("/dev/syd/sandbox/truncate:on")
651}
652
653/// Disable truncate sandboxing.
654///
655/// Returns 0 on success, negated errno on failure.
656#[no_mangle]
657pub extern "C" fn syd_disable_truncate() -> c_int {
658    stat("/dev/syd/sandbox/truncate:off")
659}
660
661/// Checks if chdir sandboxing is enabled.
662///
663/// Returns true if chdir sandboxing is enabled, false otherwise.
664#[no_mangle]
665pub extern "C" fn syd_enabled_chdir() -> bool {
666    stat("/dev/syd/sandbox/chdir?") == 0
667}
668
669/// Enable chdir sandboxing.
670///
671/// Returns 0 on success, negated errno on failure.
672#[no_mangle]
673pub extern "C" fn syd_enable_chdir() -> c_int {
674    stat("/dev/syd/sandbox/chdir:on")
675}
676
677/// Disable chdir sandboxing.
678///
679/// Returns 0 on success, negated errno on failure.
680#[no_mangle]
681pub extern "C" fn syd_disable_chdir() -> c_int {
682    stat("/dev/syd/sandbox/chdir:off")
683}
684
685/// Checks if readdir sandboxing is enabled.
686///
687/// Returns true if readdir sandboxing is enabled, false otherwise.
688#[no_mangle]
689pub extern "C" fn syd_enabled_readdir() -> bool {
690    stat("/dev/syd/sandbox/readdir?") == 0
691}
692
693/// Enable readdir sandboxing.
694///
695/// Returns 0 on success, negated errno on failure.
696#[no_mangle]
697pub extern "C" fn syd_enable_readdir() -> c_int {
698    stat("/dev/syd/sandbox/readdir:on")
699}
700
701/// Disable readdir sandboxing.
702///
703/// Returns 0 on success, negated errno on failure.
704#[no_mangle]
705pub extern "C" fn syd_disable_readdir() -> c_int {
706    stat("/dev/syd/sandbox/readdir:off")
707}
708
709/// Checks if mkdir sandboxing is enabled.
710///
711/// Returns true if mkdir sandboxing is enabled, false otherwise.
712#[no_mangle]
713pub extern "C" fn syd_enabled_mkdir() -> bool {
714    stat("/dev/syd/sandbox/mkdir?") == 0
715}
716
717/// Enable mkdir sandboxing.
718///
719/// Returns 0 on success, negated errno on failure.
720#[no_mangle]
721pub extern "C" fn syd_enable_mkdir() -> c_int {
722    stat("/dev/syd/sandbox/mkdir:on")
723}
724
725/// Disable mkdir sandboxing.
726///
727/// Returns 0 on success, negated errno on failure.
728#[no_mangle]
729pub extern "C" fn syd_disable_mkdir() -> c_int {
730    stat("/dev/syd/sandbox/mkdir:off")
731}
732
733/// Checks if rmdir sandboxing is enabled.
734///
735/// Returns true if rmdir sandboxing is enabled, false otherwise.
736#[no_mangle]
737pub extern "C" fn syd_enabled_rmdir() -> bool {
738    stat("/dev/syd/sandbox/rmdir?") == 0
739}
740
741/// Enable rmdir sandboxing.
742///
743/// Returns 0 on success, negated errno on failure.
744#[no_mangle]
745pub extern "C" fn syd_enable_rmdir() -> c_int {
746    stat("/dev/syd/sandbox/rmdir:on")
747}
748
749/// Disable rmdir sandboxing.
750///
751/// Returns 0 on success, negated errno on failure.
752#[no_mangle]
753pub extern "C" fn syd_disable_rmdir() -> c_int {
754    stat("/dev/syd/sandbox/rmdir:off")
755}
756
757/// Checks if chown sandboxing is enabled.
758///
759/// Returns true if chown sandboxing is enabled, false otherwise.
760#[no_mangle]
761pub extern "C" fn syd_enabled_chown() -> bool {
762    stat("/dev/syd/sandbox/chown?") == 0
763}
764
765/// Enable chown sandboxing.
766///
767/// Returns 0 on success, negated errno on failure.
768#[no_mangle]
769pub extern "C" fn syd_enable_chown() -> c_int {
770    stat("/dev/syd/sandbox/chown:on")
771}
772
773/// Disable chown sandboxing.
774///
775/// Returns 0 on success, negated errno on failure.
776#[no_mangle]
777pub extern "C" fn syd_disable_chown() -> c_int {
778    stat("/dev/syd/sandbox/chown:off")
779}
780
781/// Checks if chgrp sandboxing is enabled.
782///
783/// Returns true if chgrp sandboxing is enabled, false otherwise.
784#[no_mangle]
785pub extern "C" fn syd_enabled_chgrp() -> bool {
786    stat("/dev/syd/sandbox/chgrp?") == 0
787}
788
789/// Enable chgrp sandboxing.
790///
791/// Returns 0 on success, negated errno on failure.
792#[no_mangle]
793pub extern "C" fn syd_enable_chgrp() -> c_int {
794    stat("/dev/syd/sandbox/chgrp:on")
795}
796
797/// Disable chgrp sandboxing.
798///
799/// Returns 0 on success, negated errno on failure.
800#[no_mangle]
801pub extern "C" fn syd_disable_chgrp() -> c_int {
802    stat("/dev/syd/sandbox/chgrp:off")
803}
804
805/// Checks if chmod sandboxing is enabled.
806///
807/// Returns true if chmod sandboxing is enabled, false otherwise.
808#[no_mangle]
809pub extern "C" fn syd_enabled_chmod() -> bool {
810    stat("/dev/syd/sandbox/chmod?") == 0
811}
812
813/// Enable chmod sandboxing.
814///
815/// Returns 0 on success, negated errno on failure.
816#[no_mangle]
817pub extern "C" fn syd_enable_chmod() -> c_int {
818    stat("/dev/syd/sandbox/chmod:on")
819}
820
821/// Disable chmod sandboxing.
822///
823/// Returns 0 on success, negated errno on failure.
824#[no_mangle]
825pub extern "C" fn syd_disable_chmod() -> c_int {
826    stat("/dev/syd/sandbox/chmod:off")
827}
828
829/// Checks if chattr sandboxing is enabled.
830///
831/// Returns true if chattr sandboxing is enabled, false otherwise.
832#[no_mangle]
833pub extern "C" fn syd_enabled_chattr() -> bool {
834    stat("/dev/syd/sandbox/chattr?") == 0
835}
836
837/// Enable chattr sandboxing.
838///
839/// Returns 0 on success, negated errno on failure.
840#[no_mangle]
841pub extern "C" fn syd_enable_chattr() -> c_int {
842    stat("/dev/syd/sandbox/chattr:on")
843}
844
845/// Disable chattr sandboxing.
846///
847/// Returns 0 on success, negated errno on failure.
848#[no_mangle]
849pub extern "C" fn syd_disable_chattr() -> c_int {
850    stat("/dev/syd/sandbox/chattr:off")
851}
852
853/// Checks if chroot sandboxing is enabled.
854///
855/// Returns true if chroot sandboxing is enabled, false otherwise.
856#[no_mangle]
857pub extern "C" fn syd_enabled_chroot() -> bool {
858    stat("/dev/syd/sandbox/chroot?") == 0
859}
860
861/// Enable chroot sandboxing.
862///
863/// Returns 0 on success, negated errno on failure.
864#[no_mangle]
865pub extern "C" fn syd_enable_chroot() -> c_int {
866    stat("/dev/syd/sandbox/chroot:on")
867}
868
869/// Disable chroot sandboxing.
870///
871/// Returns 0 on success, negated errno on failure.
872#[no_mangle]
873pub extern "C" fn syd_disable_chroot() -> c_int {
874    stat("/dev/syd/sandbox/chroot:off")
875}
876
877/// Checks if notify sandboxing is enabled.
878///
879/// Returns true if notify sandboxing is enabled, false otherwise.
880#[no_mangle]
881pub extern "C" fn syd_enabled_notify() -> bool {
882    stat("/dev/syd/sandbox/notify?") == 0
883}
884
885/// Enable notify sandboxing.
886///
887/// Returns 0 on success, negated errno on failure.
888#[no_mangle]
889pub extern "C" fn syd_enable_notify() -> c_int {
890    stat("/dev/syd/sandbox/notify:on")
891}
892
893/// Disable notify sandboxing.
894///
895/// Returns 0 on success, negated errno on failure.
896#[no_mangle]
897pub extern "C" fn syd_disable_notify() -> c_int {
898    stat("/dev/syd/sandbox/notify:off")
899}
900
901/// Checks if utime sandboxing is enabled.
902///
903/// Returns true if utime sandboxing is enabled, false otherwise.
904#[no_mangle]
905pub extern "C" fn syd_enabled_utime() -> bool {
906    stat("/dev/syd/sandbox/utime?") == 0
907}
908
909/// Enable utime sandboxing.
910///
911/// Returns 0 on success, negated errno on failure.
912#[no_mangle]
913pub extern "C" fn syd_enable_utime() -> c_int {
914    stat("/dev/syd/sandbox/utime:on")
915}
916
917/// Disable utime sandboxing.
918///
919/// Returns 0 on success, negated errno on failure.
920#[no_mangle]
921pub extern "C" fn syd_disable_utime() -> c_int {
922    stat("/dev/syd/sandbox/utime:off")
923}
924
925/// Checks if mkbdev sandboxing is enabled.
926///
927/// Returns true if mkbdev sandboxing is enabled, false otherwise.
928#[no_mangle]
929pub extern "C" fn syd_enabled_mkbdev() -> bool {
930    stat("/dev/syd/sandbox/mkbdev?") == 0
931}
932
933/// Enable mkbdev sandboxing.
934///
935/// Returns 0 on success, negated errno on failure.
936#[no_mangle]
937pub extern "C" fn syd_enable_mkbdev() -> c_int {
938    stat("/dev/syd/sandbox/mkbdev:on")
939}
940
941/// Disable mkbdev sandboxing.
942///
943/// Returns 0 on success, negated errno on failure.
944#[no_mangle]
945pub extern "C" fn syd_disable_mkbdev() -> c_int {
946    stat("/dev/syd/sandbox/mkbdev:off")
947}
948
949/// Checks if mkcdev sandboxing is enabled.
950///
951/// Returns true if mkcdev sandboxing is enabled, false otherwise.
952#[no_mangle]
953pub extern "C" fn syd_enabled_mkcdev() -> bool {
954    stat("/dev/syd/sandbox/mkcdev?") == 0
955}
956
957/// Enable mkcdev sandboxing.
958///
959/// Returns 0 on success, negated errno on failure.
960#[no_mangle]
961pub extern "C" fn syd_enable_mkcdev() -> c_int {
962    stat("/dev/syd/sandbox/mkcdev:on")
963}
964
965/// Disable mkcdev sandboxing.
966///
967/// Returns 0 on success, negated errno on failure.
968#[no_mangle]
969pub extern "C" fn syd_disable_mkcdev() -> c_int {
970    stat("/dev/syd/sandbox/mkcdev:off")
971}
972
973/// Checks if mkfifo sandboxing is enabled.
974///
975/// Returns true if mkfifo sandboxing is enabled, false otherwise.
976#[no_mangle]
977pub extern "C" fn syd_enabled_mkfifo() -> bool {
978    stat("/dev/syd/sandbox/mkfifo?") == 0
979}
980
981/// Enable mkfifo sandboxing.
982///
983/// Returns 0 on success, negated errno on failure.
984#[no_mangle]
985pub extern "C" fn syd_enable_mkfifo() -> c_int {
986    stat("/dev/syd/sandbox/mkfifo:on")
987}
988
989/// Disable mkfifo sandboxing.
990///
991/// Returns 0 on success, negated errno on failure.
992#[no_mangle]
993pub extern "C" fn syd_disable_mkfifo() -> c_int {
994    stat("/dev/syd/sandbox/mkfifo:off")
995}
996
997/// Checks if mktemp sandboxing is enabled.
998///
999/// Returns true if mktemp sandboxing is enabled, false otherwise.
1000#[no_mangle]
1001pub extern "C" fn syd_enabled_mktemp() -> bool {
1002    stat("/dev/syd/sandbox/mktemp?") == 0
1003}
1004
1005/// Enable mktemp sandboxing.
1006///
1007/// Returns 0 on success, negated errno on failure.
1008#[no_mangle]
1009pub extern "C" fn syd_enable_mktemp() -> c_int {
1010    stat("/dev/syd/sandbox/mktemp:on")
1011}
1012
1013/// Disable mktemp sandboxing.
1014///
1015/// Returns 0 on success, negated errno on failure.
1016#[no_mangle]
1017pub extern "C" fn syd_disable_mktemp() -> c_int {
1018    stat("/dev/syd/sandbox/mktemp:off")
1019}
1020
1021/// Checks if net sandboxing is enabled.
1022///
1023/// Returns true if net sandboxing is enabled, false otherwise.
1024#[no_mangle]
1025pub extern "C" fn syd_enabled_net() -> bool {
1026    stat("/dev/syd/sandbox/net?") == 0
1027}
1028
1029/// Enable net sandboxing.
1030///
1031/// Returns 0 on success, negated errno on failure.
1032#[no_mangle]
1033pub extern "C" fn syd_enable_net() -> c_int {
1034    stat("/dev/syd/sandbox/net:on")
1035}
1036
1037/// Disable net sandboxing.
1038///
1039/// Returns 0 on success, negated errno on failure.
1040#[no_mangle]
1041pub extern "C" fn syd_disable_net() -> c_int {
1042    stat("/dev/syd/sandbox/net:off")
1043}
1044
1045/// Checks if memory sandboxing is enabled.
1046///
1047/// Returns true if memory sandboxing is enabled, false otherwise.
1048#[no_mangle]
1049pub extern "C" fn syd_enabled_mem() -> bool {
1050    stat("/dev/syd/sandbox/mem?") == 0
1051}
1052
1053/// Disable memory sandboxing.
1054///
1055/// Returns 0 on success, negated errno on failure.
1056#[no_mangle]
1057pub extern "C" fn syd_disable_mem() -> c_int {
1058    stat("/dev/syd/sandbox/mem:off")
1059}
1060
1061/// Checks if PID sandboxing is enabled.
1062///
1063/// Returns true if PID sandboxing is enabled, false otherwise.
1064#[no_mangle]
1065pub extern "C" fn syd_enabled_pid() -> bool {
1066    stat("/dev/syd/sandbox/pid?") == 0
1067}
1068
1069/// Enable PID sandboxing.
1070///
1071/// Returns 0 on success, negated errno on failure.
1072#[no_mangle]
1073pub extern "C" fn syd_enable_pid() -> c_int {
1074    stat("/dev/syd/sandbox/pid:on")
1075}
1076
1077/// Disable PID sandboxing.
1078///
1079/// Returns 0 on success, negated errno on failure.
1080#[no_mangle]
1081pub extern "C" fn syd_disable_pid() -> c_int {
1082    stat("/dev/syd/sandbox/pid:off")
1083}
1084
1085/// Checks if lock sandboxing is enabled.
1086///
1087/// Returns true if lock sandboxing is enabled, false otherwise.
1088#[no_mangle]
1089pub extern "C" fn syd_enabled_lock() -> bool {
1090    stat("/dev/syd/sandbox/lock?") == 0
1091}
1092
1093/// Checks if crypt sandboxing is enabled.
1094///
1095/// Returns true if crypt sandboxing is enabled, false otherwise.
1096#[no_mangle]
1097pub extern "C" fn syd_enabled_crypt() -> bool {
1098    stat("/dev/syd/sandbox/crypt?") == 0
1099}
1100
1101/// Checks if proxy sandboxing is enabled.
1102///
1103/// Returns true if proxy sandboxing is enabled, false otherwise.
1104#[no_mangle]
1105pub extern "C" fn syd_enabled_proxy() -> bool {
1106    stat("/dev/syd/sandbox/proxy?") == 0
1107}
1108
1109/// Checks if force sandboxing is enabled.
1110///
1111/// Returns true if force sandboxing is enabled, false otherwise.
1112#[no_mangle]
1113pub extern "C" fn syd_enabled_force() -> bool {
1114    stat("/dev/syd/sandbox/force?") == 0
1115}
1116
1117/// Disable force sandboxing.
1118///
1119/// Returns 0 on success, negated errno on failure.
1120#[no_mangle]
1121pub extern "C" fn syd_disable_force() -> c_int {
1122    stat("/dev/syd/sandbox/force:off")
1123}
1124
1125/// Checks if TPE sandboxing is enabled.
1126///
1127/// Returns true if TPE sandboxing is enabled, false otherwise.
1128#[no_mangle]
1129pub extern "C" fn syd_enabled_tpe() -> bool {
1130    stat("/dev/syd/sandbox/tpe?") == 0
1131}
1132
1133/// Enable TPE sandboxing.
1134///
1135/// Returns 0 on success, negated errno on failure.
1136#[no_mangle]
1137pub extern "C" fn syd_enable_tpe() -> c_int {
1138    stat("/dev/syd/sandbox/tpe:on")
1139}
1140
1141/// Disable TPE sandboxing.
1142///
1143/// Returns 0 on success, negated errno on failure.
1144#[no_mangle]
1145pub extern "C" fn syd_disable_tpe() -> c_int {
1146    stat("/dev/syd/sandbox/tpe:off")
1147}
1148
1149/// Set the default action for Filesystem sandboxing.
1150#[no_mangle]
1151pub extern "C" fn syd_default_fs(action: action_t) -> c_int {
1152    // Convert action_t enum to corresponding action string.
1153    let action = match Action::try_from(action) {
1154        Ok(action) => action,
1155        Err(_) => return -EINVAL,
1156    };
1157    stat(&format!("/dev/syd/default/fs:{action}"))
1158}
1159
1160/// Set the default action for Walk Sandboxing.
1161#[no_mangle]
1162pub extern "C" fn syd_default_walk(action: action_t) -> c_int {
1163    // Convert action_t enum to corresponding action string.
1164    let action = match Action::try_from(action) {
1165        Ok(action) => action,
1166        Err(_) => return -EINVAL,
1167    };
1168    stat(&format!("/dev/syd/default/walk:{action}"))
1169}
1170
1171/// Set the default action for Stat Sandboxing.
1172#[no_mangle]
1173pub extern "C" fn syd_default_stat(action: action_t) -> c_int {
1174    // Convert action_t enum to corresponding action string.
1175    let action = match Action::try_from(action) {
1176        Ok(action) => action,
1177        Err(_) => return -EINVAL,
1178    };
1179    stat(&format!("/dev/syd/default/stat:{action}"))
1180}
1181
1182/// Set the default action for Read Sandboxing.
1183#[no_mangle]
1184pub extern "C" fn syd_default_read(action: action_t) -> c_int {
1185    // Convert action_t enum to corresponding action string.
1186    let action = match Action::try_from(action) {
1187        Ok(action) => action,
1188        Err(_) => return -EINVAL,
1189    };
1190    stat(&format!("/dev/syd/default/read:{action}"))
1191}
1192
1193/// Set the default action for Write Sandboxing.
1194#[no_mangle]
1195pub extern "C" fn syd_default_write(action: action_t) -> c_int {
1196    // Convert action_t enum to corresponding action string.
1197    let action = match Action::try_from(action) {
1198        Ok(action) => action,
1199        Err(_) => return -EINVAL,
1200    };
1201    stat(&format!("/dev/syd/default/write:{action}"))
1202}
1203
1204/// Set the default action for Exec Sandboxing.
1205#[no_mangle]
1206pub extern "C" fn syd_default_exec(action: action_t) -> c_int {
1207    // Convert action_t enum to corresponding action string.
1208    let action = match Action::try_from(action) {
1209        Ok(action) => action,
1210        Err(_) => return -EINVAL,
1211    };
1212    stat(&format!("/dev/syd/default/exec:{action}"))
1213}
1214
1215/// Set the default action for Ioctl Sandboxing.
1216#[no_mangle]
1217pub extern "C" fn syd_default_ioctl(action: action_t) -> c_int {
1218    // Convert action_t enum to corresponding action string.
1219    let action = match Action::try_from(action) {
1220        Ok(action) => action,
1221        Err(_) => return -EINVAL,
1222    };
1223    stat(&format!("/dev/syd/default/ioctl:{action}"))
1224}
1225
1226/// Set the default action for Create Sandboxing.
1227#[no_mangle]
1228pub extern "C" fn syd_default_create(action: action_t) -> c_int {
1229    // Convert action_t enum to corresponding action string.
1230    let action = match Action::try_from(action) {
1231        Ok(action) => action,
1232        Err(_) => return -EINVAL,
1233    };
1234    stat(&format!("/dev/syd/default/create:{action}"))
1235}
1236
1237/// Set the default action for Delete Sandboxing.
1238#[no_mangle]
1239pub extern "C" fn syd_default_delete(action: action_t) -> c_int {
1240    // Convert action_t enum to corresponding action string.
1241    let action = match Action::try_from(action) {
1242        Ok(action) => action,
1243        Err(_) => return -EINVAL,
1244    };
1245    stat(&format!("/dev/syd/default/delete:{action}"))
1246}
1247
1248/// Set the default action for Rename Sandboxing.
1249#[no_mangle]
1250pub extern "C" fn syd_default_rename(action: action_t) -> c_int {
1251    // Convert action_t enum to corresponding action string.
1252    let action = match Action::try_from(action) {
1253        Ok(action) => action,
1254        Err(_) => return -EINVAL,
1255    };
1256    stat(&format!("/dev/syd/default/rename:{action}"))
1257}
1258
1259/// Set the default action for Symlink Sandboxing.
1260#[no_mangle]
1261pub extern "C" fn syd_default_symlink(action: action_t) -> c_int {
1262    // Convert action_t enum to corresponding action string.
1263    let action = match Action::try_from(action) {
1264        Ok(action) => action,
1265        Err(_) => return -EINVAL,
1266    };
1267    stat(&format!("/dev/syd/default/symlink:{action}"))
1268}
1269
1270/// Set the default action for Truncate Sandboxing.
1271#[no_mangle]
1272pub extern "C" fn syd_default_truncate(action: action_t) -> c_int {
1273    // Convert action_t enum to corresponding action string.
1274    let action = match Action::try_from(action) {
1275        Ok(action) => action,
1276        Err(_) => return -EINVAL,
1277    };
1278    stat(&format!("/dev/syd/default/truncate:{action}"))
1279}
1280
1281/// Set the default action for Chdir Sandboxing.
1282#[no_mangle]
1283pub extern "C" fn syd_default_chdir(action: action_t) -> c_int {
1284    // Convert action_t enum to corresponding action string.
1285    let action = match Action::try_from(action) {
1286        Ok(action) => action,
1287        Err(_) => return -EINVAL,
1288    };
1289    stat(&format!("/dev/syd/default/chdir:{action}"))
1290}
1291
1292/// Set the default action for Readdir Sandboxing.
1293#[no_mangle]
1294pub extern "C" fn syd_default_readdir(action: action_t) -> c_int {
1295    // Convert action_t enum to corresponding action string.
1296    let action = match Action::try_from(action) {
1297        Ok(action) => action,
1298        Err(_) => return -EINVAL,
1299    };
1300    stat(&format!("/dev/syd/default/readdir:{action}"))
1301}
1302
1303/// Set the default action for Mkdir Sandboxing.
1304#[no_mangle]
1305pub extern "C" fn syd_default_mkdir(action: action_t) -> c_int {
1306    // Convert action_t enum to corresponding action string.
1307    let action = match Action::try_from(action) {
1308        Ok(action) => action,
1309        Err(_) => return -EINVAL,
1310    };
1311    stat(&format!("/dev/syd/default/mkdir:{action}"))
1312}
1313
1314/// Set the default action for Rmdir Sandboxing.
1315#[no_mangle]
1316pub extern "C" fn syd_default_rmdir(action: action_t) -> c_int {
1317    // Convert action_t enum to corresponding action string.
1318    let action = match Action::try_from(action) {
1319        Ok(action) => action,
1320        Err(_) => return -EINVAL,
1321    };
1322    stat(&format!("/dev/syd/default/rmdir:{action}"))
1323}
1324
1325/// Set the default action for Chown Sandboxing.
1326#[no_mangle]
1327pub extern "C" fn syd_default_chown(action: action_t) -> c_int {
1328    // Convert action_t enum to corresponding action string.
1329    let action = match Action::try_from(action) {
1330        Ok(action) => action,
1331        Err(_) => return -EINVAL,
1332    };
1333    stat(&format!("/dev/syd/default/chown:{action}"))
1334}
1335
1336/// Set the default action for Chgrp Sandboxing.
1337#[no_mangle]
1338pub extern "C" fn syd_default_chgrp(action: action_t) -> c_int {
1339    // Convert action_t enum to corresponding action string.
1340    let action = match Action::try_from(action) {
1341        Ok(action) => action,
1342        Err(_) => return -EINVAL,
1343    };
1344    stat(&format!("/dev/syd/default/chgrp:{action}"))
1345}
1346
1347/// Set the default action for Chmod Sandboxing.
1348#[no_mangle]
1349pub extern "C" fn syd_default_chmod(action: action_t) -> c_int {
1350    // Convert action_t enum to corresponding action string.
1351    let action = match Action::try_from(action) {
1352        Ok(action) => action,
1353        Err(_) => return -EINVAL,
1354    };
1355    stat(&format!("/dev/syd/default/chmod:{action}"))
1356}
1357
1358/// Set the default action for Chattr Sandboxing.
1359#[no_mangle]
1360pub extern "C" fn syd_default_chattr(action: action_t) -> c_int {
1361    // Convert action_t enum to corresponding action string.
1362    let action = match Action::try_from(action) {
1363        Ok(action) => action,
1364        Err(_) => return -EINVAL,
1365    };
1366    stat(&format!("/dev/syd/default/chattr:{action}"))
1367}
1368
1369/// Set the default action for Chroot Sandboxing.
1370#[no_mangle]
1371pub extern "C" fn syd_default_chroot(action: action_t) -> c_int {
1372    // Convert action_t enum to corresponding action string.
1373    let action = match Action::try_from(action) {
1374        Ok(action) => action,
1375        Err(_) => return -EINVAL,
1376    };
1377    stat(&format!("/dev/syd/default/chroot:{action}"))
1378}
1379
1380/// Set the default action for Notify Sandboxing.
1381#[no_mangle]
1382pub extern "C" fn syd_default_notify(action: action_t) -> c_int {
1383    // Convert action_t enum to corresponding action string.
1384    let action = match Action::try_from(action) {
1385        Ok(action) => action,
1386        Err(_) => return -EINVAL,
1387    };
1388    stat(&format!("/dev/syd/default/notify:{action}"))
1389}
1390
1391/// Set the default action for Utime Sandboxing.
1392#[no_mangle]
1393pub extern "C" fn syd_default_utime(action: action_t) -> c_int {
1394    // Convert action_t enum to corresponding action string.
1395    let action = match Action::try_from(action) {
1396        Ok(action) => action,
1397        Err(_) => return -EINVAL,
1398    };
1399    stat(&format!("/dev/syd/default/utime:{action}"))
1400}
1401
1402/// Set the default action for Mkbdev Sandboxing.
1403#[no_mangle]
1404pub extern "C" fn syd_default_mkbdev(action: action_t) -> c_int {
1405    // Convert action_t enum to corresponding action string.
1406    let action = match Action::try_from(action) {
1407        Ok(action) => action,
1408        Err(_) => return -EINVAL,
1409    };
1410    stat(&format!("/dev/syd/default/mkbdev:{action}"))
1411}
1412
1413/// Set the default action for Mkcdev Sandboxing.
1414#[no_mangle]
1415pub extern "C" fn syd_default_mkcdev(action: action_t) -> c_int {
1416    // Convert action_t enum to corresponding action string.
1417    let action = match Action::try_from(action) {
1418        Ok(action) => action,
1419        Err(_) => return -EINVAL,
1420    };
1421    stat(&format!("/dev/syd/default/mkcdev:{action}"))
1422}
1423
1424/// Set the default action for Mkfifo Sandboxing.
1425#[no_mangle]
1426pub extern "C" fn syd_default_mkfifo(action: action_t) -> c_int {
1427    // Convert action_t enum to corresponding action string.
1428    let action = match Action::try_from(action) {
1429        Ok(action) => action,
1430        Err(_) => return -EINVAL,
1431    };
1432    stat(&format!("/dev/syd/default/mkfifo:{action}"))
1433}
1434
1435/// Set the default action for Mktemp Sandboxing.
1436#[no_mangle]
1437pub extern "C" fn syd_default_mktemp(action: action_t) -> c_int {
1438    // Convert action_t enum to corresponding action string.
1439    let action = match Action::try_from(action) {
1440        Ok(action) => action,
1441        Err(_) => return -EINVAL,
1442    };
1443    stat(&format!("/dev/syd/default/mktemp:{action}"))
1444}
1445
1446/// Set the default action for Network Sandboxing.
1447#[no_mangle]
1448pub extern "C" fn syd_default_net(action: action_t) -> c_int {
1449    // Convert action_t enum to corresponding action string.
1450    let action = match Action::try_from(action) {
1451        Ok(action) => action,
1452        Err(_) => return -EINVAL,
1453    };
1454    stat(&format!("/dev/syd/default/net:{action}"))
1455}
1456
1457/// Set the default action for IP blocklist violations.
1458#[no_mangle]
1459pub extern "C" fn syd_default_block(action: action_t) -> c_int {
1460    // Convert action_t enum to corresponding action string.
1461    let action = match Action::try_from(action) {
1462        Ok(action) => action,
1463        Err(_) => return -EINVAL,
1464    };
1465    stat(&format!("/dev/syd/default/block:{action}"))
1466}
1467
1468/// Set the default action for Memory Sandboxing.
1469#[no_mangle]
1470pub extern "C" fn syd_default_mem(action: action_t) -> c_int {
1471    // Convert action_t enum to corresponding action string.
1472    let action = match Action::try_from(action) {
1473        Ok(action) => action,
1474        Err(_) => return -EINVAL,
1475    };
1476    stat(&format!("/dev/syd/default/mem:{action}"))
1477}
1478
1479/// Set the default action for PID Sandboxing.
1480#[no_mangle]
1481pub extern "C" fn syd_default_pid(action: action_t) -> c_int {
1482    // Convert action_t enum to corresponding action string.
1483    let action = match Action::try_from(action) {
1484        Ok(action) => action,
1485        Err(_) => return -EINVAL,
1486    };
1487    stat(&format!("/dev/syd/default/pid:{action}"))
1488}
1489
1490/// Set the default action for Force Sandboxing.
1491#[no_mangle]
1492pub extern "C" fn syd_default_force(action: action_t) -> c_int {
1493    // Convert action_t enum to corresponding action string.
1494    let action = match Action::try_from(action) {
1495        Ok(action) => action,
1496        Err(_) => return -EINVAL,
1497    };
1498    stat(&format!("/dev/syd/default/force:{action}"))
1499}
1500
1501/// Set the default action for SegvGuard
1502#[no_mangle]
1503pub extern "C" fn syd_default_segvguard(action: action_t) -> c_int {
1504    // Convert action_t enum to corresponding action string.
1505    let action = match Action::try_from(action) {
1506        Ok(action) => action,
1507        Err(_) => return -EINVAL,
1508    };
1509    stat(&format!("/dev/syd/default/segvguard:{action}"))
1510}
1511
1512/// Set the default action for TPE Sandboxing.
1513#[no_mangle]
1514pub extern "C" fn syd_default_tpe(action: action_t) -> c_int {
1515    // Convert action_t enum to corresponding action string.
1516    let action = match Action::try_from(action) {
1517        Ok(action) => action,
1518        Err(_) => return -EINVAL,
1519    };
1520    stat(&format!("/dev/syd/default/tpe:{action}"))
1521}
1522
1523/// Adds a request to the _ioctl_(2) denylist.
1524#[no_mangle]
1525pub extern "C" fn syd_ioctl_deny(request: u64) -> c_int {
1526    stat(&format!("/dev/syd/deny/ioctl+{request}"))
1527}
1528
1529/// Adds an entry to the Integrity Force map for Force Sandboxing.
1530///
1531/// # Safety
1532///
1533/// This function is marked `unsafe` because it dereferences raw
1534/// pointers, which is inherently unsafe in Rust.
1535///
1536/// The caller must ensure the following conditions are met to safely
1537/// use this function:
1538///
1539/// 1. The `path` pointer must point to a valid, null-terminated C-style
1540///    string.
1541/// 2. The `alg` pointer must point to a valid, null-terminated C-style
1542///    string naming the hash algorithm (e.g. "sha3-512").
1543/// 3. The `hash` pointer must point to a valid, null-terminated C-style
1544///    string.
1545#[no_mangle]
1546pub unsafe extern "C" fn syd_force_add(
1547    path: *const c_char,
1548    alg: *const c_char,
1549    hash: *const c_char,
1550    action: action_t,
1551) -> c_int {
1552    // Convert action_t enum to corresponding action string.
1553    let action = match Action::try_from(action) {
1554        Ok(action) => action,
1555        Err(_) => return -EINVAL,
1556    };
1557
1558    if path.is_null() || alg.is_null() || hash.is_null() {
1559        return -EFAULT;
1560    }
1561
1562    // SAFETY: Trust that `path`, `alg` and `hash` are null-terminated strings.
1563    let path = unsafe { CStr::from_ptr(path) };
1564    // SAFETY: ditto.
1565    let alg = unsafe { CStr::from_ptr(alg) };
1566    // SAFETY: ditto.
1567    let hash = unsafe { CStr::from_ptr(hash) };
1568    let path = match path.to_str() {
1569        Ok(s) => s,
1570        Err(_) => return -EINVAL,
1571    };
1572    let alg = match alg.to_str() {
1573        Ok(s) => s,
1574        Err(_) => return -EINVAL,
1575    };
1576    let hash = match hash.to_str() {
1577        Ok(s) => s,
1578        Err(_) => return -EINVAL,
1579    };
1580
1581    // Call the stat function with the formatted string.
1582    stat(format!("/dev/syd/force+{path}:{alg}:{hash}:{action}"))
1583}
1584
1585/// Removes an entry from the Integrity Force map for Force Sandboxing.
1586/// # Safety
1587///
1588/// This function is marked `unsafe` because it dereferences raw
1589/// pointers, which is inherently unsafe in Rust.
1590///
1591/// The caller must ensure the following conditions are met to safely
1592/// use this function:
1593///
1594/// 1. The `path` pointer must point to a valid, null-terminated C-style
1595///    string.
1596#[no_mangle]
1597pub unsafe extern "C" fn syd_force_del(path: *const c_char) -> c_int {
1598    if path.is_null() {
1599        return -EFAULT;
1600    }
1601
1602    // SAFETY: Trust that `path` is a null-terminated string.
1603    let path = unsafe { CStr::from_ptr(path) };
1604    let path = match path.to_str() {
1605        Ok(s) => s,
1606        Err(_) => return -EINVAL,
1607    };
1608
1609    // Call the stat function with the formatted string.
1610    stat(format!("/dev/syd/force-{path}"))
1611}
1612
1613/// Clears the Integrity Force map for Force Sandboxing.
1614#[no_mangle]
1615pub extern "C" fn syd_force_clr() -> c_int {
1616    stat("/dev/syd/force^")
1617}
1618
1619/// Adds to the given actionlist of Filesystem sandboxing.
1620///
1621/// Returns 0 on success, negated errno on failure.
1622#[no_mangle]
1623pub extern "C" fn syd_fs_add(action: action_t, name: *const c_char) -> c_int {
1624    // Convert action_t enum to corresponding action string.
1625    let action = match Action::try_from(action) {
1626        Ok(action) => action,
1627        Err(_) => return -EINVAL,
1628    };
1629
1630    // Call magic function with add operator.
1631    esyd(&format!("{action}/fs"), name, b'+')
1632}
1633
1634/// Removes the first instance from the end of the given actionlist of
1635/// Filesystem sandboxing.
1636///
1637/// Returns 0 on success, negated errno on failure.
1638#[no_mangle]
1639pub extern "C" fn syd_fs_del(action: action_t, name: *const c_char) -> c_int {
1640    // Convert action_t enum to corresponding action string.
1641    let action = match Action::try_from(action) {
1642        Ok(action) => action,
1643        Err(_) => return -EINVAL,
1644    };
1645
1646    // Call magic function with del operator.
1647    esyd(&format!("{action}/fs"), name, b'-')
1648}
1649
1650/// Removes all matching patterns from the given actionlist of Filesystem sandboxing.
1651///
1652/// Returns 0 on success, negated errno on failure.
1653#[no_mangle]
1654pub extern "C" fn syd_fs_rem(action: action_t, name: *const c_char) -> c_int {
1655    // Convert action_t enum to corresponding action string.
1656    let action = match Action::try_from(action) {
1657        Ok(action) => action,
1658        Err(_) => return -EINVAL,
1659    };
1660
1661    // Call magic function with rem operator.
1662    esyd(&format!("{action}/fs"), name, b'^')
1663}
1664
1665/// Adds to the given actionlist of walk sandboxing.
1666///
1667/// Returns 0 on success, negated errno on failure.
1668#[no_mangle]
1669pub extern "C" fn syd_walk_add(action: action_t, glob: *const c_char) -> c_int {
1670    // Convert action_t enum to corresponding action string.
1671    let action = match Action::try_from(action) {
1672        Ok(action) => action,
1673        Err(_) => return -EINVAL,
1674    };
1675
1676    // Call magic function with add operator.
1677    esyd(&format!("{action}/walk"), glob, b'+')
1678}
1679
1680/// Removes the first instance from the end of the given actionlist of
1681/// walk sandboxing.
1682///
1683/// Returns 0 on success, negated errno on failure.
1684#[no_mangle]
1685pub extern "C" fn syd_walk_del(action: action_t, glob: *const c_char) -> c_int {
1686    // Convert action_t enum to corresponding action string.
1687    let action = match Action::try_from(action) {
1688        Ok(action) => action,
1689        Err(_) => return -EINVAL,
1690    };
1691
1692    // Call magic function with del operator.
1693    esyd(&format!("{action}/walk"), glob, b'-')
1694}
1695
1696/// Removes all matching patterns from the given actionlist of walk sandboxing.
1697///
1698/// Returns 0 on success, negated errno on failure.
1699#[no_mangle]
1700pub extern "C" fn syd_walk_rem(action: action_t, glob: *const c_char) -> c_int {
1701    // Convert action_t enum to corresponding action string.
1702    let action = match Action::try_from(action) {
1703        Ok(action) => action,
1704        Err(_) => return -EINVAL,
1705    };
1706
1707    // Call magic function with rem operator.
1708    esyd(&format!("{action}/walk"), glob, b'^')
1709}
1710
1711/// Adds to the given actionlist of stat sandboxing.
1712///
1713/// Returns 0 on success, negated errno on failure.
1714#[no_mangle]
1715pub extern "C" fn syd_stat_add(action: action_t, glob: *const c_char) -> c_int {
1716    // Convert action_t enum to corresponding action string.
1717    let action = match Action::try_from(action) {
1718        Ok(action) => action,
1719        Err(_) => return -EINVAL,
1720    };
1721
1722    // Call magic function with add operator.
1723    esyd(&format!("{action}/stat"), glob, b'+')
1724}
1725
1726/// Removes the first instance from the end of the given actionlist of
1727/// stat sandboxing.
1728///
1729/// Returns 0 on success, negated errno on failure.
1730#[no_mangle]
1731pub extern "C" fn syd_stat_del(action: action_t, glob: *const c_char) -> c_int {
1732    // Convert action_t enum to corresponding action string.
1733    let action = match Action::try_from(action) {
1734        Ok(action) => action,
1735        Err(_) => return -EINVAL,
1736    };
1737
1738    // Call magic function with del operator.
1739    esyd(&format!("{action}/stat"), glob, b'-')
1740}
1741
1742/// Removes all matching patterns from the given actionlist of stat sandboxing.
1743///
1744/// Returns 0 on success, negated errno on failure.
1745#[no_mangle]
1746pub extern "C" fn syd_stat_rem(action: action_t, glob: *const c_char) -> c_int {
1747    // Convert action_t enum to corresponding action string.
1748    let action = match Action::try_from(action) {
1749        Ok(action) => action,
1750        Err(_) => return -EINVAL,
1751    };
1752
1753    // Call magic function with rem operator.
1754    esyd(&format!("{action}/stat"), glob, b'^')
1755}
1756
1757/// Adds to the given actionlist of read sandboxing.
1758///
1759/// Returns 0 on success, negated errno on failure.
1760#[no_mangle]
1761pub extern "C" fn syd_read_add(action: action_t, glob: *const c_char) -> c_int {
1762    // Convert action_t enum to corresponding action string.
1763    let action = match Action::try_from(action) {
1764        Ok(action) => action,
1765        Err(_) => return -EINVAL,
1766    };
1767
1768    // Call magic function with add operator.
1769    esyd(&format!("{action}/read"), glob, b'+')
1770}
1771
1772/// Removes the first instance from the end of the given actionlist of
1773/// read sandboxing.
1774///
1775/// Returns 0 on success, negated errno on failure.
1776#[no_mangle]
1777pub extern "C" fn syd_read_del(action: action_t, glob: *const c_char) -> c_int {
1778    // Convert action_t enum to corresponding action string.
1779    let action = match Action::try_from(action) {
1780        Ok(action) => action,
1781        Err(_) => return -EINVAL,
1782    };
1783
1784    // Call magic function with del operator.
1785    esyd(&format!("{action}/read"), glob, b'-')
1786}
1787
1788/// Removes all matching patterns from the given actionlist of read sandboxing.
1789///
1790/// Returns 0 on success, negated errno on failure.
1791#[no_mangle]
1792pub extern "C" fn syd_read_rem(action: action_t, glob: *const c_char) -> c_int {
1793    // Convert action_t enum to corresponding action string.
1794    let action = match Action::try_from(action) {
1795        Ok(action) => action,
1796        Err(_) => return -EINVAL,
1797    };
1798
1799    // Call magic function with rem operator.
1800    esyd(&format!("{action}/read"), glob, b'^')
1801}
1802
1803/// Adds to the given actionlist of write sandboxing.
1804///
1805/// Returns 0 on success, negated errno on failure.
1806#[no_mangle]
1807pub extern "C" fn syd_write_add(action: action_t, glob: *const c_char) -> c_int {
1808    // Convert action_t enum to corresponding action string.
1809    let action = match Action::try_from(action) {
1810        Ok(action) => action,
1811        Err(_) => return -EINVAL,
1812    };
1813
1814    // Call magic function with add operator.
1815    esyd(&format!("{action}/write"), glob, b'+')
1816}
1817
1818/// Removes the first instance from the end of the given actionlist of
1819/// write sandboxing.
1820///
1821/// Returns 0 on success, negated errno on failure.
1822#[no_mangle]
1823pub extern "C" fn syd_write_del(action: action_t, glob: *const c_char) -> c_int {
1824    // Convert action_t enum to corresponding action string.
1825    let action = match Action::try_from(action) {
1826        Ok(action) => action,
1827        Err(_) => return -EINVAL,
1828    };
1829
1830    // Call magic function with del operator.
1831    esyd(&format!("{action}/write"), glob, b'-')
1832}
1833
1834/// Removes all matching patterns from the given actionlist of write sandboxing.
1835///
1836/// Returns 0 on success, negated errno on failure.
1837#[no_mangle]
1838pub extern "C" fn syd_write_rem(action: action_t, glob: *const c_char) -> c_int {
1839    // Convert action_t enum to corresponding action string.
1840    let action = match Action::try_from(action) {
1841        Ok(action) => action,
1842        Err(_) => return -EINVAL,
1843    };
1844
1845    // Call magic function with rem operator.
1846    esyd(&format!("{action}/write"), glob, b'^')
1847}
1848
1849/// Adds to the given actionlist of exec sandboxing.
1850///
1851/// Returns 0 on success, negated errno on failure.
1852#[no_mangle]
1853pub extern "C" fn syd_exec_add(action: action_t, glob: *const c_char) -> c_int {
1854    // Convert action_t enum to corresponding action string.
1855    let action = match Action::try_from(action) {
1856        Ok(action) => action,
1857        Err(_) => return -EINVAL,
1858    };
1859
1860    // Call magic function with add operator.
1861    esyd(&format!("{action}/exec"), glob, b'+')
1862}
1863
1864/// Removes the first instance from the end of the given actionlist of
1865/// exec sandboxing.
1866///
1867/// Returns 0 on success, negated errno on failure.
1868#[no_mangle]
1869pub extern "C" fn syd_exec_del(action: action_t, glob: *const c_char) -> c_int {
1870    // Convert action_t enum to corresponding action string.
1871    let action = match Action::try_from(action) {
1872        Ok(action) => action,
1873        Err(_) => return -EINVAL,
1874    };
1875
1876    // Call magic function with del operator.
1877    esyd(&format!("{action}/exec"), glob, b'-')
1878}
1879
1880/// Removes all matching patterns from the given actionlist of exec sandboxing.
1881///
1882/// Returns 0 on success, negated errno on failure.
1883#[no_mangle]
1884pub extern "C" fn syd_exec_rem(action: action_t, glob: *const c_char) -> c_int {
1885    // Convert action_t enum to corresponding action string.
1886    let action = match Action::try_from(action) {
1887        Ok(action) => action,
1888        Err(_) => return -EINVAL,
1889    };
1890
1891    // Call magic function with rem operator.
1892    esyd(&format!("{action}/exec"), glob, b'^')
1893}
1894
1895/// Adds to the given actionlist of create sandboxing.
1896///
1897/// Returns 0 on success, negated errno on failure.
1898#[no_mangle]
1899pub extern "C" fn syd_create_add(action: action_t, glob: *const c_char) -> c_int {
1900    // Convert action_t enum to corresponding action string.
1901    let action = match Action::try_from(action) {
1902        Ok(action) => action,
1903        Err(_) => return -EINVAL,
1904    };
1905
1906    // Call magic function with add operator.
1907    esyd(&format!("{action}/create"), glob, b'+')
1908}
1909
1910/// Removes the first instance from the end of the given actionlist of
1911/// create sandboxing.
1912///
1913/// Returns 0 on success, negated errno on failure.
1914#[no_mangle]
1915pub extern "C" fn syd_create_del(action: action_t, glob: *const c_char) -> c_int {
1916    // Convert action_t enum to corresponding action string.
1917    let action = match Action::try_from(action) {
1918        Ok(action) => action,
1919        Err(_) => return -EINVAL,
1920    };
1921
1922    // Call magic function with del operator.
1923    esyd(&format!("{action}/create"), glob, b'-')
1924}
1925
1926/// Removes all matching patterns from the given actionlist of create sandboxing.
1927///
1928/// Returns 0 on success, negated errno on failure.
1929#[no_mangle]
1930pub extern "C" fn syd_create_rem(action: action_t, glob: *const c_char) -> c_int {
1931    // Convert action_t enum to corresponding action string.
1932    let action = match Action::try_from(action) {
1933        Ok(action) => action,
1934        Err(_) => return -EINVAL,
1935    };
1936
1937    // Call magic function with rem operator.
1938    esyd(&format!("{action}/create"), glob, b'^')
1939}
1940
1941/// Adds to the given actionlist of delete sandboxing.
1942///
1943/// Returns 0 on success, negated errno on failure.
1944#[no_mangle]
1945pub extern "C" fn syd_delete_add(action: action_t, glob: *const c_char) -> c_int {
1946    // Convert action_t enum to corresponding action string.
1947    let action = match Action::try_from(action) {
1948        Ok(action) => action,
1949        Err(_) => return -EINVAL,
1950    };
1951
1952    // Call magic function with add operator.
1953    esyd(&format!("{action}/delete"), glob, b'+')
1954}
1955
1956/// Removes the first instance from the end of the given actionlist of
1957/// delete sandboxing.
1958///
1959/// Returns 0 on success, negated errno on failure.
1960#[no_mangle]
1961pub extern "C" fn syd_delete_del(action: action_t, glob: *const c_char) -> c_int {
1962    // Convert action_t enum to corresponding action string.
1963    let action = match Action::try_from(action) {
1964        Ok(action) => action,
1965        Err(_) => return -EINVAL,
1966    };
1967
1968    // Call magic function with del operator.
1969    esyd(&format!("{action}/delete"), glob, b'-')
1970}
1971
1972/// Removes all matching patterns from the given actionlist of delete sandboxing.
1973///
1974/// Returns 0 on success, negated errno on failure.
1975#[no_mangle]
1976pub extern "C" fn syd_delete_rem(action: action_t, glob: *const c_char) -> c_int {
1977    // Convert action_t enum to corresponding action string.
1978    let action = match Action::try_from(action) {
1979        Ok(action) => action,
1980        Err(_) => return -EINVAL,
1981    };
1982
1983    // Call magic function with rem operator.
1984    esyd(&format!("{action}/delete"), glob, b'^')
1985}
1986
1987/// Adds to the given actionlist of rename sandboxing.
1988///
1989/// Returns 0 on success, negated errno on failure.
1990#[no_mangle]
1991pub extern "C" fn syd_rename_add(action: action_t, glob: *const c_char) -> c_int {
1992    // Convert action_t enum to corresponding action string.
1993    let action = match Action::try_from(action) {
1994        Ok(action) => action,
1995        Err(_) => return -EINVAL,
1996    };
1997
1998    // Call magic function with add operator.
1999    esyd(&format!("{action}/rename"), glob, b'+')
2000}
2001
2002/// Removes the first instance from the end of the given actionlist of
2003/// rename sandboxing.
2004///
2005/// Returns 0 on success, negated errno on failure.
2006#[no_mangle]
2007pub extern "C" fn syd_rename_del(action: action_t, glob: *const c_char) -> c_int {
2008    // Convert action_t enum to corresponding action string.
2009    let action = match Action::try_from(action) {
2010        Ok(action) => action,
2011        Err(_) => return -EINVAL,
2012    };
2013
2014    // Call magic function with del operator.
2015    esyd(&format!("{action}/rename"), glob, b'-')
2016}
2017
2018/// Removes all matching patterns from the given actionlist of rename sandboxing.
2019///
2020/// Returns 0 on success, negated errno on failure.
2021#[no_mangle]
2022pub extern "C" fn syd_rename_rem(action: action_t, glob: *const c_char) -> c_int {
2023    // Convert action_t enum to corresponding action string.
2024    let action = match Action::try_from(action) {
2025        Ok(action) => action,
2026        Err(_) => return -EINVAL,
2027    };
2028
2029    // Call magic function with rem operator.
2030    esyd(&format!("{action}/rename"), glob, b'^')
2031}
2032
2033/// Adds to the given actionlist of symlink sandboxing.
2034///
2035/// Returns 0 on success, negated errno on failure.
2036#[no_mangle]
2037pub extern "C" fn syd_symlink_add(action: action_t, glob: *const c_char) -> c_int {
2038    // Convert action_t enum to corresponding action string.
2039    let action = match Action::try_from(action) {
2040        Ok(action) => action,
2041        Err(_) => return -EINVAL,
2042    };
2043
2044    // Call magic function with add operator.
2045    esyd(&format!("{action}/symlink"), glob, b'+')
2046}
2047
2048/// Removes the first instance from the end of the given actionlist of
2049/// symlink sandboxing.
2050///
2051/// Returns 0 on success, negated errno on failure.
2052#[no_mangle]
2053pub extern "C" fn syd_symlink_del(action: action_t, glob: *const c_char) -> c_int {
2054    // Convert action_t enum to corresponding action string.
2055    let action = match Action::try_from(action) {
2056        Ok(action) => action,
2057        Err(_) => return -EINVAL,
2058    };
2059
2060    // Call magic function with del operator.
2061    esyd(&format!("{action}/symlink"), glob, b'-')
2062}
2063
2064/// Removes all matching patterns from the given actionlist of symlink sandboxing.
2065///
2066/// Returns 0 on success, negated errno on failure.
2067#[no_mangle]
2068pub extern "C" fn syd_symlink_rem(action: action_t, glob: *const c_char) -> c_int {
2069    // Convert action_t enum to corresponding action string.
2070    let action = match Action::try_from(action) {
2071        Ok(action) => action,
2072        Err(_) => return -EINVAL,
2073    };
2074
2075    // Call magic function with rem operator.
2076    esyd(&format!("{action}/symlink"), glob, b'^')
2077}
2078
2079/// Adds to the given actionlist of truncate sandboxing.
2080///
2081/// Returns 0 on success, negated errno on failure.
2082#[no_mangle]
2083pub extern "C" fn syd_truncate_add(action: action_t, glob: *const c_char) -> c_int {
2084    // Convert action_t enum to corresponding action string.
2085    let action = match Action::try_from(action) {
2086        Ok(action) => action,
2087        Err(_) => return -EINVAL,
2088    };
2089
2090    // Call magic function with add operator.
2091    esyd(&format!("{action}/truncate"), glob, b'+')
2092}
2093
2094/// Removes the first instance from the end of the given actionlist of
2095/// truncate sandboxing.
2096///
2097/// Returns 0 on success, negated errno on failure.
2098#[no_mangle]
2099pub extern "C" fn syd_truncate_del(action: action_t, glob: *const c_char) -> c_int {
2100    // Convert action_t enum to corresponding action string.
2101    let action = match Action::try_from(action) {
2102        Ok(action) => action,
2103        Err(_) => return -EINVAL,
2104    };
2105
2106    // Call magic function with del operator.
2107    esyd(&format!("{action}/truncate"), glob, b'-')
2108}
2109
2110/// Removes all matching patterns from the given actionlist of truncate sandboxing.
2111///
2112/// Returns 0 on success, negated errno on failure.
2113#[no_mangle]
2114pub extern "C" fn syd_truncate_rem(action: action_t, glob: *const c_char) -> c_int {
2115    // Convert action_t enum to corresponding action string.
2116    let action = match Action::try_from(action) {
2117        Ok(action) => action,
2118        Err(_) => return -EINVAL,
2119    };
2120
2121    // Call magic function with rem operator.
2122    esyd(&format!("{action}/truncate"), glob, b'^')
2123}
2124
2125/// Adds to the given actionlist of chdir sandboxing.
2126///
2127/// Returns 0 on success, negated errno on failure.
2128#[no_mangle]
2129pub extern "C" fn syd_chdir_add(action: action_t, glob: *const c_char) -> c_int {
2130    // Convert action_t enum to corresponding action string.
2131    let action = match Action::try_from(action) {
2132        Ok(action) => action,
2133        Err(_) => return -EINVAL,
2134    };
2135
2136    // Call magic function with add operator.
2137    esyd(&format!("{action}/chdir"), glob, b'+')
2138}
2139
2140/// Removes the first instance from the end of the given actionlist of
2141/// chdir sandboxing.
2142///
2143/// Returns 0 on success, negated errno on failure.
2144#[no_mangle]
2145pub extern "C" fn syd_chdir_del(action: action_t, glob: *const c_char) -> c_int {
2146    // Convert action_t enum to corresponding action string.
2147    let action = match Action::try_from(action) {
2148        Ok(action) => action,
2149        Err(_) => return -EINVAL,
2150    };
2151
2152    // Call magic function with del operator.
2153    esyd(&format!("{action}/chdir"), glob, b'-')
2154}
2155
2156/// Removes all matching patterns from the given actionlist of chdir sandboxing.
2157///
2158/// Returns 0 on success, negated errno on failure.
2159#[no_mangle]
2160pub extern "C" fn syd_chdir_rem(action: action_t, glob: *const c_char) -> c_int {
2161    // Convert action_t enum to corresponding action string.
2162    let action = match Action::try_from(action) {
2163        Ok(action) => action,
2164        Err(_) => return -EINVAL,
2165    };
2166
2167    // Call magic function with rem operator.
2168    esyd(&format!("{action}/chdir"), glob, b'^')
2169}
2170
2171/// Adds to the given actionlist of readdir sandboxing.
2172///
2173/// Returns 0 on success, negated errno on failure.
2174#[no_mangle]
2175pub extern "C" fn syd_readdir_add(action: action_t, glob: *const c_char) -> c_int {
2176    // Convert action_t enum to corresponding action string.
2177    let action = match Action::try_from(action) {
2178        Ok(action) => action,
2179        Err(_) => return -EINVAL,
2180    };
2181
2182    // Call magic function with add operator.
2183    esyd(&format!("{action}/readdir"), glob, b'+')
2184}
2185
2186/// Removes the first instance from the end of the given actionlist of
2187/// readdir sandboxing.
2188///
2189/// Returns 0 on success, negated errno on failure.
2190#[no_mangle]
2191pub extern "C" fn syd_readdir_del(action: action_t, glob: *const c_char) -> c_int {
2192    // Convert action_t enum to corresponding action string.
2193    let action = match Action::try_from(action) {
2194        Ok(action) => action,
2195        Err(_) => return -EINVAL,
2196    };
2197
2198    // Call magic function with del operator.
2199    esyd(&format!("{action}/readdir"), glob, b'-')
2200}
2201
2202/// Removes all matching patterns from the given actionlist of readdir sandboxing.
2203///
2204/// Returns 0 on success, negated errno on failure.
2205#[no_mangle]
2206pub extern "C" fn syd_readdir_rem(action: action_t, glob: *const c_char) -> c_int {
2207    // Convert action_t enum to corresponding action string.
2208    let action = match Action::try_from(action) {
2209        Ok(action) => action,
2210        Err(_) => return -EINVAL,
2211    };
2212
2213    // Call magic function with del operator.
2214    esyd(&format!("{action}/readdir"), glob, b'^')
2215}
2216
2217/// Adds to the given actionlist of mkdir sandboxing.
2218///
2219/// Returns 0 on success, negated errno on failure.
2220#[no_mangle]
2221pub extern "C" fn syd_mkdir_add(action: action_t, glob: *const c_char) -> c_int {
2222    // Convert action_t enum to corresponding action string.
2223    let action = match Action::try_from(action) {
2224        Ok(action) => action,
2225        Err(_) => return -EINVAL,
2226    };
2227
2228    // Call magic function with add operator.
2229    esyd(&format!("{action}/mkdir"), glob, b'+')
2230}
2231
2232/// Removes the first instance from the end of the given actionlist of
2233/// mkdir sandboxing.
2234///
2235/// Returns 0 on success, negated errno on failure.
2236#[no_mangle]
2237pub extern "C" fn syd_mkdir_del(action: action_t, glob: *const c_char) -> c_int {
2238    // Convert action_t enum to corresponding action string.
2239    let action = match Action::try_from(action) {
2240        Ok(action) => action,
2241        Err(_) => return -EINVAL,
2242    };
2243
2244    // Call magic function with del operator.
2245    esyd(&format!("{action}/mkdir"), glob, b'-')
2246}
2247
2248/// Removes all matching patterns from the given actionlist of mkdir sandboxing.
2249///
2250/// Returns 0 on success, negated errno on failure.
2251#[no_mangle]
2252pub extern "C" fn syd_mkdir_rem(action: action_t, glob: *const c_char) -> c_int {
2253    // Convert action_t enum to corresponding action string.
2254    let action = match Action::try_from(action) {
2255        Ok(action) => action,
2256        Err(_) => return -EINVAL,
2257    };
2258
2259    // Call magic function with del operator.
2260    esyd(&format!("{action}/mkdir"), glob, b'^')
2261}
2262
2263/// Adds to the given actionlist of rmdir sandboxing.
2264///
2265/// Returns 0 on success, negated errno on failure.
2266#[no_mangle]
2267pub extern "C" fn syd_rmdir_add(action: action_t, glob: *const c_char) -> c_int {
2268    // Convert action_t enum to corresponding action string.
2269    let action = match Action::try_from(action) {
2270        Ok(action) => action,
2271        Err(_) => return -EINVAL,
2272    };
2273
2274    // Call magic function with add operator.
2275    esyd(&format!("{action}/rmdir"), glob, b'+')
2276}
2277
2278/// Removes the first instance from the end of the given actionlist of
2279/// rmdir sandboxing.
2280///
2281/// Returns 0 on success, negated errno on failure.
2282#[no_mangle]
2283pub extern "C" fn syd_rmdir_del(action: action_t, glob: *const c_char) -> c_int {
2284    // Convert action_t enum to corresponding action string.
2285    let action = match Action::try_from(action) {
2286        Ok(action) => action,
2287        Err(_) => return -EINVAL,
2288    };
2289
2290    // Call magic function with del operator.
2291    esyd(&format!("{action}/rmdir"), glob, b'-')
2292}
2293
2294/// Removes all matching patterns from the given actionlist of rmdir sandboxing.
2295///
2296/// Returns 0 on success, negated errno on failure.
2297#[no_mangle]
2298pub extern "C" fn syd_rmdir_rem(action: action_t, glob: *const c_char) -> c_int {
2299    // Convert action_t enum to corresponding action string.
2300    let action = match Action::try_from(action) {
2301        Ok(action) => action,
2302        Err(_) => return -EINVAL,
2303    };
2304
2305    // Call magic function with del operator.
2306    esyd(&format!("{action}/rmdir"), glob, b'^')
2307}
2308
2309/// Adds to the given actionlist of chown sandboxing.
2310///
2311/// Returns 0 on success, negated errno on failure.
2312#[no_mangle]
2313pub extern "C" fn syd_chown_add(action: action_t, glob: *const c_char) -> c_int {
2314    // Convert action_t enum to corresponding action string.
2315    let action = match Action::try_from(action) {
2316        Ok(action) => action,
2317        Err(_) => return -EINVAL,
2318    };
2319
2320    // Call magic function with add operator.
2321    esyd(&format!("{action}/chown"), glob, b'+')
2322}
2323
2324/// Removes the first instance from the end of the given actionlist of
2325/// chown sandboxing.
2326///
2327/// Returns 0 on success, negated errno on failure.
2328#[no_mangle]
2329pub extern "C" fn syd_chown_del(action: action_t, glob: *const c_char) -> c_int {
2330    // Convert action_t enum to corresponding action string.
2331    let action = match Action::try_from(action) {
2332        Ok(action) => action,
2333        Err(_) => return -EINVAL,
2334    };
2335
2336    // Call magic function with del operator.
2337    esyd(&format!("{action}/chown"), glob, b'-')
2338}
2339
2340/// Removes all matching patterns from the given actionlist of chown sandboxing.
2341///
2342/// Returns 0 on success, negated errno on failure.
2343#[no_mangle]
2344pub extern "C" fn syd_chown_rem(action: action_t, glob: *const c_char) -> c_int {
2345    // Convert action_t enum to corresponding action string.
2346    let action = match Action::try_from(action) {
2347        Ok(action) => action,
2348        Err(_) => return -EINVAL,
2349    };
2350
2351    // Call magic function with rem operator.
2352    esyd(&format!("{action}/chown"), glob, b'^')
2353}
2354
2355/// Adds to the given actionlist of chgrp sandboxing.
2356///
2357/// Returns 0 on success, negated errno on failure.
2358#[no_mangle]
2359pub extern "C" fn syd_chgrp_add(action: action_t, glob: *const c_char) -> c_int {
2360    // Convert action_t enum to corresponding action string.
2361    let action = match Action::try_from(action) {
2362        Ok(action) => action,
2363        Err(_) => return -EINVAL,
2364    };
2365
2366    // Call magic function with add operator.
2367    esyd(&format!("{action}/chgrp"), glob, b'+')
2368}
2369
2370/// Removes the first instance from the end of the given actionlist of
2371/// chgrp sandboxing.
2372///
2373/// Returns 0 on success, negated errno on failure.
2374#[no_mangle]
2375pub extern "C" fn syd_chgrp_del(action: action_t, glob: *const c_char) -> c_int {
2376    // Convert action_t enum to corresponding action string.
2377    let action = match Action::try_from(action) {
2378        Ok(action) => action,
2379        Err(_) => return -EINVAL,
2380    };
2381
2382    // Call magic function with del operator.
2383    esyd(&format!("{action}/chgrp"), glob, b'-')
2384}
2385
2386/// Removes all matching patterns from the given actionlist of chgrp sandboxing.
2387///
2388/// Returns 0 on success, negated errno on failure.
2389#[no_mangle]
2390pub extern "C" fn syd_chgrp_rem(action: action_t, glob: *const c_char) -> c_int {
2391    // Convert action_t enum to corresponding action string.
2392    let action = match Action::try_from(action) {
2393        Ok(action) => action,
2394        Err(_) => return -EINVAL,
2395    };
2396
2397    // Call magic function with rem operator.
2398    esyd(&format!("{action}/chgrp"), glob, b'^')
2399}
2400
2401/// Adds to the given actionlist of chmod sandboxing.
2402///
2403/// Returns 0 on success, negated errno on failure.
2404#[no_mangle]
2405pub extern "C" fn syd_chmod_add(action: action_t, glob: *const c_char) -> c_int {
2406    // Convert action_t enum to corresponding action string.
2407    let action = match Action::try_from(action) {
2408        Ok(action) => action,
2409        Err(_) => return -EINVAL,
2410    };
2411
2412    // Call magic function with add operator.
2413    esyd(&format!("{action}/chmod"), glob, b'+')
2414}
2415
2416/// Removes the first instance from the end of the given actionlist of
2417/// chmod sandboxing.
2418///
2419/// Returns 0 on success, negated errno on failure.
2420#[no_mangle]
2421pub extern "C" fn syd_chmod_del(action: action_t, glob: *const c_char) -> c_int {
2422    // Convert action_t enum to corresponding action string.
2423    let action = match Action::try_from(action) {
2424        Ok(action) => action,
2425        Err(_) => return -EINVAL,
2426    };
2427
2428    // Call magic function with del operator.
2429    esyd(&format!("{action}/chmod"), glob, b'-')
2430}
2431
2432/// Removes all matching patterns from the given actionlist of chmod sandboxing.
2433///
2434/// Returns 0 on success, negated errno on failure.
2435#[no_mangle]
2436pub extern "C" fn syd_chmod_rem(action: action_t, glob: *const c_char) -> c_int {
2437    // Convert action_t enum to corresponding action string.
2438    let action = match Action::try_from(action) {
2439        Ok(action) => action,
2440        Err(_) => return -EINVAL,
2441    };
2442
2443    // Call magic function with rem operator.
2444    esyd(&format!("{action}/chmod"), glob, b'^')
2445}
2446
2447/// Adds to the given actionlist of chattr sandboxing.
2448///
2449/// Returns 0 on success, negated errno on failure.
2450#[no_mangle]
2451pub extern "C" fn syd_chattr_add(action: action_t, glob: *const c_char) -> c_int {
2452    // Convert action_t enum to corresponding action string.
2453    let action = match Action::try_from(action) {
2454        Ok(action) => action,
2455        Err(_) => return -EINVAL,
2456    };
2457
2458    // Call magic function with add operator.
2459    esyd(&format!("{action}/chattr"), glob, b'+')
2460}
2461
2462/// Removes the first instance from the end of the given actionlist of
2463/// chattr sandboxing.
2464///
2465/// Returns 0 on success, negated errno on failure.
2466#[no_mangle]
2467pub extern "C" fn syd_chattr_del(action: action_t, glob: *const c_char) -> c_int {
2468    // Convert action_t enum to corresponding action string.
2469    let action = match Action::try_from(action) {
2470        Ok(action) => action,
2471        Err(_) => return -EINVAL,
2472    };
2473
2474    // Call magic function with del operator.
2475    esyd(&format!("{action}/chattr"), glob, b'-')
2476}
2477
2478/// Removes all matching patterns from the given actionlist of chattr sandboxing.
2479///
2480/// Returns 0 on success, negated errno on failure.
2481#[no_mangle]
2482pub extern "C" fn syd_chattr_rem(action: action_t, glob: *const c_char) -> c_int {
2483    // Convert action_t enum to corresponding action string.
2484    let action = match Action::try_from(action) {
2485        Ok(action) => action,
2486        Err(_) => return -EINVAL,
2487    };
2488
2489    // Call magic function with rem operator.
2490    esyd(&format!("{action}/chattr"), glob, b'^')
2491}
2492
2493/// Adds to the given actionlist of chroot sandboxing.
2494///
2495/// Returns 0 on success, negated errno on failure.
2496#[no_mangle]
2497pub extern "C" fn syd_chroot_add(action: action_t, glob: *const c_char) -> c_int {
2498    // Convert action_t enum to corresponding action string.
2499    let action = match Action::try_from(action) {
2500        Ok(action) => action,
2501        Err(_) => return -EINVAL,
2502    };
2503
2504    // Call magic function with add operator.
2505    esyd(&format!("{action}/chroot"), glob, b'+')
2506}
2507
2508/// Removes the first instance from the end of the given actionlist of
2509/// chroot sandboxing.
2510///
2511/// Returns 0 on success, negated errno on failure.
2512#[no_mangle]
2513pub extern "C" fn syd_chroot_del(action: action_t, glob: *const c_char) -> c_int {
2514    // Convert action_t enum to corresponding action string.
2515    let action = match Action::try_from(action) {
2516        Ok(action) => action,
2517        Err(_) => return -EINVAL,
2518    };
2519
2520    // Call magic function with del operator.
2521    esyd(&format!("{action}/chroot"), glob, b'-')
2522}
2523
2524/// Removes all matching patterns from the given actionlist of chroot sandboxing.
2525///
2526/// Returns 0 on success, negated errno on failure.
2527#[no_mangle]
2528pub extern "C" fn syd_chroot_rem(action: action_t, glob: *const c_char) -> c_int {
2529    // Convert action_t enum to corresponding action string.
2530    let action = match Action::try_from(action) {
2531        Ok(action) => action,
2532        Err(_) => return -EINVAL,
2533    };
2534
2535    // Call magic function with rem operator.
2536    esyd(&format!("{action}/chroot"), glob, b'^')
2537}
2538
2539/// Adds to the given actionlist of notify sandboxing.
2540///
2541/// Returns 0 on success, negated errno on failure.
2542#[no_mangle]
2543pub extern "C" fn syd_notify_add(action: action_t, glob: *const c_char) -> c_int {
2544    // Convert action_t enum to corresponding action string.
2545    let action = match Action::try_from(action) {
2546        Ok(action) => action,
2547        Err(_) => return -EINVAL,
2548    };
2549
2550    // Call magic function with add operator.
2551    esyd(&format!("{action}/notify"), glob, b'+')
2552}
2553
2554/// Removes the first instance from the end of the given actionlist of
2555/// notify sandboxing.
2556///
2557/// Returns 0 on success, negated errno on failure.
2558#[no_mangle]
2559pub extern "C" fn syd_notify_del(action: action_t, glob: *const c_char) -> c_int {
2560    // Convert action_t enum to corresponding action string.
2561    let action = match Action::try_from(action) {
2562        Ok(action) => action,
2563        Err(_) => return -EINVAL,
2564    };
2565
2566    // Call magic function with del operator.
2567    esyd(&format!("{action}/notify"), glob, b'-')
2568}
2569
2570/// Removes all matching patterns from the given actionlist of notify sandboxing.
2571///
2572/// Returns 0 on success, negated errno on failure.
2573#[no_mangle]
2574pub extern "C" fn syd_notify_rem(action: action_t, glob: *const c_char) -> c_int {
2575    // Convert action_t enum to corresponding action string.
2576    let action = match Action::try_from(action) {
2577        Ok(action) => action,
2578        Err(_) => return -EINVAL,
2579    };
2580
2581    // Call magic function with rem operator.
2582    esyd(&format!("{action}/notify"), glob, b'^')
2583}
2584
2585/// Adds to the given actionlist of utime sandboxing.
2586///
2587/// Returns 0 on success, negated errno on failure.
2588#[no_mangle]
2589pub extern "C" fn syd_utime_add(action: action_t, glob: *const c_char) -> c_int {
2590    // Convert action_t enum to corresponding action string.
2591    let action = match Action::try_from(action) {
2592        Ok(action) => action,
2593        Err(_) => return -EINVAL,
2594    };
2595
2596    // Call magic function with add operator.
2597    esyd(&format!("{action}/utime"), glob, b'+')
2598}
2599
2600/// Removes the first instance from the end of the given actionlist of
2601/// utime sandboxing.
2602///
2603/// Returns 0 on success, negated errno on failure.
2604#[no_mangle]
2605pub extern "C" fn syd_utime_del(action: action_t, glob: *const c_char) -> c_int {
2606    // Convert action_t enum to corresponding action string.
2607    let action = match Action::try_from(action) {
2608        Ok(action) => action,
2609        Err(_) => return -EINVAL,
2610    };
2611
2612    // Call magic function with del operator.
2613    esyd(&format!("{action}/utime"), glob, b'-')
2614}
2615
2616/// Removes all matching patterns from the given actionlist of utime sandboxing.
2617///
2618/// Returns 0 on success, negated errno on failure.
2619#[no_mangle]
2620pub extern "C" fn syd_utime_rem(action: action_t, glob: *const c_char) -> c_int {
2621    // Convert action_t enum to corresponding action string.
2622    let action = match Action::try_from(action) {
2623        Ok(action) => action,
2624        Err(_) => return -EINVAL,
2625    };
2626
2627    // Call magic function with rem operator.
2628    esyd(&format!("{action}/utime"), glob, b'^')
2629}
2630
2631/// Adds to the given actionlist of mkbdev sandboxing.
2632///
2633/// Returns 0 on success, negated errno on failure.
2634#[no_mangle]
2635pub extern "C" fn syd_mkbdev_add(action: action_t, glob: *const c_char) -> c_int {
2636    // Convert action_t enum to corresponding action string.
2637    let action = match Action::try_from(action) {
2638        Ok(action) => action,
2639        Err(_) => return -EINVAL,
2640    };
2641
2642    // Call magic function with add operator.
2643    esyd(&format!("{action}/mkbdev"), glob, b'+')
2644}
2645
2646/// Removes the first instance from the end of the given actionlist of
2647/// mkbdev sandboxing.
2648///
2649/// Returns 0 on success, negated errno on failure.
2650#[no_mangle]
2651pub extern "C" fn syd_mkbdev_del(action: action_t, glob: *const c_char) -> c_int {
2652    // Convert action_t enum to corresponding action string.
2653    let action = match Action::try_from(action) {
2654        Ok(action) => action,
2655        Err(_) => return -EINVAL,
2656    };
2657
2658    // Call magic function with del operator.
2659    esyd(&format!("{action}/mkbdev"), glob, b'-')
2660}
2661
2662/// Removes all matching patterns from the given actionlist of mkbdev sandboxing.
2663///
2664/// Returns 0 on success, negated errno on failure.
2665#[no_mangle]
2666pub extern "C" fn syd_mkbdev_rem(action: action_t, glob: *const c_char) -> c_int {
2667    // Convert action_t enum to corresponding action string.
2668    let action = match Action::try_from(action) {
2669        Ok(action) => action,
2670        Err(_) => return -EINVAL,
2671    };
2672
2673    // Call magic function with rem operator.
2674    esyd(&format!("{action}/mkbdev"), glob, b'^')
2675}
2676
2677/// Adds to the given actionlist of mkcdev sandboxing.
2678///
2679/// Returns 0 on success, negated errno on failure.
2680#[no_mangle]
2681pub extern "C" fn syd_mkcdev_add(action: action_t, glob: *const c_char) -> c_int {
2682    // Convert action_t enum to corresponding action string.
2683    let action = match Action::try_from(action) {
2684        Ok(action) => action,
2685        Err(_) => return -EINVAL,
2686    };
2687
2688    // Call magic function with add operator.
2689    esyd(&format!("{action}/mkcdev"), glob, b'+')
2690}
2691
2692/// Removes the first instance from the end of the given actionlist of
2693/// mkcdev sandboxing.
2694///
2695/// Returns 0 on success, negated errno on failure.
2696#[no_mangle]
2697pub extern "C" fn syd_mkcdev_del(action: action_t, glob: *const c_char) -> c_int {
2698    // Convert action_t enum to corresponding action string.
2699    let action = match Action::try_from(action) {
2700        Ok(action) => action,
2701        Err(_) => return -EINVAL,
2702    };
2703
2704    // Call magic function with del operator.
2705    esyd(&format!("{action}/mkcdev"), glob, b'-')
2706}
2707
2708/// Removes all matching patterns from the given actionlist of mkcdev sandboxing.
2709///
2710/// Returns 0 on success, negated errno on failure.
2711#[no_mangle]
2712pub extern "C" fn syd_mkcdev_rem(action: action_t, glob: *const c_char) -> c_int {
2713    // Convert action_t enum to corresponding action string.
2714    let action = match Action::try_from(action) {
2715        Ok(action) => action,
2716        Err(_) => return -EINVAL,
2717    };
2718
2719    // Call magic function with rem operator.
2720    esyd(&format!("{action}/mkcdev"), glob, b'^')
2721}
2722
2723/// Adds to the given actionlist of mkfifo sandboxing.
2724///
2725/// Returns 0 on success, negated errno on failure.
2726#[no_mangle]
2727pub extern "C" fn syd_mkfifo_add(action: action_t, glob: *const c_char) -> c_int {
2728    // Convert action_t enum to corresponding action string.
2729    let action = match Action::try_from(action) {
2730        Ok(action) => action,
2731        Err(_) => return -EINVAL,
2732    };
2733
2734    // Call magic function with add operator.
2735    esyd(&format!("{action}/mkfifo"), glob, b'+')
2736}
2737
2738/// Removes the first instance from the end of the given actionlist of
2739/// mkfifo sandboxing.
2740///
2741/// Returns 0 on success, negated errno on failure.
2742#[no_mangle]
2743pub extern "C" fn syd_mkfifo_del(action: action_t, glob: *const c_char) -> c_int {
2744    // Convert action_t enum to corresponding action string.
2745    let action = match Action::try_from(action) {
2746        Ok(action) => action,
2747        Err(_) => return -EINVAL,
2748    };
2749
2750    // Call magic function with del operator.
2751    esyd(&format!("{action}/mkfifo"), glob, b'-')
2752}
2753
2754/// Removes all matching patterns from the given actionlist of mkfifo sandboxing.
2755///
2756/// Returns 0 on success, negated errno on failure.
2757#[no_mangle]
2758pub extern "C" fn syd_mkfifo_rem(action: action_t, glob: *const c_char) -> c_int {
2759    // Convert action_t enum to corresponding action string.
2760    let action = match Action::try_from(action) {
2761        Ok(action) => action,
2762        Err(_) => return -EINVAL,
2763    };
2764
2765    // Call magic function with rem operator.
2766    esyd(&format!("{action}/mkfifo"), glob, b'^')
2767}
2768
2769/// Adds to the given actionlist of mktemp sandboxing.
2770///
2771/// Returns 0 on success, negated errno on failure.
2772#[no_mangle]
2773pub extern "C" fn syd_mktemp_add(action: action_t, glob: *const c_char) -> c_int {
2774    // Convert action_t enum to corresponding action string.
2775    let action = match Action::try_from(action) {
2776        Ok(action) => action,
2777        Err(_) => return -EINVAL,
2778    };
2779
2780    // Call magic function with add operator.
2781    esyd(&format!("{action}/mktemp"), glob, b'+')
2782}
2783
2784/// Removes the first instance from the end of the given actionlist of
2785/// mktemp sandboxing.
2786///
2787/// Returns 0 on success, negated errno on failure.
2788#[no_mangle]
2789pub extern "C" fn syd_mktemp_del(action: action_t, glob: *const c_char) -> c_int {
2790    // Convert action_t enum to corresponding action string.
2791    let action = match Action::try_from(action) {
2792        Ok(action) => action,
2793        Err(_) => return -EINVAL,
2794    };
2795
2796    // Call magic function with del operator.
2797    esyd(&format!("{action}/mktemp"), glob, b'-')
2798}
2799
2800/// Removes all matching patterns from the given actionlist of mktemp sandboxing.
2801///
2802/// Returns 0 on success, negated errno on failure.
2803#[no_mangle]
2804pub extern "C" fn syd_mktemp_rem(action: action_t, glob: *const c_char) -> c_int {
2805    // Convert action_t enum to corresponding action string.
2806    let action = match Action::try_from(action) {
2807        Ok(action) => action,
2808        Err(_) => return -EINVAL,
2809    };
2810
2811    // Call magic function with rem operator.
2812    esyd(&format!("{action}/mktemp"), glob, b'^')
2813}
2814
2815/// Adds to the given actionlist of net/bind sandboxing.
2816///
2817/// Returns 0 on success, negated errno on failure.
2818#[no_mangle]
2819pub extern "C" fn syd_net_bind_add(action: action_t, glob: *const c_char) -> c_int {
2820    // Convert action_t enum to corresponding action string.
2821    let action = match Action::try_from(action) {
2822        Ok(action) => action,
2823        Err(_) => return -EINVAL,
2824    };
2825
2826    // Call magic function with add operator.
2827    esyd(&format!("{action}/net/bind"), glob, b'+')
2828}
2829
2830/// Removes the first instance from the end of the given actionlist of
2831/// net/bind sandboxing.
2832///
2833/// Returns 0 on success, negated errno on failure.
2834#[no_mangle]
2835pub extern "C" fn syd_net_bind_del(action: action_t, glob: *const c_char) -> c_int {
2836    // Convert action_t enum to corresponding action string.
2837    let action = match Action::try_from(action) {
2838        Ok(action) => action,
2839        Err(_) => return -EINVAL,
2840    };
2841
2842    // Call magic function with del operator.
2843    esyd(&format!("{action}/net/bind"), glob, b'-')
2844}
2845
2846/// Removes all matching patterns from the given actionlist of net/bind sandboxing.
2847///
2848/// Returns 0 on success, negated errno on failure.
2849#[no_mangle]
2850pub extern "C" fn syd_net_bind_rem(action: action_t, glob: *const c_char) -> c_int {
2851    // Convert action_t enum to corresponding action string.
2852    let action = match Action::try_from(action) {
2853        Ok(action) => action,
2854        Err(_) => return -EINVAL,
2855    };
2856
2857    // Call magic function with rem operator.
2858    esyd(&format!("{action}/net/bind"), glob, b'^')
2859}
2860
2861/// Adds to the given actionlist of net/connect sandboxing.
2862///
2863/// Returns 0 on success, negated errno on failure.
2864#[no_mangle]
2865pub extern "C" fn syd_net_connect_add(action: action_t, glob: *const c_char) -> c_int {
2866    // Convert action_t enum to corresponding action string.
2867    let action = match Action::try_from(action) {
2868        Ok(action) => action,
2869        Err(_) => return -EINVAL,
2870    };
2871
2872    // Call magic function with add operator.
2873    esyd(&format!("{action}/net/connect"), glob, b'+')
2874}
2875
2876/// Removes the first instance from the end of the given actionlist of
2877/// net/connect sandboxing.
2878///
2879/// Returns 0 on success, negated errno on failure.
2880#[no_mangle]
2881pub extern "C" fn syd_net_connect_del(action: action_t, glob: *const c_char) -> c_int {
2882    // Convert action_t enum to corresponding action string.
2883    let action = match Action::try_from(action) {
2884        Ok(action) => action,
2885        Err(_) => return -EINVAL,
2886    };
2887
2888    // Call magic function with del operator.
2889    esyd(&format!("{action}/net/connect"), glob, b'-')
2890}
2891
2892/// Removes all matching patterns from the given actionlist of net/connect sandboxing.
2893///
2894/// Returns 0 on success, negated errno on failure.
2895#[no_mangle]
2896pub extern "C" fn syd_net_connect_rem(action: action_t, glob: *const c_char) -> c_int {
2897    // Convert action_t enum to corresponding action string.
2898    let action = match Action::try_from(action) {
2899        Ok(action) => action,
2900        Err(_) => return -EINVAL,
2901    };
2902
2903    // Call magic function with rem operator.
2904    esyd(&format!("{action}/net/connect"), glob, b'^')
2905}
2906
2907/// Adds to the given actionlist of net/sendfd sandboxing.
2908///
2909/// Returns 0 on success, negated errno on failure.
2910#[no_mangle]
2911pub extern "C" fn syd_net_sendfd_add(action: action_t, glob: *const c_char) -> c_int {
2912    // Convert action_t enum to corresponding action string.
2913    let action = match Action::try_from(action) {
2914        Ok(action) => action,
2915        Err(_) => return -EINVAL,
2916    };
2917
2918    // Call magic function with add operator.
2919    esyd(&format!("{action}/net/sendfd"), glob, b'+')
2920}
2921
2922/// Removes the first instance from the end of the given actionlist of
2923/// net/sendfd sandboxing.
2924///
2925/// Returns 0 on success, negated errno on failure.
2926#[no_mangle]
2927pub extern "C" fn syd_net_sendfd_del(action: action_t, glob: *const c_char) -> c_int {
2928    // Convert action_t enum to corresponding action string.
2929    let action = match Action::try_from(action) {
2930        Ok(action) => action,
2931        Err(_) => return -EINVAL,
2932    };
2933
2934    // Call magic function with del operator.
2935    esyd(&format!("{action}/net/sendfd"), glob, b'-')
2936}
2937
2938/// Removes all matching patterns from the given actionlist of net/sendfd sandboxing.
2939///
2940/// Returns 0 on success, negated errno on failure.
2941#[no_mangle]
2942pub extern "C" fn syd_net_sendfd_rem(action: action_t, glob: *const c_char) -> c_int {
2943    // Convert action_t enum to corresponding action string.
2944    let action = match Action::try_from(action) {
2945        Ok(action) => action,
2946        Err(_) => return -EINVAL,
2947    };
2948
2949    // Call magic function with rem operator.
2950    esyd(&format!("{action}/net/sendfd"), glob, b'^')
2951}
2952
2953/// Adds to the given actionlist of net/link sandboxing.
2954///
2955/// Returns 0 on success, negated errno on failure.
2956#[no_mangle]
2957pub extern "C" fn syd_net_link_add(action: action_t, family: *const c_char) -> c_int {
2958    // Convert action_t enum to corresponding action string.
2959    let action = match Action::try_from(action) {
2960        Ok(action) => action,
2961        Err(_) => return -EINVAL,
2962    };
2963
2964    // Call magic function with add operator.
2965    esyd(&format!("{action}/net/link"), family, b'+')
2966}
2967
2968/// Removes the first instance from the end of the given actionlist of
2969/// net/link sandboxing.
2970///
2971/// Returns 0 on success, negated errno on failure.
2972#[no_mangle]
2973pub extern "C" fn syd_net_link_del(action: action_t, family: *const c_char) -> c_int {
2974    // Convert action_t enum to corresponding action string.
2975    let action = match Action::try_from(action) {
2976        Ok(action) => action,
2977        Err(_) => return -EINVAL,
2978    };
2979
2980    // Call magic function with del operator.
2981    esyd(&format!("{action}/net/link"), family, b'-')
2982}
2983
2984/// Removes all matching patterns from the given actionlist of net/link sandboxing.
2985///
2986/// Returns 0 on success, negated errno on failure.
2987#[no_mangle]
2988pub extern "C" fn syd_net_link_rem(action: action_t, family: *const c_char) -> c_int {
2989    // Convert action_t enum to corresponding action string.
2990    let action = match Action::try_from(action) {
2991        Ok(action) => action,
2992        Err(_) => return -EINVAL,
2993    };
2994
2995    // Call magic function with rem operator.
2996    esyd(&format!("{action}/net/link"), family, b'^')
2997}
2998
2999/// Set syd maximum per-process memory usage limit for memory sandboxing.
3000///
3001/// parse-size crate is used to parse the value so formatted strings are OK.
3002///
3003/// Returns 0 on success, negated errno on failure.
3004#[no_mangle]
3005pub extern "C" fn syd_mem_max(size: *const c_char) -> c_int {
3006    esyd("mem/max", size, b':')
3007}
3008
3009/// Set syd maximum per-process virtual memory usage limit for memory sandboxing.
3010///
3011/// parse-size crate is used to parse the value so formatted strings are OK.
3012///
3013/// Returns 0 on success, negated errno on failure.
3014#[no_mangle]
3015pub extern "C" fn syd_mem_vm_max(size: *const c_char) -> c_int {
3016    esyd("mem/vm_max", size, b':')
3017}
3018
3019/// Set syd maximum process id limit for PID sandboxing
3020///
3021/// Returns 0 on success, negated errno on failure.
3022#[no_mangle]
3023pub extern "C" fn syd_pid_max(size: usize) -> c_int {
3024    stat(&format!("/dev/syd/pid/max:{size}"))
3025}
3026
3027/// Specify SegvGuard entry expiry timeout in seconds.
3028/// Setting this timeout to 0 effectively disables SegvGuard.
3029///
3030/// Returns 0 on success, negated errno on failure.
3031#[no_mangle]
3032pub extern "C" fn syd_segvguard_expiry(timeout: u64) -> c_int {
3033    stat(&format!("/dev/syd/segvguard/expiry:{timeout}"))
3034}
3035
3036/// Specify SegvGuard entry suspension timeout in seconds.
3037///
3038/// Returns 0 on success, negated errno on failure.
3039#[no_mangle]
3040pub extern "C" fn syd_segvguard_suspension(timeout: u64) -> c_int {
3041    stat(&format!("/dev/syd/segvguard/suspension:{timeout}"))
3042}
3043
3044/// Specify SegvGuard max number of crashes before suspension.
3045///
3046/// Returns 0 on success, negated errno on failure.
3047#[no_mangle]
3048pub extern "C" fn syd_segvguard_maxcrashes(max: u8) -> c_int {
3049    stat(&format!("/dev/syd/segvguard/maxcrashes:{max}"))
3050}
3051
3052/// Execute a command outside the sandbox without sandboxing
3053///
3054/// # Safety
3055///
3056/// This function is marked `unsafe` because it dereferences raw
3057/// pointers, which is inherently unsafe in Rust.
3058///
3059/// The caller must ensure the following conditions are met to safely
3060/// use this function:
3061///
3062/// 1. The `file` pointer must point to a valid, null-terminated C-style
3063///    string.
3064///
3065/// 2. The `argv` pointer must point to an array of pointers, where each
3066///    pointer refers to a valid, null-terminated C-style string. The
3067///    last pointer in the array must be null, indicating the end of the
3068///    array.
3069///
3070/// 3. The memory pointed to by `file` and `argv` must remain valid for
3071///    the duration of the call.
3072///
3073/// Failing to uphold these guarantees can lead to undefined behavior,
3074/// including memory corruption and data races.
3075///
3076/// Returns 0 on success, negated errno on failure.
3077#[no_mangle]
3078pub unsafe extern "C" fn syd_exec(file: *const c_char, argv: *const *const c_char) -> c_int {
3079    if file.is_null() || argv.is_null() {
3080        return -EFAULT;
3081    }
3082
3083    // SAFETY: Trust that `file` is a null-terminated string.
3084    let file = CStr::from_ptr(file);
3085    let file = OsStr::from_bytes(file.to_bytes());
3086
3087    let mut path = OsString::from("/dev/syd/cmd/exec!");
3088    path.push(file);
3089
3090    let mut idx: isize = 0;
3091    while !(*argv.offset(idx)).is_null() {
3092        // SAFETY: Trust that each `argv` element is a null-terminated string.
3093        let arg = CStr::from_ptr(*argv.offset(idx));
3094        let arg = OsStr::from_bytes(arg.to_bytes());
3095
3096        path.push(OsStr::from_bytes(&[b'\x1F'])); // ASCII Unit Separator
3097        path.push(arg);
3098
3099        idx = idx.saturating_add(1);
3100    }
3101
3102    let path = PathBuf::from(path);
3103    stat(path)
3104}