/*
- * $Id: file.c,v 1.141 2010-03-12 15:16:49 franklahm Exp $
+ * $Id: file.c,v 1.141 2010/03/12 15:16:49 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
(1 << FILPBIT_UNIXPR)))
/* -------------------------- */
-u_int32_t get_id(struct vol *vol, struct adouble *adp, const struct stat *st,
+u_int32_t get_id(const struct vol *vol, struct adouble *adp, const struct stat *st,
const cnid_t did, char *upath, const int len)
{
+ static int first = 1; /* mark if this func is called the first time */
u_int32_t adcnid;
u_int32_t dbcnid = CNID_INVALID;
+ restart:
if (vol->v_cdb != NULL) {
/* prime aint with what we think is the cnid, set did to zero for
catching moved files */
case CNID_ERR_PARAM:
LOG(log_error, logtype_afpd, "get_id: Incorrect parameters passed to cnid_add");
afp_errno = AFPERR_PARAM;
- return CNID_INVALID;
+ goto exit;
case CNID_ERR_PATH:
afp_errno = AFPERR_PARAM;
- return CNID_INVALID;
+ goto exit;
default:
+ /* Close CNID backend if "dbd" and switch to temp in-memory "tdb" */
+ /* we have to do it here for "dbd" because it uses "lazy opening" */
+ /* In order to not end in a loop somehow with goto restart below */
+ /* */
+ if (first && (strcmp(vol->v_cnidscheme, "dbd") == 0)) {
+ cnid_close(vol->v_cdb);
+ free(vol->v_cnidscheme);
+ vol->v_cnidscheme = strdup("tdb");
+
+ int flags = CNID_FLAG_MEMORY;
+ if ((vol->v_flags & AFPVOL_NODEV)) {
+ flags |= CNID_FLAG_NODEV;
+ }
+ LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.",
+ vol->v_path);
+ vol->v_cdb = cnid_open(vol->v_path, vol->v_umask, "tdb", flags, NULL, NULL);
+ if (vol->v_cdb) {
+ /* deactivate cnid caching/storing in AppleDouble files and set ro mode*/
+ vol->v_flags &= ~AFPVOL_CACHE;
+ vol->v_flags |= AFPVOL_RO;
+ #ifdef SERVERTEXT
+ /* kill ourself with SIGUSR2 aka msg pending */
+ setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB instead."
+ "Check server messages for details. Switching to read-only mode.");
+ kill(getpid(), SIGUSR2);
+ #endif
+ goto restart; /* not try again with the temp CNID db */
+ } else {
+ #ifdef SERVERTEXT
+ setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB failed too!"
+ "Check server messages for details, can't recover from this state!");
+ #endif
+ }
+ }
afp_errno = AFPERR_MISC;
- return CNID_INVALID;
+ goto exit;
}
}
else if (adp && (adcnid != dbcnid)) {
}
}
}
+
+ exit:
+ first = 0;
return dbcnid;
}
struct stat *st;
struct maccess ma;
-#ifdef DEBUG
- LOG(log_debug9, logtype_afpd, "begin getmetadata:");
-#endif /* DEBUG */
upath = path->u_name;
st = &path->st;
#endif
memcpy(data, &ashort, sizeof( ashort ));
data += sizeof( ashort );
+ LOG(log_debug, logtype_afpd, "metadata('%s'): AFP Attributes: %04x",
+ path->u_name, ntohs(ashort));
break;
case FILPBIT_PDID :
memcpy(data, &dir->d_did, sizeof( u_int32_t ));
data += sizeof( u_int32_t );
+ LOG(log_debug, logtype_afpd, "metadata('%s'): Parent DID: %u",
+ path->u_name, ntohl(dir->d_did));
break;
case FILPBIT_CDATE :
case FILPBIT_FNUM :
memcpy(data, &id, sizeof( id ));
data += sizeof( id );
+ LOG(log_debug, logtype_afpd, "metadata('%s'): CNID: %u",
+ path->u_name, ntohl(id));
break;
case FILPBIT_DFLEN :
int opened = 0;
int rc;
-#ifdef DEBUG
- LOG(log_debug9, logtype_default, "begin getfilparams:");
-#endif /* DEBUG */
-
opened = PARAM_NEED_ADP(bitmap);
adp = NULL;
if ( adp ) {
ad_close_metadata( adp);
}
-#ifdef DEBUG
- LOG(log_debug9, logtype_afpd, "end getfilparams:");
-#endif /* DEBUG */
return( rc );
}
}
if (NULL == ( dir = dirlookup( vol, id )) ) {
+ if (afp_errno == AFPERR_NOOBJ) {
+ err = AFPERR_NOOBJ;
+ goto delete;
+ }
return( AFPERR_PARAM );
}
else if (S_ISDIR(st.st_mode)) /* directories are bad */
return AFPERR_BADTYPE;
+delete:
if (cnid_delete(vol->v_cdb, fileid)) {
switch (errno) {
case EROFS: