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(); }
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(); }
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); }
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 */ } }
/** * * \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; }
bool ClientContext::parse() { return filter_path(m_input.c_str(), m_path, m_context) && parseContext(m_input, m_data); }