#include <errno.h>
#include <atalk/cnid.h>
-#include <atalk/volinfo.h>
#include <atalk/logger.h>
#include <atalk/util.h>
+#include <atalk/netatalk_conf.h>
#include "ad.h"
int main(int argc, char **argv)
{
+ AFPObj obj = { 0 };
+
setuplog("default:note", "/dev/tty");
if (argc < 2) {
return 1;
}
+ if (afp_config_parse(&obj) != 0)
+ return 1;
+
+ if (load_volumes(&obj, NULL) != 0)
+ return 1;
+
if (STRCMP(argv[1], ==, "ls"))
return ad_ls(argc - 1, argv + 1);
else if (STRCMP(argv[1], ==, "cp"))
#include <arpa/inet.h>
#include <atalk/ftw.h>
-#include <atalk/volinfo.h>
#include <atalk/cnid.h>
#include <atalk/compat.h>
+#include <atalk/volume.h>
#define DIR_DOT_OR_DOTDOT(a) \
((strcmp(a, ".") == 0) || (strcmp(a, "..") == 0))
} while (0)
typedef struct {
- struct volinfo volinfo;
- struct vol volume;
+ struct vol *vol;
char db_stamp[ADEDLEN_PRIVSYN];
} afpvol_t;
extern void closevol(afpvol_t *vol);
extern cnid_t cnid_for_path(const afpvol_t *vol, const char *path, cnid_t *did);
extern cnid_t cnid_for_paths_parent(const afpvol_t *vol, const char *path, cnid_t *did);
-extern char *utompath(const struct volinfo *volinfo, const char *upath);
+extern char *utompath(const struct vol *, const char *);
extern int convert_dots_encoding(const afpvol_t *svol, const afpvol_t *dvol, char *path, size_t buflen);
typedef struct {
#include <atalk/util.h>
#include <atalk/unix.h>
#include <atalk/volume.h>
-#include <atalk/volinfo.h>
#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
#include <atalk/queue.h>
}
/* Convert basename to appropiate volume encoding */
- if (dvolume.volinfo.v_path) {
+ if (dvolume.vol->v_path) {
if ((convert_dots_encoding(&svolume, &dvolume, to.p_path, MAXPATHLEN)) == -1) {
SLOG("Error converting name for %s", to.p_path);
badcp = rval = 1;
}
/* Create ad dir and copy ".Parent" */
- if (dvolume.volinfo.v_path && dvolume.volinfo.v_adouble == AD_VERSION2) {
+ if (dvolume.vol->v_path && dvolume.vol->v_adouble == AD_VERSION2) {
/* Create ".AppleDouble" dir */
mode_t omask = umask(0);
mkdir(cfrombstr(addir), 02777);
bdestroy(addir);
- if (svolume.volinfo.v_path && svolume.volinfo.v_adouble == AD_VERSION2) {
+ if (svolume.vol->v_path && svolume.vol->v_adouble == AD_VERSION2) {
/* copy ".Parent" file */
- if (dvolume.volume.vfs->vfs_copyfile(&dvolume.volume, -1, path, to.p_path)) {
+ if (dvolume.vol->vfs->vfs_copyfile(dvolume.vol, -1, path, to.p_path)) {
SLOG("Error copying adouble for %s -> %s", path, to.p_path);
badcp = rval = 1;
break;
badcp = rval = 1;
break;
}
- ad_init_old(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
+ ad_init(&ad, dvolume.vol);
if (ad_open(&ad, to.p_path, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) {
ERROR("Error opening adouble for: %s", to.p_path);
}
ad_setid( &ad, st.st_dev, st.st_ino, did, pdid, dvolume.db_stamp);
- ad_setname(&ad, utompath(&dvolume.volinfo, basename(to.p_path)));
+ ad_setname(&ad, utompath(dvolume.vol, basename(to.p_path)));
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);
if (ftw_copy_file(ftw, path, statp, dne))
badcp = rval = 1;
- if (dvolume.volinfo.v_path && dvolume.volinfo.v_adouble == AD_VERSION2) {
+ if (dvolume.vol->v_path && dvolume.vol->v_adouble == AD_VERSION2) {
mode_t omask = umask(0);
- if (svolume.volinfo.v_path && svolume.volinfo.v_adouble == AD_VERSION2) {
+ if (svolume.vol->v_path && svolume.vol->v_adouble == AD_VERSION2) {
/* copy ad-file */
- if (dvolume.volume.vfs->vfs_copyfile(&dvolume.volume, -1, path, to.p_path)) {
+ if (dvolume.vol->vfs->vfs_copyfile(dvolume.vol, -1, path, to.p_path)) {
SLOG("Error copying adouble for %s -> %s", path, to.p_path);
badcp = rval = 1;
break;
badcp = rval = 1;
break;
}
- ad_init_old(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
+ ad_init(&ad, dvolume.vol);
if (ad_open(&ad, to.p_path, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) {
ERROR("Error opening adouble for: %s", to.p_path);
}
ad_setid( &ad, st.st_dev, st.st_ino, cnid, did, dvolume.db_stamp);
- ad_setname(&ad, utompath(&dvolume.volinfo, basename(to.p_path)));
+ ad_setname(&ad, utompath(dvolume.vol, basename(to.p_path)));
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);
/* remove existing destination file name,
* create a new file */
(void)unlink(to.p_path);
- (void)dvolume.volume.vfs->vfs_deletefile(&dvolume.volume, -1, to.p_path);
+ (void)dvolume.vol->vfs->vfs_deletefile(dvolume.vol, -1, to.p_path);
to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
sp->st_mode & ~(S_ISUID | S_ISGID));
} else {
#include <atalk/adouble.h>
#include <atalk/cnid.h>
#include <atalk/cnid_dbd_private.h>
-#include <atalk/volinfo.h>
#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
#include <atalk/directory.h>
uint16_t flags = CONV_TOLOWER;
char namebuf[MAXPATHLEN + 1];
- if (convert_charset(vol.volinfo.v_volcharset,
- vol.volinfo.v_volcharset,
- vol.volinfo.v_maccharset,
+ if (convert_charset(vol.vol->v_volcharset,
+ vol.vol->v_volcharset,
+ vol.vol->v_maccharset,
argv[optind],
strlen(argv[optind]),
namebuf,
int count;
char resbuf[DBD_MAX_SRCH_RSLTS * sizeof(cnid_t)];
- if ((count = cnid_find(vol.volume.v_cdb,
+ if ((count = cnid_find(vol.vol->v_cdb,
namebuf,
strlen(namebuf),
resbuf,
bufp += sizeof(cnid_t);
bstring path = NULL;
- bstring volpath = bfromcstr(vol.volinfo.v_path);
+ bstring volpath = bfromcstr(vol.vol->v_path);
BSTRING_STRIP_SLASH(volpath);
char buffer[12 + MAXPATHLEN + 1];
int buflen = 12 + MAXPATHLEN + 1;
struct bstrList *pathlist = bstrListCreateMin(32);
while (did != DIRDID_ROOT) {
- if ((name = cnid_resolve(vol.volume.v_cdb, &did, buffer, buflen)) == NULL)
+ if ((name = cnid_resolve(vol.vol->v_cdb, &did, buffer, buflen)) == NULL)
goto next;
bstrListPush(pathlist, bfromcstr(name));
}
#include <atalk/adouble.h>
#include <atalk/cnid.h>
-#include <atalk/volinfo.h>
#include "ad.h"
#define ADv2_DIRNAME ".AppleDouble"
if (S_ISDIR(st->st_mode))
adflags = ADFLAGS_DIR;
- if (vol->volinfo.v_path == NULL)
+ if (vol->vol->v_path == NULL)
return;
- ad_init_old(&ad, vol->volinfo.v_adouble, vol->volinfo.v_ad_options);
+ ad_init(&ad, vol->vol);
if ( ad_metadata(path, adflags, &ad) < 0 )
return;
#include <atalk/util.h>
#include <atalk/unix.h>
#include <atalk/volume.h>
-#include <atalk/volinfo.h>
#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
#include <atalk/queue.h>
* 1) source AFP volume != dest AFP volume
* 2) either source or dest isn't even an AFP volume
*/
- if (!svolume.volinfo.v_path
- || !dvolume.volinfo.v_path
- || strcmp(svolume.volinfo.v_path, dvolume.volinfo.v_path) != 0)
+ if (!svolume.vol->v_path
+ || !dvolume.vol->v_path
+ || strcmp(svolume.vol->v_path, dvolume.vol->v_path) != 0)
mustcopy = 1;
cnid_t cnid = 0;
switch (sb.st_mode & S_IFMT) {
case S_IFREG:
- if (dvolume.volume.vfs->vfs_renamefile(&dvolume.volume, -1, from, to) != 0) {
+ if (dvolume.vol->vfs->vfs_renamefile(dvolume.vol, -1, from, to) != 0) {
SLOG("Error moving adouble file for %s", from);
return -1;
}
char *p = strdup(to);
char *name = basename(p);
- if (cnid_update(dvolume.volume.v_cdb, cnid, &sb, newdid, name, strlen(name)) != 0) {
+ if (cnid_update(dvolume.vol->v_cdb, cnid, &sb, newdid, name, strlen(name)) != 0) {
SLOG("Cant update CNID for: %s", to);
return 1;
}
free(p);
struct adouble ad;
- ad_init_old(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
+ ad_init(&ad, dvolume.vol);
if (ad_open(&ad, to, S_ISDIR(sb.st_mode) ? (ADFLAGS_DIR | ADFLAGS_HF | ADFLAGS_RDWR) : ADFLAGS_HF | ADFLAGS_RDWR) != 0) {
SLOG("Error opening adouble for: %s", to);
return 1;
#include <atalk/util.h>
#include <atalk/unix.h>
#include <atalk/volume.h>
-#include <atalk/volinfo.h>
#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
#include <atalk/queue.h>
switch (statp->st_mode & S_IFMT) {
case S_IFLNK:
- if (volume.volinfo.v_path) {
- if ((volume.volinfo.v_adouble == AD_VERSION2)
+ if (volume.vol->v_path) {
+ if ((volume.vol->v_adouble == AD_VERSION2)
&& (strstr(path, ".AppleDouble") != NULL)) {
/* symlink inside adouble dir */
if (unlink(path) != 0)
SLOG("Error resolving CNID for %s", path);
return -1;
}
- if (cnid_delete(volume.volume.v_cdb, cnid) != 0) {
+ if (cnid_delete(volume.vol->v_cdb, cnid) != 0) {
SLOG("Error removing CNID %u for %s", ntohl(cnid), path);
return -1;
}
return FTW_SKIP_SUBTREE;
}
- if (volume.volinfo.v_path) {
- if ((volume.volinfo.v_adouble == AD_VERSION2)
+ if (volume.vol->v_path) {
+ if ((volume.vol->v_adouble == AD_VERSION2)
&& (strstr(path, ".AppleDouble") != NULL)) {
/* should be adouble dir itself */
if (rmdir(path) != 0) {
SLOG("Error resolving CNID for %s", path);
return -1;
}
- if (cnid_delete(volume.volume.v_cdb, did) != 0) {
+ if (cnid_delete(volume.vol->v_cdb, did) != 0) {
SLOG("Error removing CNID %u for %s", ntohl(did), path);
return -1;
}
break;
default:
- if (volume.volinfo.v_path) {
- if ((volume.volinfo.v_adouble == AD_VERSION2)
+ if (volume.vol->v_path) {
+ if ((volume.vol->v_adouble == AD_VERSION2)
&& (strstr(path, ".AppleDouble") != NULL)) {
/* file in adouble dir */
if (unlink(path) != 0)
SLOG("Error resolving CNID for %s", path);
return -1;
}
- if (cnid_delete(volume.volume.v_cdb, cnid) != 0) {
+ if (cnid_delete(volume.vol->v_cdb, cnid) != 0) {
SLOG("Error removing CNID %u for %s", ntohl(cnid), path);
return -1;
}
/* Ignore errors, because with -R adouble stuff is always alread gone */
- volume.volume.vfs->vfs_deletefile(&volume.volume, -1, path);
+ volume.vol->vfs->vfs_deletefile(volume.vol, -1, path);
}
if (unlink(path) != 0) {
#include <atalk/util.h>
#include <atalk/cnid.h>
-#include <atalk/volinfo.h>
#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
#include <atalk/logger.h>
#include <atalk/errchk.h>
#include <atalk/unicode.h>
+#include <atalk/netatalk_conf.h>
#include "ad.h"
memset(vol, 0, sizeof(afpvol_t));
/* try to find a .AppleDesktop/.volinfo */
- if (loadvolinfo((char *)path, &vol->volinfo) != 0)
+ if ((vol->vol = getvolbypath(path)) == NULL)
return -1;
- if (STRCMP(vol->volinfo.v_cnidscheme, != , "dbd"))
- ERROR("\"%s\" isn't a \"dbd\" CNID volume!", vol->volinfo.v_path);
-
- if (vol_load_charsets(&vol->volinfo) == -1)
- ERROR("Error loading charsets!");
+ if (STRCMP(vol->vol->v_cnidscheme, != , "dbd"))
+ ERROR("\"%s\" isn't a \"dbd\" CNID volume!", vol->vol->v_path);
/* Sanity checks to ensure we can touch this volume */
- if (vol->volinfo.v_adouble != AD_VERSION2)
- ERROR("Unsupported adouble versions: %u", vol->volinfo.v_adouble);
-
- if (vol->volinfo.v_vfs_ea != AFPVOL_EA_SYS)
- ERROR("Unsupported Extended Attributes option: %u", vol->volinfo.v_vfs_ea);
+ if (vol->vol->v_adouble != AD_VERSION2)
+ ERROR("Unsupported adouble versions: %u", vol->vol->v_adouble);
- /* initialize sufficient struct vol for VFS initialisation */
- vol->volume.v_adouble = AD_VERSION2;
- vol->volume.v_vfs_ea = AFPVOL_EA_SYS;
- initvol_vfs(&vol->volume);
+ if (vol->vol->v_vfs_ea != AFPVOL_EA_SYS)
+ ERROR("Unsupported Extended Attributes option: %u", vol->vol->v_vfs_ea);
- if ((vol->volinfo.v_flags & AFPVOL_NODEV))
+ if ((vol->vol->v_flags & AFPVOL_NODEV))
flags |= CNID_FLAG_NODEV;
- if ((vol->volume.v_cdb = cnid_open(vol->volinfo.v_path,
- 0000,
- "dbd",
- flags,
- vol->volinfo.v_dbd_host,
- vol->volinfo.v_dbd_port)) == NULL)
- ERROR("Cant initialize CNID database connection for %s", vol->volinfo.v_path);
+ if ((vol->vol->v_cdb = cnid_open(vol->vol->v_path,
+ 0000,
+ "dbd",
+ flags,
+ vol->vol->v_cnidserver,
+ vol->vol->v_cnidport)) == NULL)
+ ERROR("Cant initialize CNID database connection for %s", vol->vol->v_path);
- cnid_getstamp(vol->volume.v_cdb,
+ cnid_getstamp(vol->vol->v_cdb,
vol->db_stamp,
sizeof(vol->db_stamp));
void closevol(afpvol_t *vol)
{
- if (vol->volume.v_cdb)
- cnid_close(vol->volume.v_cdb);
+ if (vol->vol->v_cdb)
+ cnid_close(vol->vol->v_cdb);
memset(vol, 0, sizeof(afpvol_t));
}
/*
Taken form afpd/desktop.c
*/
-char *utompath(const struct volinfo *volinfo, const char *upath)
+char *utompath(const struct vol *vol, const char *upath)
{
static char mpath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */
char *m;
u = upath;
outlen = strlen(upath);
- if ((volinfo->v_casefold & AFPVOL_UTOMUPPER))
+ if ((vol->v_casefold & AFPVOL_UTOMUPPER))
flags |= CONV_TOUPPER;
- else if ((volinfo->v_casefold & AFPVOL_UTOMLOWER))
+ else if ((vol->v_casefold & AFPVOL_UTOMLOWER))
flags |= CONV_TOLOWER;
- if ((volinfo->v_flags & AFPVOL_EILSEQ)) {
+ if ((vol->v_flags & AFPVOL_EILSEQ)) {
flags |= CONV__EILSEQ;
}
/* convert charsets */
- if ((size_t)-1 == ( outlen = convert_charset(volinfo->v_volcharset,
+ if ((size_t)-1 == ( outlen = convert_charset(vol->v_volcharset,
CH_UTF8_MAC,
- volinfo->v_maccharset,
+ vol->v_maccharset,
u, outlen, mpath, MAXPATHLEN, &flags)) ) {
SLOG("Conversion from %s to %s for %s failed.",
- volinfo->v_volcodepage, volinfo->v_maccodepage, u);
+ vol->v_volcodepage, vol->v_maccodepage, u);
return NULL;
}
int pos = bname - path;
uint16_t flags = 0;
- if ( ! svol->volinfo.v_path) {
+ if ( ! svol->vol->v_path) {
/* no source volume: escape special chars (eg ':') */
- from = dvol->volinfo.v_volcharset; /* src = dst charset */
+ from = dvol->vol->v_volcharset; /* src = dst charset */
flags |= CONV_ESCAPEHEX;
} else {
- from = svol->volinfo.v_volcharset;
+ from = svol->vol->v_volcharset;
}
- if ( (svol->volinfo.v_path)
- && ! (svol->volinfo.v_flags & AFPVOL_USEDOTS)
- && (dvol->volinfo.v_flags & AFPVOL_USEDOTS)) {
+ if ( (svol->vol->v_path)
+ && ! (svol->vol->v_flags & AFPVOL_USEDOTS)
+ && (dvol->vol->v_flags & AFPVOL_USEDOTS)) {
/* source is without dots, destination is with */
flags |= CONV_UNESCAPEHEX;
- } else if (! (dvol->volinfo.v_flags & AFPVOL_USEDOTS)) {
+ } else if (! (dvol->vol->v_flags & AFPVOL_USEDOTS)) {
flags |= CONV_ESCAPEDOTS;
}
int len = convert_charset(from,
- dvol->volinfo.v_volcharset,
- dvol->volinfo.v_maccharset,
+ dvol->vol->v_volcharset,
+ dvol->vol->v_maccharset,
bname, strlen(bname),
buf, MAXPATHLEN,
&flags);
cnid = htonl(2);
- EC_NULL(rpath = rel_path_in_vol(path, vol->volinfo.v_path));
- EC_NULL(statpath = bfromcstr(vol->volinfo.v_path));
+ EC_NULL(rpath = rel_path_in_vol(path, vol->vol->v_path));
+ EC_NULL(statpath = bfromcstr(vol->vol->v_path));
EC_ZERO(bcatcstr(statpath, "/"));
l = bsplit(rpath, '/');
cfrombstr(rpath), cfrombstr(l->entry[i]),
cfrombstr(statpath), strerror(errno));
- if ((cnid = cnid_add(vol->volume.v_cdb,
+ if ((cnid = cnid_add(vol->vol->v_cdb,
&st,
*did,
cfrombstr(l->entry[i]),
*did = htonl(1);
cnid = htonl(2);
- EC_NULL(rpath = rel_path_in_vol(path, vol->volinfo.v_path));
- EC_NULL(statpath = bfromcstr(vol->volinfo.v_path));
+ EC_NULL(rpath = rel_path_in_vol(path, vol->vol->v_path));
+ EC_NULL(statpath = bfromcstr(vol->vol->v_path));
l = bsplit(rpath, '/');
if (l->qty == 1)
cfrombstr(rpath), cfrombstr(l->entry[i]),
cfrombstr(statpath), strerror(errno));
- if ((cnid = cnid_add(vol->volume.v_cdb,
+ if ((cnid = cnid_add(vol->vol->v_cdb,
&st,
*did,
cfrombstr(l->entry[i]),
#include <atalk/util.h>
#include <atalk/dsi.h>
#include <atalk/unicode.h>
+#include <atalk/netatalk_conf.h>
#include "afp_avahi.h"
#include "afp_config.h"
#include <atalk/server_child.h>
#include <atalk/globals.h>
#include <atalk/errchk.h>
+#include <atalk/netatalk_conf.h>
+#include <atalk/fce_api.h>
#ifdef HAVE_LDAP
#include <atalk/ldapconfig.h>
EC_INIT;
DSI *dsi, **next = &obj->dsi;
char *p = NULL, *q = NULL;
+ const char *r;
auth_load(obj->options.uampath, obj->options.uamlist);
set_signature(&obj->options);
/* Now register with zeroconf, we also need the volumes for that */
if (! (obj->options.flags & OPTION_NOZEROCONF)) {
- load_volumes(obj);
+ load_volumes(obj, NULL);
zeroconf_register(obj);
}
- if ((p = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fcelistener", NULL))) {
- LOG(log_note, logtype_afpd, "Adding FCE listener: %s", p);
- fce_add_udp_socket(p);
+ if ((r = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fcelistener", NULL))) {
+ LOG(log_note, logtype_afpd, "Adding FCE listener: %s", r);
+ fce_add_udp_socket(r);
}
- if ((p = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fcecoalesce", NULL))) {
- LOG(log_note, logtype_afpd, "Fce coalesce: %s", p);
- fce_set_coalesce(p);
+ if ((r = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fcecoalesce", NULL))) {
+ LOG(log_note, logtype_afpd, "Fce coalesce: %s", r);
+ fce_set_coalesce(r);
}
- if ((p = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fceevents", NULL))) {
- LOG(log_note, logtype_afpd, "Fce events: %s", p);
- fce_set_events(p);
+ if ((r = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fceevents", NULL))) {
+ LOG(log_note, logtype_afpd, "Fce events: %s", r);
+ fce_set_events(r);
}
#include "acls.h"
#endif
-int afp_version = 11;
static int afp_version_index;
static struct uam_mod uam_modules = {NULL, NULL, &uam_modules, &uam_modules};
static struct uam_obj uam_login = {"", "", 0, {{NULL, NULL, NULL, NULL }}, &uam_login,
return( AFPERR_NOOP );
}
-static int set_auth_switch(int expired)
+static int set_auth_switch(const AFPObj *obj, int expired)
{
int i;
}
else {
afp_switch = postauth_switch;
- switch (afp_version) {
+ switch (obj->afp_version) {
case 33:
case 32:
#endif /* ADMIN_GRP */
obj->uid = geteuid();
- set_auth_switch(expired);
+ set_auth_switch(obj, expired);
/* save our euid, we need it for preexec_close */
obj->uid = geteuid();
obj->logout = logout;
num = sizeof( afp_versions ) / sizeof( afp_versions[ 0 ]);
for ( i = 0; i < num; i++ ) {
if ( strncmp( ibuf, afp_versions[ i ].av_name , len ) == 0 ) {
- afp_version = afp_versions[ i ].av_number;
+ obj->afp_version = afp_versions[ i ].av_number;
afp_version_index = i;
break;
}
return AFPERR_BADVERS ;
/* FIXME Hack */
- if (afp_version >= 30 && sizeof(off_t) != 8) {
+ if (obj->afp_version >= 30 && sizeof(off_t) != 8) {
LOG(log_error, logtype_afpd, "get_version: no LARGE_FILE support recompile!" );
return AFPERR_BADVERS ;
}
if ((len + 1) & 1) /* pad byte */
ibuf++;
- if ( afp_version < 30) {
+ if (obj->afp_version < 30) {
len = (unsigned char) *ibuf++;
if ( len > sizeof(username) - 1) {
return AFPERR_PARAM;
(ret == AFPERR_AUTHCONT) ? "continued" :
(ret ? "failed" : "succeeded"));
if ( ret == AFP_OK )
- set_auth_switch(0);
+ set_auth_switch(obj, 0);
return ret;
}
* An other option would be to call get_id in utompath but
* we need to pass parent dir
*/
- if (!(path->m_name = utompath(vol, path->u_name, 0 , utf8_encoding()) )) {
+ if (!(path->m_name = utompath(vol, path->u_name, 0 , utf8_encoding(vol->v_obj)) )) {
/*retry with the right id */
cnid_t id;
}
/* save the id for getfilparm */
path->id = id;
- if (!(path->m_name = utompath(vol, path->u_name, id , utf8_encoding()))) {
+ if (!(path->m_name = utompath(vol, path->u_name, id , utf8_encoding(vol->v_obj)))) {
return 0;
}
}
memset(&path, 0, sizeof(path));
path.u_name = name;
- path.m_name = utompath(vol, name, cnid, utf8_encoding());
+ path.m_name = utompath(vol, name, cnid, utf8_encoding(vol->v_obj));
if (of_stat(&path) != 0) {
switch (errno) {
memcpy (c1.utf8name, spec1+2, namelen);
c1.utf8name[namelen] = 0;
- if ((uname = mtoupath(vol, c1.utf8name, 0, utf8_encoding())) == NULL)
+ if ((uname = mtoupath(vol, c1.utf8name, 0, utf8_encoding(obj))) == NULL)
return AFPERR_PARAM;
/* convert charset */
char *t;
cnid_t fileid = 0;
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
if (toUTF8) {
if (dir->d_did == DIRDID_ROOT_PARENT) {
/*
/* duplicate work but we can't reuse all convert_char we did in demangle_osx
* flags weren't the same
*/
- if ( (t = utompath(vol, ret->u_name, fileid, utf8_encoding())) ) {
+ if ( (t = utompath(vol, ret->u_name, fileid, utf8_encoding(vol->v_obj))) ) {
/* at last got our view of mac name */
strcpy(ret->m_name, t);
}
/* If we haven't got it by now, get it */
if (ret->u_name == NULL) {
- if ((ret->u_name = mtoupath(vol, ret->m_name, dir->d_did, utf8_encoding())) == NULL) {
+ if ((ret->u_name = mtoupath(vol, ret->m_name, dir->d_did, utf8_encoding(vol->v_obj))) == NULL) {
afp_errno = AFPERR_PARAM;
return -1;
}
goto exit;
}
- utf8 = utf8_encoding();
+ utf8 = utf8_encoding(vol->v_obj);
maxpath = (utf8) ? MAXPATHLEN - 7 : 255;
/* Get it from the database */
return NULL;
}
- if (convert_string_allocate( (utf8_encoding()) ? CH_UTF8_MAC : vol->v_maccharset,
+ if (convert_string_allocate( (utf8_encoding(vol->v_obj)) ? CH_UTF8_MAC : vol->v_maccharset,
CH_UCS2,
m_name,
-1, (char **)&dir->d_m_name_ucs2) == (size_t)-1 ) {
/* Get macname from unixname */
if (path->m_name == NULL) {
- if ((path->m_name = utompath(vol, path->u_name, id, utf8_encoding())) == NULL) {
+ if ((path->m_name = utompath(vol, path->u_name, id, utf8_encoding(vol->v_obj))) == NULL) {
LOG(log_error, logtype_afpd, "dir_add(\"%s\"): can't assign macname", path->u_name);
err = 2;
goto exit;
data++;
len = (unsigned char) *data++;
size = 2;
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
ret.m_type = 3;
toUTF8 = 1;
}
break;
case 3:
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
data++;
memcpy(&hint, data, sizeof(hint));
hint = ntohl(hint);
if ((s_path->m_name = utompath(vol,
upath,
dir->d_did,
- utf8_encoding())) == NULL) {
+ utf8_encoding(obj))) == NULL) {
LOG(log_error, logtype_afpd,
"getdirparams(\"%s\"): can't assign macname",
cfrombstr(dir->d_fullpath));
Just pass back the same basic block for all
directories. <shirsch@ibm.net> */
case DIRPBIT_PDINFO :
- if (afp_version >= 30) { /* UTF8 name */
+ if (obj->afp_version >= 30) { /* UTF8 name */
utf8 = kTextEncodingUTF8;
if (dir->d_m_name) /* root of parent can have a null name */
utf_nameoff = data;
ProDOS information block. Skip over the data and
report nothing amiss. <shirsch@ibm.net> */
case DIRPBIT_PDINFO :
- if (afp_version < 30) {
+ if (vol->v_obj->afp_version < 30) {
buf += 6;
}
else {
case DIRPBIT_ACCESS :
break;
case DIRPBIT_PDINFO :
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
err = AFPERR_BITMAP;
goto setdirparam_done;
}
*rbuflen = 0;
if (sfunc >= 3 && sfunc <= 6) {
- if (afp_version < 30) {
+ if (obj->afp_version < 30) {
return( AFPERR_PARAM );
}
utf8 = 1;
case 5 : /* UUID -> username */
case 6 : /* UUID -> groupname */
- if ((afp_version < 32) || !(obj->options.flags & OPTION_UUID ))
+ if ((obj->afp_version < 32) || !(obj->options.flags & OPTION_UUID ))
return AFPERR_PARAM;
LOG(log_debug, logtype_afpd, "afp_mapid: valid UUID request");
uuidtype_t type;
return( AFP_OK );
}
-int afp_mapname(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
+int afp_mapname(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
{
struct passwd *pw;
struct group *gr;
ibuf++;
sfunc = (unsigned char) *ibuf++;
*rbuflen = 0;
- LOG(log_debug, logtype_afpd, "afp_mapname: sfunc: %d, afp_version: %d", sfunc, afp_version);
+ LOG(log_debug, logtype_afpd, "afp_mapname: sfunc: %d", sfunc);
switch ( sfunc ) {
case 1 :
case 2 : /* unicode */
- if (afp_version < 30) {
+ if (obj->afp_version < 30) {
return( AFPERR_PARAM );
}
memcpy(&ulen, ibuf, sizeof(ulen));
break;
case 5 : /* username -> UUID */
case 6 : /* groupname -> UUID */
- if ((afp_version < 32) || !(obj->options.flags & OPTION_UUID ))
+ if ((obj->afp_version < 32) || !(obj->options.flags & OPTION_UUID ))
return AFPERR_PARAM;
memcpy(&ulen, ibuf, sizeof(ulen));
len = ntohs(ulen);
#include <atalk/logger.h>
#include <atalk/ea.h>
#include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
#include "volume.h"
#include "desktop.h"
vol = ofork->of_vol;
- if (NULL == (u_name = mtoupath(vol, of_name(ofork), ofork->of_did, utf8_encoding())))
+ if (NULL == (u_name = mtoupath(vol, of_name(ofork), ofork->of_did, utf8_encoding(vol->v_obj))))
{
return AFPERR_MISC;
}
if (!utf8) {
/* want mac name */
- if (utf8_encoding()) {
+ if (utf8_encoding(vol->v_obj)) {
/* but name is an utf8 mac name */
char *u, *m;
data = buf;
if ( ((bitmap & ( (1 << FILPBIT_FINFO)|(1 << FILPBIT_LNAME)|(1 <<FILPBIT_PDINFO) ) ) && !path->m_name)
- || (bitmap & ( (1 << FILPBIT_LNAME) ) && utf8_encoding()) /* FIXME should be m_name utf8 filename */
+ || (bitmap & ( (1 << FILPBIT_LNAME) ) && utf8_encoding(obj)) /* FIXME should be m_name utf8 filename */
|| (bitmap & (1 << FILPBIT_FNUM))) {
if (!path->id) {
bstring fullpath;
/* Get macname from unixname first */
if (path->m_name == NULL) {
- if ((path->m_name = utompath(vol, upath, id, utf8_encoding())) == NULL) {
+ if ((path->m_name = utompath(vol, upath, id, utf8_encoding(obj))) == NULL) {
LOG(log_error, logtype_afpd, "getmetadata: utompath error");
return AFPERR_MISC;
}
return afp_errno;
if (!path->m_name) {
- path->m_name = utompath(vol, upath, id, utf8_encoding());
+ path->m_name = utompath(vol, upath, id, utf8_encoding(vol->v_obj));
}
}
while ( bitmap != 0 ) {
to "pXYZ" when we created it. See IA, Ver 2.
<shirsch@adelphia.net> */
case FILPBIT_PDINFO :
- if (afp_version >= 30) { /* UTF8 name */
+ if (obj->afp_version >= 30) { /* UTF8 name */
utf8 = kTextEncodingUTF8;
utf_nameoff = data;
data += sizeof( uint16_t );
}
break;
case FILPBIT_PDINFO :
- if (afp_version < 30) { /* else it's UTF8 name */
+ if (obj->afp_version < 30) { /* else it's UTF8 name */
achar = *buf;
buf += 2;
/* Keep special case to support crlf translations */
}
break;
case FILPBIT_PDINFO :
- if (afp_version < 30) { /* else it's UTF8 name */
+ if (obj->afp_version < 30) { /* else it's UTF8 name */
memcpy(ad_entry( adp, ADEID_FINDERI ), fdType, 4 );
memcpy(ad_entry( adp, ADEID_FINDERI ) + 4, "pdos", 4 );
break;
uint16_t len16;
uint32_t hint;
- if ( type != 2 && !(afp_version >= 30 && type == 3) ) {
+ if ( type != 2 && !(vol->v_obj->afp_version >= 30 && type == 3) ) {
return -1;
}
ibuf++;
switch (type) {
case 2:
if (( plen = (unsigned char)*ibuf++ ) != 0 ) {
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
/* convert it to UTF8
*/
if ((plen = mtoUTF8(vol, ibuf, plen, newname, AFPOBJ_TMPSIZ)) == (size_t)-1)
/* newname is always only a filename so curdir *is* its
* parent folder
*/
- if (NULL == (upath = mtoupath(d_vol, newname, curdir->d_did, utf8_encoding()))) {
+ if (NULL == (upath = mtoupath(d_vol, newname, curdir->d_did, utf8_encoding(d_vol->v_obj)))) {
retvalue =AFPERR_PARAM;
goto copy_exit;
}
/* ------------------------------
resolve a file id */
-int afp_resolveid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
+int afp_resolveid(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
{
struct vol *vol;
struct dir *dir;
/* directories are bad */
if (S_ISDIR(path.st.st_mode)) {
/* OS9 and OSX don't return the same error code */
- return (afp_version >=30)?AFPERR_NOID:AFPERR_BADTYPE;
+ return (obj->afp_version >=30)?AFPERR_NOID:AFPERR_BADTYPE;
}
memcpy(&bitmap, ibuf, sizeof(bitmap));
bitmap = ntohs( bitmap );
- if (NULL == (path.m_name = utompath(vol, upath, cnid, utf8_encoding()))) {
+ if (NULL == (path.m_name = utompath(vol, upath, cnid, utf8_encoding(obj)))) {
return AFPERR_NOID;
}
path.id = cnid;
adflags = 0;
if (!isdir) {
- if ((oldunixname = strdup(mtoupath(vol, oldname, sdir->d_did, utf8_encoding()))) == NULL)
+ if ((oldunixname = strdup(mtoupath(vol, oldname, sdir->d_did, utf8_encoding(vol->v_obj)))) == NULL)
return AFPERR_PARAM; /* can't convert */
id = cnid_get(vol->v_cdb, sdir->d_did, oldunixname, strlen(oldunixname));
}
}
- if (NULL == (upath = mtoupath(vol, newname, curdir->d_did, utf8_encoding()))){
+ if (NULL == (upath = mtoupath(vol, newname, curdir->d_did, utf8_encoding(vol->v_obj)))){
rc = AFPERR_PARAM;
goto exit;
}
{
if (vol == NULL || dir == NULL || name == NULL)
return NULL;
- return absupath(vol, dir, mtoupath(vol, name, dir->d_did, utf8_encoding()));
+ return absupath(vol, dir, mtoupath(vol, name, dir->d_did, utf8_encoding(vol->v_obj)));
}
/* ------------------------- */
rc = moveandrename(vol, sdir, sdir_fd, oldname, newname, isdir);
if ( rc == AFP_OK ) {
- char *upath = mtoupath(vol, newname, pdid, utf8_encoding());
+ char *upath = mtoupath(vol, newname, pdid, utf8_encoding(obj));
if (NULL == upath) {
rc = AFPERR_PARAM;
vol = ofork->of_vol;
dir = dirlookup(vol, ofork->of_did);
- if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding()))) {
+ if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding(obj)))) {
return( AFPERR_MISC );
}
path.m_name = of_name(ofork);
return ret;
}
-int afp_setforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen, char *rbuf _U_, size_t *rbuflen)
+int afp_setforkparams(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf _U_, size_t *rbuflen)
{
struct ofork *ofork;
off_t size;
is64 = 0;
if ((bitmap & ( (1<<FILPBIT_EXTDFLEN) | (1<<FILPBIT_EXTRFLEN) ))) {
- if (afp_version >= 30) {
+ if (obj->afp_version >= 30) {
is64 = 4;
}
else
}
if (!osx) {
/* convert back to mac name and check it's the same */
- t = utompath(vol, u_name, file_id, utf8_encoding());
+ t = utompath(vol, u_name, file_id, utf8_encoding(vol->v_obj));
if (!strcmp(t, mfilename)) {
return u_name;
}
#include <atalk/afp.h>
#include <atalk/util.h>
#include <atalk/globals.h>
+#include <atalk/volume.h>
#include "afp_config.h"
#include "auth.h"
#include "uam_auth.h"
-#define utf8_encoding() (afp_version >= 30)
-
#ifdef TRU64
#include <netdb.h>
#include <sia.h>
}
#ifndef NO_REAL_USER_NAME
- if ( (size_t) -1 == (namelen = convert_string((utf8_encoding())?CH_UTF8_MAC:obj->options.maccharset,
+ if ( (size_t) -1 == (namelen = convert_string((utf8_encoding(obj))?CH_UTF8_MAC:obj->options.maccharset,
CH_UCS2, name, -1, username, sizeof(username))))
return NULL;
spaceflag = AFPVOL_GVSMASK & vol->v_flags;
/* report up to 2GB if afp version is < 2.2 (4GB if not) */
- maxsize = (afp_version < 22) ? 0x7fffffffL : 0xffffffffL;
+ maxsize = (obj->afp_version < 22) ? 0x7fffffffL : 0xffffffffL;
#ifdef AFS
if ( spaceflag == AFPVOL_NONE || spaceflag == AFPVOL_AFSGVS ) {
ashort |= VOLPBIT_ATTR_RO;
}
/* prior 2.1 only VOLPBIT_ATTR_RO is defined */
- if (afp_version > 20) {
+ if (obj->afp_version > 20) {
if (vol->v_cdb != NULL && (vol->v_cdb->flags & CNID_FLAG_PERSISTENT))
ashort |= VOLPBIT_ATTR_FILEID;
ashort |= VOLPBIT_ATTR_CATSEARCH;
- if (afp_version >= 30) {
+ if (obj->afp_version >= 30) {
ashort |= VOLPBIT_ATTR_UTF8;
if (vol->v_flags & AFPVOL_UNIX_PRIV)
ashort |= VOLPBIT_ATTR_UNIXPRIV;
ashort |= VOLPBIT_ATTR_TM;
if (vol->v_flags & AFPVOL_NONETIDS)
ashort |= VOLPBIT_ATTR_NONETIDS;
- if (afp_version >= 32) {
+ if (obj->afp_version >= 32) {
if (vol->v_vfs_ea)
ashort |= VOLPBIT_ATTR_EXT_ATTRS;
if (vol->v_flags & AFPVOL_ACLS)
continue; /* config file changed but the volume was mounted */
}
- if (utf8_encoding()) {
+ if (utf8_encoding(obj)) {
len = ucs2_to_charset_allocate(CH_UTF8_MAC, &namebuf, volume->v_u8mname);
} else {
len = ucs2_to_charset_allocate(obj->options.maccharset, &namebuf, volume->v_macname);
if ((volname_tmp = strchr(volname,'+')) != NULL)
volname = volname_tmp+1;
- if (utf8_encoding()) {
+ if (utf8_encoding(obj)) {
namelen = convert_string(CH_UTF8_MAC, CH_UCS2, ibuf, len, volname, sizeof(obj->oldtmp));
} else {
namelen = convert_string(obj->options.maccharset, CH_UCS2, ibuf, len, volname, sizeof(obj->oldtmp));
/* initialize volume variables
* FIXME file size
*/
- if (utf8_encoding()) {
+ if (utf8_encoding(obj)) {
volume->max_filename = UTF8FILELEN_EARLY;
}
else {
volume->v_flags |= AFPVOL_OPEN;
volume->v_cdb = NULL;
- if (utf8_encoding()) {
+ if (utf8_encoding(obj)) {
len = convert_string_allocate(CH_UCS2, CH_UTF8_MAC, volume->v_u8mname, namelen, &vol_mname);
} else {
len = convert_string_allocate(CH_UCS2, obj->options.maccharset, volume->v_macname, namelen, &vol_mname);
struct timeval tv;
struct stat st;
- if (!(afp_version > 21 && obj->options.flags & OPTION_SERVERNOTIF))
+ if (!(obj->afp_version > 21 && obj->options.flags & OPTION_SERVERNOTIF))
return 0;
if ( gettimeofday( &tv, NULL ) < 0 )
/* or finder doesn't update free space
* AFP 3.2 and above clients seem to be ok without so many notification
*/
- if (afp_version < 32 && obj->options.flags & OPTION_SERVERNOTIF) {
+ if (obj->afp_version < 32 && obj->options.flags & OPTION_SERVERNOTIF) {
obj->attention(obj->dsi, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED);
}
}
#include <atalk/logger.h>
#include <atalk/cnid_dbd_private.h>
-#include <atalk/volinfo.h>
+#include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
#include <atalk/util.h>
#include "cmd_dbd.h"
#include "dbd.h"
#include "dbif.h"
#include "db_param.h"
+#include "pack.h"
#define DBOPTIONS (DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN)
int nocniddb = 0; /* Dont open CNID database, only scan filesystem */
-struct volinfo volinfo; /* needed by pack.c:idxname() */
volatile sig_atomic_t alarmed; /* flags for signals */
int db_locked; /* have we got the fcntl lock on lockfile ? */
static void usage (void)
{
printf("dbd (Netatalk %s)\n"
- "Usage: dbd [-e|-t|-v|-x] -d [-i] | -s [-c|-n]| -r [-c|-f] | -u <path to netatalk volume>\n"
+ "Usage: dbd [-etvxF] -d [-i] | -s [-c|-n]| -r [-c|-f] | -u <path to netatalk volume>\n"
"dbd can dump, scan, reindex and rebuild Netatalk dbd CNID databases.\n"
"dbd must be run with appropiate permissions i.e. as root.\n\n"
"Main commands are:\n"
" Opens the database which triggers any necessary upgrades,\n"
" then closes and exits.\n\n"
"General options:\n"
+ " -F location of the afp.conf config file\n"
" -e only work on inactive volumes and lock them (exclusive)\n"
" -x rebuild indexes (just for completeness, mostly useless!)\n"
" -t show statistics while running\n"
dbd_flags_t flags = 0;
char *volpath;
int cdir;
+ AFPObj obj = { 0 };
+ struct vol *vol;
if (geteuid() != 0) {
usage();
/* Inhereting perms in ad_mkdir etc requires this */
ad_setfuid(0);
- while ((c = getopt(argc, argv, ":cdefinrstuvx")) != -1) {
+ while ((c = getopt(argc, argv, ":cdefFinrstuvx")) != -1) {
switch(c) {
case 'c':
flags |= DBD_FLAGS_CLEANUP;
exclusive = 1;
flags |= DBD_FLAGS_FORCE | DBD_FLAGS_EXCL;
break;
+ case 'F':
+ obj.cmdlineconfigfile = strdup(optarg);
+ break;
case ':':
case '?':
usage();
else
setuplog("default:debug", "/dev/tty");
- /* Load .volinfo file */
- if (loadvolinfo(volpath, &volinfo) == -1) {
- dbd_log( LOGSTD, "Not a Netatalk volume at '%s', no .volinfo file at '%s/.AppleDesktop/.volinfo' or unknown volume options", volpath, volpath);
+ /* Load config */
+ if (afp_config_parse(&obj) != 0) {
+ dbd_log( LOGSTD, "Couldn't load afp.conf");
+ exit(EXIT_FAILURE);
+ }
+
+ if (load_volumes(&obj, NULL) != 0) {
+ dbd_log( LOGSTD, "Couldn't load volumes");
exit(EXIT_FAILURE);
}
- if (vol_load_charsets(&volinfo) == -1) {
- dbd_log( LOGSTD, "Error loading charsets!");
+
+ if ((vol = getvolbypath(volpath)) == NULL) {
+ dbd_log( LOGSTD, "Couldn't find volume for '%s'", volpath);
exit(EXIT_FAILURE);
}
+ pack_setvol(vol);
- if (volinfo.v_adouble == AD_VERSION_EA)
+ if (vol->v_adouble == AD_VERSION_EA)
dbd_log( LOGDEBUG, "adouble:ea volume");
- else if (volinfo.v_adouble == AD_VERSION2)
+ else if (vol->v_adouble == AD_VERSION2)
dbd_log( LOGDEBUG, "adouble:v2 volume");
else {
dbd_log( LOGSTD, "unknown adouble volume");
}
/* Sanity checks to ensure we can touch this volume */
- if (volinfo.v_vfs_ea != AFPVOL_EA_AD && volinfo.v_vfs_ea != AFPVOL_EA_SYS) {
- dbd_log( LOGSTD, "Unknown Extended Attributes option: %u", volinfo.v_vfs_ea);
+ if (vol->v_vfs_ea != AFPVOL_EA_AD && vol->v_vfs_ea != AFPVOL_EA_SYS) {
+ dbd_log( LOGSTD, "Unknown Extended Attributes option: %u", vol->v_vfs_ea);
exit(EXIT_FAILURE);
}
/* Enuser dbpath is there, create if necessary */
struct stat st;
- if (stat(volinfo.v_dbpath, &st) != 0) {
+ if (stat(vol->v_dbpath, &st) != 0) {
if (errno != ENOENT) {
- dbd_log( LOGSTD, "Can't stat dbpath \"%s\": %s", volinfo.v_dbpath, strerror(errno));
+ dbd_log( LOGSTD, "Can't stat dbpath \"%s\": %s", vol->v_dbpath, strerror(errno));
exit(EXIT_FAILURE);
}
- if ((mkdir(volinfo.v_dbpath, 0755)) != 0) {
- dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", dbpath, strerror(errno));
+ if ((mkdir(vol->v_dbpath, 0755)) != 0) {
+ dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", vol->v_dbpath, strerror(errno));
exit(EXIT_FAILURE);
}
}
/* Put "/.AppleDB" at end of volpath, get path from volinfo file */
- if ( (strlen(volinfo.v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) {
+ if ( (strlen(vol->v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) {
dbd_log( LOGSTD, "Volume pathname too long");
exit(EXIT_FAILURE);
}
- strncpy(dbpath, volinfo.v_dbpath, MAXPATHLEN - strlen("/.AppleDB"));
+ strncpy(dbpath, vol->v_dbpath, MAXPATHLEN - strlen("/.AppleDB"));
strcat(dbpath, "/.AppleDB");
/* Check or create dbpath */
dbd_log( LOGSTD, "Error dumping database");
}
} else if ((rebuild && ! nocniddb) || scan) {
- if (cmd_dbd_scanvol(dbd, &volinfo, flags) < 0) {
+ if (cmd_dbd_scanvol(dbd, vol, flags) < 0) {
dbd_log( LOGSTD, "Error repairing database.");
}
}
#include <signal.h>
#include <limits.h>
-#include <atalk/volinfo.h>
+#include <atalk/netatalk_conf.h>
#include "dbif.h"
enum logtype {LOGSTD, LOGDEBUG};
extern volatile sig_atomic_t alarmed;
extern void dbd_log(enum logtype lt, char *fmt, ...);
-extern int cmd_dbd_scanvol(DBD *dbd, struct volinfo *volinfo, dbd_flags_t flags);
+extern int cmd_dbd_scanvol(DBD *dbd, struct vol *vol, dbd_flags_t flags);
/*
Functions for querying the database which couldn't be reused from the existing
#include <atalk/adouble.h>
#include <atalk/unicode.h>
-#include <atalk/volinfo.h>
+#include <atalk/netatalk_conf.h>
#include <atalk/cnid_dbd_private.h>
#include <atalk/volume.h>
#include <atalk/ea.h>
#define ADFILE_OK (adfile_ok == 0)
-static struct volinfo *myvolinfo;
+static struct vol *myvol;
static char cwdbuf[MAXPATHLEN+1];
static DBD *dbd;
static DBD *dbd_rebuild;
static struct cnid_dbd_rqst rqst;
static struct cnid_dbd_rply rply;
static jmp_buf jmp;
-static struct vol volume; /* fake it for ea_open */
static char pname[MAXPATHLEN] = "../";
/*
u = upath;
outlen = strlen(upath);
- if ((myvolinfo->v_casefold & AFPVOL_UTOMUPPER))
+ if ((myvol->v_casefold & AFPVOL_UTOMUPPER))
flags |= CONV_TOUPPER;
- else if ((myvolinfo->v_casefold & AFPVOL_UTOMLOWER))
+ else if ((myvol->v_casefold & AFPVOL_UTOMLOWER))
flags |= CONV_TOLOWER;
- if ((myvolinfo->v_flags & AFPVOL_EILSEQ)) {
+ if ((myvol->v_flags & AFPVOL_EILSEQ)) {
flags |= CONV__EILSEQ;
}
/* convert charsets */
- if ((size_t)-1 == ( outlen = convert_charset(myvolinfo->v_volcharset,
+ if ((size_t)-1 == ( outlen = convert_charset(myvol->v_volcharset,
CH_UTF8_MAC,
- myvolinfo->v_maccharset,
+ myvol->v_maccharset,
u, outlen, mpath, MAXPATHLEN, &flags)) ) {
dbd_log( LOGSTD, "Conversion from %s to %s for %s failed.",
- myvolinfo->v_volcodepage, myvolinfo->v_maccodepage, u);
+ myvol->v_volcodepage, myvol->v_maccodepage, u);
return NULL;
}
}
/* set conversion flags */
- if (!(myvolinfo->v_flags & AFPVOL_NOHEX))
+ if (!(myvol->v_flags & AFPVOL_NOHEX))
flags |= CONV_ESCAPEHEX;
- if (!(myvolinfo->v_flags & AFPVOL_USEDOTS))
+ if (!(myvol->v_flags & AFPVOL_USEDOTS))
flags |= CONV_ESCAPEDOTS;
- if ((myvolinfo->v_casefold & AFPVOL_MTOUUPPER))
+ if ((myvol->v_casefold & AFPVOL_MTOUUPPER))
flags |= CONV_TOUPPER;
- else if ((myvolinfo->v_casefold & AFPVOL_MTOULOWER))
+ else if ((myvol->v_casefold & AFPVOL_MTOULOWER))
flags |= CONV_TOLOWER;
- if ((myvolinfo->v_flags & AFPVOL_EILSEQ)) {
+ if ((myvol->v_flags & AFPVOL_EILSEQ)) {
flags |= CONV__EILSEQ;
}
outlen = MAXPATHLEN;
if ((size_t)-1 == (outlen = convert_charset(CH_UTF8_MAC,
- myvolinfo->v_volcharset,
- myvolinfo->v_maccharset,
+ myvol->v_volcharset,
+ myvol->v_maccharset,
m, inplen, u, outlen, &flags)) ) {
dbd_log( LOGSTD, "conversion from UTF8-MAC to %s for %s failed.",
- myvolinfo->v_volcodepage, mpath);
+ myvol->v_volcodepage, mpath);
return NULL;
}
struct adouble ad;
const char *adname;
- if (volume.v_adouble == AD_VERSION_EA)
+ if (myvol->v_adouble == AD_VERSION_EA)
return 0;
if (dbd_flags & DBD_FLAGS_CLEANUP)
if (S_ISREG(st->st_mode))
adflags |= ADFLAGS_DIR;
- adname = volume.ad_path(fname, adflags);
+ adname = myvol->ad_path(fname, adflags);
if ((ret = access( adname, F_OK)) != 0) {
if (errno != ENOENT) {
return -1;
/* Create ad file */
- ad_init(&ad, &volume);
+ ad_init(&ad, myvol);
if ((ret = ad_open(&ad, fname, adflags | ADFLAGS_CREATE | ADFLAGS_RDWR, 0666)) != 0) {
dbd_log( LOGSTD, "Error creating AppleDouble file '%s/%s': %s",
chmod(adname, st->st_mode);
#endif
} else {
- ad_init(&ad, &volume);
+ ad_init(&ad, myvol);
if (ad_open(&ad, fname, adflags | ADFLAGS_RDONLY) != 0) {
dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s'", cwdbuf, fname);
return -1;
struct stat st;
char *eaname;
- if ((ret = ea_open(&volume, fname, EA_RDWR, &ea)) != 0) {
+ if ((ret = ea_open(myvol, fname, EA_RDWR, &ea)) != 0) {
if (errno == ENOENT)
return 0;
dbd_log(LOGSTD, "Error calling ea_open for file: %s/%s, removing EA files", cwdbuf, fname);
if (dbd_flags & DBD_FLAGS_CLEANUP)
return 0;
- if (volume.v_adouble == AD_VERSION_EA)
+ if (myvol->v_adouble == AD_VERSION_EA)
return 0;
/* Check for ad-dir */
}
/* Check for ".Parent" */
- if ( (adpar_ok = access(volume.ad_path(".", ADFLAGS_DIR), F_OK)) != 0) {
+ if ( (adpar_ok = access(myvol->ad_path(".", ADFLAGS_DIR), F_OK)) != 0) {
if (errno != ENOENT) {
dbd_log(LOGSTD, "Access error on '%s/%s': %s",
- cwdbuf, volume.ad_path(".", ADFLAGS_DIR), strerror(errno));
+ cwdbuf, myvol->ad_path(".", ADFLAGS_DIR), strerror(errno));
return -1;
}
dbd_log(LOGSTD, "Missing .AppleDouble/.Parent for '%s'", cwdbuf);
}
/* Create ad dir and set name */
- ad_init(&ad, &volume);
+ ad_init(&ad, myvol);
if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) != 0) {
dbd_log( LOGSTD, "Error creating AppleDouble dir in %s: %s", cwdbuf, strerror(errno));
return -1;
}
chown(ADv2_DIRNAME, st.st_uid, st.st_gid);
- chown(volume.ad_path(".", ADFLAGS_DIR), st.st_uid, st.st_gid);
+ chown(myvol->ad_path(".", ADFLAGS_DIR), st.st_uid, st.st_gid);
}
return 0;
char *namep, *namedup = NULL;
/* Check if this is an AFPVOL_EA_AD vol */
- if (myvolinfo->v_vfs_ea == AFPVOL_EA_AD) {
+ if (myvol->v_vfs_ea == AFPVOL_EA_AD) {
/* Does the filename contain "::EA" ? */
namedup = strdup(name);
if ((namep = strstr(namedup, "::EA")) == NULL) {
struct dirent *ep;
struct stat st;
- if (volume.v_adouble == AD_VERSION_EA)
+ if (myvol->v_adouble == AD_VERSION_EA)
return 0;
if ((chdir(ADv2_DIRNAME)) != 0) {
/* Get CNID from ad-file */
ad_cnid = 0;
if (ADFILE_OK) {
- ad_init(&ad, &volume);
+ ad_init(&ad, myvol);
if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) {
if (dbd_flags & DBD_FLAGS_CLEANUP)
return CNID_INVALID;
- if (volume.v_adouble != AD_VERSION_EA) {
+ if (myvol->v_adouble != AD_VERSION_EA) {
dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno));
return CNID_INVALID;
}
memset(&rply, 0, sizeof(struct cnid_dbd_rply));
rqst.did = did;
rqst.cnid = ad_cnid;
- if ( ! (myvolinfo->v_flags & AFPVOL_NODEV))
+ if ( ! (myvol->v_flags & AFPVOL_NODEV))
rqst.dev = st->st_dev;
rqst.ino = st->st_ino;
rqst.type = S_ISDIR(st->st_mode)?1:0;
if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
dbd_log(LOGSTD, "Updating AppleDouble file for '%s/%s' with CNID: %u from database",
cwdbuf, name, ntohl(db_cnid));
- ad_init(&ad, &volume);
+ ad_init(&ad, myvol);
if (ad_open(&ad, name, adflags | ADFLAGS_HF | ADFLAGS_RDWR) != 0) {
dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s",
cwdbuf, name, strerror(errno));
if (ADFILE_OK && ( ! (dbd_flags & DBD_FLAGS_SCAN))) {
dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file",
cwdbuf, name, ntohl(db_cnid));
- ad_init(&ad, &volume);
+ ad_init(&ad, myvol);
if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) {
dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s",
cwdbuf, name, strerror(errno));
if (ADFILE_OK && ! (dbd_flags & DBD_FLAGS_SCAN)) {
dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file",
cwdbuf, name, ntohl(db_cnid));
- ad_init(&ad, &volume);
+ ad_init(&ad, myvol);
if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) {
dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s",
cwdbuf, name, strerror(errno));
return -1;
/* Check AppleDouble files in AppleDouble folder, but only if it exists or could be created */
- if (volume.v_adouble == AD_VERSION2 && ADDIR_OK)
+ if (myvol->v_adouble == AD_VERSION2 && ADDIR_OK)
if ((read_addir()) != 0)
if ( ! (dbd_flags & DBD_FLAGS_SCAN))
/* Fatal on rebuild run, continue if only scanning ! */
}
/* Check EA files */
- if (myvolinfo->v_vfs_ea == AFPVOL_EA_AD)
+ if (myvol->v_vfs_ea == AFPVOL_EA_AD)
check_eafiles(ep->d_name);
/**************************************************************************
return ret;
}
-static int scanvol(struct volinfo *vi, dbd_flags_t flags)
+static int scanvol(struct vol *vol, dbd_flags_t flags)
{
/* Make this stuff accessible from all funcs easily */
- myvolinfo = vi;
+ myvol = vol;
dbd_flags = flags;
- /* Init a fake struct vol so that we can call ad_init(.., &volume) and initvol_vfs(&volume) */
- volume.v_adouble = vi->v_adouble;
- volume.v_ad_options = vi->v_flags;
- volume.ad_path = vi->ad_path;
- volume.v_vfs_ea = myvolinfo->v_vfs_ea;
- initvol_vfs(&volume);
-
/* Run with umask 0 */
umask(0);
- /* Remove trailing slash from volume, chdir to vol */
- if (myvolinfo->v_path[strlen(myvolinfo->v_path) - 1] == '/')
- myvolinfo->v_path[strlen(myvolinfo->v_path) - 1] = 0;
- strcpy(cwdbuf, myvolinfo->v_path);
- chdir(myvolinfo->v_path);
+ strcpy(cwdbuf, myvol->v_path);
+ chdir(myvol->v_path);
/* Start recursion */
if (dbd_readdir(1, htonl(2)) < 0) /* 2 = volumeroot CNID */
/*
Main func called from cmd_dbd.c
*/
-int cmd_dbd_scanvol(DBD *dbd_ref, struct volinfo *vi, dbd_flags_t flags)
+int cmd_dbd_scanvol(DBD *dbd_ref, struct vol *vol, dbd_flags_t flags)
{
int ret = 0;
struct db_param db_param = { 0 };
dbd = dbd_ref;
/* We only support unicode volumes ! */
- if ( vi->v_volcharset != CH_UTF8) {
- dbd_log( LOGSTD, "Not a Unicode volume: %s, %u != %u", vi->v_volcodepage, vi->v_volcharset, CH_UTF8);
+ if (vol->v_volcharset != CH_UTF8) {
+ dbd_log( LOGSTD, "Not a Unicode volume: %s, %u != %u", vol->v_volcodepage, vol->v_volcharset, CH_UTF8);
return -1;
}
}
/* scanvol */
- if ( (scanvol(vi, flags)) != 0) {
+ if ((scanvol(vol, flags)) != 0) {
ret = -1;
goto exit;
}
#include <atalk/logger.h>
#include <atalk/cnid_dbd_private.h>
#include <atalk/paths.h>
-#include <atalk/volinfo.h>
#include <atalk/compat.h>
+#include <atalk/errchk.h>
+#include <atalk/bstrlib.h>
+#include <atalk/netatalk_conf.h>
+#include <atalk/volume.h>
#include "usockfd.h"
#define DEFAULTPORT "4700"
struct server {
- struct volinfo *volinfo;
+ struct vol *vol;
pid_t pid;
time_t tm; /* When respawned last */
int count; /* Times respawned in the last TESTTIME secondes */
static struct server srv[MAXVOLS];
-/* Default logging config: log to syslog with level log_note */
-static char logconfig[MAXPATHLEN + 21 + 1] = "default log_note";
-
static void daemon_exit(int i)
{
server_unlock(_PATH_CNID_METAD_LOCK);
daemon_exit(0);
}
-static struct server *test_usockfn(struct volinfo *volinfo)
+static struct server *test_usockfn(const struct vol *vol)
{
int i;
+
+ if (!(vol->v_flags & AFPVOL_OPEN))
+ return NULL;
+
for (i = 0; i < maxvol; i++) {
- if ((srv[i].volinfo) && (strcmp(srv[i].volinfo->v_path, volinfo->v_path) == 0)) {
+ if (vol->v_vid == srv[i].vol->v_vid)
return &srv[i];
- }
}
+
return NULL;
}
/* -------------------- */
-static int maybe_start_dbd(char *dbdpn, struct volinfo *volinfo)
+static int maybe_start_dbd(const AFPObj *obj, char *dbdpn, struct vol *vol)
{
pid_t pid;
struct server *up;
time_t t;
char buf1[8];
char buf2[8];
- char *volpath = volinfo->v_path;
+ char *volpath = vol->v_path;
LOG(log_debug, logtype_cnid, "maybe_start_dbd: Volume: \"%s\"", volpath);
- up = test_usockfn(volinfo);
+ up = test_usockfn(vol);
if (up && up->pid) {
/* we already have a process, send our fd */
if (send_fd(up->control_fd, rqstfd) < 0) {
if (!up) {
/* find an empty slot (i < maxvol) or the first free slot (i == maxvol)*/
for (i = 0; i <= maxvol; i++) {
- if (srv[i].volinfo == NULL && i < MAXVOLS) {
+ if (srv[i].vol == NULL && i < MAXVOLS) {
up = &srv[i];
- up->volinfo = volinfo;
- retainvolinfo(volinfo);
+ up->vol = vol;
+ vol->v_flags |= AFPVOL_OPEN;
up->tm = t;
up->count = 0;
if (i == maxvol)
/* there's a pb with the db inform child, it will delete the db */
LOG(log_warning, logtype_cnid,
"Multiple attempts to start CNID db daemon for \"%s\" failed, wiping the slate clean...",
- up->volinfo->v_path);
- ret = execlp(dbdpn, dbdpn, "-d", volpath, buf1, buf2, logconfig, NULL);
+ up->vol->v_path);
+ ret = execlp(dbdpn, dbdpn, "-F", obj->options.configfile, "-p", volpath, "-t", buf1, "-l", buf2, "-d", NULL);
} else {
- ret = execlp(dbdpn, dbdpn, volpath, buf1, buf2, logconfig, NULL);
+ ret = execlp(dbdpn, dbdpn, "-F", obj->options.configfile, "-p", volpath, "-t", buf1, "-l", buf2, NULL);
}
/* Yikes! We're still here, so exec failed... */
LOG(log_error, logtype_cnid, "Fatal error in exec: %s", strerror(errno));
int debug = 0;
int ret;
sigset_t set;
- struct volinfo *volinfo;
-
- set_processname("cnid_metad");
+ AFPObj obj = { 0 };
+ struct vol *vol;
- while (( cc = getopt( argc, argv, "vVds:p:h:u:g:l:f:")) != -1 ) {
+ while (( cc = getopt( argc, argv, "dF:v")) != -1 ) {
switch (cc) {
- case 'v':
- case 'V':
- printf("cnid_metad (Netatalk %s)\n", VERSION);
- return -1;
case 'd':
debug = 1;
break;
- case 'h':
- host = strdup(optarg);
- break;
- case 'u':
- uid = user_to_uid (optarg);
- if (!uid) {
- LOG(log_error, logtype_cnid, "main: bad user %s", optarg);
- err++;
- }
- break;
- case 'g':
- gid =group_to_gid (optarg);
- if (!gid) {
- LOG(log_error, logtype_cnid, "main: bad group %s", optarg);
- err++;
- }
- break;
- case 'p':
- port = strdup(optarg);
- break;
- case 's':
- dbdpn = strdup(optarg);
+ case 'F':
+ obj.cmdlineconfigfile = strdup(optarg);
break;
+ case 'v':
+ printf("cnid_metad (Netatalk %s)\n", VERSION);
+ return -1;
default:
- err++;
- break;
+ printf("cnid_metad [-dv] [-F alternate configfile ]\n");
+ return -1;
}
}
if (create_lockfile("cnid_metad", _PATH_CNID_METAD_LOCK))
return -1;
- setuplog("default:note", NULL);
+ if (afp_config_parse(&obj) != 0)
+ daemon_exit(1);
+
+ set_processname("cnid_metad");
+ setuplog(obj.options.logconfig, obj.options.logfile);
- if (err) {
- LOG(log_error, logtype_cnid, "main: bad arguments");
+ if (load_volumes(&obj, NULL) != 0)
daemon_exit(1);
- }
(void)setlimits();
if (srv[i].pid == pid) {
srv[i].pid = 0;
close(srv[i].control_fd);
+ srv[i].vol->v_flags &= ~AFPVOL_OPEN;
break;
}
}
if (WIFEXITED(status)) {
- LOG(log_info, logtype_cnid, "cnid_dbd pid %i exited with exit code %i",
+ LOG(log_info, logtype_cnid, "cnid_dbd[%i] exited with exit code %i",
pid, WEXITSTATUS(status));
}
else if (WIFSIGNALED(status)) {
- LOG(log_info, logtype_cnid, "cnid_dbd pid %i exited with signal %i",
+ LOG(log_info, logtype_cnid, "cnid_dbd[%i] got signal %i",
pid, WTERMSIG(status));
}
sigchild = 0;
}
volpath[len] = '\0';
- /* Load .volinfo file */
- if ((volinfo = allocvolinfo(volpath)) == NULL) {
- LOG(log_severe, logtype_cnid, "allocvolinfo(\"%s\"): %s",
- volpath, strerror(errno));
+
+ if ((vol = getvolbypath(volpath)) == NULL) {
+ LOG(log_severe, logtype_cnid, "getvolbypath(\"%s\"): %s", volpath, strerror(errno));
goto loop_end;
}
- if (set_dbdir(volinfo->v_dbpath) < 0) {
+ if (set_dbdir(vol->v_dbpath) < 0) {
goto loop_end;
}
- maybe_start_dbd(dbdpn, volinfo);
-
- (void)closevolinfo(volinfo);
-
+ maybe_start_dbd(&obj, dbdpn, vol);
loop_end:
close(rqstfd);
}
#include <atalk/cnid_dbd_private.h>
#include <atalk/logger.h>
-#include <atalk/volinfo.h>
+#include <atalk/errchk.h>
+#include <atalk/bstrlib.h>
+#include <atalk/netatalk_conf.h>
#include "db_param.h"
#include "dbif.h"
#include "dbd.h"
#include "comm.h"
+#include "pack.h"
/*
Note: DB_INIT_LOCK is here so we can run the db_* utilities while netatalk is running.
*/
#define DBOPTIONS (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN)
-/* Global, needed by pack.c:idxname() */
-struct volinfo volinfo;
-
static DBD *dbd;
static int exit_sig = 0;
static int db_locked;
/* ------------------------ */
int main(int argc, char *argv[])
{
+ EC_INIT;
struct db_param *dbp;
- int err = 0, ret, delete_bdb = 0;
- int ctrlfd, clntfd;
+ int delete_bdb = 0;
+ int ctrlfd = -1, clntfd = -1;
char *logconfig;
+ AFPObj obj = { 0 };
+ struct vol *vol;
+ char *volpath = NULL;
+ bstring dbpath;
- set_processname("cnid_dbd");
-
- while (( ret = getopt( argc, argv, "vVd")) != -1 ) {
+ while (( ret = getopt( argc, argv, "dF:l:p:t:v")) != -1 ) {
switch (ret) {
- case 'v':
- case 'V':
- printf("cnid_dbd (Netatalk %s)\n", VERSION);
- return -1;
case 'd':
delete_bdb = 1;
break;
+ case 'F':
+ obj.cmdlineconfigfile = strdup(optarg);
+ break;
+ case 'p':
+ volpath = strdup(optarg);
+ break;
+ case 'l':
+ clntfd = atoi(optarg);
+ break;
+ case 't':
+ ctrlfd = atoi(optarg);
+ break;
+ case 'v':
+ printf("cnid_dbd (Netatalk %s)\n", VERSION);
+ return -1;
}
}
- if (argc - optind != 4) {
- LOG(log_error, logtype_cnid, "main: not enough arguments");
+ if (ctrlfd == -1 || clntfd == -1 || !volpath) {
+ LOG(log_error, logtype_cnid, "main: bad IPC fds");
exit(EXIT_FAILURE);
}
- /* Load .volinfo file */
- if (loadvolinfo(argv[optind], &volinfo) == -1) {
- LOG(log_error, logtype_cnid, "Cant load volinfo for \"%s\"", argv[1]);
- exit(EXIT_FAILURE);
- }
- /* Put "/.AppleDB" at end of volpath, get path from volinfo file */
- char dbpath[MAXPATHLEN+1];
- if ((strlen(volinfo.v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) {
- LOG(log_error, logtype_cnid, "CNID db pathname too long: \"%s\"", volinfo.v_dbpath);
- exit(EXIT_FAILURE);
- }
- strncpy(dbpath, volinfo.v_dbpath, MAXPATHLEN - strlen("/.AppleDB"));
- strcat(dbpath, "/.AppleDB");
+ EC_ZERO( afp_config_parse(&obj) );
- ctrlfd = atoi(argv[optind + 1]);
- clntfd = atoi(argv[optind + 2]);
+ set_processname("cnid_dbd");
+ setuplog(obj.options.logconfig, obj.options.logfile);
- setuplog("default:note", NULL);
+ EC_ZERO( load_volumes(&obj, NULL) );
+ EC_NULL( vol = getvolbypath(volpath) );
- if (vol_load_charsets(&volinfo) == -1) {
- LOG(log_error, logtype_cnid, "Error loading charsets!");
- exit(EXIT_FAILURE);
- }
- LOG(log_debug, logtype_cnid, "db dir: \"%s\"", dbpath);
+ pack_setvol(vol);
+
+ EC_NULL( dbpath = bfromcstr(vol->v_dbpath) );
+ EC_ZERO( bcatcstr(dbpath, "/.AppleDB") );
- switch_to_user(dbpath);
+ LOG(log_debug, logtype_cnid, "db dir: \"%s\"", bdata(dbpath));
+
+ switch_to_user(bdata(dbpath));
/* Get db lock */
- if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1) {
+ if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) == -1) {
LOG(log_error, logtype_cnid, "main: fatal db lock error");
- exit(1);
+ EC_FAIL;
}
if (db_locked != LOCK_EXCL) {
/* Couldn't get exclusive lock, try shared lock */
if ((db_locked = get_lock(LOCK_SHRD, NULL)) != LOCK_SHRD) {
LOG(log_error, logtype_cnid, "main: fatal db lock error");
- exit(1);
+ EC_FAIL;
}
}
if (delete_bdb && (db_locked == LOCK_EXCL)) {
LOG(log_warning, logtype_cnid, "main: too many CNID db opening attempts, wiping the slate clean");
- chdir(dbpath);
+ chdir(bdata(dbpath));
system("rm -f cnid2.db lock log.* __db.*");
- if ((db_locked = get_lock(LOCK_EXCL, dbpath)) != LOCK_EXCL) {
+ if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) {
LOG(log_error, logtype_cnid, "main: fatal db lock error");
- exit(EXIT_FAILURE);
+ EC_FAIL;
}
}
/* SIGINT and SIGTERM are always off, unless we are in pselect */
block_sigs_onoff(1);
- if ((dbp = db_param_read(dbpath)) == NULL)
- exit(1);
+ if ((dbp = db_param_read(bdata(dbpath))) == NULL)
+ EC_FAIL;
LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file");
- if (NULL == (dbd = dbif_init(dbpath, "cnid2.db")))
- exit(2);
+ if (NULL == (dbd = dbif_init(bdata(dbpath), "cnid2.db")))
+ EC_FAIL;
/* Only recover if we got the lock */
if (dbif_env_open(dbd,
dbp,
(db_locked == LOCK_EXCL) ? DBOPTIONS | DB_RECOVER : DBOPTIONS) < 0)
- exit(2); /* FIXME: same exit code as failure for dbif_open() */
+ EC_FAIL;
LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment");
if (dbif_open(dbd, dbp, 0) < 0) {
- dbif_close(dbd);
- exit(2);
+ ret = -1;
+ goto close_db;
}
+
LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases");
/* Downgrade db lock */
if (db_locked == LOCK_EXCL) {
if (get_lock(LOCK_UNLOCK, NULL) != 0) {
- dbif_close(dbd);
- exit(2);
+ ret = -1;
+ goto close_db;
}
+
if (get_lock(LOCK_SHRD, NULL) != LOCK_SHRD) {
- dbif_close(dbd);
- exit(2);
+ ret = -1;
+ goto close_db;
}
}
if (comm_init(dbp, ctrlfd, clntfd) < 0) {
- dbif_close(dbd);
- exit(3);
+ ret = -1;
+ goto close_db;
}
- if (loop(dbp) < 0)
- err++;
+ if (loop(dbp) < 0) {
+ ret = -1;
+ goto close_db;
+ }
+close_db:
if (dbif_close(dbd) < 0)
- err++;
+ ret = -1;
+
+ if (dbif_env_remove(bdata(dbpath)) < 0)
+ ret = -1;
- if (dbif_env_remove(dbpath) < 0)
- err++;
+EC_CLEANUP:
+ if (ret != 0)
+ exit(1);
- if (err)
- exit(4);
- else if (exit_sig)
+ if (exit_sig)
LOG(log_info, logtype_cnid, "main: Exiting on signal %i", exit_sig);
else
LOG(log_info, logtype_cnid, "main: Idle timeout, exiting");
- return 0;
+ EC_EXIT;
}
#include <db.h>
#include <atalk/unicode.h>
-#include <atalk/volinfo.h>
#include <atalk/logger.h>
#include <atalk/cnid_dbd_private.h>
+#include <atalk/volume.h>
#include "pack.h"
-/* in main.c for `cnid_dbd` or cmd_dbd.c for `dbd` */
-extern struct volinfo volinfo;
+static const struct vol *volume;
/* --------------- */
/*
uint16_t flags = CONV_TOLOWER;
memset(skey, 0, sizeof(DBT));
- if (convert_charset(volinfo.v_volcharset,
- volinfo.v_volcharset,
- volinfo.v_maccharset,
+ if (convert_charset(volume->v_volcharset,
+ volume->v_volcharset,
+ volume->v_maccharset,
(char *)pdata->data + CNID_NAME_OFS,
strlen((char *)pdata->data + CNID_NAME_OFS),
buffer,
return (0);
}
+void pack_setvol(const struct vol *vol)
+{
+ volume = vol;
+}
+
/* The equivalent to make_cnid_data in the cnid library. Non re-entrant. We
differ from make_cnid_data in that we never return NULL, rqst->name cannot
ever cause start[] to overflow because name length is checked in libatalk. */
#include <db.h>
#include <atalk/cnid_dbd_private.h>
-#define ntoh64(x) (((uint64_t)(x) << 56) | \
- (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \
- (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \
- (((uint64_t)(x) << 8) & 0xff00000000ULL) | \
- (((uint64_t)(x) >> 8) & 0xff000000ULL) | \
- (((uint64_t)(x) >> 24) & 0xff0000ULL) | \
- (((uint64_t)(x) >> 40) & 0xff00ULL) | \
- ((uint64_t)(x) >> 56))
-
extern unsigned char *pack_cnid_data(struct cnid_dbd_rqst *);
extern int didname(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
extern int devino(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
extern int idxname(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
-
+extern void pack_setvol(const struct vol *vol);
#endif /* CNID_DBD_PACK_H */
#include <atalk/cnid.h>
#include <atalk/bstrlib.h>
#include <atalk/queue.h>
+#include <atalk/unicode.h>
/* setgid directories */
#ifndef DIRBITS
struct session_info sinfo;
uid_t uid; /* client running user id */
int ipc_fd; /* anonymous PF_UNIX socket for IPC with afpd parent */
-
gid_t *groups;
int ngroups;
-
+ int afp_version;
/* Functions */
void (*logout)(void);
void (*exit)(int);
extern void unload_volumes(void);
extern struct vol *getvolumes(void);
extern struct vol *getvolbyvid(const uint16_t);
+extern struct vol *getvolbypath(const char *path);
extern void volume_free(struct vol *vol);
extern void volume_unlink(struct vol *volume);
#endif
#include <atalk/cnid.h>
#include <atalk/hash.h>
#include <atalk/vfs.h>
+#include <atalk/globals.h>
#define AFPVOL_U8MNAMELEN 255 /* AFP3 sepc */
#define AFPVOL_MACNAMELEN 27 /* AFP2 spec */
struct vol {
struct vol *v_next;
+ AFPObj *v_obj;
uint16_t v_vid;
int v_flags;
char *v_path;
#define VOLPBIT_XBTOTAL 10
#define VOLPBIT_BSIZE 11 /* block size */
-#define utf8_encoding() (afp_version >= 30)
+#define utf8_encoding(obj) ((obj)->afp_version >= 30)
#define vol_nodev(vol) (((vol)->v_flags & AFPVOL_NODEV) ? 1 : 0)
-#define vol_unix_priv(vol) (afp_version >= 30 && ((vol)->v_flags & AFPVOL_UNIX_PRIV))
+#define vol_unix_priv(vol) ((vol)->v_obj->afp_version >= 30 && ((vol)->v_flags & AFPVOL_UNIX_PRIV))
#define vol_inv_dots(vol) (((vol)->v_flags & AFPVOL_INV_DOTS) ? 1 : 0)
#include <atalk/util.h>
#include <atalk/cnid.h>
-#include <atalk/volinfo.h>
#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
#include <atalk/logger.h>
#include <atalk/cnid.h>
#include <atalk/dsi.h>
#include <atalk/uuid.h>
+#include <atalk/netatalk_conf.h>
#define VOLOPT_ALLOW 0 /* user allow list */
#define VOLOPT_DENY 1 /* user deny list */
/* check duplicate */
for ( volume = Volumes; volume; volume = volume->v_next ) {
- if ((utf8_encoding() && (strcasecmp_w(volume->v_u8mname, u8mtmpname) == 0))
+ if ((utf8_encoding(obj) && (strcasecmp_w(volume->v_u8mname, u8mtmpname) == 0))
||
- (!utf8_encoding() && (strcasecmp_w(volume->v_macname, mactmpname) == 0))) {
+ (!utf8_encoding(obj) && (strcasecmp_w(volume->v_macname, mactmpname) == 0))) {
LOG (log_error, logtype_afpd,
"Duplicate volume name, check AppleVolumes files: previous: \"%s\", new: \"%s\"",
volume->v_localname, name);
return -1;
}
- volume->v_name = utf8_encoding()?volume->v_u8mname:volume->v_macname;
+ volume->v_name = utf8_encoding(obj)?volume->v_u8mname:volume->v_macname;
volume->v_hide = hide;
strcpy( volume->v_path, path );
volume->v_next = Volumes;
Volumes = volume;
+ volume->v_obj = obj;
return 0;
}
if (Volumes) {
if (!volfile_changed(&obj->options))
goto EC_CLEANUP;
- free_volumes();
+ /* TODO: volume reloading */
+// free_volumes();
+ goto EC_CLEANUP;
}
/* try putting a read lock on the volume file twice, sleep 1 second if first attempt fails */
free_volumes();
}
-const struct vol *getvolumes(void)
+struct vol *getvolumes(void)
{
return Volumes;
}
-/* ------------------------- */
struct vol *getvolbyvid(const uint16_t vid )
{
struct vol *vol;
return( vol );
}
+struct vol *getvolbypath(const char *path)
+{
+ struct vol *vol = NULL;
+ struct vol *tmp;
+
+ for (tmp = Volumes; tmp; tmp = tmp->v_next) {
+ if (strncmp(path, tmp->v_path, strlen(tmp->v_path)) == 0) {
+ vol = tmp;
+ break;
+ }
+ }
+ return vol;
+}
+
#define MAXVAL 1024
/*!
* Initialize an AFPObj and options from ini config file
char *q, *r;
char val[MAXVAL];
+ AFPObj->afp_version = 11;
options->configfile = AFPObj->cmdlineconfigfile ? strdup(AFPObj->cmdlineconfigfile) : strdup(_PATH_CONFDIR "afp.conf");
options->sigconffile = strdup(_PATH_CONFDIR "afp_signature.conf");
options->uuidconf = strdup(_PATH_CONFDIR "afp_voluuid.conf");
options->flags = OPTION_ACL2MACCESS | OPTION_UUID | OPTION_SERVERNOTIF | AFPObj->cmdlineflags;
-
+
if ((config = iniparser_load(AFPObj->options.configfile)) == NULL)
return -1;
AFPObj->iniconfig = config;