+/*
+ Remove all files with file::EA* from adouble dir
+*/
+static void remove_eafiles(const char *name, struct ea *ea)
+{
+ DIR *dp = NULL;
+ struct dirent *ep;
+ char eaname[MAXPATHLEN];
+
+ strlcpy(eaname, name, sizeof(eaname));
+ if (strlcat(eaname, "::EA", sizeof(eaname)) >= sizeof(eaname)) {
+ dbd_log(LOGSTD, "name too long: '%s/%s/%s'", cwdbuf, ADv2_DIRNAME, name);
+ return;
+ }
+
+ if ((chdir(ADv2_DIRNAME)) != 0) {
+ dbd_log(LOGSTD, "Couldn't chdir to '%s/%s': %s",
+ cwdbuf, ADv2_DIRNAME, strerror(errno));
+ return;
+ }
+
+ if ((dp = opendir(".")) == NULL) {
+ dbd_log(LOGSTD, "Couldn't open the directory '%s/%s': %s",
+ cwdbuf, ADv2_DIRNAME, strerror(errno));
+ return;
+ }
+
+ while ((ep = readdir(dp))) {
+ if (strstr(ep->d_name, eaname) != NULL) {
+ dbd_log(LOGSTD, "Removing EA file: '%s/%s/%s'",
+ cwdbuf, ADv2_DIRNAME, ep->d_name);
+ if ((unlink(ep->d_name)) != 0) {
+ dbd_log(LOGSTD, "Error unlinking EA file '%s/%s/%s': %s",
+ cwdbuf, ADv2_DIRNAME, ep->d_name, strerror(errno));
+ }
+ } /* if */
+ } /* while */
+
+ if (dp)
+ closedir(dp);
+
+}
+
+/*
+ Check Extended Attributes files
+*/
+static int check_eafiles(const char *fname)
+{
+ unsigned int count = 0;
+ int ret = 0, remove;
+ struct ea ea;
+ struct stat st;
+ char *eaname;
+
+ if ((ret = ea_open(&volume, 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_SCAN))
+ remove_eafiles(fname, &ea);
+ return -1;
+ }
+
+ /* Check all EAs */
+ while (count < ea.ea_count) {
+ dbd_log(LOGDEBUG, "EA: %s", (*ea.ea_entries)[count].ea_name);
+ remove = 0;
+
+ eaname = ea_path(&ea, (*ea.ea_entries)[count].ea_name, 0);
+
+ if (lstat(eaname, &st) != 0) {
+ if (errno == ENOENT)
+ dbd_log(LOGSTD, "Missing EA: %s/%s", cwdbuf, eaname);
+ else
+ dbd_log(LOGSTD, "Bogus EA: %s/%s", cwdbuf, eaname);
+ remove = 1;
+ } else if (st.st_size != (*ea.ea_entries)[count].ea_size) {
+ dbd_log(LOGSTD, "Bogus EA: %s/%s, removing it...", cwdbuf, eaname);
+ remove = 1;
+ if ((unlink(eaname)) != 0)
+ dbd_log(LOGSTD, "Error removing EA file '%s/%s': %s",
+ cwdbuf, eaname, strerror(errno));
+ }
+
+ if (remove) {
+ /* Be CAREFUL here! This should do what ea_delentry does. ea_close relies on it !*/
+ free((*ea.ea_entries)[count].ea_name);
+ (*ea.ea_entries)[count].ea_name = NULL;
+ }
+
+ count++;
+ } /* while */
+
+ ea_close(&ea);
+ return ret;
+}
+