initial commit [141.14.140.180,mike]

This commit is contained in:
2026-08-10 16:12:09 +02:00
commit c534ea1c79
66 changed files with 9244 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
.DS_Store
.AppleDouble
.LSOverride
._*
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.mgshrc
+46
View File
@@ -0,0 +1,46 @@
-------------------- Debian 10/11/12 --------------------
# su -
# apt install git; git clone https://git.fhi.mpg.de/mike/linuxsetup
# cd ~/linuxsetup; ./setup.ssh
relogin as root
# cd ~/linuxsetup; ./setup.debian1x
# cd ~/linuxsetup; ./telemetry.setup
-------------------- Raspberry Pi OS --------------------
# sudo passwd root
# su -
# apt install git; git clone https://git.fhi.mpg.de/mike/linuxsetup
# cd ~/linuxsetup; ./setup.ssh
relogin as root
# cd ~/linuxsetup; ./setup.debian1x
# cd ~/linuxsetup; ./telemetry.setup
-------------------- Ubuntu 18/20/22 --------------------
# sudo passwd root
# su -
# git clone https://git.fhi.mpg.de/mike/linuxsetup
# cd ~/linuxsetup; ./setup.ssh
relogin as root
# cd ~/linuxsetup; ./setup.ubuntu2x
# cd ~/linuxsetup; ./telemetry.setup
-------------------- restic backup --------------------
decrypt restic conf (password: quo...):
# openssl enc -a -d -aes-256-cbc -salt -pbkdf2 -iter 1000000 -in restic.config.enc
# ./restic.setup
# rt backup
check crontab
-------------------- mariadb --------------------
# apt install mariadb-server
MariaDB> ALTER USER root@localhost IDENTIFIED VIA mysql_native_password USING PASSWORD("eizohphu");
# mybackup -a
# myuser <NAME>
-------------------- go --------------------
# wget https://go.dev/dl/go1.25.4.linux-arm64.tar.gz
# rm -rf /db/go && tar -C /db -xzf go1.25.4.linux-arm64.tar.gz
export PATH=/db/go/bin:$PATH
export CGO_ENABLED=0
Executable
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/perl
######################################################################################## extra setup (mwx'2025)
use Config;
$HOME=$ENV{"HOME"};
if ($Config{archname}=~/^darwin/) {
if ($Config{myuname}=~/arm64/) {
system("brew install eza");
}
} else {
system("./upd https://github.com/eza-community/eza -i /db/bin")
}
system("mkdir -p $HOME/.config");
system("cp -r extra/config/eza $HOME/.config");
system("./upd https://github.com/sxyazi/yazi -i /db/bin")
system("mkdir -p $HOME/.config");
system("cp -r extra/config/yazi $HOME/.config");
system("curl -s https://ohmyposh.dev/install.sh | bash -s -- -d /db/bin");
system("mkdir -p /db/etc");
system("cp extra/omp.json /db/etc/");
system("git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf");
system("~/.fzf/install");
system("cp -r extra/zshrc $HOME/.zshrc");
########################################################################################################### END
+218
View File
@@ -0,0 +1,218 @@
#? Config file for btop v. 1.4.0
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
color_theme = "Default"
#* If the theme set background should be shown, set to False if you want terminal background transparency.
theme_background = False
#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false.
truecolor = True
#* Set to true to force tty mode regardless if a real tty has been detected or not.
#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols.
force_tty = False
#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets.
#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box.
#* Use whitespace " " as separator between different presets.
#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty"
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"
#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists.
#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift.
vim_keys = False
#* Rounded corners on boxes, is ignored if TTY mode is ON.
rounded_corners = True
#* Default symbols to use for graph creation, "braille", "block" or "tty".
#* "braille" offers the highest resolution but might not be included in all fonts.
#* "block" has half the resolution of braille but uses more common characters.
#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY.
#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view.
graph_symbol = "braille"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_cpu = "default"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_mem = "default"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_net = "default"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_proc = "default"
#* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace.
shown_boxes = "cpu mem net proc"
#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
update_ms = 500
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct",
#* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly.
proc_sorting = "cpu lazy"
#* Reverse sorting order, True or False.
proc_reversed = False
#* Show processes as a tree.
proc_tree = False
#* Use the cpu graph colors in the process list.
proc_colors = True
#* Use a darkening gradient in the process list.
proc_gradient = True
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
proc_per_core = True
#* Show process memory as bytes instead of percent.
proc_mem_bytes = True
#* Show cpu graph for each process.
proc_cpu_graphs = True
#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate)
proc_info_smaps = False
#* Show proc box on left side of screen instead of right.
proc_left = False
#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop).
proc_filter_kernel = False
#* In tree-view, always accumulate child process resources in the parent process.
proc_aggregate = False
#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available.
#* Select from a list of detected attributes from the options menu.
cpu_graph_upper = "Auto"
#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available.
#* Select from a list of detected attributes from the options menu.
cpu_graph_lower = "Auto"
#* Toggles if the lower CPU graph should be inverted.
cpu_invert_lower = True
#* Set to True to completely disable the lower CPU graph.
cpu_single_graph = False
#* Show cpu box at bottom of screen instead of top.
cpu_bottom = False
#* Shows the system uptime in the CPU box.
show_uptime = True
#* Show cpu temperature.
check_temp = True
#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors.
cpu_sensor = "Auto"
#* Show temperatures for cpu cores also if check_temp is True and sensors has been found.
show_coretemp = True
#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core.
#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine.
#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries.
#* Example: "4:0 5:1 6:3"
cpu_core_map = ""
#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine".
temp_scale = "celsius"
#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024.
base_10_sizes = False
#* Show CPU frequency.
show_cpu_freq = True
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
#* Special formatting: /host = hostname | /user = username | /uptime = system uptime
clock_format = "%X"
#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort.
background_update = True
#* Custom cpu model name, empty string to disable.
custom_cpu_name = ""
#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ".
#* Begin line with "exclude=" to change to exclude filter, otherwise defaults to "most include" filter. Example: disks_filter="exclude=/boot /home/user".
disks_filter = ""
#* Show graphs instead of meters for memory values.
mem_graphs = True
#* Show mem box below net box instead of above.
mem_below_net = False
#* Count ZFS ARC in cached and available memory.
zfs_arc_cached = True
#* If swap memory should be shown in memory box.
show_swap = True
#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk.
swap_disk = True
#* If mem box should be split to also show disks info.
show_disks = True
#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar.
only_physical = True
#* Read disks list from /etc/fstab. This also disables only_physical.
use_fstab = True
#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool)
zfs_hide_datasets = False
#* Set to true to show available disk space for privileged users.
disk_free_priv = False
#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view.
show_io_stat = True
#* Toggles io mode for disks, showing big graphs for disk read/write speeds.
io_mode = False
#* Set to True to show combined read/write io graphs in io mode.
io_graph_combined = False
#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ".
#* Example: "/mnt/media:100 /:20 /boot:1".
io_graph_speeds = ""
#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False.
net_download = 100
net_upload = 100
#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
net_auto = False
#* Sync the auto scaling for download and upload to whichever currently has the highest scale.
net_sync = False
#* Starts with the Network Interface specified here.
net_iface = ""
#* Show battery stats in top right if battery is present.
show_battery = True
#* Which battery to use if multiple are present. "Auto" for auto detection.
selected_battery = "Auto"
#* Show power stats of battery next to charge indicator.
show_battery_watts = True
#* Set loglevel for "~/.config/btop/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG".
#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info.
log_level = "WARNING"
+123
View File
@@ -0,0 +1,123 @@
# eza theme — Palette aus coltest.go
#
# white #F0F0EA pink #F5B2F7
# yellow #F9E2AF violet #CBA6F7
# orange #FAB387 grey #AAAABB
# red #F38BA8 dark #777788
# green #94E2D5 darker #444455
# blue #B4BEFE
#
# Ort: ~/.config/eza/theme.yml (oder $EZA_CONFIG_DIR/theme.yml)
# Getestet mit eza 0.23.5.
colourful: true
filekinds:
normal: {foreground: "#F0F0EA"} # white
directory: {foreground: "#B4BEFE", is_bold: true} # blue
symlink: {foreground: "#F5B2F7", is_underline: false} # pink
pipe: {foreground: "#CBA6F7"} # violet
block_device: {foreground: "#FAB387"} # orange
char_device: {foreground: "#F9E2AF"} # yellow
socket: {foreground: "#F5B2F7", is_bold: true} # pink
special: {foreground: "#CBA6F7"} # violet
executable: {foreground: "#94E2D5", is_bold: true} # green
mount_point: {foreground: "#B4BEFE", is_underline: false}
perms:
user_read: {foreground: "#94E2D5"} # green
user_write: {foreground: "#F9E2AF"} # yellow
user_execute_file: {foreground: "#F38BA8", is_underline: false} # red
user_execute_other: {foreground: "#F38BA8", is_underline: false} # red
group_read: {foreground: "#94E2D5"}
group_write: {foreground: "#F9E2AF"}
group_execute: {foreground: "#F38BA8", is_underline: false}
other_read: {foreground: "#94E2D5"}
other_write: {foreground: "#F9E2AF"}
other_execute: {foreground: "#F38BA8", is_underline: false}
special_user_file: {foreground: "#F5B2F7", is_underline: false} # pink — setuid
special_other: {foreground: "#F5B2F7", is_underline: false} # pink
attribute: {foreground: "#777788"} # dark — @ / xattr
size:
number_byte: {foreground: "#94E2D5"} # green
number_kilo: {foreground: "#94E2D5"}
number_mega: {foreground: "#F9E2AF"} # yellow
number_giga: {foreground: "#FAB387"} # orange
number_huge: {foreground: "#F38BA8"} # red
unit_byte: {foreground: "#94E2D5"}
unit_kilo: {foreground: "#94E2D5"}
unit_mega: {foreground: "#F9E2AF"}
unit_giga: {foreground: "#FAB387"}
unit_huge: {foreground: "#F38BA8"}
major: {foreground: "#CBA6F7"} # violet — Device-Nummern
minor: {foreground: "#F5B2F7"} # pink
users:
user_you: {foreground: "#F0F0EA"} # white
user_root: {foreground: "#F38BA8"} # red
user_other: {foreground: "#AAAABB"} # grey
group_yours: {foreground: "#AAAABB"} # grey
group_other: {foreground: "#777788"} # dark
group_root: {foreground: "#F38BA8"} # red
links:
normal: {foreground: "#F5B2F7"} # pink
multi_link_file: {foreground: "#CBA6F7"} # violet
git:
new: {foreground: "#94E2D5"} # green
modified: {foreground: "#F9E2AF"} # yellow
deleted: {foreground: "#F38BA8"} # red
renamed: {foreground: "#CBA6F7"} # violet
typechange: {foreground: "#FAB387"} # orange
ignored: {foreground: "#444455"} # darker
conflicted: {foreground: "#F5B2F7"} # pink
git_repo:
branch_main: {foreground: "#94E2D5"} # green
branch_other: {foreground: "#CBA6F7"} # violet
git_clean: {foreground: "#94E2D5"} # green
git_dirty: {foreground: "#F9E2AF"} # yellow
security_context:
none: {foreground: "#777788"} # dark
selinux:
colon: {foreground: "#444455"}
user: {foreground: "#B4BEFE"}
role: {foreground: "#CBA6F7"}
typ: {foreground: "#F5B2F7"}
range: {foreground: "#F9E2AF"}
file_type:
image: {foreground: "#CBA6F7"} # violet
video: {foreground: "#F5B2F7"} # pink
music: {foreground: "#94E2D5"} # green
lossless: {foreground: "#94E2D5"} # green
crypto: {foreground: "#F38BA8"} # red
document: {foreground: "#F0F0EA"} # white
compressed: {foreground: "#FAB387"} # orange
temp: {foreground: "#444455"} # darker
compiled: {foreground: "#AAAABB"} # grey
build: {foreground: "#F9E2AF", is_underline: false} # yellow — README, Makefile, …
source: {foreground: "#B4BEFE"} # blue
punctuation: {foreground: "#444455"} # darker — die - in rwx
date: {foreground: "#B4BEFE"} # blue
inode: {foreground: "#F5B2F7"} # pink
blocks: {foreground: "#777788"} # dark
header: {foreground: "#AAAABB", is_underline: false} # grey
octal: {foreground: "#777788"} # dark
flags: {foreground: "#FAB387"} # orange
symlink_path: {foreground: "#CBA6F7", is_underline: false} # violet
control_char: {foreground: "#F38BA8"} # red
broken_symlink: {foreground: "#F38BA8", is_underline: false} # red
broken_path_overlay: {foreground: "#F38BA8", is_underline: false}
# Eigene Regeln pro Dateiname / Endung — das, was lsd nicht kann:
#
# filenames:
# Makefile: {filename: {foreground: "#F38BA8", is_bold: true}}
# extensions:
# go: {filename: {foreground: "#94E2D5"}}
# md: {filename: {foreground: "#B4BEFE"}}
+39
View File
@@ -0,0 +1,39 @@
user: 230
group: 187
permission:
read: green
write: yellow
exec: red
exec-sticky: 5
no-access: 245
octal: 6
acl: dark_cyan
context: cyan
date:
hour-old: 159
day-old: 158
older: 157
size:
none: 245
small: 229
medium: 216
large: 172
inode:
valid: 219
invalid: 245
links:
valid: 13
invalid: 245
tree-edge: 245
git-status:
default: 245
unmodified: 245
ignored: 245
new-in-index: green
new-in-workdir: green
typechange: yellow
deleted: red
renamed: green
modified: yellow
conflicted: red
+150
View File
@@ -0,0 +1,150 @@
# == Classic ==
# This is a shorthand to override some of the options to be backwards compatible
# with `ls`. It affects the "color"->"when", "sorting"->"dir-grouping", "date"
# and "icons"->"when" options.
# Possible values: false, true
classic: false
# == Blocks ==
# This specifies the columns and their order when using the long and the tree
# layout.
# Possible values: permission, user, group, context, size, date, name, inode, links, git
blocks:
- permission
- user
- date
- size
- git
- name
# == Color ==
# This has various color options. (Will be expanded in the future.)
color:
# When to colorize the output.
# When "classic" is set, this is set to "never".
# Possible values: never, auto, always
when: auto
# How to colorize the output.
# When "classic" is set, this is set to "no-color".
# Possible values: default, custom
# When "custom" is set, lsd will look in the config directory for `colors.yaml`.
theme: custom
# == Date ==
# This specifies the date format for the date column. The freeform format
# accepts a strftime like string.
# When "classic" is set, this is set to "date".
# Possible values: date, locale, relative, '+<date_format>'
# `date_format` will be a `strftime` formatted value. e.g. `date: '+%d %b %y %X'` will give you a date like this: 17 Jun 21 20:14:55
date: date
# == Dereference ==
# Whether to dereference symbolic links.
# Possible values: false, true
dereference: false
# == Display ==
# What items to display. Do not specify this for the default behavior.
# Possible values: all, almost-all, directory-only
# display: all
# == Icons ==
icons:
# When to use icons.
# When "classic" is set, this is set to "never".
# Possible values: always, auto, never
when: auto
# Which icon theme to use.
# Possible values: fancy, unicode
theme: fancy
# Separator between icon and the name
# Default to 1 space
separator: " "
# == Ignore Globs ==
# A list of globs to ignore when listing.
# ignore-globs:
# - .git
# == Indicators ==
# Whether to add indicator characters to certain listed files.
# Possible values: false, true
indicators: false
# == Layout ==
# Which layout to use. "oneline" might be a bit confusing here and should be
# called "one-per-line". It might be changed in the future.
# Possible values: grid, tree, oneline
layout: grid
# == Recursion ==
recursion:
# Whether to enable recursion.
# Possible values: false, true
enabled: false
# How deep the recursion should go. This has to be a positive integer. Leave
# it unspecified for (virtually) infinite.
# depth: 3
# == Size ==
# Specifies the format of the size column.
# Possible values: default, short, bytes
size: default
# == Permission ==
# Specify the format of the permission column
# Possible value: rwx, octal, attributes (windows only), disable
# permission: octal
# == Sorting ==
sorting:
# Specify what to sort by.
# Possible values: extension, name, time, size, version
column: name
# Whether to reverse the sorting.
# Possible values: false, true
reverse: false
# Whether to group directories together and where.
# When "classic" is set, this is set to "none".
# Possible values: first, last, none
dir-grouping: none
# == No Symlink ==
# Whether to omit showing symlink targets
# Possible values: false, true
no-symlink: false
# == Total size ==
# Whether to display the total size of directories.
# Possible values: false, true
total-size: false
# == Hyperlink ==
# Attach hyperlink to filenames
# Possible values: always, auto, never
hyperlink: never
# == Symlink arrow ==
# Specifies how the symlink arrow display, chars in both ascii and utf8
symlink-arrow: ⇒
# == Header ==
# Whether to display block headers.
# Possible values: false, true
header: false
# == Literal ==
# Whether to show quotes on filenames.
# Possible values: false, true
literal: false
# == Truncate owner ==
# How to truncate the username and group names for a file if they exceed a certain
# number of characters.
truncate-owner:
# Number of characters to keep. By default, no truncation is done (empty value).
after:
# String to be appended to a name if truncated.
marker: ""
@@ -0,0 +1,185 @@
# yazi flavor "mwx" — Palette aus coltest.go
#
# white #F0F0EA pink #F5B2F7
# yellow #F9E2AF violet #CBA6F7
# orange #FAB387 grey #AAAABB
# red #F38BA8 dark #777788
# green #94E2D5 darker #444455
# blue #B4BEFE
#
# Schema: yazi 26.2.2 — [mgr] (früher [manager]), [tabs] (früher tab_* in
# [manager]), [cmp] (früher [completion]), [indicator] (früher hovered/
# preview_hovered). Alte Sektionsnamen werden von yazi still ignoriert.
[mgr]
cwd = { fg = "#94E2D5" }
# Find
find_keyword = { fg = "#F9E2AF", bold = true, italic = true }
find_position = { fg = "#F5B2F7", bg = "reset", bold = true, italic = true }
# Symlink-Ziel
symlink_target = { fg = "#777788" }
# Marker
marker_copied = { fg = "#94E2D5", bg = "#94E2D5" }
marker_cut = { fg = "#F38BA8", bg = "#F38BA8" }
marker_marked = { fg = "#CBA6F7", bg = "#CBA6F7" }
marker_selected = { fg = "#FAB387", bg = "#FAB387" }
# Count
count_copied = { fg = "#444455", bg = "#94E2D5" }
count_cut = { fg = "#444455", bg = "#F38BA8" }
count_selected = { fg = "#444455", bg = "#FAB387" }
# Border
border_symbol = "│"
border_style = { fg = "#B4BEFE" }
[indicator]
# current = die ganze Cursor-Zeile (ersetzt das alte "hovered")
parent = { fg = "#F0F0EA", bg = "#444455" }
current = { fg = "#444455", bg = "#B4BEFE", bold = true }
preview = { fg = "#AAAABB", bg = "#444455" }
[tabs]
active = { fg = "#444455", bg = "#B4BEFE", bold = true }
inactive = { fg = "#B4BEFE", bg = "#444455" }
[mode]
normal_main = { fg = "#444455", bg = "#B4BEFE", bold = true }
normal_alt = { fg = "#B4BEFE", bg = "#444455" }
# Select mode
select_main = { fg = "#444455", bg = "#94E2D5", bold = true }
select_alt = { fg = "#94E2D5", bg = "#444455" }
# Unset mode
unset_main = { fg = "#444455", bg = "#AAAABB", bold = true }
unset_alt = { fg = "#AAAABB", bg = "#444455" }
[status]
# Permissions — wie in lsd/eza: read grün, write gelb, exec rot
perm_sep = { fg = "#777788" }
perm_type = { fg = "#B4BEFE" }
perm_read = { fg = "#94E2D5" }
perm_write = { fg = "#F9E2AF" }
perm_exec = { fg = "#F38BA8" }
# Progress
progress_label = { fg = "#F0F0EA", bold = true }
progress_normal = { fg = "#B4BEFE", bg = "#444455" }
progress_error = { fg = "#F38BA8", bg = "#444455" }
[pick]
border = { fg = "#B4BEFE" }
active = { fg = "#F5B2F7", bold = true }
inactive = {}
[input]
border = { fg = "#B4BEFE" }
title = {}
value = {}
selected = { reversed = true }
[cmp]
border = { fg = "#B4BEFE" }
[tasks]
border = { fg = "#B4BEFE" }
title = {}
hovered = { fg = "#F5B2F7", bold = true }
[which]
mask = { bg = "#444455" }
cand = { fg = "#94E2D5" }
rest = { fg = "#777788" }
desc = { fg = "#F5B2F7" }
separator = " "
separator_style = { fg = "#777788" }
[help]
on = { fg = "#94E2D5" }
run = { fg = "#F5B2F7" }
hovered = { reversed = true, bold = true }
footer = { fg = "#444455", bg = "#F0F0EA" }
[spot]
border = { fg = "#B4BEFE" }
title = { fg = "#B4BEFE" }
tbl_col = { fg = "#94E2D5" }
tbl_cell = { fg = "#F5B2F7", bg = "#444455" }
[notify]
title_info = { fg = "#94E2D5" }
title_warn = { fg = "#F9E2AF" }
title_error = { fg = "#F38BA8" }
[filetype]
rules = [
# Bilder
{ mime = "image/*", fg = "#FAB387" },
# Audio / Video
{ mime = "{audio,video}/*", fg = "#FAB387" },
# Archive
{ mime = "application/{zip,rar,7z*,tar,gzip}", fg = "#F9E2AF" },
{ mime = "application/{xz,zstd,bzip*,lzma,compress}", fg = "#F9E2AF" },
{ mime = "application/{archive,cpio,arj,xar,ms-cab*}", fg = "#F9E2AF" },
# Kaputte Links
{ url = "*", is = "orphan", fg = "#777788", crossed = true },
# Symlinks
{ url = "*", is = "link", fg = "#F5B2F7" },
{ url = "*/", is = "link", fg = "#CBA6F7" },
# Ausführbar
{ url = "*", is = "exec", fg = "#F38BA8" },
# Sprachen
{ url = "*.{c,c++,cake,cats,cc,cl,cp,cpp,cs}", fg = "#94E2D5" },
{ url = "*.{cshtml,css,csx,cxx,emacs,go}", fg = "#94E2D5" },
{ url = "*.{h,h++,hh,hpp,hs,hxx,idc,inl,ipp,ipynb}", fg = "#94E2D5" },
{ url = "*.{java,jl,js,json}", fg = "#94E2D5" },
{ url = "*.{ksh,l,lisp,lsp,lua,m}", fg = "#94E2D5" },
{ url = "*.{php,pl,ps1,py,ron}", fg = "#94E2D5" },
{ url = "*.{sass,sh,tcc,tpp}", fg = "#94E2D5" },
{ url = "*.{vbs,w,}", fg = "#94E2D5" },
{ url = "*.{sh,bash,zsh,fish}", fg = "#94E2D5" },
{ url = "*.{el,elc}", fg = "#94E2D5" },
# Config / Patches
{ url = "*.{cfg,conf,yaml,yml,toml,inc}", fg = "#F9E2AF" },
{ url = "*.{diff,patch,matlab,ron}", fg = "#F9E2AF" },
# Markup
{ url = "*.{jinja,markdown,md,mkd,mkdn,mkdown,tex}", fg = "#B4BEFE" },
{ url = "*.{htm,html,xhtml,xml}", fg = "#B4BEFE" },
{ url = "*.{org}", fg = "#CBA6F7" },
# Dokumente
{ url = "*.{pdf,txt,rtf}", fg = "#AAAABB" },
{ url = "*.{doc,docx,xls,xlsx,ppt,pptx}", fg = "#AAAABB" },
# Virtuelles Dateisystem
{ mime = "vfs/{absent,stale}", fg = "#777788" },
# Fallback
{ url = "*", fg = "#F0F0EA" },
{ url = "*/", fg = "#B4BEFE" },
]
@@ -0,0 +1,159 @@
[manager]
cwd = { fg = "#00d1e9" }
# Hovered
hovered = { fg = "#ffffff", bg = "#66ccff" }
preview_hovered = { underline = true }
# Find
find_keyword = { fg = "#ffde57", bold = true, italic = true, underline = true }
find_position = { fg = "#e45c9c", bg = "reset", bold = true, italic = true }
# Marker
marker_copied = { fg = "#6ae073", bg = "#6ae073" }
marker_cut = { fg = "#ff6e64", bg = "#ff6e64" }
marker_marked = { fg = "#00d1e9", bg = "#00d1e9" }
marker_selected = { fg = "#ffde57", bg = "#ffde57" }
# Tab
tab_active = { reversed = true }
tab_inactive = {}
tab_width = 1
# Count
count_copied = { fg = "#222327", bg = "#6ae073" }
count_cut = { fg = "#222327", bg = "#ff6e64" }
count_selected = { fg = "#222327", bg = "#ffde57" }
# Border
border_symbol = "│"
border_style = { fg = "#66ccff" }
[mode]
normal_main = { fg = "#222327", bg = "#66ccff", bold = true }
normal_alt = { fg = "#66ccff", bg = "#393939" }
# Select mode
select_main = { fg = "#222327", bg = "#6ae073", bold = true }
select_alt = { fg = "#6ae073", bg = "#393939" }
# Unset mode
unset_main = { fg = "#222327", bg = "#f2cdcd", bold = true }
unset_alt = { fg = "#f2cdcd", bg = "#393939" }
[status]
separator_open = ""
separator_close = ""
# Progress
progress_label = { fg = "#ffffff", bold = true }
progress_normal = { fg = "#66ccff", bg = "#45475a" }
progress_error = { fg = "#ff6e64", bg = "#45475a" }
# Permissions
perm_sep = { fg = "#8c8c8c" }
perm_type = { fg = "#66ccff" }
perm_read = { fg = "#ffde57" }
perm_write = { fg = "#ff6e64" }
perm_exec = { fg = "#6ae073" }
[pick]
border = { fg = "#66ccff" }
active = { fg = "#e45c9c", bold = true }
inactive = {}
[input]
border = { fg = "#0000ff" }
title = {}
value = {}
selected = { reversed = true }
[completion]
border = { fg = "#66ccff" }
[tasks]
border = { fg = "#66ccff" }
title = {}
hovered = { fg = "#e45c9c", underline = true }
[which]
mask = { bg = "#393939" }
cand = { fg = "#00d1e9" }
rest = { fg = "#8c8c8c" }
desc = { fg = "#e45c9c" }
separator = "  "
separator_style = { fg = "#585b70" }
[help]
on = { fg = "#00d1e9" }
run = { fg = "#e45c9c" }
hovered = { reversed = true, bold = true }
footer = { fg = "#393939", bg = "#eaead7" }
[notify]
title_info = { fg = "#6ae073" }
title_warn = { fg = "#ffde57" }
title_error = { fg = "#ff6e64" }
[filetype]
rules = [
# Images
{ mime = "image/*", fg = "#ffb350" },
# Media
{ mime = "{audio,video}/*", fg = "#ffb350" },
# Archives
{ mime = "application/{zip,rar,7z*,tar,gzip}", fg = "#ffde57" },
{ mime = "application/{xz,zstd,bzip*,lzma,compress}", fg = "#ffde57" },
{ mime = "application/{archive,cpio,arj,xar,ms-cab*}", fg = "#ffde57" },
# Broken links
{ name = "*", is = "orphan", fg = "#8c8c8c", crossed = true },
# Symlinks files
{ name = "*", is = "link", fg = "#e45c9c" },
{ name = "*/", is = "link", fg = "#66ffcc" },
# Executables
{ name = "*", is = "exec", fg = "#ff6e64" },
# Languages
{ name = "*.{c,c++,cake,cats,cc,cl,cp,cpp,cs}", fg = "#6ae073" },
{ name = "*.{cshtml,css,csx,cxx,emacs,go}", fg = "#6ae073" },
{ name = "*.{h,h++,hh,hpp,hs,hxx,idc,inl,ipp,ipynb}", fg = "#6ae073" },
{ name = "*.{java,jl,js,json}", fg = "#6ae073" },
{ name = "*.{ksh,l,lisp,lsp,lua,m}", fg = "#6ae073" },
{ name = "*.{php,pl,ps1,py,ron}", fg = "#6ae073" },
{ name = "*.{sass,sh,tcc,tpp}", fg = "#6ae073" },
{ name = "*.{vbs,w,}", fg = "#6ae073" },
{ name = "*.{sh,bash,zsh,fish}", fg = "#6ae073" },
{ name = "*.{cfg,conf,yaml,yml,toml,inc}", fg = "#ffde57" },
{ name = "*.{diff,patch,matlab,ron}", fg = "#ffde57" },
{ name = "*.{jinja,markdown,md,mkd,mkdn,mkdown,tex}", fg = "#00d1e9" },
{ name = "*.{htm,html,xhtml,xml}", fg = "#00d1e9" },
# Emacs
{ name = "*.{el,elc}", fg = "#6ae073" },
{ name = "*.{org}", fg = "#cd7bf6" },
# Documents
{ name = "*.{pdf,txt,rtf}", fg = "#9999ff" },
{ name = "*.{pdf,doc,docx,xls,xlsx,ppt,pptx}", fg = "#9999ff" },
# Fallback
{ name = "*", fg = "#eaead7" },
{ name = "*/", fg = "#66ccff" }
]
+4
View File
@@ -0,0 +1,4 @@
[[manager.prepend_keymap]]
on = "t"
run = "plugin max-preview"
desc = "Maximize or restore preview"
+5
View File
@@ -0,0 +1,5 @@
[plugin]
deps = []
[flavor]
deps = []
+2
View File
@@ -0,0 +1,2 @@
[flavor]
dark = "mwx"
+3
View File
@@ -0,0 +1,3 @@
[mgr]
# [parent, current, preview] — Default ist [1, 4, 3]
ratio = [1, 1, 3]
+133
View File
@@ -0,0 +1,133 @@
{
"palette": {
"white": "#F0F0EA",
"yellow": "#F9E2AF",
"orange": "#FAB387",
"red": "#F38BA8",
"green": "#94E2D5",
"blue": "#B4BEFE",
"pink": "#F5B2F7",
"violet": "#CBA6F7",
"grey": "#AAAABB",
"dark": "#777788",
"darker": "#444455"
},
"var": {
"sep": "<#ffffff>・</>"
},
"blocks": [
{
"alignment": "left",
"newline": false,
"segments": [
{
"foreground_templates": ["{{if .SSHSession }}p:violet{{else}}p:green{{ end }}"],
"style": "diamond",
"template": "<b>{{.HostName}}</b>{{.Var.sep}}{{.OS}}{{.Var.sep}}{{.Shell}}",
"type": "session"
},{
"foreground": "p:orange",
"style": "diamond",
"template": "{{.Var.sep}}{{.SHLVL}}/{{.PromptCount}}",
"type": "session"
},
{
"foreground_templates": ["{{if .Root }}p:red{{else}}p:green{{ end }}"],
"leading_diamond": "",
"style": "diamond",
"template": "{{.Var.sep}}{{.UserName}}",
"type": "session"
},
{
"foreground": "p:green",
"foreground_templates": ["{{ if gt .Code 0 }}p:red{{ end }}"],
"leading_diamond": "",
"style": "diamond",
"template": "{{.Var.sep}}{{.Code}}",
"type": "session"
},
{
"foreground": "p:yellow",
"properties": {
"branch_icon": "",
"fetch_stash_count": true,
"fetch_status": true,
"fetch_upstream_icon": true,
"fetch_worktree_count": true
},
"style": "diamond",
"template": "{{.Var.sep}}{{ .HEAD }} {{ .StashCount }}",
"trailing_diamond": "",
"type": "git"
},
{
"type": "go",
"style": "plain",
"foreground": "p:blue",
"template": "{{.Var.sep}}GO {{ .Full }} "
}
],
"type": "prompt"
},
{
"alignment": "right",
"segments": [
{
"foreground": "p:blue",
"properties": {
"time_format": "Mon, 15:04"
},
"style": "diamond",
"template": "{{ .CurrentDate | date .Format }}{{.Var.sep}}",
"type": "time"
},
{
"foreground": "#94ffa2",
"style": "diamond",
"template": "{{ round .PhysicalPercentUsed .Precision }}%{{.Var.sep}}{{ round .Load15 .Precision }}",
"properties": {
"precision": 1
},
"type": "sysinfo"
},
{
"type": "battery",
"style": "plain",
"foreground": "#FFFFFF",
"background": "",
"foreground_templates": [
"{{ if lt .Percentage 20 }}p:red{{ end }}",
"{{ if lt .Percentage 50 }}p:yellow{{ end }}",
"p:blue"
],
"template": "{{if not .Error}}{{.Var.sep}}{{.Percentage}}%{{end}} "
}
],
"type": "prompt"
},
{
"alignment": "left",
"newline": true,
"segments": [
{
"properties": {
"always_enabled": true
},
"style": "plain",
"template": "{{.PWD}} <#66ffcc><b>></b>{{if .Root }}<b>></b>{{end}}</> ",
"type": "status"
}
],
"type": "prompt"
}
],
"console_title_template": "{{.UserName}}@{{.HostName}} {{.Shell}} in {{.PWD}}",
"transient_prompt": {
"background": "transparent",
"template": "<#cc99ff><b>></b></> "
},
"version": 3
}
+27
View File
@@ -0,0 +1,27 @@
alias tsc='timeshift --yes --create --comments'
alias tsr='timeshift --yes --restore'
alias tsd='timeshift --yes --delete'
alias tsl='timeshift --list'
eval "$(oh-my-posh init zsh --config /db/etc/omp.json )"
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
alias y yazi
alias f fzf
alias ll='eza --icons auto -la'
alias ls='eza --icons auto -a'
alias lt='eza --icons auto -la -s changed'
alias lx='eza --icons auto --tree -la'
export FZF_DEFAULT_OPTS=$FZF_DEFAULT_OPTS'
--color=fg:#AAAABB,bg:#252528,hl:#F5B2F7
--color=fg+:#F0F0EA,bg+:#444455,hl+:#F5B2F7
--color=info:#94E2D5,prompt:#F38BA8,pointer:#CBA6F7
--color=marker:#94E2D5,spinner:#CBA6F7,header:#AAAABB
--color=query:#F0F0EA,disabled:#777788,gutter:#252528
--color=border:#444455,separator:#444455,scrollbar:#777788
--color=label:#AAAABB,preview-fg:#F0F0EA,preview-bg:#252528'
+3
View File
@@ -0,0 +1,3 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9kb7R4qAqRdPw90zxM9dg68bnskdgqAZLSaogAKSpcvsmVNDgz5XKAr22hg25VrhJdE4S8ptvAyDT3n18yYmqv0Bht7t/uHWUd+pzJHy5d763nII7ukQtKBZdLaLEqSGD1XkyOTj21MZiiCaNurU6pqbcx3mlfVGtH0SdBCs8Nz6tYVUC/jCn202LM5tmHakLgYBvU4QPb6nfNMGKvNVjxUCs1Vn+knPsUtiIi6ktkz8LHRSx8Qd9vlTLMccsnSm/FfaepVPLslQ2rA7fpixhWIH/sJizcTubB1ErA8BhDM7exD+UEfmN7CKvarFZxDf3WgckonIGuoS81wT+cZDT m
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCoqI8A+SES/kWp6ZqJ6agbk8lz7UhOIZZrSF1cnuv+9bCq2QtO5qkAalJSr5hNZXsEZl9OfQibcFk7GUWTaEHCg/vdTxfMUdWDQDkOyPNPQD2JRZ3NpcdtkteSEfYzPwyXFV3HSoQys6VQAib9SeMyDtTgFPN+xm2lQtVzGiFg73ny5Lq1PsaS40+6EwGZmMIfUQLVm5OjislDW1p+F1PyYUeM9wiK/KbJl99Pd5CECXN9uunAEOz/siDwpo1TXZ6od6ZKMCGDT3v742cc28HpHxK/GQ9ezXlaTZ4BldTtkoupK6KwxOZ8x/eyiGq00E/YdjtxhLi6ggmjlBk2Gk33 root@data
+49
View File
@@ -0,0 +1,49 @@
unsetenv LANG
setenv HN `hostname`
set prompt="%n@${HN}:%~ > "
if ( $USER == root ) then
set prompt="%n@${HN}:%~ >> "
endif
set history=128
set savehist=128
set watch=( any any )
set recexact
set autolist
set dunique
set matchbeep=nomatch
set pushdsilent
set fignore=( .o )
set echo_style=both
unset ignoreeof
unset mail
set notify
set time=( 1 " %E [%P] used." )
alias a 'alias'
alias h 'history'
alias L 'last -16'
alias ls 'ls -F'
alias ll 'ls -lsah'
alias lt 'ls -ltrah'
alias cd 'cd \!*;echo $cwd'
alias pwd 'echo $cwd'
alias s 'ssh'
alias sr 'ssh -l root'
alias rs 'rsync -va --delete --stats'
alias p 'ps -ef | grep ${LOGNAME}'
alias P 'ps -ef'
alias af 'apt-cache search'
alias ai 'apt-get install'
alias sd 'lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL'
alias ga 'git add -v .'
alias gb 'git branch'
alias gs 'git status'
alias gl "git log -32 --reverse --date=local --format='%h %cd %s'"
alias gc 'git commit -m'
alias go 'git checkout'
alias gp 'git push'
setenv PATH "$PATH":/db/bin
+83
View File
@@ -0,0 +1,83 @@
# joe theme — Palette aus mwxcol.go
#
# white #F0F0EA pink #F5B2F7
# yellow #F9E2AF violet #CBA6F7
# orange #FAB387 grey #AAAABB
# red #F38BA8 dark #777788
# green #94E2D5 darker #444455
# blue #B4BEFE
#
# Ort: ~/.joe/colors/default.jcf (verdeckt die System-Version)
# Getestet mit joe 4.6.
.colors *
.set white $F0F0EA
.set yellow $F9E2AF
.set orange $FAB387
.set red $F38BA8
.set green $94E2D5
.set blue $B4BEFE
.set pink $F5B2F7
.set violet $CBA6F7
.set grey $AAAABB
.set dark $777788
.set darker $444455
-text [white]
# --- Syntax -----------------------------------------------------------
=Bad [red]
=Preproc [orange]
=Define [orange]
=String [red]
=Comment [grey]
=IncLocal [green]
=IncSystem [green] bold
=Constant [red]
=Escape [green] bold
=Type [violet]
=Keyword [pink]
=Variable [green]
=Brace [white] bold
=Tag [blue] bold
=TagName +Tag
=Title bold
=TODO [yellow]
=BUG [yellow]
# --- UI ---------------------------------------------------------------
-status [white]/[darker]
-selection /[darker]
-linum [dark]
-curlinum [yellow] bold
-menu [white]/[darker]
-menusel [darker]/[blue]
# --- diff -------------------------------------------------------------
=diff.AddLine [green]
=diff.DelLine [red]
=diff.ChgLine [yellow]
=diff.Garbage [darker]
=diff.FileOld [red] bold
=diff.FileNew [green] bold
=diff.Hunk [violet] bold
# Identitäts-Mapping wie bisher: numerische Farben aus alten Syntax-Files
# greifen auf die 16 Farben des Terminals durch.
-term 0 0
-term 1 1
-term 2 2
-term 3 3
-term 4 4
-term 5 5
-term 6 6
-term 7 7
-term 8 8
-term 9 9
-term 10 10
-term 11 11
-term 12 12
-term 13 13
-term 14 14
-term 15 15
Executable
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/perl
######################################################################## count files and directories (mwx'2016)
use Getopt::Std;getopts('dnh');
$version='1.0.2';
if ($opt_h) {;&help;exit;}
if (-d $ARGV[0]) {
&dx($ARGV[0]);
} else {
&dx(".");
}
sub dx() {
my($dir)=@_;
$ml=length($dir);
opendir(DIR,$dir);
while($f=readdir(DIR)) {
if ($f ne '.' && $f ne '..') {
if (-d "$dir/$f") {
$n=0;$s=0;
open(IN,"find '$dir/$f' -type f |");
while(<IN>) {
chomp();
$s+=(stat($_))[7];
$ts+=(stat($_))[7];
$n++;
$tn++;
}
close(IN);
$N{"$f/"}=$n;
$S{"$f/"}=$s;
$ml=length($f) if (length($f)>$ml);
}
if (-f "$dir/$f" && !$opt_d) {
$S{$f}+=(stat("$dir/$f"))[7];
$ts+=(stat("$dir/$f"))[7];
$N{$f}++;
$tn++;
$ml=length($f) if (length($f)>$ml);
}
}
}
closedir(DIR);
$frm=sprintf "%%-%ds",$ml+1;
$out=sprintf "$frm %8d %8s\n",$dir,$tn,&formsize($ts);
if ($opt_n) {
for $f (sort { $N{$a} <=> $N{$b} } (keys(%N))) {
$out.=sprintf " $frm %8d %8s\n",$f,$N{$f},&formsize($S{$f});
}
} else {
for $f (sort { $S{$a} <=> $S{$b} } (keys(%S))) {
$out.=sprintf " $frm %8d %8s\n",$f,$N{$f},&formsize($S{$f});
}
}
print $out;
}
####################################################################################################### SUPPORT
sub formsize() {
my($b)=@_;
if ($b>1024*1024*1024*1024) {
$s=sprintf("%.0fT",$b/1024/1024/1024/1024)
} elsif ($b>1024*1024*1024) {
$s=sprintf("%.0fG",$b/1024/1024/1024)
} elsif ($b>1024*1024) {
$s=sprintf("%.0fM",$b/1024/1024)
} elsif ($b>1024) {
$s=sprintf("%.0fK",$b/1024)
} else {
$s=sprintf("%.0f",$b)
}
return $s;
}
sub help() {
print <<"ENDOFHELP";
dx ${version}, count files and directories, mwx'2016
usage: dx [-n] [-d] [path]
-n sort by number of files (default by size)
-d count only directories
-h this help
ENDOFHELP
}
########################################################################################################### END
Executable
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/perl
use Getopt::Std;getopts('x');
use Sys::Hostname qw(hostname);use Socket;
my($ip) = inet_ntoa( (gethostbyname(hostname()))[4] );
my($user)=getpwuid( $< );
if ($opt_x) {
$comment="[$ip,$user] " . join(' ',@ARGV);
} else {
$comment=join(' ',@ARGV);
}
$comment='-' if ($comment=~/^\s*$/);
$comment=~s/\s*$//;
system("git add -v .");
system("git commit -m '$comment'");
system("git push");
Executable
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/perl
$repo=$ARGV[0];
$repo=~s/\/\s*$//;
die if ($repo=~/^\s*$/);
$cgit='git://git.micw.org';
$pgit='ssh://git@git.micw.org:2234/home/git';
if (-d $repo) {
if (yesno('overwrite existing directory?',0)) {
&cmd("rm -rf $repo")
} else {
exit;
}
}
&cmd("git clone $cgit/$repo.git");
&cmd("cd $repo;git remote set-url origin $pgit/$repo.git");
sub cmd() {
my($cmd,$quiet)=@_;
print "$cmd\n" if (!$quiet);
system($cmd);
}
sub yesno {
my($prom,$def)=@_;
my($ans);
if ($def) {;$ans=&getkey("$prom Y/n ? ");}
else {;$ans=&getkey("$prom y/N ? ");}
if ($ans=~/^\s*$/) {
if ($def) {;return(1);}
else {;return(0);}
}
if ($ans=~/^\s*y\s*$/i || $ans=~/^\s*yes\s*$/i) {
return 1;
}
return 0;
}
sub getkey {
$|=1;
print "$_[0]";
system "stty", '-icanon', '-echo', 'eol', "\001";
$key = getc(STDIN);$key=~s/[\r\n\t]//g;
system "stty", 'icanon', 'echo', 'eol', "^@";
print "$key\n";
return $key;
}
Executable
+99
View File
@@ -0,0 +1,99 @@
-lmsg \i%k%T%W%I%X %n %m%y%R %x
-rmsg %S Row %r Col %c %p%% %u ^H help ^T menu
-nonotice
-noxon
-beep
-tab 2
-indentc 9
-nobackups
-pg 0
--autoindent
{Basic
^Y Save & Quit ^F Search/Replace ^A Begining of Line ^B Block Start
^S Save ^G Search Next ^E End of Line ^W Block Cut
^C Abort ^N Next Page ^U Begininig of File ^V Block Paste
^T Menu ^P Previous Page ^Q End of File ^H Help
^Q Undo ^K Delete Line ^L Goto Line
^R Redo ^D Delete Character mwx'2013 joerc v2.02
}
:main
type ^@ TO ÿ
rtn ^M
backs ^?
abort ^C
exsave ^Y
save ^S
undo ^Z
redo ^R
delch ^D
dellin ^K
help ^H
rtarw ^[ [ C
ltarw ^[ [ D
uparw ^[ [ A
dnarw ^[ [ B
pgdn ^N
pgup ^P
line ^L
ffirst ^F
fnext ^G
markb,msg,"Mark set",rtn ^B
markk,copy,blkdel,msg,"Block copy",rtn ^W
yank ^V
bol ^A
eol ^E
bof ^U
eof ^Q
menu,"root",rtn ^T
:prompt
:inherit main
:query
:inherit main
:querya
type ^@ TO ÿ
:querysr
:inherit main
:menu
:inherit main
abort ^Y
backsmenu ^?
bolmenu ^A
eolmenu ^E
rtarwmenu ^[ [ C
ltarwmenu ^[ [ D
uparwmenu ^[ [ A
dnarwmenu ^[ [ B
rtn ^M
:defmenu root
mode,"autoindent",rtn I Autoindent %Zautoindent%
mode,"overwrite",rtn T Overtype %Zoverwrite%
mode,"wordwrap",rtn W Word wrap %Zwordwrap%
mode,"hex",rtn % % Hex edit mode
mode,"tab",rtn D Tab width %Ztab%
mode,"crlf",rtn Z CR-LF (MS-DOS) %Zcrlf%
mode,"linums",rtn N Line numbers %Zlinums%
mode,"beep",rtn B Beep %Zbeep%
mode,"rdonly",rtn % % Read only %Zrdonly%
mode,"icase",rtn % % Search case %Zicase%
execmd C command
mode O option
Executable
+104
View File
@@ -0,0 +1,104 @@
-notite
-assume_color
-guess_non_utf8
-guess_utf16
-guess_crlf
-guess_indent
-menu_above
-transpose
-pastehack
-restore
-search_prompting
-nobackups
-nodeadjoe
-undo_keep 0
-noxon
-lmsg \i%k%T%W%I%X %n %m%y%R %x
-rmsg %S Row %r Col %c %p%% %u ^H help
-smsg ** Line %r Col %c Offset %o(0x%O) %e %a(0x%A) Width %w **
-zmsg ** Line %r Col %c Offset %o(0x%O) **
-highlight
-istep 2
-tab 2
:include ftyperc
{Basic
^Y Save & Quit ^F Search/Replace ^A Begining of Line ^B Block Start ^T^H Toggle Hex
^S Save ^G Search Next ^E End of Line ^W Block Cut ^T^O Overwrite Mode
^C Abort ^N Next Page ^U Begininig of File ^V Block Paste ^T^I Toggle Autoindent
^Z Undo ^P Previous Page ^Q End of File ^H Help ^T^T Set Tab Width
^R Redo ^K Delete Line ^L Goto Line ^T^C Execute Command
^D Delete Character mwx'2017 joerc v4.x.x
}
:windows Bindings common to all windows
type U+0 TO U+10FFFF
rtn ^M
backs ^?
abort ^C
exsave ^Y
save ^S
undo ^Z
redo ^R
delch ^D
dellin ^K
help ^H
rtarw ^[ [ C
ltarw ^[ [ D
uparw ^[ [ A
dnarw ^[ [ B
pgdn ^N
pgup ^P
line ^L
ffirst ^F
fnext ^G
markb,msg,"Mark set",rtn ^B
markk,copy,blkdel,msg,"Block copy",rtn ^W
yank ^V
bol ^A
eol ^E
bof ^U
eof ^Q
mode,"hex",rtn ^T ^H
mode,"overwrite",rtn ^T ^O
mode,"tab",rtn ^T ^T
mode,"autoindent",rtn ^T ^I
execmd ^T ^C
:main Text editing window
:inherit windows
:prompt
:inherit main
:menu
:inherit windows
:query
:inherit windows
:querya
type U+0 TO U+10FFFF
:querysr
type U+0 TO U+10FFFF
:shell Input to shell windows
:inherit main
:vtshell Input to ANSI shell windows
:inherit main
+1
View File
@@ -0,0 +1 @@
LANG="C.UTF-8"
Executable
+573
View File
@@ -0,0 +1,573 @@
#!/usr/bin/perl
############################################################################################# mbackup (mwx'2023)
$VERSION='3.2.0';
use Getopt::Std;getopts('vVDWMYhsfc:');$opt_v=1 if ($opt_V);
use Net::Ping;
use Fcntl ':flock';
chomp($HOST=`hostname`);
&help if($opt_h);
$NOW=time();
my(@z)=localtime($NOW);$z[4]+=1;$z[5]-=100;$z[6]+=1;
$z=sprintf("%02d.%02d-%02d:%02d",$z[3],$z[4],$z[5],$z[2],$z[1]);
$MAX{'daily'}=7; # default values
$MAX{'weekly'}=4;
$MAX{'monthly'}=12;
$MAX{'yearly'}=3;
$FLAT=0;
$RSYNCOPTS='--no-o --no-g --chmod=ugo=rwX';
$RSYNCRETRIES=3;
$CONFIG='';$REQUESTCONFIG=$ARGV[0]; # load configuration
for ($opt_c,"/db/etc/mbackup.conf",$ENV{'HOME'}."/etc/mbackup.conf",$ENV{'HOME'}."/.mbackup.conf") {
if (-f) {
$confile=$_;
last;
}
}
require $confile;
for (keys(%GROUPS)) { # build group list
if ($_ eq $REQUESTCONFIG) {
push(@GROUP,@{$GROUPS{$_}});
$CONFIG=$REQUESTCONFIG;
}
}
if ($CONFIG=~/^\s*$/) { # check for valid config
&log("ERROR: config '$REQUESTCONFIG' not found",1);
exit;
}
$REMOTE=0;$REMOTE=1 if ($TARGETDIR!~/^\//);
if ($opt_s) { # show configuration
if (@GROUP) {
print "\n";
print "mode: group\n\n";
print "group sleep: $GROUPSLEEP\n\n" if ($GROUPSLEEP>0);
for $job (@GROUP) {
print "/db/bin/mbackup -c $confile $job\n";
}
print "\n";
} else {
print "\n";
if ($FLAT==1) {
print "mode: flat\n";
} else {
print "mode: $MAX{'daily'} daily, $MAX{'weekly'} weekly, ";
print "$MAX{'monthly'} monthly, $MAX{'yearly'} yearly\n";
}
if ($#EXCLUDE>-1) {
print "\n";
$tmp="";$tmp.="$_, " for (@EXCLUDE);$tmp=~s/\,\s+$//;
print "exclude: $tmp\n";
}
print "\n";
$l=0;
for (keys(%SRC)) {
$l=length($_) if length($_)>$l;
}
printf "%-${l}s -> %s\/%s\n",$_,$TARGETDIR,$SRC{$_} for (keys(%SRC));
print "\n";
}
exit;
}
if (@GROUP) { # run backup group
for $job (@GROUP) {
$cmd="/db/bin/mbackup -c $confile $job";
&log("{$CONFIG} $cmd",1);
system($cmd);
if ($GROUPSLEEP>0 && $job ne $GROUP[-1]) {
&log("group loop sleep ($GROUPSLEEP seconds)",1);
sleep($GROUPSLEEP);
}
}
exit;
}
if ($MY_LOG) { # mysql loging
use DBI;
$dbh=DBI->connect("DBI:mysql:$MY_DB:$MY_HOST:",$MY_USER,$MY_PASSWD,{RaiseError=>1,PrintError=>1});
}
$mode=''; # set mode (daily,weekly,monthly,yearly)
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday)=localtime($NOW);
$mon++;$year+=1900;
$z=sprintf("%02d\.%02d\.%04d %02d\:%02d",$mday,$mon,$year,$hour,$min);
$mode='daily' if ( $MAX{'daily'}>0);
$mode='weekly' if ( $wday==0 && $MAX{'weekly'}>0);
$mode='monthly' if ( $mday==1 && $MAX{'monthly'}>0);
$mode='yearly' if ( $yday==0 && $MAX{'yearly'}>0);
$mode='daily' if ($opt_D); # set mode manual
$mode='weekly' if ($opt_W);
$mode='monthly' if ($opt_M);
$mode='yearly' if ($opt_Y);
if (defined($PING)) { # check if host is reachable
if (!Net::Ping->new("icmp", 15)->ping($PING)) {
&log("ERROR: host $PING not reachable",1);exit;
}
}
if (!-d "$TARGETDIR" && $REMOTE==0) { # check target dir
if ($opt_f) {
system("mkdir $TARGETDIR");
if (!-d "$TARGETDIR") {
&log("ERROR: target dir creation failed (mkdir $TARGETDIR)",1);
exit;
}
} else {
&log("ERROR: can not access target dir (mkdir $TARGETDIR)",1);
exit;
}
}
for $srcdir (keys(%SRC)) { # check source dir
if ($srcdir=~/^\// && !-d $srcdir) {
&log("ERROR: mising source dir '$srcdir'",1);
exit;
}
}
undef(%keycount); # check for duplicate source keys
for $srcdir (keys(%SRC)) {
$keycount{$SRC{$srcdir}}++;
if ($keycount{$SRC{$srcdir}}>1) {
&log("ERROR: duplicate source key '$SRC{$srcdir}'",1);
exit;
}
}
if ($FLAT==1 || $REMOTE==1) { # flat mode
$toterr=0;$totfiles=0;$tottfi=0;$totbytes=0;$tottby=0;$totrt=0;
for $srcdir (keys(%SRC)) {
$subname=$SRC{$srcdir};
$cmd="/usr/bin/rsync -av $RSYNCOPTS --stats --delete " .
&exf() . " --numeric-ids $srcdir/. $TARGETDIR/$subname";
($err,$fi,$tfi,$by,$tby,$rt,$try)=&rsync($cmd);
&log("[$CONFIG] $srcdir,$TARGETDIR ($err,$tfi,$fi,$tby,$by,$rt)",1);
if ($MY_LOG) { # mysql logging
$sql="INSERT INTO mbackup VALUES(0,now(),'$HOST','$VERSION','$CONFIG',".
"'$srcdir','$TARGETDIR',$fi,$tfi,$by,$tby,$rt,$err,$try)";
$dbh->do($sql);
}
if ($HTTP_LOG!~/^\s*$/) { # http logging
$tmp= "MBACKUP,$HOST,$VERSION,$CONFIG,$srcdir,$TARGETDIR,$fi,$tfi,$by,$tby,$rt,$err,$try";
use LWP::UserAgent;
my $ua = new LWP::UserAgent();
$response = $ua->post("http://$HTTP_LOG", Content => $tmp);
}
$toterr+=$err;$totfi+=$fi;$tottfi+=$tfi;$totby+=$by;$tottby+=$tby;$totrt+=$rt;
&log("rsync error $err in $srcdir/. -> $TARGETDIR/$subname") if ($err);
}
if ($toterr==0) {
&log("[$CONFIG] mbackup successful finished ($tottfi,$totfi,$tottby,$totby,$totrt)",1)
}
exit;
}
if ($mode eq '') { # check if mode is defiend otherwise exit
&log("ERROR: undefined mode",1);
exit;
}
$yweekly=0;$ymonthly=0;$yyearly=0; # search for missing snapshot
opendir(DIR,$TARGETDIR);
while ($file=readdir(DIR)) {
my(@stat)=stat("$TARGETDIR/$file");
if ($file=~/^weekly\.\d+$/) {
$yweekly=$stat[9] if ($stat[9]>$yweekly);
}
if ($file=~/^monthly\.\d+$/) {
$ymonthly=$stat[9] if ($stat[9]>$ymonthly);
}
if ($file=~/^yearly\.\d+$/) {
$yyearly=$stat[9] if ($stat[9]>$yyearly);
}
}
closedir(DIR);
if ($NOW-$yweekly>86400*10 && $yweekly!=0 && $MAX{'weekly'}>0) {
&log("WARNING: no weekly snapshot for more than 10 days",1);
}
if ($NOW-$ymonthly>86400*40 && $ymonthly!=0 && $MAX{'monthly'}>0) {
&log("WARNING: no monthly snapshot for more than 40 days",1);
}
if ($NOW-$yyearly>86400*400 && $yyearly!=0 && $MAX{'yearly'}>0) {
&log("WARNING: no yearly snapshot for more than 400 days",1);
}
undef(%SNAPLIST); # read snapshot list for current mode
opendir(DIR,$TARGETDIR);
while ($file=readdir(DIR)) {
my(@stat)=stat("$TARGETDIR/$file");
$SNAPLIST{$1}=$stat[9] if ($file=~/^$mode\.(\d+)/);
}
closedir(DIR);
for $n (sort {$b<=>$a} keys(%SNAPLIST)) { # snapshot cycling
$m=$n+1;
if (-d "$TARGETDIR/$mode.$n" && !-e "$TARGETDIR/$mode.$m") {
if ($m>=$MAX{$mode}) {
&cmd("rm -rf $TARGETDIR/$mode.$n");
} else {
&cmd("mv $TARGETDIR/$mode.$n $TARGETDIR/$mode.$m");
}
} else {
$tmp="";
$tmp="($TARGETDIR/$mode.$n not found)" if (!-d "$TARGETDIR/$mode.$n");
$tmp="($TARGETDIR/$mode.$m exists)" if (-e "$TARGETDIR/$mode.$m");
&log("ERROR: error while snapshot cycling $tmp",1);exit;
}
}
$youngest='';$y=0; # search for youngest snapshot
opendir(DIR,$TARGETDIR);
while ($file=readdir(DIR)) {
my(@stat)=stat("$TARGETDIR/$file");
if ($file=~/^((daily|weekly|monthly|yearly)\.\d+)/) {
if ($stat[9]>$y) {
$y=$stat[9];
$youngest=$file;
}
}
}
closedir(DIR);
&cmd("mkdir -m 0755 -p $TARGETDIR/$mode.tmp/"); # create new $mode.0
&cmd("touch $TARGETDIR/$mode.tmp/");
if (-d "$TARGETDIR/$mode.tmp") { # build new snapshot
$toterr=0;$totfi=0;$tottfi=0;$totbytes=0;$tottby=0;
for $srcdir (keys(%SRC)) {
$subname=$SRC{$srcdir};
$linkdest="";
if ($youngest!~/^\s*$/) {
if (-d "$TARGETDIR/$youngest" && -d "$TARGETDIR/$youngest/$subname") {
$linkdest="--link-dest=$TARGETDIR/$youngest/$subname"
}
}
$cmd="/usr/bin/rsync -av $RSYNCOPTS --no-o --no-g --chmod=ugo=rwX --stats --delete " .
&exf() . " --numeric-ids $linkdest $srcdir/. $TARGETDIR/$mode.tmp/$subname";
($err,$fi,$tfi,$by,$tby,$rt,$try)=&rsync($cmd);
&log("[$CONFIG] $srcdir,$TARGETDIR ($err,$tfi,$fi,$tby,$by,$rt)",1);
if ($MY_LOG) { # mysql logging
$sql="INSERT INTO mbackup VALUES(0,now(),'$HOST','$VERSION','$CONFIG',".
"'$srcdir','$TARGETDIR',$fi,$tfi,$by,$tby,$rt,$err,$try)";
$dbh->do($sql);
}
if ($HTTP_LOG!~/^\s*$/) { # http logging
$tmp= "MBACKUP,$HOST,$VERSION,$CONFIG,$srcdir,$TARGETDIR,$fi,$tfi,$by,$tby,$rt,$err,$try";
use LWP::UserAgent;
my $ua = new LWP::UserAgent();
$response = $ua->post("http://$HTTP_LOG", Content => $tmp);
}
$toterr+=$err;$totfi+=$fi;$tottfi+=$tfi;$totby+=$by;$tottby+=$tby;$totrt+=$rt;
}
if ($toterr==0) {
&log("[$CONFIG] mbackup successful finished ($tottfi,$totfi,$tby,$by,$totrt)",1);
&cmd("mv $TARGETDIR/$mode.tmp $TARGETDIR/$mode.0");
utime $NOW,$NOW,"$TARGETDIR/$mode.0";
}
} else {
&log("ERROR: can not access $mode.tmp",1);
}
######################################################################################################## SUPPORT
sub cmd() { # run command
my($cmd)=@_;
&log($cmd);
system($cmd);
}
sub log() { # write logs
my($str,$forceprint)=@_;
my(@z)=localtime(time());$z[4]+=1;$z[5]-=100;$z[6]+=1;
$ts=sprintf("%02d\.%02d\.%02d %02d\:%02d",$z[3],$z[4],$z[5],$z[2],$z[1]);
if ($LOGFILE!~/^\s+$/) {
open(LOG,">> $LOGFILE");
flock(LOG, LOCK_EX);
print LOG "$ts $$/$VERSION/$CONFIG $str\n";
close(LOG);
}
print "$str\n" if ($opt_v || $forceprint);
}
sub rsync() { # run rsync
my($rsynccmd)=@_;
my($files)=0;my($tfi)=0;my($bytes)=0;my($tby)=0;my($error)=0;my($try)=0;
$runtime=time();
$retries=0;
for $try (1..$RSYNCRETRIES) {
$rsynclog="";
open(RSYNC,"$rsynccmd |");while(<RSYNC>) {
print if ($opt_V);
if (/Number of files:\s*([\d\,]+)/) {;$files=$1;$files=~s/,//g;}
if (/Number of regular files transferred:\s*([\d\,]+)/) {;$tfi=$1;$tfi=~s/,//g;}
if (/Total file size:\s*([\d\,]*)\s*bytes/) {;$bytes=$1;$bytes=~s/,//g;}
if (/Total transferred file size:\s*([\d\,]*)\s*bytes/) {;$tby=$1;$tby=~s/,//g;}
}
close(RSYNC);
$error=($? >> 8);
$runtime=time()-$runtime;
if ($error==0) {
&log("$rsynccmd (successful)");
} else {
&log("$rsynccmd (error $error in try $try)")
}
last if ($error==0);
$retries++;
}
return ($error,$files,$tfi,$bytes,$tby,$runtime,$retries);
}
sub exf() { # exclude file
$ex='';
if ($#EXCLUDE>-1) {
$exfile="/tmp/mbackup.exclude.$CONFIG";
open(OUT,"> $exfile");
print OUT "$_\n" for (@EXCLUDE);
close(OUT);
$ex="--exclude-from $exfile --delete-excluded";
}
return $ex;
}
sub buildsrc() { # build source list (used in config)
my($base,@paths)=@_;
for $path (@paths) {
if ($path=~/\/([^\/]+)$/) {
$SRC{"$base$path"}=$1;
}
}
}
sub sc() { # build simple configuration (used in config)
my($uhd,$dirs,$exclude,$grp,$opt)=@_;
$mode=0;
if ($uhd=~/^([^\.]+)\.(.*)\:\:(.*)$/) {;$user=$3;$config=$1;$domain=$2;$mode=1;}
if ($uhd=~/^(\w+)\@([^\.]+)\.(.*)$/) {;$user=$1;$config=$2;$domain=$3;$mode=2;}
if ($mode>0) {
%opt=%$opt;
$config=$opt{name} if ($opt{name});
@grp=@$grp;
for $g (@grp) {
push(@{$GROUPS{$g}},$config)
}
if ($REQUESTCONFIG eq $config) {
$RSYNCOPTS=$opt{rsync} if ($opt{rsync});
$PING=$opt{ping} if ($opt{ping});
$TARGETBASE=$opt{target} if ($opt{target});
if ($opt{versions}=~/(\d+):(\d+):(\d+):(\d+)/) {
$MAX{'daily'}=$1;
$MAX{'weekly'}=$2;
$MAX{'monthly'}=$3;
$MAX{'yearly'}=$4;
$FLAT=0;
} else {
$FLAT=1;
}
@DIRS=@$dirs;
@EXCLUDE=@$exclude;
$TARGETDIR="$TARGETBASE/$config";
for $path (@DIRS) {
$tpath=$path;$tpath=~s/^\s*\///;$tpath=~s/\//\./g;
$SRC{"$uhd$path"}=$tpath if ($mode==1);
$SRC{"$uhd:$path"}=$tpath if ($mode==2);
}
$CONFIG=$REQUESTCONFIG;
}
}
}
sub help() { # help
print "mbackup v$VERSION\n";
print <<'ENDOFHELP';
USAGE:
------
mbackup [-v] [-V] [-DWMY] <backup job name>
mbackup -h
-D force daily mode
-W force weekly mode
-M force monthly mode
-Y force yearly mode
-v verbose output
-V very verbose output
-f force creation of target directory
-h this help
CONFIG FILE (/db/etc/mbackup.conf) GLOBAL OPTIONS:
--------------------------------------------------
$LOGFILE = "/var/log/mbackup.log"; # logfile location
$TARGETBASE = "/data/backup"; # targetbase for simple config
$HTTP_LOG = 'log.mxwx.org'; # http logging server
$MY_LOG = 1; # enable/disable mysql logging (deprecated)
$MY_HOST = 'localhost';
$MY_USER = '';
$MY_PASSWD = '';
$MY_DB = '';
SIMPLE BACKUP JOB CONFIGURATION (/db/etc/mbackup.conf):
-------------------------------------------------------
&sc(target,[paths],[exclude],[groups],{ option=>value, .. }
example:
&sc('root@host.domain',['/etc','/var','/home'],['/lib/lxcfs'],['all']);
&sc('host.domain::root',['/etc','/var','/home'],[],['all'], { rsync=>"-e 'ssh -p 2234'" });
&sc('root@host.domain',['/etc','/var','/home'],[],[] { versions=>'7:4:12:3' });
options:
name => 'name' # set configuration name
rsync => 'rsync options' # set additional rsync options
ping => 'ip address' # apply ping test before backup
version => 'daily:weekly:monthly:yearly' # define backup versioning
target => '/path/to/mbackup' # define backup destination
BACKUP JOB CONFIGURATION (/db/etc/mbackup.conf):
------------------------------------------------
if ($REQUESTCONFIG eq 'NAME') { # basic backup job config
<OPTIONS>
$CONFIG=$REQUESTCONFIG;
}
if ($REQUESTCONFIG eq 'NAME') { # backup group definition
@GROUP=('NAME1','NAME2',...);
$CONFIG=$REQUESTCONFIG;
}
push(@{$GROUPS{'all'}},'NAME'); # add config to group
BACKUP JOB OPTIONS:
-------------------
# backup target definition (use only once)
$TARGETDIR='/backup/NAME' # local traget directory
$TARGETDIR='10.0.1.1::root/backup/NAME' # rsync protocol target
$TARGETDIR='root@10.0.1.1:/backup/NAME' # ssh traget directory
# backup source definition (multiple allowd, different keys required)
$SRC{'/etc'} = 'etc1'; # local source
$SRC{'10.0.1.1::root/etc'} = 'etc2'; # remote source (rsync protocol)
$SRC{'root@10.0.1.1:/etc'} = 'etc3'; # remote source (ssh)
# define eculsions (absolut path definitions from source path)
@EXCLUDE=('/path1','/path2',...);
# define number of backups to keep, at least one value must be greater than 0
$MAX{'daily'} = 7; # keep n daily backup (default=7)
$MAX{'weekly'} = 4; # keep n weekly backup (default=4)
$MAX{'monthly'} = 12; # keep n monthly backup (default=12)
$MAX{'yearly'} = 3; # keep n yearly backup (default=3)
$FLAT=1; # only keep one backup (default=0)
$PING='10.0.1.1'; # perform ping test before backup run
$RSYNCOPTS="-e 'ssh -p 2234'"; # add extra options for rsync
$RSYNCRETRIES=3; # number of retries if rsync fails
MYSQL LOGGING TABLE:
--------------------
CREATE TABLE `mbackup` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ts` timestamp NULL DEFAULT NULL,
`host` varchar(255) DEFAULT NULL,
`version` varchar(255) DEFAULT NULL,
`config` varchar(255) DEFAULT NULL,
`source` varchar(255) DEFAULT NULL,
`target` varchar(255) DEFAULT NULL,
`files` bigint(11) DEFAULT NULL,
`transfiles` bigint(11) DEFAULT NULL,
`bytes` bigint(11) DEFAULT NULL,
`transbytes` bigint(11) DEFAULT NULL,
`runtime` int(11) DEFAULT NULL,
`error` int(11) DEFAULT NULL,
`retries` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ENDOFHELP
exit;
}
############################################################################################################ END
Executable
+525
View File
@@ -0,0 +1,525 @@
#!/usr/bin/perl
################################################################################################ mgsh (mwx'2023)
use Sys::Hostname qw(hostname);use Socket;
use Config;
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
use File::Compare;
$VERSION='3.1.5';
$INFO="mwx'2023";
$BASE="$ENV{HOME}/Source";
$BASE="/db/src" if ($Config{osname}=~/linux/i);
die "$BASE not found" if (!-d $BASE);
$PRJ=$ARGV[0] if (-d "$BASE/$ARGV[0]");
$GITHOST = '141.14.128.56';
$GITPORT = '2234';
$GITUSER = 'git';
$GITKEY = 'mgit_rsa';
$GITPATH ="/home/git";
$URL = "ssh://$GITUSER\@$GITHOST:$GITPORT$GITPATH";
$SSH = "ssh -p $GITPORT $GITUSER\@$GITHOST";
$IP = inet_ntoa( (gethostbyname(hostname()))[4] );
$HOST=hostname();$HOST=~s/([^\.]+)\..*$/$1/;
$USER=getpwuid( $< );
use Date::Parse; # date hashes
@D=('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
@M=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
&cmd("git config --global user.name 'Michael Wesemann'",1); # git settings
&cmd("git config --global user.email mike\@pstbx.org",1);
&cmd("git config --global push.default matching",1);
print "mgsh v$VERSION $INFO, $BASE\n"; # ready to start
for (;;) { # main mgsh loop
if ($PRJ!~/^\s*$/ && -d "$BASE/$PRJ") { # set current working directory/project
$DIR="$BASE/$PRJ";
$BPLSTATE='';
if (-l "$DIR/build.pl") {
chomp($rlf=`readlink $DIR/build.pl`);
$BPLSTATE='/OFF' if ($rlf=~/\.off$/);
}
$p=$1 if ($BASE=~/\/([^\/]+)$/);$prompt="$p/$PRJ/$I$BPLSTATE";
} else {
$DIR="$BASE";
$p=$1 if ($BASE=~/\/([^\/]+)$/);$prompt="$p";
}
chomp($REMURL= `cd $DIR; git config remote.origin.url`);
$REPO=$1 if ($REMURL=~/$url\/(.*)\.git\/?$/);
$prompt=~s/\/\s*$//;$cmd=&readline("$prompt > ","",1); # read command from command line
@tmpcmd=split(' ',$cmd);undef(@cmd);undef(%OPT); # get commandline options
for (@tmpcmd) {if (/\-(\w)/) {$OPT{$1}="-$1";} else {push(@cmd,$_);}}
if ($cmd[0] eq 'dist') { ########################################################################### list [-a]
$CP='/bin/cp';
$CP='/opt/homebrew/bin/gcp' if (-f '/opt/homebrew/bin/gcp');
$DDIR="$BASE/dist/$PRJ";
$DDIR=$cmd[1] if ($cmd[1]!~/^\s*$/);
if (-d $DDIR) {
chdir($DIR);
$n=0;
open(LS,"cd $DIR;git ls-files |");
while(<LS>) {
chomp();
if (!/^private/) {
if (compare($_,"$DDIR/$_")!=0) {
print "$_\n";
cmd("$CP --parents $_ $DDIR",1);
$n++;
}
}
}
print "$n files copied to $DDIR\n";
} else {
print "dist path not found ($DDIR)\n";
}
close(LS);
}
elsif ($cmd[0] eq 'list') { ########################################################################### list [-a]
$path=".";$path="./archive" if ($OPT{a});
open(LS,"$SSH /bin/ls -ltr $path |");
while(<LS>) {
if ($cmd[1]=~/^\s*$/ || /$cmd[1]/i) {
if ($OPT{a}) {
print "$1\n" if (/git\s+git\s+\d+\s+(.*)\.git.tar.gz$/);
} else {
print "$1\n" if (/git\s+git\s+\d+\s+(.*)\.git$/);
}
}
}
close(LS);
}
elsif ($cmd[0] eq 'show') { ############################################################################# show
$prj=$PRJ if ($PRJ!~/^\s*$/);
$prj=$cmd[1] if ($cmd[1]!~/^\s*$/);
$path=".";
$found=0;
open(LS,"$SSH /bin/ls $path |");
while(<LS>) {
$found++ if (/^$prj\.git$/);
}
close(LS);
if ($found==1) {
open($FH,"$SSH \"cd $GITPATH/$prj\.git && git log --reverse --format='%h %cd %s'\" |");
&repolog($FH);
} else {
print "repository not found\n";
}
}
elsif ($cmd[0] eq 'log' && $PRJ!~/^\s*$/) { ############################################################## log
if (-d "$DIR/.git") {
open($FH,"cd $DIR;git log --reverse --format='%h %cd %s' |");
&repolog($FH);
} else {
print "repository not found";
}
}
elsif ($cmd[0] eq 'push' && $PRJ!~/^\s*$/) { ################################################## push [comment]
if (-f "$DIR/push.pl") {
&shell("perl $DIR/push.pl");
}
$comment='';$comment.="$cmd[$_] " for (1..$#cmd);$comment=~s/\s+$//;
$comment=~s/\s{2}/ /g;
if (-d "$DIR/.git") {
&shell("git add --all .");
$msg="[$USER\@$HOST] $comment";$msg=~s/^\s+//;$msg=~s/\s+$//;
&shell("git commit -m '$msg'");
&shell("git push");
&shell("$SSH touch $GITPATH/${PRJ}.git");
} else {
print "error, no repository (.git) found";
}
}
elsif ($cmd[0] eq 'edit' && $PRJ!~/^\s*$/) { ################################################### edit [number]
$num=10;$num=$cmd[1] if ($cmd[1]=~/^\d+$/);
if (-d "$DIR/.git") {
&shell("git rebase -i HEAD~$num");
&shell("git push --force");
} else {
print "error, no repository (.git) found";
}
}
elsif ($cmd[0] eq 'archive' && $PRJ!~/^\s*$/) { ############################################ archive [comment]
$comment='';$comment.="$cmd[$_] " for (1..$#cmd);$comment=~s/\s+$//;
$comment=~s/[\,\;\:\\\/\=\'\"\|\?\>\<\-]+/ /g;
$comment=~s/\s{2}/ /g;
$comment=~s/\s+/\_/g;
my(@z)=localtime(time());$z[4]+=1;$z[5]-=100;$z[6]+=1;
$z=sprintf("%02d%02d%02d.%02d%02d",$z[3],$z[4],$z[5],$z[2],$z[1]);
if ($comment=~/^\s*$/) {
&shell(sprintf("$SSH 'cp -r ${PRJ}.git archive/${PRJ}_$z.git'"));
&shell(sprintf("$SSH 'cd archive;tar cvzf ${PRJ}_$z.git.tar.gz ${PRJ}_$z.git'"));
&shell("$SSH 'rm -rf archive/${PRJ}_$z.git'");
} else {
&shell(sprintf("$SSH cp -r ${PRJ}.git archive/${PRJ}_${z}_$comment.git"));
&shell(sprintf("$SSH 'cd archive;tar cvzf ${PRJ}_${z}_$comment.git.tar.gz ${PRJ}_${z}_$comment.git'"));
&shell("$SSH 'rm -rf archive/${PRJ}_${z}_$comment.git'");
}
}
elsif ($cmd[0] eq 'init' && $PRJ!~/^\s*$/) { ############################################################ init
&shell("perl $DIR/push.pl") if (-f "$DIR/push.pl");
if ($REPO=~/^\s*$/ || yesno('overwrite existing repository?',0)) {
&shell("$SSH 'rm -rf $GITPATH/${PRJ}.git'");
&shell("$SSH 'mkdir $GITPATH/${PRJ}.git;chdir $GITPATH/${PRJ}.git;git --bare init'");
if (!-f ".gitignore" || yesno('overwrite existing .gitignore?',0)) {
open(OUT,"> .gitignore");
print OUT &gitignore();
close(OUT);
}
&shell("rm -rf .git");
&shell("git init");
&shell("git remote add origin $URL/${PRJ}.git/");
&shell("git add .");
&shell("git commit -m 'initial commit [$IP,$USER]'");
&shell("git push -u origin master");
}
}
elsif ($cmd[0] eq 'login') { ########################################################################### login
&cmd("$SSH");
}
elsif ($cmd[0] eq 'cd' && $cmd[1]!~/^\./) { ############################################################### cd
$PRJ='';
$PRJ=$cmd[1] if (-d "$BASE/$cmd[1]");
}
elsif ($cmd[0] eq 'checkout' && $PRJ!~/^\s*$/) { ###################################### checkout [git options]
&shell("git checkout $cmd[1]");
}
elsif ($cmd[0] eq 'clone') { ###################################################################### clone [-a]
$prj=$PRJ if ($PRJ!~/^\s*$/);
$prj=$cmd[1] if ($cmd[1]!~/^\s*$/);
$DIR="$BASE";chdir($DIR);
my($path)=".";my($path)="./archive" if ($OPT{a});
my($found)=0;
open(LS,"$SSH /bin/ls $path |");
while(<LS>) {
if ($OPT{a}) {
$found++ if (/^$prj\.git.tar.gz$/);
} else {
$found++ if (/^$prj\.git$/);
}
}
close(LS);
if ($found==1) {
if (-d "$DIR/$prj") {
if (yesno('overwrite existing directory?',0)) {
&cmd("rm -rf $DIR/$prj")
} else {
goto exitclone;
}
}
&shell("git clone $URL/$prj.git") if (!$OPT{a});
if ($OPT{a}) {
&cmd("$SSH 'cd archive;tar xvzf $prj.git.tar.gz'");
&cmd("git clone $URL/archive/$prj.git");
&cmd("$SSH 'rm -rf archive/$prj.git'");
}
} else {
print "repository not found, try 'list [-a]'";
}
$PRJ=$prj if (-d "$BASE/$prj");
exitclone:;
}
elsif ($cmd[0] eq 'cloneall') { ##################################################################### cloneall
$prj=$PRJ if ($PRJ!~/^\s*$/);
$prj=$cmd[1] if ($cmd[1]!~/^\s*$/);
$DIR="$BASE";chdir($DIR);
my($path)=".";my($path)="./archive" if ($OPT{a});
my($found)=0;
open(LS,"$SSH /bin/ls $path |");
while(<LS>) {
if (/^(.*)\.git$/) {
print "-$1-\n";
&shell("git clone $URL/$1.git");
}
}
close(LS);
}
elsif ($cmd[0] eq 'open' || $cmd[0] eq 'view'){ ######################################################### open
$prj=$PRJ if ($PRJ!~/^\s*$/);
$prj=$cmd[1] if ($cmd[1]!~/^\s*$/);
if (-d "$BASE/$prj") {
$DIR="$BASE/$prj";chdir($DIR);
$xws='';$xprj='';opendir(DIR,$DIR);
while($file=readdir(DIR)) {
$xws=$file if ($file=~/.xcworkspace$/);
$xprj=$file if ($file=~/.xcodeproj$/);
}
close(DIR);
$xprj='' if ($xws!~/^\s*$/ && $xprj!~/^\s*$/);
&shell("open $xws") if ($xws!~/^\s*$/ && -d "$DIR/$xws");
&shell("open $xprj") if ($xprj!~/^\s*$/ && -d "$DIR/$xprj");
&shell("coda $DIR") if ($xws=~/^\s*$/ && $xprj=~/^\s*$/);
$PRJ=$prj if ($cmd[0] eq 'open');
} else {
print "not found\n";
}
}
elsif ($cmd[0] eq 'count') { ##################################################################### count lines
&count($DIR);
}
elsif ($cmd[0] eq 'do') { ############################################################### execute extra script
&shell("perl $DIR/do.$cmd[1].pl") if (-f "$DIR/do.$cmd[1].pl");
}
elsif ($cmd[0] eq 'tag') { # manage tag
if ($cmd[1] eq 'add' && $cmd[2]!~/^\s*$/) {
&shell("git tag -a '$cmd[2]' -m '$cmd[2]'");
&shell("git push origin '$cmd[2]'");
} elsif ($cmd[1] eq 'checkout' && $cmd[2]!~/^\s*$/) {
&shell("git checkout 'tags/$cmd[2]'");
} elsif ($cmd[1] eq 'delete' && $cmd[2]!~/^\s*$/) {
&shell("git tag -d '$cmd[2]'");
&shell("git push origin ':refs/tags/$cmd[2]'");
} else {
if ($cmd[1]!~/^\s*$/) {
print "unkown tag subcommand\n";
} else {
&shell("git tag -l --format=\"%(taggerdate:short): %(refname:short)\"");
}
}
}
elsif ($cmd[0] eq 'help') { ############################################################################# help
print <<"ENDOFHELP";
mgsh (git shell) $VERSION $INFO, builtin commands:
cd [project] change project
open [project] open project
init make new repository from current directory
push [comment] push changes to git server
edit [number] edit last [number] commits (default is 10)
clone [-a] <repository> clone repository from git server (-a for archive)
cloneall> clone all repository from git server
checkout [git options] forward checkout to git
log show log
archive [comment] archive current repository
list [-a] [pattern] list repositories on git server (-a for archive)
show <repository> show repository log on git server
dist <path> cp changed files to other directory/repository
login connect to git server
do <name> execute extra script with name do.<name>.pl
count count lines in project
tag show tags
tag add <tag> add tag
tag checkout <tag> checkout tag
tag delete <tag> delete tag
ENDOFHELP
}
else { ###################################################################### forward unknown command to shell
&shell($cmd) if ($cmd!~/^\s*$/);
}
}
######################################################################################################## SUPPORT
sub shell() { # shell
my($cmd)=@_;
chdir $DIR;
system($cmd);
}
sub cmd() { # execute command
my($cmd,$quiet)=@_;
print "$cmd\n" if (!$quiet);
system($cmd);
}
sub readline { # readline
my($prompt,$input,$mode)=@_; use Term::ReadLine;
BEGIN{ $ENV{PERL_RL} = 'Perl o=0' };
if (!$term) {
$term = new Term::ReadLine 'term';
open(IN,"$BASE/.mgsh_history");
while(<IN>) {
chomp();
push(@history,$_);
}
close(IN);
$term->SetHistory(@history);
}
my($txt)=$term->readline($prompt,$input);
my(@history)=$term->GetHistory();
shift(@history) while($#history>=10);
open(OUT,"> $BASE/.mgsh_history");
print OUT "$_\n" for (@history);
close(OUT);
return $txt;
}
sub yesno { # request yes/no answer
my($prom,$def)=@_;
my($ans);
if ($def) {;$ans=&getkey("$prom Y/n ? ");}
else {;$ans=&getkey("$prom y/N ? ");}
if ($ans=~/^\s*$/) {
if ($def) {;return(1);}
else {;return(0);}
}
if ($ans=~/^\s*y\s*$/i || $ans=~/^\s*yes\s*$/i) {
return 1;
}
return 0;
}
sub getkey { # get key from keyboard
$|=1;
print "$_[0]";
system "stty", '-icanon', '-echo', 'eol', "\001";
$key = getc(STDIN);$key=~s/[\r\n\t]//g;
system "stty", 'icanon', 'echo', 'eol', "^@";
print "$key\n";
return $key;
}
sub count() { # count lines in project
my($dir)=@_;
use File::Find;
$lines=0;
find(\&counting,$dir);
sub counting {
$f=$File::Find::name;
if (-f $f) {
if ($f=~/\.[hmc]$/ || $f=~/\.xib$/ || $f=~/\.lm$/ || $f=~/\.ym$/ || $f=~/\.pl$/ || $f=~/\.php$/ ||
(-T $f && $f=~/\/bin\//)) {
open(WC,"/usr/bin/wc -l '$f' |");
while(<WC>) {;
$lines+=$1 if (/^\s*(\d*)\s+$f/);
}
close(WC);
}
}
}
print "$lines lines total in $PRJ\n";
}
sub repolog() { # show repository log
my($FH)=@_;
my($o)='';my($os)='';my($oss)='';my($n)=0;my($ns)=0;
my($z)='';my($zs)='';my($zss)='';
while(<$FH>) {
chomp();
@tmp=split(' ');
$t=str2time($tmp[1]);
my(@z)=localtime($t);$z[4]+=1;$z[5]+=1900;$z[6]+=1;
if (time()-$t<86400) {
$z=sprintf(" %02d\:%02d",$z[2],$z[1]);
$zs=sprintf(" %02d\:%02d",$z[2],$z[1]);
$zss=sprintf("%02d\:%02d",$z[2],$z[1]);
} elsif (time()-$t<86400*7) {
$z=sprintf(" %s, %02d\:%02d",$D[$z[6]-1],$z[2],$z[1]);
$zs=sprintf("%s, %02d\:%02d",$D[$z[6]-1],$z[2],$z[1]);
$ns++;
} else {
$z=sprintf("%s, %02d %s %4d, %02d\:%02d",$D[$z[6]-1],$z[3],$M[$z[4]-1],$z[5],$z[2],$z[1]);
$n++;
}
$o.="$tmp[0] $z $tmp[2]\n";
$os.="$tmp[0] $zs $tmp[2]\n";
$oss.="$tmp[0] $zss $tmp[2]\n";
}
if ($n==0 && $ns==0) {
print $oss;
} elsif ($n==0 && $ns>0) {
print $os;
} else {
print $o;
}
}
sub gitignore() {
return << "ENDOFGITIGNORE";
.DS_Store
.AppleDouble
.LSOverride
._*
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
ENDOFGITIGNORE
}
############################################################################################################ END
Executable
+195
View File
@@ -0,0 +1,195 @@
#!/usr/bin/perl
################################################################################ mysql/mariadb backup (mwx'2021)
use Getopt::Std;getopts('bza');
use DBI;
use Term::ReadKey;
$VERSION='4.0.0';
$HOST = 'localhost'; # settings
$USER = 'mybackup';
$PASSWD = 'iexae3aitathoo4k';
$PATH = '/db/backup/mysql';
$KEEPDAILYBACKUPS = 21;
$TAR = "/bin/tar";
$RM = "/bin/rm";
$MYSQLDUMP = "/usr/bin/mysqldump";
$GZIP = "/bin/gzip";
if (!$opt_a && !$opt_b && !$opt_z) { # show usage
print <<"ENDOFHELP";
mybackup, MySQL/MariaDB backup, mwx'2021, v$VERSION
usage: mybackup -a add backup user to db (root password required)
mybackup -b run database backup
mybackup -z run database backup and compress output
ENDOFHELP
exit(0);
}
if ($opt_a) { # add backup user to db
use Term::ReadPassword;
$rootdbpw = read_password('Enter password: ');
$dbh=DBI->connect("DBI:mysql:mysql:localhost:","root",$rootdbpw,{RaiseError=>1,PrintError=>1});
$dbh->do("CREATE USER 'mybackup' IDENTIFIED BY '$PASSWD'");
$dbh->do("GRANT SELECT, SHOW VIEW, LOCK TABLES, RELOAD,REPLICATION CLIENT ON *.* TO 'mybackup'");
#
#
#
# CREATE USER 'mybackup' IDENTIFIED BY 'Yooch0esh9Ah';
#
#
# $sth=$dbh->prepare("SHOW COLUMNS FROM user");$sth->execute; # find authentication fields
# $HASPW=0;$HASAS=0;
# while ($dat = $sth->fetchrow_hashref) {
# $HASPW=1 if ($$dat{Field} eq 'Password');
# $HASAS=1 if ($$dat{Field} eq 'authentication_string');
# }
#
# $sql="INSERT INTO user SET User='$USER',Host='localhost',";
# $sql.="Password=password('$PASSWD')," if ($HASPW);
# $sql.="authentication_string=password('$PASSWD')," if ($HASAS);
# $sql.="ssl_cipher='',x509_issuer='',x509_subject='',".
# "Select_priv='Y',Reload_priv='Y',Lock_tables_priv='Y',Show_view_priv='Y',Process_priv='Y'";
#
# $dbh->do($sql);
$dbh->do("flush privileges");
if (&yesno('Write /root/.my.cnf file',1)) {
system("rm -f /root/.my.cnf");
open(OUT,"> /root/.my.cnf");
print OUT "[client]\nuser=root\npassword=$rootdbpw\n[mysqldump]\nuser=mybackup\npassword=$PASSWD\n";
close(OUT);
system("chmod 600 /root/.my.cnf");
}
&setupcron();
exit;
}
&cleanup();
@DBS=&autogetdbs();
my(@z)=localtime(time());$z[4]+=1;$z[6]+=1;$z[5]-=100;
$z=sprintf("%02d%02d%02d%02d%02d%02d",$z[3],$z[4],$z[5],$z[2],$z[1],$z[0]);
if (!-d "$PATH/$z") { # make target dir
mkdir("$PATH/$z",448);
}
for $db (@DBS) { # dump databaeses
if ($db ne 'information_schema' && $db ne 'performance_schema' && $db ne 'sys') {
my($fdb)=$db;$fdb=~s/\s/\./g;
if (!$IGNOREDB{$db}) {
if ($DBPARAM{$db}) {;$db=$DBPARAM{$db};}
&cmd("$MYSQLDUMP -h $HOST -u $USER -f -F -R --skip-extended-insert $db >$PATH/$z/$fdb.mysql");
}
}
}
$cmd="$MYSQLDUMP -h $HOST -u $USER -c -f -F -R --skip-extended-insert -A -v >$PATH/$z.mysql";
&cmd($cmd);
&cmd("$GZIP $PATH/$z.mysql");
chdir($PATH);
if (-d "$PATH/$z" && $opt_z) {
&cmd("$TAR czvf $z.tar.gz $z");
&cmd("$RM -rf $PATH/$z");
}
######################################################################################################## SUPPORT
sub cleanup() {
use Date::Parse;
opendir(DIR,"$PATH");
while($file=readdir(DIR)) {
if (-f "$PATH/$file" && $file=~/(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/) {
$m=$1;
$a=$3+2000;
$time = str2time("$a/$2/$1 $4:$5:$6");
my(@z)=localtime($time);$z[4]+=1;$z[5]-=100;$z[6]+=1;
$z=sprintf("%02d\.%02d\.%02d %02d\:%02d\:%02d",$z[3],$z[4],$z[5],$z[2],$z[1],$z[0]);
$t=(time()-$time)/86400;
if ($m!=1 && $t>$KEEPDAILYBACKUPS) {
&cmd("/bin/rm -f $PATH/$file") if (-f "$PATH/$file");
}
}
}
}
sub setupcron() {
open(CRON,"crontab -l |");
while(<CRON>) {
chomp();
push(@CRON,$_) if (!/\/db\/bin\/mybackup/);
}
push(@CRON,"0 12 * * * /db/bin/mybackup -z > /dev/null 2>&1");
open(OUT,"> /tmp/cron.$$");
for (@CRON) {
print OUT "$_\n";
}
close(OUT);
system("/usr/bin/crontab /tmp/cron.$$");
system("rm -f /tmp/cron.$$");
}
sub cmd() {
my($cmd)=@_;
print "$cmd\n";
system($cmd);
}
sub autogetdbs() {
my(@dbs);
$dbh=DBI->connect("DBI:mysql::$HOST:",$USER,$PASSWD,{RaiseError=>1,PrintError=>1});
$sth=$dbh->prepare("SHOW DATABASES");$sth->execute ;
while ($dat = $sth->fetchrow_hashref) {
push(@dbs,$$dat{Database});
}
return (@dbs);
}
sub yesno {
my($prom,$def)=@_;
my($ans);
if ($def) {;$ans=&getkey("$prom Y/n ? ");}
else {;$ans=&getkey("$prom y/N ? ");}
if ($ans=~/^\s*$/) {
if ($def) {;return(1);}
else {;return(0);}
}
if ($ans=~/^\s*y\s*$/i || $ans=~/^\s*yes\s*$/i) {
return 1;
}
return 0;
}
sub getkey {
$|=1;
print "$_[0]";
system "stty", '-icanon', '-echo', 'eol', "\001";
$key = getc(STDIN);$key=~s/[\r\n\t]//g;
system "stty", 'icanon', 'echo', 'eol', "^@";
print "$key\n";
return $key;
}
############################################################################################################ END
Executable
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/perl
########################################################################## mysql/mariadb user manager (mwx'2021)
use DBI;
use Getopt::Std;getopts('hd:x');
$VERSION='4.0.0';
&help() if ($ARGV[0]=~/^\s*$/ || $opt_h);
$USER=$DB=$ARGV[0];
$DB=$opt_d if ($opt_d!~/^\s*$/);
$PW=sprintf("$USER%03d",int(rand(100000)));
my $dsn = "DBI:mysql:mysql;mysql_read_default_file=$ENV{HOME}/.my.cnf";
$dbh=DBI->connect($dsn,undef,undef,{PrintError=>1});
&sqldo("CREATE DATABASE IF NOT EXISTS $DB") if (!$opt_x);
&sqldo("DROP USER IF EXISTS '$USER'");
&sqldo("CREATE USER '$USER' IDENTIFIED BY '$PW'");
&sqldo("GRANT ALL PRIVILEGES ON $DB.* TO '$USER'");
sub sqldo() {
my($sql)=@_;
print "$sql\n";
$dbh->do($sql);
}
sub help() {
print <<"ENDOFHELP";
myuser - mariadb user manager (v$VERSION)
myuser <NAME> add user and database with the same name to mariadb
myuser -d <DBNAME> <NAME> add user and database to mariadb
myuser -x <NAME> add only user to mariadb
ENDOFHELP
exit();
}
############################################################################################################ END
Executable
+611
View File
@@ -0,0 +1,611 @@
#!/usr/bin/env python
# Try to determine how much RAM is currently being used per program.
# Note per _program_, not per process. So for example this script
# will report RAM used by all httpd process together. In detail it reports:
# sum(private RAM for program processes) + sum(Shared RAM for program processes)
# The shared RAM is problematic to calculate, and this script automatically
# selects the most accurate method available for your kernel.
# Licence: LGPLv2
# Author: P@draigBrady.com
# Source: http://www.pixelbeat.org/scripts/ps_mem.py
# V1.0 06 Jul 2005 Initial release
# V1.1 11 Aug 2006 root permission required for accuracy
# V1.2 08 Nov 2006 Add total to output
# Use KiB,MiB,... for units rather than K,M,...
# V1.3 22 Nov 2006 Ignore shared col from /proc/$pid/statm for
# 2.6 kernels up to and including 2.6.9.
# There it represented the total file backed extent
# V1.4 23 Nov 2006 Remove total from output as it's meaningless
# (the shared values overlap with other programs).
# Display the shared column. This extra info is
# useful, especially as it overlaps between programs.
# V1.5 26 Mar 2007 Remove redundant recursion from human()
# V1.6 05 Jun 2007 Also report number of processes with a given name.
# Patch from riccardo.murri@gmail.com
# V1.7 20 Sep 2007 Use PSS from /proc/$pid/smaps if available, which
# fixes some over-estimation and allows totalling.
# Enumerate the PIDs directly rather than using ps,
# which fixes the possible race between reading
# RSS with ps, and shared memory with this program.
# Also we can show non truncated command names.
# V1.8 28 Sep 2007 More accurate matching for stats in /proc/$pid/smaps
# as otherwise could match libraries causing a crash.
# Patch from patrice.bouchand.fedora@gmail.com
# V1.9 20 Feb 2008 Fix invalid values reported when PSS is available.
# Reported by Andrey Borzenkov <arvidjaar@mail.ru>
# V3.9 07 Mar 2017
# http://github.com/pixelb/scripts/commits/master/scripts/ps_mem.py
# Notes:
#
# All interpreted programs where the interpreter is started
# by the shell or with env, will be merged to the interpreter
# (as that's what's given to exec). For e.g. all python programs
# starting with "#!/usr/bin/env python" will be grouped under python.
# You can change this by using the full command line but that will
# have the undesirable affect of splitting up programs started with
# differing parameters (for e.g. mingetty tty[1-6]).
#
# For 2.6 kernels up to and including 2.6.13 and later 2.4 redhat kernels
# (rmap vm without smaps) it can not be accurately determined how many pages
# are shared between processes in general or within a program in our case:
# http://lkml.org/lkml/2005/7/6/250
# A warning is printed if overestimation is possible.
# In addition for 2.6 kernels up to 2.6.9 inclusive, the shared
# value in /proc/$pid/statm is the total file-backed extent of a process.
# We ignore that, introducing more overestimation, again printing a warning.
# Since kernel 2.6.23-rc8-mm1 PSS is available in smaps, which allows
# us to calculate a more accurate value for the total RAM used by programs.
#
# Programs that use CLONE_VM without CLONE_THREAD are discounted by assuming
# they're the only programs that have the same /proc/$PID/smaps file for
# each instance. This will fail if there are multiple real instances of a
# program that then use CLONE_VM without CLONE_THREAD, or if a clone changes
# its memory map while we're checksumming each /proc/$PID/smaps.
#
# I don't take account of memory allocated for a program
# by other programs. For e.g. memory used in the X server for
# a program could be determined, but is not.
#
# FreeBSD is supported if linprocfs is mounted at /compat/linux/proc/
# FreeBSD 8.0 supports up to a level of Linux 2.6.16
import getopt
import time
import errno
import os
import sys
# The following exits cleanly on Ctrl-C or EPIPE
# while treating other exceptions as before.
def std_exceptions(etype, value, tb):
sys.excepthook = sys.__excepthook__
if issubclass(etype, KeyboardInterrupt):
pass
elif issubclass(etype, IOError) and value.errno == errno.EPIPE:
pass
else:
sys.__excepthook__(etype, value, tb)
sys.excepthook = std_exceptions
#
# Define some global variables
#
PAGESIZE = os.sysconf("SC_PAGE_SIZE") / 1024 #KiB
our_pid = os.getpid()
have_pss = 0
have_swap_pss = 0
class Proc:
def __init__(self):
uname = os.uname()
if uname[0] == "FreeBSD":
self.proc = '/compat/linux/proc'
else:
self.proc = '/proc'
def path(self, *args):
return os.path.join(self.proc, *(str(a) for a in args))
def open(self, *args):
try:
if sys.version_info < (3,):
return open(self.path(*args))
else:
return open(self.path(*args), errors='ignore')
except (IOError, OSError):
val = sys.exc_info()[1]
if (val.errno == errno.ENOENT or # kernel thread or process gone
val.errno == errno.EPERM or
val.errno == errno.EACCES):
raise LookupError
raise
proc = Proc()
#
# Functions
#
def parse_options():
try:
long_options = [
'split-args',
'help',
'total',
'discriminate-by-pid',
'swap'
]
opts, args = getopt.getopt(sys.argv[1:], "shtdSp:w:", long_options)
except getopt.GetoptError:
sys.stderr.write(help())
sys.exit(3)
if len(args):
sys.stderr.write("Extraneous arguments: %s\n" % args)
sys.exit(3)
# ps_mem.py options
split_args = False
pids_to_show = None
discriminate_by_pid = False
show_swap = False
watch = None
only_total = False
for o, a in opts:
if o in ('-s', '--split-args'):
split_args = True
if o in ('-t', '--total'):
only_total = True
if o in ('-d', '--discriminate-by-pid'):
discriminate_by_pid = True
if o in ('-S', '--swap'):
show_swap = True
if o in ('-h', '--help'):
sys.stdout.write(help())
sys.exit(0)
if o in ('-p',):
try:
pids_to_show = [int(x) for x in a.split(',')]
except:
sys.stderr.write(help())
sys.exit(3)
if o in ('-w',):
try:
watch = int(a)
except:
sys.stderr.write(help())
sys.exit(3)
return (
split_args,
pids_to_show,
watch,
only_total,
discriminate_by_pid,
show_swap
)
def help():
help_msg = 'Usage: ps_mem [OPTION]...\n' \
'Show program core memory usage\n' \
'\n' \
' -h, -help Show this help\n' \
' -p <pid>[,pid2,...pidN] Only show memory usage PIDs in the '\
'specified list\n' \
' -s, --split-args Show and separate by, all command line'\
' arguments\n' \
' -t, --total Show only the total value\n' \
' -d, --discriminate-by-pid Show by process rather than by program\n' \
' -S, --swap Show swap information\n' \
' -w <N> Measure and show process memory every'\
' N seconds\n'
return help_msg
# (major,minor,release)
def kernel_ver():
kv = proc.open('sys/kernel/osrelease').readline().split(".")[:3]
last = len(kv)
if last == 2:
kv.append('0')
last -= 1
while last > 0:
for char in "-_":
kv[last] = kv[last].split(char)[0]
try:
int(kv[last])
except:
kv[last] = 0
last -= 1
return (int(kv[0]), int(kv[1]), int(kv[2]))
#return Private,Shared
#Note shared is always a subset of rss (trs is not always)
def getMemStats(pid):
global have_pss
global have_swap_pss
mem_id = pid #unique
Private_lines = []
Shared_lines = []
Pss_lines = []
Rss = (int(proc.open(pid, 'statm').readline().split()[1])
* PAGESIZE)
Swap_lines = []
Swap_pss_lines = []
Swap = 0
Swap_pss = 0
if os.path.exists(proc.path(pid, 'smaps')): # stat
lines = proc.open(pid, 'smaps').readlines() # open
# Note we checksum smaps as maps is usually but
# not always different for separate processes.
mem_id = hash(''.join(lines))
for line in lines:
if line.startswith("Shared"):
Shared_lines.append(line)
elif line.startswith("Private"):
Private_lines.append(line)
elif line.startswith("Pss"):
have_pss = 1
Pss_lines.append(line)
elif line.startswith("Swap:"):
Swap_lines.append(line)
elif line.startswith("SwapPss:"):
have_swap_pss = 1
Swap_pss_lines.append(line)
Shared = sum([int(line.split()[1]) for line in Shared_lines])
Private = sum([int(line.split()[1]) for line in Private_lines])
#Note Shared + Private = Rss above
#The Rss in smaps includes video card mem etc.
if have_pss:
pss_adjust = 0.5 # add 0.5KiB as this avg error due to truncation
Pss = sum([float(line.split()[1])+pss_adjust for line in Pss_lines])
Shared = Pss - Private
# Note that Swap = Private swap + Shared swap.
Swap = sum([int(line.split()[1]) for line in Swap_lines])
if have_swap_pss:
# The kernel supports SwapPss, that shows proportional swap share.
# Note that Swap - SwapPss is not Private Swap.
Swap_pss = sum([int(line.split()[1]) for line in Swap_pss_lines])
elif (2,6,1) <= kernel_ver() <= (2,6,9):
Shared = 0 #lots of overestimation, but what can we do?
Private = Rss
else:
Shared = int(proc.open(pid, 'statm').readline().split()[2])
Shared *= PAGESIZE
Private = Rss - Shared
return (Private, Shared, mem_id, Swap, Swap_pss)
def getCmdName(pid, split_args, discriminate_by_pid):
cmdline = proc.open(pid, 'cmdline').read().split("\0")
if cmdline[-1] == '' and len(cmdline) > 1:
cmdline = cmdline[:-1]
path = proc.path(pid, 'exe')
try:
path = os.readlink(path)
# Some symlink targets were seen to contain NULs on RHEL 5 at least
# https://github.com/pixelb/scripts/pull/10, so take string up to NUL
path = path.split('\0')[0]
except OSError:
val = sys.exc_info()[1]
if (val.errno == errno.ENOENT or # either kernel thread or process gone
val.errno == errno.EPERM or
val.errno == errno.EACCES):
raise LookupError
raise
if split_args:
return ' '.join(cmdline).replace('\n', ' ')
if path.endswith(" (deleted)"):
path = path[:-10]
if os.path.exists(path):
path += " [updated]"
else:
#The path could be have prelink stuff so try cmdline
#which might have the full path present. This helped for:
#/usr/libexec/notification-area-applet.#prelink#.fX7LCT (deleted)
if os.path.exists(cmdline[0]):
path = cmdline[0] + " [updated]"
else:
path += " [deleted]"
exe = os.path.basename(path)
cmd = proc.open(pid, 'status').readline()[6:-1]
if exe.startswith(cmd):
cmd = exe #show non truncated version
#Note because we show the non truncated name
#one can have separated programs as follows:
#584.0 KiB + 1.0 MiB = 1.6 MiB mozilla-thunder (exe -> bash)
# 56.0 MiB + 22.2 MiB = 78.2 MiB mozilla-thunderbird-bin
if sys.version_info >= (3,):
cmd = cmd.encode(errors='replace').decode()
if discriminate_by_pid:
cmd = '%s [%d]' % (cmd, pid)
return cmd
#The following matches "du -h" output
#see also human.py
def human(num, power="Ki", units=None):
if units is None:
powers = ["Ki", "Mi", "Gi", "Ti"]
while num >= 1000: #4 digits
num /= 1024.0
power = powers[powers.index(power)+1]
return "%.1f %sB" % (num, power)
else:
return "%.f" % ((num * 1024) / units)
def cmd_with_count(cmd, count):
if count > 1:
return "%s (%u)" % (cmd, count)
else:
return cmd
#Warn of possible inaccuracies
#2 = accurate & can total
#1 = accurate only considering each process in isolation
#0 = some shared mem not reported
#-1= all shared mem not reported
def shared_val_accuracy():
"""http://wiki.apache.org/spamassassin/TopSharedMemoryBug"""
kv = kernel_ver()
pid = os.getpid()
if kv[:2] == (2,4):
if proc.open('meminfo').read().find("Inact_") == -1:
return 1
return 0
elif kv[:2] == (2,6):
if os.path.exists(proc.path(pid, 'smaps')):
if proc.open(pid, 'smaps').read().find("Pss:")!=-1:
return 2
else:
return 1
if (2,6,1) <= kv <= (2,6,9):
return -1
return 0
elif kv[0] > 2 and os.path.exists(proc.path(pid, 'smaps')):
return 2
else:
return 1
def show_shared_val_accuracy( possible_inacc, only_total=False ):
level = ("Warning","Error")[only_total]
if possible_inacc == -1:
sys.stderr.write(
"%s: Shared memory is not reported by this system.\n" % level
)
sys.stderr.write(
"Values reported will be too large, and totals are not reported\n"
)
elif possible_inacc == 0:
sys.stderr.write(
"%s: Shared memory is not reported accurately by this system.\n" % level
)
sys.stderr.write(
"Values reported could be too large, and totals are not reported\n"
)
elif possible_inacc == 1:
sys.stderr.write(
"%s: Shared memory is slightly over-estimated by this system\n"
"for each program, so totals are not reported.\n" % level
)
sys.stderr.close()
if only_total and possible_inacc != 2:
sys.exit(1)
def get_memory_usage(pids_to_show, split_args, discriminate_by_pid,
include_self=False, only_self=False):
cmds = {}
shareds = {}
mem_ids = {}
count = {}
swaps = {}
shared_swaps = {}
for pid in os.listdir(proc.path('')):
if not pid.isdigit():
continue
pid = int(pid)
# Some filters
if only_self and pid != our_pid:
continue
if pid == our_pid and not include_self:
continue
if pids_to_show is not None and pid not in pids_to_show:
continue
try:
cmd = getCmdName(pid, split_args, discriminate_by_pid)
except LookupError:
#operation not permitted
#kernel threads don't have exe links or
#process gone
continue
try:
private, shared, mem_id, swap, swap_pss = getMemStats(pid)
except RuntimeError:
continue #process gone
if shareds.get(cmd):
if have_pss: #add shared portion of PSS together
shareds[cmd] += shared
elif shareds[cmd] < shared: #just take largest shared val
shareds[cmd] = shared
else:
shareds[cmd] = shared
cmds[cmd] = cmds.setdefault(cmd, 0) + private
if cmd in count:
count[cmd] += 1
else:
count[cmd] = 1
mem_ids.setdefault(cmd, {}).update({mem_id: None})
# Swap (overcounting for now...)
swaps[cmd] = swaps.setdefault(cmd, 0) + swap
if have_swap_pss:
shared_swaps[cmd] = shared_swaps.setdefault(cmd, 0) + swap_pss
else:
shared_swaps[cmd] = 0
# Total swaped mem for each program
total_swap = 0
# Total swaped shared mem for each program
total_shared_swap = 0
# Add shared mem for each program
total = 0
for cmd in cmds:
cmd_count = count[cmd]
if len(mem_ids[cmd]) == 1 and cmd_count > 1:
# Assume this program is using CLONE_VM without CLONE_THREAD
# so only account for one of the processes
cmds[cmd] /= cmd_count
if have_pss:
shareds[cmd] /= cmd_count
cmds[cmd] = cmds[cmd] + shareds[cmd]
total += cmds[cmd] # valid if PSS available
total_swap += swaps[cmd]
if have_swap_pss:
total_shared_swap += shared_swaps[cmd]
sorted_cmds = sorted(cmds.items(), key=lambda x:x[1])
sorted_cmds = [x for x in sorted_cmds if x[1]]
return sorted_cmds, shareds, count, total, swaps, shared_swaps, \
total_swap, total_shared_swap
def print_header(show_swap, discriminate_by_pid):
output_string = " Private + Shared = RAM used"
if show_swap:
if have_swap_pss:
output_string += " " * 5 + "Shared Swap"
output_string += " Swap used"
output_string += "\tProgram"
if discriminate_by_pid:
output_string += "[pid]"
output_string += "\n\n"
sys.stdout.write(output_string)
def print_memory_usage(sorted_cmds, shareds, count, total, swaps, total_swap,
shared_swaps, total_shared_swap, show_swap):
for cmd in sorted_cmds:
output_string = "%9s + %9s = %9s"
output_data = (human(cmd[1]-shareds[cmd[0]]),
human(shareds[cmd[0]]), human(cmd[1]))
if show_swap:
if have_swap_pss:
output_string += "\t%9s"
output_data += (human(shared_swaps[cmd[0]]),)
output_string += " %9s"
output_data += (human(swaps[cmd[0]]),)
output_string += "\t%s\n"
output_data += (cmd_with_count(cmd[0], count[cmd[0]]),)
sys.stdout.write(output_string % output_data)
if have_pss:
if show_swap:
if have_swap_pss:
sys.stdout.write("%s\n%s%9s%s%9s%s%9s\n%s\n" %
("-" * 61, " " * 24, human(total), " " * 7,
human(total_shared_swap), " " * 3,
human(total_swap), "=" * 61))
else:
sys.stdout.write("%s\n%s%9s%s%9s\n%s\n" %
("-" * 45, " " * 24, human(total), " " * 3,
human(total_swap), "=" * 45))
else:
sys.stdout.write("%s\n%s%9s\n%s\n" %
("-" * 33, " " * 24, human(total), "=" * 33))
def verify_environment(pids_to_show):
if os.geteuid() != 0 and not pids_to_show:
sys.stderr.write("Sorry, root permission required, or specify pids with -p\n")
sys.stderr.close()
sys.exit(1)
try:
kernel_ver()
except (IOError, OSError):
val = sys.exc_info()[1]
if val.errno == errno.ENOENT:
sys.stderr.write(
"Couldn't access " + proc.path('') + "\n"
"Only GNU/Linux and FreeBSD (with linprocfs) are supported\n")
sys.exit(2)
else:
raise
def main():
split_args, pids_to_show, watch, only_total, discriminate_by_pid, \
show_swap = parse_options()
verify_environment(pids_to_show)
if not only_total:
print_header(show_swap, discriminate_by_pid)
if watch is not None:
try:
sorted_cmds = True
while sorted_cmds:
sorted_cmds, shareds, count, total, swaps, shared_swaps, \
total_swap, total_shared_swap = \
get_memory_usage(pids_to_show, split_args,
discriminate_by_pid)
if only_total and have_pss:
sys.stdout.write(human(total, units=1)+'\n')
elif not only_total:
print_memory_usage(sorted_cmds, shareds, count, total,
swaps, total_swap, shared_swaps,
total_shared_swap, show_swap)
sys.stdout.flush()
time.sleep(watch)
else:
sys.stdout.write('Process does not exist anymore.\n')
except KeyboardInterrupt:
pass
else:
# This is the default behavior
sorted_cmds, shareds, count, total, swaps, shared_swaps, total_swap, \
total_shared_swap = get_memory_usage(pids_to_show, split_args,
discriminate_by_pid)
if only_total and have_pss:
sys.stdout.write(human(total, units=1)+'\n')
elif not only_total:
print_memory_usage(sorted_cmds, shareds, count, total, swaps,
total_swap, shared_swaps, total_shared_swap,
show_swap)
# We must close explicitly, so that any EPIPE exception
# is handled by our excepthook, rather than the default
# one which is reenabled after this script finishes.
sys.stdout.close()
vm_accuracy = shared_val_accuracy()
show_shared_val_accuracy( vm_accuracy, only_total )
if __name__ == '__main__': main()
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh -e
exit 0
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh -e
find /etc/update-motd.d -type f,l ! -name '98*' -delete
/bin/run-parts /etc/update-motd.d
exit 0
Executable
+289
View File
@@ -0,0 +1,289 @@
#!/usr/bin/perl
################################################################################ rt - restic wrapper (mwx'2026)
use File::Basename;use Term::ReadKey;use Getopt::Std;getopts('c:n:i:t:p:');
$VERSION='1.5.6';
$CONFIG='default';$CONFIG=$opt_c if ($opt_c!~/^\s*$/); # set deault options options
chomp($host=`hostname`);$host=~s/^([^\.]+).*/$1/;
$NAME=$host;
$POLICY='--keep-daily 14 --keep-weekly 12 --keep-monthly 12 --keep-yearly 100';
for ('/db/etc/rt.conf',$ENV{"HOME"}.'/.rt.conf') { $CONF=$_ if (-f $_);} # find/load/check configuration
die "Fatal: no config file found\n" if ($CONF=~/^\s*$/);
require($CONF);
$NAME = $opt_n if ($opt_n!~/^\s*$/); # overwrite options with commandline (name, id, tag, password)
$ID = $opt_i if ($opt_i!~/^\s*$/);
$TAG = $opt_t if ($opt_t!~/^\s*$/);
$PASSWORD = $opt_p if ($opt_p!~/^\s*$/);
for ('$NAME','$TARGET','$SRC','$RESTIC','$LOG') {
die "Fatal: missing $_ in config\n" if (eval($_)=~/^\s*$/);
}
$ID='0' if ($ID=~/^\s*$/); # set repository
$REPOSITORY="$TARGET/$NAME.$ID";
print "rt $VERSION, Name: $NAME, Repository: $REPOSITORY, Config: $CONFIG\n";
open(PW,"> $PWFILE");print PW "$PASSWORD\n";close(PW);
$ENV{'RESTIC_REPOSITORY'} = $REPOSITORY; # set environment
$ENV{'RESTIC_PASSWORD_FILE'} = $PWFILE;
$r=`$RESTIC version`; # find restic version
if ($r=~/restic\s+([\d\.]+)\s+compiled/) {
$RVERSION=$1;
@RV=split('\.',$1);$RVN=sprintf("%02d%02d%02d",$RV[0],$RV[1],$RV[2]);
}
$TMP="/tmp";
my(@z)=localtime(time());$z[4]+=1;$z[5]-=100;$z[6]+=1;
$z=sprintf("%02d\.%02d\.%02d %02d\:%02d",$z[3],$z[4],$z[5],$z[2],$z[1]);
if ($ARGV[0] eq 'cleanup') { # ----------------------------------------------------------- forget, prune, check
$ts=time();
print "$RESTIC -r $REPOSITORY forget $POLICY --prune\n"; # forget & prune
$rms=0;
open(IN,"$RESTIC forget $POLICY --prune |");
while(<IN>) {
print;
$rms=$1 if (/^(\d+)\s+snapshots\s+have\s+been\s+removed/)
}
print "$RESTIC -r $REPOSITORY check\n"; # check
open(IN,"$RESTIC check |");
while(<IN>) {
print;
chomp($lastline=$_);
}
$rt=time()-$ts;
if ($HTTP_LOG!~/^\s*$/) { # http loging
$tmp= "RTC,$VERSION/$RVERSION,$NAME,$ID,$CONFIG,$TAG,$REPOSITORY,$lastline,$rms,$rt";
use LWP::UserAgent;
my $ua = new LWP::UserAgent();
$response = $ua->post("https://$HTTP_LOG", Content => $tmp);
}
if ($MY_HOST!~/^\s*$/) { # mysql loging
use DBI;
$dbh=DBI->connect("DBI:mysql:$MY_DB:$MY_HOST:$MY_PORT",$MY_USER,$MY_PASSWD,{RaiseError=>1,PrintError=>1});
$sql="INSERT INTO resticcleanup VALUES(now(),'$VERSION/$RVERSION',
'$NAME','$ID','$CONFIG','$TAG','$REPOSITORY','$lastline',$rms,$rt)";
$dbh->do($sql);
}
} elsif ($ARGV[0] eq 'backup' || $ARGV[0] eq 'delaybackup') { # ----------------------------------- run backup
$snap='';$added='';$total='';
if ($ARGV[0] eq 'delaybackup') {
printf "$z --- delaybackup (%d sec) ---\n",&dfn($NAME);
sleep(&dfn($NAME))
} else {
printf "$z --- backup ---\n";
}
print "$RESTIC -r $REPOSITORY -vv backup $EXCLUDE $SRC\n";
$ts=time();
open(IN,"$RESTIC -vv backup $EXCLUDE $SRC |");
while(<IN>) {
print if (!/^unchanged/);
if (/Files:\s*(\d+)\s*new,\s*(\d+)\s*changed,\s*(\d+)\s*unmodified/) {
$fn+=$1;$fc+=$2;$fu+=$3;
}
if (/Dirs:\s*(\d+)\s*new,\s*(\d+)\s*changed,\s*(\d+)\s*unmodified/) {
$fn+=$1;$fc+=$2;$fu+=$3;
}
$snap=$1 if (/snapshot\s+([^\s]+)\s+saved/);
$added=&deform($1) if (/Added\s+to\s+the\s+repo:\s+(.*)/);
$added=&deform($1) if (/Added\s+to\s+the\s+repository:\s+([^\(]*)/);
$total=&deform($1) if (/processed\s+\d+\s+files,\s+(.*)\s+in/);
$files=$1 if (/processed\s+(\d+)\s+files,\s+.*\s+in/);
}
if ($snap!~/^\s*$/ && $added!~/^\s*$/ && $total!~/^\s*$/) {
$rt=time()-$ts;
open(LOG,">> $LOG"); # write logfile
print LOG "$z [$NAME/$snap], Files: $files, New: $fn, Changed: $fc, ".
"Unmodified: $fu, Added: $added, Total: $total, Runtime: $rt\n";
close(LOG);
if ($HTTP_LOG!~/^\s*$/) { # http loging
$tmp= "RT,$VERSION/$RVERSION,$NAME,$ID,$CONFIG,$TAG,$REPOSITORY,".
"$snap,$files,$fn,$fc,$fu,$added,$total,$rt";
use LWP::UserAgent;
my $ua = new LWP::UserAgent();
$response = $ua->post("https://$HTTP_LOG", Content => $tmp);
}
if ($MY_HOST!~/^\s*$/) { # mysql loging
use DBI;
$dbh=DBI->connect("DBI:mysql:$MY_DB:$MY_HOST:$MY_PORT",$MY_USER,$MY_PASSWD,{RaiseError=>1,PrintError=>1});
$sql="INSERT INTO restic VALUES(now(),'$VERSION/$RVERSION',
'$NAME','$ID','$CONFIG','$TAG','$REPOSITORY','$snap',$files,$fn,$fc,$fu,$added,$total,$rt)";
$dbh->do($sql);
}
}
} elsif ($ARGV[0] eq 'password') { # ----------------------------------------------- setup restic password file
system("mkdir -p ".&dirname($PWFILE)) if (!-d &dirname($PWFILE));
print "new repository password: ";
chomp($pwd = &ReadLine(0));
if ($pwd!~/^\s*$/) {
open(OUT,"> $PWFILE");print OUT "$pwd\n";close(OUT);
}
} elsif ($ARGV[0] eq 'help' || $ARGV[0]=~/^\s*$/) { # ----------------------------------------------- show help
&help();
&advhelp() if ($ARGV[0] eq 'help');
} else { # ------------------------------------------------------------------------------ other restic commands
system("$RESTIC @ARGV");
if ($ARGV[0] eq 'init') {
system("rm -f /var/log/restic.log /var/log/rt.log");
}
}
####################################################################################################### SUPPORT
sub deform() { # transform sizes
my($s)=@_;
return $1<<40 if ($s=~/([\d\.]+)\s*TiB/i);
return $1<<30 if ($s=~/([\d\.]+)\s*GiB/i);
return $1<<20 if ($s=~/([\d\.]+)\s*MiB/i);
return $1<<10 if ($s=~/([\d\.]+)\s*KiB/i);
return $1 if ($s=~/([\d\.]+)\s*B/i);
}
sub dfn() { # calculate delay from string
my($s)=@_;my $v=0;my $n=1;
$v+=ord($_)*$n++ for (split('',$s));
return ($v%24)*5*60;
}
sub help() { # help
print "\nrt v$VERSION - restic wrapper (mwx'2022)\n";
print <<'ENDOFHELP';
USAGE:
------
rt [options] backup run restic backup
rt [options] delaybackup run delayed restic backup
rt [options] cleanup run forget, prune and check
rt [options] password setup restic password file
rt [options] init initialize restic repository
rt help advanced help
rt <command> other commands will be forwarded directly to restic
options: -c <config> sets $CONFIG (default is 'default')
-n <name> overwrite $NAME
-i <id> overwrite $ID
-t <tag> overwrite $TAG
-p <password> overwrite $PASSWORD
ENDOFHELP
}
sub advhelp() { # advanced help
print <<'ENDOFHELP';
CONFIG FILE (/db/etc/rt.conf)
-----------------------------
$NAME = 'NAME'; # backup name
$ID = '0'; # repository id (optional, default is 0)
$TAG = 'TAG'; # custom tag for logging (optional)
$TARGET = "/backup/restic"; # restic target
= "s3:http://188.68.34.116:9234/restic";
= "b2:mwx002:restic/server";
$SRC = '/etc /db /var /root /home /usr/local /opt'; # source paths
$EXCLUDE = '-e /var/lib/lxcfs -e /var/log/journal'; # exclude options
$RESTIC = '/db/bin/restic'; # restic binary
$LOG = '/var/log/restic.log'; # log file
$PWFILE = '/db/etc/restic.pw'; # restic password file
$HTTP_LOG = 'HOST'; # host for logging via https
$MY_HOST = 'HOST'; # mysql host
$MY_PORT = 'PORT'; # mysql port
$MY_USER = 'USER'; # mysql user
$MY_PASSWD = 'PASSWORD'; # mysql password
$MY_DB = 'DATABASE'; # mysql database
$ENV{'AWS_ACCESS_KEY_ID'} = '123456'; # S3 token example
$ENV{'AWS_SECRET_ACCESS_KEY'} = 'abcdefg';
$ENV{'B2_ACCOUNT_ID'} = '123456'; # B2 token example
$ENV{'B2_ACCOUNT_KEY'} = 'abcdefg';
MYSQL LOGGING TABLES:
---------------------
CREATE TABLE `restic` (
`ts` timestamp NULL DEFAULT NULL,
`version` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`id` int(11) DEFAULT NULL,
`config` varchar(255) DEFAULT NULL,
`tag` varchar(255) DEFAULT NULL,
`repository` varchar(255) DEFAULT NULL,
`snapshot` varchar(255) DEFAULT NULL,
`files` bigint(11) DEFAULT NULL,
`new` bigint(11) DEFAULT NULL,
`changed` bigint(11) DEFAULT NULL,
`unmodified` bigint(11) DEFAULT NULL,
`added` bigint(11) DEFAULT NULL,
`total` bigint(11) DEFAULT NULL,
`runtime` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `resticcleanup` (
`ts` timestamp NULL DEFAULT NULL,
`version` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`id` int(11) DEFAULT NULL,
`config` varchar(255) DEFAULT NULL,
`tag` varchar(255) DEFAULT NULL,
`repository` varchar(255) DEFAULT NULL,
`txt` varchar(255) DEFAULT NULL,
`rmsnap` int(11) DEFAULT NULL,
`runtime` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CRONTAB ENTRIES:
---------------
0 2 * * * /db/bin/rt delaybackup >> /var/log/rt.log 2>&1
0 7 * * 6 /db/bin/rt cleanup >> /var/log/rt.log 2>&1
ENDOFHELP
}
########################################################################################################### END
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/perl
####################################################################### telemetry collector - v1.0.0 (mwx'2020)
use LWP::UserAgent;
chomp($host=`hostname`);$host=~s/\..*$//i;
$url = 'http://monitor.rz-berlin.mpg.de/telemetry.php';
############################################################################################ collect disk usage
$data = "df,$host,";
open(IN,"/bin/df -k -T |");
while(<IN>) {
@df=split(' ');
if ($df[1]=~/^ext/ || $df[1]=~/^nfs/) {
$total=($df[2]/1024/1024);
$avail=($df[4]/1024/1024);
$used=$total - $avail;
$per=$used*100/$total;
$data.=sprintf("$df[6],%.3f,%.3f,%.3f,%.2f,",$total,$avail,$used,$per);
}
}
$data .= time();
print "$data\n";
my $ua = new LWP::UserAgent();
$response = $ua->post($url, Content => $data);
########################################################################################### collect system load
open(UPTIME,"/usr/bin/uptime |");chomp($_=<UPTIME>);
if (/load\s*averages*\:\s*[\d\.]+\,\s*[\d\.]+\,\s*([\d\.]+)/) {
$load=$1;
}
$data = "load,$host,$load,".time();
print "$data\n";
my $ua = new LWP::UserAgent();
$response = $ua->post($url, Content => $data);
########################################################################################################### END
+26
View File
@@ -0,0 +1,26 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# Entries in this file show the compile time defaults. Local configuration
# should be created by either modifying this file (or a copy of it placed in
# /etc/ if the original file is shipped in /usr/), or by creating "drop-ins" in
# the /etc/systemd/timesyncd.conf.d/ directory. The latter is generally
# recommended. Defaults can be restored by simply deleting the main
# configuration file and all drop-ins located in /etc/.
#
# Use 'systemd-analyze cat-config systemd/timesyncd.conf' to display the full config.
#
# See timesyncd.conf(5) for details.
[Time]
NTP=de.pool.ntp.org
FallbackNTP=ptbtime1.ptb.de 0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
#RootDistanceMaxSec=5
#PollIntervalMinSec=32
#PollIntervalMaxSec=2048
#ConnectionRetrySec=30
#SaveIntervalSec=60
+96
View File
@@ -0,0 +1,96 @@
unsetopt always_last_prompt
autoload -U colors && colors
zle_highlight+=(paste:none)
unsetopt BEEP
autoload -U compinit
compinit
bindkey "\e[3~" delete-char
bindkey '^[[F' end-of-line
bindkey '^[[H' beginning-of-line
bindkey '^[[6~' end-of-line
bindkey '^[[5~' beginning-of-line
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
setopt HIST_REDUCE_BLANKS
setopt EXTENDED_HISTORY
setopt INC_APPEND_HISTORY
setopt HIST_EXPIRE_DUPS_FIRST
setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_ALL_DUPS
setopt HIST_IGNORE_SPACE
setopt HIST_SAVE_NO_DUPS
setopt HIST_REDUCE_BLANKS
setopt HIST_VERIFY
setopt HIST_BEEP
setopt SHARE_HISTORY
HN=`hostname -s`
PP=">"; if [[ $USER == "root" ]] then PP=">>" fi
PROMPT="%n@${HN}:%{$fg[white]%}%~%{$reset_color%} $PP "
alias a='alias'
alias h='history -d -10000'
alias L='last -16'
alias ls='ls -F'
alias ll='ls -lsh'
alias lt='ls -ltrh'
alias lla='ls -lsah'
alias lta='ls -ltrah'
alias s='ssh'
alias sr='ssh -l root'
alias rs='rsync -va --delete --stats'
alias p='ps -ef | grep ${LOGNAME}'
alias P='ps -ef'
alias af='apt-cache search'
alias ai='apt-get install'
alias sd='lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL'
alias ga='git add -v .'
alias gb='git branch'
alias gs='git status'
alias gl="git log -32 --reverse --date=local --format='%h %cd %s'"
alias gc='git commit -m'
alias gu='git checkout'
alias gp='git push'
alias y='yazi'
alias f='fzf'
export TERM=xterm-256color
export COLORTERM=truecolor
PATH=/db/bin:"$PATH"
if [ -f /db/go/bin/go ]; then
PATH="$PATH":/db/go/bin:$(/db/go/bin/go env GOPATH)/bin
export CGO_ENABLED=0
fi
tcsh_autolist() { if [[ -z ${LBUFFER// } ]]
then BUFFER="ls " CURSOR=3 zle list-choices
else zle expand-or-complete-prefix; fi }
zle -N tcsh_autolist
bindkey '^I' tcsh_autolist
if [ -f /etc/zshcomp ]; then
source /etc/zshcom
fi
[ -f /etc/zsh/zshcomp ] && source /etc/zsh/zshcomp
if [ -f /db/etc/omp.json ]; then
if (( $+commands[oh-my-posh] )); then
eval "$(oh-my-posh init zsh --config /db/etc/omp.json )";
fi
fi
if (( $+commands[lsd] )); then
alias lx='lsd --icon never --tree -la'
alias ll='lsd --icon never -la'
alias lt='lsd --icon never -latr'
alias ls='lsd --icon never -a'
fi
Executable
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/bash
# Fetch latest version name (e.g., go1.26.2)
RELEASE=$(curl -sL https://go.dev/VERSION?m=text | head -n 1)
# Detect OS and Architecture
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
[ "$ARCH" == "x86_64" ] && ARCH="amd64"
[ "$ARCH" == "aarch64" ] && ARCH="arm64"
# Download and Extract
FILE="${RELEASE}.${OS}-${ARCH}.tar.gz"
URL="https://go.dev/dl/$FILE"
echo "Downloading $FILE $URL..."
wget $URL
rm -rf /db/go && tar -C /db -xzf $FILE
export PATH=/db/go/bin:~/go/bin:$PATH
export CGO_ENABLED=0
/db/go/bin/go install golang.org/x/tools/cmd/goimports@latest
+83
View File
@@ -0,0 +1,83 @@
Revision history for Perl extension MD5.
*** 96/06/20 Version 1.7
MD5 is now completely 64-bit clean (I hope). The basic MD5 code uses
32-bit quantities and requires a typedef UINT4 to be defined in
global.h. Perl configuration data (the value of BYTEORDER) is used to
determine if unsigned longs have 4 or 8 bytes. On 64-bit platforms (eg
DEC Alpha) then it assumes that "unsigned int" will be a 32-bit type.
If this is incorrect then adding -DUINT4_IS_LONG to the DEFINES line in
Makefile.PL will override this.
On some machines (at least Cray that I know of) there is no 32-bit
integer type. In this case defining TRUNCATE_UINT4 (which is done
automatically for a Cray) will ensure that 64-bit values are masked
down to 32 bits. I have done my best to test this but without easy
access to a true 64-bit machine I can not totally guarantee it (unless
anyone wants to lend me a spare Cray :-)
There is one remaining limitation for 64-bit enabled processors. The
amount of data passed to any single call to the underlying MD5
routines is limited to (2^32 - 1) bytes -- that's 4 gigabytes. I'm
sorry if that's a real problem for you ...
And finally, a minor complilation warning (unsigned char * used with
function having char * prototype) has also been eliminated.
*** 96/04/09 Version 1.6
Re-generated module framework using h2xs to pick up the latest module
conventions for versions etc. You can now say "use MD5 1.6;" and things
should work correctly. MD5.pod has been integrated into MD5.pm and
CHANGES renamed to Changes. There is a fairly comprehensive test.pl
which can be invoked via "make test". There are no functional changes
to the MD5 routines themselves.
*** 96/03/14 Version 1.5.3
Fixed addfile method to accept type-glob references for the file-handle
(eg \*STDOUT). This is more consistent with other routines and is now the
recommended way of passing file-handles. The documentation now gives more
examples as to how the routines might be used.
*** 96/03/12 Version 1.5.2
Minor fixes from Christopher J Madsen <madsen@computek.net> to provide
support for building on OS/2 (and to work arround a perl -w bug).
Remove warning about possible difference between add('foo', 'bar') and
add('foobar'). This is not true (it may have been true in the earliest
version of the module but is no longer the case).
*** 96/03/08 Version 1.5.1
Add CHANGES file to make it easier for people to figure out what has
been going on. (Meant to do this as part of 1.5)
*** 96/03/05 Version 1.5
Add hash() and hexhash() methods at the suggestion/request of Gary
Howland <gary@kampai.euronet.nl> before inclusion in a wider library
of cryptography modules.
*** 96/02/27 Version 1.4
Finally fixed the pesky Solaris dynamic loading bug. All kudos to Ken
Pizzini <kenp@spry.com>!
*** 95/11/29 Version 1.3.1
Add explanations of current known problems.
*** 95/06/02 Version 1.3
Fix problems with scope resolution in addfile() reported by
Jean-Claude Giese <Jean-Claude.Giese@loria.fr>. Basically ARGV is
always implicitly in package main while other filehandles aren't.
*** 95/05/23 Version 1.2.1
[Changes pre 1.2.1 not recorded]
SCCS ID @(#)Changes 1.5 96/06/28
+13
View File
@@ -0,0 +1,13 @@
README Guess what?
MANIFEST This file
MD5.pm MD5 Perl Module
MD5.xs MD5 Perl 'XS' source file
typemap Supplementary typemap
Makefile.PL Perl Makefile builder
md5c.c MD5 C source from RFC 1321
md5.h Header for above
global.h ditto
test.pl Test suite using standard Perl conventions
Changes Version history
examples/mddriver.pl Example driver script after mddriver.c in RFC 1321
examples/twdigest.pl Example code to format a digest like Tripwire
+263
View File
@@ -0,0 +1,263 @@
# SCCS ID @(#)MD5.pm 1.9 96/06/28
package MD5;
use strict;
use vars qw($VERSION @ISA @EXPORT);
require Exporter;
require DynaLoader;
require AutoLoader;
@ISA = qw(Exporter AutoLoader DynaLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
);
$VERSION = '1.7';
bootstrap MD5 $VERSION;
# Preloaded methods go here.
sub addfile
{
no strict 'refs'; # Countermand any strct refs in force so that we
# can still handle file-handle names.
my ($self, $handle) = @_;
my ($package, $file, $line) = caller;
my ($data) = '';
if (!ref($handle))
{
# Old-style passing of filehandle by name. We need to add
# the calling package scope qualifier, if there is not one
# supplied already.
$handle = $package . '::' . $handle unless ($handle =~ /(\:\:|\')/);
}
while (read($handle, $data, 1024))
{
$self->add($data);
}
}
sub hexdigest
{
my ($self) = shift;
unpack("H*", ($self->digest()));
}
sub hash
{
my ($self, $data) = @_;
if (ref($self))
{
# This is an instance method call so reset the current context
$self->reset();
}
else
{
# This is a static method invocation, create a temporary MD5 context
$self = new MD5;
}
# Now do the hash
$self->add($data);
$self->digest();
}
sub hexhash
{
my ($self, $data) = @_;
unpack("H*", ($self->hash($data)));
}
# Autoload methods go after =cut, and are processed by the autosplit program.
1;
__END__
=head1 NAME
MD5 - Perl interface to the RSA Data Security Inc. MD5 Message-Digest Algorithm
=head1 SYNOPSIS
use MD5;
$context = new MD5;
$context->reset();
$context->add(LIST);
$context->addfile(HANDLE);
$digest = $context->digest();
$string = $context->hexdigest();
$digest = MD5->hash(SCALAR);
$string = MD5->hexhash(SCALAR);
=head1 DESCRIPTION
The B<MD5> module allows you to use the RSA Data Security Inc. MD5
Message Digest algorithm from within Perl programs.
A new MD5 context object is created with the B<new> operation.
Multiple simultaneous digest contexts can be maintained, if desired.
The context is updated with the B<add> operation which adds the
strings contained in the I<LIST> parameter. Note, however, that
C<add('foo', 'bar')>, C<add('foo')> followed by C<add('bar')> and
C<add('foobar')> should all give the same result.
The final message digest value is returned by the B<digest> operation
as a 16-byte binary string. This operation delivers the result of
B<add> operations since the last B<new> or B<reset> operation. Note
that the B<digest> operation is effectively a destructive, read-once
operation. Once it has been performed, the context must be B<reset>
before being used to calculate another digest value.
Several convenience functions are also provided. The B<addfile>
operation takes an open file-handle and reads it until end-of file in
1024 byte blocks adding the contents to the context. The file-handle
can either be specified by name or passed as a type-glob reference, as
shown in the examples below. The B<hexdigest> operation calls
B<digest> and returns the result as a printable string of hexdecimal
digits. This is exactly the same operation as performed by the
B<unpack> operation in the examples below.
The B<hash> operation can act as either a static member function (ie
you invoke it on the MD5 class as in the synopsis above) or as a
normal virtual function. In both cases it performs the complete MD5
cycle (reset, add, digest) on the supplied scalar value. This is
convenient for handling small quantities of data. When invoked on the
class a temporary context is created. When invoked through an already
created context object, this context is used. The latter form is
slightly more efficient. The B<hexhash> operation is analogous to
B<hexdigest>.
=head1 EXAMPLES
use MD5;
$md5 = new MD5;
$md5->add('foo', 'bar');
$md5->add('baz');
$digest = $md5->digest();
print("Digest is " . unpack("H*", $digest) . "\n");
The above example would print out the message
Digest is 6df23dc03f9b54cc38a0fc1483df6e21
provided that the implementation is working correctly.
Remembering the Perl motto ("There's more than one way to do it"), the
following should all give the same result:
use MD5;
$md5 = new MD5;
die "Can't open /etc/passwd ($!)\n" unless open(P, "/etc/passwd");
seek(P, 0, 0);
$md5->reset;
$md5->addfile(P);
$d = $md5->hexdigest;
print "addfile (handle name) = $d\n";
seek(P, 0, 0);
$md5->reset;
$md5->addfile(\*P);
$d = $md5->hexdigest;
print "addfile (type-glob reference) = $d\n";
seek(P, 0, 0);
$md5->reset;
while (<P>)
{
$md5->add($_);
}
$d = $md5->hexdigest;
print "Line at a time = $d\n";
seek(P, 0, 0);
$md5->reset;
$md5->add(<P>);
$d = $md5->hexdigest;
print "All lines at once = $d\n";
seek(P, 0, 0);
$md5->reset;
while (read(P, $data, (rand % 128) + 1))
{
$md5->add($data);
}
$d = $md5->hexdigest;
print "Random chunks = $d\n";
seek(P, 0, 0);
$md5->reset;
undef $/;
$data = <P>;
$d = $md5->hexhash($data);
print "Single string = $d\n";
close(P);
=head1 NOTE
The MD5 extension may be redistributed under the same terms as Perl.
The MD5 algorithm is defined in RFC1321. The basic C code implementing
the algorithm is derived from that in the RFC and is covered by the
following copyright:
=over 8
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
=back
This copyright does not prohibit distribution of any version of Perl
containing this extension under the terms of the GNU or Artistic
licences.
=head1 AUTHOR
The MD5 interface was written by Neil Winton
(C<N.Winton@axion.bt.co.uk>).
=head1 SEE ALSO
perl(1).
=cut
+101
View File
@@ -0,0 +1,101 @@
/*
** Perl Extension for the
**
** RSA Data Security Inc. MD5 Message-Digest Algorithm
**
** This module by Neil Winton (N.Winton@axion.bt.co.uk)
** SCCS ID @(#)MD5.xs 1.7 96/06/28
**
** This extension may be distributed under the same terms
** as Perl. The MD5 code is covered by separate copyright and
** licence, but this does not prohibit distribution under the
** GNU or Artistic licences. See the file md5c.c or MD5.pm
** for more details.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "global.h"
#include "md5.h"
/*
** The following macro re-definitions added to work around a problem on
** Solaris where the original MD5 routines are already in /lib/libnsl.a.
** This causes dynamic linking of the module to fail.
** Thanks to Ken Pizzini (ken@spry.com) for finally nailing this one!
*/
#define MD5Init MD5Init_perl
#define MD5Update MD5Update_perl
#define MD5Final MD5Final_perl
typedef MD5_CTX *MD5;
#ifdef __cplusplus
}
#endif
MODULE = MD5 PACKAGE = MD5
PROTOTYPES: DISABLE
MD5
new(packname = "MD5")
char * packname
CODE:
{
RETVAL = (MD5_CTX *)safemalloc(sizeof(MD5_CTX));
MD5Init(RETVAL);
}
OUTPUT:
RETVAL
void
DESTROY(context)
MD5 context
CODE:
{
safefree((char *)context);
}
void
reset(context)
MD5 context
CODE:
{
MD5Init(context);
}
void
add(context, ...)
MD5 context
CODE:
{
SV *svdata;
STRLEN len;
unsigned char *data;
int i;
for (i = 1; i < items; i++)
{
data = (unsigned char *)(SvPV(ST(i), len));
MD5Update(context, data, len);
}
}
SV *
digest(context)
MD5 context
CODE:
{
unsigned char digeststr[16];
MD5Final(digeststr, context);
ST(0) = sv_2mortal(newSVpv((char *)digeststr, 16));
}
+13
View File
@@ -0,0 +1,13 @@
# SCCS ID @(#)Makefile.PL 1.10 96/06/28
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
'NAME' => 'MD5',
'VERSION_FROM' => 'MD5.pm', # finds $VERSION
'LIBS' => [''], # e.g., '-lm'
'CONFIG' => ['byteorder'], # Used to determine 64-bitness
'DEFINE' => '-DPERL_BYTEORDER=$(BYTEORDER)',
'INC' => '', # e.g., '-I/usr/include/other'
'OBJECT' => q[MD5$(OBJ_EXT) md5c$(OBJ_EXT)],
);
File diff suppressed because it is too large Load Diff
+42
View File
@@ -0,0 +1,42 @@
MD5 Extension Version 1.7
This is a Perl5 extension interface to the RSA Data Security Inc. MD5
Message Digest algorithm. Documentation is in MD5.pod.
To build the extension, unpack this distribution under the ext/
directory of your Perl source distribution, create the Makefile using
'perl Makefile.PL' and do a 'make'.
Note that the MD5.xs file uses the "PROTOTYPES: DISABLE" facility
which only became available in late betas pf perl 5.002. If you are
using a version which does not support this then merely remove
this line.
The mddriver.pl script gives a simple example of how to use the
routines. In particular 'perl mddriver.pl -x' will perform a quick
test of the routines to see if they produce the expected output. The
use of "make test" will perform a more comprehensive test. (WARNING:
You should not run mddriver.pl directly in the MD5 directory when using
dynamic linking as on some systems it will dynamically link to object
files in the current directory which may not give the correct
behaviour. This is believed to affect at least AIX and IRIX. A similar
caveat applies to the direct use of the test.pl script).
The module is known to work (using static or dynamic linking) on at
least AIX, Solaris, HP-UX and IRIX. It should work on other
"reasonable" UNIX-like platforms (for an unspecified definition of the
word "reasonable" :-)
Support is also provided for 64-bit platforms. This should be detected
and handled automatically. See the entry for version 1.7 in the
Changes file for further details.
Bugs, queries, plaudits to
Neil Winton
* Neil Winton Post Point P5 *
* N.Winton@axion.bt.co.uk BT Laboratories *
* Tel +44 1473 646079 Martlesham Heath *
* Fax +44 1473 643306 IPSWICH IP5 7RE, UK *
+69
View File
@@ -0,0 +1,69 @@
#!/usr/local/bin/perl
# SCCS ID @(#)mddriver.pl 1.3 95/05/01
require 'getopts.pl';
use MD5;
sub DoTest;
&Getopts('s:x');
$md5 = new MD5;
if (defined($opt_s))
{
$md5->add($opt_s);
$digest = $md5->digest();
print("MD5(\"$opt_s\") = " . unpack("H*", $digest) . "\n");
}
elsif ($opt_x)
{
DoTest("", "d41d8cd98f00b204e9800998ecf8427e");
DoTest("a", "0cc175b9c0f1b6a831c399e269772661");
DoTest("abc", "900150983cd24fb0d6963f7d28e17f72");
DoTest("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
DoTest("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
DoTest("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"d174ab98d277d9f5a5611c2c9f419d9f");
DoTest("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
"57edf4a22be3c955ac49da2e2107b67a");
}
else
{
if ($#ARGV >= 0)
{
foreach $ARGV (@ARGV)
{
die "Can't open file '$ARGV' ($!)\n" unless open(ARGV, $ARGV);
$md5->reset();
$md5->addfile(ARGV);
$hex = $md5->hexdigest();
print "MD5($ARGV) = $hex\n";
close(ARGV);
}
}
else
{
$md5->reset();
$md5->addfile(STDIN);
$hex = $md5->hexdigest();
print "$hex\n";
}
}
exit 0;
sub DoTest
{
my ($str, $expect) = @_;
my ($digest, $hex);
my $md5 = new MD5;
$md5->add($str);
$digest = $md5->digest();
$hex = unpack("H*", $digest);
print "MD5(\"$str\") =>\nEXPECT: $expect\nRESULT: $hex\n"
}
+35
View File
@@ -0,0 +1,35 @@
#!/usr/local/bin/perl
use MD5;
#
# twdigest -- format MD5 digest like TripWire does
#
# This converts the md5->digest binary string to
# 64-radix ascii, given the base-vector:
# 0 - 9, A - Z, a - z, :, .
#
sub twdigest {
my($digest) = @_;
my(@chunks, $bits);
# Convert to ASCII bit-string
$bits = unpack("B*", $digest);
# Round up length to multiple of 6 by prepending zeros
$bits = ("0" x ((6 - (length($bits) % 6)) % 6)) . $bits;
# Split into 6-bit chunks
@chunks = grep {$_ ne ''} (split(/(.{6})/, $bits, -1));
# Convert each 6-bit value to a single character
foreach (@chunks)
{
$_ = pack("B8", "00" . $_);
tr/\000-\011\012-\043\044-\075\076\077/0-9A-Za-z:./;
}
# Join all of the chunks into one string
join('', @chunks);
}
+49
View File
@@ -0,0 +1,49 @@
/* GLOBAL.H - RSAREF types and constants
*/
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
#define PROTOTYPES 0
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word.
We use the Perl byte-order definition to discover if a long has more than
4 bytes. If so we will try to use an unsigned int. This is OK for DEC
Alpha but may not work everywhere. See the TO32 definition below.
*/
#if (PERL_BYTEORDER <= 4321) || defined(UINT4_IS_LONG)
typedef unsigned long UINT4;
#else
typedef unsigned int UINT4;
#endif
/* TO32 ensures that UINT4 values are truncated to 32 bits.
A Cray has short, int and long all at 64 bits so we need to apply this
macro to reduce UINT4 values to 32 bits at appropriate places. If UINT4
really does have 32 bits then this is a no-op.
*/
#if defined(cray) || defined(TRUNCATE_UINT4)
#define TO32(x) ((x) & 0xffffffff)
#else
#define TO32(x) (x)
#endif
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif
+36
View File
@@ -0,0 +1,36 @@
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init PROTO_LIST ((MD5_CTX *));
void MD5Update PROTO_LIST
((MD5_CTX *, unsigned char *, unsigned long));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+351
View File
@@ -0,0 +1,351 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/*
** The following macro re-definitions added to work around a problem on
** Solaris where the original MD5 routines are already in /lib/libnsl.a.
** This causes dynamic linking of the module to fail.
**
** Thanks to Ken Pizzini (ken@spry.com) for finally nailing this one!
*/
#define MD5Init MD5Init_perl
#define MD5Update MD5Update_perl
#define MD5Final MD5Final_perl
#include "global.h"
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned long));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned long));
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned long));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned long));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) TO32((((x) & (y)) | ((~x) & (z))))
#define G(x, y, z) TO32((((x) & (z)) | ((y) & (~z))))
#define H(x, y, z) TO32(((x) ^ (y) ^ (z)))
#define I(x, y, z) TO32(((y) ^ ((x) | (~z))))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) TO32((((x) << (n)) | (TO32((x)) >> (32-(n)))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TO32((a)); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TO32((a)); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TO32((a)); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TO32((a)); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned long inputLen; /* length of input block */
{
unsigned long i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned long)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if (TO32(context->count[0] += (inputLen << 3))
< TO32(inputLen << 3))
context->count[1]++;
context->count[1] += (inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
unsigned char bits[8];
unsigned long index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned long)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a; TO32(state[0]);
state[1] += b; TO32(state[1]);
state[2] += c; TO32(state[2]);
state[3] += d; TO32(state[3]);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned long len;
{
unsigned long i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned long len;
{
unsigned long i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned long len;
{
unsigned long i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned long len;
{
unsigned long i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
+154
View File
@@ -0,0 +1,154 @@
# SCCS ID @(#)test.pl 1.1 96/04/09
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.pl'
######################### We start with some black magic to print on failure.
# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)
BEGIN {print "1..14\n";}
END {print "not ok 1\n" unless $loaded;}
use MD5;
$loaded = 1;
print "ok 1\n";
######################### End of black magic.
# Insert your test code below (better if it prints "ok 13"
# (correspondingly "not ok 13") depending on the success of chunk 13
# of the test code):
package MD5Test;
# 2: Constructor
print (($md5 = new MD5) ? "ok 2\n" : "not ok 2\n");
# 3: Basic test data as defined in RFC 1321
%data = (
"" => "d41d8cd98f00b204e9800998ecf8427e",
"a" => "0cc175b9c0f1b6a831c399e269772661",
"abc" => "900150983cd24fb0d6963f7d28e17f72",
"message digest"
=> "f96b697d7cb7938d525a2f31aaf161d0",
"abcdefghijklmnopqrstuvwxyz"
=> "c3fcd3d76192e4007dfb496cca67e13b",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
=> "d174ab98d277d9f5a5611c2c9f419d9f",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
=> "57edf4a22be3c955ac49da2e2107b67a",
);
$failed = 0;
foreach (sort(keys(%data)))
{
$md5->reset;
$md5->add($_);
$digest = $md5->digest;
$hex = unpack("H*", $digest);
if ($hex ne $data{$_})
{
$failed++;
}
}
print ($failed ? "not ok 3\n" : "ok 3\n");
# 4: Various flavours of file-handle to addfile
open(F, "<$0");
$md5->reset;
$md5->addfile(F);
$hex = $md5->hexdigest;
print ($hex ne '' ? "ok 4\n" : "not ok 4\n");
$orig = $hex;
# 5: Fully qualified with ' operator
seek(F, 0, 0);
$md5->reset;
$md5->addfile(MD5Test'F);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 5\n" : "not ok 5\n");
# 6: Fully qualified with :: operator
seek(F, 0, 0);
$md5->reset;
$md5->addfile(MD5Test::F);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 6\n" : "not ok 6\n");
# 7: Type glob
seek(F, 0, 0);
$md5->reset;
$md5->addfile(*F);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 7\n" : "not ok 7\n");
# 8: Type glob reference (the prefered mechanism)
seek(F, 0, 0);
$md5->reset;
$md5->addfile(\*F);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 8\n" : "not ok 8\n");
# 9: File-handle passed by name (really the same as 6)
seek(F, 0, 0);
$md5->reset;
$md5->addfile("MD5Test::F");
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 9\n" : "not ok 9\n");
# 10: Other ways of reading the data -- line at a time
seek(F, 0, 0);
$md5->reset;
while (<F>)
{
$md5->add($_);
}
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 10\n" : "not ok 10\n");
# 11: Input lines as a list to add()
seek(F, 0, 0);
$md5->reset;
$md5->add(<F>);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 11\n" : "not ok 11\n");
# 12: Random chunks up to 128 bytes
seek(F, 0, 0);
$md5->reset;
while (read(F, $hexata, (rand % 128) + 1))
{
$md5->add($hexata);
}
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 12\n" : "not ok 12\n");
# 13: All the data at once
seek(F, 0, 0);
$md5->reset;
undef $/;
$data = <F>;
$hex = $md5->hexhash($data);
print ($hex eq $orig ? "ok 13\n" : "not ok 13\n");
close(F);
# 14: Using static member function
$hex = MD5->hexhash($data);
print ($hex eq $orig ? "ok 14\n" : "not ok 14\n");
+3
View File
@@ -0,0 +1,3 @@
# SCCS ID @(#)typemap 1.2 94/11/07
TYPEMAP
MD5 T_PTROBJ
+6
View File
@@ -0,0 +1,6 @@
Revision history for Perl extension mwx.
0.01 Sun Jun 1 18:30:04 2003
- original version; created by h2xs 1.21 with options
-X -n mwx
+6
View File
@@ -0,0 +1,6 @@
Changes
Makefile.PL
MANIFEST
mwx.pm
README
test.pl
+17
View File
@@ -0,0 +1,17 @@
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
'NAME' => 'mwx',
'VERSION_FROM' => 'mwx.pm', # finds $VERSION
'PREREQ_PM' => { Net::SMTP => 0,
MD5 => 0,
Net::NIS => 0,
Math::BigInt => 0,
Time::HiRes => 0,
Term::ReadKey => 0},
($] >= 5.005 ? ## Add these new keywords supported since 5.005
(ABSTRACT_FROM => 'mwx.pm', # retrieve abstract from module
AUTHOR => 'M.Wesemann <mwx@gmx.de>') : ()),
);
+864
View File
@@ -0,0 +1,864 @@
# This Makefile is for the mwx extension to perl.
#
# It was generated automatically by MakeMaker version
# 7.0401 (Revision: 70401) from the contents of
# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
#
# ANY CHANGES MADE HERE WILL BE LOST!
#
# MakeMaker ARGV: ()
#
# MakeMaker Parameters:
# ABSTRACT_FROM => q[mwx.pm]
# AUTHOR => [q[M.Wesemann <mwx@gmx.de>]]
# BUILD_REQUIRES => { }
# CONFIGURE_REQUIRES => { }
# NAME => q[mwx]
# PREREQ_PM => { MD5=>q[0], Math::BigInt=>q[0], Net::NIS=>q[0], Net::SMTP=>q[0], Term::ReadKey=>q[0], Time::HiRes=>q[0] }
# TEST_REQUIRES => { }
# VERSION_FROM => q[mwx.pm]
# --- MakeMaker post_initialize section:
# --- MakeMaker const_config section:
# These definitions are from config.sh (via /usr/lib/x86_64-linux-gnu/perl/5.22/Config.pm).
# They may have been overridden via Makefile.PL or on the command line.
AR = ar
CC = x86_64-linux-gnu-gcc
CCCDLFLAGS = -fPIC
CCDLFLAGS = -Wl,-E
DLEXT = so
DLSRC = dl_dlopen.xs
EXE_EXT =
FULL_AR = /usr/bin/ar
LD = x86_64-linux-gnu-gcc
LDDLFLAGS = -shared -L/usr/local/lib -fstack-protector-strong
LDFLAGS = -fstack-protector-strong -L/usr/local/lib
LIBC = libc-2.23.so
LIB_EXT = .a
OBJ_EXT = .o
OSNAME = linux
OSVERS = 3.16.0
RANLIB = :
SITELIBEXP = /usr/local/share/perl/5.22.1
SITEARCHEXP = /usr/local/lib/x86_64-linux-gnu/perl/5.22.1
SO = so
VENDORARCHEXP = /usr/lib/x86_64-linux-gnu/perl5/5.22
VENDORLIBEXP = /usr/share/perl5
# --- MakeMaker constants section:
AR_STATIC_ARGS = cr
DIRFILESEP = /
DFSEP = $(DIRFILESEP)
NAME = mwx
NAME_SYM = mwx
VERSION = 1.21
VERSION_MACRO = VERSION
VERSION_SYM = 1_21
DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
XS_VERSION = 1.21
XS_VERSION_MACRO = XS_VERSION
XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
INST_ARCHLIB = blib/arch
INST_SCRIPT = blib/script
INST_BIN = blib/bin
INST_LIB = blib/lib
INST_MAN1DIR = blib/man1
INST_MAN3DIR = blib/man3
MAN1EXT = 1p
MAN3EXT = 3pm
INSTALLDIRS = site
DESTDIR =
PREFIX = $(SITEPREFIX)
PERLPREFIX = /usr
SITEPREFIX = /usr/local
VENDORPREFIX = /usr
INSTALLPRIVLIB = /usr/share/perl/5.22
DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
INSTALLSITELIB = /usr/local/share/perl/5.22.1
DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
INSTALLVENDORLIB = /usr/share/perl5
DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
INSTALLARCHLIB = /usr/lib/x86_64-linux-gnu/perl/5.22
DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
INSTALLSITEARCH = /usr/local/lib/x86_64-linux-gnu/perl/5.22.1
DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
INSTALLVENDORARCH = /usr/lib/x86_64-linux-gnu/perl5/5.22
DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
INSTALLBIN = /usr/bin
DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
INSTALLSITEBIN = /usr/local/bin
DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
INSTALLVENDORBIN = /usr/bin
DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
INSTALLSCRIPT = /usr/bin
DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
INSTALLSITESCRIPT = /usr/local/bin
DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT)
INSTALLVENDORSCRIPT = /usr/bin
DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT)
INSTALLMAN1DIR = /usr/share/man/man1
DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
INSTALLSITEMAN1DIR = /usr/local/man/man1
DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
INSTALLVENDORMAN1DIR = /usr/share/man/man1
DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
INSTALLMAN3DIR = /usr/share/man/man3
DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
INSTALLSITEMAN3DIR = /usr/local/man/man3
DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
INSTALLVENDORMAN3DIR = /usr/share/man/man3
DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
PERL_LIB = /usr/share/perl/5.22
PERL_ARCHLIB = /usr/lib/x86_64-linux-gnu/perl/5.22
PERL_ARCHLIBDEP = /usr/lib/x86_64-linux-gnu/perl/5.22
LIBPERL_A = libperl.a
FIRST_MAKEFILE = Makefile
MAKEFILE_OLD = Makefile.old
MAKE_APERL_FILE = Makefile.aperl
PERLMAINCC = $(CC)
PERL_INC = /usr/lib/x86_64-linux-gnu/perl/5.22/CORE
PERL_INCDEP = /usr/lib/x86_64-linux-gnu/perl/5.22/CORE
PERL = "/usr/bin/perl"
FULLPERL = "/usr/bin/perl"
ABSPERL = $(PERL)
PERLRUN = $(PERL)
FULLPERLRUN = $(FULLPERL)
ABSPERLRUN = $(ABSPERL)
PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
PERL_CORE = 0
PERM_DIR = 755
PERM_RW = 644
PERM_RWX = 755
MAKEMAKER = /usr/share/perl/5.22/ExtUtils/MakeMaker.pm
MM_VERSION = 7.0401
MM_REVISION = 70401
# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
# DLBASE = Basename part of dynamic library. May be just equal BASEEXT.
MAKE = make
FULLEXT = mwx
BASEEXT = mwx
PARENT_NAME =
DLBASE = $(BASEEXT)
VERSION_FROM = mwx.pm
OBJECT =
LDFROM = $(OBJECT)
LINKTYPE = dynamic
BOOTDEP =
# Handy lists of source code files:
XS_FILES =
C_FILES =
O_FILES =
H_FILES =
MAN1PODS =
MAN3PODS = mwx.pm
# Where is the Config information that we are using/depend on
CONFIGDEP = $(PERL_ARCHLIBDEP)$(DFSEP)Config.pm $(PERL_INCDEP)$(DFSEP)config.h
# Where to build things
INST_LIBDIR = $(INST_LIB)
INST_ARCHLIBDIR = $(INST_ARCHLIB)
INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT)
INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
INST_STATIC =
INST_DYNAMIC =
INST_BOOT =
# Extra linker info
EXPORT_LIST =
PERL_ARCHIVE =
PERL_ARCHIVEDEP =
PERL_ARCHIVE_AFTER =
TO_INST_PM = mwx.pm
PM_TO_BLIB = mwx.pm \
$(INST_LIB)/mwx.pm
# --- MakeMaker platform_constants section:
MM_Unix_VERSION = 7.0401
PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc
# --- MakeMaker tool_autosplit section:
# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
AUTOSPLITFILE = $(ABSPERLRUN) -e 'use AutoSplit; autosplit($$$$ARGV[0], $$$$ARGV[1], 0, 1, 1)' --
# --- MakeMaker tool_xsubpp section:
# --- MakeMaker tools_other section:
SHELL = /bin/sh
CHMOD = chmod
CP = cp
MV = mv
NOOP = $(TRUE)
NOECHO = @
RM_F = rm -f
RM_RF = rm -rf
TEST_F = test -f
TOUCH = touch
UMASK_NULL = umask 0
DEV_NULL = > /dev/null 2>&1
MKPATH = $(ABSPERLRUN) -MExtUtils::Command -e 'mkpath' --
EQUALIZE_TIMESTAMP = $(ABSPERLRUN) -MExtUtils::Command -e 'eqtime' --
FALSE = false
TRUE = true
ECHO = echo
ECHO_N = echo -n
UNINST = 0
VERBINST = 0
MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install([ from_to => {@ARGV}, verbose => '\''$(VERBINST)'\'', uninstall_shadows => '\''$(UNINST)'\'', dir_mode => '\''$(PERM_DIR)'\'' ]);' --
DOC_INSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'perllocal_install' --
UNINSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'uninstall' --
WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'warn_if_old_packlist' --
MACROSTART =
MACROEND =
USEMAKEFILE = -f
FIXIN = $(ABSPERLRUN) -MExtUtils::MY -e 'MY->fixin(shift)' --
CP_NONEMPTY = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'cp_nonempty' --
# --- MakeMaker makemakerdflt section:
makemakerdflt : all
$(NOECHO) $(NOOP)
# --- MakeMaker dist section:
TAR = tar
TARFLAGS = cvf
ZIP = zip
ZIPFLAGS = -r
COMPRESS = gzip --best
SUFFIX = .gz
SHAR = shar
PREOP = $(NOECHO) $(NOOP)
POSTOP = $(NOECHO) $(NOOP)
TO_UNIX = $(NOECHO) $(NOOP)
CI = ci -u
RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
DIST_CP = best
DIST_DEFAULT = tardist
DISTNAME = mwx
DISTVNAME = mwx-1.21
# --- MakeMaker macro section:
# --- MakeMaker depend section:
# --- MakeMaker cflags section:
# --- MakeMaker const_loadlibs section:
# --- MakeMaker const_cccmd section:
# --- MakeMaker post_constants section:
# --- MakeMaker pasthru section:
PASTHRU = LIBPERL_A="$(LIBPERL_A)"\
LINKTYPE="$(LINKTYPE)"\
LD="$(LD)"\
PREFIX="$(PREFIX)"
# --- MakeMaker special_targets section:
.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir
# --- MakeMaker c_o section:
# --- MakeMaker xs_c section:
# --- MakeMaker xs_o section:
# --- MakeMaker top_targets section:
all :: pure_all manifypods
$(NOECHO) $(NOOP)
pure_all :: config pm_to_blib subdirs linkext
$(NOECHO) $(NOOP)
subdirs :: $(MYEXTLIB)
$(NOECHO) $(NOOP)
config :: $(FIRST_MAKEFILE) blibdirs
$(NOECHO) $(NOOP)
help :
perldoc ExtUtils::MakeMaker
# --- MakeMaker blibdirs section:
blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists
$(NOECHO) $(NOOP)
# Backwards compat with 6.18 through 6.25
blibdirs.ts : blibdirs
$(NOECHO) $(NOOP)
$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_LIBDIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_LIBDIR)
$(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists
$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_ARCHLIB)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHLIB)
$(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists
$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_AUTODIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_AUTODIR)
$(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists
$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHAUTODIR)
$(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists
$(INST_BIN)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_BIN)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_BIN)
$(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists
$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_SCRIPT)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_SCRIPT)
$(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists
$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_MAN1DIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN1DIR)
$(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists
$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_MAN3DIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN3DIR)
$(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists
# --- MakeMaker linkext section:
linkext :: $(LINKTYPE)
$(NOECHO) $(NOOP)
# --- MakeMaker dlsyms section:
# --- MakeMaker dynamic_bs section:
BOOTSTRAP =
# --- MakeMaker dynamic section:
dynamic :: $(FIRST_MAKEFILE) $(BOOTSTRAP) $(INST_DYNAMIC)
$(NOECHO) $(NOOP)
# --- MakeMaker dynamic_lib section:
# --- MakeMaker static section:
## $(INST_PM) has been moved to the all: target.
## It remains here for awhile to allow for old usage: "make static"
static :: $(FIRST_MAKEFILE) $(INST_STATIC)
$(NOECHO) $(NOOP)
# --- MakeMaker static_lib section:
# --- MakeMaker manifypods section:
POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
POD2MAN = $(POD2MAN_EXE)
manifypods : pure_all \
mwx.pm
$(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) -u \
mwx.pm $(INST_MAN3DIR)/mwx.$(MAN3EXT)
# --- MakeMaker processPL section:
# --- MakeMaker installbin section:
# --- MakeMaker subdirs section:
# none
# --- MakeMaker clean_subdirs section:
clean_subdirs :
$(NOECHO) $(NOOP)
# --- MakeMaker clean section:
# Delete temporary files but do not touch installed files. We don't delete
# the Makefile here so a later make realclean still has a makefile to use.
clean :: clean_subdirs
- $(RM_F) \
$(BASEEXT).bso $(BASEEXT).def \
$(BASEEXT).exp $(BASEEXT).x \
$(BOOTSTRAP) $(INST_ARCHAUTODIR)/extralibs.all \
$(INST_ARCHAUTODIR)/extralibs.ld $(MAKE_APERL_FILE) \
*$(LIB_EXT) *$(OBJ_EXT) \
*perl.core MYMETA.json \
MYMETA.yml blibdirs.ts \
core core.*perl.*.? \
core.[0-9] core.[0-9][0-9] \
core.[0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9] \
core.[0-9][0-9][0-9][0-9][0-9] lib$(BASEEXT).def \
mon.out perl \
perl$(EXE_EXT) perl.exe \
perlmain.c pm_to_blib \
pm_to_blib.ts so_locations \
tmon.out
- $(RM_RF) \
blib
$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
- $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)
# --- MakeMaker realclean_subdirs section:
realclean_subdirs :
$(NOECHO) $(NOOP)
# --- MakeMaker realclean section:
# Delete temporary files (via clean) and also delete dist files
realclean purge :: clean realclean_subdirs
- $(RM_F) \
$(MAKEFILE_OLD) $(FIRST_MAKEFILE)
- $(RM_RF) \
$(DISTVNAME)
# --- MakeMaker metafile section:
metafile : create_distdir
$(NOECHO) $(ECHO) Generating META.yml
$(NOECHO) $(ECHO) '---' > META_new.yml
$(NOECHO) $(ECHO) 'abstract: '\''mikes perl tools'\''' >> META_new.yml
$(NOECHO) $(ECHO) 'author:' >> META_new.yml
$(NOECHO) $(ECHO) ' - '\''M.Wesemann <mwx@gmx.de>'\''' >> META_new.yml
$(NOECHO) $(ECHO) 'build_requires:' >> META_new.yml
$(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: '\''0'\''' >> META_new.yml
$(NOECHO) $(ECHO) 'configure_requires:' >> META_new.yml
$(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: '\''0'\''' >> META_new.yml
$(NOECHO) $(ECHO) 'dynamic_config: 1' >> META_new.yml
$(NOECHO) $(ECHO) 'generated_by: '\''ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150001'\''' >> META_new.yml
$(NOECHO) $(ECHO) 'license: unknown' >> META_new.yml
$(NOECHO) $(ECHO) 'meta-spec:' >> META_new.yml
$(NOECHO) $(ECHO) ' url: http://module-build.sourceforge.net/META-spec-v1.4.html' >> META_new.yml
$(NOECHO) $(ECHO) ' version: '\''1.4'\''' >> META_new.yml
$(NOECHO) $(ECHO) 'name: mwx' >> META_new.yml
$(NOECHO) $(ECHO) 'no_index:' >> META_new.yml
$(NOECHO) $(ECHO) ' directory:' >> META_new.yml
$(NOECHO) $(ECHO) ' - t' >> META_new.yml
$(NOECHO) $(ECHO) ' - inc' >> META_new.yml
$(NOECHO) $(ECHO) 'requires:' >> META_new.yml
$(NOECHO) $(ECHO) ' MD5: '\''0'\''' >> META_new.yml
$(NOECHO) $(ECHO) ' Math::BigInt: '\''0'\''' >> META_new.yml
$(NOECHO) $(ECHO) ' Net::NIS: '\''0'\''' >> META_new.yml
$(NOECHO) $(ECHO) ' Net::SMTP: '\''0'\''' >> META_new.yml
$(NOECHO) $(ECHO) ' Term::ReadKey: '\''0'\''' >> META_new.yml
$(NOECHO) $(ECHO) ' Time::HiRes: '\''0'\''' >> META_new.yml
$(NOECHO) $(ECHO) 'version: '\''1.21'\''' >> META_new.yml
-$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml
$(NOECHO) $(ECHO) Generating META.json
$(NOECHO) $(ECHO) '{' > META_new.json
$(NOECHO) $(ECHO) ' "abstract" : "mikes perl tools",' >> META_new.json
$(NOECHO) $(ECHO) ' "author" : [' >> META_new.json
$(NOECHO) $(ECHO) ' "M.Wesemann <mwx@gmx.de>"' >> META_new.json
$(NOECHO) $(ECHO) ' ],' >> META_new.json
$(NOECHO) $(ECHO) ' "dynamic_config" : 1,' >> META_new.json
$(NOECHO) $(ECHO) ' "generated_by" : "ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150001",' >> META_new.json
$(NOECHO) $(ECHO) ' "license" : [' >> META_new.json
$(NOECHO) $(ECHO) ' "unknown"' >> META_new.json
$(NOECHO) $(ECHO) ' ],' >> META_new.json
$(NOECHO) $(ECHO) ' "meta-spec" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",' >> META_new.json
$(NOECHO) $(ECHO) ' "version" : "2"' >> META_new.json
$(NOECHO) $(ECHO) ' },' >> META_new.json
$(NOECHO) $(ECHO) ' "name" : "mwx",' >> META_new.json
$(NOECHO) $(ECHO) ' "no_index" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "directory" : [' >> META_new.json
$(NOECHO) $(ECHO) ' "t",' >> META_new.json
$(NOECHO) $(ECHO) ' "inc"' >> META_new.json
$(NOECHO) $(ECHO) ' ]' >> META_new.json
$(NOECHO) $(ECHO) ' },' >> META_new.json
$(NOECHO) $(ECHO) ' "prereqs" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "build" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "ExtUtils::MakeMaker" : "0"' >> META_new.json
$(NOECHO) $(ECHO) ' }' >> META_new.json
$(NOECHO) $(ECHO) ' },' >> META_new.json
$(NOECHO) $(ECHO) ' "configure" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "ExtUtils::MakeMaker" : "0"' >> META_new.json
$(NOECHO) $(ECHO) ' }' >> META_new.json
$(NOECHO) $(ECHO) ' },' >> META_new.json
$(NOECHO) $(ECHO) ' "runtime" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json
$(NOECHO) $(ECHO) ' "MD5" : "0",' >> META_new.json
$(NOECHO) $(ECHO) ' "Math::BigInt" : "0",' >> META_new.json
$(NOECHO) $(ECHO) ' "Net::NIS" : "0",' >> META_new.json
$(NOECHO) $(ECHO) ' "Net::SMTP" : "0",' >> META_new.json
$(NOECHO) $(ECHO) ' "Term::ReadKey" : "0",' >> META_new.json
$(NOECHO) $(ECHO) ' "Time::HiRes" : "0"' >> META_new.json
$(NOECHO) $(ECHO) ' }' >> META_new.json
$(NOECHO) $(ECHO) ' }' >> META_new.json
$(NOECHO) $(ECHO) ' },' >> META_new.json
$(NOECHO) $(ECHO) ' "release_status" : "stable",' >> META_new.json
$(NOECHO) $(ECHO) ' "version" : "1.21"' >> META_new.json
$(NOECHO) $(ECHO) '}' >> META_new.json
-$(NOECHO) $(MV) META_new.json $(DISTVNAME)/META.json
# --- MakeMaker signature section:
signature :
cpansign -s
# --- MakeMaker dist_basics section:
distclean :: realclean distcheck
$(NOECHO) $(NOOP)
distcheck :
$(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck
skipcheck :
$(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck
manifest :
$(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
veryclean : realclean
$(RM_F) *~ */*~ *.orig */*.orig *.bak */*.bak *.old */*.old
# --- MakeMaker dist_core section:
dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
$(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
-e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';' --
tardist : $(DISTVNAME).tar$(SUFFIX)
$(NOECHO) $(NOOP)
uutardist : $(DISTVNAME).tar$(SUFFIX)
uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu
$(NOECHO) $(ECHO) 'Created $(DISTVNAME).tar$(SUFFIX)_uu'
$(DISTVNAME).tar$(SUFFIX) : distdir
$(PREOP)
$(TO_UNIX)
$(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
$(RM_RF) $(DISTVNAME)
$(COMPRESS) $(DISTVNAME).tar
$(NOECHO) $(ECHO) 'Created $(DISTVNAME).tar$(SUFFIX)'
$(POSTOP)
zipdist : $(DISTVNAME).zip
$(NOECHO) $(NOOP)
$(DISTVNAME).zip : distdir
$(PREOP)
$(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
$(RM_RF) $(DISTVNAME)
$(NOECHO) $(ECHO) 'Created $(DISTVNAME).zip'
$(POSTOP)
shdist : distdir
$(PREOP)
$(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
$(RM_RF) $(DISTVNAME)
$(NOECHO) $(ECHO) 'Created $(DISTVNAME).shar'
$(POSTOP)
# --- MakeMaker distdir section:
create_distdir :
$(RM_RF) $(DISTVNAME)
$(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
-e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"
distdir : create_distdir distmeta
$(NOECHO) $(NOOP)
# --- MakeMaker dist_test section:
disttest : distdir
cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL
cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)
# --- MakeMaker dist_ci section:
ci :
$(PERLRUN) "-MExtUtils::Manifest=maniread" \
-e "@all = keys %{ maniread() };" \
-e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \
-e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});"
# --- MakeMaker distmeta section:
distmeta : create_distdir metafile
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -e q{META.yml};' \
-e 'eval { maniadd({q{META.yml} => q{Module YAML meta-data (added by MakeMaker)}}) }' \
-e ' or print "Could not add META.yml to MANIFEST: $$$${'\''@'\''}\n"' --
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -f q{META.json};' \
-e 'eval { maniadd({q{META.json} => q{Module JSON meta-data (added by MakeMaker)}}) }' \
-e ' or print "Could not add META.json to MANIFEST: $$$${'\''@'\''}\n"' --
# --- MakeMaker distsignature section:
distsignature : create_distdir
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) }' \
-e ' or print "Could not add SIGNATURE to MANIFEST: $$$${'\''@'\''}\n"' --
$(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE
cd $(DISTVNAME) && cpansign -s
# --- MakeMaker install section:
install :: pure_install doc_install
$(NOECHO) $(NOOP)
install_perl :: pure_perl_install doc_perl_install
$(NOECHO) $(NOOP)
install_site :: pure_site_install doc_site_install
$(NOECHO) $(NOOP)
install_vendor :: pure_vendor_install doc_vendor_install
$(NOECHO) $(NOOP)
pure_install :: pure_$(INSTALLDIRS)_install
$(NOECHO) $(NOOP)
doc_install :: doc_$(INSTALLDIRS)_install
$(NOECHO) $(NOOP)
pure__install : pure_site_install
$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
doc__install : doc_site_install
$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
pure_perl_install :: all
$(NOECHO) umask 022; $(MOD_INSTALL) \
"$(INST_LIB)" "$(DESTINSTALLPRIVLIB)" \
"$(INST_ARCHLIB)" "$(DESTINSTALLARCHLIB)" \
"$(INST_BIN)" "$(DESTINSTALLBIN)" \
"$(INST_SCRIPT)" "$(DESTINSTALLSCRIPT)" \
"$(INST_MAN1DIR)" "$(DESTINSTALLMAN1DIR)" \
"$(INST_MAN3DIR)" "$(DESTINSTALLMAN3DIR)"
$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
"$(SITEARCHEXP)/auto/$(FULLEXT)"
pure_site_install :: all
$(NOECHO) umask 02; $(MOD_INSTALL) \
read "$(SITEARCHEXP)/auto/$(FULLEXT)/.packlist" \
write "$(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist" \
"$(INST_LIB)" "$(DESTINSTALLSITELIB)" \
"$(INST_ARCHLIB)" "$(DESTINSTALLSITEARCH)" \
"$(INST_BIN)" "$(DESTINSTALLSITEBIN)" \
"$(INST_SCRIPT)" "$(DESTINSTALLSITESCRIPT)" \
"$(INST_MAN1DIR)" "$(DESTINSTALLSITEMAN1DIR)" \
"$(INST_MAN3DIR)" "$(DESTINSTALLSITEMAN3DIR)"
$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
"$(PERL_ARCHLIB)/auto/$(FULLEXT)"
pure_vendor_install :: all
$(NOECHO) umask 022; $(MOD_INSTALL) \
"$(INST_LIB)" "$(DESTINSTALLVENDORLIB)" \
"$(INST_ARCHLIB)" "$(DESTINSTALLVENDORARCH)" \
"$(INST_BIN)" "$(DESTINSTALLVENDORBIN)" \
"$(INST_SCRIPT)" "$(DESTINSTALLVENDORSCRIPT)" \
"$(INST_MAN1DIR)" "$(DESTINSTALLVENDORMAN1DIR)" \
"$(INST_MAN3DIR)" "$(DESTINSTALLVENDORMAN3DIR)"
doc_perl_install :: all
doc_site_install :: all
$(NOECHO) $(ECHO) Appending installation info to "$(DESTINSTALLSITEARCH)/perllocal.pod"
-$(NOECHO) umask 02; $(MKPATH) "$(DESTINSTALLSITEARCH)"
-$(NOECHO) umask 02; $(DOC_INSTALL) \
"Module" "$(NAME)" \
"installed into" $(INSTALLSITELIB) \
LINKTYPE "$(LINKTYPE)" \
VERSION "$(VERSION)" \
EXE_FILES "$(EXE_FILES)" \
>> "$(DESTINSTALLSITEARCH)/perllocal.pod"
doc_vendor_install :: all
uninstall :: uninstall_from_$(INSTALLDIRS)dirs
$(NOECHO) $(NOOP)
uninstall_from_perldirs ::
uninstall_from_sitedirs ::
$(NOECHO) $(UNINSTALL) "$(SITEARCHEXP)/auto/$(FULLEXT)/.packlist"
uninstall_from_vendordirs ::
# --- MakeMaker force section:
# Phony target to force checking subdirectories.
FORCE :
$(NOECHO) $(NOOP)
# --- MakeMaker perldepend section:
# --- MakeMaker makefile section:
# We take a very conservative approach here, but it's worth it.
# We move Makefile to Makefile.old here to avoid gnu make looping.
$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
$(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
$(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
-$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
-$(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
- $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL)
$(PERLRUN) Makefile.PL
$(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <=="
$(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command. <=="
$(FALSE)
# --- MakeMaker staticmake section:
# --- MakeMaker makeaperl section ---
MAP_TARGET = perl
FULLPERL = "/usr/bin/perl"
$(MAP_TARGET) :: static $(MAKE_APERL_FILE)
$(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@
$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib
$(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET)
$(NOECHO) $(PERLRUNINST) \
Makefile.PL DIR="" \
MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=
# --- MakeMaker test section:
TEST_VERBOSE=0
TEST_TYPE=test_$(LINKTYPE)
TEST_FILE = test.pl
TEST_FILES =
TESTDB_SW = -d
testdb :: testdb_$(LINKTYPE)
test :: $(TEST_TYPE) subdirs-test
subdirs-test ::
$(NOECHO) $(NOOP)
test_dynamic :: pure_all
PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
testdb_dynamic :: pure_all
PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
test_ : test_dynamic
test_static :: test_dynamic
testdb_static :: testdb_dynamic
# --- MakeMaker ppd section:
# Creates a PPD (Perl Package Description) for a binary distribution.
ppd :
$(NOECHO) $(ECHO) '<SOFTPKG NAME="$(DISTNAME)" VERSION="$(VERSION)">' > $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <ABSTRACT>mikes perl tools</ABSTRACT>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <AUTHOR>M.Wesemann &lt;mwx@gmx.de&gt;</AUTHOR>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <IMPLEMENTATION>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="MD5::" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Math::BigInt" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Net::NIS" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Net::SMTP" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Term::ReadKey" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Time::HiRes" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <ARCHITECTURE NAME="x86_64-linux-gnu-thread-multi-5.22" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <CODEBASE HREF="" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' </IMPLEMENTATION>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) '</SOFTPKG>' >> $(DISTNAME).ppd
# --- MakeMaker pm_to_blib section:
pm_to_blib : $(FIRST_MAKEFILE) $(TO_INST_PM)
$(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', q[$(PM_FILTER)], '\''$(PERM_DIR)'\'')' -- \
mwx.pm $(INST_LIB)/mwx.pm
$(NOECHO) $(TOUCH) pm_to_blib
# --- MakeMaker selfdocument section:
# --- MakeMaker postamble section:
# End.
+35
View File
@@ -0,0 +1,35 @@
mwx version 0.01
================
The README is used to introduce the module and provide instructions on
how to install the module, any machine dependencies it may have (for
example C compilers and installed libraries) and any other information
that should be provided before the module is installed.
A README file is required for CPAN modules since CPAN extracts the
README file from a module distribution so that people browsing the
archive can use it get an idea of the modules uses. It is usually a
good idea to provide version information here so that people can
decide whether fixes for the module are worth downloading.
INSTALLATION
To install this module type the following:
perl Makefile.PL
make
make test
make install
DEPENDENCIES
This module requires these other modules and libraries:
blah blah blah
COPYRIGHT AND LICENCE
Put the correct copyright and licence information here.
Copyright (C) 2003 A. U. Thor blah blah blah
+281
View File
@@ -0,0 +1,281 @@
######################################### mikes perl tools (mwx,11.09.03) #####
package mwx;
use 5.006;
use strict;
use warnings;
require Exporter;
use AutoLoader qw(AUTOLOAD);
our $VERSION = '1.21';
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
sendmail
md5
gnfip
tosql
tsd
fsd
mkdatequery
mknumquery
mkquery
uniqid
shortstr
);
################################################################### TOOLS #####
sub sendmail { ##### send mail #####
my($from,$to,$subject,$message,$server)=@_;
use Net::SMTP;
my($smtp)=Net::SMTP->new("mail",Debug=>0);
$smtp->mail("<$from>");
$smtp->recipient($to);$smtp->data();
$smtp->datasend("To: $to\n");
$smtp->datasend("From: $from\n");
$smtp->datasend("Subject: $subject\n");
$smtp->datasend("$message\n");
$smtp->dataend();
$smtp->quit();
}
sub md5() { ##### calculate md5 checksum #####
my($file)=@_;
use Digest::MD5;
open(FILE,$file);binmode(FILE);
my($md5)=Digest::MD5->new->addfile(*FILE)->hexdigest;
close(FILE);
return($md5);
}
sub gnfip { ##### find hostname for given IP (bug fixed version) #####
my($ip)=@_;
use Net::DNS;
if ($ip!~/\d+\.\d+\.\d+\.\d+/) {;return $ip;}
my($res) = new Net::DNS::Resolver;
my($query)=$res->query($ip);
if ($query) {
for ($query->answer) {
if ($_->type eq 'PTR') {
my($ip)=$_->ptrdname;
return("$ip");
}
}
}
else {;return("$ip");}
}
sub tosql { ##### convert string for SQL #####
my($str)=@_;my($a)="'";my($b)="`";if(!defined($str)) {;$str="";}
$str=~s/$b/$a$a/g;$str=~s/$a/$a$a/g;$str=~s/\s*$//g;$str=~s/^\s*//g;
return $str;
}
sub tsd { ##### format date/time to MySQL date/time #####
my($tmp)=@_;my($y);
$tmp=~s/^\s*//;$tmp=~s/\s*$//;$tmp=~s/\s+/ / ;
if ($tmp=~/^(\d+)\.(\d+)\.(\d+)\s+(\d+)\:(\d+)$/) {
$y=$3;if ($3>=0 && $3<100) {;$y=$3+2000;}
return sprintf("%04d-%02d-%02d %02d:%02d",$y,$2,$1,$4,$5);
}
if ($tmp=~/^(\d+)\.(\d+)\.(\d+)\s+(\d+)\:(\d+)\:(\d+)$/) {
$y=$3;if ($3>=0 && $3<100) {;$y=$3+2000;}
return sprintf("%04d-%02d-%02d %02d:%02d:%02d",$y,$2,$1,$4,$5,$6);
}
elsif ($tmp=~/^(\d+)\.(\d+)\.(\d+)$/) {
$y=$3;if ($3>=0 && $3<100) {;$y=$3+2000;}
return sprintf("%04d-%02d-%02d",$y,$2,$1);
}
elsif ($tmp=~/^(\d+)\:(\d+)$/) {
return sprintf("%02d:%02d",$1,$2);
}
else {;return("");}
}
sub fsd { ########################### format MySQL date/time to date/time #####
my($tmp,$mode)=@_;if (!defined($mode)) {;$mode="";}
$tmp=~s/^\s*//;$tmp=~s/\s*$//;$tmp=~s/\s+/ / ;
if ($tmp=~/(\d+)\-(\d+)\-(\d+)\s+(\d+)\:(\d+)\:(\d+)/) {
if ($tmp eq '0000-00-00 00:00:00') {;return("");}
if ($mode eq 'date') {
return sprintf("%d\.%d\.%04d",$3,$2,$1);
}
elsif ($mode eq 'time') {
return sprintf("%d\:%02d",$4,$5);
}
else {
return sprintf("%d\.%d\.%04d %d\:%02d",$3,$2,$1,$4,$5);
}
}
elsif ($tmp=~/(\d+)\-(\d+)\-(\d+)/) {
if ($tmp eq '0000-00-00' || $mode eq 'time') {;return("");}
return sprintf("%d\.%d\.%04d",$3,$2,$1);
}
if ($tmp=~/(\d+)\:(\d+)\:(\d+)/) {
if ($mode eq 'date') {;return("");}
return sprintf("%d\:%02d",$1,$2);
}
else {;return("");}
}
sub mkdatequery { ###################### make query string for date range #####
my($datestr,$field)=@_;
my(@list)=split(",",$datestr);
my($tmp)="";my($da,$db);
for (@list) {
if (/^\s*([^\s]+)\s*\-\s*([^\s]+)\s*$/) {
$da=$1;$db=$2;
$da=~s/(\d+)\.(\d+)\.(\d+)/$3\-$2\-$1/;
$db=~s/(\d+)\.(\d+)\.(\d+)/$3\-$2\-$1/;
$tmp.=" $field BETWEEN '$da' AND '$db' OR ";
}
elsif (/^\s*([\>\<])\s*(.*)/) {
$da=$1;$db=$2;$db=~s/(\d+)\.(\d+)\.(\d+)/$3\-$2\-$1/;
$tmp.=" $field $da '$db' OR ";
}
elsif (/^\s*\-(\d+)$/) {
$tmp.=" UNIX_TIMESTAMP($field)>UNIX_TIMESTAMP(now())-(86400*$1) OR ";
}
elsif (/^\s*([^\s]+)\s*$/) {
$da=$1;$da=~s/(\d+)\.(\d+)\.(\d+)/$3\-$2\-$1/;
$tmp.=" $field='$da' OR ";
}
}
$tmp=~s/\s*or\s*$//i;$tmp=~s/^\s//i;$tmp=~s/\s+/ /g;
if ($tmp=~/^\s*$/) {;return "";}
return "($tmp)";
}
sub mknumquery { ##################### make query string for number range #####
my($numstr,$field)=@_;
my($tmp)="";
my(@list)=split(",",$numstr);
for (@list) {
if (/^\s*(\d+)\s*\-\s*(\d+)\s*$/) {
$tmp.=" $field BETWEEN $1 AND $2 OR ";
}
elsif (/^\s*([\>\<])\s*(\d+)/) {
$tmp.=" $field $1 $2 OR ";
}
elsif (/^\s*(\d+)\s*$/) {
$tmp.=" $field=$1 OR ";
}
}
$tmp=~s/\s*or\s*$//i;$tmp=~s/^\s//i;$tmp=~s/\s+/ /g;
return "($tmp)";
}
sub mkquery { ############################### make query string for field #####
my($query,$mode,@fields)=@_;if (!defined($query)) {;$query="";}
my(@list,$tmp,$field,@field);
use Text::ParseWords;
$query=~s/\s*\(\s*/ \( /g;$query=~s/\s*\)\s*/ \) /g;
@list=&quotewords(' ',0,$query);
$query="";
my($notflag)=0;
for (@list) {
if (!/^\s*and\s*$/i && !/^\s*or\s*$/i &&
!/^\s*andnot\s*$/i && !/^\s*ornot\s*$/i &&
!/^\s*\(\s*$/ && !/^\s*\)\s*$/ && !/^\s*$/) {
s/^\s*\'//;s/\'\s*$//;
if ($query=~/\)\s*$/) {;$query.=" AND (";}
else {;$query.="(";}
for $field (@fields) {
$tmp=$_;if($mode==1) {;$tmp=" $_ ";}
if ($notflag) {;$query.=" NOT($field LIKE '%$tmp%') ";$notflag=0;}
else {;$query.=" $field LIKE '%$tmp%' ";}
$query.="OR ";
}
$query=~s/\s*or\s*$/\)/i;
}
else {
if ($_=~/^\s*andnot\s*$/i) {;$query.=" AND ";$notflag=1;}
elsif ($_=~/^\s*andnot\s*$/i) {;$query.=" OR ";$notflag=1;}
else {;$query.=" $_ ";}
}
}
return $query;
}
sub base62() { ################################################### Base62 #####
my($s)=@_;
my(@c)=('0'..'9','a'..'z','A'..'Z');
my(@p,$u,$v,$i,$n);
my($m)=20;
$p[0]=1;
for $i (1..$m) {
$p[$i]=Math::BigInt->new($p[$i-1]);
$p[$i]=$p[$i]->bmul(62);
}
$v=Math::BigInt->new($s);
for ($i=$m;$i>=0;$i--) {
$v=Math::BigInt->new($v);
($n,$v)=$v->bdiv($p[$i]);
$u.=$c[$n];
}
$u=~s/^0+//;
return($u);
}
sub uniqid { ############################################## get unique id #####
use Math::BigInt;
use Sys::Hostname;
use Time::HiRes qw( gettimeofday usleep );
my($s,$us)=gettimeofday();
my($ia,$ib,$ic,$id)=unpack("C4", (gethostbyname(hostname()))[4]);
my($v)=sprintf("%06d%10d%06d%03d%03d%03d%03d",$us,$s,$$,$ia,$ib,$ic,$id);
return(&base62($v));
}
sub shortstr() { ########################### make short string with '...' #####
my($str,$len)=@_;
if (length($str)>$len) {
my($tmp)=substr($str,0,$len-3) . "...";
return $tmp;
} else {;return ($str);}
}
##################################################################### END #####
1;
__END__
=head1 NAME
mwx - mikes perl tools
=head1 SYNOPSIS
use mwx;
sendmail($from,$to,$subject,$message,$server);
$md5 = md5($file);
$name = gnfip($ip);
$str = tosql($str);
$sqldate = tsd($date);
$date = fsd($date);
$subsql = mkdatequery($datestr,$columnname);
$subsql = mknumquery($numstr,$columnname);
$subsql = mkquery($querystr,$mode,@columnnames);
$id = uniqid();
=head1 AUTHOR
Mike Wesemann, E<lt>mwx@gmx.deE<gt>
=cut
+45
View File
@@ -0,0 +1,45 @@
use Test;
BEGIN { plan tests => 25 };
use mwx;
use strict;
#&sendmail('mike@fhi-berlin.mpg.de','mike@fhi-berlin.mpg.de','test','MSG','mail');
ok(&md5('Makefile.PL'),'a37560d14c32201defbecaa17f23628c');
ok(&fsd('2000-10-18 09:54:01'),'18.10.2000 9:54');
ok(&fsd('0000-00-00 00:00:00'),'');
ok(&fsd('1999-09-19'),'19.9.1999');
ok(&fsd('0000-00-00'),'');
ok(&fsd('08:53:02'),'8:53');
ok(&fsd('00:00:00'),'0:00');
ok(&fsd('2000-10-18 09:54:01','date'),'18.10.2000');
ok(&fsd('2000-10-18 09:54:01','time'),'9:54');
ok(&tsd('23.12.2002'),'2002-12-23');
ok(&tsd('24.11.2001 14:12'),'2001-11-24 14:12');
ok(&tsd('24.11.2001 14:12:23'),'2001-11-24 14:12:23');
ok(&tsd('0:1'),'00:01');
ok(&gnfip('141.14.141.141'),'root.RZ-Berlin.MPG.DE');
ok(&mkdatequery("1.1.2002 , 2.2.2003","date"),
"(date='2002-1-1' OR date='2003-2-2')");
ok(&mkdatequery("1.11.2002 - 7.11.2002","date"),
"(date BETWEEN '2002-11-1' AND '2002-11-7')");
ok(&mkdatequery("> 1.11.2002","date"),"(date > '2002-11-1')");
ok(&mknumquery(" 2 - 5 ","number"),"(number BETWEEN 2 AND 5)");
ok(&mknumquery("11,22 ,33","number"),"(number=11 OR number=22 OR number=33)");
ok(&mkquery("tee or cafe",0,'string'),
"( string LIKE '%tee%') or ( string LIKE '%cafe%')");
ok(&mkquery("'tee or cafe'",0,'string'),"( string LIKE '%tee or cafe%')");
ok(&tosql(' test '),'test');
ok(&tosql("a'b"),"a''b");
ok(&shortstr('0123456789',10),'0123456789');
ok(&shortstr('0123456789',8),'01234...');
print &uniqid() . " " . &uniqid() . " " . &uniqid() . "\n";
+6
View File
@@ -0,0 +1,6 @@
U2FsdGVkX1/vb68X/pAIz5XudakFRxh3wBUxNJqWFNOcltEXfbxxegN6PXyHIii+
yGlQS5zfmPNuZNds7WIE+5E8ah2qemwTLBIidMjxI7Iq0GfJkX5SS6QOAt3Bhxa6
bsqVjf7keGXKWIc7kIu3AnwQlz+qgkW99WFLJ5MYrd60ePYQ9uAf7foIVdNs/fmz
a47jbHeDDteilzQBSJgiYhhY7Tdc/vOzuAzOXImEX3OG4FyGj90+SMgLnkrIJUOv
4wFpNz4NPXq9rIiav6z/gOblLze+4O7CkkTHqjMSJTeQUSKyXZ0bvZ1mUfzpV7ld
GYUf4zGNcVYSkVWPgS0iJnlcY+psYvk2rPDDxsBCuwk=
Executable
+117
View File
@@ -0,0 +1,117 @@
#!/usr/bin/perl
####################################################################################### restic setup (mwx'2023)
use Config;
die if (!-f "./files/rt");
#myuname: linux localhost 4.19.0 #1 smp debian 4.19.0 armv7l gnulinux
#archname: arm-linux-gnueabihf-thread-multi-64int
if ($Config{archname}=~/^darwin/) { # --------------------------------------------------------------- mac setup
$XRT = $ENV{"HOME"}.'/bin/rt';
$XRTLOG = $ENV{"HOME"}.'/.rt.log';
$XRESTIC = $ENV{"HOME"}.'/bin/restic';
$XLOG = $ENV{"HOME"}.'/.restic.log';
$XPWFILE = $ENV{"HOME"}.'/.restic.pw';
$XSRC = $ENV{"HOME"}.'/Sync /Volumes/Pictures';
$XEXCLUDE = '-e .Spotlight-V100 -e .Trashes -e .fseventsd -e .bzvol -e .DS_Store ' .
'-e .TemporaryItems -e .DocumentRevisions-V100';
$config=$ENV{"HOME"}.'/.rt.conf';
system('./upd https://github.com/restic/restic -i '.$ENV{"HOME"}.'/bin');
system("cp ./files/rt $XRT");
system("chmod 755 $XRT");
} elsif ($Config{archname}=~/-linux-/) { # ------------------------------------------------ ubuntu/debian setup
$XRT = '/db/bin/rt';
$XRTLOG = '/var/log/rt.log';
$XRESTIC = '/db/bin/restic';
$XLOG = '/var/log/restic.log';
$XLOG = '/var/log/restic.log';
$XPWFILE = '/db/etc/restic.pw';
$XSRC = '/etc /db /var /root /home /usr/local /opt';
$XEXCLUDE = '-e /var/lib/lxcfs -e /var/log/journal';
$config='/db/etc/rt.conf';
system('./upd https://github.com/restic/restic -i /db/bin');
system("cp ./files/rt $XRT");
system("chmod 755 $XRT");
system("mkdir -p /db/etc /db/tmp");
} else {die "architecture not found";} # ----------------------------------------------------------------------
chomp($host=`hostname`);$host=~s/^([^\.]+).*/$1/;
$host=&readline("Hostname: ",$host);
if (!-f $config) { # write config file
open(OUT,"> $config");
print OUT <<"ENDOFCONF";
\$NAME = '$host';
\$ID = '0';
\$TAG = 'ppb';
\$PASSWORD = "";
\$TARGET = "";
\$ENV{'AWS_ACCESS_KEY_ID'} = '';
\$ENV{'AWS_SECRET_ACCESS_KEY'} = '';
\$SRC = '$XSRC';
\$EXCLUDE = '$XEXCLUDE';
\$RESTIC = '$XRESTIC';
\$LOG = '$XLOG';
\$PWFILE = '$XPWFILE';
\$HTTP_LOG = 'log.fhi.berlin';
ENDOFCONF
}
system("vi $config");
system("$XRT init");
&setupcron();
####################################################################################################### SUPPORT
sub setupcron() {
open(CRON,"crontab -l |");
while(<CRON>) {
chomp();
push(@CRON,$_) if (!/rt\s+selfupdate/ && !/rt delaybackup/);
}
push(@CRON,"0 2 * * * $XRT delaybackup >> $XRTLOG 2>&1");
open(OUT,"> /tmp/cron.$$");
for (@CRON) {
print OUT "$_\n";
}
close(OUT);
system("/usr/bin/crontab /tmp/cron.$$");
system("rm -f /tmp/cron.$$");
}
sub readline() {
my($prompt,$input)=@_; use Term::ReadLine;
BEGIN{ $ENV{PERL_RL} = 'Perl o=0' }
if (!$term) {;$term = new Term::ReadLine 'term';}
my($txt)=$term->readline($prompt,$input);
return $txt;
}
########################################################################################################### END
Executable
+114
View File
@@ -0,0 +1,114 @@
#!/usr/bin/perl
use Getopt::Std;getopts('z');
system("userdel ppb; rm -rf /home/ppb") if (-d "/home/ppb");
system("userdel mike; rm -rf /home/mike") if (-d "/home/mike");
&ai('dnsutils','net-tools','zsh','joe','rsync','curl','fuse','libwww-perl',
'libterm-readline-perl-perl','libterm-readpassword-perl','libdbd-mysql-perl','ntp',
'libjson-perl','jq','unzip','7zip');
if ($opt_z) {
if (-x "/usr/bin/zsh") {
system("chsh root -s /usr/bin/zsh");
}
}
system("locale-gen C.UTF-8");
system("mkdir /db");
system("mkdir /db/bin");
system("mkdir /db/backup");
system("mkdir /db/backup/mysql");
system("mkdir /db/tmp");
system("mkdir /db/log");
system("mkdir /db/lib");
system("mkdir /db/data");
system("mkdir /db/etc");
system("mkdir /db/src");
system("mkdir /db/upload");
system("chmod 777 /db/tmp");
system("chmod 777 /db/log");
system("chmod 777 /db/upload");
system("mkdir -p ~/.joe/colors/");
system("cp ./files/default.jcf ~/.joe/colors/default.jcf");
system("cp ./files/joerc4 /root/.joerc");
system("cp ./files/csh.cshrc /etc");
system("cp ./files/rc.local.debian /etc/rc.local");
system("chmod 755 /etc/rc.local");
system("cp ./files/myuser /db/bin");
system("cp ./files/mybackup /db/bin");
system("cp ./files/dx /db/bin");
system("cp ./files/gx /db/bin");
system("cp ./files/gy /db/bin");
system("cp ./files/telemetry /db/bin");
system("cp ./files/rt /db/bin");
system("cp ./files/mgsh /db/bin");
system("cp ./files/locale /etc/default/locale");
system("cp ./files/zshrc /etc/zsh/zshrc");
system("rm /etc/motd; touch /etc/motd");
system("mkdir /root/.ssh") if (!-d "/root/.ssh");
&readak("/root/.ssh/authorized_keys");
&readak("./files/authorized_keys");
open(OUT,"> /root/.ssh/authorized_keys");
for (sort(keys(%K))) {print OUT "$_\n" if (!/^\s*$/);}
close(OUT);
sub readak() {
my($file)=@_;
if (-f $file) {open(IN,$file);while(<IN>) {chomp();$K{$_}=$_;}close(IN);}
}
system("chmod 700 /root/.ssh");
system("chmod 600 /root/.ssh/authorized_keys");
if (!$opt_x) {
system("/usr/bin/apt-get update");
system("/usr/bin/apt-get upgrade");
if (is_debian_13_or_later()) {
system("cp ./files/timesyncd.conf /etc/systemd/");
} else {
system("service ntp stop");
system("/usr/sbin/ntpd -gq");
system("service ntp start");
}
}
sub ai {
my @pkgs=@_;
for (@pkgs) {
system("/usr/bin/apt-get -y install $_");
}
}
sub is_debian_13_or_later {
return 0 unless -r '/etc/os-release';
my %os_release;
open(my $fh, '<', '/etc/os-release') or return 0;
while (my $line = <$fh>) {
chomp $line;
if ($line =~ /^([A-Z_]+)=(.*)$/) {
my ($key, $val) = ($1, $2);
$val =~ s/^"|"$//g;
$os_release{$key} = $val;
}
}
close($fh);
return 0 unless ($os_release{ID} // '') eq 'debian';
return 0 unless ($os_release{VERSION_ID} // '') =~ /^(\d+)/;
return $1 >= 13 ? 1 : 0;
}
Executable
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/perl
for $v ('7.2','7.3','7.4','8.1') {
if (-f "/etc/php/$v/apache2/php.ini") {
$FILE = "/etc/php/$v/apache2/php.ini";
$OFILE = "/etc/php/$v/apache2/php.ini.org";
}
}
die "$FILE not found" if (!-f $FILE);
die "$FILE skipped" if (-f $OFILE);
$epre = "\"<br><span style='color:#F00;font-family:monospace;font-size:15px;'>\"";
$epost = "\"</span><br>\"";
$P{'html_errors'} = 'On';
$P{'display_errors'} = 'On';
$P{'error_prepend_string'} = $epre;
$P{'error_append_string'} = $epost;
$P{'error_reporting'} = 'E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED';
$P{'short_open_tag'} = 'On';
$P{'upload_tmp_dir'} = '/db/upload';
$P{'upload_max_filesize'} = '10000M';
$P{'post_max_size'} = '10000M';
$P{'max_execution_time'} = '300';
$P{'max_input_time'} = '600';
$P{'memory_limit'} = '512M';
if (!-f $OFILE) {
system("cp $FILE $OFILE");
}
open(IN,$OFILE);
open(OUT,"> $FILE");
while(<IN>) {
if (!/^;/ && !/^\s*$/) {
print OUT "\n" if (/^\[/);
$match=0;
for $key (keys(%P)) {
$match++ if (/^$key/);
}
if ($match>0) {
print OUT ";$_";
} else {
print OUT "$_";
}
}
if (/^\[PHP\]/) {
for $key (sort(keys(%P))) {
print OUT "$key = $P{$key}\n";
}
print OUT "\n";
}
}
close(IN);
close(OUT);
Executable
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/perl
&ai('tcsh','joe','libterm-readpassword-perl','libterm-readline-perl-perl','resolvconf');
system("/usr/bin/chsh -s /usr/bin/tcsh root");
system("mkdir /db");
system("mkdir /db/bin");
system("mkdir /db/tmp");
system("chmod 777 /db/tmp");
system("cp ./files/joerc4 /etc/joe/joerc");
system("cp ./files/csh.cshrc /etc");
system("cp ./files/dx /db/bin");
system("cp ./files/gx /db/bin");
system("cp ./files/gy /db/bin");
system("cp ./restic/restic_0.9.5_linux_arm /db/bin/restic");
system("rm /etc/motd");
system("mkdir /root/.ssh");
system("cp ./files/authorized_keys /root/.ssh");
system("chmod 700 /root/.ssh");
system("chmod 600 /root/.ssh/authorized_keys");
system("/usr/bin/apt-get update");
system("/usr/bin/apt-get upgrade");
sub ai {
my @pkgs=@_;
for (@pkgs) {
system("/usr/bin/apt-get -y install $_");
}
}
Executable
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/perl
$SSHCONF='/etc/ssh/sshd_config';
$out="";
open(IN,$SSHCONF);
while(<IN>) {
if (/^\s*\#*\s*PermitRootLogin/) {
$out.="PermitRootLogin yes\n" ;
} elsif (/(^\s*AcceptEnv.*$)/) {
$out.="#$1";
} else {
$out.=$_;
}
}
close(IN);
open(OUT,"> $SSHCONF");
print OUT $out;
close(OUT);
system("service ssh restart");
Executable
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/perl
system("userdel ppb; rm -rf /home/ppb") if (-d "/home/ppb");
system("userdel mike; rm -rf /home/mike") if (-d "/home/mike");
&ai('net-tools','zsh','joe','fuse','libwww-perl','bzip2','jq',
'libterm-readline-perl-perl','libterm-readpassword-perl','libdbd-mysql-perl','ntp');
system("chsh root -s /usr/bin/zsh");
system("mkdir /db");
system("mkdir /db/bin");
system("mkdir /db/backup");
system("mkdir /db/backup/mysql");
system("mkdir /db/tmp");
system("mkdir /db/log");
system("mkdir /db/lib");
system("mkdir /db/data");
system("mkdir /db/etc");
system("mkdir /db/src");
system("mkdir /db/upload");
system("chmod 777 /db/tmp");
system("chmod 777 /db/log");
system("chmod 777 /db/upload");
system("cp ./files/joerc4 /root/.joerc");
system("cp ./files/csh.cshrc /etc");
system("cp ./files/rc.local.ubuntu /etc/rc.local");
system("chmod 755 /etc/rc.local");
system("cp ./files/myuser /db/bin");
system("cp ./files/mybackup /db/bin");
system("cp ./files/dx /db/bin");
system("cp ./files/gx /db/bin");
system("cp ./files/gy /db/bin");
system("cp ./files/telemetry /db/bin");
system("cp ./files/rt /db/bin");
system("cp ./files/mgsh /db/bin");
system("cp ./files/zshrc /etc/zsh/zshrc");
system("mkdir /root/.ssh") if (!-d "/root/.ssh");
system("cp ./files/authorized_keys /root/.ssh");
system("chmod 700 /root/.ssh");
system("chmod 600 /root/.ssh/authorized_keys");
system("/usr/bin/apt update");
system("/usr/bin/apt upgrade");
system("service ntp stop");
system("/usr/sbin/ntpd -gq");
system("service ntp start");
sub ai {
my @pkgs=@_;
for (@pkgs) {
system("/usr/bin/apt -qq -y install $_");
}
}
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/perl
#################################################################################### telemetry setup (mwx'2020)
&setupcron();
####################################################################################################### SUPPORT
sub setupcron() {
open(CRON,"crontab -l |");
while(<CRON>) {
chomp();
push(@CRON,$_) if (!/\/db\/bin\/telemetry/);
}
push(@CRON,"*/5 * * * * /db/bin/telemetry > /dev/null 2>&1");
open(OUT,"> /tmp/cron.$$");
for (@CRON) {
print OUT "$_\n";
}
close(OUT);
system("/usr/bin/crontab /tmp/cron.$$");
system("rm -f /tmp/cron.$$");
}
########################################################################################################### END
Executable
+1227
View File
File diff suppressed because it is too large Load Diff