netatalk: Using libatalk from third party apps

netatalk 4.5.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
Using libatalk from third party apps

Third party developers wishing to add Netatalk support to their applications have two choices

1. Directly integrate libatalk from the Netatalk source tree
2. Link with libatalk which is a shared library in its own right starting with Netatalk 3

Please note that you need at least Netatalk 3.0.1 for approach 2 to work, because in earlier Netatalk versions some necessary headers are not installed correctly.

# Example

This examples links a trivial example program with the libatalk shared library. Assuming Netatalk has been installed to /usr/local/netatalk, compiling backup_demo.c is done like this:

c99 -I/usr/local/netatalk/include -o backup_demo backup_demo.c -L/usr/local/netatalk/lib -latalk -Wl,-rpath=/usr/local/netatalk/lib

Here follows the backup_demo.c code which copies metadata and resource from one file to another:

/*
* Copyright (c) 2012, Frank Lahm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <atalk/logger.h>
#include <atalk/netatalk_conf.h>
#include <atalk/volume.h>
#define ERROR(...) \
do { \
_log(__VA_ARGS__); \
exit(1); \
} while (0)
static void _log(char *fmt, ...)
{
int len;
static char logbuffer[1024];
va_list args;
va_start(args, fmt);
len = vsnprintf(logbuffer, 1023, fmt, args);
va_end(args);
logbuffer[1023] = 0;
printf("%s\n", logbuffer);
}
int main(int argc, char **argv)
{
const char *file, *newfile;
struct vol *vol;
struct adouble ad, adnew;
struct stat st;
if (argc != 3) {
ERROR("usage: backup_demo FILE NEWFILE");
}
file = argv[1];
newfile = argv[2];
AFPObj obj = { 0 };
if (afp_config_parse(&obj, "ad") != 0) {
ERROR("No Netatalk 3 afp.conf found", file);
}
setuplog("default:note", "/dev/tty");
if (load_volumes(&obj, NULL) != 0) {
ERROR("Couldn't load volumes");
}
if ((vol = getvolbypath(&obj, file)) == NULL) {
ERROR("Not a Netatalk volume for file \"%s\"", file);
}
printf("Volume path \"%s\"\n", vol->v_path);
if (vol->v_adouble == AD_VERSION2) {
printf("Volume adouble version v2\n");
} else if (vol->v_adouble == AD_VERSION_EA) {
printf("Volume adouble version ea\n");
} else {
ERROR("Unknown adouble version");
}
ad_init(&ad, vol);
/* Open an existing file's metadata and resource */
if (ad_open(&ad, file, ADFLAGS_HF | ADFLAGS_RDONLY) != 0) {
ERROR("Couldn't open metadata of \"%s\"", file);
}
int ad_size = vol->v_adouble == AD_VERSION2 ? AD_DATASZ2 : AD_DATASZ_EA;
printf("%d bytes in adouble metadata buffer ad->ad_data\n", ad_size);
if (ad_open(&ad, file, ADFLAGS_RF | ADFLAGS_RDONLY) != 0) {
ERROR("Couldn't open resource of \"%s\"", file);
}
printf("File has resource fork of size: %d, fd: %d\n", ad.ad_rlen,
ad_reso_fileno(&ad));
/* Copy over metadata and resource to new file */
if (lstat(newfile, &st) != 0) {
ERROR("Can't stat \"%s\", must exist, create with eg touch", newfile);
}
ad_init(&adnew, vol);
if (ad_open(&ad, file, ADFLAGS_HF | ADFLAGS_RF | ADFLAGS_RDWR | ADFLAGS_CREATE)
!= 0) {
ERROR("Couldn't create metadata/resource of \"%s\"", newfile);
}
memcpy(adnew.ad_data, ad.ad_data, ad_size);
ad_flush(&adnew);
if (vol->vfs->vfs_copyfile(vol, -1, file, newfile) != 0) {
ERROR("Couln't copy resource to \"%s\"", newfile);
}
ad_close(&ad, ADFLAGS_HF | ADFLAGS_RF);
ad_close(&adnew, ADFLAGS_HF | ADFLAGS_RF);
#if 0
/* examples setting some stuff */
ad_setdate(&ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime);
ad_setdate(&ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime);
ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START);
ad_flush(&ad);
#endif
return 0;
}
ADFLAGS_CREATE
#define ADFLAGS_CREATE
Definition adouble.h:240
AD_DATE_CREATE
#define AD_DATE_CREATE
Definition adouble.h:284
AD_VERSION2
#define AD_VERSION2
Definition adouble.h:45
AD_DATASZ_EA
#define AD_DATASZ_EA
Definition adouble.h:127
AD_DATE_START
#define AD_DATE_START
Definition adouble.h:291
ADFLAGS_RDWR
#define ADFLAGS_RDWR
Definition adouble.h:238
ad_init
void ad_init(struct adouble *, const struct vol *)
Definition ad_open.c:2242
ad_open
int ad_open(struct adouble *ad, const char *path, int adflags,...)
Open data-, metadata(header)- or resource fork.
Definition ad_open.c:2308
ad_size
off_t ad_size(const struct adouble *, uint32_t)
Definition ad_size.c:18
AD_DATE_UNIX
#define AD_DATE_UNIX
Definition adouble.h:290
AD_DATE_BACKUP
#define AD_DATE_BACKUP
Definition adouble.h:286
ad_flush
int ad_flush(struct adouble *)
Definition ad_flush.c:448
ad_close
int ad_close(struct adouble *, int)
Definition ad_flush.c:485
AD_DATASZ2
#define AD_DATASZ2
Definition adouble.h:119
AD_VERSION_EA
#define AD_VERSION_EA
Definition adouble.h:46
ADFLAGS_HF
#define ADFLAGS_HF
Definition adouble.h:227
ADFLAGS_RDONLY
#define ADFLAGS_RDONLY
Definition adouble.h:239
ad_reso_fileno
#define ad_reso_fileno(ad)
Definition adouble.h:356
AD_DATE_MODIFY
#define AD_DATE_MODIFY
Definition adouble.h:285
ADFLAGS_RF
#define ADFLAGS_RF
Definition adouble.h:226
AD_DATE_ACCESS
#define AD_DATE_ACCESS
Definition adouble.h:287
ad_setdate
int ad_setdate(struct adouble *, unsigned int, uint32_t)
Definition ad_date.c:10
config.h
volume.h
logger.h
setuplog
void setuplog(const char *loglevel, const char *logfile, const bool log_us_timestamp)
Definition logger.c:558
ERROR
#define ERROR(...)
Definition nad.h:38
_log
void _log(enum logtype lt, char *fmt,...)
Definition nad_util.c:118
obj
static AFPObj obj
Definition netatalk.c:69
netatalk_conf.h
getvolbypath
struct vol * getvolbypath(AFPObj *obj, const char *path)
Search volume by path, creating user home vols as necessary.
Definition netatalk_conf.c:2541
load_volumes
int load_volumes(AFPObj *obj, lv_flags_t flags)
Initialize volumes and load ini configfile.
Definition netatalk_conf.c:2272
afp_config_parse
int afp_config_parse(AFPObj *obj, char *processname)
Definition netatalk_conf.c:2781
main
int main(void)
Definition sanity_check_for_c.c:1
AFPObj
Definition globals.h:166
adouble
Definition adouble.h:191
vfs_ops::vfs_copyfile
vfs_copyfile_fn vfs_copyfile
Definition vfs.h:109
vol
Definition include/atalk/volume.h:33
vol::v_adouble
int v_adouble
Definition include/atalk/volume.h:50
vol::v_path
char * v_path
Definition include/atalk/volume.h:38
vol::vfs
struct vfs_ops * vfs
Definition include/atalk/volume.h:70
args
static char * args[]
Definition test.c:48
NULL
#define NULL
Definition utf8util.c:47

Authored by Ralph Böhme