====== Lehky kolovy tucnak ====== Ani balik neodstranis, protoze je to v zavislostech...! ===== Vira duveru prenasi ===== # rm -rfv /etc/ssl/certs $ echo "check-certificate = off" > $HOME/.wgetrc ===== Fixovani hipstrovin ===== Edit "/etc/default/grub" GRUB_CMDLINE_LINUX_DEFAULT="quiet nouveau.modeset=0 net.ifnames=0 biosdevname=0" Zakaz IPv6 v /etc/sysctl.d/ipv6.conf net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf..disable_ipv6 = 1 ===== clubmate ===== $ gsettings set org.mate.Marco.window-keybindings minimize Super_L $ gsettings set org.mate.Marco.general button-layout 'close,maximize,minimize:' $ gsettings set org.mate.caja.desktop computer-icon-visible false $ gsettings set org.mate.caja.desktop home-icon-visible false $ gsettings set org.mate.caja.desktop network-icon-visible false $ gsettings set org.mate.caja.desktop trash-icon-visible false $ gsettings set org.mate.caja.desktop volumes-icon-visible true ===== Nebezpecny SW pod jinym uzivatelem ===== Odriznuti prohlizece nebo jineho nebezpecneho SW od dat bezneho uzivatele (sachy) tim, ze se bude spoustet pod vlastnim neprivilegovanym uzivatelem (ffuser). Obdobne pro jiny crapware... # echo "sachy ALL=(ffuser) NOPASSWD: /home/ffuser/firefox/firefox" >> /etc/sudoers $ xhost +si:localuser:ffuser # povolit ffuserovi pouzit $DISPLAY ... $ sudo -u ffuser /home/ffuser/firefox/firefox === LibreOffice === LO is a bit complicated since it does not have portable tgz archive so one have to rely on compiled/packaged version. The other issue is that there are 2 entry points of main executable - soffice and libreoffice symbolic links. /usr/bin/libreoffice -> ../lib/libreoffice/program/libreoffice /usr/bin/soffice -> ../lib/libreoffice/program/soffice The first idea is to set uid/gid to the special libreoffice user - but Gtk will prevent execution this way, so one have to replace those two symlinks with bash script. #!/bin/bash sudo -u lo /usr/lib/libreoffice/program/soffice "$@" ===== Finch a jeho zavislosti ===== Finch je TUI irc/jabber/... komunikator nad libpurple0 (oboji soucast pidginu, ale pouzitelne samostatne). V debian-like distrech terminalovy klient zavisi na fontech a dalsich GUI nesmyslech. Stazeni .deb a rozbaleni: $ apt-get download finch libpurple0 $ dpkg-deb -R ./finch.deb ./fmin $ dpkg-deb -R ./libpurple0.deb ./lp0min Nahrazeni zavislosti finche (./fmin/DEBIAN/control) Pozor na nazev "finch" -> "finch-minimal" a zavislost "libpurple0" -> "libpurple0-minimal"! Package: finch-minimal Source: finch-minimal Version: 2.11.0-0+deb8u1 Architecture: amd64 Maintainer: Ari Pollak Installed-Size: 744 Depends: libc6 (>= 2.14), libglib2.0-0 (>= 2.35.9), libncursesw5 (>= 5.6+20070908), libpurple0-minimal (>= 2.8.0), libtinfo5, libxml2 (>= 2.7.4) Podobne pro libpurple0 (./lp0min/DEBIAN/control) Package: libpurple0-minimal Source: libpurple0-minimal Version: 2.11.0-0+deb8u1 Architecture: amd64 Maintainer: Ari Pollak Installed-Size: 4861 Depends: libc6 (>= 2.15), libdbus-1-3 (>= 1.0.2), libdbus-glib-1-2 (>= 0.78), libglib2.0-0 (>= 2.37.3), libidn11 (>= 1.13), libnspr4 (>= 2:4.9-2~) | libnspr4-0d (>= 1.8.0.10), libnss3 (>= 2:3.14), libperl5.20 (>= 5.20.2), libsasl2-2, libxml2 (>= 2.7.4), perl-base (>= 5.20.2-3+deb8u5), perlapi-5.20.2, libsasl2-modules Suggests: libtcl8.6 (>= 8.6.0) Instalace upravenych baliku: $ dpkg-deb --build ./fmin ./ $ dpkg-deb --build ./lp0min ./ # dpkg -i ./finch-minimal.deb ./libpurple0-minimal.deb # apt-get install -f # dotazeni zavislosti Pripadne, pokud nekdo chce kompilovat, tak: (pozor na --with-static-prpls="") $ ./configure --disable-gtkui --disable-screensaver --disable-sm --disable-startup-notification --disable-gtkspell --disable-gevolution --disable-cap --disable-gestures --disable-schemas-install --disable-gstreamer --disable-gstreamer-video --disable-gstreamer-interfaces --disable-farstream --disable-vv --disable-meanwhile --disable-avahi --disable-nm --disable-plugins --disable-perl --enable-gnutls=yes --enable-nss=yes --disable-tcl --disable-tk --disable-pixmaps-install --disable-doxygen --disable-dot --with-static-prpls="irc jabber" --disable-idn --disable-dbus --with-x=no --enable-consoleui --disable-nls $ make -j 1 # make install # make checkinstall Profit! ===== mutt ===== === Zvyraznovac dulezitych headeru v muttu === /usr/share/nano/mutt.nanorc ## Here is an example for quoted emails (under e.g. mutt). ## syntax "mutt" color yellow "^>.*" color green "^> >.*" color yellow "^Subject: .*" color yellow "^From: .*" color yellow "^Date: .*" # echo 'include "/usr/share/nano/mutt.nanorc"' >> /etc/nanorc $ echo 'set editor="nano --syntax=mutt "' >> $HOME/.mutt/muttrc === Mutt v ruznych sitich === Nekteri poskytovalete maji pocit, ze vsechna odchozi posta musi projit pres jejich SMTP server a ostatni SMTPS spojeni zariznou. Rucne menit konfiguraky pri prechodech je otrava, pomuze script :) V globalnim muttrc je asi neco takoveho (makra na zmenu schranky, dle poctu ruznych mailu): macro index 'source $HOME/.mutt/MAILBOX.muttrc!' MAILBOX.muttrc jsou specificke volby pro danou schranku. Je tedy potreba je vygenerovat z predlohy a docpat tam spravny smtp_url, pripadne dalsi upravy dle poskytovatele. mutt1.sh #!/bin/bash cp -f $HOME/.mutt/MAILBOX.muttrc.src $HOME/.mutt/MAILBOX.muttrc echo 'set smtp_url="smtps://such.security.wtf"' >> $HOME/.mutt/MAILBOX.muttrc mutt exit Podobne pro dalsi poskytovatele mutt2.sh atd. Generatory lze ulozit bud do /usr/local/bin nebo pres alias do .bashrc a pak mutt spoustet generatorem, nikoli rovnou. === gnupg-2.1 === Gnupg-2.1 zmenilo API, takze mutt s nim nefunguje. Je potreba zmenit parametry: set pgp_decode_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --no-auto-check-trustdb --batch --output - %f" set pgp_verify_command="gpg --pinentry-mode loopback --verbose --batch --output - --no-auto-check-trustdb --verify %s %f" set pgp_decrypt_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --batch --output - %f" set pgp_sign_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --batch --output - --armor --textmode %?a?-u %a? --detach-sign %f" set pgp_clearsign_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --batch --output - --armor --textmode %?a?-u %a? --detach-sign %f" set pgp_encrypt_sign_command="pgpewrap gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --batch --textmode --trust-model always --output - %?a?-u %a? --armor --encrypt --sign --armor -- -r %r -- %f" set pgp_encrypt_only_command="pgpewrap gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --batch --trust-model always --output --output - --encrypt --textmode --armor -- -r %r -- %f" set pgp_import_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --import -v %f" set pgp_export_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --export --armor %r" set pgp_verify_key_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --batch --fingerprint --check-sigs %r" set pgp_list_pubring_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --batch --with-colons --list-keys %r" set pgp_list_secring_command="gpg %?p?--pinentry-mode loopback --passphrase-fd 0? --verbose --batch --with-colons --list-secret-keys %r" viz: [[https://robbat2.livejournal.com/241544.html?nojs=1]] V novem gnupg uz nejde vynutit autorizace bez gpg-agent, takze pouzijeme pinentry-curses # apt install pinentry-curses # update-alternatives --config pinentry In mutt 1.14.6 there is an error in handling gpg encrypted messages, falsely claiming that the decryption failed. Use my patch... --- PATCHES~ Wed Jul 29 19:00:54 CEST 2020 +++ PATCHES Wed Jul 29 19:00:54 CEST 2020 @@ -1,0 +1 @@ +patch.1.14.6.ms.gpg.1 diff /s/mutt-1.14.6/pgp.c ./pgp.c 1011c1011,1012 < if (pgp_check_decryption_okay (pgperr) < 0) --- > if (pgp_check_decryption_okay (pgperr) <= -3) === Change file permissions of saved attachments === Mutt calls on itself umask(077) and when you decide to save/open an attachment, Mutt is creating the file with 0600 permissions. The following patch is adding a support for a new muttrc option save_file_perm, which allows change the default mask to something else (for example 644). diff -Naru /s/mutt-2.2.12/globals.h ./globals.h --- /s/mutt-2.2.12/globals.h 2023-09-01 08:32:23.000000000 +0200 +++ ./globals.h 2023-09-10 10:13:54.320014522 +0200 @@ -250,6 +250,8 @@ WHERE short ScoreThresholdRead; WHERE short ScoreThresholdFlag; +WHERE short SaveFilePerm; + #ifdef USE_SIDEBAR WHERE short SidebarWidth; WHERE LIST *SidebarWhitelist; diff -Naru /s/mutt-2.2.12/init.h ./init.h --- /s/mutt-2.2.12/init.h 2023-09-01 08:32:23.000000000 +0200 +++ ./init.h 2023-09-10 10:18:22.900015368 +0200 @@ -3460,6 +3460,11 @@ ** \fBNote:\fP This only applies to mbox and MMDF folders, Mutt does not ** delete MH and Maildir directories. */ + { "save_file_perm", DT_NUM, R_NONE, {.p=&SaveFilePerm}, {.l=0600} }, + /* + ** This variable controls the permissions of saved attachments. + ** Use standard POSIX permissions in octal notation, i.e. 0644. + */ { "save_history", DT_NUM, R_NONE, {.p=&SaveHist}, {.l=0} }, /* ** .pp diff -Naru /s/mutt-2.2.12/main.c ./main.c --- /s/mutt-2.2.12/main.c 2023-09-01 08:32:23.000000000 +0200 +++ ./main.c 2023-09-10 10:15:20.128014792 +0200 @@ -690,7 +690,10 @@ mutt_error = mutt_nocurses_error; mutt_message = mutt_nocurses_error; SRAND (time (NULL)); - umask (077); + if(SaveFilePerm==600) + umask (077); + else + umask (000); memset (Options, 0, sizeof (Options)); memset (QuadOptions, 0, sizeof (QuadOptions)); diff -Naru /s/mutt-2.2.12/muttlib.c ./muttlib.c --- /s/mutt-2.2.12/muttlib.c 2023-08-18 05:03:18.000000000 +0200 +++ ./muttlib.c 2023-09-10 10:36:18.872018760 +0200 @@ -2562,6 +2562,22 @@ BUFFER *safe_file = NULL; BUFFER *safe_dir = NULL; + /* Convert file permission from decadic to octal */ + unsigned short own=0; + unsigned short grp=0; + unsigned short oth=0; + unsigned short SFPoct=0; + own=SaveFilePerm/100; + grp=(SaveFilePerm-own*100)/10; + oth=SaveFilePerm-(own*100)-(grp*10); + if(own>7||grp>7||oth>7) + { + SFPoct=0600; + dprint(1,(debugfile,"safe_open: Value %d is not valid octal permission mask.\n",SaveFilePerm)); + } + else + SFPoct=own<<6|grp<<3|oth; + if (flags & O_EXCL) { safe_file = mutt_buffer_pool_get (); @@ -2573,7 +2589,7 @@ goto cleanup; } - if ((fd = open (mutt_b2s (safe_file), flags, 0600)) < 0) + if ((fd = open (mutt_b2s (safe_file), flags, SFPoct)) < 0) { rmdir (mutt_b2s (safe_dir)); goto cleanup; @@ -2588,7 +2604,7 @@ } } - if ((fd = open (path, flags & ~O_EXCL, 0600)) < 0) + if ((fd = open (path, flags & ~O_EXCL, SFPoct)) < 0) goto cleanup; /* make sure the file is not symlink */ Compile with following configure: ./configure --prefix=/usr --enable-pgp --enable-imap --enable-smtp --with-gnutls --enable-hcache --with-tokyocabinet --enable-debug --enable-largefile --enable-smime --with-sasl The patch was rejected by the Mutt development team because the maintainers do not want to have such a feature, as was discussed several times during the Mutts history. === text/html a text/plain === How to read HTML emails in mutt, but automatically prefer plaintext if available in the multipart? The way is self-explaining... auto_view text/html alternative_order text/plain text/html text/html; links %s; nametemplate=%s.html text/html; links -dump %s; nametemplate=%s.html; copiousoutput === Export message as .eml === Sometimes third party requires an .eml message to be send as a "proof" of communication. So be it... Make sure to have '|' bound to default behavior in index and pager contexts. Also pick some invocation key, for example 's'. The macro will invoke external script called file_email.sh macro index,pager s "| ~/.mutt/file_email.sh /tmp" set pipe_decode=yes And now the script to store the email to the /tmp #!/bin/bash # Save piped email to "$1/YYMMDD_SUBJECT.eml" # Make sure commands 's' and '|' have default meaning and are NOT unbinded # Don't overwrite existing file set -o noclobber message=$(cat) maildate=$(<<<"$message" grep -oPm 1 '^Date: ?\K.*') fdate=$(date -d "$maildate" "+%y%m%d") subject=$(<<<"$message" grep -oPm 1 '^Subject: ?\K.*' | sed 's,/,∕,g') if [[ "$fdate" == '' ]]; then echo "Error: no date parsed" exit 1 elif [[ "$subject" == '' ]]; then echo "Warning: no subject found" fi echo "${message}" > "$1/$fdate""_""$subject.eml" && echo "Email saved to $1/$fdate""_""$subject.eml" exit ===== URL MitM ===== Nektera dialogova okna maji klikaci odkaz u ktereho nejde zjistit cilova adresa, nebo se crapware snazi otevrit nejaky web sam od sebe. Resenim je nahradit vychozi browser dialogovym oknem, ktery onen odkaz zobrazi. Fake browser: /opt/displaylink.sh #!/bin/bash zenity --info --text="$1" exit Nastaveni MitM jako defaultniho browseru (system-wide): # update-alternatives --install /opt/x-www-browser x-www-browser /opt/displaylink.sh 666 user-wide /usr/share/applications/displaylink.desktop [Desktop Entry] Version=1.0 Name=Displaylink Exec=/opt/displaylink.sh %U Terminal=false Type=Application a pak pro http, https, ftp, ...: $ sed -i 's/x-scheme-handler\/http=.*/x-scheme-handler\/http=displaylink.desktop/g' $HOME/.config/mimeapps.list ===== Zniceni .xsession-errors ===== V HOME se tvori zbytecny, obrovsky log .xsession-errors a .xsession-errors.old. Presmerovani do /dev/null nepomaha, Xka si ho zase nahradi za bezny soubor. Takhle se ho da zbavit: # echo "exec >> /dev/null 2>&1" > /etc/X11/Xsession.d/05-noerr # chmod +x /etc/X11/Xsession.d/05-noerr ===== Snizovani zbytecneho IO ===== v /etc/fstab se da pripojovat filesystem s volbami "noatime,nodiratime", coz zakaze aktualizace casu pristupu k souboru/adresari (IMHO uplne zbytecny timestamp). Zruseni xsession-errors (viz vyse) /var/log se da mountit jako tmpfs. none /var/log tmpfs size=100M,mode=777,noatime,nodiratime 0 0 ~.cache je trikove - ukladaji se tam napriklad nahledy medialnich souboru (kdo pracuje s mc, tak nahledy nepotrebuje), dconf "dvoubajtovy binarni blob"... Takze muze byt uzitecne si .cache presunout do tmpfs/nullfs: Pozor na dostatek RAM! $ rm -rfv $HOME/.cache $ ln -s /dev/shm $HOME/.cache $ rm -rfv $HOME/.mozilla/firefox//cache $ ln -s /dev/shm $HOME/.mozilla/firefox//cache ===== Nenazrane pulseaudio ===== Pulseaudio si v /dev/shm dela 64MiB binarni bloby (pulseaudio-shm-*) a NEMAZE je po sobe, cimz efektivne zere "cached" (protoze tmpfs) RAM. Pokud se tyhle bloby zakazou, podle internetu muze vzrust latence (ale nepozoroval jsem)... Nastesti se to da zakazat upravou /etc/pulse/daemon.conf (pozor na strednik na zacatku radku) enable-shm = no ===== Nefunkcni suspend (uspani do RAM) ===== Devuan (MATE 1.8) se neumi uspat do RAM i s nainstalovanym acpi a pm-utils. Je potreba vyresit uspani a zaroven zamkuti obrazovky (pm-suspend jen uspi, ale nezamkne). Pokud se pm-suspend zavola pred dokoncenim zamknuti (je-li screensaver nastaveny na fade-to-black), po probuzeni jsou v obraze artefakty a muze leaknout buffer desktopu pred zamcenim. Distribucni script /etc/acpi/lid.sh vola (pokud existuje a je spustitelny) soubor /etc/acpi/local/lid.sh.pre (pravdepodobné neexistuje -> vytvor): grep -q closed /proc/acpi/button/lid/*/state if [ $? = 0 ]; then xscreensaver-command -display :0.0 -lock && sleep 3; pm-suspend fi Nekdy je jeste potreba vytvorit event pro acpid /etc/acpi/events/lid event=button/lid LID [^o] action=/etc/acpi/lid.sh ===== Zakazani diskretni nvidie ===== Kdyz diskretni grafika jenom zere baterku a nani potreba, tak se da defaultne vypnout: # apt-get install bbswitch-dkms # echo "bbswitch load_state=0" >> /etc/modules # update-initramfs -u -v Pripadne rucne: # echo "OFF" > /proc/acpi/bbswitch # echo "ON" > /proc/acpi/bbswitch ===== Firefox searchplugin ===== Vyhledavac [[https://duckduckgo.com|DDG]] umi vysledky poskytovat bez JS v cistem HTML, pripadne vyhledavat primo obrazky. Umi taky parametricky vypnout "filtrovani nevhodneho obsahu" (GET parametr "kp=-2"). Udelal jsem adekvatni searchpluginy do firefoxu: HTML only, vypnute filtrovani: DuckDuckGoGG HTML Search DuckDuckGoGG (HTML) UTF-8 Hledani rovnou obrazku: DuckDuckGoGG Img Search DuckDuckGoGG (Image) UTF-8 Ulozit do .mozilla/firefox/PROFIL/searchplugins/NAZEV_VYHLEDAVACE.xml ===== Disable USB automount === echo 'ACTION=="add",KERNEL=="sd*",RUN=="/bin/true"' >> /etc/udev/rules.d/noautomount.rules ===== Debian/Devuan cekaji pri bootu 90 s na sit ===== Nejaky idiot implementoval default, ze kdyz pri bootu neni link na eth, tak se musi pockat 90s a on se mozna zazracne objevi. Reseni je snadne: na zacatek /etc/init.d/networking nacpat "exit 0" ===== Rychlejsi internety ===== [[https://www.root.cz/clanky/rizeni-toku-algoritmem-bbr-buldozer-nebere-ohledy-na-ostatni-spojeni/]] # echo "tcp_bbr" >> /etc/modules # echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.d/bbr.conf ===== .nanorc ===== set smooth set softwrap set tabsize 2 set constantshow unset locking bind ^L copytext all ===== URL v xattr ===== Nejaky debil vymyslel a defaultne zapnul ukladani URL stahovaneho souboru do xattr. Informace samotná je uložena jako vlastnost user.xdg.origin.url, případně user.xdg.referrer.url By default se tak chova wget (při kompilaci vypnout parametrem --disable-xattr; za běhu --no-xattr) a chromajzl. [[https://www.root.cz/clanky/atributy-souboru-mohou-obsahovat-url-ze-ktere-byl-soubor-stazen/]] ===== Leading zeros v bc ===== "bc" zahazuje 0 na zacatku desetinnych cisel, protoze americani maji vseobecne s cislama problem (a neexistuje ani zadny prepinac ktery by to zapnul) echo "5*0.1" | bc .5 Nastesti co nedokaze basic calculator, dokaze sed... Fix do .bashrc: alias bc="bc | sed -e 's/^\./0./g' -e 's/^-\./-0./g'" ===== /tmp a tmpfs ===== Software, which was written with the Abacus in mind, expects that the typical processed data wont fit into available RAM. The /tmp directory is the offloading space for such purpose - save the interproduct there and return to it afterwards. But now we have so much RAM, that there are some rumors spreading about the possibility to run TWO electron applications at once! So to move the archaic slow, storage limited /tmp into the RAM, put next line into /etc/fstab: none /tmp tmpfs size=60G,mode=777,noatime,nodiratime 0 0 ===== Strange behavior of touchpad and broken scrolling ===== X11 migrated from evdev to libinput. Lets go back to the working method... apt-get purge xserver-xorg-input-libinput apt-get install xserver-xorg-input-evdev ===== Release.pgp unsupported binary format ===== When apt-get update says ^^, it means that just some junk is left in /var/lib/apt/lists ... # rm -rfv /var/lib/apt/lists/* ===== ALSA ===== Well, audio output gets fucked up completely, since "alsa" command is not provided anymore by any package... apt-get purge alsa* pulseaudio* # Na trisky nehled, me to odjebalo cely mate-desktop shutdown -r now apt-get install alsa-utils libasound2 libasound2-data volumeicon-alsa shutdown -r now So "aplay -l", note proper device you want to use and disable the other ones in /etc/modprobe.d/alsafucked.conf options snd-hda-intel index=HUGE_INTEGER_DEFINITELY_NOT_0,0 Restart again... a v "alsamixer" nastav co je potreba. Restart again and it works (or GOTO 1) ===== Boot do tty ===== Suddenly boots to tty and startx says: modeset: permission denied? apt-get install elogind libpam-elogind ===== IEEEtran.bst ===== Enhancement of popular LaTeX/bibtex style with DOI reference. Just apply {{:user:sachy:ieeetran.bst.diff|the diff}} to the original [[https://www.ieee.org/conferences/publishing/templates.html|IEEEtran.bst]] file... Your .bib file than can use the //doi// variable for articles and books. To make the DOI clickable, change the the .bst file to: FUNCTION {format.doi} { doi empty$ { "" } { this.to.prev.status this.status.std "\doi{" doi * "}" * } if$ } and add to your .tex file \newcommand*{\doi}[1]{\href{http://dx.doi.org/#1}{DOI:\,#1}} ===== Pychess ===== The new version of pychess (1.0.0) is just crippled compared to the previous versions. Not only calls home on each and every start (lookup on github for new version), but the widget at the end of the game hides the back/forth controls unless the game window is insanely huge. So apply following patches: *** ../Utils/checkversion.py 2018-10-29 09:54:18.000000000 +0100 --- /usr/lib/python3/dist-packages/pychess/Utils/checkversion.py 2020-06-12 17:09:50.107964455 +0200 *************** *** 13,18 **** --- 13,19 ---- @asyncio.coroutine def checkversion(): + return new_version = None filename = yield from download_file_async(URL) *** ./gamewidget.py 2019-02-25 11:48:07.000000000 +0100 --- /usr/lib/python3/dist-packages/pychess/widgets/gamewidget.py 2020-06-12 17:21:13.511937822 +0200 *************** *** 655,667 **** prevButton.set_tooltip_text(_("Step back one move")) toolbar.insert(prevButton, -1) ! mainButton = Gtk.ToolButton(stock_id=Gtk.STOCK_GOTO_FIRST) ! mainButton.set_tooltip_text(_("Go back to the main line")) ! toolbar.insert(mainButton, -1) ! ! upButton = Gtk.ToolButton(stock_id=Gtk.STOCK_GOTO_TOP) ! upButton.set_tooltip_text(_("Go back to the parent line")) ! toolbar.insert(upButton, -1) nextButton = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_FORWARD) nextButton.set_tooltip_text(_("Step forward one move")) --- 655,667 ---- prevButton.set_tooltip_text(_("Step back one move")) toolbar.insert(prevButton, -1) ! # mainButton = Gtk.ToolButton(stock_id=Gtk.STOCK_GOTO_FIRST) ! # mainButton.set_tooltip_text(_("Go back to the main line")) ! # toolbar.insert(mainButton, -1) ! ! # upButton = Gtk.ToolButton(stock_id=Gtk.STOCK_GOTO_TOP) ! # upButton.set_tooltip_text(_("Go back to the parent line")) ! # toolbar.insert(upButton, -1) nextButton = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_FORWARD) nextButton.set_tooltip_text(_("Step forward one move")) *************** *** 671,679 **** lastButton.set_tooltip_text(_("Jump to latest position")) toolbar.insert(lastButton, -1) ! filterButton = Gtk.ToolButton(stock_id=Gtk.STOCK_FIND) ! filterButton.set_tooltip_text(_("Find postion in current database")) ! toolbar.insert(filterButton, -1) self.saveButton = Gtk.ToolButton(stock_id=Gtk.STOCK_SAVE) self.saveButton.set_tooltip_text(_("Save arrows/circles")) --- 671,679 ---- lastButton.set_tooltip_text(_("Jump to latest position")) toolbar.insert(lastButton, -1) ! # filterButton = Gtk.ToolButton(stock_id=Gtk.STOCK_FIND) ! # filterButton.set_tooltip_text(_("Find postion in current database")) ! # toolbar.insert(filterButton, -1) self.saveButton = Gtk.ToolButton(stock_id=Gtk.STOCK_SAVE) self.saveButton.set_tooltip_text(_("Save arrows/circles")) *************** *** 688,698 **** self.cids[firstButton] = firstButton.connect("clicked", on_clicked, self.board.view.showFirst) self.cids[prevButton] = prevButton.connect("clicked", on_clicked, self.board.view.showPrev) ! self.cids[mainButton] = mainButton.connect("clicked", on_clicked, self.board.view.backToMainLine) ! self.cids[upButton] = upButton.connect("clicked", on_clicked, self.board.view.backToParentLine) self.cids[nextButton] = nextButton.connect("clicked", on_clicked, self.board.view.showNext) self.cids[lastButton] = lastButton.connect("clicked", on_clicked, self.board.view.showLast) ! self.cids[filterButton] = filterButton.connect("clicked", on_clicked, self.find_in_database) self.cids[self.saveButton] = self.saveButton.connect("clicked", on_clicked, self.save_shapes_to_pgn) self.on_shapes_changed(self.board) --- 688,698 ---- self.cids[firstButton] = firstButton.connect("clicked", on_clicked, self.board.view.showFirst) self.cids[prevButton] = prevButton.connect("clicked", on_clicked, self.board.view.showPrev) ! # self.cids[mainButton] = mainButton.connect("clicked", on_clicked, self.board.view.backToMainLine) ! # self.cids[upButton] = upButton.connect("clicked", on_clicked, self.board.view.backToParentLine) self.cids[nextButton] = nextButton.connect("clicked", on_clicked, self.board.view.showNext) self.cids[lastButton] = lastButton.connect("clicked", on_clicked, self.board.view.showLast) ! # self.cids[filterButton] = filterButton.connect("clicked", on_clicked, self.find_in_database) self.cids[self.saveButton] = self.saveButton.connect("clicked", on_clicked, self.save_shapes_to_pgn) self.on_shapes_changed(self.board) ===== Disable hostname change by DHCP ===== Someone got a briliant idea of changing system's hostname via DHCP lease reply *by default*. Disable this idiotism by removing "host-name" from the requrest and/or by enforcing your hostname with the "supersede" option. request subnet-mask, broadcast-address, routers, domain-name, domain-name-servers, domain-search, interface-mtu, rfc3442-classless-static-routes; supersede host-name "clusterfuck"; ===== redshift ===== Recent versions of package redshift comes with crazy dependencies, so lets build it from source without ballast... apt-get source redshift cd ./redshift* ./configure --prefix=/usr --disable-quartz --disable-wingdi --disable-geoclue2 --disable-corelocation --disable-gui --disable-ubuntu --disable-apparmor --without-systemduserunitdir --enable-randr make sudo make install You may need to install x11proto-randr-dev. Config file is straightforward [redshift] temp-day=5500 temp-night=3000 location-provider=manual [manual] lat=50 lon=15 ===== exfat on CentOS 5 ===== So you have prehistoric enterprise/medical workstation but the users come with poshy exfat USB drives... === Repositories === Disable (enabled=0 in all files in /etc/yum.respos.d/ ) all native repositories since they are of no use anymore anyway and allow only the /etc/yum.repos.d/CentOS-Vault.repo yum clean all yum update And install the necessary packages for successful compilation of exfat FUSE driver. Note that you will most probably need to add --no-check-certificate to the wget command or fetch the files elsewhere and push them to the centos via SSH (this is due to SSL/TSL craziness with no respect to longterm compatibility). yum install make gcc fuse-devel automake autoconf wget https://github.com/relan/exfat/archive/master.zip -O ./exfatmaster.zip # exfat driver wget https://raw.githubusercontent.com/memcached/memcached/a0a70329033f3f88de500b8f098e989247dd8f91/m4/c99-backport.m4 # patch for old automake unzip ./exfatmaster.zip cp ./c99-backport.m4 ./exfat-master cd ./exfat-master === exfat patching === Now you need to patch the configure.ac to fake some details... Note the change of version of AM_INIT_AUTOMAKE, inclusion of the C99 patch and other tuning... In case the patch disappeared... {{ :user:sachy:c99-backport.m4}} m4_include([c99backport.m4]) AC_INIT([Free exFAT implementation], [1.3.0], [relan@users.noreply.github.com], [exfat], [https://github.com/relan/exfat]) m4_pattern_allow AM_INIT_AUTOMAKE([1.9.6 -Wall -Werror foreign subdir-objects]) AC_PROG_CC #m4_ifdef([AC_PROG_CC_C99], [AC_PROG_CC_C99]) AC_PROG_CC_C99 AM_PROG_CC_C_O AC_PROG_RANLIB m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) #AM_PROG_AR AC_SYS_LARGEFILE AC_CANONICAL_HOST PKG_CHECK_MODULES([UBLIO], [libublio], [ CFLAGS="$CFLAGS $UBLIO_CFLAGS" LIBS="$LIBS $UBLIO_LIBS" AC_DEFINE([USE_UBLIO], [1], [Define if block devices are not supported.]) ], [:]) PKG_CHECK_MODULES([FUSE], [fuse]) case "$host_os" in *-gnu) AC_DEFINE([_XOPEN_SOURCE], [500], [Enable pread() and pwrite().]) AC_DEFINE([_DEFAULT_SOURCE], [], [Enable vsyslog().]) ;; esac AC_CONFIG_HEADERS([libexfat/config.h]) AC_CONFIG_FILES([ libexfat/Makefile dump/Makefile fsck/Makefile fuse/Makefile label/Makefile mkfs/Makefile Makefile]) AC_OUTPUT You also need to patch the fuse/main.c to disable big_writes capability cause its not supported on the old systems. Just comment out or delete the two snippets... #ifdef FUSE_CAP_BIG_WRITES // fci->want |= FUSE_CAP_BIG_WRITES; #endif ... #if defined(__linux__) || defined(__FreeBSD__) // "big_writes," #endif Now we can compile and hope autoreconf --install ./configure make make install No errors? Congratz. ===== youtube-dl ===== If your youtube-dl says: [generic] example.com/supervideopage: Requesting header [generic] example.com/supervideopage: Downloading webpage ERROR: Unable to download webpage: (caused by URLError(SSLError(1, u'[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:727)'),)) you can fix it with changing the the CipherString as follows: CipherString = DEFAULT@SECLEVEL=0 ===== df: Operation not permitted ===== Someone in GOME decided that it is a great idea to break essential tools like 'df' by introducing ehm "feature" called portal. $ df -h df: /run/user/1000/doc: Operation not permitted ... # apt-get purge xdg-desktop-portal ===== Speed-up hibernation ===== When hibernating the system (storing the state on disk), all RAM content is dumped into the swap area. This includes also caches and other rubbish which can be safely dropped. By default, the pm-utils try to fit the state under 2/5 of the RAM size when hibernating to shorten the store/reload time. This is however not a hard-limit, if the content cant fit, then more data is stored. To change the limit, one can edit /sys/power/image_size to desired soft-limit in bytes. In particular, 0 means that the system will hibernate with the smallest amount of data and all caches will be dropped. ===== Custom LiveCD ===== When you want to have an immutable virtual machine, booting directly the LiveCD of preffered distro is the easiest option. But sometimes one might want to edit some parts of the base ISO. New users are created from skeleton /etc/skel, so whatever is there, the live user will have too. apt-get install squashfs-tools mount -o loop livecd.iso /mountpoint/iso unsquashfs /mountpoint/iso/casper/filesystem.squashfs # make your changes in squashfs-root mksquashfs squashfs-root filesystem.squashfs -b 1024k -comp xz -Xbcj x86 -e boot # cd inside the extracted ISO content and create the isofile somewhere else mkisofs -J -l -R -v -o ../livecd_new.iso ./ Sometimes the former ISO does not boot in a crippled environment. So xorriso to create hybrid EFI/MBR image... apt-get install xorriso isolinux syslinux xorriso -as mkisofs -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -c isolinux/boot.cat -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot -isohybrid-gpt-basdat -o OUTPUT.iso INPUT_DIR Virtualbox got a feature called "virtual iso" (VISO), so you can point to the directory with the changed iso files without repackaging into real ISO. Good for debugging. ===== Dokuwiki sidebar everywhere ===== For some reason, default dokuwiki shows the sidebar only while reading the pages. In edit/admin mode, the sidebar is not shown. Solution: update the lib/tpl/dokuwiki/main.php and at the very beginning of the file change the appropriate line as follows: $showSidebar=true; ===== Collabora Office ===== === Disable welcome screen === The "Kolaborant" shows unwanted Welcome Screen everytime new browser is detected. There is no configuration option to disable it, so one have to hide it by editing the CSS. Edit "/usr/share/coolwsd/browser/dist/bundle.css", find rules for class "iframe-welcome-wrap" and add there a single rule "display:none!important;" Be warned that the CSS is a oneliner. .iframe-welcome-wrap, .iframe-welcome-content { display:none!important; position:absolute; z-index:1106; display:flex; width:100%; height:100%; justify-content:center; align-items:center; background-color:var(--color-overlay) } === Remove Loto* and Liberation* fonts === There comes billion spamfonts by default, so lets get rid of them... cd /opt/collaboraoffice/share/fonts/truetype rm -rfv ./Noto* rm -rfv ./Liberation* coolconfig update-system-template service coolwsd restart If you want to install MS common fonts for compatibility with strangers (Arial, Times New Roman etc), just search for mscorefonts or similar in your package manager. === Collabora/coolwsd + LetsEncrypt certificates === To run web+kolaborant on a single server we need to tweek a little the settings. Coolwsd need paths to fullchain.pem and privkey.pem defined in /etc/coolwsd/config.xml Maybe you will need to lease the permissions a little so not only apache, but also coolwsd can read it chmod 750 /etc/letsencrypt/live chmod 750 /etc/letsencrypt/archive service coolwsd restart === Document cannot be saved ... contact storage server administrator === Owncloud stores internal locks of files in the database, but have hard time to remove the locks when not needed anymore. As the lock table grows, operations take longer and one day may not arrive before deadline, rendering the file "locked", ie. read-only even when from the users perspective all priviledges are OK. The solution is to flush the oc_file_locks table. Be prepared for millions of invalid entries there. DELETE FROM oc_file_locks WHERE 1; Do this in maintenance mode to avoid removing valid locks. ===== ffmpeg capture pulseaudio ===== pactl list short sources ffmpeg -f pulse -i alsa_output.pci-0000_00_1b.0.analog-stereo.monitor -ac 2 output.flac ===== MIDI keyboard over USB ===== To actually listern to MIDI instrument, you need to get a database of sounds and software to bind MIDI events to sounds, and mix multiple sounds together. Such software is called synthetizer. apt-get install qsynth fluid-soundfont-gm nohup qsynth -a alsa & # run synther aconnect -i # get the "client" number of the input device (probably the highest one) aconnect -o # get the "FLUID" client number, probably 128 aconnect # combine input with output Additional settings may be needed depending on the MIDI device and software used. ===== JSON in mc ===== The view function of mc can be enhanced to show JSON files nicely. Just create mcjson.py: #!/usr/bin/python3 import json import sys gj=json.load(open(sys.argv[1])) print(json.dumps(gj,indent=2)) And in mc itself just assign the View function to the proper JSON file: # json regex/\.[jJ][sS][oO][nN]$ Open=(pluma %f >/dev/null 2>&1) View=%view{ascii} prettyjson.py %f 2>&1 ===== mutt vs Oauth2 ===== Oauth2 protocol is more and more popular auth mechanism, so mutt - as the least wrong mail client - have support too. Yet the support is a bit tricky... First, download [[https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py|mutt_oauth2.py]] to the .mutt/ and read [[https://gitlab.com/muttmua/mutt/-/blob/master/contrib/mutt_oauth2.py.README|official README]]. Then generate new PGP key for encryption of the Oauth secrets. "gpg --gen-key". Set the name/email to something mutty, like "mutt@mutt.mutt" to clearly distinguish it and never use in daily life. Also --edit-key to set neverending validity (default one year). Edit the downloaded mutt_oauth2.py and change the following: ENCRYPTION_PIPE = ['gpg', '--encrypt', '--recipient', 'mutt@mutt.mutt'] # the name of the gpgkey in last param ... 'client_id': '9e5f94bc-e8a4-4e73-b8be-63364c29d753', # generic client_id for Thunderbird. Valid (almost?) everywhere If you want to use your own client_id, search faculty/company/google/MS support for help how to create one. Make first contact: ./mutt_oauth2.py LOGIN_NAME@DOMAIN.tokens --verbose --authorize # Just a file keeping the secrets... Follow the instructions, I recommend to pick "authcode" when asked. Copy generated URL (whole!!!) to the browser (with JS), accept all permissions for Thunderbird (remember the fake client-id we used?) and blank page will appear. DO NOT PANIC! Copy the whole URL to text editor and copy out the content of code= parameter back to the mutt_oauth2 prompt. Its long, invalid, base64 stuff ending prior "&session_state=". Example: 0.AQIABsRF82hSsEOxn1hi-mgz-LyUX56k6HNOuL5j-LOTOFGARBAGE-REALLYLOTOFGARBAGE-EVENMOREGARBAGE-vUFlgHtUs6n5bmmRQgQ7AMH8zojnZWycMA Be sure not to copy newlines from vim/nano. Its one string, no newlines. NO NEWLINES! If done correctly, the script will respond: Exchanging the authorization code for an access token NOTICE: Obtained new access token, expires 2023-03-23T12:30:00.00000. Access Token: lot-of-garbage Now is time to test the Oauth2 SMTP/IMAP connection: $ /mutt_oauth2.py LOGIN_NAME@DOMAIN.tokens --verbose --test # the token file Access Token: garbage... IMAP authentication succeeded POP authentication succeeded SMTP authentication succeeded Good, the last thing is to edit the .mutt/muttrc (use your provider instead of Utlouk) set imap_user="userid@myschool.edu" set folder="imap://outlook.office365.com/" set smtp_url="smtp://${imap_user}@smtp.office365.com:587/" set imap_authenticators="oauthbearer:xoauth2" set imap_oauth_refresh_command="/home/USER/.mutt/mutt_oauth2.py /home/USER/.mutt/LOGIN_NAME@DOMAIN.tokens" set smtp_authenticators=${imap_authenticators} set smtp_oauth_refresh_command=${imap_oauth_refresh_command} If you have setup for more mailboxes, dont forget to clean the setting for all the others: # reset Oauth2 to normal set imap_authenticators="gssapi:digest:cram-md5:sasl-ir:login" set imap_oauth_refresh_command="" set smtp_authenticators=${imap_authenticators} set smtp_oauth_refresh_command=""