int main(int argc, char** argv) { int i; /* initialize MPI */ MPI_Init(&argc, &argv); mfu_init(); /* get our rank and the size of comm_world */ int rank, ranks; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &ranks); /* parse command line options */ char* inputname = NULL; char* regex_exp = NULL; int walk = 0; int exclude = 0; int name = 0; int dryrun = 0; int option_index = 0; static struct option long_options[] = { {"input", 1, 0, 'i'}, {"lite", 0, 0, 'l'}, {"exclude", 1, 0, 'e'}, {"match", 1, 0, 'a'}, {"name", 0, 0, 'n'}, {"help", 0, 0, 'h'}, {"dryrun", 0, 0, 'd'}, {"verbose", 0, 0, 'v'}, {0, 0, 0, 0} }; int usage = 0; while (1) { int c = getopt_long( argc, argv, "i:nlhv", long_options, &option_index ); if (c == -1) { break; } switch (c) { case 'i': inputname = MFU_STRDUP(optarg); break; case 'l': walk_stat = 0; break; case 'e': regex_exp = MFU_STRDUP(optarg); exclude = 1; break; case 'a': regex_exp = MFU_STRDUP(optarg); exclude = 0; break; case 'n': name = 1; break; case 'h': usage = 1; break; case 'd': dryrun = 1; break; case 'v': mfu_debug_level = MFU_LOG_VERBOSE; break; case '?': usage = 1; break; default: if (rank == 0) { printf("?? getopt returned character code 0%o ??\n", c); } } } /* paths to walk come after the options */ int numpaths = 0; mfu_param_path* paths = NULL; if (optind < argc) { /* got a path to walk */ walk = 1; /* determine number of paths specified by user */ numpaths = argc - optind; /* allocate space for each path */ paths = (mfu_param_path*) MFU_MALLOC((size_t)numpaths * sizeof(mfu_param_path)); /* process each path */ char** argpaths = &argv[optind]; mfu_param_path_set_all(numpaths, argpaths, paths); /* advance to next set of options */ optind += numpaths; /* don't allow input file and walk */ if (inputname != NULL) { usage = 1; } } else { /* if we're not walking, we must be reading, * and for that we need a file */ if (inputname == NULL) { usage = 1; } } /* print usage if we need to */ if (usage) { if (rank == 0) { print_usage(); } mfu_finalize(); MPI_Finalize(); return 1; } /* create an empty file list */ mfu_flist flist = mfu_flist_new(); /* get our list of files, either by walking or reading an * input file */ if (walk) { /* walk list of input paths */ mfu_param_path_walk(numpaths, paths, walk_stat, flist, dir_perm); } else { /* read list from file */ mfu_flist_read_cache(inputname, flist); } /* assume we'll use the full list */ mfu_flist srclist = flist; /* filter the list if needed */ mfu_flist filtered_flist = MFU_FLIST_NULL; if (regex_exp != NULL) { /* filter the list based on regex */ filtered_flist = mfu_flist_filter_regex(flist, regex_exp, exclude, name); /* update our source list to use the filtered list instead of the original */ srclist = filtered_flist; } /* only actually delete files if the user wasn't doing a dry run */ if (dryrun) { /* just print what we would delete without actually doing anything, * this is useful if the user is trying to get a regex right */ mfu_flist_print(srclist); } else { /* remove files */ mfu_flist_unlink(srclist); } /* free list if it was used */ if (filtered_flist != MFU_FLIST_NULL){ /* free the filtered flist (if any) */ mfu_flist_free(&filtered_flist); } /* free the file list */ mfu_flist_free(&flist); /* free the path parameters */ mfu_param_path_free_all(numpaths, paths); /* free memory allocated to hold params */ mfu_free(&paths); /* free the regex string if we have one */ mfu_free(®ex_exp); /* free the input file name */ mfu_free(&inputname); /* shut down MPI */ mfu_finalize(); MPI_Finalize(); return 0; }
int main(int argc, char** argv) { int i; /* initialize MPI */ MPI_Init(&argc, &argv); mfu_init(); /* get our rank and the size of comm_world */ int rank, ranks; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &ranks); /* pointer to mfu_walk_opts */ mfu_walk_opts_t* walk_opts = mfu_walk_opts_new(); /* TODO: extend options * - allow user to cache scan result in file * - allow user to load cached scan as input * * - allow user to filter by user, group, or filename using keyword or regex * - allow user to specify time window * - allow user to specify file sizes * * - allow user to sort by different fields * - allow user to group output (sum all bytes, group by user) */ char* inputname = NULL; char* outputname = NULL; char* sortfields = NULL; char* distribution = NULL; int file_histogram = 0; int walk = 0; int print = 0; int text = 0; struct distribute_option option; /* verbose by default */ mfu_debug_level = MFU_LOG_VERBOSE; int option_index = 0; static struct option long_options[] = { {"input", 1, 0, 'i'}, {"output", 1, 0, 'o'}, {"text", 0, 0, 't'}, {"lite", 0, 0, 'l'}, {"sort", 1, 0, 's'}, {"distribution", 1, 0, 'd'}, {"file_histogram", 0, 0, 'f'}, {"print", 0, 0, 'p'}, {"verbose", 0, 0, 'v'}, {"quiet", 0, 0, 'q'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; int usage = 0; while (1) { int c = getopt_long( argc, argv, "i:o:tls:d:fpvqh", long_options, &option_index ); if (c == -1) { break; } switch (c) { case 'i': inputname = MFU_STRDUP(optarg); break; case 'o': outputname = MFU_STRDUP(optarg); break; case 'l': /* don't stat each file on the walk */ walk_opts->use_stat = 0; break; case 's': sortfields = MFU_STRDUP(optarg); break; case 'd': distribution = MFU_STRDUP(optarg); break; case 'f': file_histogram = 1; break; case 'p': print = 1; break; case 'v': mfu_debug_level = MFU_LOG_VERBOSE; break; case 'q': mfu_debug_level = 0; break; case 't': text = 1; break; case 'h': usage = 1; break; case '?': usage = 1; break; default: if (rank == 0) { printf("?? getopt returned character code 0%o ??\n", c); } } } /* paths to walk come after the options */ int numpaths = 0; mfu_param_path* paths = NULL; if (optind < argc) { /* got a path to walk */ walk = 1; /* determine number of paths specified by user */ numpaths = argc - optind; /* allocate space for each path */ paths = (mfu_param_path*) MFU_MALLOC((size_t)numpaths * sizeof(mfu_param_path)); /* process each path */ char** p = &argv[optind]; mfu_param_path_set_all((uint64_t)numpaths, (const char**)p, paths); optind += numpaths; /* don't allow user to specify input file with walk */ if (inputname != NULL) { usage = 1; } } else { /* if we're not walking, we must be reading, * and for that we need a file */ if (inputname == NULL) { usage = 1; } } /* if user is trying to sort, verify the sort fields are valid */ if (sortfields != NULL) { int maxfields; int nfields = 0; char* sortfields_copy = MFU_STRDUP(sortfields); if (walk_opts->use_stat) { maxfields = 7; char* token = strtok(sortfields_copy, ","); while (token != NULL) { if (strcmp(token, "name") != 0 && strcmp(token, "-name") != 0 && strcmp(token, "user") != 0 && strcmp(token, "-user") != 0 && strcmp(token, "group") != 0 && strcmp(token, "-group") != 0 && strcmp(token, "uid") != 0 && strcmp(token, "-uid") != 0 && strcmp(token, "gid") != 0 && strcmp(token, "-gid") != 0 && strcmp(token, "atime") != 0 && strcmp(token, "-atime") != 0 && strcmp(token, "mtime") != 0 && strcmp(token, "-mtime") != 0 && strcmp(token, "ctime") != 0 && strcmp(token, "-ctime") != 0 && strcmp(token, "size") != 0 && strcmp(token, "-size") != 0) { /* invalid token */ if (rank == 0) { printf("Invalid sort field: %s\n", token); } usage = 1; } nfields++; token = strtok(NULL, ","); } } else { maxfields = 1; char* token = strtok(sortfields_copy, ","); while (token != NULL) { if (strcmp(token, "name") != 0 && strcmp(token, "-name") != 0) { /* invalid token */ if (rank == 0) { printf("Invalid sort field: %s\n", token); } usage = 1; } nfields++; token = strtok(NULL, ","); } } if (nfields > maxfields) { if (rank == 0) { printf("Exceeded maximum number of sort fields: %d\n", maxfields); } usage = 1; } mfu_free(&sortfields_copy); } if (distribution != NULL) { if (distribution_parse(&option, distribution) != 0) { if (rank == 0) { printf("Invalid distribution argument: %s\n", distribution); } usage = 1; } else if (rank == 0 && option.separator_number != 0) { printf("Separators: "); for (i = 0; i < option.separator_number; i++) { if (i != 0) { printf(", "); } printf("%"PRIu64, option.separators[i]); } printf("\n"); } } if (usage) { if (rank == 0) { print_usage(); } MPI_Finalize(); return 0; } /* TODO: check stat fields fit within MPI types */ // if (sizeof(st_uid) > uint64_t) error(); etc... /* create an empty file list with default values */ mfu_flist flist = mfu_flist_new(); if (walk) { /* walk list of input paths */ mfu_flist_walk_param_paths(numpaths, paths, walk_opts, flist); } else { /* read data from cache file */ mfu_flist_read_cache(inputname, flist); } /* TODO: filter files */ //filter_files(&flist); /* sort files */ if (sortfields != NULL) { /* TODO: don't sort unless all_count > 0 */ mfu_flist_sort(sortfields, &flist); } /* print details for individual files */ if (print) { mfu_flist_print(flist); } /* print summary statistics of flist */ mfu_flist_print_summary(flist); /* print distribution if user specified this option */ if (distribution != NULL || file_histogram) { print_flist_distribution(file_histogram, &option, &flist, rank); } /* write data to cache file */ if (outputname != NULL) { if (!text) { mfu_flist_write_cache(outputname, flist); } else { mfu_flist_write_text(outputname, flist); } } /* free users, groups, and files objects */ mfu_flist_free(&flist); /* free memory allocated for options */ mfu_free(&distribution); mfu_free(&sortfields); mfu_free(&outputname); mfu_free(&inputname); /* free the path parameters */ mfu_param_path_free_all(numpaths, paths); /* free memory allocated to hold params */ mfu_free(&paths); /* free the walk options */ mfu_walk_opts_delete(&walk_opts); /* shut down MPI */ mfu_finalize(); MPI_Finalize(); return 0; }