13 Commits

12 changed files with 257 additions and 397 deletions

View File

@ -21,32 +21,29 @@
name: C/C++ CI (DOS DJGPP) name: C/C++ CI (DOS DJGPP)
on: on:
push: workflow_call:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
env: env:
CMAKE_C_COMPILER: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-gcc CC: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-gcc
CMAKE_CXX_COMPILER: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-g++ CXX: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-g++
CMAKE_FIND_ROOT_PATH: ${{ github.workspace }}/djgpp CMAKE_FIND_ROOT_PATH: ${{ github.workspace }}/djgpp
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM: NEVER
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY: ONLY
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE: ONLY
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE: ONLY
WATT_ROOT: ${{ github.workspace }}/djgpp/watt32 WATT_ROOT: ${{ github.workspace }}/djgpp/watt32
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Source Tree
uses: actions/checkout@v3
- name: Setup build environment - name: Setup build environment
run: | run: |
sudo apt -y update sudo apt -y update
sudo apt -y install build-essential cmake wget 7zip git flex nasm libslang2-dev pkg-config libslang2-modules gcc-multilib sudo apt -y install build-essential cmake wget 7zip git flex libfl-dev nasm libslang2-dev pkg-config libslang2-modules gcc-multilib
- name: Download and Setup DJGPP Toolchain - name: Download and Setup DJGPP Toolchain
run: | run: |
pushd ${{ github.workspace }}
wget https://github.com/andrewwutw/build-djgpp/releases/download/v3.4/djgpp-linux64-gcc1220.tar.bz2 wget https://github.com/andrewwutw/build-djgpp/releases/download/v3.4/djgpp-linux64-gcc1220.tar.bz2
tar xjf djgpp-linux64-gcc1220.tar.bz2 tar xjf djgpp-linux64-gcc1220.tar.bz2
cd ${{ github.workspace }}/djgpp cd ${{ github.workspace }}/djgpp
@ -54,40 +51,34 @@ jobs:
cd watt32/util cd watt32/util
make clean && make linux make clean && make linux
cd ../src cd ../src
source ${{ github.workspace }}/djgpp/setenv
./configur.sh djgpp ./configur.sh djgpp
make -f djgpp.mak make -f djgpp.mak
ln -s ${{ github.workspace }}/djgpp/watt32/lib/libwatt.a ${{ github.workspace }}/djgpp/lib ln -s ${WATT_ROOT}/lib/libwatt.a ${{ github.workspace }}/djgpp/lib
- name: Checkout and Cross Compile OpenSSL 3.1 - name: Checkout and Cross Compile OpenSSL 3.1.2
run: | run: |
git clone https://github.com/UMSKT/openssl.git openssl git clone https://github.com/UMSKT/openssl.git openssl
pushd openssl pushd openssl
git checkout openssl-3.1.1
source ${{ github.workspace }}/djgpp/setenv source ${{ github.workspace }}/djgpp/setenv
./Configure no-threads -DOPENSSL_DEV_NO_ATOMICS --prefix=${{ github.workspace }}/djgpp DJGPP ./Configure no-threads -DOPENSSL_DEV_NO_ATOMICS --prefix=${{ github.workspace }}/djgpp DJGPP
make && make install make && make install
popd popd
ls ${{ github.workspace }}/djgpp/i586-pc-msdosdjgpp/bin/
- name: Checkout Source Tree
uses: actions/checkout@v3
- name: Build - name: Build
uses: threeal/cmake-action@v1.2.0
with:
c-compiler: gcc
cxx-compiler: g++
options: OPENSSL_ROOT_DIR:string=${{ github.workspace }}/djgpp DJGPP_WATT32=ON
run-build: true
- name: Test & Move files to correct directory
run: | run: |
mkdir -p build/actions_upload source ${{ github.workspace }}/djgpp/setenv
mv build/umskt build/actions_upload/umskt pushd build
cmake ../ -D DJGPP_WATT32=${WATT_ROOT}/lib/libwatt.a -D CMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH}
make
- name: Move executable to upload directory
run: |
mkdir build/actions_upload
mv build/umskt.exe build/actions_upload/
- name: Upload build artifact - name: Upload build artifact
uses: actions/upload-artifact@v3.1.2 uses: actions/upload-artifact@v3.1.2
with: with:
name: UMSKT-DOS-DJGPP name: UMSKT-DOS
path: build/actions_upload path: build/actions_upload

View File

@ -1,61 +0,0 @@
# This file is a part of the UMSKT Project
#
# Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# @FileCreated by techguy16 on 07/23/2023
# @Maintainer techguy16
name: C/C++ CI (FreeBSD)
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: macos-latest
name: build-x86_64
steps:
- uses: actions/checkout@v3
- name: Build & Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v0
with:
envs: 'MYTOKEN MYTOKEN2'
usesh: true
prepare: |
pkg install -y cmake openssl git bash
run: |
mkdir build
cd build
cmake ..
make
./umskt # Execute the test here
- name: Move files to correct directory
run: |
mkdir -p build/actions_upload
mv build/umskt build/actions_upload/umskt
- name: Upload build artifact
uses: actions/upload-artifact@v3.1.2
with:
name: UMSKT-FreeBSD
path: build/actions_upload

View File

@ -60,7 +60,7 @@ jobs:
run-build: true run-build: true
shell: alpine-target.sh {0} shell: alpine-target.sh {0}
- name: Move files to correct directory - name: Move executable to upload directory
run: | run: |
mkdir -p build/actions_upload mkdir -p build/actions_upload
mv build/umskt build/actions_upload/umskt mv build/umskt build/actions_upload/umskt

View File

