예제 #1
0
void GMSyncTask::update() {
  GMTrackFilenameList tracklist;
  FXStringList        pathlist;
  FXStat              data;

  database->beginTask();

  taskmanager->setStatus("Updating Files..");

  for (FXint i=0;i<files.no() && processing;i++) {

    database->getPathList(files[i],pathlist);

    for (FXint p=0;p<pathlist.no() && processing;p++) {

      const FXString & path  = pathlist[p];

      if (!options.exclude_folder.empty() && filter_path(options.exclude_folder,path))
        continue;

      const FXint path_index = dbtracks.hasPath(path);

      database->getFileList(path,tracklist);

      for (FXint t=0;t<tracklist.no() && processing;t++) {

        const FXString & name = tracklist[t].filename;

        if (options.exclude_file.empty() || !FXPath::match(name,options.exclude_file,matchflags)) {
          if (FXStat::statFile(path+PATHSEPSTRING+name,data)) {
            if (data.isReadable())
              parse_update(path,name,options_sync.update_always ? forever : data.modified(),path_index);
            else
              parse_update(path,name,0,path_index);
            }
          else if (options_sync.remove_missing) {
            dbtracks.remove(tracklist[t].id);
            changed=true;
            }
          }
        }
      if (processing) update_tracks(path_index);
      }
    }
  if (changed) {
    database->sync_album_year();
    database->sync_tracks_removed();
    }
  database->commitTask();
  }
예제 #2
0
void GMSyncTask::remove_missing() {
  FXStringList        pathlist;
  GMTrackFilenameList tracklist;

  database->beginTask();

  taskmanager->setStatus("Clearing Files..");

  for (FXint i=0;i<files.no() && processing;i++) {

    database->getPathList(files[i],pathlist);

    for (FXint p=0;p<pathlist.no() && processing;p++) {

      if (!options.exclude_folder.empty() && filter_path(options.exclude_folder,pathlist[p]))
        continue;

      database->getFileList(pathlist[p],tracklist);

      for (FXint t=0;t<tracklist.no() && processing;t++) {

        const FXString & name = tracklist[t].filename;

        if (database->interrupt)
          database->waitTask();

        if (options.exclude_file.empty() || !FXPath::match(name,options.exclude_file,matchflags)) {
          if (options_sync.remove_all || !FXStat::exists(pathlist[p]+PATHSEPSTRING+name)){
            dbtracks.remove(tracklist[t].id);
            changed=true;
            }
          }
        }
      }
    }
  if (changed) database->sync_tracks_removed();
  database->commitTask();
  }
