├── .github ├── FUNDING.yml └── workflows │ └── macos.yml ├── .gitignore ├── CHANGES.md ├── LICENSE.txt ├── Makefile ├── README.md ├── Sloth.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── Sloth.xcscmblueprint ├── sveinbjorn.mode1 └── xcuserdata │ └── sveinbjorn.xcuserdatad │ └── xcschemes │ ├── Sloth.xcscheme │ └── xcschememanagement.plist ├── TODO.md ├── assets ├── SlothIcon.iconset │ ├── icon_128x128.png │ ├── icon_128x128@2x.png │ ├── icon_16x16.png │ ├── icon_16x16@2x.png │ ├── icon_256x256.png │ ├── icon_256x256@2x.png │ ├── icon_32x32.png │ ├── icon_32x32@2x.png │ ├── icon_512x512.png │ └── icon_512x512@2x.png ├── pipe-240px.png ├── sloth-icon-old.ai ├── sloth-icon.ai └── socket-512px.png ├── resources ├── Credits.rtf ├── Defaults.plist ├── Images.xcassets │ ├── Cog.imageset │ │ ├── Contents.json │ │ ├── cog.png │ │ └── cog@2x.png │ ├── Contents.json │ ├── Dollar.imageset │ │ ├── Contents.json │ │ ├── Dollar.png │ │ └── Dollar@2x.png │ ├── GitHub.imageset │ │ ├── Contents.json │ │ ├── GitHub.png │ │ └── GitHub@2x.png │ ├── Info.imageset │ │ ├── Contents.json │ │ ├── Info@1x.png │ │ └── Info@2x.png │ ├── Kill.imageset │ │ ├── Contents.json │ │ ├── Kill@1x.png │ │ └── Kill@2x.png │ ├── Pipe.imageset │ │ ├── Contents.json │ │ ├── Pipe@2x.png │ │ └── pipe.png │ ├── QuestionMark.imageset │ │ ├── Contents.json │ │ ├── question_mark.png │ │ └── question_mark@2x.png │ └── Socket.imageset │ │ ├── Contents.json │ │ ├── Socket@2x.png │ │ └── socket.png ├── Info.plist ├── InfoPanel.xib ├── MainMenu.xib ├── Prefs.xib ├── Sloth.entitlements ├── sloth.icns ├── sloth_icon.png ├── sloth_screenshot1.jpg ├── sloth_screenshot2.jpg └── sloth_screenshot3.jpg ├── source ├── Common.h ├── InfoPanelController.h ├── InfoPanelController.m ├── Item.h ├── Item.m ├── LsofTask.h ├── LsofTask.m ├── PrefsController.h ├── PrefsController.m ├── SlothController.h ├── SlothController.m ├── Util │ ├── Alerts.h │ ├── Alerts.m │ ├── FSUtils.h │ ├── FSUtils.m │ ├── IPUtils.h │ ├── IPUtils.m │ ├── IconUtils.h │ ├── IconUtils.m │ ├── MutableDictProxy.h │ ├── MutableDictProxy.m │ ├── NSString+RegexConvenience.h │ ├── NSString+RegexConvenience.m │ ├── NSWorkspace+Additions.h │ ├── NSWorkspace+Additions.m │ ├── ProcessUtils.h │ ├── ProcessUtils.m │ ├── STPrivilegedTask.h │ ├── STPrivilegedTask.m │ ├── VolumesPopUpButton.h │ └── VolumesPopUpButton.m └── main.m └── sparkle ├── SlothAppcast.xml ├── Sparkle.framework ├── Autoupdate ├── Headers ├── Modules ├── PrivateHeaders ├── Resources ├── Sparkle ├── Updater.app ├── Versions │ ├── B │ │ ├── Autoupdate │ │ ├── Headers │ │ │ ├── SPUDownloadData.h │ │ │ ├── SPUStandardUpdaterController.h │ │ │ ├── SPUStandardUserDriver.h │ │ │ ├── SPUStandardUserDriverDelegate.h │ │ │ ├── SPUUpdateCheck.h │ │ │ ├── SPUUpdatePermissionRequest.h │ │ │ ├── SPUUpdater.h │ │ │ ├── SPUUpdaterDelegate.h │ │ │ ├── SPUUpdaterSettings.h │ │ │ ├── SPUUserDriver.h │ │ │ ├── SPUUserUpdateState.h │ │ │ ├── SUAppcast.h │ │ │ ├── SUAppcastItem.h │ │ │ ├── SUErrors.h │ │ │ ├── SUExport.h │ │ │ ├── SUStandardVersionComparator.h │ │ │ ├── SUUpdatePermissionResponse.h │ │ │ ├── SUUpdater.h │ │ │ ├── SUUpdaterDelegate.h │ │ │ ├── SUVersionComparisonProtocol.h │ │ │ ├── SUVersionDisplayProtocol.h │ │ │ └── Sparkle.h │ │ ├── Modules │ │ │ └── module.modulemap │ │ ├── PrivateHeaders │ │ │ ├── SPUAppcastItemStateResolver.h │ │ │ ├── SPUGentleUserDriverReminders.h │ │ │ ├── SPUInstallationType.h │ │ │ ├── SPUStandardUserDriver+Private.h │ │ │ ├── SPUUserAgent+Private.h │ │ │ ├── SUAppcastItem+Private.h │ │ │ └── SUInstallerLauncher+Private.h │ │ ├── Resources │ │ │ ├── Base.lproj │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ │ │ ├── keyedobjects-101300.nib │ │ │ │ │ └── keyedobjects-110000.nib │ │ │ │ └── Sparkle.strings │ │ │ ├── Info.plist │ │ │ ├── ReleaseNotesColorStyle.css │ │ │ ├── SUStatus.nib │ │ │ └── en.lproj │ │ │ │ ├── SUUpdateAlert.strings │ │ │ │ └── SUUpdatePermissionPrompt.strings │ │ ├── Sparkle │ │ ├── Updater.app │ │ │ └── Contents │ │ │ │ ├── Info.plist │ │ │ │ ├── MacOS │ │ │ │ └── Updater │ │ │ │ ├── PkgInfo │ │ │ │ ├── Resources │ │ │ │ └── SUStatus.nib │ │ │ │ └── _CodeSignature │ │ │ │ └── CodeResources │ │ ├── XPCServices │ │ │ ├── Downloader.xpc │ │ │ │ └── Contents │ │ │ │ │ ├── Info.plist │ │ │ │ │ ├── MacOS │ │ │ │ │ └── Downloader │ │ │ │ │ └── _CodeSignature │ │ │ │ │ └── CodeResources │ │ │ └── Installer.xpc │ │ │ │ └── Contents │ │ │ │ ├── Info.plist │ │ │ │ ├── MacOS │ │ │ │ └── Installer │ │ │ │ └── _CodeSignature │ │ │ │ └── CodeResources │ │ └── _CodeSignature │ │ │ └── CodeResources │ └── Current └── XPCServices ├── dsa_pub.pem ├── generate_keys ├── sign_update └── sign_update.rb /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: ["https://paypal.me/sveinbjornt", sveinbjorn.org/donations] 4 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [ '*' ] 6 | pull_request: 7 | branches: [ '*' ] 8 | 9 | jobs: 10 | build: 11 | name: Build on macOS 12 | runs-on: macos-latest 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | - run: gem install xcpretty 18 | - name: Build app 19 | run: make build_unsigned | xcpretty -c && exit ${PIPESTATUS[0]} 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | products/ 4 | DerivedData 5 | ## Various settings 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | ## Other 16 | *.xccheckout 17 | *.moved-aside 18 | *.xcuserstate 19 | *.xcworkspace 20 | dsa_priv.pem 21 | .xcbkptlist 22 | sparkle/update_appcast.sh 23 | keys/* 24 | notarize.sh 25 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## Sloth version history 4 | 5 | ### 19/05/2025 - Version 3.4 6 | 7 | * "Copy" on app/process or file now copies both filesystem representation and string 8 | * Faster asynchronous file info processing in Info Panel 9 | * Various minor improvements 10 | 11 | ### 25/04/2024 - Version 3.3 12 | 13 | * Added optional path bar which is shown when a file system item is selected 14 | * Now defaults to killing w. SIGTERM. The old behaviour of sending SIGKILL can be set in Prefs 15 | * Minor bug fixes and improvements 16 | 17 | ### 30/01/2022 - Version 3.2 18 | 19 | * Various minor bug fixes and interface refinements 20 | 21 | ### 18/03/2021 - Version 3.1 22 | 23 | * Configurable refresh interval 24 | * Default (regex) filters can be set in Preferences 25 | * Fixed filtering by volume on Catalina and Big Sur 26 | * Various minor bug fixes and interface improvements 27 | 28 | ### 26/11/2020 - Version 3.0.1 29 | 30 | * Fixed crash bug on macOS Big Sur 31 | 32 | ### 24/11/2020 - Version 3.0 33 | 34 | * Universal binary supporting Apple's arm64 architecture 35 | * New square icon for Big Sur 36 | * Info Panel now shows volume name and mount point for file system items 37 | * New "Show Package Contents" contextual menu item for bundles 38 | * Various minor fixes and performance improvements 39 | * Now requires macOS 10.9 or later 40 | 41 | ### 27/02/2020 - Version 2.9 42 | 43 | * Sort by process type, bundle identifier or Carbon Process Serial Number 44 | * Better handling of errors in lsof output 45 | 46 | ### 30/03/2019 - Version 2.8.1 47 | 48 | * Fixed potential crash bug introduced in version 2.8. 49 | 50 | ### 27/03/2019 - Version 2.8 51 | 52 | * New Dark Mode friendly template icons for Mojave 53 | * Multiple items can now be selected and copied 54 | * Info Panel now shows which processes are connected to each other via unix pipes & domain sockets 55 | * Info Panel now also shows file system info such as device name & inode 56 | * Cmd-L menu action to show selected item 57 | * Minor performance improvements 58 | * Sparkle update framework now has Mojave Dark Mode-compatible appearance 59 | * No longer shows hidden volumes in Volumes filter 60 | * Fixed issue with mangled process names 61 | * Fixed issue with pipe icon on non-retina displays 62 | * Fixed minor memory leak 63 | * More graceful error handling when file descriptor lookup fails in lsof 64 | 65 | ### 10/02/2019 - Version 2.7 66 | 67 | * Info Panel now shows file Uniform Type Identifier 68 | * Fixed crash bug on macOS 10.9 and earlier 69 | * Various minor bug fixes and interface improvements 70 | 71 | ### 26/09/2018 - Version 2.6 72 | 73 | * New and improved contextual menu 74 | * Fixed quirks with macOS Mojave's "Dark Mode" 75 | * Various user interface improvements 76 | 77 | ### 02/06/2018 - Version 2.5 78 | 79 | * Fixed critical lsof output parsing bug introduced in 2.4 80 | * New "Authenticate on launch" option in Preferences 81 | * Various minor interface refinements 82 | 83 | ### 10/05/2018 - Version 2.4 84 | 85 | * Now defaults to showing Mac-friendly process names (e.g. "Safari Web Content" instead of "com.apple.WebKit.WebContent") 86 | * Unix process names no longer truncated to 32 characters 87 | * Search filter can now be used to filter by IP protocol (e.g. TCP or UDP) or IP version (e.g. IPv4 or IPv6) 88 | * Now shows TCP socket state (e.g. LISTEN, ESTABLISHED) in list and Info Panel 89 | * Info Panel now shows file descriptor integer 90 | * Info Panel now shows additional info for character devices 91 | * Info Panel now shows Carbon Process Serial Number (PSN) for processes, if available 92 | * Much improved IPv6 socket handling 93 | * DNS to IP and port name resolution in Info Panel when DNS/port lookup enabled in Prefs 94 | * Minor user interface enhancements 95 | 96 | ### 16/04/2018 - Version 2.3 97 | 98 | * Now supports access mode filtering (e.g. read, write, read/write) 99 | * Search filter now also filters by PID 100 | * DNS and port name lookup for IP Sockets in Info Panel 101 | * Info Panel now identifies standard I/O stream character devices 102 | * New Search Filter menu with case sensitivity and regex options 103 | * New application icon 104 | * Fixed bug where Volumes filter wouldn't work 105 | * Minor interface improvements 106 | 107 | ### 07/03/2018 - Version 2.2 108 | 109 | * Now defaults to excluding process binaries, shared libraries and current working directories in listing 110 | * DNS and port name lookup now disabled by default for faster execution (can be enabled in Preferences) 111 | * Info Panel now displays file access mode and process owner 112 | * New sort option: User ID 113 | * Info Panel now shows IP socket protocol and version 114 | * New Preferences window 115 | * New high-resolution pipe and socket icons 116 | * Fixed bug where sort settings were not respected on launch 117 | 118 | ### 12/02/2018 - Version 2.1 119 | 120 | * Copying a file path now creates a file representation in clipboard in addition to text 121 | * File paths are now red in colour if selected file does not exist at path 122 | * Uniform Type Identifier now used to identify app bundles instead of .app suffix 123 | * Fixed issue with Info Window's handling of moved or non-existent files 124 | * Minor interface refinements 125 | 126 | ### 01/10/2017 - Version 2.0 127 | 128 | * New Volumes filter 129 | * New "Sort By" submenu under View in main menu 130 | * Sorting by PID now correctly does numerical sort instead of alphabetic 131 | 132 | ### 07/06/2017- Version 1.9 133 | 134 | * Files can now be dragged and dropped 135 | * Cmd-F now focuses on filter field 136 | * File representations can now be copied to the clipboard 137 | * Cmd-double-click now reveals file in Finder 138 | * Fixed various minor user interface bugs 139 | * Fixed collapse all bug with Info Panel open 140 | * New compact interface size option 141 | * Fixed broken permissions display for non-bundle processes in Info Panel 142 | 143 | ### 03/05/2017 - Version 1.8 144 | 145 | * Sloth is now code-signed 146 | * QuickLook now works from the Info panel 147 | * Minor user interface improvements 148 | 149 | ### 17/06/2016 - Version 1.7 150 | 151 | * New Info Panel for items 152 | * Minor UI changes 153 | 154 | ### 24/02/2016 - Version 1.6 155 | 156 | * Asynchronous refresh 157 | * Much improved performance 158 | * UI improvements 159 | * New filtering options 160 | * Smarter regex filtering 161 | * Load results as root without relaunching application 162 | * Expanded sorting options 163 | * Migrated project to ARC, modern Objective-C and Xcode 7 164 | * Now requires OS X 10.8 or later 165 | 166 | ### 08/07/2010 - Version 1.5 167 | 168 | * Column sorting, column rearrangement 169 | * Several bug fixes 170 | * Copy/drag and drop selected items 171 | 172 | ### 29/05/2009 - Version 1.4 173 | 174 | * Regular expressions in search filter 175 | * New "Relaunch as root" option 176 | * Fixed bug in Mac OS X 10.5 177 | * Now built for Mac OS X 10.4 or later 178 | 179 | ### 28/07/2006 - Version 1.3.1 180 | 181 | * Released as a Universal Binary 182 | 183 | ### 05/03/2004 - Version 1.3 184 | 185 | * Live update for search filter 186 | * Sorting by column now works 187 | * Performance improvements 188 | * Lots of code replaced by Cocoa bindings thanks to Bill Bumgarner 189 | 190 | ### 27/02/2004 - Version 1.2 191 | 192 | * Filter search field now tries to match all fields when filtering 193 | * Added auto-refresh timer option 194 | * lsof binary and kill signal type can now be set in Preferences 195 | * New application icon 196 | * Added Icelandic and Japanese localizations 197 | 198 | ### 22/02/2004 - Version 1.1 199 | 200 | * Added search filter. 201 | * New Action menu with menu items and shortcuts for button actions 202 | 203 | ### 21/02/2004 - Version 1.0 204 | 205 | * Initial release 206 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sloth app 2 | 3 | XCODE_PROJ := "Sloth.xcodeproj" 4 | BUILD_DIR := "products" 5 | 6 | VERSION := $(shell /usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" resources/Info.plist) 7 | APP_NAME := $(shell /usr/libexec/PlistBuddy -c "Print :CFBundleName" resources/Info.plist) 8 | APP_NAME_LC := $(shell echo "${APP_NAME}" | tr '[:upper:]' '[:lower:]') # lowercase name 9 | APP_BUNDLE_NAME := "$(APP_NAME).app" 10 | 11 | APP_ZIP_NAME := $(APP_NAME_LC:=-${VERSION}).zip 12 | APP_SRC_ZIP_NAME := $(APP_NAME_LC:=-${VERSION}).src.zip 13 | APP_PATH := $(BUILD_DIR:=/${APP_BUNDLE_NAME}) 14 | 15 | all: clean build_unsigned 16 | 17 | release: clean build_signed archives size 18 | 19 | build_unsigned: 20 | mkdir -p $(BUILD_DIR) 21 | xattr -w com.apple.xcode.CreatedByBuildSystem true $(BUILD_DIR) 22 | xcodebuild -parallelizeTargets \ 23 | -project "$(XCODE_PROJ)" \ 24 | -target "$(APP_NAME)" \ 25 | -configuration "Release" \ 26 | CONFIGURATION_BUILD_DIR="$(BUILD_DIR)" \ 27 | CODE_SIGN_IDENTITY="" \ 28 | CODE_SIGNING_REQUIRED=NO \ 29 | CODE_SIGNING_ALLOWED=NO \ 30 | clean build 31 | 32 | build_signed: 33 | mkdir -p $(BUILD_DIR) 34 | xattr -w com.apple.xcode.CreatedByBuildSystem true $(BUILD_DIR) 35 | xcodebuild -parallelizeTargets \ 36 | -project "$(XCODE_PROJ)" \ 37 | -target "$(APP_NAME)" \ 38 | -configuration "Release" \ 39 | CONFIGURATION_BUILD_DIR="$(BUILD_DIR)" \ 40 | clean build 41 | 42 | archives: 43 | @echo "Creating application archive ${APP_ZIP_NAME}..." 44 | @cd $(BUILD_DIR); zip -qy --symlinks $(APP_ZIP_NAME) -r $(APP_BUNDLE_NAME) 45 | 46 | @echo "Creating source archive ${APP_SRC_ZIP_NAME}..." 47 | @cd $(BUILD_DIR); zip -qy --symlinks -r "${APP_SRC_ZIP_NAME}" ".." -x \*.git\* -x \*.zip\* -x \*.DS_Store\* -x \*dsa_priv.pem\* -x \*Sparkle/dsa_priv.pem\* -x \*products/\* -x \*build/\* -x \*xcuserdata\* 48 | 49 | @echo "Generating Sparkle EdDSA signature for archive" 50 | @cd $(BUILD_DIR); ../sparkle/sign_update $(APP_ZIP_NAME) 51 | 52 | size: 53 | @echo "App bundle size:" 54 | @du -hs $(APP_PATH) 55 | @echo "Binary size:" 56 | @stat -f %z $(APP_PATH)/Contents/MacOS/* 57 | @echo "Archive Sizes:" 58 | @cd $(BUILD_DIR); du -hs $(APP_ZIP_NAME) 59 | @cd $(BUILD_DIR); du -hs $(APP_SRC_ZIP_NAME) 60 | 61 | clean: 62 | xattr -w com.apple.xcode.CreatedByBuildSystem true $(BUILD_DIR) 63 | xcodebuild -project "$(XCODE_PROJ)" clean 64 | rm -rf $(BUILD_DIR)/* 2> /dev/null 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![macOS](https://img.shields.io/badge/macOS-000000?style=flat&logo=apple&logoColor=white)]() 2 | [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 3 | [![Language](https://img.shields.io/badge/language-objective--c-lightgrey)]() 4 | [![Release](https://shields.io/github/v/release/sveinbjornt/sloth?display_name=tag)]() 5 | [![Build](https://github.com/sveinbjornt/sloth/actions/workflows/macos.yml/badge.svg)]() 6 | 7 | # Sloth 8 | 9 | 10 | 11 | **Sloth** is a native Mac app that shows all open files, directories, sockets, pipes, and devices in use by all running processes on your system. This makes it easy to inspect which apps are using which files, etc. 12 | 13 | * View all open files, directories, IP sockets, devices, Unix domain sockets, and pipes 14 | * Filter by name, access mode, volume, type, location, or using regular expressions 15 | * Sort by process name, file count, type, process ID, user ID, Carbon PSN, bundle UTI, etc. 16 | * View IP socket status, protocol, port and version 17 | * View sockets and pipes established between processes 18 | * Inspection window with detailed macOS and Unix file/socket/process info 19 | * Powerful contextual menu for file operations 20 | * In-app authentication to scan with root privileges 21 | * Very fast, responsive native app written in Objective-C/Cocoa 22 | 23 | Sloth is essentially a friendly, exploratory graphical user interface built on top of the [`lsof`](https://en.wikipedia.org/wiki/Lsof) command line tool. The output of `lsof` is parsed and shown in a sortable, searchable outline view with all sorts of convenient additional functionality. Check out the screenshots below. 24 | 25 | ## Download 26 | 27 | 28 | 29 | Sloth is free, open source software and has been continuously developed and maintained for a very long time (since 2004). 30 | **If you find this program useful, please [make a donation](https://sveinbjorn.org/donations).** 31 | 32 | * **[⬇ Download Sloth 3.4](https://sveinbjorn.org/files/software/sloth.zip)** (~1.3 MB, Universal ARM/Intel 64-bit, macOS 10.13 or later, Developer ID signed and notarized) 33 | 34 | Sloth can also be installed via [Homebrew](https://brew.sh) (may not be the latest version): 35 | 36 | ```shell 37 | brew install --cask sloth 38 | ``` 39 | 40 | If you need to run it on 10.9-10.12, version 3.2 works just fine. Older versions supporting macOS 10.8 and earlier can be downloaded [here](https://sveinbjorn.org/files/software/sloth/). 41 | 42 | 43 | ## Screenshots 44 | 45 | #### View open files 46 | 47 | 48 | Sloth Screenshot 1 - Files 49 | 50 | 51 | #### View IP sockets 52 | 53 | 54 | Sloth Screenshot 2 - IP Sockets 55 | 56 | 57 | #### View sockets and pipes between processes 58 | 59 | 60 | Sloth Screenshot 3 - Pipes and Unix Sockets 61 | 62 | 63 | ## Build 64 | 65 | Sloth can be built using a reasonably modern version of Xcode via the `xcodeproj` or by running the following command in the repository root (requires Xcode build tools): 66 | 67 | ``` 68 | make build_unsigned 69 | ``` 70 | 71 | Built products are created in `products/`. 72 | 73 | ## BSD License 74 | 75 | Copyright (c) 2004-2025 Sveinbjorn Thordarson 76 | <sveinbjorn@sveinbjorn.org> 77 | 78 | Redistribution and use in source and binary forms, with or without modification, 79 | are permitted provided that the following conditions are met: 80 | 81 | 1. Redistributions of source code must retain the above copyright notice, this 82 | list of conditions and the following disclaimer. 83 | 84 | 2. Redistributions in binary form must reproduce the above copyright notice, this 85 | list of conditions and the following disclaimer in the documentation and/or other 86 | materials provided with the distribution. 87 | 88 | 3. Neither the name of the copyright holder nor the names of its contributors may 89 | be used to endorse or promote products derived from this software without specific 90 | prior written permission. 91 | 92 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 93 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 94 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 95 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 96 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 97 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 98 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 99 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 100 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 101 | POSSIBILITY OF SUCH DAMAGE. 102 | -------------------------------------------------------------------------------- /Sloth.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sloth.xcodeproj/project.xcworkspace/xcshareddata/Sloth.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "23BB23A2BE8CFBB51BCFB6E922187A2D50765A04+++1CD677A", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | "23BB23A2BE8CFBB51BCFB6E922187A2D50765A04+++1CD677A" : { 5 | 6 | }, 7 | "358f39d3-f018-0410-80e3-90439a6411fa++15+++12218B3" : { 8 | 9 | } 10 | }, 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 12 | "23BB23A2BE8CFBB51BCFB6E922187A2D50765A04+++1CD677A" : 0, 13 | "358f39d3-f018-0410-80e3-90439a6411fa++15+++12218B3" : 0 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "9F3B1CC8-C28B-4C65-B0EB-61AC54A3C15E", 16 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 17 | "23BB23A2BE8CFBB51BCFB6E922187A2D50765A04+++1CD677A" : "sloth\/", 18 | "358f39d3-f018-0410-80e3-90439a6411fa++15+++12218B3" : "sloth\/" 19 | }, 20 | "DVTSourceControlWorkspaceBlueprintNameKey" : "Sloth", 21 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 22 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Sloth.xcodeproj", 23 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "svn+ssh:\/\/subversion.sveinbjorn.org\/svnroot\/sveinbjorn", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Subversion", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "23BB23A2BE8CFBB51BCFB6E922187A2D50765A04+++1CD677A" 28 | }, 29 | { 30 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:sveinbjornt\/Sloth.git", 31 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 32 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "358f39d3-f018-0410-80e3-90439a6411fa++15+++12218B3" 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /Sloth.xcodeproj/xcuserdata/sveinbjorn.xcuserdatad/xcschemes/Sloth.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Sloth.xcodeproj/xcuserdata/sveinbjorn.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Sloth.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8D1107260486CEB800E47090 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO for Sloth 3.4 2 | 3 | * Fix checking Regex and Case Insensitive in filter field options 4 | * Preserve selection between refreshes (preserve expanded items between refreshes?) 5 | * Fix path bar folders contextual click 6 | * Show full command (w/args) for process (ala ps -ef) in Info Panel 7 | * Highlight matching part of string when filtering (option in filter field popup) 8 | * Store authentication privileges and use them to run command line tool "/usr/bin/file" for Info Dialog 9 | * Add tests for lsof output parsing 10 | * Click on connected process f. pipes to select and show info of that process 11 | * Create visualization of pipes between processes in special view 12 | * Update antiquated screenshots in README 13 | * Fix exception raised when "unknown file type" is selected 14 | -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_128x128.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_16x16.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_256x256.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_32x32.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_512x512.png -------------------------------------------------------------------------------- /assets/SlothIcon.iconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/SlothIcon.iconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /assets/pipe-240px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/pipe-240px.png -------------------------------------------------------------------------------- /assets/sloth-icon-old.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/sloth-icon-old.ai -------------------------------------------------------------------------------- /assets/sloth-icon.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/sloth-icon.ai -------------------------------------------------------------------------------- /assets/socket-512px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/assets/socket-512px.png -------------------------------------------------------------------------------- /resources/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1561\cocoasubrtf400 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | {\*\expandedcolortbl;;} 5 | \paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0 6 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc\partightenfactor0 7 | 8 | \f0\fs24 \cf0 Created by {\field{\*\fldinst{HYPERLINK "mailto:sveinbjorn@sveinbjorn.org"}}{\fldrslt Sveinbjorn Thordarson}}\ 9 | \ 10 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc\partightenfactor0 11 | {\field{\*\fldinst{HYPERLINK "https://sveinbjorn.org/sloth"}}{\fldrslt \cf0 https://sveinbjorn.org/sloth}}\ 12 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc\partightenfactor0 13 | \cf0 \ 14 | Sloth is free, open source software. If you find this program useful, please {\field{\*\fldinst{HYPERLINK "https://sveinbjorn.org/donations"}}{\fldrslt make a donation}} to support continued development.} -------------------------------------------------------------------------------- /resources/Defaults.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ascending 6 | 7 | disclosure 8 | 9 | interfaceSize 10 | Normal 11 | showApplicationsOnly 12 | 13 | showCharacterDevices 14 | 15 | showDirectories 16 | 17 | showHomeFolderOnly 18 | 19 | showIPSockets 20 | 21 | showPipes 22 | 23 | showRegularFiles 24 | 25 | showUnixSockets 26 | 27 | sortBy 28 | name 29 | dnsLookup 30 | 31 | showProcessBinaries 32 | 33 | showCurrentWorkingDirectories 34 | 35 | searchFilterCaseSensitive 36 | 37 | searchFilterRegex 38 | 39 | friendlyProcessNames 40 | 41 | authenticateOnLaunch 42 | 43 | updateInterval 44 | 0 45 | accessMode 46 | Any 47 | showPathBar 48 | 49 | alwaysUseSigkill 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /resources/Images.xcassets/Cog.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "cog.png", 5 | "idiom" : "mac", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "cog@2x.png", 10 | "idiom" : "mac", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | }, 18 | "properties" : { 19 | "template-rendering-intent" : "template" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/Images.xcassets/Cog.imageset/cog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Cog.imageset/cog.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Cog.imageset/cog@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Cog.imageset/cog@2x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /resources/Images.xcassets/Dollar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Dollar.png", 5 | "idiom" : "mac", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "Dollar@2x.png", 10 | "idiom" : "mac", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | }, 18 | "properties" : { 19 | "template-rendering-intent" : "template" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/Images.xcassets/Dollar.imageset/Dollar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Dollar.imageset/Dollar.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Dollar.imageset/Dollar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Dollar.imageset/Dollar@2x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/GitHub.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "GitHub.png", 5 | "idiom" : "mac", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "GitHub@2x.png", 10 | "idiom" : "mac", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | }, 18 | "properties" : { 19 | "template-rendering-intent" : "template" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/Images.xcassets/GitHub.imageset/GitHub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/GitHub.imageset/GitHub.png -------------------------------------------------------------------------------- /resources/Images.xcassets/GitHub.imageset/GitHub@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/GitHub.imageset/GitHub@2x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Info.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Info@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "filename" : "Info@2x.png", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | }, 18 | "properties" : { 19 | "template-rendering-intent" : "template", 20 | "preserves-vector-representation" : true 21 | } 22 | } -------------------------------------------------------------------------------- /resources/Images.xcassets/Info.imageset/Info@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Info.imageset/Info@1x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Info.imageset/Info@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Info.imageset/Info@2x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Kill.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Kill@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "filename" : "Kill@2x.png", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | }, 18 | "properties" : { 19 | "template-rendering-intent" : "template" 20 | } 21 | } -------------------------------------------------------------------------------- /resources/Images.xcassets/Kill.imageset/Kill@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Kill.imageset/Kill@1x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Kill.imageset/Kill@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Kill.imageset/Kill@2x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Pipe.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Pipe.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "filename" : "Pipe@2x.png", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | }, 18 | "properties" : { 19 | "template-rendering-intent" : "template" 20 | } 21 | } -------------------------------------------------------------------------------- /resources/Images.xcassets/Pipe.imageset/Pipe@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Pipe.imageset/Pipe@2x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Pipe.imageset/pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Pipe.imageset/pipe.png -------------------------------------------------------------------------------- /resources/Images.xcassets/QuestionMark.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "question_mark.png", 5 | "idiom" : "mac", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "question_mark@2x.png", 10 | "idiom" : "mac", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | }, 18 | "properties" : { 19 | "template-rendering-intent" : "template" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/Images.xcassets/QuestionMark.imageset/question_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/QuestionMark.imageset/question_mark.png -------------------------------------------------------------------------------- /resources/Images.xcassets/QuestionMark.imageset/question_mark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/QuestionMark.imageset/question_mark@2x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Socket.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Socket.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "filename" : "Socket@2x.png", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | }, 18 | "properties" : { 19 | "template-rendering-intent" : "template" 20 | } 21 | } -------------------------------------------------------------------------------- /resources/Images.xcassets/Socket.imageset/Socket@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Socket.imageset/Socket@2x.png -------------------------------------------------------------------------------- /resources/Images.xcassets/Socket.imageset/socket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/Images.xcassets/Socket.imageset/socket.png -------------------------------------------------------------------------------- /resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | Sloth 9 | CFBundleGetInfoString 10 | © 2004-2025 Sveinbjorn Thordarson. 11 | CFBundleIconFile 12 | sloth 13 | CFBundleIdentifier 14 | org.sveinbjorn.Sloth 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | Sloth 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 3.4 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 346 27 | LSApplicationCategoryType 28 | public.app-category.utilities 29 | LSMinimumSystemVersion 30 | 10.13 31 | NSHumanReadableCopyright 32 | © 2004-2025 Sveinbjorn Thordarson. 33 | NSMainNibFile 34 | MainMenu 35 | NSPrincipalClass 36 | NSApplication 37 | NSSupportsSuddenTermination 38 | 39 | SUFeedURL 40 | https://sveinbjorn.org/files/appcasts/SlothAppcast.xml 41 | SUPublicEDKey 42 | XqfjBk0i1aF2FrZQfUIcpU+h7151345+3pSN9Bs7GwI= 43 | 44 | 45 | -------------------------------------------------------------------------------- /resources/Sloth.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.automation.apple-events 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/sloth.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/sloth.icns -------------------------------------------------------------------------------- /resources/sloth_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/sloth_icon.png -------------------------------------------------------------------------------- /resources/sloth_screenshot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/sloth_screenshot1.jpg -------------------------------------------------------------------------------- /resources/sloth_screenshot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/sloth_screenshot2.jpg -------------------------------------------------------------------------------- /resources/sloth_screenshot3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/resources/sloth_screenshot3.jpg -------------------------------------------------------------------------------- /source/Common.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #define PROGRAM_NAME @"Sloth" 32 | #define PROGRAM_VERSION @"3.4" 33 | #define PROGRAM_WEBSITE @"https://sveinbjorn.org/sloth" 34 | #define PROGRAM_DONATIONS @"https://sveinbjorn.org/donations" 35 | #define PROGRAM_GITHUB_WEBSITE @"https://github.com/sveinbjornt/Sloth" 36 | 37 | #define LSOF_PATH @"/usr/sbin/lsof" 38 | #define LSOF_ARGS @[@"-F", @"fpPcntuaTdDiR", @"+c0"] 39 | #define LSOF_NO_DNS_ARGS @[@"-n", @"-P"] 40 | 41 | #define DYNAMIC_UTI_PREFIX @"dyn." 42 | 43 | #define VALUES_KEYPATH(X) [NSString stringWithFormat:@"values.%@", (X)] 44 | 45 | // Let's make things a bit less verbose 46 | #define FILEMGR [NSFileManager defaultManager] 47 | #define DEFAULTS [NSUserDefaults standardUserDefaults] 48 | #define WORKSPACE [NSWorkspace sharedWorkspace] 49 | 50 | // Logging in debug mode only 51 | #ifdef DEBUG 52 | #define DLog(...) NSLog(__VA_ARGS__) 53 | #else 54 | #define DLog(...) 55 | #endif 56 | -------------------------------------------------------------------------------- /source/InfoPanelController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @class Item; 34 | 35 | @interface InfoPanelController : NSWindowController 36 | 37 | - (void)loadItem:(Item *)item; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /source/Item.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | #import "MutableDictProxy.h" 33 | 34 | // This class behaves like a dict since it inherits from MutableDictProxy object and 35 | // can therefore be subscripted using modern Objective-C syntax, e.g. spec[@"key"] 36 | @interface Item : MutableDictProxy 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /source/Item.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "Item.h" 32 | #import "ProcessUtils.h" 33 | 34 | @interface Item () 35 | { 36 | NSDictionary *lazyAttrs; 37 | } 38 | @end 39 | 40 | @implementation Item 41 | 42 | - (instancetype)init { 43 | self = [super init]; 44 | if (self) { 45 | // Getting som item properties is expensive and therefore lazy-loaded 46 | lazyAttrs = @{ 47 | //@"identifier": [NSValue valueWithPointer:@selector(bundleIdentifier)] 48 | }; 49 | } 50 | return self; 51 | } 52 | 53 | - (id)objectForKey:(id)aKey { 54 | // See if dict has an entry for this key 55 | id obj = [properties objectForKey:aKey]; 56 | if (!obj) { 57 | // If not, check if it's a lazy-load property 58 | id val = [lazyAttrs objectForKey:aKey]; 59 | // If it is, generate the value using the appropriate selector 60 | if (val) { 61 | SEL sel = [val pointerValue]; 62 | if (sel && [self respondsToSelector:sel]) { 63 | #pragma clang diagnostic push 64 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 65 | properties[aKey] = [self performSelector:sel]; 66 | #pragma clang diagnostic pop 67 | return properties[aKey]; 68 | } 69 | } 70 | } 71 | return obj; 72 | } 73 | 74 | - (NSString *)bundleIdentifier { 75 | return [ProcessUtils identifierForBundleAtPath:self[@"path"]]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /source/LsofTask.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | #import "Item.h" 33 | 34 | @class Item; 35 | 36 | @interface LsofTask : NSObject 37 | 38 | - (NSMutableArray *)launch:(AuthorizationRef)authRef numFiles:(int *)numFiles; 39 | + (void)updateProcessInfo:(NSMutableDictionary *)p; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /source/PrefsController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @interface PrefsController : NSWindowController 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /source/PrefsController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "Common.h" 32 | #import "PrefsController.h" 33 | #import "IconUtils.h" 34 | 35 | #define DEFAULT_FILTER @".*\\.metallib$" 36 | 37 | @interface PrefsController () 38 | { 39 | NSMutableArray *filters; 40 | } 41 | @property (weak) IBOutlet NSTabView *tabView; 42 | @property (weak) IBOutlet NSTableView *filtersTableView; 43 | @property (weak) IBOutlet NSButton *removeFilterButton; 44 | @property (weak) IBOutlet NSButton *addFilterButton; 45 | 46 | @end 47 | 48 | @implementation PrefsController 49 | 50 | - (void)windowDidLoad { 51 | [super windowDidLoad]; 52 | NSImage *img = [IconUtils imageNamed:@"Prefs"]; 53 | if (img) { 54 | [self.window setRepresentedURL:[NSURL URLWithString:@""]]; // Not representing a URL 55 | [[self.window standardWindowButton:NSWindowDocumentIconButton] setImage:img]; 56 | } 57 | filters = [NSMutableArray new]; 58 | for (NSArray *a in [DEFAULTS objectForKey:@"filters"]) { 59 | [filters addObject:[a mutableCopy]]; 60 | } 61 | [self updateRemoveFilterButtonStatus]; 62 | } 63 | 64 | - (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu { 65 | // Prevent popup menu when window icon/title is cmd-clicked 66 | return NO; 67 | } 68 | 69 | - (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard { 70 | // Prevent dragging of title bar icon 71 | return NO; 72 | } 73 | 74 | - (void)showWindow:(id)sender { 75 | [super showWindow:sender]; 76 | [self.tabView selectFirstTabViewItem:self]; 77 | } 78 | 79 | #pragma mark - 80 | 81 | - (IBAction)restoreDefaults:(id)sender { 82 | [DEFAULTS setBool:NO forKey:@"dnsLookup"]; 83 | [DEFAULTS setBool:NO forKey:@"showProcessBinaries"]; 84 | [DEFAULTS setBool:NO forKey:@"showCurrentWorkingDirectories"]; 85 | [DEFAULTS setBool:YES forKey:@"friendlyProcessNames"]; 86 | [DEFAULTS setBool:NO forKey:@"authenticateOnLaunch"]; 87 | [DEFAULTS setBool:NO forKey:@"alwaysUseSigkill"]; 88 | 89 | [DEFAULTS setObject:@[@[@NO, DEFAULT_FILTER]] forKey:@"filters"]; 90 | [DEFAULTS synchronize]; 91 | 92 | filters = [NSMutableArray new]; 93 | for (NSArray *a in [DEFAULTS objectForKey:@"filters"]) { 94 | [filters addObject:[a mutableCopy]]; 95 | } 96 | 97 | [self.filtersTableView reloadData]; 98 | } 99 | 100 | #pragma mark - Filters UI 101 | 102 | - (IBAction)addFilter:(id)sender { 103 | [filters addObject:[@[@YES, DEFAULT_FILTER] mutableCopy]]; 104 | [self saveFilters]; 105 | [self.filtersTableView reloadData]; 106 | [self.filtersTableView editColumn:1 107 | row:[filters count]-1 108 | withEvent:[[NSApplication sharedApplication] currentEvent] 109 | select:YES]; 110 | } 111 | 112 | - (IBAction)removeFilter:(id)sender { 113 | NSInteger selected = [self.filtersTableView selectedRow]; 114 | if (selected != -1 && selected < [filters count]) { 115 | [filters removeObjectAtIndex:selected]; 116 | } 117 | [self saveFilters]; 118 | [self.filtersTableView reloadData]; 119 | [self updateRemoveFilterButtonStatus]; 120 | } 121 | 122 | - (void)saveFilters { 123 | [DEFAULTS setObject:filters forKey:@"filters"]; 124 | [DEFAULTS synchronize]; 125 | } 126 | 127 | - (void)updateRemoveFilterButtonStatus { 128 | BOOL hasSelection = ([[self.filtersTableView selectedRowIndexes] count] > 0); 129 | [self.removeFilterButton setEnabled:hasSelection]; 130 | } 131 | 132 | #pragma mark - NSTableViewDataSource 133 | 134 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView { 135 | return [filters count]; 136 | } 137 | 138 | - (void)tableView:(NSTableView *)tableView 139 | setObjectValue:(id)value 140 | forTableColumn:(NSTableColumn *)column 141 | row:(NSInteger)row { 142 | if ([[column identifier] isEqualToString:@"1"]) { 143 | [filters objectAtIndex:row][0] = @(![[filters objectAtIndex:row][0] boolValue]); 144 | } else { 145 | [filters objectAtIndex:row][1] = value; 146 | } 147 | [self saveFilters]; 148 | [self.filtersTableView reloadData]; 149 | } 150 | 151 | - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)column row:(NSInteger)rowIndex { 152 | if ([[column identifier] isEqualToString:@"1"]) { 153 | return [[filters objectAtIndex:rowIndex] objectAtIndex:0]; 154 | } else { 155 | NSString *filterStr = [[filters objectAtIndex:rowIndex] objectAtIndex:1]; 156 | // Make sure the string successfully compiles as a regex 157 | NSError *error = nil; 158 | [NSRegularExpression regularExpressionWithPattern:filterStr options:0 error:&error]; 159 | // If regex compilation fails, show it colored red 160 | if (error != nil) { 161 | DLog(@"Regex compilation failed: %@", [error localizedDescription]); 162 | NSDictionary *textAttributes = @{ NSForegroundColorAttributeName: [NSColor redColor] }; 163 | return [[NSAttributedString alloc] initWithString:filterStr attributes:textAttributes]; 164 | } 165 | return filterStr; 166 | } 167 | return nil; 168 | } 169 | 170 | - (void)tableViewSelectionDidChange:(NSNotification *)aNotification { 171 | [self updateRemoveFilterButtonStatus]; 172 | } 173 | 174 | @end 175 | -------------------------------------------------------------------------------- /source/SlothController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | #import "VolumesPopUpButton.h" 33 | 34 | @interface SlothController : NSObject 41 | - (IBAction)kill:(id)sender; 42 | - (void)revealItemInFinder:(NSDictionary *)item; 43 | @end 44 | -------------------------------------------------------------------------------- /source/Util/Alerts.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | #import 33 | 34 | @interface Alerts : NSObject 35 | 36 | + (void)alert:(NSString *)message subText:(NSString *)subtext style:(NSAlertStyle)style; 37 | + (void)alert:(NSString *)message subText:(NSString *)subtext; 38 | + (void)alert:(NSString *)message subTextFormat:(NSString *)formatString, ...; 39 | 40 | + (void)fatalAlert:(NSString *)message subText:(NSString *)subtext; 41 | + (void)fatalAlert:(NSString *)message subTextFormat:(NSString *)formatString, ...; 42 | 43 | + (BOOL)proceedAlert:(NSString *)message subText:(NSString *)subtext withActionNamed:(NSString *)action; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /source/Util/Alerts.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "Alerts.h" 32 | 33 | @implementation Alerts 34 | 35 | + (void)alert:(NSString *)message subText:(NSString *)subtext style:(NSAlertStyle)style { 36 | NSAlert *alert = [[NSAlert alloc] init]; 37 | [alert addButtonWithTitle:@"OK"]; 38 | [alert setMessageText:message]; 39 | [alert setInformativeText:subtext]; 40 | [alert setAlertStyle:style]; 41 | [[alert window] setPreventsApplicationTerminationWhenModal:YES]; 42 | [alert runModal]; 43 | } 44 | 45 | + (void)alert:(NSString *)message subTextFormat:(NSString *)formatString, ... { 46 | va_list args; 47 | va_start(args, formatString); 48 | NSString *formattedString = [[NSString alloc] initWithFormat:formatString arguments:args]; 49 | va_end(args); 50 | [self alert:message subText:formattedString]; 51 | } 52 | 53 | + (void)alert:(NSString *)message subText:(NSString *)subtext { 54 | [self alert:message subText:subtext style:NSAlertStyleWarning]; 55 | } 56 | 57 | + (void)fatalAlert:(NSString *)message subText:(NSString *)subtext { 58 | [self alert:message subText:subtext style:NSAlertStyleCritical]; 59 | [[NSApplication sharedApplication] terminate:self]; 60 | } 61 | 62 | + (void)fatalAlert:(NSString *)message subTextFormat:(NSString *)formatString, ... { 63 | va_list args; 64 | va_start(args, formatString); 65 | NSString *formattedString = [[NSString alloc] initWithFormat:formatString arguments:args]; 66 | va_end(args); 67 | [self fatalAlert:message subText:formattedString]; 68 | } 69 | 70 | #pragma mark - 71 | 72 | + (BOOL)proceedAlert:(NSString *)message subText:(NSString *)subtext withActionNamed:(NSString *)actionName { 73 | NSAlert *alert = [[NSAlert alloc] init]; 74 | [alert addButtonWithTitle:actionName ? actionName : @"Proceed"]; 75 | [alert addButtonWithTitle:@"Cancel"]; 76 | [alert setMessageText:message]; 77 | [alert setInformativeText:subtext]; 78 | [alert setAlertStyle:NSAlertStyleWarning]; 79 | return ([alert runModal] == NSAlertFirstButtonReturn); 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /source/Util/FSUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @interface FSUtils : NSObject 34 | 35 | + (NSDictionary *)mountedFileSystems; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /source/Util/FSUtils.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "FSUtils.h" 32 | #import "Common.h" 33 | 34 | #import 35 | #import 36 | 37 | #define MAX_FILESYSTEMS 128 38 | 39 | @implementation FSUtils 40 | 41 | + (NSDictionary *)mountedFileSystems { 42 | 43 | int fs_count = getfsstat(NULL, 0, MNT_NOWAIT); 44 | if (fs_count == -1) { 45 | fprintf(stderr, "Error: %d\n", errno); 46 | return @{}; 47 | } 48 | if (fs_count > MAX_FILESYSTEMS) { 49 | // We set a maximum number of filesystems to prevent 50 | // a stack overflow. 51 | // TODO: Manually allocate memory from heap instead of using stack 52 | // to handle an arbitrary number of filesystems. 53 | fprintf(stderr, "Too many filesystems, bailing"); 54 | return @{}; 55 | } 56 | 57 | struct statfs buf[fs_count]; 58 | getfsstat(buf, fs_count * sizeof(buf[0]), MNT_NOWAIT); 59 | 60 | NSMutableDictionary *fsdict = [NSMutableDictionary new]; 61 | 62 | for (int i = 0; i < fs_count; ++i) { 63 | dev_t fsid = buf[i].f_fsid.val[0]; 64 | 65 | fsdict[@(fsid)] = @{ 66 | @"devid": @(fsid), 67 | @"devid_major": @(major(fsid)), 68 | @"devid_minor": @(minor(fsid)), 69 | @"fstype": @(buf[i].f_fstypename), 70 | @"devname": @(buf[i].f_mntfromname), 71 | @"mountpoint": @(buf[i].f_mntonname) 72 | }; 73 | } 74 | 75 | return [fsdict copy]; // Return immutable copy 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /source/Util/IPUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @interface IPUtils : NSObject 34 | 35 | + (BOOL)isIPv4AddressString:(NSString *)ipStr; 36 | + (BOOL)isIPv6AddressString:(NSString *)ipString; 37 | + (BOOL)isPortNumberString:(NSString *)portNumStr; 38 | 39 | + (NSString *)dnsNameForIPv4AddressString:(NSString *)ipAddrStr; 40 | + (NSString *)dnsNameForIPv6AddressString:(NSString *)ipAddStr; 41 | + (NSString *)dnsNameForIPAddressString:(NSString *)ipAddStr; 42 | 43 | + (NSString *)IPAddressStringForDNSName:(NSString *)dnsNameString; 44 | + (NSString *)IPv4AddressStringForDNSName:(NSString *)dnsNameString; 45 | + (NSString *)IPv6AddressStringForDNSName:(NSString *)dnsNameString; 46 | 47 | + (NSString *)portNameForPortNumString:(NSString *)portNumStr; 48 | + (NSString *)portNumberForPortNameString:(NSString *)portNameString; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /source/Util/IPUtils.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "IPUtils.h" 32 | #import "NSString+RegexConvenience.h" 33 | 34 | #import 35 | #import 36 | #import 37 | 38 | @implementation IPUtils 39 | 40 | + (BOOL)isIPv4AddressString:(NSString *)ipString { 41 | NSRegularExpression *regex = 42 | [NSRegularExpression regularExpressionWithPattern: 43 | @"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" 44 | options:NSRegularExpressionCaseInsensitive 45 | error:nil]; 46 | return [ipString isMatchedByRegex:regex]; 47 | } 48 | 49 | + (BOOL)isIPv6AddressString:(NSString *)ipString { 50 | NSRegularExpression *regex = 51 | [NSRegularExpression regularExpressionWithPattern: 52 | @"(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" 53 | options:NSRegularExpressionCaseInsensitive 54 | error:nil]; 55 | return [ipString isMatchedByRegex:regex]; 56 | } 57 | 58 | + (BOOL)isPortNumberString:(NSString *)portNumString { 59 | // Starts with, contains only, and ends with numbers 60 | NSRegularExpression *rx = [NSRegularExpression regularExpressionWithPattern:@"^\\d+$" 61 | options:0 62 | error:nil]; 63 | BOOL match = [portNumString isMatchedByRegex:rx]; 64 | int portNum = [portNumString intValue]; 65 | BOOL validRange = (portNum >= 0 && portNum < 65535); 66 | return match && validRange; 67 | } 68 | 69 | #pragma mark - 70 | 71 | + (NSString *)dnsNameForIPv4AddressString:(NSString *)ipAddrStr { 72 | if ([IPUtils isIPv4AddressString:ipAddrStr] == NO) { 73 | return nil; 74 | } 75 | // Do DNS lookup for IP address 76 | return [[NSHost hostWithAddress:ipAddrStr] name]; 77 | } 78 | 79 | + (NSString *)dnsNameForIPv6AddressString:(NSString *)ipAddrStr { 80 | if ([IPUtils isIPv6AddressString:ipAddrStr] == NO) { 81 | return nil; 82 | } 83 | // Do DNS lookup for IP address 84 | return [[NSHost hostWithAddress:ipAddrStr] name]; 85 | } 86 | 87 | + (NSString *)dnsNameForIPAddressString:(NSString *)ipAddStr; { 88 | NSString *dns = [IPUtils dnsNameForIPv4AddressString:ipAddStr]; 89 | if (dns) { 90 | return dns; 91 | } 92 | return [IPUtils dnsNameForIPv6AddressString:ipAddStr]; 93 | } 94 | 95 | #pragma mark - 96 | 97 | + (NSString *)IPAddressStringForDNSName:(NSString *)dnsNameString { 98 | NSString *ipAddr = [IPUtils IPv4AddressStringForDNSName:dnsNameString]; 99 | if (ipAddr) { 100 | return ipAddr; 101 | } 102 | return [IPUtils IPv6AddressStringForDNSName:dnsNameString]; 103 | } 104 | 105 | + (NSString *)IPv4AddressStringForDNSName:(NSString *)dnsNameString { 106 | NSHost *host = [NSHost hostWithName:dnsNameString]; 107 | if (host) { 108 | for (NSString *addr in [host addresses]) { 109 | if ([IPUtils isIPv4AddressString:addr]) { 110 | return addr; 111 | } 112 | } 113 | } 114 | return nil; 115 | } 116 | 117 | + (NSString *)IPv6AddressStringForDNSName:(NSString *)dnsNameString { 118 | NSHost *host = [NSHost hostWithName:dnsNameString]; 119 | if (host) { 120 | for (NSString *addr in [host addresses]) { 121 | if ([IPUtils isIPv6AddressString:addr]) { 122 | return addr; 123 | } 124 | } 125 | } 126 | return nil; 127 | } 128 | 129 | #pragma mark - 130 | 131 | // Look up port name, e.g. "http" for "80", "ssh" for "22", etc. 132 | + (NSString *)portNameForPortNumString:(NSString *)portNumStr { 133 | if ([IPUtils isPortNumberString:portNumStr] == NO) { 134 | return nil; 135 | } 136 | 137 | int port = [portNumStr intValue]; 138 | struct servent *serv; 139 | serv = getservbyport(htons(port), NULL); 140 | 141 | // Just return original port num string if port name couldn't be resolved 142 | if (!serv) { 143 | return portNumStr; 144 | } 145 | 146 | return [NSString stringWithCString:serv->s_name encoding:NSASCIIStringEncoding]; 147 | } 148 | 149 | // Look up port number for name, e.g. "80" for "http", "22" for "ssh", etc. 150 | + (NSString *)portNumberForPortNameString:(NSString *)portNameString { 151 | const char *portName = [portNameString cStringUsingEncoding:NSUTF8StringEncoding]; 152 | struct servent *serv = getservbyname(portName, NULL); 153 | if (serv != NULL) { 154 | int portNum = ntohs(serv->s_port); 155 | return [NSString stringWithFormat:@"%d", portNum]; 156 | } 157 | return nil; 158 | } 159 | 160 | @end 161 | -------------------------------------------------------------------------------- /source/Util/IconUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @interface IconUtils : NSObject 34 | 35 | + (NSImage *)imageNamed:(NSString *)name; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /source/Util/IconUtils.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "Common.h" 32 | #import "IconUtils.h" 33 | 34 | #define CORE_TYPES_RESOURCE(X) \ 35 | [NSString stringWithFormat:@"/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/%@",(X)] 36 | 37 | #define EXEC_ICON_PATH CORE_TYPES_RESOURCE(@"ExecutableBinaryIcon.icns") 38 | #define NETWORK_ICON_PATH CORE_TYPES_RESOURCE(@"SidebarNetwork.icns") 39 | #define FILE_ICON_PATH CORE_TYPES_RESOURCE(@"SidebarGenericFile.icns") 40 | #define FOLDER_ICON_PATH CORE_TYPES_RESOURCE(@"SidebarGenericFolder.icns") 41 | #define APPL_ICON_PATH CORE_TYPES_RESOURCE(@"SidebarApplicationsFolder.icns") 42 | #define HOME_ICON_PATH CORE_TYPES_RESOURCE(@"SidebarHomeFolder.icns") 43 | #define ERR_ICON_PATH CORE_TYPES_RESOURCE(@"AlertStopIcon.icns") 44 | #define QUESTIONMARK_ICON_PATH CORE_TYPES_RESOURCE(@"GenericQuestionMarkIcon.icns") 45 | 46 | static NSMutableDictionary *iconStore; 47 | 48 | @implementation IconUtils 49 | 50 | + (NSMutableDictionary *)_loadIcons { 51 | // We want to use the cool invertible Mojave template icons to represent 52 | // files, directories, IP sockets, etc. but they might not available. We 53 | // therefore define primary icon assets and fallbacks in case they're 54 | // not available on the version of macOS we're running on. This way we 55 | // get the best of both worlds: The old icons when running on an older 56 | // version of macOS, the new ones on Mojave onwards. Saves us from having 57 | // to bloat the application bundle with custom icon assets. 58 | NSMutableDictionary *icons = [NSMutableDictionary dictionary]; 59 | 60 | NSDictionary *iconSettings = @{ 61 | @"File": @[ 62 | @{ @"path": FILE_ICON_PATH, @"template": @YES }, 63 | @{ @"name": @"NSGenericDocument", @"template": @NO } 64 | ], 65 | @"Directory": @[ 66 | @{ @"path": FOLDER_ICON_PATH, @"template": @YES }, 67 | @{ @"name": NSImageNameFolder, @"template": @NO } 68 | ], 69 | @"SmallDirectory": @[ 70 | @{ @"path": FOLDER_ICON_PATH, @"template": @YES }, 71 | @{ @"name": NSImageNameFolder, @"template": @NO } 72 | ], 73 | @"Character Device": @[ 74 | @{ @"name": @"Cog", @"template": @YES }, 75 | @{ @"name": NSImageNameActionTemplate, @"template": @YES }, 76 | @{ @"name": NSImageNameSmartBadgeTemplate, @"template": @YES } 77 | ], 78 | @"Pipe": @[ 79 | @{ @"name": @"Pipe", @"template": @YES } 80 | ], 81 | @"Unix Domain Socket": @[ 82 | @{ @"name": @"Socket", @"template": @YES } 83 | ], 84 | @"IP Socket": @[ 85 | @{ @"path": NETWORK_ICON_PATH, @"template": @YES }, 86 | @{ @"name": NSImageNameNetwork, @"template": @NO } 87 | ], 88 | @"Error": @[ 89 | @{ @"path": ERR_ICON_PATH, @"template": @NO }, 90 | @{ @"name": NSImageNameCaution, @"template": @NO } 91 | ], 92 | @"Prefs": @[ 93 | @{ @"name": NSImageNamePreferencesGeneral, @"template": @NO } 94 | ], 95 | @"Applications": @[ 96 | @{ @"path": APPL_ICON_PATH, @"template": @YES }, 97 | @{ @"name": @"NSDefaultApplicationIcon", @"template": @NO } 98 | ], 99 | @"Home": @[ 100 | @{ @"path": HOME_ICON_PATH, @"template": @YES }, 101 | @{ @"type": NSFileTypeForHFSTypeCode(kToolbarHomeIcon), @"template": @NO } 102 | ], 103 | // @"GenericApplication": @[ 104 | // @{ @"name": @"NSDefaultApplicationIcon", @"template": @NO } 105 | // ], 106 | @"GenericExecutable": @[ 107 | @{ @"path": EXEC_ICON_PATH, @"template": @NO }, 108 | ], 109 | @"Locked": @[ 110 | @{ @"type": NSFileTypeForHFSTypeCode(kLockedIcon), @"template": @NO } 111 | ], 112 | @"Unlocked": @[ 113 | @{ @"type": NSFileTypeForHFSTypeCode(kUnlockedIcon), @"template": @NO } 114 | ], 115 | @"QuestionMark": @[ 116 | @{ @"name": @"QuestionMark", @"template": @YES }, 117 | @{ @"path": QUESTIONMARK_ICON_PATH, @"template": @NO } 118 | ], 119 | @"Dollar": @[ 120 | @{ @"name": @"Dollar", @"template": @YES } 121 | ], 122 | @"GitHub": @[ 123 | @{ @"name": @"GitHub", @"template": @YES } 124 | ], 125 | }; 126 | 127 | for (NSString *name in iconSettings) { 128 | NSArray *opts = iconSettings[name]; 129 | NSImage *img; 130 | 131 | for (NSDictionary *o in opts) { 132 | if (o[@"path"] && [FILEMGR fileExistsAtPath:o[@"path"]]) { 133 | img = [[NSImage alloc] initWithContentsOfFile:o[@"path"]]; 134 | } 135 | else if (o[@"name"] && [NSImage imageNamed:o[@"name"]]) { 136 | img = [NSImage imageNamed:o[@"name"]]; 137 | } 138 | else if (o[@"type"]) { 139 | img = [WORKSPACE iconForFileType:o[@"type"]]; 140 | } 141 | 142 | if (img) { 143 | [img setSize:NSMakeSize(16, 16)]; 144 | [img setTemplate:[o[@"template"] boolValue]]; 145 | break; 146 | } 147 | } 148 | 149 | if (img) { 150 | icons[name] = img; 151 | } else { 152 | DLog(@"Unable to load icon '%@'", name); 153 | } 154 | } 155 | 156 | return icons; 157 | } 158 | 159 | + (NSImage *)imageNamed:(NSString *)name { 160 | // Lazy-load 161 | if (iconStore == nil) { 162 | iconStore = [self _loadIcons]; 163 | } 164 | NSImage *img = [iconStore objectForKey:name]; 165 | if (img == nil) { 166 | DLog(@"Icon '%@' not found", name); 167 | } 168 | return img; 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /source/Util/MutableDictProxy.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @interface MutableDictProxy : NSMutableDictionary 34 | { 35 | NSMutableDictionary *properties; 36 | } 37 | @end 38 | -------------------------------------------------------------------------------- /source/Util/MutableDictProxy.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "MutableDictProxy.h" 32 | 33 | @interface MutableDictProxy() 34 | 35 | @end 36 | 37 | @implementation MutableDictProxy 38 | 39 | #pragma mark - NSMutableDictionary proxy 40 | 41 | - (instancetype)init { 42 | if (self = [super init]) { 43 | // Proxy dictionary object 44 | properties = [[NSMutableDictionary alloc] init]; 45 | } 46 | return self; 47 | } 48 | 49 | - (instancetype)initWithContentsOfFile:(NSString *)path { 50 | if (self = [super init]) { 51 | properties = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; 52 | } 53 | return self; 54 | } 55 | 56 | - (instancetype)initWithCoder:(NSCoder *)aDecoder{ 57 | if (self = [super init]) { 58 | properties = [[NSMutableDictionary alloc] initWithCoder:aDecoder]; 59 | } 60 | return self; 61 | } 62 | 63 | - (instancetype)initWithDictionary:(NSDictionary *)dict { 64 | if (self = [super init]) { 65 | properties = [[NSMutableDictionary alloc] initWithDictionary:dict]; 66 | } 67 | return self; 68 | } 69 | 70 | - (void)removeObjectForKey:(id)aKey { 71 | [properties removeObjectForKey:aKey]; 72 | } 73 | 74 | - (void)setObject:(id)anObject forKey:(id )aKey { 75 | [properties setObject:anObject forKey:aKey]; 76 | } 77 | 78 | - (id)objectForKey:(id)aKey { 79 | return [properties objectForKey:aKey]; 80 | } 81 | 82 | - (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary { 83 | [properties addEntriesFromDictionary:otherDictionary]; 84 | } 85 | 86 | - (NSEnumerator *)keyEnumerator { 87 | return [properties keyEnumerator]; 88 | } 89 | 90 | - (NSUInteger)count { 91 | return [properties count]; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /source/Util/NSString+RegexConvenience.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @interface NSString (RegexConvenience) 34 | 35 | - (BOOL)isMatchedByRegex:(NSRegularExpression *)regex; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /source/Util/NSString+RegexConvenience.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "NSString+RegexConvenience.h" 32 | 33 | @implementation NSString (RegexConvenience) 34 | 35 | - (BOOL)isMatchedByRegex:(NSRegularExpression *)regex { 36 | NSTextCheckingResult *res = [regex firstMatchInString:self options:0 range:NSMakeRange(0, [self length])]; 37 | return (res != nil); 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /source/Util/NSWorkspace+Additions.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @interface NSWorkspace (Additions) 34 | 35 | - (NSArray *)handlerApplicationsForFile:(NSString *)filePath; 36 | - (NSString *)defaultHandlerApplicationForFile:(NSString *)filePath; 37 | - (NSMenu *)openWithMenuForFile:(NSString *)path target:(id)target action:(SEL)selector menu:(NSMenu *)menu; 38 | 39 | - (NSString *)kindStringForFile:(NSString *)path; 40 | - (NSString *)UTIForFile:(NSString *)filePath; 41 | - (BOOL)canRevealFileAtPath:(NSString *)path; 42 | 43 | - (NSString *)fileSizeAsHumanReadableString:(UInt64)size; 44 | 45 | - (BOOL)showFinderGetInfoForFile:(NSString *)path; 46 | - (BOOL)moveFileToTrash:(NSString *)path; 47 | - (BOOL)showPackageContents:(NSString *)path; 48 | 49 | - (BOOL)runAppleScript:(NSString *)scriptSource; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /source/Util/ProcessUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | #import 33 | 34 | @interface ProcessUtils : NSObject 35 | 36 | + (NSRunningApplication *)appForPID:(pid_t)pid; 37 | + (BOOL)isAppProcess:(NSString *)bundlePath; 38 | + (NSString *)identifierForBundleAtPath:(NSString *)path; 39 | + (BOOL)isProcessOwnedByCurrentUser:(pid_t)pid; 40 | + (uid_t)UIDForPID:(pid_t)pid; 41 | + (NSString *)ownerUserNameForPID:(pid_t)pid; 42 | + (NSString *)macProcessNameForPID:(pid_t)pid; 43 | + (NSString *)carbonProcessSerialNumberForPID:(pid_t)pid; 44 | + (NSString *)procNameForPID:(pid_t)pid; 45 | + (NSString *)fullKernelProcessNameForPID:(pid_t)pid; 46 | + (NSString *)executablePathForPID:(pid_t)pid; 47 | + (BOOL)killProcess:(int)pid 48 | asRoot:(BOOL)asRoot 49 | usingSIGKILL:(BOOL)useSigkill; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /source/Util/ProcessUtils.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "ProcessUtils.h" 32 | #import "STPrivilegedTask.h" 33 | 34 | #import 35 | #import 36 | #import 37 | #import 38 | #import 39 | #import 40 | #import 41 | 42 | @implementation ProcessUtils 43 | 44 | + (NSRunningApplication *)appForPID:(pid_t)pid { 45 | return [NSRunningApplication runningApplicationWithProcessIdentifier:pid]; 46 | } 47 | 48 | + (BOOL)isAppProcess:(NSString *)bundlePath { 49 | if (!bundlePath) { 50 | return NO; 51 | } 52 | NSString *fileType = [[NSWorkspace sharedWorkspace] typeOfFile:bundlePath error:nil]; 53 | return [[NSWorkspace sharedWorkspace] type:fileType conformsToType:@"com.apple.application"]; 54 | } 55 | 56 | + (NSString *)identifierForBundleAtPath:(NSString *)path { 57 | return [[NSBundle bundleWithPath:path] bundleIdentifier]; 58 | } 59 | 60 | + (BOOL)isProcessOwnedByCurrentUser:(pid_t)pid { 61 | return ([ProcessUtils UIDForPID:pid] == getuid()); 62 | } 63 | 64 | + (uid_t)UIDForPID:(pid_t)pid { 65 | uid_t uid = -1; 66 | 67 | struct kinfo_proc process; 68 | size_t proc_buf_size = sizeof(process); 69 | 70 | // Compose search path for sysctl. Here you can specify PID directly. 71 | const u_int path_len = 4; 72 | int path[path_len] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; 73 | 74 | int sysctl_result = sysctl(path, path_len, &process, &proc_buf_size, NULL, 0); 75 | 76 | // If sysctl did not fail and process with PID available - take UID. 77 | if ((sysctl_result == 0) && (proc_buf_size != 0)) { 78 | uid = process.kp_eproc.e_ucred.cr_uid; 79 | } 80 | 81 | return uid; 82 | } 83 | 84 | + (NSString *)ownerUserNameForPID:(pid_t)pid { 85 | uid_t uid = [ProcessUtils UIDForPID:pid]; 86 | if (uid == -1) { 87 | return nil; 88 | } 89 | register struct passwd *pw = getpwuid(uid); 90 | if (pw == NULL) { 91 | return nil; 92 | } 93 | return [NSString stringWithCString:pw->pw_name encoding:NSUTF8StringEncoding]; 94 | } 95 | 96 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 97 | #pragma clang diagnostic push 98 | 99 | + (NSString *)macProcessNameForPID:(pid_t)pid { 100 | ProcessSerialNumber psn; 101 | if (GetProcessForPID(pid, &psn) == noErr) { 102 | CFStringRef procName = NULL; 103 | if (CopyProcessName(&psn, &procName) == noErr) { 104 | NSString *nameStr = CFBridgingRelease(procName); 105 | return nameStr.length > 0 ? [nameStr copy] : nil; 106 | } 107 | } 108 | return nil; 109 | } 110 | 111 | // Some processes on macOS have a Carbon Process Manager 112 | // Serial Number (PSN) in addition to a PID 113 | + (NSString *)carbonProcessSerialNumberForPID:(pid_t)pid { 114 | ProcessSerialNumber psn; 115 | if (GetProcessForPID(pid, &psn) == noErr) { 116 | return [NSString stringWithFormat:@"%d", 117 | // (unsigned int)psn.highLongOfPSN, 118 | (unsigned int)psn.lowLongOfPSN]; 119 | } 120 | return nil; 121 | } 122 | 123 | #pragma clang diagnostic pop 124 | 125 | 126 | // This function returns process name truncated to 32 characters 127 | // This is a limitation with libproc on macOS 128 | + (NSString *)procNameForPID:(pid_t)pid { 129 | char name[1024]; 130 | if (proc_name(pid, name, sizeof(name)) > 0) { 131 | NSString *nameStr = @(name); 132 | return [nameStr length] ? nameStr : nil; 133 | } 134 | return nil; 135 | } 136 | 137 | // This is the method used by the macOS/BSD `ps` tool 138 | // Adapted from getproclline() in print.c in the 'ps' 139 | // codebase, which is part of Apple's adv_cmds package 140 | // See: https://opensource.apple.com/tarballs/adv_cmds/ 141 | // NOTE: This doesn't work for processes not owned by 142 | // the current user. /bin/ps gets around this with suid. 143 | + (NSString *)fullKernelProcessNameForPID:(pid_t)pid { 144 | int mib[3], argmax; 145 | size_t syssize; 146 | char *procargs, *cp; 147 | 148 | mib[0] = CTL_KERN; 149 | mib[1] = KERN_ARGMAX; 150 | 151 | syssize = sizeof(argmax); 152 | if (sysctl(mib, 2, &argmax, &syssize, NULL, 0) == -1) { 153 | return nil; 154 | } 155 | 156 | procargs = malloc(argmax); 157 | if (procargs == NULL) { 158 | return nil; 159 | } 160 | 161 | mib[0] = CTL_KERN; 162 | mib[1] = KERN_PROCARGS; 163 | mib[2] = pid; 164 | 165 | syssize = (size_t)argmax; 166 | if (sysctl(mib, 3, procargs, &syssize, NULL, 0) == -1) { 167 | free(procargs); 168 | return nil; 169 | } 170 | 171 | for (cp = procargs; cp < &procargs[syssize]; cp++) { 172 | if (*cp == '\0') { 173 | break; 174 | } 175 | } 176 | 177 | if (cp == &procargs[syssize]) { 178 | free(procargs); 179 | return nil; 180 | } 181 | 182 | for (; cp < &procargs[syssize]; cp++) { 183 | if (*cp != '\0') { 184 | break; 185 | } 186 | } 187 | 188 | if (cp == &procargs[syssize]) { 189 | free(procargs); 190 | return nil; 191 | } 192 | 193 | NSString *pname = [@(cp) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 194 | free(procargs); 195 | return ([pname length] == 0) ? nil : [pname lastPathComponent]; 196 | } 197 | 198 | + (NSString *)executablePathForPID:(pid_t)pid { 199 | NSString *path = nil; 200 | char *pathbuf = calloc(PROC_PIDPATHINFO_MAXSIZE, 1); 201 | 202 | int ret = proc_pidpath(pid, pathbuf, PROC_PIDPATHINFO_MAXSIZE); 203 | if (ret > 0) { 204 | path = @(pathbuf); 205 | } 206 | 207 | free(pathbuf); 208 | return path; 209 | } 210 | 211 | + (BOOL)killProcess:(int)pid asRoot:(BOOL)asRoot usingSIGKILL:(BOOL)useSigkill { 212 | int signal = useSigkill ? SIGKILL : SIGTERM; 213 | if (!asRoot) { 214 | return (kill(pid, signal) == 0); 215 | } 216 | 217 | // Kill process as root 218 | const char *toolPath = [@"/bin/kill" fileSystemRepresentation]; 219 | 220 | AuthorizationRef authRef; 221 | AuthorizationItem myItems = { kAuthorizationRightExecute, strlen(toolPath), &toolPath, 0 }; 222 | AuthorizationRights myRights = { 1, &myItems }; 223 | AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights; 224 | 225 | // Create authorization reference 226 | OSStatus err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authRef); 227 | if (err != errAuthorizationSuccess) { 228 | return NO; 229 | } 230 | 231 | // Pre-authorize the privileged operation 232 | err = AuthorizationCopyRights(authRef, &myRights, kAuthorizationEmptyEnvironment, flags, NULL); 233 | if (err != errAuthorizationSuccess) { 234 | return NO; 235 | } 236 | 237 | // Create and launch authorized task 238 | STPrivilegedTask *task = [[STPrivilegedTask alloc] init]; 239 | [task setLaunchPath:@(toolPath)]; 240 | [task setArguments:@[@"-9", [NSString stringWithFormat:@"%d", pid]]]; 241 | [task launchWithAuthorization:authRef]; 242 | 243 | AuthorizationFree(authRef, kAuthorizationFlagDestroyRights); 244 | 245 | return YES; 246 | } 247 | 248 | @end 249 | -------------------------------------------------------------------------------- /source/Util/STPrivilegedTask.h: -------------------------------------------------------------------------------- 1 | /* 2 | STPrivilegedTask - NSTask-like wrapper around AuthorizationExecuteWithPrivileges 3 | 4 | Copyright (C) 2008-2025 Sveinbjorn Thordarson 5 | 6 | Redistribution and use in source and binary forms, with or without modification, 7 | are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, this 13 | list of conditions and the following disclaimer in the documentation and/or other 14 | materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its contributors may 17 | be used to endorse or promote products derived from this software without specific 18 | prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | #import 33 | 34 | #define STPrivilegedTaskDidTerminateNotification @"STPrivilegedTaskDidTerminateNotification" 35 | 36 | // Defines error value for when AuthorizationExecuteWithPrivileges no longer exists 37 | // Rather than defining a new enum, we just create a global constant 38 | extern const OSStatus errAuthorizationFnNoLongerExists; 39 | 40 | @interface STPrivilegedTask : NSObject 41 | 42 | @property (copy) NSArray *arguments; 43 | @property (copy) NSString *currentDirectoryPath; 44 | @property (copy) NSString *launchPath; 45 | 46 | @property (readonly) NSFileHandle *outputFileHandle; 47 | @property (readonly) BOOL isRunning; 48 | @property (readonly) pid_t processIdentifier; 49 | @property (readonly) int terminationStatus; 50 | 51 | @property (copy) void (^terminationHandler)(STPrivilegedTask *); 52 | 53 | + (BOOL)authorizationFunctionAvailable; 54 | 55 | - (instancetype)initWithLaunchPath:(NSString *)path; 56 | - (instancetype)initWithLaunchPath:(NSString *)path 57 | arguments:(NSArray *)args; 58 | - (instancetype)initWithLaunchPath:(NSString *)path 59 | arguments:(NSArray *)args 60 | currentDirectory:(NSString *)cwd; 61 | 62 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path; 63 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path 64 | arguments:(NSArray *)args; 65 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path 66 | arguments:(NSArray *)args 67 | currentDirectory:(NSString *)cwd; 68 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path 69 | arguments:(NSArray *)args 70 | currentDirectory:(NSString *)cwd authorization:(AuthorizationRef)authorization; 71 | 72 | - (OSStatus)launch; 73 | - (OSStatus)launchWithAuthorization:(AuthorizationRef)authorization; 74 | // - (void)terminate; // doesn't work 75 | - (void)waitUntilExit; 76 | 77 | @end 78 | 79 | -------------------------------------------------------------------------------- /source/Util/VolumesPopUpButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | @protocol VolumesPopUpButtonDelegate 34 | - (void)volumeSelectionChanged:(NSString *)volumePath; 35 | @end 36 | 37 | @interface VolumesPopUpButton : NSPopUpButton 38 | @property (nonatomic, weak) IBOutlet id delegate; 39 | @end 40 | -------------------------------------------------------------------------------- /source/Util/VolumesPopUpButton.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import "VolumesPopUpButton.h" 32 | #import "FSUtils.h" 33 | 34 | @implementation VolumesPopUpButton 35 | 36 | - (instancetype)initWithCoder:(NSCoder *)coder { 37 | self = [super initWithCoder:coder]; 38 | if (self) { 39 | [self setup]; 40 | } 41 | return self; 42 | } 43 | 44 | - (instancetype)initWithFrame:(NSRect)frameRect { 45 | self = [super initWithFrame:frameRect]; 46 | if (self) { 47 | [self setup]; 48 | } 49 | return self; 50 | } 51 | 52 | - (void)setup { 53 | [[self menu] setDelegate:self]; 54 | 55 | [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self 56 | selector:@selector(volumesChanged:) 57 | name:NSWorkspaceDidMountNotification 58 | object:nil]; 59 | [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self 60 | selector:@selector(volumesChanged:) 61 | name:NSWorkspaceDidUnmountNotification 62 | object:nil]; 63 | [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self 64 | selector:@selector(volumesChanged:) 65 | name:NSWorkspaceDidRenameVolumeNotification 66 | object:nil]; 67 | 68 | [self populateMenu]; 69 | } 70 | 71 | - (void)menuWillOpen:(NSMenu *)menu { 72 | for (NSMenuItem *item in [menu itemArray]) { 73 | NSString *volPath = [item toolTip]; 74 | if (volPath && ![volPath isEqualToString:@""]) { 75 | NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:[item toolTip]]; 76 | [icon setSize:NSMakeSize(16, 16)]; 77 | [item setImage:icon]; 78 | } 79 | } 80 | } 81 | 82 | - (void)menuDidClose:(NSMenu *)menu { 83 | for (NSMenuItem *item in [menu itemArray]) { 84 | [item setImage:nil]; 85 | } 86 | } 87 | 88 | - (void)volumesChanged:(NSNotification *)notification { 89 | [self populateMenu]; 90 | } 91 | 92 | - (void)notifyDelegateSelectionHasChanged:(id)sender { 93 | [[self delegate] volumeSelectionChanged:[[self selectedItem] toolTip]]; 94 | } 95 | 96 | - (void)populateMenu { 97 | NSMenu *volumesMenu = [self menu]; 98 | 99 | // Get currently selected volume 100 | NSMenuItem *selectedItem = [self selectedItem]; 101 | NSString *selectedPath = [selectedItem toolTip]; 102 | 103 | // Get info about mounted file systems 104 | NSDictionary *filesystems = [FSUtils mountedFileSystems]; 105 | 106 | // Clear menu 107 | [volumesMenu removeAllItems]; 108 | 109 | // All + separator 110 | NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"All" 111 | action:@selector(notifyDelegateSelectionHasChanged:) 112 | keyEquivalent:@""]; 113 | [item setTarget:self]; 114 | [item setToolTip:@""]; 115 | [volumesMenu addItem:item]; 116 | [volumesMenu addItem:[NSMenuItem separatorItem]]; 117 | 118 | // NEW METHOD: Add all filesystems (except /dev) 119 | for (NSNumber *fsid in [filesystems allKeys]) { 120 | NSDictionary *fs = filesystems[fsid]; 121 | if ([fs[@"mountpoint"] isEqualToString:@"/dev"]) { 122 | continue; 123 | } 124 | NSString *menuItemName = fs[@"mountpoint"]; 125 | 126 | // Get volume name, if possible 127 | NSURL *url = [NSURL fileURLWithPath:fs[@"mountpoint"]]; 128 | NSString *volumeName; 129 | NSError *err; 130 | [url getResourceValue:&volumeName forKey:NSURLVolumeNameKey error:&err]; 131 | if (volumeName != nil) { 132 | menuItemName = [NSString stringWithFormat:@"%@ - %@", volumeName, fs[@"mountpoint"]]; 133 | } 134 | 135 | SEL action = @selector(notifyDelegateSelectionHasChanged:); 136 | NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:menuItemName 137 | action:action 138 | keyEquivalent:@""]; 139 | [item setTarget:self]; 140 | [item setToolTip:fs[@"mountpoint"]]; 141 | [item setRepresentedObject:fs]; 142 | [volumesMenu addItem:item]; 143 | 144 | } 145 | 146 | // Restore selection, if possible 147 | NSMenuItem *itemToSelect = [volumesMenu itemArray][0]; 148 | for (NSMenuItem *item in [volumesMenu itemArray]) { 149 | if ([[item toolTip] isEqualToString:selectedPath]) { 150 | itemToSelect = item; 151 | break; 152 | } 153 | } 154 | [self selectItem:itemToSelect]; 155 | 156 | if (selectedItem != itemToSelect) { 157 | [self notifyDelegateSelectionHasChanged:itemToSelect]; 158 | } 159 | } 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /source/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2025, Sveinbjorn Thordarson 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without specific 17 | prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #import 32 | 33 | int main(int argc, const char *argv[]) { 34 | return NSApplicationMain(argc, argv); 35 | } 36 | -------------------------------------------------------------------------------- /sparkle/SlothAppcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sloth Version Release Appcast 5 | https://sveinbjorn.org/files/appcasts/SlothAppcast.xml 6 | Most recent Sloth releases, with links to signed updates. 7 | en 8 | 9 | Version 3.4 10 | Monday, 19 May 2025 22:24:00 +0000 11 | 12 | 10.13.0 13 | New in Sloth 3.4 15 |
    16 |
  • Copying (Cmd-C) an app/process or file now copies both filesystem representation and string to the clipboard
  • 17 |
  • Faster asynchronous file info processing in Info Panel
  • 18 |
  • Various minor improvements
  • 19 |
  • App is now notarized by Apple in addition to being Developer ID signed
  • 20 |
