From 53fe4e9ed3572dd4172578730e78c11a44223c75 Mon Sep 17 00:00:00 2001 From: Princess Pi Date: Fri, 25 Sep 2026 15:16:30 -0600 Subject: [PATCH] waypoint --- Windows-Scripts/checksum.ps1 | 349 ++++++++++++++++++---------- customscripts/python_pyenv_setup.sh | 85 ------- 2 files changed, 224 insertions(+), 210 deletions(-) delete mode 100644 customscripts/python_pyenv_setup.sh diff --git a/Windows-Scripts/checksum.ps1 b/Windows-Scripts/checksum.ps1 index c97db57..dab3ad1 100644 --- a/Windows-Scripts/checksum.ps1 +++ b/Windows-Scripts/checksum.ps1 @@ -7,28 +7,33 @@ param( # Output file to save generated checksums (-o mode) [Parameter(Mandatory = $false, ParameterSetName = 'Generate')] - [Alias('o')] + [Alias('o', '-outfile')] [string]$OutFile, # File containing checksums to verify (-c mode) [Parameter(Mandatory = $false, ParameterSetName = 'Verify')] - [Alias('c')] + [Alias('c', '-check')] [string]$Check, # Direct checksum hash string to match against (-m mode) [Parameter(Mandatory = $true, ParameterSetName = 'Match')] - [Alias('m')] + [Alias('m', '-match')] [string]$Match, # Hashing algorithm to use (Defaults to SHA256) [Parameter(Mandatory = $false)] - [Alias('a')] + [Alias('a', 'algo', '-algo', '-algorithm')] [ValidateSet('SHA1', 'SHA256', 'SHA384', 'SHA512', 'MD5')] [string]$Algorithm, - # Help flag (-h, -Help) + # Recursive flag (-r, -recursive, --recursive) [Parameter(Mandatory = $false)] - [Alias('h')] + [Alias('r', 'recursive', '-recursive')] + [switch]$Recursive, + + # Help flag (-h, -Help, --Help, --H) + [Parameter(Mandatory = $false)] + [Alias('h', '-h', '-help')] [switch]$Help ) @@ -39,35 +44,47 @@ NAME checksum - Compute and verify message digests / file checksums SYNOPSIS - .\checksum.ps1 [-FilePath] [-OutFile ] [-Algorithm ] - .\checksum.ps1 [-FilePath] -Match [-Algorithm ] - .\checksum.ps1 -Check [-Algorithm ] + .\checksum.ps1 [-FilePath] [-OutFile ] [-Algorithm ] [-Recursive] + .\checksum.ps1 [-FilePath] -Match [-Algorithm ] [-Recursive] + .\checksum.ps1 -Check [-Algorithm ] [-Recursive] .\checksum.ps1 -Help DESCRIPTION Computes or verifies checksums using various cryptographic algorithms. Outputs hash values in standard Linux utility format ( ). + Ignores checksum files (.md5, .sha1, .sha256, .sha384, .sha512) unless explicitly passed. + + NOTE: All flags and parameters are completely case-insensitive + (e.g., -r, -R, --Recursive, and --recursive are treated identically). PARAMETERS -FilePath Specifies the path to one or more files to hash. Accepts wildcards (*). - -o, -OutFile - Specifies an output file to save the checksum results to, while still - displaying the output on screen. + -o, -OutFile, --OutFile + Specifies an output file to save the checksum results to. + If passed as an empty string (e.g. -o ""), the file is auto-named: + - If input has a wildcard (*), outputs to 'checksums.' + - If no wildcard is used, outputs to '.' per file. + When combined with -r and *, it auto-generates checksum files + inside the current working directory and each subdirectory recursively. - -c, -Check + -r, -Recursive, --Recursive + Recursively generate or verify checksums in subdirectories. + + -c, -Check, --Check Read checksums from the specified file and verify them against files on disk. + If -r is used, searches for the specified filename recursively in subdirectories. - -m, -Match + -m, -Match, --Match Compare the computed hash of the target file(s) against a specific hash string. - -a, -Algorithm + -a, -Algorithm, --Algorithm, -Algo, --Algo Specifies the cryptographic hash algorithm to use. Supported values: SHA1, SHA256 (default), SHA384, SHA512, MD5. If omitted in -c or -m mode, the algorithm is auto-detected by hash length. - -h, -Help + -h, -Help, --Help, --H Display this help message. EXAMPLES @@ -75,13 +92,13 @@ EXAMPLES .\checksum.ps1 myfile.iso 2. Compute checksums for all files and write to a file while showing output: - .\checksum.ps1 * -o checksums.sha256 + .\checksum.ps1 * --OutFile checksums.sha256 - 3. Verify a file against a explicit hash string: - .\checksum.ps1 myfile.iso -m "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + 3. Auto-generate per-directory checksum files recursively for all files: + .\checksum.ps1 * -r -o "" - 4. Verify checksums from a verification file (auto-detects algorithm): - .\checksum.ps1 -c checksums.sha256 + 4. Verify checksums from verification files recursively: + .\checksum.ps1 --Check checksums.sha256 --Recursive '@ } @@ -105,9 +122,9 @@ EXAMPLES process { # Match help arguments passed either as switch (-h, -Help) or positional string ('help', 'h', '--help', etc.) - $isHelpRequested = $Help.IsPresent -or ( - $FilePath -and $FilePath.Count -eq 1 -and ( - $FilePath[0] -match '^(?i)[-/]{0,2}(h|help)$' + $isHelpRequested =$Help.IsPresent -or ( + $FilePath -and$FilePath.Count -eq 1 -and ( + $FilePath[0] -match '^(?i)[-/]{0,2}(h\vert{}help)$' ) ) @@ -118,17 +135,59 @@ process { # Normalize explicit algorithm input if provided if (-not [string]::IsNullOrWhiteSpace($Algorithm)) { - $Algorithm = $Algorithm.ToUpper() + $Algorithm =$Algorithm.ToUpper() + } + + # --- ITEM GATHERING (Generate & Match Modes) --- + if ($PSCmdlet.ParameterSetName -in @('Generate', 'Match')) { + if (-not $FilePath -or$FilePath.Count -eq 0) { + Write-Error "checksum: Missing file path parameter. Use -Help for usage." + return + } + + $allItems = @()$isWildcardGlobal = $false$skipExtensions = @('.md5', '.sha1', '.sha256', '.sha384', '.sha512') + + foreach ($pathEntry in$FilePath) { + $isWildcard = ($pathEntry -match '\*') + if ($isWildcard) { $isWildcardGlobal =$true } + + $resolvedItems = @() + if ($Recursive) { + $resolvedItems = Get-ChildItem -Path$pathEntry -Recurse -File -ErrorAction SilentlyContinue + } else { + if ($isWildcard -or ($pathEntry -match '\?')) { + $resolvedItems = Get-ChildItem -Path$pathEntry -File -ErrorAction SilentlyContinue + } else { + $resolvedItems = Get-Item -Path$pathEntry -ErrorAction SilentlyContinue + } + } + + if (-not $resolvedItems) { + Write-Error "checksum: $pathEntry`: No such file or directory" + continue + } + + $explicitFileFound = $false + if ((-not $isWildcard) -and (Test-Path -Path $pathEntry -PathType Leaf)) { + $explicitFileFound = $true + } + + foreach ($item in $resolvedItems) { + if ($item.PSIsContainer) { continue } + + # Feature 1: Skip checksum extension files unless they were named explicitly + if (-not $explicitFileFound) { + if ($skipExtensions -contains $item.Extension.ToLower()) { + continue + } + } + $allItems += $item + } + } } # --- DIRECT MATCH MODE (-m / -Match) --- if ($PSCmdlet.ParameterSetName -eq 'Match') { - if (-not $FilePath -or $FilePath.Count -eq 0) { - Write-Error "checksum: Missing file path parameter for matching. Use -Help for usage." - return - } - - # Auto-detect algorithm from provided -Match hash string if not explicitly given if ([string]::IsNullOrWhiteSpace($Algorithm)) { $Algorithm = Get-AlgorithmFromHashLength -HashString $Match if (-not $Algorithm) { return } @@ -137,139 +196,179 @@ process { $expectedHash = $Match.Trim().ToLower() - foreach ($pathEntry in $FilePath) { - $resolvedItems = Get-Item -Path $pathEntry -ErrorAction SilentlyContinue + foreach ($item in $allItems) { + $actualHash = (Get-FileHash -Path $item.FullName -Algorithm $Algorithm).Hash.ToLower() + $targetFile = Resolve-Path -Path $item.FullName -Relative + if ($targetFile.StartsWith(".\")) { $targetFile = $targetFile.Substring(2) } - if (-not $resolvedItems) { - Write-Error "checksum: $pathEntry`: No such file or directory" - continue - } - - foreach ($item in $resolvedItems) { - if ($item.PSIsContainer) { - Write-Error "checksum: $($item.Name)`: Is a directory" - } else { - $actualHash = (Get-FileHash -Path $item.FullName -Algorithm $Algorithm).Hash.ToLower() - $targetFile = Resolve-Path -Path $item.FullName -Relative - if ($targetFile.StartsWith(".\")) { $targetFile = $targetFile.Substring(2) } - - if ($actualHash -eq $expectedHash) { - Write-Host "${targetFile}: " -NoNewline - Write-Host "OK" -ForegroundColor Green - } else { - Write-Host "${targetFile}: " -NoNewline - Write-Host "FAILED" -ForegroundColor Red - } - } + if ($actualHash -eq $expectedHash) { + Write-Host "${targetFile}: " -NoNewline + Write-Host "OK" -ForegroundColor Green + } else { + Write-Host "${targetFile}: " -NoNewline + Write-Host "FAILED" -ForegroundColor Red } } } # --- VERIFICATION MODE (-c / -Check) --- elseif ($PSCmdlet.ParameterSetName -eq 'Verify') { - if (-not (Test-Path -Path $Check -PathType Leaf)) { + $checkFiles = @() + if ($Recursive) { + # Find all files matching the name of $Check recursively + $checkFileName = Split-Path $Check -Leaf + $checkFiles = Get-ChildItem -Path .\ -Filter $checkFileName -Recurse -File -ErrorAction SilentlyContinue + } else { + if (Test-Path -Path $Check -PathType Leaf) { + $checkFiles = @(Get-Item -Path $Check) + } + } + + if (-not $checkFiles -or $checkFiles.Count -eq 0) { Write-Error "checksum: $Check`: No such file or directory" return } - $lines = Get-Content -Path $Check - - # Auto-detect algorithm based on hash length if not explicitly provided - if ([string]::IsNullOrWhiteSpace($Algorithm)) { - foreach ($line in $lines) { - if ([string]::IsNullOrWhiteSpace($line) -or $line.StartsWith("#")) { continue } - if ($line -match '^([a-fA-F0-9]+)\s+') { - $Algorithm = Get-AlgorithmFromHashLength -HashString $Matches[1] - if (-not $Algorithm) { return } - Write-Verbose "Auto-detected algorithm: $Algorithm" - break - } - } + foreach ($cf in$checkFiles) { + $lines = Get-Content -Path$cf.FullName + $baseDir =$cf.DirectoryName - # Fallback if file contained no parsable hashes - if ([string]::IsNullOrWhiteSpace($Algorithm)) { - $Algorithm = 'SHA256' + $fileAlgo =$Algorithm + if ([string]::IsNullOrWhiteSpace($fileAlgo)) { + foreach ($line in$lines) { + if ([string]::IsNullOrWhiteSpace($line) -or$line.StartsWith("#")) { continue } + if ($line -match '^([a-fA-F0-9]+)\s+') { + $fileAlgo = Get-AlgorithmFromHashLength -HashString$Matches[1] + if ($fileAlgo) { Write-Verbose "Auto-detected algorithm: $fileAlgo in $($cf.Name)" } + break + } + } + if ([string]::IsNullOrWhiteSpace($fileAlgo)) {$fileAlgo = 'SHA256' } } - } - foreach ($line in $lines) { - # Skip empty lines or comments - if ([string]::IsNullOrWhiteSpace($line) -or $line.StartsWith("#")) { continue } + foreach ($line in$lines) { + if ([string]::IsNullOrWhiteSpace($line) -or$line.StartsWith("#")) { continue } - # Match standard checksum output format: " [* ]" - if ($line -match '^([a-fA-F0-9]+)\s+[* ]?(.*)$') { - $expectedHash = $Matches[1].ToLower() - # Strip leading whitespace and any leftover leading asterisk - $targetFile = $Matches[2].Trim().TrimStart('*') + if ($line -match '^([a-fA-F0-9]+)\s+[* ]?(.*)$') { + $expectedHash =$Matches[1].ToLower() + $targetFile =$Matches[2].Trim().TrimStart('*') + + # Resolve path relative to where the check file currently resides + $targetFullPath = Join-Path -Path $baseDir -ChildPath$targetFile - if (Test-Path -Path $targetFile -PathType Leaf) { - $actualHash = (Get-FileHash -Path $targetFile -Algorithm $Algorithm).Hash.ToLower() + if (Test-Path -Path $targetFullPath -PathType Leaf) {$actualHash = (Get-FileHash -Path $targetFullPath -Algorithm$fileAlgo).Hash.ToLower() + + $displayPath = Resolve-Path -Path$targetFullPath -Relative + if ($displayPath.StartsWith(".\")) { $displayPath =$displayPath.Substring(2) } - if ($actualHash -eq $expectedHash) { - Write-Host "${targetFile}: " -NoNewline - Write-Host "OK" -ForegroundColor Green + if ($actualHash -eq$expectedHash) { + Write-Host "${displayPath}: " -NoNewline + Write-Host "OK" -ForegroundColor Green + } else { + Write-Host "${displayPath}: " -NoNewline + Write-Host "FAILED" -ForegroundColor Red + } } else { - Write-Host "${targetFile}: " -NoNewline - Write-Host "FAILED" -ForegroundColor Red + # Format missing path nicely + $displayPath =$targetFile + if ($baseDir -ne (Get-Location).Path) {$displayPath = Join-Path -Path (Resolve-Path -Path $baseDir -Relative) -ChildPath$targetFile + if ($displayPath.StartsWith(".\")) { $displayPath =$displayPath.Substring(2) } + } + Write-Host "${displayPath}: " -NoNewline + Write-Host "FAILED open or read" -ForegroundColor Red } } else { - Write-Host "${targetFile}: " -NoNewline - Write-Host "FAILED open or read" -ForegroundColor Red + Write-Warning "checksum: improperly formatted line in $($cf.Name):$line" } - } else { - Write-Warning "checksum: improperly formatted line: $line" } } } # --- GENERATION MODE --- else { - # Default to SHA256 if no algorithm was specified in generation mode - if ([string]::IsNullOrWhiteSpace($Algorithm)) { - $Algorithm = 'SHA256' + if ([string]::IsNullOrWhiteSpace($Algorithm)) {$Algorithm = 'SHA256' } - if (-not $FilePath -or $FilePath.Count -eq 0) { - Write-Error "checksum: Missing file path parameter. Use -Help for usage." - return - } + # Check if -o / -OutFile parameter was explicitly invoked + $wantOutFile =$PSBoundParameters.ContainsKey('OutFile') + $outFilename =$OutFile - # Clear/initialize output file if specified before writing hashes - if (-not [string]::IsNullOrWhiteSpace($OutFile)) { - $null = New-Item -Path $OutFile -ItemType File -Force - } + if ($wantOutFile) { + # Feature 2 & 3: Recursive, Wildcard + Passed output flag splits hashes strictly into localized directory files + if ($Recursive -and$isWildcardGlobal) { + $groupedItems =$allItems | Group-Object DirectoryName - foreach ($pathEntry in $FilePath) { - # Resolve wildcards and single file inputs - $resolvedItems = Get-Item -Path $pathEntry -ErrorAction SilentlyContinue - - if (-not $resolvedItems) { - Write-Error "checksum: $pathEntry`: No such file or directory" - continue - } - - foreach ($item in $resolvedItems) { - # Handle directories like Linux sha256sum does - if ($item.PSIsContainer) { - Write-Error "checksum: $($item.Name)`: Is a directory" - } else { - $hash = (Get-FileHash -Path $item.FullName -Algorithm $Algorithm).Hash.ToLower() + foreach ($group in$groupedItems) { + $dirPath =$group.Name + $filesInDir =$group.Group - # Format standard relative path (stripping leading '.\') - $relativePath = Resolve-Path -Path $item.FullName -Relative + if ([string]::IsNullOrWhiteSpace($outFilename)) { + $currentOutFile = Join-Path -Path$dirPath -ChildPath "checksums.$($Algorithm.ToLower())" + } else { + $currentOutFile = Join-Path -Path $dirPath -ChildPath$outFilename + } + + # Clear existing file before iterating + $null = New-Item -Path$currentOutFile -ItemType File -Force + + foreach ($item in $filesInDir) {$hash = (Get-FileHash -Path $item.FullName -Algorithm$Algorithm).Hash.ToLower() + $relativePath =$item.Name # Localization relies purely on internal filenames + + $outputLine = "$hash$relativePath" + Add-Content -Path $currentOutFile -Value$outputLine + Write-Output $outputLine + } + } + } + # Non-localized standard generation (Singular master file, or Per-file auto naming) + else { + $singleOutFile =$null + + # Check for standard auto naming rules + if ([string]::IsNullOrWhiteSpace($outFilename)) { + if ($isWildcardGlobal) {$singleOutFile = "checksums.$($Algorithm.ToLower())" + } + } else { + $singleOutFile =$outFilename + } + + # Clear master file if consolidating to one file + if ($singleOutFile) { + $null = New-Item -Path$singleOutFile -ItemType File -Force + } + + foreach ($item in $allItems) {$hash = (Get-FileHash -Path $item.FullName -Algorithm$Algorithm).Hash.ToLower() + + $relativePath = Resolve-Path -Path$item.FullName -Relative if ($relativePath.StartsWith(".\")) { - $relativePath = $relativePath.Substring(2) + $relativePath =$relativePath.Substring(2) } - $outputLine = "$hash $relativePath" + $outputLine = "$hash$relativePath" - # If -OutFile is provided, write line to file - if (-not [string]::IsNullOrWhiteSpace($OutFile)) { - Add-Content -Path $OutFile -Value $outputLine + if ($singleOutFile) { + Add-Content -Path $singleOutFile -Value$outputLine + } else { + # Single-file auto naming (.) + $currentOutFile = "$($item.FullName).$($Algorithm.ToLower())" + $null = New-Item -Path$currentOutFile -ItemType File -Force + Add-Content -Path $currentOutFile -Value$outputLine } - # Output to stdout Write-Output $outputLine } } + } + # Standard fallback if no -o was invoked: Stream perfectly to console + else { + foreach ($item in $allItems) {$hash = (Get-FileHash -Path $item.FullName -Algorithm$Algorithm).Hash.ToLower() + + $relativePath = Resolve-Path -Path$item.FullName -Relative + if ($relativePath.StartsWith(".\")) { + $relativePath =$relativePath.Substring(2) + } + + $outputLine = "$hash$relativePath" + Write-Output $outputLine + } } } } diff --git a/customscripts/python_pyenv_setup.sh b/customscripts/python_pyenv_setup.sh deleted file mode 100644 index c115d9f..0000000 --- a/customscripts/python_pyenv_setup.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash -# usage -## curl -s https://raw.githubusercontent.com/PrincessPi3/general-scripts-and-system-ssssssetup/refs/heads/main/customscripts/python_pyenv_setup.sh | sudo "$SHELL" && source ~/.zshrc && exec "$SHELL" && pyenv install 3:latest && pyenv global 3:latest -# set -e - -# set rcfile -rcfile="$HOME/.zshrc" # zsh -# rcfile="$USER/.bashrc" # bash -package_log="/home/princesspi/python_packages_removed.txt" - -# check if a command exists, and if so, purge that package -# usage: check_purge_package -check_purge_package () { - package_name=$1 - - # which -s $package_name 2>/dev/null 1>/dev/null # silently test for command - # package_check=$? # get return code. 0 for found, any other for not found - - # if [ $package_check -eq 0 ]; then # if package is found, purge it - echo "purging $package_name" - sudo apt purge $package_name -y 2>>"$package_log" 1>>"$package_log" - echo "finished purging $package_name" - # else # otherwise skip - # echo "no $package_name installation found, skipping uninstall" - #fi -} - -# cleanup previous python installs -# check_purge_package pyenv* -# check_purge_package python3* -# check_purge_package python2* -# check_purge_package python* -# check_purge_package pip* -# check_purge_package pip3* -# check_purge_package pip2* - - -# cleanup -# echo "Autoremoving packages" -# sudo apt autoremove -y 2>>"$package_log" 1>>"$package_log" -# echo -e "DONE CLEARING OLD PACKAGES!\n\tRemoved packages logged to $package_log" - -if [ -d $HOME/.pyenv ]; then - echo "Removing existing pyenv installation" - rm -rf $HOME/.pyenv -else - echo "No existing pyenv installation found, skipping removal" -fi - -# install pyenv -curl -fsSL https://pyenv.run | bash -## setup shell -### check for pyenv in rcfile -grep -q .pyenv $rcfile -rc_pyenv_check=$? # get retcode, 0 for found not 0 for not found - -if [ $rc_pyenv_check -eq 0 ]; then # if pyenv found - echo "pyenv already set up in $rcfile, skipping add init" -else # if pyenv not found - echo "Setting up pyenv in $rcfile" - echo -e "\n# pyenv setup" >> $rcfile - echo 'export PYENV_ROOT="$HOME/.pyenv"' >> $rcfile - echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> $rcfile - echo 'eval "$(pyenv init - zsh)"' >> $rcfile -fi -## add aliases -### check for aliases in rcfile -grep -q '## python aliases' $rcfile -rc_pyalias_check=$? # get retcode, 0 for found not 0 for not found - -if [ $rc_pyalias_check -eq 0 ]; then # if aliases found - echo "pyenv aliases already set up in $rcfile, skipping" -else # if aliases not found, add python shit - echo "Setting up pyenv aliases in $rcfile" - echo "## python aliases" >> $rcfile - echo 'alias py=python' >> $rcfile - echo 'alias py3=python' >> $rcfile - echo 'alias py2=python' >> $rcfile - echo 'alias python3=python' >> $rcfile - echo 'alias python2=python' >> $rcfile - echo 'alias pip3=pip' >> $rcfile - echo -e "alias pip2=pip\n" >> $rcfile -fi - -echo -e "\n\ndone~ :3~\n\treset shell with exec \"\$SHELL\"\n" \ No newline at end of file