+
+2001-08-14 jeff b <jeff@univrel.pr.uconn.edu>
+
+ * acconfig.h, configure.in, etc/afpd/directory.c,
+ etc/afpd/enumerate.c, etc/afpd/file.c, etc/afpd/file.h,
+ etc/afpd/filedir.c, etc/afpd/fork.c, etc/afpd/volume.c,
+ etc/afpd/volume.h, libatalk/Makefile.am,
+ libatalk/cnid/cnid_add.c, libatalk/cnid/cnid_close.c,
+ libatalk/cnid/cnid_delete.c, libatalk/cnid/cnid_lookup.c,
+ libatalk/cnid/cnid_nextid.c, libatalk/cnid/cnid_open.c,
+ libatalk/cnid/cnid_private.h, libatalk/cnid/cnid_update.c:
+ DID database and reincluding libatalk/cnid back into
+ compiled tree (Uwe Hees)
+
+ * libatalk/cnid/.cvsignore: updated .cvsignore list for
+ CNID patch (Jeff)
+
2001-08-09 Sam Noble <ns@shadow.org>
* configure.in, acconfig.h: Merged a patch from meeroh@mit.edu
2001-06-27 jeff b <jeff@univrel.pr.uconn.edu>
* many, many, files: more malformed ifdef correction, nicer
- comments, etc, etc, etc
+ comments, etc, etc, etc (Jeff)
* etc/afpd/directory.c, etc/afpd/uid.c, etc/afpd/uid.h: fixes
for force-uidgid to compile properly. haven't tested it, but
support in both afpd and papd (Jason Keltz <jas@cs.yorku.ca>)
* etc/*/*.{c,h}: corrected malformed defines, nicer comments,
- CVS Id tags
+ CVS Id tags (Jeff)
2001-06-20 jeff b <jeff@univrel.pr.uconn.edu>
#undef ADMIN_GRP
#undef AFS
#undef BSD4_4
+#undef CNID_DB
#undef DEBUG
#undef DLSYM_PREPEND_UNDERSCORE
#undef DID_MTAB
-dnl $Id: configure.in,v 1.95 2001-08-09 16:54:57 samnoble Exp $
+dnl $Id: configure.in,v 1.96 2001-08-14 14:00:08 rufustfirefly Exp $
dnl configure.in for netatalk
AC_INIT(bin/adv1tov2/adv1tov2.c)
AC_ARG_ENABLE(force-uidgid,
[ --enable-force-uidgid allow forcing of uid/gid per volume (BROKEN) ],
- if test "$enableval" = "yes"; then
+ if test "$enableval" = "yes"; then
AC_DEFINE(FORCE_UIDGID, 1)
AC_MSG_RESULT([enabling forcing of uid/gid per volume])
fi
)
+AC_ARG_ENABLE(cnid-db,
+ [ --enable-cnid-db use persistent cnid database per volume (EXPERIMENTAL) ],
+ if test "$enableval" = "yes"; then
+ AC_DEFINE(CNID_DB, 1)
+ AC_MSG_RESULT([using persistent cnid database per volume])
+ fi
+)
+
AC_ARG_WITH(did,
[ --with-did=[scheme] set DID scheme (last,mtab)],
if test "x$withval" != "xno" ; then
- if test "$withval" = "last"; then
+ if test "$withval" = "last"; then
AC_DEFINE(USE_LASTDID, 1)
AC_MSG_RESULT([enabling build without DID dev/inode mapping kludge])
fi
- if test "$withval" = "mtab"; then
+ if test "$withval" = "mtab"; then
AC_DEFINE(DID_MTAB, 1)
AC_MSG_RESULT([enabling mtab-based DID creation support])
fi
compile_pam=no
use_pam_so=no
AC_DEFINE(USE_PAM, 0)
- AC_MSG_RESULT([Disabling pam modules support])
+ AC_MSG_RESULT([disabling pam modules support])
)
if test "x$compile_pam" = "xyes"; then
use_pam_so=yes
- AC_MSG_RESULT([Enabling pam modules support])
+ AC_MSG_RESULT([enabling pam modules support])
fi
shadowpw=no
dnl --------------------- check for building Kerberos v4 UAM module
AC_ARG_ENABLE(krb4-uam,
- [ --enable-krb4-uam enable build of Kerberos v4 UAM module],
+ [ --enable-krb4-uam enable build of Kerberos v4 UAM module],
if test "$enableval" = "yes"; then
AC_DEFINE(UAM_KRB4, 1)
compile_kerberos=yes
libatalk/adouble/Makefile
libatalk/asp/Makefile
libatalk/atp/Makefile
+ libatalk/cnid/Makefile
libatalk/compat/Makefile
libatalk/dsi/Makefile
libatalk/nbp/Makefile
/*
- * $Id: directory.c,v 1.13 2001-06-27 14:53:16 rufustfirefly Exp $
+ * $Id: directory.c,v 1.14 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <atalk/adouble.h>
#include <atalk/afp.h>
#include <atalk/util.h>
+#ifdef CNID_DB
#include <atalk/cnid.h>
+#endif /* CNID_DB */
#include <utime.h>
#include <stdio.h>
#include <stdlib.h>
}
dirchildremove(curdir, fdir);
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
cnid_delete(vol->v_db, fdir->d_did);
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
dir_remove( vol, fdir );
#ifdef FORCE_UIDGID
/*
- * $Id: enumerate.c,v 1.5 2001-06-20 18:33:04 rufustfirefly Exp $
+ * $Id: enumerate.c,v 1.6 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <netatalk/endian.h>
#include <atalk/afp.h>
#include <atalk/adouble.h>
+#ifdef CNID_DB
#include <atalk/cnid.h>
-
+#endif /* CNID_DB */
#include "desktop.h"
#include "directory.h"
#include "volume.h"
strcpy( cdir->d_name, name );
cdir->d_name[namlen] = '\0';
-#if AD_VERSION > AD_VERSION1
+ cdir->d_did = 0;
+
+#ifdef CNID_DB
/* find out if we have a fixed did already */
- if (!(cdir->d_did = cnid_lookup(vol->v_db, st, dir->d_did, upath,
- upathlen))) {
- memset(&ad, 0, sizeof(ad));
+ cdir->d_did = cnid_lookup(vol->v_db, st, dir->d_did, upath,
+ upathlen);
+#endif /* CNID_DB */
+
+ if (cdir->d_did == 0) {
+#if AD_VERSION > AD_VERSION1
+ memset(&ad, 0, sizeof(ad));
if (ad_open(upath, ADFLAGS_HF|ADFLAGS_DIR, O_RDONLY, 0, &ad) < 0) {
/* if we can't parse the AppleDouble header, return 0 for the DID */
cdir->d_did = 0;
/* ... else retrieve the DID entry into cdir->d_did */
memcpy(&cdir->d_did, ad_entry(&ad, ADEID_DID), sizeof(cdir->d_did));
ad_close(&ad, ADFLAGS_HF);
- }
-
- if (!(cdir->d_did = cnid_add(vol->v_db, st, dir->d_did, upath,
- upathlen, cdir->d_did))) {
-#ifdef USE_LASTDID
+ }
+#endif /* AD_VERSION */
+
+#ifdef CNID_DB
+ /* add to cnid db */
+ cdir->d_did = cnid_add(vol->v_db, st, dir->d_did, upath,
+ upathlen, cdir->d_did);
+#endif /* CNID_DB */
+ }
+
+ if (cdir->d_did == 0) {
+#ifdef USE_LASTDID
/* last way of doing DIDs */
cdir->d_did = htonl( vol->v_lastdid++ );
#else /* USE_LASTDID */
cdir->d_did = htonl( CNID(lstp, 0) );
#endif /* DID_MTAB */
#endif /* USE_LASTDID */
- }
}
-#else /* AD_VERSION */
-
-#ifdef USE_LASTDID
- /* last way of doing DIDs */
- cdir->d_did = htonl( vol->v_lastdid++ );
-#else /* USE_LASTDID */
- lstp = lstat(upath, &lst) < 0 ? st : &lst;
-#ifdef DID_MTAB
- /* mtab way of doing DIDs */
- cdir->d_did = htonl( afpd_st_cnid ( lstp ) );
-#else /* DID_MTAB */
- /* the old way of doing DIDs (default) */
- cdir->d_did = htonl( CNID(lstp, 0) );
-#endif /* DID_MTAB */
-#endif /* USE_LASTDID */
-#endif /* AD_VERSION */
if ((edir = dirinsert( vol, cdir ))) {
if (edir->d_name) {
/*
- * $Id: file.c,v 1.24 2001-07-12 23:18:12 srittau Exp $
+ * $Id: file.c,v 1.25 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <atalk/adouble.h>
#include <atalk/afp.h>
#include <atalk/util.h>
+#ifdef CNID_DB
#include <atalk/cnid.h>
-
+#endif /* CNID_DB */
#include "directory.h"
#include "desktop.h"
#include "volume.h"
* files:
* ioFlFndrInfo 16 -> type 4 type field
* creator 4 creator field
- * flags 2 finder flags:
+ * flags 2 finder flags:
* alias, bundle, etc.
* location 4 location in window
* folder 2 window that contains file
break;
case FILPBIT_FNUM :
+ aint = 0;
+#ifdef CNID_DB
+ /* find out if we have a fixed did already */
+ aint = cnid_lookup(vol->v_db, st, dir->d_did, upath,
+ strlen(upath));
+#endif /* CNID_DB */
+
+ /* look in AD v2 header */
+ if (aint == 0)
+ {
#if AD_VERSION > AD_VERSION1
- /* use the CNID database if we're using AD v2 */
- if (isad)
- memcpy(&aint, ad_entry(adp, ADEID_DID), sizeof(aint));
- else
- aint = 0;
-
- if (!(aint = cnid_add(vol->v_db, st, dir->d_did, upath,
- strlen(upath), aint))) {
+ if (isad)
+ memcpy(&aint, ad_entry(adp, ADEID_DID), sizeof(aint));
#endif /* AD_VERSION > AD_VERSION1 */
+
+#ifdef CNID_DB
+ aint = cnid_add(vol->v_db, st, dir->d_did, upath,
+ strlen(upath), aint);
+#endif /* CNID_DB */
+ }
+
+ if (aint == 0) {
/*
* What a fucking mess. First thing: DID and FNUMs are
* in the same space for purposes of enumerate (and several
* new algorithm:
* due to complaints over did's being non-persistent,
* here's the current hack to provide semi-persistent
- * did's:
+ * did's:
* 1) we reserve the first bit for file ids.
* 2) the next 7 bits are for the device.
* 3) the remaining 24 bits are for the inode.
aint = htonl(CNID(lstp, 1));
#endif /* DID_MTAB */
#endif /* USE_LASTDID */
+ }
-#if AD_VERSION > AD_VERSION1
- }
-#endif /* AD_VERSION > AD_VERSION1 */
- memcpy(data, &aint, sizeof( aint ));
+ memcpy(data, &aint, sizeof( aint ));
data += sizeof( aint );
break;
achar = '\x00';
ashort = 0x0000;
}
-
+
*data++ = achar;
*data++ = 0;
memcpy(data, &ashort, sizeof( ashort ));
}
ad_setentrylen( adp, ADEID_NAME, strlen( path ));
- memcpy(ad_entry( adp, ADEID_NAME ), path,
+ memcpy(ad_entry( adp, ADEID_NAME ), path,
ad_getentrylen( adp, ADEID_NAME ));
ad_flush( adp, ADFLAGS_DF|ADFLAGS_HF );
ad_close( adp, ADFLAGS_DF|ADFLAGS_HF );
case FILPBIT_FINFO :
if ((memcmp( ad_entry( adp, ADEID_FINDERI ), ufinderi, 8 ) == 0)
- && (em = getextmap( path )) &&
+ && (em = getextmap( path )) &&
(memcmp(buf, em->em_type, sizeof( em->em_type )) == 0) &&
(memcmp(buf + 4, em->em_creator,
sizeof( em->em_creator )) == 0)) {
#endif /* SENDFILE_FLAVOR_LINUX */
while (1) {
if ((cc = read(sfd, filebuf, sizeof(filebuf))) < 0) {
- if (errno == EINTR)
+ if (errno == EINTR)
continue;
err = AFPERR_PARAM;
break;
unlink(dst);
return err;
}
-
+
if (newname) {
memset(&ad, 0, sizeof(ad));
if ( ad_open( dst, noadouble | ADFLAGS_HF, O_RDWR|O_CREAT,
}
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
/* return a file id */
int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
#ifdef DEBUG
syslog(LOG_INFO, "begin afp_createid:");
#endif /* DEBUG */
-
+
*rbuflen = 0;
ibuf += 2;
return AFPERR_EXISTID;
}
+#if AD_VERSION > AD_VERSION1
memset(&ad, 0, sizeof(ad));
if (ad_open( upath, ADFLAGS_HF, O_RDONLY, 0, &ad ) < 0)
id = 0;
*rbuflen = sizeof(id);
return AFP_OK;
}
+#endif /* AD_VERSION > AD_VERSION1 */
#ifdef DEBUG
syslog(LOG_INFO, "ending afp_createid...:");
#ifdef DEBUG
syslog(LOG_INFO, "begin afp_resolveid:");
#endif /* DEBUG */
-
+
*rbuflen = 0;
ibuf += 2;
#ifdef DEBUG
syslog(LOG_INFO, "end afp_resolveid:");
#endif /* DEBUG */
-
+
return AFP_OK;
}
return err;
}
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
#define APPLETEMP ".AppleTempXXXXXX"
char *spath, temp[17], *path, *p;
char *supath, *upath;
int err;
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
int slen, dlen;
-#endif /* AD_VERSION > AD_VERSION1 */
- cnid_t sid, did;
+#endif /* CNID_DB */
+ u_int32_t sid, did;
u_int16_t vid;
#ifdef DEBUG
/* look for the source cnid. if it doesn't exist, don't worry about
* it. */
-#if AD_VERSION > AD_VERSION1
- sid = cnid_lookup(vol->v_db, &srcst, sdir->d_did, supath,
+#ifdef CNID_DB
+ sid = cnid_lookup(vol->v_db, &srcst, sdir->d_did, supath,
slen = strlen(supath));
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
if (( dir = dirsearch( vol, did )) == NULL ) {
return( AFPERR_PARAM );
}
}
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
/* look for destination id. */
- did = cnid_lookup(vol->v_db, &destst, curdir->d_did, upath,
+ did = cnid_lookup(vol->v_db, &destst, curdir->d_did, upath,
dlen = strlen(upath));
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
- /* construct a temp name.
+ /* construct a temp name.
* NOTE: the temp file will be in the dest file's directory. it
* will also be inaccessible from AFP. */
memcpy(temp, APPLETEMP, sizeof(APPLETEMP));
of_rename(vol, sdir, spath, curdir, temp);
/* rename destination to source */
- if ((err = renamefile(path, p, spath, vol_noadouble(vol))) < 0)
+ if ((err = renamefile(path, p, spath, vol_noadouble(vol))) < 0)
goto err_src_to_tmp;
of_rename(vol, curdir, path, sdir, spath);
goto err_dest_to_src;
of_rename(vol, curdir, temp, curdir, path);
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
/* id's need switching. src -> dest and dest -> src. */
- if (sid && (cnid_update(vol->v_db, sid, &destst, curdir->d_did,
+ if (sid && (cnid_update(vol->v_db, sid, &destst, curdir->d_did,
upath, dlen) < 0)) {
switch (errno) {
case EPERM:
cnid_update(vol->v_db, sid, &srcst, sdir->d_did, supath, slen);
goto err_temp_to_dest;
}
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
#ifdef DEBUG
syslog(LOG_INFO, "ending afp_exchangefiles:");
return AFP_OK;
- /* all this stuff is so that we can unwind a failed operation
+ /* all this stuff is so that we can unwind a failed operation
* properly. */
err_temp_to_dest:
/* rename dest to temp */
/*
- * $Id: file.h,v 1.2 2001-06-20 18:33:04 rufustfirefly Exp $
+ * $Id: file.h,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
extern int afp_setfilparams __P((AFPObj *, char *, int, char *, int *));
extern int afp_copyfile __P((AFPObj *, char *, int, char *, int *));
extern int afp_createfile __P((AFPObj *, char *, int, char *, int *));
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
extern int afp_createid __P((AFPObj *, char *, int, char *, int *));
extern int afp_resolveid __P((AFPObj *, char *, int, char *, int *));
extern int afp_deleteid __P((AFPObj *, char *, int, char *, int *));
-#else /* AD_VERSION > AD_VERSION1 */
+#else /* CNID_DB */
#define afp_createid afp_null
#define afp_resolveid afp_null
#define afp_deleteid afp_null
/*
- * $Id: filedir.c,v 1.10 2001-06-20 18:33:04 rufustfirefly Exp $
+ * $Id: filedir.c,v 1.11 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <atalk/adouble.h>
#include <atalk/afp.h>
#include <atalk/util.h>
+#ifdef CNID_DB
#include <atalk/cnid.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_FCNTL_H
u_int32_t did;
int plen;
u_int16_t vid;
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
cnid_t id;
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
#ifdef DEBUG
syslog(LOG_INFO, "begin afp_rename:");
upath = mtoupath(vol, path);
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
if ( rename( upath, newpath ) < 0 ) {
switch ( errno ) {
}
}
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
if (stat(newpath, &st) < 0) /* this shouldn't fail */
return AFPERR_MISC;
cnid_update(vol->v_db, id, &st, curdir->d_did, newpath, strlen(newpath));
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
if ( !odir ) {
newadpath = obj->newtmp;
} else if (of_findname(vol, curdir, path)) {
rc = AFPERR_BUSY;
} else if ((rc = deletefile( upath = mtoupath(vol, path ))) == AFP_OK) {
-#if AD_VERSION > AD_VERSION1 /* get rid of entry */
+#ifdef CNID_DB /* get rid of entry */
cnid_t id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
cnid_delete(vol->v_db, id);
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
}
if ( rc == AFP_OK ) {
setvoltime(obj, vol );
int did, rc;
int plen;
u_int16_t vid;
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
cnid_t id;
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
#ifdef DROPKLUDGE
int retvalue;
#endif /* DROPKLUDGE */
/* not a directory */
strcpy(newname, path);
strcpy(oldname, path); /* an extra copy for of_rename */
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
p = mtoupath(vol, path);
id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
p = ctoupath( vol, sdir, newname );
} else {
odir = curdir;
strcpy( newname, odir->d_name );
- strcpy(oldname, odir->d_name);
+ strcpy(oldname, odir->d_name);
p = ctoupath( vol, odir->d_parent, newname );
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
id = curdir->d_did; /* we already have the CNID */
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
}
/*
* p now points to the full pathname of the source fs object.
#endif /* DROPKLUDGE */
if ( rc == AFP_OK ) {
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
/* renaming may have moved the file/dir across a filesystem */
- if (stat(upath, &st) < 0)
+ if (stat(upath, &st) < 0)
return AFPERR_MISC;
-
+
/* fix up the catalog entry */
cnid_update(vol->v_db, id, &st, curdir->d_did, upath, strlen(upath));
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
setvoltime(obj, vol );
}
/*
- * $Id: fork.c,v 1.5 2001-06-20 18:33:04 rufustfirefly Exp $
+ * $Id: fork.c,v 1.6 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <atalk/afp.h>
#include <atalk/adouble.h>
#include <atalk/util.h>
+#ifdef CNID_DB
#include <atalk/cnid.h>
+#endif
#include "fork.h"
#include "file.h"
memcpy(data, ufinderi, 8 );
if (( em = getextmap( ofork->of_name )) != NULL ) {
memcpy(data, em->em_type, sizeof( em->em_type ));
- memcpy(data + 4, em->em_creator,
+ memcpy(data + 4, em->em_creator,
sizeof( em->em_creator ));
}
}
break;
case FILPBIT_FNUM :
- /*
- * See file.c getfilparams() for why this is done this
- * way.
- */
+ aint = 0;
+#ifdef CNID_DB
+ /* find out if we have a fixed did already */
+ aint = cnid_lookup(ofork->of_vol->v_db, &st,
+ ofork->of_dir->d_did,
+ upath, strlen(upath));
+#endif /* CNID_DB */
+
+ /* look in AD v2 header */
+ if (aint == 0)
+ {
#if AD_VERSION > AD_VERSION1
- if (isad)
- memcpy(&aint, ad_entry(ofork->of_ad, ADEID_DID), sizeof(aint));
- else
- aint = 0;
-
- if (!(aint = cnid_add(ofork->of_vol->v_db, &st,
- ofork->of_dir->d_did,
- upath, strlen(upath), aint))) {
+ if (isad)
+ memcpy(&aint, ad_entry(ofork->of_ad, ADEID_DID), sizeof(aint));
#endif /* AD_VERSION > AD_VERSION1 */
+
+#ifdef CNID_DB
+ aint = cnid_add(ofork->of_vol->v_db, &st,
+ ofork->of_dir->d_did,
+ upath, strlen(upath), aint);
+#endif /* CNID_DB */
+ }
+
+ if (aint == 0) {
#ifdef AFS
aint = st.st_ino;
#else /* AFS */
aint = ( st.st_dev << 16 ) | ( st.st_ino & 0x0000ffff );
#endif /* AFS */
-#if AD_VERSION > AD_VERSION1
}
-#endif /* AD_VERSION > AD_VERSION1 */
- memcpy(data, &aint, sizeof( aint ));
+
+ memcpy(data, &aint, sizeof( aint ));
data += sizeof( aint );
break;
if (!ret && (access & OPENACC_RD)) {
ofork->of_flags |= AFPFORK_ACCRD;
ret = ad_lock(ofork->of_ad, eid, ADLOCK_RD | ADLOCK_FILELOCK,
- AD_FILELOCK_RD, 1, ofrefnum);
+ AD_FILELOCK_RD, 1, ofrefnum);
}
/* can we access the fork? */
/*
- * $Id: volume.c,v 1.8 2001-06-20 18:33:04 rufustfirefly Exp $
+ * $Id: volume.c,v 1.9 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <atalk/adouble.h>
#include <atalk/afp.h>
#include <atalk/util.h>
+#ifdef CNID_DB
#include <atalk/cnid.h>
+#endif /* CNID_DB*/
#include <dirent.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
static struct vol *volumes = NULL;
static int lastvid = 0;
-#if AD_VERSION == AD_VERSION1
+#ifndef CNID_DB
static char *Trash = "\02\024Network Trash Folder";
-#endif /* AD_VERSION == AD_VERSION1 */
+#endif /* CNID_DB */
static struct extmap *extmap = NULL, *defextmap = NULL;
#define VOLOPT_ALLOW 0 /* user allow list */
p = strtok(NULL, ",");
}
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
} else if (optionok(tmp, "dbpath:", val)) {
if (options[VOLOPT_DBPATH].c_value)
free(options[VOLOPT_DBPATH].c_value);
-
+
options[VOLOPT_DBPATH].c_value = strdup(val + 1);
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
} else if (optionok(tmp, "mapchars:",val)) {
if (options[VOLOPT_MAPCHARS].c_value)
free(options[VOLOPT_MAPCHARS].c_value);
} else {
/* we'll assume it's a volume name. */
- strncpy(volname, tmp, vlen);
+ strncpy(volname, tmp, vlen);
}
}
if (options[VOLOPT_PASSWORD].c_value)
volume->v_password = strdup(options[VOLOPT_PASSWORD].c_value);
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
if (options[VOLOPT_DBPATH].c_value)
volume->v_dbpath = strdup(options[VOLOPT_DBPATH].c_value);
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
#ifdef FORCE_UIDGID
if (strncmp(path, VOLOPT_DEFAULT, VOLOPT_DEFAULT_LEN) == 0) {
*tmp = '\0';
for (i = 0; i < VOLOPT_NUM; i++) {
- if (parseline( sizeof( path ) - VOLOPT_DEFAULT_LEN - 1,
+ if (parseline( sizeof( path ) - VOLOPT_DEFAULT_LEN - 1,
path + VOLOPT_DEFAULT_LEN) < 0)
break;
- volset(save_options, tmp, sizeof(tmp) - 1,
+ volset(save_options, tmp, sizeof(tmp) - 1,
obj->options.nlspath, path + VOLOPT_DEFAULT_LEN);
}
}
if (((options[VOLOPT_FLAGS].i_value & AFPVOL_RO) == 0) &&
((accessvol(options[VOLOPT_ROLIST].c_value,
obj->username) == 1) ||
- !accessvol(options[VOLOPT_RWLIST].c_value,
+ !accessvol(options[VOLOPT_RWLIST].c_value,
obj->username)))
options[VOLOPT_FLAGS].i_value |= AFPVOL_RO;
} else if (pwent) {
/*
* Read user's AppleVolumes or .AppleVolumes file
- * If neither are readable, read the default volumes file. if
+ * If neither are readable, read the default volumes file. if
* that doesn't work, create a user share.
*/
if ( readvolfile(obj, pwent->pw_dir, "AppleVolumes", 1, pwent) < 0 &&
* .Parent file here if it doesn't exist. */
memset(&ad, 0, sizeof(ad));
- if ( ad_open( vol->v_path, vol_noadouble(vol) |
+ if ( ad_open( vol->v_path, vol_noadouble(vol) |
ADFLAGS_HF|ADFLAGS_DIR, O_RDWR | O_CREAT,
0666, &ad) < 0 ) {
isad = 0;
switch ( bit ) {
case VOLPBIT_ATTR :
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
ashort = VOLPBIT_ATTR_FILEID;
-#else /* AD_VERSION > AD_VERSION1 */
+#else /* CNID_DB */
ashort = 0;
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
/* check for read-only.
* NOTE: we don't actually set the read-only flag unless
* it's passed in that way as it's possible to mount
{
struct stat st;
char *volname;
-#if AD_VERSION == AD_VERSION1
+#ifndef CNID_DB
char *p;
-#endif /* AD_VERSION == AD_VERSION1 */
+#endif /* CNID_DB */
struct vol *volume;
struct dir *dir;
int len, ret, buflen;
ret = AFPERR_PARAM;
goto openvol_err;
}
-#if AD_VERSION == AD_VERSION1
+
+#ifdef CNID_DB
+ if (volume->v_dbpath)
+ volume->v_db = cnid_open (volume->v_dbpath);
+ if (volume->v_db == 0)
+ volume->v_db = cnid_open (volume->v_path);
+#endif /* CNID_DB */
+
+#ifndef CNID_DB
/*
* If you mount a volume twice, the second time the trash appears on
* the desk-top. That's because the Mac remembers the DID for the
*/
p = Trash;
cname( volume, volume->v_dir, &p );
-#endif /* AD_VERSION == AD_VERSION1 */
+#endif /* CNID_DB */
return( AFP_OK );
dirfree( vol->v_root );
vol->v_dir = NULL;
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
cnid_close(vol->v_db);
vol->v_db = NULL;
#endif /* AD_VERSION > AD_VERSION1 */
* where no other users can interfere, so there's no issue here
*/
}
-
+
/* a little granularity */
if (vol->v_time < tv.tv_sec) {
vol->v_time = tv.tv_sec;
/*
- * $Id: volume.h,v 1.5 2001-06-20 18:33:04 rufustfirefly Exp $
+ * $Id: volume.h,v 1.6 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1990,1994 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
int v_nfs, v_casefold;
struct codepage *v_mtoupage, *v_utompage, *v_badumap;
char *v_password;
-#if AD_VERSION > AD_VERSION1
+#ifdef CNID_DB
void *v_db;
char *v_dbpath;
-#endif /* AD_VERSION > AD_VERSION1 */
+#endif /* CNID_DB */
#ifdef FORCE_UIDGID
char *v_forceuid;
char *v_forcegid;
# Makefile.am for libatalk/
-SUBDIRS = adouble asp atp compat dsi nbp netddp util
+SUBDIRS = adouble asp atp compat cnid dsi nbp netddp util
lib_LTLIBRARIES = libatalk.la
asp/libasp.la \
atp/libatp.la \
compat/libcompat.la \
+ cnid/libcnid.la \
dsi/libdsi.la \
nbp/libnbp.la \
netddp/libnetddp.la \
--- /dev/null
+Makefile.in
+Makefile
+.libs
+.deps
+*.lo
+*.la
+*.o
-/*
- * $Id: cnid_add.c,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+/*
+ * $Id: cnid_add.c,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT.
*
- * cnid_add (db, dev, ino, did, name, hint):
+ * cnid_add (db, dev, ino, did, name, hint):
* add a name to the CNID database. we use both dev/ino and did/name
* to keep track of things.
*/
/* add an entry to the CNID databases. we do this as a transaction
* to prevent messiness. */
-static int add_cnid(CNID_private *db, DBT *key, DBT *data)
+static int add_cnid(CNID_private *db, DB_TXN *ptid, DBT *key, DBT *data)
{
DBT altkey, altdata;
DB_TXN *tid;
- DB_TXNMGR *txnp;
- txnp = db->dbenv.tx_info;
memset(&altkey, 0, sizeof(altkey));
memset(&altdata, 0, sizeof(altdata));
retry:
- if (errno = txn_begin(txnp, NULL, &tid)) {
+ if (errno = txn_begin(db->dbenv, ptid, &tid,0)) {
return errno;
}
/* main database */
- if (errno = db->db_cnid->put(db->db_cnid, tid,
+ if (errno = db->db_cnid->put(db->db_cnid, tid,
key, data, DB_NOOVERWRITE)) {
txn_abort(tid);
if (errno == EAGAIN)
return errno;
}
- return txn_commit(tid);
+ return txn_commit(tid, 0);
}
-
+
/* 0 is not a valid cnid. this will do a cnid_lookup beforehand and
return that cnid if it exists. */
-cnid_t cnid_add(void *CNID, const struct stat *st,
+cnid_t cnid_add(void *CNID, const struct stat *st,
const cnid_t did, const char *name, const int len,
cnid_t hint)
{
CNID_private *db;
DBT key, data;
+ DBT rootinfo_key, rootinfo_data;
+ DB_TXN *tid;
struct flock lock;
cnid_t id, save;
-
-
- if (!(db = CNID) || !st || !name)
+
+ int debug = 0;
+
+
+ if (!(db = CNID) || !st || !name) {
return 0;
-
- /* just do a lookup if RootInfo is read-only. */
- if (db->flags & (CNIDFLAG_ROOTINFO_RO | CNIDFLAG_DB_RO))
- return cnid_lookup(db, st, did, name, len);
+ }
+
+ /* do a lookup... */
+ id = cnid_lookup(db, st, did, name, len);
+ /* ...return id if it is valid or if RootInfo is read-only. */
+ if (id || (db->flags & CNIDFLAG_DB_RO)) {
+ if (debug)
+ syslog(LOG_ERR, "cnid_add: looked up did %d, name %s as %d", did, name, id);
+ return id;
+ }
/* initialize everything */
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
- /* acquire a lock on RootInfo. as the cnid database is the only user
- * of RootInfo, we just use our own locks.
- *
- * NOTE: we lock it here to serialize access to the database. */
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = ad_getentryoff(&db->rootinfo, ADEID_DID);
- lock.l_len = ad_getentrylen(&db->rootinfo, ADEID_DID);
- if (fcntl(ad_hfileno(&db->rootinfo), F_SETLKW, &lock) < 0) {
- syslog(LOG_ERR, "cnid_add: can't establish lock: %m");
- goto cleanup_err;
- }
-
- /* if it's already stored, just return it */
- if ((id = cnid_lookup(db, st, did, name, len))) {
- hint = id;
- goto cleanup_unlock;
- }
-
/* just set hint, and the key will change. */
key.data = &hint;
key.size = sizeof(hint);
-
- if ((data.data =
+
+ if ((data.data =
make_cnid_data(st, did, name, len)) == NULL) {
syslog(LOG_ERR, "cnid_add: path name too long.");
- goto cleanup_unlock;
+ goto cleanup_err;
}
data.size = CNID_HEADER_LEN + len + 1;
-
- /* start off with the hint. it should be in network byte order.
+
+ /* Abort and retry the modification. */
+ if (0) {
+retry: if ((errno = txn_abort(tid)) != 0)
+ syslog(LOG_ERR, "cnid_add: txn_begin failed (%d)", errno);
+ /* FALLTHROUGH */
+ }
+
+ /* Begin the transaction. */
+ if ((errno = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
+ syslog(LOG_ERR, "cnid_add: txn_begin failed (%d)", errno);
+ goto cleanup_err;
+ }
+
+ /* start off with the hint. it should be in network byte order.
* we need to make sure that somebody doesn't add in restricted
* cnid's to the database. */
if (ntohl(hint) >= CNID_START) {
/* if the key doesn't exist, add it in. don't fiddle with nextID. */
- errno = add_cnid(db, &key, &data);
+ errno = add_cnid(db, tid, &key, &data);
switch (errno) {
case DB_KEYEXIST: /* need to use RootInfo after all. */
break;
default:
- syslog(LOG_ERR, "cnid_add: unable to add CNID(%x)", hint);
+ syslog(LOG_ERR, "cnid_add: unable to add CNID(%x)", hint);
hint = 0;
- /* fall through */
+ goto cleanup_abort;
case 0:
- goto cleanup_unlock;
+ if (debug)
+ syslog(LOG_ERR, "cnid_add: used hint for did %d, name %s as %d", did, name, hint);
+ goto cleanup_commit;
}
- }
-
- /* no need to refresh the header file */
- memcpy(&hint, ad_entry(&db->rootinfo, ADEID_DID), sizeof(hint));
+ }
+
+ memset(&rootinfo_key, 0, sizeof(&rootinfo_key));
+ memset(&rootinfo_data, 0, sizeof(&rootinfo_data));
+
+ /* just set hint, and the key will change. */
+ rootinfo_key.data = ROOTINFO_KEY;
+ rootinfo_key.size = ROOTINFO_KEYLEN;
+
+ /* Get the key. */
+ switch (errno = db->db_didname->get(db->db_didname, tid, &rootinfo_key, &rootinfo_data, 0)) {
+ case DB_LOCK_DEADLOCK:
+ goto retry;
+ case 0:
+ memcpy (&hint, rootinfo_data.data, sizeof(hint));
+ if (debug)
+ syslog(LOG_ERR, "cnid_add: found rootinfo for did %d, name %s as %d", did, name, hint);
+ break;
+ case DB_NOTFOUND:
+ hint = htonl(CNID_START);
+ if (debug)
+ syslog(LOG_ERR, "cnid_add: using CNID_START for did %d, name %s as %d", did, name, hint);
+ break;
+ default:
+ syslog(LOG_ERR, "cnid_add: unable to lookup rootinfo (%d)", errno);
+ goto cleanup_abort;
+ }
/* search for a new id. we keep the first id around to check for
* wrap-around. NOTE: i do it this way so that we can go back and
* fill in holes. */
save = id = ntohl(hint);
- while (errno = add_cnid(db, &key, &data)) {
+ while (errno = add_cnid(db, tid, &key, &data)) {
/* don't use any of the special CNIDs */
if (++id < CNID_START)
id = CNID_START;
if ((errno != DB_KEYEXIST) || (save == id)) {
syslog(LOG_ERR, "cnid_add: unable to add CNID(%x)", hint);
hint = 0;
- goto cleanup_unlock;
+ goto cleanup_abort;
}
hint = htonl(id);
}
/* update RootInfo with the next id. */
- id = htonl(++id);
- memcpy(ad_entry(&db->rootinfo, ADEID_DID), &id, sizeof(id));
- ad_flush(&db->rootinfo, ADFLAGS_HF);
+ rootinfo_data.data = &hint;
+ rootinfo_data.size = sizeof(hint);
+
+ switch (errno = db->db_didname->put(db->db_didname, tid, &rootinfo_key, &rootinfo_data, 0)) {
+ case DB_LOCK_DEADLOCK:
+ goto retry;
+ case 0:
+ break;
+ default:
+ syslog(LOG_ERR, "cnid_add: unable to update rootinfo (%d)", errno);
+ goto cleanup_abort;
+ }
+
-cleanup_unlock:
- lock.l_type = F_UNLCK;
- fcntl(ad_hfileno(&db->rootinfo), F_SETLK, &lock);
+cleanup_commit:
+ /* The transaction finished, commit it. */
+ if ((errno = txn_commit(tid, 0)) != 0) {
+ syslog(LOG_ERR, "cnid_add: txn_commit failed (%d)", errno);
+ goto cleanup_err;
+ }
+
+ if (debug)
+ syslog(LOG_ERR, "cnid_add: returned cnid for did %d, name %s as %d", did, name, hint);
return hint;
+cleanup_abort:
+ txn_abort(tid);
+
cleanup_err:
return 0;
}
/*
- * $Id: cnid_close.c,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: cnid_close.c,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*/
#ifdef HAVE_CONFIG_H
lock.l_whence = SEEK_SET;
lock.l_start = lock.l_len = 0;
if (fcntl(db->lockfd, F_SETLK, &lock) == 0) {
- DB_TXNMGR *txnp;
char **list, **first;
-
- txnp = db->dbenv.tx_info;
- errno = txn_checkpoint(txnp, 0, 0);
+
+ errno = txn_checkpoint(db->dbenv, 0, 0, 0);
while (errno == DB_INCOMPLETE)
- errno = txn_checkpoint(txnp, 0, 0);
-
- /* we've checkpointed, so clean up the log files.
+ errno = txn_checkpoint(db->dbenv, 0, 0, 0);
+
+ /* we've checkpointed, so clean up the log files.
* NOTE: any real problems will make log_archive return an error. */
- chdir(db->dbenv.db_log_dir ? db->dbenv.db_log_dir : db->dbenv.db_home);
- if (!log_archive(db->dbenv.lg_info, &first, DB_ARCH_LOG, NULL)) {
+ chdir(db->dbenv->db_log_dir ? db->dbenv->db_log_dir : db->dbenv->db_home);
+ if (!log_archive(db->dbenv, &first, DB_ARCH_LOG, NULL)) {
list = first;
while (*list) {
if (truncate(*list, 0) < 0)
db->db_didname->close(db->db_didname, 0);
db->db_devino->close(db->db_devino, 0);
db->db_cnid->close(db->db_cnid, 0);
- db_appexit(&db->dbenv);
+
+ db->dbenv->close(db->dbenv, 0);
+ /* db->dbenv->remove(db->dbenv, db->dbenv->db_home, 0); */
+
if (db->lockfd > -1)
close(db->lockfd); /* this will also close any lock we have. */
- ad_close(&db->rootinfo, ADFLAGS_HF);
free(db);
}
-/*
- * $Id: cnid_delete.c,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+/*
+ * $Id: cnid_delete.c,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT.
CNID_private *db;
DBT key, data;
DB_TXN *tid;
- DB_TXNMGR *txnp;
if (!(db = CNID) || !id || (db->flags & CNIDFLAG_DB_RO))
return -1;
- txnp = db->dbenv.tx_info;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
-
+
retry:
- if (errno = txn_begin(txnp, NULL, &tid)) {
+ if (errno = txn_begin(db->dbenv, NULL, &tid, 0)) {
return errno;
}
goto abort_err;
}
- return txn_commit(tid);
+ return txn_commit(tid, 0);
abort_err:
syslog(LOG_ERR, "cnid_del: unable to delete CNID(%x)", id);
/*
- * $Id: cnid_lookup.c,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: cnid_lookup.c,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*/
#ifdef HAVE_CONFIG_H
char *buf;
CNID_private *db;
DBT key, devdata, diddata;
- DB_TXNMGR *txnp;
int devino = 1, didname = 1;
cnid_t id = 0;
-
+
+ int debug = 0;
+
if (!(db = CNID) || !st || !name)
return 0;
- /* do a little checkpointing if necessary. i stuck it here as
- * cnid_lookup gets called when we do directory lookups. only do
+ /* do a little checkpointing if necessary. i stuck it here as
+ * cnid_lookup gets called when we do directory lookups. only do
* this if we're using a read-write database. */
if ((db->flags & CNIDFLAG_DB_RO) == 0) {
- txnp = db->dbenv.tx_info;
- errno = txn_checkpoint(txnp, LOGFILEMAX, CHECKTIMEMAX);
+ errno = txn_checkpoint(db->dbenv, LOGFILEMAX, CHECKTIMEMAX, 0);
while (errno == DB_INCOMPLETE)
- errno = txn_checkpoint(txnp, 0, 0);
+ errno = txn_checkpoint(db->dbenv, 0, 0, 0);
}
if ((buf = make_cnid_data(st, did, name, len)) == NULL) {
&key, &devdata, 0)) {
if (errno == EAGAIN)
continue;
-
+
if (errno == DB_NOTFOUND) {
devino = 0;
break;
}
-
+
syslog(LOG_ERR, "cnid_lookup: can't get CNID(%u/%u)",
st->st_dev, st->st_ino);
return 0;
}
/* did/name is right afterwards. */
- key.data = buf + CNID_DEVINO_LEN;
+ key.data = buf + CNID_DEVINO_LEN;
key.size = CNID_DID_LEN + len + 1;
memset(&diddata, 0, sizeof(diddata));
while (errno = db->db_didname->get(db->db_didname, NULL,
return 0;
}
- /* set id. honor did/name over dev/ino as dev/ino isn't necessarily
+ /* set id. honor did/name over dev/ino as dev/ino isn't necessarily
* 1-1. */
if (didname) {
memcpy(&id, diddata.data, sizeof(id));
} else if (devino) {
memcpy(&id, devdata.data, sizeof(id));
- }
+ }
/* either entries in both databases exist or neither of them do. */
- if ((devino && didname) || !(devino || didname))
+ if ((devino && didname) || !(devino || didname)) {
+ if (debug)
+ syslog(LOG_ERR, "cnid_lookup: looked up did %d, name %s as %d", did, name, id);
return id;
-
+ }
/* fix up the databases */
cnid_update(db, id, st, did, name, len);
+ if (debug)
+ syslog(LOG_ERR, "cnid_lookup: looked up did %d, name %s as %d (needed update)", did, name, id);
return id;
}
/*
- * $Id: cnid_nextid.c,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: cnid_nextid.c,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*/
+#ifdef unused
#ifdef HAVE_CONFIG_H
#include "config.h"
memcpy(&id, ad_entry(&db->rootinfo, ADEID_DID), sizeof(id));
return id;
}
+#endif
\ No newline at end of file
-/*
- * $Id: cnid_open.c,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+/*
+ * $Id: cnid_open.c,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT.
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif /* ! MIN */
-#define ROOTINFO "RootInfo"
-#define ROOTINFO_LEN 8
-
#define DBHOME ".AppleDB"
#define DBCNID "cnid.db"
#define DBDEVINO "devino.db"
#define DBSHORTNAME "shortname.db" /* did/8+3 mapping */
#define DBMACNAME "macname.db" /* did/31 mapping */
#define DBLONGNAME "longname.db" /* did/unicode mapping */
-#define DBLOCKFILE "/cnid.lock"
+#define DBLOCKFILE "cnid.lock"
#define DBHOMELEN 8
#define DBLEN 10
#define DBOPTIONS (DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | \
DB_INIT_LOG | DB_INIT_TXN | DB_TXN_NOSYNC | DB_RECOVER)
-#define MAXITER 0xFFFF /* maximum number of simultaneously open CNID
+#define MAXITER 0xFFFF /* maximum number of simultaneously open CNID
* databases. */
/* the first compare that's always done. */
for (len = MIN(a->size, b->size); len-- > 4; sa++, sb++)
if (ret = (*sa - *sb))
return ret; /* sort by lexical ordering */
+
return a->size - b->size; /* sort by length */
}
* did/macname, and did/shortname. i think did/longname needs a
* unicode table to work. also, we can't use strdiacasecmp as that
* returns a match if a < b. */
-static int compare_mac(const DBT *a, const DBT *b)
+static int compare_mac(const DBT *a, const DBT *b)
{
u_int8_t *sa, *sb;
int len, ret;
-
+
/* sort by did */
if (ret = compare_did(a, b))
return ret;
sb = b->data + 4;
for (len = MIN(a->size, b->size); len-- > 4; sa++, sb++)
if (ret = (_diacasemap[*sa] - _diacasemap[*sb]))
- return ret; /* sort by lexical ordering */
+ return ret; /* sort by lexical ordering */
+
return a->size - b->size; /* sort by length */
}
/* for unicode names -- right now it's the same as compare_mac. */
-#define compare_unicode(a, b) compare_mac((a), (b))
+static int compare_unicode(const DBT *a, const DBT *b)
+{
+ return compare_mac(a,b);
+}
void *cnid_open(const char *dir)
{
struct flock lock;
char path[MAXPATHLEN + 1];
CNID_private *db;
- DB_INFO dbi;
DBT key, data;
int open_flag, len;
if (!dir)
return NULL;
- /* this checks both RootInfo and .AppleDB */
+ /* this checks .AppleDB */
if ((len = strlen(dir)) > (MAXPATHLEN - DBLEN - 1)) {
syslog(LOG_ERR, "cnid_open: path too large");
return NULL;
return NULL;
}
db->magic = CNID_DB_MAGIC;
-
+
strcpy(path, dir);
if (path[len - 1] != '/') {
strcat(path, "/");
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
- /* we create and initialize RootInfo if it doesn't exist. */
- strcat(path, ROOTINFO);
- if (ad_open(path, ADFLAGS_HF, O_RDWR, 0666, &db->rootinfo) < 0) {
- cnid_t id;
-
- /* see if we can open it read-only. if it's read-only, we can't
- * add CNIDs. */
- memset(&db->rootinfo, 0, sizeof(db->rootinfo));
- if (ad_open(path, ADFLAGS_HF, O_RDONLY, 0666, &db->rootinfo) == 0) {
- db->flags = CNIDFLAG_ROOTINFO_RO;
- syslog(LOG_INFO, "cnid_open: read-only RootInfo");
- goto mkdir_appledb;
- }
-
- /* create the file */
- memset(&db->rootinfo, 0, sizeof(db->rootinfo));
- if (ad_open(path, ADFLAGS_HF, O_CREAT | O_RDWR, 0666,
- &db->rootinfo) < 0) {
- syslog(LOG_ERR, "cnid_open: ad_open(RootInfo)");
- goto fail_db;
- }
-
- /* lock the RootInfo file. this and cnid_add are the only places
- * that should fiddle with RootInfo. */
- lock.l_start = ad_getentryoff(&db->rootinfo, ADEID_DID);
- lock.l_len = ad_getentrylen(&db->rootinfo, ADEID_DID);
- if (fcntl(ad_hfileno(&db->rootinfo), F_SETLKW, &lock) < 0) {
- syslog(LOG_ERR, "cnid_open: can't establish lock: %m");
- goto fail_adouble;
- }
-
- /* store the beginning CNID */
- id = htonl(CNID_START);
- memcpy(ad_entry(&db->rootinfo, ADEID_DID), &id, sizeof(id));
- ad_flush(&db->rootinfo, ADFLAGS_HF);
-
- /* unlock it */
- lock.l_type = F_UNLCK;
- fcntl(ad_hfileno(&db->rootinfo), F_SETLK, &lock);
- lock.l_type = F_WRLCK;
- }
-
mkdir_appledb:
strcpy(path + len, DBHOME);
if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777) < 0)) {
close(db->lockfd);
db->lockfd = -1;
break;
- }
+ }
}
- }
+ }
path[len + DBHOMELEN] = '\0';
open_flag = DB_CREATE;
/* try a full-blown transactional environment */
- if (db_appinit(path, NULL, &db->dbenv, DBOPTIONS)) {
+ if (db_env_create(&db->dbenv, 0)) {
+ syslog(LOG_ERR, "cnid_open: db_env_create failed");
+ goto fail_lock;
+ }
+
+ if (db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666)) {
/* try with a shared memory pool */
- memset(&db->dbenv, 0, sizeof(db->dbenv));
- if (db_appinit(path, NULL, &db->dbenv, DB_INIT_MPOOL)) {
+ if (db->dbenv->open(db->dbenv, path, DB_INIT_MPOOL, 0666)) {
/* try without any options. */
- memset(&db->dbenv, 0, sizeof(db->dbenv));
- if (db_appinit(path, NULL, &db->dbenv, 0)) {
- syslog(LOG_ERR, "cnid_open: db_appinit failed");
- goto fail_lock;
+ if (db->dbenv->open(db->dbenv, path, 0, 0666)) {
+ syslog(LOG_ERR, "cnid_open: db_env_open failed");
+ goto fail_lock;
}
}
db->flags |= CNIDFLAG_DB_RO;
syslog(LOG_INFO, "cnid_open: read-only CNID database");
}
- memset(&dbi, 0, sizeof(dbi));
-
/* did/name reverse mapping. we use a btree for this one. */
- dbi.bt_compare = compare_unix;
- if (db_open(DBDIDNAME, DB_BTREE, open_flag, 0666, &db->dbenv, &dbi,
- &db->db_didname)) {
+ if (db_create(&db->db_didname, db->dbenv, 0))
+ goto fail_appinit;
+
+ db->db_didname->set_bt_compare(db->db_didname, compare_unix);
+ if (db->db_didname->open(db->db_didname, DBDIDNAME, NULL, DB_BTREE, open_flag, 0666)) {
goto fail_appinit;
}
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = DBVERSION_KEY;
- key.len = DBVERSION_KEY_LEN;
+ key.size = DBVERSION_KEYLEN;
while (errno = db->db_didname->get(db->db_didname, NULL, &key, &data, 0)) {
switch (errno) {
case EAGAIN:
continue;
-
+
case DB_NOTFOUND:
+ {
u_int32_t version = htonl(DBVERSION);
data.data = &version;
- data.len = sizeof(version);
+ data.size = sizeof(version);
+ }
dbversion_retry:
if (db->db_didname->put(db->db_didname, NULL, &key, &data,
DB_NOOVERWRITE))
goto fail_appinit;
}
}
-
+
/* XXX: in the future, we might check for version number here. */
#if 0
memcpy(&version, data.data, sizeof(version));
}
#endif /* 0 */
+#ifdef EXTENDED_DB
/* did/macname mapping. btree this one. */
- dbi.bt_compare = compare_mac;
- if (db_open(DBMACNAME, DB_BTREE, open_flag, 0666, &db->dbenv, &dbi,
- &db->db_macname)) {
+ if (db_create(&db->db_macname, db->dbenv, 0))
+ goto fail_appinit;
+
+ db->db_macname->set_bt_compare(db->db_macname, compare_mac);
+ if (db->db_macname->open(db->db_macname, DBMACNAME, NULL, DB_BTREE, open_flag, 0666)) {
db->db_didname->close(db->db_didname, 0);
goto fail_appinit;
}
/* did/shortname mapping */
- if (db_open(DBSHORTNAME, DB_BTREE, open_flag, 0666, &db->dbenv, &dbi,
- &db->db_shortname)) {
+ if (db_create(&db->db_shortname, db->dbenv, 0))
+ goto fail_appinit;
+
+ db->db_shortname->set_bt_compare(db->db_shortname, compare_mac);
+ if (db->db_shortname->open(db->db_shortname, DBSHORTNAME, NULL, DB_BTREE, open_flag, 0666)) {
db->db_didname->close(db->db_didname, 0);
db->db_macname->close(db->db_macname, 0);
goto fail_appinit;
}
/* did/longname mapping */
- dbi.bt_compare = compare_unicode;
- if (db_open(DBLONGNAME, DB_BTREE, open_flag, 0666, &db->dbenv, &dbi,
- &db->db_longname)) {
+ if (db_create(&db->db_longname, db->dbenv, 0))
+ goto fail_appinit;
+
+ db->db_longname->set_bt_compare(db->db_longname, compare_unicode);
+ if (db->db_longname->open(db->db_longname, DBLONGNAME, NULL, DB_BTREE, open_flag, 0666)) {
db->db_didname->close(db->db_didname, 0);
db->db_macname->close(db->db_macname, 0);
db->db_shortname->close(db->db_shortname, 0);
goto fail_appinit;
}
+#endif /* EXTENDED_DB */
/* dev/ino reverse mapping. we hash this one. */
- dbi.bt_compare = NULL;
- if (db_open(DBDEVINO, DB_HASH, open_flag, 0666, &db->dbenv, &dbi,
- &db->db_devino)) {
+ if (db_create(&db->db_devino, db->dbenv, 0))
+ goto fail_appinit;
+
+ if (db->db_devino->open(db->db_devino, DBDEVINO, NULL, DB_HASH, open_flag, 0666)) {
db->db_didname->close(db->db_didname, 0);
+#ifdef EXTENDED_DB
db->db_macname->close(db->db_macname, 0);
db->db_shortname->close(db->db_shortname, 0);
db->db_longname->close(db->db_longname, 0);
+#endif /* EXTENDED_DB */
goto fail_appinit;
}
/* main cnid database. we hash this one as well. */
- if (db_open(DBCNID, DB_HASH, open_flag, 0666, &db->dbenv, &dbi,
- &db->db_cnid)) {
+ if (db_create(&db->db_cnid, db->dbenv, 0))
+ goto fail_appinit;
+
+ if (db->db_cnid->open(db->db_cnid, DBCNID, NULL, DB_HASH, open_flag, 0666)) {
db->db_didname->close(db->db_didname, 0);
+#ifdef EXTENDED_DB
db->db_macname->close(db->db_macname, 0);
db->db_shortname->close(db->db_shortname, 0);
db->db_longname->close(db->db_longname, 0);
+#endif /* EXTENDED_DB */
db->db_devino->close(db->db_devino, 0);
goto fail_appinit;
}
+
return db;
-
+
fail_appinit:
syslog(LOG_ERR, "cnid_open: db_open failed");
- db_appexit(&db->dbenv);
+ db->dbenv->close(db->dbenv, 0);
+ /* db->dbenv->remove(db->dbenv, db->dbenv->db_home, 0); */
fail_lock:
if (db->lockfd > -1)
close(db->lockfd);
fail_adouble:
- ad_close(&db->rootinfo, ADFLAGS_HF);
fail_db:
free(db);
/*
- * $Id: cnid_private.h,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: cnid_private.h,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*/
#ifndef LIBATALK_CNID_PRIVATE_H
#define CNIDFLAG_ROOTINFO_RO (1 << 0)
#define CNIDFLAG_DB_RO (1 << 1)
+/* the key is in the form of a did/name pair. in this case,
+ * we use 0/RootInfo. */
+#define ROOTINFO_KEY "\0\0\0\0RootInfo"
+#define ROOTINFO_KEYLEN 12
+
typedef struct CNID_private {
u_int32_t magic;
- DB *db_cnid, *db_didname, *db_devino,
- *db_shortname, *db_macname, *db_longname;
- DB_ENV dbenv;
- struct adouble rootinfo;
- int lockfd, flags;
+ DB *db_cnid;
+ DB *db_didname;
+ DB *db_devino;
+#ifdef EXTENDED_DB
+ DB *db_shortname;
+ DB *db_macname;
+ DB *db_longname;
+#endif /* EXTENDED_DB */
+ DB_ENV* dbenv;
+ int lockfd, flags;
} CNID_private;
/* on-disk data format (in network byte order where appropriate) --
const char *name, const int len)
{
static char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
+ char *buf = start;
u_int32_t i;
-
+
if (len > MAXPATHLEN)
return NULL;
i = htonl(st->st_dev);
- memcpy(start, &i, sizeof(i));
+ buf = memcpy(buf, &i, sizeof(i));
i = htonl(st->st_ino);
- memcpy(start + sizeof(i), &i, sizeof(i));
+ buf = memcpy(buf + sizeof(i), &i, sizeof(i));
/* did is already in network byte order */
- memcpy(start + CNID_DEVINO_LEN, &did, sizeof(did));
- memcpy(start + CNID_HEADER_LEN, name, len);
+ buf = memcpy(buf + sizeof(i), &did, sizeof(did));
+ buf = memcpy(buf + sizeof(did), name, len);
*(buf + len) = '\0';
buf += len + 1;
/*
- * $Id: cnid_update.c,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: cnid_update.c,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
*/
#ifdef HAVE_CONFIG_H
/* cnid_update: takes the given cnid and updates the metadata. to
handle the did/name data, there are a bunch of functions to get
and set the various fields. */
-int cnid_update(void *CNID, cnid_t id, const struct stat *st,
- const cnid_t did, const char *name, const int len,
- const char *info, const int infolen)
+int cnid_update(void *CNID, const cnid_t id, const struct stat *st,
+ const cnid_t did, const char *name, const int len/*,
+ const char *info, const int infolen*/)
{
CNID_private *db;
DBT key, data, altdata;
DB_TXN *tid;
- DB_TXNMGR *txnp;
if (!(db = CNID) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO))
return -1;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
memset(&altdata, 0, sizeof(altdata));
- txnp = db->dbenv.tx_info;
/* begin a transaction */
retry:
- if (errno = txn_begin(txnp, NULL, &tid)) {
+ if (errno = txn_begin(db->dbenv, NULL, &tid, 0)) {
return errno;
}
txn_abort(tid);
goto retry;
}
-
+
/* silently fail on a non-existent entry */
if (errno != DB_NOTFOUND) {
txn_abort(tid);
goto update_err;
}
}
-
+
/* delete the old aliases if necessary */
/* make a new entry */
data.data = make_cnid_data(st, did, name, len);
data.size = CNID_HEADER_LEN + len + 1;
-
+
/* put a new dev/ino mapping in */
key.data = data.data;
key.size = CNID_DEVINO_LEN;
}
goto update_err;
}
-
+
/* put a new did/name mapping in */
key.data = data.data + CNID_DEVINO_LEN;
key.size = data.size - CNID_DEVINO_LEN;
}
goto update_err;
}
-
+
/* update the old CNID with the new info */
key.data = &id;
key.size = sizeof(id);
}
goto update_err;
}
-
+
/* end transaction */
- return txn_commit(tid);
+ return txn_commit(tid, 0);
update_err:
syslog(LOG_ERR, "cnid_update: can't update CNID(%x)", id);