diff --git a/exec/fileareas.js b/exec/fileareas.js
new file mode 100644
index 0000000000000000000000000000000000000000..c47b00ac0da15713bc66b57c09830759c54c6664
--- /dev/null
+++ b/exec/fileareas.js
@@ -0,0 +1,183 @@
+// $Id$
+
+// *****************************************************************
+// Output a file area listing from the BBS's file area configuration
+// *****************************************************************
+
+// Description:
+// The output of this utility module contains information about file
+// "directories", not the files that might be stored in those directories
+// (use the 'filelist' utility for that purpose).
+
+// The default behavior is to output a tab-delimited list of the configuration
+// properties of all directories in all file libraries in SCFG->File Areas.
+
+// To include column headings, use the -hdr command-line option, for example:
+// jsexec fileareas.js -hdr > fileareas.tab
+
+// To restrict the output to specific libraries, specify one or more 
+// '-lib <library_name>' options on the command-line.
+
+// To output a comma-delimited file (e.g. suitable for import into spreadsheet
+// applications), you may to quote string values, for example:
+// jsexec fileareas.js -delim , -quote > fileareas.cvs
+
+// If you specify property names on the command-line, only those configuration
+// properties will be included in the output. You may also follow a property
+// name with the -fmt <format> or -upr options to specify a printf-style
+// format string or to convert the value to uppercase before printing. a -lwr
+// (lowercase) option is also available.
+
+// As an example, to generate a RAID/FILEBONE.NA/FILEGATE.ZXX format listing:
+// jsexec fileareas.js code -upr -fmt "Area %-16s 0 !" description
+
+// When using the -json or -json_space command-line options, the output will
+// be formatted as JSON objects and certain options (e.g. -delim, -hdr, -quote)
+// will have no effect on the output. For example, to output a pretty-printed
+// JSON represenation of all file areas:
+// jsexec fileareas.js -json 4 > fileareas.json
+
+// NOTE:
+// By default, JSexec will change the current working directory to your
+// Synchronet "ctrl" directory before executing the script, so the redirected
+// output (stdout) of the example commands above would go into files created
+// there. To write output files to a different directory, either specify the
+// *full* path or use the jsexec '-C' command-line option to disable the
+// change-directory function.
+
+// To load this module from another JavaScript module and capture the output,
+// var output = load({}, "fileareas.js", "-quiet");
+
+"use strict";
+
+var options = {
+	hdr: false,
+	sort: false,
+	quote: false,
+	quiet: false,
+};
+var json;
+var delim = '\t';
+var props = [];
+var fmt = {}
+var upr = [];
+var lwr = [];
+var lib = [];
+
+for(var i = 0; i < argc; i++) {
+	if(argv[i].charAt(0) != '-') {
+		props.push(argv[i]);
+		continue;
+	}
+	switch(argv[i]) {
+		case '-lib':
+			lib.push(argv[++i].toLowerCase());
+			continue;
+		case '-fmt':
+			if(props.length > 0)
+				fmt[props[props.length - 1]] = argv[++i];
+			else
+				throw(argv[i] + " must follow a property specificatoin");
+			continue;
+		case '-upr':
+			if(props.length > 0)
+				upr[props[props.length - 1]] = true;
+			else
+				throw(argv[i] + " must follow a property specificatoin");
+			continue;
+		case '-lwr':
+			if(props.length > 0)
+				lwr[props[props.length - 1]] = true;
+			else
+				throw(argv[i] + " must follow a property specificatoin");
+			continue;
+		case '-delim':
+			delim = argv[++i];
+			continue;
+		case '-json':
+			var spacing = parseInt(argv[i + 1], 10);
+			if(!isNaN(spacing))
+				json = spacing, i++;
+			else
+				json = 0;
+			break;
+		default:
+			var arg = argv[i].slice(1);
+			if(options[arg] === undefined) {
+				writeln("usage: fileareas.js [[-lib <name>] [...]] [[-option] [...]] [[[prop] [-fmt <format>] [-upr | -lwr]] [...]]");
+				writeln("options:");
+				writeln(format("\t%-12s <default>", "<option>"));
+				for(var o in options)
+					writeln(format("\t%-12s %s", '-' + o, JSON.stringify(options[o])));
+				writeln(format("\t%-12s \\t", "-delim"));
+				writeln(format("\t%-12s undefined (specify a numeric argument for pretty-printing)", "-json"));
+				exit(0);
+			}
+			var value = parseInt(argv[i + 1], 10);
+			if(value >= 0)
+				options[arg] = value, i++;
+			else
+				options[arg] = true;
+			continue;
+	}
+}
+
+var output = [];
+for(var i in file_area.dir) {
+	var area = file_area.dir[i];
+	if(lib.length && lib.indexOf(area.lib_name.toLowerCase()) < 0)
+		continue;
+	var obj = {};
+	if(props.length == 0)
+		obj = area;
+	else
+		for(var f in props) {
+			var value = area[props[f]];
+			if(typeof value == 'string') {
+				if(upr[props[f]])
+					value = value.toUpperCase();
+				else if(lwr[props[f]])
+					value = value.toLowerCase();
+			}
+			obj[props[f]] = value;
+		}
+	var line = '';
+	if(json !== undefined)
+		line = JSON.stringify(obj, null, json);
+	else {
+		if(options.hdr == true && !output.length) {
+			for(var f in obj) {	
+				if(fmt[f])
+					write(format(fmt[f], f));
+				else
+					write(f);
+				write(delim);
+			}
+			writeln();
+		}
+		for(var f in obj) {
+			var value = obj[f];
+			if(value === undefined)
+				throw(f + ' is undefined');
+			if(options.quote)
+				value = JSON.stringify(value);
+			if(line.length)
+				line += delim;
+			if(fmt[f])
+				line += format(fmt[f], value);
+			else
+				line += value;
+		}
+	}
+	if(js.global.bbs)
+		line = lfexpand(line);
+	output.push(line);
+}
+
+if(options.sort)
+	output.sort();
+if(!options.quiet)
+	for(var i in output)
+		writeln(output[i]);
+
+output;
\ No newline at end of file