@ -1,60 +0,0 @@
# This file is a part of the UMSKT Project
#
# Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# @FileCreated by techguy16 on 07/23/2023
# @Maintainer techguy16
name: C/C++ CI (macOS)
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build-x86:
runs-on: macos-latest
strategy:
matrix:
include:
- arch: x86_64
steps:
- name: Checkout Source Tree
uses: actions/checkout@v3
- name: Configure and build UMSKT
run: |
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
- name: Move files to correct directory
run: |
mkdir -p build/actions_upload
mv build/umskt build/actions_upload/umskt
- name: Run tests
run: |
cd build/actions_upload
./umskt
- name: Upload build artifact
uses: actions/upload-artifact@v3.1.2
with:
name: UMSKT-macOS-${{ matrix.arch }}-static
path: build/actions_upload

View File

@ -27,122 +27,91 @@ on:
branches: [ "master" ] branches: [ "master" ]
jobs: jobs:
build-32bit: build-djgpp:
runs-on: windows-latest uses: ./.github/workflows/dos-djgpp.yml
steps:
# https://github.com/actions/runner-images/issues/6067#issuecomment-1213069040
- name: Install Windows XP Support for Visual Studio
run: |
Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer\"
$InstallPath = "C:\Program Files\Microsoft Visual Studio\2022\Enterprise"
$componentsToAdd = @(
"Microsoft.VisualStudio.Component.WinXP"
)
[string]$workloadArgs = $componentsToAdd | ForEach-Object {" --add " + $_}
$Arguments = ('/c', "vs_installer.exe", 'modify', '--installPath', "`"$InstallPath`"",$workloadArgs, '--quiet', '--norestart', '--nocache')
$process = Start-Process -FilePath cmd.exe -ArgumentList $Arguments -Wait -PassThru -WindowStyle Hidden
if ($process.ExitCode -eq 0)
{
Write-Host "components have been successfully added"
Get-ChildItem C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.Windows.XPSupport.*
}
else
{
Write-Host "components were not installed"
exit 1
}
- name: Download And Install 32-bit OpenSSL 3.1.2 build:
runs-on: windows-latest
needs: build-djgpp
strategy:
matrix:
include:
- arch: Win32
OpenSSL-File: Win32OpenSSL-3_1_1.exe
msbuild-arch: Win32
cmake-args: -D MSVC_MSDOS_STUB=..\umskt.exe
- arch: Win64
OpenSSL-File: Win64OpenSSL-3_1_1.exe
msbuild-arch: x64
cmake-args: ""
steps:
- name: Checkout Source Tree
uses: actions/checkout@v3
- name: Install Windows XP Support for Visual Studio
uses: thepwrtank18/install-vs-components@v1.0.0
with:
components: Microsoft.VisualStudio.Component.WinXP
- name: Download And Install ${{ matrix.OpenSSL-File }}
run: | run: |
$installDir = "$Env:ProgramFiles\OpenSSL" $installDir = "$Env:ProgramFiles\OpenSSL"
$installerURL = "https://slproweb.com/download/Win32OpenSSL-3_1_2.exe" $installerURL = "https://slproweb.com/download/${{ matrix.OpenSSL-File }}"
$installerName = "Win32OpenSSL-3_1_2.exe" $installerName = "${{ matrix.OpenSSL-File }}"
$installerPath = Join-Path -Path "${env:Temp}" -ChildPath "$installerName" $installerPath = Join-Path -Path "${env:Temp}" -ChildPath "$installerName"
(New-Object System.Net.WebClient).DownloadFile($installerURL, $installerPath) (New-Object System.Net.WebClient).DownloadFile($installerURL, $installerPath)
Remove-Item "$installDir" -Force -Recurse Remove-Item "$installDir" -Force -Recurse
$installerArgs = '/silent', '/sp-', '/suppressmsgboxes', "/DIR=`"$installDir`"" $installerArgs = '/silent', '/sp-', '/suppressmsgboxes', "/DIR=`"$installDir`""
Start-Process -FilePath $installerPath -ArgumentList $installerArgs -Wait -PassThru Start-Process -FilePath $installerPath -ArgumentList $installerArgs -Wait -PassThru
- name: Checkout Source Tree
uses: actions/checkout@v3
- name: Setup MSBuild - name: Setup MSBuild
uses: microsoft/setup-msbuild@v1 uses: microsoft/setup-msbuild@v1
- name: Download UMSKT-DJGPP compiled artifact
if: matrix.arch == 'Win32'
uses: actions/download-artifact@v3
with:
name: UMSKT-DOS
- name: List build directory contents
if: matrix.arch == 'Win32'
run: |
Get-ChildItem
- name: Configure UMSKT - name: Configure UMSKT
uses: threeal/cmake-action@v1.2.0 uses: threeal/cmake-action@v1.2.0
with: with:
generator: "Visual Studio 17 2022" generator: "Visual Studio 17 2022"
options: CMAKE_SYSTEM_VERSION="5.1.2600" options: CMAKE_SYSTEM_VERSION="5.1.2600"
args: -A "Win32" -T v141_xp args: -A ${{ matrix.msbuild-arch }} -T v141_xp ${{ matrix.cmake-args }}
- name: Build UMSKT - name: Build UMSKT
working-directory: build working-directory: build
run: msbuild ALL_BUILD.vcxproj /P:Configuration=Release run: msbuild ALL_BUILD.vcxproj /P:Configuration=Release /P:XPDeprecationWarning=false
- name: Move executable to upload directory
run: |
mkdir build/actions_upload
Move-Item build/Release/umskt.exe build/actions_upload
- name: Upload build artifact - name: Upload build artifact
uses: actions/upload-artifact@v3.1.2 uses: actions/upload-artifact@v3.1.2
with: with:
name: UMSKT-Win32 name: UMSKT-${{ matrix.arch }}
path: build/Release path: build/actions_upload
build-64bit: - name: Move Win32+DOS executable to upload directory
runs-on: windows-latest if: matrix.arch == 'Win32'
steps:
- name: Install Windows XP Support for Visual Studio
run: | run: |
Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer\" Remove-Item "build/actions_upload" -Force -Recurse
$InstallPath = "C:\Program Files\Microsoft Visual Studio\2022\Enterprise" mkdir build/actions_upload
$componentsToAdd = @( Move-Item build/Release/umskt_win32_dos.exe build/actions_upload/umskt.exe
"Microsoft.VisualStudio.Component.WinXP"
)
[string]$workloadArgs = $componentsToAdd | ForEach-Object {" --add " + $_}
$Arguments = ('/c', "vs_installer.exe", 'modify', '--installPath', "`"$InstallPath`"",$workloadArgs, '--quiet', '--norestart', '--nocache')
$process = Start-Process -FilePath cmd.exe -ArgumentList $Arguments -Wait -PassThru -WindowStyle Hidden
if ($process.ExitCode -eq 0)
{
Write-Host "components have been successfully added"
Get-ChildItem C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.Windows.XPSupport.*
}
else
{
Write-Host "components were not installed"
exit 1
}
- name: Download And Install 64-bit OpenSSL 3.1.2
run: |
$installDir = "$Env:ProgramFiles\OpenSSL"
$installerURL = "https://slproweb.com/download/Win64OpenSSL-3_1_2.exe"
$installerName = "Win64OpenSSL-3_1_2.exe"
$installerPath = Join-Path -Path "${env:Temp}" -ChildPath "$installerName"
(New-Object System.Net.WebClient).DownloadFile($installerURL, $installerPath)
Remove-Item "$installDir" -Force -Recurse
$installerArgs = '/silent', '/sp-', '/suppressmsgboxes', "/DIR=`"$installDir`""
Start-Process -FilePath $installerPath -ArgumentList $installerArgs -Wait -PassThru
- name: Checkout Source Tree
uses: actions/checkout@v3
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1
- name: Configure UMSKT
uses: threeal/cmake-action@v1.2.0
with:
generator: "Visual Studio 17 2022"
args: -A "x64" -T "v141_xp"
- name: Build UMSKT
working-directory: build
run: msbuild ALL_BUILD.vcxproj /P:Configuration=Release
- name: Upload build artifact - name: Upload build artifact
if: matrix.arch == 'Win32'
uses: actions/upload-artifact@v3.1.2 uses: actions/upload-artifact@v3.1.2
with: with:
name: UMSKT-Win64 name: UMSKT-Win32+DOS
path: build/Release path: build/actions_upload

View File

@ -18,92 +18,170 @@
# @FileCreated by Andrew on 05/30/2023 # @FileCreated by Andrew on 05/30/2023
# @Maintainer Neo # @Maintainer Neo
cmake_minimum_required(VERSION 3.12) CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
PROJECT(UMSKT)
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
OPTION(UMSKT_USE_SHARED_OPENSSL "Force linking against the system-wide OpenSSL library" OFF)
OPTION(MUSL_STATIC "Enable fully static builds in a muslc environment (i.e. Alpine Linux)" OFF)
OPTION(DJGPP_WATT32 "Enable compilation and linking with DJGPP/WATT32/OpenSSL" OFF)
OPTION(MSVC_MSDOS_STUB "Specify a custom MS-DOS stub for a 32-bit MSVC compilation" OFF)
project(UMSKT) SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS})
set(CMAKE_OSX_SYSROOT "macosx" CACHE PATH "macOS SDK path") SET(UMSKT_LINK_DIRS ${UMSKT_LINK_DIRS})
set(CMAKE_CXX_STANDARD 17) IF(UMSKT_USE_SHARED_OPENSSL)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) SET(OPENSSL_USE_STATIC_LIBS FALSE)
SET(OPENSSL_MSVC_STATIC_RT FALSE)
MESSAGE(WARNING "[UMSKT] Forcing shared OpenSSL runtime")
ELSE()
SET(OPENSSL_USE_STATIC_LIBS TRUE)
SET(OPENSSL_MSVC_STATIC_RT TRUE)
ENDIF()
option(UMSKT_USE_SHARED_OPENSSL "Force linking against the system-wide OpenSSL library" OFF) IF(DJGPP_WATT32)
option(MUSL_STATIC "Enable fully static builds in a muslc environment (i.e. Alpine Linux)" OFF) SET(CMAKE_SYSTEM_NAME MSDOS)
option(DJGPP_WATT32 "Enable compilation and linking with DJGPP/WATT32/OpenSSL" OFF) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
option(MSVC_MSDOS_STUB "Specify a custom MS-DOS stub for a 32-bit MSVC compilation" OFF) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS} ${DJGPP_WATT32})
SET(UMSKT_LINK_DIRS ${UMSKT_LINK_DIRS} ${WATT_ROOT}/lib)
ENDIF()
find_package(OpenSSL REQUIRED) # find the system installed OpenSSL development library
FIND_PACKAGE(OpenSSL REQUIRED)
IF(NOT OPENSSL_FOUND)
MESSAGE(SEND_ERROR "OpenSSL Development Libraries Not Found")
MESSAGE(SEND_ERROR "Please consult your package manager of choice to install the prerequisite")
MESSAGE(SEND_ERROR "The package name is commonly called libssl-dev or openssl-dev depending on distribution")
MESSAGE(FATAL_ERROR "Can not continue without OpenSSL")
ENDIF()
if(NOT OpenSSL_FOUND) # if we found shared libraries - do the following:
message(FATAL_ERROR "OpenSSL Development Libraries Not Found. Please install the required OpenSSL development package.") STRING(REGEX MATCH "(\\.so|\\.dll|\\.dylib)$" OPENSSL_CRYPTO_SHARED "${OPENSSL_CRYPTO_LIBRARY}")
endif() IF(OPENSSL_CRYPTO_SHARED)
MESSAGE(STATUS "[UMSKT] Detected Shared library version of OpenSSL")
SET(BUILD_SHARED_LIBS ON)
ELSE()
MESSAGE(STATUS "[UMSKT] Detected Static Library version of OpenSSL")
ENDIF()
if(UMSKT_USE_SHARED_OPENSSL) # if we're compiling with MSVC, respect the DEBUG compile option
set(OPENSSL_USE_STATIC_LIBS FALSE) IF(MSVC)
set(OPENSSL_MSVC_STATIC_RT FALSE) SET(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
else() IF(NOT BUILD_SHARED_LIBS)
set(OPENSSL_USE_STATIC_LIBS TRUE) SET(CMAKE_CXX_FLAGS_RELEASE "/MT")
set(OPENSSL_MSVC_STATIC_RT TRUE) SET(CMAKE_CXX_FLAGS_DEBUG "/MTd")
endif() ELSE()
SET(CMAKE_CXX_FLAGS_RELEASE "/MD")
SET(CMAKE_CXX_FLAGS_DEBUG "/MDd")
ENDIF()
SET(CMAKE_EXE_LINKER_FLAGS "/INCREMENTAL:NO /NODEFAULTLIB:MSVCRT")
SET(CMAKE_ENABLE_EXPORTS ON)
SET(UMSKT_EXE_WINDOWS_EXTRA src/windows/umskt.rc)
SET(UMSKT_EXE_WINDOWS_DLL src/windows/dllmain.cpp)
ENDIF()
if(MUSL_STATIC AND NOT UMSKT_USE_SHARED_OPENSSL) IF(MUSL_STATIC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") MESSAGE(STATUS "[UMSKT] Performing a fully static build using muslc")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -static-libstdc++") SET(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc -static-libstdc++")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") SET(CMAKE_SHARED_LINKER_FLAGS "-static -static-libgcc -static-libstdc++")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -static-libstdc++") SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -static-libstdc++")
endif() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
ENDIF()
include(cmake/CPM.cmake) # initalize cpm.CMake
INCLUDE(cmake/CPM.cmake)
# fetch cpm.CMake dependencies
# Include JSON development library
CPMAddPackage( CPMAddPackage(
NAME nlohmann_json NAME nlohmann_json
GITHUB_REPOSITORY nlohmann/json GITHUB_REPOSITORY nlohmann/json
VERSION 3.11.2 VERSION 3.11.2
) )
# Include fmt development library
CPMAddPackage( CPMAddPackage(
NAME fmt NAME fmt
GITHUB_REPOSITORY fmtlib/fmt GITHUB_REPOSITORY fmtlib/fmt
GIT_TAG 10.0.0 GIT_TAG 10.0.0
VERSION 10.0.0 VERSION 10.0.0
) )
# Include cmrc resource compiler
CPMAddPackage( CPMAddPackage(
NAME cmrc NAME cmrc
GITHUB_REPOSITORY vector-of-bool/cmrc GITHUB_REPOSITORY vector-of-bool/cmrc
GIT_TAG 2.0.1 GIT_TAG 2.0.1
VERSION 2.0.1 VERSION 2.0.1
) )
# For Emscripten builds, set CMAKE_TOOLCHAIN_FILE to the appropriate file # Include Crypto++ development library
set(EMSCRIPTEN_BUILD OFF CACHE BOOL "Build for Emscripten" FORCE) #CPMAddPackage(
if(EMSCRIPTEN_BUILD) # NAME cryptopp-cmake
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cmake/Emscripten.cmake" CACHE STRING "Emscripten toolchain file") # GITHUB_REPOSITORY abdes/cryptopp-cmake
endif() # GIT_TAG CRYPTOPP_8_8_0
# VERSION 8.8.0
# OPTIONS "CRYPTOPP_BUILD_TESTING OFF"
#)
#include googletest unit testing library
#CPMAddPackage(
# NAME googletest
# GITHUB_REPOSITORY google/googletest
# VERSION 1.13.0
# OPTIONS "INSTALL_GTEST OFF" "gtest_force_shared_crt"
#)
### Resource compilation
CMRC_ADD_RESOURCE_LIBRARY(umskt-rc ALIAS umskt::rc NAMESPACE umskt keys.json) CMRC_ADD_RESOURCE_LIBRARY(umskt-rc ALIAS umskt::rc NAMESPACE umskt keys.json)
set(LIBUMSKT_SRC SET(LIBUMSKT_SRC src/libumskt/libumskt.cpp src/libumskt/pidgen3/BINK1998.cpp src/libumskt/pidgen3/BINK2002.cpp src/libumskt/pidgen3/key.cpp src/libumskt/pidgen3/util.cpp src/libumskt/confid/confid.cpp src/libumskt/pidgen2/PIDGEN2.cpp src/libumskt/debugoutput.cpp)
src/libumskt/libumskt.cpp
src/libumskt/pidgen3/BINK1998.cpp
src/libumskt/pidgen3/BINK2002.cpp
src/libumskt/pidgen3/key.cpp
src/libumskt/pidgen3/util.cpp
src/libumskt/confid/confid.cpp
src/libumskt/pidgen2/PIDGEN2.cpp
src/libumskt/debugoutput.cpp
)
if(UMSKT_USE_SHARED_OPENSSL) #### Separate Build Path for emscripten
add_library(_umskt SHARED ${LIBUMSKT_SRC}) IF (EMSCRIPTEN)
else() ADD_EXECUTABLE(umskt ${LIBUMSKT_SRC})
add_library(_umskt STATIC ${LIBUMSKT_SRC}) TARGET_INCLUDE_DIRECTORIES(umskt PUBLIC ${OPENSSL_INCLUDE_DIR})
endif() TARGET_LINK_LIBRARIES(umskt -static OpenSSL::Crypto fmt)
SET(CMAKE_EXECUTABLE_SUFFIX ".html")
target_include_directories(_umskt PUBLIC ${OPENSSL_INCLUDE_DIR}) SET_TARGET_PROPERTIES(umskt PROPERTIES COMPILE_FLAGS "-Os -sEXPORTED_RUNTIME_METHODS=ccall,cwrap")
target_link_libraries(_umskt PRIVATE OpenSSL::Crypto fmt) SET_TARGET_PROPERTIES(umskt PROPERTIES LINK_FLAGS "-Os -sWASM=1 -sEXPORT_ALL=1 -sEXPORTED_RUNTIME_METHODS=ccall,cwrap --no-entry")
ELSE()
IF(NOT UMSKT_USE_SHARED_OPENSSL)
### Static library compilation
ADD_LIBRARY(_umskt STATIC ${LIBUMSKT_SRC})
TARGET_INCLUDE_DIRECTORIES(_umskt PUBLIC ${OPENSSL_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(_umskt -static OpenSSL::Crypto fmt ${UMSKT_LINK_LIBS})
ELSE()
### Shared library compilation
ADD_LIBRARY(_umskt SHARED ${LIBUMSKT_SRC} ${UMSKT_EXE_WINDOWS_EXTRA} ${UMSKT_EXE_WINDOWS_DLL})
TARGET_INCLUDE_DIRECTORIES(_umskt PUBLIC ${OPENSSL_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(_umskt OpenSSL::Crypto fmt ${UMSKT_LINK_LIBS})
TARGET_LINK_DIRECTORIES(_umskt PUBLIC ${UMSKT_LINK_DIRS})
ENDIF()
add_executable(umskt src/main.cpp src/cli.cpp ${UMSKT_EXE_WINDOWS_EXTRA}) ### UMSKT executable compilation
ADD_EXECUTABLE(umskt src/main.cpp src/cli.cpp ${UMSKT_EXE_WINDOWS_EXTRA})
TARGET_INCLUDE_DIRECTORIES(umskt PUBLIC ${OPENSSL_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(umskt _umskt OpenSSL::Crypto fmt nlohmann_json::nlohmann_json umskt::rc ${UMSKT_LINK_LIBS})
TARGET_LINK_DIRECTORIES(umskt PUBLIC ${UMSKT_LINK_DIRS})
target_include_directories(umskt PUBLIC ${OPENSSL_INCLUDE_DIR}) ### UMSKT with specified DOS Stub compilation
target_link_libraries(umskt PRIVATE _umskt OpenSSL::Crypto fmt nlohmann_json::nlohmann_json umskt::rc) IF(MSVC AND MSVC_MSDOS_STUB)
ADD_EXECUTABLE(umskt_win32_dos src/main.cpp src/cli.cpp ${UMSKT_EXE_WINDOWS_EXTRA})
TARGET_INCLUDE_DIRECTORIES(umskt_win32_dos PUBLIC ${OPENSSL_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(umskt_win32_dos _umskt OpenSSL::Crypto fmt nlohmann_json::nlohmann_json umskt::rc ${UMSKT_LINK_LIBS})
TARGET_LINK_DIRECTORIES(umskt_win32_dos PUBLIC ${UMSKT_LINK_DIRS})
SET_PROPERTY(TARGET umskt_win32_dos APPEND PROPERTY LINK_FLAGS /STUB:${MSVC_MSDOS_STUB})
ENDIF()
### Copy Shared Libraries and dependency files
IF (OPENSSL_CRYPTO_SHARED)
GET_FILENAME_COMPONENT(OPENSSL_CRYPTO_LIBRARY_FILENAME ${OPENSSL_CRYPTO_LIBRARY} NAME)
CONFIGURE_FILE(${OPENSSL_CRYPTO_LIBRARY} "${CMAKE_CURRENT_BINARY_DIR}/${OPENSSL_CRYPTO_LIBRARY_FILENAME}" COPYONLY)
ENDIF()
ENDIF()

View File

@ -54,16 +54,9 @@ WORKDIR /tmp
# Stage 2: compile djgpp for muslc # Stage 2: compile djgpp for muslc
ENV DJGPP_PREFIX=/djgpp BUILD_VER=12.2.0-i386 ENV DJGPP_PREFIX=/djgpp BUILD_VER=12.2.0-i386
RUN git clone https://github.com/andrewwutw/build-djgpp.git djgpp \ RUN git clone https://github.com/UMSKT/build-djgpp.git djgpp \
&& cd djgpp \ && cd djgpp \
&& cd script \ && chmod +x script/$BUILD_VER \
&& wget https://gist.github.com/Neo-Desktop/4cfd708f61f5847a7bf457d38db3b59f/raw/25d24cf509b0fc486d5d18ecb6656f120c3d0e51/12.2.0-i386 -O 12.2.0-i386 \
&& chmod +x 12.2.0-i386 \
&& cd ../patch \
&& wget https://gist.github.com/Neo-Desktop/4cfd708f61f5847a7bf457d38db3b59f/raw/25d24cf509b0fc486d5d18ecb6656f120c3d0e51/patch-alpine-Fix-attempt-to-use-poisoned-calloc-error-in-libgccji.patch -O patch-alpine-Fix-attempt-to-use-poisoned-calloc-error-in-libgccji.patch \
&& cd .. \
&& sed -i 's/i586/i386/g' setenv/setenv \
&& sed -i 's/i586/i386/g' setenv/setenv.bat \
&& ./build-djgpp.sh $BUILD_VER \ && ./build-djgpp.sh $BUILD_VER \
&& rm -rf /tmp/djgpp && rm -rf /tmp/djgpp
@ -72,15 +65,12 @@ FROM djgpp as watt32
WORKDIR /djgpp WORKDIR /djgpp
ENV WATT_ROOT=/djgpp/watt32 DJGPP_PREFIX=i386-pc-msdosdjgpp ENV WATT_ROOT=/djgpp/watt32 DJGPP_PREFIX=i386-pc-msdosdjgpp
SHELL ["/bin/bash", "-c"] SHELL ["/bin/bash", "-c"]
RUN git clone https://github.com/gvanem/Watt-32.git watt32 \ RUN git clone https://github.com/UMSKT/Watt-32.git watt32 \
&& cd watt32/util \ && cd watt32/util \
&& make clean && make linux \ && make clean && make linux \
&& cd ../src \ && cd ../src \
&& source /djgpp/setenv \ && source /djgpp/setenv \
&& ./configur.sh djgpp \ && ./configur.sh djgpp \
&& sed -i 's/i586/i386/g' djgpp.mak \
&& wget https://gist.github.com/Neo-Desktop/ad26e888d64b22a59c743ab4e21ac186/raw/c9a73e1eb75ba8857883ac5c08691d2fe5b82594/djgpp.err -O ../inc/sys/djgpp.err \
&& wget https://gist.github.com/Neo-Desktop/ad26e888d64b22a59c743ab4e21ac186/raw/c9a73e1eb75ba8857883ac5c08691d2fe5b82594/syserr.c -O build/djgpp/syserr.c \
&& make -f djgpp.mak \ && make -f djgpp.mak \
&& ln -s /djgpp/watt32/lib/libwatt.a /djgpp/lib && ln -s /djgpp/watt32/lib/libwatt.a /djgpp/lib
@ -88,12 +78,9 @@ RUN git clone https://github.com/gvanem/Watt-32.git watt32 \
FROM watt32 as openssl FROM watt32 as openssl
WORKDIR /tmp WORKDIR /tmp
SHELL ["/bin/bash", "-c"] SHELL ["/bin/bash", "-c"]
RUN git clone https://github.com/openssl/openssl.git openssl \ RUN git clone https://github.com/umskt/openssl.git openssl \
&& cd openssl \ && cd openssl \
&& git checkout openssl-3.1.1 \
&& source /djgpp/setenv \ && source /djgpp/setenv \
&& wget https://gist.github.com/Neo-Desktop/ad26e888d64b22a59c743ab4e21ac186/raw/c9a73e1eb75ba8857883ac5c08691d2fe5b82594/50-djgpp.conf.patch -O Configurations/50-djgpp.conf.patch \
&& git apply Configurations/50-djgpp.conf.patch \
&& ./Configure no-threads -DOPENSSL_DEV_NO_ATOMICS --prefix=/djgpp DJGPP \ && ./Configure no-threads -DOPENSSL_DEV_NO_ATOMICS --prefix=/djgpp DJGPP \
&& make && make install && make && make install

View File

@ -78,6 +78,7 @@ RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat && `
FROM mcr.microsoft.com/dotnet/framework/runtime:4.8.1 as output FROM mcr.microsoft.com/dotnet/framework/runtime:4.8.1 as output
COPY --from=Build32 C:\umskt\build\Release\umskt.exe C:\umskt\umskt.exe COPY --from=Build32 C:\umskt\build\Release\umskt.exe C:\umskt\umskt.exe
COPY --from=Build32 C:\umskt\build\Release\umskt_win32_dos.exe C:\umskt\umskt_win32_dos.exe
COPY --from=Build64 C:\umskt\build\Release\umskt.exe C:\umskt\umskt64.exe COPY --from=Build64 C:\umskt\build\Release\umskt.exe C:\umskt\umskt64.exe
#invoke via #invoke via

View File

@ -1,29 +1,17 @@
# Universal MS Key Toolkit (UMSKT) # **Universal MS Key Toolkit (UMSKT)**
**Connect with us**
[![Zulip chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://umskt.zulipchat.com) [![Zulip chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://umskt.zulipchat.com)
[![libera.chat - #mspid](https://img.shields.io/badge/libera.chat-%23mspid-brightgreen)](https://web.libera.chat/gamja/?nick=Guest?#mspid) [![libera.chat - #mspid](https://img.shields.io/badge/libera.chat-%23mspid-brightgreen)](https://web.libera.chat/gamja/?nick=Guest?#mspid)
[![C/C++ CI (Linux)](https://github.com/UMSKT/UMSKT/actions/workflows/linux.yml/badge.svg)](../../actions/workflows/linux.yml)
**Build status**
[![C/C++ CI (Windows)](https://github.com/UMSKT/UMSKT/actions/workflows/windows.yml/badge.svg)](../../actions/workflows/windows.yml) [![C/C++ CI (Windows)](https://github.com/UMSKT/UMSKT/actions/workflows/windows.yml/badge.svg)](../../actions/workflows/windows.yml)
[![C/C++ CI (macOS)](https://github.com/UMSKT/UMSKT/actions/workflows/macos.yml/badge.svg)](../../actions/workflows/macos.yml)
[![C/C++ CI (Linux)](https://github.com/UMSKT/UMSKT/actions/workflows/linux.yml/badge.svg)](../../actions/workflows/linux.yml) ### **Plan of Action / ToDo List**
[![C/C++ CI (FreeBSD)](https://github.com/UMSKT/UMSKT/actions/workflows/freebsd.yml/badge.svg)](../../actions/workflows/dos-djgpp.yml)
[![C/C++ CI (DOS DJGPP)](https://github.com/UMSKT/UMSKT/actions/workflows/dos-djgpp.yml/badge.svg)](../../actions/workflows/freebsd.yml)
------
### Plan of Action / ToDo List
In light of the recent exponential interest in this project I've decided to put updates of this project here: In light of the recent exponential interest in this project I've decided to put updates of this project here:
[Please see ticket #8 for more information](https://github.com/UMSKT/UMSKT/issues/8) * [Please see ticket #8 for more information](../../issues/8)
------ ------
@ -41,32 +29,27 @@ In light of the recent exponential interest in this project I've decided to put
* It all comes down to four simple steps: * It all comes down to four simple steps:
------
### **Usage** ### **Usage**
#### 1. Download the latest version of UMSKT #### 1. Download the latest version of WindowsXPKg
* *(GitHub account required)* * *(GitHub account required)*
* Download the latest experimental version using the Actions tab ([Windows](../../actions/workflows/windows.yml?query=branch%3Amaster+is%3Asuccess), [Linux](../../actions/workflows/linux.yml?query=branch%3Amaster+is%3Asuccess), [macOS](../../actions/workflows/macos.yml?query=branch%3Amaster+is%3Asuccess), [FreeBSD](../../actions/workflows/freebsd.yml?query=branch%3Amaster+is%3Asuccess), [DOS DJGPP](../../actions/workflows/dos-djgpp.yml?query=branch%3Amaster+is%3Asuccess)) * Download the latest experimental version using the Actions tab ([Windows](../../actions/workflows/windows.yml?query=branch%3Amaster), [Linux](../../actions/workflows/linux.yml?query=branch%3Amaster)).
* ~~*(GitHub account \*not\* required)*~~ * *(GitHub account \*not\* required)*
* ~~Download the latest release for your operating system and architecture from [the releases page](../../releases)~~ * Download the latest release for your operating system and architecture from [the releases page](../../releases)
* No official releases right now, use the other method to get the latest version.
* **Note:** Before continuing, please ensure you have the `umskt` executable extracted and on UNIX-like systems, have execution permissions (`chmod +x umskt`).
#### 2. Install OpenSSL 3.1.2. * **Note:** Before continuing, please ensure you have both the `xpkey` program and the `keys.json` datum extracted and in the same directory
For Windows, click [here](https://slproweb.com/products/Win32OpenSSL.html) and choose the right version. For other operating systems, consult your package manager.
*Note: This only applies if the build you download has OpenSSL embedded (static library) or not. You can usually tell if the download size is measured in KB or MB. If it's MB, you don't need this.*
#### 3. Run `umskt` to generate a key, or add `--help` or `-h` to see more options. #### 2. Run `xpkey` to generate a key, or add `--help` to see more options.
#### 4. *(Activation step for `Retail` and `OEM` only)* #### 3. *(Activation step for `Retail` and `OEM` only)*
* After installation, you will be prompted to activate Windows. * After installation, you will be prompted to activate Windows.
* Select the **telephone activation** method, then, run `umskt -i <Installation ID>` using the `Installation ID` the activation Wizard provides for you * Select the **telephone activation** method, then, run `xpkey -i <Installation ID>` using the `Installation ID` the activation Wizard provides for you
#### 4. Profit! #### 4. Profit!
@ -78,6 +61,7 @@ For Windows, click [here](https://slproweb.com/products/Win32OpenSSL.html) and c
The list of people who have helped to bring the XP generation to where it is now: The list of people who have helped to bring the XP generation to where it is now:
* z22 * z22
* MSKey * MSKey
* sk00ter
* diamondggg * diamondggg
* pottzman * pottzman
* Endermanch * Endermanch
@ -86,7 +70,6 @@ The list of people who have helped to bring the XP generation to where it is now
* TheTank20 * TheTank20
* InvoxiPlayGames * InvoxiPlayGames
* brakmic * brakmic
* techguy16
(the list will be updated to add more collaborators) (the list will be updated to add more collaborators)
@ -94,26 +77,20 @@ The list of people who have helped to bring the XP generation to where it is now
### **Development Requirements:** ### **Development Requirements:**
* `build-essential` * `CMake, make, gcc` (`build-essential`)
* `cmake`
* `make`
* `gcc`
* `g++`
* `git` * `git`
#### Build Steps: #### Build Steps:
1. `git clone https://github.com/UMSKT/UMSKT` 1. `git clone`
2. `cd UMSKT/build` 2. `cd build/ && cmake ../ && make`
3. `cmake ..`
4. `make`
----- -----
### **Known Ports** ### **Known Ports**
| Language | Author | Repo URL | | Language | Author | Repo URL |
|----------|-----------|-----------------------------------------------------------| |----------|-----------|-------------------------------------------------------|
| Rust | Alex Page | [anpage/umskt-rs](https://github.com/anpage/umskt-rs) | | Rust | Alex Page | [anpage/umskt-rs](https://github.com/anpage/umskt-rs) |
| Python | techguy16 | [techguy16/umsktpy](https://github.com/techguy16/umsktpy) |

View File

@ -45,9 +45,6 @@
"Office XP Applications": { "Office XP Applications": {
"BINK": ["20", "21"] "BINK": ["20", "21"]
}, },
"Works Suite 2003 and 2004": {
"BINK": ["20", "21"]
},
"Office XP": { "Office XP": {
"BINK": ["22", "23"] "BINK": ["22", "23"]
}, },
@ -120,9 +117,6 @@
"Office 2003 Small Business": { "Office 2003 Small Business": {
"BINK": ["70", "71"] "BINK": ["70", "71"]
}, },
"Office 2003 Student and Teacher": {
"BINK": ["70", "71"]
},
"Office 2003 Professional": { "Office 2003 Professional": {
"BINK": ["72", "73"] "BINK": ["72", "73"]
}, },
@ -1574,4 +1568,4 @@
"iid_key": "1513142771" "iid_key": "1513142771"
} }
} }
} }

View File

@ -57,7 +57,6 @@ void CLI::showHelp(char *argv[]) {
fmt::print("\t-l --list\tshow which products/binks can be loaded\n"); fmt::print("\t-l --list\tshow which products/binks can be loaded\n");
fmt::print("\t-c --channelid\tspecify which Channel Identifier to use (defaults to 640)\n"); fmt::print("\t-c --channelid\tspecify which Channel Identifier to use (defaults to 640)\n");
fmt::print("\t-s --serial\tspecifies a serial to use in the product ID (defaults to random, BINK1998 only)\n"); fmt::print("\t-s --serial\tspecifies a serial to use in the product ID (defaults to random, BINK1998 only)\n");
fmt::print("\t-u --upgrade\tspecifies the Product Key will be an \"Upgrade\" version\n");
fmt::print("\t-V --validate\tproduct key to validate signature\n"); fmt::print("\t-V --validate\tproduct key to validate signature\n");
fmt::print("\n"); fmt::print("\n");
} }
@ -72,7 +71,6 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
640, 640,
0, 0,
1, 1,
false,
false, false,
false, false,
false, false,
@ -139,8 +137,6 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
options->serial = serial_val; options->serial = serial_val;
} }
i++; i++;
} else if (arg == "-u" || arg == "--upgrade") {
options->upgrade = true;
} else if (arg == "-f" || arg == "--file") { } else if (arg == "-f" || arg == "--file") {
if (i == argc - 1) { if (i == argc - 1) {
options->error = true; options->error = true;
@ -220,12 +216,6 @@ int CLI::validateCommandLine(Options* options, char *argv[], json *keys) {
int intBinkID; int intBinkID;
sscanf(options->binkid.c_str(), "%x", &intBinkID); sscanf(options->binkid.c_str(), "%x", &intBinkID);
// FE and FF are BINK 1998, but do not generate valid keys, so we throw an error
if (intBinkID >= 0xFE) {
fmt::print("ERROR: Terminal Services BINKs (FE and FF) are unsupported at this time\n");
return 1;
}
if (intBinkID >= 0x40) { if (intBinkID >= 0x40) {
// set bink2002 validate mode if in bink1998 validate mode, else set bink2002 generate mode // set bink2002 validate mode if in bink1998 validate mode, else set bink2002 generate mode
options->applicationMode = (options->applicationMode == MODE_BINK1998_VALIDATE) ? MODE_BINK2002_VALIDATE : MODE_BINK2002_GENERATE; options->applicationMode = (options->applicationMode == MODE_BINK1998_VALIDATE) ? MODE_BINK2002_VALIDATE : MODE_BINK2002_GENERATE;
@ -251,7 +241,7 @@ void CLI::printID(DWORD *pid) {
int i, digit = 0; int i, digit = 0;
// Convert PID to ascii-number (=raw) // Convert PID to ascii-number (=raw)
snprintf(raw, sizeof(raw), "%09u", pid[0]); sprintf(raw, "%09u", pid[0]);
// Make b-part {640-....} // Make b-part {640-....}
strncpy(b, raw, 3); strncpy(b, raw, 3);
@ -391,8 +381,6 @@ int CLI::BINK1998Generate() {
// Specify whether an upgrade version or not // Specify whether an upgrade version or not
bool bUpgrade = false; bool bUpgrade = false;
if (options.upgrade == true)
bUpgrade = true;
for (int i = 0; i < this->total; i++) { for (int i = 0; i < this->total; i++) {
PIDGEN3::BINK1998::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, nRaw, bUpgrade, this->pKey); PIDGEN3::BINK1998::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, nRaw, bUpgrade, this->pKey);
@ -444,26 +432,23 @@ int CLI::BINK2002Generate() {
fmt::print("> AuthInfo: {}\n", pAuthInfo); fmt::print("> AuthInfo: {}\n", pAuthInfo);
} }
// Specify whether an upgrade version or not PIDGEN3::BINK2002::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, pChannelID, pAuthInfo, false, this->pKey);
bool bUpgrade = false; CLI::printKey(this->pKey);
if (options.upgrade == true) fmt::print("\n");
bUpgrade = true;
PIDGEN3::BINK2002::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, pChannelID, pAuthInfo, bUpgrade, this->pKey);
bool isValid = PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey); bool isValid = PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey);
if (isValid) { if (isValid) {
CLI::printKey(this->pKey); CLI::printKey(this->pKey);
if (i < this->total - 1 || this->options.verbose) { // check if end of list or verbose if (i < this->total - 1 || this->options.verbose) {
fmt::print("\n"); fmt::print("\n");
} }
this->count += isValid; // add to count this->count += isValid;
} }
else { else {
if (this->options.verbose) { if (this->options.verbose) {
CLI::printKey(this->pKey); // print the key CLI::printKey(this->pKey);
fmt::print(" [Invalid]"); // and add " [Invalid]" to the key fmt::print(" [Invalid]");
if (i < this->total - 1) { // check if end of list if (i < this->total - 1) {
fmt::print("\n"); fmt::print("\n");
} }
} }

View File

@ -52,7 +52,6 @@ struct Options {
int channelID; int channelID;
int serial; int serial;
int numKeys; int numKeys;
bool upgrade;
bool serialSet; bool serialSet;
bool verbose; bool verbose;
bool help; bool help;