21 | ]]>
22 |
23 |
24 |
25 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Autoupdate: -------------------------------------------------------------------------------- 1 | Versions/Current/Autoupdate -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Modules: -------------------------------------------------------------------------------- 1 | Versions/Current/Modules -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/PrivateHeaders: -------------------------------------------------------------------------------- 1 | Versions/Current/PrivateHeaders -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Sparkle: -------------------------------------------------------------------------------- 1 | Versions/Current/Sparkle -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Updater.app: -------------------------------------------------------------------------------- 1 | Versions/Current/Updater.app -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Autoupdate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Autoupdate -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SPUDownloadData.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloadData.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SUExport.h" 16 | #pragma clang diagnostic pop 17 | #else 18 | #import 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | /** 24 | * A class for containing downloaded data along with some information about it. 25 | */ 26 | SU_EXPORT @interface SPUDownloadData : NSObject 27 | 28 | /** 29 | * The raw data that was downloaded. 30 | */ 31 | @property (nonatomic, readonly) NSData *data; 32 | 33 | /** 34 | * The URL that was fetched from. 35 | * 36 | * This may be different from the URL in the request if there were redirects involved. 37 | */ 38 | @property (nonatomic, readonly, copy) NSURL *URL; 39 | 40 | /** 41 | * The IANA charset encoding name if available. Eg: "utf-8" 42 | */ 43 | @property (nonatomic, readonly, nullable, copy) NSString *textEncodingName; 44 | 45 | /** 46 | * The MIME type if available. Eg: "text/plain" 47 | */ 48 | @property (nonatomic, readonly, nullable, copy) NSString *MIMEType; 49 | 50 | @end 51 | 52 | NS_ASSUME_NONNULL_END 53 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SPUStandardUpdaterController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUStandardUpdaterController.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/28/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SUExport.h" 16 | #pragma clang diagnostic pop 17 | #else 18 | #import 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | @class SPUUpdater; 24 | @class SPUStandardUserDriver; 25 | @class NSMenuItem; 26 | @protocol SPUUserDriver, SPUUpdaterDelegate, SPUStandardUserDriverDelegate; 27 | 28 | /** 29 | A controller class that instantiates a `SPUUpdater` and allows binding UI to its updater settings. 30 | 31 | This class can be instantiated in a nib or created programmatically using `-initWithUpdaterDelegate:userDriverDelegate:` or `-initWithStartingUpdater:updaterDelegate:userDriverDelegate:`. 32 | 33 | The controller's updater targets the application's main bundle and uses Sparkle's standard user interface. 34 | Typically, this class is used by sticking it as a custom NSObject subclass in an Interface Builder nib (probably in MainMenu) but it works well programmatically too. 35 | 36 | The controller creates an `SPUUpdater` instance using a `SPUStandardUserDriver` and allows hooking up the check for updates action and handling menu item validation. 37 | It also allows hooking up the updater's and user driver's delegates. 38 | 39 | If you need more control over what bundle you want to update, or you want to provide a custom user interface (via `SPUUserDriver`), please use `SPUUpdater` directly instead. 40 | */ 41 | SU_EXPORT @interface SPUStandardUpdaterController : NSObject 42 | { 43 | #pragma clang diagnostic push 44 | #pragma clang diagnostic ignored "-Wobjc-interface-ivars" 45 | /** 46 | * Interface builder outlet for the updater's delegate. 47 | */ 48 | IBOutlet __weak id updaterDelegate; 49 | 50 | /** 51 | * Interface builder outlet for the user driver's delegate. 52 | */ 53 | IBOutlet __weak id userDriverDelegate; 54 | #pragma clang diagnostic pop 55 | } 56 | 57 | /** 58 | Accessible property for the updater. Some properties on the updater can be binded via KVO 59 | 60 | When instantiated from a nib, don't perform update checks before the application has finished launching in a MainMenu nib (i.e applicationDidFinishLaunching:) or before the corresponding window/view controller has been loaded (i.e, windowDidLoad or viewDidLoad). The updater is not guaranteed to be started yet before these points. 61 | */ 62 | @property (nonatomic, readonly) SPUUpdater *updater; 63 | 64 | /** 65 | Accessible property for the updater's user driver. 66 | */ 67 | @property (nonatomic, readonly) SPUStandardUserDriver *userDriver; 68 | 69 | /** 70 | Create a new `SPUStandardUpdaterController` from a nib. 71 | 72 | You cannot call this initializer directly. You must instantiate a `SPUStandardUpdaterController` inside of a nib (typically the MainMenu nib) to use it. 73 | 74 | To create a `SPUStandardUpdaterController` programmatically, use `-initWithUpdaterDelegate:userDriverDelegate:` or `-initWithStartingUpdater:updaterDelegate:userDriverDelegate:` instead. 75 | */ 76 | - (instancetype)init NS_UNAVAILABLE; 77 | 78 | /** 79 | Create a new `SPUStandardUpdaterController` programmatically. 80 | 81 | The updater is started automatically. See `-startUpdater` for more information. 82 | */ 83 | - (instancetype)initWithUpdaterDelegate:(nullable id)updaterDelegate userDriverDelegate:(nullable id)userDriverDelegate; 84 | 85 | /** 86 | Create a new `SPUStandardUpdaterController` programmatically allowing you to specify whether or not to start the updater immediately. 87 | 88 | You can specify whether or not you want to start the updater immediately. 89 | If you do not start the updater, you must invoke `-startUpdater` at a later time to start it. 90 | */ 91 | - (instancetype)initWithStartingUpdater:(BOOL)startUpdater updaterDelegate:(nullable id)updaterDelegate userDriverDelegate:(nullable id)userDriverDelegate; 92 | 93 | /** 94 | Starts the updater if it has not already been started. 95 | 96 | You should only call this method yourself if you opted out of starting the updater on initialization. 97 | Hence, do not call this yourself if you are instantiating this controller from a nib. 98 | 99 | This invokes `-[SPUUpdater startUpdater:]`. If the application is misconfigured with Sparkle, an error is logged and an alert is shown to the user (after a few seconds) to contact the developer. 100 | If you want more control over this behavior, you can create your own `SPUUpdater` instead of using `SPUStandardUpdaterController`. 101 | */ 102 | - (void)startUpdater; 103 | 104 | /** 105 | Explicitly checks for updates and displays a progress dialog while doing so. 106 | 107 | This method is meant for a main menu item. 108 | Connect any NSMenuItem to this action in Interface Builder or programmatically, 109 | and Sparkle will check for updates and report back its findings verbosely when it is invoked. 110 | 111 | When the target/action of the menu item is set to this controller and this method, 112 | this controller also handles enabling/disabling the menu item by checking 113 | `-[SPUUpdater canCheckForUpdates]` 114 | 115 | This action checks updates by invoking `-[SPUUpdater checkForUpdates]` 116 | */ 117 | - (IBAction)checkForUpdates:(nullable id)sender; 118 | 119 | @end 120 | 121 | NS_ASSUME_NONNULL_END 122 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SPUStandardUserDriver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUStandardUserDriver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/14/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SPUUserDriver.h" 16 | #import "SUExport.h" 17 | #pragma clang diagnostic pop 18 | #else 19 | #import 20 | #import 21 | #endif 22 | 23 | NS_ASSUME_NONNULL_BEGIN 24 | 25 | @protocol SPUStandardUserDriverDelegate; 26 | 27 | /** 28 | Sparkle's standard built-in user driver for updater interactions 29 | */ 30 | SU_EXPORT @interface SPUStandardUserDriver : NSObject 31 | 32 | /** 33 | Initializes a Sparkle's standard user driver for user update interactions 34 | 35 | @param hostBundle The target bundle of the host that is being updated. 36 | @param delegate The optional delegate to this user driver. 37 | */ 38 | - (instancetype)initWithHostBundle:(NSBundle *)hostBundle delegate:(nullable id)delegate; 39 | 40 | /** 41 | Use initWithHostBundle:delegate: instead. 42 | */ 43 | - (instancetype)init NS_UNAVAILABLE; 44 | 45 | @end 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SPUUpdateCheck.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdateCheck.h 3 | // SPUUpdateCheck 4 | // 5 | // Created by Mayur Pawashe on 8/28/21. 6 | // Copyright © 2021 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SPUUpdateCheck_h 10 | #define SPUUpdateCheck_h 11 | 12 | /** 13 | Describes the type of update check being performed. 14 | 15 | Each update check corresponds to an update check method on `SPUUpdater`. 16 | */ 17 | typedef NS_ENUM(NSInteger, SPUUpdateCheck) 18 | { 19 | /** 20 | The user-initiated update check corresponding to `-[SPUUpdater checkForUpdates]`. 21 | */ 22 | SPUUpdateCheckUpdates = 0, 23 | /** 24 | The background scheduled update check corresponding to `-[SPUUpdater checkForUpdatesInBackground]`. 25 | */ 26 | SPUUpdateCheckUpdatesInBackground = 1, 27 | /** 28 | The informational probe update check corresponding to `-[SPUUpdater checkForUpdateInformation]`. 29 | */ 30 | SPUUpdateCheckUpdateInformation = 2 31 | }; 32 | 33 | #endif /* SPUUpdateCheck_h */ 34 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SPUUpdatePermissionRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdatePermissionRequest.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/14/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SUExport.h" 16 | #pragma clang diagnostic pop 17 | #else 18 | #import 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | /** 24 | This class represents information needed to make a permission request for checking updates. 25 | */ 26 | SU_EXPORT @interface SPUUpdatePermissionRequest : NSObject 27 | 28 | /** 29 | Initializes a new update permission request instance. 30 | 31 | @param systemProfile The system profile information. 32 | */ 33 | - (instancetype)initWithSystemProfile:(NSArray *> *)systemProfile; 34 | 35 | /** 36 | A read-only property for the user's system profile. 37 | */ 38 | @property (nonatomic, readonly) NSArray *> *systemProfile; 39 | 40 | @end 41 | 42 | NS_ASSUME_NONNULL_END 43 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SPUUpdaterSettings.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUpdaterSettings.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 3/27/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SUExport.h" 16 | #pragma clang diagnostic pop 17 | #else 18 | #import 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | /** 24 | This class can be used for reading certain updater settings. 25 | 26 | It retrieves the settings by first looking into the host's user defaults. 27 | If the setting is not found in there, then the host's Info.plist file is looked at. 28 | */ 29 | SU_EXPORT @interface SPUUpdaterSettings : NSObject 30 | 31 | - (instancetype)initWithHostBundle:(NSBundle *)hostBundle; 32 | 33 | /** 34 | * Indicates whether or not automatic update checks are enabled. 35 | */ 36 | @property (readonly, nonatomic) BOOL automaticallyChecksForUpdates; 37 | 38 | /** 39 | * The regular update check interval. 40 | */ 41 | @property (readonly, nonatomic) NSTimeInterval updateCheckInterval; 42 | 43 | /** 44 | * Indicates whether or not automatically downloading updates is allowed to be turned on by the user. 45 | * If this value is nil, the developer has not explicitly specified this option. 46 | */ 47 | @property (readonly, nonatomic, nullable) NSNumber *allowsAutomaticUpdatesOption; 48 | 49 | /** 50 | * Indicates whether or not automatically downloading updates is allowed to be turned on by the user. 51 | */ 52 | @property (readonly, nonatomic) BOOL allowsAutomaticUpdates; 53 | 54 | /** 55 | * Indicates whether or not automatically downloading updates is enabled by the user or developer. 56 | * 57 | * Note this does not indicate whether or not automatic downloading of updates is allowable. 58 | * See `-allowsAutomaticUpdates` property for that. 59 | */ 60 | @property (readonly, nonatomic) BOOL automaticallyDownloadsUpdates; 61 | 62 | /** 63 | * Indicates whether or not anonymous system profile information is sent when checking for updates. 64 | */ 65 | @property (readonly, nonatomic) BOOL sendsSystemProfile; 66 | 67 | @end 68 | 69 | NS_ASSUME_NONNULL_END 70 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SPUUserUpdateState.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUserUpdateState.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/29/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SPUUserUpdateState_h 10 | #define SPUUserUpdateState_h 11 | 12 | #import 13 | 14 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 15 | // Ignore incorrect warning 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 18 | #import "SUExport.h" 19 | #pragma clang diagnostic pop 20 | #else 21 | #import 22 | #endif 23 | 24 | NS_ASSUME_NONNULL_BEGIN 25 | 26 | /** 27 | A choice made by the user when prompted with a new update. 28 | */ 29 | typedef NS_ENUM(NSInteger, SPUUserUpdateChoice) { 30 | /** 31 | Dismisses the update and skips being notified of it in the future. 32 | */ 33 | SPUUserUpdateChoiceSkip, 34 | /** 35 | Downloads (if needed) and installs the update. 36 | */ 37 | SPUUserUpdateChoiceInstall, 38 | /** 39 | Dismisses the update until Sparkle reminds the user of it at a later time. 40 | */ 41 | SPUUserUpdateChoiceDismiss, 42 | }; 43 | 44 | /** 45 | Describes the current stage an update is undergoing. 46 | */ 47 | typedef NS_ENUM(NSInteger, SPUUserUpdateStage) { 48 | /** 49 | The update has not been downloaded. 50 | */ 51 | SPUUserUpdateStageNotDownloaded, 52 | /** 53 | The update has already been downloaded but not begun installing. 54 | */ 55 | SPUUserUpdateStageDownloaded, 56 | /** 57 | The update has already been downloaded and began installing in the background. 58 | */ 59 | SPUUserUpdateStageInstalling 60 | }; 61 | 62 | /** 63 | This represents the user's current update state. 64 | */ 65 | SU_EXPORT @interface SPUUserUpdateState : NSObject 66 | 67 | - (instancetype)init NS_UNAVAILABLE; 68 | 69 | /** 70 | The current update stage. 71 | 72 | This stage indicates if data has been already downloaded or not, or if an update is currently being installed. 73 | */ 74 | @property (nonatomic, readonly) SPUUserUpdateStage stage; 75 | 76 | /** 77 | Indicates whether or not the update check was initiated by the user. 78 | */ 79 | @property (nonatomic, readonly) BOOL userInitiated; 80 | 81 | @end 82 | 83 | NS_ASSUME_NONNULL_END 84 | 85 | #endif /* SPUUserUpdateState_h */ 86 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SUAppcast.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcast.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCAST_H 10 | #define SUAPPCAST_H 11 | 12 | #import 13 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 14 | // Ignore incorrect warning 15 | #pragma clang diagnostic push 16 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 17 | #import "SUExport.h" 18 | #pragma clang diagnostic pop 19 | #else 20 | #import 21 | #endif 22 | 23 | NS_ASSUME_NONNULL_BEGIN 24 | 25 | @class SUAppcastItem; 26 | 27 | /** 28 | The appcast representing a collection of `SUAppcastItem` items in the feed. 29 | */ 30 | SU_EXPORT @interface SUAppcast : NSObject 31 | 32 | - (instancetype)init NS_UNAVAILABLE; 33 | 34 | /** 35 | The collection of update items. 36 | 37 | These `SUAppcastItem` items are in the same order as specified in the appcast XML feed and are thus not sorted by version. 38 | */ 39 | @property (readonly, nonatomic, copy) NSArray *items; 40 | 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SUErrors.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUErrors.h 3 | // Sparkle 4 | // 5 | // Created by C.W. Betts on 10/13/14. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUERRORS_H 10 | #define SUERRORS_H 11 | 12 | #import 13 | 14 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 15 | // Ignore incorrect warning 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 18 | #import "SUExport.h" 19 | #pragma clang diagnostic pop 20 | #else 21 | #import 22 | #endif 23 | 24 | /** 25 | * Error domain used by Sparkle 26 | */ 27 | SU_EXPORT extern NSString *const SUSparkleErrorDomain; 28 | 29 | typedef NS_ENUM(OSStatus, SUError) { 30 | // Configuration phase errors 31 | SUNoPublicDSAFoundError = 0001, 32 | SUInsufficientSigningError = 0002, 33 | SUInsecureFeedURLError = 0003, 34 | SUInvalidFeedURLError = 0004, 35 | SUInvalidUpdaterError = 0005, 36 | SUInvalidHostBundleIdentifierError = 0006, 37 | SUInvalidHostVersionError = 0007, 38 | 39 | // Appcast phase errors. 40 | SUAppcastParseError = 1000, 41 | SUNoUpdateError = 1001, 42 | SUAppcastError = 1002, 43 | SURunningFromDiskImageError = 1003, 44 | SUResumeAppcastError = 1004, 45 | SURunningTranslocated = 1005, 46 | SUWebKitTerminationError = 1006, 47 | SUReleaseNotesError = 1007, 48 | 49 | // Download phase errors. 50 | SUTemporaryDirectoryError = 2000, 51 | SUDownloadError = 2001, 52 | 53 | // Extraction phase errors. 54 | SUUnarchivingError = 3000, 55 | SUSignatureError = 3001, 56 | SUValidationError = 3002, 57 | 58 | // Installation phase errors. 59 | SUFileCopyFailure = 4000, 60 | SUAuthenticationFailure = 4001, 61 | SUMissingUpdateError = 4002, 62 | SUMissingInstallerToolError = 4003, 63 | SURelaunchError = 4004, 64 | SUInstallationError = 4005, 65 | SUDowngradeError = 4006, 66 | SUInstallationCanceledError = 4007, 67 | SUInstallationAuthorizeLaterError = 4008, 68 | SUNotValidUpdateError = 4009, 69 | SUAgentInvalidationError = 4010, 70 | SUInstallationRootInteractiveError = 4011, 71 | SUInstallationWriteNoPermissionError = 4012, 72 | 73 | // API misuse errors. 74 | SUIncorrectAPIUsageError = 5000 75 | }; 76 | 77 | /** 78 | The reason why a new update is not available. 79 | */ 80 | typedef NS_ENUM(OSStatus, SPUNoUpdateFoundReason) { 81 | /** 82 | A new update is unavailable for an unknown reason. 83 | */ 84 | SPUNoUpdateFoundReasonUnknown, 85 | /** 86 | A new update is unavailable because the user is on the latest known version in the appcast feed. 87 | */ 88 | SPUNoUpdateFoundReasonOnLatestVersion, 89 | /** 90 | A new update is unavailable because the user is on a version newer than the latest known version in the appcast feed. 91 | */ 92 | SPUNoUpdateFoundReasonOnNewerThanLatestVersion, 93 | /** 94 | A new update is unavailable because the user's operating system version is too old for the update. 95 | */ 96 | SPUNoUpdateFoundReasonSystemIsTooOld, 97 | /** 98 | A new update is unavailable because the user's operating system version is too new for the update. 99 | */ 100 | SPUNoUpdateFoundReasonSystemIsTooNew 101 | }; 102 | 103 | SU_EXPORT extern NSString *const SPUNoUpdateFoundReasonKey; 104 | SU_EXPORT extern NSString *const SPULatestAppcastItemFoundKey; 105 | SU_EXPORT extern NSString *const SPUNoUpdateFoundUserInitiatedKey; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SUExport.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUExport.h 3 | // Sparkle 4 | // 5 | // Created by Jake Petroules on 2014-08-23. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUEXPORT_H 10 | #define SUEXPORT_H 11 | 12 | #ifdef BUILDING_SPARKLE 13 | #define SU_EXPORT __attribute__((visibility("default"))) 14 | #else 15 | #define SU_EXPORT 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SUStandardVersionComparator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStandardVersionComparator.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUSTANDARDVERSIONCOMPARATOR_H 10 | #define SUSTANDARDVERSIONCOMPARATOR_H 11 | 12 | #import 13 | 14 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 15 | // Ignore incorrect warning 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 18 | #import "SUExport.h" 19 | #import "SUVersionComparisonProtocol.h" 20 | #pragma clang diagnostic pop 21 | #else 22 | #import 23 | #import 24 | #endif 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | /** 29 | Sparkle's default version comparator. 30 | 31 | This comparator is adapted from MacPAD, by Kevin Ballard. 32 | It's "dumb" in that it does essentially string comparison, 33 | in components split by character type. 34 | */ 35 | SU_EXPORT @interface SUStandardVersionComparator : NSObject 36 | 37 | /** 38 | Initializes a new instance of the standard version comparator. 39 | */ 40 | - (instancetype)init; 41 | 42 | /** 43 | A singleton instance of the comparator. 44 | */ 45 | @property (nonatomic, class, readonly) SUStandardVersionComparator *defaultComparator; 46 | 47 | /** 48 | Compares two version strings through textual analysis. 49 | 50 | These version strings should be in the format of x, x.y, or x.y.z where each component is a number. 51 | For example, valid version strings include "1.5.3", "500", or "4000.1" 52 | These versions that are compared correspond to the @c CFBundleVersion values of the updates. 53 | 54 | @param versionA The first version string to compare. 55 | @param versionB The second version string to compare. 56 | @return A comparison result between @c versionA and @c versionB 57 | */ 58 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; 59 | 60 | @end 61 | 62 | NS_ASSUME_NONNULL_END 63 | #endif 64 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SUUpdatePermissionResponse.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdatePermissionResponse.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 2/8/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SUExport.h" 16 | #pragma clang diagnostic pop 17 | #else 18 | #import 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | /** 24 | This class represents a response for permission to check updates. 25 | */ 26 | SU_EXPORT @interface SUUpdatePermissionResponse : NSObject 27 | 28 | /** 29 | Initializes a new update permission response instance. 30 | 31 | @param automaticUpdateChecks Flag to enable automatic update checks. 32 | @param sendSystemProfile Flag for if system profile information should be sent to the server hosting the appcast. 33 | */ 34 | - (instancetype)initWithAutomaticUpdateChecks:(BOOL)automaticUpdateChecks sendSystemProfile:(BOOL)sendSystemProfile; 35 | 36 | /** 37 | Initializes a new update permission response instance. 38 | 39 | @param automaticUpdateChecks Flag to enable automatic update checks. 40 | @param automaticUpdateDownloading Flag to enable automatic downloading and installing of updates. If this is nil, this option will be ignored. 41 | @param sendSystemProfile Flag for if system profile information should be sent to the server hosting the appcast. 42 | */ 43 | - (instancetype)initWithAutomaticUpdateChecks:(BOOL)automaticUpdateChecks automaticUpdateDownloading:(NSNumber * _Nullable)automaticUpdateDownloading sendSystemProfile:(BOOL)sendSystemProfile; 44 | 45 | /* 46 | Use -initWithAutomaticUpdateChecks:sendSystemProfile: instead. 47 | */ 48 | - (instancetype)init NS_UNAVAILABLE; 49 | 50 | /** 51 | A read-only property indicating if update checks should be done automatically. 52 | */ 53 | @property (nonatomic, readonly) BOOL automaticUpdateChecks; 54 | 55 | /** 56 | A read-only property indicating if updates should be automatically downloaded and installed. 57 | 58 | If this property is `nil`, then no user choice was made for this option. 59 | 60 | If `automaticUpdateChecks` is `NO` then this property should not be `@(YES)`. 61 | Set it to `NO` if the user was given the choice of automatically downloading and installing updates, 62 | otherwise set it to `nil`. 63 | */ 64 | @property (nonatomic, readonly, nullable) NSNumber *automaticUpdateDownloading; 65 | 66 | /** 67 | A read-only property indicating if system profile should be sent or not. 68 | */ 69 | @property (nonatomic, readonly) BOOL sendSystemProfile; 70 | 71 | @end 72 | 73 | NS_ASSUME_NONNULL_END 74 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SUUpdater.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdater.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 1/4/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUUPDATER_H 10 | #define SUUPDATER_H 11 | 12 | #import 13 | 14 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 15 | // Ignore incorrect warning 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 18 | #import "SUExport.h" 19 | #import "SUVersionComparisonProtocol.h" 20 | #import "SUVersionDisplayProtocol.h" 21 | #import "SUUpdaterDelegate.h" 22 | #pragma clang diagnostic pop 23 | #else 24 | #import 25 | #import 26 | #import 27 | #import 28 | #endif 29 | 30 | @class SUAppcastItem, SUAppcast, NSMenuItem; 31 | 32 | @protocol SUUpdaterDelegate; 33 | 34 | /** 35 | The legacy API in Sparkle for controlling the update mechanism. 36 | 37 | This class is now deprecated and acts as a thin wrapper around `SPUUpdater` and `SPUStandardUserDriver`. 38 | 39 | If you are migrating to Sparkle 2, use `SPUStandardUpdaterController` instead, or `SPUUpdater` if you need more control. 40 | */ 41 | __deprecated_msg("Deprecated in Sparkle 2. Use SPUStandardUpdaterController instead, or SPUUpdater if you need more control.") 42 | SU_EXPORT @interface SUUpdater : NSObject 43 | 44 | @property (unsafe_unretained, nonatomic) IBOutlet id delegate; 45 | 46 | /*! 47 | The shared updater for the main bundle. 48 | 49 | This is equivalent to passing [NSBundle mainBundle] to SUUpdater::updaterForBundle: 50 | */ 51 | + (SUUpdater *)sharedUpdater; 52 | 53 | /*! 54 | The shared updater for a specified bundle. 55 | If an updater has already been initialized for the provided bundle, that shared instance will be returned. 56 | */ 57 | + (SUUpdater *)updaterForBundle:(NSBundle *)bundle; 58 | 59 | /*! 60 | Designated initializer for SUUpdater. 61 | 62 | If an updater has already been initialized for the provided bundle, that shared instance will be returned. 63 | */ 64 | - (instancetype)initForBundle:(NSBundle *)bundle; 65 | 66 | /*! 67 | Explicitly checks for updates and displays a progress dialog while doing so. 68 | 69 | This method is meant for a main menu item. 70 | Connect any menu item to this action in Interface Builder, 71 | and Sparkle will check for updates and report back its findings verbosely 72 | when it is invoked. 73 | 74 | This will find updates that the user has opted into skipping. 75 | */ 76 | - (IBAction)checkForUpdates:(id)sender; 77 | 78 | /*! 79 | The menu item validation used for the -checkForUpdates: action 80 | */ 81 | - (BOOL)validateMenuItem:(NSMenuItem *)menuItem; 82 | 83 | /*! 84 | Checks for updates, but does not display any UI unless an update is found. 85 | 86 | This is meant for programmatically initiating a check for updates. That is, 87 | it will display no UI unless it actually finds an update, in which case it 88 | proceeds as usual. 89 | 90 | If automatic downloading of updates it turned on and allowed, however, 91 | this will invoke that behavior, and if an update is found, it will be downloaded 92 | in the background silently and will be prepped for installation. 93 | 94 | This will not find updates that the user has opted into skipping. 95 | */ 96 | - (void)checkForUpdatesInBackground; 97 | 98 | /*! 99 | A property indicating whether or not to check for updates automatically. 100 | 101 | Setting this property will persist in the host bundle's user defaults. 102 | The update schedule cycle will be reset in a short delay after the property's new value is set. 103 | This is to allow reverting this property without kicking off a schedule change immediately 104 | */ 105 | @property (nonatomic) BOOL automaticallyChecksForUpdates; 106 | 107 | /*! 108 | A property indicating whether or not updates can be automatically downloaded in the background. 109 | 110 | Note that automatic downloading of updates can be disallowed by the developer. 111 | In this case, -automaticallyDownloadsUpdates will return NO regardless of how this property is set. 112 | 113 | Setting this property will persist in the host bundle's user defaults. 114 | */ 115 | @property (nonatomic) BOOL automaticallyDownloadsUpdates; 116 | 117 | /*! 118 | A property indicating the current automatic update check interval. 119 | 120 | Setting this property will persist in the host bundle's user defaults. 121 | The update schedule cycle will be reset in a short delay after the property's new value is set. 122 | This is to allow reverting this property without kicking off a schedule change immediately 123 | */ 124 | @property (nonatomic) NSTimeInterval updateCheckInterval; 125 | 126 | /*! 127 | Begins a "probing" check for updates which will not actually offer to 128 | update to that version. 129 | 130 | However, the delegate methods 131 | SUUpdaterDelegate::updater:didFindValidUpdate: and 132 | SUUpdaterDelegate::updaterDidNotFindUpdate: will be called, 133 | so you can use that information in your UI. 134 | 135 | Updates that have been skipped by the user will not be found. 136 | */ 137 | - (void)checkForUpdateInformation; 138 | 139 | /*! 140 | The URL of the appcast used to download update information. 141 | 142 | Setting this property will persist in the host bundle's user defaults. 143 | If you don't want persistence, you may want to consider instead implementing 144 | SUUpdaterDelegate::feedURLStringForUpdater: or SUUpdaterDelegate::feedParametersForUpdater:sendingSystemProfile: 145 | 146 | This property must be called on the main thread. 147 | */ 148 | @property (nonatomic, copy) NSURL *feedURL; 149 | 150 | /*! 151 | The host bundle that is being updated. 152 | */ 153 | @property (readonly, nonatomic) NSBundle *hostBundle; 154 | 155 | /*! 156 | The bundle this class (SUUpdater) is loaded into. 157 | */ 158 | @property (nonatomic, readonly) NSBundle *sparkleBundle; 159 | 160 | /*! 161 | The user agent used when checking for and downloading updates. 162 | 163 | The default implementation can be overridden. 164 | */ 165 | @property (nonatomic, copy) NSString *userAgentString; 166 | 167 | /*! 168 | The HTTP headers used when checking for and downloading updates. 169 | 170 | The keys of this dictionary are HTTP header fields (NSString) and values are corresponding values (NSString) 171 | */ 172 | @property (copy, nonatomic) NSDictionary *httpHeaders; 173 | 174 | /*! 175 | A property indicating whether or not the user's system profile information is sent when checking for updates. 176 | 177 | Setting this property will persist in the host bundle's user defaults. 178 | */ 179 | @property (nonatomic) BOOL sendsSystemProfile; 180 | 181 | /*! 182 | A property indicating the decryption password used for extracting updates shipped as Apple Disk Images (dmg) 183 | */ 184 | @property (nonatomic, copy) NSString *decryptionPassword; 185 | 186 | /*! 187 | Returns the date of last update check. 188 | 189 | \returns \c nil if no check has been performed. 190 | */ 191 | @property (nonatomic, readonly, copy) NSDate *lastUpdateCheckDate; 192 | 193 | /*! 194 | Appropriately schedules or cancels the update checking timer according to 195 | the preferences for time interval and automatic checks. 196 | 197 | This call does not change the date of the next check, 198 | but only the internal NSTimer. 199 | */ 200 | - (void)resetUpdateCycle; 201 | 202 | /*! 203 | A property indicating whether or not an update is in progress. 204 | 205 | Note this property is not indicative of whether or not user initiated updates can be performed. 206 | Use SUUpdater::validateMenuItem: for that instead. 207 | */ 208 | @property (nonatomic, readonly) BOOL updateInProgress; 209 | 210 | @end 211 | 212 | #endif 213 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SUVersionComparisonProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionComparisonProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUVERSIONCOMPARISONPROTOCOL_H 10 | #define SUVERSIONCOMPARISONPROTOCOL_H 11 | 12 | #import 13 | 14 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 15 | // Ignore incorrect warning 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 18 | #import "SUExport.h" 19 | #pragma clang diagnostic pop 20 | #else 21 | #import 22 | #endif 23 | 24 | NS_ASSUME_NONNULL_BEGIN 25 | 26 | /** 27 | Provides version comparison facilities for Sparkle. 28 | */ 29 | @protocol SUVersionComparison 30 | 31 | /** 32 | An abstract method to compare two version strings. 33 | 34 | Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, 35 | and NSOrderedSame if they are equivalent. 36 | */ 37 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD! 38 | 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | #endif 43 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/SUVersionDisplayProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionDisplayProtocol.h 3 | // EyeTV 4 | // 5 | // Created by Uli Kusterer on 08.12.09. 6 | // Copyright 2009 Elgato Systems GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SUExport.h" 16 | #pragma clang diagnostic pop 17 | #else 18 | #import 19 | #endif 20 | 21 | @class SUAppcastItem; 22 | 23 | NS_ASSUME_NONNULL_BEGIN 24 | 25 | /** 26 | Applies special display formatting to version numbers of the bundle to update and the update before presenting them to the user. 27 | */ 28 | SU_EXPORT @protocol SUVersionDisplay 29 | 30 | /** 31 | Formats an update's version string and bundle's version string for display. 32 | 33 | This method is used to format both the display version of the update and the display version of the bundle to update. 34 | 35 | The display versions returned by this method are then used for presenting to the user when a new update is available, 36 | or when the user cannot download/install the latest update for a specific reason, or when the user has a newer version 37 | installed than the latest known version in the update feed. 38 | 39 | On input, the `update.displayVersionString` and `*inOutBundleDisplayVersion` may be the same, but the 40 | `update.versionString` and `bundleVersion` will differ. To differentiate between these display versions, you may 41 | choose to return different display version strings for the update and bundle. 42 | 43 | @param update The update to format the update display version from. You can query `update.displayVersionString` and `update.versionString` to retrieve the update's version information. 44 | @param inOutBundleDisplayVersion On input, the display version string (or `CFBundleShortVersionString`) of the bundle to update. On output, this is the display version string of the bundle to show to the user. 45 | @param bundleVersion The version (or CFBundleVersion) of the bundle to update. 46 | @return A new display version string of the `update.displayVersionString` to show to the user. 47 | */ 48 | - (NSString *)formatUpdateDisplayVersionFromUpdate:(SUAppcastItem *)update andBundleDisplayVersion:(NSString * _Nonnull __autoreleasing * _Nonnull)inOutBundleDisplayVersion withBundleVersion:(NSString *)bundleVersion; 49 | 50 | @optional 51 | 52 | /** 53 | Formats a bundle's version string for display. 54 | 55 | This method is used to format the display version of the bundle. 56 | This method may be used when no new update is available and the user is already on the latest known version. 57 | In this case, no new update version is shown to the user. 58 | 59 | This method is optional. If it's not implemented, Sparkle will default to using the `bundleDisplayVersion` passed to this method. 60 | 61 | @param bundleDisplayVersion The display version string (or `CFBundleShortVersionString`) of the bundle to update. 62 | @param bundleVersion The version (or `CFBundleVersion`) of the bundle to update. 63 | @param matchingUpdate The update in the feed that corresponds to the current bundle, or `nil` if no matching update item could be found in the feed. 64 | @return A new display version string of the bundle to show to the user. 65 | */ 66 | - (NSString *)formatBundleDisplayVersion:(NSString *)bundleDisplayVersion withBundleVersion:(NSString *)bundleVersion matchingUpdate:(SUAppcastItem * _Nullable)matchingUpdate; 67 | 68 | /** 69 | Formats two version strings. 70 | 71 | Both versions are provided so that important distinguishing information 72 | can be displayed while also leaving out unnecessary/confusing parts. 73 | */ 74 | - (void)formatVersion:(NSString *_Nonnull*_Nonnull)inOutVersionA andVersion:(NSString *_Nonnull*_Nonnull)inOutVersionB __deprecated_msg("Please use -formatUpdateDisplayVersionFromUpdate:andBundleDisplayVersion:withBundleVersion:"); 75 | 76 | @end 77 | 78 | NS_ASSUME_NONNULL_END 79 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Headers/Sparkle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sparkle.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SPARKLE_H 10 | #define SPARKLE_H 11 | 12 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless 13 | // there are name-space collisions) so we can list all of them to start with: 14 | 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | #import 26 | #import 27 | #import 28 | #import 29 | 30 | // UI bits 31 | #import 32 | #import 33 | #import 34 | 35 | // Deprecated bits 36 | #import 37 | #import 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module Sparkle { 2 | umbrella header "Sparkle.h" 3 | export * 4 | 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/PrivateHeaders/SPUAppcastItemStateResolver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUAppcastItemStateResolver.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 5/31/21. 6 | // Copyright © 2021 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SUExport.h" 16 | #pragma clang diagnostic pop 17 | #else 18 | #import 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | @class SUStandardVersionComparator, SPUAppcastItemState; 24 | @protocol SUVersionComparison; 25 | 26 | /** 27 | Private exposed class used to resolve Appcast Item properties that rely on external factors such as a host. 28 | This resolver is used for constructing appcast items. 29 | */ 30 | SU_EXPORT @interface SPUAppcastItemStateResolver : NSObject 31 | 32 | - (instancetype)init NS_UNAVAILABLE; 33 | 34 | - (instancetype)initWithHostVersion:(NSString *)hostVersion applicationVersionComparator:(id)applicationVersionComparator standardVersionComparator:(SUStandardVersionComparator *)standardVersionComparator; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/PrivateHeaders/SPUGentleUserDriverReminders.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUGentleUserDriverReminders.h 3 | // Sparkle 4 | // 5 | // Copyright © 2022 Sparkle Project. All rights reserved. 6 | // 7 | 8 | #ifndef SPUGentleUserDriverReminders_h 9 | #define SPUGentleUserDriverReminders_h 10 | 11 | /** 12 | A private protocol for user drivers implementing gentle scheduled reminders 13 | */ 14 | @protocol SPUGentleUserDriverReminders 15 | 16 | - (void)logGentleScheduledUpdateReminderWarningIfNeeded; 17 | 18 | - (void)resetTimeSinceOpportuneUpdateNotice; 19 | 20 | @end 21 | 22 | #endif /* SPUGentleUserDriverReminders_h */ 23 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/PrivateHeaders/SPUInstallationType.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUInstallationType.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 7/24/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SPUInstallationType_h 10 | #define SPUInstallationType_h 11 | 12 | #define SPUInstallationTypeApplication @"application" // the default installation type for ordinary application updates 13 | #define SPUInstallationTypeGuidedPackage @"package" // the preferred installation type for package installations 14 | #define SPUInstallationTypeInteractivePackage @"interactive-package" // the deprecated installation type; use guided package instead 15 | 16 | #define SPUInstallationTypesArray (@[SPUInstallationTypeApplication, SPUInstallationTypeGuidedPackage, SPUInstallationTypeInteractivePackage]) 17 | #define SPUValidInstallationType(x) ((x != nil) && [SPUInstallationTypesArray containsObject:(NSString * _Nonnull)x]) 18 | 19 | #endif /* SPUInstallationType_h */ 20 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/PrivateHeaders/SPUStandardUserDriver+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUStandardUserDriver+Private.h 3 | // Sparkle 4 | // 5 | // Copyright © 2022 Sparkle Project. All rights reserved. 6 | // 7 | 8 | #ifndef SPUStandardUserDriver_Private_h 9 | #define SPUStandardUserDriver_Private_h 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SPUStandardUserDriver.h" 16 | #import "SUExport.h" 17 | #pragma clang diagnostic pop 18 | #else 19 | #import 20 | #import 21 | #endif 22 | 23 | @class NSWindowController; 24 | 25 | NS_ASSUME_NONNULL_BEGIN 26 | 27 | SU_EXPORT @interface SPUStandardUserDriver (Private) 28 | 29 | /** 30 | Private API for accessing the active update alert's window controller. 31 | This is the window controller that shows the update's release notes and install choices. 32 | This can be accessed in -[SPUStandardUserDriverDelegate standardUserDriverWillHandleShowingUpdate:forUpdate:state:] 33 | */ 34 | @property (nonatomic, readonly, nullable) NSWindowController *activeUpdateAlert; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | 40 | #endif /* SPUStandardUserDriver_Private_h */ 41 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/PrivateHeaders/SPUUserAgent+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUUserAgent+Private.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 11/12/21. 6 | // Copyright © 2021 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 12 | // Ignore incorrect warning 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 15 | #import "SUExport.h" 16 | #pragma clang diagnostic pop 17 | #else 18 | #import 19 | #endif 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | @class SUHost; 24 | 25 | SU_EXPORT NSString *SPUMakeUserAgentWithHost(SUHost *responsibleHost, NSString * _Nullable displayNameSuffix); 26 | 27 | SU_EXPORT NSString *SPUMakeUserAgentWithBundle(NSBundle *responsibleBundle, NSString * _Nullable displayNameSuffix); 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/PrivateHeaders/SUAppcastItem+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastItem+Private.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/30/21. 6 | // Copyright © 2021 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUAppcastItem_Private_h 10 | #define SUAppcastItem_Private_h 11 | 12 | #import 13 | #import 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | // Available in SPUAppcastItemStateResolver.h (a private exposed header) 18 | @class SPUAppcastItemStateResolver; 19 | @class SUSignatures; 20 | 21 | @interface SUAppcastItem (Private) 22 | 23 | /** 24 | Initializes with data from a dictionary provided by the RSS class and state resolver 25 | 26 | This initializer method is intended to be marked "private" and discouraged from public usage. 27 | This method is available however. Talk to us to describe your use case and if you need to construct appcast items yourself. 28 | */ 29 | - (nullable instancetype)initWithDictionary:(NSDictionary *)dict relativeToURL:(NSURL * _Nullable)appcastURL stateResolver:(SPUAppcastItemStateResolver *)stateResolver failureReason:(NSString * _Nullable __autoreleasing *_Nullable)error; 30 | 31 | /** 32 | The EdDSA and DSA signatures along with their statuses. 33 | */ 34 | @property (readonly, nonatomic, nullable) SUSignatures *signatures; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | 40 | #endif /* SUAppcastItem_Private_h */ 41 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/PrivateHeaders/SUInstallerLauncher+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUInstallerLauncher+Private.h 3 | // SUInstallerLauncher+Private 4 | // 5 | // Created by Mayur Pawashe on 8/21/21. 6 | // Copyright © 2021 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUInstallerLauncher_Private_h 10 | #define SUInstallerLauncher_Private_h 11 | 12 | #if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY) 13 | // Ignore incorrect warning 14 | #pragma clang diagnostic push 15 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 16 | #import "SUExport.h" 17 | #import "SPUInstallationType.h" 18 | #pragma clang diagnostic pop 19 | #else 20 | #import 21 | // Chances are clients will need this too 22 | #import 23 | #endif 24 | 25 | @class NSString; 26 | 27 | /** 28 | Private API for determining if the system needs authorization access to update a bundle path 29 | 30 | This API is not supported when used directly from a Sandboxed applications and will always return @c YES in that case. 31 | 32 | @param bundlePath The bundle path to test if authorization is needed when performing an update that replaces this bundle. 33 | @return @c YES if Sparkle thinks authorization is needed to update the @c bundlePath, otherwise @c NO. 34 | */ 35 | SU_EXPORT BOOL SPUSystemNeedsAuthorizationAccessForBundlePath(NSString *bundlePath); 36 | 37 | #endif /* SUInstallerLauncher_Private_h */ 38 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/Base.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Resources/Base.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/Base.lproj/SUUpdatePermissionPrompt.nib/keyedobjects-101300.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Resources/Base.lproj/SUUpdatePermissionPrompt.nib/keyedobjects-101300.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/Base.lproj/SUUpdatePermissionPrompt.nib/keyedobjects-110000.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Resources/Base.lproj/SUUpdatePermissionPrompt.nib/keyedobjects-110000.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/Base.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Resources/Base.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 24C101 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | Sparkle 11 | CFBundleIdentifier 12 | org.sparkle-project.Sparkle 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Sparkle 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 2.7.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 2044 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 24B75 33 | DTPlatformName 34 | macosx 35 | DTPlatformVersion 36 | 15.1 37 | DTSDKBuild 38 | 24B75 39 | DTSDKName 40 | macosx15.1 41 | DTXcode 42 | 1610 43 | DTXcodeBuild 44 | 16B40 45 | LSMinimumSystemVersion 46 | 10.13 47 | 48 | 49 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/ReleaseNotesColorStyle.css: -------------------------------------------------------------------------------- 1 | @media (prefers-color-scheme: dark) { 2 | html { 3 | color-scheme: dark; 4 | color: white; 5 | background: transparent; 6 | } 7 | :link { 8 | color: #419CFF; 9 | } 10 | :link:active { 11 | color: #FF1919; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Resources/SUStatus.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/en.lproj/SUUpdateAlert.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */ 3 | "5.title" = "Software Update"; 4 | 5 | /* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */ 6 | "170.title" = "Release Notes:"; 7 | 8 | /* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */ 9 | "171.title" = "Remind Me Later"; 10 | 11 | /* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */ 12 | "172.title" = "Skip This Version"; 13 | 14 | /* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */ 15 | "173.title" = "Install Update"; 16 | 17 | /* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */ 18 | "175.title" = "Automatically download and install updates in the future"; 19 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Resources/en.lproj/SUUpdatePermissionPrompt.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */ 3 | "43.title" = "Text Cell"; 4 | 5 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */ 6 | "45.title" = "Text Cell"; 7 | 8 | /* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "176"; */ 9 | "OhZ-1K-DmA.title" = "Check Automatically"; 10 | 11 | /* Class = "NSButtonCell"; title = "Don’t Check"; ObjectID = "177"; */ 12 | "cCJ-V0-aTi.title" = "Don’t Check"; 13 | 14 | /* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "178"; */ 15 | "gmh-T4-BO0.title" = "Check for updates automatically?"; 16 | 17 | /* Class = "NSTextFieldCell"; title = "DO NOT LOCALIZE"; ObjectID = "179"; */ 18 | "179.title" = "DO NOT LOCALIZE"; 19 | 20 | /* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "180"; */ 21 | "gz7-LM-gNf.title" = "Include anonymous system profile"; 22 | 23 | /* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */ 24 | "AUc-33-qGN.title" = "Automatically download and install updates"; 25 | 26 | /* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */ 27 | "183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; 28 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Sparkle -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Updater.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 24C101 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | Updater 11 | CFBundleIdentifier 12 | org.sparkle-project.Sparkle.Updater 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleLocalizations 16 | 17 | en 18 | ca 19 | ar 20 | cs 21 | da 22 | de 23 | el 24 | en 25 | es 26 | fa 27 | fi 28 | fr 29 | he 30 | hr 31 | hu 32 | is 33 | it 34 | ja 35 | ko 36 | nb 37 | nl 38 | pl 39 | pt-BR 40 | pt-PT 41 | ro 42 | ru 43 | sk 44 | sl 45 | sv 46 | th 47 | tr 48 | uk 49 | zh_CN 50 | zh_HK 51 | zh_TW 52 | 53 | CFBundleName 54 | Updater 55 | CFBundlePackageType 56 | APPL 57 | CFBundleShortVersionString 58 | 2.7.0 59 | CFBundleSignature 60 | ???? 61 | CFBundleSupportedPlatforms 62 | 63 | MacOSX 64 | 65 | CFBundleVersion 66 | 2044 67 | DTCompiler 68 | com.apple.compilers.llvm.clang.1_0 69 | DTPlatformBuild 70 | 24B75 71 | DTPlatformName 72 | macosx 73 | DTPlatformVersion 74 | 15.1 75 | DTSDKBuild 76 | 24B75 77 | DTSDKName 78 | macosx15.1 79 | DTXcode 80 | 1610 81 | DTXcodeBuild 82 | 16B40 83 | LSApplicationCategoryType 84 | public.app-category.utilities 85 | LSMinimumSystemVersion 86 | 10.13 87 | LSUIElement 88 | 1 89 | NSPrincipalClass 90 | NSApplication 91 | 92 | 93 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Updater.app/Contents/MacOS/Updater: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Updater.app/Contents/MacOS/Updater -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Updater.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Updater.app/Contents/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/Updater.app/Contents/Resources/SUStatus.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/Updater.app/Contents/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Resources/SUStatus.nib 8 | 9 | JXSzmd9QtRzF4pgKH2QOexbwQI4= 10 | 11 | 12 | files2 13 | 14 | Resources/SUStatus.nib 15 | 16 | hash2 17 | 18 | cxhlq2f7KC6tRzyB/cGFybWBhEaIikl2blGtzetb3Es= 19 | 20 | 21 | 22 | rules 23 | 24 | ^Resources/ 25 | 26 | ^Resources/.*\.lproj/ 27 | 28 | optional 29 | 30 | weight 31 | 1000 32 | 33 | ^Resources/.*\.lproj/locversion.plist$ 34 | 35 | omit 36 | 37 | weight 38 | 1100 39 | 40 | ^Resources/Base\.lproj/ 41 | 42 | weight 43 | 1010 44 | 45 | ^version.plist$ 46 | 47 | 48 | rules2 49 | 50 | .*\.dSYM($|/) 51 | 52 | weight 53 | 11 54 | 55 | ^(.*/)?\.DS_Store$ 56 | 57 | omit 58 | 59 | weight 60 | 2000 61 | 62 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 63 | 64 | nested 65 | 66 | weight 67 | 10 68 | 69 | ^.* 70 | 71 | ^Info\.plist$ 72 | 73 | omit 74 | 75 | weight 76 | 20 77 | 78 | ^PkgInfo$ 79 | 80 | omit 81 | 82 | weight 83 | 20 84 | 85 | ^Resources/ 86 | 87 | weight 88 | 20 89 | 90 | ^Resources/.*\.lproj/ 91 | 92 | optional 93 | 94 | weight 95 | 1000 96 | 97 | ^Resources/.*\.lproj/locversion.plist$ 98 | 99 | omit 100 | 101 | weight 102 | 1100 103 | 104 | ^Resources/Base\.lproj/ 105 | 106 | weight 107 | 1010 108 | 109 | ^[^/]+$ 110 | 111 | nested 112 | 113 | weight 114 | 10 115 | 116 | ^embedded\.provisionprofile$ 117 | 118 | weight 119 | 20 120 | 121 | ^version\.plist$ 122 | 123 | weight 124 | 20 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 24C101 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | Downloader 11 | CFBundleIdentifier 12 | org.sparkle-project.DownloaderService 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Downloader 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 2.7.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 2044 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 24B75 33 | DTPlatformName 34 | macosx 35 | DTPlatformVersion 36 | 15.1 37 | DTSDKBuild 38 | 24B75 39 | DTSDKName 40 | macosx15.1 41 | DTXcode 42 | 1610 43 | DTXcodeBuild 44 | 16B40 45 | LSMinimumSystemVersion 46 | 10.13 47 | NSAppTransportSecurity 48 | 49 | NSAllowsArbitraryLoads 50 | 51 | 52 | NSHumanReadableCopyright 53 | Copyright © 2016 Sparkle Project. All rights reserved. 54 | XPCService 55 | 56 | RunLoopType 57 | NSRunLoop 58 | ServiceType 59 | Application 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc/Contents/MacOS/Downloader: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc/Contents/MacOS/Downloader -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc/Contents/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | files2 8 | 9 | rules 10 | 11 | ^Resources/ 12 | 13 | ^Resources/.*\.lproj/ 14 | 15 | optional 16 | 17 | weight 18 | 1000 19 | 20 | ^Resources/.*\.lproj/locversion.plist$ 21 | 22 | omit 23 | 24 | weight 25 | 1100 26 | 27 | ^Resources/Base\.lproj/ 28 | 29 | weight 30 | 1010 31 | 32 | ^version.plist$ 33 | 34 | 35 | rules2 36 | 37 | .*\.dSYM($|/) 38 | 39 | weight 40 | 11 41 | 42 | ^(.*/)?\.DS_Store$ 43 | 44 | omit 45 | 46 | weight 47 | 2000 48 | 49 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 50 | 51 | nested 52 | 53 | weight 54 | 10 55 | 56 | ^.* 57 | 58 | ^Info\.plist$ 59 | 60 | omit 61 | 62 | weight 63 | 20 64 | 65 | ^PkgInfo$ 66 | 67 | omit 68 | 69 | weight 70 | 20 71 | 72 | ^Resources/ 73 | 74 | weight 75 | 20 76 | 77 | ^Resources/.*\.lproj/ 78 | 79 | optional 80 | 81 | weight 82 | 1000 83 | 84 | ^Resources/.*\.lproj/locversion.plist$ 85 | 86 | omit 87 | 88 | weight 89 | 1100 90 | 91 | ^Resources/Base\.lproj/ 92 | 93 | weight 94 | 1010 95 | 96 | ^[^/]+$ 97 | 98 | nested 99 | 100 | weight 101 | 10 102 | 103 | ^embedded\.provisionprofile$ 104 | 105 | weight 106 | 20 107 | 108 | ^version\.plist$ 109 | 110 | weight 111 | 20 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/XPCServices/Installer.xpc/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 24C101 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | Installer 11 | CFBundleIdentifier 12 | org.sparkle-project.InstallerLauncher 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Installer 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 2.7.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 2044 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 24B75 33 | DTPlatformName 34 | macosx 35 | DTPlatformVersion 36 | 15.1 37 | DTSDKBuild 38 | 24B75 39 | DTSDKName 40 | macosx15.1 41 | DTXcode 42 | 1610 43 | DTXcodeBuild 44 | 16B40 45 | LSMinimumSystemVersion 46 | 10.13 47 | NSHumanReadableCopyright 48 | Copyright © 2016 Sparkle Project. All rights reserved. 49 | XPCService 50 | 51 | JoinExistingSession 52 | 53 | ServiceType 54 | Application 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/XPCServices/Installer.xpc/Contents/MacOS/Installer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/Sparkle.framework/Versions/B/XPCServices/Installer.xpc/Contents/MacOS/Installer -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/B/XPCServices/Installer.xpc/Contents/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | files2 8 | 9 | rules 10 | 11 | ^Resources/ 12 | 13 | ^Resources/.*\.lproj/ 14 | 15 | optional 16 | 17 | weight 18 | 1000 19 | 20 | ^Resources/.*\.lproj/locversion.plist$ 21 | 22 | omit 23 | 24 | weight 25 | 1100 26 | 27 | ^Resources/Base\.lproj/ 28 | 29 | weight 30 | 1010 31 | 32 | ^version.plist$ 33 | 34 | 35 | rules2 36 | 37 | .*\.dSYM($|/) 38 | 39 | weight 40 | 11 41 | 42 | ^(.*/)?\.DS_Store$ 43 | 44 | omit 45 | 46 | weight 47 | 2000 48 | 49 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 50 | 51 | nested 52 | 53 | weight 54 | 10 55 | 56 | ^.* 57 | 58 | ^Info\.plist$ 59 | 60 | omit 61 | 62 | weight 63 | 20 64 | 65 | ^PkgInfo$ 66 | 67 | omit 68 | 69 | weight 70 | 20 71 | 72 | ^Resources/ 73 | 74 | weight 75 | 20 76 | 77 | ^Resources/.*\.lproj/ 78 | 79 | optional 80 | 81 | weight 82 | 1000 83 | 84 | ^Resources/.*\.lproj/locversion.plist$ 85 | 86 | omit 87 | 88 | weight 89 | 1100 90 | 91 | ^Resources/Base\.lproj/ 92 | 93 | weight 94 | 1010 95 | 96 | ^[^/]+$ 97 | 98 | nested 99 | 100 | weight 101 | 10 102 | 103 | ^embedded\.provisionprofile$ 104 | 105 | weight 106 | 20 107 | 108 | ^version\.plist$ 109 | 110 | weight 111 | 20 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | B -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/XPCServices: -------------------------------------------------------------------------------- 1 | Versions/Current/XPCServices -------------------------------------------------------------------------------- /sparkle/dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIDRjCCAjkGByqGSM44BAEwggIsAoIBAQDknXTIoCIKOnt1ycbHuLjkahzene1Y 3 | VUeM1XIqsHOl1Qc1U3sirD42Luqul5/bLnSQaZxNAn+Zvteg8kWQc7cKSPljKh4s 4 | O1oUYQ7hNsaDEqwNEhjbRK6v0iFLl90gxo68bu6e/BxsJJn0cDhmVM+6Qh0ILGai 5 | B97JBvc6JHkXhj+XYaHRXZIm+q+SOwV9EbsBUg69+fbdfTE2MD9405qFsKKmOgls 6 | IGfAQtwz3ZuxxUNQ5S/pKTaOwdLnyFVYbJsSbNPQkERDfAUFDJ1hoQdnhdl3S/hm 7 | uJNQHMWutDGfUGSbu4+dcr9zIa13SzGdqYZed0bQ5Gusw3uOvLHXvIcxAiEAjh1r 8 | 9GTzUkGUBIn6v9ip27SrbX/hyKdAUJiak1ffpbUCggEAe5J4shGO/C3XzTAiANDz 9 | 8TPGFztkbNpengkhm6A5cHkabBbi9DzS1oHtLNW4uroRcDXmn1e/3CtH7bLDkzpd 10 | pBk0JR2KGx1neor4znzJg6G+9tJMU6mWV9q617wrvLKUyjrLqEH38kGOYmvW9YqM 11 | rjQhXnD6R5UrB6gszD9Zc6UwFW7gVF2vhX+AlOe+TijwrqH7eDePKUJ+yc9KFz3+ 12 | M/d1DamACHKXEivUNwUDy0Ue2pzFrniXCRA/+eWmnaQRxMyZzZifDdN6SomdivgJ 13 | UnPXpSyHR5VQ2r5g9mUowlZQ9QGu2oG3h2FJGtOa5xKwvkRfAHtTxPxp/MviN78S 14 | SwOCAQUAAoIBABReNGag4JMurfOhMKGpT/gxN3nLKxZq7mNxlrH7/cdgar3tuf7l 15 | QX10apAolKwrRlc8pb5xP13ITPOV2e40iQx3fLEVYy+wupPskqb+RigRyMdWDGnA 16 | T5DHJxv0SumM6zmsB3X2oi4zYT0MDssiQbhfMG2ab+JRzt8dsWS05rvGPyj1mKSj 17 | Tq0P3BmPFaWes6Gfglt6OKUkesj+Wwvz+DiyZNHEDx7unwAs8EpLU1jCQQSI6lKn 18 | Y1YHCejl6XbiZqoRafjH1HUs/+3+u/goNLnkcBlUOIHuJcJAQD4+4EYXKweeWxpG 19 | a0+QqTQBiG9uWOjDnhZstodNCaQDqv6YlJo= 20 | -----END PUBLIC KEY----- 21 | -------------------------------------------------------------------------------- /sparkle/generate_keys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/generate_keys -------------------------------------------------------------------------------- /sparkle/sign_update: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sveinbjornt/Sloth/bf40084f87313606446d8df32c7b700ca327374a/sparkle/sign_update -------------------------------------------------------------------------------- /sparkle/sign_update.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | if ARGV.length < 2 3 | puts "Usage: ruby sign_update.rb update_archive private_key" 4 | exit 5 | end 6 | 7 | puts `openssl dgst -sha1 -binary < "#{ARGV[0]}" | openssl dgst -dss1 -sign "#{ARGV[1]}" | openssl enc -base64` --------------------------------------------------------------------------------