예제 #3
0
void state_device(struct snapraid_state* state, int operation, tommy_list* filterlist_disk)
{
	tommy_node* i;
	unsigned j;
	tommy_list high;
	tommy_list low;
	int ret;

	switch (operation) {
	case DEVICE_UP : msg_progress("Spinup...\n"); break;
	case DEVICE_DOWN : msg_progress("Spindown...\n"); break;
	}

	tommy_list_init(&high);
	tommy_list_init(&low);

	/* for all disks */
	for (i = state->disklist; i != 0; i = i->next) {
		struct snapraid_disk* disk = i->data;
		devinfo_t* entry;

		if (filterlist_disk != 0 && filter_path(filterlist_disk, 0, disk->name, 0) != 0)
			continue;

		entry = calloc_nofail(1, sizeof(devinfo_t));

		entry->device = disk->device;
		pathcpy(entry->name, sizeof(entry->name), disk->name);
		pathcpy(entry->mount, sizeof(entry->mount), disk->dir);
		pathcpy(entry->smartctl, sizeof(entry->smartctl), disk->smartctl);

		tommy_list_insert_tail(&high, &entry->node, entry);
	}

	/* for all parities */
	for (j = 0; j < state->level; ++j) {
		devinfo_t* entry;

		if (filterlist_disk != 0 && filter_path(filterlist_disk, 0, lev_config_name(j), 0) != 0)
			continue;

		entry = calloc_nofail(1, sizeof(devinfo_t));

		entry->device = state->parity[j].device;
		pathcpy(entry->name, sizeof(entry->name), lev_config_name(j));
		pathcpy(entry->mount, sizeof(entry->mount), state->parity[j].path);
		pathcpy(entry->smartctl, sizeof(entry->smartctl), state->parity[j].smartctl);
		pathcut(entry->mount); /* remove the parity file */

		tommy_list_insert_tail(&high, &entry->node, entry);
	}

	if (state->opt.fake_device) {
		ret = devtest(&low, operation);
	} else {
		int others = operation == DEVICE_SMART;

		ret = devquery(&high, &low, operation, others);
	}

	/* if the list is empty, it's not supported in this platform */
	if (ret == 0 && tommy_list_empty(&low))
		ret = -1;

	if (ret != 0) {
		const char* ope = 0;
		switch (operation) {
		case DEVICE_UP : ope = "Spinup"; break;
		case DEVICE_DOWN : ope = "Spindown"; break;
		case DEVICE_LIST : ope = "Device listing"; break;
		case DEVICE_SMART : ope = "Smart"; break;
		}
		log_fatal("%s is unsupported in this platform.\n", ope);
	} else {
		if (operation == DEVICE_LIST) {
			for (i = tommy_list_head(&low); i != 0; i = i->next) {
				devinfo_t* devinfo = i->data;
				devinfo_t* parent = devinfo->parent;
#ifdef _WIN32
				printf("%" PRIu64 "\t%s\t%08" PRIx64 "\t%s\t%s\n", devinfo->device, devinfo->wfile, parent->device, parent->wfile, parent->name);
#else
				printf("%u:%u\t%s\t%u:%u\t%s\t%s\n", major(devinfo->device), minor(devinfo->device), devinfo->file, major(parent->device), minor(parent->device), parent->file, parent->name);
#endif
			}
		}

		if (operation == DEVICE_SMART)
			state_smart(state->level + tommy_list_count(&state->disklist), &low);
	}

	tommy_list_foreach(&high, free);
	tommy_list_foreach(&low, free);
}
예제 #4
0
static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk, const char* dir, const char* sub)
{
	DIR* d;

	d = opendir(dir);
	if (!d) {
		/* LCOV_EXCL_START */
		msg_error("Error opening directory '%s'. %s.\n", dir, strerror(errno));
		exit(EXIT_FAILURE);
		/* LCOV_EXCL_STOP */
	}

	while (1) {
		char path_next[PATH_MAX];
		char sub_next[PATH_MAX];
		char out[PATH_MAX];
		struct snapraid_filter* reason = 0;
		struct stat st;
		const char* name;
		struct dirent* dd;

		/* clear errno to detect erroneous conditions */
		errno = 0;
		dd = readdir(d);
		if (dd == 0 && errno != 0) {
			/* LCOV_EXCL_START */
			msg_error("Error reading directory '%s'. %s.\n", dir, strerror(errno));
			exit(EXIT_FAILURE);
			/* LCOV_EXCL_STOP */
		}
		if (dd == 0) {
			break; /* finished */
		}

		/* skip "." and ".." files */
		name = dd->d_name;
		if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
			continue;

		pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
		pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);

		/* exclude hidden files even before calling lstat() */
		if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) {
			msg_verbose("Excluding hidden '%s'\n", path_next);
			continue;
		}

		/* exclude content files even before calling lstat() */
		if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) {
			msg_verbose("Excluding content '%s'\n", path_next);
			continue;
		}

#if HAVE_STRUCT_DIRENT_D_STAT
		/* convert dirent to lstat result */
		dirent_lstat(dd, &st);

		/* if the st_mode field is missing, takes care to fill it using normal lstat() */
		/* at now this can happen only in Windows (with HAVE_STRUCT_DIRENT_D_STAT defined), */
		/* because we use a directory reading method that doesn't read info about ReparsePoint. */
		/* Note that here we cannot call here lstat_sync(), because we don't know what kind */
		/* of file is it, and lstat_sync() doesn't always work */
		if (st.st_mode == 0) {
			if (lstat(path_next, &st) != 0) {
				/* LCOV_EXCL_START */
				msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
				exit(EXIT_FAILURE);
				/* LCOV_EXCL_STOP */
			}
		}
#else
		/* get lstat info about the file */
		if (lstat(path_next, &st) != 0) {
			/* LCOV_EXCL_START */
			msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
			exit(EXIT_FAILURE);
			/* LCOV_EXCL_STOP */
		}
