X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fcnid_dbd%2Fcmd_dbd_scanvol.c;h=ba1cd623e0b54dd778ccf2b5a80cdfc3df0a72d4;hp=48deb5f08d9c73dd34c40f89c23f2dae304afe4b;hb=e421da9fdfa2026757b60277a83614fe4a7db2ab;hpb=30963c2b3ee34139e0c3307677d181178a15f37f diff --git a/etc/cnid_dbd/cmd_dbd_scanvol.c b/etc/cnid_dbd/cmd_dbd_scanvol.c index 48deb5f0..ba1cd623 100644 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@ -49,7 +49,6 @@ static char cwdbuf[MAXPATHLEN+1]; static struct vol *vol; -static DBD *dbd_rebuild; static dbd_flags_t dbd_flags; static char stamp[CNID_DEV_LEN]; static char *netatalk_dirs[] = { @@ -611,6 +610,22 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi return db_cnid; } +static void check_orphaned(const char *name) +{ + int rc; + struct stat sb; + + if (strlen(name) < 3) + return; + + rc = lstat(&name[2], &sb); + + if (rc != 0 && errno == ENOENT) { + dbd_log(LOGSTD, "Removing orphaned AppleDouble \"%s/%s\"", cwdbuf, name); + unlink(name); + } +} + /* This is called recursively for all dirs. volroot=1 means we're in the volume root dir, 0 means we aren't. @@ -686,10 +701,8 @@ static int dbd_readdir(int volroot, cnid_t did) switch (st.st_mode & S_IFMT) { case S_IFREG: case S_IFDIR: - break; case S_IFLNK: - dbd_log(LOGDEBUG, "Ignoring symlink %s/%s", cwdbuf, ep->d_name); - continue; + break; default: dbd_log(LOGSTD, "Bad filetype: %s/%s", cwdbuf, ep->d_name); if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { @@ -720,47 +733,36 @@ static int dbd_readdir(int volroot, cnid_t did) Tests **************************************************************************/ + /* Check for invalid names and orphaned ._ files */ + if (S_ISREG(st.st_mode) && (strncmp(ep->d_name, "._", strlen("._")) == 0)) + check_orphaned(ep->d_name); + + if (!vol->vfs->vfs_validupath(vol, ep->d_name)) { + dbd_log(LOGSTD, "Ignoring \"%s/%s\"", cwdbuf, ep->d_name); + continue; + } + /* Check for appledouble file, create if missing, but only if we have addir */ const char *name = NULL; adfile_ok = -1; if (ADDIR_OK) adfile_ok = check_adfile(ep->d_name, &st, &name); - if (name == NULL) { - name = ep->d_name; - } else { - update_cnid(did, &st, ep->d_name, name); - } + if (!S_ISLNK(st.st_mode)) { + if (name == NULL) { + name = ep->d_name; + } else { + update_cnid(did, &st, ep->d_name, name); + } - /* Check CNIDs */ - cnid = check_cnid(name, did, &st, adfile_ok); + /* Check CNIDs */ + cnid = check_cnid(name, did, &st, adfile_ok); - /* Now add this object to our rebuild dbd */ - if (cnid && dbd_rebuild) { - static uint count = 0; - rqst.cnid = rply.cnid; - ret = dbd_rebuild_add(dbd_rebuild, &rqst, &rply); - if (dbif_txn_close(dbd_rebuild, ret) != 0) - return -1; - if (rply.result != CNID_DBD_RES_OK) { - dbd_log( LOGSTD, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db", - cnid, cwdbuf, name); - return -1; - } - count++; - if (count == 10000) { - if (dbif_txn_checkpoint(dbd_rebuild, 0, 0, 0) < 0) { - dbd_log(LOGSTD, "Error checkpointing!"); - return -1; - } - count = 0; - } + /* Check EA files */ + if (vol->v_vfs_ea == AFPVOL_EA_AD) + check_eafiles(name); } - /* Check EA files */ - if (vol->v_vfs_ea == AFPVOL_EA_AD) - check_eafiles(name); - /************************************************************************** Recursion **************************************************************************/