diff options
author | Andreas Fankhauser hiddenalpha.ch | 2023-01-17 11:01:25 +0100 |
---|---|---|
committer | Andreas Fankhauser hiddenalpha.ch | 2023-01-17 11:01:25 +0100 |
commit | b55452aca69ea85d5f8be9f1926c46b3d72ce4ff (patch) | |
tree | 2c8111fa60900aa1f60f92fda20a86a3529a4bb9 | |
parent | 91627b0ec1ceeb9521e351381aa6b585573e630a (diff) | |
parent | 41a0f97bafb3d95cfd9f05fd11b01adf8ac62e50 (diff) | |
download | UnspecifiedGarbage-b55452aca69ea85d5f8be9f1926c46b3d72ce4ff.zip UnspecifiedGarbage-b55452aca69ea85d5f8be9f1926c46b3d72ce4ff.tar.gz |
Merge branch 'master' into wip-MvnDepScan-20221207
29 files changed, 476 insertions, 134 deletions
diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..b9e20aa --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,14 @@ +
+Copyright (c) 2022 Andreas Fankhauser
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/doc/note/cross-compile/CrossCompile.txt b/doc/note/cross-compile/CrossCompile.txt new file mode 100644 index 0000000..5341164 --- /dev/null +++ b/doc/note/cross-compile/CrossCompile.txt @@ -0,0 +1,8 @@ + +Cross Compilation & Portability +=============================== + +10 most essential rules for portable C code: + + https://www.ski-epic.com/source_code_essays/ten_rules_for_writing_cross_platform_c_source_code.html + diff --git a/doc/note/docker/Docker.txt b/doc/note/docker/Docker.txt index 7a9d130..ac283c9 100644 --- a/doc/note/docker/Docker.txt +++ b/doc/note/docker/Docker.txt @@ -57,6 +57,17 @@ Side-Mount tcpdump into container where it does not exist docker run --rm -ti --network container:"${CNTNR_TO_DUMP:?}" -v "/tmp/foo:/work" "${IMG_WITH_TCPDUMP_EG_BASEIMG:?}" bash +## Inspect failing docker-build + +See "https://stackoverflow.com/a/26222636/4415884" + + docker run --rm -ti 42424242 sh + +HINT: Use the line which looks like: +"---> 42424242" +and NOT the one like: +"---> Running in 42424242" + ## Publish custom images to artifactory diff --git a/doc/note/ffmpeg/ffmpeg.txt b/doc/note/ffmpeg/ffmpeg.txt index 9d95bfd..057c11d 100644 --- a/doc/note/ffmpeg/ffmpeg.txt +++ b/doc/note/ffmpeg/ffmpeg.txt @@ -2,7 +2,6 @@ ffmpeg ================ -j ## Extract Audio From webm Lookup format of audio stream with: @@ -17,9 +16,21 @@ Then use that knowlege to extract that (audio) stream: ## Convert Formats -ffmpeg -i in.opus out.wav + ffmpeg -i in.opus out.wav +## Fine-tune audio codec + +[See also](https://slhck.info/video/2017/02/24/vbr-settings.html) + +Use -codec:v copy to keep video, or -codec:v no for audio-only. + + -codec:a aac -q:a 1.3 (min=0.1, good=1.3 max=2) + -codec:a aac -b:a 96k + -codec:a libmp3lame -q:a 2 + -codec:a libopus + -filter:a lowpass=f=16000 + ## Record Desktop diff --git a/doc/note/gpg/gpg.txt b/doc/note/gpg/gpg.txt new file mode 100644 index 0000000..015887c --- /dev/null +++ b/doc/note/gpg/gpg.txt @@ -0,0 +1,82 @@ + +How to GnuPG +============ + +WARN: You MUST only use those instructions if you know exactly what +you're doing! If you don't, you MUST NOT use those instructions! + + +## Prepare for a master key creation + +- Choose a storage medium which will keep the master key and will be + kept VERY SAVE somewhere (also think for some redundancy). WARN: If + you choose a medium which probably could fail, you will be screwed up + in a later point in time! +- Choose how (or where?) to keep master passphrase. + + +## Initialize a new master key + + export GNUPGHOME=/mnt/your/master/.gnupg + gpg --full-gen-key + + +## Add additional identities (as needed) + + export GNUPGHOME=/mnt/your/master/.gnupg + gpg --edit-key foo@example.com + gpg> adduid + gpg> save + + +## Create keys for some daily-use devices + + export GNUPGHOME=/mnt/your/master/.gnupg + gpg --edit-key foo@example.com + # Add an encryption and a sign key + gpg> addkey (then choose "encryp only") + gpg> addkey (then choose "sign only") + + +## Export subkeys for use on a daily-use device + + # From now work with a temporary copy. + mkdir /mnt/your/tmp/.gnupg + (cd /mnt/your/master/.gnupg && tar c $(ls -A)) | (cd /mnt/your/tmp/.gnupg && tar x) + export GNUPGHOME=/mnt/your/tmp/.gnupg + # Print list of what we have + gpg --edit-key foo@example.com quit + # I suggest to use a different passphrase than the master key has. + # (HINT: just ignore error about missing private key. it works anyway) + gpg --edit-key foo@example.com passwd quit + # For each device choose one encrypt and one sign key and replace F00 and BA5 + # below with them. + gpg --export-secret-subkeys F00! BA5! > keys-for-device + + +## Import prepared subkeys on daily-use device + + gpg --import keys-for-device + gpg --edit-key foo@example.com + gpg> trust + gpg> save + + +## Sign a foreign key to express to the world that we trust it + + gpgwin --sign-key foreignUser@example.com + + +## Some other helpful places + +- "https://insight.o-o.studio/article/setting-up-gpg.html#encryption-key" +- "https://davesteele.github.io/gpg/2014/09/20/anatomy-of-a-gpg-key/" +- "https://gpg.wtf/" + + +## Start/stop gpg-agent + + gpgconf --kill gpg-agent + gpgconf --launch gpg-agent + + diff --git a/doc/note/links/links.txt b/doc/note/links/links.txt index 3ca26ba..af41581 100644 --- a/doc/note/links/links.txt +++ b/doc/note/links/links.txt @@ -1,5 +1,5 @@ -Links (Aka arguments) +Links (Aka argument amplifiers) ===================== ## Pro DI over serviceLocator @@ -82,7 +82,7 @@ Links (Aka arguments) - SRP "https://blog.ndepend.com/solid-design-the-single-responsibility-principle-srp/" - OCP "https://blog.ndepend.com/solid-design-the-open-close-principle-ocp/" - LSP "https://blog.ndepend.com/solid-design-the-liskov-substitution-principle/" -- DIP "https://stackify.com/dependency-inversion-principle/" +- DIP "https://stackify.com/dependency-inversion-principle/#post-18184-_nuqaxpnmvpn7" ## Java how to handle InterruptedException: - "https://www.yegor256.com/2015/10/20/interrupted-exception.html" @@ -121,7 +121,7 @@ Links (Aka arguments) ## Why I Have Given Up On Coding Standards - "http://www.richardrodger.com/2012/11/03/why-i-have-given-up-on-coding-standards/" -## slf4j logger dos and donts0 +## slf4j logger dos and donts - [case SO](https://stackoverflow.com/questions/1417190/should-a-static-final-logger-be-declared-in-upper-case) - [case java-styleguide](https://web.archive.org/web/20120911192801if_/http://developers.sun.com/sunstudio/products/archive/whitepapers/java-style.pdf#G3.5426) - [case slf4j](http://www.slf4j.org/api/org/slf4j/Logger.html) @@ -148,10 +148,13 @@ Links (Aka arguments) - "https://gitit.post.ch/projects/ISA/repos/zarquon/pull-requests/2/overview?commentId=61312" ## Code Style format auto-formatters +- [warning about formatters](https://gitit.post.ch/projects/ISA/repos/trin/pull-requests/79/overview?commentId=235667) - [static final java uppercase](https://gitit.post.ch/projects/ISA/repos/preflux/pull-requests/82/overview?commentId=39126) - [invalid java class name](https://gitit.post.ch/projects/ISA/repos/preflux/pull-requests/82/overview?commentId=39125) -- [Formatters produce crap](https://gitit.post.ch/projects/ISA/repos/minetti/pull-requests/14/overview) -- [Formatters produce crap](https://gitit.post.ch/projects/ISA/repos/veet/pull-requests/2/overview?commentId=233638) +- [Spotless produces crap](https://gitit.post.ch/projects/ISA/repos/minetti/pull-requests/14/overview) +- [Spotless produces crap](https://gitit.post.ch/projects/ISA/repos/veet/pull-requests/2/overview?commentId=233638) +- [Spotless produces crap](https://gitit.post.ch/projects/ISA/repos/trin/pull-requests/79) +- [Linter produces crap](https://gitit.post.ch/projects/ISA/repos/preflux/pull-requests/567/overview?commentId=237627) - [Suddenly NEW formatting rules in PaISA since 2021](https://gitit.post.ch/projects/ISA/repos/watson/pull-requests/1/overview?commentId=234597) - "https://gitit.post.ch/projects/ISA/repos/zarniwoop/pull-requests/20/overview?commentId=85912" - "https://gitit.post.ch/projects/ISA/repos/zarniwoop/pull-requests/21/overview?commentId=87250" @@ -299,6 +302,7 @@ Links (Aka arguments) ## Command Escaping And Injection - "https://jira.post.ch/browse/SDCISA-3602" +- [My hopefully bullet-proove shell escaping](https://gitit.post.ch/projects/ISA/repos/jenkins-shared-libraries/pull-requests/82/overview?commentId=237165) ## logger noise spam verbose - [fix the REAL problem please](https://jira.post.ch/browse/SDCISA-3637?focusedCommentId=1252741&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-1252741) @@ -310,6 +314,7 @@ Links (Aka arguments) ## YAGNI (but also KISS and DRY) - "https://medium.com/swlh/yagni-and-dry-the-kiss-of-death-for-your-software-project-cfd44b0654b6#fc82" +- [eagle queue json only](https://gitit.post.ch/projects/ISA/repos/eagle/pull-requests/331/overview?commentId=236944) ## How to format method parameters - "https://gitit.post.ch/projects/ISA/repos/god-backend/pull-requests/281/overview?commentId=210650" @@ -409,3 +414,21 @@ Links (Aka arguments) ## Encoding mime application/octet-stream string utf8 unicode json payload data - [eagle queue browser](https://gitit.post.ch/projects/ISA/repos/eagle/pull-requests/331/overview?commentId=232322) +## Stop using that stupid mouse! For some reason you've got a keyboard +- [_](https://www.vice.com/en/article/d3m8ga/i-stopped-using-a-computer-mouse-for-a-week) +- [_](https://medium.com/ae-studio/save-a-month-of-your-life-by-using-these-keyboard-shortcuts-a07fdba5dc6e) +- [_](https://blog.superhuman.com/keyboard-vs-mouse/) + +## How to get real InputStream from RestTemplate +- [java spring http web InputStream RestTemplate body](https://stackoverflow.com/a/62649586/4415884) + +## Stone age deprecated obsolete for years +- [API using naming deprecated for 7 years](https://gitit.post.ch/projects/ISA/repos/notifications-api/pull-requests/7/overview?commentId=238160) + +## ImageMagic +- [Bulk resize pictures](https://stackoverflow.com/questions/36986436/how-to-batch-resize-millions-of-images-to-fit-a-max-width-and-height) +- [mogrify bulk changes](https://www.lostsaloon.com/technology/resize-multiple-images-batch-command-line-linux/) + +## Windoof +- [Enable w32 crashdump](https://learn.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps?source=recommendations) + diff --git a/doc/note/maven-pom/base.xml b/doc/note/maven-pom/base.xml new file mode 100644 index 0000000..68624fb --- /dev/null +++ b/doc/note/maven-pom/base.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <groupId>TODO</groupId> + <artifactId>TODO</artifactId> + <version>0.0.0-SNAPSHOT</version> + + <!-- <parent> --> + <!-- <groupId>TODO</groupId> --> + <!-- <artifactId>TODO</artifactId> --> + <!-- <version>TODO</version> --> + <!-- </parent> --> + + <!-- <packaging>Choose: jar, pom, war</packaging> --> + + <!-- <properties> --> + <!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> --> + <!-- <maven.compiler.source>8</maven.compiler.source> --> + <!-- <maven.compiler.target>8</maven.compiler.target> --> + <!-- </properties> --> + + <!-- <dependencies> --> + <!-- </dependencies> --> + + <!-- <dependencyManagement> --> + <!-- <dependencies> --> + <!-- </dependencies> --> + <!-- </dependencyManagement> --> + +</project> diff --git a/doc/note/ssh/_SeeAlsoTls b/doc/note/ssh/_SeeAlsoTls new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/doc/note/ssh/_SeeAlsoTls diff --git a/doc/note/tls/_SeeAlsoSsh b/doc/note/tls/_SeeAlsoSsh new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/doc/note/tls/_SeeAlsoSsh diff --git a/doc/note/tls/tls.txt b/doc/note/tls/tls.txt new file mode 100644 index 0000000..ce1e305 --- /dev/null +++ b/doc/note/tls/tls.txt @@ -0,0 +1,34 @@ + +TLS Key Management +================== + +WARN: Nothing useful here. Just some nonsense copy-pasta lines. + + +## Create new server PEM cert + +```sh +openssl genrsa -out path/to/private/key 2048 +``` + +```sh +openssl req -new -key path/to/private/key -new -nodes -x509 -days 42 -out path/to/certSignRequest.csr -subj "/C=/ST=/L=/O=/OU=/CN=example.com" +``` + +```sh +openssl x509 -req -days 42 -in path/to/certSignRequest.csr -signkey path/to/private/key -out path/to/cert.crt +``` + +```sh +cat path/to/private/key path/to/cert.crt > path/to/cert.pem +``` + + +## TLS debugging + +```sh +socat OPENSSL-LISTEN:1234,reuseaddr,cert=server.pem tcp-connect:127.0.0.1:1235 +``` + +HINT: Add option 'fork' to ssl sock to serve multiple requests. + diff --git a/src/main/docker/windoof-gcc.Dockerfile b/src/main/docker/gcc-windoof.Dockerfile index 69cc18e..69cc18e 100644 --- a/src/main/docker/windoof-gcc.Dockerfile +++ b/src/main/docker/gcc-windoof.Dockerfile diff --git a/src/main/docker/debian-gcc.Dockerfile b/src/main/docker/gcc.Dockerfile index 5894667..5894667 100644 --- a/src/main/docker/debian-gcc.Dockerfile +++ b/src/main/docker/gcc.Dockerfile diff --git a/src/main/docker/debian-cxx.Dockerfile b/src/main/docker/gxx.Dockerfile index f29f168..f29f168 100644 --- a/src/main/docker/debian-cxx.Dockerfile +++ b/src/main/docker/gxx.Dockerfile diff --git a/src/main/docker/debian-jni.Dockerfile b/src/main/docker/jni.Dockerfile index c790e47..c790e47 100644 --- a/src/main/docker/debian-jni.Dockerfile +++ b/src/main/docker/jni.Dockerfile diff --git a/src/main/docker/alpine-jre8.Dockerfile b/src/main/docker/jre8.Dockerfile index 603b5f5..603b5f5 100644 --- a/src/main/docker/alpine-jre8.Dockerfile +++ b/src/main/docker/jre8.Dockerfile diff --git a/src/main/docker/alpine-mvn.Dockerfile b/src/main/docker/maven.Dockerfile index e6c68f9..c33d519 100644 --- a/src/main/docker/alpine-mvn.Dockerfile +++ b/src/main/docker/maven.Dockerfile @@ -1,12 +1,9 @@ # # Maven build env. # -# Make sure to use arg +# Use this to share your hosts repository with the container: # -# -v "$HOME/.m2/repo:/data/maven/.m2/repo" -# -# so it can use your hosts artifacts cache. If you miss this, mvn has to -# download all the dependencies from remote uselessly often. +# -v "$HOME/.m2/repository:/data/maven/.m2/repository" # ARG PARENT_IMAGE=alpine:3.16.0 @@ -24,7 +21,7 @@ WORKDIR /work RUN true \ && $PKGINIT \ && $PKGADD $PKGS_TO_ADD \ - && sed -i "s,</settings>, <localRepository>/data/maven/.m2/repo</localRepository>\n</settings>,g" /usr/share/java/maven-3/conf/settings.xml \ + && sed -i "s,</settings>, <localRepository>/data/maven/.m2/repository</localRepository>\n</settings>,g" /usr/share/java/maven-3/conf/settings.xml \ && mkdir /data /data/maven \ && chown 1000:1000 /data/maven \ && chown 1000:1000 /work \ diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/collection/CollectionUtils.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/collection/CollectionUtils.java index a75594f..415090f 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/collection/CollectionUtils.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/collection/CollectionUtils.java @@ -13,9 +13,9 @@ public class CollectionUtils { * @param <T> * Type of the elements we are working with. */ - public static <T> boolean contains(T[] haystack, T needle, java.util.function.BiPredicate<T, T> equals) { - for (T t : haystack) { - if (equals.test(needle, t)) { + public static <T> boolean contains( T[] haystack, T needle, java.util.function.BiPredicate<T, T> equals ){ + for( T t : haystack ){ + if( equals.test(needle, t) ){ return true; } } diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/format/FormatUtils.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/format/FormatUtils.java index bd39e40..e156eb8 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/format/FormatUtils.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/format/FormatUtils.java @@ -1,54 +1,6 @@ package ch.hiddenalpha.unspecifiedgarbage.format; -public class FormatUtils { - - /** - * Tries to format 'val' as a small integer. If not possible falls back - * to decimal representation. If also not possible, falls back to scientific - * notation. - * - * Handy in cases where we need to "just print that number" without having - * stupid amount of nonsense decimal places or bother readers with - * scientific notation where "just an int" would perfectly do the job. - * - * @param val - * The number to format. - * - * @param ndig - * How many significant digits to be printed. MUST be in range 1..7. - */ - public static String toStr(float val, int ndig) { - int exp; - float limit; - if (val == 0) return "0"; - switch (ndig) { - case 1: exp = 1; limit = 1e4F; break; - case 2: exp = 10; limit = 1e6F; break; - case 3: exp = 100; limit = 1e7F; break; - case 4: exp = 1000; limit = 1e8F; break; - case 5: exp = 10000; limit = 1e9F; break; - case 6: exp = 100000; limit = 1e10F; break; - case 7: exp = 1000000; limit = 1e11F; break; - default: throw new IllegalArgumentException("ndig " + ndig + " not in expected range 1..7"); - } - if (val >= exp && val <= limit) { - // Just print as an int. - return String.valueOf((int) val); - } else { - String fmt; - switch (ndig) { // Select an appropriate format. - case 1: fmt = "%.1g"; break; - case 2: fmt = "%.2g"; break; - case 3: fmt = "%.3g"; break; - case 4: fmt = "%.4g"; break; - case 5: fmt = "%.5g"; break; - case 6: fmt = "%.6g"; break; - case 7: fmt = "%.7g"; break; - default: throw new IllegalArgumentException("ndig " + ndig + " not in expected range 1..7"); - } - return String.format(fmt, val).replace(',', '.').replace("'", ""); - } - } - -} +/** Obsolete: This class did migrate to "xtra4j" */ +@Deprecated +public class FormatUtils {} diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/json/JsonUtils.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/json/JsonUtils.java index c8be86a..f860b85 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/json/JsonUtils.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/json/JsonUtils.java @@ -24,18 +24,18 @@ public class JsonUtils { */ public static <TreeToValueFunc extends ObjectCodecIface<JsonNode, Map>, JsonNode, K, V> - Map<K, V> decodeMap(TreeToValueFunc treeToValueFunc, JsonNode mapNode, Class<K> keyType, Class<V> valueType) throws IOException { + Map<K, V> decodeMap( TreeToValueFunc treeToValueFunc, JsonNode mapNode, Class<K> keyType, Class<V> valueType ) throws IOException { final Map<K, V> envVars; - if (mapNode == null) { + if( mapNode == null ){ envVars = new LinkedHashMap<>(); - } else { + }else{ envVars = treeToValueFunc.treeToValue(mapNode, Map.class); } return envVars; } public static interface ObjectCodecIface<TreeNode, Value> { - Value treeToValue(TreeNode input, Class<Map> returnType) throws IOException; + Value treeToValue( TreeNode input, Class<Map> returnType ) throws IOException; } diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ByteChunkOStream.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ByteChunkOStream.java index 04688d6..49959fc 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ByteChunkOStream.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ByteChunkOStream.java @@ -38,8 +38,8 @@ public class ByteChunkOStream extends OutputStream { len -= appendedBytes; }else if( remainingBytes == 0 ){ break; // Done :) - }else { - throw new UnsupportedOperationException("Huh?!? why is remainingBytes " + remainingBytes + "?"); + }else{ + throw new UnsupportedOperationException("Huh?!? why is remainingBytes "+ remainingBytes +"?"); } } } @@ -117,11 +117,11 @@ public class ByteChunkOStream extends OutputStream { /** Inspired by {@link java.util.function.Consumer} */ public static interface ChunkHandler { - void accept(byte[] bytes) throws IOException; + void accept( byte[] bytes ) throws IOException; } - /** Inspired by {@link Runnable#run()} */ + /** Inspired by {@link java.util.function.Runnable#run()} */ public static interface EndHandler { void run() throws IOException; } diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ByteCountOutputStream.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ByteCountOutputStream.java index 006ea6b..8e2b47f 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ByteCountOutputStream.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ByteCountOutputStream.java @@ -31,13 +31,9 @@ public class ByteCountOutputStream extends OutputStream { } @Override - public void flush() throws IOException { - origin.flush(); - } + public void flush() throws IOException { origin.flush(); } @Override - public void close() throws IOException { - origin.close(); - } + public void close() throws IOException { origin.close(); } } diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/BytePool.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/BytePool.java index 4a619da..b6c8131 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/BytePool.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/BytePool.java @@ -91,7 +91,7 @@ public class BytePool { long amountLong = oldVal - newVal; this.amount.set((int) amountLong); if( this.amount.get() != amountLong ){ - throw new RuntimeException("A moron just tried to allocate " + amountLong + " bytes (more than INT_MAX)"); + throw new RuntimeException("A moron just tried to allocate "+ amountLong +" bytes (more than INT_MAX)"); } } @@ -107,7 +107,7 @@ public class BytePool { * // Don't know exactly how much we need. Make a guess.<br/> * allocdBytes = pool.alloc(42);<br/> * int actuallyNeeded = source.read(buf, 0, allocdBytes.getAmount());<br/> - * // Now we know exactly how much we need and can free the rest.<br/> + * // Now we know exactly how much we need and can release the rest.<br/> * allocdBytes.shrinkTo(actuallyNeeded);<br/> * </code> */ diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/CRLFtoLFOutputStream.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/CRLFtoLFOutputStream.java index 75b1a9f..0c242aa 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/CRLFtoLFOutputStream.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/CRLFtoLFOutputStream.java @@ -4,13 +4,15 @@ import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; +import org.slf4j.ILoggerFactory; +import org.slf4j.Logger; -/** - * Filter to fix broken newlines. - */ + +/** Filters away broken newlines. */ public class CRLFtoLFOutputStream extends FilterOutputStream { private static final int EMPTY = -42; + private final Logger log; private int previous = EMPTY; /** @@ -18,7 +20,16 @@ public class CRLFtoLFOutputStream extends FilterOutputStream { * Destination where the result will be written to. */ public CRLFtoLFOutputStream( OutputStream dst ) { + this(dst, null); + } + + /** + * @param dst + * Destination where the result will be written to. + */ + public CRLFtoLFOutputStream( OutputStream dst, ILoggerFactory lf ) { super(dst); + this.log = (lf == null) ? null : lf.getLogger(CRLFtoLFOutputStream.class.getName()); } @Override @@ -27,7 +38,7 @@ public class CRLFtoLFOutputStream extends FilterOutputStream { // This allows us to assign special meanings to those values internally (eg our // 'EMPTY' value). For this to work, we clear the high bits to not get confused // just in case someone really passes such values. - current = current & 0xFF; + current &= 0xFF; if( previous == '\r' && current == '\n' ){ // Ignore the CR and only write the LF. @@ -43,14 +54,21 @@ public class CRLFtoLFOutputStream extends FilterOutputStream { } } + // TODO we should override this. + //@Override + //public void write( byte[] buf, int off, int len ) throws IOException { + // throw new UnsupportedOperationException("TODO impl");/*TODO*/ + //} + @Override public void flush() throws IOException { if( previous == '\r' ){ - //log.warn("Have to flush a CR byte without knowing if the next byte might be a LF"); + log.debug("Have to flush a CR byte without knowing if the next byte might be a LF"); } if( previous != EMPTY ){ - super.write(previous); + int tmp = previous; previous = EMPTY; + super.write(tmp); } super.flush(); } diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/CloseNotifyOutputStream.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/CloseNotifyOutputStream.java index 2e19c52..a8d6eea 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/CloseNotifyOutputStream.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/CloseNotifyOutputStream.java @@ -17,9 +17,9 @@ public class CloseNotifyOutputStream extends FilterOutputStream { private final Runnable onClose; private final AtomicBoolean isFired = new AtomicBoolean(false); - public CloseNotifyOutputStream(OutputStream out, Runnable onClose) { + public CloseNotifyOutputStream( OutputStream out, Runnable onClose ){ super(out); - if(true) throw new UnsupportedOperationException("TODO need to delegate close call");/*TODO*/ + if( true ) throw new UnsupportedOperationException("TODO need to delegate close call");/*TODO*/ this.onClose = requireNonNull(onClose); } @@ -28,6 +28,10 @@ public class CloseNotifyOutputStream extends FilterOutputStream { if (!isFired.getAndSet(true)) { onClose.run(); } + // TODO Need to delegate to filtered stream. + // Properly delegating requires to propery handle all the + // special cases around exceptions. See also + // CloseNotifyInputStream which does a similar task. } } diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ConcatInputStream.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ConcatInputStream.java index 819e6da..8c89fc0 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ConcatInputStream.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/octetstream/ConcatInputStream.java @@ -57,12 +57,13 @@ public class ConcatInputStream extends InputStream { public void close() throws IOException { // Close all remaining sources. Exception firstException = null; - for( int i = iSrc; i < sources.length; ++i ){ + for( int i = iSrc ; i < sources.length ; ++i ){ try{ sources[i].close(); }catch( IOException|RuntimeException ex ){ if( firstException == null ){ - // Track the exception. But we need to close the remaining ones. + // Track the exception. But we have to close the + // remaining streams regardless of early exceptions. firstException = ex; }else if( firstException != ex ){ firstException.addSuppressed(ex); @@ -72,7 +73,7 @@ public class ConcatInputStream extends InputStream { sources = null; // Allow GC // Bubble exception if we had any. if( firstException instanceof RuntimeException ){ - throw (RuntimeException) firstException; + throw (RuntimeException)firstException; }else if( firstException != null ){ throw (IOException)firstException; } @@ -83,6 +84,8 @@ public class ConcatInputStream extends InputStream { InputStream oldSrc = sources[iSrc]; sources[iSrc] = null; iSrc += 1; + // Calling close as last step to prevent trouble with our + // state as it potentially could throw. oldSrc.close(); } } diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/shell/ShellUtils.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/shell/ShellUtils.java index 5e2aff2..6c903ec 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/shell/ShellUtils.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/shell/ShellUtils.java @@ -6,10 +6,13 @@ public class ShellUtils { /** * Escapes the string so we can use the result in a * <a href="https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_02_03">double-quoted shell string</a>. - * But keeps <a href="https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02">parameter expansion</a> alive. + * But keeps <a href="https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02">parameter expansion</a> + * alive. * Example usage: - * String path = "pâth \\with ${varToResolve} but a|so €vil chars like spaces, p|pes or * asterisk"; - * cmd = "ls '"+ escapeForSnglQuotEverything(path) +"'"; + * <code> + * String path = "pâth \\with ${varToResolve} but a|so €vil chars like spaces, p|pes or * asterisk";<br/> + * cmd = "ls \""+ escapeForDblQuotButParams(path) +"\"";<br/> + * </code> */ public static String escapeForDblQuotButParams( String s ){ s = s.replace("\\", "\\\\"); @@ -23,8 +26,10 @@ public class ShellUtils { * Escapes the string so we can use result in a * <a href="https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_02_02">single-quoted shell string</a>. * Example usage: - * String path = "pâth \\with ${MustNotResolveThisVar} and a|so €vil chars like spaces, p|pes or * asterisk"; - * cmd = "ls '"+ escapeForSnglQuotEverything(path) +"'"; + * <code> + * String path = "pâth \\with ${MustNotResolveThisVar} and a|so €vil chars like spaces, p|pes or * asterisk";<br/> + * cmd = "ls '"+ escapeForSnglQuotEverything(path) +"'";<br/> + * </code> */ public static String escapeForSingleQuotEverything( String s ){ // Cited from "Single-Quotes" in "https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html": diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/stream/StreamUtils.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/stream/StreamUtils.java index 696d4d3..7d712ee 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/stream/StreamUtils.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/stream/StreamUtils.java @@ -1,5 +1,8 @@ package ch.hiddenalpha.unspecifiedgarbage.stream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Iterator; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -11,28 +14,29 @@ public class StreamUtils { /** * Copies 'is' to 'os' until end of 'is' is reached. (Blocking) + * + * <p>BTW: Using this function makes no longer sense in projects using java + * 9 or later. Just use {@link java.io.InputStream#transferTo(java.io.OutputStream)} + * instead.</p> + * * @return * Count of copied bytes. */ - public static long copy(java.io.InputStream is, java.io.OutputStream os) throws java.io.IOException { - byte[] buffer = new byte[1024]; + public static long copy( java.io.InputStream is, java.io.OutputStream os ) throws java.io.IOException { + byte[] buffer = new byte[8192]; long totalBytes = 0; int readLen; while( -1 != (readLen=is.read(buffer,0,buffer.length)) ){ totalBytes += readLen; - os.write( buffer , 0 , readLen ); + os.write(buffer, 0, readLen); } return totalBytes; } - public static <SRC,DST> java.util.Iterator<DST> map(java.util.Iterator<SRC> src , java.util.function.Function<SRC,DST> mapper) { + public static <SRC,DST> java.util.Iterator<DST> map( java.util.Iterator<SRC> src , java.util.function.Function<SRC,DST> mapper ) { return new Iterator<DST>() { - @Override public boolean hasNext() { - return src.hasNext(); - } - @Override public DST next() { - return mapper.apply(src.next()); - } + @Override public boolean hasNext() { return src.hasNext(); } + @Override public DST next() { return mapper.apply(src.next()); } }; } @@ -41,7 +45,7 @@ public class StreamUtils { return t -> seen.add(keyExtractor.apply(t)); } - public static <T> Predicate<T> not(Predicate<T> p){ + public static <T> Predicate<T> not( Predicate<T> p ){ return e -> !p.test(e); } diff --git a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/time/TimeUtils.java b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/time/TimeUtils.java index ddb1c13..2bb1bfb 100644 --- a/src/main/java/ch/hiddenalpha/unspecifiedgarbage/time/TimeUtils.java +++ b/src/main/java/ch/hiddenalpha/unspecifiedgarbage/time/TimeUtils.java @@ -4,17 +4,17 @@ package ch.hiddenalpha.unspecifiedgarbage.time; public class TimeUtils { /** - * Delegates to {@link #nanosToEpochMillis(long, long, long)} and assumes - * that the 'nanos' value was measure in the same JVM process as this call - * here occurs and is not too long back. + * Delegates to {@link #nanosToEpochMillis(long, long, long)} and + * assumes that the 'nanos' value was measured in the same JVM + * process as this call here occurs and is not too long back. */ - public static long nanosToEpochMillis(long nanos) { + public static long nanosToEpochMillis( long nanos ){ return nanosToEpochMillis(nanos, System.nanoTime(), System.currentTimeMillis()); } - public static long nanosToEpochMillis(long nanos, long referenceNanos, long referenceEpochMs) { + public static long nanosToEpochMillis( long nanos, long referenceNanos, long referenceEpochMs ){ long diffNs = nanos - referenceNanos; - if (diffNs < (Long.MIN_VALUE >> 1) || diffNs > (Long.MAX_VALUE>>1)) { + if( diffNs < (Long.MIN_VALUE >> 1) || diffNs > (Long.MAX_VALUE>>1) ){ // Looks as System.nanoTime() did overflow while measurement. So flip result too. diffNs -= Long.MAX_VALUE; } @@ -22,29 +22,38 @@ public class TimeUtils { } /** - * Computers cannot represent all existing integers. Due to how integers - * are represented in computers, they are not infinite but more like a circle. - * Speak when we infinitely increment an integer, it overflows and (usually) - * continues to walk around this (imaginary) circle. + * Find smallest distance assuming integers overflow "like a circle". * - * This function takes two of those numbers on this circle and returns the - * smallest distance to travel on the circle between them. Here some examples: - * - f(7, 13) = 6 - * - f(-7, +11) = 18 - * - f(LONG_MIN, LONG_MAX) = 1 - * - f(-9223372036854775805, 9223372036854775802) = 9 + * Computers cannot represent all existing integers. Due to how + * integers are represented in computers, they are not infinite but + * more like a circle. Speak when we infinitely increment an + * integer, it overflows and (usually) continues to walk around this + * (imaginary) circle. + * + * This function takes two of those numbers on this circle and + * returns the smallest distance to travel on the circle between + * them. Here some examples: + * <ul> + * <li>f(7, 13) = 6</li> + * <li>f(-7, +11) = 18</li> + * <li>f(LONG_MIN, LONG_MAX) = 1</li> + * <li>f(-9223372036854775805, 9223372036854775802) = 9</li> + * </ul> * * This can be handy for example in conjunction with {@link System#nanoTime()}. - * Because in case of overflows between measuring begNs and endNs a simple subtraction - * would lead to uselessly large results. So we can use it as: - * long begNs = System.nanoTime(); - * long endNs = System.nanoTime(); - * long durationNs = nanosSmallDiff(begNs, endNs); + * Because in case of overflows between measuring begNs and endNs a + * simple subtraction would lead to uselessly large results. So we + * can use it as: + * <code> + * long begNs = System.nanoTime(); + * long endNs = System.nanoTime(); + * long durationNs = nanosSmallDiff(endNs, begNs); + * </code> * - * WARN: Do NOT use this if your distance can reach (LONG_MAX / 2). Because - * in this case you would get wrong (too small) results. + * WARN: Do NOT use this if your distance can reach (LONG_MAX / 2). + * Because in this case you would get wrong (too small) results. */ - public static long nanosSmallDiff(long a, long b) { + public static long nanosSmallDiff( long a, long b ){ return (a - b >= 0) ? a - b : b - a; } diff --git a/src/main/shell/BackupByRsync/backup.sh b/src/main/shell/BackupByRsync/backup.sh new file mode 100755 index 0000000..e557d45 --- /dev/null +++ b/src/main/shell/BackupByRsync/backup.sh @@ -0,0 +1,137 @@ + +# Some tinkering about how I could do backup. +# +# Inspired by: +# https://linuxconfig.org/how-to-create-incremental-backups-using-rsync-on-linux +# +# mount /dev/sdx1 /mnt/x +# + +set -o errexit +set -o pipefail + +readonly NOW_SHORT="$(date -u '+%Y%m%d-%H%M%S')" +readonly DIR_FROM="/home/${USER:?}/." +readonly DST_PREFIX="${DIR_FROM:?}" +readonly DIR_TO="/mnt/x/ROOT_DIR/bkup-rsync/tux-six" +readonly BACKUP_PATH="${DIR_TO}/${NOW_SHORT}" + + +printHelp () { + printf "\n\ + TODO write help page\n\ + \n"; +} + + +parseArgs () { + local arg0="$0" + local isExample="false" + while [ $# -gt 0 ]; do + local arg="$1" + if false; then + true + elif [ "$arg" == "--help" ]; then + printHelp; return 1 + elif [ "$arg" == "--example" ]; then + isExample="true"; + else + echo "Unexpected arg: $arg"; return 1 + fi + shift 1 + done + if ! $isExample; then echo >&2 "Bad args"; return 1; fi + return 0 +} + + +run () { + if [ ! -e "${DIR_TO:?}" ]; then + echo >&2 "Backup root dir does not exist. Abort." + return 1 + fi + mkdir -p "${BACKUP_PATH:?}/${DST_PREFIX:?}" + rsync --archive --verbose \ + --link-dest "${DIR_TO}/latest/${DST_PREFIX:?}" \ + --filter=':- .gitignore' \ + --exclude=".git/COMMIT_EDITMSG" \ + --exclude=".git/FETCH_HEAD" \ + --exclude=".git/ORIG_HEAD" \ + --exclude=".git/branches" \ + --exclude=".git/hooks/*.sample" \ + --exclude=".git/index" \ + --exclude=".git/info" \ + --exclude=".git/logs" \ + --exclude=".git/objects" \ + --exclude=".git/packed-refs" \ + --exclude=".git/refs/remotes" \ + --exclude=".git/refs/tags" \ + --exclude=".idea" \ + --exclude="/.NERDTreeBookmarks" \ + --exclude="/.Xauthority" \ + --exclude="/.bash_history" \ + --exclude="/.config/VirtualBox/HostInterfaceNetworking-vboxnet0-Dhcpd.leases*" \ + --exclude="/.config/VirtualBox/HostInterfaceNetworking-vboxnet0-Dhcpd.log*" \ + --exclude="/.config/VirtualBox/VBoxSVC.log*" \ + --exclude="/.config/VirtualBox/compreg.dat" \ + --exclude="/.config/VirtualBox/selectorwindow.log*" \ + --exclude="/.config/VirtualBox/vbox-ssl-cacertificate.crt" \ + --exclude="/.config/VirtualBox/xpti.dat" \ + --exclude="/.config/libreoffice" \ + --exclude="/.config/GIMP" \ + --exclude="/.config/JetBrains" \ + --exclude="/.gdb_history" \ + --exclude="/.lesshst" \ + --exclude="/.profile" \ + --exclude="/.vimrc" \ + --exclude="/.xsession-errors" \ + --exclude="/.xsession-errors.old" \ + --exclude="/mnt" \ + --exclude="/.android" \ + --exclude="/.cache" \ + --exclude="/.config/chromium" \ + --exclude="/.config/inkscape" \ + --exclude="/.local/share" \ + --exclude="/.m2/repository" \ + --exclude="/.mozilla/firefox" \ + --exclude="/.squirrel-sql" \ + --exclude="/.viking-maps" \ + --exclude="/Downloads" \ + --exclude="/crashdumps" \ + --exclude="/images" \ + --exclude="/projects/apple/cups" \ + --exclude="/projects/gnu" \ + --exclude="/projects/lua" \ + --exclude="/projects/misc/OpenSSL" \ + --exclude="/projects/misc/OpenVPN" \ + --exclude="/projects/misc/busybox" \ + --exclude="/projects/misc/cgit" \ + --exclude="/projects/misc/dash" \ + --exclude="/projects/misc/endlessh" \ + --exclude="/projects/misc/jssc" \ + --exclude="/projects/misc/libqrencode" \ + --exclude="/projects/misc/mbedtls" \ + --exclude="/projects/misc/openbox" \ + --exclude="cee-misc-lib/external" \ + --exclude="cee-misc-lib/tmp" \ + --exclude="/tmp" \ + --exclude="/virtualbox-*" \ + --exclude="/vmshare" \ + "${DIR_FROM:?}" \ + "${BACKUP_PATH:?}/${DST_PREFIX}" \ + ; + (cd "${DIR_TO:?}" && + rm -f latest && + ln --symbolic "${NOW_SHORT:?}" latest + ) +} + + +main () { + parseArgs "$@" + if [ $? -ne 0 ]; then exit 2; fi + run +} + + +main "$@" |