Seregon/zftpd

Zero-copy FTP/HTTP Daemon compatible with all POSIX systems

C/11.0 KB/No license
ffi/go/zftpd/zftpd.go
zftpd / ffi / go / zftpd / zftpd.go
1package zftpd
2 
3/*
4#cgo darwin LDFLAGS: -L../../../build/macos/release -lzftpd_ffi
5#cgo linux LDFLAGS: -L../../../build/linux/release -lzftpd_ffi
6#cgo CFLAGS: -I../../c_core
7#include "pal_ffi.h"
8#include <stdlib.h>
9*/
10import "C"
11import (
12 "errors"
13 "unsafe"
14)
15 
16// --- Allocator ---
17 
18// PalAllocInitDefault initializes the default memory allocator.
19func PalAllocInitDefault() error {
20 res := C.pal_ffi_alloc_init_default()
21 if res != C.PAL_FFI_OK {
22 return errors.New("failed to initialize allocator")
23 }
24 return nil
25}
26 
27// PalMalloc allocates size bytes.
28func PalMalloc(size uint64) unsafe.Pointer {
29 return C.pal_ffi_malloc(C.size_t(size))
30}
31 
32// PalFree frees the allocated pointer.
33func PalFree(ptr unsafe.Pointer) {
34 if ptr != nil {
35 C.pal_ffi_free(ptr)
36 }
37}
38 
39// PalGetArenaFreeApprox returns approximate free bytes.
40func PalGetArenaFreeApprox() uint64 {
41 return uint64(C.pal_ffi_alloc_arena_free_approx())
42}
43 
44// --- Event Loop ---
45 
46type EventLoop struct {
47 handle unsafe.Pointer
48}
49 
50func NewEventLoop() (*EventLoop, error) {
51 handle := C.pal_ffi_event_loop_create()
52 if handle == nil {
53 return nil, errors.New("failed to create event loop")
54 }
55 return &EventLoop{handle: handle}, nil
56}
57 
58func (e *EventLoop) Run() error {
59 res := C.pal_ffi_event_loop_run(e.handle)
60 if res != 0 {
61 return errors.New("event loop run failed")
62 }
63 return nil
64}
65 
66func (e *EventLoop) Stop() {
67 if e.handle != nil {
68 C.pal_ffi_event_loop_stop(e.handle)
69 }
70}
71 
72func (e *EventLoop) Close() {
73 if e.handle != nil {
74 C.pal_ffi_event_loop_destroy(e.handle)
75 e.handle = nil
76 }
77}
78 
79// --- FTP Server ---
80 
81type FtpServer struct {
82 handle unsafe.Pointer
83}
84 
85func NewFtpServer(bindIp string, port uint16, rootPath string) (*FtpServer, error) {
86 cIp := C.CString(bindIp)
87 defer C.free(unsafe.Pointer(cIp))
88 
89 cPath := C.CString(rootPath)
90 defer C.free(unsafe.Pointer(cPath))
91 
92 handle := C.pal_ffi_ftp_server_create(cIp, C.uint16_t(port), cPath)
93 if handle == nil {
94 return nil, errors.New("failed to create ftp server")
95 }
96 return &FtpServer{handle: handle}, nil
97}
98 
99func (s *FtpServer) Start() error {
100 res := C.pal_ffi_ftp_server_start(s.handle)
101 if res != C.PAL_FFI_OK {
102 return errors.New("failed to start ftp server")
103 }
104 return nil
105}
106 
107func (s *FtpServer) IsRunning() bool {
108 return C.pal_ffi_ftp_server_is_running(s.handle) == 1
109}
110 
111func (s *FtpServer) ActiveSessions() uint32 {
112 return uint32(C.pal_ffi_ftp_server_get_active_sessions(s.handle))
113}
114 
115func (s *FtpServer) Stop() {
116 if s.handle != nil {
117 C.pal_ffi_ftp_server_stop(s.handle)
118 }
119}
120 
121func (s *FtpServer) Close() {
122 if s.handle != nil {
123 C.pal_ffi_ftp_server_destroy(s.handle)
124 s.handle = nil
125 }
126}
127 
128// --- HTTP Server ---
129 
130type HttpServer struct {
131 handle unsafe.Pointer
132}
133 
134func NewHttpServer(loop *EventLoop, port uint16) (*HttpServer, error) {
135 handle := C.pal_ffi_http_server_create(loop.handle, C.uint16_t(port))
136 if handle == nil {
137 return nil, errors.New("failed to create http server (maybe disabled?)")
138 }
139 return &HttpServer{handle: handle}, nil
140}
141 
142func (s *HttpServer) Close() {
143 if s.handle != nil {
144 C.pal_ffi_http_server_destroy(s.handle)
145 s.handle = nil
146 }
147}
148