-
Notifications
You must be signed in to change notification settings - Fork 100
Dev Docs API Libatalk
WIP - ALL LINKS IN THIS WIKI STRUCTURE ARE CURRENTLY BROKEN DURING WIKI MIGRATION
THESE ARE COMMUNITY DOCS
The libatalk library provides the core functionality for Netatalk's AFP implementation. This document covers the primary APIs, data structures, and utility functions available to developers working with or extending Netatalk.
Source Code Location: libatalk/
directory contains all core library implementations
Header Files: include/atalk/
directory contains public API definitions
Build Configuration: libatalk/meson.build
defines library structure and dependencies
libatalk/
├── adouble/ # AppleDouble format handling
├── bstring/ # String manipulation utilities
├── cnid/ # CNID database interface
├── compat/ # Platform compatibility layer
├── dsi/ # DSI protocol implementation
├── unicode/ # Character encoding support
├── util/ # General utility functions
└── vfs/ # Virtual filesystem layer
Implementation Files:
-
Core Library Build:
libatalk/meson.build
- Library compilation and linking configuration -
Public Headers:
include/atalk/*.h
- API definitions and structures - Private Headers: Each subdirectory contains internal headers for implementation details
The AppleDouble API handles Mac metadata storage on Unix filesystems.
Implementation Files:
-
Core Implementation:
libatalk/adouble/ad_open.c
- File opening and initialization -
Metadata Operations:
libatalk/adouble/ad_attr.c
- Attribute handling -
Entry Management:
libatalk/adouble/ad_read.c
,libatalk/adouble/ad_write.c
- I/O operations -
Locking:
libatalk/adouble/ad_lock.c
- File locking mechanisms -
Date Operations:
libatalk/adouble/ad_date.c
- Timestamp management -
Header Definitions:
include/atalk/adouble.h
- Public API and constants
// Open AppleDouble file
struct adouble *ad_init(struct adouble *ad, int flags);
// Open AppleDouble for file
int ad_open(struct adouble *ad, const char *path, int adflags, int mode);
// Close AppleDouble file
int ad_close(struct adouble *ad, int adflags);
// Flush AppleDouble data
int ad_flush(struct adouble *ad);
// Set file lock
int ad_lock(struct adouble *ad, uint32_t eid, int locktype,
off_t off, off_t len, int fork);
// Release file lock
int ad_unlock(struct adouble *ad, int fork, int unlockall);
// Get AppleDouble entry data
char *ad_entry(struct adouble *ad, int eid);
// Get entry length
off_t ad_getentrylen(struct adouble *ad, int eid);
// Set entry data
int ad_setentry(struct adouble *ad, int eid,
const void *buf, size_t len);
// Set entry offset and length
int ad_setentrylen(struct adouble *ad, int eid, size_t len);
// Standard AppleDouble entries
#define ADEID_DFORK 1 // Data fork
#define ADEID_RFORK 2 // Resource fork
#define ADEID_NAME 3 // Real name
#define ADEID_COMMENT 4 // Comment
#define ADEID_ICONBW 5 // Icon (B&W)
#define ADEID_ICONCOL 6 // Icon (color)
#define ADEID_FILEI 7 // File info
#define ADEID_FILEDATESI 8 // File dates info
#define ADEID_FINDERI 9 // Finder info
#define ADEID_MACFILEI 10 // Mac file info
#define ADEID_PRODOSFILEI 11 // ProDOS file info
#define ADEID_MSDOSFILEI 12 // MS-DOS file info
#define ADEID_SHORTNAME 13 // Short name
#define ADEID_AFPFILEI 14 // AFP file info
#define ADEID_DID 15 // Directory ID
// Open AppleDouble file for reading/writing
struct adouble ad;
ad_init(&ad, 0);
if (ad_open(&ad, "/path/to/file", ADFLAGS_HF | ADFLAGS_CREATE, 0666) == 0) {
// Get Finder info
char *finderinfo = ad_entry(&ad, ADEID_FINDERI);
if (finderinfo) {
// Process Finder info (32 bytes)
memcpy(file_type, finderinfo, 4);
memcpy(file_creator, finderinfo + 4, 4);
}
// Set file comment
const char *comment = "This is a test comment";
ad_setentry(&ad, ADEID_COMMENT, comment, strlen(comment));
ad_flush(&ad);
ad_close(&ad, ADFLAGS_HF);
}
The CNID API provides file identification services.
Implementation Files:
-
Core Interface:
libatalk/cnid/cnid.c
- Main CNID operations and database interface -
Database Backend:
etc/cnid_dbd/
- CNID database daemon implementation -
Database Operations:
etc/cnid_dbd/cmd_dbd.c
- Database command processing -
Database Storage:
etc/cnid_dbd/dbd.c
- Core database operations -
Database Utilities:
etc/cnid_dbd/dbd_*.c
- Specialized database functions -
Header Definitions:
include/atalk/cnid.h
- Public CNID API definitions
// Open CNID database
struct cnid_db *cnid_open(const char *volpath, mode_t mask,
char *type, int flags,
char *cnidserver, char *cnidport);
// Close CNID database
void cnid_close(struct cnid_db *cdb);
// Add new CNID entry
cnid_t cnid_add(struct cnid_db *cdb, const struct stat *st,
cnid_t did, const char *name, size_t len, char *hint);
// Get CNID by directory ID and name
cnid_t cnid_get(struct cnid_db *cdb, cnid_t did,
const char *name, size_t len);
// Look up CNID (get or add)
cnid_t cnid_lookup(struct cnid_db *cdb, const struct stat *st,
cnid_t did, const char *name, size_t len);
// Update CNID entry
int cnid_update(struct cnid_db *cdb, cnid_t id, const struct stat *st,
cnid_t did, const char *name, size_t len);
// Delete CNID entry
int cnid_delete(struct cnid_db *cdb, cnid_t id);
// Resolve CNID to path
int cnid_resolve(struct cnid_db *cdb, cnid_t id,
void *buffer, size_t len);
typedef uint32_t cnid_t;
#define CNID_INVALID 0
#define CNID_START 17 // First assignable CNID
#define DIRDID_ROOT 2 // Root directory ID
#define DIRDID_ROOT_PARENT 1 // Root parent ID
// CNID database flags
#define CNID_FLAG_NODEV 0x01 // Ignore device numbers
#define CNID_FLAG_MEMORY 0x02 // Memory-only database
// Open CNID database
struct cnid_db *cdb = cnid_open("/srv/afp_volume", 0, "dbd", 0, NULL, NULL);
if (cdb) {
// Look up file CNID
struct stat st;
if (stat("/srv/afp_volume/document.txt", &st) == 0) {
cnid_t cnid = cnid_lookup(cdb, &st, DIRDID_ROOT,
"document.txt", strlen("document.txt"));
printf("File CNID: %u\n", cnid);
}
cnid_close(cdb);
}
The DSI API implements the Data Stream Interface protocol.
Implementation Files:
-
Protocol Core:
libatalk/dsi/dsi_stream.c
- Main DSI protocol implementation -
Network I/O:
libatalk/dsi/dsi_tcp.c
- TCP transport layer and socket handling -
Command Processing:
libatalk/dsi/dsi_cmdreply.c
- Command/reply processing -
Connection Management:
libatalk/dsi/dsi_init.c
- DSI initialization and cleanup -
Attention Handling:
libatalk/dsi/dsi_attn.c
- Attention packet processing -
Header Definitions:
include/atalk/dsi.h
- DSI protocol constants and structures
// Initialize DSI structure
DSI *dsi_init(AFPObj *obj, const char *hostname,
const char *address, const char *port);
// Accept DSI connection
int dsi_stream_accept_loop(DSI *dsi);
// Read DSI command
void dsi_commandreply(DSI *dsi, int err);
// Write DSI data
ssize_t dsi_stream_write(DSI *dsi, void *data, const size_t length);
// Read DSI data
ssize_t dsi_stream_read(DSI *dsi, void *data, const size_t length);
// Send DSI attention packet
int dsi_attention(DSI *dsi, AFPUserBytes flags);
typedef struct DSI {
int socket; // Network socket
int serversock; // Server listening socket
// Protocol state
uint8_t commands[DSI_CMDSIZ]; // Command buffer
uint8_t data[DSI_DATASIZ]; // Data buffer
size_t cmdlen; // Command length
size_t datalen; // Data length
// DSI header fields
uint8_t flags; // DSI flags
uint8_t command; // DSI command
uint16_t requestID; // Request ID
uint32_t code; // Error/result code
uint32_t reserved; // Reserved field
// Connection info
struct sockaddr_storage client; // Client address
AFPObj *AFPobj; // AFP object
} DSI;
#define DSIFUNC_CLOSE 1 // Close session
#define DSIFUNC_CMD 2 // AFP command
#define DSIFUNC_STAT 3 // Get server status
#define DSIFUNC_OPEN 4 // Open session
#define DSIFUNC_TICKLE 5 // Keep-alive
#define DSIFUNC_WRITE 6 // Write data
#define DSIFUNC_ATTN 8 // Attention
Character encoding conversion and Unicode support.
Implementation Files:
-
Charset Conversion:
libatalk/unicode/charset.c
- Core character set conversion engine -
UTF-8 Support:
libatalk/unicode/utf8.c
- UTF-8 encoding/decoding functions -
Unicode Normalization:
libatalk/unicode/precompose.c
- Unicode composition/decomposition -
Character Tables:
libatalk/unicode/charsets/
- Character mapping tables and definitions -
Mac Encoding:
libatalk/unicode/charsets/mac_*.c
- Mac-specific character encodings -
Header Definitions:
include/atalk/unicode.h
- Unicode API and charset constants
// Initialize charset conversion
int charset_init(void);
// Convert between charsets
size_t charset_conv(charset_t from, charset_t to,
char *src, size_t srclen,
char *dest, size_t destlen);
// Convert to UTF-8
size_t charset_to_utf8(charset_t from, char *src, size_t srclen,
char *dest, size_t destlen);
// Convert from UTF-8
size_t charset_from_utf8(charset_t to, char *src, size_t srclen,
char *dest, size_t destlen);
// Precompose Unicode string
size_t charset_precompose(char *src, size_t srclen,
char *dest, size_t destlen);
// Decompose Unicode string
size_t charset_decompose(char *src, size_t srclen,
char *dest, size_t destlen);
typedef enum {
CH_UCS2 = 0, // UCS-2
CH_UTF8, // UTF-8
CH_UTF8_MAC, // UTF-8 (Mac variant)
CH_UNIX, // System default
CH_MAC_ROMAN, // Mac Roman
CH_ISO8859_1, // ISO 8859-1
CH_CP1252, // Windows-1252
} charset_t;
General utility functions and macros.
Implementation Files:
-
String Utilities:
libatalk/util/string.c
- Safe string functions and utilities -
Path Operations:
libatalk/util/unix.c
- Unix path and filesystem utilities -
Network Utilities:
libatalk/util/socket.c
- Socket and network helper functions -
System Integration:
libatalk/util/server_ipc.c
- Inter-process communication -
Logging System:
libatalk/util/logger.c
- Centralized logging implementation -
Header Definitions:
include/atalk/util.h
- Utility macros and function declarations
// Safe string copy
size_t strlcpy(char *dst, const char *src, size_t size);
size_t strlcat(char *dst, const char *src, size_t size);
// String comparison (case-insensitive)
int strcasecmp_w(const char *s1, const char *s2);
int strncasecmp_w(const char *s1, const char *s2, size_t n);
// Path utilities
char *mtoupath(const struct vol *vol, const char *mpath,
cnid_t did, int utf8);
char *utompath(const struct vol *vol, const char *upath,
cnid_t cnid, int utf8);
// Error checking initialization
#define EC_INIT int ret = 0
// Check for NULL pointer
#define EC_NULL(expr) do { \
if ((expr) == NULL) { \
ret = -1; \
goto EC_CLEANUP; \
} \
} while(0)
// Check for zero return
#define EC_ZERO(expr) do { \
if ((expr) != 0) { \
ret = -1; \
goto EC_CLEANUP; \
} \
} while(0)
// Set return status
#define EC_STATUS(status) ret = (status)
// Cleanup and exit
#define EC_EXIT return ret
// Safe memory allocation
void *malloc_safe(size_t size);
void *calloc_safe(size_t nmemb, size_t size);
char *strdup_safe(const char *s);
// Memory debugging (if enabled)
#ifdef DEBUG_MEMORY
#define MALLOC(size) debug_malloc(size, __FILE__, __LINE__)
#define FREE(ptr) debug_free(ptr, __FILE__, __LINE__)
#else
#define MALLOC(size) malloc(size)
#define FREE(ptr) free(ptr)
#endif
Centralized logging system.
Implementation Files:
-
Core Logging:
libatalk/util/logger.c
- Main logging system implementation -
Log Configuration:
etc/afpd/afp_config.c
- Logging setup and configuration parsing -
Log Levels:
include/atalk/logger.h
- Log level definitions and macros - Debug Support: Various source files use LOG() macros for debugging output
// Primary logging function
void LOG(enum loglevels loglevel, const char *fmt, ...);
// Setup logging system
void log_setup(const char *filename, enum loglevels loglevel,
int display_options);
// Close logging system
void log_close(void);
// Log levels
enum loglevels {
log_none = 0,
log_severe, // System errors
log_error, // Serious errors
log_warning, // Warnings
log_note, // Important info
log_info, // General info
log_debug, // Debug info
log_debug6, // Verbose debug
log_debug7, // Very verbose
log_debug8, // Extremely verbose
log_debug9, // Maximum verbosity
log_maxdebug
};
// Initialize logging
log_setup("/var/log/netatalk.log", log_info, 0);
// Log messages
LOG(log_info, "Server started on port %d", port);
LOG(log_error, "Failed to open file: %s", strerror(errno));
LOG(log_debug, "Processing command %d from client %s", cmd, client_ip);
// Cleanup
log_close();
Configuration file parsing and management.
Implementation Files:
-
Configuration Parser:
etc/afpd/afp_config.c
- Main configuration file parsing -
Volume Configuration:
etc/afpd/volume.c
- Volume-specific configuration handling -
INI Parser:
libatalk/iniparser/
- Configuration file parsing library -
Options Processing:
etc/afpd/afp_options.c
- Command-line and config option processing -
Global Configuration:
libatalk/util/netatalk_conf.c
- Global configuration management -
Header Definitions:
include/atalk/netatalk_conf.h
- Configuration structures and constants
// Load configuration
int afp_config_parse(AFPObj *obj, char *filename);
// Free configuration
void afp_config_free(AFPObj *obj);
// Get volume list
struct vol *getvolumes(void);
// Get volume by name
struct vol *getvolbyname(const char *name);
// Get volume by path
struct vol *getvolbypath(const char *path);
struct afp_options {
char *configfile; // Configuration file path
char *uampath; // UAM module path
char *fqdn; // Server FQDN
char *hostname; // Server hostname
char *admingroup; // Admin group name
char *guest; // Guest account name
int port; // TCP port
int transports; // Enabled transports
int server_notif; // Server notifications
int authprintdir; // Print directory auth
int signature; // Server signature
int k5service; // Kerberos service
int k5realm; // Kerberos realm
int volnamelen; // Volume name length
int sleep; // Sleep time
int disconnected; // Disconnected timeout
int fce_fmodwait; // FCE file mod wait
int passwdminlen; // Minimum password length
int loginmaxfail; // Max login failures
};
Build System Integration:
-
Library Compilation:
libatalk/meson.build
- Complete build configuration for all library components -
Dependency Management:
meson_options.txt
- Build-time feature selection and dependencies -
Feature Detection:
meson.build
(root) - Platform and feature detection logic
Testing and Debugging:
-
Unit Tests:
test/afpd_test.c
- Core functionality testing -
Performance Tests:
test/performance/
- Performance benchmarking utilities - Memory Debugging: Compile-time DEBUG_MEMORY support throughout codebase
Platform Compatibility:
-
Compatibility Layer:
libatalk/compat/
- Platform-specific implementations -
System Headers:
include/atalk/compat.h
- Cross-platform compatibility definitions
This API reference provides the foundation for understanding and working with Netatalk's internal APIs. For detailed implementation examples and advanced usage patterns, refer to the existing source code in the respective directories listed above.
Resources
OS Specific Guides
- Installing Netatalk on Alpine Linux
- Installing Netatalk on Debian Linux
- Installing Netatalk on Fedora Linux
- Installing Netatalk on FreeBSD
- Installing Netatalk on macOS
- Installing Netatalk on NetBSD
- Installing Netatalk on OmniOS
- Installing Netatalk on OpenBSD
- Installing Netatalk on OpenIndiana
- Installing Netatalk on openSUSE
- Installing Netatalk on Solaris
- Installing Netatalk on Ubuntu
Technical Docs
- CatalogSearch
- Kerberos
- Special Files and Folders
- Spotlight
- AppleTalk Kernel Module
- Print Server
- MacIP Gateway
- MySQL CNID Backend
Development