Merge pull request #1225 from majestrate/macos-cpack-setup-and-bootstrap-2020-04-10

macos cpack installer infra
pull/1232/head
Jeff 4 years ago committed by GitHub
commit edc0d1a3ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5.1) # xenial's cmake version
cmake_minimum_required(VERSION 3.10) # bionic's cmake version
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
@ -6,15 +6,16 @@ if(CCACHE_PROGRAM)
endif()
set(PROJECT_NAME lokinet)
project(${PROJECT_NAME} C CXX)
project(${PROJECT_NAME}
VERSION 0.7.0
DESCRIPTION "lokinet - IP packet onion router"
LANGUAGES C CXX)
set(LLARP_VERSION_MAJOR 0)
set(LLARP_VERSION_MINOR 7)
set(LLARP_VERSION_PATCH 0)
set(RELEASE_MOTTO "I'll remember that..." CACHE STRING "Release motto")
add_definitions(-DLLARP_VERSION_MAJOR=${LLARP_VERSION_MAJOR})
add_definitions(-DLLARP_VERSION_MINOR=${LLARP_VERSION_MINOR})
add_definitions(-DLLARP_VERSION_PATCH=${LLARP_VERSION_PATCH})
add_definitions(-DLLARP_VERSION_MAJOR=${lokinet_VERSION_MAJOR})
add_definitions(-DLLARP_VERSION_MINOR=${lokinet_VERSION_MINOR})
add_definitions(-DLLARP_VERSION_PATCH=${lokinet_VERSION_PATCH})
# Core options
@ -39,6 +40,7 @@ option(WARNINGS_AS_ERRORS "treat all warnings as errors. turn off for developmen
option(TRACY_ROOT "include tracy profiler source" OFF)
option(WITH_TESTS "build unit tests" ON)
option(WITH_HIVE "build simulation stubs" OFF)
option(BUILD_PACKAGE "builds extra components for making an installer (with 'make package')" OFF)
if(WITH_HIVE)
set(WITH_SHARED ON)
@ -330,4 +332,6 @@ endif()
add_subdirectory(docs)
include(cmake/installer.cmake)
if(BUILD_PACKAGE)
include(cmake/installer.cmake)
endif()

@ -174,7 +174,7 @@ debug-configure:
release-configure: clean
mkdir -p '$(BUILD_ROOT)'
$(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)'
$(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)'
debug: debug-configure
$(MAKE) -C $(BUILD_ROOT)
@ -238,7 +238,7 @@ check: debug
test: check
static-configure: $(LIBUV_PREFIX) $(LIBCURL_PREFIX)
(test x$(TOOLCHAIN) = x && $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DSTATIC_LINK=ON -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DLIBCURL_ROOT='$(LIBCURL_PREFIX)' -DNATIVE_BUILD=OFF ) || (test x$(TOOLCHAIN) != x && $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DSTATIC_LINK=ON -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DLIBCURL_ROOT='$(LIBCURL_PREFIX)' -DCMAKE_TOOLCHAIN_FILE=$(TOOLCHAIN) -DNATIVE_BUILD=OFF )
(test x$(TOOLCHAIN) = x && $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DSTATIC_LINK=ON -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DLIBCURL_ROOT='$(LIBCURL_PREFIX)' -DNATIVE_BUILD=OFF ) || (test x$(TOOLCHAIN) != x && $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DSTATIC_LINK=ON -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DLIBCURL_ROOT='$(LIBCURL_PREFIX)' -DCMAKE_TOOLCHAIN_FILE=$(TOOLCHAIN) -DNATIVE_BUILD=OFF )
static: static-configure
$(MAKE) -C '$(BUILD_ROOT)'
@ -287,7 +287,7 @@ windows-debug: windows-debug-configure
windows-release-configure: $(LIBUV_PREFIX)
mkdir -p '$(BUILD_ROOT)'
$(CONFIG_CMD_WINDOWS) -DNATIVE_BUILD=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE='$(REPO)/contrib/cross/mingw$(WINDOWS_ARCH).cmake' -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DWITH_TESTS=OFF '$(REPO)'
$(CONFIG_CMD_WINDOWS) -DNATIVE_BUILD=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_PACKAGE=ON -DCMAKE_TOOLCHAIN_FILE='$(REPO)/contrib/cross/mingw$(WINDOWS_ARCH).cmake' -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DWITH_TESTS=OFF '$(REPO)'
windows-release: windows-release-configure
$(MAKE) -C '$(BUILD_ROOT)'
@ -297,7 +297,7 @@ windows: windows-release
mac-release-configure: $(LIBUV_PREFIX)
mkdir -p '$(BUILD_ROOT)'
$(CONFIG_CMD) -DNATIVE_BUILD=OFF -DCMAKE_BUILD_TYPE=Release -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DWITH_TESTS=OFF '$(REPO)'
$(CONFIG_CMD) -DNATIVE_BUILD=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_PACKAGE=ON -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DWITH_TESTS=OFF '$(REPO)'
mac-release: mac-release-configure
$(MAKE) -C '$(BUILD_ROOT)'
@ -359,7 +359,7 @@ docker-fedora:
debian-configure:
mkdir -p '$(BUILD_ROOT)'
$(CONFIG_CMD) -DDEBIAN=ON -DRELEASE_MOTTO="$(shell cat $(REPO)/motto.txt)" -DCMAKE_BUILD_TYPE=Release
$(CONFIG_CMD) -DDEBIAN=ON -DCMAKE_BUILD_TYPE=Release
debian: debian-configure
$(MAKE) -C '$(BUILD_ROOT)'

@ -18,11 +18,3 @@ get_filename_component(ABYSS_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/inclu
set(LIBTUNTAP_SRC
${TT_ROOT}/tuntap.cpp
${TT_ROOT}/tuntap_log.cpp)
set(LLARP_VERSION_MAJOR 0)
set(LLARP_VERSION_MINOR 7)
set(LLARP_VERSION_PATCH 0)
set(LLARP_VERSION "v${LLARP_VERSION_MAJOR}.${LLARP_VERSION_MINOR}.${LLARP_VERSION_PATCH}")
add_definitions(-DLLARP_VERSION_MAJ=${LLARP_VERSION_MAJOR})
add_definitions(-DLLARP_VERSION_MIN=${LLARP_VERSION_MINOR})
add_definitions(-DLLARP_VERSION_PATCH=${LLARP_VERSION_PATCH})

@ -1,12 +1,7 @@
set(CPACK_PACKAGE_NAME "lokinet")
set(CPACK_PACKAGE_VENDOR "lokinet.org")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://lokinet.org/")
set(CPACK_PACKAGE_DESCRIPTION "lokinet - IP packet onion router")
set(CPACK_PACKAGE_README_FILE "${CMAKE_SOURCE_DIR}/readme.md")
set(CPACK_PACKAGE_VERSION_MAJOR "${LLARP_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${LLARP_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${LLARP_VERSION_PATCH}")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/contrib/readme-installer.txt")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.txt")
if(WIN32)
include(cmake/win32_installer_deps.cmake)

@ -1,3 +1,90 @@
# macos specific cpack stuff goes here
# Here we build lokinet-network-control-panel into 'lokinet-gui.app' in "extra/" where a postinstall
# script will then move it to /Applications/.
set(LOKINET_GUI_REPO "https://github.com/loki-project/loki-network-control-panel.git"
CACHE STRING "Can be set to override the default lokinet-gui git repository")
set(LOKINET_GUI_CHECKOUT "origin/master"
CACHE STRING "Can be set to specify a particular branch or tag to build from LOKINET_GUI_REPO")
set(MACOS_SIGN_APP "" # FIXME: it doesn't use a Apple Distribution key because WTF knows.
CACHE STRING "enable codesigning of the stuff inside the .app and the lokinet binary -- use a 'Apple Distribution' key (or description) from `security find-identity -v`")
set(MACOS_SIGN_PKG ""
CACHE STRING "enable codesigning of the .pkg -- use a 'Developer ID Installer' key (or description) from `security find-identity -v`")
set(MACOS_NOTARIZE_USER ""
CACHE STRING "set macos notarization username; can also set it in ~/.notarization.cmake")
set(MACOS_NOTARIZE_PASS ""
CACHE STRING "set macos notarization password; can also set it in ~/.notarization.cmake")
set(MACOS_NOTARIZE_ASC ""
CACHE STRING "set macos notarization asc provider; can also set it in ~/.notarization.cmake")
include(ExternalProject)
message(STATUS "Building LokinetGUI.app from ${LOKINET_GUI_REPO} @ ${LOKINET_GUI_CHECKOUT}")
ExternalProject_Add(lokinet-gui
GIT_REPOSITORY "${LOKINET_GUI_REPO}"
GIT_TAG "${LOKINET_GUI_CHECKOUT}"
CMAKE_ARGS -DMACOS_APP=ON -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR} -DMACOS_SIGN=${MACOS_SIGN_APP}
-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}
)
install(FILES ${CMAKE_SOURCE_DIR}/contrib/macos/lokinet_uninstall.sh
DESTINATION "bin/"
COMPONENT lokinet)
install(DIRECTORY ${PROJECT_BINARY_DIR}/LokinetGUI.app
DESTINATION "../../Applications"
USE_SOURCE_PERMISSIONS
COMPONENT gui
PATTERN "*"
)
# copy files that will be later moved by the postinstall script to proper locations
install(FILES ${CMAKE_SOURCE_DIR}/contrib/macos/lokinet_macos_daemon_script.sh
${CMAKE_SOURCE_DIR}/contrib/macos/network.loki.lokinet.daemon.plist
DESTINATION "extra/"
COMPONENT lokinet)
set(CPACK_COMPONENTS_ALL lokinet gui)
set(CPACK_COMPONENT_LOKINET_DISPLAY_NAME "Lokinet Service")
set(CPACK_COMPONENT_LOKINET_DESCRIPTION "Main Lokinet runtime service, managed by Launchd")
set(CPACK_COMPONENT_GUI_DISPLAY_NAME "Lokinet GUI")
set(CPACK_COMPONENT_GUI_DESCRIPTION "Small GUI which provides stats and limited runtime control of the Lokinet service. Resides in the system tray.")
set(CPACK_GENERATOR "productbuild")
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local")
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/lokinet")
set(CPACK_POSTFLIGHT_LOKINET_SCRIPT ${CMAKE_SOURCE_DIR}/contrib/macos/postinstall)
# The GUI is GPLv3, and so the bundled core+GUI must be as well:
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/contrib/gpl-3.0.txt")
set(CPACK_PRODUCTBUILD_IDENTITY_NAME "${MACOS_SIGN_PKG}")
if(MACOS_SIGN_APP)
add_custom_target(sign ALL
echo "Signing lokinet and lokinetctl binaries"
COMMAND codesign -s "${MACOS_SIGN_APP}" --strict --options runtime --force -vvv $<TARGET_FILE:lokinet> $<TARGET_FILE:lokinetctl>
DEPENDS lokinet lokinetctl
)
endif()
if(MACOS_SIGN_APP AND MACOS_SIGN_PKG)
if(NOT MACOS_NOTARIZE_USER)
if(EXISTS "$ENV{HOME}/.notarization.cmake")
include("$ENV{HOME}/.notarization.cmake")
endif()
endif()
if(MACOS_NOTARIZE_USER AND MACOS_NOTARIZE_PASS AND MACOS_NOTARIZE_ASC)
message(STATUS "'notarization' target enabled")
configure_file(${CMAKE_SOURCE_DIR}/contrib/macos/notarize.py.in ${CMAKE_CURRENT_BINARY_DIR}/contrib/notarize.py ESCAPE_QUOTES @ONLY)
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/contrib/notarize.py DESTINATION ${PROJECT_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
add_custom_target(notarize ./notarize.py)
else()
message(WARNING "Not enable 'notarization' target: signing is enabled but notarization info not provided. Create ~/.notarization.cmake or set cmake parameters directly")
endif()
endif()

@ -0,0 +1,683 @@
LokiNET is the reference implementation of LLARP (Low Latency Anonymous
Routing Protocol); this distribution of LokiNET and the Lokinet control
panel is licensed under the GNU General Public License, version 3.
Copyright (c) 2018-2020 The Loki Project
Copyright (c) 2018-2020 Jeff Becker
Windows NT port and portions Copyright (c) 2018-2020 Rick V.
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

@ -0,0 +1,32 @@
#!/bin/sh
scutil_query()
{
key=$1
scutil<<EOT
open
get $key
d.show
close
EOT
}
SERVICE_GUID=`scutil_query State:/Network/Global/IPv4 \
| grep "PrimaryService" \
| awk '{print $3}'`
SERVICE_NAME=`scutil_query Setup:/Network/Service/$SERVICE_GUID \
| grep "UserDefinedName" \
| awk -F': ' '{print $2}'`
OLD_SERVERS="$(networksetup -getdnsservers "$SERVICE_NAME" \
| tr '\n' ' ' \
| sed 's/ $//')"
networksetup -setdnsservers "$SERVICE_NAME" 127.0.0.1
/opt/lokinet/bin/lokinet /var/lib/lokinet/lokinet.ini
networksetup -setdnsservers "$SERVICE_NAME" $OLD_SERVERS

@ -0,0 +1,12 @@
#!/bin/sh
launchctl stop network.loki.lokinet.daemon
launchctl unload /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
killall lokinet
rm -rf /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
rm -rf /Applications/LokinetGUI.app
rm -rf /var/lib/lokinet
rm -rf /usr/local/lokinet/
rm -rf /opt/lokinet

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>network.loki.lokinet.daemon</string>
<key>ProgramArguments</key>
<array>
<string>/var/lib/lokinet/lokinet_macos_daemon_script.sh</string>
</array>
<!-- Keep Lokinet alive unless magic file exists -->
<key>KeepAlive</key>
<dict>
<key>PathState</key>
<dict>
<key>/var/lib/lokinet/suspend-launchd-service</key>
<false/>
</dict>
</dict>
<key>StandardOutPath</key>
<string>/var/lib/lokinet/stdout</string>
<key>StandardErrorPath</key>
<string>/var/lib/lokinet/stderr</string>
</dict>
</plist>

@ -0,0 +1,70 @@
#!/usr/bin/env python3
import sys
import plistlib
import subprocess
import time
pkg = "lokinet-@PROJECT_VERSION@-Darwin.pkg"
userpass = ('--username', "@MACOS_NOTARIZE_USER@", '--password', "@MACOS_NOTARIZE_PASS@")
print("Submitting {} for notarization; this may take a minute...".format(pkg))
started = time.time()
result = subprocess.run([
'xcrun', 'altool',
'--notarize-app',
'--primary-bundle-id', 'org.lokinet.lokinet.pkg.@PROJECT_VERSION@',
*userpass,
'--asc-provider', "@MACOS_NOTARIZE_ASC@",
'--file', pkg,
'--output-format', 'xml'
], stdout=subprocess.PIPE)
data = plistlib.loads(result.stdout)
if 'success-message' not in data or 'notarization-upload' not in data or 'RequestUUID' not in data['notarization-upload']:
print("Something failed, leaving you with this nice XML to figure out:\n{}".format(data))
sys.exit(1)
uuid = data['notarization-upload']['RequestUUID']
elapsed = time.time() - started
mins, secs = int(elapsed // 60), elapsed % 60
print("Notarization submitted with request uuid = {} in {:d}m{:05.2f}s".format(uuid, mins, secs))
print(data['success-message'])
print("Begin polling for notarization result")
started_waiting = time.time()
done = False
success = False
while not done:
time.sleep(5)
result = subprocess.run([
'xcrun', 'altool',
'--notarization-info', uuid,
*userpass,
'--output-format', 'xml'
], stdout=subprocess.PIPE)
result.check_returncode()
data = plistlib.loads(result.stdout)
if 'notarization-info' not in data or 'Status' not in data['notarization-info']:
status = 'Request failed'
else:
status = data['notarization-info']['Status Message'] if 'Status Message' in data['notarization-info'] else ''
st = data['notarization-info']['Status']
if st == 'success':
success = True
done = True
elif st == 'invalid':
done = True
elif st == 'in progress' and len(status) == 0:
status = 'Notarization in progress'
if done and 'LogFileURL' in data['notarization-info']:
status += '\n\nlog file: {}'.format(data['notarization-info']['LogFileURL'])
elapsed = time.time() - started_waiting
mins, secs = int(elapsed // 60), int(elapsed % 60)
print("\033[1K\r(+{:d}m{:02d}s) {}: {}".format(mins, secs, st, status), end='', flush=True)
print("\n")
sys.exit(0 if success else 42)

@ -0,0 +1,34 @@
#!/bin/sh
PERMS_OWNER=root
PERMS_GROUP=admin
CHOWN=$PERMS_OWNER:$PERMS_GROUP
# set up lokinet data dir
[ -e /var/lib/lokinet/ ] || mkdir /var/lib/lokinet
chown $CHOWN /var/lib/lokinet
chmod g+w /var/lib/lokinet
# mv files copied into $INSTALL_PREFIX/extra/ to their proper locations
mv /opt/lokinet/extra/lokinet_macos_daemon_script.sh /var/lib/lokinet
chown $CHOWN /var/lib/lokinet/lokinet_macos_daemon_script.sh
chmod 770 /var/lib/lokinet/lokinet_macos_daemon_script.sh
mv /opt/lokinet/extra/network.loki.lokinet.daemon.plist /Library/LaunchDaemons/
chown $CHOWN /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
chmod 640 /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
# clean up by removing 'extra/' (so long as it's empty)
rmdir /opt/lokinet/extra/
# bootstrap
/opt/lokinet/bin/lokinet-bootstrap mainnet /var/lib/lokinet/bootstrap.signed
chown $CHOWN /var/lib/lokinet/bootstrap.signed
# generate configs
/opt/lokinet/bin/lokinet -g /var/lib/lokinet/lokinet.ini
chown $CHOWN /var/lib/lokinet/lokinet.ini
# register with launchd and start
launchctl load /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
launchctl start network.loki.lokinet.daemon

@ -0,0 +1,5 @@
Lokinet is the reference implementation of LLARP (low latency anonymous routing protocol), a layer 3 onion routing protocol.
This installer provides the needed control panel to get up an running on Lokinet.
You can view additional documentation and information on Lokinet at https://lokinet.org

@ -24,8 +24,8 @@ add_custom_command(
OUTPUT html/index.html
COMMAND ${SPHINX_BUILD}
-Dbreathe_projects.lokinet=${CMAKE_CURRENT_BINARY_DIR}/doxyxml
-Dversion=${LLARP_VERSION} -Drelease=${LLARP_VERSION}
-Aversion=${LLARP_VERSION} -Aversions=${LLARP_VERSION_MAJOR},${LLARP_VERSION_MINOR},${LLARP_VERSION_PATCH}
-Dversion=${lokinet_VERSION} -Drelease=${lokinet_VERSION}
-Aversion=${lokinet_VERSION} -Aversions=${lokinet_VERSION_MAJOR},${lokinet_VERSION_MINOR},${lokinet_VERSION_PATCH}
-b html
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/html
DEPENDS

@ -1,5 +1,5 @@
PROJECT_NAME = "Lokinet"
PROJECT_NUMBER = v@LLARP_VERSION@
PROJECT_NUMBER = v@lokinet_VERSION@
PROJECT_BRIEF = "Anonymous, decentralized and IP based overlay network for the internet."
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@
STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@ @PROJECT_BINARY_DIR@

@ -0,0 +1,73 @@
Codesigning and notarization on macOS
This is painful. Thankfully most of the pain is now in CMake and a python script.
To build, codesign, and notarized and installer package, CMake needs to be invoked with:
cd build
rm -rf * # optional but recommended
cmake .. -DBUILD_PACKAGE=ON -DDOWNLOAD_SODIUM=ON -DMACOS_SIGN_APP=ABC123... -DMACOS_SIGN_PKG=DEF456...
where the ABC123... key is a "Developer ID Installer" key and PKG key is a "Developer ID
Application" key. You have to go through a bunch of pain, pay Apple money, and then read a bunch of
poorly written documentation that doesn't help very much to create these and get them working. But once you have them
set up in Keychain, you should be able to list your keys with:
security find-identity -v
and you should see (at least) one "Developer ID Installer: ..." and one "Developer ID Application:
...". You need both for reasons that only Apple knows. The former is used to sign the installer
.pkg, and the latter is used to sign everything *inside* the .pkg, and you can't use the same key
for both because Apple designed code signing by marketing committee rather than ask any actual
competent software developers how code signing should work.
Either way, these two values can be specified either by hex value or description string that
`security find-identity -v` spits out.
You also need to set up the notarization parameters; these can either be specified directly on the
cmake command line by adding:
-DMACOS_NOTARIZE_ASC=XYZ123 -DMACOS_NOTARIZE_USER=me@example.com -DMACOS_NOTARIZE_PASS=@keychain:codesigning-password
or, more simply, by putting them inside a `~/.notarization.cmake` file that will be included if it
exists (and the MACOS_SIGN_* variables are set) -- see below.
These three values here are:
MACOS_NOTARIZE_ASC:
Organization-specific unique value; this is printed inside (brackets) when you run: `security
find-identity -v`:
1) 1C75DDBF884DEF3D5927C3F29BB7FC5ADAE2E1B3 "Apple Development: me@example.com (ABC123XYZ9)"
MACOS_NOTARIZE_USER:
Your Apple Developer login.
MACOS_NOTARIZE_PASS:
This should be an app-specific password created for signing on the Apple Developer website. You
*can* specify it directly, but it is much better to use the magic `@keychain:blah` value, where
'blah' is a password name recorded in Keychain. To get that in place you run:
export HISTFILE='' # for bash: you don't want to store this in your history
xcrun altool --store-password-in-keychain-item "NOTARIZE_PASSWORD" -u "user" -p "password"
where NOTARIZE_PASSWORD is just some name for the password (I called it 'blah' or
'codesigning-password' above), and the "user" and "password" are replaced with your actual Apple
Developer account device-specific login credentials.
Optionally, put these last three inside a `~/.notarization.cmake` file:
set(MACOS_NOTARIZE_USER "jagerman@jagerman.com")
set(MACOS_NOTARIZE_PASS "@keychain:codesigning-password")
set(MACOS_NOTARIZE_ASC "SUQ8J2PCT7")
Then, finally, you can build the package from the build directory with:
make package -j4 # or whatever -j makes you happy
make notarize
The former builds and signs the package, the latter submits it for notarization. This can take a
few minutes; the script polls Apple's server until it is finished passing or failing notarization.

@ -15,8 +15,8 @@
namespace llarp
{
// clang-format off
const std::array<uint16_t, 3> VERSION{{LLARP_VERSION_MAJ, LLARP_VERSION_MIN, LLARP_VERSION_PATCH}};
const std::array<uint64_t, 4> ROUTER_VERSION{{LLARP_PROTO_VERSION, LLARP_VERSION_MAJ, LLARP_VERSION_MIN, LLARP_VERSION_PATCH}};
const std::array<uint16_t, 3> VERSION{{LLARP_VERSION_MAJOR, LLARP_VERSION_MINOR, LLARP_VERSION_PATCH}};
const std::array<uint64_t, 4> ROUTER_VERSION{{LLARP_PROTO_VERSION, LLARP_VERSION_MAJOR, LLARP_VERSION_MINOR, LLARP_VERSION_PATCH}};
const char* const VERSION_STR = LLARP_VERSION_STR;
const char* const VERSION_TAG = "@VERSIONTAG@";
const char* const VERSION_FULL = LLARP_NAME "-" LLARP_VERSION_STR "-@VERSIONTAG@";

@ -1 +0,0 @@
I'll remember that...

@ -1,60 +0,0 @@
cmake_minimum_required(VERSION 3.14)
set(PROJECT_NAME lokinet)
project(${PROJECT_NAME} C CXX Swift)
get_filename_component(LOKINET_ROOT .. ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
include("${LOKINET_ROOT}/cmake/target_link_libraries_system.cmake")
include("${LOKINET_ROOT}/cmake/add_import_library.cmake")
include("${LOKINET_ROOT}/cmake/add_log_tag.cmake")
include("${LOKINET_ROOT}/cmake/libatomic.cmake")
if (STATIC_LINK AND STATIC_LINK_RUNTIME)
message(FATAL "Cannot set both STATIC_LINK and STATIC_LINK_RUNTIME")
endif()
set(CMAKE_Swift_LANGUAGE_VERSION 5.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
list(APPEND CMAKE_MODULE_PATH "${LOKINET_ROOT}/cmake")
include(FetchContent)
FetchContent_Declare(
libuv
GIT_REPOSITORY https://github.com/libuv/libuv.git
GIT_TAG v1.32.0
)
FetchContent_Populate(libuv)
add_subdirectory(${libuv_SOURCE_DIR} ${libuv_BINARY_DIR})
include("${LOKINET_ROOT}/cmake/basic_definitions.cmake")
set(LIBUV_IN_SOURCE ON)
set(LIBUV_LIBRARY uv_a)
include("${LOKINET_ROOT}/cmake/unix.cmake")
unset(LIBTUNTAP_SRC)
find_package(Threads REQUIRED)
set(ABSEIL_DIR "${LOKINET_ROOT}/vendor/abseil-cpp")
macro(add_loki_dir name)
add_subdirectory("${LOKINET_ROOT}/${name}" "${name}")
endmacro()
include_directories(SYSTEM ${ABSEIL_DIR})
add_loki_dir(vendor/cxxopts)
add_loki_dir(vendor/nlohmann)
include_directories(SYSTEM "${LOKINET_ROOT}/vendor/cxxopts/include")
include_directories("${LOKINET_ROOT}/include")
include_directories("${libuv_SOURCE_DIR}/include")
add_loki_dir(vendor/gtest)
add_subdirectory(${ABSEIL_DIR} "vendor/abseil-cpp")
add_loki_dir(crypto)
add_loki_dir(llarp)
add_loki_dir(libabyss)
add_subdirectory(lokinet)

@ -1,4 +0,0 @@
set(CMAKE_MACOSX_BUNDLE YES)
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED NO)
set(CMAKE_OSX_SYSROOT iphoneos)
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")

@ -1,92 +0,0 @@
//
// AppDelegate.swift
// lokinet
//
// Copyright © 2019 Loki. All rights reserved.
//
import UIKit
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
self.saveContext()
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "lokinet")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}

@ -1,98 +0,0 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

@ -1 +0,0 @@
add_executable(lokinet AppDelegate.swift ViewController.swift)

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

@ -1,19 +0,0 @@
//
// ViewController.swift
// lokinet
//
// Copyright © 2019 Loki. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>dns-proxy</string>
<string>packet-tunnel-provider</string>
</array>
<key>com.apple.developer.networking.vpn.api</key>
<array>
<string>allow-vpn</string>
</array>
</dict>
</plist>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>lokinet.xcdatamodel</string>
</dict>
</plist>

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<elements/>
</model>

@ -1,29 +0,0 @@
//
// WindowsManager.swift
// lokinet
//
// Copyright © 2019 Loki. All rights reserved.
//
import AppKit
import Foundation
struct WindowsManager {
static func getVC<T: NSViewController>(withIdentifier identifier: String,
ofType: T.Type?,
storyboard: String = "Main",
bundle: Bundle? = nil) -> T? {
let storyboard = NSStoryboard(name: storyboard, bundle: bundle)
guard let vc: T = storyboard.instantiateController(withIdentifier: identifier) as? T else {
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = "Error initiating the viewcontroller"
alert.runModal()
return nil
}
return vc
}
}

@ -1,641 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objects = {
/* Begin PBXBuildFile section */
7B28BD1A232EA8B40073B955 /* DNSManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B28BD19232EA8B40073B955 /* DNSManager.swift */; };
7B28BD1C232EB6EF0073B955 /* LokinetRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B28BD1B232EB6EF0073B955 /* LokinetRunner.swift */; };
7BA4FB642340D5940098E20A /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA4FB632340D5940098E20A /* Preferences.swift */; };
7BA4FB662340DA820098E20A /* StatusMenuExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA4FB652340DA820098E20A /* StatusMenuExt.swift */; };
7BA4FB6C2340F2270098E20A /* WindowsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA4FB6B2340F2270098E20A /* WindowsManager.swift */; };
7BA4FB7023411FF60098E20A /* PrefsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA4FB6E23411FF60098E20A /* PrefsViewController.swift */; };
7BA4FB7323412D700098E20A /* Interfaces.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA4FB7223412D700098E20A /* Interfaces.swift */; };
7BED5B7A232D78D900DF603F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BED5B79232D78D900DF603F /* AppDelegate.swift */; };
7BED5B7E232D78DB00DF603F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7BED5B7D232D78DB00DF603F /* Assets.xcassets */; };
7BED5B81232D78DB00DF603F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7BED5B7F232D78DB00DF603F /* Main.storyboard */; };
7BED5B8D232D78DB00DF603F /* lokinetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BED5B8C232D78DB00DF603F /* lokinetTests.swift */; };
7BED5B98232D78DB00DF603F /* lokinetUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BED5B97232D78DB00DF603F /* lokinetUITests.swift */; };
7BED5BA6232E7E6600DF603F /* LokinetLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BED5BA5232E7E6600DF603F /* LokinetLog.swift */; };
7BED5BA8232E831B00DF603F /* StreamReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BED5BA7232E831B00DF603F /* StreamReader.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
7BED5B89232D78DB00DF603F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7BED5B6E232D78D900DF603F /* Project object */;
proxyType = 1;
remoteGlobalIDString = 7BED5B75232D78D900DF603F;
remoteInfo = lokinet;
};
7BED5B94232D78DB00DF603F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7BED5B6E232D78D900DF603F /* Project object */;
proxyType = 1;
remoteGlobalIDString = 7BED5B75232D78D900DF603F;
remoteInfo = lokinet;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
7B28BD19232EA8B40073B955 /* DNSManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSManager.swift; sourceTree = "<group>"; };
7B28BD1B232EB6EF0073B955 /* LokinetRunner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokinetRunner.swift; sourceTree = "<group>"; };
7BA4FB632340D5940098E20A /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
7BA4FB652340DA820098E20A /* StatusMenuExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusMenuExt.swift; sourceTree = "<group>"; };
7BA4FB6B2340F2270098E20A /* WindowsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowsManager.swift; sourceTree = "<group>"; };
7BA4FB6E23411FF60098E20A /* PrefsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefsViewController.swift; sourceTree = "<group>"; };
7BA4FB7223412D700098E20A /* Interfaces.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Interfaces.swift; sourceTree = "<group>"; };
7BED5B76232D78D900DF603F /* lokinet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = lokinet.app; sourceTree = BUILT_PRODUCTS_DIR; };
7BED5B79232D78D900DF603F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7BED5B7D232D78DB00DF603F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
7BED5B80232D78DB00DF603F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
7BED5B82232D78DB00DF603F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7BED5B83232D78DB00DF603F /* lokinet.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = lokinet.entitlements; sourceTree = "<group>"; };
7BED5B88232D78DB00DF603F /* lokinetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = lokinetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7BED5B8C232D78DB00DF603F /* lokinetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lokinetTests.swift; sourceTree = "<group>"; };
7BED5B8E232D78DB00DF603F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7BED5B93232D78DB00DF603F /* lokinetUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = lokinetUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7BED5B97232D78DB00DF603F /* lokinetUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lokinetUITests.swift; sourceTree = "<group>"; };
7BED5B99232D78DB00DF603F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7BED5BA5232E7E6600DF603F /* LokinetLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokinetLog.swift; sourceTree = "<group>"; };
7BED5BA7232E831B00DF603F /* StreamReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamReader.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7BED5B73232D78D900DF603F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
7BED5B85232D78DB00DF603F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
7BED5B90232D78DB00DF603F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
7BED5B6D232D78D900DF603F = {
isa = PBXGroup;
children = (
7BA4FB6B2340F2270098E20A /* WindowsManager.swift */,
7BED5B78232D78D900DF603F /* lokinet */,
7BED5B8B232D78DB00DF603F /* lokinetTests */,
7BED5B96232D78DB00DF603F /* lokinetUITests */,
7BED5B77232D78D900DF603F /* Products */,
7BED5BA9232E993E00DF603F /* Frameworks */,
);
sourceTree = "<group>";
};
7BED5B77232D78D900DF603F /* Products */ = {
isa = PBXGroup;
children = (
7BED5B76232D78D900DF603F /* lokinet.app */,
7BED5B88232D78DB00DF603F /* lokinetTests.xctest */,
7BED5B93232D78DB00DF603F /* lokinetUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
7BED5B78232D78D900DF603F /* lokinet */ = {
isa = PBXGroup;
children = (
7BED5B79232D78D900DF603F /* AppDelegate.swift */,
7BA4FB652340DA820098E20A /* StatusMenuExt.swift */,
7BA4FB632340D5940098E20A /* Preferences.swift */,
7BA4FB6E23411FF60098E20A /* PrefsViewController.swift */,
7BED5B7D232D78DB00DF603F /* Assets.xcassets */,
7BED5B7F232D78DB00DF603F /* Main.storyboard */,
7BED5B82232D78DB00DF603F /* Info.plist */,
7BED5B83232D78DB00DF603F /* lokinet.entitlements */,
7BED5BA5232E7E6600DF603F /* LokinetLog.swift */,
7B28BD19232EA8B40073B955 /* DNSManager.swift */,
7BED5BA7232E831B00DF603F /* StreamReader.swift */,
7B28BD1B232EB6EF0073B955 /* LokinetRunner.swift */,
7BA4FB7223412D700098E20A /* Interfaces.swift */,
);
path = lokinet;
sourceTree = "<group>";
};
7BED5B8B232D78DB00DF603F /* lokinetTests */ = {
isa = PBXGroup;
children = (
7BED5B8C232D78DB00DF603F /* lokinetTests.swift */,
7BED5B8E232D78DB00DF603F /* Info.plist */,
);
path = lokinetTests;
sourceTree = "<group>";
};
7BED5B96232D78DB00DF603F /* lokinetUITests */ = {
isa = PBXGroup;
children = (
7BED5B97232D78DB00DF603F /* lokinetUITests.swift */,
7BED5B99232D78DB00DF603F /* Info.plist */,
);
path = lokinetUITests;
sourceTree = "<group>";
};
7BED5BA9232E993E00DF603F /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7BED5B75232D78D900DF603F /* lokinet */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7BED5B9C232D78DB00DF603F /* Build configuration list for PBXNativeTarget "lokinet" */;
buildPhases = (
7BED5B72232D78D900DF603F /* Sources */,
7BED5B73232D78D900DF603F /* Frameworks */,
7BED5B74232D78D900DF603F /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = lokinet;
productName = lokinet;
productReference = 7BED5B76232D78D900DF603F /* lokinet.app */;
productType = "com.apple.product-type.application";
};
7BED5B87232D78DB00DF603F /* lokinetTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7BED5B9F232D78DB00DF603F /* Build configuration list for PBXNativeTarget "lokinetTests" */;
buildPhases = (
7BED5B84232D78DB00DF603F /* Sources */,
7BED5B85232D78DB00DF603F /* Frameworks */,
7BED5B86232D78DB00DF603F /* Resources */,
);
buildRules = (
);
dependencies = (
7BED5B8A232D78DB00DF603F /* PBXTargetDependency */,
);
name = lokinetTests;
productName = lokinetTests;
productReference = 7BED5B88232D78DB00DF603F /* lokinetTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
7BED5B92232D78DB00DF603F /* lokinetUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7BED5BA2232D78DB00DF603F /* Build configuration list for PBXNativeTarget "lokinetUITests" */;
buildPhases = (
7BED5B8F232D78DB00DF603F /* Sources */,
7BED5B90232D78DB00DF603F /* Frameworks */,
7BED5B91232D78DB00DF603F /* Resources */,
);
buildRules = (
);
dependencies = (
7BED5B95232D78DB00DF603F /* PBXTargetDependency */,
);
name = lokinetUITests;
productName = lokinetUITests;
productReference = 7BED5B93232D78DB00DF603F /* lokinetUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
7BED5B6E232D78D900DF603F /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1020;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = Loki;
TargetAttributes = {
7BED5B75232D78D900DF603F = {
CreatedOnToolsVersion = 10.2.1;
SystemCapabilities = {
com.apple.ApplicationGroups.Mac = {
enabled = 0;
};
com.apple.NetworkExtensions = {
enabled = 0;
};
com.apple.Sandbox = {
enabled = 0;
};
};
};
7BED5B87232D78DB00DF603F = {
CreatedOnToolsVersion = 10.2.1;
TestTargetID = 7BED5B75232D78D900DF603F;
};
7BED5B92232D78DB00DF603F = {
CreatedOnToolsVersion = 10.2.1;
TestTargetID = 7BED5B75232D78D900DF603F;
};
};
};
buildConfigurationList = 7BED5B71232D78D900DF603F /* Build configuration list for PBXProject "lokinet" */;
compatibilityVersion = "Xcode 10.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 7BED5B6D232D78D900DF603F;
productRefGroup = 7BED5B77232D78D900DF603F /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
7BED5B75232D78D900DF603F /* lokinet */,
7BED5B87232D78DB00DF603F /* lokinetTests */,
7BED5B92232D78DB00DF603F /* lokinetUITests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
7BED5B74232D78D900DF603F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7BED5B7E232D78DB00DF603F /* Assets.xcassets in Resources */,
7BED5B81232D78DB00DF603F /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
7BED5B86232D78DB00DF603F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
7BED5B91232D78DB00DF603F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7BED5B72232D78D900DF603F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7BED5BA8232E831B00DF603F /* StreamReader.swift in Sources */,
7BA4FB7023411FF60098E20A /* PrefsViewController.swift in Sources */,
7BED5BA6232E7E6600DF603F /* LokinetLog.swift in Sources */,
7BA4FB662340DA820098E20A /* StatusMenuExt.swift in Sources */,
7B28BD1A232EA8B40073B955 /* DNSManager.swift in Sources */,
7B28BD1C232EB6EF0073B955 /* LokinetRunner.swift in Sources */,
7BA4FB6C2340F2270098E20A /* WindowsManager.swift in Sources */,
7BA4FB7323412D700098E20A /* Interfaces.swift in Sources */,
7BA4FB642340D5940098E20A /* Preferences.swift in Sources */,
7BED5B7A232D78D900DF603F /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
7BED5B84232D78DB00DF603F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7BED5B8D232D78DB00DF603F /* lokinetTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
7BED5B8F232D78DB00DF603F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7BED5B98232D78DB00DF603F /* lokinetUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
7BED5B8A232D78DB00DF603F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 7BED5B75232D78D900DF603F /* lokinet */;
targetProxy = 7BED5B89232D78DB00DF603F /* PBXContainerItemProxy */;
};
7BED5B95232D78DB00DF603F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 7BED5B75232D78D900DF603F /* lokinet */;
targetProxy = 7BED5B94232D78DB00DF603F /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
7BED5B7F232D78DB00DF603F /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
7BED5B80232D78DB00DF603F /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
7BED5B9A232D78DB00DF603F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 23TKR8Q2XE;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
7BED5B9B232D78DB00DF603F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 23TKR8Q2XE;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
7BED5B9D232D78DB00DF603F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = lokinet/lokinet.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 23TKR8Q2XE;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = lokinet/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
PRODUCT_BUNDLE_IDENTIFIER = loki.lokinet;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
7BED5B9E232D78DB00DF603F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = lokinet/lokinet.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 23TKR8Q2XE;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = lokinet/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
PRODUCT_BUNDLE_IDENTIFIER = loki.lokinet;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Release;
};
7BED5BA0232D78DB00DF603F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = lokinetTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = loki.lokinetTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/lokinet.app/Contents/MacOS/lokinet";
};
name = Debug;
};
7BED5BA1232D78DB00DF603F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = lokinetTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = loki.lokinetTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/lokinet.app/Contents/MacOS/lokinet";
};
name = Release;
};
7BED5BA3232D78DB00DF603F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = lokinetUITests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = loki.lokinetUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_TARGET_NAME = lokinet;
};
name = Debug;
};
7BED5BA4232D78DB00DF603F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = lokinetUITests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = loki.lokinetUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_TARGET_NAME = lokinet;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7BED5B71232D78D900DF603F /* Build configuration list for PBXProject "lokinet" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7BED5B9A232D78DB00DF603F /* Debug */,
7BED5B9B232D78DB00DF603F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7BED5B9C232D78DB00DF603F /* Build configuration list for PBXNativeTarget "lokinet" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7BED5B9D232D78DB00DF603F /* Debug */,
7BED5B9E232D78DB00DF603F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7BED5B9F232D78DB00DF603F /* Build configuration list for PBXNativeTarget "lokinetTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7BED5BA0232D78DB00DF603F /* Debug */,
7BED5BA1232D78DB00DF603F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7BED5BA2232D78DB00DF603F /* Build configuration list for PBXNativeTarget "lokinetUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7BED5BA3232D78DB00DF603F /* Debug */,
7BED5BA4232D78DB00DF603F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 7BED5B6E232D78D900DF603F /* Project object */;
}

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

