diff --git a/exec/delfiles.js b/exec/delfiles.js new file mode 100755 index 0000000000000000000000000000000000000000..7440a934fe381c34669b7fed202c16e01c70de51 --- /dev/null +++ b/exec/delfiles.js @@ -0,0 +1,131 @@ +// Delete files from Synchronet v3.19 file bases + +require("sbbsdefs.js", "DIR_SINCEDL"); + +"use strict"; + +var dir_list = []; +var exclude = []; +var options = {}; +for(var i = 0; i < argc; i++) { + var arg = argv[i]; + if(arg[0] == '-') { + var opt = arg; + while(opt[0] == '-') + opt = opt.slice(1); + if(opt == "help" || opt == "?") { + writeln("usage: [-options] [[dir_code] [...]]"); + writeln("options:"); + writeln(" -lib=<name> search for duplicates in specified library only"); + writeln(" -ex=<filename> add to excluded file name list (case-insensitive)"); + writeln(" -offline remove files that are offline (don't exist on disk)"); + writeln(" -test don't actually remove files, just report findings"); + exit(0); + } + if(opt.indexOf("ex=") == 0) { + exclude.push(opt.slice(3).toUpperCase()); + continue; + } + if(opt.indexOf("lib=") == 0) { + var lib = opt.slice(4); + if(!file_area.lib[lib]) { + alert("Library not found: " + lib); + exit(1); + } + for(var j = 0; j < file_area.lib[lib].dir_list.length; j++) + dir_list.push(file_area.lib[lib].dir_list[j].code); + continue; + } + options[opt] = true; + continue; + } + dir_list.push(arg); +} + +if(dir_list.length < 1) + for(var dir in file_area.dir) + dir_list.push(dir); + +var now = time(); +for(var i in dir_list) { + var dir_code = dir_list[i]; + var dir = file_area.dir[dir_code]; + var base = new FileBase(dir_code); + if(!base.open()) + throw new Error(base.last_error); + if(options.offline) { + log("Purging offline files"); + var list = base.get_names(/* sort: */false); + var removed = 0; + for(var j = 0; j < list.length; j++) { + var file = list[j]; + if(exclude.indexOf(file.toUpperCase()) >= 0) + continue; + if(base.get_size(file) < 0) { + log("Removing offline file: " + base.get_path(file)); + if(options.test) + removed++; + else { + if(!base.remove(file, /* delete: */true)) + alert(base.error); + else + removed++; + } + } + } + log("Removed " + removed + " offline files"); + } + if(base.max_age) { + log("Purging old files, imposing max age of " + base.max_age + " days"); + var list = base.get_list(FileBase.DETAIL.NORM, /* sort: */false); + var removed = 0; + for(var j = 0; j < list.length; j++) { + var file = list[j]; + if(exclude.indexOf(file.name.toUpperCase()) >= 0) + continue; + var t = file.added; + var age_desc = "uploaded"; + if(file.last_downloaded + && (file_area.dir[dir_code].settings & DIR_SINCEDL)) { + t = file.last_downloaded; + age_desc = "last downloaded"; + } + var file_age = Math.floor((now - t) / (24 * 60 * 60)); + if(file_age > base.max_age) { + log("Removing " + base.get_path(file.name) + " " + age_desc + " " + file_age + " days ago"); + if(options.test) + removed++; + else { + if(!base.remove(file.name, /* delete: */true)) + alert(base.error); + else + removed++; + } + } + } + log("Removed " + removed + " of " + list.length + " files due to age of " + base.max_age + " days"); + } + if(base.max_files) { + log("Purging excess files, imposing max files limit of " + base.max_files); + var list = base.get_list(FileBase.DETAIL.MIN, /* sort: */false); + var removed = 0; + var excess = list.length - base.max_files; + for(var j = 0; j < list.length && removed < excess; j++) { + var file = list[j]; + if(exclude.indexOf(file.name.toUpperCase()) >= 0) + continue; + log("Removing " + file.name); + if(options.test) + removed++; + else { + if(!base.remove(file.name, /* delete: */true)) + alert(base.error); + else + removed++; + } + } + log("Removed " + removed + " of " + list.length + " files due to max file limit of " + base.max_files); + } + + base.close(); +}