Skip to main content

libbsd_sys/
imp.rs

1use core::ffi::{c_char, c_int, c_long, c_uchar, c_uint, c_void};
2
3// Re-export libc types used in signatures.
4pub use libc::{FILE, gid_t, mode_t, off_t, pid_t, size_t, ssize_t, uid_t};
5
6// ---------------------------------------------------------------------------
7// <bsd/string.h>
8// ---------------------------------------------------------------------------
9
10unsafe extern "C" {
11    pub fn strlcpy(dst: *mut c_char, src: *const c_char, siz: size_t) -> size_t;
12    pub fn strlcat(dst: *mut c_char, src: *const c_char, siz: size_t) -> size_t;
13    pub fn strnstr(s: *const c_char, find: *const c_char, slen: size_t) -> *mut c_char;
14    pub fn strmode(mode: mode_t, str_: *mut c_char);
15    pub fn explicit_bzero(buf: *mut c_void, len: size_t);
16}
17
18// ---------------------------------------------------------------------------
19// <bsd/stdlib.h>
20// ---------------------------------------------------------------------------
21
22unsafe extern "C" {
23    pub fn arc4random() -> u32;
24    pub fn arc4random_buf(buf: *mut c_void, n: size_t);
25    pub fn arc4random_uniform(upper_bound: u32) -> u32;
26    #[cfg(target_os = "linux")]
27    pub fn arc4random_stir();
28    #[cfg(target_os = "linux")]
29    pub fn arc4random_addrandom(dat: *mut c_uchar, datlen: c_int);
30
31    #[cfg(target_os = "linux")]
32    pub fn dehumanize_number(str_: *const c_char, size: *mut i64) -> c_int;
33
34    pub fn getprogname() -> *const c_char;
35    pub fn setprogname(name: *const c_char);
36
37    pub fn heapsort(
38        base: *mut c_void,
39        nmemb: size_t,
40        size: size_t,
41        cmp: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
42    ) -> c_int;
43    pub fn mergesort(
44        base: *mut c_void,
45        nmemb: size_t,
46        size: size_t,
47        cmp: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
48    ) -> c_int;
49    pub fn radixsort(
50        base: *mut *const c_uchar,
51        nmemb: c_int,
52        table: *const c_uchar,
53        endbyte: c_uint,
54    ) -> c_int;
55    pub fn sradixsort(
56        base: *mut *const c_uchar,
57        nmemb: c_int,
58        table: *const c_uchar,
59        endbyte: c_uint,
60    ) -> c_int;
61
62    pub fn reallocf(ptr: *mut c_void, size: size_t) -> *mut c_void;
63    pub fn reallocarray(ptr: *mut c_void, nmemb: size_t, size: size_t) -> *mut c_void;
64    #[cfg(not(target_os = "macos"))]
65    pub fn recallocarray(
66        ptr: *mut c_void,
67        oldnmemb: size_t,
68        nmemb: size_t,
69        size: size_t,
70    ) -> *mut c_void;
71    #[cfg(not(target_os = "macos"))]
72    pub fn freezero(ptr: *mut c_void, size: size_t);
73
74    pub fn strtonum(
75        nptr: *const c_char,
76        minval: i64,
77        maxval: i64,
78        errstr: *mut *const c_char,
79    ) -> i64;
80
81    pub fn getbsize(headerlenp: *mut c_int, blocksizep: *mut c_long) -> *mut c_char;
82}
83
84// ---------------------------------------------------------------------------
85// <bsd/unistd.h>
86// ---------------------------------------------------------------------------
87
88unsafe extern "C" {
89    pub static mut optreset: c_int;
90
91    #[cfg(target_os = "linux")]
92    pub fn bsd_getopt(argc: c_int, argv: *const *mut c_char, shortopts: *const c_char) -> c_int;
93
94    pub fn getmode(set: *const c_void, mode: mode_t) -> mode_t;
95    pub fn setmode(mode_str: *const c_char) -> *mut c_void;
96
97    pub fn closefrom(lowfd: c_int);
98
99    #[cfg(target_os = "linux")]
100    pub fn setproctitle_init(argc: c_int, argv: *mut *mut c_char, envp: *mut *mut c_char);
101    #[cfg(not(target_os = "macos"))]
102    pub fn setproctitle(fmt: *const c_char, ...);
103
104    pub fn getpeereid(s: c_int, euid: *mut uid_t, egid: *mut gid_t) -> c_int;
105}
106
107// ---------------------------------------------------------------------------
108// <bsd/stdio.h>
109// ---------------------------------------------------------------------------
110
111unsafe extern "C" {
112    pub fn fmtcheck(f1: *const c_char, f2: *const c_char) -> *const c_char;
113
114    pub fn fgetln(fp: *mut FILE, lenp: *mut size_t) -> *mut c_char;
115
116    pub fn funopen(
117        cookie: *const c_void,
118        readfn: Option<unsafe extern "C" fn(*mut c_void, *mut c_char, c_int) -> c_int>,
119        writefn: Option<unsafe extern "C" fn(*mut c_void, *const c_char, c_int) -> c_int>,
120        seekfn: Option<unsafe extern "C" fn(*mut c_void, off_t, c_int) -> off_t>,
121        closefn: Option<unsafe extern "C" fn(*mut c_void) -> c_int>,
122    ) -> *mut FILE;
123
124    pub fn fpurge(fp: *mut FILE) -> c_int;
125}
126
127// ---------------------------------------------------------------------------
128// <bsd/readpassphrase.h>
129// ---------------------------------------------------------------------------
130
131pub const RPP_ECHO_OFF: c_int = 0x00;
132pub const RPP_ECHO_ON: c_int = 0x01;
133pub const RPP_REQUIRE_TTY: c_int = 0x02;
134pub const RPP_FORCELOWER: c_int = 0x04;
135pub const RPP_FORCEUPPER: c_int = 0x08;
136pub const RPP_SEVENBIT: c_int = 0x10;
137pub const RPP_STDIN: c_int = 0x20;
138
139unsafe extern "C" {
140    pub fn readpassphrase(
141        prompt: *const c_char,
142        buf: *mut c_char,
143        bufsiz: size_t,
144        flags: c_int,
145    ) -> *mut c_char;
146}
147
148// ---------------------------------------------------------------------------
149// <bsd/vis.h>
150// ---------------------------------------------------------------------------
151
152pub const VIS_OCTAL: c_int = 0x0001;
153pub const VIS_CSTYLE: c_int = 0x0002;
154pub const VIS_SP: c_int = 0x0004;
155pub const VIS_TAB: c_int = 0x0008;
156pub const VIS_NL: c_int = 0x0010;
157pub const VIS_WHITE: c_int = VIS_SP | VIS_TAB | VIS_NL;
158pub const VIS_SAFE: c_int = 0x0020;
159pub const VIS_DQ: c_int = 0x8000;
160pub const VIS_NOSLASH: c_int = 0x0040;
161pub const VIS_HTTP1808: c_int = 0x0080;
162pub const VIS_HTTPSTYLE: c_int = 0x0080;
163pub const VIS_MIMESTYLE: c_int = 0x0100;
164pub const VIS_HTTP1866: c_int = 0x0200;
165pub const VIS_NOESCAPE: c_int = 0x0400;
166pub const VIS_GLOB: c_int = 0x1000;
167pub const VIS_SHELL: c_int = 0x2000;
168pub const VIS_META: c_int = VIS_WHITE | VIS_GLOB | VIS_SHELL;
169pub const VIS_NOLOCALE: c_int = 0x4000;
170
171pub const UNVIS_VALID: c_int = 1;
172pub const UNVIS_VALIDPUSH: c_int = 2;
173pub const UNVIS_NOCHAR: c_int = 3;
174pub const UNVIS_SYNBAD: c_int = -1;
175pub const UNVIS_ERROR: c_int = -2;
176pub const UNVIS_END: c_int = 0x0800;
177
178unsafe extern "C" {
179    pub fn vis(dst: *mut c_char, c: c_int, flag: c_int, nextc: c_int) -> *mut c_char;
180    pub fn nvis(dst: *mut c_char, dlen: size_t, c: c_int, flag: c_int, nextc: c_int)
181    -> *mut c_char;
182
183    pub fn svis(
184        dst: *mut c_char,
185        c: c_int,
186        flag: c_int,
187        nextc: c_int,
188        extra: *const c_char,
189    ) -> *mut c_char;
190    pub fn snvis(
191        dst: *mut c_char,
192        dlen: size_t,
193        c: c_int,
194        flag: c_int,
195        nextc: c_int,
196        extra: *const c_char,
197    ) -> *mut c_char;
198
199    pub fn strvis(dst: *mut c_char, src: *const c_char, flag: c_int) -> c_int;
200    pub fn stravis(dst: *mut *mut c_char, src: *const c_char, flag: c_int) -> c_int;
201    // NB: strnvis has different parameter order depending on the platform's
202    // convention: FreeBSD (and libbsd) put src before dlen, while NetBSD
203    // (and macOS/OpenBSD) put dlen before src.
204    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
205    pub fn strnvis(dst: *mut c_char, src: *const c_char, dlen: size_t, flag: c_int) -> c_int;
206    #[cfg(any(target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
207    pub fn strnvis(dst: *mut c_char, dlen: size_t, src: *const c_char, flag: c_int) -> c_int;
208
209    pub fn strsvis(
210        dst: *mut c_char,
211        src: *const c_char,
212        flag: c_int,
213        extra: *const c_char,
214    ) -> c_int;
215    pub fn strsnvis(
216        dst: *mut c_char,
217        dlen: size_t,
218        src: *const c_char,
219        flag: c_int,
220        extra: *const c_char,
221    ) -> c_int;
222
223    pub fn strvisx(dst: *mut c_char, src: *const c_char, len: size_t, flag: c_int) -> c_int;
224    pub fn strnvisx(
225        dst: *mut c_char,
226        dlen: size_t,
227        src: *const c_char,
228        len: size_t,
229        flag: c_int,
230    ) -> c_int;
231    pub fn strenvisx(
232        dst: *mut c_char,
233        dlen: size_t,
234        src: *const c_char,
235        len: size_t,
236        flag: c_int,
237        cerr_ptr: *mut c_int,
238    ) -> c_int;
239
240    pub fn strsvisx(
241        dst: *mut c_char,
242        src: *const c_char,
243        len: size_t,
244        flag: c_int,
245        extra: *const c_char,
246    ) -> c_int;
247    pub fn strsnvisx(
248        dst: *mut c_char,
249        dlen: size_t,
250        src: *const c_char,
251        len: size_t,
252        flag: c_int,
253        extra: *const c_char,
254    ) -> c_int;
255    pub fn strsenvisx(
256        dst: *mut c_char,
257        dlen: size_t,
258        src: *const c_char,
259        len: size_t,
260        flag: c_int,
261        extra: *const c_char,
262        cerr_ptr: *mut c_int,
263    ) -> c_int;
264
265    pub fn strunvis(dst: *mut c_char, src: *const c_char) -> c_int;
266    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
267    pub fn strnunvis(dst: *mut c_char, src: *const c_char, dlen: size_t) -> ssize_t;
268    #[cfg(any(target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
269    pub fn strnunvis(dst: *mut c_char, dlen: size_t, src: *const c_char) -> c_int;
270
271    pub fn strunvisx(dst: *mut c_char, src: *const c_char, flag: c_int) -> c_int;
272    pub fn strnunvisx(dst: *mut c_char, dlen: size_t, src: *const c_char, flag: c_int) -> c_int;
273
274    pub fn unvis(cp: *mut c_char, c: c_int, apts: *mut c_int, flag: c_int) -> c_int;
275}
276
277// ---------------------------------------------------------------------------
278// <bsd/libutil.h>
279// ---------------------------------------------------------------------------
280
281#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
282pub const HN_DECIMAL: c_int = 0x01;
283#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
284pub const HN_NOSPACE: c_int = 0x02;
285#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
286pub const HN_B: c_int = 0x04;
287#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
288pub const HN_DIVISOR_1000: c_int = 0x08;
289#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
290pub const HN_IEC_PREFIXES: c_int = 0x10;
291#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
292pub const HN_GETSCALE: c_int = 0x10;
293#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
294pub const HN_AUTOSCALE: c_int = 0x20;
295
296pub const FPARSELN_UNESCESC: c_int = 0x01;
297pub const FPARSELN_UNESCCONT: c_int = 0x02;
298pub const FPARSELN_UNESCCOMM: c_int = 0x04;
299pub const FPARSELN_UNESCREST: c_int = 0x08;
300pub const FPARSELN_UNESCALL: c_int = 0x0f;
301
302#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
303#[repr(C)]
304pub struct pidfh {
305    _opaque: [u8; 0],
306}
307
308#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
309unsafe extern "C" {
310    pub fn humanize_number(
311        buf: *mut c_char,
312        len: size_t,
313        bytes: i64,
314        suffix: *const c_char,
315        scale: c_int,
316        flags: c_int,
317    ) -> c_int;
318    pub fn expand_number(buf: *const c_char, num: *mut u64) -> c_int;
319
320    pub fn pidfile_open(path: *const c_char, mode: mode_t, pidptr: *mut pid_t) -> *mut pidfh;
321    pub fn pidfile_fileno(pfh: *const pidfh) -> c_int;
322    pub fn pidfile_write(pfh: *mut pidfh) -> c_int;
323    pub fn pidfile_close(pfh: *mut pidfh) -> c_int;
324    pub fn pidfile_remove(pfh: *mut pidfh) -> c_int;
325}
326
327// flopen/flopenat are FreeBSD-specific; not available on NetBSD.
328#[cfg(any(target_os = "linux", target_os = "freebsd"))]
329unsafe extern "C" {
330    pub fn flopen(path: *const c_char, flags: c_int, ...) -> c_int;
331    pub fn flopenat(dirfd: c_int, path: *const c_char, flags: c_int, ...) -> c_int;
332}
333
334unsafe extern "C" {
335    pub fn fparseln(
336        fp: *mut FILE,
337        size: *mut size_t,
338        lineno: *mut size_t,
339        delim: *const [c_char; 3],
340        flags: c_int,
341    ) -> *mut c_char;
342}
343
344// ---------------------------------------------------------------------------
345// <bsd/nlist.h>
346// ---------------------------------------------------------------------------
347
348// On macOS, struct nlist has a different layout (Mach-O format).
349#[cfg(not(target_os = "macos"))]
350#[repr(C)]
351pub struct nlist {
352    pub n_name: *mut c_char,
353    pub n_type: u8,
354    pub n_other: c_char,
355    pub n_desc: i16,
356    pub n_value: c_ulong,
357}
358
359pub use core::ffi::c_ulong;
360
361pub const N_UNDF: u8 = 0x00;
362pub const N_ABS: u8 = 0x02;
363pub const N_TEXT: u8 = 0x04;
364pub const N_DATA: u8 = 0x06;
365pub const N_BSS: u8 = 0x08;
366pub const N_INDR: u8 = 0x0a;
367pub const N_SIZE: u8 = 0x0c;
368pub const N_COMM: u8 = 0x12;
369pub const N_SETA: u8 = 0x14;
370pub const N_SETT: u8 = 0x16;
371pub const N_SETD: u8 = 0x18;
372pub const N_SETB: u8 = 0x1a;
373pub const N_SETV: u8 = 0x1c;
374pub const N_FN: u8 = 0x1e;
375pub const N_WARN: u8 = 0x1e;
376pub const N_EXT: u8 = 0x01;
377pub const N_TYPE: u8 = 0x1e;
378pub const N_STAB: u8 = 0xe0;
379
380#[cfg(not(target_os = "macos"))]
381unsafe extern "C" {
382    pub fn nlist(filename: *const c_char, list: *mut nlist) -> c_int;
383}
384
385// ---------------------------------------------------------------------------
386// <bsd/stringlist.h>
387// ---------------------------------------------------------------------------
388
389#[repr(C)]
390pub struct StringList {
391    pub sl_str: *mut *mut c_char,
392    pub sl_max: size_t,
393    pub sl_cur: size_t,
394}
395
396unsafe extern "C" {
397    pub fn sl_init() -> *mut StringList;
398    pub fn sl_add(sl: *mut StringList, item: *mut c_char) -> c_int;
399    pub fn sl_free(sl: *mut StringList, freel: c_int);
400    pub fn sl_find(sl: *mut StringList, name: *const c_char) -> *mut c_char;
401    #[cfg(target_os = "linux")]
402    pub fn sl_delete(sl: *mut StringList, name: *const c_char, freel: c_int) -> c_int;
403}
404
405// ---------------------------------------------------------------------------
406// <bsd/timeconv.h>
407// ---------------------------------------------------------------------------
408
409#[cfg(target_os = "linux")]
410unsafe extern "C" {
411    #[link_name = "_time32_to_time"]
412    pub fn time32_to_time(t32: i32) -> libc::time_t;
413    #[link_name = "_time_to_time32"]
414    pub fn time_to_time32(t: libc::time_t) -> i32;
415    #[link_name = "_time64_to_time"]
416    pub fn time64_to_time(t64: i64) -> libc::time_t;
417    #[link_name = "_time_to_time64"]
418    pub fn time_to_time64(t: libc::time_t) -> i64;
419    #[link_name = "_time_to_long"]
420    pub fn time_to_long(t: libc::time_t) -> c_long;
421    #[link_name = "_long_to_time"]
422    pub fn long_to_time(tlong: c_long) -> libc::time_t;
423    #[link_name = "_time_to_int"]
424    pub fn time_to_int(t: libc::time_t) -> c_int;
425    #[link_name = "_int_to_time"]
426    pub fn int_to_time(tint: c_int) -> libc::time_t;
427}
428
429// ---------------------------------------------------------------------------
430// <bsd/err.h>  (subset; TODO: add the rest)
431// ---------------------------------------------------------------------------
432
433unsafe extern "C" {
434    pub fn warnc(code: c_int, format: *const c_char, ...);
435    pub fn errc(status: c_int, code: c_int, format: *const c_char, ...) -> !;
436}
437
438// ---------------------------------------------------------------------------
439// <bsd/wchar.h>
440// ---------------------------------------------------------------------------
441
442unsafe extern "C" {
443    pub fn fgetwln(stream: *mut FILE, len: *mut size_t) -> *mut libc::wchar_t;
444    pub fn wcslcat(dst: *mut libc::wchar_t, src: *const libc::wchar_t, size: size_t) -> size_t;
445    pub fn wcslcpy(dst: *mut libc::wchar_t, src: *const libc::wchar_t, size: size_t) -> size_t;
446}
447
448// ---------------------------------------------------------------------------
449// <bsd/grp.h>
450// ---------------------------------------------------------------------------
451
452unsafe extern "C" {
453    pub fn gid_from_group(name: *const c_char, gid: *mut gid_t) -> c_int;
454    pub fn group_from_gid(gid: gid_t, nosuchgroup: c_int) -> *const c_char;
455}
456
457// ---------------------------------------------------------------------------
458// <bsd/pwd.h>
459// ---------------------------------------------------------------------------
460
461unsafe extern "C" {
462    pub fn uid_from_user(name: *const c_char, uid: *mut uid_t) -> c_int;
463    pub fn user_from_uid(uid: uid_t, nosuchuser: c_int) -> *const c_char;
464}
465
466// ---------------------------------------------------------------------------
467// Misc functions found in libbsd without a dedicated header
468// ---------------------------------------------------------------------------
469
470unsafe extern "C" {
471    pub fn inet_net_pton(af: c_int, src: *const c_char, dst: *mut c_void, size: size_t) -> c_int;
472}