@ -1,112 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7BED5B75232D78D900DF603F"
BuildableName = "lokinet.app"
BlueprintName = "lokinet"
ReferencedContainer = "container:lokinet.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7BED5B87232D78DB00DF603F"
BuildableName = "lokinetTests.xctest"
BlueprintName = "lokinetTests"
ReferencedContainer = "container:lokinet.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7BED5B92232D78DB00DF603F"
BuildableName = "lokinetUITests.xctest"
BlueprintName = "lokinetUITests"
ReferencedContainer = "container:lokinet.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7BED5B75232D78D900DF603F"
BuildableName = "lokinet.app"
BlueprintName = "lokinet"
ReferencedContainer = "container:lokinet.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
debugAsWhichUser = "root"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7BED5B75232D78D900DF603F"
BuildableName = "lokinet.app"
BlueprintName = "lokinet"
ReferencedContainer = "container:lokinet.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7BED5B75232D78D900DF603F"
BuildableName = "lokinet.app"
BlueprintName = "lokinet"
ReferencedContainer = "container:lokinet.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -1,155 +0,0 @@
//
// AppDelegate.swift
// lokinet
//
// Copyright © 2019 Loki. All rights reserved.
//
import Cocoa
let LOG_WINDOW_CONTROLLER: NSWindowController = NSWindowController(window: nil)
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var lokinet: LokinetRunner? = nil
var appender: Appendable? = nil
var statusBarItem: NSStatusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
func applicationWillFinishLaunching(_ notification: Notification) {
if (!Preferences.firstRunDone) {
Preferences.firstRunDone = true
Preferences.restore()
}
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
guard let statusButton = statusBarItem.button else { return }
statusButton.title = "LokiNet"
let statusMenu: NSMenu = NSMenu()
statusMenu.autoenablesItems = false
statusMenu.addItem(withTitle: "LokiNet", action: nil, keyEquivalent: "")
let runItem: NSMenuItem = {
let item = NSMenuItem(
title: "Run",
action: #selector(runLokinet),
keyEquivalent: "r"
)
item.target = self
return item
}()
let stopItem: NSMenuItem = {
let item = NSMenuItem(
title: "Stop",
action: #selector(stopLokinet),
keyEquivalent: "s"
)
item.isEnabled = false
item.target = self
return item
}()
let showWindowItem: NSMenuItem = {
let item = NSMenuItem(
title: "Show Window",
action: #selector(showWindow),
keyEquivalent: "w"
)
item.target = self
return item
}()
let quitApplicationItem: NSMenuItem = {
let item = NSMenuItem(
title: "Quit",
action: #selector(terminate),
keyEquivalent: "q")
item.target = self
return item
}()
statusMenu.addItems(
.separator(),
runItem,
stopItem,
.separator(),
showWindowItem,
.separator(),
quitApplicationItem
)
statusBarItem.menu = statusMenu
}
func applicationWillTerminate(_ aNotification: Notification) {
lokinet?.stop()
}
}
extension AppDelegate {
@objc
func showWindow(sender: NSMenuItem) {
if let vc = WindowsManager.getVC(withIdentifier: "LokinetLogController", ofType: LokinetLogController.self) {
appender = vc.log
let window: NSWindow = {
let w = NSWindow(contentViewController: vc)
w.styleMask.remove(.fullScreen)
w.styleMask.remove(.resizable)
w.styleMask.remove(.miniaturizable)
w.level = .floating
return w
}()
lokinet?.logAppender = vc.log
if LOG_WINDOW_CONTROLLER.window == nil {
LOG_WINDOW_CONTROLLER.window = window
}
LOG_WINDOW_CONTROLLER.showWindow(window)
}
}
@objc
func runLokinet(sender: NSMenuItem) {
if lokinet == nil {
lokinet = LokinetRunner(interface: Preferences.interfaceName, path: Preferences.lokinetPath)
lokinet?.logAppender = appender
lokinet?.start()
}
sender.isEnabled = false;
if let menu = statusBarItem.menu, let stop = menu.item(withTitle: "Stop") {
stop.isEnabled = true
}
}
@objc
func stopLokinet(_ sender: NSMenuItem) {
lokinet?.stop()
lokinet = nil
sender.isEnabled = false;
if let menu = statusBarItem.menu, let start = menu.item(withTitle: "Run") {
start.isEnabled = true
}
}
@objc
func terminate(_ sender: NSMenuItem) {
NSApp.terminate(sender)
}
}

