For a while I was keeping a private branch where there were a lot of non-public things included, and that became the de-facto branch while this one lagged. This one is now up-to-date, all private stuff is dealt with via config files which are not committed.main
@ -0,0 +1,34 @@ |
||||
|
||||
# prevents default audio devices from changing when connecting to audio dock
|
||||
setup-pulseaudio: |
||||
sudo sed -i 's/^load-module module-switch-on-connect$/# load-module module-switch-on-connect/g' /etc/pulse/default.pa
|
||||
pulseaudio -k
|
||||
|
||||
# add vfat to MODULES in /etc/mkinitcpio.conf
|
||||
# add `cryptkey=UUID=<uuid>:vfat:/keyfile` to boot line in bootloader
|
||||
# - use lsblk -o NAME,UUID to get UUID
|
||||
install-rm-keyfile: |
||||
sudo cp ./base/rm-keyfile.service /etc/systemd/system
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
install-pamd: |
||||
drv=$$(nix-instantiate -E '((import ./pkgs.nix).stable {}).i3lock'); \
|
||||
store=$$(nix-store --realise $$drv); \
|
||||
sudo cp $$store"/etc/pam.d/i3lock" /etc/pam.d/i3lock
|
||||
|
||||
install-loadout: |
||||
@if [ -z "$(HOSTNAME)" ]; then echo "USAGE: make HOSTNAME=... install-loadout"; exit 1; fi
|
||||
nix-env -i loadout -f default.nix --arg hostConfig "import ./config/$(HOSTNAME).nix"
|
||||
|
||||
install-fonts: |
||||
@if [ -z "$(HOSTNAME)" ]; then echo "USAGE: make HOSTNAME=... install-loadout"; exit 1; fi
|
||||
mkdir -p ~/.local/share/fonts/
|
||||
p=$$(nix-build --no-out-link --arg hostConfig ./config/$(HOSTNAME).nix -A fonts); \
|
||||
cp -rL $$p/share/fonts ~/.local/share/fonts/loadout
|
||||
chmod o+w -R ~/.local/share/fonts/loadout
|
||||
fc-cache
|
||||
|
||||
install-keyboard: |
||||
sudo cp ./base/00-keyboard.conf /etc/X11/xorg.conf.d/00-keyboard.conf
|
||||
|
||||
install: setup-pulseaudio install-pamd install-rm-keyfile install-fonts install-keyboard install-loadout |
@ -1,105 +0,0 @@ |
||||
# Mediocre Loadout |
||||
|
||||
This repo contains everything needed to build my loadout, which is everything |
||||
which I tend to take from one linux machine to the next. This includes: |
||||
|
||||
* My development environment (neovim + plugins + a lot of customization) |
||||
* My shell (zsh + plugins + a custom theme) |
||||
* My window manager (awesome + plugins + a lot of customization) |
||||
|
||||
I'm calling the result the "Mediocre Loadout". It is designed to be completely |
||||
agnostic to the system it is running on, and to make little to no mutations to |
||||
that system. |
||||
|
||||
# Build/Installation/Usage options |
||||
|
||||
To build the Mediocre Loadout you must have a working |
||||
[nix](https://nixos.org/manual/nix/stable/) installation, as well as an `x86_64` |
||||
machine. That's it. |
||||
|
||||
There are multiple build/installation options: |
||||
|
||||
## nix Derivation |
||||
|
||||
To build the nix derivation of the loadout you can do: |
||||
|
||||
``` |
||||
nix-build -A loadout |
||||
``` |
||||
|
||||
This will place the result in the `result` symlink in the root directory. |
||||
Components of the loadout can then be executed from the `bin` subdirectory, |
||||
e.g.: |
||||
|
||||
``` |
||||
./result/bin/nvim |
||||
``` |
||||
|
||||
## nix Environment |
||||
|
||||
Alternatively, to install it to your nix profile do: |
||||
|
||||
``` |
||||
nix-env -i default.nix -A loadout |
||||
``` |
||||
|
||||
Assuming your nix environment is set up correctly, you should be able to execute |
||||
components directly: |
||||
|
||||
``` |
||||
nvim |
||||
``` |
||||
|
||||
## AppImage |
||||
|
||||
An [AppImage](https://appimage.org/) binary can be built which can run any |
||||
component of the loadout individually. This binary can be copied from one |
||||
machine to the next without any of them requiring nix or any other dependencry |
||||
to run it. |
||||
|
||||
To build the binary: |
||||
|
||||
``` |
||||
nix-build -A appimage |
||||
``` |
||||
|
||||
The resulting binary will be placed in the `result` symlink in the root |
||||
directory. |
||||
|
||||
Specific components of the loadout can be run by passing an argument to the |
||||
binary: |
||||
|
||||
``` |
||||
./Mediocre_Loadout-x86_64.AppImage nvim |
||||
``` |
||||
|
||||
NOTE that the AppImage doesn't like working with files within `/tmp`. I don't |
||||
know of a workaround for this at the moment. |
||||
|
||||
# Available Components |
||||
|
||||
Components of the loadout can be run separate from the others, depending on what |
||||
you're trying to do. The following components are available to be run: |
||||
|
||||
* `zsh`: My terminal shell. There's some customization |
||||
to it but it should be pretty self-explanatory to "just use". |
||||
|
||||
* `nvim`: My neovim development environment, plus all plugins I use. I mostly |
||||
work in golang, so it's most tuned for that, but it does fine for general dev |
||||
work. `Ctrl-N` will open NerdTree, `<backslash>tn` will open a terminal tab, |
||||
and `<backslash>th`/`<backslash>tl` can be used to navigate tabs. There's a |
||||
lot more customization that's been done, see the `nvim/init.vim` file. |
||||
|
||||
* `alacritty`: Terminal GUI which I use. Yes, I always use a light-mode theme, |
||||
because I work in well lit spaces generally. There's not much else to this. |
||||
|
||||
* `awesome`: My window manager. There's so much customization I couldn't begin |
||||
to start. `Meta+Enter` should open a terminal, where `Meta` is probably the |
||||
windows key on your keyboard. |
||||
|
||||
# Status |
||||
|
||||
This configuration is still fairly new, and so expect it to be fairly broken. |
||||
I'll be updating it as I go though, so it should stabalize into something |
||||
functional. I don't test the AppImage build very much, it's more of a gimick, |
||||
but the shell and dev environment should work well from it at least. |
@ -1,35 +1,49 @@ |
||||
{ |
||||
|
||||
pkgs ? (import ../pkgs.nix) {}, |
||||
config, |
||||
|
||||
pkgs ? (import ../pkgs.nix).stable2305 {}, |
||||
zsh ? pkgs.zsh, |
||||
|
||||
}: rec { |
||||
|
||||
# TODO figure out a way to provide my font to alacritty at runtime. fontconfig |
||||
# is a hot mess... |
||||
# |
||||
#dataDir = pkgs.stdenv.mkDerivation { |
||||
# name = "alacritty-dataDir"; |
||||
# src = ./fonts; |
||||
# buildInputs = [ pkgs.fontconfig ]; |
||||
# builder = builtins.toFile "builder.sh" '' |
||||
# source $stdenv/setup |
||||
# mkdir "$out" |
||||
# cp -r "$src" "$out"/fonts |
||||
# chmod -R +w "$out" |
||||
defaultXDGOpenRules = [ |
||||
{ |
||||
name = "open-url"; |
||||
pattern = "(ipfs:|ipns:|magnet:|mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)[^<>\"\\s{-}\\^⟨⟩`]+"; |
||||
xdgOpen = "$1"; |
||||
} |
||||
]; |
||||
|
||||
# env |
||||
xdgOpenRules = defaultXDGOpenRules ++ config.alacritty.xdgOpenRules; |
||||
|
||||
# export FONTCONFIG_FILE="$out"/fontconfig |
||||
# fc-cache --verbose "$out"/fonts |
||||
hints = { |
||||
enabled = (builtins.map (r: |
||||
{ |
||||
regex = r.pattern; |
||||
hyperlinks = true; |
||||
command = (pkgs.writeShellScript "alacritty-hints-${r.name}" '' |
||||
xdg-open "${r.xdgOpen}" |
||||
''); |
||||
post_processing = true; |
||||
mouse.enabled = true; |
||||
} |
||||
) xdgOpenRules); |
||||
}; |
||||
|
||||
# ''; |
||||
#}; |
||||
configFile = pkgs.writeText "alacritty-config" ( |
||||
builtins.replaceStrings |
||||
["$HINTS"] |
||||
[(builtins.toJSON hints)] |
||||
(builtins.readFile ./alacritty.yml) |
||||
); |
||||
|
||||
alacritty = pkgs.writeScriptBin "alacritty" '' |
||||
#!${pkgs.bash}/bin/bash |
||||
exec ${pkgs.nixgl}/bin/nixGLIntel ${pkgs.alacritty}/bin/alacritty \ |
||||
--config-file ${./alacritty.yml} \ |
||||
|
||||
exec ${pkgs.nixgl}/bin/nixGL ${pkgs.alacritty}/bin/alacritty \ |
||||
-o font.size=${builtins.toString config.alacritty.fontSize} \ |
||||
--config-file ${configFile} \ |
||||
-e "${zsh}/bin/zsh" |
||||
''; |
||||
} |
||||
|
@ -1,17 +0,0 @@ |
||||
{ |
||||
|
||||
pkgsSrc ? ./pkgs.nix, |
||||
|
||||
}: let |
||||
|
||||
nixBundle = builtins.fetchGit { |
||||
url = "https://github.com/matthewbauer/nix-bundle.git"; |
||||
rev = "223f4ffc4179aa318c34dc873a08cb00090db829"; |
||||
}; |
||||
|
||||
appimageTop = (import "${nixBundle}/appimage-top.nix") { |
||||
nixpkgs' = pkgsSrc; |
||||
}; |
||||
|
||||
in { name, target }: |
||||
appimageTop.appimage (appimageTop.appdir { inherit name target; }) |
@ -1,9 +0,0 @@ |
||||
# For use in ubuntu, just copy into /usr/share/xsessions |
||||
|
||||
[Desktop Entry] |
||||
Name=awesome |
||||
Comment=Highly configurable framework window manager |
||||
Exec=/home/mediocregopher/.nix-profile/bin/awesome |
||||
Type=Application |
||||
Icon=/usr/share/pixmaps/awesome.xpm |
||||
Keywords=Window manager |
@ -1,43 +0,0 @@ |
||||
local io = io |
||||
local math = math |
||||
local tonumber = tonumber |
||||
local string = string |
||||
local naughty = require("naughty") |
||||
|
||||
function batteryInfo() |
||||
for i=0,1 do |
||||
local dir = "/sys/class/power_supply/BAT" .. tostring(i) .. "/" |
||||
local f_status = io.popen("cat " .. dir .. "status 2>/dev/null") |
||||
local c_status = f_status:read() |
||||
f_status:close() |
||||
|
||||
if c_status and c_status ~= "" then |
||||
local prefix = "energy" |
||||
local f_now = io.popen("cat " .. dir .. prefix .. "_now 2>/dev/null") |
||||
local c_now_str = f_now:read() |
||||
f_now:close() |
||||
|
||||
if not c_now_str or c_now_str == "" then |
||||
prefix = "charge" |
||||
local f_now = io.popen("cat " .. dir .. prefix .. "_now") |
||||
c_now_str = f_now:read() |
||||
f_now:close() |
||||
end |
||||
|
||||
local f_full = io.popen("cat " .. dir .. prefix .. "_full") |
||||
local c_full_str = f_full:read() |
||||
f_full:close() |
||||
|
||||
local c_now = tonumber(c_now_str) |
||||
local c_full = tonumber(c_full_str) |
||||
|
||||
local charging = (c_status == "Charging" or c_status == "Full") |
||||
|
||||
if c_now ~= nil and c_full ~= nil then |
||||
local percent = math.floor((c_now/c_full) * 100) |
||||
return percent, charging |
||||
end |
||||
end |
||||
end |
||||
return nil, charging |
||||
end |
@ -1,4 +0,0 @@ |
||||
#!/bin/sh |
||||
|
||||
scrot -o -s "/tmp/shot.png" |
||||
eog /tmp/shot.png |
@ -0,0 +1,7 @@ |
||||
#!/bin/sh |
||||
|
||||
set -e |
||||
mkdir -p ~/Screenshots |
||||
f="$HOME/Screenshots/shot-$(date +%s).png" |
||||
scrot -o -s "$f" |
||||
feh "$f" |
@ -1,50 +0,0 @@ |
||||
#!/bin/bash |
||||
|
||||
cd $(dirname "$0") |
||||
|
||||
sep=" | " |
||||
|
||||
out=$(/home/mediocregopher/.config/awesome/bin/cricket \ |
||||
--limit 1 \ |
||||
--ping-hosts 8.8.8.8 \ |
||||
--net-interval "" \ |
||||
--disk-interval "" \ |
||||
--disk-io-interval "") |
||||
|
||||
function outNum { |
||||
echo "$out" | grep "$1" | grep -oP "$2=\"[0-9]+\"" | grep -oP '[0-9]+' |
||||
} |
||||
|
||||
echo -n "ping:$(outNum "ping result" "tookMSAvg")ms" |
||||
|
||||
echo -n "$sep" |
||||
|
||||
memBarSize=10 |
||||
memPer=$(outNum "mem stats" "memUsedPer") |
||||
memUsed=$(expr $memPer / $memBarSize) |
||||
memUnused=$(expr $memBarSize - $memUsed) |
||||
echo -n "mem:" |
||||
for i in $(seq $memUsed); do echo -n "█"; done |
||||
for i in $(seq $memUnused); do echo -n "░"; done |
||||
for i in $(seq $(expr $memBarSize - $memUsed - $memUnused)); do echo -n "░"; done |
||||
|
||||
echo -n "$sep" |
||||
|
||||
cpuBarSize=20 |
||||
cpuIdle=$(outNum "cpu stats" "cpuIdle") |
||||
cpuSys=$(outNum "cpu stats" "cpuSystem") |
||||
cpuUser=$(outNum "cpu stats" "cpuUser") |
||||
cpuTot=$(expr $cpuIdle + $cpuSys + $cpuUser) |
||||
function cpuL { |
||||
python -c "print(int($1 / $cpuTot * $cpuBarSize))" |
||||
} |
||||
cpuLIdle=$(cpuL $cpuIdle) |
||||
cpuLSys=$(cpuL $cpuSys) |
||||
cpuLUser=$(cpuL $cpuUser) |
||||
echo -n "cpu:" |
||||
for i in $(seq $cpuLUser); do echo -n "█"; done |
||||
for i in $(seq $cpuLSys); do echo -n "▓"; done |
||||
for i in $(seq $cpuLIdle); do echo -n "░"; done |
||||
for i in $(seq $(expr $cpuBarSize - $cpuLIdle - $cpuLSys - $cpuLUser)); do echo -n "░"; done |
||||
|
||||
echo "" |
@ -0,0 +1,3 @@ |
||||
file:///tmp |
||||
file:///home/mediocregopher/Screenshots |
||||
file:///home/mediocregopher/Downloads |
@ -0,0 +1,2 @@ |
||||
[Settings] |
||||
gtk-icon-theme-name = Tela |
@ -1,29 +1,122 @@ |
||||
{ |
||||
|
||||
pkgs ? (import ../pkgs.nix) {}, |
||||
config, |
||||
|
||||
|
||||
}: rec { |
||||
|
||||
cfg = ./.; |
||||
pkgs = (import ../pkgs.nix).stable {}; |
||||
pkgs2305 = (import ../pkgs.nix).stable2305 {}; |
||||
pkgsEdge = (import ../pkgs.nix).edge {}; |
||||
|
||||
# nativeWrap is used for apps which are not installed via nix which don't play |
||||
# nicely with it. |
||||
nativeWrap = pkgs.writeScriptBin "native-wrap" '' |
||||
#!${pkgs.bash}/bin/bash |
||||
|
||||
unset XDG_CONFIG_DIRS |
||||
unset XDG_DATA_DIRS |
||||
unset GDK_PIXBUF_MODULE_FILE |
||||
|
||||
exec "$@" |
||||
''; |
||||
|
||||
browser = pkgs.writeScriptBin "browser" '' |
||||
#!${pkgs.bash}/bin/bash |
||||
exec ${nativeWrap}/bin/native-wrap ${config.browser} "$@" |
||||
''; |
||||
|
||||
env = pkgs.buildEnv { |
||||
name = "awesome-env"; |
||||
paths = [ |
||||
|
||||
pkgs.awesome |
||||
pkgs.tela-icon-theme |
||||
|
||||
nativeWrap |
||||
browser |
||||
|
||||
pkgs.xorg.xrandr |
||||
pkgs.xsel |
||||
pkgs.pavucontrol |
||||
pkgs.xdg-utils |
||||
pkgs.arandr |
||||
|
||||
pkgs.i3lock |
||||
pkgs.scrot |
||||
pkgs.feh |
||||
pkgs.brightnessctl |
||||
|
||||
pkgs.cbatticon |
||||
pkgs.phwmon |
||||
|
||||
pkgs.castor |
||||
pkgs2305.libreoffice |
||||
pkgs.gimp |
||||
pkgs.inkscape |
||||
pkgs.vlc |
||||
pkgs.sylpheed |
||||
|
||||
pkgsEdge.lagrange |
||||
]; |
||||
}; |
||||
|
||||
wp = ../wallpapers; |
||||
|
||||
dirsLua = pkgs.writeTextDir "dirs.lua" '' |
||||
home_dir = os.getenv("HOME").."/" |
||||
conf_dir = "${cfg}/" |
||||
bin_dir = "${./bin}/" |
||||
share_dir = "${./share}/" |
||||
wp_dir = "${wp}/" |
||||
''; |
||||
|
||||
awesome = pkgs.writeScriptBin "awesome" '' |
||||
#!${pkgs.bash}/bin/bash |
||||
|
||||
export BROWSER=/usr/bin/google-chrome |
||||
export BROWSER=${browser}/bin/browser |
||||
|
||||
# Turn off powersaving (fuck the environment) |
||||
xset -dpms |
||||
xset s off |
||||
|
||||
export PATH=${env}/bin:$PATH |
||||
|
||||
export XDG_CONFIG_DIRS=${./config} |
||||
|
||||
export XDG_DATA_DIRS=${env}/share |
||||
export XDG_DATA_DIRS=$XDG_DATA_DIRS:/home/mediocregopher/.nix-profile/share |
||||
|
||||
${config.awesome.startupExtra} |
||||
|
||||
# HACK: This sleep is here because phwmon actually creates a separate tray |
||||
# icon for each thing it monitors, and if the process runs at the same time |
||||
# as another process which creates a tray icon they can get interleaved. |
||||
(sleep 5 && phwmon.py) & |
||||
|
||||
echo "[$(date)] New awesome session starting" > ~/.awesome.log |
||||
exec ${pkgs.awesome}/bin/awesome \ |
||||
-c ${cfg}/rc.lua \ |
||||
############################################################################ |
||||
# Init awesome |
||||
|
||||
data_dir="$HOME/.local/share/awesome"; |
||||
mkdir -p "$dataDir" |
||||
|
||||
log_dir="$data_dir"/logs |
||||
mkdir -p $log_dir |
||||
|
||||
# only keep last N awesome.log files |
||||
ls "$log_dir" | sort -n | head -n -5 | while read f; do rm "$log_dir"/"$f"; done |
||||
|
||||
############################################################################ |
||||
# Exec |
||||
|
||||
this_log=$log_dir/awesome.$(date '+%Y%m%d.%H%M%S').log |
||||
|
||||
echo "New awesome session starting" > $this_log |
||||
|
||||
exec awesome \ |
||||
-c ${./rc.lua} \ |
||||
--search ${dirsLua} \ |
||||
--search ${cfg} \ |
||||
2>&1 2>>~/.awesome.log |
||||
--search ${./share} \ |
||||
--search ${env}/share/awesome/themes \ |
||||
2>&1 2>>$this_log |
||||
''; |
||||
|
||||
} |
||||
|
@ -1,13 +0,0 @@ |
||||
[Unit] |
||||
Description=mediocregopher's sysstats |
||||
Requires=network.target |
||||
After=network.target |
||||
|
||||
[Service] |
||||
Restart=always |
||||
RestartSec=1s |
||||
User=mediocregopher |
||||
ExecStart=/bin/bash -c 'while [ 1 ]; do out=$(~/.config/awesome/bin/sysstats.sh); echo "$out" > /tmp/sysstats; sleep 1; done' |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@ -0,0 +1,22 @@ |
||||
function load_theme(avgcolor, comcolor) |
||||
|
||||
local theme = require("default/theme") |
||||
|
||||
if avgcolor then |
||||
theme.bg_normal = avgcolor |
||||
theme.bg_focus = theme.bg_normal |
||||
theme.bg_urgent = "#ff0000" -- TODO should be opposite of bg_normal |
||||
theme.bg_minimize = theme.bg_normal |
||||
theme.bg_systray = theme.bg_normal |
||||
end |
||||
|
||||
if comcolor then |
||||
theme.fg_normal = comcolor |
||||
theme.fg_focus = comcolor |
||||
theme.fg_urgent = "#ffffff" |
||||
theme.fg_minimize = comcolor |
||||
end |
||||
|
||||
return theme |
||||
|
||||
end |
@ -1,3 +0,0 @@ |
||||
Background images: |
||||
Mikael Eriksson <mikael_eriksson@miffe.org> |
||||
Licensed under CC-BY-SA-3.0 |
Before Width: | Height: | Size: 220 KiB |
Before Width: | Height: | Size: 265 KiB |
Before Width: | Height: | Size: 967 B |
Before Width: | Height: | Size: 997 B |
Before Width: | Height: | Size: 194 B |
Before Width: | Height: | Size: 194 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 395 B |
Before Width: | Height: | Size: 388 B |
Before Width: | Height: | Size: 202 B |
Before Width: | Height: | Size: 202 B |
Before Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 321 B |
Before Width: | Height: | Size: 321 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 174 B |
Before Width: | Height: | Size: 195 B |
Before Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 170 B |
Before Width: | Height: | Size: 195 B |
Before Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 168 B |
Before Width: | Height: | Size: 440 B |
Before Width: | Height: | Size: 187 B |
Before Width: | Height: | Size: 193 B |
@ -1,105 +0,0 @@ |
||||
--------------------------- |
||||
-- Default awesome theme -- |
||||
--------------------------- |
||||
|
||||
function load_theme(avgcolor, comcolor) |
||||
if not avgcolor then avgcolor = "#000000" end |
||||
if not comcolor then comcolor = "#FFFFFF" end |
||||
|
||||
local theme = {} |
||||
|
||||
theme.font = "sans 8" |
||||
|
||||
--theme.bg_normal = "#222222" |
||||
theme.bg_normal = avgcolor |
||||
theme.bg_focus = theme.bg_normal |
||||
theme.bg_urgent = "#ff0000" -- TODO should be opposite of bg_normal |
||||
theme.bg_minimize = theme.bg_normal |
||||
theme.bg_systray = theme.bg_normal |
||||
|
||||
|
||||
--theme.fg_normal = "#aaaaaa" |
||||
theme.fg_normal = comcolor |
||||
theme.fg_focus = comcolor |
||||
theme.fg_urgent = "#ffffff" |
||||
theme.fg_minimize = comcolor |
||||
|
||||
theme.border_width = 1 |
||||
theme.border_normal = "#000000" |
||||
theme.border_focus = "#535d6c" |
||||
theme.border_marked = "#91231c" |
||||
|
||||
-- There are other variable sets |
||||
-- overriding the default one when |
||||
-- defined, the sets are: |
||||
-- [taglist|tasklist]_[bg|fg]_[focus|urgent] |
||||
-- titlebar_[bg|fg]_[normal|focus] |
||||
-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color] |
||||
-- mouse_finder_[color|timeout|animate_timeout|radius|factor] |
||||
-- Example: |
||||
--theme.taglist_bg_focus = "#ff0000" |
||||
|
||||
-- Display the taglist squares |
||||
theme.taglist_squares_sel = "/usr/share/awesome/themes/default/taglist/squarefw.png" |
||||
theme.taglist_squares_unsel = "/usr/share/awesome/themes/default/taglist/squarew.png" |
||||
|
||||
-- Variables set for theming the menu: |
||||
-- menu_[bg|fg]_[normal|focus] |
||||
-- menu_[border_color|border_width] |
||||
theme.menu_submenu_icon = "/usr/share/awesome/themes/default/submenu.png" |
||||
theme.menu_height = 15 |
||||
theme.menu_width = 100 |
||||
|
||||
-- You can add as many variables as |
||||
-- you wish and access them by using |
||||
-- beautiful.variable in your rc.lua |
||||
--theme.bg_widget = "#cc0000" |
||||
|
||||
-- Define the image to load |
||||
theme.titlebar_close_button_normal = "/usr/share/awesome/themes/default/titlebar/close_normal.png" |
||||
theme.titlebar_close_button_focus = "/usr/share/awesome/themes/default/titlebar/close_focus.png" |
||||
|
||||
theme.titlebar_ontop_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/ontop_normal_inactive.png" |
||||
theme.titlebar_ontop_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/ontop_focus_inactive.png" |
||||
theme.titlebar_ontop_button_normal_active = "/usr/share/awesome/themes/default/titlebar/ontop_normal_active.png" |
||||
theme.titlebar_ontop_button_focus_active = "/usr/share/awesome/themes/default/titlebar/ontop_focus_active.png" |
||||
|
||||
theme.titlebar_sticky_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/sticky_normal_inactive.png" |
||||
theme.titlebar_sticky_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/sticky_focus_inactive.png" |
||||
theme.titlebar_sticky_button_normal_active = "/usr/share/awesome/themes/default/titlebar/sticky_normal_active.png" |
||||
theme.titlebar_sticky_button_focus_active = "/usr/share/awesome/themes/default/titlebar/sticky_focus_active.png" |
||||
|
||||
theme.titlebar_floating_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/floating_normal_inactive.png" |
||||
theme.titlebar_floating_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/floating_focus_inactive.png" |
||||
theme.titlebar_floating_button_normal_active = "/usr/share/awesome/themes/default/titlebar/floating_normal_active.png" |
||||
theme.titlebar_floating_button_focus_active = "/usr/share/awesome/themes/default/titlebar/floating_focus_active.png" |
||||
|
||||
theme.titlebar_maximized_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/maximized_normal_inactive.png" |
||||
theme.titlebar_maximized_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/maximized_focus_inactive.png" |
||||
theme.titlebar_maximized_button_normal_active = "/usr/share/awesome/themes/default/titlebar/maximized_normal_active.png" |
||||
theme.titlebar_maximized_button_focus_active = "/usr/share/awesome/themes/default/titlebar/maximized_focus_active.png" |
||||
|
||||
theme.wallpaper = "/usr/share/awesome/themes/default/background.png" |
||||
|
||||
-- You can use your own layout icons like this: |
||||
theme.layout_fairh = "/usr/share/awesome/themes/default/layouts/fairhw.png" |
||||
theme.layout_fairv = "/usr/share/awesome/themes/default/layouts/fairvw.png" |
||||
theme.layout_floating = "/usr/share/awesome/themes/default/layouts/floatingw.png" |
||||
theme.layout_magnifier = "/usr/share/awesome/themes/default/layouts/magnifierw.png" |
||||
theme.layout_max = "/usr/share/awesome/themes/default/layouts/maxw.png" |
||||
theme.layout_fullscreen = "/usr/share/awesome/themes/default/layouts/fullscreenw.png" |
||||
theme.layout_tilebottom = "/usr/share/awesome/themes/default/layouts/tilebottomw.png" |
||||
theme.layout_tileleft = "/usr/share/awesome/themes/default/layouts/tileleftw.png" |
||||
theme.layout_tile = "/usr/share/awesome/themes/default/layouts/tilew.png" |
||||
theme.layout_tiletop = "/usr/share/awesome/themes/default/layouts/tiletopw.png" |
||||
theme.layout_spiral = "/usr/share/awesome/themes/default/layouts/spiralw.png" |
||||
theme.layout_dwindle = "/usr/share/awesome/themes/default/layouts/dwindlew.png" |
||||
|
||||
theme.awesome_icon = "/usr/share/awesome/icons/awesome16.png" |
||||
|
||||
-- Define the icon theme for application icons. If not set then the icons |
||||
-- from /usr/share/icons and /usr/share/icons/hicolor will be used. |
||||
theme.icon_theme = nil |
||||
|
||||
return theme |
||||
end |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 830 B |
Before Width: | Height: | Size: 598 B |
Before Width: | Height: | Size: 549 B |
Before Width: | Height: | Size: 814 B |
Before Width: | Height: | Size: 553 B |
Before Width: | Height: | Size: 1013 B |
Before Width: | Height: | Size: 754 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 740 B |
Before Width: | Height: | Size: 774 B |
Before Width: | Height: | Size: 679 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 682 B |
Before Width: | Height: | Size: 833 B |
Before Width: | Height: | Size: 624 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 601 B |
@ -0,0 +1,6 @@ |
||||
Section "InputClass" |
||||
Identifier "system-keyboard" |
||||
MatchIsKeyboard "on" |
||||
Option "XkbLayout" "us" |
||||
Option "XkbOptions" "caps:swapescape" |
||||
EndSection |
@ -0,0 +1,9 @@ |
||||
[Unit] |
||||
Description=rm keyfile |
||||
|
||||
[Service] |
||||
Type=oneshot |
||||
ExecStart=/bin/sh -c 'rm /boot/keyfile || true' |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,16 @@ |
||||
#!/usr/bin/env bash |
||||
|
||||
xrandr \ |
||||
--output eDP-1 \ |
||||
--primary \ |
||||
--mode 1920x1080 \ |
||||
--pos 0x0 \ |
||||
--rotate normal \ |
||||
--output DP-1 --off \ |
||||
--output HDMI-1 --off \ |
||||
--output DP-2 --off \ |
||||
--output HDMI-2 \ |
||||
--mode 1920x1080 \ |
||||
--pos 0x0 \ |
||||
--rotate normal \ |
||||
--brightness 0.9 |
@ -1,921 +0,0 @@ |
||||
#!/bin/sh |
||||
|
||||
# git-remote-gcrypt |
||||
# |
||||
# Copyright (c) 2013 engla |
||||
# Copyright (c) 2013, 2014 Joey Hess <id@joeyh.name> |
||||
# Copyright (c) 2016 Sean Whitton <spwhitton@spwhitton.name> and contributors |
||||
# |
||||
# This program is free software: you can redistribute it and/or modify |
||||
# it under the terms of the GNU General Public License as published by |
||||
# the Free Software Foundation, either version 3 of the License, or |
||||
# (at your option) version 2 or any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
# |
||||
# See README.rst for usage instructions |
||||
|
||||
set -e # errexit |
||||
set -f # noglob |
||||
set -C # noclobber |
||||
|
||||
export GITCEPTION="${GITCEPTION:-}+" # Reuse $Gref except when stacked |
||||
Gref="refs/gcrypt/gitception$GITCEPTION" |
||||
Gref_rbranch="refs/heads/master" |
||||
Packkey_bytes=63 # nbr random bytes for packfile keys, any >= 256 bit is ok |
||||
Hashtype=SHA256 # SHA512 SHA384 SHA256 SHA224 supported. |
||||
Manifestfile=91bd0c092128cf2e60e1a608c31e92caf1f9c1595f83f2890ef17c0e4881aa0a |
||||
Hex40="[a-f0-9]" |
||||
Hex40=$Hex40$Hex40$Hex40$Hex40$Hex40$Hex40$Hex40$Hex40 |
||||
Hex40=$Hex40$Hex40$Hex40$Hex40$Hex40 # Match SHA-1 hexdigest |
||||
GPG="$(git config --get "gpg.program" '.+' || echo gpg)" |
||||
|
||||
Did_find_repo= # yes for connected, no for no repo |
||||
Localdir="${GIT_DIR:=.git}/remote-gcrypt" |
||||
Tempdir= |
||||
|
||||
Repoid= |
||||
Refslist= |
||||
Packlist= |
||||
Keeplist= |
||||
Extnlist= |
||||
Repack_limit=25 |
||||
|
||||
Recipients= |
||||
|
||||
# compat/utility functions |
||||
# xfeed: The most basic output function puts $1 into the stdin of $2..$# |
||||
xfeed() |
||||
{ |
||||
local input_= |
||||
input_=$1; shift |
||||
"$@" <<EOF |
||||
$input_ |
||||
EOF |
||||
} |
||||
xecho() { xfeed "$*" cat; } |
||||
xecho_n() { xecho "$@" | tr -d \\n ; } # kill newlines |
||||
echo_git() { xecho "$@" ; } # Code clarity |
||||
echo_info() { xecho "gcrypt:" "$@" >&2; } |
||||
echo_die() { echo_info "$@" ; exit 1; } |
||||
|
||||
isnull() { case "$1" in "") return 0;; *) return 1;; esac; } |
||||
isnonnull() { ! isnull "$1"; } |
||||
iseq() { case "$1" in "$2") return 0;; *) return 1;; esac; } |
||||
isnoteq() { ! iseq "$1" "$2"; } |
||||
negate() { ! "$@"; } |
||||
|
||||
# Execute $@ or die |
||||
pipefail() |
||||
{ |
||||
"$@" || { echo_info "'$1' failed!"; kill $$; exit 1; } |
||||
} |
||||
|
||||
isurl() { isnull "${2%%$1://*}"; } |
||||
islocalrepo() { isnull "${1##/*}" && [ ! -e "$1/HEAD" ]; } |
||||
|
||||
xgrep() { command grep "$@" || : ; } |
||||
|
||||
# setvar is used for named return variables |
||||
# $1 *must* be a valid variable name, $2 is any value |
||||
# |
||||
# Conventions |
||||
# return variable names are passed with a @ prefix |
||||
# return variable functions use f_ prefix local vars |
||||
# return var consumers use r_ prefix vars (or Titlecase globals) |
||||
setvar() |
||||
{ |
||||
isnull "${1##@*}" || echo_die "Missing @ for return variable: $1" |
||||
eval ${1#@}=\$2 |
||||
} |
||||
|
||||
Newline=" |
||||
" |
||||
|
||||
# $1 is return var, $2 is value appended with newline separator |
||||
append_to() |
||||
{ |
||||
local f_append_tmp_= |
||||
eval f_append_tmp_=\$${1#@} |
||||
isnull "$f_append_tmp_" || f_append_tmp_=$f_append_tmp_$Newline |
||||
setvar "$1" "$f_append_tmp_$2" |
||||
} |
||||
|
||||
# Pick words from each line |
||||
# $1 return variable name |
||||
# $2 input value |
||||
pick_fields_1_2() |
||||
{ |
||||
local f_ret= f_one= f_two= |
||||
while read f_one f_two _ # from << here-document |
||||
do |
||||
f_ret="$f_ret$f_one $f_two$Newline" |
||||
done <<EOF |
||||
$2 |
||||
EOF |
||||
setvar "$1" "${f_ret#$Newline}" |
||||
} |
||||
|
||||
# Take all lines matching $2 (full line) |
||||
# $1 return variable name |
||||
# $2 filter word |
||||
# $3 input value |
||||
# if $1 is a literal `!', the match is reversed (and arguments shift) |
||||
# we instead remove all lines matching |
||||
filter_to() |
||||
{ |
||||
local f_neg= f_line= f_ret= IFS= |
||||
isnoteq "$1" "!" || { f_neg=negate; shift; } |
||||
IFS=$Newline |
||||
for f_line in $3 |
||||
do |
||||
$f_neg isnonnull "${f_line##$2}" || f_ret=$f_ret$f_line$Newline |
||||
done |
||||
setvar "$1" "${f_ret%$Newline}" |
||||
} |
||||
|
||||
# Output the number of lines in $1 |
||||
line_count() |
||||
{ |
||||
local IFS= |
||||
IFS=$Newline |
||||
set -- $1 |
||||
xecho "$#" |
||||
} |
||||
|
||||
|
||||
## gitception part |
||||
# Fetch giturl $1, file $2 |
||||
gitception_get() |
||||
{ |
||||
# Take care to preserve FETCH_HEAD |
||||
local ret_=: obj_id= fet_head="$GIT_DIR/FETCH_HEAD" |
||||
[ -e "$fet_head" ] && command mv -f "$fet_head" "$fet_head.$$~" || : |
||||
git fetch -q -f "$1" "$Gref_rbranch:$Gref" >/dev/null && |
||||
obj_id="$(git ls-tree "$Gref" | xgrep -E '\b'"$2"'$' | awk '{print $3}')" && |
||||
isnonnull "$obj_id" && git cat-file blob "$obj_id" && ret_=: || |
||||
{ ret_=false && : ; } |
||||
[ -e "$fet_head.$$~" ] && command mv -f "$fet_head.$$~" "$fet_head" || : |
||||
$ret_ |
||||
} |
||||
|
||||
anon_commit() |
||||
{ |
||||
GIT_AUTHOR_NAME="root" GIT_AUTHOR_EMAIL="root@localhost" \ |
||||
GIT_AUTHOR_DATE="1356994801 -0400" GIT_COMMITTER_NAME="root" \ |
||||
GIT_COMMITTER_EMAIL="root@localhost" \ |
||||
GIT_COMMITTER_DATE="1356994801 -0400" \ |
||||
git commit-tree "$@" <<EOF |
||||
Initial commit |
||||
EOF |
||||
} |
||||
|
||||
# Get 'tree' from $1, change file $2 to obj id $3 |
||||
update_tree() |
||||
{ |
||||
local tab_=" " |
||||
# $2 is a filename from the repo format |
||||
(set +e; |
||||
git ls-tree "$1" | xgrep -v -E '\b'"$2"'$'; |
||||
xecho "100644 blob $3$tab_$2" |
||||
) | git mktree |
||||
} |
||||
|
||||
# Put giturl $1, file $2 |
||||
# depends on previous GET to set $Gref and depends on PUT_FINAL later |
||||
gitception_put() |
||||
{ |
||||
local obj_id= tree_id= commit_id= |
||||
obj_id=$(git hash-object -w --stdin) && |
||||
tree_id=$(update_tree "$Gref" "$2" "$obj_id") && |
||||
commit_id=$(anon_commit "$tree_id") && |
||||
git update-ref "$Gref" "$commit_id" |
||||
} |
||||
|
||||
# Remove giturl $1, file $2 |
||||
# depends on previous GET like put |
||||
gitception_remove() |
||||
{ |
||||
local tree_id= commit_id= tab_=" " |
||||
# $2 is a filename from the repo format |
||||
tree_id=$(git ls-tree "$Gref" | xgrep -v -E '\b'"$2"'$' | git mktree) && |
||||
commit_id=$(anon_commit "$tree_id") && |
||||
git update-ref "$Gref" "$commit_id" |
||||
} |
||||
|
||||
gitception_new_repo() |
||||
{ |
||||
local commit_id= empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904 |
||||
# get any file to update Gref, and if it's not updated we create empty |
||||
git update-ref -d "$Gref" || : |
||||
gitception_get "$1" "x" 2>/dev/null >&2 || : |
||||
git rev-parse -q --verify "$Gref" >/dev/null && return 0 || |
||||
commit_id=$(anon_commit "$empty_tree") && |
||||
git update-ref "$Gref" "$commit_id" |
||||
} |
||||
## end gitception |
||||
|
||||
# Fetch repo $1, file $2, tmpfile in $3 |
||||
GET() |
||||
{ |
||||
if isurl sftp "$1" |
||||
then |
||||
(exec 0>&-; curl -s -S -k "$1/$2") > "$3" |
||||
elif isurl rsync "$1" |
||||
then |
||||
(exec 0>&-; rsync -I -W "${1#rsync://}"/"$2" "$3" >&2) |
||||
elif islocalrepo "$1" |
||||
then |
||||
cat "$1/$2" > "$3" |
||||
else |
||||
gitception_get "${1#gitception://}" "$2" > "$3" |
||||
fi |
||||
} |
||||
|
||||
# Put repo $1, file $2 or fail, tmpfile in $3 |
||||
PUT() |
||||
{ |
||||
if isurl sftp "$1" |
||||
then |
||||
curl -s -S -k --ftp-create-dirs -T "$3" "$1/$2" |
||||
elif isurl rsync "$1" |
||||
then |
||||
rsync -I -W "$3" "${1#rsync://}"/"$2" >&2 |
||||
elif islocalrepo "$1" |
||||
then |
||||
cat >| "$1/$2" < "$3" |
||||
else |
||||
gitception_put "${1#gitception://}" "$2" < "$3" |
||||
fi |
||||
} |
||||
|
||||
# Put all PUT changes for repo $1 at once |
||||
PUT_FINAL() |
||||
{ |
||||
if isurl sftp "$1" || islocalrepo "$1" || isurl rsync "$1" |
||||
then |
||||
: |
||||
else |
||||
git push --quiet -f "${1#gitception://}" "$Gref:$Gref_rbranch" |
||||
fi |
||||
} |
||||
|
||||
# Put directory for repo $1 |
||||
PUTREPO() |
||||
{ |
||||
if isurl sftp "$1" |
||||
then |
||||
: |
||||
elif isurl rsync "$1" |
||||
then |
||||
rsync -q -r --exclude='*' "$Localdir/" "${1#rsync://}" >&2 |
||||
elif islocalrepo "$1" |
||||
then |
||||
mkdir -p "$1" |
||||
else |
||||
gitception_new_repo "${1#gitception://}" |
||||
fi |
||||
} |
||||
|
||||
# For repo $1, delete all newline-separated files in $2 |
||||
REMOVE() |
||||
{ |
||||
local fn_= |
||||
if isurl sftp "$1" |
||||
then |
||||
# FIXME |
||||
echo_info "sftp: Ignore remove request $1/$2" |
||||
elif isurl rsync "$1" |
||||
then |
||||
xfeed "$2" rsync -I -W -v -r --delete --include-from=- \ |
||||
--exclude='*' "$Localdir"/ "${1#rsync://}/" >&2 |
||||
elif islocalrepo "$1" |
||||
then |
||||
for fn_ in $2; do |
||||
rm -f "$1"/"$fn_" |
||||
done |
||||
else |
||||
for fn_ in $2; do |
||||
gitception_remove "${1#gitception://}" "$fn_" |
||||
done |
||||
fi |
||||
} |
||||
|
||||
CLEAN_FINAL() |
||||
{ |
||||
if isurl sftp "$1" || islocalrepo "$1" || isurl rsync "$1" |
||||
then |
||||
: |
||||
else |
||||
git update-ref -d "$Gref" || : |
||||
fi |
||||
} |
||||
|
||||
ENCRYPT() |
||||
{ |
||||
rungpg --batch --force-mdc --compress-algo none --trust-model=always --passphrase-fd 3 -c 3<<EOF |
||||
$1 |
||||
EOF |
||||
} |
||||
|
||||
DECRYPT() |
||||
{ |
||||
rungpg -q --batch --no-default-keyring --secret-keyring /dev/null \ |
||||
--keyring /dev/null --passphrase-fd 3 -d 3<<EOF |
||||
$1 |
||||
EOF |
||||
} |
||||
|
||||
# Encrypt to recipients $1 |
||||
PRIVENCRYPT() |
||||
{ |
||||
set -- $1 |
||||
if isnonnull "$Conf_signkey"; then |
||||
set -- "$@" -u "$Conf_signkey" |
||||
fi |
||||
rungpg --compress-algo none --trust-model=always -se "$@" |
||||
} |
||||
|
||||
# $1 is the match for good signature, $2 is the textual signers list |
||||
PRIVDECRYPT() |
||||
{ |
||||
local status_= |
||||
exec 4>&1 && |
||||
status_=$(rungpg --status-fd 3 -q -d 3>&1 1>&4) && |
||||
xfeed "$status_" grep "^\[GNUPG:\] ENC_TO " >/dev/null && |
||||
(xfeed "$status_" grep -e "$1" >/dev/null || { |
||||
echo_info "Failed to verify manifest signature!" && |
||||
echo_info "Only accepting signatories: ${2:-(none)}" && |
||||
return 1 |
||||
}) |
||||
} |
||||
|
||||
# Generate $1 random bytes |
||||
genkey() |
||||
{ |
||||
rungpg --armor --gen-rand 1 "$1" |
||||
} |
||||
|
||||
gpg_hash() |
||||
{ |
||||
local hash_= |
||||
hash_=$(rungpg --with-colons --print-md "$1" | tr A-F a-f) |
||||
hash_=${hash_#:*:} |
||||
xecho "${hash_%:}" |
||||
} |
||||
|
||||
rungpg() |
||||
{ |
||||
if isnonnull "$Conf_gpg_args"; then |
||||
set -- "$Conf_gpg_args" "$@" |
||||
fi |
||||
# gpg will fail to run when there is no controlling tty, |
||||
# due to trying to print messages to it, even if a gpg agent is set |
||||
# up. --no-tty fixes this. |
||||
if [ "x$GPG_AGENT_INFO" != "x" ]; then |
||||
${GPG} --no-tty $@ |
||||
else |
||||
${GPG} $@ |
||||
fi |
||||
} |
||||
|
||||
# Pass the branch/ref by pipe to git |
||||
safe_git_rev_parse() |
||||
{ |
||||
git cat-file --batch-check 2>/dev/null | |
||||
xgrep -v "missing" | cut -f 1 -d ' ' |
||||
} |
||||
|
||||
make_new_repo() |
||||
{ |
||||
echo_info "Setting up new repository" |
||||
PUTREPO "$URL" |
||||
|
||||
# Needed assumption: the same user should have no duplicate Repoid |
||||
Repoid=":id:$(genkey 15)" |
||||
iseq "${NAME#gcrypt::}" "$URL" || |
||||
git config "remote.$NAME.gcrypt-id" "$Repoid" |
||||
echo_info "Remote ID is $Repoid" |
||||
Extnlist="extn comment" |
||||
} |
||||
|
||||
|
||||
# $1 return var for goodsig match, $2 return var for signers text |
||||
read_config() |
||||
{ |
||||
local recp_= r_tail= r_keyinfo= r_keyfpr= gpg_list= cap_= conf_part= good_sig= signers_= |
||||
Conf_signkey=$(git config --get "remote.$NAME.gcrypt-signingkey" '.+' || |
||||
git config --path user.signingkey || :) |
||||
conf_part=$(git config --get "remote.$NAME.gcrypt-participants" '.+' || |
||||
git config --get gcrypt.participants '.+' || :) |
||||
Conf_pubish_participants=$(git config --get --bool "remote.$NAME.gcrypt-publish-participants" '.+' || |
||||
git config --get --bool gcrypt.publish-participants || :) |
||||
Conf_gpg_args=$(git config --get gcrypt.gpg-args '.+' || :) |
||||
|
||||
# Figure out which keys we should encrypt to or accept signatures from |
||||
if isnull "$conf_part" || iseq "$conf_part" simple |
||||
then |
||||
signers_="(default keyring)" |
||||
Recipients="--throw-keyids --default-recipient-self" |
||||
good_sig="^\[GNUPG:\] GOODSIG " |
||||
setvar "$1" "$good_sig" |
||||
setvar "$2" "$signers_" |
||||
return 0 |
||||
fi |
||||
|
||||
for recp_ in $conf_part |
||||
do |
||||
gpg_list=$(rungpg --with-colons --fingerprint -k "$recp_") |
||||
r_tail_=$(echo "$recp_" | sed -e 's/^0x//') |
||||
filter_to @r_keyinfo "pub*" "$gpg_list" |
||||
if echo "$recp_" | grep -E -q '^[xA-F0-9]+$'; then # is $recp_ a keyid? |
||||
filter_to @r_keyfpr "fpr*$r_tail_*" "$gpg_list" |
||||
else |
||||
filter_to @r_keyfpr "fpr*" "$gpg_list" |
||||
fi |
||||
isnull "$r_keyinfo" || isnonnull "${r_keyinfo##*"$Newline"*}" || |
||||
echo_info "WARNING: '$recp_' matches multiple keys, using one" |
||||
isnull "$r_keyfpr" || isnonnull "${r_keyfpr##*"$Newline"*}" || |
||||
echo_info "WARNING: '$recp_' matches multiple fingerprints, using one" |
||||
r_keyinfo=${r_keyinfo%%"$Newline"*} |
||||
r_keyfpr=${r_keyfpr%%"$Newline"*} |
||||
keyid_=$(xfeed "$r_keyinfo" cut -f 5 -d :) |
||||
fprid_=$(xfeed "$r_keyfpr" cut -f 10 -d :) |
||||
|
||||
isnonnull "$fprid_" && |
||||
signers_="$signers_ $keyid_" && |
||||
append_to @good_sig "^\[GNUPG:\] VALIDSIG .*$fprid_$" || { |
||||
echo_info "WARNING: Skipping missing key $recp_" |
||||
continue |
||||
} |
||||
# Check 'E'ncrypt capability |
||||
cap_=$(xfeed "$r_keyinfo" cut -f 12 -d :) |
||||
if ! iseq "${cap_#*E}" "$cap_"; then |
||||
if [ "$Conf_pubish_participants" = true ]; then |
||||
Recipients="$Recipients -r $keyid_" |
||||
else |
||||
Recipients="$Recipients -R $keyid_" |
||||
fi |
||||
fi |
||||
done |
||||
|
||||
if isnull "$Recipients" |
||||
then |
||||
echo_info "You have not configured any keys you can encrypt to" \ |
||||
"for this repository" |
||||
echo_info "Use ::" |
||||
echo_info " git config gcrypt.participants YOURKEYID" |
||||
exit 1 |
||||
fi |
||||
setvar "$1" "$good_sig" |
||||
setvar "$2" "$signers_" |
||||
} |
||||
|
||||
ensure_connected() |
||||
{ |
||||
local manifest_= r_repoid= r_name= url_frag= r_sigmatch= r_signers= \ |
||||
tmp_manifest= |
||||
|
||||
if isnonnull "$Did_find_repo" |
||||
then |
||||
return |
||||
fi |
||||
Did_find_repo=no |
||||
read_config @r_sigmatch @r_signers |
||||
|
||||
iseq "${NAME#gcrypt::}" "$URL" || r_name=$NAME |
||||
|
||||
if isurl gitception "$URL" && isnonnull "$r_name"; then |
||||
git config "remote.$r_name.url" "gcrypt::${URL#gitception://}" |
||||
echo_info "Updated URL for $r_name, gitception:// -> ()" |
||||
fi |
||||
|
||||
# Find the URL fragment |
||||
url_frag=${URL##*"#"} |
||||
isnoteq "$url_frag" "$URL" || url_frag= |
||||
URL=${URL%"#$url_frag"} |
||||
|
||||
# manifestfile -- sha224 hash if we can, else the default location |
||||
if isurl sftp "$URL" || islocalrepo "$URL" || isurl rsync "$URL" |
||||
then |
||||
# not for gitception |
||||
isnull "$url_frag" || |
||||
Manifestfile=$(xecho_n "$url_frag" | gpg_hash SHA224) |
||||
else |
||||
isnull "$url_frag" || Gref_rbranch="refs/heads/$url_frag" |
||||
fi |
||||
|
||||
Repoid= |
||||
isnull "$r_name" || |
||||
Repoid=$(git config "remote.$r_name.gcrypt-id" || :) |
||||
|
||||
|
||||
tmp_manifest="$Tempdir/maniF" |
||||
GET "$URL" "$Manifestfile" "$tmp_manifest" 2>/dev/null || { |
||||
echo_info "Repository not found: $URL" |
||||
if ! isnull "$Repoid"; then |
||||
echo_info "..but repository ID is set. Aborting." |
||||
return 1 |
||||
else |
||||
return 0 |
||||
fi |
||||
} |
||||
|
||||
Did_find_repo=yes |
||||
echo_info "Decrypting manifest" |
||||
manifest_=$(PRIVDECRYPT "$r_sigmatch" "$r_signers" < "$tmp_manifest") && |
||||
isnonnull "$manifest_" || |
||||
echo_die "Failed to decrypt manifest!" |
||||
rm -f "$tmp_manifest" |
||||
|
||||
filter_to @Refslist "$Hex40 *" "$manifest_" |
||||
filter_to @Packlist "pack :*:* *" "$manifest_" |
||||
filter_to @Keeplist "keep :*:*" "$manifest_" |
||||
filter_to @Extnlist "extn *" "$manifest_" |
||||
filter_to @r_repoid "repo *" "$manifest_" |
||||
|
||||
r_repoid=${r_repoid#repo } |
||||
r_repoid=${r_repoid% *} |
||||
if isnull "$Repoid" |
||||
then |
||||
echo_info "Remote ID is $r_repoid" |
||||
Repoid=$r_repoid |
||||
elif isnoteq "$r_repoid" "$Repoid" |
||||
then |
||||
echo_info "WARNING:" |
||||
echo_info "WARNING: Remote ID has changed!" |
||||
echo_info "WARNING: from $Repoid" |
||||
echo_info "WARNING: to $r_repoid" |
||||
echo_info "WARNING:" |
||||
Repoid=$r_repoid |
||||
else |
||||
return 0 |
||||
fi |
||||
|
||||
isnull "$r_name" || git config "remote.$r_name.gcrypt-id" "$r_repoid" |
||||
} |
||||
|
||||
# $1 is the hash type (SHA256 etc) |
||||
# $2 the pack id |
||||
# $3 the key |
||||
get_verify_decrypt_pack() |
||||
{ |
||||
local rcv_id= tmp_encrypted= |
||||
tmp_encrypted="$Tempdir/packF" |
||||
GET "$URL" "$2" "$tmp_encrypted" && |
||||
rcv_id=$(gpg_hash "$1" < "$tmp_encrypted") && |
||||
iseq "$rcv_id" "$2" || echo_die "Packfile $2 does not match digest!" |
||||
DECRYPT "$3" < "$tmp_encrypted" |
||||
rm -f "$tmp_encrypted" |
||||
} |
||||
|
||||
# download all packlines (pack :SHA256:a32abc1231) from stdin (or die) |
||||
# $1 destdir (when repack, else "") |
||||
get_pack_files() |
||||
{ |
||||
local pack_id= r_pack_key_line= htype_= pack_= key_= |
||||
while IFS=': ' read -r _ htype_ pack_ # <<here-document |
||||
do |
||||
isnonnull "$pack_" || continue |
||||
|
||||
# Get the Packlist line with the key |
||||
pack_id=":${htype_}:$pack_" |
||||
filter_to @r_pack_key_line "pack $pack_id *" "$Packlist" |
||||
key_=${r_pack_key_line#pack $pack_id } |
||||
|
||||
if isnonnull "${pack_##$Hex40*}" || |
||||
isnoteq "$htype_" SHA256 && isnoteq "$htype_" SHA224 && |
||||
isnoteq "$htype_" SHA384 && isnoteq "$htype_" SHA512 |
||||
then |
||||
echo_die "Packline malformed: $pack_id" |
||||
fi |
||||
|
||||
get_verify_decrypt_pack "$htype_" "$pack_" "$key_" | \ |
||||
if isnull "${1:-}" |
||||
then |
||||
# add to local pack list |
||||
git index-pack -v --stdin >/dev/null |
||||
xecho "pack $pack_id" >> "$Localdir/have_packs$GITCEPTION" |
||||
else |
||||
git index-pack -v --stdin "$1/${pack_}.pack" >/dev/null |
||||
fi |
||||
done |
||||
} |
||||
|
||||
# Download and unpack remote packfiles |
||||
# $1 return var for list of packfiles to delete |
||||
repack_if_needed() |
||||
{ |
||||
local n_= m_= kline_= r_line= r_keep_packlist= r_del_list= |
||||
|
||||
isnonnull "$Packlist" || return 0 |
||||
|
||||
if isnonnull "${GCRYPT_FULL_REPACK:-}" |
||||
then |
||||
Keeplist= |
||||
Repack_limit=0 |
||||
fi |
||||
|
||||
pick_fields_1_2 @r_del_list "$Packlist" |
||||
|
||||
n_=$(line_count "$Packlist") |
||||
m_=$(line_count "$Keeplist") |
||||
if iseq 0 "$(( $Repack_limit < ($n_ - $m_) ))"; then |
||||
return |
||||
fi |
||||
echo_info "Repacking remote $NAME, ..." |
||||
|
||||
mkdir "$Tempdir/pack" |
||||
|
||||
# Split packages to keep and to repack |
||||
if isnonnull "$Keeplist"; then |
||||
while read -r _ kline_ _ # <<here-document |
||||
do |
||||
isnonnull "$kline_" || continue |
||||
filter_to @r_line "pack $kline_ *" "$Packlist" |
||||
append_to @r_keep_packlist "$r_line" |
||||
filter_to ! @r_del_list "pack $kline_" "$r_del_list" |
||||
done <<EOF |
||||
$Keeplist |
||||
EOF |
||||
fi |
||||
|
||||
xfeed "$r_del_list" get_pack_files "$Tempdir/pack/" |
||||
|
||||
(set +f; pipefail git verify-pack -v "$Tempdir"/pack/*.idx) | |
||||
grep -E '^[0-9a-f]{40}' | cut -f 1 -d ' ' |
||||
|
||||
Packlist=$r_keep_packlist |
||||
setvar "$1" "$r_del_list" |
||||
} |
||||
|
||||
do_capabilities() |
||||
{ |
||||
echo_git fetch |
||||
echo_git push |
||||
echo_git |
||||
} |
||||
|
||||
do_list() |
||||
{ |
||||
local obj_id= ref_name= line_= |
||||
ensure_connected |
||||
|
||||
xecho "$Refslist" | while read line_ |
||||
do |
||||
isnonnull "$line_" || break |
||||
obj_id=${line_%% *} |
||||
ref_name=${line_##* } |
||||
echo_git "$obj_id" "$ref_name" |
||||
if iseq "$ref_name" "refs/heads/master" |
||||
then |
||||
echo_git "@refs/heads/master HEAD" |
||||
fi |
||||
done |
||||
|
||||
# end with blank line |
||||
echo_git |
||||
} |
||||
|
||||
do_fetch() |
||||
{ |
||||
# Download packs in the manifest that don't appear in have_packs |
||||
local pneed_= premote_= |
||||
|
||||
ensure_connected |
||||
|
||||
# The `+` for $GITCEPTION is pointless but we will be safe for stacking |
||||
pick_fields_1_2 @premote_ "$Packlist" |
||||
if [ -s "$Localdir/have_packs+" ] |
||||
then |
||||
pneed_=$(xfeed "$premote_" xgrep -v -x -f "$Localdir/have_packs+") |
||||
else |
||||
pneed_=$premote_ |
||||
fi |
||||
|
||||
xfeed "$pneed_" get_pack_files |
||||
|
||||
echo_git # end with blank line |
||||
} |
||||
|
||||
# do_push PUSHARGS (multiple lines like +src:dst, with both + and src opt.) |
||||
do_push() |
||||
{ |
||||
# Security protocol: |
||||
# Each git packfile is encrypted and then named for the encrypted |
||||
# file's hash. The manifest is updated with the pack id. |
||||
# The manifest is encrypted. |
||||
local r_revlist= pack_id= key_= obj_= src_= dst_= \ |
||||
r_pack_delete= tmp_encrypted= tmp_objlist= tmp_manifest= |
||||
|
||||
ensure_connected |
||||
|
||||
if iseq "$Did_find_repo" "no" |
||||
then |
||||
make_new_repo |
||||
fi |
||||
|
||||
if isnonnull "$Refslist" |
||||
then |
||||
# mark all remote refs with ^<sha-1> (if sha-1 exists locally) |
||||
r_revlist=$(xfeed "$Refslist" cut -f 1 -d ' ' | |
||||
safe_git_rev_parse | sed -e 's/^\(.\)/^&/') |
||||
fi |
||||
|
||||
while IFS=: read -r src_ dst_ # << +src:dst |
||||
do |
||||
src_=${src_#+} |
||||
filter_to ! @Refslist "$Hex40 $dst_" "$Refslist" |
||||
|
||||
if isnonnull "$src_" |
||||
then |
||||
append_to @r_revlist "$src_" |
||||
obj_=$(xfeed "$src_" safe_git_rev_parse) |
||||
append_to @Refslist "$obj_ $dst_" |
||||
fi |
||||
done <<EOF |
||||
$1 |
||||
EOF |
||||
|
||||
tmp_encrypted="$Tempdir/packP" |
||||
tmp_objlist="$Tempdir/objlP" |
||||
|
||||
{ |
||||
xfeed "$r_revlist" git rev-list --objects --stdin -- |
||||
repack_if_needed @r_pack_delete |
||||
} > "$tmp_objlist" |
||||
|
||||
# Only send pack if we have any objects to send |
||||
if [ -s "$tmp_objlist" ] |
||||
then |
||||
key_=$(genkey "$Packkey_bytes") |
||||
pack_id=$(export GIT_ALTERNATE_OBJECT_DIRECTORIES=$Tempdir; |
||||
pipefail git pack-objects --stdout < "$tmp_objlist" | |
||||
pipefail ENCRYPT "$key_" | |
||||
tee "$tmp_encrypted" | gpg_hash "$Hashtype") |
||||
|
||||
append_to @Packlist "pack :${Hashtype}:$pack_id $key_" |
||||
if isnonnull "$r_pack_delete" |
||||
then |
||||
append_to @Keeplist "keep :${Hashtype}:$pack_id 1" |
||||
fi |
||||
fi |
||||
|
||||
# Generate manifest |
||||
echo_info "Encrypting to: $Recipients" |
||||
echo_info "Requesting manifest signature" |
||||
|
||||
tmp_manifest="$Tempdir/maniP" |
||||
PRIVENCRYPT "$Recipients" > "$tmp_manifest" <<EOF |
||||
$Refslist |
||||
$Packlist |
||||
$Keeplist |
||||
repo $Repoid |
||||
$Extnlist |
||||
EOF |
||||
|
||||
# Upload pack |
||||
if [ -s "$tmp_objlist" ] |
||||
then |
||||
PUT "$URL" "$pack_id" "$tmp_encrypted" |
||||
fi |
||||
|
||||
# Upload manifest |
||||
PUT "$URL" "$Manifestfile" "$tmp_manifest" |
||||
|
||||
rm -f "$tmp_encrypted" |
||||
rm -f "$tmp_objlist" |
||||
rm -f "$tmp_manifest" |
||||
|
||||
# Delete packs |
||||
if isnonnull "$r_pack_delete"; then |
||||
REMOVE "$URL" "$(xecho "$r_pack_delete" | \ |
||||
while IFS=': ' read -r _ _ pack_ |
||||
do |
||||
isnonnull "$pack_" || continue |
||||
xecho "$pack_" |
||||
done)" |
||||
fi |
||||
|
||||
PUT_FINAL "$URL" |
||||
|
||||
# ok all updates |
||||
while IFS=: read -r src_ dst_ # << +src:dst |
||||
do |
||||
echo_git "ok $dst_" |
||||
done <<EOF |
||||
$1 |
||||
EOF |
||||
|
||||
echo_git |
||||
} |
||||
|
||||
cleanup_tmpfiles() |
||||
{ |
||||
if isnonnull "${Tempdir%%*."$$"}"; then |
||||
echo_die "Unexpected Tempdir value: $Tempdir" |
||||
fi |
||||
rm -r -f -- "${Tempdir}" >&2 |
||||
} |
||||
|
||||
setup() |
||||
{ |
||||
mkdir -p "$Localdir" |
||||
|
||||
# Set up a subdirectory in /tmp |
||||
temp_key=$(genkey 9 | tr '/' _) |
||||
Tempdir="${TMPDIR:-/tmp}/git-remote-gcrypt-${temp_key}.$$" |
||||
case "${MSYSTEM:-unknown}" in |
||||
MSYS*|MINGW*) |
||||
mkdir "${Tempdir}" |
||||
echo_info "Warning: Not securing tempdir ${Tempdir} because we are on mingw/msys" |
||||
;; |
||||
unknown|*) |
||||
mkdir -m 700 "${Tempdir}" |
||||
;; |
||||
esac |
||||
|
||||
trap cleanup_tmpfiles EXIT |
||||
trap 'exit 1' 1 2 3 15 |
||||
} |
||||
|
||||
# handle git-remote-helpers protocol |
||||
gcrypt_main_loop() |
||||
{ |
||||
local input_= input_inner= r_args= temp_key= |
||||
|
||||
NAME=$1 # Remote name |
||||
URL=$2 # Remote URL |
||||
|
||||
setup |
||||
|
||||
while read input_ |
||||
do |
||||
case "$input_" in |
||||
capabilities) |
||||
do_capabilities |
||||
;; |
||||
list|list\ for-push) |
||||
do_list |
||||
;; |
||||
fetch\ *) |
||||
r_args=${input_##fetch } |
||||
while read input_inner |
||||
do |
||||
case "$input_inner" in |
||||
fetch*) |
||||
r_args= #ignored |
||||
;; |
||||
*) |
||||
break |
||||
;; |
||||
esac |
||||
done |
||||
do_fetch "$r_args" |
||||
;; |
||||
push\ *) |
||||
r_args=${input_##push } |
||||
while read input_inner |
||||
do |
||||
case "$input_inner" in |
||||
push\ *) |
||||
append_to @r_args "${input_inner#push }" |
||||
;; |
||||
*) |
||||
break |
||||
;; |
||||
esac |
||||
done |
||||
do_push "$r_args" |
||||
;; |
||||
?*) |
||||
echo_die "Unknown input!" |
||||
;; |
||||
*) |
||||
CLEAN_FINAL "$URL" |
||||
exit 0 |
||||
;; |
||||
esac |
||||
done |
||||
} |
||||
|
||||
if [ "x$1" = x--check ] |
||||
then |
||||
NAME=dummy-gcrypt-check |
||||
URL=$2 |
||||
setup |
||||
ensure_connected |
||||
git remote remove $NAME 2>/dev/null || true |
||||
if iseq "$Did_find_repo" "no" |
||||
then |
||||
exit 100 |
||||
fi |
||||
else |
||||
gcrypt_main_loop "$@" |
||||
fi |
@ -1,5 +1,5 @@ |
||||
#!/bin/sh |
||||
cd "$(mktemp -d)"; |
||||
go mod init local-playground; |
||||
echo -e 'package main\n\nimport (\n\t"fmt"\n)\n\nfunc main() {\n\tfmt.Println("aloha")\n}\n' > main.go; |
||||
echo 'package main\n\nimport (\n\t"fmt"\n)\n\nfunc main() {\n\tfmt.Println("aloha")\n}\n' > main.go; |
||||
$EDITOR main.go; |
||||
|
@ -0,0 +1,31 @@ |
||||
#!/bin/sh |
||||
|
||||
set -e |
||||
|
||||
# This assumes that /proc/cmdline contains a cryptdevice with a UUID identifier, |
||||
# like: |
||||
# |
||||
# cryptdevice=UUID=1ff1d6f7-7540-4500-8011-1abe1e9ac00d:cryptroot |
||||
uuid=$(cat /proc/cmdline | \ |
||||
tr ' ' '\n' | \ |
||||
grep cryptdevice | \ |
||||
cut -d= -f3 | \ |
||||
cut -d: -f1) |
||||
|
||||
device=$(lsblk -o PATH,UUID | grep "$uuid" | awk '{print $1}') |
||||
echo "Root device is $device" |
||||
|
||||
echo -n "Enter root key: " |
||||
read -s pw |
||||
echo "" |
||||
|
||||
# This will check if the key is right, and cause the process to exit if not due |
||||
# to the "set -e" |
||||
echo "Checking key..." |
||||
echo "$pw" | sudo cryptsetup open --test-passphrase "$device" |
||||
|
||||
echo "Good job, writing /boot/keyfile..." |
||||
echo -n "$pw" | sudo tee /boot/keyfile >/dev/null |
||||
|
||||
echo "Rebooting..." |
||||
sudo systemctl reboot |
@ -0,0 +1,31 @@ |
||||
#!/bin/sh |
||||
|
||||
set -e |
||||
|
||||
# This assumes that /proc/cmdline contains a cryptdevice with a UUID identifier, |
||||
# like: |
||||
# |
||||
# cryptdevice=UUID=1ff1d6f7-7540-4500-8011-1abe1e9ac00d:cryptroot |
||||
uuid=$(cat /proc/cmdline | \ |
||||
tr ' ' '\n' | \ |
||||
grep cryptdevice | \ |
||||
cut -d= -f3 | \ |
||||
cut -d: -f1) |
||||
|
||||
device=$(lsblk -o PATH,UUID | grep "$uuid" | awk '{print $1}') |
||||
echo "Root device is $device" |
||||
|
||||
echo -n "Enter root key: " |
||||
read -s pw |
||||
echo "" |
||||
|
||||
# This will check if the key is right, and cause the process to exit if not due |
||||
# to the "set -e" |
||||
echo "Checking key..." |
||||
echo "$pw" | sudo cryptsetup open --test-passphrase "$device" |
||||
|
||||
echo "Good job, writing /boot/keyfile..." |
||||
echo -n "$pw" | sudo tee /boot/keyfile >/dev/null |
||||
|
||||
echo "Shutting down..." |
||||
sudo systemctl poweroff |
@ -0,0 +1,353 @@ |
||||
#!/bin/sh |
||||
set -uf |
||||
IFS="$(printf '\n\t')" |
||||
LC_ALL="C" |
||||
|
||||
# Copyright (C) 2019 Jamie Nguyen <j@jamielinux.com> |
||||
# |
||||
# A simple shell script to recursively generate, update and verify checksums |
||||
# for files you care about. It's useful for detecting bit rot. |
||||
# |
||||
# It's written in POSIX shell, but requires GNU coreutils, BusyBox or some |
||||
# other collection that includes similar checksum tools. |
||||
|
||||
VERSION=1.1.2 |
||||
COMMAND="sha512sum" |
||||
CHECKFILE="./.rotcheck" |
||||
|
||||
APPEND_MODE=0 |
||||
CHECK_MODE=0 |
||||
DELETE_MODE=0 |
||||
UPDATE_MODE=0 |
||||
|
||||
IGNORE_MISSING=0 |
||||
FOLLOW_SYMLINKS=1 |
||||
VERBOSE=0 |
||||
WARN_FORMATTING=0 |
||||
EXCLUDE_HIDDEN=0 |
||||
FORCE_UPDATE=0 |
||||
|
||||
usage() { |
||||
cat << EOF |
||||
rotcheck $VERSION |
||||
Usage: rotcheck MODE [OPTIONS] |
||||
or: rotcheck MODE [OPTIONS] -- [DIRECTORY]... [ARBITRARY FIND OPTION]... |
||||
Recursively generate, update and verify checksums. |
||||
|
||||
MODES: |
||||
-a APPEND mode: Record checksums for any files without a checksum |
||||
already. Never modify existing checksums. |
||||
-c CHECK mode: Check that files checksums are the same. |
||||
-d DELETE mode: Remove checksums for files that don't exist. |
||||
-u APPEND-AND-UPDATE mode: Like append-only mode, but also update |
||||
checksums for files with a modification date newer than the |
||||
the checksum file. (NB: Also see \`-M\`.) |
||||
|
||||
OPTIONS: |
||||
-b COMMAND Checksum command to use. Default: sha512sum |
||||
-f FILE File to store checksums. For relative paths, prefix with "./" |
||||
or the checksum file will be checksummed. Default: ./.rotcheck |
||||
-h Display this help. |
||||
-n Don't follow symlinks. The default is to follow symlinks. |
||||
-v Be more verbose when adding, deleting, changing or verifying |
||||
checksums. |
||||
-w Warn about improperly formatted checksum lines. |
||||
-x Exclude all hidden files and directories when generating |
||||
checksums. The default is to include them. |
||||
-M Use with \`-u\` to update checksums regardless of modification |
||||
time. This is very slow so avoid if possible; try \`touch\` |
||||
instead to bump the modification time of specific files. |
||||
WARNING: The checksums might have changed due to bit rot so |
||||
use this option with care! |
||||
|
||||
(specific to GNU coreutils >= 8.25) |
||||
-i Ignore missing files when verifying checksums. |
||||
|
||||
|
||||
Supported commands: |
||||
GNU coreutils: |
||||
md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, b2sum |
||||
|
||||
BusyBox (applets must be symlinked): |
||||
md5sum, sha1sum, sha256sum, sha512sum, sha3sum |
||||
|
||||
BSD & macOS (install GNU coreutils): |
||||
gmd5sum, gsha1sum, gsha224sum, gsha256sum, gsha384sum, gsha512sum, gb2sum |
||||
|
||||
|
||||
Examples: |
||||
# Create checksum file (located at "./.rotcheck"): |
||||
rotcheck -a |
||||
|
||||
# You've added some new files and need to append some checksums: |
||||
rotcheck -va |
||||
|
||||
# You've edited some files and need to update the checksums (for files with |
||||
# a modification time newer than the checksum file): |
||||
rotcheck -vu |
||||
|
||||
# Verify checksums: |
||||
rotcheck -c |
||||
|
||||
# Search other directories instead of the current directory. |
||||
# WARNING: checksums might get duplicated if mixing relative and absolute |
||||
# paths, or if you change the way you specify directory paths! |
||||
rotcheck -a -- /mnt/archive-2018/ /mnt/archive-2019/ |
||||
|
||||
# Exclude .git folders (these arguments are passed directly to find): |
||||
rotcheck -a -- ! -path '*/\\.git/*' |
||||
|
||||
EOF |
||||
exit 0 |
||||
} |
||||
|
||||
fail() { |
||||
printf '%s\n' "$@"; exit 1 |
||||
} |
||||
|
||||
# Curiously, I stumbled across a bug in bash-3.0.16 (c. 2004) or older |
||||
# where \0177 (DEL) isn't handled properly. See the `find_safe` function below. |
||||
# bash-3.1 (c. 2005), dash-0.5.2 (c. 2005), and zsh-3.1 (c. 2000) all work |
||||
# and probably others too. |
||||
if [ -n ${BASH+x} ] && [ -n ${BASH_VERSION+x} ]; then |
||||
if printf '%s' "${BASH_VERSION:-x}" | grep -qE '^[0-2]+|^3\.0'; then |
||||
fail "bash-3.0.16 and older are broken." \ |
||||
"Try bash>=3.1, dash, zsh, or another POSIX shell." |
||||
fi |
||||
fi |
||||
|
||||
# Command-line arguments. `getopts` is POSIX, while `getopt` is not. |
||||
[ $# -gt 0 ] && [ "$1" = "--help" ] && usage |
||||
while getopts ":acdub:f:hinvwxM" opt; do |
||||
case "$opt" in |
||||
a) APPEND_MODE=1;; |
||||
c) CHECK_MODE=1;; |
||||
d) DELETE_MODE=1;; |
||||
u) UPDATE_MODE=1;; |
||||
b) COMMAND="$OPTARG";; |
||||
f) CHECKFILE="$OPTARG";; |
||||
h) usage;; |
||||
i) IGNORE_MISSING=1;; |
||||
n) FOLLOW_SYMLINKS=0;; |
||||
v) VERBOSE=1;; |
||||
w) WARN_FORMATTING=1;; |
||||
x) EXCLUDE_HIDDEN=1;; |
||||
M) FORCE_UPDATE=1;; |
||||
\?) fail "-$OPTARG: Invalid argument";; |
||||
:) fail "-$OPTARG requires an argument";; |
||||
esac |
||||
done; shift $(($OPTIND - 1)) |
||||
|
||||
|
||||
|
||||
# A few sanity checks. |
||||
MODE=$(($APPEND_MODE + $CHECK_MODE + $DELETE_MODE + $UPDATE_MODE)) |
||||
if [ $MODE -eq 0 ]; then |
||||
fail "Please specify one of -a, -c, -d, or -u." \ |
||||
"See \`rotcheck -h\` for help with usage." |
||||
elif [ $MODE -gt 1 ]; then |
||||
fail "You can only use one of -a, -c, -d, or -u options." \ |
||||
"See \`rotcheck -h\` for help with usage." |
||||
elif [ $CHECK_MODE -eq 1 ] || [ $DELETE_MODE -eq 1 ]; then |
||||
if [ ! -f "$CHECKFILE" ]; then |
||||
fail "$CHECKFILE: No such file." \ |
||||
"Try running \`rotcheck -a\` first, or see \`rotcheck -h\`." |
||||
fi |
||||
elif ! command -v "$COMMAND" >/dev/null 2>/dev/null; then |
||||
fail "$COMMAND: command not found" \ |
||||
"Try specifying a supported command using \`rotcheck -b COMMAND\`." \ |
||||
"You may need to install GNU coreutils or BusyBox." \ |
||||
"On *BSD, GNU coreutils commands begin with 'g', like 'gsha512sum'." \ |
||||
"See \`rotcheck -h\` for help with usage." |
||||
fi |
||||
|
||||
# When printing text to terminal, make sure it won't do anything unexpected. |
||||
printf_sanitized() { |
||||
printf '%s' "$@" | tr -d '[:cntrl:]' | iconv -cs -f UTF-8 -t UTF-8 |
||||
printf '\n' |
||||
} |
||||
|
||||
verify_checksums() { |
||||
IGNORE="" ; [ $IGNORE_MISSING -eq 1 ] && IGNORE="--ignore-missing" |
||||
WARN="" ; [ $WARN_FORMATTING -eq 1 ] && WARN="-w" |
||||
$COMMAND -c $WARN $IGNORE -- "$CHECKFILE" |
||||
} |
||||
|
||||
# Just verify checksums. |
||||
if [ $CHECK_MODE -eq 1 ]; then |
||||
# Only GNU coreutils supports `--quiet`, so use `grep -v` instead. |
||||
# Unfortunately, pipefail isn't POSIX so to return the exit status from the |
||||
# checksum command, we have to be clever (aka crazy) with file descriptors |
||||
# and subshells instead. |
||||
if [ $VERBOSE -eq 1 ]; then |
||||
verify_checksums |
||||
exit $? |
||||
else |
||||
exec 4>&1 |
||||
( |
||||
exec 3>&1 |
||||
( |
||||
# 2>&1 preserves order of stdout/stderr. |
||||
verify_checksums 2>&1; printf '%d' $? 1>&3 |
||||
) | grep -Ev ': OK$' 1>&4 |
||||
exec 3>&- |
||||
) | ( read -r retval; exit $retval ); retval=$? |
||||
exec 4>&- |
||||
exit $retval |
||||
fi |
||||
fi |
||||
|
||||
# Delete checksums for files that no longer exist. |
||||
if [ $DELETE_MODE -eq 1 ]; then |
||||
i=1 |
||||
for file in $(cut -d ' ' -f 3- -- "$CHECKFILE"); do |
||||
# `sed -i` isn't POSIX (nor is `mktemp`), so use `ex` instead. |
||||
if [ ! -f "$file" ]; then |
||||
cat << EOF | ex -s -- "$CHECKFILE" |
||||
${i}d |
||||
x |
||||
EOF |
||||
# Print what checksums were deleted. |
||||
if [ $VERBOSE -eq 1 ]; then |
||||
printf '%s' "DELETED: " |
||||
printf_sanitized "$file" |
||||
fi |
||||
else |
||||
# Only increment the line number if we didn't delete a line. |
||||
i=$(($i + 1)) |
||||
fi |
||||
done |
||||
exit $? |
||||
fi |
||||
|
||||
# For safety and sanity, ignore all filenames that have control characters |
||||
# like newline, tab, delete etc. |
||||
find_safe() { |
||||
FIND_L="" |
||||
FIND_FOLLOW="" |
||||
if [ $FOLLOW_SYMLINKS -eq 1 ]; then |
||||
# Old versions of findutils don't have -L. Use it if available. |
||||
if find -L / -maxdepth 0 -type d >/dev/null 2>/dev/null; then |
||||
FIND_L="-L" |
||||
else |
||||
FIND_FOLLOW="-follow" |
||||
fi |
||||
fi |
||||
|
||||
# POSIX find requires that you specify the search path either first |
||||
# or immediately after -H/-L. Use current directory by default unless |
||||
# user has specified a path. |
||||
FIND_DOT="./" |
||||
if [ $# -gt 0 ]; then |
||||
first_char="$(printf '%s' "$1" | cut -c 1)" |
||||
# Replace search path unless first arg is a non-path `find` option. |
||||
if [ "$first_char" != "-" ] \ |
||||
&& [ "$first_char" != "!" ] && [ "$first_char" != "(" ]; then |
||||
FIND_DOT="" |
||||
fi |
||||
fi |
||||
|
||||
HIDDEN="" |
||||
[ $EXCLUDE_HIDDEN -eq 1 ] && HIDDEN='*/\.*' |
||||
|
||||
find $FIND_L $FIND_DOT "$@" $FIND_FOLLOW \ |
||||
-type f ! -path "$CHECKFILE" ! -path "$HIDDEN" \ |
||||
! -name "$(printf '*%b*' '\0001')" ! -name "$(printf '*%b*' '\0002')" \ |
||||
! -name "$(printf '*%b*' '\0003')" ! -name "$(printf '*%b*' '\0004')" \ |
||||
! -name "$(printf '*%b*' '\0005')" ! -name "$(printf '*%b*' '\0006')" \ |
||||
! -name "$(printf '*%b*' '\0007')" ! -name "$(printf '*%b*' '\0010')" \ |
||||
! -name "$(printf '*%b*' '\0011')" ! -name "$(printf '*%b*' '\0012')" \ |
||||
! -name "$(printf '*%b*' '\0013')" ! -name "$(printf '*%b*' '\0014')" \ |
||||
! -name "$(printf '*%b*' '\0015')" ! -name "$(printf '*%b*' '\0016')" \ |
||||
! -name "$(printf '*%b*' '\0017')" ! -name "$(printf '*%b*' '\0020')" \ |
||||
! -name "$(printf '*%b*' '\0021')" ! -name "$(printf '*%b*' '\0022')" \ |
||||
! -name "$(printf '*%b*' '\0023')" ! -name "$(printf '*%b*' '\0024')" \ |
||||
! -name "$(printf '*%b*' '\0025')" ! -name "$(printf '*%b*' '\0026')" \ |
||||
! -name "$(printf '*%b*' '\0027')" ! -name "$(printf '*%b*' '\0030')" \ |
||||
! -name "$(printf '*%b*' '\0031')" ! -name "$(printf '*%b*' '\0032')" \ |
||||
! -name "$(printf '*%b*' '\0033')" ! -name "$(printf '*%b*' '\0034')" \ |
||||
! -name "$(printf '*%b*' '\0035')" ! -name "$(printf '*%b*' '\0036')" \ |
||||
! -name "$(printf '*%b*' '\0037')" ! -name "$(printf '*%b*' '\0177')" |
||||
} |
||||
|
||||
find_updated_files() { |
||||
if [ $FORCE_UPDATE -eq 1 ]; then |
||||
find_safe "$@" |
||||
else |
||||
find_safe "$@" -newer "$CHECKFILE" |
||||
fi |
||||
} |
||||
|
||||
# This function could be replaced entirely with the much simpler: |
||||
# cut -d ' ' -f 3- "$CHECKFILE" | grep -Fxn -- "$file" | cut -d ':' -f 1 |
||||
# But this function is slightly faster as it avoids passing huge chunks of text |
||||
# (ie, the whole checksum file minus the first column) through a pipe. |
||||
get_line_number() { |
||||
# Avoid `grep -E` as filename characters might get interpreted (eg, $). |
||||
for l in $(grep -Fn -- "$file" "$CHECKFILE" | cut -d ':' -f 1); do |
||||
if sed -n -e "${l}p" -- "$CHECKFILE" \ |
||||
| cut -d ' ' -f 3- | grep -Fxq -- "$file" >/dev/null; then |
||||
printf '%d' "$l" |
||||
return 0 |
||||
fi |
||||
done |
||||
printf '%d' "0" |
||||
} |
||||
|
||||
umask 077 |
||||
# For files with a modification date newer than the checksum file, if there's |
||||
# an existing checksum then update it. Otherwise append a new checksum. |
||||
if [ $UPDATE_MODE -eq 1 ] && [ -f "$CHECKFILE" ]; then |
||||
for file in $(find_updated_files "$@"); do |
||||
line_num="$(get_line_number)" |
||||
if [ ${line_num:-0} -eq 0 ]; then |
||||
# No checksum yet, so append one. |
||||
$COMMAND -- "$file" >> "$CHECKFILE" |
||||
else |
||||
old="$(sed -n -e "${line_num}p" -- "$CHECKFILE" | cut -d ' ' -f 1)" |
||||
new="$($COMMAND -- "$file")" |
||||
# Should never happen, but double check these aren't empty: |
||||
if [ -z ${old:+x} ] || [ -z ${new:+x} ]; then |
||||
continue |
||||
fi |
||||
# `sed -i` isn't POSIX (nor is `mktemp`), so use `ex` instead. |
||||
if [ "$old" != "${new%% *}" ]; then |
||||
cat << EOF | ex -s -- "$CHECKFILE" |
||||
${line_num}c |
||||
$new |
||||
. |
||||
x |
||||
EOF |
||||
# Bail immediately if something went wrong. |
||||
[ $? -ne 0 ] && fail "Failed to update checksum file." |
||||
|
||||
# Print what checksums were changed. |
||||
if [ $VERBOSE -eq 1 ]; then |
||||
printf '%s' "CHANGED: " |
||||
printf_sanitized "$file" |
||||
fi |
||||
fi |
||||
fi |
||||
done |
||||
fi |
||||
|
||||
# Append checksums for files that have no checksum yet. |
||||
if [ $APPEND_MODE -eq 1 ] || [ $UPDATE_MODE -eq 1 ]; then |
||||
for file in $(find_safe "$@"); do |
||||
# Avoid `grep -E` as filename characters might get interpreted (eg, $). |
||||
# The first grep isn't strictly needed, but grep+cut+grep is faster |
||||
# than just cut+grep here. |
||||
if [ ! -f "$CHECKFILE" ] || ! grep -- "$file" "$CHECKFILE" \ |
||||
| cut -d ' ' -f 3- | grep -Fxq -- "$file"; then |
||||
if ! $COMMAND -- "$file" >> "$CHECKFILE"; then |
||||
fail "Failed to write to checksum file." |
||||
fi |
||||
|
||||
# Print what checksums were appended. |
||||
if [ $VERBOSE -eq 1 ]; then |
||||
printf '%s' "ADDED: " |
||||
printf_sanitized "$file" |
||||
fi |
||||
fi |
||||
done |
||||
fi |
@ -0,0 +1,29 @@ |
||||
{ |
||||
browser = "/usr/bin/firefox"; |
||||
|
||||
git = { |
||||
user = { |
||||
email = "me@mediocregopher.com"; |
||||
name = "Brian Picciano"; |
||||
}; |
||||
}; |
||||
|
||||
awesome = { |
||||
startupExtra = ""; |
||||
}; |
||||
|
||||
alacritty = { |
||||
fontSize = 11; |
||||
xdgOpenRules = [ |
||||
#{ |
||||
# name = "some-unique-name"; |
||||
# pattern = "regex pattern"; |
||||
|
||||
# # where $1 is the string which matched pattern |
||||
# xdgOpen = "https://some-url/$1"; |
||||
#} |
||||
]; |
||||
}; |
||||
|
||||
binExtra = []; |
||||
} |
@ -1,41 +1,50 @@ |
||||
let |
||||
rec { |
||||
|
||||
src = builtins.fetchTarball { |
||||
name = "nixpkgs-2105"; |
||||
url = "https://github.com/nixos/nixpkgs/archive/7e9b0dff974c89e070da1ad85713ff3c20b0ca97.tar.gz"; |
||||
sha256 = "1ckzhh24mgz6jd1xhfgx0i9mijk6xjqxwsshnvq789xsavrmsc36"; |
||||
}; |
||||
mkPkgs = src: let |
||||
|
||||
normalPkgs = (import src) {}; |
||||
normalPkgs = (import src) {}; |
||||
|
||||
config = { |
||||
allowUnfree = true; |
||||
packageOverrides = pkgs: { |
||||
|
||||
go = builtins.fetchTarball { |
||||
url = "https://golang.org/dl/go1.17.1.linux-amd64.tar.gz"; |
||||
sha256 = "1196h1jx9cn5ks1y9r95z0q2s6m6ssvnx7jd34g435jvxjgb2c94"; |
||||
}; |
||||
config = { |
||||
allowUnfree = true; |
||||
packageOverrides = pkgs: { |
||||
|
||||
nixgl = let |
||||
nixgl = let |
||||
|
||||
src = builtins.fetchTarball { |
||||
name = "nixgl-unstable"; |
||||
url = "https://github.com/guibou/nixGL/archive/51f19871a31b15b482ac4c80976da173289e77fb.tar.gz"; |
||||
sha256 = "0dj2apbx5iqvkiixyz1dzx4id51iw9s2isp1f9x60a03f5sqcvvi"; |
||||
}; |
||||
src = builtins.fetchTarball { |
||||
name = "nixgl-unstable"; |
||||
url = "https://github.com/guibou/nixGL/archive/7165ffbccbd2cf4379b6cd6d2edd1620a427e5ae.tar.gz"; |
||||
sha256 = "1wc85xqnq2wb008y9acb29jbfkc242m9697g2b8j6q3yqmfhrks1"; |
||||
}; |
||||
|
||||
nixgl = (import src) { |
||||
inherit pkgs; |
||||
enable32bits = false; |
||||
}; |
||||
nixgl = (import src) { |
||||
inherit pkgs; |
||||
enable32bits = false; |
||||
}; |
||||
|
||||
in nixgl.nixGLIntel; |
||||
in nixgl.auto.nixGLDefault; |
||||
|
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
in pkgsArg: |
||||
(import src) ( |
||||
in pkgsArg: (import src) ( |
||||
normalPkgs.lib.attrsets.recursiveUpdate { config = config; } pkgsArg |
||||
) |
||||
); |
||||
|
||||
stable = mkPkgs (builtins.fetchTarball { |
||||
name = "nixpkgs-2105"; |
||||
url = "https://github.com/nixos/nixpkgs/archive/7e9b0dff974c89e070da1ad85713ff3c20b0ca97.tar.gz"; |
||||
sha256 = "1ckzhh24mgz6jd1xhfgx0i9mijk6xjqxwsshnvq789xsavrmsc36"; |
||||
}); |
||||
|
||||
stable2305 = mkPkgs (builtins.fetchTarball { |
||||
name = "nixpkgs-2305"; |
||||
url = "https://github.com/nixos/nixpkgs/archive/4ecab3273592f27479a583fb6d975d4aba3486fe.tar.gz"; |
||||
sha256 = "sha256:10wn0l08j9lgqcw8177nh2ljrnxdrpri7bp0g7nvrsn9rkawvlbf"; |
||||
}); |
||||
|
||||
edge = mkPkgs (builtins.fetchTarball { |
||||
name = "nixpkgs-edge"; |
||||
url = "https://github.com/nixos/nixpkgs/archive/f9418c4c7fab906c52ae07cf27a618de7722d1e9.tar.gz"; |
||||
sha256 = "sha256:067m1gzj1n06m3anshwgabd1liaja8gcvd90spmnyi3a6vhqdvq0"; |
||||
}); |
||||
} |
||||
|
@ -1,18 +0,0 @@ |
||||
#Global stuff shitty programs use |
||||
export EDITOR=~/.nix-profile/bin/nvim |
||||
|
||||
#Basics |
||||
export PATH=$PATH:/bin |
||||
export PATH=$PATH:/usr/bin |
||||
export PATH=$PATH:/usr/local/bin |
||||
|
||||
#my shit |
||||
export PATH=~/bin:$PATH |
||||
|
||||
#Go has its own path system. Way to be difficult go |
||||
export GOPATH=~/.go |
||||
export GOBIN=$GOPATH/bin |
||||
export PATH=$GOPATH/bin:$PATH |
||||
|
||||
# GPG is needy |
||||
export GPG_TTY=$(tty) |