This document explains file area configuration, storage layout, and file area rules.
File areas are categorized by:
tag(e.g.,NODELIST,GENERAL_FILES)domain(e.g.,fidonet,localnet)- Flags such as
is_local,is_active, andscan_virus
File areas can be managed via /fileareas in the web UI.
File areas are typically written to by two different OS users:
- Web server (e.g.
www-data) — handles user uploads through the web interface - BinkP daemon (e.g.
binktermphp) — handles inbound TIC file imports
Both users must be able to read and write each other's files. The recommended approach is to add the BinkP daemon user to the www-data group and ensure data/files/ is group-owned by www-data:
sudo usermod -aG www-data binktermphp
sudo chgrp -R www-data data/files/Substitute binktermphp with whatever user the BinkP daemon runs as on your system.
setup.php sets data/files/ and its subdirectories to mode 02775 (setgid + group-writable). The setgid bit causes all new files and subdirectories to inherit the www-data group automatically, so no manual chgrp is needed after new file areas are created.
All stored files are set to mode 0664 (group-writable) by both the web upload and TIC import code paths.
Note: Group membership changes do not take effect in already-running processes. After adding the daemon user to
www-data, restart the BinkP daemons withscripts/restart_daemons.shand log out/in on any shell sessions running as that user.
File area storage directories use the naming convention:
TAGNAME-DATABASEID
Example:
NODELIST-6
New uploads and TIC imports will automatically create the directory if it does not exist.
File area rules are configured in config/filearea_rules.json and allow post-upload automation.
Rules are applied in this order:
- All
global_rules - Area-specific
area_rules[TAG]
Rules are evaluated by regex against the filename. Each matching rule runs its script in order.
{
"global_rules": [
{
"name": "Block Dangerous Extensions",
"pattern": "/\\.(exe|com|bat|cmd|scr|vbs|js)$/i",
"script": "echo 'Blocked dangerous file: %filename%'",
"success_action": "delete+notify",
"fail_action": "keep",
"enabled": false,
"timeout": 10
}
],
"area_rules": {
"NODELIST@fidonet": [
{
"name": "Import FidoNet Nodelist",
"pattern": "/^NODELIST\\.(Z|A|L|R|J)[0-9]{2}$/i",
"script": "php %basedir%/scripts/import_nodelist.php %filepath% %domain% --force",
"success_action": "delete",
"fail_action": "keep+notify",
"enabled": true,
"timeout": 300
}
]
}
}The rule key format depends on whether the file area belongs to a network domain.
Always use
TAG@DOMAINfor file areas linked to a network domain. The processor looks up rules by constructingTAG@DOMAINfrom the file's actual domain at runtime, so the match is exact. Two networks can share the same area tag (e.g.NODELIST@fidonetandNODELIST@fsxnet) and each will only trigger its own rules.
"area_rules": {
"NODELIST@fidonet": [
{
"name": "Import FidoNet Nodelist",
"pattern": "/^NODELIST\\.(Z|A|L|R|J)[0-9]{2}$/i",
"script": "php %basedir%/scripts/import_nodelist.php %filepath% %domain% --force"
}
],
"NODELIST@fsxnet": [
{
"name": "Import fsxNet Nodelist",
"pattern": "/^NODELIST\\.[0-9]{3}$/i",
"script": "php %basedir%/scripts/import_nodelist.php %filepath% %domain% --force"
}
]
}Individual rules within a TAG@DOMAIN group do not need a domain field — it is redundant.
For file areas that are not linked to any network domain, use the plain tag:
"area_rules": {
"LOCAL_FILES": [
{
"name": "Scan uploaded files",
"pattern": "/.*$/",
"script": "php %basedir%/scripts/scan_file.php %filepath%"
}
]
}name(string): Human-friendly description.pattern(string): PHP regex used to matchfilename.script(string): Command to execute when the rule matches.success_action(string): Action(s) when script exits with code 0.fail_action(string): Action(s) when script exits non-zero or times out.enabled(bool): Toggle rule execution.timeout(int): Script timeout in seconds.domain(string, optional): Restricts the rule to a specific domain. Only useful under a plainTAGkey — when usingTAG@DOMAINkeys this field is redundant and can be omitted.
Actions can be chained with + and are executed in order:
delete- Delete file from disk and database.keep- No change (useful for explicit “do nothing”).notify- Send a sysop netmail notification.move:TAG- Move file to another file area.archive- Move file todata/archive/<AREATAG>/and mark asarchived.stop- Stop processing any remaining rules.
Macros are replaced before executing the script:
%basedir%- Application base directory%filepath%- Full path to file%filename%- Filename only%filesize%- File size in bytes%domain%- File area domain%areatag%- File area tag%uploader%- Uploader address or username%ticfile%- Path to associated TIC file (if available)%tempdir%- System temp directory
Rule execution logs are written to:
data/logs/filearea_rules.log(configurable viaFILEAREA_RULE_ACTION_LOG)
Debug logging can be enabled with:
FILE_ACTION_DEBUG=true
Debug logs are written to:
data/logs/file_action_debug.log
The rule configuration editor is available at:
/admin/filearea-rules
Changes are saved through the admin daemon.
- Rules are applied after virus scanning.
- Infected files are rejected and will not run rules.
- Rule processing runs for both user uploads and TIC imports.