@ -1,58 +0,0 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -1,238 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="lokinet" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="lokinet" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About lokinet" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW">
<connections>
<segue destination="I5t-b2-LMF" kind="show" id="DG8-M4-AZh"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide lokinet" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit lokinet" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="lokinet Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="lokinet" customModuleProvider="target"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="123" y="-201"/>
</scene>
<!--lokinet-->
<scene sceneID="KyO-ZK-znh">
<objects>
<viewController title="lokinet" storyboardIdentifier="LokinetLogController" id="Bom-14-aTM" customClass="LokinetLogController" customModule="lokinet" sceneMemberID="viewController">
<view key="view" id="vMu-xc-OqT">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pjx-TF-AEF">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="LWK-yZ-W61">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView ambiguous="YES" editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" id="Iv9-j0-Ji1" customClass="LokinetLog" customModule="lokinet" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="systemGrayColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="450" height="300"/>
<size key="maxSize" width="498" height="10000000"/>
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
</textView>
</subviews>
</clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="2H0-hl-PSz">
<rect key="frame" x="-100" y="-100" width="240" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="0vF-TP-EGb">
<rect key="frame" x="434" y="0.0" width="16" height="300"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
</view>
</viewController>
<customObject id="4KZ-DK-tjg" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
</scene>
<!--Preferences-->
<scene sceneID="DWQ-D6-m8l">
<objects>
<viewController title="Preferences" id="I5t-b2-LMF" customClass="PrefsViewController" customModule="lokinet" sceneMemberID="viewController">
<view key="view" id="KZz-Tr-Jig">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<box fixedFrame="YES" title="Options" translatesAutoresizingMaskIntoConstraints="NO" id="Mbe-YJ-q14">
<rect key="frame" x="-3" y="-4" width="456" height="304"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<view key="contentView" id="tbu-Pf-Pbq">
<rect key="frame" x="3" y="3" width="450" height="286"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="keI-0V-OFa">
<rect key="frame" x="0.0" y="226" width="450" height="5"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</box>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NuC-QX-tDB">
<rect key="frame" x="18" y="269" width="414" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Lokinet Path" id="J0z-ru-wAJ">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Faq-SR-HLK">
<rect key="frame" x="18" y="201" width="414" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Network Interface" id="EAM-Cf-Ujw">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<comboBox identifier="lokinetInterface" verticalHuggingPriority="750" fixedFrame="YES" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="S5U-xg-7pX">
<rect key="frame" x="20" y="169" width="413" height="26"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" numberOfVisibleItems="7" id="f1D-GI-o0g">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</comboBoxCell>
<connections>
<action selector="comboAction:" target="I5t-b2-LMF" id="Bji-8L-xCR"/>
</connections>
</comboBox>
<textField verticalHuggingPriority="750" fixedFrame="YES" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="esl-Vn-YX2">
<rect key="frame" x="20" y="239" width="410" height="22"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="WCQ-qF-r0o">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
</box>
</subviews>
</view>
<connections>
<outlet property="interfaceEntry" destination="S5U-xg-7pX" id="OaG-RT-28K"/>
<outlet property="pathEntry" destination="WCQ-qF-r0o" id="aVf-iB-WbW"/>
</connections>
</viewController>
<customObject id="ncN-3l-Dyn" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="845" y="227"/>
</scene>
</scenes>
</document>

