init
This commit is contained in:
+104
@@ -0,0 +1,104 @@
|
||||
@[has_globals]
|
||||
module netio
|
||||
|
||||
import os
|
||||
import sync
|
||||
|
||||
// Mutex for accessing to protocol entries via getprotoent(3).
|
||||
__global netio_protoent_mutex &sync.Mutex
|
||||
|
||||
struct C.protoent {
|
||||
p_name &char
|
||||
p_aliases &&char
|
||||
p_proto i32
|
||||
}
|
||||
|
||||
fn C.getprotoent() &C.protoent
|
||||
fn C.getprotobyname(&char) &C.protoent
|
||||
fn C.getprotobynumber(i32) &C.protoent
|
||||
fn C.setprotoent(i32)
|
||||
fn C.endprotoent()
|
||||
|
||||
// The protocol number type.
|
||||
// See [protocols(5)](https://man7.org/linux/man-pages/man5/protocols.5.html),
|
||||
// and [getprotoent(3)](https://man7.org/linux/man-pages/man3/getprotoent.3.html) for details.
|
||||
pub type Protocol = int
|
||||
|
||||
// entry returns the protocol entry from database.
|
||||
pub fn (p Protocol) entry() !ProtocolEntry {
|
||||
return protocol_by_number(p)!
|
||||
}
|
||||
|
||||
pub struct ProtocolEntry {
|
||||
pub:
|
||||
name string // The official name of protocol.
|
||||
aliases []string // List of alternative names for the protocol.
|
||||
number int // The protocol number.
|
||||
}
|
||||
|
||||
fn make_proto(ent C.protoent) ProtocolEntry {
|
||||
mut aliases := []string{}
|
||||
if unsafe { ent.p_aliases[0] != nil } {
|
||||
mut ptr := *ent.p_aliases
|
||||
mut nullterm := 1
|
||||
for {
|
||||
if *ptr == 0 {
|
||||
break
|
||||
}
|
||||
str := unsafe { cstring_to_vstring(ptr) }
|
||||
ptr = unsafe { ptr + str.len + nullterm }
|
||||
nullterm++
|
||||
aliases << str
|
||||
}
|
||||
}
|
||||
return ProtocolEntry{
|
||||
name: unsafe { cstring_to_vstring(ent.p_name) }
|
||||
aliases: aliases
|
||||
number: int(ent.p_proto)
|
||||
}
|
||||
}
|
||||
|
||||
// protocols returns all protocol entries from database in arbitrary order.
|
||||
pub fn protocols() []ProtocolEntry {
|
||||
netio_protoent_mutex.@lock()
|
||||
C.setprotoent(1)
|
||||
defer {
|
||||
C.endprotoent()
|
||||
netio_protoent_mutex.unlock()
|
||||
}
|
||||
mut protos := []ProtocolEntry{}
|
||||
for {
|
||||
proto := C.getprotoent()
|
||||
if isnil(proto) {
|
||||
break
|
||||
}
|
||||
protos << make_proto(proto)
|
||||
}
|
||||
return protos
|
||||
}
|
||||
|
||||
// protocol_by_name returns the protocol entry by name e.g. 'tcp', 'icmp'.
|
||||
pub fn protocol_by_name(name string) !ProtocolEntry {
|
||||
netio_protoent_mutex.@lock()
|
||||
defer {
|
||||
netio_protoent_mutex.unlock()
|
||||
}
|
||||
proto := C.getprotobyname(&char(name.str))
|
||||
if isnil(proto) {
|
||||
return os.last_error()
|
||||
}
|
||||
return make_proto(proto)
|
||||
}
|
||||
|
||||
// protocol_by_number returns the protocol entry by protocol number.
|
||||
pub fn protocol_by_number(num int) !ProtocolEntry {
|
||||
netio_protoent_mutex.@lock()
|
||||
defer {
|
||||
netio_protoent_mutex.unlock()
|
||||
}
|
||||
proto := C.getprotobynumber(num)
|
||||
if isnil(proto) {
|
||||
return os.last_error()
|
||||
}
|
||||
return make_proto(proto)
|
||||
}
|
||||
Reference in New Issue
Block a user