{"id":18974514,"url":"https://github.com/m7a/lo-jmbb","last_synced_at":"2026-04-08T15:30:19.788Z","repository":{"id":164554605,"uuid":"208365193","full_name":"m7a/lo-jmbb","owner":"m7a","description":"Java Ma_Sys.ma Block Based Backup (Incremental, Compressed, Data+Metadata-Encrypted Linux Backup Program)","archived":false,"fork":false,"pushed_at":"2024-04-28T19:43:34.000Z","size":1457,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-01T09:08:01.074Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m7a.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-14T00:01:50.000Z","updated_at":"2024-04-28T19:43:37.000Z","dependencies_parsed_at":"2023-07-02T14:16:27.355Z","dependency_job_id":null,"html_url":"https://github.com/m7a/lo-jmbb","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m7a%2Flo-jmbb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m7a%2Flo-jmbb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m7a%2Flo-jmbb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m7a%2Flo-jmbb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m7a","download_url":"https://codeload.github.com/m7a/lo-jmbb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239972038,"owners_count":19727290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T15:15:17.568Z","updated_at":"2026-04-08T15:30:19.741Z","avatar_url":"https://github.com/m7a.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\nx-masysma-name: jmbb\nsection: 32\ntitle: Java Ma_Sys.ma Block Backup JMBB\nkeywords: [\"jmbb\", \"backup\", \"readme\"]\nlang: en-US\nx-masysma-version: 1.0.3\ndate: 2014/08/06 01:16:35\nauthor: [\"Linux-Fan, Ma_Sys.ma (Ma_Sys.ma@web.de)\"]\nx-masysma-copyright: |\n  Copyright (c) 2013, 2014, 2015, 2017, 2019, 2020 Ma_Sys.ma.\n  For further info send an e-mail to Ma_Sys.ma@web.de.\n  This program's encryption functions are modifications of\n  Java AESCrypt, Copyright 2008 Vócali Sistemas Inteligentes.\n  For further information refer to http://www.aescrypt.com/java_aes_crypt.html.\nx-masysma-website: https://masysma.net/32/jmbb.xhtml\nx-masysma-repository: https://www.github.com/m7a/lo-jmbb\nx-masysma-owned: 1\n---\nDescription\n===========\n\nJMBB allows you to create encrypted incremental backups from source directories\nto a destination directory. Unlike most encrypting backups JMBB does not use\nencryption on per-file basis. Instead, it adds multiple files to a compressed\nand encrypted archive file called “block”. This securely encryptes the source\ndirectory structure and all file metadata. Whenever files have changed, they\nare added to new blocks at the next incremental backup. When all files\ncontained in a block have been replaced by files from newer blocks (i.e. when\nall files in an old block were changed over time) the old block is deleted.\nThis ensures that with common usecases the incremental backup will not be\nbigger than the source data.\n\nBasic Usage\n===========\n\nAn automatically generated usage information which also conatins “long”\narguments can be obtained by invoking JMBB with `--help`.\n\nJMBB is usually run through either a `jmbb` command if it was installed on UNIX\nor Linux or with `java -jar JARFILE` with JARFILE being the `.jar` file\ncontaining the program.\n\nExample: Creating a backup with JMBB from `/data` to `/media/backup`\n\n\t$ java -Xmx5G -jar jmbb.jar -o /media/backup -i /data\n\nIf you are getting an out of memory error add suitable `-XmxNG` values with N\nbeing enough RAM for the program to work. On Linux you can enter about as much\nas your amount of physical RAM + size of available swap space. \n\nJCE Dependency\n==============\n\nOn Windows and all other systems where they are not installed by default you\nneed the “Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction\nPolicy Files” from\n\u003chttp://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html\u003e\nor JMBB will not encrypt or decrypt and therefore not work at all. This is\nrelated to the fact, that JMBB uses AESCrypt's strong cryptography which you\nneed to enable separately for your Java installation. To resolve this, JMBB\nwould either need to package the file with it (licensing issues prevent me from\ndoing this) or implement the whole AES stuff itself which would lead to more\nbugs in the code and is therefore also not an option. \n\nIntention\n=========\n\nJMBB was created with the following scenario in mind: The user wants to create\nan online “cloud” backup but wants to encrypt his/her files. However,\ntransferring a whole, encrypted 7z archive for every backup is very\ntime-consuming. Instead, the user wants to create an incremental backup. The\nbest solutions widely known are either “encfs” or “Box Cryptor” both of which\nact on per file basis and therefore not encrypt access times, file sizes and\nonly obfuscate filenames, not encrypt directory structures. JMBB can not\ndirectly synchronize with an online storage but write to any directory which\nmay then be synced using the client program provided by the “cloud service”.\nJMBB is an incremental backup program, that means neither a program to\nsynchronize files, nor a program to create disk images or backup system\ninstallations. The technical limitations (cf. tables below) make JMBB unuseable\nfor handling large files of 8 GiB or larger. Creating a backup of 8 GiB or\nmore data however, is not an issue. \n\nMaintenance\n===========\n\nJMBB has an internal editor for database maintenace tasks. It can be started\nas follows:\n\n\t$ jmbb -e BACKUP\n\nThe editor can be used interactively to set new passwords, display existing\npasswords, display database statistics and clear blocks which mainly consist of\nobsolete files. Also, it allows the user to view contents of a specific block\nas they are registered in the database. If a password has been cracked or\nleaked, the editor can also “deprecate” passwords, i. e. force all blocks\nusing the obsolete password to be re-created on the next JMBB invocation.\n\nTransition to 1.0.1.0\n=====================\n\nBefore 1.0.1.0, sometimes an incremental backup would create sparsely filled\nblocks without an apparent reason. This was a result of how JMBB decided which\nfiles were to be added to blocks – files which matched their previous version\nwere not added at the stage of block creation when it as already defined which\nfiles would be contained in a block. Using programs which rewrite a lot of data\nwhich has not chagned upon program exit, this caused empty blocks. Although\nempty blocks were no “danger”, they had a major issue: JMBB did not ever delete\nthem because their contained files never changed to obsolete (because there\nwere no files contained).\n\nWith Version 1.0.1.0, this issue has been fixed by applying the following:\nChecksums are now calculated at the stage of block file list creation in a\nsingle threaded manner if the checksum could influence if the file is added to\na block or not. Therefore, empty blocks will no longer be created. To be able\nto clean your old backup tree, a new command `empty` has been added to list and\nwith `emtpy rm` delete all empty blocks. It has been tested that empty blocks\nare not relevant for restoration.\n\nTransition to 1.0.2.0\n=====================\n\nBefore 1.0.2.0, JMBB did not store any information whenever a file was found to\nhave a newer timestamp but already existed in the database with the same\nchecksum. The main idea about this was to avoid backing up a known file again\nand instead just keep the existing (copy) where the modification time is older\nbut all other metadata (and the content) are equal.\n\nUpon upgrading to Debian Stretch with Java 8, a strong disadvantage of this\napproach was found: Due to the upgrade, the modification times of existing\nfiles could be read more exactly, i. e. instead of always being 000, the last\nthree digits of the modification time in milliseconds suddenly got a value for\na lot of files. By this, JMBB found a lot of files with different timestamps\nbut only few of them had changed, making it update only the copies of said few\nfiles. The other (unchanged) files' new times were not stored leading to very\nlong scanning times due to checksuming _all_ files in the filesystem where new\ntimes were available upon _each invocation_.\n\nWhile one could have started the backups from scratch or reduce the accuracy of\nmetdata, another approach was chosen (cf. `DBNewTimes.java` in the source code\nfor reasoning about the design decision): A new place in the “database” XML\nfile is now used to track files which have only changed in modification time\nand thus not been backed up again. For these files, whenever the file is\nscanned again with the same time, it is treated as already present in the\nbackup (which it is except for an older timestamp) making it unnecessary to\nre-checksum the affected files upon every invocation.\n\nCompatibility with previous versions\n:   Currently, the additional database entries are not used for restoration\n    which means the new JMBB can restore (and update) backups created with\n    previous versions. Upon updating an old backup, JMBB will automatically\n    create the new structure in the XML file.\n\nShort Summary\n:   If you experience unusually long backup update times after a Java and/or OS\n    upgrade (with a lot of HDD activity), this update is likely to solve the\n    issue after the 2nd (!) backup update done with it.\n\nWith this version update, no manual database editing is necessary.\n\nUpdates in 1.0.3\n================\n\nNo changes should be necessary. This release fixes an issue with backup\ntransactionality: In case a backup were updated and some files that existed\nalready previously were changed but no longer readable (e. g. due to\nintermittent deletion or `chmod 000`), then this could cause a backup\ninconsistency (blocks being deleted but not marked in the database as such).\nThis version attempts to fix the issue by only deleting blocks after the DB\nwith the changes could be saved successfully.\n\nUpdates in 1.0.4 to 1.0.6\n=========================\n\nNo changes should be necessary. This release adds the integrity check feature\ndescribed in section _Performing Integrity Checks_.\n\nTables\n======\n\n## JMBB Features and their respective implementations\n\nFeature         Implementation\n--------------  --------------------------------------------------------\nArchiving       GNU CPIO \"Portable ASCII Format\" (filesize limit: 8 GiB)\nCompression     XZ For Java \u003chttp://tukaani.org/xz/java.html\u003e\nEncryption      AESCrypt AES256, see copyright \u003chttp://aescrypt.com/\u003e\nDatabase        GZipped XML with DTD included in JMBB JAR\nFile traversal  Java NIO for backup source directory traversal\n\n## Envorinoment variables affecting backup creation. Use with care\n\nVariable        Description\n--------------  --------------------------------------------------------\n`JMBB_THREADS`  Number of XZ threads to create. Default: number of cores\n`JMBB_XZLEVEL`  Changes the XZ compression level from 1 to 9, default: 8\n`JMBB_WINDOWS`  `true` means warnings about failed `stat()`s are hidden\n\n## JMBB performance comparison table\n\nCommand                            User/s  Sys/s  Real/s  MaxRes/k  Comp/O\n---------------------------------  ------  -----  ------  --------  ------\n`jmbb -o BAK -i SRC`               1231    71     298     3959444   0.3122\n`tar -c SRC | 7z* BAK`             822     7      239     3785532   0.3065\n`jmbb -r DST -s BAK`               162     15     175     478300    n/a\n`7z x -so BAK p* | tar -C DST -x`  38      4      53      68300     n/a\n\n### Command aliases for the JMBB performance comparison table \n\n * `p* := -ptestwort`\n * `7z* := 7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=64m -ms=2g -l p* -si -bd`\n\nMachine and OS Requirements and Recommendations\n===============================================\n\n## System requirements \n\n * Linux or UNIX with GNU CPIO\n * Java 7 or higher Runtime Environment (only Java 7 and 8 known to work). For\n   more than three (virtual) cores a 64 Bit JVM is required.\n * Enough HDD space to store the newly created backup.\n * RAM requirements (see below)\n\n## System recommendations \n\n * Multicore (4+ recommended) system with much RAM (6 GiB+ recommended).\n\nJMBB is a “heavyweight” Java program which requires a lot of RAM depending on\nyour system because it creates distinct XZ compressors for every processor core\nand because it reads it's whole database into your RAM.\n\nApproximately you will need\n\n\t300 MiB + (virtual) cores * 600 MiB free RAM.\n\t=\u003e old singlecore: 1 GiB of free RAM recommended.\n\t=\u003e new quadcore:   5 GiB of free RAM recommended (rem: 8 virtual cores).\n\nYou might need more than 300 MiB of additional RAM depending on the size of the\ndirectory tree you want to backup. Also, the amount of RAM required for the\ndata base slowly grows with each incremental backup. This is currently an\nunfortunate design error/requirement.\n\nIf you do not fulfil the RAM requirements but still want to use JMBB you might\nbe able to tune the amount of memory required by lowering compression settings\nor reducing the number of threads to be created. These values can be affected\nby environment variables as listed in the table above.\n\nAlso, the increasing RAM usage of the database is considered a “known issue”\nwhich should be resolved in the future. Be aware, however, that a solution to\nthat issue will at least require you to convert your database if not to switch\nto anoter program.\n\nPerforming Integrity Checks\n===========================\n\nSince version 1.0.6, a new mode of invoking JMBB has been added: The integrity\ncheck. The idea behind the integrity check is to supply a database file and\na directory that contains `.cxe` files. JMBB will then attempt to decrypt all\nof the blocks and compare their checksum against the value stored in the\ndatabase. Additionally, JMBB checks if all blocks necessary to restore the\nbackup state from the database are present on disk.\n\nDespite being a computationally and I/O intensive operation, the integrity\ncheck can achieve good performance: Below invocation ran on about 250 GiB of\nblock data and finished in about half an hour, i.e. averaged 140 MiB/s on an\nIntel Core i7-4770 with 24 GiB of RAM and a software RAID 1 of SATA HDDs.\n\n\t$ jmbb -I /fs/backuphist/metadata/db.xml.gz -R /fs/backuphist/blocks\n\tDetails\n\t=======\n\n\t0000000000000001  [ ok ]  obsolete, absent\n\t0000000000000002  [ ok ]  obsolete, absent\n\t0000000000000003  [ ok ]  obsolete, absent\n\t[...]\n\t00000000000013b2  [FAIL]  active,   absent\n\t00000000000013b3  [FAIL]  active,   absent\n\t00000000000013b4  [FAIL]  active,   absent\n\t[...]\n\t00000000000033a8  [ ok ]  active,   verified\n\t00000000000033a9  [ ok ]  active,   verified\n\t\n\tStatistics\n\t==========\n\n\t[ ok ]  active,   verified               3098\n\t[ ok ]  obsolete, verified               8942\n\t[ ok ]  obsolete, absent                 915\n\t        -- SUM                           12955\n\t[FAIL]  active,   absent                 269\n\n\tSummary\n\t=======\n\n\tBACKUP IS INCONSISTENT!\n\nThe report is structured as follows:\n\n## Details\n\nAll blocks are listed in a sorted and tabular fashion. The table columns are as\nfollows:\n\n 1. Block ID: The number of the block\n 2. `[ ok ]` or `[FAIL]` depending on whether this block is good or not.\n    A block is good if either (a) it exists on disk and its checksum matches\n    OR (b) it does not exist on disk and is no longer needed (obsolete).\n 3. Whether the block under consideration is needed (`active`) or obsolete.\n 4. Whether the block is present on disk and verified (`verified`),\n    not present on disk (`absent`) or present but not the same as recorded\n    in the database (`CHECKSUM MISMATCH`). In case multiple block files exist\n    with the same name, their individual file paths and whether they match the\n    database will also be reported in separate lines following the current\n    entry. In case you are interested in the complete set of messages that\n    can appear here, check file `ma/jmbb/IRStatus.java`.\n\n## Statistics\n\nThis section counts each of the result messages' occurrences. In case of\na backup archive there might be a constant number of blocks in the\n`obsolete absent` category that should not increase (unless the archive\nis losing blocks!). Hence, these statistics allow insights into the completeness\nof such an archive beyond a simple “is able to restore”.\n\n## Summary\n\nThis section will only ever display one of two messages:\n\n`BACKUP IS INCONSISTENT!`\n:   At least one of the active blocks is absent or\n    at least one block file was found to have a mismatching checksum.\n`Backup is consistent.`\n:   All blocks on disk match the database's contents and it should be possible\n    to restore the state of the database from the blocks. Note: JMBB does not\n    extract all of the blocks' contents, thus a minor uncertainity remains that\n    the blocks' contents may have been invalid in the first place. Such\n    anomalies can currently only be detected by performing a proper restore and\n    then comparing against the original data.\n\nCompiling\n=========\n\nAs JMBB is a Java-Application it is normally unnecessary to recompile it. But\nif you extract the source from the jarfile, you can compile JMBB with `$ ant`\nto generate all .class files or `$ ant jar` to generate the jmbb.jar\n\nRedistribution\n==============\n\nThis program is free software: you can redistribute it and/or modify it under\nthe terms of the GNU General Public License as published by the Free Software\nFoundation, either version 3 of the License, or (at your option) any later\nversion.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\nPARTICULAR PURPOSE. See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with\nthis program. If not, see \u003chttp://www.gnu.org/licenses/\u003e.\n\nNote\n:   You can view the GPL by either browsing the JMBB jarfile or running JMBB\n    with the `-$` parameter. The full sourcecode is also part of the jarfile.\n\nEmergency\n=========\n\nJMBB was designed to allow the user to restore his/her data even if many things\nare lost. Depending on the situation, most of the restoration can be done by\nJMBB itself. Should JMBB not be able to run or should a compatible `cpio`\nimplementation not be available, it is possible to restore the data from the\nblocks. To restore all data (including possibly deleted files) from a block, it\ncan be extracted with common utilities all of which may be substituted if\nnecessary.\n\nBlock files `.cxe` are CPIO XZ Encrypted files which means that they can be\nextracted in reverse order of creation, e. g.:\n\n\t$ aescrypt -d -p PASSWORD -o result.cpio.xz block.cxe\n\t$ xzcat result.cpio.xz | cpio -i\n\nApart from user data, every block file contains a file `meta.xml` with\nchecksums and information about the contained files. The “global” database file\napplying to the whole backup contains everything including all `meta.xml`\nfiles. It can be used to find out about which files should be restored and\nwhich files were deleted or replaced by another file. Usually, this is done by\nthe JMBB restoration function … it is listed here for emergency cases only.\n\nTo reduce the possiblity of such an emergency where JMBB might not be\navailable, it is advisable to store JMBB and a “reference” CPIO implementation\nnext to the backup, ideally in the same folder the backup resides in.\n\nAlternatives\n============\n\nRelying on backup software used by few people, which JMBB is for example, is\nalways a security risk: No experts have reviewed the sourcecode and chances are\nbad data can be recovered in case of failure. To mitigate the potential\nnegative aspects, JMBB relies on _standard formats_ for all of its features.\nStill, some risks remain. To give an overview about the alternatives which are\nused by more users, there used to be a list of alternatives here.\n\nSince 2021/04/10, a new and more exhaustive analysis of the alternatives\nexists under [backup_tests_borg_bupstash_kopia(37)](../37/backup_tests_borg_bupstash_kopia.xhtml).\n\nAdvanced Usage\n==============\n\nCreating and updating a backup with JMBB is simple enough. However, JMBB was\nalso designed to be used for complex backup strategies. As an example, this\nsection describes how to setup a backup strategy similar to JMBB's author's.\n\n## Integration into a Backup Strategy\n\nMy backup consists of multiple layers: A quick incremental backup to another\ninternal HDD is created on every shutdown and an encrypted copy is sent to a\nseparate PC for synchronizing the data to a cloud service. Its main purpose is\nto record changes and allowing to fetch older versions of files if a file was\naccidentally deleted or changed. About once per week, a backup of important data\nand programs is copied to an external SSD. This backup strategy is implemented\nusing JMBB and standard Linux utilities.\n\n### The backup upon shutdown\n\n * `$ jmbb -o $HOME/backup -i /data/main | copydelta.sh`\n * `copydelta.sh` collects new blocks into a separate directory.\n\n### The weekly backup to an external SSD\n\n * `$ jmbb -d $HOME/backup -c /mnt/backup`\n * Mirroring is sufficient.\n\n### The system and data backup\n\n * `$ jmbb -d $HOME/backup -c /mnt/backup_system`\n * `$ rsync -av /data/programs /mnt/backup_system`\n\n### The online backup.\n\n * `$ jmbb -d $HOME/backup -c $HOME/backup`\n   This shows a special JMBB feature: A mirror can be stored in a database.\n   By storing all blocks in a directory called \"cnt\" and an encrypted copy of\n   the database with it, it is easily possible to sync \"cnt\" to a (possibly\n   public) online storage without disclosing any information about your files.\n   To extract the files, a copy of the DB (`cnt/../db.xml.gz`) or the password\n   are required.\n * `$ onlinesync.sh $HOME/backup/cnt`\n   `onlinesync.sh` is a hypothethical name of a script to synchronize a normal\n   directory with the online storage.\n\n### The archive backup\n\nOn an irregular schedule, new blocks that were collected upon shutdown are\narchived to separate machine. After arriving there, the integrity check\nfeature is used to check the existent and newly created blocks' consistency.\nThis archive acts in a pull-based fashion and does not ever overwrite existent\ndata to achive some resistance against file corruption caused by malware.\n\n## Wrapper scripts\n\nAs you can see, JMBB is best used in conjunction with other scripts and\nutilities. Also, it is recommended not to invoke JMBB directly but create a\nscript to create an interface for your personal backup strategy in order to\nmake backups more convenient.\n\nWrapper scripts are also helpful to add additional utility invocations, provide\nrequired environment variables (cf. table above) and to enter source\ndirectories automatically.\n\nBug reporting\n=============\n\nImmediately report bugs informally with important information (OS,\narchitecture, CPIO, Java versions, etc.) and exact error message including\nstack trace (if available) to the Ma_Sys.ma e-mail address listed at the very\nbeginning of this file. If you are able to reproduce the bug, add the minimum\namount of steps which result in the bug to your mail.\n\nKnown issues\n============\n\nYou can currently not create restorable backups on Windows systems. This is a\nbug which results from the treatment of file names: The fixed separator\n\n`/` is assumed for CPIO's patterns but obviously CPIO's Windows version also\nexpects (and writes to the CPIO archives) real Windows filenames. Backups with\nUnix filenames however, are restored correctly even on Windows systems if you\nhave a Windows version of CPIO.\n\n### Bugs \n\n * OutOfMemoryError does not cause nonzero exit status (but also does not update\n   DB and therefore leaves it in a consistent state) → TEST\n * File Name Handling defect: File names which are invalid UTF-8 are not\n   processed properly.\n * Studying AES-CBC in detail it seems that it might be good to make IV\n   generation not only depend on the key but proably on the block number as\n   well!\n\n### Plans for enhanced robustness \n\n * For a JMBB SQL variant breaking the program at arbitrary points should be\n   fully supported by creating blocks transactionally (once block on HDD: commit\n   metadata, before block to HDD: commit as “failed” which will be deleted upon\n   reentering the program with the same block ID not being used again and the\n   metadata not being discarded but marked as “failed”\n * It would be nice if JMBB handled FS changes sensibly: Upon doing a STAT for\n   the file, the size should be noted. If it later changes → add to a\n   notification list (incl. delta) and if it later disappears → repeat STAT and\n   if it does not appear by then add it to a notification list. At the end of a\n   JMBB invocation, a summary of size-changed and vanished files should be\n   printed. (Does it make sense to do a 2-nd stat phase to detect _added_ files,\n   too?)\n\n### Misc. notes\n\n * `afio` may replace `cpio` with higher limits.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm7a%2Flo-jmbb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm7a%2Flo-jmbb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm7a%2Flo-jmbb/lists"}