#endif

		if (S_ISREG(st.st_mode)) {
			if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
				search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
			} else {
				msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
			}
		} else if (S_ISDIR(st.st_mode)) {
			if (disk == 0 || filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
				pathslash(path_next, sizeof(path_next));
				pathslash(sub_next, sizeof(sub_next));
				search_dir(state, disk, path_next, sub_next);
			} else {
				msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
			}
		}
	}

	if (closedir(d) != 0) {
		/* LCOV_EXCL_START */
		msg_error("Error closing directory '%s'. %s.\n", dir, strerror(errno));
		exit(EXIT_FAILURE);
		/* LCOV_EXCL_STOP */
	}
}
예제 #5
0
/**
 *
 * \brief Handle the file.
 *
 * \param file_name is the filename which has to be checked against the find options.
 * \param file_info file information of file_name which has to be checked against the find options.
 * \param params is the program argument vector.
 *
 * \return int represents the exit status of do_file.
 * \retval EXIT_SUCCESS successful exit status.
 * \retval EXIT_FAILURE failing exit status.
 */
static int do_file(const char* file_name, StatType* file_info, const char* const* params)
{

    int i = 1;
    boolean printed_print = FALSE; /* flag for: already printed */
    boolean printed_ls = FALSE; /* flag for: already printed in ls mode*/
    boolean to_print_ls = FALSE; /* flag for: must be printed in ls mode*/
    boolean matched = FALSE; /* flag for: line meets filter criteria */
    boolean filter = FALSE; /* flag for: result of filter */
    boolean filtered = FALSE; /* flag for: at least one filter has been applied */
    boolean path_given = FALSE; /* flag for: first commandline parameter is a file/dir */
    char test_char = '\0';

    /*check if first command line parameter is an option or a file/dir*/
    test_char = *params[1];
    path_given = ('-' == test_char) ? FALSE : TRUE;
    matched = path_given;

    /* loop all command line parameters */
    while (NULL != params[i])
    {
        /* could be later optimzed by remembering for each params[i] element, if it
         * is matched for the i-th parameter, store for each filter in an bool filter_array[argc]
         * if strcmp matched for the filter e.g for type cmp_filter_type[arg]
         */
        /* apply filters */
        if (strcmp(params[i], PARAM_STR_TYPE) == 0)
        {
            filter = filter_type(i, params, file_info);
            matched = matched && filter;
            filtered = TRUE;
            ++i;
            continue;
        }

        if (strcmp(params[i], PARAM_STR_USER) == 0)
        {
            filter = filter_user(i, params, file_info);
            matched = matched && filter;
            filtered = TRUE;
            ++i;
            continue;
        }

        if (strcmp(params[i], PARAM_STR_NOUSER) == 0)
        {
            filter = filter_nouser(file_info);
            matched = matched && filter;
            filtered = TRUE;
            ++i;
            continue;
        }

        if (strcmp(params[i], PARAM_STR_NAME) == 0)
        {
            filter = filter_name(file_name, i, params);
            matched = matched && filter;
            filtered = TRUE;
            ++i;
            continue;
        }

        if (strcmp(params[i], PARAM_STR_PATH) == 0)
        {
            filter = filter_path(file_name, i, params);
            matched = matched && filter;
            filtered = TRUE;
            ++i;
            continue;
        }

        /* apply actions */
        if (strcmp(params[i], PARAM_STR_LS) == 0)
        {
            if (filtered && matched)
            {
                print_detail_ls(file_name, file_info);
                printed_ls = TRUE;
            }
            else
            {
                /* special case -ls defined before filter parameters */
                to_print_ls = TRUE;
            }
        }
        if (strcmp(params[i], PARAM_STR_PRINT) == 0)
        {
            if (filtered && matched)
            {
                print_detail_print(file_name);
                printed_print = TRUE;
            }
        }

        ++i;
    }

    /* special cases */
    /* no -print action or no filter parameter on command line */
    if ((matched && !printed_print && !printed_ls) || (!filtered))
    {
        if (to_print_ls)
        {
            print_detail_ls(file_name, file_info);
        }
        else
        {
            print_detail_print(file_name);
        }
    }

    return EXIT_SUCCESS;
}
예제 #6
0
bool
ClientContext::parse()
{
	return filter_path(m_input.c_str(), m_path, m_context)
		&& parseContext(m_input, m_data);
}