@ -1,79 +0,0 @@
//
// DNSManager.swift
// lokinet
//
// Copyright © 2019 Loki. All rights reserved.
//
import Foundation
func split(str: String?) -> [String] {
let res = str?.components(separatedBy: NSCharacterSet.whitespacesAndNewlines) ?? []
return res.filter({!$0.isEmpty})
}
class DNSManager {
static let netSetup = URL(fileURLWithPath: "/usr/sbin/networksetup")
let interface: String
var oldDNSSettings: [String] = []
func getOldSettings() -> [String] {
let netprocess = Process()
netprocess.executableURL = DNSManager.netSetup
netprocess.arguments = ["-getdnsservers", interface]
do {
let pipe = Pipe()
netprocess.standardOutput = pipe
try netprocess.run()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let asStr = String(data: data, encoding: .ascii)
if asStr?.contains("There aren't any DNS Servers") ?? true {
return []
} else {
return split(str: asStr).filter({$0 != "127.0.0.1"})
}
} catch {
return []
}
}
func setNewSettings() throws {
self.oldDNSSettings = getOldSettings()
print("Overriding DNS Settings of \(self.oldDNSSettings)")
let netprocess = Process()
netprocess.executableURL = DNSManager.netSetup
netprocess.arguments = ["-setdnsservers", self.interface, "127.0.0.1"]
try netprocess.run()
}
func restoreOldSettings() {
let netprocess = Process()
netprocess.executableURL = DNSManager.netSetup
netprocess.arguments = ["-setdnsservers", self.interface]
if oldDNSSettings.isEmpty {
// networkmsetup uses "networksetup -setdnsservers <interface> Empty" to reset
netprocess.arguments?.append("Empty")
} else {
netprocess.arguments?.append(contentsOf: oldDNSSettings)
}
do {
try netprocess.run()
print("Resetting DNS Settings to \(self.oldDNSSettings)")
} catch {
// do nothing
}
}
init(interface: String) {
self.interface = interface
}
}

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2019 Loki. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

@ -1,37 +0,0 @@
//
// LokinetLog.swift
// lokinet
//
// Copyright © 2019 Loki. All rights reserved.
//
import AppKit
class LokinetLogController : NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var log: LokinetLog {
get {
// this is walking down the UI stack.
// TODO: work out a better way of doing this
let scroll = self.view.subviews[0] as! NSScrollView
let clip = scroll.subviews[0] as! NSClipView
let log = clip.subviews[0] as! LokinetLog
return log
}
}
}
protocol Appendable {
func append(string: String)
}
final class LokinetLog : NSTextView, Appendable {
func append(string: String) {
self.textStorage?.append(NSAttributedString(string: string + "\n"))
self.scrollToEndOfDocument(nil)
}
}

@ -1,60 +0,0 @@
//
// LokinetRunner.swift
// lokinet
//
// Copyright © 2019 Loki. All rights reserved.
//
import Foundation
import Cocoa
class LokinetRunner {
let dnsManager: DNSManager
let lokinetPath: URL
var process = Process()
var logAppender: Appendable? = nil
init(interface: String, path: String) {
self.lokinetPath = URL(fileURLWithPath: path)
self.dnsManager = DNSManager(interface: interface)
}
func start() {
process.executableURL = self.lokinetPath
process.arguments = ["--colour=false"]
let outputPipe = Pipe()
process.standardOutput = outputPipe
process.standardError = outputPipe
do {
try self.dnsManager.setNewSettings()
try process.run()
} catch {
NSApp.presentError(error)
}
guard let reader = StreamReader(fh: outputPipe.fileHandleForReading) else {
let err = NSError(domain: "lokinet", code: 0, userInfo: ["msg": "Failed to read from filehandle"])
NSApp.presentError(err)
return
}
DispatchQueue.global(qos: .background).async {
for line in reader {
print(line)
DispatchQueue.main.async {
self.logAppender?.append(string: line)
}
}
}
}
func stop() {
if process.isRunning {
process.terminate()
process.waitUntilExit()
}
dnsManager.restoreOldSettings()
}
}

@ -1,73 +0,0 @@
//
// StreamReader.swift
// lokinet
//
// Copyright © 2019 Loki. All rights reserved.
//
import Foundation
final class StreamReader {
let encoding : String.Encoding
let chunkSize : Int
var fileHandle : FileHandle!
var buffer : Data
let delimData : Data
var atEof : Bool = false
init?(fh: FileHandle, delimiter: String = "\n", encoding : String.Encoding = .utf8, chunkSize : Int = 4096) {
self.chunkSize = chunkSize
self.encoding = encoding
self.fileHandle = fh
guard let delimData = delimiter.data(using: encoding) else {
return nil
}
self.delimData = delimData
self.buffer = Data(capacity: chunkSize)
}
/// Return next line, or nil on EOF.
func nextLine() -> String? {
precondition(fileHandle != nil, "Attempt to read from closed file")
if atEof {
return nil
}
// Read data chunks from file until a line delimiter is found:
while !atEof {
if let range = buffer.range(of: delimData) {
// Convert complete line (excluding the delimiter) to a string:
let line = String(data: buffer.subdata(in: 0..<range.lowerBound), encoding: encoding)
// Remove line (and the delimiter) from the buffer:
buffer.removeSubrange(0..<range.upperBound)
return line
}
let tmpData = fileHandle.readData(ofLength: chunkSize)
if tmpData.count > 0 {
buffer.append(tmpData)
} else {
// EOF or read error.
atEof = true
if buffer.count > 0 {
// Buffer contains last line in file (not terminated by delimiter).
let line = String(data: buffer as Data, encoding: encoding)
buffer.count = 0
return line
}
}
}
return nil
}
}
extension StreamReader : Sequence {
func makeIterator() -> AnyIterator<String> {
return AnyIterator {
return self.nextLine()
}
}
}

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array/>
</dict>
</plist>

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

@ -1,33 +0,0 @@
//
// lokinetTests.swift
// lokinetTests
//
// Copyright © 2019 Loki. All rights reserved.
//
import XCTest
@testable import lokinet
class lokinetTests: XCTestCase {
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

@ -1,33 +0,0 @@
//
// lokinetUITests.swift
// lokinetUITests
//
// Copyright © 2019 Loki. All rights reserved.
//
import XCTest
class lokinetUITests: XCTestCase {
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
XCUIApplication().launch()
// In UI tests its important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() {
// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
}

338
ui-win32/.gitignore vendored

@ -1,338 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true
**/wwwroot/lib/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/

@ -1,186 +0,0 @@
namespace network.loki.lokinet.win32.ui
{
partial class AboutBox
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox));
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.logoPictureBox = new System.Windows.Forms.PictureBox();
this.labelProductName = new System.Windows.Forms.Label();
this.labelVersion = new System.Windows.Forms.Label();
this.labelCopyright = new System.Windows.Forms.Label();
this.labelCompanyName = new System.Windows.Forms.Label();
this.textBoxDescription = new System.Windows.Forms.TextBox();
this.okButton = new System.Windows.Forms.Button();
this.tableLayoutPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
this.SuspendLayout();
//
// tableLayoutPanel
//
this.tableLayoutPanel.ColumnCount = 2;
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67F));
this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0);
this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0);
this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1);
this.tableLayoutPanel.Controls.Add(this.labelCopyright, 1, 2);
this.tableLayoutPanel.Controls.Add(this.labelCompanyName, 1, 3);
this.tableLayoutPanel.Controls.Add(this.textBoxDescription, 1, 4);
this.tableLayoutPanel.Controls.Add(this.okButton, 1, 5);
this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9);
this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.RowCount = 6;
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tableLayoutPanel.Size = new System.Drawing.Size(417, 265);
this.tableLayoutPanel.TabIndex = 0;
//
// logoPictureBox
//
this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.logoPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("logoPictureBox.Image")));
this.logoPictureBox.Location = new System.Drawing.Point(3, 3);
this.logoPictureBox.Name = "logoPictureBox";
this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 6);
this.logoPictureBox.Size = new System.Drawing.Size(131, 259);
this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.logoPictureBox.TabIndex = 12;
this.logoPictureBox.TabStop = false;
//
// labelProductName
//
this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelProductName.Location = new System.Drawing.Point(143, 0);
this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelProductName.MaximumSize = new System.Drawing.Size(0, 17);
this.labelProductName.Name = "labelProductName";
this.labelProductName.Size = new System.Drawing.Size(271, 17);
this.labelProductName.TabIndex = 19;
this.labelProductName.Text = "Product Name";
this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// labelVersion
//
this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelVersion.Location = new System.Drawing.Point(143, 26);
this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelVersion.MaximumSize = new System.Drawing.Size(0, 17);
this.labelVersion.Name = "labelVersion";
this.labelVersion.Size = new System.Drawing.Size(271, 17);
this.labelVersion.TabIndex = 0;
this.labelVersion.Text = "Version";
this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// labelCopyright
//
this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelCopyright.Location = new System.Drawing.Point(143, 52);
this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 17);
this.labelCopyright.Name = "labelCopyright";
this.labelCopyright.Size = new System.Drawing.Size(271, 17);
this.labelCopyright.TabIndex = 21;
this.labelCopyright.Text = "Copyright";
this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// labelCompanyName
//
this.labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelCompanyName.Location = new System.Drawing.Point(143, 78);
this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelCompanyName.MaximumSize = new System.Drawing.Size(0, 17);
this.labelCompanyName.Name = "labelCompanyName";
this.labelCompanyName.Size = new System.Drawing.Size(271, 17);
this.labelCompanyName.TabIndex = 22;
this.labelCompanyName.Text = "Company Name";
this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// textBoxDescription
//
this.textBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBoxDescription.Location = new System.Drawing.Point(143, 107);
this.textBoxDescription.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
this.textBoxDescription.Multiline = true;
this.textBoxDescription.Name = "textBoxDescription";
this.textBoxDescription.ReadOnly = true;
this.textBoxDescription.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBoxDescription.Size = new System.Drawing.Size(271, 126);
this.textBoxDescription.TabIndex = 23;
this.textBoxDescription.TabStop = false;
this.textBoxDescription.Text = "Description";
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.okButton.Location = new System.Drawing.Point(339, 239);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 24;
this.okButton.Text = "&OK";
//
// AboutBox
//
this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(435, 283);
this.Controls.Add(this.tableLayoutPanel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "AboutBox";
this.Padding = new System.Windows.Forms.Padding(9);
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "AboutBox1";
this.tableLayoutPanel.ResumeLayout(false);
this.tableLayoutPanel.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
private System.Windows.Forms.PictureBox logoPictureBox;
private System.Windows.Forms.Label labelProductName;
private System.Windows.Forms.Label labelVersion;
private System.Windows.Forms.Label labelCopyright;
private System.Windows.Forms.Label labelCompanyName;
private System.Windows.Forms.TextBox textBoxDescription;
private System.Windows.Forms.Button okButton;
}
}

@ -1,118 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
namespace network.loki.lokinet.win32.ui
{
partial class AboutBox : Form
{
public AboutBox()
{
InitializeComponent();
var lic = File.ReadAllText(String.Format("{0}/LICENSE", Directory.GetCurrentDirectory()));
this.Text = String.Format("About {0}", AssemblyTitle);
this.labelProductName.Text = AssemblyProduct;
this.labelVersion.Text = String.Format("Version {0}", AssemblyInformationalVersion);
this.labelCopyright.Text = AssemblyCopyright;
this.labelCompanyName.Text = AssemblyCompany;
this.textBoxDescription.Text = lic;
}
#region Assembly Attribute Accessors
public string AssemblyTitle
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title != "")
{
return titleAttribute.Title;
}
}
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
}
}
public string AssemblyVersion
{
get
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
}
public string AssemblyInformationalVersion
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyInformationalVersionAttribute)attributes[0]).InformationalVersion;
}
}
public string AssemblyDescription
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyDescriptionAttribute)attributes[0]).Description;
}
}
public string AssemblyProduct
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyProductAttribute)attributes[0]).Product;
}
}
public string AssemblyCopyright
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}
}
public string AssemblyCompany
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyCompanyAttribute)attributes[0]).Company;
}
}
#endregion
}
}

@ -1,454 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="logoPictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
</root>

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="network.loki.lokinet.win32.ui.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup useLegacyV2RuntimeActivationPolicy="false">
<!-- for modern PCs without .NET 2.0 -->
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
<userSettings>
<network.loki.lokinet.win32.ui.Properties.Settings>
<setting name="autoScroll" serializeAs="String">
<value>True</value>
</setting>
</network.loki.lokinet.win32.ui.Properties.Settings>
</userSettings>
</configuration>

@ -1,62 +0,0 @@
using network.loki.lokinet.win32.ui.Properties;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
namespace network.loki.lokinet.win32.ui
{
class LogDumper
{
private const string LogFolderName = "logs";
private const string LogFileName = "lokinet.log";
private string tmp;
private string LogPath;
public LogDumper(string text_dump)
{
tmp = text_dump;
}
public void setText(string text)
{
tmp = text;
}
public string getLogPath()
{
return LogPath;
}
public void CreateLog(string path)
{
var logFolderPath = Path.Combine(path, LogFolderName);
if (!Directory.Exists(logFolderPath))
Directory.CreateDirectory(logFolderPath);
var logFilePath = Path.Combine(logFolderPath, LogFileName);
LogPath = logFilePath;
Rotate(logFilePath);
using (var sw = File.AppendText(logFilePath))
{
sw.WriteLine(tmp);
}
}
private void Rotate(string filePath)
{
if (!File.Exists(filePath))
return;
var fileInfo = new FileInfo(filePath);
var fileTime = DateTime.Now.ToString("dd-MM-yy__h-m-s");
var rotatedPath = filePath.Replace(".log", $".{fileTime}.log");
File.Move(filePath, rotatedPath);
}
}
}

@ -1,41 +0,0 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
namespace network.loki.lokinet.win32.ui
{
static class Program
{
public static OperatingSystem os_id = Environment.OSVersion;
public static PlatformID platform = os_id.Platform;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// Scrub any old lokinet process left behind
Mutex m = new Mutex(true, "lokinet_dotnet_ui");
Process[] old_pids = Process.GetProcessesByName("lokinet");
foreach (Process pid in old_pids)
{
try
{
pid.Kill();
}
catch { } // don't yell
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new main_frame());
try
{
main_frame.lokiNetDaemon.Kill();
}
catch
{ }
m.ReleaseMutex();
}
}
}

@ -1,46 +0,0 @@
// WARNING: for the love of all that is good and holy
// please DO NOT convert this file to UTF-8, much less
// UTF-16 - the UNIX port of Roslyn does not understand UTF-16,
// and UTF-8 chews up the copyright symbols.
// -rick
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Lokinet for Windows")]
[assembly: AssemblyDescription("Lokinet end-user UI")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Loki Project")]
[assembly: AssemblyProduct("Lokinet Launcher")]
[assembly: AssemblyCopyright("Copyright ©2018-2020 Loki Project. All rights reserved. See LICENSE for more details.")]
[assembly: AssemblyTrademark("Loki, Loki Project, LokiNET are ™ & ©2018-2020 Loki Foundation")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1cdee73c-29c5-4781-bd74-1eeac6f75a14")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.7.0")]
[assembly: AssemblyFileVersion("0.7.0")]
#if DEBUG
[assembly: AssemblyInformationalVersion("0.7.0-dev-{chash:8}")]
#else
[assembly: AssemblyInformationalVersion("0.7.0 (RELEASE_CODENAME)")]
#endif

@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace network.loki.lokinet.win32.ui.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("network.loki.lokinet.win32.ui.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

@ -1,38 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace network.loki.lokinet.win32.ui.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool autoScroll {
get {
return ((bool)(this["autoScroll"]));
}
set {
this["autoScroll"] = value;
}
}
}
}

@ -1,9 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="network.loki.lokinet.win32.ui.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="autoScroll" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
</Settings>
</SettingsFile>

@ -1,28 +0,0 @@
namespace network.loki.lokinet.win32.ui.Properties {
// This class allows you to handle specific events on the settings class:
// The SettingChanging event is raised before a setting's value is changed.
// The PropertyChanged event is raised after a setting's value is changed.
// The SettingsLoaded event is raised after the setting values are loaded.
// The SettingsSaving event is raised before the setting values are saved.
internal sealed partial class Settings {
public Settings() {
// // To add event handlers for saving and changing settings, uncomment the lines below:
//
// this.SettingChanging += this.SettingChangingEventHandler;
//
// this.SettingsSaving += this.SettingsSavingEventHandler;
//
}
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
// Add code to handle the SettingChangingEvent event here.
}
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
// Add code to handle the SettingsSaving event here.
}
}
}

@ -1,253 +0,0 @@
namespace network.loki.lokinet.win32.ui
{
partial class main_frame
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(main_frame));
this.StatusLabel = new System.Windows.Forms.Label();
this.lokinetd_fd1 = new System.Windows.Forms.TextBox();
this.NotificationTrayIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.TrayMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.showToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.TrayConnect = new System.Windows.Forms.ToolStripMenuItem();
this.TrayDisconnect = new System.Windows.Forms.ToolStripMenuItem();
this.saveLogToFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.btnHide = new System.Windows.Forms.Button();
this.UIVersionLabel = new System.Windows.Forms.Label();
this.btnConnect = new System.Windows.Forms.Button();
this.btnDrop = new System.Windows.Forms.Button();
this.btnConfigProfile = new System.Windows.Forms.Button();
this.btnAbout = new System.Windows.Forms.Button();
this.TrayMenu.SuspendLayout();
this.SuspendLayout();
//
// StatusLabel
//
this.StatusLabel.AutoSize = true;
this.StatusLabel.Location = new System.Drawing.Point(13, 13);
this.StatusLabel.Name = "StatusLabel";
this.StatusLabel.Size = new System.Drawing.Size(97, 13);
this.StatusLabel.TabIndex = 0;
this.StatusLabel.Text = "[connection status]";
//
// lokinetd_fd1
//
this.lokinetd_fd1.AcceptsReturn = true;
this.lokinetd_fd1.AcceptsTab = true;
this.lokinetd_fd1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lokinetd_fd1.BackColor = System.Drawing.SystemColors.InfoText;
this.lokinetd_fd1.Font = new System.Drawing.Font("Iosevka Term Light", 9.749999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lokinetd_fd1.ForeColor = System.Drawing.Color.Lime;
this.lokinetd_fd1.Location = new System.Drawing.Point(12, 39);
this.lokinetd_fd1.MaxLength = 0;
this.lokinetd_fd1.Multiline = true;
this.lokinetd_fd1.Name = "lokinetd_fd1";
this.lokinetd_fd1.ReadOnly = true;
this.lokinetd_fd1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.lokinetd_fd1.Size = new System.Drawing.Size(776, 330);
this.lokinetd_fd1.TabIndex = 1;
this.lokinetd_fd1.TextChanged += new System.EventHandler(this.lokinetd_fd1_TextChanged);
//
// NotificationTrayIcon
//
this.NotificationTrayIcon.ContextMenuStrip = this.TrayMenu;
this.NotificationTrayIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("NotificationTrayIcon.Icon")));
this.NotificationTrayIcon.Text = "LokiNET - disconnected";
this.NotificationTrayIcon.Visible = true;
this.NotificationTrayIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.NotificationTrayIcon_MouseDoubleClick);
//
// TrayMenu
//
this.TrayMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.showToolStripMenuItem,
this.TrayConnect,
this.TrayDisconnect,
this.saveLogToFileToolStripMenuItem,
this.aboutToolStripMenuItem,
this.exitToolStripMenuItem});
this.TrayMenu.Name = "TrayMenu";
this.TrayMenu.Size = new System.Drawing.Size(166, 136);
//
// showToolStripMenuItem
//
this.showToolStripMenuItem.Name = "showToolStripMenuItem";
this.showToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
this.showToolStripMenuItem.Text = "Show";
this.showToolStripMenuItem.Click += new System.EventHandler(this.showToolStripMenuItem_Click);
//
// TrayConnect
//
this.TrayConnect.Name = "TrayConnect";
this.TrayConnect.Size = new System.Drawing.Size(165, 22);
this.TrayConnect.Text = "Connect";
this.TrayConnect.Click += new System.EventHandler(this.TrayConnect_Click);
//
// TrayDisconnect
//
this.TrayDisconnect.Name = "TrayDisconnect";
this.TrayDisconnect.Size = new System.Drawing.Size(165, 22);
this.TrayDisconnect.Text = "Disconnect";
this.TrayDisconnect.Click += new System.EventHandler(this.TrayDisconnect_Click);
//
// saveLogToFileToolStripMenuItem
//
this.saveLogToFileToolStripMenuItem.Name = "saveLogToFileToolStripMenuItem";
this.saveLogToFileToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
this.saveLogToFileToolStripMenuItem.Text = "Save Log to File...";
this.saveLogToFileToolStripMenuItem.Click += new System.EventHandler(this.saveLogToFileToolStripMenuItem_Click);
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
this.aboutToolStripMenuItem.Text = "About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
this.exitToolStripMenuItem.Text = "Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// btnHide
//
this.btnHide.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnHide.Location = new System.Drawing.Point(713, 415);
this.btnHide.Name = "btnHide";
this.btnHide.Size = new System.Drawing.Size(75, 23);
this.btnHide.TabIndex = 2;
this.btnHide.Text = "Hide";
this.btnHide.UseVisualStyleBackColor = true;
this.btnHide.Click += new System.EventHandler(this.btnHide_Click);
//
// UIVersionLabel
//
this.UIVersionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.UIVersionLabel.Location = new System.Drawing.Point(455, 388);
this.UIVersionLabel.Name = "UIVersionLabel";
this.UIVersionLabel.Size = new System.Drawing.Size(333, 13);
this.UIVersionLabel.TabIndex = 3;
this.UIVersionLabel.Text = "version label";
this.UIVersionLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
//
// btnConnect
//
this.btnConnect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnConnect.Location = new System.Drawing.Point(13, 415);
this.btnConnect.Name = "btnConnect";
this.btnConnect.Size = new System.Drawing.Size(75, 23);
this.btnConnect.TabIndex = 4;
this.btnConnect.Text = "Connect";
this.btnConnect.UseVisualStyleBackColor = true;
this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
//
// btnDrop
//
this.btnDrop.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnDrop.Enabled = false;
this.btnDrop.Location = new System.Drawing.Point(95, 415);
this.btnDrop.Name = "btnDrop";
this.btnDrop.Size = new System.Drawing.Size(75, 23);
this.btnDrop.TabIndex = 5;
this.btnDrop.Text = "Disconnect";
this.btnDrop.UseVisualStyleBackColor = true;
this.btnDrop.Click += new System.EventHandler(this.btnDrop_Click);
//
// btnConfigProfile
//
this.btnConfigProfile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnConfigProfile.Location = new System.Drawing.Point(177, 415);
this.btnConfigProfile.Name = "btnConfigProfile";
this.btnConfigProfile.Size = new System.Drawing.Size(75, 23);
this.btnConfigProfile.TabIndex = 6;
this.btnConfigProfile.Text = "Settings...";
this.btnConfigProfile.UseVisualStyleBackColor = true;
this.btnConfigProfile.Click += new System.EventHandler(this.btnConfigProfile_Click);
//
// btnAbout
//
this.btnAbout.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnAbout.Location = new System.Drawing.Point(259, 415);
this.btnAbout.Name = "btnAbout";
this.btnAbout.Size = new System.Drawing.Size(75, 23);
this.btnAbout.TabIndex = 7;
this.btnAbout.Text = "About...";
this.btnAbout.UseVisualStyleBackColor = true;
this.btnAbout.Click += new System.EventHandler(this.btnAbout_Click);
//
// main_frame
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.btnAbout);
this.Controls.Add(this.btnConfigProfile);
this.Controls.Add(this.btnDrop);
this.Controls.Add(this.btnConnect);
this.Controls.Add(this.UIVersionLabel);
this.Controls.Add(this.btnHide);
this.Controls.Add(this.lokinetd_fd1);
this.Controls.Add(this.StatusLabel);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "main_frame";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Lokinet Launcher";
this.TrayMenu.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label StatusLabel;
private System.Windows.Forms.NotifyIcon NotificationTrayIcon;
private System.Windows.Forms.Button btnHide;
private System.Windows.Forms.Label UIVersionLabel;
private System.Windows.Forms.Button btnConnect;
private System.Windows.Forms.Button btnDrop;
private System.Windows.Forms.Button btnConfigProfile;
public System.Windows.Forms.TextBox lokinetd_fd1;
private System.Windows.Forms.Button btnAbout;
private System.Windows.Forms.ContextMenuStrip TrayMenu;
private System.Windows.Forms.ToolStripMenuItem TrayConnect;
private System.Windows.Forms.ToolStripMenuItem TrayDisconnect;
private System.Windows.Forms.ToolStripMenuItem saveLogToFileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem showToolStripMenuItem;
}
}

@ -1,178 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
namespace network.loki.lokinet.win32.ui
{
public partial class main_frame : Form
{
public static Process lokiNetDaemon = new Process();
public static bool isConnected;
public static string logText;
private string config_path;
private LogDumper ld;
void UpdateUI(string text)
{
this.Invoke(new MethodInvoker(delegate () { lokinetd_fd1.AppendText(text); }));
}
public main_frame()
{
InitializeComponent();
if (Program.platform == PlatformID.Win32NT)
config_path = Environment.ExpandEnvironmentVariables("%APPDATA%\\.lokinet");
else
config_path = Environment.ExpandEnvironmentVariables("%HOME%/.lokinet");
StatusLabel.Text = "Disconnected";
var build = ((AssemblyInformationalVersionAttribute)Assembly
.GetAssembly(typeof(main_frame))
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)[0])
.InformationalVersion;
UIVersionLabel.Text = String.Format("Lokinet version {0}", build);
lokinetd_fd1.Text = string.Empty;
logText = string.Empty;
lokiNetDaemon.OutputDataReceived += new DataReceivedEventHandler((s, ev) =>
{
if (!string.IsNullOrEmpty(ev.Data))
{
UpdateUI(ev.Data + Environment.NewLine);
}
});
}
private void btnConfigProfile_Click(object sender, EventArgs e)
{
//MessageBox.Show("not implemented yet", "error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
UserSettingsForm f = new UserSettingsForm();
f.ShowDialog();
f.Dispose();
}
private void btnConnect_Click(object sender, EventArgs e)
{
string lokinetExeString;
if (Program.platform == PlatformID.Win32NT)
lokinetExeString = String.Format("{0}\\lokinet.exe", Directory.GetCurrentDirectory());
else
lokinetExeString = String.Format("{0}/lokinet", Directory.GetCurrentDirectory());
lokiNetDaemon.StartInfo.UseShellExecute = false;
lokiNetDaemon.StartInfo.RedirectStandardOutput = true;
//lokiNetDaemon.EnableRaisingEvents = true;
lokiNetDaemon.StartInfo.CreateNoWindow = true;
lokiNetDaemon.StartInfo.FileName = lokinetExeString;
lokiNetDaemon.Start();
lokiNetDaemon.BeginOutputReadLine();
btnConnect.Enabled = false;
TrayConnect.Enabled = false;
StatusLabel.Text = "Connected";
isConnected = true;
NotificationTrayIcon.Text = "Lokinet - connected";
btnDrop.Enabled = true;
TrayDisconnect.Enabled = true;
NotificationTrayIcon.ShowBalloonTip(5, "Lokinet", "Connected to network.", ToolTipIcon.Info);
}
private void btnDrop_Click(object sender, EventArgs e)
{
lokiNetDaemon.CancelOutputRead();
lokiNetDaemon.Kill();
btnConnect.Enabled = true;
TrayConnect.Enabled = true;
btnDrop.Enabled = false;
TrayDisconnect.Enabled = false;
StatusLabel.Text = "Disconnected";
NotificationTrayIcon.Text = "Lokinet - disconnected";
isConnected = false;
logText = lokinetd_fd1.Text;
lokinetd_fd1.Text = string.Empty;
NotificationTrayIcon.ShowBalloonTip(5, "Lokinet", "Disconnected from network.", ToolTipIcon.Info);
}
private void lokinetd_fd1_TextChanged(object sender, EventArgs e)
{
if (Properties.Settings.Default.autoScroll)
lokinetd_fd1.ScrollToCaret();
else
return;
}
private void btnHide_Click(object sender, EventArgs e)
{
Hide();
if (isConnected)
NotificationTrayIcon.ShowBalloonTip(5, "Lokinet", "Currently connected.", ToolTipIcon.Info);
else
NotificationTrayIcon.ShowBalloonTip(5, "Lokinet", "Currently disconnected.", ToolTipIcon.Info);
}
private void NotificationTrayIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (!Visible)
{
Show();
}
}
private void btnAbout_Click(object sender, EventArgs e)
{
AboutBox a = new AboutBox();
a.ShowDialog(this);
a.Dispose();
}
private void saveLogToFileToolStripMenuItem_Click(object sender, EventArgs e)
{
if (isConnected)
MessageBox.Show("Cannot dump log when client is running.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
else
{
if (logText == string.Empty)
{
MessageBox.Show("Log is empty", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
if (ld == null)
ld = new LogDumper(logText);
else
ld.setText(logText);
ld.CreateLog(config_path);
MessageBox.Show(string.Format("Wrote log to {0}, previous log rotated", ld.getLogPath()), "Lokinet", MessageBoxButtons.OK, MessageBoxIcon.Information);
logText = string.Empty;
}
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutBox a = new AboutBox();
a.ShowDialog();
a.Dispose();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void TrayDisconnect_Click(object sender, EventArgs e)
{
btnDrop_Click(sender, e);
}
private void TrayConnect_Click(object sender, EventArgs e)
{
btnConnect_Click(sender, e);
}
private void showToolStripMenuItem_Click(object sender, EventArgs e)
{
Show();
}
}
}

@ -1,279 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="NotificationTrayIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="TrayMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>179, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="NotificationTrayIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAABISEgccHBygHBwcmRISEgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvgEkMIjYpvBwcHP8cHBz/HBwcuBQUFAwAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANpdVGEW+bM00fUv/HB0c/xwcHP8cHBz/HBwcyRYW
FhUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADujXCZFvmzdRb5s/0W9a/82hE/4HBwc+Rwc
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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMTBxwcHKAcHBypFRYWCgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA//////////////////w////4H///8A///+AH///AA///gYH//wPA//4E
IH/8CBA//BAIP/wAAD/8AAA//AGAP/wBgD/8AAA//AAAP/wQCD/8CBA//gQgf/8DwP//gYH//8AD///g
B///8A////gf///8P/////////////////8=
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAABISEgccHBygHBwcmRISEgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvgEkMIjYpvBwcHP8cHBz/HBwcuBQUFAwAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANpdVGEW+bM00fUv/HB0c/xwcHP8cHBz/HBwcyRYW
FhUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADujXCZFvmzdRb5s/0W9a/82hE/4HBwc+Rwc
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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMTBxwcHKAcHBypFRYWCgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA//////////////////w////4H///8A///+AH///AA///gYH//wPA//4E
IH/8CBA//BAIP/wAAD/8AAA//AGAP/wBgD/8AAA//AAAP/wQCD/8CBA//gQgf/8DwP//gYH//8AD///g
B///8A////gf///8P/////////////////8=
</value>
</data>
</root>

@ -1,137 +0,0 @@
namespace network.loki.lokinet.win32.ui
{
partial class UserSettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnOK = new System.Windows.Forms.Button();
this.btnBoot = new System.Windows.Forms.Button();
this.btnDumpLog = new System.Windows.Forms.Button();
this.btnVSettings = new System.Windows.Forms.Button();
this.btnEditCfg = new System.Windows.Forms.Button();
this.btnNewCfg = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnOK
//
this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnOK.Location = new System.Drawing.Point(109, 167);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 0;
this.btnOK.Text = "Close";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnBoot
//
this.btnBoot.Location = new System.Drawing.Point(13, 13);
this.btnBoot.Name = "btnBoot";
this.btnBoot.Size = new System.Drawing.Size(270, 23);
this.btnBoot.TabIndex = 1;
this.btnBoot.Text = "Bootstrap Client from Web...";
this.btnBoot.UseVisualStyleBackColor = true;
this.btnBoot.Click += new System.EventHandler(this.btnBoot_Click);
//
// btnDumpLog
//
this.btnDumpLog.Location = new System.Drawing.Point(13, 43);
this.btnDumpLog.Name = "btnDumpLog";
this.btnDumpLog.Size = new System.Drawing.Size(270, 23);
this.btnDumpLog.TabIndex = 2;
this.btnDumpLog.Text = "Save Log...";
this.btnDumpLog.UseVisualStyleBackColor = true;
this.btnDumpLog.Click += new System.EventHandler(this.btnDumpLog_Click);
//
// btnVSettings
//
this.btnVSettings.Location = new System.Drawing.Point(13, 73);
this.btnVSettings.Name = "btnVSettings";
this.btnVSettings.Size = new System.Drawing.Size(270, 23);
this.btnVSettings.TabIndex = 3;
this.btnVSettings.Text = "Display Settings...";
this.btnVSettings.UseVisualStyleBackColor = true;
this.btnVSettings.Click += new System.EventHandler(this.btnVSettings_Click);
//
// btnEditCfg
//
this.btnEditCfg.Location = new System.Drawing.Point(13, 102);
this.btnEditCfg.Name = "btnEditCfg";
this.btnEditCfg.Size = new System.Drawing.Size(270, 23);
this.btnEditCfg.TabIndex = 4;
this.btnEditCfg.Text = "Edit Configuration File...";
this.btnEditCfg.UseVisualStyleBackColor = true;
this.btnEditCfg.Click += new System.EventHandler(this.BtnEditCfg_Click);
//
// btnNewCfg
//
this.btnNewCfg.Location = new System.Drawing.Point(12, 131);
this.btnNewCfg.Name = "btnNewCfg";
this.btnNewCfg.Size = new System.Drawing.Size(270, 23);
this.btnNewCfg.TabIndex = 5;
this.btnNewCfg.Text = "New Configuration File...";
this.btnNewCfg.UseVisualStyleBackColor = true;
this.btnNewCfg.Click += new System.EventHandler(this.BtnNewCfg_Click);
//
// UserSettingsForm
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnOK;
this.ClientSize = new System.Drawing.Size(295, 202);
this.ControlBox = false;
this.Controls.Add(this.btnNewCfg);
this.Controls.Add(this.btnEditCfg);
this.Controls.Add(this.btnVSettings);
this.Controls.Add(this.btnDumpLog);
this.Controls.Add(this.btnBoot);
this.Controls.Add(this.btnOK);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "UserSettingsForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Settings";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnBoot;
private System.Windows.Forms.Button btnDumpLog;
private System.Windows.Forms.Button btnVSettings;
private System.Windows.Forms.Button btnEditCfg;
private System.Windows.Forms.Button btnNewCfg;
}
}

@ -1,111 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
namespace network.loki.lokinet.win32.ui
{
public partial class UserSettingsForm : Form
{
public UserSettingsForm()
{
InitializeComponent();
if (Program.platform == PlatformID.Win32NT)
config_path = Environment.ExpandEnvironmentVariables("%APPDATA%\\.lokinet");
else
config_path = Environment.ExpandEnvironmentVariables("%HOME%/.lokinet");
}
private string config_path;
private LogDumper ld;
private void btnOK_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnBoot_Click(object sender, EventArgs e)
{
dlgBootstrap b = new dlgBootstrap();
b.ShowDialog();
b.Dispose();
}
private void btnDumpLog_Click(object sender, EventArgs e)
{
if (main_frame.isConnected)
MessageBox.Show("Cannot dump log when client is running.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
else
{
if (main_frame.logText == string.Empty)
{
MessageBox.Show("Log is empty", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
if (ld == null)
ld = new LogDumper(main_frame.logText);
else
ld.setText(main_frame.logText);
ld.CreateLog(config_path);
MessageBox.Show(string.Format("Wrote log to {0}, previous log rotated", ld.getLogPath()), "LokiNET", MessageBoxButtons.OK, MessageBoxIcon.Information);
main_frame.logText = string.Empty;
}
}
private void btnVSettings_Click(object sender, EventArgs e)
{
VisualSettings v = new VisualSettings();
v.ShowDialog();
v.Dispose();
}
private void BtnEditCfg_Click(object sender, EventArgs e)
{
try {
Process.Start(string.Format("{0}/lokinet.ini", config_path)); }
catch
{
MessageBox.Show("No existing config found");
BtnNewCfg_Click(sender, e);
}
}
private void BtnNewCfg_Click(object sender, EventArgs e)
{
if (File.Exists(string.Format("{0}/lokinet.ini", config_path)))
{
DialogResult resp = MessageBox.Show("WARNING: This will overwrite your existing config file, Continue?", "Lokinet", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
switch(resp)
{
case DialogResult.Yes:
File.Delete(string.Format("{0}/lokinet.ini", config_path));
break;
case DialogResult.No:
return;
}
}
string lokinetExeString;
if (Program.platform == PlatformID.Win32NT)
lokinetExeString = String.Format("{0}\\lokinet.exe", Directory.GetCurrentDirectory());
else
lokinetExeString = String.Format("{0}/lokinet", Directory.GetCurrentDirectory());
Process p = new Process();
p.StartInfo.FileName = lokinetExeString;
p.StartInfo.Arguments = "-g";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.EnableRaisingEvents = true;
p.Exited += new EventHandler(msg);
p.Start();
}
private void msg(object sender, EventArgs e)
{
MessageBox.Show(string.Format("Created new config file at {0}/lokinet.ini", config_path), "Success", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
}
}

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

@ -1,96 +0,0 @@
namespace network.loki.lokinet.win32.ui
{
partial class VisualSettings
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.ToggleAutoScroll = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// btnOK
//
this.btnOK.Location = new System.Drawing.Point(104, 135);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 0;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(186, 135);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// ToggleAutoScroll
//
this.ToggleAutoScroll.AutoSize = true;
this.ToggleAutoScroll.Location = new System.Drawing.Point(13, 13);
this.ToggleAutoScroll.Name = "ToggleAutoScroll";
this.ToggleAutoScroll.Size = new System.Drawing.Size(172, 17);
this.ToggleAutoScroll.TabIndex = 2;
this.ToggleAutoScroll.Text = "Scroll log window automatically";
this.ToggleAutoScroll.UseVisualStyleBackColor = true;
//
// VisualSettings
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(365, 170);
this.ControlBox = false;
this.Controls.Add(this.ToggleAutoScroll);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOK);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "VisualSettings";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Display Settings";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.CheckBox ToggleAutoScroll;
}
}

@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace network.loki.lokinet.win32.ui
{
public partial class VisualSettings : Form
{
public VisualSettings()
{
InitializeComponent();
ToggleAutoScroll.Checked = Properties.Settings.Default.autoScroll;
}
private void btnOK_Click(object sender, EventArgs e)
{
if (ToggleAutoScroll.Checked)
Properties.Settings.Default.autoScroll = true;
else
Properties.Settings.Default.autoScroll = false;
Close();
}
}
}

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

@ -1,101 +0,0 @@
namespace network.loki.lokinet.win32.ui
{
partial class dlgBootstrap
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(dlgBootstrap));
this.label1 = new System.Windows.Forms.Label();
this.uriBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.btnDownload = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
resources.ApplyResources(this.label1, "label1");
this.label1.Name = "label1";
//
// uriBox
//
resources.ApplyResources(this.uriBox, "uriBox");
this.uriBox.Name = "uriBox";
//
// label2
//
resources.ApplyResources(this.label2, "label2");
this.label2.Name = "label2";
//
// btnDownload
//
resources.ApplyResources(this.btnDownload, "btnDownload");
this.btnDownload.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnDownload.Name = "btnDownload";
this.btnDownload.UseVisualStyleBackColor = true;
this.btnDownload.Click += new System.EventHandler(this.button1_Click);
//
// btnCancel
//
resources.ApplyResources(this.btnCancel, "btnCancel");
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Name = "btnCancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.button1_Click_1);
//
// dlgBootstrap
//
this.AcceptButton = this.btnDownload;
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ControlBox = false;
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnDownload);
this.Controls.Add(this.label2);
this.Controls.Add(this.uriBox);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "dlgBootstrap";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox uriBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button btnDownload;
private System.Windows.Forms.Button btnCancel;
}
}

@ -1,98 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;
namespace network.loki.lokinet.win32.ui
{
public partial class dlgBootstrap : Form
{
public dlgBootstrap()
{
InitializeComponent();
if (Program.platform == PlatformID.Win32NT)
default_path = Environment.ExpandEnvironmentVariables("%APPDATA%\\.lokinet");
else
default_path = Environment.ExpandEnvironmentVariables("%HOME%/.lokinet");
label2.Text = String.Format("This file is automatically saved as {0}{1}{2}.", default_path, Path.DirectorySeparatorChar, rcName);
}
private WebClient wc;
private string default_path;
private const string rcName = "bootstrap.signed";
private void button1_Click(object sender, EventArgs e)
{
Directory.CreateDirectory(default_path);
var build = ((AssemblyInformationalVersionAttribute)Assembly
.GetAssembly(typeof(main_frame))
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)[0])
.InformationalVersion;
// add something more unique, this is the IE 5.0 default string
try
{
ServicePointManager.ServerCertificateValidationCallback += cert_check;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)48 | 0 | (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
wc = new WebClient();
wc.Headers.Add("User-Agent", string.Format("Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0); lokinet-win32-managed-ui/{0}", build));
wc.DownloadFile(uriBox.Text, string.Format("{0}{1}{2}", default_path, Path.DirectorySeparatorChar, rcName));
MessageBox.Show("LokiNET node bootstrapped", "LokiNET", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
}
catch (Exception ex)
{
string lokinetExeString;
Process lokinet_bootstrap = new Process();
if (Program.platform == PlatformID.Win32NT)
lokinetExeString = String.Format("{0}\\lokinet-bootstrap.exe", Directory.GetCurrentDirectory());
else
lokinetExeString = String.Format("{0}/lokinet-bootstrap", Directory.GetCurrentDirectory());
lokinet_bootstrap.StartInfo.UseShellExecute = false;
lokinet_bootstrap.StartInfo.CreateNoWindow = true;
lokinet_bootstrap.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
lokinet_bootstrap.StartInfo.FileName = lokinetExeString;
lokinet_bootstrap.StartInfo.Arguments = string.Format("--cacert rootcerts.pem -L {0} --output \"{1}{2}{3}\"", uriBox.Text, default_path, Path.DirectorySeparatorChar, rcName);
lokinet_bootstrap.Start();
lokinet_bootstrap.WaitForExit();
if (lokinet_bootstrap.ExitCode == 0)
{
DialogResult = DialogResult.OK;
MessageBox.Show("LokiNET node bootstrapped", "LokiNET", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show(string.Format("An error occured while downloading data. {0}", ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
DialogResult = DialogResult.Abort;
}
}
Close();
}
private bool cert_check(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
// If the certificate is a valid, signed certificate, return true.
if (error == System.Net.Security.SslPolicyErrors.None)
{
return true;
}
MessageBox.Show(string.Format("X509Certificate [{0}] Policy Error: '{1}'",
cert.Subject,
error.ToString()), "SSL Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return false;
}
private void button1_Click_1(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

@ -1,279 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
<value>13, 13</value>
</data>
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
<value>196, 13</value>
</data>
<data name="label1.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Enter a URI to a node to bootstrap from:</value>
</data>
<data name="&gt;&gt;label1.Name" xml:space="preserve">
<value>label1</value>
</data>
<data name="&gt;&gt;label1.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="uriBox.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Left, Right</value>
</data>
<data name="uriBox.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 29</value>
</data>
<data name="uriBox.Size" type="System.Drawing.Size, System.Drawing">
<value>520, 20</value>
</data>
<data name="uriBox.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="uriBox.Text" xml:space="preserve">
<value>https://seed.lokinet.org/lokinet.signed</value>
</data>
<data name="&gt;&gt;uriBox.Name" xml:space="preserve">
<value>uriBox</value>
</data>
<data name="&gt;&gt;uriBox.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;uriBox.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;uriBox.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="label2.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="label2.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 52</value>
</data>
<data name="label2.Size" type="System.Drawing.Size, System.Drawing">
<value>347, 13</value>
</data>
<data name="label2.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>This file is automatically saved as $APPDATA\.lokinet\bootstrap.signed.</value>
</data>
<data name="&gt;&gt;label2.Name" xml:space="preserve">
<value>label2</value>
</data>
<data name="&gt;&gt;label2.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label2.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label2.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="btnDownload.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom</value>
</data>
<data name="btnDownload.Location" type="System.Drawing.Point, System.Drawing">
<value>196, 75</value>
</data>
<data name="btnDownload.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
</data>
<data name="btnDownload.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="btnDownload.Text" xml:space="preserve">
<value>OK</value>
</data>
<data name="&gt;&gt;btnDownload.Name" xml:space="preserve">
<value>btnDownload</value>
</data>
<data name="&gt;&gt;btnDownload.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;btnDownload.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;btnDownload.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="btnCancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom</value>
</data>
<data name="btnCancel.Location" type="System.Drawing.Point, System.Drawing">
<value>278, 75</value>
</data>
<data name="btnCancel.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
</data>
<data name="btnCancel.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="btnCancel.Text" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="&gt;&gt;btnCancel.Name" xml:space="preserve">
<value>btnCancel</value>
</data>
<data name="&gt;&gt;btnCancel.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;btnCancel.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;btnCancel.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>6, 13</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>548, 111</value>
</data>
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
<value>CenterParent</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>bootstrap from web...</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>dlgBootstrap</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

@ -1,131 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>network.loki.lokinet.win32.ui</RootNamespace>
<AssemblyName>lokinetui</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>lokinet.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AboutBox.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AboutBox.Designer.cs">
<DependentUpon>AboutBox.cs</DependentUpon>
</Compile>
<Compile Include="LogDumper.cs" />
<Compile Include="dlgBootstrap.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="dlgBootstrap.Designer.cs">
<DependentUpon>dlgBootstrap.cs</DependentUpon>
</Compile>
<Compile Include="Settings.cs" />
<Compile Include="UserSettings.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UserSettings.Designer.cs">
<DependentUpon>UserSettings.cs</DependentUpon>
</Compile>
<Compile Include="UIMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UIMain.Designer.cs">
<DependentUpon>UIMain.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VisualSettings.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="VisualSettings.Designer.cs">
<DependentUpon>VisualSettings.cs</DependentUpon>
</Compile>
<EmbeddedResource Include="AboutBox.resx">
<DependentUpon>AboutBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="dlgBootstrap.resx">
<DependentUpon>dlgBootstrap.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UserSettings.resx">
<DependentUpon>UserSettings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UIMain.resx">
<DependentUpon>UIMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<EmbeddedResource Include="VisualSettings.resx">
<DependentUpon>VisualSettings.cs</DependentUpon>
</EmbeddedResource>
<None Include="App.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="lokinet.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>$(SolutionDir)versioning\NetRevisionTool /info /patch "$(ProjectDir)"
$(SolutionDir)versioning\release.bat</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>$(SolutionDir)versioning\NetRevisionTool /restore "$(ProjectDir)"
$(SolutionDir)versioning\unpatch.bat</PostBuildEvent>
</PropertyGroup>
</Project>

@ -1,25 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lokivpn", "lokivpn.csproj", "{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {43867E52-9394-4EFC-A8FA-4382447D4B24}
EndGlobalSection
EndGlobal

@ -1,4 +0,0 @@
REM this requires some kind of cygwin toolset in $PATH
REM or just having sed(1) at a minimum
set /P RELEASE_NAME=<..\..\..\motto.txt
sed -i "s/RELEASE_CODENAME/%RELEASE_NAME%/g" ..\..\Properties\AssemblyInfo.cs

@ -1,4 +0,0 @@
REM this requires some kind of cygwin toolset in $PATH
REM or just having sed(1) at a minimum
set /P RELEASE_NAME=<..\..\..\motto.txt
sed -i "s/%RELEASE_NAME%/RELEASE_CODENAME/g" ..\..\Properties\AssemblyInfo.cs
Loading…
Cancel
Save